Merge branch 'patch/JAL-2197_jpredforjnets' into develop
authorJim Procter <jprocter@issues.jalview.org>
Wed, 14 Dec 2016 15:08:14 +0000 (15:08 +0000)
committerJim Procter <jprocter@issues.jalview.org>
Wed, 14 Dec 2016 15:08:14 +0000 (15:08 +0000)
merge was missed for 2.10.1 release!

412 files changed:
.classpath
AUTHORS
RELEASE
THIRDPARTYLIBS
appletlib/JmolApplet-14.2.14_2015.06.11.jar [deleted file]
appletlib/JmolApplet-14.6.4_2016.10.26.jar [new file with mode: 0644]
build.xml
examples/appletDeployment.html
examples/applets.html
examples/embedded.html
examples/embeddedWJmol.html
examples/exampleFile.jar
examples/exampleFile_2_3.jar
examples/exampleFile_2_7.jar
examples/ferredoxin.nw
examples/formComplete.html
examples/groovy/selectColumnsByFeatureAndGroup.groovy
examples/javascript/facebox-1.3.js [new file with mode: 0644]
examples/javascriptLaunch.html
examples/linkedapplets_ng.html
examples/plantfdx.fa
examples/uniref50.fa
examples/uniref50_mz.fa
help/help.jhm
help/helpTOC.xml
help/html/colourSchemes/abovePID.html
help/html/editing/index.html
help/html/features/chimera.html
help/html/features/clarguments.html
help/html/features/featuresFormat.html
help/html/features/jmol.html
help/html/features/search.html
help/html/io/exportseqreport.html
help/html/keys.html
help/html/menus/alignmentMenu.html
help/html/menus/alwselect.html
help/html/misc/aaproperties.html
help/html/releases.html
help/html/webServices/dbreffetcher.html
help/html/webServices/urllinks.html
help/html/whatsNew.html
lib/Jmol-14.2.14_2015.06.11.jar [deleted file]
lib/Jmol-14.6.4_2016.10.26.jar [new file with mode: 0644]
nbproject/project.properties
resources/authors.props
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/MCview/AppletPDBCanvas.java
src/MCview/AppletPDBViewer.java
src/MCview/PDBCanvas.java
src/MCview/PDBChain.java
src/MCview/PDBViewer.java
src/MCview/PDBfile.java
src/ext/edu/ucsf/rbvi/strucviz2/ChimUtils.java
src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java
src/ext/edu/ucsf/rbvi/strucviz2/ChimeraModel.java
src/ext/edu/ucsf/rbvi/strucviz2/StructureManager.java
src/ext/edu/ucsf/rbvi/strucviz2/StructureSettings.java
src/ext/edu/ucsf/rbvi/strucviz2/port/ListenerThreads.java
src/jalview/analysis/AAFrequency.java
src/jalview/analysis/AlignSeq.java
src/jalview/analysis/Conservation.java
src/jalview/analysis/Finder.java
src/jalview/api/AlignViewControllerI.java
src/jalview/api/AlignViewportI.java
src/jalview/api/FeatureRenderer.java
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AlignViewport.java
src/jalview/appletgui/AlignmentPanel.java
src/jalview/appletgui/AppletJmol.java
src/jalview/appletgui/AppletJmolBinding.java
src/jalview/appletgui/CutAndPasteTransfer.java
src/jalview/appletgui/ExtJmol.java
src/jalview/appletgui/FeatureRenderer.java
src/jalview/appletgui/Finder.java
src/jalview/appletgui/IdPanel.java
src/jalview/appletgui/SeqCanvas.java
src/jalview/appletgui/SeqPanel.java
src/jalview/appletgui/TreeCanvas.java
src/jalview/bin/Jalview.java
src/jalview/bin/JalviewLite.java
src/jalview/bin/JalviewLiteURLRetrieve.java
src/jalview/controller/AlignViewController.java
src/jalview/datamodel/AlignedCodonFrame.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentI.java
src/jalview/datamodel/PDBEntry.java
src/jalview/datamodel/Profile.java [new file with mode: 0644]
src/jalview/datamodel/ProfileI.java [new file with mode: 0644]
src/jalview/datamodel/Profiles.java [new file with mode: 0644]
src/jalview/datamodel/ProfilesI.java [new file with mode: 0644]
src/jalview/datamodel/ResidueCount.java [new file with mode: 0644]
src/jalview/datamodel/SearchResultMatchI.java [new file with mode: 0644]
src/jalview/datamodel/SearchResults.java
src/jalview/datamodel/SearchResultsI.java [new file with mode: 0644]
src/jalview/datamodel/SequenceFeature.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/ext/android/ContainerHelpers.java [new file with mode: 0644]
src/jalview/ext/android/SparseIntArray.java [new file with mode: 0644]
src/jalview/ext/android/SparseShortArray.java [new file with mode: 0644]
src/jalview/ext/ensembl/EnsemblFeatures.java
src/jalview/ext/ensembl/EnsemblRestClient.java
src/jalview/ext/ensembl/EnsemblSeqProxy.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/ext/jmol/JmolParser.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/gui/AlignExportSettings.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/AnnotationChooser.java
src/jalview/gui/AnnotationLabels.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/AppJmol.java
src/jalview/gui/AppJmolBinding.java
src/jalview/gui/AppVarnaBinding.java
src/jalview/gui/AssociatePdbFileWithSeq.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/CrossRefAction.java
src/jalview/gui/CutAndPasteTransfer.java
src/jalview/gui/DasSourceBrowser.java
src/jalview/gui/Desktop.java
src/jalview/gui/EPSOptions.java
src/jalview/gui/EditNameDialog.java
src/jalview/gui/FeatureRenderer.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/Finder.java
src/jalview/gui/FontChooser.java
src/jalview/gui/HTMLOptions.java
src/jalview/gui/IdPanel.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/Jalview2XML_V1.java
src/jalview/gui/JalviewChimeraBindingModel.java
src/jalview/gui/JvOptionPane.java [new file with mode: 0644]
src/jalview/gui/OOMWarning.java
src/jalview/gui/PCAPanel.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/Preferences.java
src/jalview/gui/PromptUserConfig.java
src/jalview/gui/RestInputParamEditDialog.java
src/jalview/gui/SVGOptions.java
src/jalview/gui/SeqCanvas.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/SequenceFetcher.java
src/jalview/gui/StructureChooser.java
src/jalview/gui/StructureViewerBase.java
src/jalview/gui/TextColourChooser.java
src/jalview/gui/TreeCanvas.java
src/jalview/gui/TreePanel.java
src/jalview/gui/UserDefinedColours.java
src/jalview/gui/UserQuestionnaireCheck.java
src/jalview/gui/VamsasApplication.java
src/jalview/gui/WebserviceInfo.java
src/jalview/gui/WsJobParameters.java
src/jalview/gui/WsParamSetManager.java
src/jalview/gui/WsPreferences.java
src/jalview/io/AMSAFile.java
src/jalview/io/AlignFile.java
src/jalview/io/AlignmentFileI.java [new file with mode: 0644]
src/jalview/io/AnnotationFile.java
src/jalview/io/AppletFormatAdapter.java
src/jalview/io/BLCFile.java
src/jalview/io/BioJsHTMLOutput.java
src/jalview/io/ClustalFile.java
src/jalview/io/DBRefFile.java
src/jalview/io/DataSourceType.java [new file with mode: 0644]
src/jalview/io/FastaFile.java
src/jalview/io/FeaturesFile.java
src/jalview/io/FileFormat.java [new file with mode: 0644]
src/jalview/io/FileFormatException.java [new file with mode: 0644]
src/jalview/io/FileFormatI.java [new file with mode: 0644]
src/jalview/io/FileLoader.java
src/jalview/io/FileParse.java
src/jalview/io/FormatAdapter.java
src/jalview/io/HTMLOutput.java
src/jalview/io/HtmlFile.java
src/jalview/io/HtmlSvgOutput.java
src/jalview/io/IdentifyFile.java
src/jalview/io/JPredFile.java
src/jalview/io/JSONFile.java
src/jalview/io/JalviewFileChooser.java
src/jalview/io/JalviewFileView.java
src/jalview/io/JnetAnnotationMaker.java
src/jalview/io/MSFfile.java
src/jalview/io/NewickFile.java
src/jalview/io/PIRFile.java
src/jalview/io/PfamFile.java
src/jalview/io/PhylipFile.java
src/jalview/io/PileUpfile.java
src/jalview/io/RnamlFile.java
src/jalview/io/SequenceAnnotationReport.java
src/jalview/io/SimpleBlastFile.java
src/jalview/io/StockholmFile.java
src/jalview/io/StructureFile.java
src/jalview/io/TCoffeeScoreFile.java
src/jalview/io/WSWUBlastClient.java
src/jalview/io/packed/ParsePackedSet.java
src/jalview/jbgui/GAlignExportSettings.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/jbgui/GDesktop.java
src/jalview/jbgui/GFinder.java
src/jalview/jbgui/GSequenceLink.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/renderer/seqfeatures/FeatureRenderer.java
src/jalview/schemes/Blosum62ColourScheme.java
src/jalview/schemes/ColourSchemeI.java
src/jalview/schemes/FollowerColourScheme.java
src/jalview/schemes/PIDColourScheme.java
src/jalview/schemes/ResidueColourScheme.java
src/jalview/schemes/ResidueProperties.java
src/jalview/structure/SequenceListener.java
src/jalview/structure/StructureImportSettings.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/structures/models/AAStructureBindingModel.java
src/jalview/util/ColorUtils.java
src/jalview/util/Comparison.java
src/jalview/util/DBRefUtils.java
src/jalview/util/Format.java
src/jalview/util/ImageMaker.java
src/jalview/util/MappingUtils.java
src/jalview/util/Platform.java
src/jalview/util/SparseCount.java [new file with mode: 0644]
src/jalview/util/UrlConstants.java [new file with mode: 0644]
src/jalview/util/UrlLink.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java
src/jalview/workers/ComplementConsensusThread.java
src/jalview/workers/ConsensusThread.java
src/jalview/workers/ConservationThread.java
src/jalview/ws/DasSequenceFeatureFetcher.java
src/jalview/ws/dbsources/EmblXmlSource.java
src/jalview/ws/dbsources/Pdb.java
src/jalview/ws/dbsources/Pfam.java
src/jalview/ws/dbsources/Uniprot.java
src/jalview/ws/dbsources/Xfam.java
src/jalview/ws/ebi/EBIFetchClient.java
src/jalview/ws/jws1/Annotate3D.java
src/jalview/ws/jws1/Discoverer.java
src/jalview/ws/jws1/JPredClient.java
src/jalview/ws/jws1/JPredThread.java
src/jalview/ws/jws1/MsaWSClient.java
src/jalview/ws/jws1/SeqSearchWSClient.java
src/jalview/ws/jws1/SeqSearchWSThread.java
src/jalview/ws/jws2/MsaWSClient.java
src/jalview/ws/jws2/SequenceAnnotationWSClient.java
src/jalview/ws/rest/RestClient.java
src/jalview/ws/rest/params/Alignment.java
src/jalview/ws/seqfetcher/DbSourceProxyImpl.java
src/jalview/ws/sifts/SiftsClient.java
test/MCview/AtomTest.java
test/MCview/BondTest.java
test/MCview/PDBChainTest.java
test/MCview/PDBfileTest.java
test/MCview/ResidueTest.java
test/jalview/analysis/AAFrequencyTest.java
test/jalview/analysis/AlignSeqTest.java
test/jalview/analysis/AlignmentAnnotationUtilsTest.java
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/analysis/AnnotationSorterTest.java
test/jalview/analysis/CodingUtilsTest.java
test/jalview/analysis/ConservationTest.java [new file with mode: 0644]
test/jalview/analysis/CrossRefTest.java
test/jalview/analysis/DnaAlignmentGenerator.java
test/jalview/analysis/DnaTest.java
test/jalview/analysis/FinderTest.java [new file with mode: 0644]
test/jalview/analysis/GroupingTest.java
test/jalview/analysis/ParsePropertiesTest.java
test/jalview/analysis/RnaTest.java
test/jalview/analysis/SeqsetUtilsTest.java
test/jalview/analysis/SequenceIdMatcherTest.java
test/jalview/analysis/TestAlignSeq.java
test/jalview/analysis/scoremodels/FeatureScoreModelTest.java
test/jalview/bin/ArgsParserTest.java
test/jalview/bin/CacheTest.java
test/jalview/bin/CommandLineOperations.java
test/jalview/bin/JalviewLiteTest.java
test/jalview/commands/EditCommandTest.java
test/jalview/commands/TrimRegionCommandTest.java
test/jalview/controller/AlignViewControllerTest.java
test/jalview/datamodel/AlignedCodonFrameTest.java
test/jalview/datamodel/AlignedCodonIteratorTest.java
test/jalview/datamodel/AlignedCodonTest.java
test/jalview/datamodel/AlignmentAnnotationTests.java
test/jalview/datamodel/AlignmentTest.java
test/jalview/datamodel/AlignmentViewTest.java
test/jalview/datamodel/ColumnSelectionTest.java
test/jalview/datamodel/ConcurrentModificationTest.java [new file with mode: 0644]
test/jalview/datamodel/DBRefEntryTest.java
test/jalview/datamodel/HiddenSequencesTest.java
test/jalview/datamodel/MappingTest.java
test/jalview/datamodel/MappingTypeTest.java
test/jalview/datamodel/MatchTest.java
test/jalview/datamodel/PDBEntryTest.java
test/jalview/datamodel/ResidueCountTest.java [new file with mode: 0644]
test/jalview/datamodel/SearchResultsTest.java
test/jalview/datamodel/SeqCigarTest.java
test/jalview/datamodel/SequenceDummyTest.java
test/jalview/datamodel/SequenceFeatureTest.java
test/jalview/datamodel/SequenceTest.java
test/jalview/datamodel/xdb/embl/EmblEntryTest.java
test/jalview/datamodel/xdb/embl/EmblFileTest.java
test/jalview/ext/android/SparseIntArrayTest.java [new file with mode: 0644]
test/jalview/ext/android/SparseShortArrayTest.java [new file with mode: 0644]
test/jalview/ext/ensembl/EnsemblCdnaTest.java
test/jalview/ext/ensembl/EnsemblCdsTest.java
test/jalview/ext/ensembl/EnsemblGeneTest.java
test/jalview/ext/ensembl/EnsemblGenomeTest.java
test/jalview/ext/ensembl/EnsemblProteinTest.java
test/jalview/ext/ensembl/EnsemblSeqProxyTest.java
test/jalview/ext/ensembl/EnsemblXrefTest.java
test/jalview/ext/htsjdk/TestHtsContigDb.java
test/jalview/ext/jmol/JmolCommandsTest.java
test/jalview/ext/jmol/JmolParserTest.java
test/jalview/ext/jmol/JmolViewerTest.java
test/jalview/ext/jmol/JmolVsJalviewPDBParserEndToEndTest.java
test/jalview/ext/paradise/TestAnnotate3D.java
test/jalview/ext/rbvi/chimera/ChimeraCommandsTest.java
test/jalview/ext/rbvi/chimera/ChimeraConnect.java
test/jalview/ext/rbvi/chimera/JalviewChimeraView.java
test/jalview/ext/so/SequenceOntologyTest.java
test/jalview/fts/core/FTSRestClientTest.java
test/jalview/fts/service/pdb/PDBFTSPanelTest.java
test/jalview/fts/service/pdb/PDBFTSRestClientTest.java
test/jalview/gui/AlignFrameTest.java
test/jalview/gui/AlignViewportTest.java
test/jalview/gui/AnnotationChooserTest.java
test/jalview/gui/AppVarnaTest.java
test/jalview/gui/FontChooserTest.java
test/jalview/gui/HelpTest.java
test/jalview/gui/JAL1353bugdemo.java
test/jalview/gui/JvOptionPaneTest.java [new file with mode: 0644]
test/jalview/gui/JvSwingUtilsTest.java
test/jalview/gui/PaintRefresherTest.java
test/jalview/gui/PopupMenuTest.java
test/jalview/gui/ProgressBarTest.java
test/jalview/gui/SequenceRendererTest.java
test/jalview/gui/StructureChooserTest.java
test/jalview/gui/StructureViewerTest.java
test/jalview/io/3ucu.cif [new file with mode: 0644]
test/jalview/io/AnnotatedPDBFileInputTest.java
test/jalview/io/AnnotationFileIOTest.java
test/jalview/io/BioJsHTMLOutputTest.java
test/jalview/io/CrossRef2xmlTests.java
test/jalview/io/FeaturesFileTest.java
test/jalview/io/FileIOTester.java
test/jalview/io/FormatAdapterTest.java
test/jalview/io/HtmlFileTest.java
test/jalview/io/IdentifyFileTest.java
test/jalview/io/JSONFileTest.java
test/jalview/io/Jalview2xmlBase.java
test/jalview/io/Jalview2xmlTests.java
test/jalview/io/JalviewExportPropertiesTests.java
test/jalview/io/JalviewFileViewTest.java [new file with mode: 0644]
test/jalview/io/NewickFileTests.java
test/jalview/io/PfamFormatInputTest.java
test/jalview/io/PhylipFileTests.java
test/jalview/io/RNAMLfileTest.java
test/jalview/io/SequenceAnnotationReportTest.java
test/jalview/io/StockholmFileTest.java
test/jalview/io/TCoffeeScoreFileTest.java
test/jalview/io/gff/ExonerateHelperTest.java
test/jalview/io/gff/Gff3HelperTest.java
test/jalview/io/gff/GffHelperBaseTest.java
test/jalview/io/gff/GffHelperFactoryTest.java
test/jalview/io/gff/GffTests.java
test/jalview/io/gff/InterProScanHelperTest.java
test/jalview/schemes/DnaCodonTests.java
test/jalview/schemes/FeatureColourTest.java
test/jalview/schemes/ResidueColourSchemeTest.java [new file with mode: 0644]
test/jalview/schemes/ResiduePropertiesTest.java
test/jalview/schemes/ScoreMatrixPrinter.java
test/jalview/schemes/UserColourSchemeTest.java
test/jalview/structure/Mapping.java
test/jalview/structure/StructureSelectionManagerTest.java
test/jalview/structures/models/AAStructureBindingModelTest.java
test/jalview/util/ArrayUtilsTest.java
test/jalview/util/CaseInsensitiveStringTest.java
test/jalview/util/ColorUtilsTest.java
test/jalview/util/ComparisonTest.java
test/jalview/util/DBRefUtilsTest.java
test/jalview/util/DnaUtilsTest.java
test/jalview/util/FormatTest.java [new file with mode: 0644]
test/jalview/util/MapListTest.java
test/jalview/util/MappingUtilsTest.java
test/jalview/util/ParseHtmlBodyAndLinksTest.java
test/jalview/util/PlatformTest.java [new file with mode: 0644]
test/jalview/util/QuickSortTest.java
test/jalview/util/ShiftListTest.java
test/jalview/util/SparseCountTest.java [new file with mode: 0644]
test/jalview/util/StringUtilsTest.java
test/jalview/util/UrlLinkTest.java [new file with mode: 0644]
test/jalview/viewmodel/styles/ViewStyleTest.java
test/jalview/workers/AlignCalcManagerTest.java
test/jalview/ws/PDBSequenceFetcherTest.java
test/jalview/ws/SequenceFetcherTest.java
test/jalview/ws/dbsources/UniprotTest.java
test/jalview/ws/dbsources/XfamFetcherTest.java
test/jalview/ws/ebi/EBIFetchClientTest.java
test/jalview/ws/gui/Jws2ParamView.java
test/jalview/ws/jabaws/DisorderAnnotExportImport.java
test/jalview/ws/jabaws/JalviewJabawsTestUtils.java
test/jalview/ws/jabaws/JpredJabaStructExportImport.java
test/jalview/ws/jabaws/MinJabawsClientTests.java
test/jalview/ws/jabaws/RNAStructExportImport.java
test/jalview/ws/jws2/ParameterUtilsTest.java
test/jalview/ws/rest/RestClientTest.java
test/jalview/ws/rest/ShmmrRSBSService.java
test/jalview/ws/seqfetcher/DasSequenceFetcher.java
test/jalview/ws/seqfetcher/DbRefFetcherTest.java
test/jalview/ws/sifts/SiftsClientTest.java
utils/InstallAnywhere/Jalview.iap_xml

index 6583992..8aef745 100644 (file)
@@ -64,7 +64,7 @@
        <classpathentry kind="lib" path="lib/jetty-http-9.2.10.v20150310.jar"/>
        <classpathentry kind="lib" path="lib/jetty-io-9.2.10.v20150310.jar"/>
        <classpathentry kind="lib" path="lib/java-json.jar"/>
-       <classpathentry kind="lib" path="lib/Jmol-14.2.14_2015.06.11.jar"/>
+       <classpathentry kind="lib" path="lib/Jmol-14.6.4_2016.10.26.jar"/>
        <classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
        <classpathentry kind="lib" path="lib/biojava-core-4.1.0.jar"/>
        <classpathentry kind="lib" path="lib/biojava-ontology-4.1.0.jar"/>
diff --git a/AUTHORS b/AUTHORS
index f0b4787..1bfc734 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -7,15 +7,16 @@ or might otherwise be considered author of Jalview.
 The people listed below are 'The Jalview Authors', who collectively
 own the copyright to the Jalview source code and permit it to be released under GPL.
 
-This is the authoritative list. It was correct on 6th Oct 2016.
+This is the authoritative list. It was correct on 23rd November 2016.
 If you are releasing a version of Jalview, please make sure any
 statement of authorship in the GUI reflects the list shown here.
 In particular, check the resources/authors.props file ! 
 
 Jim Procter
-Andrew Waterhouse
 Mungo Carstairs
 Tochukwu 'Charles' Ofoegbu
+Kira Mourao
+Andrew Waterhouse
 Jan Engelhardt
 Lauren Lui
 Anne Menard
diff --git a/RELEASE b/RELEASE
index c29c5d5..9bc5817 100644 (file)
--- a/RELEASE
+++ b/RELEASE
@@ -1,2 +1,2 @@
-jalview.release=Release_2_10_Branch
-jalview.version=2.10.0
+jalview.release=releases/Release_2_10_1_Branch
+jalview.version=2.10.1
index 31ad2f5..e0be904 100644 (file)
@@ -6,11 +6,14 @@ A number of sources have also been adapted for incorporation into Jalview's sour
 
 ext.edu.ucsf.rbvi.strucviz2 includes sources originally developed by Scooter Morris and Nadezhda Doncheva for the Cytoscape StructureViz2 plugin. It is released under the Berkley license and we hereby acknowledge its original copyright is held by the UCSF Computer Graphics Laboratory
  and the software was developed with support by the NIH National Center for Research Resources, grant P41-RR01081. 
+ jalview.ext.android includes code taken from the Android Open Source Project (https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util).
+ The Apache 2.0 Licence (http://www.apache.org/licenses/LICENSE-2.0) is acknowledged in the source code.
 
-Licencing information for each library is given below:
+Licensing information for each library is given below:
 
 JGoogleAnalytics_0.3.jar       APL 2.0 License - http://code.google.com/p/jgoogleanalytics/
-Jmol-14.2.14_2015.06.11.jar    GPL/LGPLv2 http://sourceforge.net/projects/jmol/files/
+Jmol-14.6.4_2016.10.26.jar     GPL/LGPLv2 http://sourceforge.net/projects/jmol/files/
 VARNAv3-93.jar GPL licenced software by K�vin Darty, Alain Denise and Yann Ponty. http://varna.lri.fr
 activation.jar 
 apache-mime4j-0.6.jar
@@ -58,4 +61,5 @@ Additional dependencies
 examples/javascript/deployJava.js : http://java.com/js/deployJava.js
 examples/javascript/jquery*.js : BSD license
 examples/javascript/jshashtable-2.1.js : Apache License
+examples/javascript/facebox-1.3.js : MTI License - http://www.opensource.org/licenses/mit-license.php
 
diff --git a/appletlib/JmolApplet-14.2.14_2015.06.11.jar b/appletlib/JmolApplet-14.2.14_2015.06.11.jar
deleted file mode 100644 (file)
index 5d6338c..0000000
Binary files a/appletlib/JmolApplet-14.2.14_2015.06.11.jar and /dev/null differ
diff --git a/appletlib/JmolApplet-14.6.4_2016.10.26.jar b/appletlib/JmolApplet-14.6.4_2016.10.26.jar
new file mode 100644 (file)
index 0000000..e5c312c
Binary files /dev/null and b/appletlib/JmolApplet-14.6.4_2016.10.26.jar differ
index d8f12e0..8d27614 100755 (executable)
--- a/build.xml
+++ b/build.xml
     <property name="packageDir" value="dist" />
     <property name="outputJar" value="jalview.jar" />
     <!-- Jalview Applet JMol Jar Dependency -->
-    <property name="jmolJar" value="JmolApplet-14.2.14_2015.06.11.jar" />
+    <property name="jmolJar" value="JmolApplet-14.6.4_2016.10.26.jar" />
     <property name="varnaJar" value="VARNAv3-93.jar" />
     <property name="jsoup" value="jsoup-1.8.1.jar" />
     <property name="jsonSimple" value="json_simple-1.1.jar" />
 </target>
 <target name="sourcedist" description="create jalview source distribution" depends="init">
   <delete file="${source.dist.name}" />
-  <tar destfile="${source.dist.name}" compression="gzip">
-    <tarfileset dir="./" prefix="jalview" preserveLeadingSlashes="true">
+  <!-- temporary copy of source to update timestamps -->
+  <copy todir="_sourcedist">
+    <fileset dir=".">
+      <exclude name=".*" />
+      <exclude name="**/.*" />
+      <exclude name="*.class" />
+      <exclude name="**/*.class" />
       <include name="LICENSE" />
       <include name="README" />
       <include name="build.xml" />
       <exclude name="utils/InstallAnywhere/**Build.iap_xml" />
       <exclude name="utils/InstallAnywhere/**Build*/**" />
       <exclude name="utils/InstallAnywhere/**Build*/**" />
+      <exclude name="utils/InstallAnywhere/.build*.*/**" />
       <exclude name="utils/InstallAnywhere/**locale*" />
       <exclude name="utils/InstallAnywhere/**locale*/**" />
+      <exclude name="utils/InstallAnywhere/**locale*/**" />
       <include name="${schemaDir}/**/*" />
       <include name="utils/**/*" />
       <include name="${docDir}/**/*" />
       <include name="examples/**/*" />
+    </fileset>
+  </copy>
+
+  <tstamp prefix="build">
+    <format property="year" pattern="yyyy" />
+  </tstamp>
+  <!-- each replacetoken CDATA body must be on one line - 
+       otherwise the pattern doesn't match -->
+  <replace value="${JALVIEW_VERSION}">
+    <replacetoken><![CDATA[$$Version-Rel$$]]></replacetoken>
+    <fileset dir="_sourcedist">
+      <include name="**/*" />
+    </fileset>
+  </replace>
+  <replace dir="_sourcedist" value="${build.year}">
+    <replacetoken><![CDATA[$$Year-Rel$$]]></replacetoken>
+    <fileset dir="_sourcedist">
+      <include name="**/*" />
+    </fileset>
+  </replace>
+
+  <tar destfile="${source.dist.name}" compression="gzip">
+    <tarfileset dir="_sourcedist/" prefix="jalview" preserveLeadingSlashes="true">
     </tarfileset>
   </tar>
+
+  <delete dir="_sourcedist" />
 </target>
 <target name="prepubapplet_1" depends="makeApplet">
   <copy todir="${packageDir}/examples">
index 9438fa4..e9c22e5 100644 (file)
@@ -33,7 +33,7 @@
     <td>Main Jalview Applet Jar</td>
   </tr>
   <tr>
-    <td><a href="http://www.jalview.org/builds/develop/examples/JmolApplet-14.2.14_2015.06.11.jar">JmolApplet-14.2.14_2015.06.11.jar</a> </td>
+    <td><a href="http://www.jalview.org/builds/develop/examples/JmolApplet-14.6.4_2016.10.26.jar">JmolApplet-14.6.4_2016.10.26.jar</a> </td>
     <td>Jmol Applet Jar</td>
   </tr>
   <tr>
@@ -48,7 +48,7 @@
 
 <p>To run Jalview applet in your web page download the Jars listed above. The snippet below shows a minimal code for embedding Jalview applet into a web page.    
 <pre><code>
-&lt;applet code="jalview.bin.JalviewLite" width="756" height="560" archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar"&gt;
+&lt;applet code="jalview.bin.JalviewLite" width="756" height="560" archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar"&gt;
        &lt;param name="permissions" value="sandbox" /&gt;
        &lt;param name="file" value="plantfdx.fa" /&gt;
        &lt;param name="features" value="plantfdx.features" /&gt;
index e0695b9..b789672 100644 (file)
@@ -41,7 +41,7 @@ Try out JalviewLite by pressing one of the buttons below.
       <td width="10%" valign="center">
       <applet
        code="jalview.bin.JalviewLite" width="140" height="35"
-       archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">  
+       archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">  
        <param name="permissions" value="sandbox"/>
        <param name="file" value="uniref50.fa"/>
        <param name="treeFile" value="ferredoxin.nw"/>
@@ -64,7 +64,7 @@ Try out JalviewLite by pressing one of the buttons below.
     <tr>
       <td width="10%" valign="center"><applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="uniref50.fa"/>
 <param name="features" value="exampleFeatures.txt"/>
@@ -89,7 +89,7 @@ Try out JalviewLite by pressing one of the buttons below.
     <tr>
       <td width="10%" valign="center"><applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="uniref50.fa"/>
 <param name="showFullId" value="false"/>
@@ -116,7 +116,7 @@ Try out JalviewLite by pressing one of the buttons below.
     <tr>
       <td width="10%" valign="center"><applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="jpred_msa.fasta"/>
 <param name="jnetfile" value="jpred_msa.seq.concise"/>
@@ -147,7 +147,7 @@ Try out JalviewLite by pressing one of the buttons below.
     <tr>
       <td width="10%" valign="center"><applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="RF00031_folded.stk"/>
 <param name="showFullId" value="false"/>
@@ -171,7 +171,7 @@ Try out JalviewLite by pressing one of the buttons below.
       <td width="10%" valign="center">
 <applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file2" value="estrogenReceptorCdna_frag.fa"/>
 <param name="file" value="estrogenReceptorProtein_frag.fa"/>
index 0d5ddf3..0cea17d 100644 (file)
@@ -40,7 +40,7 @@
   <a href="view-source:http://www.jalview.org/builds/develop/examples/embedded.html" target="_blank">View the source code for this example here</a> (If the link doesn't work on your browser try going to <a href="http://www.jalview.org/builds/develop/examples/embedded.html">this page</a> and viewing the page source manually).<p>
   <applet
    code="jalview.bin.JalviewLite" width="756" height="560"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="plantfdx.fa"/>
 <param name="features" value="plantfdx.features"/>
index 501c20e..6fdcc07 100644 (file)
@@ -211,7 +211,7 @@ jQuery.extend(Drupal.settings, {"basePath":"\/","pathPrefix":"","ajaxPageState":
 <script language="JavaScript">
 // instead of this, we use a custom JmolApplet spec
 // jmolInitialize('jmol');
-jmolInitialize("","JmolApplet-14.2.14_2015.06.11.jar");
+jmolInitialize("","JmolApplet-14.6.4_2016.10.26.jar");
 </script>
 <script>
  var loglevel=1;
@@ -242,7 +242,7 @@ jmolInitialize("","JmolApplet-14.2.14_2015.06.11.jar");
  var _jvA=new Object();
  _jvA.attributes = {
   code : 'jalview.bin.JalviewLite',
-  archive : 'jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar',
+  archive : 'jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar',
   width : '500',
   height : '350',
   mayscript : 'True',
@@ -295,7 +295,7 @@ jmolInitialize("","JmolApplet-14.2.14_2015.06.11.jar");
 </div>
 <div>
 <applet
-   code="jalview.bin.JalviewLite" width="500" height="350" id="jvA" mayscript="mayscript" archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   code="jalview.bin.JalviewLite" width="500" height="350" id="jvA" mayscript="mayscript" archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="java_arguments" value="-Xmx256m"/>
 <param name="externalstructureviewer" value="true"/>
index 3231974..2f9000d 100755 (executable)
Binary files a/examples/exampleFile.jar and b/examples/exampleFile.jar differ
index adf707e..1a8bef0 100644 (file)
Binary files a/examples/exampleFile_2_3.jar and b/examples/exampleFile_2_3.jar differ
index 0b70e66..7cd9d77 100644 (file)
Binary files a/examples/exampleFile_2_7.jar and b/examples/exampleFile_2_7.jar differ
index 0b949de..89ea348 100755 (executable)
@@ -1 +1 @@
-(((FER_BRANA:128.0,FER3_RAPSA:128.0):50.75,FER_CAPAA:178.75):121.94443,(Q93Z60_ARATH:271.45456,((O80429_MAIZE:183.0,FER1_MAIZE:183.0):30.5,((Q7XA98_TRIPR:90.0,FER1_PEA:90.0):83.32143,(((FER2_ARATH:64.0,FER1_ARATH:64.0):94.375,(FER1_SPIOL:124.5,FER1_MESCR:124.5):33.875):6.4166718,((Q93XJ9_SOLTU:33.5,FER1_SOLLC:33.5):49.0,FER_CAPAN:82.5):82.29167):8.529755):40.178574):57.95456):29.239868);
+(((FER_BRANA:128.0,FER3_RAPSA:128.0):50.75,FER_CAPAA:178.75):121.94443,(Q93Z60_ARATH:271.45456,((O80429_MAIZE:183.0,FER1_MAIZE:183.0):30.5,((Q7XA98_TRIPR:90.0,FER1_PEA:90.0):83.32143,(((FER1_ARATH:64.0,FER2_ARATH:64.0):94.375,(FER1_SPIOL:124.5,FER1_MESCR:124.5):33.875):6.4166718,((Q93XJ9_SOLTU:33.5,FER1_SOLLC:33.5):49.0,FER_CAPAN:82.5):82.29167):8.529755):40.178574):57.95456):29.239868);
index 9e89990..65a3a45 100644 (file)
@@ -36,7 +36,7 @@ instance on the page.</p>
   <a href="view-source:http://www.jalview.org/builds/develop/examples/formComplete.html" target="_blank">View the source here to see how it has been done</a>  (If the link doesn't work on your browser try going to <a href="http://www.jalview.org/builds/develop/examples/formComplete.html">this page</a> and viewing the page source manually).<br/>
 <a name="api">View the full <a href="javascript:doSubmit('jalviewLiteJs')">JalviewLite API documentation</a>.</a>
 <applet code="jalview.bin.JalviewLite" width="0" height="0"
-       archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar" name="Jalview">
+       archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar" name="Jalview">
   
   <param name="file" value="plantfdx.fa"/>
   <param name="features" value="plantfdx.features"/>
index 0b479bf..b8edaa7 100644 (file)
@@ -92,8 +92,8 @@ return "Found a total of ${nfeat} features across ${nseq} sequences in ${nal} al
     
 String getFeatureInput(){
         def swingBuilder = new SwingBuilder();
-        def response = JOptionPane.showInputDialog(
-                   null, 'Select columns by feature by type','Enter type of feature', JOptionPane.OK_OPTION)
+        def response = JvOptionPane.showInputDialog(
+                   null, 'Select columns by feature by type','Enter type of feature', JvOptionPane.OK_OPTION)
 
         return response
     }
\ No newline at end of file
diff --git a/examples/javascript/facebox-1.3.js b/examples/javascript/facebox-1.3.js
new file mode 100644 (file)
index 0000000..ad45310
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * Facebox (for jQuery)
+ * version: 1.2 (05/05/2008)
+ * @requires jQuery v1.2 or later
+ *
+ * Examples at http://famspam.com/facebox/
+ *
+ * Licensed under the MIT:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *
+ * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ]
+ *
+ * Usage:
+ *
+ *  jQuery(document).ready(function() {
+ *    jQuery('a[rel*=facebox]').facebox()
+ *  })
+ *
+ *  <a href="#terms" rel="facebox">Terms</a>
+ *    Loads the #terms div in the box
+ *
+ *  <a href="terms.html" rel="facebox">Terms</a>
+ *    Loads the terms.html page in the box
+ *
+ *  <a href="terms.png" rel="facebox">Terms</a>
+ *    Loads the terms.png image in the box
+ *
+ *
+ *  You can also use it programmatically:
+ *
+ *    jQuery.facebox('some html')
+ *    jQuery.facebox('some html', 'my-groovy-style')
+ *
+ *  The above will open a facebox with "some html" as the content.
+ *
+ *    jQuery.facebox(function($) {
+ *      $.get('blah.html', function(data) { $.facebox(data) })
+ *    })
+ *
+ *  The above will show a loading screen before the passed function is called,
+ *  allowing for a better ajaxy experience.
+ *
+ *  The facebox function can also display an ajax page, an image, or the contents of a div:
+ *
+ *    jQuery.facebox({ ajax: 'remote.html' })
+ *    jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')
+ *    jQuery.facebox({ image: 'stairs.jpg' })
+ *    jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')
+ *    jQuery.facebox({ div: '#box' })
+ *    jQuery.facebox({ div: '#box' }, 'my-groovy-style')
+ *
+ *  Want to close the facebox?  Trigger the 'close.facebox' document event:
+ *
+ *    jQuery(document).trigger('close.facebox')
+ *
+ *  Facebox also has a bunch of other hooks:
+ *
+ *    loading.facebox
+ *    beforeReveal.facebox
+ *    reveal.facebox (aliased as 'afterReveal.facebox')
+ *    init.facebox
+ *    afterClose.facebox
+ *
+ *  Simply bind a function to any of these hooks:
+ *
+ *   $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
+ *
+ */
+(function($) {
+  $.facebox = function(data, klass) {
+    $.facebox.loading()
+
+    if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)
+    else if (data.image) fillFaceboxFromImage(data.image, klass)
+    else if (data.div) fillFaceboxFromHref(data.div, klass)
+    else if ($.isFunction(data)) data.call($)
+    else $.facebox.reveal(data, klass)
+  }
+
+  /*
+   * Public, $.facebox methods
+   */
+
+  $.extend($.facebox, {
+    settings: {
+      opacity      : 0.2,
+      overlay      : true,
+      loadingImage : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/loading.gif',
+      closeImage   : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png',
+      imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ],
+      faceboxHtml  : '\
+    <div id="facebox" style="display:none;"> \
+      <div class="popup"> \
+        <div class="content"> \
+        </div> \
+        <a href="#" class="close"><img src="https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png" title="close" class="close_image" /></a> \
+      </div> \
+    </div>'
+    },
+
+    loading: function() {
+      init()
+      if ($('#facebox .loading').length == 1) return true
+      showOverlay()
+
+      $('#facebox .content').empty()
+      $('#facebox .body').children().hide().end().
+        append('<div class="loading"><img src="'+$.facebox.settings.loadingImage+'"/></div>')
+
+      $('#facebox').css({
+        top:   getPageScroll()[1] + (getPageHeight() / 10),
+        left:  $(window).width() / 2 - 205
+      }).show()
+
+      $(document).bind('keydown.facebox', function(e) {
+        if (e.keyCode == 27) $.facebox.close()
+        return true
+      })
+      $(document).trigger('loading.facebox')
+    },
+
+    reveal: function(data, klass) {
+      $(document).trigger('beforeReveal.facebox')
+      if (klass) $('#facebox .content').addClass(klass)
+      $('#facebox .content').append('<pre><code>'+JSON.stringify(JSON.parse(data),null,4)+'</pre></code>')
+      $('#facebox .loading').remove()
+      $('#facebox .body').children().fadeIn('normal')
+      $('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').width() / 2))
+      $(document).trigger('reveal.facebox').trigger('afterReveal.facebox')
+    },
+
+    close: function() {
+      $(document).trigger('close.facebox')
+      return false
+    }
+  })
+
+  /*
+   * Public, $.fn methods
+   */
+
+  $.fn.facebox = function(settings) {
+    if ($(this).length == 0) return
+
+    init(settings)
+
+    function clickHandler() {
+      $.facebox.loading(true)
+
+      // support for rel="facebox.inline_popup" syntax, to add a class
+      // also supports deprecated "facebox[.inline_popup]" syntax
+      var klass = this.rel.match(/facebox\[?\.(\w+)\]?/)
+      if (klass) klass = klass[1]
+
+      fillFaceboxFromHref(this.href, klass)
+      return false
+    }
+
+    return this.bind('click.facebox', clickHandler)
+  }
+
+  /*
+   * Private methods
+   */
+
+  // called one time to setup facebox on this page
+  function init(settings) {
+    if ($.facebox.settings.inited) return true
+    else $.facebox.settings.inited = true
+
+    $(document).trigger('init.facebox')
+    makeCompatible()
+
+    var imageTypes = $.facebox.settings.imageTypes.join('|')
+    $.facebox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')$', 'i')
+
+    if (settings) $.extend($.facebox.settings, settings)
+    $('body').append($.facebox.settings.faceboxHtml)
+
+    var preload = [ new Image(), new Image() ]
+    preload[0].src = $.facebox.settings.closeImage
+    preload[1].src = $.facebox.settings.loadingImage
+
+    $('#facebox').find('.b:first, .bl').each(function() {
+      preload.push(new Image())
+      preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1')
+    })
+
+    $('#facebox .close').click($.facebox.close)
+    $('#facebox .close_image').attr('src', $.facebox.settings.closeImage)
+  }
+
+  // getPageScroll() by quirksmode.com
+  function getPageScroll() {
+    var xScroll, yScroll;
+    if (self.pageYOffset) {
+      yScroll = self.pageYOffset;
+      xScroll = self.pageXOffset;
+    } else if (document.documentElement && document.documentElement.scrollTop) {        // Explorer 6 Strict
+      yScroll = document.documentElement.scrollTop;
+      xScroll = document.documentElement.scrollLeft;
+    } else if (document.body) {// all other Explorers
+      yScroll = document.body.scrollTop;
+      xScroll = document.body.scrollLeft;
+    }
+    return new Array(xScroll,yScroll)
+  }
+
+  // Adapted from getPageSize() by quirksmode.com
+  function getPageHeight() {
+    var windowHeight
+    if (self.innerHeight) {    // all except Explorer
+      windowHeight = self.innerHeight;
+    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
+      windowHeight = document.documentElement.clientHeight;
+    } else if (document.body) { // other Explorers
+      windowHeight = document.body.clientHeight;
+    }
+    return windowHeight
+  }
+
+  // Backwards compatibility
+  function makeCompatible() {
+    var $s = $.facebox.settings
+
+    $s.loadingImage = $s.loading_image || $s.loadingImage
+    $s.closeImage = $s.close_image || $s.closeImage
+    $s.imageTypes = $s.image_types || $s.imageTypes
+    $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml
+  }
+
+  // Figures out what you want to display and displays it
+  // formats are:
+  //     div: #id
+  //   image: blah.extension
+  //    ajax: anything else
+  function fillFaceboxFromHref(href, klass) {
+    // div
+    if (href.match(/#/)) {
+      var url    = window.location.href.split('#')[0]
+      var target = href.replace(url,'')
+      if (target == '#') return
+      $.facebox.reveal($(target).html(), klass)
+
+    // image
+    } else if (href.match($.facebox.settings.imageTypesRegexp)) {
+      fillFaceboxFromImage(href, klass)
+    // ajax
+    } else {
+      fillFaceboxFromAjax(href, klass)
+    }
+  }
+
+  function fillFaceboxFromImage(href, klass) {
+    var image = new Image()
+    image.onload = function() {
+      $.facebox.reveal('<div class="image"><img src="' + image.src + '" /></div>', klass)
+    }
+    image.src = href
+  }
+
+  function fillFaceboxFromAjax(href, klass) {
+    $.get(href, function(data) { $.facebox.reveal(data, klass) })
+  }
+
+  function skipOverlay() {
+    return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null
+  }
+
+  function showOverlay() {
+    if (skipOverlay()) return
+
+    if ($('#facebox_overlay').length == 0)
+      $("body").append('<div id="facebox_overlay" class="facebox_hide"></div>')
+
+    $('#facebox_overlay').hide().addClass("facebox_overlayBG")
+      .css('opacity', $.facebox.settings.opacity)
+      .click(function() { $(document).trigger('close.facebox') })
+      .fadeIn(200)
+    return false
+  }
+
+  function hideOverlay() {
+    if (skipOverlay()) return
+
+    $('#facebox_overlay').fadeOut(200, function(){
+      $("#facebox_overlay").removeClass("facebox_overlayBG")
+      $("#facebox_overlay").addClass("facebox_hide")
+      $("#facebox_overlay").remove()
+    })
+
+    return false
+  }
+
+  /*
+   * Bindings
+   */
+
+  $(document).bind('close.facebox', function() {
+    $(document).unbind('keydown.facebox')
+    $('#facebox').fadeOut(function() {
+      $('#facebox .content').removeClass().addClass('content')
+      $('#facebox .loading').remove()
+      $(document).trigger('afterClose.facebox')
+    })
+    hideOverlay()
+  })
+
+})(jQuery);
index 35b1d81..38f80b7 100644 (file)
@@ -110,7 +110,7 @@ function startJalview(aligURL,title,alwvar) {
 </SCRIPT>
   <form name="Form1">
 <applet name="JalviewLite"  code="jalview.bin.JalviewLite"
-archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar" width="0" height="0">
+archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar" width="0" height="0">
 <param name="debug" value="true"/>
 <param name="showbutton" value="false"/>
 </applet>
index 5890515..8ddfd2f 100644 (file)
@@ -38,7 +38,7 @@
 
 
 <applet
-   code="jalview.bin.JalviewLite" width="800" height="300" id="jvapp" mayscript="True" scriptable="True" archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   code="jalview.bin.JalviewLite" width="800" height="300" id="jvapp" mayscript="True" scriptable="True" archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="oninit" value="lJvApp"/>
 <param name="automaticScrolling" value="true"/>
 <param name="file" value="plantfdx.fa"/>
@@ -61,7 +61,7 @@
 
 
 <applet
-   code="jalview.bin.JalviewLite" width="800" height="300" id="jvfollower" mayscript="True" scriptable="True" archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   code="jalview.bin.JalviewLite" width="800" height="300" id="jvfollower" mayscript="True" scriptable="True" archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="oninit" value="lJvFollow"/>
 <param name="file" value="plantfdx.fa"/>
 <param name="annotations" value="plantfdx.annotations"/>
index f314c85..80d7133 100644 (file)
@@ -34,18 +34,18 @@ IETHKEEELTA-
 ----------------------------------------------------------ATYKVKFITPEGEQ
 EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDVT
 IETHREEDMV--
->FER1_ARATH/1-148
-----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQ
-EVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDVV
-IETHKEEAIM--
->FER_BRANA/1-96
-----------------------------------------------------------ATYKVKFITPEGEQ
-EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDVT
-IETHKEEELV--
 >FER2_ARATH/1-148
 ----MASTALSSAIVGTSFIRRSPAPISLRSLPSANT-QSLFGLKS-GTARGGRVTAMATYKVKFITPEGEL
 EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDVT
 IETHKEEDIV--
+>FER_BRANA/1-96
+----------------------------------------------------------ATYKVKFITPEGEQ
+EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDVT
+IETHKEEELV--
+>FER1_ARATH/1-148
+----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQ
+EVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDVV
+IETHKEEAIM--
 >Q93Z60_ARATH/1-118
 ----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQ
 EVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD--------------------
index 4bdbfb4..6e6c670 100755 (executable)
@@ -34,18 +34,18 @@ TIETHKEEELTA-
 -----------------------------------------------------------ATYKVKFITPEGE
 QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDV
 TIETHREEDMV--
->FER1_ARATH Ferredoxin-1, chloroplast precursor
-MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
-QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV
-VIETHKEEAIM--
->FER_BRANA Ferredoxin
------------------------------------------------------------ATYKVKFITPEGE
-QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV
-TIETHKEEELV--
 >FER2_ARATH Ferredoxin-2, chloroplast precursor
 MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE
 LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV
 TIETHKEEDIV--
+>FER_BRANA Ferredoxin
+-----------------------------------------------------------ATYKVKFITPEGE
+QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV
+TIETHKEEELV--
+>FER1_ARATH Ferredoxin-1, chloroplast precursor
+MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
+QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV
+VIETHKEEAIM--
 >Q93Z60_ARATH At1g10960/T19D16_12
 MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
 QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD-------------------
index 9974fc7..725d210 100644 (file)
@@ -18,11 +18,11 @@ AAYKVTLVTPEGKQELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDGSFLDD
 AAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDD
 >FER3_RAPSA/1-66 Ferredoxin, leaf L-A
 ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDD
->FER1_ARATH/53-118 Ferredoxin-1, chloroplast precursor
+>FER2_ARATH/53-118 Ferredoxin-1, chloroplast precursor
 ATYKVKFITPEGELEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDD
 >FER_BRANA/1-66 Ferredoxin
 ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDD
->FER2_ARATH/53-118 Ferredoxin-2, chloroplast precursor
+>FER1_ARATH/53-118 Ferredoxin-2, chloroplast precursor
 ATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD
 >Q93Z60_ARATH/53-118 At1g10960/T19D16_12
 ATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD
index 06c5817..f69ed00 100755 (executable)
@@ -22,7 +22,7 @@
    <mapID target="home" url="html/index.html" />
    
    <mapID target="new" url="html/whatsNew.html"/>
-   <mapID target="release" url="html/releases.html#Jalview.2.9"/>
+   <mapID target="release" url="html/releases.html#Jalview.2.10.1"/>
    <mapID target="alannotation" url="html/features/annotation.html"/>
    <mapID target="keys" url="html/keys.html"/>
    <mapID target="newkeys" url="html/features/newkeystrokes.html"/>
index 1248d36..54abd53 100755 (executable)
@@ -23,9 +23,6 @@
 <!-- DO NOT WRAP THESE LINES - help2Website relies on each item being on one line! -->
        <tocitem text="Jalview Documentation" target="home" expand="true">
                        <tocitem text="What's new" target="new" expand="true">
-                               <tocitem text="Retrieval from ENSEMBL" target="ensemblfetch" />
-                               <tocitem text="UniProt Free Text Search" target="uniprotfetcher" />
-                               <tocitem text="SIFTS for mapping PDB structures to UniProt" target="siftsmapping" />
                                <tocitem text="Latest Release Notes" target="release"/>
                </tocitem>
                
index 614764b..8adacc9 100755 (executable)
@@ -35,10 +35,10 @@ td {
     <strong>Colouring above a percentage identity threshold</strong>
   </p>
   <p>Selecting this option causes the colour scheme to be applied to
-    only those residues that occur in that column more than a certain
-    percentage of the time. For instance selecting the threshold to be
-    100 will only colour those columns with 100 % identity. This
-    threshold option can be applied to the Zappo, Taylor, Hydrophobicity
-    and User colour schemes.</p>
+    only those residues that occur in that column at least a certain
+    percentage of the time. For instance, selecting the threshold to be
+    100 will only colour those columns with 100% identity, and selecting 50 will shade residues appearing in least 50% of the rows (or sequences) in each column.</p>
+   <p>The percentage calculation may include or exclude gaps in the column, depending on the option selected for the <a href="../calculations/consensus.html">consensus calculation</a>.</p>
+   <p>With a threshold of 0, colouring is unchanged.</p>
 </body>
 </html>
index 471e520..fd8c5a3 100755 (executable)
@@ -49,9 +49,8 @@
     right to insert gaps and remove gaps.<br> If the current
     selection is a group over all sequences in the alignment, or a group
     over some sequences or all columns in the alignment, then hold down
-    either &quot;Control&quot; key (or the &quot;Alt;&quot; on OSX if
-    &quot;Control&quot; does not work) and drag the residue left or
-    right to edit all sequences in the defined group at once.
+    &quot;Control&quot; key (&quot;Cmd&quot; key on OSX) and drag the residue 
+    left or right to edit all sequences in the defined group at once.
   </p>
   <p>
     <em>Copy/paste/cut/delete</em> - any sequences which are in the
index 1b0b9c1..5ae00af 100644 (file)
     number and chain code ([RES]Num:Chain). Moving the mouse over an
     associated residue in an alignment window highlights the associated
     atoms in the displayed structures. When residues are selected in the
-    Chimera window, they are highlighted on the alignment. For
-    comprehensive details of Chimera's commands, refer to the tool's
-    Help menu.
+    Chimera window, they are highlighted on the alignment.
+  <p>For comprehensive details of Chimera's commands, refer to the
+    tool's Help menu.</p>
+  <p>
+    <strong>Selecting residues in Jalview from Chimera</strong><br />
+    When a selection is highlighted in a Jalview window, use the
+    <em>Select&#8594;Select Highlighted Region</em> or press <em>B</em>
+    to add the mapped positions to the alignment window's column
+    selection.<br /> <em>Hint: Use your machine's 'switch
+      application' key combination (Alt-Tab on Windows and Linux,
+      Cmd-Tab on OSX) to quickly switch between UCSF Chimera and Jalview
+      before pressing 'B' to select highlighted regions.</em>
+  </p>
   <p>
     Basic screen operations (see <a
       href="http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/mouse.html">Chimera
index 4b4aab9..e065494 100644 (file)
       <td><div align="left">Create Scalable Vector Graphics
           file FILE from alignment.</div></td>
     </tr>
+    <tr>
+      <td><div align="center">-biojsMSA FILE</div></td>
+      <td><div align="left">Write an HTML page to display
+          the alignment with the <a href="biojsmsa.html">
+          BioJS MSAviewer MSA</a>
+          </div>
+      </td>
+    </tr>
   </table>
 </body>
 </html>
index ec1e093..fd6b99f 100755 (executable)
     a colour the feature).</p>
 
   <p>
-    If your sequence annotation is already available in GFF Format (see
-    <a href="http://gmod.org/wiki/GFF2">gmod.org/wiki/GFF2</a>), then
-    you can leave it as is, after first adding a line containing only
+    If your sequence annotation is already available in <a href="http://gmod.org/wiki/GFF2">GFF2</a> (http://gmod.org/wiki/GFF2) or
+    <a href="https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md">GFF3</a> 
+    (http://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md) format, 
+    then you can leave it as is, after first adding a line containing only
     'GFF' after any Jalview feature colour definitions (<em>this
-      mixed format capability was added in Jalview 2.6</em>). Alternately,
+    mixed format capability was added in Jalview 2.6</em>). Alternately,
     you can use Jalview's own sequence feature annotation format, which
     additionally allows HTML and URLs to be directly attached to each
     piece of annotation.
index 2f10196..0cd6168 100644 (file)
       based structure superposition was added in Jalview 2.6</em>
   </p>
   <p>
-    <strong>Controls</strong><br> The structure is by default
-    rendered as a ribbon diagram. Moving the mouse over the structure
-    brings up tooltips giving the residue name, PDB residue number and
-    chain code, atom name and number
-    ([RES]Num:Chain.AtomName#AtomNumber). If a mapping exists to a
-    residue in any associated sequences, then this will be highlighted
-    in each one's alignment window. The converse also occurs - moving
-    the mouse over an associated residue in an alignment window
-    highlights the associated atoms in the displayed structures.
+    <strong>Controls</strong><br> The structure is by default rendered
+    as a ribbon diagram. Moving the mouse over the structure brings up
+    tooltips giving the residue name, PDB residue number and chain code,
+    atom name and number ([RES]Num:Chain.AtomName#AtomNumber). If a
+    mapping exists to a residue in any associated sequences, then this
+    will be highlighted in each one's alignment window. The converse
+    also occurs - moving the mouse over an associated residue in an
+    alignment window highlights the associated atoms in the displayed
+    structures. Press B or use
+    <em>Select&#8594;Select Highlighted columns</em> from any linked
+    alignment window to mark the columns highlighted after mousing over
+    the structure.
   </p>
   <p>Selecting a residue highlights its associated sequence residue
     and alpha carbon location. Double clicking an atom allows distances
index 9766782..69f3315 100755 (executable)
@@ -65,6 +65,19 @@ td {
     Settings&quot; under the &quot;View&quot; menu to change the
     visibility and colour of the new sequence feature.</p>
   <p>
+  <p>
+    <strong>Selecting regions from Search Results</strong>
+  </p>
+  <p>
+    Press 'B' or use the <em>Select Highlighted Columns</em> option from
+    the alignment window's select menu to add columns containing
+    highlighted search results to the alignment window's column
+    selection. Alt-'B' will add all but the highlighted columns, and
+    Ctrl (or Cmd) -B will toggle the column selection for the
+    highlighted region.
+  </p>
+  <p>
+  
     <strong>A quick Regular Expression Guide</strong>
   </p>
   <p>A regular expression is not just a simple text query - although
@@ -73,7 +86,7 @@ td {
     the match. For example, a simple query like &quot;ACDED&quot; would
     match all occurences of that string, but &quot;ACD+ED&quot; matches
     both 'ACDDED' and 'ACDDDDDDDDED'. More usefully, the query
-    &quot;[ILGVMA]{;5,}&quot; would find stretches of small, hydrophobic
+    &quot;[GVATC]{;5,}&quot; would find stretches of small, hydrophobic
     amino acids of at least five residues in length.</p>
   <p>
     The table below describes some of the regular expression syntax:<br>
index ba97557..3f6a058 100644 (file)
     Much of the information retrieved by Jalview about a sequence is
     visualized on the alignment. Often, however, there are a huge number
     of ontology terms, cross-references, links to publications and other
-    kinds of data shown in the sequence ID tooltip that cannot be
-    examined. In this case, you can view and export the information
-    shown in a sequence's ID tooltip by right-clicking and selecting the
+    kinds of data associated with a sequence, and only some of these are shown in 
+    sequence ID tooltip. To show the full set of annotation and database links for
+    a sequence, right-click and select the
     <strong>&quot;<em>(sequence's name)</em></em>&rarr;Sequence
       Details ...&quot;
     </strong> entry from the <a href="../menus/popupMenu.html">pop-up menu</a>.
   </p>
   <p>
     <strong>Annotation Reports for a range of sequences</strong><br />
-    If you would like to view the tooltips for a number of sequences,
+    If you would like to view database and metadata for a number of sequences,
     simply select them all and then use the <strong>Selection&rarr;Sequence
       Details ...</strong> entry in the <a href="../menus/popupMenu.html">pop-up
       menu</a>.
index 2ba9a49..1a5fc18 100755 (executable)
@@ -167,6 +167,19 @@ columns are selected, you should use the <a href="features/hiddenRegions.html">H
       <td>Both</td>
       <td>Launches the search window</td>
     </tr>
+    <tr><td><strong>B</strong></td>
+      <td>Both</td>
+      <td>Add highlighted columns to current column selection</td>
+    </tr>
+    <tr><td><strong>Alt 'B'</strong></td>
+      <td>Both</td>
+      <td>Add all but the currently highlighted columns to current selection</td>
+    </tr>
+    <tr><td><strong>Control 'B'</strong></td>
+      <td>Both</td>
+      <td>Toggle the column selection marks for the currently highlighted 
+          columns (or all others if Alt is also pressed)</td>
+    </tr>
     <tr>
       <td><strong>H</strong></td>
       <td>Both</td>
index b30fbab..51ad601 100755 (executable)
               Columns by Annotation</a></strong> <br /> <em>Select or Hide
             columns in the alignment according to secondary structure,
             labels and values shown in alignment annotation rows. </em></li>
+        <li><strong>Select Highlighted Columns</strong> <br /> <em>Selects
+        the columns currently highlighted as a result of a find, mouse
+        over, or selection event from a linked structure viewer or other
+        application. Modifiers will work on some platforms: ALT will add
+        all but the highlighted set to the column selection, and CTRL
+        (or META) will toggle the selection. </em></li>
       </ul></li>
     <li><strong>View</strong>
       <ul>
index b93f85b..07828a3 100644 (file)
           Columns by Annotation</a></strong> <br /> <em>Select or Hide columns
         in the alignment according to secondary structure, labels and
         values shown in alignment annotation rows. </em></li>
+    <li><strong>Select Highlighted Columns</strong> <br /> <em>Selects
+        the columns currently highlighted as a result of a find, mouse
+        over, or selection event from a linked structure viewer or other
+        application. Modifiers will work on some platforms: ALT will add
+        all but the highlighted set to the column selection, and CTRL
+        (or META) will toggle the selection. </em></li>
   </ul>
 </body>
 </html>
index 51274d7..b53f6ef 100755 (executable)
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  -->
 <head>
-<title>Amino Acid Properties</title>
+<style>
+body {
+    font-size: 100%;
+}
+table {
+    border: solid;
+    border-collapse: separate;
+}
+th, td {
+    border-style:none;
+    font-family: "Courier New", Courier, mono;
+    font-size: large;
+}
+</style><title>Amino Acid Properties</title>
 </head>
 <body>
   <div align="center">
     <h1>Amino Acid Properties</h1>
     <img src="properties.gif"> <br>
-    <table width="295" border="1" cellspacing="0" cellpadding="0">
-      <tr>
-        <td width="291"><pre>
-            <font size="4" face="Courier New, Courier, mono"><strong>ILVCAGMFYWHKREQDNSTPBZX-</strong>
-XXXXXXXXXXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;X&middot;&middot;&middot;XX Hydrophobic
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXXXXXXXXX&middot;XXXXX Polar
-&middot;&middot;XXXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXXXX&middot;&middot;XX Small
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;X&middot;&middot;XX Proline
-&middot;&middot;&middot;&middot;XX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;X&middot;&middot;&middot;&middot;XX Tiny
-XXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XX Aliphatic
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XX Aromatic
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XX Positive
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;X&middot;X&middot;&middot;&middot;&middot;&middot;&middot;XX Negative
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXXX&middot;X&middot;&middot;&middot;&middot;&middot;&middot;XX Charged</font>
-          </pre></td>
-      </tr>
+    <table>
+    <tr><th>ILVCA</th><th>GMFYW</th><th>HKREQ</th><th>DNSTP</th><th>BZX-</th><th></th></tr>
+      <tr><td>XXXXX</td><td>XXXXX</td><td>XX&middot;&middot;&middot;</td><td>&middot;&middot;&middot;X&middot;</td><td>&middot;&middot;XX</td><td>Hydrophobic</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;XX</td><td>XXXXX</td><td>XXXX&middot;</td><td>XXXX</td><td>Polar</td></tr>
+<tr><td>&middot;&middot;XXX</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>XXXXX</td><td>&middot;&middot;XX</td><td>Small</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;X</td><td>&middot;&middot;XX</td><td>Proline</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;X</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;X&middot;&middot;</td><td>&middot;&middot;XX</td><td>Tiny</td></tr>
+<tr><td>XXX&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Aliphatic</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XXX</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Aromatic</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>XXX&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Positive</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;X&middot;</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Negative</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>XXXX&middot;</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Charged</td></tr>
     </table>
+    </font>
   </div>
   <p>
     <br> From Livingstone, C. D. and Barton, G. J. (1993), <br>
index 5718926..6f44b3d 100755 (executable)
     <tr>
       <td width="60" nowrap>
         <div align="center">
+          <strong><a name="Jalview.2.10.1">2.10.1</a><br />
+            <em>29/11/2016</em></strong>
+        </div>
+      </td>
+      <td><div align="left">
+          <em>General</em>
+          <ul>
+            <li>
+              <!-- JAL-98 -->Improved memory usage: sparse arrays used
+              for all consensus calculations
+            </li>
+            <li>
+              <!-- JAL-2177 -->Jmol updated to version 14.6.4 (released 3rd Oct 2016)
+            </li>
+            <li>Updated Jalview's Certum code signing certificate
+              for 2016-2017</li>
+          </ul>
+          <em>Application</em>
+          <ul>
+            <li>
+              <!-- JAL-1723 -->Sequence ID tool tip presents abridged
+              set of database cross-references, sorted alphabetically
+            </li>
+            <li>
+              <!-- JAL-2282-->New replacement token for creating URLs <em>just</em>
+              from database cross references. Users with custom links
+              will receive a <a href="webServices/urllinks.html#warning">warning
+                dialog</a> asking them to update their preferences.
+            </li>
+            <li>
+              <!-- JAL-2287-->Cancel button and escape listener on
+              dialog warning user about disconnecting Jalview from a
+              Chimera session
+            </li>
+            <li>
+              <!-- JAL-2320-->Jalview's Chimera control window closes if
+              the Chimera it is connected to is shut down
+            </li>
+            <li>
+              <!-- JAL-1738-->New keystroke (B) and Select highlighted
+              columns menu item to mark columns containing
+              highlighted regions (e.g. from structure selections or results
+              of a Find operation)
+            </li>
+            <li>
+              <!-- JAL-2284-->Command line option for batch-generation
+              of HTML pages rendering alignment data with the BioJS
+              MSAviewer
+            </li>
+          </ul>
+        </div></td>
+      <td>
+        <div align="left">
+          <em>General</em>
+          <ul>
+            <li>
+              <!-- JAL-2286 -->Columns with more than one modal residue
+              are not coloured or thresholded according to percent
+              identity (first observed in Jalview 2.8.2)
+            </li>
+            <li>
+              <!-- JAL-2301 -->Threonine incorrectly reported as not
+              hydrophobic
+            </li>
+            <li>
+              <!-- JAL-2318 -->Updates to documentation pages (above PID
+              threshold, amino acid properties)
+            </li>
+            <li>
+              <!-- JAL-2292 -->Lower case residues in sequences are not
+              reported as mapped to residues in a structure file in the
+              View Mapping report
+            </li>
+            <li>
+              <!--JAL-2324 -->Identical features with non-numeric scores
+              could be added multiple times to a sequence
+            </li>
+            <li>
+              <!--JAL-2323, JAL-2333,JAL-2335,JAL-2327 -->Disulphide
+              bond features shown as two highlighted residues rather
+              than a range in linked structure views, and treated
+              correctly when selecting and computing trees from features
+            </li>
+            <li>
+              <!-- JAL-2281-->Custom URL links for database
+              cross-references are matched to database name regardless
+              of case
+            </li>
+
+          </ul>
+          <em>Application</em>
+          <ul>
+            <li>
+              <!-- JAL-2282-->Custom URL links for specific database
+              names without regular expressions also offer links from
+              Sequence ID
+            </li>
+            <li>
+              <!-- JAL-2315-->Removing a single configured link in the
+              URL links pane in Connections preferences doesn't actually
+              update Jalview configuration
+            </li>
+            <li>
+              <!-- JAL-2272-->CTRL-Click on a selected region to open
+              the alignment area popup menu doesn't work on El-Capitan
+            </li>
+            <li>
+              <!-- JAL-2280 -->Jalview doesn't offer to associate mmCIF
+              files with similarly named sequences if dropped onto the
+              alignment
+            </li>
+            <li>
+              <!-- JAL-2312 -->Additional mappings are shown for PDB
+              entries where more chains exist in the PDB accession than
+              are reported in the SIFTS file
+            </li>
+            <li>
+              <!-- JAL-2317-->Certain structures do not get mapped to
+              the structure view when displayed with Chimera
+            </li>
+            <li>
+              <!-- JAL-2317-->No chains shown in the Chimera view
+              panel's View->Show Chains submenu
+            </li>
+            <li>
+              <!--JAL-2277 -->Export as HTML with embedded SVG doesn't
+              work for wrapped alignment views
+            </li>
+            <li>
+              <!--JAL-2197 -->Rename UI components for running JPred
+              predictions from 'JNet' to 'JPred'
+            </li>
+            <li>
+              <!-- JAL-2337,JAL-2277 -->Export as PNG or SVG is
+              corrupted when annotation panel vertical scroll is not at
+              first annotation row
+            </li>
+            <li>
+              <!--JAL-2332 -->Attempting to view structure for Hen
+              lysozyme results in a PDB Client error dialog box
+            </li>
+          </ul>
+<!--           <em>New Known Issues</em>
+          <ul>
+            <li></li>
+          </ul> -->
+        </div>
+      </td>
+    </tr>
+      <td width="60" nowrap>
+        <div align="center">
           <strong><a name="Jalview.2.10.0b1">2.10.0b1</a><br />
             <em>25/10/2016</em></strong>
         </div>
       </td>
       <td><em>Application</em>
         <ul>
-          <li>3D Structure chooser opens with 'Cached structures' view if structures already loaded</li>
-          <li>Progress bar reports models as they are loaded to structure views</li> 
+          <li>3D Structure chooser opens with 'Cached structures'
+            view if structures already loaded</li>
+          <li>Progress bar reports models as they are loaded to
+            structure views</li>
         </ul></td>
       <td>
         <div align="left">
           <em>General</em>
           <ul>
-            <li>Colour by conservation always enabled and no tick shown in menu when PID shading applied</li>
+            <li>Colour by conservation always enabled and no tick
+              shown in menu when BLOSUM or PID shading applied</li>
+            <li>FER1_ARATH and FER2_ARATH labels were switched in
+              example sequences/projects/trees</li>
           </ul>
           <em>Application</em>
           <ul>
-            <li>Jalview projects with views of local PDB structure files saved on Windows cannot be opened on OSX</li>
-            <li>Multiple structure views can be opened and superposed without timeout for structures with multiple models or multiple sequences in alignment</li>
-            <li>Cannot import or associated local PDB files without a PDB ID HEADER line</li>
-            <li>RMSD is not output in Jmol console when superposition is performed</li> 
-            <li>Drag and drop of URL from Browser fails for Linux and OSX versions earlier than El Capitan</li>
+            <li>Jalview projects with views of local PDB structure
+              files saved on Windows cannot be opened on OSX</li>
+            <li>Multiple structure views can be opened and
+              superposed without timeout for structures with multiple
+              models or multiple sequences in alignment</li>
+            <li>Cannot import or associated local PDB files without
+              a PDB ID HEADER line</li>
+            <li>RMSD is not output in Jmol console when
+              superposition is performed</li>
+            <li>Drag and drop of URL from Browser fails for Linux
+              and OSX versions earlier than El Capitan</li>
             <li>ENA client ignores invalid content from ENA server</li>
-            <li>Exceptions are not raised in console when ENA client attempts to fetch non-existent IDs via Fetch DB Refs UI option</li>
-            <li>Exceptions are not raised in console when a new view is created on the alignment</li>
+            <li>Exceptions are not raised in console when ENA
+              client attempts to fetch non-existent IDs via Fetch DB
+              Refs UI option</li>
+            <li>Exceptions are not raised in console when a new
+              view is created on the alignment</li>
+            <li>OSX right-click fixed for group selections:
+              CMD-click to insert/remove gaps in groups and CTRL-click
+              to open group pop-up menu</li>
           </ul>
-          <em>New Known Issues</em>
-          <ul><li>Drag and drop from URL links in browsers do not work on Windows</li></ul>
           <em>Build and deployment</em>
-          <ul><li>URL link checker now copes with multi-line anchor tags</li></ul>
+          <ul>
+            <li>URL link checker now copes with multi-line anchor
+              tags</li>
+          </ul>
+          <em>New Known Issues</em>
+          <ul>
+            <li>Drag and drop from URL links in browsers do not
+              work on Windows</li>
+          </ul>
         </div>
       </td>
     </tr>
               <!-- JAL-1306 -->Quality and Conservation are now shown on
               load even when Consensus calculation is disabled
             </li>
+            <li>
+              <!-- JAL-1932 -->Remove right on penultimate column of 
+              alignment does nothing
+            </li>
           </ul>
           <em>Application</em>
           <ul>
               <!-- JAL-1887 -->Incorrect start and end reported for PDB
               to sequence mapping in 'View Mappings' report
             </li>
+            <li>
+              <!-- JAL-2284 -->Unable to read old Jalview projects that
+              contain non-XML data added after Jalvew wrote project.
+            </li>
+            <li><!-- JAL-2118 -->Newly created annotation row reorders
+              after clicking on it to create new annotation for a
+              column.
+            </li>
             <!--  may exclude, this is an external service stability issue  JAL-1941 
             -- > RNA 3D structure not added via DSSR service</li> -->
           </ul>
         </ul> <em>Applet</em>
         <ul>
           <li>Split frame example added to applet examples page</li>
+        </ul><em>Build and Deployment</em>
+        <ul>
+          <li><!--  JAL-1888 -->New ant target for running Jalview's test suite</li>
         </ul></td>
       <td>
         <div align="left">
index 52220d2..83c80ba 100644 (file)
 <p>
 <p>
   <strong>Discovering Database References for Sequences</strong><br>
-  Database references are associated with a sequence are displayed as a
-  list in the tooltip shown when mousing over its sequence ID. Jalview
-  uses references for the retrieval of <a
-    href="../features/viewingpdbs.html">PDB structures</a> and <a
+  Database references associated with a sequence are displayed as an
+  abbreviated list in the tooltip shown when mousing over its sequence
+  ID, and can be viewed in full via the
+  <a href="../io/exportseqreport.html">Sequence Details</a> window. .
+  Jalview also uses references for the retrieval of
+  <a href="../features/viewingpdbs.html">PDB structures</a> and <a
     href="../features/dasfeatures.html">DAS features</a>, and for
   retrieving sequence cross-references such as the protein products of a
   DNA sequence.
index 0a4c650..088a539 100644 (file)
@@ -28,7 +28,7 @@
     and the desktop application are able to open URLs as 'popups' in
     your web browser. <br> Double-clicking on the ID of a sequence
     will open the first URL that can be generated from its sequence ID.
-    This is often the SRS site, but you can easily configure your own <a
+    This is by default the EMBL-EBI site, but you can easily configure your own <a
       href="#urllinks">sequence URL links</a>.
   </p>
   <p>
   <p>
     <strong><a name="urllinks">Configuring URL Links</a></strong> <br>URL
     links are defined in the &quot;Connections&quot; tab of the <a
-      href="../features/preferences.html">Jalview desktop
-      preferences</a>, or specified as <a
-      href="http://www.jalview.org/examples/appletParameters.html#parameters">applet
-      parameters</a>. <br> By default the item &quot;SRS&quot; is added
+    href="../features/preferences.html">Jalview desktop
+    preferences</a>, or specified as <a
+    href="http://www.jalview.org/examples/appletParameters.html#parameters">applet
+    parameters</a>. <br> By default the item &quot;EMBL-EBI Search&quot; is added
     to this link menu. This link will show a web page in your default
     browser with the selected sequence id as part of the URL.<br>
     In the preferences dialog box, click <strong>new</strong> to add a
@@ -51,9 +51,9 @@
     to remove it.<br> You can name the link, this will be displayed
     on a new menu item under the &quot;Link&quot; menu when you right
     click on a sequence id. <br> The URL string must contain a
-    token that can be replaced with a sequence ID. The simplest token is
+    token that can be replaced with a sequence ID or DB accession ID. The simplest token is
     &quot;$SEQUENCE_ID$&quot;, which will be replaced by the chosen
-    sequence id when you click on it.
+    sequence id when you click on it. 
   </p>
   <p>
     eg.<br> UniRef100 =
     Swissprot = http://www.expasy.org/uniprot/$SEQUENCE_ID$ <br> <br>
     Links will also be made for any database cross references associated
     with the sequence where the database name exactly matches a URL link
-    name. In this case, the $SEQUENCE_ID$ string will be replaced with
+    name. In this case, the $DB_ACCESSION$ string will be replaced with
     the accession string for the database cross-reference, rather than
-    the sequence ID for the sequence (<em>since Jalview 2.4</em>).
+    the sequence ID for the sequence (<em>since Jalview 2.10.1</em>).
+  </p>
+  <p>
+    <strong><a name="warning">Warning dialog about updating
+        your configured URL links</a></strong><br /> In the desktop
+    prior to Jalview 2.10.1, the only way to configure custom links for
+    a particular database cross-reference for a sequence was to give it
+    a name that
+    <em>exactly</em> matched the database source, and a regular
+    expression for filtering out any spurious matches generated when the
+    custom linked was tested against the Sequence's ID string. Since the
+    introduction of the $DB_ACCESSION$ token, however, $SEQUENCE_ID$
+    will not be used for database cross-reference accession strings, and
+    if you have custom links configured, Jalview will raise a warning
+    message so let you know that you may need to update your links to
+    use $DB_ACCESSION$.
   </p>
   <p>
     <strong>Regular Expression Substitution</strong><br> A url may
     contain a string of the form $SEQUENCE_ID=/<em>regular
-      expression</em>/=$. In this case, the regular expression will be
-    applied to the full sequence ID string and the resulting match will
+    expression</em>/=$ or $DB_ACCESSION=/<em>regular expression</em>/=$. 
+    In this case, the regular expression will be
+    applied to the full sequence ID or DB accession ID string and the resulting match will
     be inserted into the URL. Groups of parentheses can be used to
     specify which regions of the regular expression will be used to
     generate the URL:
index cab871c..d1d141d 100755 (executable)
 </head>
 <body>
   <p>
-    <strong>What's new in Jalview 2.10 ?</strong>
+    <strong>What's new in Jalview 2.10.1 ?</strong>
   </p>
   <p>
-    Jalview 2.10 is the next major release in the Jalview 2 series. Full
-    details are in the <a href="releases.html#Jalview.2.10.0">Jalview
-      2.10 Release Notes</a>, but the highlights are below.
+    Jalview 2.10.1 was released on 29th November 2016. Full details are
+    in the <a href="releases.html#Jalview.2.10.1">Jalview 2.10.1
+      Release Notes</a>, but the highlights are below. This is also the
+    first release to include contributions from Kira Mour&atilde;o, who
+    joined Jalview's core development team in October 2016.
   </p>
   <ul>
-    <li><strong>Ensembl sequence fetcher</strong><br />Annotated
-      Genes, transcripts and proteins can be retrieved via Jalview's new
-      <a href="features/ensemblsequencefetcher.html">Ensembl REST
-        client</a>. Support for import of Ensembl data allows:
-      <ul>
-        <li><strong>Aligned locus view</strong><br />Transcripts
-          retrieved for a gene identifier via the Ensembl or
-          EnsemblGenomes sequence databases are automatically aligned to
-          their reference genome, and introns hidden from the view.</li>
-        <li><strong>Sequence variant data</strong><br />Jalview
-          propagates variant annotation on genomic regions onto
-          transcripts and protein products, complete with associated
-          metadata such as clinical significance.</li>
-      </ul></li>
-    <li><strong>Ensembl and ENA 'show cross-references'
-        support</strong><br />The Calculations menu's <strong>'Show
-        cross-references'</strong> now offers Ensembl as well as EMBLCDS and
-      Uniprot when CDS/Protein mapping data is available for download or
-      display. This allows variant annotation to be added directly to an
-      alignment of UniProt sequences.</li>
-    <li><strong>Working with structures</strong>
-      <ul>
-        <li><strong>More accurate structure mappings</strong><br />
-          Jalview now utilises the PDBe's SIFTS database (at EMBL-EBI)
-          to <a href="features/siftsmapping.html">match structures
-            to UniProt sequences</a>, even for structures containing
-          multiple copies of a sequence.</li>
-        <li><strong>Import structures as mmCIF</strong><br />Jalview
-          now downloads data from the EMBL-EBI's PDBe site as <a
-          href="features/mmcif.html">mmCIF</a>. This allows very large
-          structures to be imported, such as the HIV virus capsid
-          assembly.</li>
-        <li><strong>Chimera users will need to upgrade to
-            1.11.1</strong><br />If you use Chimera to view structures
-          downloaded by Jalview 2.10, you will need to make sure you are
-          running the latest version of <a href="features/chimera.html">Chimera</a>.</li>
-      </ul></li>
-    <li><strong>UniProt Free Text Search</strong><br />The new
-      search dialog for UniProt allows you to browse and retrieve
-      sequences with free-text search, or structured queries.</li>
-    <li><strong>Reference sequence alignment view</strong><br />
-      Jalview 2.9 introduced support for reference sequences. In 2.10,
-      when a reference sequence is defined for the alignment, the
-      alignment column ruler is now numbered according to the reference
-      sequence. The reference sequence for alignment views can also be
-      saved and restored from Jalview projects.</li>
+    <li><strong>More memory efficient</strong><br />We've slimmed
+      down the consensus analysis data structures used by Jalview so
+      even wider alignments can be worked with.</li>
+    <li><strong>Select highlighted region</strong><br />Press 'B'
+      or use the new menu option in the alignment window's Select menu
+      to mark columns containing highlighted regions generated from
+      structure selections, mouse-overs, or resulting from a Find
+      operation.</li>
+    <li><strong>New custom link mechanism for opening URLs
+        for database cross references.</strong><br /> If you have customised URL
+      links in your Jalview preferences, then you may already have seen
+      the <a href="#warning"> warning dialog (see below).</a></li>
+    <li><strong>New command line export option for BioJS
+        MSAviewer</strong><br />A number of small bugs with the HTML export
+      functions from the Jalview desktop were also fixed.</li>
+    <li><strong>Small but significant changes to the
+        physicochemical properties and consensus calculations</strong><br />Threonine
+      is no longer considered a non-hydrophobic residue in the protein
+      conservation calculation, and minor bugs addressed in PID and
+      consensus colouring.</li>
+    <li><strong>Correct display of disulphide bond
+        features</strong><br /> In linked structure views, Jalview would
+      highlight all residues between in addition to the two linked
+      cysteines. The 'select columns by feature' function in the feature
+      settings would also select all intermediate columns.
   </ul>
 
+  <p>
+    <strong><a name="warning">Warning dialog about updating
+        your configured URL links</a></strong><br /> In the desktop prior to Jalview
+    2.10.1, the only way to configure custom links for a particular
+    database cross-reference for a sequence was to give it a name that <em>exactly</em>
+    matched the database source, and a regular expression for filtering
+    out any spurious matches generated when the custom linked was tested
+    against the Sequence's ID string. Since the introduction of the
+    $DB_ACCESSION$ token, however, $SEQUENCE_ID$ will not be used for
+    database cross-reference accession strings, and if you have custom
+    links configured, Jalview will raise a warning message so let you
+    know that you may need to update your links to use $DB_ACCESSION$.
+  </p>
 </body>
 </html>
diff --git a/lib/Jmol-14.2.14_2015.06.11.jar b/lib/Jmol-14.2.14_2015.06.11.jar
deleted file mode 100644 (file)
index 1470745..0000000
Binary files a/lib/Jmol-14.2.14_2015.06.11.jar and /dev/null differ
diff --git a/lib/Jmol-14.6.4_2016.10.26.jar b/lib/Jmol-14.6.4_2016.10.26.jar
new file mode 100644 (file)
index 0000000..1016c3f
Binary files /dev/null and b/lib/Jmol-14.6.4_2016.10.26.jar differ
index ac1a2e3..b569f55 100644 (file)
@@ -59,8 +59,8 @@ file.reference.jalview-src=src
 file.reference.jaxrpc.jar=lib/jaxrpc.jar
 file.reference.JGoogleAnalytics_0.3.jar=lib/JGoogleAnalytics_0.3.jar
 file.reference.jhall.jar=lib/jhall.jar
-file.reference.Jmol-14.2.14_2015.06.11.jar=lib/Jmol-14.2.14_2015.06.11.jar
-file.reference.JmolApplet-14.2.14_2015.06.11.jar=appletlib/JmolApplet-14.2.14_2015.06.11.jar
+file.reference.Jmol-14.6.4_2016.10.26.jar=lib/Jmol-14.6.4_2016.10.26.jar
+file.reference.JmolApplet-14.6.4_2016.10.26.jar=appletlib/JmolApplet-14.6.4_2016.10.26.jar
 file.reference.log4j-1.2.8.jar=lib/log4j-1.2.8.jar
 file.reference.mail.jar=lib/mail.jar
 file.reference.min-jaba-client.jar=lib/min-jaba-client-2.0.jar
@@ -92,7 +92,7 @@ javac.classpath=\
     ${file.reference.jaxrpc.jar}:\
     ${file.reference.JGoogleAnalytics_0.3.jar}:\
     ${file.reference.jhall.jar}:\
-    ${file.reference.Jmol-14.2.14_2015.06.11.jar}:\
+    ${file.reference.Jmol-14.6.4_2016.10.26.jar}:\
     ${file.reference.miglayout-4.0-swing.jar}:\
     ${file.reference.log4j-1.2.8.jar}:\
     ${file.reference.mail.jar}:\
@@ -101,7 +101,7 @@ javac.classpath=\
     ${file.reference.xml-apis.jar}:\
     ${file.reference.xercesImpl.jar}:\
     ${file.reference.wsdl4j.jar}:\
-    ${file.reference.JmolApplet-14.2.14_2015.06.11.jar} \
+    ${file.reference.JmolApplet-14.6.4_2016.10.26.jar} \
     ${file.reference.varna-3.9-dev.jar}
 # Space-separated list of extra javac options
 javac.compilerargs=
index bcb07cf..3488ac6 100644 (file)
@@ -1,4 +1,4 @@
 YEAR=2016
-AUTHORS=J Procter, M Carstairs, TC Ofoegbu, AM Waterhouse, J Engelhardt, LM Lui, A Menard, D Barton, N Sherstnev, D Roldan-Martinez, M Clamp, S Searle, G Barton
-AUTHORFNAMES=Jim Procter, Mungo Carstairs, Tochukwu 'Charles' Ofoegbu, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Anne Menard, Daniel Barton, Natasha Sherstnev, David Roldan-Martinez, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+AUTHORS=J Procter, M Carstairs, TC Ofoegbu, K Mourao, AM Waterhouse, J Engelhardt, LM Lui, A Menard, D Barton, N Sherstnev, D Roldan-Martinez, M Clamp, S Searle, G Barton
+AUTHORFNAMES=Jim Procter, Mungo Carstairs, Tochukwu 'Charles' Ofoegbu, Kira Mourao, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Anne Menard, Daniel Barton, Natasha Sherstnev, David Roldan-Martinez, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
  
\ No newline at end of file
index fc35351..d418c76 100644 (file)
@@ -125,6 +125,8 @@ action.change_font_tree_panel = Change Font (Tree Panel)
 action.colour = Colour
 action.calculate = Calculate
 action.select_all = Select all
+action.select_highlighted_columns = Select Highlighted Columns
+tooltip.select_highlighted_columns = Press B to mark highlighted columns, Ctrl-(or Cmd)-B to toggle, and Alt-B to mark all but highlighted columns 
 action.deselect_all = Deselect all
 action.invert_selection = Invert selection
 action.using_jmol = Using Jmol
@@ -382,8 +384,8 @@ label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation =
 label.translation_failed = Translation Failed
 label.error_when_translating_sequences_submit_bug_report = Unfortunately, something went wrong when translating your sequences.\nPlease take a look in the Jalview java console\nand submit a bug report including the stacktrace.
 label.implementation_error  = Implementation error:
-label.automatically_associate_pdb_files_with_sequences_same_name = Do you want to automatically associate the {0} PDB files with sequences in the alignment that have the same name?
-label.automatically_associate_pdb_files_by_name = Automatically Associate PDB files by name
+label.automatically_associate_structure_files_with_sequences_same_name = Do you want to automatically associate the {0} structure file(s) with sequences in the alignment that have the same name?
+label.automatically_associate_structure_files_by_name = Automatically Associate Structure files by name
 label.ignore_unmatched_dropped_files_info = <html>Do you want to <em>ignore</em> the {0} files whose names did not match any sequence IDs ?</html>
 label.ignore_unmatched_dropped_files = Ignore unmatched dropped files?
 label.view_name_original = Original
@@ -787,8 +789,10 @@ label.hide_columns_containing = Hide columns containing
 label.hide_columns_not_containing = Hide columns that do not contain
 option.trim_retrieved_seqs = Trim retrieved sequences
 label.trim_retrieved_sequences = When the reference sequence is longer than the sequence that you are working with, only keep the relevant subsequences.
-label.use_sequence_id_1 = Use $SEQUENCE_ID$ or $SEQUENCE_ID=/<regex>/=$
-label.use_sequence_id_2 = \nto embed sequence id in URL
+label.use_sequence_id_1 = Use $DB_ACCESSION$ or $DB_ACCESSION=/<regex>/=$
+label.use_sequence_id_2 = to embed accession id in URL
+label.use_sequence_id_3 = Use $SEQUENCE_ID$ similarly to embed sequence id
+label.use_sequence_id_4 = 
 label.ws_parameters_for = Parameters for {0}
 label.switch_server = Switch server
 label.choose_jabaws_server = Choose a server for running this service
@@ -1142,7 +1146,7 @@ warn.user_defined_width_requirements = The user defined width for the\nannotatio
 label.couldnt_create_sequence_fetcher = Couldn't create SequenceFetcher
 warn.couldnt_create_sequence_fetcher_client = Could not create the sequence fetcher client. Check error logs for details.
 warn.server_didnt_pass_validation = Service did not pass validation.\nCheck the Jalview Console for more details.
-warn.url_must_contain = Sequence URL must contain $SEQUENCE_ID$ or a regex $SEQUENCE_ID=/<regex>/=$
+warn.url_must_contain = Sequence URL must contain $SEQUENCE_ID$, $DB_ACCESSION$, or a regex
 warn.urls_not_contacted = URLs that could not be contacted
 warn.urls_no_jaba = URLs without any JABA Services
 info.validate_jabaws_server = Validate JabaWS Server ?\n(Look in console output for results)
@@ -1266,3 +1270,8 @@ status.exporting_alignment_as_x_file = Exporting alignment as {0} file
 label.column = Column
 label.cant_map_cds = Unable to map CDS to protein\nCDS missing or incomplete
 label.operation_failed = Operation failed
+label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ is no longer used for DB accessions
+label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window:
+label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'.
+label.do_not_display_again = Do not display this message again
+label.output_seq_details = Output Sequence Details to list all database references
index bf8e2fb..8cdcd52 100644 (file)
@@ -122,6 +122,8 @@ action.change_font_tree_panel = Cambiar fuente (panel del 
 action.colour = Color
 action.calculate = Calcular
 action.select_all = Seleccionar Todo
+action.select_highlighted_columns = Seleccionar columnas resaltadas
+tooltip.select_highlighted_columns = Presione B para marcar las columnas resaltadas, Ctrl (o Cmd)-B para cambiarlas, y Alt-B para marcar todas menos las columnas resaltadas
 action.deselect_all = Deseleccionar Todo
 action.invert_selection = Invertir selección
 action.using_jmol = Usar Jmol
@@ -351,8 +353,8 @@ label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation =
 label.translation_failed = Translation Failed
 label.error_when_translating_sequences_submit_bug_report = Desafortunadamente, algo fue mal a la hora de traducir tus secuencias.\nPor favor, revisa la consola Jalview java \ny presenta un informe de error que incluya el seguimiento.
 label.implementation_error  = Error de implementación:
-label.automatically_associate_pdb_files_with_sequences_same_name = Quieres asociar automáticamente los {0} ficheros PDB con las secuencias del alineamiento que tengan el mismo nombre?
-label.automatically_associate_pdb_files_by_name = Asociar los ficheros PDB por nombre automáticamente
+label.automatically_associate_structure_files_with_sequences_same_name = Quieres asociar automáticamente los {0} ficheros estructura con las secuencias del alineamiento que tengan el mismo nombre?
+label.automatically_associate_structure_files_by_name = Asociar los ficheros estructura por nombre automáticamente
 label.ignore_unmatched_dropped_files_info = Quieres <em>ignorar</em> los {0} ficheros cuyos nombres no coincidan con ningún IDs de las secuencias ?
 label.ignore_unmatched_dropped_files = Ignorar los ficheros sin coincidencias?
 label.enter_view_name = Introduzca un nombre para la vista
@@ -720,8 +722,10 @@ label.select_columns_containing = Seleccione las columnas que contengan
 label.select_columns_not_containing = Seleccione las columnas que no contengan
 option.trim_retrieved_seqs = Ajustar las secuencias recuperadas
 label.trim_retrieved_sequences = Cuando la secuencia de referencia es más larga que la secuencia con la que está trabajando, sólo se mantienen las subsecuencias relevantes.
-label.use_sequence_id_1 = Utilice $SEQUENCE_ID$ o $SEQUENCE_ID=/<regex>/=$
-label.use_sequence_id_2 = \nto para embeber el id de la secuencia en una URL
+label.use_sequence_id_1 = Utilice $DB_ACCESSION$ o $DB_ACCESSION=/<regex>/=$
+label.use_sequence_id_2 = para embeber el ID de accesión en una URL
+label.use_sequence_id_3 = Utilice $SEQUENCE_ID$ de manera similar para embeber
+label.use_sequence_id_4 = el ID de la secuencia
 label.ws_parameters_for = Parámetros para {0}
 label.switch_server = Cambiar servidor
 label.open_jabaws_web_page = Abra el página principal del servidor JABAWS en un navegador web
@@ -1068,7 +1072,7 @@ warn.user_defined_width_requirements = La anchura definida por el usuario para l
 label.couldnt_create_sequence_fetcher = No es posible crear SequenceFetcher
 warn.couldnt_create_sequence_fetcher_client = No es posible crear el cliente de recuperador de secuencias. Comprueba el fichero de log para más detalles.
 warn.server_didnt_pass_validation = El servicio no ha pasado la validaci\u00F3n.\nCompruebe la consola de Jalview para m\u00E1s detalles.
-warn.url_must_contain = La URL de la secuencia debe contener $SEQUENCE_ID$ o un regex $SEQUENCE_ID=/<regex>/=$
+warn.url_must_contain = La URL de la secuencia debe contener $SEQUENCE_ID$, $DB_ACCESSION$ o un regex
 info.validate_jabaws_server = \u00BFValidar el servidor JabaWS?\n(Consulte la consola de salida para obtener los resultados)
 label.test_server = ¿Probar servidor?
 info.you_want_jalview_to_find_uniprot_accessions = \u00BFDesea que Jalview encuentre\nUniprot Accession ids para los nombres de secuencias dados?
@@ -1267,3 +1271,8 @@ status.exporting_alignment_as_x_file = Exportando alineamiento como fichero tipo
 label.column = Columna
 label.cant_map_cds = No se pudo mapear CDS a proteína\nDatos CDS faltantes o incompletos
 label.operation_failed = Operación fallada
+label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ no se utiliza más para accesiones DB
+label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias:
+label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'.
+label.do_not_display_again = No mostrar este mensaje de nuevo
+label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas
index ad5837e..aac796c 100644 (file)
@@ -26,6 +26,7 @@ import jalview.appletgui.FeatureRenderer;
 import jalview.appletgui.SequenceRenderer;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
 import jalview.io.StructureFile;
 import jalview.structure.AtomSpec;
 import jalview.structure.StructureListener;
@@ -145,7 +146,7 @@ public class AppletPDBCanvas extends Panel implements MouseListener,
   StructureSelectionManager ssm;
 
   public AppletPDBCanvas(PDBEntry pdbentry, SequenceI[] seq,
-          String[] chains, AlignmentPanel ap, String protocol)
+          String[] chains, AlignmentPanel ap, DataSourceType protocol)
 
   {
     this.ap = ap;
@@ -159,7 +160,7 @@ public class AppletPDBCanvas extends Panel implements MouseListener,
     {
       pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
 
-      if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
+      if (protocol == DataSourceType.PASTE)
       {
         pdbentry.setFile("INLINE" + pdb.getId());
       }
index 8233ac3..76ee4b0 100644 (file)
@@ -24,6 +24,7 @@ import jalview.appletgui.AlignmentPanel;
 import jalview.appletgui.EmbmenuFrame;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
 import jalview.schemes.BuriedColourScheme;
 import jalview.schemes.HelixColourScheme;
 import jalview.schemes.HydrophobicColourScheme;
@@ -51,7 +52,7 @@ public class AppletPDBViewer extends EmbmenuFrame implements
   AppletPDBCanvas pdbcanvas;
 
   public AppletPDBViewer(PDBEntry pdbentry, SequenceI[] seq,
-          String[] chains, AlignmentPanel ap, String protocol)
+          String[] chains, AlignmentPanel ap, DataSourceType protocol)
   {
     try
     {
@@ -73,6 +74,7 @@ public class AppletPDBViewer extends EmbmenuFrame implements
 
   }
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     if (evt.getSource() == mapping)
@@ -143,6 +145,7 @@ public class AppletPDBViewer extends EmbmenuFrame implements
 
   }
 
+  @Override
   public void itemStateChanged(ItemEvent evt)
   {
     if (evt.getSource() == allchains)
index 0dd58ad..292de91 100644 (file)
@@ -26,6 +26,7 @@ import jalview.datamodel.SequenceI;
 import jalview.gui.AlignmentPanel;
 import jalview.gui.FeatureRenderer;
 import jalview.gui.SequenceRenderer;
+import jalview.io.DataSourceType;
 import jalview.io.StructureFile;
 import jalview.structure.AtomSpec;
 import jalview.structure.StructureListener;
@@ -141,7 +142,7 @@ public class PDBCanvas extends JPanel implements MouseListener,
   String errorMessage;
 
   void init(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
-          AlignmentPanel ap, String protocol)
+          AlignmentPanel ap, DataSourceType protocol)
   {
     this.ap = ap;
     this.pdbentry = pdbentry;
@@ -153,7 +154,7 @@ public class PDBCanvas extends JPanel implements MouseListener,
     {
       pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
 
-      if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
+      if (protocol.equals(jalview.io.DataSourceType.PASTE))
       {
         pdbentry.setFile("INLINE" + pdb.getId());
       }
index 7774dac..783a4e2 100755 (executable)
@@ -31,6 +31,7 @@ import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureImportSettings;
 import jalview.structure.StructureMapping;
+import jalview.util.Comparison;
 
 import java.awt.Color;
 import java.util.List;
@@ -146,7 +147,9 @@ public class PDBChain
         pdbpos++;
       }
 
-      if (as.astr1.charAt(i) == as.astr2.charAt(i))
+      boolean sameResidue = Comparison.isSameResidue(as.astr1.charAt(i),
+              as.astr2.charAt(i), false);
+      if (sameResidue)
       {
         if (pdbpos >= residues.size())
         {
index eaa33df..f108fc2 100755 (executable)
@@ -24,8 +24,10 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignmentPanel;
 import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
 import jalview.gui.OOMWarning;
 import jalview.gui.UserDefinedColours;
+import jalview.io.DataSourceType;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
 import jalview.schemes.BuriedColourScheme;
@@ -60,7 +62,6 @@ import javax.swing.JInternalFrame;
 import javax.swing.JMenu;
 import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 import javax.swing.JRadioButtonMenuItem;
 
 public class PDBViewer extends JInternalFrame implements Runnable
@@ -79,12 +80,12 @@ public class PDBViewer extends JInternalFrame implements Runnable
 
   AlignmentPanel ap;
 
-  String protocol;
+  DataSourceType protocol;
 
   String tmpPDBFile;
 
   public PDBViewer(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
-          AlignmentPanel ap, String protocol)
+          AlignmentPanel ap, DataSourceType protocol)
   {
     this.pdbentry = pdbentry;
     this.seq = seq;
@@ -113,7 +114,7 @@ public class PDBViewer extends JInternalFrame implements Runnable
       {
         tmpPDBFile = pdbentry.getFile();
         PDBfile pdbfile = new PDBfile(false, false, false, tmpPDBFile,
-                jalview.io.AppletFormatAdapter.FILE);
+                DataSourceType.FILE);
 
         pdbcanvas.init(pdbentry, seq, chains, ap, protocol);
 
@@ -150,7 +151,7 @@ public class PDBViewer extends JInternalFrame implements Runnable
     {
       EBIFetchClient ebi = new EBIFetchClient();
       String query = "pdb:" + pdbentry.getId();
-      pdbentry.setFile(ebi.fetchDataAsFile(query, "default", ".xml")
+      pdbentry.setFile(ebi.fetchDataAsFile(query, "default", "xml")
               .getAbsolutePath());
 
       if (pdbentry.getFile() != null)
@@ -436,13 +437,13 @@ public class PDBViewer extends JInternalFrame implements Runnable
           {
             radioItem.removeActionListener(radioItem.getActionListeners()[0]);
 
-            int option = JOptionPane.showInternalConfirmDialog(
+            int option = JvOptionPane.showInternalConfirmDialog(
                     jalview.gui.Desktop.desktop, MessageManager
                             .getString("label.remove_from_default_list"),
                     MessageManager
                             .getString("label.remove_user_defined_colour"),
-                    JOptionPane.YES_NO_OPTION);
-            if (option == JOptionPane.YES_OPTION)
+                    JvOptionPane.YES_NO_OPTION);
+            if (option == JvOptionPane.YES_OPTION)
             {
               jalview.gui.UserDefinedColours
                       .removeColourFromDefaults(radioItem.getText());
index f5a0255..6d3d342 100755 (executable)
@@ -23,6 +23,7 @@ package MCview;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
 import jalview.io.FileParse;
 import jalview.io.StructureFile;
 import jalview.util.MessageManager;
@@ -46,10 +47,11 @@ public class PDBfile extends StructureFile
   }
 
   public PDBfile(boolean addAlignmentAnnotations, boolean predictSecStr,
-          boolean externalSecStr, String dataObject, String protocol)
+          boolean externalSecStr, String dataObject,
+          DataSourceType sourceType)
           throws IOException
   {
-    super(false, dataObject, protocol);
+    super(false, dataObject, sourceType);
     addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
     doParse();
   }
@@ -63,7 +65,7 @@ public class PDBfile extends StructureFile
   }
 
   @Override
-  public String print()
+  public String print(SequenceI[] seqs, boolean jvSuffix)
   {
     return null;
   }
index 95221d2..1d57a31 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 import java.awt.Color;
index fdcf34f..439d479 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 import jalview.ws.HttpClientUtils;
@@ -348,6 +380,8 @@ public class ChimeraManager
       sendChimeraCommand("stop really", false);
       try
       {
+        // TODO is this too violent? could it force close the process
+        // before it has done an orderly shutdown?
         chimera.destroy();
       } catch (Exception ex)
       {
@@ -854,4 +888,9 @@ public class ChimeraManager
   {
     return busy;
   }
+
+  public Process getChimeraProcess()
+  {
+    return chimera;
+  }
 }
index 7da7a48..d2f4b11 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 import java.awt.Color;
index 6fd6340..effe556 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 import jalview.bin.Cache;
index 08a6cb7..77c1883 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 /**
index 2b2ce48..379097c 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2.port;
 
 import java.io.BufferedReader;
index fb49541..17874e6 100755 (executable)
@@ -24,7 +24,15 @@ import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.Profile;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.Profiles;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.ResidueCount;
+import jalview.datamodel.ResidueCount.SymbolCounts;
 import jalview.datamodel.SequenceI;
+import jalview.ext.android.SparseIntArray;
+import jalview.util.Comparison;
 import jalview.util.Format;
 import jalview.util.MappingUtils;
 import jalview.util.QuickSort;
@@ -44,20 +52,8 @@ import java.util.List;
  */
 public class AAFrequency
 {
-  private static final int TO_UPPER_CASE = 'A' - 'a'; // -32
-
-  public static final String MAXCOUNT = "C";
-
-  public static final String MAXRESIDUE = "R";
-
-  public static final String PID_GAPS = "G";
-
-  public static final String PID_NOGAPS = "N";
-
   public static final String PROFILE = "P";
 
-  public static final String ENCODED_CHARS = "E";
-
   /*
    * Quick look-up of String value of char 'A' to 'Z'
    */
@@ -71,13 +67,13 @@ public class AAFrequency
     }
   }
 
-  public static final Hashtable[] calculate(List<SequenceI> list,
+  public static final ProfilesI calculate(List<SequenceI> list,
           int start, int end)
   {
     return calculate(list, start, end, false);
   }
 
-  public static final Hashtable[] calculate(List<SequenceI> sequences,
+  public static final ProfilesI calculate(List<SequenceI> sequences,
           int start, int end, boolean profile)
   {
     SequenceI[] seqs = new SequenceI[sequences.size()];
@@ -87,307 +83,262 @@ public class AAFrequency
       for (int i = 0; i < sequences.size(); i++)
       {
         seqs[i] = sequences.get(i);
-        if (seqs[i].getLength() > width)
+        int length = seqs[i].getLength();
+        if (length > width)
         {
-          width = seqs[i].getLength();
+          width = length;
         }
       }
 
-      Hashtable[] reply = new Hashtable[width];
-
       if (end >= width)
       {
         end = width;
       }
 
-      calculate(seqs, start, end, reply, profile);
+      ProfilesI reply = calculate(seqs, width, start, end, profile);
       return reply;
     }
   }
 
-  public static final void calculate(SequenceI[] sequences, int start,
-          int end, Hashtable[] result, boolean profile)
+  /**
+   * Calculate the consensus symbol(s) for each column in the given range.
+   * 
+   * @param sequences
+   * @param width
+   *          the full width of the alignment
+   * @param start
+   *          start column (inclusive, base zero)
+   * @param end
+   *          end column (exclusive)
+   * @param saveFullProfile
+   *          if true, store all symbol counts
+   */
+  public static final ProfilesI calculate(final SequenceI[] sequences,
+          int width, int start, int end, boolean saveFullProfile)
   {
-    Hashtable residueHash;
-    int maxCount, nongap, i, j, v;
-    int jSize = sequences.length;
-    String maxResidue;
-    char c = '-';
-    float percentage;
+    // long now = System.currentTimeMillis();
+    int seqCount = sequences.length;
+    boolean nucleotide = false;
+    int nucleotideCount = 0;
+    int peptideCount = 0;
 
-    int[] values = new int[255];
+    ProfileI[] result = new ProfileI[width];
 
-    char[] seq;
-
-    for (i = start; i < end; i++)
+    for (int column = start; column < end; column++)
     {
-      residueHash = new Hashtable();
-      maxCount = 0;
-      maxResidue = "";
-      nongap = 0;
-      values = new int[255];
+      /*
+       * Apply a heuristic to detect nucleotide data (which can
+       * be counted in more compact arrays); here we test for
+       * more than 90% nucleotide; recheck every 10 columns in case
+       * of misleading data e.g. highly conserved Alanine in peptide!
+       * Mistakenly guessing nucleotide has a small performance cost,
+       * as it will result in counting in sparse arrays.
+       * Mistakenly guessing peptide has a small space cost, 
+       * as it will use a larger than necessary array to hold counts. 
+       */
+      if (nucleotideCount > 100 && column % 10 == 0)
+      {
+        nucleotide = (9 * peptideCount < nucleotideCount);
+      }
+      ResidueCount residueCounts = new ResidueCount(nucleotide);
 
-      for (j = 0; j < jSize; j++)
+      for (int row = 0; row < seqCount; row++)
       {
-        if (sequences[j] == null)
+        if (sequences[row] == null)
         {
           System.err
                   .println("WARNING: Consensus skipping null sequence - possible race condition.");
           continue;
         }
-        seq = sequences[j].getSequence();
-        if (seq.length > i)
+        char[] seq = sequences[row].getSequence();
+        if (seq.length > column)
         {
-          c = seq[i];
-
-          if (c == '.' || c == ' ')
+          char c = seq[column];
+          residueCounts.add(c);
+          if (Comparison.isNucleotide(c))
           {
-            c = '-';
+            nucleotideCount++;
           }
-
-          if (c == '-')
-          {
-            values['-']++;
-            continue;
-          }
-          else if ('a' <= c && c <= 'z')
+          else if (!Comparison.isGap(c))
           {
-            c += TO_UPPER_CASE;
+            peptideCount++;
           }
-
-          nongap++;
-          values[c]++;
-
         }
         else
         {
-          values['-']++;
-        }
-      }
-      if (jSize == 1)
-      {
-        maxResidue = String.valueOf(c);
-        maxCount = 1;
-      }
-      else
-      {
-        for (v = 'A'; v <= 'Z'; v++)
-        {
-          // TODO why ignore values[v] == 1?
-          if (values[v] < 1 /* 2 */|| values[v] < maxCount)
-          {
-            continue;
-          }
-
-          if (values[v] > maxCount)
-          {
-            maxResidue = CHARS[v - 'A'];
-          }
-          else if (values[v] == maxCount)
-          {
-            maxResidue += CHARS[v - 'A'];
-          }
-          maxCount = values[v];
+          /*
+           * count a gap if the sequence doesn't reach this column
+           */
+          residueCounts.addGap();
         }
       }
-      if (maxResidue.length() == 0)
-      {
-        maxResidue = "-";
-      }
-      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 } });
-      }
-      residueHash.put(MAXCOUNT, new Integer(maxCount));
-      residueHash.put(MAXRESIDUE, maxResidue);
 
-      percentage = ((float) maxCount * 100) / jSize;
-      residueHash.put(PID_GAPS, new Float(percentage));
+      int maxCount = residueCounts.getModalCount();
+      String maxResidue = residueCounts.getResiduesForCount(maxCount);
+      int gapCount = residueCounts.getGapCount();
+      ProfileI profile = new Profile(seqCount, gapCount, maxCount,
+              maxResidue);
 
-      if (nongap > 0)
+      if (saveFullProfile)
       {
-        // calculate for non-gapped too
-        percentage = ((float) maxCount * 100) / nongap;
+        profile.setCounts(residueCounts);
       }
-      residueHash.put(PID_NOGAPS, new Float(percentage));
 
-      result[i] = residueHash;
+      result[column] = profile;
     }
+    return new Profiles(result);
+    // long elapsed = System.currentTimeMillis() - now;
+    // System.out.println(elapsed);
   }
 
   /**
-   * Compute all or part of the annotation row from the given consensus
-   * hashtable
+   * Make an estimate of the profile size we are going to compute i.e. how many
+   * different characters may be present in it. Overestimating has a cost of
+   * using more memory than necessary. Underestimating has a cost of needing to
+   * extend the SparseIntArray holding the profile counts.
    * 
-   * @param consensus
-   *          - pre-allocated annotation row
-   * @param hconsensus
-   * @param iStart
-   * @param width
-   * @param ignoreGapsInConsensusCalculation
-   * @param includeAllConsSymbols
-   * @param nseq
+   * @param profileSizes
+   *          counts of sizes of profiles so far encountered
+   * @return
    */
-  public static void completeConsensus(AlignmentAnnotation consensus,
-          Hashtable[] hconsensus, int iStart, int width,
-          boolean ignoreGapsInConsensusCalculation,
-          boolean includeAllConsSymbols, long nseq)
+  static int estimateProfileSize(SparseIntArray profileSizes)
   {
-    completeConsensus(consensus, hconsensus, iStart, width,
-            ignoreGapsInConsensusCalculation, includeAllConsSymbols, null,
-            nseq);
+    if (profileSizes.size() == 0)
+    {
+      return 4;
+    }
+
+    /*
+     * could do a statistical heuristic here e.g. 75%ile
+     * for now just return the largest value
+     */
+    return profileSizes.keyAt(profileSizes.size() - 1);
   }
 
   /**
    * 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.
+   * display options, such as 'ignore gaps', which may in turn result in a
+   * change in the derived values.
    * 
    * @param consensus
    *          the annotation row to add annotations to
-   * @param hconsensus
+   * @param profiles
    *          the source consensus data
-   * @param iStart
-   *          start column
-   * @param width
-   *          end column
-   * @param ignoreGapsInConsensusCalculation
-   *          if true, use the consensus calculated ignoring gaps
-   * @param includeAllConsSymbols
+   * @param startCol
+   *          start column (inclusive)
+   * @param endCol
+   *          end column (exclusive)
+   * @param ignoreGaps
+   *          if true, normalise residue percentages ignoring gaps
+   * @param showSequenceLogo
    *          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)
+          ProfilesI profiles, int startCol, int endCol, boolean ignoreGaps,
+          boolean showSequenceLogo, long nseq)
   {
+    // long now = System.currentTimeMillis();
     if (consensus == null || consensus.annotations == null
-            || consensus.annotations.length < width)
+            || consensus.annotations.length < endCol)
     {
-      // called with a bad alignment annotation row - wait for it to be
-      // initialised properly
+      /*
+       * called with a bad alignment annotation row 
+       * wait for it to be initialised properly
+       */
       return;
     }
 
-    final Format fmt = getPercentageFormat(nseq);
-
-    for (int i = iStart; i < width; i++)
+    for (int i = startCol; i < endCol; i++)
     {
-      Hashtable hci;
-      if (i >= hconsensus.length || ((hci = hconsensus[i]) == null))
+      ProfileI profile = profiles.get(i);
+      if (profile == null)
       {
-        // happens if sequences calculated over were shorter than alignment
-        // width
+        /*
+         * happens if sequences calculated over were 
+         * shorter than alignment width
+         */
         consensus.annotations[i] = null;
-        continue;
+        return;
       }
-      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;
-      }
-      float value = fv.floatValue();
-      String maxRes = hci.get(AAFrequency.MAXRESIDUE).toString();
-      StringBuilder mouseOver = new StringBuilder(64);
-      if (maxRes.length() > 1)
+
+      final int dp = getPercentageDp(nseq);
+
+      float value = profile.getPercentageIdentity(ignoreGaps);
+
+      String description = getTooltip(profile, value, showSequenceLogo,
+              ignoreGaps, dp);
+
+      String modalResidue = profile.getModalResidue();
+      if ("".equals(modalResidue))
       {
-        mouseOver.append("[").append(maxRes).append("] ");
-        maxRes = "+";
+        modalResidue = "-";
       }
-      else
+      else if (modalResidue.length() > 1)
       {
-        mouseOver.append(hci.get(AAFrequency.MAXRESIDUE) + " ");
+        modalResidue = "+";
       }
-      int[][] profile = (int[][]) hci.get(AAFrequency.PROFILE);
-      if (profile != null && includeAllConsSymbols)
-      {
-        int sequenceCount = profile[1][0];
-        int nonGappedCount = profile[1][1];
-        int normalisedBy = ignoreGapsInConsensusCalculation ? nonGappedCount
-                : sequenceCount;
-        mouseOver.setLength(0);
-        if (alphabet != null)
-        {
-          for (int c = 0; c < alphabet.length; c++)
-          {
-            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
-        {
-          // 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] = (char) c;
-            // ca[c] = new char[]
-            // { (char) c };
-            vl[c] = profile[0][c];
-          }
-          QuickSort.sort(vl, ca);
-          for (int p = 0, c = ca.length - 1; profile[0][ca[c]] > 0; c--)
-          {
-            final char residue = ca[c];
-            if (residue != '-')
-            {
-              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.append(
-                (((fmt != null) ? fmt.form(value) : ((int) value))))
-                .append("%");
-      }
-      consensus.annotations[i] = new Annotation(maxRes,
-              mouseOver.toString(), ' ', value);
+      consensus.annotations[i] = new Annotation(modalResidue, description,
+              ' ', value);
     }
+    // long elapsed = System.currentTimeMillis() - now;
+    // System.out.println(-elapsed);
   }
 
   /**
-   * 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"
+   * Returns a tooltip showing either
+   * <ul>
+   * <li>the full profile (percentages of all residues present), if
+   * showSequenceLogo is true, or</li>
+   * <li>just the modal (most common) residue(s), if showSequenceLogo is false</li>
+   * </ul>
+   * Percentages are as a fraction of all sequence, or only ungapped sequences
+   * if ignoreGaps is true.
    * 
-   * @param nseq
+   * @param profile
+   * @param pid
+   * @param showSequenceLogo
+   * @param ignoreGaps
+   * @param dp
+   *          the number of decimal places to format percentages to
    * @return
    */
-  protected static Format getPercentageFormat(long nseq)
+  static String getTooltip(ProfileI profile, float pid,
+          boolean showSequenceLogo, boolean ignoreGaps, int dp)
   {
-    int scale = 0;
-    while (nseq >= 10)
+    ResidueCount counts = profile.getCounts();
+
+    String description = null;
+    if (counts != null && showSequenceLogo)
     {
-      scale++;
-      nseq /= 10;
+      int normaliseBy = ignoreGaps ? profile.getNonGapped() : profile
+              .getHeight();
+      description = counts.getTooltip(normaliseBy, dp);
+    }
+    else
+    {
+      StringBuilder sb = new StringBuilder(64);
+      String maxRes = profile.getModalResidue();
+      if (maxRes.length() > 1)
+      {
+        sb.append("[").append(maxRes).append("]");
+      }
+      else
+      {
+        sb.append(maxRes);
+      }
+      if (maxRes.length() > 0)
+      {
+        sb.append(" ");
+        Format.appendPercentage(sb, pid, dp);
+        sb.append("%");
+      }
+      description = sb.toString();
     }
-    return scale <= 1 ? null : new Format("%3." + (scale - 1) + "f");
+    return description;
   }
 
   /**
@@ -399,46 +350,46 @@ public class AAFrequency
    * in descending order of percentage value
    * </pre>
    * 
-   * @param hconsensus
-   *          the data table from which to extract and sort values
+   * @param profile
+   *          the data object 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,
+  public static int[] extractProfile(ProfileI profile,
           boolean ignoreGaps)
   {
     int[] rtnval = new int[64];
-    int[][] profile = (int[][]) hconsensus.get(AAFrequency.PROFILE);
-    if (profile == null)
+    ResidueCount counts = profile.getCounts();
+    if (counts == null)
     {
       return null;
     }
-    char[] ca = new char[profile[0].length];
-    float[] vl = new float[profile[0].length];
-    for (int c = 0; c < ca.length; c++)
-    {
-      ca[c] = (char) c;
-      vl[c] = profile[0][c];
-    }
-    QuickSort.sort(vl, ca);
+
+    SymbolCounts symbolCounts = counts.getSymbolCounts();
+    char[] symbols = symbolCounts.symbols;
+    int[] values = symbolCounts.values;
+    QuickSort.sort(values, symbols);
     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--)
+    final int divisor = ignoreGaps ? profile.getNonGapped() : profile
+            .getHeight();
+
+    /*
+     * traverse the arrays in reverse order (highest counts first)
+     */
+    for (int i = symbols.length - 1; i >= 0; i--)
     {
-      if (ca[c] != '-')
-      {
-        rtnval[nextArrayPos++] = ca[c];
-        final int percentage = (int) (profile[0][ca[c]] * 100f / divisor);
-        rtnval[nextArrayPos++] = percentage;
-        totalPercentage += percentage;
-        distinctValuesCount++;
-      }
+      int theChar = symbols[i];
+      int charCount = values[i];
+
+      rtnval[nextArrayPos++] = theChar;
+      final int percentage = (charCount * 100) / divisor;
+      rtnval[nextArrayPos++] = percentage;
+      totalPercentage += percentage;
     }
-    rtnval[0] = distinctValuesCount;
+    rtnval[0] = symbols.length;
     rtnval[1] = totalPercentage;
     int[] result = new int[rtnval.length + 1];
     result[0] = AlignmentAnnotation.SEQUENCE_PROFILE;
@@ -647,7 +598,7 @@ public class AAFrequency
       StringBuilder samePercent = new StringBuilder();
       String percent = null;
       String lastPercent = null;
-      Format fmt = getPercentageFormat(nseqs);
+      int percentDecPl = getPercentageDp(nseqs);
 
       for (int j = codons.length - 1; j >= 0; j--)
       {
@@ -669,7 +620,9 @@ public class AAFrequency
         final int pct = codonCount * 100 / totalCount;
         String codon = String
                 .valueOf(CodingUtils.decodeCodon(codonEncoded));
-        percent = fmt == null ? Integer.toString(pct) : fmt.form(pct);
+        StringBuilder sb = new StringBuilder();
+        Format.appendPercentage(sb, pct, percentDecPl);
+        percent = sb.toString();
         if (showProfileLogo || codonCount == modalCodonCount)
         {
           if (percent.equals(lastPercent) && j > 0)
@@ -695,4 +648,23 @@ public class AAFrequency
               mouseOver.toString(), ' ', pid);
     }
   }
+
+  /**
+   * Returns the number of decimal places to show for profile percentages. For
+   * less than 100 sequences, returns zero (the integer percentage value will be
+   * displayed). For 100-999 sequences, returns 1, for 1000-9999 returns 2, etc.
+   * 
+   * @param nseq
+   * @return
+   */
+  protected static int getPercentageDp(long nseq)
+  {
+    int scale = 0;
+    while (nseq >= 100)
+    {
+      scale++;
+      nseq /= 10;
+    }
+    return scale;
+  }
 }
index 3ad3188..86bf721 100755 (executable)
@@ -620,7 +620,10 @@ public class AlignSeq
       {
         if ((i + (j * len)) < astr1.length())
         {
-          if (astr1.charAt(i + (j * len)) == astr2.charAt(i + (j * len))
+          boolean sameChar = Comparison.isSameResidue(
+                  astr1.charAt(i + (j * len)), astr2.charAt(i + (j * len)),
+                  false);
+          if (sameChar
                   && !jalview.util.Comparison.isGap(astr1.charAt(i
                           + (j * len))))
           {
index 75dec63..7b9da46 100755 (executable)
@@ -22,24 +22,33 @@ package jalview.analysis;
 
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.ResidueCount;
+import jalview.datamodel.ResidueCount.SymbolCounts;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
 
 import java.awt.Color;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
 import java.util.Vector;
 
 /**
  * Calculates conservation values for a given set of sequences
- * 
- * @author $author$
- * @version $Revision$
  */
 public class Conservation
 {
+  /*
+   * need to have a minimum of 3% of sequences with a residue
+   * for it to be included in the conservation calculation
+   */
+  private static final int THRESHOLD_PERCENT = 3;
+
+  private static final int TOUPPERCASE = 'a' - 'A';
+
   SequenceI[] sequences;
 
   int start;
@@ -53,6 +62,11 @@ public class Conservation
 
   boolean seqNumsChanged = false; // updated after any change via calcSeqNum;
 
+  /*
+   * a map per column with {property, conservation} where conservation value is
+   * 1 (property is conserved), 0 (absence of property is conserved) or -1
+   * (property is not conserved i.e. column has residues with and without it)
+   */
   Map<String, Integer>[] total;
 
   boolean canonicaliseAa = true; // if true then conservation calculation will
@@ -69,6 +83,9 @@ public class Conservation
 
   private Sequence consSequence;
 
+  /*
+   * percentage of residues in a column to qualify for counting conservation
+   */
   private int threshold;
 
   private String name = "";
@@ -78,12 +95,10 @@ public class Conservation
   private String[] consSymbs;
 
   /**
-   * Creates a new Conservation object.
+   * Constructor using default threshold of 3%
    * 
    * @param name
    *          Name of conservation
-   * @param threshold
-   *          to count the residues in residueHash(). commonly used value is 3
    * @param sequences
    *          sequences to be used in calculation
    * @param start
@@ -91,6 +106,27 @@ public class Conservation
    * @param end
    *          end residue position
    */
+  public Conservation(String name, List<SequenceI> sequences, int start,
+          int end)
+  {
+    this(name, THRESHOLD_PERCENT, sequences, start, end);
+  }
+
+  /**
+   * Constructor
+   * 
+   * @param name
+   *          Name of conservation
+   * @param threshold
+   *          percentage of sequences at or below which property conservation is
+   *          ignored
+   * @param sequences
+   *          sequences to be used in calculation
+   * @param start
+   *          start column position
+   * @param end
+   *          end column position
+   */
   public Conservation(String name, int threshold,
           List<SequenceI> sequences, int start, int end)
   {
@@ -188,147 +224,187 @@ public class Conservation
    */
   public void calculate()
   {
-    int thresh, j, jSize = sequences.length;
-    int[] values; // Replaces residueHash
-    char c;
+    int height = sequences.length;
 
-    total = new Hashtable[maxLength];
+    total = new Map[maxLength];
 
-    for (int i = start; i <= end; i++)
+    for (int column = start; column <= end; column++)
     {
-      values = new int[255];
+      ResidueCount values = countResidues(column);
+
+      /*
+       * percentage count at or below which we ignore residues
+       */
+      int thresh = (threshold * height) / 100;
 
-      for (j = 0; j < jSize; j++)
+      /*
+       * check observed residues in column and record whether each 
+       * physico-chemical property is conserved (+1), absence conserved (0),
+       * or not conserved (-1)
+       * Using TreeMap means properties are displayed in alphabetical order
+       */
+      Map<String, Integer> resultHash = new TreeMap<String, Integer>();
+      SymbolCounts symbolCounts = values.getSymbolCounts();
+      char[] symbols = symbolCounts.symbols;
+      int[] counts = symbolCounts.values;
+      for (int j = 0; j < symbols.length; j++)
       {
-        if (sequences[j].getLength() > i)
+        char c = symbols[j];
+        if (counts[j] > thresh)
         {
-          c = sequences[j].getCharAt(i);
-
-          if (canonicaliseAa)
-          { // lookup the base aa code symbol
-            c = (char) ResidueProperties.aaIndex[sequences[j].getCharAt(i)];
-            if (c > 20)
-            {
-              c = '-';
-            }
-            else
-            {
-              // recover canonical aa symbol
-              c = ResidueProperties.aa[c].charAt(0);
-            }
-          }
-          else
-          {
-            // original behaviour - operate on ascii symbols directly
-            // No need to check if its a '-'
-            if (c == '.' || c == ' ')
-            {
-              c = '-';
-            }
-
-            c = toUpperCase(c);
-          }
-          values[c]++;
+          recordConservation(resultHash, String.valueOf(c));
+        }
+      }
+      if (values.getGapCount() > thresh)
+      {
+        recordConservation(resultHash, "-");
+      }
+
+      if (total.length > 0)
+      {
+        total[column - start] = resultHash;
+      }
+    }
+  }
+
+  /**
+   * Updates the conservation results for an observed residue
+   * 
+   * @param resultMap
+   *          a map of {property, conservation} where conservation value is +1
+   *          (all residues have the property), 0 (no residue has the property)
+   *          or -1 (some do, some don't)
+   * @param res
+   */
+  protected static void recordConservation(Map<String, Integer> resultMap,
+          String res)
+  {
+    res = res.toUpperCase();
+    for (Entry<String, Map<String, Integer>> property : ResidueProperties.propHash
+            .entrySet())
+    {
+      String propertyName = property.getKey();
+      Integer residuePropertyValue = property.getValue().get(res);
+
+      if (!resultMap.containsKey(propertyName))
+      {
+        /*
+         * first time we've seen this residue - note whether it has this property
+         */
+        if (residuePropertyValue != null)
+        {
+          resultMap.put(propertyName, residuePropertyValue);
         }
         else
         {
-          values['-']++;
+          /*
+           * unrecognised residue - use default value for property
+           */
+          resultMap.put(propertyName, property.getValue().get("-"));
         }
       }
+      else
+      {
+        Integer currentResult = resultMap.get(propertyName);
+        if (currentResult.intValue() != -1
+                && !currentResult.equals(residuePropertyValue))
+        {
+          /*
+           * property is unconserved - residues seen both with and without it
+           */
+          resultMap.put(propertyName, Integer.valueOf(-1));
+        }
+      }
+    }
+  }
 
-      // What is the count threshold to count the residues in residueHash()
-      thresh = (threshold * (jSize)) / 100;
+  /**
+   * Counts residues (upper-cased) and gaps in the given column
+   * 
+   * @param column
+   * @return
+   */
+  protected ResidueCount countResidues(int column)
+  {
+    ResidueCount values = new ResidueCount(false);
 
-      // loop over all the found residues
-      Hashtable<String, Integer> resultHash = new Hashtable<String, Integer>();
-      for (char v = '-'; v < 'Z'; v++)
+    for (int row = 0; row < sequences.length; row++)
+    {
+      if (sequences[row].getLength() > column)
       {
-
-        if (values[v] > thresh)
+        char c = sequences[row].getCharAt(column);
+        if (canonicaliseAa)
         {
-          String res = String.valueOf(v);
-
-          // Now loop over the properties
-          for (String type : ResidueProperties.propHash.keySet())
-          {
-            Map<String, Integer> ht = ResidueProperties.propHash.get(type);
-
-            // Have we ticked this before?
-            if (!resultHash.containsKey(type))
-            {
-              if (ht.containsKey(res))
-              {
-                resultHash.put(type, ht.get(res));
-              }
-              else
-              {
-                resultHash.put(type, ht.get("-"));
-              }
-            }
-            else if (!resultHash.get(type).equals(ht.get(res)))
-            {
-              resultHash.put(type, new Integer(-1));
-            }
-          }
+          int index = ResidueProperties.aaIndex[c];
+          c = index > 20 ? '-' : ResidueProperties.aa[index].charAt(0);
+        }
+        else
+        {
+          c = toUpperCase(c);
+        }
+        if (Comparison.isGap(c))
+        {
+          values.addGap();
+        }
+        else
+        {
+          values.add(c);
         }
       }
-
-      if (total.length > 0)
+      else
       {
-        total[i - start] = resultHash;
+        values.addGap();
       }
     }
+    return values;
   }
 
-  /*****************************************************************************
-   * count conservation for the j'th column of the alignment
+  /**
+   * Counts conservation and gaps for a column of the alignment
    * 
-   * @return { gap count, conserved residue count}
+   * @return { 1 if fully conserved, else 0, gap count }
    */
-  public int[] countConsNGaps(int j)
+  public int[] countConservationAndGaps(int column)
   {
-    int count = 0;
-    int cons = 0;
-    int nres = 0;
-    int[] r = new int[2];
-    char f = '$';
-    int i, iSize = sequences.length;
-    char c;
+    int gapCount = 0;
+    boolean fullyConserved = true;
+    int iSize = sequences.length;
 
-    for (i = 0; i < iSize; i++)
+    if (iSize == 0)
+    {
+      return new int[] { 0, 0 };
+    }
+
+    char lastRes = '0';
+    for (int i = 0; i < iSize; i++)
     {
-      if (j >= sequences[i].getLength())
+      if (column >= sequences[i].getLength())
       {
-        count++;
+        gapCount++;
         continue;
       }
 
-      c = sequences[i].getCharAt(j); // gaps do not have upper/lower case
+      char c = sequences[i].getCharAt(column); // gaps do not have upper/lower case
 
-      if (jalview.util.Comparison.isGap((c)))
+      if (Comparison.isGap((c)))
       {
-        count++;
+        gapCount++;
       }
       else
       {
         c = toUpperCase(c);
-        nres++;
-
-        if (nres == 1)
+        if (lastRes == '0')
         {
-          f = c;
-          cons++;
+          lastRes = c;
         }
-        else if (f == c)
+        if (c != lastRes)
         {
-          cons++;
+          fullyConserved = false;
         }
       }
     }
 
-    r[0] = (nres == cons) ? 1 : 0;
-    r[1] = count;
-
+    int[] r = new int[] { fullyConserved ? 1 : 0, gapCount };
     return r;
   }
 
@@ -343,7 +419,7 @@ public class Conservation
   {
     if ('a' <= c && c <= 'z')
     {
-      c -= (32); // 32 = 'a' - 'A'
+      c -= TOUPPERCASE;
     }
     return c;
   }
@@ -351,15 +427,18 @@ public class Conservation
   /**
    * Calculates the conservation sequence
    * 
-   * @param consflag
-   *          if true, positive conservation; false calculates negative
-   *          conservation
-   * @param percentageGaps
-   *          commonly used value is 25
+   * @param positiveOnly
+   *          if true, calculate positive conservation; else calculate both
+   *          positive and negative conservation
+   * @param maxPercentageGaps
+   *          the percentage of gaps in a column, at or above which no
+   *          conservation is asserted
    */
-  public void verdict(boolean consflag, float percentageGaps)
+  public void verdict(boolean positiveOnly, float maxPercentageGaps)
   {
-    StringBuffer consString = new StringBuffer();
+    // TODO call this at the end of calculate(), should not be a public method
+
+    StringBuilder consString = new StringBuilder(end);
 
     // NOTE THIS SHOULD CHECK IF THE CONSEQUENCE ALREADY
     // EXISTS AND NOT OVERWRITE WITH '-', BUT THIS CASE
@@ -371,44 +450,50 @@ public class Conservation
     consSymbs = new String[end - start + 1];
     for (int i = start; i <= end; i++)
     {
-      int[] gapcons = countConsNGaps(i);
+      int[] gapcons = countConservationAndGaps(i);
+      boolean fullyConserved = gapcons[0] == 1;
       int totGaps = gapcons[1];
-      float pgaps = ((float) totGaps * 100) / sequences.length;
-      consSymbs[i - start] = new String();
+      float pgaps = (totGaps * 100f) / sequences.length;
 
-      if (percentageGaps > pgaps)
+      if (maxPercentageGaps > pgaps)
       {
         Map<String, Integer> resultHash = total[i - start];
-        // Now find the verdict
         int count = 0;
+        StringBuilder positives = new StringBuilder(64);
+        StringBuilder negatives = new StringBuilder(32);
         for (String type : resultHash.keySet())
         {
           int result = resultHash.get(type).intValue();
-          // Do we want to count +ve conservation or +ve and -ve cons.?
-          if (consflag)
+          if (result == -1)
+          {
+            /*
+             * not conserved (present or absent)
+             */
+            continue;
+          }
+          count++;
+          if (result == 1)
           {
-            if (result == 1)
-            {
-              consSymbs[i - start] = type + " " + consSymbs[i - start];
-              count++;
-            }
+            /*
+             * positively conserved property (all residues have it)
+             */
+            positives.append(positives.length() == 0 ? "" : " ");
+            positives.append(type);
           }
-          else
+          if (result == 0 && !positiveOnly)
           {
-            if (result != -1)
-            {
-              if (result == 0)
-              {
-                consSymbs[i - start] = consSymbs[i - start] + " !" + type;
-              }
-              else
-              {
-                consSymbs[i - start] = type + " " + consSymbs[i - start];
-              }
-              count++;
-            }
+            /*
+             * absense of property is conserved (all residues lack it)
+             */
+            negatives.append(negatives.length() == 0 ? "" : " ");
+            negatives.append("!").append(type);
           }
         }
+        if (negatives.length() > 0)
+        {
+          positives.append(" ").append(negatives);
+        }
+        consSymbs[i - start] = positives.toString();
 
         if (count < 10)
         {
@@ -416,7 +501,7 @@ public class Conservation
         }
         else
         {
-          consString.append((gapcons[0] == 1) ? "*" : "+");
+          consString.append(fullyConserved ? "*" : "+");
         }
       }
       else
@@ -720,29 +805,27 @@ public class Conservation
    * 
    * @param name
    *          - name of conservation
-   * @param threshold
-   *          - minimum number of conserved residues needed to indicate
-   *          conservation (typically 3)
    * @param seqs
    * @param start
    *          first column in calculation window
    * @param end
    *          last column in calculation window
-   * @param posOrNeg
-   *          positive (true) or negative (false) conservation
-   * @param consPercGaps
+   * @param positiveOnly
+   *          calculate positive (true) or positive and negative (false)
+   *          conservation
+   * @param maxPercentGaps
    *          percentage of gaps tolerated in column
    * @param calcQuality
    *          flag indicating if alignment quality should be calculated
    * @return Conservation object ready for use in visualization
    */
   public static Conservation calculateConservation(String name,
-          int threshold, List<SequenceI> seqs, int start, int end,
-          boolean posOrNeg, int consPercGaps, boolean calcQuality)
+          List<SequenceI> seqs, int start, int end, boolean positiveOnly,
+          int maxPercentGaps, boolean calcQuality)
   {
-    Conservation cons = new Conservation(name, threshold, seqs, start, end);
+    Conservation cons = new Conservation(name, seqs, start, end);
     cons.calculate();
-    cons.verdict(posOrNeg, consPercGaps);
+    cons.verdict(positiveOnly, maxPercentGaps);
 
     if (calcQuality)
     {
@@ -751,4 +834,24 @@ public class Conservation
 
     return cons;
   }
+
+  /**
+   * Returns the computed tooltip (annotation description) for a given column.
+   * The tip is empty if the conservation score is zero, otherwise holds the
+   * conserved properties (and, optionally, properties whose absence is
+   * conserved).
+   * 
+   * @param column
+   * @return
+   */
+  String getTooltip(int column)
+  {
+    char[] sequence = getConsSequence().getSequence();
+    char val = column < sequence.length ? sequence[column] : '-';
+    boolean hasConservation = val != '-' && val != '0';
+    int consp = column - start;
+    String tip = (hasConservation && consp > -1 && consp < consSymbs.length) ? consSymbs[consp]
+            : "";
+    return tip;
+  }
 }
index 72097e0..25ee7d2 100644 (file)
 package jalview.analysis;
 
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
-import jalview.datamodel.Sequence;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Vector;
 
+import com.stevesoft.pat.Regex;
+
 public class Finder
 {
   /**
    * Implements the search algorithms for the Find dialog box.
    */
-  SearchResults searchResults;
+  SearchResultsI searchResults;
 
   AlignmentI alignment;
 
-  jalview.datamodel.SequenceGroup selection = null;
+  SequenceGroup selection = null;
 
-  Vector idMatch = null;
+  Vector<SequenceI> idMatch = null;
 
   boolean caseSensitive = false;
 
@@ -46,10 +53,10 @@ public class Finder
 
   boolean findAll = false;
 
-  com.stevesoft.pat.Regex regex = null;
+  Regex regex = null;
 
   /**
-   * hold's last-searched position between calles to find(false)
+   * holds last-searched position between calls to find(false)
    */
   int seqIndex = 0, resIndex = -1;
 
@@ -83,11 +90,10 @@ public class Finder
     {
       searchString = searchString.toUpperCase();
     }
-    regex = new com.stevesoft.pat.Regex(searchString);
+    regex = new Regex(searchString);
     regex.setIgnoreCase(!caseSensitive);
     searchResults = new SearchResults();
-    idMatch = new Vector();
-    Sequence seq;
+    idMatch = new Vector<SequenceI>();
     String item = null;
     boolean found = false;
     int end = alignment.getHeight();
@@ -102,10 +108,11 @@ public class Finder
         selection = null;
       }
     }
+    SearchResultMatchI lastm = null;
 
     while (!found && (seqIndex < end))
     {
-      seq = (Sequence) alignment.getSequenceAt(seqIndex);
+      SequenceI seq = alignment.getSequenceAt(seqIndex);
 
       if ((selection != null && selection.getSize() > 0)
               && !selection.getSequences(null).contains(seq))
@@ -140,7 +147,7 @@ public class Finder
         {
         }
 
-        if (regex.search(seq.getName()))
+        if (regex.search(seq.getName()) && !idMatch.contains(seq))
         {
           idMatch.addElement(seq);
           hasResults = true;
@@ -153,7 +160,8 @@ public class Finder
         }
 
         if (isIncludeDescription() && seq.getDescription() != null
-                && regex.search(seq.getDescription()))
+                && regex.search(seq.getDescription())
+                && !idMatch.contains(seq))
         {
           idMatch.addElement(seq);
           hasResults = true;
@@ -174,16 +182,16 @@ public class Finder
       }
 
       // /Shall we ignore gaps???? - JBPNote: Add Flag for forcing this or not
-      StringBuffer noGapsSB = new StringBuffer();
+      StringBuilder noGapsSB = new StringBuilder();
       int insertCount = 0;
-      Vector spaces = new Vector();
+      List<Integer> spaces = new ArrayList<Integer>();
 
       for (int j = 0; j < item.length(); j++)
       {
-        if (!jalview.util.Comparison.isGap(item.charAt(j)))
+        if (!Comparison.isGap(item.charAt(j)))
         {
           noGapsSB.append(item.charAt(j));
-          spaces.addElement(new Integer(insertCount));
+          spaces.add(Integer.valueOf(insertCount));
         }
         else
         {
@@ -192,7 +200,6 @@ public class Finder
       }
 
       String noGaps = noGapsSB.toString();
-
       for (int r = resIndex; r < noGaps.length(); r++)
       {
 
@@ -201,22 +208,22 @@ public class Finder
           resIndex = regex.matchedFrom();
 
           if ((selection != null && selection.getSize() > 0)
-                  && ((resIndex + Integer.parseInt(spaces.elementAt(
-                          resIndex).toString())) < selection.getStartRes()))
+                  && (resIndex + spaces.get(resIndex) < selection
+                          .getStartRes()))
           {
             continue;
           }
           // if invalid string used, then regex has no matched to/from
-          int sres = seq
-                  .findPosition(resIndex
-                          + Integer.parseInt(spaces.elementAt(resIndex)
-                                  .toString()));
-          int eres = seq.findPosition(regex.matchedTo()
-                  - 1
-                  + Integer.parseInt(spaces
-                          .elementAt(regex.matchedTo() - 1).toString()));
-
-          searchResults.addResult(seq, sres, eres);
+          int sres = seq.findPosition(resIndex + spaces.get(resIndex));
+          int eres = seq.findPosition(regex.matchedTo() - 1
+                  + (spaces.get(regex.matchedTo() - 1)));
+          // only add result if not contained in previous result
+          if (lastm == null
+                  || (lastm.getSequence() != seq || (!(lastm.getStart() <= sres && lastm
+                          .getEnd() >= eres))))
+          {
+            lastm = searchResults.addResult(seq, sres, eres);
+          }
           hasResults = true;
           if (!findAll)
           {
@@ -320,9 +327,12 @@ public class Finder
   }
 
   /**
-   * @return the idMatch
+   * Returns the (possibly empty) list of matching sequences (when search
+   * includes searching sequence names)
+   * 
+   * @return
    */
-  public Vector getIdMatch()
+  public Vector<SequenceI> getIdMatch()
   {
     return idMatch;
   }
@@ -338,7 +348,7 @@ public class Finder
   /**
    * @return the searchResults
    */
-  public SearchResults getSearchResults()
+  public SearchResultsI getSearchResults()
   {
     return searchResults;
   }
index 26966ba..a7ec69e 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.api;
 
+import jalview.io.DataSourceType;
+
 import java.util.List;
 
 /**
@@ -88,13 +90,25 @@ public interface AlignViewControllerI
    * add a features file of some kind to the current view
    * 
    * @param file
-   * @param protocol
+   * @param sourceType
    * @param relaxedIdMatching
    *          if true, try harder to match up IDs with local sequence data
    * @return true if parsing resulted in something being imported to the view or
    *         dataset
    */
-  public boolean parseFeaturesFile(String file, String protocol,
+  public boolean parseFeaturesFile(String file, DataSourceType sourceType,
           boolean relaxedIdMatching);
 
+  /**
+   * mark columns containing highlighted regions (e.g. from search, structure
+   * highlight, or a mouse over event in another viewer)
+   * 
+   * @param invert
+   * @param extendCurrent
+   * @param toggle
+   * @return
+   */
+  boolean markHighlightedColumns(boolean invert, boolean extendCurrent,
+          boolean toggle);
+
 }
index bd7d53d..72542b3 100644 (file)
@@ -26,6 +26,8 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -81,7 +83,7 @@ public interface AlignViewportI extends ViewStyleI
 
   ColumnSelection getColumnSelection();
 
-  Hashtable[] getSequenceConsensusHash();
+  ProfilesI getSequenceConsensusHash();
 
   /**
    * Get consensus data table for the cDNA complement of this alignment (if any)
@@ -144,7 +146,7 @@ public interface AlignViewportI extends ViewStyleI
    * 
    * @param hconsensus
    */
-  void setSequenceConsensusHash(Hashtable[] hconsensus);
+  void setSequenceConsensusHash(ProfilesI hconsensus);
 
   /**
    * Set the cDNA complement consensus for the viewport
@@ -422,4 +424,25 @@ public interface AlignViewportI extends ViewStyleI
    * @return true if group is defined on the alignment
    */
   boolean isSelectionDefinedGroup();
+
+  /**
+   * 
+   * @return true if there are search results on the view
+   */
+  boolean hasSearchResults();
+
+  /**
+   * set the search results for the view
+   * 
+   * @param results
+   *          - or null to clear current results
+   */
+  void setSearchResults(SearchResultsI results);
+
+  /**
+   * get search results for this view (if any)
+   * 
+   * @return search results or null
+   */
+  SearchResultsI getSearchResults();
 }
index dbc9880..f54231e 100644 (file)
@@ -132,7 +132,8 @@ public interface FeatureRenderer
   void setGroupVisibility(String group, boolean visible);
 
   /**
-   * locate features at a particular position on the given sequence
+   * Returns features at the specified position on the given sequence.
+   * Non-positional features are not included.
    * 
    * @param sequence
    * @param res
index c30fdad..015734f 100644 (file)
@@ -24,17 +24,19 @@ import jalview.analysis.AAFrequency;
 import jalview.analysis.AlignmentAnnotationUtils;
 import jalview.analysis.AlignmentUtils;
 import jalview.analysis.Conservation;
+import jalview.bin.JalviewLite;
 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.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.SequenceAnnotationReport;
 import jalview.schemes.Blosum62ColourScheme;
 import jalview.schemes.BuriedColourScheme;
@@ -59,6 +61,7 @@ import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -213,10 +216,9 @@ public class APopupMenu extends java.awt.PopupMenu implements
       e.printStackTrace();
     }
 
-    for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length; i++)
+    for (String ff : FileFormat.getWritableFormats(true))
     {
-      MenuItem item = new MenuItem(
-              jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i]);
+      MenuItem item = new MenuItem(ff);
 
       item.addActionListener(this);
       outputmenu.add(item);
@@ -253,122 +255,9 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
     if (links != null && links.size() > 0)
     {
-      Menu linkMenu = new Menu(MessageManager.getString("action.link"));
-      for (int i = 0; i < links.size(); i++)
-      {
-        String link = links.elementAt(i);
-        UrlLink urlLink = new UrlLink(link);
-        if (!urlLink.isValid())
-        {
-          System.err.println(urlLink.getInvalidMessage());
-          continue;
-        }
-        final String target = urlLink.getTarget(); // link.substring(0,
-        // link.indexOf("|"));
-        final String label = urlLink.getLabel();
-        if (seq != null && urlLink.isDynamic())
-        {
-
-          // collect matching db-refs
-          DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(
-                  seq.getDBRefs(), new String[] { target });
-          // collect id string too
-          String id = seq.getName();
-          String descr = seq.getDescription();
-          if (descr != null && descr.length() < 1)
-          {
-            descr = null;
-          }
-          if (dbr != null)
-          {
-            for (int r = 0; r < dbr.length; r++)
-            {
-              if (id != null && dbr[r].getAccessionId().equals(id))
-              {
-                // suppress duplicate link creation for the bare sequence ID
-                // string with this link
-                id = null;
-              }
-              // create Bare ID link for this RUL
-              String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(),
-                      true);
-              if (urls != null)
-              {
-                for (int u = 0; u < urls.length; u += 2)
-                {
-                  addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]);
-                }
-              }
-            }
-          }
-          if (id != null)
-          {
-            // create Bare ID link for this RUL
-            String[] urls = urlLink.makeUrls(id, true);
-            if (urls != null)
-            {
-              for (int u = 0; u < urls.length; u += 2)
-              {
-                addshowLink(linkMenu, label, urls[u + 1]);
-              }
-            }
-            // addshowLink(linkMenu, target, url_pref + id + url_suff);
-          }
-          // Now construct URLs from description but only try to do it for regex
-          // URL links
-          if (descr != null && urlLink.getRegexReplace() != null)
-          {
-            // create link for this URL from description only if regex matches
-            String[] urls = urlLink.makeUrls(descr, true);
-            if (urls != null)
-            {
-              for (int u = 0; u < urls.length; u += 2)
-              {
-                addshowLink(linkMenu, label, urls[u + 1]);
-              }
-            }
-          }
-        }
-        else
-        {
-          addshowLink(linkMenu, target, urlLink.getUrl_prefix()); // link.substring(link.lastIndexOf("|")+1));
-        }
-        /*
-         * final String url;
-         * 
-         * if (link.indexOf("$SEQUENCE_ID$") > -1) { // Substitute SEQUENCE_ID
-         * string and any matching database reference accessions String url_pref
-         * = link.substring(link.indexOf("|") + 1,
-         * link.indexOf("$SEQUENCE_ID$"));
-         * 
-         * String url_suff = link.substring(link.indexOf("$SEQUENCE_ID$") + 13);
-         * // collect matching db-refs DBRefEntry[] dbr =
-         * jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new
-         * String[]{target}); // collect id string too String id =
-         * seq.getName(); if (id.indexOf("|") > -1) { id =
-         * id.substring(id.lastIndexOf("|") + 1); } if (dbr!=null) { for (int
-         * r=0;r<dbr.length; r++) { if (dbr[r].getAccessionId().equals(id)) { //
-         * suppress duplicate link creation for the bare sequence ID string with
-         * this link id = null; } addshowLink(linkMenu,
-         * dbr[r].getSource()+"|"+dbr[r].getAccessionId(), target,
-         * url_pref+dbr[r].getAccessionId()+url_suff); } } if (id!=null) { //
-         * create Bare ID link for this RUL addshowLink(linkMenu, target,
-         * url_pref + id + url_suff); } } else { addshowLink(linkMenu, target,
-         * link.substring(link.lastIndexOf("|")+1)); }
-         */
-      }
-      if (linkMenu.getItemCount() > 0)
-      {
-        if (seq != null)
-        {
-          seqMenu.add(linkMenu);
-        }
-        else
-        {
-          add(linkMenu);
-        }
-      }
+      addFeatureLinks(seq, links);
     }
+
     // TODO: add group link menu entry here
     if (seq != null)
     {
@@ -414,6 +303,71 @@ public class APopupMenu extends java.awt.PopupMenu implements
   }
 
   /**
+   * Adds a 'Link' menu item with a sub-menu item for each hyperlink provided.
+   * 
+   * @param seq
+   * @param links
+   */
+  void addFeatureLinks(final SequenceI seq, List<String> links)
+  {
+    Menu linkMenu = new Menu(MessageManager.getString("action.link"));
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+
+    for (String link : links)
+    {
+      UrlLink urlLink = null;
+      try
+      {
+        urlLink = new UrlLink(link);
+      } catch (Exception foo)
+      {
+        System.err.println("Exception for URLLink '" + link + "': "
+                + foo.getMessage());
+        continue;
+      }
+
+      if (!urlLink.isValid())
+      {
+        System.err.println(urlLink.getInvalidMessage());
+        continue;
+      }
+
+      urlLink.createLinksFromSeq(seq, linkset);
+    }
+
+    addshowLinks(linkMenu, linkset.values());
+
+    // disable link menu if there are no valid entries
+    if (linkMenu.getItemCount() > 0)
+    {
+      linkMenu.setEnabled(true);
+    }
+    else
+    {
+      linkMenu.setEnabled(false);
+    }
+
+    if (seq != null)
+    {
+      seqMenu.add(linkMenu);
+    }
+    else
+    {
+      add(linkMenu);
+    }
+
+  }
+
+  private void addshowLinks(Menu linkMenu, Collection<List<String>> linkset)
+  {
+    for (List<String> linkstrset : linkset)
+    {
+      // split linkstr into label and url
+      addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3));
+    }
+  }
+
+  /**
    * Build menus for annotation types that may be shown or hidden, and for
    * 'reference annotations' that may be added to the alignment.
    */
@@ -823,15 +777,16 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
     Frame frame = new Frame();
     frame.add(cap);
-    jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage(
+    JalviewLite.addFrame(frame, MessageManager.formatMessage(
             "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.getShowJVSuffix(), ap, true));
+    FileFormat fileFormat = FileFormat.valueOf(e.getActionCommand());
+    cap.setText(new AppletFormatAdapter().formatSequences(fileFormat,
+            ap.av.getShowJVSuffix(), ap, true));
 
   }
 
@@ -850,7 +805,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
     CutAndPasteTransfer cap = new CutAndPasteTransfer(false, ap.alignFrame);
 
-    StringBuffer contents = new StringBuffer();
+    StringBuilder contents = new StringBuilder(128);
     for (SequenceI seq : sequences)
     {
       contents.append(MessageManager.formatMessage(
@@ -861,7 +816,6 @@ public class APopupMenu extends java.awt.PopupMenu implements
               seq,
               true,
               true,
-              false,
               (ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr
                       .getMinMax() : null);
       contents.append("</p>");
@@ -892,19 +846,20 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
   void addPDB()
   {
-    if (seq.getAllPDBEntries() != null)
+    Vector<PDBEntry> pdbs = seq.getAllPDBEntries();
+    if (pdbs != null&& !pdbs.isEmpty())
     {
-      PDBEntry entry = seq.getAllPDBEntries().firstElement();
+      PDBEntry entry = pdbs.firstElement();
 
       if (ap.av.applet.jmolAvailable)
       {
         new jalview.appletgui.AppletJmol(entry, new SequenceI[] { seq },
-                null, ap, AppletFormatAdapter.URL);
+                null, ap, DataSourceType.URL);
       }
       else
       {
         new MCview.AppletPDBViewer(entry, new SequenceI[] { seq }, null,
-                ap, AppletFormatAdapter.URL);
+                ap, DataSourceType.URL);
       }
 
     }
@@ -1206,11 +1161,10 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
     if (conservationMenuItem.getState())
     {
-
-      sg.cs.setConservation(Conservation.calculateConservation("Group", 3,
-              sg.getSequences(ap.av.getHiddenRepSequences()), 0, ap.av
-                      .getAlignment().getWidth(), false, ap.av
-                      .getConsPercGaps(), false));
+      sg.cs.setConservation(Conservation.calculateConservation("Group", sg
+              .getSequences(ap.av.getHiddenRepSequences()), 0, ap.av
+              .getAlignment().getWidth(), false, ap.av.getConsPercGaps(),
+              false));
       SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
       SliderPanel.showConservationSlider();
     }
index af91399..175b171 100644 (file)
@@ -49,7 +49,9 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.io.AnnotationFile;
 import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
 import jalview.io.FeaturesFile;
+import jalview.io.FileFormat;
 import jalview.io.TCoffeeScoreFile;
 import jalview.schemes.Blosum62ColourScheme;
 import jalview.schemes.BuriedColourScheme;
@@ -345,7 +347,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    *          is protocol for accessing data referred to by file
    */
 
-  public boolean parseFeaturesFile(String file, String type)
+  public boolean parseFeaturesFile(String file, DataSourceType type)
   {
     return parseFeaturesFile(file, type, true);
   }
@@ -355,14 +357,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    * 
    * @param file
    *          file URL, content, or other resolvable path
-   * @param type
+   * @param sourceType
    *          is protocol for accessing data referred to by file
    * @param autoenabledisplay
    *          when true, display features flag will be automatically enabled if
    *          features are loaded
    * @return true if data parsed as a features file
    */
-  public boolean parseFeaturesFile(String file, String type,
+  public boolean parseFeaturesFile(String file, DataSourceType sourceType,
           boolean autoenabledisplay)
   {
     boolean featuresFile = false;
@@ -372,7 +374,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
               .getFeatureRenderer().getFeatureColours();
       boolean relaxedIdMatching = viewport.applet.getDefaultParameter(
               "relaxedidmatch", false);
-      featuresFile = new FeaturesFile(file, type).parse(
+      featuresFile = new FeaturesFile(file, sourceType).parse(
               viewport.getAlignment(), colours, true, relaxedIdMatching);
     } catch (Exception ex)
     {
@@ -1356,13 +1358,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
     Frame frame = new Frame();
     frame.add(cap);
-    jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage(
+    JalviewLite.addFrame(frame, MessageManager.formatMessage(
             "label.alignment_output_command",
             new Object[] { e.getActionCommand() }), 600, 500);
 
-    FeatureRenderer fr = this.alignPanel.cloneFeatureRenderer();
+    FileFormat fileFormat = FileFormat.valueOf(e.getActionCommand());
     cap.setText(new AppletFormatAdapter(alignPanel).formatSequences(
-            e.getActionCommand(), viewport.getAlignment(),
+            fileFormat, viewport.getAlignment(),
             viewport.getShowJVSuffix()));
   }
 
@@ -3237,11 +3239,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     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++)
+    for (String ff : FileFormat.getWritableFormats(true))
     {
-
-      MenuItem item = new MenuItem(
-              jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i]);
+      MenuItem item = new MenuItem(ff);
 
       item.addActionListener(new java.awt.event.ActionListener()
       {
@@ -4019,7 +4019,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       }
       // resolve data source
       // TODO: this code should be a refactored to an io package
-      String protocol = AppletFormatAdapter.resolveProtocol(pdbFile, "PDB");
+      DataSourceType protocol = AppletFormatAdapter.resolveProtocol(
+              pdbFile, FileFormat.PDB);
       if (protocol == null)
       {
         return false;
@@ -4063,7 +4064,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   }
 
   public void newStructureView(JalviewLite applet, PDBEntry pdb,
-          SequenceI[] seqs, String[] chains, String protocol)
+          SequenceI[] seqs, String[] chains, DataSourceType protocol)
   {
     // Scrub any null sequences from the array
     Object[] sqch = cleanSeqChainArrays(seqs, chains);
@@ -4074,10 +4075,16 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       System.err
               .println("JalviewLite.AlignFrame:newStructureView: No sequence to bind structure to.");
     }
-    if (protocol == null || protocol.trim().length() == 0
-            || protocol.equals("null"))
+    if (protocol == null)
     {
-      protocol = (String) pdb.getProperty("protocol");
+      String sourceType = (String) pdb.getProperty("protocol");
+      try
+      {
+        protocol = DataSourceType.valueOf(sourceType);
+      } catch (IllegalArgumentException e)
+      {
+        // ignore
+      }
       if (protocol == null)
       {
         System.err.println("Couldn't work out protocol to open structure: "
@@ -4100,12 +4107,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     {
       // can only do alignments with Jmol
       // find the last jmol window assigned to this alignment
-      jalview.appletgui.AppletJmol ajm = null, tajm;
-      Vector jmols = applet
-              .getAppletWindow(jalview.appletgui.AppletJmol.class);
+      AppletJmol ajm = null, tajm;
+      Vector jmols = applet.getAppletWindow(AppletJmol.class);
       for (int i = 0, iSize = jmols.size(); i < iSize; i++)
       {
-        tajm = (jalview.appletgui.AppletJmol) jmols.elementAt(i);
+        tajm = (AppletJmol) jmols.elementAt(i);
         if (tajm.ap.alignFrame == this)
         {
           ajm = tajm;
@@ -4124,7 +4130,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     // otherwise, create a new window
     if (applet.jmolAvailable)
     {
-      new jalview.appletgui.AppletJmol(pdb, seqs, chains, alignPanel,
+      new AppletJmol(pdb, seqs, chains, alignPanel,
               protocol);
       applet.lastFrameX += 40;
       applet.lastFrameY += 40;
index e5178cb..4bd77b6 100644 (file)
@@ -28,6 +28,7 @@ import jalview.commands.CommandI;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -433,7 +434,7 @@ public class AlignViewport extends AlignmentViewport implements
      * there is no complement, or it is not following highlights, or no mapping
      * is found, the result will be empty.
      */
-    SearchResults sr = new SearchResults();
+    SearchResultsI sr = new SearchResults();
     int seqOffset = findComplementScrollTarget(sr);
     if (!sr.isEmpty())
     {
index 813ab84..e97c347 100644 (file)
@@ -25,7 +25,7 @@ import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.bin.JalviewLite;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceI;
 import jalview.structure.StructureSelectionManager;
 
@@ -293,7 +293,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    * Highlight the given results on the alignment.
    * 
    */
-  public void highlightSearchResults(SearchResults results)
+  public void highlightSearchResults(SearchResultsI results)
   {
     scrollToPosition(results);
     seqPanel.seqCanvas.highlightSearchResults(results);
@@ -306,7 +306,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    * @param results
    * @return false if results were not found
    */
-  public boolean scrollToPosition(SearchResults results)
+  public boolean scrollToPosition(SearchResultsI results)
   {
     return scrollToPosition(results, true);
   }
@@ -320,10 +320,10 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    *          - when set, the overview will be recalculated (takes longer)
    * @return false if results were not found
    */
-  public boolean scrollToPosition(SearchResults results,
+  public boolean scrollToPosition(SearchResultsI results,
           boolean redrawOverview)
   {
-    return scrollToPosition(results, redrawOverview, false);
+    return scrollToPosition(results, 0, redrawOverview, false);
   }
 
   /**
@@ -335,7 +335,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    *          - when set, the overview will be recalculated (takes longer)
    * @return false if results were not found
    */
-  public boolean scrollToPosition(SearchResults results,
+  public boolean scrollToPosition(SearchResultsI results,
+          int verticalOffset,
           boolean redrawOverview, boolean centre)
   {
     // do we need to scroll the panel?
@@ -347,6 +348,10 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
       {
         return false;
       }
+      /*
+       * allow for offset of target sequence (actually scroll to one above it)
+       */
+
       SequenceI seq = alignment.getSequenceAt(seqIndex);
       int[] r = results.getResults(seq, 0, alignment.getWidth());
       if (r == null)
@@ -391,6 +396,11 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
       {
         return false;
       }
+
+      /*
+       * allow for offset of target sequence (actually scroll to one above it)
+       */
+      seqIndex = Math.max(0, seqIndex - verticalOffset);
       return scrollTo(start, end, seqIndex, false, redrawOverview);
     }
     return true;
@@ -419,6 +429,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
     {
       start = ostart;
     }
+
     if (!av.getWrapAlignment())
     {
       /*
@@ -902,14 +913,14 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    * @param seqOffset
    *          the number of visible sequences to show above the mapped region
    */
-  protected void scrollToCentre(SearchResults sr, int seqOffset)
+  protected void scrollToCentre(SearchResultsI sr, int seqOffset)
   {
     /*
      * To avoid jumpy vertical scrolling (if some sequences are gapped or not
      * mapped), we can make the scroll-to location a sequence above the one
      * actually mapped.
      */
-    SequenceI mappedTo = sr.getResultSequence(0);
+    SequenceI mappedTo = sr.getResults().get(0).getSequence();
     List<SequenceI> seqs = av.getAlignment().getSequences();
 
     /*
@@ -931,16 +942,14 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
     {
       return; // failsafe, shouldn't happen
     }
-    sequenceIndex = Math.max(0, sequenceIndex - seqOffset);
-    sr.getResults().get(0)
-            .setSequence(av.getAlignment().getSequenceAt(sequenceIndex));
 
     /*
      * Scroll to position but centring the target residue. Also set a state flag
      * to prevent adjustmentValueChanged performing this recursively.
      */
     setFollowingComplementScroll(true);
-    scrollToPosition(sr, true, true);
+    // this should be scrollToPosition(sr,verticalOffset,
+    scrollToPosition(sr, seqOffset, true, true);
   }
 
   private void sendViewPosition()
index b925284..9d4779c 100644 (file)
  */
 package jalview.appletgui;
 
+import jalview.bin.JalviewLite;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
 import jalview.io.FileParse;
+import jalview.io.DataSourceType;
 import jalview.io.StructureFile;
 import jalview.schemes.BuriedColourScheme;
 import jalview.schemes.HelixColourScheme;
@@ -175,16 +176,16 @@ public class AppletJmol extends EmbmenuFrame implements
   }
 
   public AppletJmol(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
-          AlignmentPanel ap, String protocol)
+          AlignmentPanel ap, DataSourceType protocol)
   {
     this.ap = ap;
     jmb = new AppletJmolBinding(this, ap.getStructureSelectionManager(),
             new PDBEntry[] { pdbentry }, new SequenceI[][] { seq },
-            new String[][] { chains }, protocol);
+            protocol);
     jmb.setColourBySequence(true);
     if (pdbentry.getId() == null || pdbentry.getId().length() < 1)
     {
-      if (protocol.equals(AppletFormatAdapter.PASTE))
+      if (protocol == DataSourceType.PASTE)
       {
         pdbentry.setId("PASTED PDB"
                 + (chains == null ? "_" : chains.toString()));
@@ -195,7 +196,7 @@ public class AppletJmol extends EmbmenuFrame implements
       }
     }
 
-    if (jalview.bin.JalviewLite.debug)
+    if (JalviewLite.debug)
     {
       System.err
               .println("AppletJmol: PDB ID is '" + pdbentry.getId() + "'");
@@ -290,18 +291,18 @@ public class AppletJmol extends EmbmenuFrame implements
       }
     });
     pdbentry.setProperty("protocol", protocol);
-
     if (pdbentry.getFile() != null)
+    
     {
       // import structure data from pdbentry.getFile based on given protocol
-      if (protocol.equals(AppletFormatAdapter.PASTE))
+      if (protocol == DataSourceType.PASTE)
       {
         // TODO: JAL-623 : correctly record file contents for matching up later
         // pdbentry.getProperty().put("pdbfilehash",""+pdbentry.getFile().hashCode());
         loadInline(pdbentry.getFile());
       }
-      else if (protocol.equals(AppletFormatAdapter.FILE)
-              || protocol.equals(AppletFormatAdapter.URL))
+      else if (protocol == DataSourceType.FILE
+              || protocol == DataSourceType.URL)
       {
         jmb.viewer.openFile(pdbentry.getFile());
       }
@@ -369,7 +370,7 @@ public class AppletJmol extends EmbmenuFrame implements
     jmb.loadInline(string);
   }
 
-  void setChainMenuItems(Vector<String> chains)
+  void setChainMenuItems(List<String> chains)
   {
     chainMenu.removeAll();
 
@@ -588,7 +589,7 @@ public class AppletJmol extends EmbmenuFrame implements
       repaint();
       return;
     }
-    setChainMenuItems(jmb.chainNames);
+    setChainMenuItems(jmb.getChainNames());
     jmb.colourBySequence(ap);
 
     setTitle(jmb.getViewerTitle());
index 6ec5b4d..f938cad 100644 (file)
@@ -24,13 +24,12 @@ import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.io.DataSourceType;
 import jalview.structure.StructureSelectionManager;
 
 import java.awt.Container;
 import java.util.Map;
 
-import javajs.awt.Dimension;
-
 import org.jmol.api.JmolAppConsoleInterface;
 import org.jmol.console.AppletConsole;
 import org.jmol.java.BS;
@@ -45,9 +44,9 @@ class AppletJmolBinding extends JalviewJmolBinding
 
   public AppletJmolBinding(AppletJmol appletJmol,
           StructureSelectionManager sSm, PDBEntry[] pdbentry,
-          SequenceI[][] seq, String[][] chains, String protocol)
+          SequenceI[][] seq, DataSourceType protocol)
   {
-    super(sSm, pdbentry, seq, chains, protocol);
+    super(sSm, pdbentry, seq, protocol);
     appletJmolBinding = appletJmol;
   }
 
@@ -113,12 +112,14 @@ class AppletJmolBinding extends JalviewJmolBinding
     appletJmolBinding.updateTitleAndMenus();
   }
 
+  @Override
   public void updateColours(Object source)
   {
     AlignmentPanel ap = (AlignmentPanel) source;
     colourBySequence(ap);
   }
 
+  @Override
   public void showUrl(String url)
   {
     try
@@ -143,6 +144,7 @@ class AppletJmolBinding extends JalviewJmolBinding
     // do nothing.
   }
 
+  @Override
   public void selectionChanged(BS arg0)
   {
     // TODO Auto-generated method stub
@@ -183,7 +185,7 @@ class AppletJmolBinding extends JalviewJmolBinding
   }
 
   @Override
-  public Dimension resizeInnerPanel(String data)
+  public int[] resizeInnerPanel(String data)
   {
     // TODO Auto-generated method stub
     return null;
index bbaeb68..d50fcef 100644 (file)
@@ -28,9 +28,11 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.io.AlignmentFileI;
 import jalview.io.AnnotationFile;
 import jalview.io.AppletFormatAdapter;
-import jalview.io.FileParse;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormatI;
 import jalview.io.IdentifyFile;
 import jalview.io.NewickFile;
 import jalview.io.TCoffeeScoreFile;
@@ -51,6 +53,7 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
+import java.io.IOException;
 
 public class CutAndPasteTransfer extends Panel implements ActionListener,
         MouseListener
@@ -65,7 +68,7 @@ public class CutAndPasteTransfer extends Panel implements ActionListener,
 
   AlignFrame alignFrame;
 
-  FileParse source = null;
+  AlignmentFileI source = null;
 
   public CutAndPasteTransfer(boolean forImport, AlignFrame alignFrame)
   {
@@ -194,7 +197,8 @@ public class CutAndPasteTransfer extends Panel implements ActionListener,
   {
     try
     {
-      NewickFile fin = new NewickFile(textarea.getText(), "Paste");
+      NewickFile fin = new NewickFile(textarea.getText(),
+              DataSourceType.PASTE);
 
       fin.parse();
       if (fin.getTree() != null)
@@ -225,17 +229,14 @@ public class CutAndPasteTransfer extends Panel implements ActionListener,
   {
     AlignmentI al = null;
 
-    String format = new IdentifyFile().identify(text,
-            AppletFormatAdapter.PASTE);
-    AppletFormatAdapter afa = new AppletFormatAdapter(alignFrame.alignPanel);
     try
     {
-      al = afa.readFile(text, AppletFormatAdapter.PASTE, format);
+      FileFormatI format = new IdentifyFile().identify(text,
+              DataSourceType.PASTE);
+      AppletFormatAdapter afa = new AppletFormatAdapter(
+              alignFrame.alignPanel);
+      al = afa.readFile(text, DataSourceType.PASTE, format);
       source = afa.getAlignFile();
-    } catch (java.io.IOException ex)
-    {
-      ex.printStackTrace();
-    }
 
     if (al != null)
     {
@@ -296,6 +297,10 @@ public class CutAndPasteTransfer extends Panel implements ActionListener,
                 .getString("label.successfully_pasted_alignment_file"));
       }
     }
+    } catch (IOException ex)
+    {
+      ex.printStackTrace();
+    }
   }
 
   /**
@@ -306,7 +311,7 @@ public class CutAndPasteTransfer extends Panel implements ActionListener,
    * @param al
    * @return
    */
-  protected boolean openSplitFrame(AlignmentI al, String format)
+  protected boolean openSplitFrame(AlignmentI al, FileFormatI format)
   {
     final AlignmentI thisAlignment = this.alignFrame.getAlignViewport()
             .getAlignment();
@@ -376,7 +381,7 @@ public class CutAndPasteTransfer extends Panel implements ActionListener,
     try
     {
       tcf = new TCoffeeScoreFile(textarea.getText(),
-              jalview.io.AppletFormatAdapter.PASTE);
+              jalview.io.DataSourceType.PASTE);
       if (tcf.isValid())
       {
         if (tcf.annotateAlignment(alignFrame.viewport.getAlignment(), true))
@@ -409,7 +414,7 @@ public class CutAndPasteTransfer extends Panel implements ActionListener,
     if (tcf == null)
     {
       if (new AnnotationFile().annotateAlignmentView(alignFrame.viewport,
-              textarea.getText(), jalview.io.AppletFormatAdapter.PASTE))
+              textarea.getText(), jalview.io.DataSourceType.PASTE))
       {
         alignFrame.alignPanel.fontChanged();
         alignFrame.alignPanel.setScrollValues(0, 0);
@@ -421,7 +426,7 @@ public class CutAndPasteTransfer extends Panel implements ActionListener,
       else
       {
         if (!alignFrame.parseFeaturesFile(textarea.getText(),
-                jalview.io.AppletFormatAdapter.PASTE))
+                jalview.io.DataSourceType.PASTE))
         {
           alignFrame.statusBar
                   .setText(MessageManager
@@ -445,12 +450,12 @@ public class CutAndPasteTransfer extends Panel implements ActionListener,
     if (alignFrame.alignPanel.av.applet.jmolAvailable)
     {
       new jalview.appletgui.AppletJmol(pdb, new SequenceI[] { seq }, null,
-              alignFrame.alignPanel, AppletFormatAdapter.PASTE);
+              alignFrame.alignPanel, DataSourceType.PASTE);
     }
     else
     {
       new MCview.AppletPDBViewer(pdb, new SequenceI[] { seq }, null,
-              alignFrame.alignPanel, AppletFormatAdapter.PASTE);
+              alignFrame.alignPanel, DataSourceType.PASTE);
     }
   }
 
index 929a871..189fe88 100644 (file)
@@ -26,6 +26,7 @@ import jalview.api.SequenceRenderer;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.io.DataSourceType;
 
 import java.awt.Container;
 import java.util.ArrayList;
@@ -48,12 +49,12 @@ public class ExtJmol extends JalviewJmolBinding
 
   private AlignmentPanel ap;
 
-  protected ExtJmol(jalview.appletgui.AlignFrame alframe,
-          PDBEntry[] pdbentry, SequenceI[][] seq, String[][] chains,
-          String protocol)
+  protected ExtJmol(AlignFrame alframe,
+          PDBEntry[] pdbentry, SequenceI[][] seq,
+          DataSourceType protocol)
   {
     super(alframe.alignPanel.getStructureSelectionManager(), pdbentry, seq,
-            chains, protocol);
+            protocol);
   }
 
   public ExtJmol(Viewer viewer, AlignmentPanel alignPanel,
@@ -64,6 +65,7 @@ public class ExtJmol extends JalviewJmolBinding
     notifyFileLoaded(null, null, null, null, 0);
   }
 
+  @Override
   public void updateColours(Object source)
   {
 
@@ -71,6 +73,7 @@ public class ExtJmol extends JalviewJmolBinding
 
   }
 
+  @Override
   public void showUrl(String arg0)
   {
     showUrl(arg0, "jmol");
@@ -126,6 +129,7 @@ public class ExtJmol extends JalviewJmolBinding
     // ignore
   }
 
+  @Override
   public void selectionChanged(BS arg0)
   {
     System.out.println(arg0);
index 82736d7..2fca07d 100644 (file)
@@ -22,6 +22,7 @@ package jalview.appletgui;
 
 import jalview.api.FeatureColourI;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.io.FeaturesFile;
@@ -225,7 +226,7 @@ public class FeatureRenderer extends
             start.setText(features[index].getBegin() + "");
             end.setText(features[index].getEnd() + "");
 
-            SearchResults highlight = new SearchResults();
+            SearchResultsI highlight = new SearchResults();
             highlight.addResult(sequences[0], features[index].getBegin(),
                     features[index].getEnd());
 
index 75d9b9e..d2fe69c 100644 (file)
@@ -20,7 +20,8 @@
  */
 package jalview.appletgui;
 
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.util.MessageManager;
@@ -50,7 +51,7 @@ public class Finder extends Panel implements ActionListener
 
   Frame frame;
 
-  SearchResults searchResults;
+  SearchResultsI searchResults;
 
   int seqIndex = 0;
 
@@ -76,6 +77,7 @@ public class Finder extends Panel implements ActionListener
     frame.repaint();
     frame.addWindowListener(new WindowAdapter()
     {
+      @Override
       public void windowClosing(WindowEvent evt)
       {
         ap.highlightSearchResults(null);
@@ -84,6 +86,7 @@ public class Finder extends Panel implements ActionListener
     textfield.requestFocus();
   }
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     if (evt.getSource() == textfield)
@@ -114,13 +117,15 @@ public class Finder extends Panel implements ActionListener
     SequenceFeature[] features = new SequenceFeature[searchResults
             .getSize()];
 
-    for (int i = 0; i < searchResults.getSize(); i++)
+    int i = 0;
+    for (SearchResultMatchI match : searchResults.getResults())
     {
-      seqs[i] = searchResults.getResultSequence(i);
+      seqs[i] = match.getSequence().getDatasetSequence();
 
       features[i] = new SequenceFeature(textfield.getText().trim(),
-              "Search Results", null, searchResults.getResultStart(i),
-              searchResults.getResultEnd(i), "Search Results");
+              "Search Results", null, match.getStart(), match.getEnd(),
+              "Search Results");
+      i++;
     }
 
     if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
@@ -152,7 +157,7 @@ public class Finder extends Panel implements ActionListener
     seqIndex = finder.getSeqIndex();
     resIndex = finder.getResIndex();
     searchResults = finder.getSearchResults();
-    Vector idMatch = finder.getIdMatch();
+    Vector<SequenceI> idMatch = finder.getIdMatch();
     boolean haveResults = false;
     // set or reset the GUI
     if ((idMatch.size() > 0))
@@ -246,6 +251,7 @@ public class Finder extends Panel implements ActionListener
     textfield.setBounds(new Rectangle(40, 17, 133, 21));
     textfield.addKeyListener(new java.awt.event.KeyAdapter()
     {
+      @Override
       public void keyTyped(KeyEvent e)
       {
         textfield_keyTyped(e);
index ed96b55..182f20e 100755 (executable)
@@ -20,6 +20,9 @@
  */
 package jalview.appletgui;
 
+import static jalview.util.UrlConstants.EMBLEBI_STRING;
+import static jalview.util.UrlConstants.SRS_STRING;
+
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
@@ -82,19 +85,16 @@ public class IdPanel extends Panel implements MouseListener,
     }
     {
       // upgrade old SRS link
-      int srsPos = links
-              .indexOf("SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
+      int srsPos = links.indexOf(SRS_STRING);
       if (srsPos > -1)
       {
-        links.setElementAt(
-                "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$",
-                srsPos);
+        links.setElementAt(EMBLEBI_STRING, srsPos);
       }
     }
     if (links.size() < 1)
     {
       links = new java.util.Vector();
-      links.addElement("EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$");
+      links.addElement(EMBLEBI_STRING);
     }
   }
 
@@ -246,7 +246,14 @@ public class IdPanel extends Panel implements MouseListener,
         url = null;
         continue;
       }
-      ;
+
+      if (urlLink.usesDBAccession())
+      {
+        // this URL requires an accession id, not the name of a sequence
+        url = null;
+        continue;
+      }
+
       if (!urlLink.isValid())
       {
         System.err.println(urlLink.getInvalidMessage());
index 7216bfe..5d6bb07 100755 (executable)
@@ -21,7 +21,7 @@
 package jalview.appletgui;
 
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.renderer.ScaleRenderer;
@@ -50,8 +50,6 @@ public class SeqCanvas extends Panel
 
   AlignViewport av;
 
-  SearchResults searchResults = null;
-
   boolean fastPaint = false;
 
   int cursorX = 0;
@@ -632,9 +630,10 @@ public class SeqCanvas extends Panel
 
       // / Highlight search Results once all sequences have been drawn
       // ////////////////////////////////////////////////////////
-      if (searchResults != null)
+      if (av.hasSearchResults())
       {
-        int[] visibleResults = searchResults.getResults(nextSeq, startRes,
+        int[] visibleResults = av.getSearchResults().getResults(nextSeq,
+                startRes,
                 endRes);
         if (visibleResults != null)
         {
@@ -843,10 +842,9 @@ public class SeqCanvas extends Panel
     }
   }
 
-  public void highlightSearchResults(SearchResults results)
+  public void highlightSearchResults(SearchResultsI results)
   {
-    searchResults = results;
-
+    av.setSearchResults(results);
     repaint();
   }
 
index 6ca9499..8d6e683 100644 (file)
@@ -25,8 +25,9 @@ import jalview.commands.EditCommand;
 import jalview.commands.EditCommand.Action;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
@@ -458,7 +459,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
    * @param results
    * @return true if results were matched, false if not
    */
-  private boolean setStatusMessage(SearchResults results)
+  private boolean setStatusMessage(SearchResultsI results)
   {
     AlignmentI al = this.av.getAlignment();
     int sequenceIndex = al.findIndex(results);
@@ -467,7 +468,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       return false;
     }
     SequenceI ds = al.getSequenceAt(sequenceIndex).getDatasetSequence();
-    for (Match m : results.getResults())
+    for (SearchResultMatchI m : results.getResults())
     {
       SequenceI seq = m.getSequence();
       if (seq.getDatasetSequence() != null)
@@ -559,7 +560,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
       if (features != null && features.length > 0)
       {
-        SearchResults highlight = new SearchResults();
+        SearchResultsI highlight = new SearchResults();
         highlight.addResult(sequence, features[0].getBegin(),
                 features[0].getEnd());
         seqCanvas.highlightSearchResults(highlight);
@@ -731,7 +732,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
   }
 
   @Override
-  public void highlightSequence(SearchResults results)
+  public void highlightSequence(SearchResultsI results)
   {
     if (av.isFollowHighlight())
     {
index 3b509e5..8292a5a 100755 (executable)
@@ -676,8 +676,8 @@ public class TreeCanvas extends Panel implements MouseListener,
       if (av.getGlobalColourScheme() != null
               && av.getGlobalColourScheme().conservationApplied())
       {
-        Conservation c = new Conservation("Group", 3,
-                sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
+        Conservation c = new Conservation("Group", sg.getSequences(null),
+                sg.getStartRes(), sg.getEndRes());
 
         c.calculate();
         c.verdict(false, av.getConsPercGaps());
index 763b10b..39c0a5b 100755 (executable)
@@ -29,8 +29,11 @@ import jalview.gui.Desktop;
 import jalview.gui.PromptUserConfig;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.BioJsHTMLOutput;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatException;
+import jalview.io.FileFormatI;
 import jalview.io.FileLoader;
-import jalview.io.FormatAdapter;
 import jalview.io.HtmlSvgOutput;
 import jalview.io.IdentifyFile;
 import jalview.io.NewickFile;
@@ -51,6 +54,7 @@ import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.net.MalformedURLException;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.security.AllPermission;
 import java.security.CodeSource;
@@ -355,7 +359,9 @@ public class Jalview
       BioJsHTMLOutput.updateBioJS();
     }
 
-    String file = null, protocol = null, format = null, data = null;
+    String file = null, data = null;
+    FileFormatI format = null;
+    DataSourceType protocol = null;
     FileLoader fileLoader = new FileLoader(!headless);
     Vector<String> getFeatures = null; // vector of das source nicknames to
                                        // fetch
@@ -388,13 +394,13 @@ public class Jalview
       {
         try
         {
-          String viprotocol = AppletFormatAdapter
+          DataSourceType viprotocol = AppletFormatAdapter
                   .checkProtocol(vamsasImport);
-          if (viprotocol == jalview.io.FormatAdapter.FILE)
+          if (viprotocol == DataSourceType.FILE)
           {
             inSession = desktop.vamsasImport(new File(vamsasImport));
           }
-          else if (viprotocol == FormatAdapter.URL)
+          else if (viprotocol == DataSourceType.URL)
           {
             inSession = desktop.vamsasImport(new URL(vamsasImport));
           }
@@ -483,7 +489,13 @@ public class Jalview
 
       protocol = AppletFormatAdapter.checkProtocol(file);
 
-      format = new IdentifyFile().identify(file, protocol);
+      try
+      {
+        format = new IdentifyFile().identify(file, protocol);
+      } catch (FileFormatException e1)
+      {
+        // TODO ?
+      }
 
       AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
               format);
@@ -628,17 +640,17 @@ public class Jalview
         String imageName = "unnamed.png";
         while (aparser.getSize() > 1)
         {
-          format = aparser.nextValue();
+          String outputFormat = aparser.nextValue();
           file = aparser.nextValue();
 
-          if (format.equalsIgnoreCase("png"))
+          if (outputFormat.equalsIgnoreCase("png"))
           {
             af.createPNG(new File(file));
             imageName = (new File(file)).getName();
             System.out.println("Creating PNG image: " + file);
             continue;
           }
-          else if (format.equalsIgnoreCase("svg"))
+          else if (outputFormat.equalsIgnoreCase("svg"))
           {
             File imageFile = new File(file);
             imageName = imageFile.getName();
@@ -646,21 +658,44 @@ public class Jalview
             System.out.println("Creating SVG image: " + file);
             continue;
           }
-          else if (format.equalsIgnoreCase("html"))
+          else if (outputFormat.equalsIgnoreCase("html"))
           {
             File imageFile = new File(file);
             imageName = imageFile.getName();
-            new HtmlSvgOutput(new File(file), af.alignPanel);
+            HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
+            htmlSVG.exportHTML(file);
+
             System.out.println("Creating HTML image: " + file);
             continue;
           }
-          else if (format.equalsIgnoreCase("imgMap"))
+          else if (outputFormat.equalsIgnoreCase("biojsmsa"))
+          {
+            if (file == null)
+            {
+              System.err.println("The output html file must not be null");
+              return;
+            }
+            try
+            {
+              BioJsHTMLOutput
+                      .refreshVersionInfo(BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
+            } catch (URISyntaxException e)
+            {
+              e.printStackTrace();
+            }
+            BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
+            bjs.exportHTML(file);
+            System.out.println("Creating BioJS MSA Viwer HTML file: "
+                    + file);
+            continue;
+          }
+          else if (outputFormat.equalsIgnoreCase("imgMap"))
           {
             af.createImageMap(new File(file), imageName);
             System.out.println("Creating image map: " + file);
             continue;
           }
-          else if (format.equalsIgnoreCase("eps"))
+          else if (outputFormat.equalsIgnoreCase("eps"))
           {
             File outputFile = new File(file);
             System.out.println("Creating EPS file: "
@@ -709,20 +744,26 @@ public class Jalview
         jalview.bin.Cache.removeProperty("STARTUP_FILE");
       }
 
-      protocol = "File";
+      protocol = DataSourceType.FILE;
 
       if (file.indexOf("http:") > -1)
       {
-        protocol = "URL";
+        protocol = DataSourceType.URL;
       }
 
       if (file.endsWith(".jar"))
       {
-        format = "Jalview";
+        format = FileFormat.Jalview;
       }
       else
       {
-        format = new IdentifyFile().identify(file, protocol);
+        try
+        {
+          format = new IdentifyFile().identify(file, protocol);
+        } catch (FileFormatException e)
+        {
+          // TODO what?
+        }
       }
 
       startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
@@ -789,6 +830,7 @@ public class Jalview
                     + "-png FILE\tCreate PNG image FILE from alignment.\n"
                     + "-svg FILE\tCreate SVG image FILE from alignment.\n"
                     + "-html FILE\tCreate HTML file from alignment.\n"
+                    + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
                     + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
                     + "-eps FILE\tCreate EPS file FILE from alignment.\n"
                     + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
index a3b2b0b..de011ea 100644 (file)
@@ -37,6 +37,9 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.io.AnnotationFile;
 import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
 import jalview.io.FileParse;
 import jalview.io.IdentifyFile;
 import jalview.io.JPredFile;
@@ -63,6 +66,7 @@ import java.awt.event.ActionEvent;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.io.BufferedReader;
+import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.URL;
 import java.util.ArrayList;
@@ -513,21 +517,23 @@ public class JalviewLite extends Applet implements
   {
     try
     {
+      FileFormatI theFormat = FileFormat.valueOf(format);
       boolean seqlimits = suffix.equalsIgnoreCase(TRUE);
       if (alf.viewport.getSelectionGroup() != null)
       {
         // JBPNote: getSelectionAsNewSequence behaviour has changed - this
         // method now returns a full copy of sequence data
         // TODO consider using getSequenceSelection instead here
-        String reply = new AppletFormatAdapter().formatSequences(format,
+        String reply = new AppletFormatAdapter().formatSequences(theFormat,
                 new Alignment(alf.viewport.getSelectionAsNewSequence()),
                 seqlimits);
         return reply;
       }
-    } catch (Exception ex)
+    } catch (IllegalArgumentException ex)
     {
       ex.printStackTrace();
-      return "Error retrieving alignment in " + format + " format. ";
+      return "Error retrieving alignment, possibly invalid format specifier: "
+              + format;
     }
     return "";
   }
@@ -709,13 +715,15 @@ public class JalviewLite extends Applet implements
     {
       boolean seqlimits = suffix.equalsIgnoreCase(TRUE);
 
-      String reply = new AppletFormatAdapter().formatSequences(format,
+      FileFormatI theFormat = FileFormat.valueOf(format);
+      String reply = new AppletFormatAdapter().formatSequences(theFormat,
               alf.viewport.getAlignment(), seqlimits);
       return reply;
-    } catch (Exception ex)
+    } catch (IllegalArgumentException ex)
     {
       ex.printStackTrace();
-      return "Error retrieving alignment in " + format + " format. ";
+      return "Error retrieving alignment, possibly invalid format specifier: "
+              + format;
     }
   }
 
@@ -741,14 +749,14 @@ public class JalviewLite extends Applet implements
   public void loadAnnotationFrom(AlignFrame alf, String annotation)
   {
     if (new AnnotationFile().annotateAlignmentView(alf.getAlignViewport(),
-            annotation, AppletFormatAdapter.PASTE))
+            annotation, DataSourceType.PASTE))
     {
       alf.alignPanel.fontChanged();
       alf.alignPanel.setScrollValues(0, 0);
     }
     else
     {
-      alf.parseFeaturesFile(annotation, AppletFormatAdapter.PASTE);
+      alf.parseFeaturesFile(annotation, DataSourceType.PASTE);
     }
   }
 
@@ -774,7 +782,7 @@ public class JalviewLite extends Applet implements
   public boolean loadFeaturesFrom(AlignFrame alf, String features,
           boolean autoenabledisplay)
   {
-    return alf.parseFeaturesFile(features, AppletFormatAdapter.PASTE,
+    return alf.parseFeaturesFile(features, DataSourceType.PASTE,
             autoenabledisplay);
   }
 
@@ -882,17 +890,17 @@ public class JalviewLite extends Applet implements
   {
     AlignmentI al = null;
 
-    String format = new IdentifyFile().identify(text,
-            AppletFormatAdapter.PASTE);
     try
     {
-      al = new AppletFormatAdapter().readFile(text,
-              AppletFormatAdapter.PASTE, format);
+      FileFormatI format = new IdentifyFile().identify(text,
+              DataSourceType.PASTE);
+      al = new AppletFormatAdapter().readFile(text, DataSourceType.PASTE,
+              format);
       if (al.getHeight() > 0)
       {
         return new AlignFrame(al, this, title, false);
       }
-    } catch (java.io.IOException ex)
+    } catch (IOException ex)
     {
       ex.printStackTrace();
     }
@@ -1818,7 +1826,7 @@ public class JalviewLite extends Applet implements
     /**
      * State variable: protocol for access to file source
      */
-    String protocol;
+    DataSourceType protocol;
 
     String _file; // alignment file or URL spec
 
@@ -1848,7 +1856,7 @@ public class JalviewLite extends Applet implements
        */
       if (path.startsWith("PASTE"))
       {
-        protocol = AppletFormatAdapter.PASTE;
+        protocol = DataSourceType.PASTE;
         return path.substring(5);
       }
 
@@ -1857,7 +1865,7 @@ public class JalviewLite extends Applet implements
        */
       if (path.indexOf("://") != -1)
       {
-        protocol = AppletFormatAdapter.URL;
+        protocol = DataSourceType.URL;
         return path;
       }
 
@@ -1873,7 +1881,7 @@ public class JalviewLite extends Applet implements
           System.err.println("Prepended document base '" + documentBase
                   + "' to make: '" + withDocBase + "'");
         }
-        protocol = AppletFormatAdapter.URL;
+        protocol = DataSourceType.URL;
         return withDocBase;
       }
 
@@ -1886,7 +1894,7 @@ public class JalviewLite extends Applet implements
       if (!withCodeBase.equals(withDocBase)
               && HttpUtils.isValidUrl(withCodeBase))
       {
-        protocol = AppletFormatAdapter.URL;
+        protocol = DataSourceType.URL;
         if (debug)
         {
           System.err.println("Prepended codebase '" + codeBase
@@ -1901,7 +1909,7 @@ public class JalviewLite extends Applet implements
        */
       if (inArchive(path))
       {
-        protocol = AppletFormatAdapter.CLASSLOADER;
+        protocol = DataSourceType.CLASSLOADER;
       }
       return path;
     }
@@ -2015,11 +2023,12 @@ public class JalviewLite extends Applet implements
         return null;
       }
       String resolvedFile = resolveFileProtocol(fileParam);
-      String format = new IdentifyFile().identify(resolvedFile, protocol);
-      dbgMsg("File identified as '" + format + "'");
       AlignmentI al = null;
       try
       {
+        FileFormatI format = new IdentifyFile().identify(resolvedFile,
+                protocol);
+        dbgMsg("File identified as '" + format + "'");
         al = new AppletFormatAdapter().readFile(resolvedFile, protocol,
                 format);
         if ((al != null) && (al.getHeight() > 0))
@@ -2036,7 +2045,7 @@ public class JalviewLite extends Applet implements
           // update the focus.
           currentAlignFrame = newAlignFrame;
 
-          if (protocol == AppletFormatAdapter.PASTE)
+          if (protocol == DataSourceType.PASTE)
           {
             newAlignFrame.setTitle(MessageManager.formatMessage(
                     "label.sequences_from", new Object[] { applet
@@ -2207,8 +2216,7 @@ public class JalviewLite extends Applet implements
             }
             else
             {
-              pdbs.addElement(new Object[] { pdb, seqs, chains,
-                  new String(protocol) });
+              pdbs.addElement(new Object[] { pdb, seqs, chains, protocol });
             }
           }
         }
index fd88028..156e146 100644 (file)
@@ -22,7 +22,11 @@ package jalview.bin;
 
 import jalview.datamodel.AlignmentI;
 import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
 import jalview.io.FileParse;
+import jalview.io.IdentifyFile;
 
 import java.applet.Applet;
 import java.io.InputStream;
@@ -45,6 +49,7 @@ public class JalviewLiteURLRetrieve extends Applet
    * 
    * @return void
    */
+  @Override
   public void init()
   {
     this.setSize(300, 200);
@@ -55,7 +60,7 @@ public class JalviewLiteURLRetrieve extends Applet
               .println("Specify a resource to read on the file parameter");
       return;
     }
-    String protocol = null;
+    DataSourceType protocol = null;
     try
     {
       System.out.println("Loading thread started with:\n>>file\n" + file
@@ -75,7 +80,7 @@ public class JalviewLiteURLRetrieve extends Applet
                 + (rtn ? "" : "not") + " located by classloader.");
         if (rtn)
         {
-          protocol = AppletFormatAdapter.CLASSLOADER;
+          protocol = DataSourceType.CLASSLOADER;
         }
 
       } catch (Exception ex)
@@ -85,12 +90,12 @@ public class JalviewLiteURLRetrieve extends Applet
       }
       if (file.indexOf("://") > -1)
       {
-        protocol = AppletFormatAdapter.URL;
+        protocol = DataSourceType.URL;
       }
       else
       {
         // skipping codebase prepend check.
-        protocol = AppletFormatAdapter.FILE;
+        protocol = DataSourceType.FILE;
       }
 
       System.out.println("Trying to get contents of resource:");
@@ -110,10 +115,10 @@ public class JalviewLiteURLRetrieve extends Applet
                 + " cannot be read with protocol==" + protocol);
         return;
       }
-      String format = getParameter("format");
-      if (format == null || format.length() == 0)
+      FileFormatI format = FileFormat.valueOf(getParameter("format"));
+      if (format == null)
       {
-        format = new jalview.io.IdentifyFile().identify(file, protocol);
+        format = new IdentifyFile().identify(file, protocol);
         System.out.println("Format is " + format);
       }
       else
@@ -132,7 +137,7 @@ public class JalviewLiteURLRetrieve extends Applet
       if (al != null)
       {
         System.out.println(new AppletFormatAdapter().formatSequences(
-                "FASTA", al, false));
+                FileFormat.Fasta, al, false));
       }
     } catch (Exception e)
     {
index f508bc3..bc7f212 100644 (file)
@@ -33,6 +33,7 @@ import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
 import jalview.io.FeaturesFile;
 import jalview.util.MessageManager;
 
@@ -243,10 +244,6 @@ public class AlignViewController implements AlignViewControllerI
         SequenceFeature[] sfs = sq.getSequenceFeatures();
         if (sfs != null)
         {
-          /*
-           * check whether the feature start/end (base 1) 
-           * overlaps the selection start/end
-           */
           int ist = sq.findIndex(sq.getStart());
           int iend = sq.findIndex(sq.getEnd());
           if (iend < startPosition || ist > endPosition)
@@ -264,29 +261,54 @@ public class AlignViewController implements AlignViewControllerI
               // - findIndex wastes time by starting from first character and
               // counting
 
-              int i = sq.findIndex(sf.getBegin());
-              int j = sq.findIndex(sf.getEnd());
-              if (j < startPosition || i > endPosition)
+              int sfStartCol = sq.findIndex(sf.getBegin());
+              int sfEndCol = sq.findIndex(sf.getEnd());
+
+              if (sf.isContactFeature())
+              {
+                /*
+                 * 'contact' feature - check for 'start' or 'end'
+                 * position within the selected region
+                 */
+                if (sfStartCol >= startPosition
+                        && sfStartCol <= endPosition)
+                {
+                  bs.set(sfStartCol - 1);
+                  sequenceHasFeature = true;
+                }
+                if (sfEndCol >= startPosition && sfEndCol <= endPosition)
+                {
+                  bs.set(sfEndCol - 1);
+                  sequenceHasFeature = true;
+                }
+                continue;
+              }
+
+              /*
+               * contiguous feature - select feature positions (if any) 
+               * within the selected region
+               */
+              if (sfStartCol > endPosition || sfEndCol < startPosition)
               {
                 // feature is outside selected region
                 continue;
               }
               sequenceHasFeature = true;
-              if (i < startPosition)
+              if (sfStartCol < startPosition)
               {
-                i = startPosition;
+                sfStartCol = startPosition;
               }
-              if (i < ist)
+              if (sfStartCol < ist)
               {
-                i = ist;
+                sfStartCol = ist;
               }
-              if (j > endPosition)
+              if (sfEndCol > endPosition)
               {
-                j = endPosition;
+                sfEndCol = endPosition;
               }
-              for (; i <= j; i++)
+              for (; sfStartCol <= sfEndCol; sfStartCol++)
               {
-                bs.set(i - 1); // convert to base 0
+                bs.set(sfStartCol - 1); // convert to base 0
               }
             }
           }
@@ -349,7 +371,7 @@ public class AlignViewController implements AlignViewControllerI
   }
 
   @Override
-  public boolean parseFeaturesFile(String file, String protocol,
+  public boolean parseFeaturesFile(String file, DataSourceType protocol,
           boolean relaxedIdMatching)
   {
     boolean featuresFile = false;
@@ -381,4 +403,66 @@ public class AlignViewController implements AlignViewControllerI
     return featuresFile;
 
   }
+
+  @Override
+  public boolean markHighlightedColumns(boolean invert,
+          boolean extendCurrent, boolean toggle)
+  {
+    if (!viewport.hasSearchResults())
+    {
+      // do nothing if no selection exists
+      return false;
+    }
+    // JBPNote this routine could also mark rows, not just columns.
+    BitSet bs = new BitSet();
+    SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null || extendCurrent) ? viewport
+            .getAlignment() : viewport.getSelectionGroup();
+
+    // this could be a lambda... - the remains of the method is boilerplate,
+    // except for the different messages for reporting selection.
+    int nseq = viewport.getSearchResults().markColumns(sqcol, bs);
+
+    ColumnSelection cs = viewport.getColumnSelection();
+    if (cs == null)
+    {
+      cs = new ColumnSelection();
+    }
+
+    if (bs.cardinality() > 0 || invert)
+    {
+      boolean changed = cs.markColumns(bs, sqcol.getStartRes(),
+              sqcol.getEndRes(), invert, extendCurrent, toggle);
+      if (changed)
+      {
+        viewport.setColumnSelection(cs);
+        alignPanel.paintAlignment(true);
+        int columnCount = invert ? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
+                - bs.cardinality()
+                : bs.cardinality();
+        avcg.setStatus(MessageManager.formatMessage(
+                "label.view_controller_toggled_marked",
+                new String[] {
+                    toggle ? MessageManager.getString("label.toggled")
+                            : MessageManager.getString("label.marked"),
+                    String.valueOf(columnCount),
+                    invert ? MessageManager
+                            .getString("label.not_containing")
+                            : MessageManager.getString("label.containing"),
+                    "Highlight", Integer.valueOf(nseq).toString() }));
+        return true;
+      }
+    }
+    else
+    {
+      avcg.setStatus(MessageManager
+              .formatMessage("No highlighted regions marked"));
+      if (!extendCurrent)
+      {
+        cs.clear();
+        alignPanel.paintAlignment(true);
+      }
+    }
+    return false;
+  }
+
 }
index c5204eb..4fbfd62 100644 (file)
@@ -301,7 +301,7 @@ public class AlignedCodonFrame
    *          where highlighted regions go
    */
   public void markMappedRegion(SequenceI seq, int index,
-          SearchResults results)
+          SearchResultsI results)
   {
     int[] codon;
     SequenceI ds = seq.getDatasetSequence();
index 2289ac6..d651c1d 100755 (executable)
@@ -661,7 +661,7 @@ public class Alignment implements AlignmentI
    * jalview.datamodel.AlignmentI#findIndex(jalview.datamodel.SearchResults)
    */
   @Override
-  public int findIndex(SearchResults results)
+  public int findIndex(SearchResultsI results)
   {
     int i = 0;
 
@@ -1837,7 +1837,7 @@ public class Alignment implements AlignmentI
   @Override
   public String toString()
   {
-    return new FastaFile().print(getSequencesArray());
+    return new FastaFile().print(getSequencesArray(), true);
   }
 
   /**
index 1d37fa6..7274e5f 100755 (executable)
@@ -426,7 +426,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param results
    * @return -1 or index of sequence in alignment
    */
-  int findIndex(SearchResults results);
+  int findIndex(SearchResultsI results);
 
   /**
    * append sequences and annotation from another alignment object to this one.
index 6a6ccd0..8debacf 100755 (executable)
@@ -46,7 +46,38 @@ public class PDBEntry
 
   public enum Type
   {
-    PDB, MMCIF, FILE;
+    // TODO is FILE needed; if not is this enum needed, or can we
+    // use FileFormatI for PDB, MMCIF?
+    PDB("pdb", "pdb"), MMCIF("mmcif", "cif"), FILE("?", "?");
+
+    /*
+     * file extension for cached structure file; must be one that
+     * is recognised by Chimera 'open' command
+     * @see https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/filetypes.html
+     */
+    String ext;
+
+    /*
+     * format specifier used in dbfetch request
+     * @see http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/dbfetch.databases#pdb
+     */
+    String format;
+
+    private Type(String fmt, String ex)
+    {
+      format = fmt;
+      ext = ex;
+    }
+
+    public String getFormat()
+    {
+      return format;
+    }
+    public String getExtension()
+    {
+      return ext;
+    }
+
     /**
      * case insensitive matching for Type enum
      * 
@@ -77,7 +108,6 @@ public class PDBEntry
     }
   }
 
-
   /**
    * Answers true if obj is a PDBEntry with the same id and chain code (both
    * ignoring case), file, type and properties
@@ -121,16 +151,6 @@ public class PDBEntry
   {
   }
 
-  /**
-   * Constructor given file path and PDB id.
-   * 
-   * @param filePath
-   */
-  // public PDBEntry(String filePath, String pdbId)
-  // {
-  // this.file = filePath;
-  // this.id = pdbId;
-  // }
 
   public PDBEntry(String pdbId, String chain, PDBEntry.Type type,
           String filePath)
diff --git a/src/jalview/datamodel/Profile.java b/src/jalview/datamodel/Profile.java
new file mode 100644 (file)
index 0000000..1501808
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.datamodel;
+
+
+/**
+ * A profile for one column of an alignment
+ * 
+ * @author gmcarstairs
+ *
+ */
+public class Profile implements ProfileI
+{
+  /*
+   * an object holding counts of symbols in the profile
+   */
+  private ResidueCount counts;
+
+  /*
+   * the number of sequences (gapped or not) in the profile
+   */
+  private int height;
+
+  /*
+   * the number of non-gapped sequences in the profile
+   */
+  private int gapped;
+
+  /*
+   * the highest count for any residue in the profile
+   */
+  private int maxCount;
+
+  /*
+   * the residue (e.g. K) or residues (e.g. KQW) with the
+   * highest count in the profile
+   */
+  private String modalResidue;
+
+  /**
+   * Constructor which allows derived data to be stored without having to store
+   * the full profile
+   * 
+   * @param seqCount
+   *          the number of sequences in the profile
+   * @param gaps
+   *          the number of gapped sequences
+   * @param max
+   *          the highest count for any residue
+   * @param modalres
+   *          the residue (or concatenated residues) with the highest count
+   */
+  public Profile(int seqCount, int gaps, int max, String modalRes)
+  {
+    this.height = seqCount;
+    this.gapped = gaps;
+    this.maxCount = max;
+    this.modalResidue = modalRes;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#setCounts(jalview.datamodel.ResidueCount)
+   */
+  @Override
+  public void setCounts(ResidueCount residueCounts)
+  {
+    this.counts = residueCounts;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getPercentageIdentity(boolean)
+   */
+  @Override
+  public float getPercentageIdentity(boolean ignoreGaps)
+  {
+    if (height == 0)
+    {
+      return 0f;
+    }
+    float pid = 0f;
+    if (ignoreGaps && gapped < height)
+    {
+      pid = (maxCount * 100f) / (height - gapped);
+    }
+    else
+    {
+      pid = (maxCount * 100f) / height;
+    }
+    return pid;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getCounts()
+   */
+  @Override
+  public ResidueCount getCounts()
+  {
+    return counts;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getHeight()
+   */
+  @Override
+  public int getHeight()
+  {
+    return height;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getGapped()
+   */
+  @Override
+  public int getGapped()
+  {
+    return gapped;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getMaxCount()
+   */
+  @Override
+  public int getMaxCount()
+  {
+    return maxCount;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getModalResidue()
+   */
+  @Override
+  public String getModalResidue()
+  {
+    return modalResidue;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getNonGapped()
+   */
+  @Override
+  public int getNonGapped()
+  {
+    return height - gapped;
+  }
+}
diff --git a/src/jalview/datamodel/ProfileI.java b/src/jalview/datamodel/ProfileI.java
new file mode 100644 (file)
index 0000000..65a5c0d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.datamodel;
+
+public interface ProfileI
+{
+
+  /**
+   * Set the full profile of counts
+   * 
+   * @param residueCounts
+   */
+  public abstract void setCounts(ResidueCount residueCounts);
+
+  /**
+   * Returns the percentage identity of the profile, i.e. the highest proportion
+   * of conserved (equal) symbols. The percentage is as a fraction of all
+   * sequences, or only ungapped sequences if flag ignoreGaps is set true.
+   * 
+   * @param ignoreGaps
+   * @return
+   */
+  public abstract float getPercentageIdentity(boolean ignoreGaps);
+
+  /**
+   * Returns the full symbol counts for this profile
+   * 
+   * @return
+   */
+  public abstract ResidueCount getCounts();
+
+  /**
+   * Returns the number of sequences in the profile
+   * 
+   * @return
+   */
+  public abstract int getHeight();
+
+  /**
+   * Returns the number of sequences in the profile which had a gap character
+   * (or were too short to be included in this column's profile)
+   * 
+   * @return
+   */
+  public abstract int getGapped();
+
+  /**
+   * Returns the highest count for any symbol(s) in the profile
+   * 
+   * @return
+   */
+  public abstract int getMaxCount();
+
+  /**
+   * Returns the symbol (or concatenated symbols) which have the highest count
+   * in the profile, or an empty string if there were no symbols counted
+   * 
+   * @return
+   */
+  public abstract String getModalResidue();
+
+  /**
+   * Answers the number of non-gapped sequences in the profile
+   * 
+   * @return
+   */
+  public abstract int getNonGapped();
+
+}
\ No newline at end of file
diff --git a/src/jalview/datamodel/Profiles.java b/src/jalview/datamodel/Profiles.java
new file mode 100644 (file)
index 0000000..f65830a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.datamodel;
+
+public class Profiles implements ProfilesI
+{
+
+  private ProfileI[] profiles;
+
+  public Profiles(ProfileI[] p)
+  {
+    profiles = p;
+  }
+
+  /**
+   * Returns the profile for the given column, or null if none found
+   * 
+   * @param col
+   */
+  @Override
+  public ProfileI get(int col)
+  {
+    return profiles != null && col >= 0 && col < profiles.length ? profiles[col]
+            : null;
+  }
+
+  /**
+   * Returns the first column (base 0) covered by the profiles
+   */
+  @Override
+  public int getStartColumn()
+  {
+    return 0;
+  }
+
+  /**
+   * Returns the last column (base 0) covered by the profiles
+   */
+  @Override
+  public int getEndColumn()
+  {
+    return profiles == null ? 0 : profiles.length - 1;
+  }
+
+}
diff --git a/src/jalview/datamodel/ProfilesI.java b/src/jalview/datamodel/ProfilesI.java
new file mode 100644 (file)
index 0000000..82398d9
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.datamodel;
+
+public interface ProfilesI
+{
+
+  ProfileI get(int i);
+
+  int getStartColumn();
+
+  int getEndColumn();
+
+}
diff --git a/src/jalview/datamodel/ResidueCount.java b/src/jalview/datamodel/ResidueCount.java
new file mode 100644 (file)
index 0000000..3e3a966
--- /dev/null
@@ -0,0 +1,641 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.datamodel;
+
+import jalview.util.Comparison;
+import jalview.util.Format;
+import jalview.util.QuickSort;
+import jalview.util.SparseCount;
+
+/**
+ * A class to count occurrences of residues in a profile, optimised for speed
+ * and memory footprint.
+ * @author gmcarstairs
+ *
+ */
+public class ResidueCount
+{
+  /**
+   * A data bean to hold the results of counting symbols
+   */
+  public class SymbolCounts
+  {
+    /**
+     * the symbols seen (as char values), in no particular order
+     */
+    public final char[] symbols;
+
+    /**
+     * the counts for each symbol, in the same order as the symbols
+     */
+    public final int[] values;
+
+    SymbolCounts(char[] s, int[] v)
+    {
+      symbols = s;
+      values = v;
+    }
+  }
+
+  private static final int TOUPPERCASE = 'A' - 'a';
+
+  /*
+   * nucleotide symbols to count (including N unknown)
+   */
+  private static final String NUCS = "ACGNTU";
+
+  /*
+   * amino acid symbols to count (including X unknown)
+   * NB we also include U so as to support counting of RNA bases
+   * in the "don't know" case of nucleotide / peptide
+   */
+  private static final String AAS = "ACDEFGHIKLMNPQRSTUVWXY";
+
+  private static final int GAP_COUNT = 0;
+
+  /*
+   * fast lookup tables holding the index into our count
+   * arrays of each symbol; index 0 is reserved for gap counting
+   */
+  private static int[] NUC_INDEX = new int[26];
+
+  private static int[] AA_INDEX = new int[26];
+  static
+  {
+    for (int i = 0; i < NUCS.length(); i++)
+    {
+      NUC_INDEX[NUCS.charAt(i) - 'A'] = i + 1;
+    }
+    for (int i = 0; i < AAS.length(); i++)
+    {
+      AA_INDEX[AAS.charAt(i) - 'A'] = i + 1;
+    }
+  }
+
+  /*
+   * counts array, just big enough for the nucleotide or peptide
+   * character set (plus gap counts in position 0)
+   */
+  private short[] counts;
+
+  /*
+   * alternative array of int counts for use if any count 
+   * exceeds the maximum value of short (32767)
+   */
+  private int[] intCounts;
+
+  /*
+   * flag set if we switch from short to int counts
+   */
+  private boolean useIntCounts;
+
+  /*
+   * general-purpose counter, only for use for characters
+   * that are not in the expected alphabet
+   */
+  private SparseCount otherData;
+
+  /*
+   * keeps track of the maximum count value recorded
+   * (if this class ever allows decrements, would need to
+   * calculate this on request instead) 
+   */
+  int maxCount;
+
+  /*
+   * if we think we are counting nucleotide, can get by with smaller
+   * array to hold counts
+   */
+  private boolean isNucleotide;
+
+  /**
+   * Default constructor allocates arrays able to count either nucleotide or
+   * peptide bases. Use this constructor if not sure which the data is.
+   */
+  public ResidueCount()
+  {
+    this(false);
+  }
+
+  /**
+   * Constructor that allocates an array just big enough for the anticipated
+   * characters, plus one position to count gaps
+   */
+  public ResidueCount(boolean nucleotide)
+  {
+    isNucleotide = nucleotide;
+    int charsToCount = nucleotide ? NUCS.length() : AAS.length();
+    counts = new short[charsToCount + 1];
+  }
+
+  /**
+   * Increments the count for the given character. The supplied character may be
+   * upper or lower case but counts are for the upper case only. Gap characters
+   * (space, ., -) are all counted together.
+   * 
+   * @param c
+   * @return the new value of the count for the character
+   */
+  public int add(final char c)
+  {
+    char u = toUpperCase(c);
+    int newValue = 0;
+    int offset = getOffset(u);
+
+    /*
+     * offset 0 is reserved for gap counting, so 0 here means either
+     * an unexpected character, or a gap character passed in error
+     */
+    if (offset == 0)
+    {
+      if (Comparison.isGap(u))
+      {
+        newValue = addGap();
+      }
+      else
+      {
+        newValue = addOtherCharacter(u);
+      }
+    }
+    else
+    {
+      newValue = increment(offset);
+    }
+    return newValue;
+  }
+
+  /**
+   * Increment the count at the specified offset. If this would result in short
+   * overflow, promote to counting int values instead.
+   * 
+   * @param offset
+   * @return the new value of the count at this offset
+   */
+  int increment(int offset)
+  {
+    int newValue = 0;
+    if (useIntCounts)
+    {
+      newValue = intCounts[offset];
+      intCounts[offset] = ++newValue;
+    }
+    else
+    {
+      if (counts[offset] == Short.MAX_VALUE)
+      {
+        handleOverflow();
+        newValue = intCounts[offset];
+        intCounts[offset] = ++newValue;
+      }
+      else
+      {
+        newValue = counts[offset];
+        counts[offset] = (short) ++newValue;
+      }
+    }
+    maxCount = Math.max(maxCount, newValue);
+    return newValue;
+  }
+
+  /**
+   * Switch from counting in short to counting in int
+   */
+  synchronized void handleOverflow()
+  {
+    intCounts = new int[counts.length];
+    for (int i = 0; i < counts.length; i++)
+    {
+      intCounts[i] = counts[i];
+    }
+    counts = null;
+    useIntCounts = true;
+  }
+
+  /**
+   * Returns this character's offset in the count array
+   * 
+   * @param c
+   * @return
+   */
+  int getOffset(char c)
+  {
+    int offset = 0;
+    if ('A' <= c && c <= 'Z')
+    {
+      offset = isNucleotide ? NUC_INDEX[c - 'A'] : AA_INDEX[c - 'A'];
+    }
+    return offset;
+  }
+
+  /**
+   * @param c
+   * @return
+   */
+  protected char toUpperCase(final char c)
+  {
+    char u = c;
+    if ('a' <= c && c <= 'z')
+    {
+      u = (char) (c + TOUPPERCASE);
+    }
+    return u;
+  }
+
+  /**
+   * Increment count for some unanticipated character. The first time this
+   * called, a SparseCount is instantiated to hold these 'extra' counts.
+   * 
+   * @param c
+   * @return the new value of the count for the character
+   */
+  int addOtherCharacter(char c)
+  {
+    if (otherData == null)
+    {
+      otherData = new SparseCount();
+    }
+    int newValue = otherData.add(c, 1);
+    maxCount = Math.max(maxCount, newValue);
+    return newValue;
+  }
+
+  /**
+   * Set count for some unanticipated character. The first time this called, a
+   * SparseCount is instantiated to hold these 'extra' counts.
+   * 
+   * @param c
+   * @param value
+   */
+  void setOtherCharacter(char c, int value)
+  {
+    if (otherData == null)
+    {
+      otherData = new SparseCount();
+    }
+    otherData.put(c, value);
+  }
+
+  /**
+   * Increment count of gap characters
+   * 
+   * @return the new count of gaps
+   */
+  public int addGap()
+  {
+    int newValue;
+    if (useIntCounts)
+    {
+      newValue = ++intCounts[GAP_COUNT];
+    }
+    else
+    {
+      newValue = ++counts[GAP_COUNT];
+    }
+    return newValue;
+  }
+
+  /**
+   * Answers true if we are counting ints (only after overflow of short counts)
+   * 
+   * @return
+   */
+  boolean isCountingInts()
+  {
+    return useIntCounts;
+  }
+
+  /**
+   * Sets the count for the given character. The supplied character may be upper
+   * or lower case but counts are for the upper case only.
+   * 
+   * @param c
+   * @param count
+   */
+  public void put(char c, int count)
+  {
+    char u = toUpperCase(c);
+    int offset = getOffset(u);
+
+    /*
+     * offset 0 is reserved for gap counting, so 0 here means either
+     * an unexpected character, or a gap character passed in error
+     */
+    if (offset == 0)
+    {
+      if (Comparison.isGap(u))
+      {
+        set(0, count);
+      }
+      else
+      {
+        setOtherCharacter(u, count);
+        maxCount = Math.max(maxCount, count);
+      }
+    }
+    else
+    {
+      set(offset, count);
+      maxCount = Math.max(maxCount, count);
+    }
+  }
+
+  /**
+   * Sets the count at the specified offset. If this would result in short
+   * overflow, promote to counting int values instead.
+   * 
+   * @param offset
+   * @param value
+   */
+  void set(int offset, int value)
+  {
+    if (useIntCounts)
+    {
+      intCounts[offset] = value;
+    }
+    else
+    {
+      if (value > Short.MAX_VALUE || value < Short.MIN_VALUE)
+      {
+        handleOverflow();
+        intCounts[offset] = value;
+      }
+      else
+      {
+        counts[offset] = (short) value;
+      }
+    }
+  }
+
+  /**
+   * Returns the count for the given character, or zero if no count held
+   * 
+   * @param c
+   * @return
+   */
+  public int getCount(char c)
+  {
+    char u = toUpperCase(c);
+    int offset = getOffset(u);
+    if (offset == 0)
+    {
+      if (!Comparison.isGap(u))
+      {
+        // should have called getGapCount()
+        return otherData == null ? 0 : otherData.get(u);
+      }
+    }
+    return useIntCounts ? intCounts[offset] : counts[offset];
+  }
+
+  public int getGapCount()
+  {
+    return useIntCounts ? intCounts[0] : counts[0];
+  }
+
+  /**
+   * Answers true if this object wraps a counter for unexpected characters
+   * 
+   * @return
+   */
+  boolean isUsingOtherData()
+  {
+    return otherData != null;
+  }
+
+  /**
+   * Returns the character (or concatenated characters) for the symbol(s) with
+   * the given count in the profile. Can be used to get the modal residue by
+   * supplying the modal count value. Returns an empty string if no symbol has
+   * the given count. The symbols are in alphabetic order of standard peptide or
+   * nucleotide characters, followed by 'other' symbols if any.
+   * 
+   * @return
+   */
+  public String getResiduesForCount(int count)
+  {
+    if (count == 0)
+    {
+      return "";
+    }
+
+    /*
+     * find counts for the given value and append the
+     * corresponding symbol
+     */
+    StringBuilder modal = new StringBuilder();
+    if (useIntCounts)
+    {
+      for (int i = 1; i < intCounts.length; i++)
+      {
+        if (intCounts[i] == count)
+        {
+          modal.append(isNucleotide ? NUCS.charAt(i - 1) : AAS
+                  .charAt(i - 1));
+        }
+      }
+    }
+    else
+    {
+      for (int i = 1; i < counts.length; i++)
+      {
+        if (counts[i] == count)
+        {
+          modal.append(isNucleotide ? NUCS.charAt(i - 1) : AAS
+                  .charAt(i - 1));
+        }
+      }
+    }
+    if (otherData != null)
+    {
+      for (int i = 0; i < otherData.size(); i++)
+      {
+        if (otherData.valueAt(i) == count)
+        {
+          modal.append((char) otherData.keyAt(i));
+        }
+      }
+    }
+    return modal.toString();
+  }
+
+  /**
+   * Returns the highest count for any symbol(s) in the profile (excluding gap)
+   * 
+   * @return
+   */
+  public int getModalCount()
+  {
+    return maxCount;
+  }
+
+  /**
+   * Returns the number of distinct symbols with a non-zero count (excluding the
+   * gap symbol)
+   * 
+   * @return
+   */
+  public int size() {
+    int size = 0;
+    if (useIntCounts)
+    {
+      for (int i = 1; i < intCounts.length; i++)
+      {
+        if (intCounts[i] > 0)
+        {
+          size++;
+        }
+      }
+    }
+    else
+    {
+      for (int i = 1; i < counts.length; i++)
+      {
+        if (counts[i] > 0)
+        {
+          size++;
+        }
+      }
+    }
+
+    /*
+     * include 'other' characters recorded (even if count is zero
+     * though that would be a strange use case)
+     */
+    if (otherData != null)
+    {
+      size += otherData.size();
+    }
+
+    return size;
+  }
+
+  /**
+   * Returns a data bean holding those symbols that have a non-zero count
+   * (excluding the gap symbol), with their counts.
+   * 
+   * @return
+   */
+  public SymbolCounts getSymbolCounts()
+  {
+    int size = size();
+    char[] symbols = new char[size];
+    int[] values = new int[size];
+    int j = 0;
+
+    if (useIntCounts)
+    {
+      for (int i = 1; i < intCounts.length; i++)
+      {
+        if (intCounts[i] > 0)
+        {
+          char symbol = isNucleotide ? NUCS.charAt(i - 1) : AAS
+                  .charAt(i - 1);
+          symbols[j] = symbol;
+          values[j] = intCounts[i];
+          j++;
+        }
+      }
+    }
+    else
+    {
+      for (int i = 1; i < counts.length; i++)
+      {
+        if (counts[i] > 0)
+        {
+          char symbol = isNucleotide ? NUCS.charAt(i - 1) : AAS
+                  .charAt(i - 1);
+          symbols[j] = symbol;
+          values[j] = counts[i];
+          j++;
+        }
+      }
+    }
+    if (otherData != null)
+    {
+      for (int i = 0; i < otherData.size(); i++)
+      {
+        symbols[j] = (char) otherData.keyAt(i);
+        values[j] = otherData.valueAt(i);
+        j++;
+      }
+    }
+
+    return new SymbolCounts(symbols, values);
+  }
+
+  /**
+   * Returns a tooltip string showing residues in descending order of their
+   * percentage frequency in the profile
+   * 
+   * @param normaliseBy
+   *          the divisor for residue counts (may or may not include gapped
+   *          sequence count)
+   * @param percentageDecPl
+   *          the number of decimal places to show in percentages
+   * @return
+   */
+  public String getTooltip(int normaliseBy, int percentageDecPl)
+  {
+    SymbolCounts symbolCounts = getSymbolCounts();
+    char[] ca = symbolCounts.symbols;
+    int[] vl = symbolCounts.values;
+
+    /*
+     * sort characters into ascending order of their counts
+     */
+    QuickSort.sort(vl, ca);
+
+    /*
+     * traverse in reverse order (highest count first) to build tooltip
+     */
+    boolean first = true;
+    StringBuilder sb = new StringBuilder(64);
+    for (int c = ca.length - 1; c >= 0; c--)
+    {
+      final char residue = ca[c];
+      // TODO combine residues which share a percentage
+      // (see AAFrequency.completeCdnaConsensus)
+      float tval = (vl[c] * 100f) / normaliseBy;
+      sb.append(first ? "" : "; ").append(residue).append(" ");
+      Format.appendPercentage(sb, tval, percentageDecPl);
+      sb.append("%");
+      first = false;
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Returns a string representation of the symbol counts, for debug purposes.
+   */
+  @Override
+  public String toString()
+  {
+    StringBuilder sb = new StringBuilder();
+    sb.append("[ ");
+    SymbolCounts sc = getSymbolCounts();
+    for (int i = 0; i < sc.symbols.length; i++)
+    {
+      sb.append(sc.symbols[i]).append(":").append(sc.values[i]).append(" ");
+    }
+    sb.append("]");
+    return sb.toString();
+  }
+}
diff --git a/src/jalview/datamodel/SearchResultMatchI.java b/src/jalview/datamodel/SearchResultMatchI.java
new file mode 100644 (file)
index 0000000..a47ca8b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.datamodel;
+
+/**
+ * An interface that describes one matched region of an alignment, as one
+ * contiguous portion of a single dataset sequence
+ */
+public interface SearchResultMatchI
+{
+  /**
+   * Returns the matched sequence
+   * 
+   * @return
+   */
+  SequenceI getSequence();
+
+  /**
+   * Returns the start position of the match in the sequence (base 1)
+   * 
+   * @return
+   */
+  int getStart();
+
+  /**
+   * Returns the end position of the match in the sequence (base 1)
+   * 
+   * @return
+   */
+  int getEnd();
+
+}
\ No newline at end of file
index b9db461..1bf5475 100755 (executable)
 package jalview.datamodel;
 
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.BitSet;
 import java.util.List;
 
 /**
  * Holds a list of search result matches, where each match is a contiguous
  * stretch of a single sequence.
  * 
- * @author gmcarstairs
+ * @author gmcarstairs amwaterhouse
  *
  */
-public class SearchResults
+public class SearchResults implements SearchResultsI
 {
 
-  private List<Match> matches = new ArrayList<Match>();
+  private List<SearchResultMatchI> matches = new ArrayList<SearchResultMatchI>();
 
   /**
    * One match consists of a sequence reference, start and end positions.
    * Discontiguous ranges in a sequence require two or more Match objects.
    */
-  public class Match
+  public class Match implements SearchResultMatchI
   {
     SequenceI sequence;
 
@@ -55,7 +55,10 @@ public class SearchResults
     int end;
 
     /**
-     * Constructor
+     * create a Match on a range of sequence. Match always holds region in
+     * forwards order, even if given in reverse order (such as from a mapping to
+     * a reverse strand); this avoids trouble for routines that highlight search
+     * results etc
      * 
      * @param seq
      *          a sequence
@@ -80,48 +83,54 @@ public class SearchResults
       }
       else
       {
+        // TODO: JBP could mark match as being specified in reverse direction
+        // for use
+        // by caller ? e.g. visualizing reverse strand highlight
         this.start = end;
         this.end = start;
       }
     }
 
+    /* (non-Javadoc)
+     * @see jalview.datamodel.SearchResultMatchI#getSequence()
+     */
+    @Override
     public SequenceI getSequence()
     {
       return sequence;
     }
 
+    /* (non-Javadoc)
+     * @see jalview.datamodel.SearchResultMatchI#getStart()
+     */
+    @Override
     public int getStart()
     {
       return start;
     }
 
+    /* (non-Javadoc)
+     * @see jalview.datamodel.SearchResultMatchI#getEnd()
+     */
+    @Override
     public int getEnd()
     {
       return end;
     }
 
     /**
-     * Returns the string of characters in the matched region, prefixed by the
-     * start position, e.g. "12CGT" or "208K"
+     * Returns a representation as "seqid/start-end"
      */
     @Override
     public String toString()
     {
-      final int from = Math.max(start - 1, 0);
-      String startPosition = String.valueOf(from);
-      return startPosition + getCharacters();
-    }
-
-    /**
-     * Returns the string of characters in the matched region.
-     */
-    public String getCharacters()
-    {
-      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));
+      StringBuilder sb = new StringBuilder();
+      if (sequence != null)
+      {
+        sb.append(sequence.getName()).append("/");
+      }
+      sb.append(start).append("-").append(end);
+      return sb.toString();
     }
 
     public void setSequence(SequenceI seq)
@@ -150,46 +159,38 @@ public class SearchResults
     @Override
     public boolean equals(Object obj)
     {
-      if (obj == null || !(obj instanceof Match))
+      if (obj == null || !(obj instanceof SearchResultMatchI))
       {
         return false;
       }
-      Match m = (Match) obj;
-      return (this.sequence == m.sequence && this.start == m.start && this.end == m.end);
+      SearchResultMatchI m = (SearchResultMatchI) obj;
+      return (sequence == m.getSequence() && start == m.getStart() && end == m
+              .getEnd());
     }
   }
 
-  /**
-   * This method replaces the old search results which merely held an alignment
-   * index of search matches. This broke when sequences were moved around the
-   * alignment
-   * 
-   * @param seq
-   *          Sequence
-   * @param start
-   *          int
-   * @param end
-   *          int
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#addResult(jalview.datamodel.SequenceI, int, int)
    */
-  public void addResult(SequenceI seq, int start, int end)
+  @Override
+  public SearchResultMatchI addResult(SequenceI seq, int start, int end)
   {
-    matches.add(new Match(seq, start, end));
+    Match m = new Match(seq, start, end);
+    matches.add(m);
+    return m;
   }
 
-  /**
-   * Quickly check if the given sequence is referred to in the search results
-   * 
-   * @param sequence
-   *          (specific alignment sequence or a dataset sequence)
-   * @return true if the results involve sequence
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#involvesSequence(jalview.datamodel.SequenceI)
    */
+  @Override
   public boolean involvesSequence(SequenceI sequence)
   {
     SequenceI ds = sequence.getDatasetSequence();
-    for (Match m : matches)
+    for (SearchResultMatchI _m : matches)
     {
-      if (m.sequence != null
-              && (m.sequence == sequence || m.sequence == ds))
+      SequenceI matched = _m.getSequence();
+      if (matched != null && (matched == sequence || matched == ds))
       {
         return true;
       }
@@ -197,11 +198,10 @@ public class SearchResults
     return false;
   }
 
-  /**
-   * This Method returns the search matches which lie between the start and end
-   * points of the sequence in question. It is optimised for returning objects
-   * for drawing on SequenceCanvas
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#getResults(jalview.datamodel.SequenceI, int, int)
    */
+  @Override
   public int[] getResults(SequenceI sequence, int start, int end)
   {
     if (matches.isEmpty())
@@ -213,8 +213,11 @@ public class SearchResults
     int[] tmp = null;
     int resultLength, matchStart = 0, matchEnd = 0;
     boolean mfound;
-    for (Match m : matches)
+    Match m;
+    for (SearchResultMatchI _m : matches)
     {
+      m = (Match) _m;
+
       mfound = false;
       if (m.sequence == sequence)
       {
@@ -269,97 +272,76 @@ public class SearchResults
     return result;
   }
 
-  public int getSize()
-  {
-    return matches.size();
-  }
-
-  public SequenceI getResultSequence(int index)
-  {
-    return matches.get(index).sequence;
-  }
-
-  /**
-   * Returns the start position of the i'th match in the search results.
-   * 
-   * @param i
-   * @return
-   */
-  public int getResultStart(int i)
+  @Override
+  public int markColumns(SequenceCollectionI sqcol, BitSet bs)
   {
-    return matches.get(i).start;
+    int count = 0;
+    BitSet mask = new BitSet();
+    for (SequenceI s : sqcol.getSequences())
+    {
+      int[] cols = getResults(s, sqcol.getStartRes(), sqcol.getEndRes());
+      if (cols != null)
+      {
+        for (int pair = 0; pair < cols.length; pair += 2)
+        {
+          mask.set(cols[pair], cols[pair + 1] + 1);
+        }
+      }
+    }
+    // compute columns that were newly selected
+    BitSet original = (BitSet) bs.clone();
+    original.and(mask);
+    count = mask.cardinality() - original.cardinality();
+    // and mark ranges not already marked
+    bs.or(mask);
+    return count;
   }
 
-  /**
-   * Returns the end position of the i'th match in the search results.
-   * 
-   * @param i
-   * @return
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#getSize()
    */
-  public int getResultEnd(int i)
+  @Override
+  public int getSize()
   {
-    return matches.get(i).end;
+    return matches.size();
   }
 
-  /**
-   * Returns true if no search result matches are held.
-   * 
-   * @return
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#isEmpty()
    */
+  @Override
   public boolean isEmpty()
   {
     return matches.isEmpty();
   }
 
-  /**
-   * Returns the list of matches.
-   * 
-   * @return
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#getResults()
    */
-  public List<Match> getResults()
+  @Override
+  public List<SearchResultMatchI> getResults()
   {
     return matches;
   }
 
   /**
-   * Return the results as a string of characters (bases) prefixed by start
-   * position(s). Meant for use when the context ensures that all matches are to
-   * regions of the same sequence (otherwise the result is meaningless).
+   * Return the results as a list of matches [seq1/from-to, seq2/from-to, ...]
    * 
    * @return
    */
   @Override
   public String toString()
   {
-    StringBuilder result = new StringBuilder(256);
-    for (Match m : matches)
-    {
-      result.append(m.toString());
-    }
-    return result.toString();
-  }
-
-  /**
-   * Return the results as a string of characters (bases). Meant for use when
-   * the context ensures that all matches are to regions of the same sequence
-   * (otherwise the result is meaningless).
-   * 
-   * @return
-   */
-  public String getCharacters()
-  {
-    StringBuilder result = new StringBuilder(256);
-    for (Match m : matches)
-    {
-      result.append(m.getCharacters());
-    }
-    return result.toString();
+    return matches == null ? "" : matches.toString();
   }
 
   /**
-   * Hashcode is has derived from the list of matches. This ensures that when
-   * two SearchResults objects satisfy the test for equals(), then they have the
+   * Hashcode is derived from the list of matches. This ensures that when two
+   * SearchResults objects satisfy the test for equals(), then they have the
    * same hashcode.
+   * 
+   * @see Match#hashCode()
+   * @see java.util.AbstractList#hashCode()
    */
   @Override
   public int hashCode()
@@ -374,11 +356,11 @@ public class SearchResults
   @Override
   public boolean equals(Object obj)
   {
-    if (obj == null || !(obj instanceof SearchResults))
+    if (obj == null || !(obj instanceof SearchResultsI))
     {
       return false;
     }
-    SearchResults sr = (SearchResults) obj;
-    return ((ArrayList<Match>) this.matches).equals(sr.matches);
+    SearchResultsI sr = (SearchResultsI) obj;
+    return matches.equals(sr.getResults());
   }
 }
diff --git a/src/jalview/datamodel/SearchResultsI.java b/src/jalview/datamodel/SearchResultsI.java
new file mode 100644 (file)
index 0000000..52a0467
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.datamodel;
+
+import java.util.BitSet;
+import java.util.List;
+
+/**
+ * An interface describing the result of a search or other operation which
+ * highlights matched regions of an alignment
+ */
+public interface SearchResultsI
+{
+
+  /**
+   * Adds one region to the results
+   * 
+   * @param seq
+   *          Sequence
+   * @param start
+   *          int
+   * @param end
+   *          int
+   * @return
+   */
+  SearchResultMatchI addResult(SequenceI seq, int start, int end);
+
+  /**
+   * Answers true if the search results include the given sequence (or its
+   * dataset sequence), else false
+   * 
+   * @param sequence
+   * @return
+   */
+  boolean involvesSequence(SequenceI sequence);
+
+  /**
+   * Returns an array of [from, to, from, to..] matched columns (base 0) between
+   * the given start and end columns of the given sequence. Returns null if no
+   * matches overlap the specified region.
+   * <p>
+   * Implementations should provide an optimised method to return locations to
+   * highlight on a visible portion of an alignment.
+   * 
+   * @param sequence
+   * @param start
+   *          first column of range (base 0, inclusive)
+   * @param end
+   *          last column of range base 0, inclusive)
+   * @return int[]
+   */
+  int[] getResults(SequenceI sequence, int start, int end);
+
+  /**
+   * Returns the number of matches found
+   * 
+   * @return
+   */
+  int getSize();
+
+  /**
+   * Returns true if no search result matches are held.
+   * 
+   * @return
+   */
+  boolean isEmpty();
+
+  /**
+   * Returns the list of matches.
+   * 
+   * @return
+   */
+  List<SearchResultMatchI> getResults();
+
+  /**
+   * Set bits in a bitfield for all columns in the given sequence collection
+   * that are highlighted
+   * 
+   * @param sqcol
+   *          the set of sequences to search for highlighted regions
+   * @param bs
+   *          bitset to set
+   * @return number of bits set
+   */
+  int markColumns(SequenceCollectionI sqcol, BitSet bs);
+}
\ No newline at end of file
index c75d6f2..15f54b9 100755 (executable)
@@ -208,7 +208,9 @@ public class SequenceFeature
     }
 
     SequenceFeature sf = (SequenceFeature) o;
-    if (begin != sf.begin || end != sf.end || score != sf.score)
+    boolean sameScore = Float.isNaN(score) ? Float.isNaN(sf.score)
+            : score == sf.score;
+    if (begin != sf.begin || end != sf.end || !sameScore)
     {
       return false;
     }
@@ -530,4 +532,20 @@ public class SequenceFeature
     return s.hashCode() + getBegin() + getEnd() + (int) getScore()
             + getStrand();
   }
+
+  /**
+   * Answers true if the feature's start/end values represent two related
+   * positions, rather than ends of a range. Such features may be visualised or
+   * reported differently to features on a range.
+   */
+  public boolean isContactFeature()
+  {
+    // TODO abstract one day to a FeatureType class
+    if ("disulfide bond".equalsIgnoreCase(type)
+            || "disulphide bond".equalsIgnoreCase(type))
+    {
+      return true;
+    }
+    return false;
+  }
 }
index 9a408e3..9245761 100755 (executable)
@@ -26,10 +26,8 @@ import jalview.schemes.ColourSchemeI;
 
 import java.awt.Color;
 import java.util.ArrayList;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
 
 /**
  * Collects a set contiguous ranges on a set of sequences
@@ -45,8 +43,6 @@ public class SequenceGroup implements AnnotatedCollectionI
 
   Conservation conserve;
 
-  Vector aaFrequency;
-
   boolean displayBoxes = true;
 
   boolean displayText = true;
@@ -531,7 +527,7 @@ public class SequenceGroup implements AnnotatedCollectionI
     boolean upd = false;
     try
     {
-      Hashtable cnsns[] = AAFrequency.calculate(sequences, startRes,
+      ProfilesI cnsns = AAFrequency.calculate(sequences, startRes,
               endRes + 1, showSequenceLogo);
       if (consensus != null)
       {
@@ -547,8 +543,8 @@ public class SequenceGroup implements AnnotatedCollectionI
       if ((conservation != null)
               || (cs != null && cs.conservationApplied()))
       {
-        Conservation c = new Conservation(groupName, 3, sequences,
-                startRes, endRes + 1);
+        Conservation c = new Conservation(groupName, sequences, startRes,
+                endRes + 1);
         c.calculate();
         c.verdict(false, consPercGaps);
         if (conservation != null)
@@ -603,9 +599,9 @@ public class SequenceGroup implements AnnotatedCollectionI
     c.completeAnnotations(conservation, null, startRes, endRes + 1);
   }
 
-  public Hashtable[] consensusData = null;
+  public ProfilesI consensusData = null;
 
-  private void _updateConsensusRow(Hashtable[] cnsns, long nseq)
+  private void _updateConsensusRow(ProfilesI cnsns, long nseq)
   {
     if (consensus == null)
     {
diff --git a/src/jalview/ext/android/ContainerHelpers.java b/src/jalview/ext/android/ContainerHelpers.java
new file mode 100644 (file)
index 0000000..4033dcc
--- /dev/null
@@ -0,0 +1,108 @@
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copied to Jalview September 2016.
+ * Only the members of this class required for SparseIntArray were copied.
+ * Method binarySearch(short[] array, int size, short value) added to support
+ * SparseShortArray.
+ */
+class ContainerHelpers
+{
+  static final boolean[] EMPTY_BOOLEANS = new boolean[0];
+
+  static final int[] EMPTY_INTS = new int[0];
+
+  static final long[] EMPTY_LONGS = new long[0];
+
+  static final Object[] EMPTY_OBJECTS = new Object[0];
+
+  // This is Arrays.binarySearch(), but doesn't do any argument validation.
+  static int binarySearch(int[] array, int size, int value)
+  {
+    int lo = 0;
+    int hi = size - 1;
+    while (lo <= hi)
+    {
+      final int mid = (lo + hi) >>> 1;
+      final int midVal = array[mid];
+      if (midVal < value)
+      {
+        lo = mid + 1;
+      }
+      else if (midVal > value)
+      {
+        hi = mid - 1;
+      }
+      else
+      {
+        return mid; // value found
+      }
+    }
+    return ~lo; // value not present
+  }
+
+  static int binarySearch(long[] array, int size, long value)
+  {
+    int lo = 0;
+    int hi = size - 1;
+    while (lo <= hi)
+    {
+      final int mid = (lo + hi) >>> 1;
+      final long midVal = array[mid];
+      if (midVal < value)
+      {
+        lo = mid + 1;
+      }
+      else if (midVal > value)
+      {
+        hi = mid - 1;
+      }
+      else
+      {
+        return mid; // value found
+      }
+    }
+    return ~lo; // value not present
+  }
+
+  // This is Arrays.binarySearch(), but doesn't do any argument validation.
+  static int binarySearch(short[] array, int size, short value)
+  {
+    int lo = 0;
+    int hi = size - 1;
+    while (lo <= hi)
+    {
+      final int mid = (lo + hi) >>> 1;
+      final short midVal = array[mid];
+      if (midVal < value)
+      {
+        lo = mid + 1;
+      }
+      else if (midVal > value)
+      {
+        hi = mid - 1;
+      }
+      else
+      {
+        return mid; // value found
+      }
+    }
+    return ~lo; // value not present
+  }
+}
diff --git a/src/jalview/ext/android/SparseIntArray.java b/src/jalview/ext/android/SparseIntArray.java
new file mode 100644 (file)
index 0000000..fcd4f1f
--- /dev/null
@@ -0,0 +1,432 @@
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * SparseIntArrays map integers to integers. Unlike a normal array of integers,
+ * there can be gaps in the indices. It is intended to be more memory efficient
+ * than using a HashMap to map Integers to Integers, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra
+ * entry object for each mapping.
+ *
+ * <p>
+ * Note that this container keeps its mappings in an array data structure, using
+ * a binary search to find keys. The implementation is not intended to be
+ * appropriate for data structures that may contain large numbers of items. It
+ * is generally slower than a traditional HashMap, since lookups require a
+ * binary search and adds and removes require inserting and deleting entries in
+ * the array. For containers holding up to hundreds of items, the performance
+ * difference is not significant, less than 50%.
+ * </p>
+ *
+ * <p>
+ * It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.
+ * </p>
+ */
+
+/*
+ * Imported into Jalview September 2016
+ * Change log:
+ *   Sep 2016 method add(int, int) added for more efficient increment of counts
+ *            (a single binary search, rather than one on read and one on write)
+ */
+public class SparseIntArray implements Cloneable
+{
+  private int[] mKeys;
+
+  private int[] mValues;
+
+  private int mSize;
+
+  /**
+   * Creates a new SparseIntArray containing no mappings.
+   */
+  public SparseIntArray()
+  {
+    this(10);
+  }
+
+  /**
+   * Creates a new SparseIntArray containing no mappings that will not require
+   * any additional memory allocation to store the specified number of mappings.
+   * If you supply an initial capacity of 0, the sparse array will be
+   * initialized with a light-weight representation not requiring any additional
+   * array allocations.
+   */
+  public SparseIntArray(int initialCapacity)
+  {
+    if (initialCapacity == 0)
+    {
+      mKeys = ContainerHelpers.EMPTY_INTS;
+      mValues = ContainerHelpers.EMPTY_INTS;
+    }
+    else
+    {
+      initialCapacity = idealIntArraySize(initialCapacity);
+      mKeys = new int[initialCapacity];
+      mValues = new int[initialCapacity];
+    }
+    mSize = 0;
+  }
+
+  @Override
+  public SparseIntArray clone()
+  {
+    SparseIntArray clone = null;
+    try
+    {
+      clone = (SparseIntArray) super.clone();
+      clone.mKeys = mKeys.clone();
+      clone.mValues = mValues.clone();
+    } catch (CloneNotSupportedException cnse)
+    {
+      /* ignore */
+    }
+    return clone;
+  }
+
+  /**
+   * Gets the int mapped from the specified key, or <code>0</code> if no such
+   * mapping has been made.
+   */
+  public int get(int key)
+  {
+    return get(key, 0);
+  }
+
+  /**
+   * Gets the int mapped from the specified key, or the specified value if no
+   * such mapping has been made.
+   */
+  public int get(int key, int valueIfKeyNotFound)
+  {
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+    if (i < 0)
+    {
+      return valueIfKeyNotFound;
+    }
+    else
+    {
+      return mValues[i];
+    }
+  }
+
+  /**
+   * Removes the mapping from the specified key, if there was any.
+   */
+  public void delete(int key)
+  {
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+    if (i >= 0)
+    {
+      removeAt(i);
+    }
+  }
+
+  /**
+   * Removes the mapping at the given index.
+   */
+  public void removeAt(int index)
+  {
+    System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+    System.arraycopy(mValues, index + 1, mValues, index, mSize
+            - (index + 1));
+    mSize--;
+  }
+
+  /**
+   * Adds a mapping from the specified key to the specified value, replacing the
+   * previous mapping from the specified key if there was one.
+   */
+  public void put(int key, int value)
+  {
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+    if (i >= 0)
+    {
+      mValues[i] = value;
+    }
+    else
+    {
+      i = ~i;
+      if (mSize >= mKeys.length)
+      {
+        int n = idealIntArraySize(mSize + 1);
+        int[] nkeys = new int[n];
+        int[] nvalues = new int[n];
+        // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
+        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+        mKeys = nkeys;
+        mValues = nvalues;
+      }
+      if (mSize - i != 0)
+      {
+        // Log.e("SparseIntArray", "move " + (mSize - i));
+        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+      }
+      mKeys[i] = key;
+      mValues[i] = value;
+      mSize++;
+    }
+  }
+
+  /**
+   * Returns the number of key-value mappings that this SparseIntArray currently
+   * stores.
+   */
+  public int size()
+  {
+    return mSize;
+  }
+
+  /**
+   * Given an index in the range <code>0...size()-1</code>, returns the key from
+   * the <code>index</code>th key-value mapping that this SparseIntArray stores.
+   *
+   * <p>
+   * The keys corresponding to indices in ascending order are guaranteed to be
+   * in ascending order, e.g., <code>keyAt(0)</code> will return the smallest
+   * key and <code>keyAt(size()-1)</code> will return the largest key.
+   * </p>
+   */
+  public int keyAt(int index)
+  {
+    return mKeys[index];
+  }
+
+  /**
+   * Given an index in the range <code>0...size()-1</code>, returns the value
+   * from the <code>index</code>th key-value mapping that this SparseIntArray
+   * stores.
+   *
+   * <p>
+   * The values corresponding to indices in ascending order are guaranteed to be
+   * associated with keys in ascending order, e.g., <code>valueAt(0)</code> will
+   * return the value associated with the smallest key and
+   * <code>valueAt(size()-1)</code> will return the value associated with the
+   * largest key.
+   * </p>
+   */
+  public int valueAt(int index)
+  {
+    return mValues[index];
+  }
+
+  /**
+   * Returns the index for which {@link #keyAt} would return the specified key,
+   * or a negative number if the specified key is not mapped.
+   */
+  public int indexOfKey(int key)
+  {
+    return ContainerHelpers.binarySearch(mKeys, mSize, key);
+  }
+
+  /**
+   * Returns an index for which {@link #valueAt} would return the specified key,
+   * or a negative number if no keys map to the specified value. Beware that
+   * this is a linear search, unlike lookups by key, and that multiple keys can
+   * map to the same value and this will find only one of them.
+   */
+  public int indexOfValue(int value)
+  {
+    for (int i = 0; i < mSize; i++)
+    {
+      if (mValues[i] == value)
+      {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Removes all key-value mappings from this SparseIntArray.
+   */
+  public void clear()
+  {
+    mSize = 0;
+  }
+
+  /**
+   * Puts a key/value pair into the array, optimizing for the case where the key
+   * is greater than all existing keys in the array.
+   */
+  public void append(int key, int value)
+  {
+    if (mSize != 0 && key <= mKeys[mSize - 1])
+    {
+      put(key, value);
+      return;
+    }
+    int pos = mSize;
+    if (pos >= mKeys.length)
+    {
+      int n = idealIntArraySize(pos + 1);
+      int[] nkeys = new int[n];
+      int[] nvalues = new int[n];
+      // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
+      System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+      System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+      mKeys = nkeys;
+      mValues = nvalues;
+    }
+    mKeys[pos] = key;
+    mValues[pos] = value;
+    mSize = pos + 1;
+  }
+
+  /**
+   * Inlined here by copying from com.android.internal.util.ArrayUtils
+   * 
+   * @param i
+   * @return
+   */
+  public static int idealIntArraySize(int need)
+  {
+    return idealByteArraySize(need * 4) / 4;
+  }
+
+  /**
+   * Inlined here by copying from com.android.internal.util.ArrayUtils
+   * 
+   * @param i
+   * @return
+   */
+  public static int idealByteArraySize(int need)
+  {
+    for (int i = 4; i < 32; i++)
+    {
+      if (need <= (1 << i) - 12)
+      {
+        return (1 << i) - 12;
+      }
+    }
+
+    return need;
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * <p>
+   * This implementation composes a string by iterating over its mappings.
+   */
+  @Override
+  public String toString()
+  {
+    if (size() <= 0)
+    {
+      return "{}";
+    }
+    StringBuilder buffer = new StringBuilder(mSize * 28);
+    buffer.append('{');
+    for (int i = 0; i < mSize; i++)
+    {
+      if (i > 0)
+      {
+        buffer.append(", ");
+      }
+      int key = keyAt(i);
+      buffer.append(key);
+      buffer.append('=');
+      int value = valueAt(i);
+      buffer.append(value);
+    }
+    buffer.append('}');
+    return buffer.toString();
+  }
+
+  /**
+   * Method (copied from put) added for Jalview to efficiently increment a key's
+   * value if present, else add it with the given value. This avoids a double
+   * binary search (once to get the value, again to put the updated value).
+   * 
+   * @param key
+   * @oparam toAdd
+   * @return the new value of the count for the key
+   * @throw ArithmeticException if the result would exceed the maximum value of
+   *        an int
+   */
+  public int add(int key, int toAdd)
+  {
+    int newValue = toAdd;
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+    if (i >= 0)
+    {
+      checkOverflow(mValues[i], toAdd);
+      mValues[i] += toAdd;
+      newValue = mValues[i];
+    }
+    else
+    {
+      i = ~i;
+      if (mSize >= mKeys.length)
+      {
+        int n = idealIntArraySize(mSize + 1);
+        int[] nkeys = new int[n];
+        int[] nvalues = new int[n];
+        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+        mKeys = nkeys;
+        mValues = nvalues;
+      }
+      if (mSize - i != 0)
+      {
+        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+      }
+      mKeys[i] = key;
+      mValues[i] = toAdd;
+      mSize++;
+    }
+    return newValue;
+  }
+
+  /**
+   * Throws ArithmeticException if adding addend to value would exceed the range
+   * of int
+   * 
+   * @param value
+   * @param addend
+   */
+  static void checkOverflow(int value, int addend)
+  {
+    /*
+     * test cases being careful to avoid overflow while testing!
+     */
+    if (addend > 0)
+    {
+      if (value > 0 && Integer.MAX_VALUE - value < addend)
+      {
+        throw new ArithmeticException("Integer overflow adding " + addend
+                + " to  " + value);
+      }
+    }
+    else if (addend < 0)
+    {
+      if (value < 0 && Integer.MIN_VALUE - value > addend)
+      {
+        throw new ArithmeticException("Integer underflow adding " + addend
+                + " to  " + value);
+      }
+    }
+  }
+}
diff --git a/src/jalview/ext/android/SparseShortArray.java b/src/jalview/ext/android/SparseShortArray.java
new file mode 100644 (file)
index 0000000..f961f55
--- /dev/null
@@ -0,0 +1,442 @@
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * SparseShortArrays map shorts to shorts. Unlike a normal array of shorts,
+ * there can be gaps in the indices. It is intended to be more memory efficient
+ * than using a HashMap to map Shorts to Shorts, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra
+ * entry object for each mapping.
+ *
+ * <p>
+ * Note that this container keeps its mappings in an array data structure, using
+ * a binary search to find keys. The implementation is not intended to be
+ * appropriate for data structures that may contain large numbers of items. It
+ * is generally slower than a traditional HashMap, since lookups require a
+ * binary search and adds and removes require inserting and deleting entries in
+ * the array. For containers holding up to hundreds of items, the performance
+ * difference is not significant, less than 50%.
+ * </p>
+ *
+ * <p>
+ * It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.
+ * </p>
+ */
+
+/*
+ * Added to Jalview September 2016. A copy of SparseIntArray designed to store
+ * short values (to minimise space usage).
+ * <p>
+ * Note that operations append, put, add throw ArithmeticException if either the
+ * key or the resulting value overflows the range of a short. Calling code
+ * should trap and handle this, for example by switching to using a
+ * SparseIntArray instead.
+ */
+public class SparseShortArray implements Cloneable
+{
+  private short[] mKeys;
+
+  private short[] mValues;
+
+  private int mSize;
+
+  /**
+   * Creates a new SparseShortArray containing no mappings.
+   */
+  public SparseShortArray()
+  {
+    this(10);
+  }
+
+  /**
+   * Creates a new SparseShortArray containing no mappings that will not require
+   * any additional memory allocation to store the specified number of mappings.
+   * If you supply an initial capacity of 0, the sparse array will be
+   * initialized with a light-weight representation not requiring any additional
+   * array allocations.
+   */
+  public SparseShortArray(int initialCapacity)
+  {
+    if (initialCapacity == 0)
+    {
+      mKeys = new short[0];
+      mValues = new short[0];
+    }
+    else
+    {
+      initialCapacity = idealShortArraySize(initialCapacity);
+      mKeys = new short[initialCapacity];
+      mValues = new short[initialCapacity];
+    }
+    mSize = 0;
+  }
+
+  @Override
+  public SparseShortArray clone()
+  {
+    SparseShortArray clone = null;
+    try
+    {
+      clone = (SparseShortArray) super.clone();
+      clone.mKeys = mKeys.clone();
+      clone.mValues = mValues.clone();
+    } catch (CloneNotSupportedException cnse)
+    {
+      /* ignore */
+    }
+    return clone;
+  }
+
+  /**
+   * Gets the int mapped from the specified key, or <code>0</code> if no such
+   * mapping has been made.
+   */
+  public int get(int key)
+  {
+    return get(key, 0);
+  }
+
+  /**
+   * Gets the int mapped from the specified key, or the specified value if no
+   * such mapping has been made.
+   * 
+   * @throws ArithmeticException
+   *           if key is outside the range of a short value
+   */
+  public int get(int key, int valueIfKeyNotFound)
+  {
+    checkOverflow(key);
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+    if (i < 0)
+    {
+      return valueIfKeyNotFound;
+    }
+    else
+    {
+      return mValues[i];
+    }
+  }
+
+  /**
+   * Removes the mapping from the specified key, if there was any.
+   * 
+   * @throws ArithmeticException
+   *           if key is outside the range of a short value
+   */
+  public void delete(int key)
+  {
+    checkOverflow(key);
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+    if (i >= 0)
+    {
+      removeAt(i);
+    }
+  }
+
+  /**
+   * Removes the mapping at the given index.
+   */
+  public void removeAt(int index)
+  {
+    System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+    System.arraycopy(mValues, index + 1, mValues, index, mSize
+            - (index + 1));
+    mSize--;
+  }
+
+  /**
+   * Adds a mapping from the specified key to the specified value, replacing the
+   * previous mapping from the specified key if there was one.
+   * 
+   * @throws ArithmeticException
+   *           if either argument is outside the range of a short value
+   */
+  public void put(int key, int value)
+  {
+    checkOverflow(key);
+    checkOverflow(value);
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+    if (i >= 0)
+    {
+      mValues[i] = (short) value;
+    }
+    else
+    {
+      i = ~i;
+      if (mSize >= mKeys.length)
+      {
+        int n = idealShortArraySize(mSize + 1);
+        short[] nkeys = new short[n];
+        short[] nvalues = new short[n];
+        // Log.e("SparseShortArray", "grow " + mKeys.length + " to " + n);
+        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+        mKeys = nkeys;
+        mValues = nvalues;
+      }
+      if (mSize - i != 0)
+      {
+        // Log.e("SparseShortArray", "move " + (mSize - i));
+        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+      }
+      mKeys[i] = (short) key;
+      mValues[i] = (short) value;
+      mSize++;
+    }
+  }
+
+  /**
+   * Returns the number of key-value mappings that this SparseShortArray
+   * currently stores.
+   */
+  public int size()
+  {
+    return mSize;
+  }
+
+  /**
+   * Given an index in the range <code>0...size()-1</code>, returns the key from
+   * the <code>index</code>th key-value mapping that this SparseShortArray
+   * stores.
+   *
+   * <p>
+   * The keys corresponding to indices in ascending order are guaranteed to be
+   * in ascending order, e.g., <code>keyAt(0)</code> will return the smallest
+   * key and <code>keyAt(size()-1)</code> will return the largest key.
+   * </p>
+   */
+  public short keyAt(int index)
+  {
+    return mKeys[index];
+  }
+
+  /**
+   * Given an index in the range <code>0...size()-1</code>, returns the value
+   * from the <code>index</code>th key-value mapping that this SparseShortArray
+   * stores.
+   *
+   * <p>
+   * The values corresponding to indices in ascending order are guaranteed to be
+   * associated with keys in ascending order, e.g., <code>valueAt(0)</code> will
+   * return the value associated with the smallest key and
+   * <code>valueAt(size()-1)</code> will return the value associated with the
+   * largest key.
+   * </p>
+   */
+  public short valueAt(int index)
+  {
+    return mValues[index];
+  }
+
+  /**
+   * Returns the index for which {@link #keyAt} would return the specified key,
+   * or a negative number if the specified key is not mapped.
+   * 
+   * @throws ArithmeticException
+   *           if key is outside the range of a short value
+   */
+  public int indexOfKey(int key)
+  {
+    checkOverflow(key);
+    return ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+  }
+
+  /**
+   * Returns an index for which {@link #valueAt} would return the specified key,
+   * or a negative number if no keys map to the specified value. Beware that
+   * this is a linear search, unlike lookups by key, and that multiple keys can
+   * map to the same value and this will find only one of them.
+   */
+  public int indexOfValue(int value)
+  {
+    for (int i = 0; i < mSize; i++)
+    {
+      if (mValues[i] == value)
+      {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Removes all key-value mappings from this SparseShortArray.
+   */
+  public void clear()
+  {
+    mSize = 0;
+  }
+
+  /**
+   * Puts a key/value pair into the array, optimizing for the case where the key
+   * is greater than all existing keys in the array.
+   */
+  public void append(int key, int value)
+  {
+    if (mSize != 0 && key <= mKeys[mSize - 1])
+    {
+      put(key, value);
+      return;
+    }
+    int pos = mSize;
+    if (pos >= mKeys.length)
+    {
+      int n = idealShortArraySize(pos + 1);
+      short[] nkeys = new short[n];
+      short[] nvalues = new short[n];
+      // Log.e("SparseShortArray", "grow " + mKeys.length + " to " + n);
+      System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+      System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+      mKeys = nkeys;
+      mValues = nvalues;
+    }
+    checkOverflow(key);
+    checkOverflow(value);
+    mKeys[pos] = (short) key;
+    mValues[pos] = (short) value;
+    mSize = pos + 1;
+  }
+
+  /**
+   * Throws an exception if the value is outside the range of a short.
+   * 
+   * @param value
+   * @throws ArithmeticException
+   */
+  public static void checkOverflow(int value)
+  {
+    if (value > Short.MAX_VALUE || value < Short.MIN_VALUE)
+    {
+      throw new ArithmeticException(String.valueOf(value));
+    }
+  }
+
+  /**
+   * Inlined here by copying from com.android.internal.util.ArrayUtils
+   * 
+   * @param i
+   * @return
+   */
+  public static int idealShortArraySize(int need)
+  {
+    return idealByteArraySize(need * 2) / 2;
+  }
+
+  /**
+   * Inlined here by copying from com.android.internal.util.ArrayUtils
+   * 
+   * @param i
+   * @return
+   */
+  public static int idealByteArraySize(int need)
+  {
+    for (int i = 4; i < 32; i++)
+    {
+      if (need <= (1 << i) - 12)
+      {
+        return (1 << i) - 12;
+      }
+    }
+
+    return need;
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * <p>
+   * This implementation composes a string by iterating over its mappings.
+   */
+  @Override
+  public String toString()
+  {
+    if (size() <= 0)
+    {
+      return "{}";
+    }
+    StringBuilder buffer = new StringBuilder(mSize * 28);
+    buffer.append('{');
+    for (int i = 0; i < mSize; i++)
+    {
+      if (i > 0)
+      {
+        buffer.append(", ");
+      }
+      int key = keyAt(i);
+      buffer.append(key);
+      buffer.append('=');
+      int value = valueAt(i);
+      buffer.append(value);
+    }
+    buffer.append('}');
+    return buffer.toString();
+  }
+
+  /**
+   * Method (copied from put) added for Jalview to efficiently increment a key's
+   * value if present, else add it with the given value. This avoids a double
+   * binary search (once to get the value, again to put the updated value).
+   * 
+   * @param key
+   * @oparam toAdd
+   * @return the new value of the count for the key
+   * @throws ArithmeticException
+   *           if key, or result of adding toAdd, is outside the range of a
+   *           short value
+   */
+  public int add(int key, int toAdd)
+  {
+    int newValue = toAdd;
+    checkOverflow(key);
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+    if (i >= 0)
+    {
+      checkOverflow(toAdd + mValues[i]);
+      mValues[i] += (short) toAdd;
+      newValue = mValues[i];
+    }
+    else
+    {
+      checkOverflow(toAdd);
+      i = ~i;
+      if (mSize >= mKeys.length)
+      {
+        int n = idealShortArraySize(mSize + 1);
+        short[] nkeys = new short[n];
+        short[] nvalues = new short[n];
+        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+        mKeys = nkeys;
+        mValues = nvalues;
+      }
+      if (mSize - i != 0)
+      {
+        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+      }
+      mKeys[i] = (short) key;
+      mValues[i] = (short) toAdd;
+      mSize++;
+    }
+    return newValue;
+  }
+}
index b28a37f..7570822 100644 (file)
@@ -85,6 +85,10 @@ class EnsemblFeatures extends EnsemblRestClient
     List<String> queries = new ArrayList<String>();
     queries.add(query);
     FileParse fp = getSequenceReader(queries);
+    if (fp == null || !fp.isValid())
+    {
+      return null;
+    }
     FeaturesFile fr = new FeaturesFile(fp);
     return new Alignment(fr.getSeqsAsArray());
   }
index 5903f69..ab3b197 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.ext.ensembl;
 
+import jalview.io.DataSourceType;
 import jalview.io.FileParse;
 import jalview.util.StringUtils;
 
@@ -60,9 +61,9 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
    * @see https://github.com/Ensembl/ensembl-rest/wiki/Change-log
    * @see http://rest.ensembl.org/info/rest?content-type=application/json
    */
-  private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "4.6";
+  private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "4.8";
 
-  private static final String LATEST_ENSEMBL_REST_VERSION = "4.7";
+  private static final String LATEST_ENSEMBL_REST_VERSION = "4.8";
 
   private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log";
 
@@ -245,7 +246,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
       // request failed
       return null;
     }
-    FileParse fp = new FileParse(reader, url.toString(), "HTTP_POST");
+    FileParse fp = new FileParse(reader, url.toString(), DataSourceType.URL);
     return fp;
   }
 
index 7aa7178..732bc0f 100644 (file)
@@ -233,7 +233,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
       EnsemblFeatureType[] features = getFeaturesToFetch();
       AlignmentI geneFeatures = gffFetcher.getSequenceRecords(accId,
               features);
-      if (geneFeatures.getHeight() > 0)
+      if (geneFeatures != null && geneFeatures.getHeight() > 0)
       {
         genomicSequence = geneFeatures.getSequenceAt(0);
       }
index fbac400..2d2d10e 100644 (file)
@@ -27,7 +27,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
 import jalview.io.StructureFile;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
@@ -49,8 +49,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
-import javajs.awt.Dimension;
-
 import org.jmol.adapter.smarter.SmarterJmolAdapter;
 import org.jmol.api.JmolAppConsoleInterface;
 import org.jmol.api.JmolSelectionListener;
@@ -74,7 +72,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
 
   Vector<String> atomsPicked = new Vector<String>();
 
-  public Vector<String> chainNames;
+  private List<String> chainNames;
 
   Hashtable<String, String> chainFile;
 
@@ -99,10 +97,10 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   public Viewer viewer;
 
   public JalviewJmolBinding(StructureSelectionManager ssm,
-          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
-          String protocol)
+          PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
+          DataSourceType protocol)
   {
-    super(ssm, pdbentry, sequenceIs, chains, protocol);
+    super(ssm, pdbentry, sequenceIs, protocol);
     /*
      * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
      * "jalviewJmol", ap.av.applet .getDocumentBase(),
@@ -1083,7 +1081,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     fileLoadingError = null;
     String[] oldmodels = modelFileNames;
     modelFileNames = null;
-    chainNames = new Vector<String>();
+    chainNames = new ArrayList<String>();
     chainFile = new Hashtable<String, String>();
     boolean notifyLoaded = false;
     String[] modelfilenames = getPdbFile();
@@ -1143,13 +1141,14 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       for (int pe = 0; pe < getPdbCount(); pe++)
       {
         boolean matches = false;
+        addSequence(pe, getSequence()[pe]);
         if (fileName == null)
         {
           if (false)
           // see JAL-623 - need method of matching pasted data up
           {
             pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
-                    pdbfile, AppletFormatAdapter.PASTE);
+                    pdbfile, DataSourceType.PASTE);
             getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
             matches = true;
             foundEntry = true;
@@ -1167,12 +1166,12 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
             // needs
             // to be tested. See mantis bug
             // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
-            String protocol = AppletFormatAdapter.URL;
+            DataSourceType protocol = DataSourceType.URL;
             try
             {
               if (fl.exists())
               {
-                protocol = AppletFormatAdapter.FILE;
+                protocol = DataSourceType.FILE;
               }
             } catch (Exception e)
             {
@@ -1194,7 +1193,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
             String chid = new String(pdb.getId() + ":"
                     + pdb.getChains().elementAt(i).id);
             chainFile.put(chid, fileName);
-            chainNames.addElement(chid);
+            chainNames.add(chid);
           }
           notifyLoaded = true;
         }
@@ -1242,6 +1241,12 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     setLoadingFromArchive(false);
   }
 
+  @Override
+  public List<String> getChainNames()
+  {
+    return chainNames;
+  }
+
   public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
   {
     notifyAtomPicked(iatom, strMeasure, null);
@@ -1404,7 +1409,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   }
 
   @Override
-  public Dimension resizeInnerPanel(String data)
+  public int[] resizeInnerPanel(String data)
   {
     // Jalview doesn't honour resize panel requests
     return null;
index b2ba256..f08e40e 100644 (file)
@@ -24,6 +24,7 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
 import jalview.io.FileParse;
 import jalview.io.StructureFile;
 import jalview.schemes.ResidueProperties;
@@ -38,8 +39,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
-import javajs.awt.Dimension;
-
 import org.jmol.api.JmolStatusListener;
 import org.jmol.api.JmolViewer;
 import org.jmol.c.CBK;
@@ -61,9 +60,10 @@ public class JmolParser extends StructureFile implements JmolStatusListener
 {
   Viewer viewer = null;
 
-  public JmolParser(String inFile, String type) throws IOException
+  public JmolParser(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public JmolParser(FileParse fp) throws IOException
@@ -472,7 +472,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
    * Not implemented - returns null
    */
   @Override
-  public String print()
+  public String print(SequenceI[] seqs, boolean jvSuffix)
   {
     return null;
   }
@@ -626,7 +626,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
    * Not implemented - returns null
    */
   @Override
-  public Dimension resizeInnerPanel(String data)
+  public int[] resizeInnerPanel(String data)
   {
     return null;
   }
index 7ba9186..262b8a2 100644 (file)
@@ -23,12 +23,14 @@ package jalview.ext.rbvi.chimera;
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureRenderer;
 import jalview.api.SequenceRenderer;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.httpserver.AbstractRequestHandler;
+import jalview.io.DataSourceType;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.AtomSpec;
@@ -40,6 +42,7 @@ import jalview.util.MessageManager;
 import java.awt.Color;
 import java.net.BindException;
 import java.util.ArrayList;
+import java.util.Hashtable;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -63,6 +66,10 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   private static final String ALPHACARBON = "CA";
 
+  private List<String> chainNames = new ArrayList<String>();
+
+  private Hashtable<String, String> chainFile = new Hashtable<String, String>();
+  
   /*
    * Object through which we talk to Chimera
    */
@@ -110,6 +117,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    */
   private long loadNotifiesHandled = 0;
 
+  private Thread chimeraMonitor;
+
   /**
    * Open a PDB structure file in Chimera and set up mappings from Jalview.
    * 
@@ -187,16 +196,44 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    * @param ssm
    * @param pdbentry
    * @param sequenceIs
-   * @param chains
    * @param protocol
    */
   public JalviewChimeraBinding(StructureSelectionManager ssm,
-          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
-          String protocol)
+          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, DataSourceType protocol)
+  {
+    super(ssm, pdbentry, sequenceIs, protocol);
+    viewer = new ChimeraManager(new StructureManager(true));
+  }
+
+  /**
+   * Starts a thread that waits for the Chimera process to finish, so that we
+   * can then close the associated resources. This avoids leaving orphaned
+   * Chimera viewer panels in Jalview if the user closes Chimera.
+   */
+  protected void startChimeraProcessMonitor()
   {
-    super(ssm, pdbentry, sequenceIs, chains, protocol);
-    viewer = new ChimeraManager(
-            new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true));
+    final Process p = viewer.getChimeraProcess();
+    chimeraMonitor = new Thread(new Runnable()
+    {
+
+      @Override
+      public void run()
+      {
+        try
+        {
+          p.waitFor();
+          JalviewStructureDisplayI display = getViewer();
+          if (display != null)
+          {
+            display.closeViewer(false);
+          }
+        } catch (InterruptedException e)
+        {
+          // exit thread if Chimera Viewer is closed in Jalview
+        }
+      }
+    });
+    chimeraMonitor.start();
   }
 
   /**
@@ -244,11 +281,14 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     boolean first = true;
     for (String chain : toshow)
     {
+      int modelNumber = getModelNoForChain(chain);
+      String showChainCmd = modelNumber == -1 ? "" : modelNumber + ":."
+              + chain.split(":")[1];
       if (!first)
       {
         cmd.append(",");
       }
-      cmd.append(":.").append(chain);
+      cmd.append(showChainCmd);
       first = false;
     }
 
@@ -257,7 +297,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
      * window, but it looks more helpful not to (easier to relate chains to the
      * whole)
      */
-    final String command = "~display #*; ~ribbon #*; ribbon "
+    final String command = "~display #*; ~ribbon #*; ribbon :"
             + cmd.toString();
     sendChimeraCommand(command, false);
   }
@@ -281,6 +321,10 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     lastCommand = null;
     viewer = null;
 
+    if (chimeraMonitor != null)
+    {
+      chimeraMonitor.interrupt();
+    }
     releaseUIResources();
   }
 
@@ -561,23 +605,29 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   /**
    * Launch Chimera, unless an instance linked to this object is already
-   * running. Returns true if chimera is successfully launched, or already
+   * running. Returns true if Chimera is successfully launched, or already
    * running, else false.
    * 
    * @return
    */
   public boolean launchChimera()
   {
-    if (!viewer.isChimeraLaunched())
-    {
-      return viewer.launchChimera(StructureManager.getChimeraPaths());
-    }
     if (viewer.isChimeraLaunched())
     {
       return true;
     }
-    log("Failed to launch Chimera!");
-    return false;
+
+    boolean launched = viewer.launchChimera(StructureManager
+            .getChimeraPaths());
+    if (launched)
+    {
+      startChimeraProcessMonitor();
+    }
+    else
+    {
+      log("Failed to launch Chimera!");
+    }
+    return launched;
   }
 
   /**
@@ -758,18 +808,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     {
       return new String[0];
     }
-    // if (modelFileNames == null)
-    // {
-    // Collection<ChimeraModel> chimodels = viewer.getChimeraModels();
-    // _modelFileNameMap = new int[chimodels.size()];
-    // int j = 0;
-    // for (ChimeraModel chimodel : chimodels)
-    // {
-    // String mdlName = chimodel.getModelName();
-    // }
-    // modelFileNames = new String[j];
-    // // System.arraycopy(mset, 0, modelFileNames, 0, j);
-    // }
 
     return chimeraMaps.keySet().toArray(
             modelFileNames = new String[chimeraMaps.size()]);
@@ -1062,35 +1100,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   }
 
   /**
-   * Returns a list of chains mapped in this viewer. Note this list is not
-   * currently scoped per structure.
-   * 
-   * @return
-   */
-  public List<String> getChainNames()
-  {
-    List<String> names = new ArrayList<String>();
-    String[][] allNames = getChains();
-    if (allNames != null)
-    {
-      for (String[] chainsForPdb : allNames)
-      {
-        if (chainsForPdb != null)
-        {
-          for (String chain : chainsForPdb)
-          {
-            if (chain != null && !names.contains(chain))
-            {
-              names.add(chain);
-            }
-          }
-        }
-      }
-    }
-    return names;
-  }
-
-  /**
    * Send a 'focus' command to Chimera to recentre the visible display
    */
   public void focusView()
@@ -1125,4 +1134,31 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       sm.highlightStructure(this, seq, positions);
     }
   }
+
+
+  @Override
+  public List<String> getChainNames()
+  {
+    return chainNames;
+  }
+
+  public Hashtable<String, String> getChainFile()
+  {
+    return chainFile;
+  }
+
+  public List<ChimeraModel> getChimeraModelByChain(String chain)
+  {
+    return chimeraMaps.get(chainFile.get(chain));
+  }
+
+  public int getModelNoForChain(String chain)
+  {
+    List<ChimeraModel> foundModels = getChimeraModelByChain(chain);
+    if (foundModels != null && !foundModels.isEmpty())
+    {
+      return foundModels.get(0).getModelNumber();
+    }
+    return -1;
+  }
 }
index 2a12630..b9845a4 100644 (file)
@@ -22,6 +22,7 @@ package jalview.gui;
 
 import jalview.api.AlignExportSettingI;
 import jalview.bin.Jalview;
+import jalview.io.FileFormatI;
 import jalview.jbgui.GAlignExportSettings;
 import jalview.util.MessageManager;
 
@@ -41,18 +42,19 @@ public class AlignExportSettings extends GAlignExportSettings implements
   JDialog dialog;
 
   public AlignExportSettings(boolean hasHiddenSeq, boolean hasHiddenCols,
-          String alignFileFormat)
+          FileFormatI format)
   {
-    super(hasHiddenSeq, hasHiddenCols, alignFileFormat);
+    super(hasHiddenSeq, hasHiddenCols, format);
     if (!Jalview.isHeadlessMode() && isShowDialog())
     {
 
       JOptionPane pane = new JOptionPane(null, JOptionPane.DEFAULT_OPTION,
-              JOptionPane.DEFAULT_OPTION, null, new Object[] { this });
+              JvOptionPane.DEFAULT_OPTION, null, new Object[] { this });
       dialog = pane.createDialog(Desktop.desktop,
               MessageManager.getString("label.export_settings"));
       dialog.addWindowListener(new WindowAdapter()
       {
+        @Override
         public void windowClosing(WindowEvent e)
         {
           cancelled = true;
@@ -66,6 +68,7 @@ public class AlignExportSettings extends GAlignExportSettings implements
     }
   }
 
+  @Override
   public void ok_actionPerformed(ActionEvent e)
   {
     cancelled = false;
@@ -73,6 +76,7 @@ public class AlignExportSettings extends GAlignExportSettings implements
     dialog.dispose();
   }
 
+  @Override
   public void cancel_actionPerformed(ActionEvent e)
   {
     cancelled = true;
@@ -110,6 +114,7 @@ public class AlignExportSettings extends GAlignExportSettings implements
     return chkExportGrps.isSelected();
   }
 
+  @Override
   public boolean isCancelled()
   {
     return cancelled;
index 63620e5..df2a742 100644 (file)
@@ -63,10 +63,14 @@ import jalview.gui.ViewSelectionMenu.ViewSetProvider;
 import jalview.io.AlignmentProperties;
 import jalview.io.AnnotationFile;
 import jalview.io.BioJsHTMLOutput;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
 import jalview.io.FileLoader;
 import jalview.io.FormatAdapter;
 import jalview.io.HtmlSvgOutput;
 import jalview.io.IdentifyFile;
+import jalview.io.JPredFile;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
 import jalview.io.JnetAnnotationMaker;
@@ -142,7 +146,6 @@ import javax.swing.JInternalFrame;
 import javax.swing.JLayeredPane;
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 import javax.swing.JRadioButtonMenuItem;
 import javax.swing.JScrollPane;
 import javax.swing.SwingUtilities;
@@ -175,7 +178,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   /**
    * Last format used to load or save alignments in this window
    */
-  String currentFileFormat = null;
+  FileFormatI currentFileFormat = null;
 
   /**
    * Current filename for this alignment
@@ -484,7 +487,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * @param format
    *          format of file
    */
-  public void setFileName(String file, String format)
+  public void setFileName(String file, FileFormatI format)
   {
     fileName = file;
     setFileFormat(format);
@@ -669,6 +672,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           toggleHiddenRegions(toggleSeqs, toggleCols);
           break;
         }
+        case KeyEvent.VK_B:
+        {
+          boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
+          boolean modifyExisting = true; // always modify, don't clear
+                                         // evt.isShiftDown();
+          boolean invertHighlighted = evt.isAltDown();
+          avc.markHighlightedColumns(invertHighlighted, modifyExisting,
+                  toggleSel);
+          break;
+        }
         case KeyEvent.VK_PAGE_UP:
           if (viewport.getWrapAlignment())
           {
@@ -844,7 +857,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     modifyConservation.setEnabled(!nucleotide);
     showGroupConservation.setEnabled(!nucleotide);
     rnahelicesColour.setEnabled(nucleotide);
+    nucleotideColour.setEnabled(nucleotide);
     purinePyrimidineColour.setEnabled(nucleotide);
+    RNAInteractionColour.setEnabled(nucleotide);
     showComplementMenuItem.setText(nucleotide ? MessageManager
             .getString("label.protein") : MessageManager
             .getString("label.nucleotide"));
@@ -1003,7 +1018,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       // originating file's format
       // TODO: work out how to recover feature settings for correct view(s) when
       // file is reloaded.
-      if (currentFileFormat.equals("Jalview"))
+      if (FileFormat.Jalview.equals(currentFileFormat))
       {
         JInternalFrame[] frames = Desktop.desktop.getAllFrames();
         for (int i = 0; i < frames.length; i++)
@@ -1025,7 +1040,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         Desktop.instance.closeAssociatedWindows();
 
         FileLoader loader = new FileLoader();
-        String protocol = fileName.startsWith("http:") ? "URL" : "File";
+        DataSourceType protocol = fileName.startsWith("http:") ? DataSourceType.URL
+                : DataSourceType.FILE;
         loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
       }
       else
@@ -1033,7 +1049,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         Rectangle bounds = this.getBounds();
 
         FileLoader loader = new FileLoader();
-        String protocol = fileName.startsWith("http:") ? "URL" : "File";
+        DataSourceType protocol = fileName.startsWith("http:") ? DataSourceType.URL
+                : DataSourceType.FILE;
         AlignFrame newframe = loader.LoadFileWaitTillLoaded(fileName,
                 protocol, currentFileFormat);
 
@@ -1077,9 +1094,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void save_actionPerformed(ActionEvent e)
   {
-    if (fileName == null
-            || (currentFileFormat == null || !jalview.io.FormatAdapter
-                    .isValidIOFormat(currentFileFormat, true))
+    if (fileName == null || (currentFileFormat == null)
             || fileName.startsWith("http"))
     {
       saveAs_actionPerformed(null);
@@ -1099,11 +1114,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void saveAs_actionPerformed(ActionEvent e)
   {
-    JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            jalview.io.AppletFormatAdapter.WRITABLE_EXTENSIONS,
-            jalview.io.AppletFormatAdapter.WRITABLE_FNAMES,
-            currentFileFormat, false);
+    String format = currentFileFormat == null ? null : currentFileFormat
+            .toString();
+    JalviewFileChooser chooser = JalviewFileChooser.forWrite(
+            Cache.getProperty("LAST_DIRECTORY"), format);
 
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
@@ -1117,14 +1131,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       currentFileFormat = chooser.getSelectedFormat();
       while (currentFileFormat == null)
       {
-        JOptionPane
+        JvOptionPane
                 .showInternalMessageDialog(
                         Desktop.desktop,
                         MessageManager
                                 .getString("label.select_file_format_before_saving"),
                         MessageManager
                                 .getString("label.file_format_not_specified"),
-                        JOptionPane.WARNING_MESSAGE);
+                        JvOptionPane.WARNING_MESSAGE);
         currentFileFormat = chooser.getSelectedFormat();
         value = chooser.showSaveDialog(this);
         if (value != JalviewFileChooser.APPROVE_OPTION)
@@ -1135,24 +1149,19 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
       fileName = chooser.getSelectedFile().getPath();
 
-      jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT",
-              currentFileFormat);
+      Cache.setProperty("DEFAULT_FILE_FORMAT",
+              currentFileFormat.toString());
 
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", fileName);
-      if (currentFileFormat.indexOf(" ") > -1)
-      {
-        currentFileFormat = currentFileFormat.substring(0,
-                currentFileFormat.indexOf(" "));
-      }
+      Cache.setProperty("LAST_DIRECTORY", fileName);
       saveAlignment(fileName, currentFileFormat);
     }
   }
 
-  public boolean saveAlignment(String file, String format)
+  public boolean saveAlignment(String file, FileFormatI format)
   {
     boolean success = true;
 
-    if (format.equalsIgnoreCase("Jalview"))
+    if (FileFormat.Jalview.equals(format))
     {
       String shortName = title;
 
@@ -1171,16 +1180,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
     else
     {
-      if (!jalview.io.AppletFormatAdapter.isValidFormat(format, true))
-      {
-        warningMessage("Cannot save file " + fileName + " using format "
-                + format, "Alignment output format not supported");
-        if (!Jalview.isHeadlessMode())
-        {
-          saveAs_actionPerformed(null);
-        }
-        return false;
-      }
+      // if (!jalview.io.AppletFormatAdapter.isValidFormat(format, true))
+      // {
+      // warningMessage("Cannot save file " + fileName + " using format "
+      // + format, "Alignment output format not supported");
+      // if (!Jalview.isHeadlessMode())
+      // {
+      // saveAs_actionPerformed(null);
+      // }
+      // return false;
+      // }
 
       AlignmentExportData exportData = getAlignmentForExport(format,
               viewport, null);
@@ -1225,11 +1234,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     if (!success)
     {
-      JOptionPane.showInternalMessageDialog(this, MessageManager
+      JvOptionPane.showInternalMessageDialog(this, MessageManager
               .formatMessage("label.couldnt_save_file",
                       new Object[] { fileName }), MessageManager
               .getString("label.error_saving_file"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
     }
 
     return success;
@@ -1244,8 +1253,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
     else
     {
-      JOptionPane.showInternalMessageDialog(this, warning, title,
-              JOptionPane.WARNING_MESSAGE);
+      JvOptionPane.showInternalMessageDialog(this, warning, title,
+              JvOptionPane.WARNING_MESSAGE);
     }
     return;
   }
@@ -1260,8 +1269,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void outputText_actionPerformed(ActionEvent e)
   {
 
-    AlignmentExportData exportData = getAlignmentForExport(
-            e.getActionCommand(), viewport, null);
+    FileFormatI fileFormat = FileFormat.forName(e.getActionCommand());
+    AlignmentExportData exportData = getAlignmentForExport(fileFormat,
+            viewport, null);
     if (exportData.getSettings().isCancelled())
     {
       return;
@@ -1270,8 +1280,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     cap.setForInput(null);
     try
     {
+      FileFormatI format = fileFormat;
       cap.setText(new FormatAdapter(alignPanel, exportData.getSettings())
-              .formatSequences(e.getActionCommand(),
+              .formatSequences(format,
                       exportData.getAlignment(),
                       exportData.getOmitHidden(),
                       exportData.getStartEndPostions(),
@@ -1288,7 +1299,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   public static AlignmentExportData getAlignmentForExport(
-          String exportFormat, AlignViewportI viewport,
+          FileFormatI format, AlignViewportI viewport,
           AlignExportSettingI exportSettings)
   {
     AlignmentI alignmentToExport = null;
@@ -1304,7 +1315,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if (settings == null)
     {
       settings = new AlignExportSettings(hasHiddenSeqs,
-              viewport.hasHiddenColumns(), exportFormat);
+              viewport.hasHiddenColumns(), format);
     }
     // settings.isExportAnnotations();
 
@@ -1340,14 +1351,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   protected void htmlMenuItem_actionPerformed(ActionEvent e)
   {
-    new HtmlSvgOutput(null, alignPanel);
+    HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
+    htmlSVG.exportHTML(null);
   }
 
   @Override
   public void bioJSMenuItem_actionPerformed(ActionEvent e)
   {
-    BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel, this);
-    bjs.exportJalviewAlignmentAsBioJsHtmlFile();
+    BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
+    bjs.exportHTML(null);
   }
 
   public void createImageMap(File file, String image)
@@ -1861,7 +1873,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       omitHidden = viewport.getViewAsString(true);
     }
 
-    String output = new FormatAdapter().formatSequences("Fasta", seqs,
+    String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
+            seqs,
             omitHidden, null);
 
     StringSelection ss = new StringSelection(output);
@@ -1948,7 +1961,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         return;
       }
 
-      String str, format;
+      String str;
+      FileFormatI format;
       try
       {
         str = (String) contents.getTransferData(DataFlavor.stringFlavor);
@@ -1957,7 +1971,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           return;
         }
 
-        format = new IdentifyFile().identify(str, "Paste");
+        format = new IdentifyFile().identify(str, DataSourceType.PASTE);
 
       } catch (OutOfMemoryError er)
       {
@@ -1987,7 +2001,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       else
       {
         // parse the clipboard as an alignment.
-        alignment = new FormatAdapter().readFile(str, "Paste", format);
+        alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
+                format);
         sequences = alignment.getSequencesArray();
       }
 
@@ -2356,13 +2371,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               .getAlignment().getWidth()) ? true : false;
       if (isEntireAlignWidth)
       {
-        int confirm = JOptionPane.showConfirmDialog(this,
+        int confirm = JvOptionPane.showConfirmDialog(this,
                 MessageManager.getString("warn.delete_all"), // $NON-NLS-1$
                 MessageManager.getString("label.delete_all"), // $NON-NLS-1$
-                JOptionPane.OK_CANCEL_OPTION);
+                JvOptionPane.OK_CANCEL_OPTION);
 
-        if (confirm == JOptionPane.CANCEL_OPTION
-                || confirm == JOptionPane.CLOSED_OPTION)
+        if (confirm == JvOptionPane.CANCEL_OPTION
+                || confirm == JvOptionPane.CLOSED_OPTION)
         {
           return;
         }
@@ -2907,8 +2922,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     viewport.setFollowHighlight(state);
     if (state)
     {
-      alignPanel.scrollToPosition(
-              alignPanel.getSeqPanel().seqCanvas.searchResults, false);
+      alignPanel.scrollToPosition(viewport.getSearchResults(), false);
     }
   }
 
@@ -3640,13 +3654,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           {
             radioItem.removeActionListener(radioItem.getActionListeners()[0]);
 
-            int option = JOptionPane.showInternalConfirmDialog(
+            int option = JvOptionPane.showInternalConfirmDialog(
                     jalview.gui.Desktop.desktop, MessageManager
                             .getString("label.remove_from_default_list"),
                     MessageManager
                             .getString("label.remove_user_defined_colour"),
-                    JOptionPane.YES_NO_OPTION);
-            if (option == JOptionPane.YES_OPTION)
+                    JvOptionPane.YES_NO_OPTION);
+            if (option == JvOptionPane.YES_OPTION)
             {
               jalview.gui.UserDefinedColours
                       .removeColourFromDefaults(radioItem.getText());
@@ -3794,10 +3808,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if ((viewport.getSelectionGroup() == null)
             || (viewport.getSelectionGroup().getSize() < 2))
     {
-      JOptionPane.showInternalMessageDialog(this, MessageManager
+      JvOptionPane.showInternalMessageDialog(this, MessageManager
               .getString("label.you_must_select_least_two_sequences"),
               MessageManager.getString("label.invalid_selection"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
     }
     else
     {
@@ -3823,14 +3837,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             .getSelectionGroup().getSize() > 0))
             || (viewport.getAlignment().getHeight() < 4))
     {
-      JOptionPane
+      JvOptionPane
               .showInternalMessageDialog(
                       this,
                       MessageManager
                               .getString("label.principal_component_analysis_must_take_least_four_input_sequences"),
                       MessageManager
                               .getString("label.sequence_selection_insufficient"),
-                      JOptionPane.WARNING_MESSAGE);
+                      JvOptionPane.WARNING_MESSAGE);
 
       return;
     }
@@ -3928,14 +3942,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       if (viewport.getSelectionGroup().getSize() < 3)
       {
-        JOptionPane
+        JvOptionPane
                 .showMessageDialog(
                         Desktop.desktop,
                         MessageManager
                                 .getString("label.you_need_more_two_sequences_selected_build_tree"),
                         MessageManager
                                 .getString("label.not_enough_sequences"),
-                        JOptionPane.WARNING_MESSAGE);
+                        JvOptionPane.WARNING_MESSAGE);
         return;
       }
 
@@ -3946,14 +3960,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       {
         if (_s.getLength() < sg.getEndRes())
         {
-          JOptionPane
+          JvOptionPane
                   .showMessageDialog(
                           Desktop.desktop,
                           MessageManager
                                   .getString("label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
                           MessageManager
                                   .getString("label.sequences_selection_not_aligned"),
-                          JOptionPane.WARNING_MESSAGE);
+                          JvOptionPane.WARNING_MESSAGE);
 
           return;
         }
@@ -3967,14 +3981,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       // are the visible sequences aligned?
       if (!viewport.getAlignment().isAligned(false))
       {
-        JOptionPane
+        JvOptionPane
                 .showMessageDialog(
                         Desktop.desktop,
                         MessageManager
                                 .getString("label.sequences_must_be_aligned_before_creating_tree"),
                         MessageManager
                                 .getString("label.sequences_not_aligned"),
-                        JOptionPane.WARNING_MESSAGE);
+                        JvOptionPane.WARNING_MESSAGE);
 
         return;
       }
@@ -4239,11 +4253,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     else if (viewport.getSelectionGroup() != null
             && viewport.getSelectionGroup().getSize() == 1)
     {
-      int option = JOptionPane.showConfirmDialog(this,
+      int option = JvOptionPane.showConfirmDialog(this,
               MessageManager.getString("warn.oneseq_msainput_selection"),
               MessageManager.getString("label.invalid_selection"),
-              JOptionPane.OK_CANCEL_OPTION);
-      if (option == JOptionPane.OK_OPTION)
+              JvOptionPane.OK_CANCEL_OPTION);
+      if (option == JvOptionPane.OK_OPTION)
       {
         msa = viewport.getAlignmentView(false);
       }
@@ -4315,25 +4329,25 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       jalview.io.NewickFile fin = null;
       try
       {
-        fin = new jalview.io.NewickFile(choice, "File");
+        fin = new NewickFile(choice, DataSourceType.FILE);
         viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());
       } catch (Exception ex)
       {
-        JOptionPane
+        JvOptionPane
                 .showMessageDialog(
                         Desktop.desktop,
                         ex.getMessage(),
                         MessageManager
                                 .getString("label.problem_reading_tree_file"),
-                        JOptionPane.WARNING_MESSAGE);
+                        JvOptionPane.WARNING_MESSAGE);
         ex.printStackTrace();
       }
       if (fin != null && fin.hasWarningMessage())
       {
-        JOptionPane.showMessageDialog(Desktop.desktop, fin
+        JvOptionPane.showMessageDialog(Desktop.desktop, fin
                 .getWarningMessage(), MessageManager
                 .getString("label.possible_problem_with_tree_file"),
-                JOptionPane.WARNING_MESSAGE);
+                JvOptionPane.WARNING_MESSAGE);
       }
     }
   }
@@ -4718,8 +4732,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       final String errorTitle = MessageManager
               .getString("label.implementation_error")
               + MessageManager.getString("label.translation_failed");
-      JOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
-              JOptionPane.ERROR_MESSAGE);
+      JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
+              JvOptionPane.ERROR_MESSAGE);
       return;
     }
     if (al == null || al.getHeight() == 0)
@@ -4728,8 +4742,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
       final String errorTitle = MessageManager
               .getString("label.translation_failed");
-      JOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
-              JOptionPane.WARNING_MESSAGE);
+      JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
+              JvOptionPane.WARNING_MESSAGE);
     }
     else
     {
@@ -4755,11 +4769,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   /**
    * Set the file format
    * 
-   * @param fileFormat
+   * @param format
    */
-  public void setFileFormat(String fileFormat)
+  public void setFileFormat(FileFormatI format)
   {
-    this.currentFileFormat = fileFormat;
+    this.currentFileFormat = format;
   }
 
   /**
@@ -4767,14 +4781,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param file
    *          contents or path to retrieve file
-   * @param type
+   * @param sourceType
    *          access mode of file (see jalview.io.AlignFile)
    * @return true if features file was parsed correctly.
    */
-  public boolean parseFeaturesFile(String file, String type)
+  public boolean parseFeaturesFile(String file, DataSourceType sourceType)
   {
-    return avc.parseFeaturesFile(file, type,
-            jalview.bin.Cache.getDefault("RELAXEDSEQIDMATCHING", false));
+    return avc.parseFeaturesFile(file, sourceType,
+            Cache.getDefault("RELAXEDSEQIDMATCHING", false));
 
   }
 
@@ -4819,7 +4833,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     // Java's Transferable for native dnd
     evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
     Transferable t = evt.getTransferable();
-    java.util.List<String> files = new ArrayList<String>(), protocols = new ArrayList<String>();
+    List<String> files = new ArrayList<String>();
+    List<DataSourceType> protocols = new ArrayList<DataSourceType>();
 
     try
     {
@@ -4845,13 +4860,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         {
           String file = files.get(i).toString();
           String pdbfn = "";
-          String protocol = FormatAdapter.checkProtocol(file);
-          if (protocol == jalview.io.FormatAdapter.FILE)
+          DataSourceType protocol = FormatAdapter.checkProtocol(file);
+          if (protocol == DataSourceType.FILE)
           {
             File fl = new File(file);
             pdbfn = fl.getName();
           }
-          else if (protocol == jalview.io.FormatAdapter.URL)
+          else if (protocol == DataSourceType.URL)
           {
             URL url = new URL(file);
             pdbfn = url.getFile();
@@ -4875,7 +4890,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             }
             if (mtch != null)
             {
-              String type = null;
+              FileFormatI type = null;
               try
               {
                 type = new IdentifyFile().identify(file, protocol);
@@ -4883,13 +4898,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               {
                 type = null;
               }
-              if (type != null)
+              if (type != null && type.isStructureFile())
               {
-                if (type.equalsIgnoreCase("PDB"))
-                {
-                  filesmatched.add(new Object[] { file, protocol, mtch });
-                  continue;
-                }
+                filesmatched.add(new Object[] { file, protocol, mtch });
+                continue;
               }
             }
             // File wasn't named like one of the sequences or wasn't a PDB file.
@@ -4900,20 +4912,20 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         if (filesmatched.size() > 0)
         {
           if (Cache.getDefault("AUTOASSOCIATE_PDBANDSEQS", false)
-                  || JOptionPane
+                  || JvOptionPane
                           .showConfirmDialog(
                                   this,
                                   MessageManager
                                           .formatMessage(
-                                                  "label.automatically_associate_pdb_files_with_sequences_same_name",
+                                                  "label.automatically_associate_structure_files_with_sequences_same_name",
                                                   new Object[] { Integer
                                                           .valueOf(
                                                                   filesmatched
                                                                           .size())
                                                           .toString() }),
                                   MessageManager
-                                          .getString("label.automatically_associate_pdb_files_by_name"),
-                                  JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
+                                          .getString("label.automatically_associate_structure_files_by_name"),
+                                  JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION)
 
           {
             for (Object[] fm : filesmatched)
@@ -4925,7 +4937,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               {
                 PDBEntry pe = new AssociatePdbFileWithSeq()
                         .associatePdbWithSeq((String) fm[0],
-                                (String) fm[1], toassoc, false,
+                                (DataSourceType) fm[1], toassoc, false,
                                 Desktop.instance);
                 if (pe != null)
                 {
@@ -4943,7 +4955,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         {
           if (assocfiles > 0
                   && (Cache.getDefault(
-                          "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false) || JOptionPane
+                          "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false) || JvOptionPane
                           .showConfirmDialog(
                                   this,
                                   "<html>"
@@ -4958,7 +4970,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                                           + "</html>",
                                   MessageManager
                                           .getString("label.ignore_unmatched_dropped_files"),
-                                  JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION))
+                                  JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
           {
             return;
           }
@@ -4984,21 +4996,21 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * @param file
    *          either a filename or a URL string.
    */
-  public void loadJalviewDataFile(String file, String protocol,
-          String format, SequenceI assocSeq)
+  public void loadJalviewDataFile(String file, DataSourceType sourceType,
+          FileFormatI format, SequenceI assocSeq)
   {
     try
     {
-      if (protocol == null)
+      if (sourceType == null)
       {
-        protocol = FormatAdapter.checkProtocol(file);
+        sourceType = FormatAdapter.checkProtocol(file);
       }
       // if the file isn't identified, or not positively identified as some
       // other filetype (PFAM is default unidentified alignment file type) then
       // try to parse as annotation.
-      boolean isAnnotation = (format == null || format
-              .equalsIgnoreCase("PFAM")) ? new AnnotationFile()
-              .annotateAlignmentView(viewport, file, protocol) : false;
+      boolean isAnnotation = (format == null || FileFormat.Pfam
+              .equals(format)) ? new AnnotationFile()
+              .annotateAlignmentView(viewport, file, sourceType) : false;
 
       if (!isAnnotation)
       {
@@ -5006,7 +5018,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         TCoffeeScoreFile tcf = null;
         try
         {
-          tcf = new TCoffeeScoreFile(file, protocol);
+          tcf = new TCoffeeScoreFile(file, sourceType);
           if (tcf.isValid())
           {
             if (tcf.annotateAlignment(viewport.getAlignment(), true))
@@ -5023,7 +5035,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             {
               // some problem - if no warning its probable that the ID matching
               // process didn't work
-              JOptionPane
+              JvOptionPane
                       .showMessageDialog(
                               Desktop.desktop,
                               tcf.getWarningMessage() == null ? MessageManager
@@ -5031,7 +5043,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                                       : tcf.getWarningMessage(),
                               MessageManager
                                       .getString("label.problem_reading_tcoffee_score_file"),
-                              JOptionPane.WARNING_MESSAGE);
+                              JvOptionPane.WARNING_MESSAGE);
             }
           }
           else
@@ -5052,12 +5064,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           // try to parse it as a features file
           if (format == null)
           {
-            format = new IdentifyFile().identify(file, protocol);
+            format = new IdentifyFile().identify(file, sourceType);
           }
-          if (format.equalsIgnoreCase("JnetFile"))
+          if (FileFormat.Jnet.equals(format))
           {
-            jalview.io.JPredFile predictions = new jalview.io.JPredFile(
-                    file, protocol);
+            JPredFile predictions = new JPredFile(
+                    file, sourceType);
             new JnetAnnotationMaker();
             JnetAnnotationMaker.add_annotation(predictions,
                     viewport.getAlignment(), 0, false);
@@ -5068,16 +5080,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             viewport.setColumnSelection(cs);
             isAnnotation = true;
           }
-          else if (IdentifyFile.FeaturesFile.equals(format))
+          // else if (IdentifyFile.FeaturesFile.equals(format))
+          else if (FileFormat.Features.equals(format))
           {
-            if (parseFeaturesFile(file, protocol))
+            if (parseFeaturesFile(file, sourceType))
             {
               alignPanel.paintAlignment(true);
             }
           }
           else
           {
-            new FileLoader().LoadFile(viewport, file, protocol, format);
+            new FileLoader().LoadFile(viewport, file, sourceType, format);
           }
         }
       }
@@ -5102,8 +5115,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       }
       new OOMWarning(
               "loading data "
-                      + (protocol != null ? (protocol.equals(FormatAdapter.PASTE) ? "from clipboard."
-                              : "using " + protocol + " from " + file)
+                      + (sourceType != null ? (sourceType == DataSourceType.PASTE ? "from clipboard."
+                              : "using " + sourceType + " from " + file)
                               : ".")
                       + (format != null ? "(parsing as '" + format
                               + "' file)" : ""), oom, Desktop.desktop);
@@ -5152,8 +5165,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if (e.isPopupTrigger())
     {
       String msg = MessageManager.getString("label.enter_view_name");
-      String reply = JOptionPane.showInternalInputDialog(this, msg, msg,
-              JOptionPane.QUESTION_MESSAGE);
+      String reply = JvOptionPane.showInternalInputDialog(this, msg, msg,
+              JvOptionPane.QUESTION_MESSAGE);
 
       if (reply != null)
       {
@@ -5892,12 +5905,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       } catch (Exception ex)
       {
         System.err.println((ex.toString()));
-        JOptionPane
+        JvOptionPane
                 .showInternalMessageDialog(Desktop.desktop, MessageManager
                         .getString("label.couldnt_run_groovy_script"),
                         MessageManager
                                 .getString("label.groovy_support_failed"),
-                        JOptionPane.ERROR_MESSAGE);
+                        JvOptionPane.ERROR_MESSAGE);
       }
     }
     else
@@ -5930,6 +5943,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
     return false;
   }
+
+  @Override
+  protected void selectHighlightedColumns_actionPerformed(
+          ActionEvent actionEvent)
+  {
+    // include key modifier check in case user selects from menu
+    avc.markHighlightedColumns(
+            (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0,
+            true,
+            (actionEvent.getModifiers() & (ActionEvent.META_MASK | ActionEvent.CTRL_MASK)) != 0);
+  }
 }
 
 class PrintThread extends Thread
index d0a0f11..53d118b 100644 (file)
@@ -37,6 +37,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -875,9 +876,9 @@ public class AlignViewport extends AlignmentViewport implements
         MessageManager.getString("label.new_window"), };
     final String question = JvSwingUtils.wrapTooltip(true,
             MessageManager.getString("label.open_split_window?"));
-    int response = JOptionPane.showOptionDialog(Desktop.desktop, question,
+    int response = JvOptionPane.showOptionDialog(Desktop.desktop, question,
             MessageManager.getString("label.open_split_window"),
-            JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
+            JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
             options, options[0]);
 
     if (response != 1 && response != 2)
@@ -917,7 +918,7 @@ public class AlignViewport extends AlignmentViewport implements
 
     // 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))
+    // if (!protocol.equals(DataSourceType.PASTE))
     // {
     // alignFrame.setFileName(file, format);
     // }
@@ -1042,7 +1043,7 @@ public class AlignViewport extends AlignmentViewport implements
      * there is no complement, or it is not following highlights, or no mapping
      * is found, the result will be empty.
      */
-    SearchResults sr = new SearchResults();
+    SearchResultsI sr = new SearchResults();
     int verticalOffset = findComplementScrollTarget(sr);
     if (!sr.isEmpty())
     {
index 4db029c..e61b042 100644 (file)
@@ -25,7 +25,7 @@ import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -297,7 +297,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * Highlight the given results on the alignment.
    * 
    */
-  public void highlightSearchResults(SearchResults results)
+  public void highlightSearchResults(SearchResultsI results)
   {
     scrollToPosition(results);
     getSeqPanel().seqCanvas.highlightSearchResults(results);
@@ -309,7 +309,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * 
    * @param results
    */
-  public boolean scrollToPosition(SearchResults results)
+  public boolean scrollToPosition(SearchResultsI results)
   {
     return scrollToPosition(results, 0, true, false);
   }
@@ -322,7 +322,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @param redrawOverview
    * @return
    */
-  public boolean scrollToPosition(SearchResults searchResults,
+  public boolean scrollToPosition(SearchResultsI searchResults,
           boolean redrawOverview)
   {
     return scrollToPosition(searchResults, 0, redrawOverview, false);
@@ -342,7 +342,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    *          if true, try to centre the search results horizontally in the view
    * @return false if results were not found
    */
-  public boolean scrollToPosition(SearchResults results,
+  public boolean scrollToPosition(SearchResultsI results,
           int verticalOffset, boolean redrawOverview, boolean centre)
   {
     int startv, endv, starts, ends;
@@ -956,11 +956,11 @@ public class AlignmentPanel extends GAlignmentPanel implements
 
     if (av.getWrapAlignment())
     {
-      return printWrappedAlignment(pg, pwidth, pheight, pi);
+      return printWrappedAlignment(pwidth, pheight, pi, pg);
     }
     else
     {
-      return printUnwrapped(pg, pwidth, pheight, pi);
+      return printUnwrapped(pwidth, pheight, pi, pg, pg);
     }
   }
 
@@ -981,84 +981,103 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @throws PrinterException
    *           DOCUMENT ME!
    */
-  public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi)
+  /**
+   * Draws the alignment image, including sequence ids, sequences, and
+   * annotation labels and annotations if shown, on either one or two Graphics
+   * context.
+   * 
+   * @param pageWidth
+   * @param pageHeight
+   * @param pi
+   * @param idGraphics
+   *          the graphics context for sequence ids and annotation labels
+   * @param alignmentGraphics
+   *          the graphics context for sequences and annotations (may or may not
+   *          be the same context as idGraphics)
+   * @return
+   * @throws PrinterException
+   */
+  public int printUnwrapped(int pageWidth, int pageHeight, int pi,
+          Graphics idGraphics, Graphics alignmentGraphics)
           throws PrinterException
   {
-    int idWidth = getVisibleIdWidth(false);
-    FontMetrics fm = getFontMetrics(av.getFont());
-    int scaleHeight = av.getCharHeight() + fm.getDescent();
+    final int idWidth = getVisibleIdWidth(false);
 
-    pg.setColor(Color.white);
-    pg.fillRect(0, 0, pwidth, pheight);
-    pg.setFont(av.getFont());
-
-    // //////////////////////////////////
-    // / How many sequences and residues can we fit on a printable page?
-    int totalRes = (pwidth - idWidth) / av.getCharWidth();
+    /*
+     * Get the horizontal offset to where we draw the sequences.
+     * This is idWidth if using a single Graphics context, else zero.
+     */
+    final int alignmentGraphicsOffset = idGraphics != alignmentGraphics ? 0 : idWidth;
 
-    int totalSeq = (pheight - scaleHeight) / av.getCharHeight() - 1;
+    FontMetrics fm = getFontMetrics(av.getFont());
+    int charHeight = av.getCharHeight();
+    int scaleHeight = charHeight + fm.getDescent();
 
-    int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;
+    idGraphics.setColor(Color.white);
+    idGraphics.fillRect(0, 0, pageWidth, pageHeight);
+    idGraphics.setFont(av.getFont());
 
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int startRes;
+    /*
+     * How many sequences and residues can we fit on a printable page?
+     */
+    int totalRes = (pageWidth - idWidth) / av.getCharWidth();
 
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int endRes;
+    int totalSeq = (pageHeight - scaleHeight) / charHeight - 1;
 
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int startSeq;
+    int alignmentWidth = av.getAlignment().getWidth();
+    int pagesWide = (alignmentWidth / totalRes) + 1;
 
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int endSeq;
-    startRes = (pi % pagesWide) * totalRes;
-    endRes = (startRes + totalRes) - 1;
+    final int startRes = (pi % pagesWide) * totalRes;
+    int endRes = (startRes + totalRes) - 1;
 
-    if (endRes > (av.getAlignment().getWidth() - 1))
+    if (endRes > (alignmentWidth - 1))
     {
-      endRes = av.getAlignment().getWidth() - 1;
+      endRes = alignmentWidth - 1;
     }
 
-    startSeq = (pi / pagesWide) * totalSeq;
-    endSeq = startSeq + totalSeq;
+    final int startSeq = (pi / pagesWide) * totalSeq;
+    int endSeq = startSeq + totalSeq;
 
-    if (endSeq > av.getAlignment().getHeight())
+    int alignmentHeight = av.getAlignment().getHeight();
+    if (endSeq > alignmentHeight)
     {
-      endSeq = av.getAlignment().getHeight();
+      endSeq = alignmentHeight;
     }
 
-    int pagesHigh = ((av.getAlignment().getHeight() / totalSeq) + 1)
-            * pheight;
+    int pagesHigh = ((alignmentHeight / totalSeq) + 1)
+            * pageHeight;
 
     if (av.isShowAnnotation())
     {
       pagesHigh += getAnnotationPanel().adjustPanelHeight() + 3;
     }
 
-    pagesHigh /= pheight;
+    pagesHigh /= pageHeight;
 
     if (pi >= (pagesWide * pagesHigh))
     {
       return Printable.NO_SUCH_PAGE;
     }
+    final int alignmentDrawnHeight = (endSeq - startSeq) * charHeight
+            + 3;
 
-    // draw Scale
-    pg.translate(idWidth, 0);
-    getScalePanel().drawScale(pg, startRes, endRes, pwidth - idWidth,
-            scaleHeight);
-    pg.translate(-idWidth, scaleHeight);
+    /*
+     * draw the Scale at horizontal offset, then reset to top left (0, 0)
+     */
+    alignmentGraphics.translate(alignmentGraphicsOffset, 0);
+    getScalePanel().drawScale(alignmentGraphics, startRes, endRes,
+            pageWidth - idWidth, scaleHeight);
+    alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
 
-    // //////////////
-    // Draw the ids
+    /*
+     * Draw the sequence ids, offset for scale height,
+     * then reset to top left (0, 0)
+     */
+    idGraphics.translate(0, scaleHeight);
+    idGraphics.setFont(getIdPanel().getIdCanvas().getIdfont());
     Color currentColor = null;
     Color currentTextColor = null;
 
-    pg.setFont(getIdPanel().getIdCanvas().getIdfont());
-
     SequenceI seq;
     for (int i = startSeq; i < endSeq; i++)
     {
@@ -1066,6 +1085,9 @@ public class AlignmentPanel extends GAlignmentPanel implements
       if ((av.getSelectionGroup() != null)
               && av.getSelectionGroup().getSequences(null).contains(seq))
       {
+        /*
+         * gray out ids of sequences in selection group (if any)
+         */
         currentColor = Color.gray;
         currentTextColor = Color.black;
       }
@@ -1075,45 +1097,58 @@ public class AlignmentPanel extends GAlignmentPanel implements
         currentTextColor = Color.black;
       }
 
-      pg.setColor(currentColor);
-      pg.fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth,
-              av.getCharHeight());
+      idGraphics.setColor(currentColor);
+      idGraphics.fillRect(0, (i - startSeq) * charHeight, idWidth,
+              charHeight);
 
-      pg.setColor(currentTextColor);
+      idGraphics.setColor(currentTextColor);
 
       int xPos = 0;
+      String displayId = seq.getDisplayId(av.getShowJVSuffix());
       if (av.isRightAlignIds())
       {
-        fm = pg.getFontMetrics();
+        fm = idGraphics.getFontMetrics();
         xPos = idWidth
-                - fm.stringWidth(seq.getDisplayId(av.getShowJVSuffix()))
+                - fm.stringWidth(displayId)
                 - 4;
       }
 
-      pg.drawString(seq.getDisplayId(av.getShowJVSuffix()), xPos,
-              (((i - startSeq) * av.getCharHeight()) + av.getCharHeight())
-                      - (av.getCharHeight() / 5));
+      idGraphics.drawString(displayId, xPos,
+              (((i - startSeq) * charHeight) + charHeight)
+                      - (charHeight / 5));
     }
+    idGraphics.setFont(av.getFont());
+    idGraphics.translate(0, -scaleHeight);
 
-    pg.setFont(av.getFont());
+    /*
+     * draw the sequences, offset for scale height, and id width (if using a
+     * single graphics context), then reset to (0, scale height)
+     */
+    alignmentGraphics.translate(alignmentGraphicsOffset, scaleHeight);
+    getSeqPanel().seqCanvas.drawPanel(alignmentGraphics, startRes, endRes,
+            startSeq, endSeq, 0);
+    alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
 
-    // draw main sequence panel
-    pg.translate(idWidth, 0);
-    getSeqPanel().seqCanvas.drawPanel(pg, startRes, endRes, startSeq,
-            endSeq, 0);
-
-    if (av.isShowAnnotation() && (endSeq == av.getAlignment().getHeight()))
-    {
-      // draw annotation - need to offset for current scroll position
-      int offset = -getAlabels().getScrollOffset();
-      pg.translate(0, offset);
-      pg.translate(-idWidth - 3, (endSeq - startSeq) * av.getCharHeight()
-              + 3);
-      getAlabels().drawComponent(pg, idWidth);
-      pg.translate(idWidth + 3, 0);
+    if (av.isShowAnnotation() && (endSeq == alignmentHeight))
+    {
+      /*
+       * draw annotation labels; drawComponent() translates by
+       * getScrollOffset(), so compensate for that first;
+       * then reset to (0, scale height)
+       */
+      int offset = getAlabels().getScrollOffset();
+      idGraphics.translate(0, -offset);
+      idGraphics.translate(0, alignmentDrawnHeight);
+      getAlabels().drawComponent(idGraphics, idWidth);
+      idGraphics.translate(0, -alignmentDrawnHeight);
+
+      /*
+       * draw the annotations starting at 
+       * (idOffset, alignmentHeight) from (0, scaleHeight)
+       */
+      alignmentGraphics.translate(alignmentGraphicsOffset, alignmentDrawnHeight);
       getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(), av,
-              pg, -1, startRes, endRes + 1);
-      pg.translate(0, -offset);
+              alignmentGraphics, -1, startRes, endRes + 1);
     }
 
     return Printable.PAGE_EXISTS;
@@ -1136,8 +1171,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @throws PrinterException
    *           DOCUMENT ME!
    */
-  public int printWrappedAlignment(Graphics pg, int pwidth, int pheight,
-          int pi) throws PrinterException
+  public int printWrappedAlignment(int pwidth, int pheight, int pi,
+          Graphics pg) throws PrinterException
   {
     int annotationHeight = 0;
     AnnotationLabels labels = null;
@@ -1264,8 +1299,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
     if (onscreen
             || (idwidth = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH")) == null)
     {
-      return (getIdPanel().getWidth() > 0 ? getIdPanel().getWidth()
-              : calculateIdWidth().width + 4);
+      int w = getIdPanel().getWidth();
+      return (w > 0 ? w : calculateIdWidth().width + 4);
     }
     return idwidth.intValue() + 4;
   }
@@ -1312,21 +1347,23 @@ public class AlignmentPanel extends GAlignmentPanel implements
                 aDimension.getWidth(), aDimension.getHeight()
                         + boarderBottomOffset, file, imageTitle,
                 alignFrame, pSessionId, headless);
+        Graphics graphics = im.getGraphics();
         if (av.getWrapAlignment())
         {
-          if (im.getGraphics() != null)
+          if (graphics != null)
           {
-            printWrappedAlignment(im.getGraphics(), aDimension.getWidth(),
-                    aDimension.getHeight() + boarderBottomOffset, 0);
+            printWrappedAlignment(aDimension.getWidth(),
+                    aDimension.getHeight() + boarderBottomOffset, 0,
+                    graphics);
             im.writeImage();
           }
         }
         else
         {
-          if (im.getGraphics() != null)
+          if (graphics != null)
           {
-            printUnwrapped(im.getGraphics(), aDimension.getWidth(),
-                    aDimension.getHeight(), 0);
+            printUnwrapped(aDimension.getWidth(), aDimension.getHeight(),
+                    0, graphics, graphics);
             im.writeImage();
           }
         }
@@ -1411,7 +1448,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
 
   public void makePNGImageMap(File imgMapFile, String imageName)
   {
-    // /////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS
+    // /////ONLY WORKS WITH NON WRAPPED ALIGNMENTS
     // ////////////////////////////////////////////
     int idWidth = getVisibleIdWidth(false);
     FontMetrics fm = getFontMetrics(av.getFont());
@@ -1425,7 +1462,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
       {
         int s, sSize = av.getAlignment().getHeight(), res, alwidth = av
                 .getAlignment().getWidth(), g, gSize, f, fSize, sy;
-        StringBuffer text = new StringBuffer();
         PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));
         out.println(jalview.io.HTMLOutput.getImageMapHTML());
         out.println("<img src=\"" + imageName
@@ -1441,7 +1477,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
           SequenceGroup[] groups = av.getAlignment().findAllGroups(seq);
           for (res = 0; res < alwidth; res++)
           {
-            text = new StringBuffer();
+            StringBuilder text = new StringBuilder();
             String triplet = null;
             if (av.getAlignment().isNucleotide())
             {
@@ -1465,18 +1501,20 @@ public class AlignmentPanel extends GAlignmentPanel implements
             {
               if (text.length() < 1)
               {
-                text.append("<area shape=\"rect\" coords=\""
-                        + (idWidth + res * av.getCharWidth()) + "," + sy
-                        + "," + (idWidth + (res + 1) * av.getCharWidth())
-                        + "," + (av.getCharHeight() + sy) + "\""
-                        + " onMouseOver=\"toolTip('" + alIndex + " "
-                        + triplet);
+                text.append("<area shape=\"rect\" coords=\"")
+                        .append((idWidth + res * av.getCharWidth()))
+                        .append(",").append(sy).append(",")
+                        .append((idWidth + (res + 1) * av.getCharWidth()))
+                        .append(",").append((av.getCharHeight() + sy))
+                        .append("\"").append(" onMouseOver=\"toolTip('")
+                        .append(alIndex).append(" ").append(triplet);
               }
 
               if (groups[g].getStartRes() < res
                       && groups[g].getEndRes() > res)
               {
-                text.append("<br><em>" + groups[g].getName() + "</em>");
+                text.append("<br><em>").append(groups[g].getName())
+                        .append("</em>");
               }
             }
 
@@ -1484,12 +1522,13 @@ public class AlignmentPanel extends GAlignmentPanel implements
             {
               if (text.length() < 1)
               {
-                text.append("<area shape=\"rect\" coords=\""
-                        + (idWidth + res * av.getCharWidth()) + "," + sy
-                        + "," + (idWidth + (res + 1) * av.getCharWidth())
-                        + "," + (av.getCharHeight() + sy) + "\""
-                        + " onMouseOver=\"toolTip('" + alIndex + " "
-                        + triplet);
+                text.append("<area shape=\"rect\" coords=\"")
+                        .append((idWidth + res * av.getCharWidth()))
+                        .append(",").append(sy).append(",")
+                        .append((idWidth + (res + 1) * av.getCharWidth()))
+                        .append(",").append((av.getCharHeight() + sy))
+                        .append("\"").append(" onMouseOver=\"toolTip('")
+                        .append(alIndex).append(" ").append(triplet);
               }
               fSize = features.length;
               for (f = 0; f < fSize; f++)
@@ -1498,15 +1537,15 @@ public class AlignmentPanel extends GAlignmentPanel implements
                 if ((features[f].getBegin() <= seq.findPosition(res))
                         && (features[f].getEnd() >= seq.findPosition(res)))
                 {
-                  if (features[f].getType().equals("disulfide bond"))
+                  if (features[f].isContactFeature())
                   {
                     if (features[f].getBegin() == seq.findPosition(res)
                             || features[f].getEnd() == seq
                                     .findPosition(res))
                     {
-                      text.append("<br>disulfide bond "
-                              + features[f].getBegin() + ":"
-                              + features[f].getEnd());
+                      text.append("<br>").append(features[f].getType())
+                              .append(" ").append(features[f].getBegin())
+                              .append(":").append(features[f].getEnd());
                     }
                   }
                   else
@@ -1517,13 +1556,13 @@ public class AlignmentPanel extends GAlignmentPanel implements
                             && !features[f].getType().equals(
                                     features[f].getDescription()))
                     {
-                      text.append(" " + features[f].getDescription());
+                      text.append(" ").append(features[f].getDescription());
                     }
 
                     if (features[f].getValue("status") != null)
                     {
-                      text.append(" (" + features[f].getValue("status")
-                              + ")");
+                      text.append(" (").append(features[f].getValue("status"))
+                              .append(")");
                     }
                   }
                 }
@@ -1788,14 +1827,14 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @param verticalOffset
    *          the number of visible sequences to show above the mapped region
    */
-  public void scrollToCentre(SearchResults sr, int verticalOffset)
+  public void scrollToCentre(SearchResultsI sr, int verticalOffset)
   {
     /*
      * To avoid jumpy vertical scrolling (if some sequences are gapped or not
      * mapped), we can make the scroll-to location a sequence above the one
      * actually mapped.
      */
-    SequenceI mappedTo = sr.getResultSequence(0);
+    SequenceI mappedTo = sr.getResults().get(0).getSequence();
     List<SequenceI> seqs = av.getAlignment().getSequences();
 
     /*
index 718e0f0..f20d0e6 100644 (file)
@@ -242,7 +242,7 @@ public class AnnotationChooser extends JPanel
    * type which are in the application scope (all, selected or unselected
    * sequences).
    * 
-   * @param type
+   * @param dataSourceType
    */
   protected void changeShowHide_actionPerformed()
   {
index 1a9541c..4b774d6 100755 (executable)
@@ -27,6 +27,7 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 import jalview.util.MessageManager;
 
@@ -979,8 +980,8 @@ public class AnnotationLabels extends JPanel implements MouseListener,
       alignmentStartEnd = av.getAlignment().getVisibleStartAndEndIndex(
               hiddenCols);
     }
-    String output = new FormatAdapter().formatSequences("Fasta", seqs,
-            omitHidden, alignmentStartEnd);
+    String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
+            seqs, omitHidden, alignmentStartEnd);
 
     Toolkit.getDefaultToolkit().getSystemClipboard()
             .setContents(new StringSelection(output), Desktop.instance);
index 199c4e5..b1f0edb 100755 (executable)
@@ -300,7 +300,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     else if (action.equals(LABEL))
     {
       String exMesg = collectAnnotVals(anot, LABEL);
-      String label = JOptionPane.showInputDialog(this,
+      String label = JvOptionPane.showInputDialog(this,
               MessageManager.getString("label.enter_label"), exMesg);
 
       if (label == null)
@@ -380,7 +380,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         aa[activeRow].hasIcons = true;
       }
 
-      String label = JOptionPane.showInputDialog(MessageManager
+      String label = JvOptionPane.showInputDialog(MessageManager
               .getString("label.enter_label_for_the_structure"), symbol);
 
       if (label == null)
index 1c0dfe6..e2e54aa 100644 (file)
@@ -50,7 +50,6 @@ import java.awt.Font;
 import java.awt.Graphics;
 import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.io.BufferedReader;
@@ -67,7 +66,6 @@ import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JColorChooser;
 import javax.swing.JInternalFrame;
 import javax.swing.JMenu;
-import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JSplitPane;
@@ -131,7 +129,7 @@ public class AppJmol extends StructureViewerBase
     // / TODO: check if protocol is needed to be set, and if chains are
     // autodiscovered.
     jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(),
-            pdbentrys, seqs, null, null);
+            pdbentrys, seqs, null);
 
     jmb.setLoadingFromArchive(true);
     addAlignmentPanel(ap);
@@ -301,7 +299,7 @@ public class AppJmol extends StructureViewerBase
   {
     progressBar = ap.alignFrame;
     jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(),
-            pdbentrys, seqs, null, null);
+            pdbentrys, seqs, null);
     addAlignmentPanel(ap);
     useAlignmentPanelForColourbyseq(ap);
     if (pdbentrys.length > 1)
@@ -394,57 +392,12 @@ public class AppJmol extends StructureViewerBase
     jmb.setFinishedInit(true);
   }
 
-  void setChainMenuItems(Vector<String> chains)
-  {
-    chainMenu.removeAll();
-    if (chains == null)
-    {
-      return;
-    }
-    JMenuItem menuItem = new JMenuItem(
-            MessageManager.getString("label.all"));
-    menuItem.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent evt)
-      {
-        allChainsSelected = true;
-        for (int i = 0; i < chainMenu.getItemCount(); i++)
-        {
-          if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
-          {
-            ((JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);
-          }
-        }
-        centerViewer();
-        allChainsSelected = false;
-      }
-    });
-
-    chainMenu.add(menuItem);
-
-    for (String chain : chains)
-    {
-      menuItem = new JCheckBoxMenuItem(chain, true);
-      menuItem.addItemListener(new ItemListener()
-      {
-        @Override
-        public void itemStateChanged(ItemEvent evt)
-        {
-          if (!allChainsSelected)
-          {
-            centerViewer();
-          }
-        }
-      });
 
-      chainMenu.add(menuItem);
-    }
-  }
 
   boolean allChainsSelected = false;
 
-  void centerViewer()
+  @Override
+  void showSelectedChains()
   {
     Vector<String> toshow = new Vector<String>();
     for (int i = 0; i < chainMenu.getItemCount(); i++)
@@ -722,11 +675,11 @@ public class AppJmol extends StructureViewerBase
     }
     if (errormsgs.length() > 0)
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.pdb_entries_couldnt_be_retrieved",
                       new String[] { errormsgs.toString() }),
               MessageManager.getString("label.couldnt_load_file"),
-              JOptionPane.ERROR_MESSAGE);
+              JvOptionPane.ERROR_MESSAGE);
     }
     return files;
   }
@@ -1075,7 +1028,7 @@ public class AppJmol extends StructureViewerBase
       repaint();
       return;
     }
-    setChainMenuItems(jmb.chainNames);
+    setChainMenuItems(jmb.getChainNames());
 
     this.setTitle(jmb.getViewerTitle());
     if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1)
index 1c54a5e..75e0c5e 100644 (file)
 package jalview.gui;
 
 import jalview.api.AlignmentViewPanel;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.io.DataSourceType;
 import jalview.structure.StructureSelectionManager;
 
 import java.awt.Container;
@@ -41,10 +43,9 @@ public class AppJmolBinding extends JalviewJmolBinding
   private FeatureRenderer fr = null;
 
   public AppJmolBinding(AppJmol appJmol, StructureSelectionManager sSm,
-          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
-          String protocol)
+          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, DataSourceType protocol)
   {
-    super(sSm, pdbentry, sequenceIs, chains, protocol);
+    super(sSm, pdbentry, sequenceIs, protocol);
     appJmolWindow = appJmol;
   }
 
@@ -113,6 +114,7 @@ public class AppJmolBinding extends JalviewJmolBinding
     // appJmolWindow.repaint();
     javax.swing.SwingUtilities.invokeLater(new Runnable()
     {
+      @Override
       public void run()
       {
         appJmolWindow.updateTitleAndMenus();
@@ -121,6 +123,7 @@ public class AppJmolBinding extends JalviewJmolBinding
     });
   }
 
+  @Override
   public void updateColours(Object source)
   {
     AlignmentPanel ap = (AlignmentPanel) source;
@@ -144,6 +147,7 @@ public class AppJmolBinding extends JalviewJmolBinding
     // msWalltime);
   }
 
+  @Override
   public void showUrl(String url)
   {
     showUrl(url, "jmol");
@@ -205,4 +209,10 @@ public class AppJmolBinding extends JalviewJmolBinding
     // TODO Auto-generated method stub
     return null;
   }
+
+  @Override
+  public JalviewStructureDisplayI getViewer()
+  {
+    return appJmolWindow;
+  }
 }
index 521bb3e..8ab1e61 100644 (file)
@@ -374,9 +374,9 @@ public class AppVarnaBinding extends JalviewVarnaBinding
 
       _sideList.ensureIndexIsVisible(index);
       /*
-       * TODO Object newName = JOptionPane.showInputDialog( this,
+       * TODO Object newName = JvOptionPane.showInputDialog( this,
        * "Specify a new name for this RNA", "Rename RNA",
-       * JOptionPane.QUESTION_MESSAGE, (Icon)null, null, item.toString()); if
+       * JvOptionPane.QUESTION_MESSAGE, (Icon)null, null, item.toString()); if
        * (newName!=null) { item.name = newName.toString();
        * this._sideList.repaint(); }
        */
index e2637a9..ddf38c6 100644 (file)
@@ -23,6 +23,7 @@ package jalview.gui;
 import jalview.api.StructureSelectionManagerProvider;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
 import jalview.io.StructureFile;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
@@ -44,7 +45,7 @@ public class AssociatePdbFileWithSeq
    * @param choice
    * @param sequence
    */
-  public PDBEntry associatePdbWithSeq(String choice, String protocol,
+  public PDBEntry associatePdbWithSeq(String choice, DataSourceType file,
           SequenceI sequence, boolean prompt,
           StructureSelectionManagerProvider ssmp)
   {
@@ -52,7 +53,7 @@ public class AssociatePdbFileWithSeq
     StructureFile pdbfile = null;
     pdbfile = StructureSelectionManager.getStructureSelectionManager(ssmp)
             .setMapping(false, new SequenceI[] { sequence }, null, choice,
-                    protocol);
+                    file);
     if (pdbfile == null)
     {
       // stacktrace already thrown so just return
@@ -64,11 +65,11 @@ public class AssociatePdbFileWithSeq
 
       if (prompt)
       {
-        reply = JOptionPane.showInternalInputDialog(Desktop.desktop,
+        reply = JvOptionPane.showInternalInputDialog(Desktop.desktop,
                 MessageManager
                         .getString("label.couldnt_find_pdb_id_in_file"),
                 MessageManager.getString("label.no_pdb_id_in_file"),
-                JOptionPane.QUESTION_MESSAGE);
+                JvOptionPane.QUESTION_MESSAGE);
       }
       if (reply == null)
       {
index c30a418..b82eef3 100644 (file)
@@ -28,9 +28,10 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.ext.rbvi.chimera.JalviewChimeraBinding;
 import jalview.gui.StructureViewer.ViewerType;
-import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
+import jalview.io.StructureFile;
 import jalview.schemes.BuriedColourScheme;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.HelixColourScheme;
@@ -46,7 +47,6 @@ import jalview.util.Platform;
 import jalview.ws.dbsources.Pdb;
 
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.io.BufferedReader;
@@ -59,16 +59,13 @@ import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.Random;
-import java.util.Set;
 import java.util.Vector;
 
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JColorChooser;
 import javax.swing.JInternalFrame;
 import javax.swing.JMenu;
-import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.event.InternalFrameAdapter;
 import javax.swing.event.InternalFrameEvent;
@@ -196,7 +193,7 @@ public class ChimeraViewFrame extends StructureViewerBase
   public ChimeraViewFrame(PDBEntry pdbentry, SequenceI[] seq,
           String[] chains, final AlignmentPanel ap)
   {
-    super();
+    this();
     String pdbId = pdbentry.getId();
 
     /*
@@ -250,10 +247,8 @@ public class ChimeraViewFrame extends StructureViewerBase
   {
     createProgressBar();
     // FIXME extractChains needs pdbentries to match IDs to PDBEntry(s) on seqs
-    String[][] chains = extractChains(seqs);
     jmb = new JalviewChimeraBindingModel(this,
-            ap.getStructureSelectionManager(), pdbentrys, seqs, chains,
-            null);
+            ap.getStructureSelectionManager(), pdbentrys, seqs, null);
     addAlignmentPanel(ap);
     useAlignmentPanelForColourbyseq(ap);
     if (pdbentrys.length > 1)
@@ -280,41 +275,7 @@ public class ChimeraViewFrame extends StructureViewerBase
 
   }
 
-  /**
-   * Retrieve chains for sequences by inspecting their PDB refs. The hope is
-   * that the first will be to the sequence's own chain. Really need a more
-   * managed way of doing this.
-   * 
-   * @param seqs
-   * @return
-   */
-  protected String[][] extractChains(SequenceI[][] seqs)
-  {
-    String[][] chains = new String[seqs.length][];
-    for (int i = 0; i < seqs.length; i++)
-    {
-      chains[i] = new String[seqs[i].length];
-      int seqno = 0;
-      for (SequenceI seq : seqs[i])
-      {
-        String chain = null;
-        if (seq.getDatasetSequence() != null)
-        {
-          Vector<PDBEntry> pdbrefs = seq.getDatasetSequence()
-                  .getAllPDBEntries();
-          if (pdbrefs != null && pdbrefs.size() > 0)
-          {
-            // FIXME: SequenceI.PDBEntry[0] chain mapping used for
-            // ChimeraViewFrame. Is this even used ???
 
-            chain = pdbrefs.get(0).getChainCode();
-          }
-        }
-        chains[i][seqno++] = chain;
-      }
-    }
-    return chains;
-  }
 
   /**
    * Create a new viewer from saved session state data including Chimera session
@@ -333,7 +294,7 @@ public class ChimeraViewFrame extends StructureViewerBase
           SequenceI[][] seqsArray, boolean colourByChimera,
           boolean colourBySequence, String newViewId)
   {
-    super();
+    this();
     setViewId(newViewId);
     this.chimeraSessionFile = chimeraSessionFile;
     openNewChimera(alignPanel, pdbArray, seqsArray);
@@ -362,31 +323,22 @@ public class ChimeraViewFrame extends StructureViewerBase
   public ChimeraViewFrame(PDBEntry[] pe, SequenceI[][] seqs,
           AlignmentPanel ap)
   {
-    super();
+    this();
     openNewChimera(ap, pe, seqs);
   }
 
-  public ChimeraViewFrame(Map<PDBEntry, List<SequenceI>> toView,
-          AlignmentPanel alignPanel)
+  /**
+   * Default constructor
+   */
+  public ChimeraViewFrame()
   {
     super();
 
     /*
-     * Convert the map of sequences per pdb entry into the tied arrays expected
-     * by openNewChimera
-     * 
-     * TODO pass the Map down to openNewChimera and its callees instead
+     * closeViewer will decide whether or not to close this frame
+     * depending on whether user chooses to Cancel or not
      */
-    final Set<PDBEntry> pdbEntries = toView.keySet();
-    PDBEntry[] pdbs = pdbEntries.toArray(new PDBEntry[pdbEntries.size()]);
-    SequenceI[][] seqsForPdbs = new SequenceI[pdbEntries.size()][];
-    for (int i = 0; i < pdbs.length; i++)
-    {
-      final List<SequenceI> seqsForPdb = toView.get(pdbs[i]);
-      seqsForPdbs[i] = seqsForPdb.toArray(new SequenceI[seqsForPdb.size()]);
-    }
-
-    openNewChimera(alignPanel, pdbs, seqsForPdbs);
+    setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
   }
 
   /**
@@ -425,10 +377,10 @@ public class ChimeraViewFrame extends StructureViewerBase
 
     if (!jmb.launchChimera())
     {
-      JOptionPane.showMessageDialog(Desktop.desktop,
+      JvOptionPane.showMessageDialog(Desktop.desktop,
               MessageManager.getString("label.chimera_failed"),
               MessageManager.getString("label.error_loading_file"),
-              JOptionPane.ERROR_MESSAGE);
+              JvOptionPane.ERROR_MESSAGE);
       this.dispose();
       return;
     }
@@ -448,63 +400,11 @@ public class ChimeraViewFrame extends StructureViewerBase
     jmb.startChimeraListener();
   }
 
-  /**
-   * If the list is not empty, add menu items for 'All' and each individual
-   * chain to the "View | Show Chain" sub-menu. Multiple selections are allowed.
-   * 
-   * @param chainNames
-   */
-  void setChainMenuItems(List<String> chainNames)
-  {
-    chainMenu.removeAll();
-    if (chainNames == null || chainNames.isEmpty())
-    {
-      return;
-    }
-    JMenuItem menuItem = new JMenuItem(
-            MessageManager.getString("label.all"));
-    menuItem.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent evt)
-      {
-        allChainsSelected = true;
-        for (int i = 0; i < chainMenu.getItemCount(); i++)
-        {
-          if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
-          {
-            ((JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);
-          }
-        }
-        showSelectedChains();
-        allChainsSelected = false;
-      }
-    });
-
-    chainMenu.add(menuItem);
-
-    for (String chainName : chainNames)
-    {
-      menuItem = new JCheckBoxMenuItem(chainName, true);
-      menuItem.addItemListener(new ItemListener()
-      {
-        @Override
-        public void itemStateChanged(ItemEvent evt)
-        {
-          if (!allChainsSelected)
-          {
-            showSelectedChains();
-          }
-        }
-      });
-
-      chainMenu.add(menuItem);
-    }
-  }
 
   /**
    * Show only the selected chain(s) in the viewer
    */
+  @Override
   void showSelectedChains()
   {
     List<String> toshow = new ArrayList<String>();
@@ -541,10 +441,18 @@ public class ChimeraViewFrame extends StructureViewerBase
                 "label.confirm_close_chimera",
                 new Object[] { jmb.getViewerTitle("Chimera", false) });
         prompt = JvSwingUtils.wrapTooltip(true, prompt);
-        int confirm = JOptionPane.showConfirmDialog(this, prompt,
+        int confirm = JvOptionPane.showConfirmDialog(this, prompt,
                 MessageManager.getString("label.close_viewer"),
-                JOptionPane.YES_NO_OPTION);
-        closeChimera = confirm == JOptionPane.YES_OPTION;
+                JvOptionPane.YES_NO_CANCEL_OPTION);
+        /*
+         * abort closure if user hits escape or Cancel
+         */
+        if (confirm == JvOptionPane.CANCEL_OPTION
+                || confirm == JvOptionPane.CLOSED_OPTION)
+        {
+          return;
+        }
+        closeChimera = confirm == JvOptionPane.YES_OPTION;
       }
       jmb.closeViewer(closeChimera);
     }
@@ -555,6 +463,7 @@ public class ChimeraViewFrame extends StructureViewerBase
     // TODO: check for memory leaks where instance isn't finalised because jmb
     // holds a reference to the window
     jmb = null;
+    dispose();
   }
 
   /**
@@ -571,6 +480,7 @@ public class ChimeraViewFrame extends StructureViewerBase
     List<PDBEntry> filePDB = new ArrayList<PDBEntry>();
     List<Integer> filePDBpos = new ArrayList<Integer>();
     PDBEntry thePdbEntry = null;
+    StructureFile pdb = null;
     try
     {
       String[] curfiles = jmb.getPdbFile(); // files currently in viewer
@@ -631,11 +541,11 @@ public class ChimeraViewFrame extends StructureViewerBase
     if (errormsgs.length() > 0)
     {
 
-      JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.pdb_entries_couldnt_be_retrieved",
                       new Object[] { errormsgs.toString() }),
               MessageManager.getString("label.couldnt_load_file"),
-              JOptionPane.ERROR_MESSAGE);
+              JvOptionPane.ERROR_MESSAGE);
     }
 
     if (files.length() > 0)
@@ -665,12 +575,12 @@ public class ChimeraViewFrame extends StructureViewerBase
             jmb.openFile(pe);
             jmb.addSequence(pos, jmb.getSequence()[pos]);
             File fl = new File(pe.getFile());
-            String protocol = AppletFormatAdapter.URL;
+            DataSourceType protocol = DataSourceType.URL;
             try
             {
               if (fl.exists())
               {
-                protocol = AppletFormatAdapter.FILE;
+                protocol = DataSourceType.FILE;
               }
             } catch (Throwable e)
             {
@@ -679,8 +589,9 @@ public class ChimeraViewFrame extends StructureViewerBase
               stopProgressBar("", startTime);
             }
             // Explicitly map to the filename used by Chimera ;
-            jmb.getSsm().setMapping(jmb.getSequence()[pos],
+            pdb = jmb.getSsm().setMapping(jmb.getSequence()[pos],
                     jmb.getChains()[pos], pe.getFile(), protocol);
+            stashFoundChains(pdb, pe.getFile());
           } catch (OutOfMemoryError oomerror)
           {
             new OOMWarning(
@@ -696,6 +607,7 @@ public class ChimeraViewFrame extends StructureViewerBase
           }
         }
       }
+      jmb.refreshGUI();
       jmb.setFinishedInit(true);
       jmb.setLoadingFromArchive(false);
 
@@ -731,6 +643,17 @@ public class ChimeraViewFrame extends StructureViewerBase
    * @return
    * @throws Exception
    */
+
+  private void stashFoundChains(StructureFile pdb, String file)
+  {
+    for (int i = 0; i < pdb.getChains().size(); i++)
+    {
+      String chid = new String(pdb.getId() + ":"
+              + pdb.getChains().elementAt(i).id);
+      jmb.getChainNames().add(chid);
+      jmb.getChainFile().put(chid, file);
+    }
+  }
   private String fetchPdbFile(PDBEntry processingEntry) throws Exception
   {
     // FIXME: this is duplicated code with Jmol frame ?
index 32af226..7768b22 100644 (file)
@@ -121,10 +121,10 @@ public class CrossRefAction implements Runnable
                   xrefsAlignment.getSequencesArray());
           if (copyAlignment.getHeight() == 0)
           {
-            JOptionPane.showMessageDialog(alignFrame,
+            JvOptionPane.showMessageDialog(alignFrame,
                     MessageManager.getString("label.cant_map_cds"),
                     MessageManager.getString("label.operation_failed"),
-                    JOptionPane.OK_OPTION);
+                    JvOptionPane.OK_OPTION);
             System.err.println("Failed to make CDS alignment");
           }
 
index ed2b9bf..df0142c 100644 (file)
@@ -30,8 +30,11 @@ import jalview.bin.Jalview;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.SequenceI;
+import jalview.io.AlignmentFileI;
 import jalview.io.AppletFormatAdapter;
-import jalview.io.FileParse;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormatException;
+import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
 import jalview.io.IdentifyFile;
 import jalview.io.JalviewFileChooser;
@@ -49,9 +52,11 @@ import java.awt.datatransfer.Transferable;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.MouseEvent;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
 
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 import javax.swing.JPopupMenu;
 import javax.swing.SwingUtilities;
 
@@ -68,7 +73,7 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer
 
   AlignViewportI viewport;
 
-  FileParse source = null;
+  AlignmentFileI source = null;
 
   public CutAndPasteTransfer()
   {
@@ -145,8 +150,8 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer
     {
       try
       {
-        java.io.PrintWriter out = new java.io.PrintWriter(
-                new java.io.FileWriter(chooser.getSelectedFile()));
+        PrintWriter out = new PrintWriter(new FileWriter(
+                chooser.getSelectedFile()));
 
         out.print(getText());
         out.close();
@@ -213,17 +218,24 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer
       return;
     }
 
-    String format = new IdentifyFile().identify(text, "Paste");
-    if (format == null || format.equalsIgnoreCase("EMPTY DATA FILE"))
+    FileFormatI format = null;
+    try
+    {
+      format = new IdentifyFile().identify(text, DataSourceType.PASTE);
+    } catch (FileFormatException e1)
+    {
+      // leave as null
+    }
+    if (format == null)
     {
       System.err.println(MessageManager
               .getString("label.couldnt_read_data"));
       if (!Jalview.isHeadlessMode())
       {
-        javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                 AppletFormatAdapter.SUPPORTED_FORMATS,
                 MessageManager.getString("label.couldnt_read_data"),
-                JOptionPane.WARNING_MESSAGE);
+                JvOptionPane.WARNING_MESSAGE);
       }
       return;
     }
@@ -231,29 +243,26 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer
     // TODO: identify feature, annotation or tree file and parse appropriately.
     AlignmentI al = null;
 
-    if (FormatAdapter.isValidFormat(format))
+    try
     {
-      try
-      {
-        FormatAdapter fa = new FormatAdapter(alignpanel);
-        al = fa.readFile(getText(), "Paste", format);
-        source = fa.getAlignFile();
+      FormatAdapter fa = new FormatAdapter(alignpanel);
+      al = fa.readFile(getText(), DataSourceType.PASTE, format);
+      source = fa.getAlignFile();
 
-      } catch (java.io.IOException ex)
-      {
-        JOptionPane.showInternalMessageDialog(Desktop.desktop,
-                MessageManager.formatMessage(
-                        "label.couldnt_read_pasted_text",
-                        new String[] { ex.toString() }), MessageManager
-                        .getString("label.error_parsing_text"),
-                JOptionPane.WARNING_MESSAGE);
-      }
+    } catch (IOException ex)
+    {
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+              .formatMessage("label.couldnt_read_pasted_text", new String[]
+              { ex.toString() }), MessageManager
+              .getString("label.error_parsing_text"),
+              JvOptionPane.WARNING_MESSAGE);
     }
 
     if (al != null && al.hasValidSequence())
     {
       String title = MessageManager.formatMessage(
-              "label.input_cut_paste_params", new String[] { format });
+              "label.input_cut_paste_params",
+              new String[] { format.toString() });
       FeatureSettingsModelI proxyColourScheme = source
               .getFeatureColourScheme();
 
@@ -330,10 +339,10 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer
               .getString("label.couldnt_read_data"));
       if (!Jalview.isHeadlessMode())
       {
-        javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                 AppletFormatAdapter.SUPPORTED_FORMATS,
                 MessageManager.getString("label.couldnt_read_data"),
-                JOptionPane.WARNING_MESSAGE);
+                JvOptionPane.WARNING_MESSAGE);
       }
     }
   }
index e677084..8c8f228 100644 (file)
@@ -459,12 +459,12 @@ public class DasSourceBrowser extends GDasSourceBrowser implements
     pane12.add(urltf, BorderLayout.EAST);
     panel.add(pane12, BorderLayout.SOUTH);
 
-    int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+    int reply = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
             panel,
             MessageManager.getString("label.enter_local_das_source"),
-            JOptionPane.OK_CANCEL_OPTION);
+            JvOptionPane.OK_CANCEL_OPTION);
 
-    if (reply != JOptionPane.OK_OPTION)
+    if (reply != JvOptionPane.OK_OPTION)
     {
       return;
     }
@@ -534,21 +534,21 @@ public class DasSourceBrowser extends GDasSourceBrowser implements
 
     if (!sourceRegistry.getSource(nickname).isLocal())
     {
-      JOptionPane
+      JvOptionPane
               .showInternalMessageDialog(
                       Desktop.desktop,
                       MessageManager
                               .getString("label.you_can_only_edit_or_remove_local_das_sources"),
                       MessageManager.getString("label.public_das_source"),
-                      JOptionPane.WARNING_MESSAGE);
+                      JvOptionPane.WARNING_MESSAGE);
       return;
     }
 
     Object[] options = { "Edit", "Remove", "Cancel" };
-    int choice = JOptionPane.showInternalOptionDialog(Desktop.desktop,
+    int choice = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
             "Do you want to edit or remove " + nickname + "?",
             "Edit / Remove Local DAS Source",
-            JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,
+            JvOptionPane.YES_NO_CANCEL_OPTION, JvOptionPane.QUESTION_MESSAGE,
             null, options, options[2]);
 
     switch (choice)
index 3f457ea..ac957d8 100644 (file)
  */
 package jalview.gui;
 
+import static jalview.util.UrlConstants.EMBLEBI_STRING;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.bin.Cache;
 import jalview.bin.Jalview;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatException;
+import jalview.io.FileFormatI;
 import jalview.io.FileLoader;
-import jalview.io.FormatAdapter;
 import jalview.io.IdentifyFile;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
@@ -75,6 +81,7 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.StringTokenizer;
 import java.util.Vector;
 import java.util.concurrent.ExecutorService;
@@ -82,9 +89,12 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Semaphore;
 
 import javax.swing.AbstractAction;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
 import javax.swing.DefaultDesktopManager;
 import javax.swing.DesktopManager;
 import javax.swing.JButton;
+import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
 import javax.swing.JDesktopPane;
@@ -92,7 +102,6 @@ import javax.swing.JFrame;
 import javax.swing.JInternalFrame;
 import javax.swing.JLabel;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JPopupMenu;
 import javax.swing.JProgressBar;
@@ -382,6 +391,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
     showNews.setVisible(false);
 
+    checkURLLinks();
+
     this.addWindowListener(new WindowAdapter()
     {
       @Override
@@ -443,7 +454,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       }
     });
 
-    // displayed.
     // Thread off a new instance of the file chooser - this reduces the time it
     // takes to open it later on.
     new Thread(new Runnable()
@@ -452,11 +462,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       public void run()
       {
         Cache.log.debug("Filechooser init thread started.");
-        new JalviewFileChooser(
-                jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-                jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
-                jalview.io.AppletFormatAdapter.READABLE_FNAMES,
-                jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
+        String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
+        JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
+                fileFormat);
         Cache.log.debug("Filechooser init thread finished.");
       }
     }).start();
@@ -676,10 +684,10 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         String file = (String) contents
                 .getTransferData(DataFlavor.stringFlavor);
 
-        String format = new IdentifyFile().identify(file,
-                FormatAdapter.PASTE);
+        FileFormatI format = new IdentifyFile().identify(file,
+                DataSourceType.PASTE);
 
-        new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
+        new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
 
       }
     } catch (Exception ex)
@@ -882,9 +890,10 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       }
     });
 
+    desktop.add(frame);
+
     windowMenu.add(menuItem);
 
-    desktop.add(frame);
     frame.toFront();
     try
     {
@@ -945,8 +954,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     // Java's Transferable for native dnd
     evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
     Transferable t = evt.getTransferable();
-    java.util.List<String> files = new ArrayList<String>();
-    java.util.List<String> protocols = new ArrayList<String>();
+    List<String> files = new ArrayList<String>();
+    List<DataSourceType> protocols = new ArrayList<DataSourceType>();
 
     try
     {
@@ -964,13 +973,13 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         for (int i = 0; i < files.size(); i++)
         {
           String file = files.get(i).toString();
-          String protocol = (protocols == null) ? FormatAdapter.FILE
-                  : (String) protocols.get(i);
-          String format = null;
+          DataSourceType protocol = (protocols == null) ? DataSourceType.FILE
+                  : protocols.get(i);
+          FileFormatI format = null;
 
           if (file.endsWith(".jar"))
           {
-            format = "Jalview";
+            format = FileFormat.Jalview;
 
           }
           else
@@ -999,11 +1008,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   @Override
   public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
   {
-    JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
-            jalview.io.AppletFormatAdapter.READABLE_FNAMES,
-            jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
+    String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
+    JalviewFileChooser chooser = JalviewFileChooser.forRead(
+            Cache.getProperty("LAST_DIRECTORY"), fileFormat);
 
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
@@ -1015,28 +1022,34 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     if (value == JalviewFileChooser.APPROVE_OPTION)
     {
       String choice = chooser.getSelectedFile().getPath();
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
+      Cache.setProperty("LAST_DIRECTORY", chooser
               .getSelectedFile().getParent());
 
-      String format = null;
-      if (chooser.getSelectedFormat() != null
-              && chooser.getSelectedFormat().equals("Jalview"))
+      FileFormatI format = null;
+      FileFormatI selectedFormat = chooser.getSelectedFormat();
+      if (FileFormat.Jalview.equals(selectedFormat))
       {
-        format = "Jalview";
+        format = FileFormat.Jalview;
       }
       else
       {
-        format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
+        try
+        {
+          format = new IdentifyFile().identify(choice, DataSourceType.FILE);
+        } catch (FileFormatException e)
+        {
+          // format is null
+        }
       }
 
       if (viewport != null)
       {
-        new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
+        new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
                 format);
       }
       else
       {
-        new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
+        new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
       }
     }
   }
@@ -1077,11 +1090,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       }
     }
 
-    int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
+    int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
             MessageManager.getString("label.input_alignment_from_url"),
-            JOptionPane.OK_CANCEL_OPTION);
+            JvOptionPane.OK_CANCEL_OPTION);
 
-    if (reply != JOptionPane.OK_OPTION)
+    if (reply != JvOptionPane.OK_OPTION)
     {
       return;
     }
@@ -1092,36 +1105,46 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     {
       if (viewport != null)
       {
-        new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
-                "Jalview");
+        new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
+                FileFormat.Jalview);
       }
       else
       {
-        new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
+        new FileLoader().LoadFile(url, DataSourceType.URL,
+                FileFormat.Jalview);
       }
     }
     else
     {
-      String format = new IdentifyFile().identify(url, FormatAdapter.URL);
+      FileFormatI format = null;
+      try
+      {
+        format = new IdentifyFile().identify(url, DataSourceType.URL);
+      } catch (FileFormatException e)
+      {
+        // TODO revise error handling, distinguish between
+        // URL not found and response not valid
+      }
 
-      if (format.equals("URL NOT FOUND"))
+      if (format == null)
       {
-        JOptionPane.showInternalMessageDialog(Desktop.desktop,
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                 MessageManager.formatMessage("label.couldnt_locate",
                         new Object[] { url }), MessageManager
                         .getString("label.url_not_found"),
-                JOptionPane.WARNING_MESSAGE);
+                JvOptionPane.WARNING_MESSAGE);
 
         return;
       }
 
       if (viewport != null)
       {
-        new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
+        new FileLoader()
+                .LoadFile(viewport, url, DataSourceType.URL, format);
       }
       else
       {
-        new FileLoader().LoadFile(url, FormatAdapter.URL, format);
+        new FileLoader().LoadFile(url, DataSourceType.URL, format);
       }
     }
   }
@@ -1205,9 +1228,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   public void aboutMenuItem_actionPerformed(ActionEvent e)
   {
     // StringBuffer message = getAboutMessage(false);
-    // JOptionPane.showInternalMessageDialog(Desktop.desktop,
+    // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
     //
-    // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
+    // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
     new Thread(new Runnable()
     {
       @Override
@@ -1507,9 +1530,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   public void saveState_actionPerformed(ActionEvent e)
   {
     JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "jvp" }, new String[] { "Jalview Project" },
-            "Jalview Project");
+            Cache.getProperty("LAST_DIRECTORY"), "jvp", "Jalview Project");
 
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager.getString("label.save_state"));
@@ -1547,11 +1568,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements
             Cache.log.error(
                     "Problems whilst trying to save to " + choice.getName(),
                     ex);
-            JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
+            JvOptionPane.showMessageDialog(me, MessageManager.formatMessage(
                     "label.error_whilst_saving_current_state_to",
                     new Object[] { choice.getName() }), MessageManager
                     .getString("label.couldnt_save_project"),
-                    JOptionPane.WARNING_MESSAGE);
+                    JvOptionPane.WARNING_MESSAGE);
           }
           setProgressBar(null, choice.hashCode());
         }
@@ -1579,7 +1600,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   public void loadState_actionPerformed(ActionEvent e)
   {
     JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
+            Cache.getProperty("LAST_DIRECTORY"), new String[] {
                 "jvp", "jar" }, new String[] { "Jalview Project",
                 "Jalview Project (old)" }, "Jalview Project");
     chooser.setFileView(new JalviewFileView());
@@ -1592,7 +1613,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       final File selectedFile = chooser.getSelectedFile();
       setProjectFile(selectedFile);
       final String choice = selectedFile.getAbsolutePath();
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY",
+      Cache.setProperty("LAST_DIRECTORY",
               selectedFile.getParent());
       new Thread(new Runnable()
       {
@@ -1613,12 +1634,12 @@ public class Desktop extends jalview.jbgui.GDesktop implements
           {
             Cache.log.error("Problems whilst loading project from "
                     + choice, ex);
-            JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+            JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
                     .formatMessage(
                             "label.error_whilst_loading_project_from",
                             new Object[] { choice }), MessageManager
                     .getString("label.couldnt_load_project"),
-                    JOptionPane.WARNING_MESSAGE);
+                    JvOptionPane.WARNING_MESSAGE);
           }
           setProgressBar(null, choice.hashCode());
         }
@@ -1903,7 +1924,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         String fle = chooser.getSelectedFile().toString();
         if (!vamsasImport(chooser.getSelectedFile()))
         {
-          JOptionPane
+          JvOptionPane
                   .showInternalMessageDialog(
                           Desktop.desktop,
                           MessageManager.formatMessage(
@@ -1911,7 +1932,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
                                   new Object[] { fle }),
                           MessageManager
                                   .getString("label.vamsas_document_import_failed"),
-                          JOptionPane.ERROR_MESSAGE);
+                          JvOptionPane.ERROR_MESSAGE);
         }
       }
     }
@@ -2163,9 +2184,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     if (v_client != null)
     {
       JalviewFileChooser chooser = new JalviewFileChooser(
-              jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
-              { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
-              new String[] { "Vamsas Document" }, "Vamsas Document");
+              Cache.getProperty("LAST_DIRECTORY"), "vdj",// TODO: VAMSAS DOCUMENT EXTENSION is VDJ
+              "Vamsas Document");
 
       chooser.setFileView(new JalviewFileView());
       chooser.setDialogTitle(MessageManager
@@ -2179,7 +2199,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
                 "label.saving_vamsas_doc",
                 new Object[] { choice.getName() }));
-        jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
+        Cache.setProperty("LAST_DIRECTORY", choice.getParent());
         String warnmsg = null;
         String warnttl = null;
         try
@@ -2203,9 +2223,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         removeProgressPanel(progpanel);
         if (warnmsg != null)
         {
-          JOptionPane.showInternalMessageDialog(Desktop.desktop,
+          JvOptionPane.showInternalMessageDialog(Desktop.desktop,
 
-          warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
+          warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
         }
       }
     }
@@ -2221,7 +2241,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    */
   public void setVamsasUpdate(boolean b)
   {
-    jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
+    Cache.log.debug("Setting gui for Vamsas update "
             + (b ? "in progress" : "finished"));
 
     if (vamUpdate != null)
@@ -2256,6 +2276,84 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     new Thread(jvq).start();
   }
 
+  public void checkURLLinks()
+  {
+    // Thread off the URL link checker
+    addDialogThread(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        if (Cache.getDefault("CHECKURLLINKS", true))
+        {
+          // check what the actual links are - if it's just the default don't
+          // bother with the warning
+          Vector<String> links = Preferences.sequenceURLLinks;
+
+          // only need to check links if there is one with a
+          // SEQUENCE_ID which is not the default EMBL_EBI link
+          ListIterator<String> li = links.listIterator();
+          boolean check = false;
+          List<JLabel> urls = new ArrayList<JLabel>();
+          while (li.hasNext())
+          {
+            String link = li.next();
+            if (link.contains(SEQUENCE_ID) && !link.equals(EMBLEBI_STRING))
+            {
+              check = true;
+              int barPos = link.indexOf("|");
+              String urlMsg = barPos == -1 ? link : link.substring(0,
+                      barPos) + ": " + link.substring(barPos + 1);
+              urls.add(new JLabel(urlMsg));
+            }
+          }
+          if (!check)
+          {
+            return;
+          }
+
+          // ask user to check in case URL links use old style tokens
+          // ($SEQUENCE_ID$ for sequence id _or_ accession id)
+          JPanel msgPanel = new JPanel();
+          msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
+          msgPanel.add(Box.createVerticalGlue());
+          JLabel msg = new JLabel(
+                  MessageManager
+                          .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
+          JLabel msg2 = new JLabel(
+                  MessageManager
+                          .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
+          msgPanel.add(msg);
+          for (JLabel url : urls)
+          {
+            msgPanel.add(url);
+          }
+          msgPanel.add(msg2);
+
+          final JCheckBox jcb = new JCheckBox(
+                  MessageManager.getString("label.do_not_display_again"));
+          jcb.addActionListener(new ActionListener()
+          {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+              // update Cache settings for "don't show this again"
+              boolean showWarningAgain = !jcb.isSelected();
+              Cache.setProperty("CHECKURLLINKS",
+                      Boolean.valueOf(showWarningAgain).toString());
+            }
+          });
+          msgPanel.add(jcb);
+
+          JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
+                  MessageManager
+                          .getString("label.SEQUENCE_ID_no_longer_used"),
+                  JvOptionPane.WARNING_MESSAGE);
+        }
+      }
+    });
+    }
+
   /**
    * Proxy class for JDesktopPane which optionally displays the current memory
    * usage and highlights the desktop area with a red bar if free memory runs
@@ -2457,11 +2555,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     } catch (Exception ex)
     {
       jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
-      JOptionPane.showInternalMessageDialog(Desktop.desktop,
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop,
 
       MessageManager.getString("label.couldnt_create_groovy_shell"),
               MessageManager.getString("label.groovy_support_failed"),
-              JOptionPane.ERROR_MESSAGE);
+              JvOptionPane.ERROR_MESSAGE);
     }
   }
 
@@ -2802,7 +2900,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
                  * 
                  * jd.waitForInput();
                  */
-                JOptionPane
+                JvOptionPane
                         .showConfirmDialog(
                                 Desktop.desktop,
                                 new JLabel(
@@ -2814,8 +2912,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
                                                 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
                                                 + " Tools->Preferences dialog box to change them.</p></html>"),
                                 "Web Service Configuration Problem",
-                                JOptionPane.DEFAULT_OPTION,
-                                JOptionPane.ERROR_MESSAGE);
+                                JvOptionPane.DEFAULT_OPTION,
+                                JvOptionPane.ERROR_MESSAGE);
                 serviceChangedDialog = null;
 
               }
@@ -2872,11 +2970,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements
           jalview.util.BrowserLauncher.openURL(url);
         } catch (Exception ex)
         {
-          JOptionPane.showInternalMessageDialog(Desktop.desktop,
+          JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                   MessageManager
                           .getString("label.web_browser_not_found_unix"),
                   MessageManager.getString("label.web_browser_not_found"),
-                  JOptionPane.WARNING_MESSAGE);
+                  JvOptionPane.WARNING_MESSAGE);
 
           ex.printStackTrace();
         }
@@ -3173,7 +3271,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   }
 
   public static void transferFromDropTarget(List<String> files,
-          List<String> protocols, DropTargetDropEvent evt, Transferable t)
+          List<DataSourceType> protocols, DropTargetDropEvent evt,
+          Transferable t)
           throws Exception
   {
 
@@ -3187,7 +3286,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
               .getTransferData(DataFlavor.javaFileListFlavor))
       {
         files.add(((File) file).toString());
-        protocols.add(FormatAdapter.FILE);
+        protocols.add(DataSourceType.FILE);
       }
     }
     else
@@ -3217,7 +3316,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       {
         Cache.log.debug("Adding missing FILE protocol for "
                 + files.get(protocols.size()));
-        protocols.add(FormatAdapter.FILE);
+        protocols.add(DataSourceType.FILE);
       }
       for (java.util.StringTokenizer st = new java.util.StringTokenizer(
               data, "\r\n"); st.hasMoreTokens();)
@@ -3232,14 +3331,14 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         java.net.URI uri = new java.net.URI(s);
         if (uri.getScheme().toLowerCase().startsWith("http"))
         {
-          protocols.add(FormatAdapter.URL);
+          protocols.add(DataSourceType.URL);
           files.add(uri.toString());
         }
         else
         {
           // otherwise preserve old behaviour: catch all for file objects
           java.io.File file = new java.io.File(uri);
-          protocols.add(FormatAdapter.FILE);
+          protocols.add(DataSourceType.FILE);
           files.add(file.toString());
         }
       }
index 69fde89..fa67999 100644 (file)
@@ -58,8 +58,8 @@ public class EPSOptions extends JPanel
     bg.add(lineart);
     bg.add(text);
 
-    JOptionPane pane = new JOptionPane(null, JOptionPane.DEFAULT_OPTION,
-            JOptionPane.DEFAULT_OPTION, null, new Object[] { this });
+    JOptionPane pane = new JOptionPane(null, JvOptionPane.DEFAULT_OPTION,
+            JvOptionPane.DEFAULT_OPTION, null, new Object[] { this });
 
     dialog = pane.createDialog(Desktop.desktop, "EPS Rendering options");
     dialog.setVisible(true);
@@ -78,6 +78,7 @@ public class EPSOptions extends JPanel
     ok.setText(MessageManager.getString("action.ok"));
     ok.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         ok_actionPerformed(e);
@@ -86,6 +87,7 @@ public class EPSOptions extends JPanel
     cancel.setText(MessageManager.getString("action.cancel"));
     cancel.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         cancel_actionPerformed(e);
index baad794..0ec4a87 100644 (file)
@@ -80,13 +80,13 @@ public class EditNameDialog
       panel2.add(description, BorderLayout.CENTER);
       panel.add(panel2, BorderLayout.SOUTH);
     }
-    int reply = JOptionPane.showInternalConfirmDialog(parent, panel, title,
-            JOptionPane.OK_CANCEL_OPTION);
+    int reply = JvOptionPane.showInternalConfirmDialog(parent, panel, title,
+            JvOptionPane.OK_CANCEL_OPTION);
     if (!parent.requestFocusInWindow())
     {
       System.err.println("Bad focus for dialog!");
     }
-    if (reply == JOptionPane.OK_OPTION)
+    if (reply == JvOptionPane.OK_OPTION)
     {
       accept = true;
     }
index 426ea32..ae911ed 100644 (file)
@@ -22,6 +22,7 @@ package jalview.gui;
 
 import jalview.api.FeatureColourI;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.FeatureColour;
@@ -200,7 +201,7 @@ public class FeatureRenderer extends
             start.setValue(new Integer(features[index].getBegin()));
             end.setValue(new Integer(features[index].getEnd()));
 
-            SearchResults highlight = new SearchResults();
+            SearchResultsI highlight = new SearchResults();
             highlight.addResult(sequences[0], features[index].getBegin(),
                     features[index].getEnd());
 
@@ -329,14 +330,14 @@ public class FeatureRenderer extends
             : MessageManager.formatMessage("label.amend_delete_features",
                     new String[] { sequences[0].getName() });
 
-    int reply = JOptionPane.showInternalOptionDialog(Desktop.desktop,
-            bigPanel, title, JOptionPane.YES_NO_CANCEL_OPTION,
-            JOptionPane.QUESTION_MESSAGE, null, options,
+    int reply = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
+            bigPanel, title, JvOptionPane.YES_NO_CANCEL_OPTION,
+            JvOptionPane.QUESTION_MESSAGE, null, options,
             MessageManager.getString("action.ok"));
 
     jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile();
 
-    if (reply == JOptionPane.OK_OPTION && name.getText().length() > 0)
+    if (reply == JvOptionPane.OK_OPTION && name.getText().length() > 0)
     {
       // This ensures that the last sequence
       // is refreshed and new features are rendered
@@ -355,11 +356,11 @@ public class FeatureRenderer extends
     {
       SequenceFeature sf = features[featureIndex];
 
-      if (reply == JOptionPane.NO_OPTION)
+      if (reply == JvOptionPane.NO_OPTION)
       {
         sequences[0].getDatasetSequence().deleteFeature(sf);
       }
-      else if (reply == JOptionPane.YES_OPTION)
+      else if (reply == JvOptionPane.YES_OPTION)
       {
         sf.type = lastFeatureAdded;
         sf.featureGroup = lastFeatureGroupAdded;
@@ -382,7 +383,7 @@ public class FeatureRenderer extends
     else
     // NEW FEATURES ADDED
     {
-      if (reply == JOptionPane.OK_OPTION && lastFeatureAdded.length() > 0)
+      if (reply == JvOptionPane.OK_OPTION && lastFeatureAdded.length() > 0)
       {
         for (int i = 0; i < sequences.length; i++)
         {
index 15f3e5b..bb5f13c 100644 (file)
@@ -27,6 +27,7 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.Help.HelpId;
 import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
 import jalview.schemabinding.version2.JalviewUserColours;
 import jalview.schemes.FeatureColour;
 import jalview.util.Format;
@@ -79,7 +80,6 @@ import javax.swing.JInternalFrame;
 import javax.swing.JLabel;
 import javax.swing.JLayeredPane;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
@@ -749,11 +749,9 @@ public class FeatureSettings extends JPanel implements
   void load()
   {
     JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "fc" },
-            new String[] { "Sequence Feature Colours" },
+            Cache.getProperty("LAST_DIRECTORY"), "fc",
             "Sequence Feature Colours");
-    chooser.setFileView(new jalview.io.JalviewFileView());
+    chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
             .getString("label.load_feature_colours"));
     chooser.setToolTipText(MessageManager.getString("action.load"));
@@ -818,8 +816,8 @@ public class FeatureSettings extends JPanel implements
           }
           else
           {
-            Color color = new Color(Integer.parseInt(jucs.getColour(i)
-                    .getRGB(), 16));
+            Color color = new Color(
+                    Integer.parseInt(jucs.getColour(i).getRGB(), 16));
             fr.setColour(name = jucs.getColour(i).getName(),
                     new FeatureColour(color));
           }
@@ -844,10 +842,9 @@ public class FeatureSettings extends JPanel implements
   void save()
   {
     JalviewFileChooser chooser = new JalviewFileChooser(
-            Cache.getProperty("LAST_DIRECTORY"), new String[] { "fc" },
-            new String[] { "Sequence Feature Colours" },
+            Cache.getProperty("LAST_DIRECTORY"), "fc",
             "Sequence Feature Colours");
-    chooser.setFileView(new jalview.io.JalviewFileView());
+    chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
             .getString("label.save_feature_colours"));
     chooser.setToolTipText(MessageManager.getString("action.save"));
@@ -1402,15 +1399,15 @@ public class FeatureSettings extends JPanel implements
   public void noDasSourceActive()
   {
     complete();
-    JOptionPane
+    JvOptionPane
             .showInternalConfirmDialog(
                     Desktop.desktop,
                     MessageManager
                             .getString("label.no_das_sources_selected_warn"),
                     MessageManager
                             .getString("label.no_das_sources_selected_title"),
-                    JOptionPane.DEFAULT_OPTION,
-                    JOptionPane.INFORMATION_MESSAGE);
+                    JvOptionPane.DEFAULT_OPTION,
+                    JvOptionPane.INFORMATION_MESSAGE);
   }
 
   // ///////////////////////////////////////////////////////////////////////
index 6bff69a..af23ceb 100755 (executable)
@@ -20,7 +20,8 @@
  */
 package jalview.gui;
 
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.jbgui.GFinder;
@@ -67,7 +68,7 @@ public class Finder extends GFinder
 
   int resIndex = -1;
 
-  SearchResults searchResults;
+  SearchResultsI searchResults;
 
   /**
    * Creates a new Finder object with no associated viewport or panel.
@@ -109,6 +110,7 @@ public class Finder extends GFinder
             KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "Cancel");
     getRootPane().getActionMap().put("Cancel", new AbstractAction()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         escapeActionPerformed();
@@ -130,6 +132,7 @@ public class Finder extends GFinder
    * 
    * @param e
    */
+  @Override
   public void findNext_actionPerformed(ActionEvent e)
   {
     if (getFocusedViewport())
@@ -143,6 +146,7 @@ public class Finder extends GFinder
    * 
    * @param e
    */
+  @Override
   public void findAll_actionPerformed(ActionEvent e)
   {
     if (getFocusedViewport())
@@ -198,19 +202,22 @@ public class Finder extends GFinder
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   public void createNewGroup_actionPerformed(ActionEvent e)
   {
     SequenceI[] seqs = new SequenceI[searchResults.getSize()];
     SequenceFeature[] features = new SequenceFeature[searchResults
             .getSize()];
 
-    for (int i = 0; i < searchResults.getSize(); i++)
+    int i = 0;
+    for (SearchResultMatchI match : searchResults.getResults())
     {
-      seqs[i] = searchResults.getResultSequence(i).getDatasetSequence();
+      seqs[i] = match.getSequence().getDatasetSequence();
 
       features[i] = new SequenceFeature(textfield.getText().trim(),
-              "Search Results", null, searchResults.getResultStart(i),
-              searchResults.getResultEnd(i), "Search Results");
+              "Search Results", null, match.getStart(), match.getEnd(),
+              "Search Results");
+      i++;
     }
 
     if (ap.getSeqPanel().seqCanvas.getFeatureRenderer().amendFeatures(seqs,
@@ -256,7 +263,7 @@ public class Finder extends GFinder
 
     searchResults = finder.getSearchResults(); // find(regex,
     // caseSensitive.isSelected(), )
-    Vector idMatch = finder.getIdMatch();
+    Vector<SequenceI> idMatch = finder.getIdMatch();
     boolean haveResults = false;
     // set or reset the GUI
     if ((idMatch.size() > 0))
@@ -286,9 +293,9 @@ public class Finder extends GFinder
     // 'SelectRegion' selection
     if (!haveResults)
     {
-      JOptionPane.showInternalMessageDialog(this,
+      JvOptionPane.showInternalMessageDialog(this,
               MessageManager.getString("label.finished_searching"), null,
-              JOptionPane.INFORMATION_MESSAGE);
+              JvOptionPane.INFORMATION_MESSAGE);
       resIndex = -1;
       seqIndex = 0;
     }
@@ -308,8 +315,8 @@ public class Finder extends GFinder
           message += searchResults.getSize()
                   + " subsequence matches found.";
         }
-        JOptionPane.showInternalMessageDialog(this, message, null,
-                JOptionPane.INFORMATION_MESSAGE);
+        JvOptionPane.showInternalMessageDialog(this, message, null,
+                JvOptionPane.INFORMATION_MESSAGE);
         resIndex = -1;
         seqIndex = 0;
       }
@@ -331,9 +338,9 @@ public class Finder extends GFinder
     {
       return false;
     }
-    JOptionPane.showInternalMessageDialog(this, error,
+    JvOptionPane.showInternalMessageDialog(this, error,
             MessageManager.getString("label.invalid_search"), // $NON-NLS-1$
-            JOptionPane.ERROR_MESSAGE);
+            JvOptionPane.ERROR_MESSAGE);
     return true;
   }
 
index 1f6c068..8220aea 100755 (executable)
@@ -253,9 +253,9 @@ public class FontChooser extends GFontChooser
       String message = iBounds.getHeight() < 1 ? MessageManager
               .getString("label.font_doesnt_have_letters_defined")
               : MessageManager.getString("label.font_too_small");
-      JOptionPane.showInternalMessageDialog(this, message,
+      JvOptionPane.showInternalMessageDialog(this, message,
               MessageManager.getString("label.invalid_font"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
       /*
        * Restore the changed value - note this will reinvoke this method via the
        * ActionListener, but now validation should pass
index 108080b..12af734 100644 (file)
@@ -58,8 +58,8 @@ public class HTMLOptions extends JPanel
     bg.add(lineart);
     bg.add(text);
 
-    JOptionPane pane = new JOptionPane(null, JOptionPane.DEFAULT_OPTION,
-            JOptionPane.DEFAULT_OPTION, null, new Object[] { this });
+    JOptionPane pane = new JOptionPane(null, JvOptionPane.DEFAULT_OPTION,
+            JvOptionPane.DEFAULT_OPTION, null, new Object[] { this });
 
     dialog = pane.createDialog(Desktop.desktop, "HTML Rendering options");
     dialog.setVisible(true);
@@ -78,6 +78,7 @@ public class HTMLOptions extends JPanel
     ok.setText(MessageManager.getString("action.ok"));
     ok.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         ok_actionPerformed(e);
@@ -86,6 +87,7 @@ public class HTMLOptions extends JPanel
     cancel.setText(MessageManager.getString("action.cancel"));
     cancel.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         cancel_actionPerformed(e);
index a65be7b..59d12d9 100755 (executable)
@@ -109,8 +109,8 @@ public class IdPanel extends JPanel implements MouseListener,
     if (seq > -1 && seq < av.getAlignment().getHeight())
     {
       SequenceI sequence = av.getAlignment().getSequenceAt(seq);
-      StringBuffer tip = new StringBuffer(64);
-      seqAnnotReport.createSequenceAnnotationReport(tip, sequence,
+      StringBuilder tip = new StringBuilder(64);
+      seqAnnotReport.createTooltipAnnotationReport(tip, sequence,
               av.isShowDBRefs(), av.isShowNPFeats(),
               sp.seqCanvas.fr.getMinMax());
       setToolTipText(JvSwingUtils.wrapTooltip(true,
@@ -225,7 +225,14 @@ public class IdPanel extends JPanel implements MouseListener,
         url = null;
         continue;
       }
-      ;
+
+      if (urlLink.usesDBAccession())
+      {
+        // this URL requires an accession id, not the name of a sequence
+        url = null;
+        continue;
+      }
+
       if (!urlLink.isValid())
       {
         jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
@@ -247,10 +254,10 @@ public class IdPanel extends JPanel implements MouseListener,
       jalview.util.BrowserLauncher.openURL(url);
     } catch (Exception ex)
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop,
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop,
               MessageManager.getString("label.web_browser_not_found_unix"),
               MessageManager.getString("label.web_browser_not_found"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
       ex.printStackTrace();
     }
   }
index 1c90889..35db33f 100644 (file)
@@ -37,6 +37,8 @@ import jalview.datamodel.StructureViewerModel;
 import jalview.datamodel.StructureViewerModel.StructureData;
 import jalview.ext.varna.RnaModel;
 import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.schemabinding.version2.AlcodMap;
 import jalview.schemabinding.version2.AlcodonFrame;
 import jalview.schemabinding.version2.Annotation;
@@ -2636,10 +2638,10 @@ public class Jalview2XML
           @Override
           public void run()
           {
-            JOptionPane.showInternalMessageDialog(Desktop.desktop,
+            JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                     finalErrorMessage, "Error "
                             + (saving ? "saving" : "loading")
-                            + " Jalview file", JOptionPane.WARNING_MESSAGE);
+                            + " Jalview file", JvOptionPane.WARNING_MESSAGE);
           }
         });
       }
@@ -3401,8 +3403,8 @@ public class Jalview2XML
         }
         if (jGroup.getConsThreshold() != 0)
         {
-          Conservation c = new Conservation("All", 3,
-                  sg.getSequences(null), 0, sg.getWidth() - 1);
+          Conservation c = new Conservation("All", sg.getSequences(null),
+                  0, sg.getWidth() - 1);
           c.calculate();
           c.verdict(false, 25);
           sg.cs.setConservation(c);
@@ -4230,8 +4232,7 @@ public class Jalview2XML
       StructureData filedat = oldFiles.get(id);
       String pdbFile = filedat.getFilePath();
       SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
-      binding.getSsm().setMapping(seq, null, pdbFile,
-              jalview.io.AppletFormatAdapter.FILE);
+      binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE);
       binding.addSequenceForStructFile(pdbFile, seq);
     }
     // and add the AlignmentPanel's reference to the view panel
@@ -4346,7 +4347,7 @@ public class Jalview2XML
     af = new AlignFrame(al, view.getWidth(), view.getHeight(),
             uniqueSeqSetId, viewId);
 
-    af.setFileName(file, "Jalview");
+    af.setFileName(file, FileFormat.Jalview);
 
     for (int i = 0; i < JSEQ.length; i++)
     {
index f8a296f..52f61b1 100755 (executable)
@@ -36,6 +36,7 @@ import jalview.binding.Tree;
 import jalview.binding.UserColours;
 import jalview.binding.Viewport;
 import jalview.datamodel.PDBEntry;
+import jalview.io.FileFormat;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
 import jalview.structure.StructureSelectionManager;
@@ -155,11 +156,11 @@ public class Jalview2XML_V1
 
             System.err.println("Couldn't locate Jalview XML file : " + ex
                     + "\n");
-            JOptionPane.showInternalMessageDialog(Desktop.desktop,
+            JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                     MessageManager.formatMessage("label.couldnt_locate",
                             new String[] { file }), MessageManager
                             .getString("label.url_not_found"),
-                    JOptionPane.WARNING_MESSAGE);
+                    JvOptionPane.WARNING_MESSAGE);
           }
         });
       }
@@ -176,12 +177,12 @@ public class Jalview2XML_V1
           public void run()
           {
 
-            JOptionPane.showInternalMessageDialog(Desktop.desktop,
+            JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                     MessageManager.formatMessage(
                             "label.error_loading_file_params", new String[]
                             { file }), MessageManager
                             .getString("label.error_loading_jalview_file"),
-                    JOptionPane.WARNING_MESSAGE);
+                    JvOptionPane.WARNING_MESSAGE);
           }
         });
       }
@@ -305,7 +306,7 @@ public class Jalview2XML_V1
 
     AlignFrame af = new AlignFrame(al, view.getWidth(), view.getHeight());
 
-    af.setFileName(file, "Jalview");
+    af.setFileName(file, FileFormat.Jalview);
 
     for (int i = 0; i < JSEQ.length; i++)
     {
@@ -359,8 +360,8 @@ public class Jalview2XML_V1
 
         if (groups[i].getConsThreshold() != 0)
         {
-          Conservation c = new Conservation("All", 3,
-                  sg.getSequences(null), 0, sg.getWidth() - 1);
+          Conservation c = new Conservation("All", sg.getSequences(null),
+                  0, sg.getWidth() - 1);
           c.calculate();
           c.verdict(false, 25);
           sg.cs.setConservation(c);
index 7a54732..801b285 100644 (file)
 package jalview.gui;
 
 import jalview.api.AlignmentViewPanel;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.ext.rbvi.chimera.JalviewChimeraBinding;
+import jalview.io.DataSourceType;
 import jalview.structure.StructureSelectionManager;
 
 public class JalviewChimeraBindingModel extends JalviewChimeraBinding
@@ -32,11 +34,12 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
 
   private FeatureRenderer fr = null;
 
+
   public JalviewChimeraBindingModel(ChimeraViewFrame chimeraViewFrame,
           StructureSelectionManager ssm, PDBEntry[] pdbentry,
-          SequenceI[][] sequenceIs, String[][] chains, String protocol)
+          SequenceI[][] sequenceIs, DataSourceType protocol)
   {
-    super(ssm, pdbentry, sequenceIs, chains, protocol);
+    super(ssm, pdbentry, sequenceIs, protocol);
     cvf = chimeraViewFrame;
   }
 
@@ -72,6 +75,7 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
   {
     javax.swing.SwingUtilities.invokeLater(new Runnable()
     {
+      @Override
       public void run()
       {
         cvf.updateTitleAndMenus();
@@ -80,6 +84,7 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
     });
   }
 
+  @Override
   public void updateColours(Object source)
   {
     AlignmentPanel ap = (AlignmentPanel) source;
@@ -113,6 +118,7 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
    * Send an asynchronous command to Chimera, in a new thread, optionally with
    * an 'in progress' message in a progress bar somewhere
    */
+  @Override
   protected void sendAsynchronousCommand(final String command,
           final String progressMsg)
   {
@@ -135,4 +141,10 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
     thread.start();
 
   }
+
+  @Override
+  public JalviewStructureDisplayI getViewer()
+  {
+    return cvf;
+  }
 }
diff --git a/src/jalview/gui/JvOptionPane.java b/src/jalview/gui/JvOptionPane.java
new file mode 100644 (file)
index 0000000..539f3c2
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.gui;
+
+import java.awt.Component;
+import java.awt.HeadlessException;
+
+import javax.swing.Icon;
+import javax.swing.JOptionPane;
+
+public class JvOptionPane extends JOptionPane
+{
+  /**
+   * 
+   */
+  private static final long serialVersionUID = -3019167117756785229L;
+
+  private static Object mockResponse = JvOptionPane.CANCEL_OPTION;
+
+  private static boolean interactiveMode = true;
+
+  public static int showConfirmDialog(Component parentComponent,
+          Object message) throws HeadlessException
+  {
+    return isInteractiveMode() ? JOptionPane.showConfirmDialog(
+            parentComponent, message) : (int) getMockResponse();
+  }
+
+  public static int showConfirmDialog(Component parentComponent,
+          Object message, String title, int optionType)
+          throws HeadlessException
+  {
+    return isInteractiveMode() ? JOptionPane.showConfirmDialog(
+            parentComponent, message, title, optionType)
+            : (int) getMockResponse();
+  }
+
+  public static int showConfirmDialog(Component parentComponent,
+          Object message, String title, int optionType, int messageType)
+          throws HeadlessException
+  {
+    return isInteractiveMode() ? JOptionPane.showConfirmDialog(
+            parentComponent, message, title, optionType, messageType)
+            : (int) getMockResponse();
+  }
+
+  public static int showConfirmDialog(Component parentComponent,
+          Object message, String title, int optionType, int messageType,
+          Icon icon) throws HeadlessException
+  {
+    return isInteractiveMode() ? JOptionPane.showConfirmDialog(
+            parentComponent, message, title, optionType, messageType, icon)
+            : (int) getMockResponse();
+  }
+
+  public static int showInternalConfirmDialog(Component parentComponent,
+          Object message)
+  {
+    return isInteractiveMode() ? JOptionPane.showInternalConfirmDialog(
+            parentComponent, message) : (int) getMockResponse();
+  }
+
+  public static int showInternalConfirmDialog(Component parentComponent,
+          Object message, String title, int optionType)
+  {
+    return isInteractiveMode() ? JOptionPane.showConfirmDialog(
+            parentComponent, message, title, optionType)
+            : (int) getMockResponse();
+  }
+
+  public static int showInternalConfirmDialog(Component parentComponent,
+          Object message, String title, int optionType, int messageType)
+  {
+    return isInteractiveMode() ? JOptionPane.showConfirmDialog(
+            parentComponent, message, title, optionType, messageType)
+            : (int) getMockResponse();
+  }
+
+  public static int showInternalConfirmDialog(Component parentComponent,
+          Object message, String title, int optionType, int messageType,
+          Icon icon)
+  {
+    return isInteractiveMode() ? JOptionPane.showInternalConfirmDialog(
+            parentComponent, message, title, optionType, messageType, icon)
+            : (int) getMockResponse();
+  }
+
+  public static int showOptionDialog(Component parentComponent,
+          Object message, String title, int optionType, int messageType,
+          Icon icon, Object[] options, Object initialValue)
+          throws HeadlessException
+  {
+    return isInteractiveMode() ? JOptionPane.showOptionDialog(
+            parentComponent, message, title, optionType, messageType, icon,
+            options, initialValue) : (int) getMockResponse();
+  }
+
+  public static void showMessageDialog(Component parentComponent,
+          Object message) throws HeadlessException
+  {
+    if (isInteractiveMode())
+    {
+      JOptionPane.showMessageDialog(parentComponent, message);
+    }
+    else
+    {
+      outputMessage(message);
+    }
+  }
+
+  public static void showMessageDialog(Component parentComponent,
+          Object message, String title, int messageType)
+          throws HeadlessException
+  {
+    if (isInteractiveMode())
+    {
+      JOptionPane.showMessageDialog(parentComponent, message, title,
+              messageType);
+    }
+    else
+    {
+      outputMessage(message);
+    }
+  }
+
+  public static void showMessageDialog(Component parentComponent,
+          Object message, String title, int messageType, Icon icon)
+          throws HeadlessException
+  {
+    if (isInteractiveMode())
+    {
+      JOptionPane.showMessageDialog(parentComponent, message, title,
+              messageType, icon);
+    }
+    else
+    {
+      outputMessage(message);
+    }
+  }
+
+  public static void showInternalMessageDialog(Component parentComponent,
+          Object message)
+  {
+    if (isInteractiveMode())
+    {
+      JOptionPane.showMessageDialog(parentComponent, message);
+    }
+    else
+    {
+      outputMessage(message);
+    }
+  }
+
+  public static void showInternalMessageDialog(Component parentComponent,
+          Object message, String title, int messageType)
+  {
+    if (isInteractiveMode())
+    {
+      JOptionPane.showMessageDialog(parentComponent, message, title,
+              messageType);
+    }
+    else
+    {
+      outputMessage(message);
+    }
+  }
+
+  public static void showInternalMessageDialog(Component parentComponent,
+          Object message, String title, int messageType, Icon icon)
+  {
+    if (isInteractiveMode())
+    {
+      JOptionPane.showMessageDialog(parentComponent, message, title,
+              messageType, icon);
+    }
+    else
+    {
+      outputMessage(message);
+    }
+  }
+
+  public static String showInputDialog(Object message)
+          throws HeadlessException
+  {
+    return isInteractiveMode() ? JOptionPane.showInputDialog(message)
+            : getMockResponse().toString();
+  }
+
+  public static String showInputDialog(Object message,
+          Object initialSelectionValue)
+  {
+    return isInteractiveMode() ? JOptionPane.showInputDialog(message,
+            initialSelectionValue) : getMockResponse().toString();
+  }
+
+  public static String showInputDialog(Component parentComponent,
+          Object message) throws HeadlessException
+  {
+    return isInteractiveMode() ? JOptionPane.showInputDialog(
+            parentComponent, message) : getMockResponse().toString();
+  }
+
+  public static String showInputDialog(Component parentComponent,
+          Object message, Object initialSelectionValue)
+  {
+    return isInteractiveMode() ? JOptionPane.showInputDialog(
+            parentComponent, message, initialSelectionValue)
+            : getMockResponse().toString();
+  }
+
+  public static String showInputDialog(Component parentComponent,
+          Object message, String title, int messageType)
+          throws HeadlessException
+  {
+    return isInteractiveMode() ? JOptionPane.showInputDialog(
+            parentComponent, message, title, messageType)
+            : getMockResponse().toString();
+  }
+
+  public static Object showInputDialog(Component parentComponent,
+          Object message, String title, int messageType, Icon icon,
+          Object[] selectionValues, Object initialSelectionValue)
+          throws HeadlessException
+  {
+    return isInteractiveMode() ? JOptionPane.showInputDialog(
+            parentComponent, message, title, messageType, icon,
+            selectionValues, initialSelectionValue) : getMockResponse()
+            .toString();
+  }
+
+  public static String showInternalInputDialog(Component parentComponent,
+          Object message)
+  {
+    return isInteractiveMode() ? JOptionPane.showInternalInputDialog(
+            parentComponent, message) : getMockResponse().toString();
+  }
+
+  public static String showInternalInputDialog(Component parentComponent,
+          Object message, String title, int messageType)
+  {
+    return isInteractiveMode() ? JOptionPane.showInternalInputDialog(
+            parentComponent, message, title, messageType)
+            : getMockResponse().toString();
+  }
+
+  public static Object showInternalInputDialog(Component parentComponent,
+          Object message, String title, int messageType, Icon icon,
+          Object[] selectionValues, Object initialSelectionValue)
+  {
+    return isInteractiveMode() ? JOptionPane.showInternalInputDialog(
+            parentComponent, message, title, messageType, icon,
+            selectionValues, initialSelectionValue) : getMockResponse()
+            .toString();
+  }
+
+  private static void outputMessage(Object message)
+  {
+    System.out.println(">>> JOption Message : " + message.toString());
+  }
+
+  public static Object getMockResponse()
+  {
+    return mockResponse;
+  }
+
+  public static void setMockResponse(Object mockOption)
+  {
+    JvOptionPane.mockResponse = mockOption;
+  }
+
+  public static void resetMock()
+  {
+    setMockResponse(JvOptionPane.CANCEL_OPTION);
+    setInteractiveMode(true);
+  }
+
+  public static boolean isInteractiveMode()
+  {
+    return interactiveMode;
+  }
+
+  public static void setInteractiveMode(boolean interactiveMode)
+  {
+    JvOptionPane.interactiveMode = interactiveMode;
+  }
+
+}
index eb4425e..f519b85 100644 (file)
@@ -75,13 +75,15 @@ public class OOMWarning implements Runnable
     this(string, oomerror, Desktop.desktop);
   }
 
+  @Override
   public void run()
   {
-    javax.swing.JOptionPane.showInternalMessageDialog(desktop,
+    JvOptionPane
+            .showInternalMessageDialog(desktop,
             MessageManager.formatMessage("warn.out_of_memory_when_action",
                     new String[] { action }), MessageManager
                     .getString("label.out_of_memory"),
-            javax.swing.JOptionPane.WARNING_MESSAGE);
+                    JvOptionPane.WARNING_MESSAGE);
     // hope that there's enough memory left that no more appear.
     oomInprogress = false;
   }
index 51d247d..4f5a018 100644 (file)
@@ -114,10 +114,10 @@ public class PCAPanel extends GPCAPanel implements Runnable,
 
     if (!sameLength)
     {
-      JOptionPane.showMessageDialog(Desktop.desktop,
+      JvOptionPane.showMessageDialog(Desktop.desktop,
               MessageManager.getString("label.pca_sequences_not_aligned"),
               MessageManager.getString("label.sequences_not_aligned"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
 
       return;
     }
index 7ab6022..e1b2560 100644 (file)
@@ -38,6 +38,8 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
 import jalview.io.SequenceAnnotationReport;
 import jalview.schemes.AnnotationColourGradient;
@@ -54,7 +56,6 @@ import jalview.schemes.TaylorColourScheme;
 import jalview.schemes.TurnColourScheme;
 import jalview.schemes.UserColourScheme;
 import jalview.schemes.ZappoColourScheme;
-import jalview.util.DBRefUtils;
 import jalview.util.GroupUrlLink;
 import jalview.util.GroupUrlLink.UrlStringTooLongException;
 import jalview.util.MessageManager;
@@ -63,8 +64,8 @@ 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;
@@ -255,10 +256,9 @@ public class PopupMenu extends JPopupMenu
     colours.add(purinePyrimidineColour);
     colours.add(RNAInteractionColour);
 
-    for (int i = 0; i < jalview.io.FormatAdapter.WRITEABLE_FORMATS.length; i++)
+    for (String ff : FileFormat.getWritableFormats(true))
     {
-      JMenuItem item = new JMenuItem(
-              jalview.io.FormatAdapter.WRITEABLE_FORMATS[i]);
+      JMenuItem item = new JMenuItem(ff);
 
       item.addActionListener(new java.awt.event.ActionListener()
       {
@@ -617,7 +617,8 @@ public class PopupMenu extends JPopupMenu
   void addFeatureLinks(final SequenceI seq, List<String> links)
   {
     JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
-    List<String> linkset = new ArrayList<String>();
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+
     for (String link : links)
     {
       UrlLink urlLink = null;
@@ -629,97 +630,28 @@ public class PopupMenu extends JPopupMenu
         Cache.log.error("Exception for URLLink '" + link + "'", foo);
         continue;
       }
-      ;
+
       if (!urlLink.isValid())
       {
         Cache.log.error(urlLink.getInvalidMessage());
         continue;
       }
-      final String label = urlLink.getLabel();
-      if (seq != null && urlLink.isDynamic())
-      {
 
-        // collect matching db-refs
-        DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
-                new String[] { urlLink.getTarget() });
-        // collect id string too
-        String id = seq.getName();
-        String descr = seq.getDescription();
-        if (descr != null && descr.length() < 1)
-        {
-          descr = null;
-        }
+      urlLink.createLinksFromSeq(seq, linkset);
+    }
 
-        if (dbr != null)
-        {
-          for (int r = 0; r < dbr.length; r++)
-          {
-            if (id != null && dbr[r].getAccessionId().equals(id))
-            {
-              // suppress duplicate link creation for the bare sequence ID
-              // string with this link
-              id = null;
-            }
-            // create Bare ID link for this URL
-            String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
-            if (urls != null)
-            {
-              for (int u = 0; u < urls.length; u += 2)
-              {
-                if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
-                {
-                  linkset.add(urls[u] + "|" + urls[u + 1]);
-                  addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]);
-                }
-              }
-            }
-          }
-        }
-        if (id != null)
-        {
-          // create Bare ID link for this URL
-          String[] urls = urlLink.makeUrls(id, true);
-          if (urls != null)
-          {
-            for (int u = 0; u < urls.length; u += 2)
-            {
-              if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
-              {
-                linkset.add(urls[u] + "|" + urls[u + 1]);
-                addshowLink(linkMenu, label, urls[u + 1]);
-              }
-            }
-          }
-        }
-        // Create urls from description but only for URL links which are regex
-        // links
-        if (descr != null && urlLink.getRegexReplace() != null)
-        {
-          // create link for this URL from description where regex matches
-          String[] urls = urlLink.makeUrls(descr, true);
-          if (urls != null)
-          {
-            for (int u = 0; u < urls.length; u += 2)
-            {
-              if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
-              {
-                linkset.add(urls[u] + "|" + urls[u + 1]);
-                addshowLink(linkMenu, label, urls[u + 1]);
-              }
-            }
-          }
-        }
-      }
-      else
-      {
-        if (!linkset.contains(label + "|" + urlLink.getUrl_prefix()))
-        {
-          linkset.add(label + "|" + urlLink.getUrl_prefix());
-          // Add a non-dynamic link
-          addshowLink(linkMenu, label, urlLink.getUrl_prefix());
-        }
-      }
+    addshowLinks(linkMenu, linkset.values());
+
+    // disable link menu if there are no valid entries
+    if (linkMenu.getItemCount() > 0)
+    {
+      linkMenu.setEnabled(true);
     }
+    else
+    {
+      linkMenu.setEnabled(false);
+    }
+
     if (sequence != null)
     {
       sequenceMenu.add(linkMenu);
@@ -728,8 +660,11 @@ public class PopupMenu extends JPopupMenu
     {
       add(linkMenu);
     }
+
   }
 
+
+
   /**
    * Add annotation types to 'Show annotations' and/or 'Hide annotations' menus.
    * "All" is added first, followed by a separator. Then add any annotation
@@ -1004,6 +939,15 @@ public class PopupMenu extends JPopupMenu
     }
   }
 
+  private void addshowLinks(JMenu linkMenu, Collection<List<String>> linkset)
+  {
+    for (List<String> linkstrset : linkset)
+    {
+      // split linkstr into label and url
+      addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3));
+    }
+  }
+
   /**
    * add a show URL menu item to the given linkMenu
    * 
@@ -1734,7 +1678,7 @@ public class PopupMenu extends JPopupMenu
   public void createSequenceDetailsReport(SequenceI[] sequences)
   {
     CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
-    StringBuffer contents = new StringBuffer();
+    StringBuilder contents = new StringBuilder(128);
     for (SequenceI seq : sequences)
     {
       contents.append("<p><h2>"
@@ -1749,7 +1693,6 @@ public class PopupMenu extends JPopupMenu
                       seq,
                       true,
                       true,
-                      false,
                       (ap.getSeqPanel().seqCanvas.fr != null) ? ap
                               .getSeqPanel().seqCanvas.fr.getMinMax()
                               : null);
@@ -2037,7 +1980,7 @@ public class PopupMenu extends JPopupMenu
     if (conservationMenuItem.isSelected())
     {
       // JBPNote: Conservation name shouldn't be i18n translated
-      Conservation c = new Conservation("Group", 3, sg.getSequences(ap.av
+      Conservation c = new Conservation("Group", sg.getSequences(ap.av
               .getHiddenRepSequences()), sg.getStartRes(),
               sg.getEndRes() + 1);
 
@@ -2146,14 +2089,14 @@ public class PopupMenu extends JPopupMenu
     {
       if (dialog.getName().indexOf(" ") > -1)
       {
-        JOptionPane
+        JvOptionPane
                 .showMessageDialog(
                         ap,
                         MessageManager
                                 .getString("label.spaces_converted_to_backslashes"),
                         MessageManager
                                 .getString("label.no_spaces_allowed_sequence_name"),
-                        JOptionPane.WARNING_MESSAGE);
+                        JvOptionPane.WARNING_MESSAGE);
       }
 
       sequence.setName(dialog.getName().replace(' ', '_'));
@@ -2252,10 +2195,10 @@ public class PopupMenu extends JPopupMenu
       jalview.util.BrowserLauncher.openURL(url);
     } catch (Exception ex)
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop,
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop,
               MessageManager.getString("label.web_browser_not_found_unix"),
               MessageManager.getString("label.web_browser_not_found"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
 
       ex.printStackTrace();
     }
@@ -2331,8 +2274,8 @@ public class PopupMenu extends JPopupMenu
     // or we simply trust the user wants
     // wysiwig behaviour
 
-    cap.setText(new FormatAdapter(ap).formatSequences(e.getActionCommand(),
-            ap, true));
+    FileFormatI fileFormat = FileFormat.forName(e.getActionCommand());
+    cap.setText(new FormatAdapter(ap).formatSequences(fileFormat, ap, true));
   }
 
   public void sequenceFeature_actionPerformed()
index 8dbe5e2..0b65c1b 100755 (executable)
  */
 package jalview.gui;
 
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.EMBLEBI_STRING;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+import static jalview.util.UrlConstants.SRS_STRING;
+
 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.bin.Cache;
 import jalview.gui.Help.HelpId;
 import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.FileFormatI;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
 import jalview.jbgui.GPreferences;
@@ -50,7 +56,6 @@ import javax.help.HelpSetException;
 import javax.swing.JColorChooser;
 import javax.swing.JFileChooser;
 import javax.swing.JInternalFrame;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 
 import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
@@ -110,10 +115,7 @@ public class Preferences extends GPreferences
   public static List<String> groupURLLinks;
   static
   {
-    String string = Cache
-            .getDefault(
-                    "SEQUENCE_LINKS",
-                    "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$");
+    String string = Cache.getDefault("SEQUENCE_LINKS", EMBLEBI_STRING);
     sequenceURLLinks = new Vector<String>();
 
     try
@@ -124,7 +126,11 @@ public class Preferences extends GPreferences
         String name = st.nextToken();
         String url = st.nextToken();
         // check for '|' within a regex
-        int rxstart = url.indexOf("$SEQUENCE_ID$");
+        int rxstart = url.indexOf("$" + DB_ACCESSION + "$");
+        if (rxstart == -1)
+        {
+          rxstart = url.indexOf("$" + SEQUENCE_ID + "$");
+        }
         while (rxstart == -1 && url.indexOf("/=$") == -1)
         {
           url = url + "|" + st.nextToken();
@@ -137,14 +143,10 @@ public class Preferences extends GPreferences
     }
     {
       // upgrade old SRS link
-      int srsPos = sequenceURLLinks
-              .indexOf("SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
+      int srsPos = sequenceURLLinks.indexOf(SRS_STRING);
       if (srsPos > -1)
       {
-        sequenceURLLinks
-                .setElementAt(
-                        "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$",
-                        srsPos);
+        sequenceURLLinks.setElementAt(EMBLEBI_STRING, srsPos);
       }
     }
 
@@ -565,6 +567,7 @@ public class Preferences extends GPreferences
     else
     {
       Cache.applicationProperties.remove("SEQUENCE_LINKS");
+      sequenceURLLinks.clear();
     }
 
     Cache.applicationProperties.setProperty("USE_PROXY",
@@ -683,12 +686,9 @@ public class Preferences extends GPreferences
   @Override
   public void startupFileTextfield_mouseClicked()
   {
-    JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
-                "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
-                "jar" }, new String[] { "Fasta", "Clustal", "PFAM", "MSF",
-                "PIR", "BLC", "Jalview" },
-            jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
+    String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
+    JalviewFileChooser chooser = JalviewFileChooser.forRead(
+            Cache.getProperty("LAST_DIRECTORY"), fileFormat);
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
             .getString("label.select_startup_file"));
@@ -697,8 +697,12 @@ public class Preferences extends GPreferences
 
     if (value == JalviewFileChooser.APPROVE_OPTION)
     {
-      jalview.bin.Cache.applicationProperties.setProperty(
-              "DEFAULT_FILE_FORMAT", chooser.getSelectedFormat());
+      FileFormatI format = chooser.getSelectedFormat();
+      if (format != null)
+      {
+        Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
+                format.toString());
+      }
       startupFileTextfield.setText(chooser.getSelectedFile()
               .getAbsolutePath());
     }
@@ -751,9 +755,9 @@ public class Preferences extends GPreferences
     boolean valid = false;
     while (!valid)
     {
-      if (JOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
+      if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
               MessageManager.getString("label.new_sequence_url_link"),
-              JOptionPane.OK_CANCEL_OPTION, -1, null) == JOptionPane.OK_OPTION)
+              JvOptionPane.OK_CANCEL_OPTION, -1, null) == JvOptionPane.OK_OPTION)
       {
         if (link.checkValid())
         {
@@ -778,10 +782,10 @@ public class Preferences extends GPreferences
     int index = linkNameList.getSelectedIndex();
     if (index == -1)
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop,
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop,
               MessageManager.getString("label.no_link_selected"),
               MessageManager.getString("label.no_link_selected"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
       return;
     }
 
@@ -792,9 +796,9 @@ public class Preferences extends GPreferences
     while (!valid)
     {
 
-      if (JOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
+      if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
               MessageManager.getString("label.new_sequence_url_link"),
-              JOptionPane.OK_CANCEL_OPTION, -1, null) == JOptionPane.OK_OPTION)
+              JvOptionPane.OK_CANCEL_OPTION, -1, null) == JvOptionPane.OK_OPTION)
       {
         if (link.checkValid())
         {
@@ -818,10 +822,10 @@ public class Preferences extends GPreferences
     int index = linkNameList.getSelectedIndex();
     if (index == -1)
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop,
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop,
               MessageManager.getString("label.no_link_selected"),
               MessageManager.getString("label.no_link_selected"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
       return;
     }
     nameLinks.removeElementAt(index);
@@ -913,10 +917,10 @@ public class Preferences extends GPreferences
       }
     } catch (NumberFormatException x)
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
               .getString("warn.user_defined_width_requirements"),
               MessageManager.getString("label.invalid_id_column_width"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
       userIdWidth.setText("");
     }
   }
@@ -939,10 +943,10 @@ public class Preferences extends GPreferences
       File f = new File(chimeraPath.getText());
       if (!f.canExecute())
       {
-        JOptionPane.showInternalMessageDialog(Desktop.desktop,
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                 MessageManager.getString("label.invalid_chimera_path"),
                 MessageManager.getString("label.invalid_name"),
-                JOptionPane.ERROR_MESSAGE);
+                JvOptionPane.ERROR_MESSAGE);
         return false;
       }
     }
@@ -978,13 +982,13 @@ public class Preferences extends GPreferences
     if (!found)
     {
       String[] options = { "OK", "Help" };
-      int showHelp = JOptionPane.showInternalOptionDialog(
+      int showHelp = JvOptionPane.showInternalOptionDialog(
               Desktop.desktop,
               JvSwingUtils.wrapTooltip(true,
                       MessageManager.getString("label.chimera_missing")),
-              "", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
+              "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
               null, options, options[0]);
-      if (showHelp == JOptionPane.NO_OPTION)
+      if (showHelp == JvOptionPane.NO_OPTION)
       {
         try
         {
index d7449d0..fb90ce7 100644 (file)
@@ -201,12 +201,12 @@ public class PromptUserConfig implements Runnable
     }
     try
     {
-      int reply = JOptionPane.showConfirmDialog(
+      int reply = JvOptionPane.showConfirmDialog(
               Desktop.desktop, // component,
               dialogText, dialogTitle,
-              (allowCancel) ? JOptionPane.YES_NO_CANCEL_OPTION
-                      : JOptionPane.YES_NO_OPTION,
-              JOptionPane.QUESTION_MESSAGE);
+              (allowCancel) ? JvOptionPane.YES_NO_CANCEL_OPTION
+                      : JvOptionPane.YES_NO_OPTION,
+              JvOptionPane.QUESTION_MESSAGE);
       // now, ask the desktop to relayer any external windows that might have
       // been obsured
       if (Desktop.instance != null)
@@ -215,11 +215,11 @@ public class PromptUserConfig implements Runnable
       }
       // and finish parsing the result
       jalview.bin.Cache.log.debug("Got response : " + reply);
-      if (reply == JOptionPane.YES_OPTION)
+      if (reply == JvOptionPane.YES_OPTION)
       {
         jalview.bin.Cache.setProperty(property, "true");
       }
-      else if (reply == JOptionPane.NO_OPTION)
+      else if (reply == JvOptionPane.NO_OPTION)
       {
         if (removeifunset)
         {
index 8056189..19a9b51 100644 (file)
@@ -74,13 +74,13 @@ public class RestInputParamEditDialog extends GRestInputParamEditDialog
     @Override
     protected void okPressed()
     {
-      reply = JOptionPane.OK_OPTION;
+      reply = JvOptionPane.OK_OPTION;
     }
 
     @Override
     protected void cancelPressed()
     {
-      reply = JOptionPane.CANCEL_OPTION;
+      reply = JvOptionPane.CANCEL_OPTION;
 
     }
   };
@@ -107,14 +107,14 @@ public class RestInputParamEditDialog extends GRestInputParamEditDialog
             + currentservice.getName(), 600, 800);
 
     initTypeLists();
-    reply = JOptionPane.CANCEL_OPTION;
+    reply = JvOptionPane.CANCEL_OPTION;
     old = toedit;
     current = null;
     if (old != null)
     {
       setStateFor(old);
     }
-    updated = updated && reply == JOptionPane.OK_OPTION;
+    updated = updated && reply == JvOptionPane.OK_OPTION;
     frame.validate();
   }
 
index a64819a..ea8e360 100644 (file)
@@ -58,8 +58,8 @@ public class SVGOptions extends JPanel
     bg.add(lineart);
     bg.add(text);
 
-    JOptionPane pane = new JOptionPane(null, JOptionPane.DEFAULT_OPTION,
-            JOptionPane.DEFAULT_OPTION, null, new Object[] { this });
+    JOptionPane pane = new JOptionPane(null, JvOptionPane.DEFAULT_OPTION,
+            JvOptionPane.DEFAULT_OPTION, null, new Object[] { this });
 
     dialog = pane.createDialog(Desktop.desktop, "SVG Rendering options");
     dialog.setVisible(true);
@@ -78,6 +78,7 @@ public class SVGOptions extends JPanel
     ok.setText(MessageManager.getString("action.ok"));
     ok.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         ok_actionPerformed(e);
@@ -86,6 +87,7 @@ public class SVGOptions extends JPanel
     cancel.setText(MessageManager.getString("action.cancel"));
     cancel.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         cancel_actionPerformed(e);
index 760ece0..d015292 100755 (executable)
@@ -21,7 +21,7 @@
 package jalview.gui;
 
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.renderer.ScaleRenderer;
@@ -62,8 +62,6 @@ public class SeqCanvas extends JComponent
 
   AlignViewport av;
 
-  SearchResults searchResults = null;
-
   boolean fastPaint = false;
 
   int LABEL_WEST;
@@ -740,10 +738,10 @@ public class SeqCanvas extends JComponent
 
       // / Highlight search Results once all sequences have been drawn
       // ////////////////////////////////////////////////////////
-      if (searchResults != null)
+      if (av.hasSearchResults())
       {
-        int[] visibleResults = searchResults.getResults(nextSeq, startRes,
-                endRes);
+        int[] visibleResults = av.getSearchResults().getResults(nextSeq,
+                startRes, endRes);
         if (visibleResults != null)
         {
           for (int r = 0; r < visibleResults.length; r += 2)
@@ -965,11 +963,11 @@ public class SeqCanvas extends JComponent
    * @param results
    *          DOCUMENT ME!
    */
-  public void highlightSearchResults(SearchResults results)
+  public void highlightSearchResults(SearchResultsI results)
   {
     img = null;
 
-    searchResults = results;
+    av.setSearchResults(results);
 
     repaint();
   }
index bae80db..8726c4a 100644 (file)
@@ -27,8 +27,9 @@ import jalview.commands.EditCommand.Action;
 import jalview.commands.EditCommand.Edit;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
@@ -124,7 +125,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   private final SequenceAnnotationReport seqARep;
 
-  StringBuffer tooltipText = new StringBuffer();
+  StringBuilder tooltipText = new StringBuilder();
 
   String tmpString;
 
@@ -132,7 +133,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   StructureSelectionManager ssm;
 
-  SearchResults lastSearchResults;
+  SearchResultsI lastSearchResults;
 
   /**
    * Creates a new SeqPanel object.
@@ -616,13 +617,14 @@ public class SeqPanel extends JPanel implements MouseListener,
       return;
     }
 
-    if (evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())
+    boolean isControlDown = Platform.isControlDown(evt);
+    if (evt.isShiftDown() || isControlDown)
     {
-      if (evt.isAltDown() || evt.isControlDown())
+      editingSeqs = true;
+      if (isControlDown)
       {
         groupEditing = true;
       }
-      editingSeqs = true;
     }
     else
     {
@@ -675,7 +677,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    * the start of the highlighted region.
    */
   @Override
-  public void highlightSequence(SearchResults results)
+  public void highlightSequence(SearchResultsI results)
   {
     if (results == null || results.equals(lastSearchResults))
     {
@@ -784,7 +786,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       seqARep.appendFeatures(tooltipText, rpos, features,
               this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
     }
-    if (tooltipText.length() == 6) // <html></html>
+    if (tooltipText.length() == 6) // <html>
     {
       setToolTipText(null);
       lastTooltip = null;
@@ -909,7 +911,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    * 
    * @param results
    */
-  private void setStatusMessage(SearchResults results)
+  private void setStatusMessage(SearchResultsI results)
   {
     AlignmentI al = this.av.getAlignment();
     int sequenceIndex = al.findIndex(results);
@@ -918,7 +920,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       return;
     }
     SequenceI ds = al.getSequenceAt(sequenceIndex).getDatasetSequence();
-    for (Match m : results.getResults())
+    for (SearchResultMatchI m : results.getResults())
     {
       SequenceI seq = m.getSequence();
       if (seq.getDatasetSequence() != null)
@@ -1500,7 +1502,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
       if (features != null && features.size() > 0)
       {
-        SearchResults highlight = new SearchResults();
+        SearchResultsI highlight = new SearchResults();
         highlight.addResult(sequence, features.get(0).getBegin(), features
                 .get(0).getEnd());
         seqCanvas.highlightSearchResults(highlight);
@@ -1564,10 +1566,10 @@ public class SeqPanel extends JPanel implements MouseListener,
 
     if (av.getWrapAlignment() && seq > av.getAlignment().getHeight())
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
               .getString("label.cannot_edit_annotations_in_wrapped_view"),
               MessageManager.getString("label.wrapped_view_no_edit"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
       return;
     }
 
index bbe2f68..8e1d549 100755 (executable)
@@ -28,6 +28,7 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.fts.service.pdb.PDBFTSPanel;
 import jalview.fts.service.uniprot.UniprotFTSPanel;
+import jalview.io.FileFormatI;
 import jalview.io.gff.SequenceOntologyI;
 import jalview.util.DBRefUtils;
 import jalview.util.MessageManager;
@@ -234,14 +235,14 @@ public class SequenceFetcher extends JPanel implements Runnable
             @Override
             public void run()
             {
-              JOptionPane
+              JvOptionPane
                       .showInternalMessageDialog(
                               Desktop.desktop,
                               MessageManager
                                       .getString("warn.couldnt_create_sequence_fetcher_client"),
                               MessageManager
                                       .getString("label.couldnt_create_sequence_fetcher"),
-                              JOptionPane.ERROR_MESSAGE);
+                              JvOptionPane.ERROR_MESSAGE);
             }
           });
 
@@ -978,7 +979,7 @@ public class SequenceFetcher extends JPanel implements Runnable
   }
 
   AlignmentI parseResult(AlignmentI al, String title,
-          String currentFileFormat,
+          FileFormatI currentFileFormat,
           FeatureSettingsModelI preferredFeatureColours)
   {
 
@@ -1059,9 +1060,9 @@ public class SequenceFetcher extends JPanel implements Runnable
       @Override
       public void run()
       {
-        JOptionPane.showInternalMessageDialog(Desktop.desktop, error,
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop, error,
                 MessageManager.getString("label.error_retrieving_data"),
-                JOptionPane.WARNING_MESSAGE);
+                JvOptionPane.WARNING_MESSAGE);
       }
     });
   }
index 3350f6c..ee22ae4 100644 (file)
@@ -32,6 +32,7 @@ import jalview.fts.api.FTSRestClientI;
 import jalview.fts.core.FTSRestRequest;
 import jalview.fts.core.FTSRestResponse;
 import jalview.fts.service.pdb.PDBFTSRestClient;
+import jalview.io.DataSourceType;
 import jalview.jbgui.GStructureChooser;
 import jalview.structure.StructureMapping;
 import jalview.structure.StructureSelectionManager;
@@ -65,6 +66,8 @@ import javax.swing.table.AbstractTableModel;
 public class StructureChooser extends GStructureChooser implements
         IProgressIndicator
 {
+  private static int MAX_QLENGTH = 7820;
+
   private SequenceI selectedSequence;
 
   private SequenceI[] selectedSequences;
@@ -214,9 +217,9 @@ public class StructureChooser extends GStructureChooser implements
         {
           errorMsg.append(error).append("\n");
         }
-        JOptionPane.showMessageDialog(this, errorMsg.toString(),
+        JvOptionPane.showMessageDialog(this, errorMsg.toString(),
                 MessageManager.getString("label.pdb_web-service_error"),
-                JOptionPane.ERROR_MESSAGE);
+                JvOptionPane.ERROR_MESSAGE);
       }
     }
   }
@@ -259,7 +262,8 @@ public class StructureChooser extends GStructureChooser implements
     StringBuilder queryBuilder = new StringBuilder();
     Set<String> seqRefs = new LinkedHashSet<String>();
 
-    if (seq.getAllPDBEntries() != null)
+    if (seq.getAllPDBEntries() != null
+            && queryBuilder.length() < MAX_QLENGTH)
     {
       for (PDBEntry entry : seq.getAllPDBEntries())
       {
@@ -268,7 +272,6 @@ public class StructureChooser extends GStructureChooser implements
           queryBuilder.append("pdb_id:")
                   .append(entry.getId().toLowerCase()).append(" OR ");
           isPDBRefsFound = true;
-          // seqRefs.add(entry.getId());
         }
       }
     }
@@ -277,7 +280,8 @@ public class StructureChooser extends GStructureChooser implements
     {
       for (DBRefEntry dbRef : seq.getDBRefs())
       {
-        if (isValidSeqName(getDBRefId(dbRef)))
+        if (isValidSeqName(getDBRefId(dbRef))
+                && queryBuilder.length() < MAX_QLENGTH)
         {
           if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT))
           {
@@ -481,11 +485,11 @@ public class StructureChooser extends GStructureChooser implements
             {
               errorMsg.append(error).append("\n");
             }
-            JOptionPane.showMessageDialog(
+            JvOptionPane.showMessageDialog(
                     null,
                     errorMsg.toString(),
                     MessageManager.getString("label.pdb_web-service_error"),
-                    JOptionPane.ERROR_MESSAGE);
+                    JvOptionPane.ERROR_MESSAGE);
           }
         }
 
@@ -752,7 +756,7 @@ public class StructureChooser extends GStructureChooser implements
           int[] selectedRows = getResultTable().getSelectedRows();
           PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
           int count = 0;
-          ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+          List<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
           for (int row : selectedRows)
           {
             String pdbIdStr = getResultTable().getValueAt(row,
@@ -788,7 +792,7 @@ public class StructureChooser extends GStructureChooser implements
                   .getModelIndex();
           int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
                   .getModelIndex();
-          ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+          List<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
           for (int row : selectedRows)
           {
             PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
@@ -832,19 +836,19 @@ public class StructureChooser extends GStructureChooser implements
           PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
           launchStructureViewer(ssm, pdbEntriesToView, ap,
                   new SequenceI[] { selectedSequence });
-        }
-        else if (currentView == VIEWS_FROM_FILE)
-        {
-          SequenceI userSelectedSeq = ((AssociateSeqOptions) fileChooserAssSeqPanel
-                  .getCmb_assSeq().getSelectedItem()).getSequence();
-          if (userSelectedSeq != null)
-          {
-            selectedSequence = userSelectedSeq;
-          }
-          PDBEntry fileEntry = new AssociatePdbFileWithSeq()
-                  .associatePdbWithSeq(selectedPdbFileName,
-                          jalview.io.AppletFormatAdapter.FILE,
-                          selectedSequence, true, Desktop.instance);
+    }
+    else if (currentView == VIEWS_FROM_FILE)
+    {
+      SequenceI userSelectedSeq = ((AssociateSeqOptions) fileChooserAssSeqPanel
+              .getCmb_assSeq().getSelectedItem()).getSequence();
+      if (userSelectedSeq != null)
+      {
+        selectedSequence = userSelectedSeq;
+      }
+      PDBEntry fileEntry = new AssociatePdbFileWithSeq()
+              .associatePdbWithSeq(selectedPdbFileName,
+                          DataSourceType.FILE,
+                      selectedSequence, true, Desktop.instance);
 
           launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
                   new SequenceI[] { selectedSequence });
index 7df42fd..91d7130 100644 (file)
@@ -24,16 +24,21 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.gui.StructureViewer.ViewerType;
 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
-import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
 import jalview.jbgui.GStructureViewer;
 import jalview.structures.models.AAStructureBindingModel;
 import jalview.util.MessageManager;
 
 import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
 
+import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 
@@ -76,6 +81,8 @@ public abstract class StructureViewerBase extends GStructureViewer
 
   protected Thread worker = null;
 
+  protected boolean allChainsSelected = false;
+
   /**
    * 
    * @param ap2
@@ -152,6 +159,7 @@ public abstract class StructureViewerBase extends GStructureViewer
     this.ap = alp;
   }
 
+  @Override
   public AlignmentPanel[] getAllAlignmentPanels()
   {
     AlignmentPanel[] t, list = new AlignmentPanel[0];
@@ -291,6 +299,7 @@ public abstract class StructureViewerBase extends GStructureViewer
         // queue.
         new Thread(new Runnable()
         {
+          @Override
           public void run()
           {
             while (worker != null && worker.isAlive() && _started)
@@ -327,17 +336,17 @@ public abstract class StructureViewerBase extends GStructureViewer
    * 
    * @param pdbId
    * @param view
-   * @return YES, NO or CANCEL JOptionPane code
+   * @return YES, NO or CANCEL JvOptionPane code
    */
   protected int chooseAlignStructureToViewer(String pdbId,
           StructureViewerBase view)
   {
-    int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+    int option = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
             MessageManager.formatMessage("label.add_pdbentry_to_view",
                     new Object[] { pdbId, view.getTitle() }),
             MessageManager
                     .getString("label.align_to_existing_structure_view"),
-            JOptionPane.YES_NO_CANCEL_OPTION);
+            JvOptionPane.YES_NO_CANCEL_OPTION);
     return option;
   }
 
@@ -372,11 +381,11 @@ public abstract class StructureViewerBase extends GStructureViewer
         continue;
       }
       int option = chooseAlignStructureToViewer(pdbId, view);
-      if (option == JOptionPane.CANCEL_OPTION)
+      if (option == JvOptionPane.CANCEL_OPTION)
       {
         return true;
       }
-      else if (option == JOptionPane.YES_OPTION)
+      else if (option == JvOptionPane.YES_OPTION)
       {
         view.useAlignmentPanelForSuperposition(apanel);
         view.addStructure(pdbentry, seq, chains, true, apanel.alignFrame);
@@ -411,7 +420,7 @@ public abstract class StructureViewerBase extends GStructureViewer
      * create the mappings
      */
     apanel.getStructureSelectionManager().setMapping(seq, chains,
-            pdbFilename, AppletFormatAdapter.FILE);
+            pdbFilename, DataSourceType.FILE);
 
     /*
      * alert the FeatureRenderer to show new (PDB RESNUM) features
@@ -472,19 +481,19 @@ public abstract class StructureViewerBase extends GStructureViewer
       /*
        * the PDB file is already loaded
        */
-      int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+      int option = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
               MessageManager.formatMessage(
                       "label.pdb_entry_is_already_displayed",
                       new Object[] { pdbId }), MessageManager
                       .formatMessage(
                               "label.map_sequences_to_visible_window",
                               new Object[] { pdbId }),
-              JOptionPane.YES_NO_CANCEL_OPTION);
-      if (option == JOptionPane.CANCEL_OPTION)
+              JvOptionPane.YES_NO_CANCEL_OPTION);
+      if (option == JvOptionPane.CANCEL_OPTION)
       {
         finished = true;
       }
-      else if (option == JOptionPane.YES_OPTION)
+      else if (option == JvOptionPane.YES_OPTION)
       {
         addSequenceMappingsToStructure(seq, chains, apanel, alreadyMapped);
         finished = true;
@@ -492,4 +501,55 @@ public abstract class StructureViewerBase extends GStructureViewer
     }
     return finished;
   }
+
+  void setChainMenuItems(List<String> chainNames)
+  {
+    chainMenu.removeAll();
+    if (chainNames == null || chainNames.isEmpty())
+    {
+      return;
+    }
+    JMenuItem menuItem = new JMenuItem(
+            MessageManager.getString("label.all"));
+    menuItem.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent evt)
+      {
+        allChainsSelected = true;
+        for (int i = 0; i < chainMenu.getItemCount(); i++)
+        {
+          if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
+          {
+            ((JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);
+          }
+        }
+        showSelectedChains();
+        allChainsSelected = false;
+      }
+    });
+
+    chainMenu.add(menuItem);
+
+    for (String chain : chainNames)
+    {
+      menuItem = new JCheckBoxMenuItem(chain, true);
+      menuItem.addItemListener(new ItemListener()
+      {
+        @Override
+        public void itemStateChanged(ItemEvent evt)
+        {
+          if (!allChainsSelected)
+          {
+            showSelectedChains();
+          }
+        }
+      });
+
+      chainMenu.add(menuItem);
+    }
+  }
+
+  abstract void showSelectedChains();
+
 }
index 39d9c1d..49fdaf7 100644 (file)
@@ -128,16 +128,16 @@ public class TextColourChooser
       }
     });
 
-    int reply = JOptionPane
+    int reply = JvOptionPane
             .showInternalOptionDialog(
                     ap,
                     bigpanel,
                     MessageManager
                             .getString("label.adjunst_foreground_text_colour_threshold"),
-                    JOptionPane.OK_CANCEL_OPTION,
-                    JOptionPane.QUESTION_MESSAGE, null, null, null);
+                    JvOptionPane.OK_CANCEL_OPTION,
+                    JvOptionPane.QUESTION_MESSAGE, null, null, null);
 
-    if (reply == JOptionPane.CANCEL_OPTION)
+    if (reply == JvOptionPane.CANCEL_OPTION)
     {
       if (sg == null)
       {
index 0e513f7..84fd82f 100755 (executable)
@@ -1017,8 +1017,8 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
         if (aps[a].av.getGlobalColourScheme() != null
                 && aps[a].av.getGlobalColourScheme().conservationApplied())
         {
-          Conservation c = new Conservation("Group", 3,
-                  sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
+          Conservation c = new Conservation("Group", sg.getSequences(null),
+                  sg.getStartRes(), sg.getEndRes());
           c.calculate();
           c.verdict(false, aps[a].av.getConsPercGaps());
           sg.cs.setConservation(c);
index fafa610..6fa4493 100755 (executable)
@@ -42,6 +42,7 @@ import jalview.io.JalviewFileView;
 import jalview.io.NewickFile;
 import jalview.jbgui.GTreePanel;
 import jalview.schemes.ResidueProperties;
+import jalview.util.ImageMaker;
 import jalview.util.MessageManager;
 import jalview.viewmodel.AlignmentViewport;
 
@@ -747,24 +748,23 @@ public class TreePanel extends GTreePanel
 
     try
     {
-      jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(
-              jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
-              { "eps" }, new String[] { "Encapsulated Postscript" },
-              "Encapsulated Postscript");
-      chooser.setFileView(new jalview.io.JalviewFileView());
+      JalviewFileChooser chooser = new JalviewFileChooser(
+              Cache.getProperty("LAST_DIRECTORY"),
+              ImageMaker.EPS_EXTENSION, ImageMaker.EPS_EXTENSION);
+      chooser.setFileView(new JalviewFileView());
       chooser.setDialogTitle(MessageManager
               .getString("label.create_eps_from_tree"));
       chooser.setToolTipText(MessageManager.getString("action.save"));
 
       int value = chooser.showSaveDialog(this);
 
-      if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)
+      if (value != JalviewFileChooser.APPROVE_OPTION)
       {
         return;
       }
 
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
-              .getSelectedFile().getParent());
+      Cache.setProperty("LAST_DIRECTORY", chooser.getSelectedFile()
+              .getParent());
 
       FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());
       EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width, height);
@@ -795,10 +795,9 @@ public class TreePanel extends GTreePanel
 
     try
     {
-      jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(
-              jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
-              { "png" }, new String[] { "Portable network graphics" },
-              "Portable network graphics");
+      JalviewFileChooser chooser = new JalviewFileChooser(
+              Cache.getProperty("LAST_DIRECTORY"),
+              ImageMaker.PNG_EXTENSION, ImageMaker.PNG_DESCRIPTION);
 
       chooser.setFileView(new jalview.io.JalviewFileView());
       chooser.setDialogTitle(MessageManager
index c9c1531..0df23e0 100755 (executable)
 package jalview.gui;
 
 import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.bin.Cache;
 import jalview.datamodel.SequenceGroup;
 import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
 import jalview.jbgui.GUserDefinedColours;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
@@ -46,7 +48,6 @@ import java.util.StringTokenizer;
 
 import javax.swing.JButton;
 import javax.swing.JInternalFrame;
-import javax.swing.JOptionPane;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 
@@ -456,10 +457,10 @@ public class UserDefinedColours extends GUserDefinedColours implements
   {
     if (isNoSelectionMade())
     {
-      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
               .getString("label.no_colour_selection_in_scheme"),
               MessageManager.getString("label.no_colour_selection_warn"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
     }
     else
     {
@@ -502,10 +503,10 @@ public class UserDefinedColours extends GUserDefinedColours implements
   {
     if (isNoSelectionMade())
     {
-      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
               .getString("label.no_colour_selection_in_scheme"),
               MessageManager.getString("label.no_colour_selection_warn"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
 
     }
     UserColourScheme ucs = getSchemeFromButtons();
@@ -597,10 +598,9 @@ public class UserDefinedColours extends GUserDefinedColours implements
     lowerCaseButtons = new ArrayList<JButton>();
 
     JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "jc" }, new String[] { "Jalview User Colours" },
+            Cache.getProperty("LAST_DIRECTORY"), "jc",
             "Jalview User Colours");
-    chooser.setFileView(new jalview.io.JalviewFileView());
+    chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
             .getString("label.load_colour_scheme"));
     chooser.setToolTipText(MessageManager.getString("action.load"));
@@ -809,23 +809,23 @@ public class UserDefinedColours extends GUserDefinedColours implements
   {
     if (schemeName.getText().trim().length() < 1)
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
               .getString("label.user_colour_scheme_must_have_name"),
               MessageManager.getString("label.no_name_colour_scheme"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
       return;
     }
 
     if (userColourSchemes != null
             && userColourSchemes.containsKey(schemeName.getText()))
     {
-      int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+      int reply = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
               MessageManager.formatMessage(
                       "label.colour_scheme_exists_overwrite", new Object[] {
                           schemeName.getText(), schemeName.getText() }),
               MessageManager.getString("label.duplicate_scheme_name"),
-              JOptionPane.YES_NO_OPTION);
-      if (reply != JOptionPane.YES_OPTION)
+              JvOptionPane.YES_NO_OPTION);
+      if (reply != JvOptionPane.YES_OPTION)
       {
         return;
       }
@@ -833,11 +833,10 @@ public class UserDefinedColours extends GUserDefinedColours implements
       userColourSchemes.remove(schemeName.getText());
     }
     JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "jc" }, new String[] { "Jalview User Colours" },
+            Cache.getProperty("LAST_DIRECTORY"), "jc",
             "Jalview User Colours");
 
-    chooser.setFileView(new jalview.io.JalviewFileView());
+    chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
             .getString("label.save_colour_scheme"));
     chooser.setToolTipText(MessageManager.getString("action.save"));
index eb38ee6..5e5d965 100644 (file)
@@ -142,15 +142,15 @@ public class UserQuestionnaireCheck implements Runnable
                 + qid + "&rid=" + rid;
         jalview.bin.Cache.log.info("Prompting user for questionnaire at "
                 + qurl);
-        int reply = JOptionPane
+        int reply = JvOptionPane
                 .showInternalConfirmDialog(Desktop.desktop, MessageManager
                         .getString("label.jalview_new_questionnaire"),
                         MessageManager
                                 .getString("label.jalview_user_survey"),
-                        JOptionPane.YES_NO_OPTION,
-                        JOptionPane.QUESTION_MESSAGE);
+                        JvOptionPane.YES_NO_OPTION,
+                        JvOptionPane.QUESTION_MESSAGE);
 
-        if (reply == JOptionPane.YES_OPTION)
+        if (reply == JvOptionPane.YES_OPTION)
         {
           jalview.bin.Cache.log.debug("Opening " + qurl);
           jalview.util.BrowserLauncher.openURL(qurl);
index afb6df4..75ddba5 100644 (file)
@@ -174,7 +174,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
           }
         } catch (InvalidSessionDocumentException e)
         {
-          JOptionPane
+          JvOptionPane
                   .showInternalMessageDialog(
                           Desktop.desktop,
 
@@ -182,7 +182,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
                                   .getString("label.vamsas_doc_couldnt_be_opened_as_new_session"),
                           MessageManager
                                   .getString("label.vamsas_document_import_failed"),
-                          JOptionPane.ERROR_MESSAGE);
+                          JvOptionPane.ERROR_MESSAGE);
 
         }
       }
@@ -665,15 +665,15 @@ public class VamsasApplication implements SelectionSource, VamsasSource
                 {
                   Cache.log
                           .debug("Asking user if the vamsas session should be stored.");
-                  int reply = JOptionPane
+                  int reply = JvOptionPane
                           .showInternalConfirmDialog(
                                   Desktop.desktop,
                                   "The current VAMSAS session has unsaved data - do you want to save it ?",
                                   "VAMSAS Session Shutdown",
-                                  JOptionPane.YES_NO_OPTION,
-                                  JOptionPane.QUESTION_MESSAGE);
+                                  JvOptionPane.YES_NO_OPTION,
+                                  JvOptionPane.QUESTION_MESSAGE);
 
-                  if (reply == JOptionPane.YES_OPTION)
+                  if (reply == JvOptionPane.YES_OPTION)
                   {
                     Cache.log.debug("Prompting for vamsas store filename.");
                     Desktop.instance.vamsasSave_actionPerformed(null);
index dd0e6c2..f650807 100644 (file)
@@ -707,8 +707,8 @@ public class WebserviceInfo extends GWebserviceInfo implements
     {
       public void run()
       {
-        JOptionPane.showInternalMessageDialog(Desktop.desktop, message,
-                title, JOptionPane.WARNING_MESSAGE);
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop, message,
+                title, JvOptionPane.WARNING_MESSAGE);
 
       }
     });
index c4d215e..17c0760 100644 (file)
@@ -61,7 +61,6 @@ import javax.swing.JComboBox;
 import javax.swing.JDialog;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JSplitPane;
@@ -233,6 +232,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
     frame.validate();
     javax.swing.SwingUtilities.invokeLater(new Runnable()
     {
+      @Override
       public void run()
       {
         // jobPanel.setDividerLocation(0.25);
@@ -272,6 +272,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
             new ActionListener()
             {
 
+              @Override
               public void actionPerformed(ActionEvent e)
               {
                 update_actionPerformed(e);
@@ -283,6 +284,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
             new ActionListener()
             {
 
+              @Override
               public void actionPerformed(ActionEvent e)
               {
                 delete_actionPerformed(e);
@@ -294,6 +296,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
             new ActionListener()
             {
 
+              @Override
               public void actionPerformed(ActionEvent e)
               {
                 create_actionPerformed(e);
@@ -305,6 +308,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
             new ActionListener()
             {
 
+              @Override
               public void actionPerformed(ActionEvent e)
               {
                 revert_actionPerformed(e);
@@ -315,6 +319,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
             MessageManager.getString("label.start_job_current_settings"),
             new ActionListener()
             {
+              @Override
               public void actionPerformed(ActionEvent e)
               {
                 startjob_actionPerformed(e);
@@ -325,6 +330,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
             MessageManager.getString("label.cancel_job_close_dialog"),
             new ActionListener()
             {
+              @Override
               public void actionPerformed(ActionEvent e)
               {
                 canceljob_actionPerformed(e);
@@ -736,6 +742,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
     validate();
   }
 
+  @Override
   public void argSetModified(Object modifiedElement, boolean b)
   {
     if (settingDialog)
@@ -827,6 +834,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
     settingDialog = stn;
   }
 
+  @Override
   public void refreshParamLayout()
   {
     // optsAndparams.setPreferredSize(null);
@@ -1113,40 +1121,47 @@ public class WsJobParameters extends JPanel implements ItemListener,
             jf.addWindowListener(new WindowListener()
             {
 
+              @Override
               public void windowActivated(WindowEvent e)
               {
                 // TODO Auto-generated method stub
 
               }
 
+              @Override
               public void windowClosed(WindowEvent e)
               {
               }
 
+              @Override
               public void windowClosing(WindowEvent e)
               {
                 thr.interrupt();
 
               }
 
+              @Override
               public void windowDeactivated(WindowEvent e)
               {
                 // TODO Auto-generated method stub
 
               }
 
+              @Override
               public void windowDeiconified(WindowEvent e)
               {
                 // TODO Auto-generated method stub
 
               }
 
+              @Override
               public void windowIconified(WindowEvent e)
               {
                 // TODO Auto-generated method stub
 
               }
 
+              @Override
               public void windowOpened(WindowEvent e)
               {
                 // TODO Auto-generated method stub
@@ -1316,6 +1331,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
 
   String curSetName = null;
 
+  @Override
   public void itemStateChanged(ItemEvent e)
   {
     if (e.getSource() == setName && e.getStateChange() == e.SELECTED)
@@ -1334,6 +1350,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
       }
       javax.swing.SwingUtilities.invokeLater(new Runnable()
       {
+        @Override
         public void run()
         {
           doPreferenceComboStateChange(setname);
@@ -1355,14 +1372,14 @@ public class WsJobParameters extends JPanel implements ItemListener,
       }
       settingDialog = true;
       System.out.println("Prompting to save " + lsetname);
-      if (javax.swing.JOptionPane
+      if (JvOptionPane
               .showConfirmDialog(
                       this,
                       "Parameter set '"
                               + lsetname
                               + "' is modifed, and your changes will be lost.\nReally change preset ?",
                       "Warning: Unsaved Changes",
-                      javax.swing.JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION)
+                      JvOptionPane.OK_CANCEL_OPTION) != JvOptionPane.OK_OPTION)
       {
         // revert the combobox to the current item
         settingDialog = true;
@@ -1414,6 +1431,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
    */
   String lastDescrText = null;
 
+  @Override
   public void actionPerformed(ActionEvent e)
   {
     if (e.getSource() instanceof Component)
@@ -1434,12 +1452,13 @@ public class WsJobParameters extends JPanel implements ItemListener,
           settingDialog = false;
           javax.swing.SwingUtilities.invokeLater(new Runnable()
           {
+            @Override
             public void run()
             {
-              JOptionPane.showMessageDialog(ourframe, MessageManager
+              JvOptionPane.showMessageDialog(ourframe, MessageManager
                       .getString("label.invalid_name_preset_exists"),
                       MessageManager.getString("label.invalid_name"),
-                      JOptionPane.WARNING_MESSAGE);
+                      JvOptionPane.WARNING_MESSAGE);
             }
           });
 
@@ -1475,16 +1494,19 @@ public class WsJobParameters extends JPanel implements ItemListener,
     }
   }
 
+  @Override
   public void insertUpdate(DocumentEvent e)
   {
     checkDescrModified();
   }
 
+  @Override
   public void removeUpdate(DocumentEvent e)
   {
     checkDescrModified();
   }
 
+  @Override
   public void changedUpdate(DocumentEvent e)
   {
     checkDescrModified();
index b6a7672..b260e1b 100644 (file)
@@ -22,6 +22,7 @@ package jalview.gui;
 
 import jalview.bin.Cache;
 import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
 import jalview.util.MessageManager;
 import jalview.ws.params.ParamDatastoreI;
 import jalview.ws.params.ParamManager;
@@ -38,8 +39,6 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.StringTokenizer;
 
-import javax.swing.JOptionPane;
-
 /**
  * store and retrieve web service parameter sets.
  * 
@@ -185,11 +184,9 @@ public class WsParamSetManager implements ParamManager
     if (filename == null)
     {
       JalviewFileChooser chooser = new JalviewFileChooser(
-              jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
-              { "wsparams" },
-              new String[] { "Web Service Parameter File" },
+              Cache.getProperty("LAST_DIRECTORY"), "wsparams",
               "Web Service Parameter File");
-      chooser.setFileView(new jalview.io.JalviewFileView());
+      chooser.setFileView(new JalviewFileView());
       chooser.setDialogTitle(MessageManager
               .getString("label.choose_filename_for_param_file"));
       chooser.setToolTipText(MessageManager.getString("action.save"));
@@ -294,9 +291,9 @@ public class WsParamSetManager implements ParamManager
       File pfile = new File(filename);
       if (pfile.exists() && pfile.canWrite())
       {
-        if (JOptionPane.showConfirmDialog(Desktop.instance,
+        if (JvOptionPane.showConfirmDialog(Desktop.instance,
                 "Delete the preset's file, too ?", "Delete User Preset ?",
-                JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION)
+                JvOptionPane.OK_CANCEL_OPTION) == JvOptionPane.OK_OPTION)
         {
           pfile.delete();
         }
index 6ec25b2..165e8f2 100644 (file)
@@ -459,11 +459,11 @@ public class WsPreferences extends GWsPreferences
     pane12.add(urltf, BorderLayout.EAST);
     panel.add(pane12, BorderLayout.NORTH);
     boolean valid = false;
-    int resp = JOptionPane.CANCEL_OPTION;
+    int resp = JvOptionPane.CANCEL_OPTION;
     while (!valid
-            && (resp = JOptionPane.showInternalConfirmDialog(
+            && (resp = JvOptionPane.showInternalConfirmDialog(
                     Desktop.desktop, panel, title,
-                    JOptionPane.OK_CANCEL_OPTION)) == JOptionPane.OK_OPTION)
+                    JvOptionPane.OK_CANCEL_OPTION)) == JvOptionPane.OK_OPTION)
     {
       try
       {
@@ -480,18 +480,18 @@ public class WsPreferences extends GWsPreferences
       } catch (Exception e)
       {
         valid = false;
-        JOptionPane.showInternalMessageDialog(Desktop.desktop,
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                 MessageManager.getString("label.invalid_url"));
       }
     }
-    if (valid && resp == JOptionPane.OK_OPTION)
+    if (valid && resp == JvOptionPane.OK_OPTION)
     {
-      int validate = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+      int validate = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
               MessageManager.getString("info.validate_jabaws_server"),
               MessageManager.getString("label.test_server"),
-              JOptionPane.YES_NO_OPTION);
+              JvOptionPane.YES_NO_OPTION);
 
-      if (validate == JOptionPane.OK_OPTION)
+      if (validate == JvOptionPane.OK_OPTION)
       {
         if (Jws2Discoverer.testServiceUrl(foo))
         {
@@ -499,22 +499,22 @@ public class WsPreferences extends GWsPreferences
         }
         else
         {
-          int opt = JOptionPane
+          int opt = JvOptionPane
                   .showInternalOptionDialog(
                           Desktop.desktop,
                           "The Server  '"
                                   + foo.toString()
                                   + "' failed validation,\ndo you want to add it anyway? ",
                           "Server Validation Failed",
-                          JOptionPane.YES_NO_OPTION,
-                          JOptionPane.INFORMATION_MESSAGE, null, null, null);
-          if (opt == JOptionPane.YES_OPTION)
+                          JvOptionPane.YES_NO_OPTION,
+                          JvOptionPane.INFORMATION_MESSAGE, null, null, null);
+          if (opt == JvOptionPane.YES_OPTION)
           {
             return foo.toString();
           }
           else
           {
-            JOptionPane
+            JvOptionPane
                     .showInternalMessageDialog(
                             Desktop.desktop,
                             MessageManager
index f82407e..34eace4 100644 (file)
@@ -22,6 +22,9 @@ package jalview.io;
 
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+
+import java.io.IOException;
 
 public class AMSAFile extends jalview.io.FastaFile
 {
@@ -36,14 +39,26 @@ public class AMSAFile extends jalview.io.FastaFile
     this.al = al;
   }
 
+  public AMSAFile(String inFile, DataSourceType sourceType)
+          throws IOException
+  {
+    super(inFile, sourceType);
+  }
+
+  public AMSAFile(FileParse source) throws IOException
+  {
+    super(source);
+  }
+
   /**
    * DOCUMENT ME!
    * 
    * @return DOCUMENT ME!
    */
-  public String print()
+  @Override
+  public String print(SequenceI[] sqs, boolean jvsuffix)
   {
-    super.print(getSeqsAsArray());
+    super.print(sqs, jvsuffix);
 
     AlignmentAnnotation aa;
     if (al.getAlignmentAnnotation() != null)
index 5760fbe..4de510a 100755 (executable)
@@ -40,7 +40,7 @@ import java.util.Vector;
  * @author $author$
  * @version $Revision$
  */
-public abstract class AlignFile extends FileParse
+public abstract class AlignFile extends FileParse implements AlignmentFileI
 {
   int noSeqs = 0;
 
@@ -65,14 +65,12 @@ public abstract class AlignFile extends FileParse
   /**
    * Properties to be added to generated alignment object
    */
-  protected Hashtable properties;
+  private Hashtable properties;
 
   long start;
 
   long end;
 
-  boolean jvSuffix = true;
-
   private boolean parseCalled;
 
   /**
@@ -86,17 +84,24 @@ public abstract class AlignFile extends FileParse
     initData();
   }
 
+  public AlignFile(SequenceI[] seqs)
+  {
+    this();
+    setSeqs(seqs);
+  }
+
   /**
    * Constructor which parses the data from a file of some specified type.
    * 
    * @param dataObject
    *          Filename, URL or Pasted String to read from.
-   * @param type
+   * @param sourceType
    *          What type of file to read from (File, URL, Pasted String)
    */
-  public AlignFile(String dataObject, String type) throws IOException
+  public AlignFile(String dataObject, DataSourceType sourceType)
+          throws IOException
   {
-    this(true, dataObject, type);
+    this(true, dataObject, sourceType);
   }
 
   /**
@@ -107,14 +112,15 @@ public abstract class AlignFile extends FileParse
    *          if false, need to call 'doParse()' to begin parsing data
    * @param dataObject
    *          Filename, URL or Pasted String to read from.
-   * @param type
+   * @param sourceType
    *          What type of file to read from (File, URL)
    * @throws IOException
    */
-  public AlignFile(boolean parseImmediately, String dataObject, String type)
+  public AlignFile(boolean parseImmediately, String dataObject,
+          DataSourceType sourceType)
           throws IOException
   {
-    super(dataObject, type);
+    super(dataObject, sourceType);
     initData();
     if (parseImmediately)
     {
@@ -191,6 +197,7 @@ public abstract class AlignFile extends FileParse
   /**
    * Return the Sequences in the seqs Vector as an array of Sequences
    */
+  @Override
   public SequenceI[] getSeqsAsArray()
   {
     SequenceI[] s = new SequenceI[seqs.size()];
@@ -209,6 +216,7 @@ public abstract class AlignFile extends FileParse
    * 
    * @param al
    */
+  @Override
   public void addAnnotations(AlignmentI al)
   {
     addProperties(al);
@@ -314,7 +322,8 @@ public abstract class AlignFile extends FileParse
    * @param s
    *          DOCUMENT ME!
    */
-  protected void setSeqs(SequenceI[] s)
+  @Override
+  public void setSeqs(SequenceI[] s)
   {
     seqs = new Vector<SequenceI>();
 
@@ -330,16 +339,6 @@ public abstract class AlignFile extends FileParse
   public abstract void parse() throws IOException;
 
   /**
-   * Print out in alignment file format the Sequences in the seqs Vector.
-   */
-  public abstract String print();
-
-  public void addJVSuffix(boolean b)
-  {
-    jvSuffix = b;
-  }
-
-  /**
    * A general parser for ids.
    * 
    * @String id Id to be parsed
@@ -371,14 +370,21 @@ public abstract class AlignFile extends FileParse
   }
 
   /**
-   * Creates the output id. Adds prefix Uniprot format source|id And suffix
-   * Jalview /start-end
+   * Creates the output id. Adds prefix Uniprot format source|id and optionally
+   * suffix Jalview /start-end
+   * 
+   * @param jvsuffix
    * 
    * @String id Id to be parsed
    */
+  String printId(SequenceI seq, boolean jvsuffix)
+  {
+    return seq.getDisplayId(jvsuffix);
+  }
+
   String printId(SequenceI seq)
   {
-    return seq.getDisplayId(jvSuffix);
+    return printId(seq, true);
   }
 
   /**
@@ -400,6 +406,7 @@ public abstract class AlignFile extends FileParse
     return newickStrings == null ? 0 : newickStrings.size();
   }
 
+  @Override
   public void addGroups(AlignmentI al)
   {
 
diff --git a/src/jalview/io/AlignmentFileI.java b/src/jalview/io/AlignmentFileI.java
new file mode 100644 (file)
index 0000000..1a000a3
--- /dev/null
@@ -0,0 +1,38 @@
+package jalview.io;
+
+import jalview.api.AlignExportSettingI;
+import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureSettingsModelI;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+
+public interface AlignmentFileI
+{
+
+  SequenceI[] getSeqsAsArray();
+
+  void addAnnotations(AlignmentI al);
+
+  void addGroups(AlignmentI al);
+
+  void setNewlineString(String newline);
+
+  void setExportSettings(AlignExportSettingI exportSettings);
+
+  void configureForView(AlignmentViewPanel viewpanel);
+
+  void setSeqs(SequenceI[] sequencesArray);
+
+  String print(SequenceI[] seqs, boolean jvsuffix);
+
+  boolean hasWarningMessage();
+
+  String getWarningMessage();
+
+  String getInFile();
+
+  DataSourceType getDataSourceType();
+
+  FeatureSettingsModelI getFeatureColourScheme();
+
+}
index 34fdabe..82e71b5 100755 (executable)
@@ -660,7 +660,7 @@ public class AnnotationFile
   String refSeqId = null;
 
   public boolean annotateAlignmentView(AlignViewportI viewport,
-          String file, String protocol)
+          String file, DataSourceType protocol)
   {
     ColumnSelection colSel = viewport.getColumnSelection();
     if (colSel == null)
@@ -678,31 +678,31 @@ public class AnnotationFile
   }
 
   public boolean readAnnotationFile(AlignmentI al, String file,
-          String protocol)
+          DataSourceType sourceType)
   {
-    return readAnnotationFile(al, null, file, protocol);
+    return readAnnotationFile(al, null, file, sourceType);
   }
 
   public boolean readAnnotationFile(AlignmentI al, ColumnSelection colSel,
-          String file, String protocol)
+          String file, DataSourceType sourceType)
   {
     BufferedReader in = null;
     try
     {
-      if (protocol.equals(AppletFormatAdapter.FILE))
+      if (sourceType == DataSourceType.FILE)
       {
         in = new BufferedReader(new FileReader(file));
       }
-      else if (protocol.equals(AppletFormatAdapter.URL))
+      else if (sourceType == DataSourceType.URL)
       {
         URL url = new URL(file);
         in = new BufferedReader(new InputStreamReader(url.openStream()));
       }
-      else if (protocol.equals(AppletFormatAdapter.PASTE))
+      else if (sourceType == DataSourceType.PASTE)
       {
         in = new BufferedReader(new StringReader(file));
       }
-      else if (protocol.equals(AppletFormatAdapter.CLASSLOADER))
+      else if (sourceType == DataSourceType.CLASSLOADER)
       {
         java.io.InputStream is = getClass().getResourceAsStream("/" + file);
         if (is != null)
@@ -1637,9 +1637,8 @@ public class AnnotationFile
         else if (key.equalsIgnoreCase("consThreshold"))
         {
           sg.cs.setConservationInc(Integer.parseInt(value));
-          Conservation c = new Conservation("Group", 3,
-                  sg.getSequences(null), sg.getStartRes(),
-                  sg.getEndRes() + 1);
+          Conservation c = new Conservation("Group", sg.getSequences(null),
+                  sg.getStartRes(), sg.getEndRes() + 1);
 
           c.calculate();
           c.verdict(false, 25); // TODO: refer to conservation percent threshold
index 9695891..45d65d6 100755 (executable)
@@ -27,9 +27,9 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.PDBEntry.Type;
+import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JmolParser;
 import jalview.structure.StructureImportSettings;
-import jalview.util.MessageManager;
 
 import java.io.File;
 import java.io.IOException;
@@ -49,14 +49,6 @@ public class AppletFormatAdapter
 {
   private AlignmentViewPanel viewpanel;
 
-  public static String FILE = "File";
-
-  public static String URL = "URL";
-
-  public static String PASTE = "Paste";
-
-  public static String CLASSLOADER = "ClassLoader";
-
   /**
    * add jalview-derived non-secondary structure annotation from PDB structure
    */
@@ -72,7 +64,7 @@ public class AppletFormatAdapter
    */
   boolean serviceSecondaryStruct = false;
 
-  private AlignFile alignFile = null;
+  private AlignmentFileI alignFile = null;
 
   String inFile;
 
@@ -83,61 +75,10 @@ public class AppletFormatAdapter
 
   private AlignExportSettingI exportSettings;
 
-  /**
-   * 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, JSONFile.FILE_DESC,
-      IdentifyFile.FeaturesFile, "HTML", "mmCIF" };
-
-  /**
-   * 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, JSONFile.FILE_EXT,
-      ".gff2,gff3", "jar,jvp", HtmlFile.FILE_EXT, "cif" };
-
-  /**
-   * 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, JSONFile.FILE_DESC, IdentifyFile.FeaturesFile,
-      "Jalview", HtmlFile.FILE_DESC, "mmCIF" };
-
-  /**
-   * List of valid format strings for use by callers of the formatSequences
-   * method
-   */
-  public static final String[] WRITEABLE_FORMATS = new String[] { "BLC",
-      "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "AMSA", "STH",
-      PhylipFile.FILE_DESC, JSONFile.FILE_DESC };
-
-  /**
-   * List of extensions corresponding to file format types in WRITABLE_FNAMES
-   * that are writable by the application.
-   */
-  public static final String[] WRITABLE_EXTENSIONS = new String[] {
-      "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
-      "sto,stk", PhylipFile.FILE_EXT, JSONFile.FILE_EXT, "jvp" };
-
-  /**
-   * List of writable formats by the application. Order must correspond with the
-   * WRITABLE_EXTENSIONS list of formats.
-   */
-  public static final String[] WRITABLE_FNAMES = new String[] { "Fasta",
-      "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "STH",
-      PhylipFile.FILE_DESC, JSONFile.FILE_DESC, "Jalview" };
-
   public static String INVALID_CHARACTERS = "Contains invalid characters";
 
-  // TODO: make these messages dynamic
   public static String SUPPORTED_FORMATS = "Formats currently supported are\n"
-          + prettyPrint(READABLE_FORMATS);
+          + prettyPrint(FileFormat.getReadableFormats());
 
   public AppletFormatAdapter()
   {
@@ -156,19 +97,21 @@ public class AppletFormatAdapter
   }
 
   /**
-   *
-   * @param els
-   * @return grammatically correct(ish) list consisting of els elements.
+   * Formats a grammatically correct(ish) list consisting of the given objects
+   * 
+   * @param things
+   * @return
    */
-  public static String prettyPrint(String[] els)
+  public static String prettyPrint(List<? extends Object> things)
   {
     StringBuffer list = new StringBuffer();
-    for (int i = 0, iSize = els.length - 1; i < iSize; i++)
+    for (int i = 0, iSize = things.size() - 1; i < iSize; i++)
     {
-      list.append(els[i]);
+      list.append(things.get(i).toString());
       list.append(", ");
     }
-    list.append(" and " + els[els.length - 1] + ".");
+    // could i18n 'and' here
+    list.append(" and " + things.get(things.size() - 1).toString() + ".");
     return list.toString();
   }
 
@@ -183,200 +126,89 @@ public class AppletFormatAdapter
   }
 
   /**
-   * check that this format is valid for reading
-   *
-   * @param format
-   *          a format string to be compared with READABLE_FORMATS
-   * @return true if format is readable
-   */
-  public static final boolean isValidFormat(String format)
-  {
-    return isValidFormat(format, false);
-  }
-
-  /**
-   * validate format is valid for IO
-   *
-   * @param format
-   *          a format string to be compared with either READABLE_FORMATS or
-   *          WRITEABLE_FORMATS
-   * @param forwriting
-   *          when true, format is checked for containment in WRITEABLE_FORMATS
-   * @return true if format is valid
-   */
-  public static final boolean isValidFormat(String format,
-          boolean forwriting)
-  {
-    if (format == null)
-    {
-      return false;
-    }
-    boolean valid = false;
-    String[] format_list = (forwriting) ? WRITEABLE_FORMATS
-            : READABLE_FORMATS;
-    for (String element : format_list)
-    {
-      if (element.equalsIgnoreCase(format))
-      {
-        return true;
-      }
-    }
-
-    return valid;
-  }
-
-  /**
    * Constructs the correct filetype parser for a characterised datasource
    *
    * @param inFile
    *          data/data location
-   * @param type
+   * @param sourceType
    *          type of datasource
-   * @param format
-   *          File format of data provided by datasource
+   * @param fileFormat
    *
-   * @return DOCUMENT ME!
+   * @return
    */
-  public AlignmentI readFile(String inFile, String type, String format)
-          throws java.io.IOException
+  public AlignmentI readFile(String file, DataSourceType sourceType,
+          FileFormatI fileFormat) throws IOException
   {
-    // TODO: generalise mapping between format string and io. class instances
-    // using Constructor.invoke reflection
-    this.inFile = inFile;
+    this.inFile = file;
     try
     {
-      if (format.equals("FASTA"))
-      {
-        alignFile = new FastaFile(inFile, type);
-      }
-      else if (format.equals("MSF"))
-      {
-        alignFile = new MSFfile(inFile, type);
-      }
-      else if (format.equals("PileUp"))
-      {
-        alignFile = new PileUpfile(inFile, type);
-      }
-      else if (format.equals("CLUSTAL"))
-      {
-        alignFile = new ClustalFile(inFile, type);
-      }
-      else if (format.equals("BLC"))
-      {
-        alignFile = new BLCFile(inFile, type);
-      }
-      else if (format.equals("PIR"))
-      {
-        alignFile = new PIRFile(inFile, type);
-      }
-      else if (format.equals("PFAM"))
+      if (fileFormat.isStructureFile())
       {
-        alignFile = new PfamFile(inFile, type);
-      }
-      else if (format.equals("JnetFile"))
-      {
-        alignFile = new JPredFile(inFile, type);
-        ((JPredFile) alignFile).removeNonSequences();
-      }
-      else if (format.equals("PDB"))
-      {
-        // TODO obtain config value from preference settings.
-        // Set value to 'true' to test PDB processing with Jmol: JAL-1213
-        boolean isParseWithJMOL = StructureImportSettings
-                .getDefaultPDBFileParser().equalsIgnoreCase(
+        String structureParser = StructureImportSettings
+                .getDefaultPDBFileParser();
+        boolean isParseWithJMOL = structureParser.equalsIgnoreCase(
                         StructureImportSettings.StructureParser.JMOL_PARSER
                                 .toString());
+        StructureImportSettings.addSettings(annotFromStructure,
+                localSecondaryStruct, serviceSecondaryStruct);
         if (isParseWithJMOL)
         {
-          StructureImportSettings.addSettings(annotFromStructure,
-                  localSecondaryStruct, serviceSecondaryStruct);
-          alignFile = new jalview.ext.jmol.JmolParser(inFile, type);
+          alignFile = new JmolParser(inFile, sourceType);
         }
         else
         {
-          StructureImportSettings.addSettings(annotFromStructure,
-                  localSecondaryStruct, serviceSecondaryStruct);
+          // todo is MCview parsing obsolete yet?
           StructureImportSettings.setShowSeqFeatures(true);
           alignFile = new MCview.PDBfile(annotFromStructure,
                   localSecondaryStruct, serviceSecondaryStruct, inFile,
-                  type);
+                  sourceType);
         }
-        ((StructureFile) alignFile).setDbRefType(format);
-      }
-      else if (format.equalsIgnoreCase("mmCIF"))
-      {
-        StructureImportSettings.addSettings(annotFromStructure,
-                localSecondaryStruct, serviceSecondaryStruct);
-        alignFile = new jalview.ext.jmol.JmolParser(inFile, type);
-        ((StructureFile) alignFile).setDbRefType(format);
-      }
-      else if (format.equals("STH"))
-      {
-        alignFile = new StockholmFile(inFile, type);
-      }
-      else if (format.equals("SimpleBLAST"))
-      {
-        alignFile = new SimpleBlastFile(inFile, type);
-      }
-      else if (format.equals(PhylipFile.FILE_DESC))
-      {
-        alignFile = new PhylipFile(inFile, type);
-      }
-      else if (format.equals(JSONFile.FILE_DESC))
-      {
-        alignFile = new JSONFile(inFile, type);
-      }
-      else if (format.equals(HtmlFile.FILE_DESC))
-      {
-        alignFile = new HtmlFile(inFile, type);
+        ((StructureFile) alignFile).setDbRefType(FileFormat.PDB
+                .equals(fileFormat) ? Type.PDB : Type.MMCIF);
       }
-      else if (format.equals("RNAML"))
-      {
-        alignFile = new RnamlFile(inFile, type);
-      }
-      else if (format.equals(IdentifyFile.FeaturesFile))
+      else
       {
-        alignFile = new FeaturesFile(true, inFile, type);
+        alignFile = fileFormat.getAlignmentFile(inFile, sourceType);
       }
-      return buildAlignmentFrom(alignFile);
+      return buildAlignmentFromFile();
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println("Failed to read alignment using the '" + format
-              + "' reader.\n" + e);
+      System.err.println("Failed to read alignment using the '"
+              + fileFormat + "' reader.\n" + e);
 
       if (e.getMessage() != null
               && e.getMessage().startsWith(INVALID_CHARACTERS))
       {
-        throw new java.io.IOException(e.getMessage());
+        throw new IOException(e.getMessage());
       }
 
       // Finally test if the user has pasted just the sequence, no id
-      if (type.equalsIgnoreCase("Paste"))
+      if (sourceType == DataSourceType.PASTE)
       {
         try
         {
           // Possible sequence is just residues with no label
-          alignFile = new FastaFile(">UNKNOWN\n" + inFile, "Paste");
-          return buildAlignmentFrom(alignFile);
+          alignFile = new FastaFile(">UNKNOWN\n" + inFile,
+                  DataSourceType.PASTE);
+          return buildAlignmentFromFile();
 
         } catch (Exception ex)
         {
           if (ex.toString().startsWith(INVALID_CHARACTERS))
           {
-            throw new java.io.IOException(e.getMessage());
+            throw new IOException(e.getMessage());
           }
 
           ex.printStackTrace();
         }
       }
-      if (format.equalsIgnoreCase("HTML"))
+      if (FileFormat.Html.equals(fileFormat))
       {
         throw new IOException(e.getMessage());
       }
-      // If we get to this stage, the format was not supported
-      throw new java.io.IOException(SUPPORTED_FORMATS);
     }
+    throw new FileFormatException(SUPPORTED_FORMATS);
   }
 
   /**
@@ -387,53 +219,16 @@ public class AppletFormatAdapter
    * @param format
    *          File format of data that will be provided by datasource
    *
-   * @return DOCUMENT ME!
+   * @return
    */
-  public AlignmentI readFromFile(FileParse source, String format)
-          throws java.io.IOException
+  public AlignmentI readFromFile(FileParse source, FileFormatI format)
+          throws IOException
   {
-    // TODO: generalise mapping between format string and io. class instances
-    // using Constructor.invoke reflection
-    // This is exactly the same as the readFile method except we substitute
-    // 'inFile, type' with 'source'
     this.inFile = source.getInFile();
-    String type = source.type;
+    DataSourceType type = source.dataSourceType;
     try
     {
-      if (format.equals("FASTA"))
-      {
-        alignFile = new FastaFile(source);
-      }
-      else if (format.equals("MSF"))
-      {
-        alignFile = new MSFfile(source);
-      }
-      else if (format.equals("PileUp"))
-      {
-        alignFile = new PileUpfile(source);
-      }
-      else if (format.equals("CLUSTAL"))
-      {
-        alignFile = new ClustalFile(source);
-      }
-      else if (format.equals("BLC"))
-      {
-        alignFile = new BLCFile(source);
-      }
-      else if (format.equals("PIR"))
-      {
-        alignFile = new PIRFile(source);
-      }
-      else if (format.equals("PFAM"))
-      {
-        alignFile = new PfamFile(source);
-      }
-      else if (format.equals("JnetFile"))
-      {
-        alignFile = new JPredFile(source);
-        ((JPredFile) alignFile).removeNonSequences();
-      }
-      else if (format.equals("PDB"))
+      if (FileFormat.PDB.equals(format) || FileFormat.MMCif.equals(format))
       {
         // TODO obtain config value from preference settings
         boolean isParseWithJMOL = false;
@@ -451,43 +246,12 @@ public class AppletFormatAdapter
         }
         ((StructureFile) alignFile).setDbRefType(Type.PDB);
       }
-      else if (format.equalsIgnoreCase("mmCIF"))
-      {
-        StructureImportSettings.addSettings(annotFromStructure,
-                localSecondaryStruct, serviceSecondaryStruct);
-        alignFile = new JmolParser(source);
-        ((StructureFile) alignFile).setDbRefType(Type.MMCIF);
-      }
-      else if (format.equals("STH"))
-      {
-        alignFile = new StockholmFile(source);
-      }
-      else if (format.equals("RNAML"))
-      {
-        alignFile = new RnamlFile(source);
-      }
-      else if (format.equals("SimpleBLAST"))
-      {
-        alignFile = new SimpleBlastFile(source);
-      }
-      else if (format.equals(PhylipFile.FILE_DESC))
-      {
-        alignFile = new PhylipFile(source);
-      }
-      else if (format.equals(IdentifyFile.FeaturesFile))
-      {
-        alignFile = new FeaturesFile(inFile, type);
-      }
-      else if (format.equals(JSONFile.FILE_DESC))
-      {
-        alignFile = new JSONFile(source);
-      }
-      else if (format.equals(HtmlFile.FILE_DESC))
+      else
       {
-        alignFile = new HtmlFile(source);
+        alignFile = format.getAlignmentFile(source);
       }
 
-      return buildAlignmentFrom(alignFile);
+      return buildAlignmentFromFile();
 
     } catch (Exception e)
     {
@@ -498,23 +262,24 @@ public class AppletFormatAdapter
       if (e.getMessage() != null
               && e.getMessage().startsWith(INVALID_CHARACTERS))
       {
-        throw new java.io.IOException(e.getMessage());
+        throw new FileFormatException(e.getMessage());
       }
 
       // Finally test if the user has pasted just the sequence, no id
-      if (type.equalsIgnoreCase("Paste"))
+      if (type == DataSourceType.PASTE)
       {
         try
         {
           // Possible sequence is just residues with no label
-          alignFile = new FastaFile(">UNKNOWN\n" + inFile, "Paste");
-          return buildAlignmentFrom(alignFile);
+          alignFile = new FastaFile(">UNKNOWN\n" + inFile,
+                  DataSourceType.PASTE);
+          return buildAlignmentFromFile();
 
         } catch (Exception ex)
         {
           if (ex.toString().startsWith(INVALID_CHARACTERS))
           {
-            throw new java.io.IOException(e.getMessage());
+            throw new IOException(e.getMessage());
           }
 
           ex.printStackTrace();
@@ -522,7 +287,7 @@ public class AppletFormatAdapter
       }
 
       // If we get to this stage, the format was not supported
-      throw new java.io.IOException(SUPPORTED_FORMATS);
+      throw new FileFormatException(SUPPORTED_FORMATS);
     }
   }
 
@@ -530,10 +295,9 @@ public class AppletFormatAdapter
    * boilerplate method to handle data from an AlignFile and construct a new
    * alignment or import to an existing alignment
    * 
-   * @param alignFile2
    * @return AlignmentI instance ready to pass to a UI constructor
    */
-  private AlignmentI buildAlignmentFrom(AlignFile alignFile2)
+  private AlignmentI buildAlignmentFromFile()
   {
     // Standard boilerplate for creating alignment from parser
     // alignFile.configureForView(viewpanel);
@@ -556,7 +320,7 @@ public class AppletFormatAdapter
    * @param selectedOnly
    * @return flatfile in a string
    */
-  public String formatSequences(String format, boolean jvsuffix,
+  public String formatSequences(FileFormatI format, boolean jvsuffix,
           AlignmentViewPanel ap, boolean selectedOnly)
   {
 
@@ -592,86 +356,31 @@ public class AppletFormatAdapter
    *
    * @return alignment flat file contents
    */
-  public String formatSequences(String format, AlignmentI alignment,
+  public String formatSequences(FileFormatI format, AlignmentI alignment,
           boolean jvsuffix)
   {
     try
     {
-      AlignFile afile = null;
-      if (format.equalsIgnoreCase("FASTA"))
-      {
-        afile = new FastaFile();
-      }
-      else if (format.equalsIgnoreCase("MSF"))
-      {
-        afile = new MSFfile();
-      }
-      else if (format.equalsIgnoreCase("PileUp"))
-      {
-        afile = new PileUpfile();
-      }
-      else if (format.equalsIgnoreCase("CLUSTAL"))
-      {
-        afile = new ClustalFile();
-      }
-      else if (format.equalsIgnoreCase("BLC"))
-      {
-        afile = new BLCFile();
-      }
-      else if (format.equalsIgnoreCase("PIR"))
-      {
-        afile = new PIRFile();
-      }
-      else if (format.equalsIgnoreCase("PFAM"))
-      {
-        afile = new PfamFile();
-      }
-      else if (format.equalsIgnoreCase("STH"))
-      {
-        afile = new StockholmFile(alignment);
-      }
-      else if (format.equalsIgnoreCase("AMSA"))
-      {
-        afile = new AMSAFile(alignment);
-      }
-      else if (format.equalsIgnoreCase(PhylipFile.FILE_DESC))
-      {
-        afile = new PhylipFile();
-      }
-      else if (format.equalsIgnoreCase(JSONFile.FILE_DESC))
-      {
-        afile = new JSONFile();
-      }
-      else if (format.equalsIgnoreCase("RNAML"))
-      {
-        afile = new RnamlFile();
-      }
-
-      else
-      {
-        throw new Exception(
-                MessageManager
-                        .getString("error.implementation_error_unknown_file_format_string"));
-      }
+      AlignmentFileI afile = format.getAlignmentFile(alignment);
 
       afile.setNewlineString(newline);
-      afile.addJVSuffix(jvsuffix);
       afile.setExportSettings(exportSettings);
       afile.configureForView(viewpanel);
 
       // check whether we were given a specific alignment to export, rather than
       // the one in the viewpanel
+      SequenceI[] seqs = null;
       if (viewpanel == null || viewpanel.getAlignment() == null
               || viewpanel.getAlignment() != alignment)
       {
-        afile.setSeqs(alignment.getSequencesArray());
+        seqs = alignment.getSequencesArray();
       }
       else
       {
-        afile.setSeqs(viewpanel.getAlignment().getSequencesArray());
+        seqs = viewpanel.getAlignment().getSequencesArray();
       }
 
-      String afileresp = afile.print();
+      String afileresp = afile.print(seqs, jvsuffix);
       if (afile.hasWarningMessage())
       {
         System.err.println("Warning raised when writing as " + format
@@ -688,14 +397,14 @@ public class AppletFormatAdapter
     return null;
   }
 
-  public static String checkProtocol(String file)
+  public static DataSourceType checkProtocol(String file)
   {
-    String protocol = FILE;
+    DataSourceType protocol = DataSourceType.FILE;
     String ft = file.toLowerCase().trim();
     if (ft.indexOf("http:") == 0 || ft.indexOf("https:") == 0
             || ft.indexOf("file:") == 0)
     {
-      protocol = URL;
+      protocol = DataSourceType.URL;
     }
     return protocol;
   }
@@ -716,8 +425,10 @@ public class AppletFormatAdapter
           System.gc();
           long memf = -r.totalMemory() + r.freeMemory();
           long t1 = -System.currentTimeMillis();
-          AlignmentI al = afa.readFile(args[i], FILE,
-                  new IdentifyFile().identify(args[i], FILE));
+          AlignmentI al = afa
+                  .readFile(args[i], DataSourceType.FILE,
+                          new IdentifyFile().identify(args[i],
+                                  DataSourceType.FILE));
           t1 += System.currentTimeMillis();
           System.gc();
           memf += r.totalMemory() - r.freeMemory();
@@ -728,7 +439,7 @@ public class AppletFormatAdapter
             try
             {
               System.out.println(new AppletFormatAdapter().formatSequences(
-                      "FASTA", al, true));
+                      FileFormat.Fasta, al, true));
             } catch (Exception e)
             {
               System.err
@@ -767,16 +478,17 @@ public class AppletFormatAdapter
    * @param format
    * @return protocol that yields the data parsable as the given type
    */
-  public static String resolveProtocol(String file, String format)
+  public static DataSourceType resolveProtocol(String file,
+          FileFormatI format)
   {
     return resolveProtocol(file, format, false);
   }
 
-  public static String resolveProtocol(String file, String format,
-          boolean debug)
+  public static DataSourceType resolveProtocol(String file,
+          FileFormatI format, boolean debug)
   {
     // TODO: test thoroughly!
-    String protocol = null;
+    DataSourceType protocol = null;
     if (debug)
     {
       System.out.println("resolving datasource started with:\n>>file\n"
@@ -800,10 +512,9 @@ public class AppletFormatAdapter
         System.err.println("Resource '" + file + "' was "
                 + (rtn ? "" : "not") + " located by classloader.");
       }
-      ;
       if (rtn)
       {
-        protocol = AppletFormatAdapter.CLASSLOADER;
+        protocol = DataSourceType.CLASSLOADER;
       }
 
     } catch (Exception ex)
@@ -814,12 +525,12 @@ public class AppletFormatAdapter
 
     if (file.indexOf("://") > -1)
     {
-      protocol = AppletFormatAdapter.URL;
+      protocol = DataSourceType.URL;
     }
     else
     {
       // skipping codebase prepend check.
-      protocol = AppletFormatAdapter.FILE;
+      protocol = DataSourceType.FILE;
     }
     FileParse fp = null;
     try
@@ -855,7 +566,7 @@ public class AppletFormatAdapter
       {
         System.out.println("Accessing as paste.");
       }
-      protocol = AppletFormatAdapter.PASTE;
+      protocol = DataSourceType.PASTE;
       fp = null;
       try
       {
@@ -875,7 +586,7 @@ public class AppletFormatAdapter
     {
       return null;
     }
-    if (format == null || format.length() == 0)
+    if (format == null)
     {
       return protocol;
     }
@@ -883,8 +594,7 @@ public class AppletFormatAdapter
     {
       try
       {
-        String idformat = new jalview.io.IdentifyFile().identify(file,
-                protocol);
+        FileFormatI idformat = new IdentifyFile().identify(file, protocol);
         if (idformat == null)
         {
           if (debug)
@@ -923,20 +633,13 @@ public class AppletFormatAdapter
           System.err.println("File deemed not accessible via " + protocol);
           e.printStackTrace();
         }
-        ;
-
       }
     }
     return null;
   }
 
-  public AlignFile getAlignFile()
+  public AlignmentFileI getAlignFile()
   {
     return alignFile;
   }
-
-  public void setAlignFile(AlignFile alignFile)
-  {
-    this.alignFile = alignFile;
-  }
 }
index a499f75..6317e83 100755 (executable)
@@ -48,15 +48,16 @@ public class BLCFile extends AlignFile
    * 
    * @param inFile
    *          DOCUMENT ME!
-   * @param type
+   * @param sourceType
    *          DOCUMENT ME!
    * 
    * @throws IOException
    *           DOCUMENT ME!
    */
-  public BLCFile(String inFile, String type) throws IOException
+  public BLCFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public BLCFile(FileParse source) throws IOException
@@ -67,6 +68,7 @@ public class BLCFile extends AlignFile
   /**
    * DOCUMENT ME!
    */
+  @Override
   public void initData()
   {
     super.initData();
@@ -89,6 +91,7 @@ public class BLCFile extends AlignFile
   /**
    * DOCUMENT ME!
    */
+  @Override
   public void parse() throws IOException
   {
     StringBuffer headerLines = new StringBuffer();
@@ -215,22 +218,13 @@ public class BLCFile extends AlignFile
   /**
    * DOCUMENT ME!
    * 
-   * @return DOCUMENT ME!
-   */
-  public String print()
-  {
-    return print(getSeqsAsArray());
-  }
-
-  /**
-   * DOCUMENT ME!
-   * 
    * @param s
    *          DOCUMENT ME!
    * 
    * @return DOCUMENT ME!
    */
-  public String print(SequenceI[] s)
+  @Override
+  public String print(SequenceI[] s, boolean jvsuffix)
   {
     StringBuffer out = new StringBuffer();
     /**
@@ -244,7 +238,7 @@ public class BLCFile extends AlignFile
 
     while ((i < s.length) && (s[i] != null))
     {
-      out.append(">" + printId(s[i]));
+      out.append(">" + printId(s[i], jvsuffix));
       if (s[i].getDescription() != null)
       {
         out.append(" " + s[i].getDescription());
index f8fa1f5..fd9c584 100644 (file)
  */
 package jalview.io;
 
-import jalview.api.AlignExportSettingI;
-import jalview.api.AlignmentViewPanel;
-import jalview.datamodel.AlignmentExportData;
 import jalview.exceptions.NoFileSelectedException;
-import jalview.gui.IProgressIndicator;
+import jalview.gui.AlignmentPanel;
 import jalview.gui.OOMWarning;
 import jalview.json.binding.biojs.BioJSReleasePojo;
 import jalview.json.binding.biojs.BioJSRepositoryPojo;
@@ -42,15 +39,8 @@ import java.net.URL;
 import java.util.Objects;
 import java.util.TreeMap;
 
-public class BioJsHTMLOutput
+public class BioJsHTMLOutput extends HTMLOutput
 {
-  private AlignmentViewPanel ap;
-
-  private long pSessionId;
-
-  private IProgressIndicator pIndicator;
-
-  private boolean headless;
 
   private static File currentBJSTemplateFile;
 
@@ -67,183 +57,41 @@ public class BioJsHTMLOutput
                   "biojs_template_git_repo",
                   "https://raw.githubusercontent.com/jalview/exporter-templates/master/biojs/package.json");
 
-  public BioJsHTMLOutput(AlignmentViewPanel ap,
-          IProgressIndicator pIndicator)
+  public BioJsHTMLOutput(AlignmentPanel ap)
   {
-    if (ap != null)
-    {
-      this.ap = ap;
-      this.pSessionId = System.currentTimeMillis();
-      this.pIndicator = pIndicator;
-      this.headless = (System.getProperty("java.awt.headless") != null && System
-              .getProperty("java.awt.headless").equals("true"));
-    }
+    super(ap);
   }
 
-  public void exportJalviewAlignmentAsBioJsHtmlFile()
+  @Override
+  public void exportHTML(String outputFile)
   {
-    String outputFile = null;
+    exportStarted();
     try
     {
-      outputFile = getOutputFile();
-      AlignExportSettingI exportSettings = new AlignExportSettingI()
+      if (outputFile == null)
       {
-        @Override
-        public boolean isExportHiddenSequences()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isExportHiddenColumns()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isExportAnnotations()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isExportFeatures()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isExportGroups()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isCancelled()
-        {
-          return false;
-        }
-
-      };
-      AlignmentExportData exportData = jalview.gui.AlignFrame
-              .getAlignmentForExport(JSONFile.FILE_DESC,
-                      ap.getAlignViewport(), exportSettings);
-      String bioJSON = new FormatAdapter(ap, exportData.getSettings())
-              .formatSequences(JSONFile.FILE_DESC, exportData
-                      .getAlignment(), exportData.getOmitHidden(),
-                      exportData.getStartEndPostions(), ap
-                              .getAlignViewport().getColumnSelection());
-
-      String bioJSTemplateString = getBioJsTemplateAsString();
-      String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
-              .replaceAll("#sequenceData#", bioJSON).toString();
-
-      PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
-              outputFile));
-      out.print(generatedBioJsWithJalviewAlignmentAsJson);
-      out.flush();
-      out.close();
-      jalview.util.BrowserLauncher.openURL("file:///" + outputFile);
-      if (pIndicator != null && !headless)
-      {
-        pIndicator.setProgressBar(MessageManager.formatMessage(
-                "status.export_complete", "BioJS"), pSessionId);
+        outputFile = getOutputFile();
       }
-    } catch (NoFileSelectedException ex)
+      generatedFile = new File(outputFile);
+    } catch (NoFileSelectedException e)
     {
-      // do noting if no file was selected
-    } catch (OutOfMemoryError err)
-    {
-      System.out.println("########################\n" + "OUT OF MEMORY "
-              + outputFile + "\n" + "########################");
-      new OOMWarning("Creating Image for " + outputFile, err);
+      setProgressMessage(MessageManager.formatMessage(
+              "status.cancelled_image_export_operation", "BioJS MSA"));
+      return;
     } catch (Exception e)
     {
-      pIndicator.setProgressBar(MessageManager.formatMessage(
-              "info.error_creating_file", "HTML"), pSessionId);
+      setProgressMessage(MessageManager.formatMessage(
+              "info.error_creating_file", "BioJS MSA"));
       e.printStackTrace();
+      return;
     }
-  }
-
-  public String getOutputFile() throws NoFileSelectedException
-  {
-    String selectedFile = null;
-    if (pIndicator != null && !headless)
-    {
-      pIndicator.setProgressBar(MessageManager.formatMessage(
-              "status.waiting_for_user_to_select_output_file", "HTML"),
-              pSessionId);
-    }
-
-    JalviewFileChooser jvFileChooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "html" }, new String[] { "HTML files" },
-            "HTML files");
-    jvFileChooser.setFileView(new JalviewFileView());
+    new Thread(this).start();
 
-    jvFileChooser.setDialogTitle(MessageManager
-            .getString("label.save_as_biojs_html"));
-    jvFileChooser.setToolTipText(MessageManager.getString("action.save"));
-
-    int fileChooserOpt = jvFileChooser.showSaveDialog(null);
-    if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
-    {
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
-              .getSelectedFile().getParent());
-      selectedFile = jvFileChooser.getSelectedFile().getPath();
-    }
-    else
-    {
-      pIndicator.setProgressBar(MessageManager.formatMessage(
-              "status.cancelled_image_export_operation", "BioJS"),
-              pSessionId);
-      throw new NoFileSelectedException("No file was selected.");
-    }
-    return selectedFile;
   }
 
-  public static String getBioJsTemplateAsString() throws IOException
-  {
-    InputStreamReader isReader = null;
-    BufferedReader buffReader = null;
-    StringBuilder sb = new StringBuilder();
-    Objects.requireNonNull(getCurrentBJSTemplateFile(),
-            "BioJsTemplate File not initialized!");
-    @SuppressWarnings("deprecation")
-    URL url = getCurrentBJSTemplateFile().toURL();
-    if (url != null)
-    {
-      try
-      {
-        isReader = new InputStreamReader(url.openStream());
-        buffReader = new BufferedReader(isReader);
-        String line;
-        String lineSeparator = System.getProperty("line.separator");
-        while ((line = buffReader.readLine()) != null)
-        {
-          sb.append(line).append(lineSeparator);
-        }
 
-      } catch (Exception ex)
-      {
-        ex.printStackTrace();
-      } finally
-      {
-        if (isReader != null)
-        {
-          isReader.close();
-        }
 
-        if (buffReader != null)
-        {
-          buffReader.close();
-        }
-      }
-    }
-    return sb.toString();
-  }
-
-  public static void refreshBioJSVersionsInfo(String dirName)
+  public static void refreshVersionInfo(String dirName)
           throws URISyntaxException
   {
     File directory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
@@ -291,7 +139,7 @@ public class BioJsHTMLOutput
             BioJSRepositoryPojo release = new BioJSRepositoryPojo(
                     gitRepoPkgJson);
             syncUpdates(BJS_TEMPLATES_LOCAL_DIRECTORY, release);
-            refreshBioJSVersionsInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
+            refreshVersionInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
           }
         } catch (URISyntaxException e)
         {
@@ -412,4 +260,56 @@ public class BioJsHTMLOutput
     BioJsHTMLOutput.bioJsMSAVersions = bioJsMSAVersions;
   }
 
+  @Override
+  public boolean isEmbedData()
+  {
+    return true;
+  }
+
+  @Override
+  public boolean isLaunchInBrowserAfterExport()
+  {
+    return true;
+  }
+
+  @Override
+  public File getExportedFile()
+  {
+    return generatedFile;
+  }
+
+  @Override
+  public void run()
+  {
+    try
+    {
+      String bioJSON = getBioJSONData();
+      String bioJSTemplateString = HTMLOutput
+              .readFileAsString(getCurrentBJSTemplateFile());
+      String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
+              .replaceAll("#sequenceData#", bioJSON).toString();
+
+      PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
+              generatedFile));
+      out.print(generatedBioJsWithJalviewAlignmentAsJson);
+      out.flush();
+      out.close();
+      setProgressMessage(MessageManager.formatMessage(
+              "status.export_complete", "BioJS"));
+      exportCompleted();
+
+    } catch (OutOfMemoryError err)
+    {
+      System.out.println("########################\n" + "OUT OF MEMORY "
+              + generatedFile + "\n" + "########################");
+      new OOMWarning("Creating Image for " + generatedFile, err);
+    } catch (Exception e)
+    {
+      setProgressMessage(MessageManager.formatMessage(
+              "info.error_creating_file", "HTML"));
+      e.printStackTrace();
+    }
+
+  }
+
 }
index f7a45de..5d58d42 100755 (executable)
@@ -37,9 +37,10 @@ public class ClustalFile extends AlignFile
   {
   }
 
-  public ClustalFile(String inFile, String type) throws IOException
+  public ClustalFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public ClustalFile(FileParse source) throws IOException
@@ -196,13 +197,7 @@ public class ClustalFile extends AlignFile
   }
 
   @Override
-  public String print()
-  {
-    return print(getSeqsAsArray());
-    // TODO: locaRNA style aln output
-  }
-
-  public String print(SequenceI[] s)
+  public String print(SequenceI[] s, boolean jvsuffix)
   {
     StringBuffer out = new StringBuffer("CLUSTAL" + newline + newline);
 
@@ -213,7 +208,7 @@ public class ClustalFile extends AlignFile
 
     while ((i < s.length) && (s[i] != null))
     {
-      String tmp = printId(s[i]);
+      String tmp = printId(s[i], jvsuffix);
 
       if (s[i].getSequence().length > max)
       {
@@ -244,7 +239,8 @@ public class ClustalFile extends AlignFile
 
       while ((j < s.length) && (s[j] != null))
       {
-        out.append(new Format("%-" + maxid + "s").form(printId(s[j]) + " "));
+        out.append(new Format("%-" + maxid + "s").form(printId(s[j],
+                jvsuffix) + " "));
 
         int start = i * len;
         int end = start + len;
index 769f8b9..11cb4bf 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.io;
 
+import jalview.datamodel.SequenceI;
+
 import java.io.IOException;
 
 /**
@@ -32,13 +34,15 @@ import java.io.IOException;
 public class DBRefFile extends AlignFile
 {
 
+  @Override
   public void parse() throws IOException
   {
     // TODO Auto-generated method stub
 
   }
 
-  public String print()
+  @Override
+  public String print(SequenceI[] sqs, boolean jvsuffix)
   {
     // TODO Auto-generated method stub
     return null;
diff --git a/src/jalview/io/DataSourceType.java b/src/jalview/io/DataSourceType.java
new file mode 100644 (file)
index 0000000..e2808e8
--- /dev/null
@@ -0,0 +1,6 @@
+package jalview.io;
+
+public enum DataSourceType
+{
+  FILE, URL, PASTE, CLASSLOADER;
+}
index ec1c82e..da925e4 100755 (executable)
@@ -55,15 +55,16 @@ public class FastaFile extends AlignFile
    * 
    * @param inFile
    *          DOCUMENT ME!
-   * @param type
+   * @param sourceType
    *          DOCUMENT ME!
    * 
    * @throws IOException
    *           DOCUMENT ME!
    */
-  public FastaFile(String inFile, String type) throws IOException
+  public FastaFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public FastaFile(FileParse source) throws IOException
@@ -71,6 +72,11 @@ public class FastaFile extends AlignFile
     super(source);
   }
 
+  public FastaFile(SequenceI[] seqs)
+  {
+    super(seqs);
+  }
+
   /**
    * DOCUMENT ME!
    * 
@@ -180,28 +186,15 @@ public class FastaFile extends AlignFile
     }
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param s
-   *          DOCUMENT ME!
-   * @param len
-   *          DOCUMENT ME!
-   * @param gaps
-   *          DOCUMENT ME!
-   * @param displayId
-   *          DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
-   */
-  public String print(SequenceI[] s)
+  @Override
+  public String print(SequenceI[] s, boolean jvsuffix)
   {
     out = new StringBuffer();
     int i = 0;
 
     while ((i < s.length) && (s[i] != null))
     {
-      out.append(">" + printId(s[i]));
+      out.append(">" + printId(s[i], jvsuffix));
       if (s[i].getDescription() != null)
       {
         out.append(" " + s[i].getDescription());
@@ -233,15 +226,4 @@ public class FastaFile extends AlignFile
 
     return out.toString();
   }
-
-  /**
-   * DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
-   */
-  @Override
-  public String print()
-  {
-    return print(getSeqsAsArray());
-  }
 }
index 73783e5..6af0cdf 100755 (executable)
@@ -94,12 +94,13 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * Constructor which does not parse the file immediately
    * 
    * @param inFile
-   * @param type
+   * @param paste
    * @throws IOException
    */
-  public FeaturesFile(String inFile, String type) throws IOException
+  public FeaturesFile(String inFile, DataSourceType paste)
+          throws IOException
   {
-    super(false, inFile, type);
+    super(false, inFile, paste);
   }
 
   /**
@@ -119,7 +120,8 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * @param type
    * @throws IOException
    */
-  public FeaturesFile(boolean parseImmediately, String inFile, String type)
+  public FeaturesFile(boolean parseImmediately, String inFile,
+          DataSourceType type)
           throws IOException
   {
     super(parseImmediately, inFile, type);
@@ -710,7 +712,8 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
       dataset = new Alignment(new SequenceI[] {});
     }
 
-    boolean parseResult = parse(dataset, null, false, true);
+    Map<String, FeatureColourI> featureColours = new HashMap<String, FeatureColourI>();
+    boolean parseResult = parse(dataset, featureColours, false, true);
     if (!parseResult)
     {
       // pass error up somehow
@@ -731,9 +734,10 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * @return error message
    */
   @Override
-  public String print()
+  public String print(SequenceI[] sqs, boolean jvsuffix)
   {
-    return "Use printGffFormat() or printJalviewFormat()";
+    System.out.println("Use printGffFormat() or printJalviewFormat()");
+    return null;
   }
 
   /**
diff --git a/src/jalview/io/FileFormat.java b/src/jalview/io/FileFormat.java
new file mode 100644 (file)
index 0000000..5f441d2
--- /dev/null
@@ -0,0 +1,612 @@
+package jalview.io;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.PDBEntry;
+import jalview.ext.jmol.JmolParser;
+import jalview.structure.StructureImportSettings;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public enum FileFormat implements FileFormatI
+{
+  Fasta("Fasta", "fa, fasta, mfa, fastq", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new FastaFile(inFile, sourceType);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new FastaFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new FastaFile();
+    }
+  },
+  Pfam("PFAM", "pfam", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new PfamFile(inFile, sourceType);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new PfamFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new PfamFile();
+    }
+  },
+  Stockholm("Stockholm", "sto,stk", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new StockholmFile(inFile, sourceType);
+    }
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new StockholmFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new StockholmFile(al);
+    }
+
+  },
+
+  PIR("PIR", "pir", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new PIRFile(inFile, sourceType);
+    }
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new PIRFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new PIRFile();
+    }
+  },
+  BLC("BLC", "BLC", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new BLCFile(inFile, sourceType);
+    }    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new BLCFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new BLCFile();
+    }
+  },
+  AMSA("AMSA", "amsa", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new AMSAFile(inFile, sourceType);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new AMSAFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new AMSAFile(al);
+    }
+  },
+  Html("HTML", "html", true, false)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new HtmlFile(inFile, sourceType);
+    }    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new HtmlFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new HtmlFile();
+    }
+
+    @Override
+    public boolean isComplexAlignFile()
+    {
+      return true;
+    }
+
+  },
+  Rnaml("RNAML", "xml,rnaml", true, false)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new RnamlFile(inFile, sourceType);
+    }    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new RnamlFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new RnamlFile();
+    }
+
+  },
+  Json("JSON","json", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new JSONFile(inFile, sourceType);
+    }    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new JSONFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new JSONFile();
+    }
+
+    @Override
+    public boolean isComplexAlignFile()
+    {
+      return true;
+    }
+
+  },
+  Pileup("PileUp", "pileup", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new PileUpfile(inFile, sourceType);
+    }    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new PileUpfile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new PileUpfile();
+    }
+
+  },
+  MSF("MSF", "msf", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new MSFfile(inFile, sourceType);
+    }    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new MSFfile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new MSFfile();
+    }
+
+  },
+  Clustal("Clustal", "aln", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new ClustalFile(inFile, sourceType);
+    }    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new ClustalFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new ClustalFile();
+    }
+  },
+  Phylip("PHYLIP", "phy", true, true)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new PhylipFile(inFile, sourceType);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new PhylipFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new PhylipFile();
+    }
+  },
+  Jnet("JnetFile", "", false, false)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      JPredFile af = new JPredFile(inFile, sourceType);
+      af.removeNonSequences();
+      return af;
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      JPredFile af = new JPredFile(source);
+      af.removeNonSequences();
+      return af;
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return null; // todo is this called?
+    }
+
+  },
+  Features("GFF or Jalview features", "gff2,gff3", true, false)
+  {
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new FeaturesFile(true, inFile, sourceType);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new FeaturesFile(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new FeaturesFile();
+    }
+  },
+  PDB("PDB", "pdb,ent", true, false)
+  {
+
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      // TODO obtain config value from preference settings.
+      // Set value to 'true' to test PDB processing with Jmol: JAL-1213
+      boolean isParseWithJMOL = StructureImportSettings
+              .getDefaultStructureFileFormat() != PDBEntry.Type.PDB;
+      if (isParseWithJMOL)
+      {
+        return new JmolParser(inFile, sourceType);
+      }
+      else
+      {
+        StructureImportSettings.setShowSeqFeatures(true);
+        return new MCview.PDBfile(
+                StructureImportSettings.isVisibleChainAnnotation(),
+                StructureImportSettings.isProcessSecondaryStructure(),
+                StructureImportSettings.isExternalSecondaryStructure(),
+                inFile,
+                sourceType);
+      }
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      boolean isParseWithJMOL = StructureImportSettings
+              .getDefaultStructureFileFormat() != PDBEntry.Type.PDB;
+      if (isParseWithJMOL)
+      {
+        return new JmolParser(source);
+      }
+      else
+      {
+        StructureImportSettings.setShowSeqFeatures(true);
+        return new MCview.PDBfile(
+                StructureImportSettings.isVisibleChainAnnotation(),
+                StructureImportSettings.isProcessSecondaryStructure(),
+                StructureImportSettings.isExternalSecondaryStructure(),
+                source);
+      }
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new JmolParser(); // todo or null?
+    }
+
+    @Override
+    public boolean isStructureFile()
+    {
+      return true;
+    }
+  },
+  MMCif("mmCIF", "cif", true, false)
+  {
+
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return new JmolParser(inFile, sourceType);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return new JmolParser(source);
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return new JmolParser(); // todo or null?
+    }
+
+    @Override
+    public boolean isStructureFile()
+    {
+      return true;
+    }
+  },
+  Jalview("Jalview", "jar,jvp", true, true)
+  {
+
+    @Override
+    public AlignmentFileI getAlignmentFile(String inFile,
+            DataSourceType sourceType) throws IOException
+    {
+      return null;
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(FileParse source)
+            throws IOException
+    {
+      return null;
+    }
+
+    @Override
+    public AlignmentFileI getAlignmentFile(AlignmentI al)
+    {
+      return null;
+    }
+
+    @Override
+    public boolean isTextFormat()
+    {
+      return false;
+    }
+  };
+
+  /**
+   * A lookup map of enums by upper-cased name
+   */
+  private static Map<String, FileFormat> names;
+  static
+  {
+    names = new HashMap<String, FileFormat>();
+    for (FileFormat format : FileFormat.values())
+    {
+      names.put(format.toString().toUpperCase(), format);
+    }
+  }
+
+  private boolean writable;
+
+  private boolean readable;
+
+  private String extensions;
+
+  private String name;
+
+  /**
+   * Answers a list of writeable file formats (as string, corresponding to the
+   * toString() and forName() methods)
+   * 
+   * @return
+   */
+  public static List<String> getWritableFormats(boolean textOnly)
+  {
+    List<String> l = new ArrayList<String>();
+    for (FileFormatI ff : values())
+    {
+      if (ff.isWritable() && (!textOnly || ff.isTextFormat()))
+      {
+        l.add(ff.toString());
+      }
+    }
+    return l;
+  }
+
+  /**
+   * Answers a list of readable file formats (as string, corresponding to the
+   * toString() and forName() methods)
+   * 
+   * @return
+   */
+  public static List<String> getReadableFormats()
+  {
+    List<String> l = new ArrayList<String>();
+    for (FileFormatI ff : values())
+    {
+      if (ff.isReadable())
+      {
+        l.add(ff.toString());
+      }
+    }
+    return l;
+  }
+
+  @Override
+  public boolean isComplexAlignFile()
+  {
+    return false;
+  }
+
+  /**
+   * Returns the file format with the given name, or null if format is null or
+   * invalid. Unlike valueOf(), this is not case-sensitive, to be kind to
+   * writers of javascript.
+   * 
+   * @param format
+   * @return
+   */
+  public static FileFormatI forName(String format)
+  {
+    // or could store format.getShortDescription().toUpperCase()
+    // in order to decouple 'given name' from enum name
+    return format == null ? null : names.get(format.toUpperCase());
+  }
+
+  @Override
+  public boolean isReadable()
+  {
+    return readable;
+  }
+
+  @Override
+  public boolean isWritable()
+  {
+    return writable;
+  }
+
+  /**
+   * Constructor
+   * 
+   * @param shortName
+   * @param extensions
+   *          comma-separated list of file extensions associated with the format
+   * @param isReadable
+   * @param isWritable
+   */
+  private FileFormat(String shortName, String extensions,
+          boolean isReadable, boolean isWritable)
+  {
+    this.name = shortName;
+    this.extensions = extensions;
+    this.readable = isReadable;
+    this.writable = isWritable;
+  }
+
+  @Override
+  public String getExtensions()
+  {
+    return extensions;
+  }
+
+  @Override
+  public String toString()
+  {
+    return name;
+  }
+
+  @Override
+  public AlignmentFileI getAlignmentFile()
+  {
+    return getAlignmentFile((AlignmentI) null);
+  }
+
+  @Override
+  public boolean isTextFormat()
+  {
+    return true;
+  }
+
+  @Override
+  public boolean isStructureFile()
+  {
+    return false;
+  }
+}
diff --git a/src/jalview/io/FileFormatException.java b/src/jalview/io/FileFormatException.java
new file mode 100644 (file)
index 0000000..c037cf2
--- /dev/null
@@ -0,0 +1,13 @@
+package jalview.io;
+
+import java.io.IOException;
+
+public class FileFormatException extends IOException
+{
+
+  public FileFormatException(String msg)
+  {
+    super(msg);
+  }
+
+}
diff --git a/src/jalview/io/FileFormatI.java b/src/jalview/io/FileFormatI.java
new file mode 100644 (file)
index 0000000..0593d1e
--- /dev/null
@@ -0,0 +1,63 @@
+package jalview.io;
+
+import jalview.datamodel.AlignmentI;
+
+import java.io.IOException;
+
+public interface FileFormatI
+{
+
+  AlignmentFileI getAlignmentFile(String inFile, DataSourceType sourceType)
+          throws IOException;
+
+  // TODO can we get rid of one of these methods?
+  AlignmentFileI getAlignmentFile(FileParse source) throws IOException;
+
+  AlignmentFileI getAlignmentFile(AlignmentI al);
+
+  AlignmentFileI getAlignmentFile();
+
+  boolean isComplexAlignFile();
+
+  /**
+   * Returns a comma-separated list of file extensions associated with the
+   * format
+   * 
+   * @return
+   */
+  String getExtensions();
+
+  /**
+   * Answers true if the format is one that Jalview can read. This implies that
+   * the format provides implementations for getAlignmentFile(FileParse) and
+   * getAlignmentFile(String, DataSourceType) which parse the data source for
+   * sequence data.
+   * 
+   * @return
+   */
+  boolean isReadable();
+
+  /**
+   * Answers true if the format is one that Jalview can write. This implies that
+   * the object returned by getAlignmentFile provides an implementation of the
+   * print() method.
+   * 
+   * @return
+   */
+  boolean isWritable();
+
+  /**
+   * Answers true if the format is one that Jalview can output as text, e.g. to
+   * a text box
+   * 
+   * @return
+   */
+  boolean isTextFormat();
+
+  /**
+   * Answers true if the file format is one that provides a 3D structure
+   * 
+   * @return
+   */
+  boolean isStructureFile();
+}
index b449d19..3ad74c7 100755 (executable)
@@ -24,6 +24,7 @@ import jalview.api.ComplexAlignFile;
 import jalview.api.FeatureSettingsModelI;
 import jalview.api.FeaturesDisplayedI;
 import jalview.api.FeaturesSourceI;
+import jalview.bin.Cache;
 import jalview.bin.Jalview;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
@@ -33,6 +34,7 @@ import jalview.gui.AlignFrame;
 import jalview.gui.AlignViewport;
 import jalview.gui.Desktop;
 import jalview.gui.Jalview2XML;
+import jalview.gui.JvOptionPane;
 import jalview.json.binding.biojson.v1.ColourSchemeMapper;
 import jalview.schemes.ColourSchemeI;
 import jalview.structure.StructureSelectionManager;
@@ -41,18 +43,17 @@ import jalview.util.MessageManager;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
-import javax.swing.JOptionPane;
 import javax.swing.SwingUtilities;
 
 public class FileLoader implements Runnable
 {
   String file;
 
-  String protocol;
+  DataSourceType protocol;
 
-  String format;
+  FileFormatI format;
 
-  FileParse source = null; // alternative specification of where data comes
+  AlignmentFileI source = null; // alternative specification of where data comes
 
   // from
 
@@ -86,13 +87,14 @@ public class FileLoader implements Runnable
   }
 
   public void LoadFile(AlignViewport viewport, String file,
-          String protocol, String format)
+          DataSourceType protocol, FileFormatI format)
   {
     this.viewport = viewport;
     LoadFile(file, protocol, format);
   }
 
-  public void LoadFile(String file, String protocol, String format)
+  public void LoadFile(String file, DataSourceType protocol,
+          FileFormatI format)
   {
     this.file = file;
     this.protocol = protocol;
@@ -116,7 +118,7 @@ public class FileLoader implements Runnable
    * @param file
    * @param protocol
    */
-  public void LoadFile(String file, String protocol)
+  public void LoadFile(String file, DataSourceType protocol)
   {
     LoadFile(file, protocol, null);
   }
@@ -125,27 +127,28 @@ public class FileLoader implements Runnable
    * Load alignment from (file, protocol) and wait till loaded
    * 
    * @param file
-   * @param protocol
+   * @param sourceType
    * @return alignFrame constructed from file contents
    */
-  public AlignFrame LoadFileWaitTillLoaded(String file, String protocol)
+  public AlignFrame LoadFileWaitTillLoaded(String file,
+          DataSourceType sourceType)
   {
-    return LoadFileWaitTillLoaded(file, protocol, null);
+    return LoadFileWaitTillLoaded(file, sourceType, null);
   }
 
   /**
    * Load alignment from (file, protocol) of type format and wait till loaded
    * 
    * @param file
-   * @param protocol
+   * @param sourceType
    * @param format
    * @return alignFrame constructed from file contents
    */
-  public AlignFrame LoadFileWaitTillLoaded(String file, String protocol,
-          String format)
+  public AlignFrame LoadFileWaitTillLoaded(String file,
+          DataSourceType sourceType, FileFormatI format)
   {
     this.file = file;
-    this.protocol = protocol;
+    this.protocol = sourceType;
     this.format = format;
     return _LoadFileWaitTillLoaded();
   }
@@ -157,12 +160,13 @@ public class FileLoader implements Runnable
    * @param format
    * @return alignFrame constructed from file contents
    */
-  public AlignFrame LoadFileWaitTillLoaded(FileParse source, String format)
+  public AlignFrame LoadFileWaitTillLoaded(AlignmentFileI source,
+          FileFormatI format)
   {
     this.source = source;
 
     file = source.getInFile();
-    protocol = source.type;
+    protocol = source.getDataSourceType();
     this.format = format;
     return _LoadFileWaitTillLoaded();
   }
@@ -194,13 +198,13 @@ public class FileLoader implements Runnable
   public void updateRecentlyOpened()
   {
     Vector recent = new Vector();
-    if (protocol.equals(FormatAdapter.PASTE))
+    if (protocol == DataSourceType.PASTE)
     {
       // do nothing if the file was pasted in as text... there is no filename to
       // refer to it as.
       return;
     }
-    String type = protocol.equals(FormatAdapter.FILE) ? "RECENT_FILE"
+    String type = protocol == DataSourceType.FILE ? "RECENT_FILE"
             : "RECENT_URL";
 
     String historyItems = jalview.bin.Cache.getProperty(type);
@@ -229,18 +233,18 @@ public class FileLoader implements Runnable
       newHistory.append(recent.elementAt(i));
     }
 
-    jalview.bin.Cache.setProperty(type, newHistory.toString());
+    Cache.setProperty(type, newHistory.toString());
 
-    if (protocol.equals(FormatAdapter.FILE))
+    if (protocol == DataSourceType.FILE)
     {
-      jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT", format);
+      Cache.setProperty("DEFAULT_FILE_FORMAT", format.toString());
     }
   }
 
   @Override
   public void run()
   {
-    String title = protocol.equals(AppletFormatAdapter.PASTE) ? "Copied From Clipboard"
+    String title = protocol == DataSourceType.PASTE ? "Copied From Clipboard"
             : file;
     Runtime rt = Runtime.getRuntime();
     try
@@ -254,10 +258,8 @@ public class FileLoader implements Runnable
         // just in case the caller didn't identify the file for us
         if (source != null)
         {
-          format = new IdentifyFile().identify(source, false); // identify
-          // stream and
-          // rewind rather
-          // than close
+          format = new IdentifyFile().identify(source, false);
+          // identify stream and rewind rather than close
         }
         else
         {
@@ -266,20 +268,20 @@ public class FileLoader implements Runnable
 
       }
 
-      if (format == null || format.equalsIgnoreCase("EMPTY DATA FILE"))
+      if (format == null)
       {
         Desktop.instance.stopLoading();
         System.err.println("The input file \"" + file
                 + "\" has null or unidentifiable data content!");
         if (!Jalview.isHeadlessMode())
         {
-          javax.swing.JOptionPane.showInternalMessageDialog(
+          JvOptionPane.showInternalMessageDialog(
                   Desktop.desktop,
                   MessageManager.getString("label.couldnt_read_data")
                           + " in " + file + "\n"
                           + AppletFormatAdapter.SUPPORTED_FORMATS,
                   MessageManager.getString("label.couldnt_read_data"),
-                  JOptionPane.WARNING_MESSAGE);
+                  JvOptionPane.WARNING_MESSAGE);
         }
         return;
       }
@@ -296,7 +298,7 @@ public class FileLoader implements Runnable
       loadtime = -System.currentTimeMillis();
       AlignmentI al = null;
 
-      if (format.equalsIgnoreCase("Jalview"))
+      if (FileFormat.Jalview.equals(format))
       {
         if (source != null)
         {
@@ -310,14 +312,12 @@ public class FileLoader implements Runnable
       else
       {
         String error = AppletFormatAdapter.SUPPORTED_FORMATS;
-        if (FormatAdapter.isValidFormat(format))
-        {
           try
           {
             if (source != null)
             {
               // read from the provided source
-              al = new FormatAdapter().readFromFile(source, format);
+            al = new FormatAdapter().readFromFile(source, format);
             }
             else
             {
@@ -332,15 +332,6 @@ public class FileLoader implements Runnable
           {
             error = ex.getMessage();
           }
-        }
-        else
-        {
-          if (format != null && format.length() > 7)
-          {
-            // ad hoc message in format.
-            error = format + "\n" + error;
-          }
-        }
 
         if ((al != null) && (al.getHeight() > 0) && al.hasValidSequence())
         {
@@ -410,7 +401,7 @@ public class FileLoader implements Runnable
               }
             }
             // add metadata and update ui
-            if (!protocol.equals(AppletFormatAdapter.PASTE))
+            if (!(protocol == DataSourceType.PASTE))
             {
               alignFrame.setFileName(file, format);
             }
@@ -464,10 +455,10 @@ public class FileLoader implements Runnable
               @Override
               public void run()
               {
-                JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                         errorMessage, MessageManager
                                 .getString("label.error_loading_file"),
-                        JOptionPane.WARNING_MESSAGE);
+                        JvOptionPane.WARNING_MESSAGE);
               }
             });
           }
@@ -491,12 +482,12 @@ public class FileLoader implements Runnable
           @Override
           public void run()
           {
-            javax.swing.JOptionPane.showInternalMessageDialog(
+            JvOptionPane.showInternalMessageDialog(
                     Desktop.desktop, MessageManager.formatMessage(
                             "label.problems_opening_file",
                             new String[] { file }), MessageManager
                             .getString("label.file_open_error"),
-                    javax.swing.JOptionPane.WARNING_MESSAGE);
+                    JvOptionPane.WARNING_MESSAGE);
           }
         });
       }
@@ -513,12 +504,12 @@ public class FileLoader implements Runnable
           @Override
           public void run()
           {
-            javax.swing.JOptionPane.showInternalMessageDialog(
+            JvOptionPane.showInternalMessageDialog(
                     Desktop.desktop, MessageManager.formatMessage(
                             "warn.out_of_memory_loading_file", new String[]
                             { file }), MessageManager
                             .getString("label.out_of_memory"),
-                    javax.swing.JOptionPane.WARNING_MESSAGE);
+                    JvOptionPane.WARNING_MESSAGE);
           }
         });
       }
index fddb565..dc0418f 100755 (executable)
@@ -95,7 +95,7 @@ public class FileParse
    */
   protected String suffix = null;
 
-  protected String type = null;
+  protected DataSourceType dataSourceType = null;
 
   protected BufferedReader dataIn = null;
 
@@ -139,7 +139,7 @@ public class FileParse
     suffix = from.suffix;
     errormessage = from.errormessage; // inherit potential error messages
     error = false; // reset any error condition.
-    type = from.type;
+    dataSourceType = from.dataSourceType;
     dataIn = from.dataIn;
     if (dataIn != null)
     {
@@ -279,9 +279,9 @@ public class FileParse
    * configurable values for the origin and the type of the source
    */
   public FileParse(BufferedReader source, String originString,
-          String typeString)
+          DataSourceType sourceType)
   {
-    type = typeString;
+    dataSourceType = sourceType;
     error = false;
     inFile = null;
     dataName = originString;
@@ -304,18 +304,18 @@ public class FileParse
    * 
    * @param fileStr
    *          - datasource locator/content
-   * @param type
+   * @param sourceType
    *          - protocol of source
    * @throws MalformedURLException
    * @throws IOException
    */
-  public FileParse(String fileStr, String type)
+  public FileParse(String fileStr, DataSourceType sourceType)
           throws MalformedURLException, IOException
   {
-    this.type = type;
+    this.dataSourceType = sourceType;
     error = false;
 
-    if (type.equals(AppletFormatAdapter.FILE))
+    if (sourceType == DataSourceType.FILE)
     {
       if (checkFileSource(fileStr))
       {
@@ -338,7 +338,7 @@ public class FileParse
         }
       }
     }
-    else if (type.equals(AppletFormatAdapter.URL))
+    else if (sourceType == DataSourceType.URL)
     {
       try
       {
@@ -375,13 +375,13 @@ public class FileParse
         error = true;
       }
     }
-    else if (type.equals(AppletFormatAdapter.PASTE))
+    else if (sourceType == DataSourceType.PASTE)
     {
       errormessage = "PASTE INACCESSIBLE!";
       dataIn = new BufferedReader(new StringReader(fileStr));
       dataName = "Paste";
     }
-    else if (type.equals(AppletFormatAdapter.CLASSLOADER))
+    else if (sourceType == DataSourceType.CLASSLOADER)
     {
       errormessage = "RESOURCE CANNOT BE LOCATED";
       java.io.InputStream is = getClass()
@@ -407,7 +407,7 @@ public class FileParse
     else
     {
       errormessage = "PROBABLE IMPLEMENTATION ERROR : Datasource Type given as '"
-              + (type != null ? type : "null") + "'";
+              + (sourceType != null ? sourceType : "null") + "'";
       error = true;
     }
     if (dataIn == null || error)
@@ -625,4 +625,9 @@ public class FileParse
   {
     return null;
   }
+
+  public DataSourceType getDataSourceType()
+  {
+    return dataSourceType;
+  }
 }
index 6d94616..1dbfdef 100755 (executable)
@@ -22,6 +22,7 @@ package jalview.io;
 
 import jalview.api.AlignExportSettingI;
 import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
@@ -29,6 +30,9 @@ import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
+
+import java.io.IOException;
 
 /**
  * Additional formatting methods used by the application in a number of places.
@@ -76,7 +80,7 @@ public class FormatAdapter extends AppletFormatAdapter
     }
   }
 
-  public String formatSequences(String format, SequenceI[] seqs,
+  public String formatSequences(FileFormatI format, SequenceI[] seqs,
           String[] omitHiddenColumns, int[] exportRange)
   {
 
@@ -112,14 +116,14 @@ public class FormatAdapter extends AppletFormatAdapter
           startIndex = startEnd[0];
           endIndex = startEnd[1];
           // get first non-gaped residue start position
-          while (jalview.util.Comparison.isGap(seqs[i]
+          while (Comparison.isGap(seqs[i]
                   .getCharAt(startIndex)) && startIndex < endIndex)
           {
             startIndex++;
           }
 
           // get last non-gaped residue end position
-          while (jalview.util.Comparison.isGap(seqs[i].getCharAt(endIndex))
+          while (Comparison.isGap(seqs[i].getCharAt(endIndex))
                   && endIndex > startIndex)
           {
             endIndex--;
@@ -144,112 +148,100 @@ public class FormatAdapter extends AppletFormatAdapter
    * 
    * 
    * @param format
-   *          Format string as givien in the AppletFormatAdaptor list (exact
-   *          match to name of class implementing file io for that format)
    * @param seqs
    *          vector of sequences to write
    * 
    * @return String containing sequences in desired format
    */
-  public String formatSequences(String format, SequenceI[] seqs)
+  public String formatSequences(FileFormatI format, SequenceI[] seqs)
   {
+    //
+    // try
+    // {
+    boolean withSuffix = getCacheSuffixDefault(format);
+    return format.getAlignmentFile().print(seqs, withSuffix);
+      // null;
+      //
+      // if (format.equalsIgnoreCase("FASTA"))
+      // {
+      // afile = new FastaFile();
+      // afile.addJVSuffix(jalview.bin.Cache.getDefault("FASTA_JVSUFFIX",
+      // true));
+      // }
+      // else if (format.equalsIgnoreCase("MSF"))
+      // {
+      // afile = new MSFfile();
+      // afile.addJVSuffix(jalview.bin.Cache
+      // .getDefault("MSF_JVSUFFIX", true));
+      // }
+      // else if (format.equalsIgnoreCase("PileUp"))
+      // {
+      // afile = new PileUpfile();
+      // afile.addJVSuffix(jalview.bin.Cache.getDefault("PILEUP_JVSUFFIX",
+      // true));
+      // }
+      // else if (format.equalsIgnoreCase("CLUSTAL"))
+      // {
+      // afile = new ClustalFile();
+      // afile.addJVSuffix(jalview.bin.Cache.getDefault("CLUSTAL_JVSUFFIX",
+      // true));
+      // }
+      // else if (format.equalsIgnoreCase("BLC"))
+      // {
+      // afile = new BLCFile();
+      // afile.addJVSuffix(jalview.bin.Cache
+      // .getDefault("BLC_JVSUFFIX", true));
+      // }
+      // else if (format.equalsIgnoreCase("PIR"))
+      // {
+      // afile = new PIRFile();
+      // afile.addJVSuffix(jalview.bin.Cache
+      // .getDefault("PIR_JVSUFFIX", true));
+      // }
+      // else if (format.equalsIgnoreCase("PFAM"))
+      // {
+      // afile = new PfamFile();
+      // afile.addJVSuffix(jalview.bin.Cache.getDefault("PFAM_JVSUFFIX",
+      // true));
+      // }
+      // /*
+      // * amsa is not supported by this function - it requires an alignment
+      // * rather than a sequence vector else if
+      // (format.equalsIgnoreCase("AMSA"))
+      // * { afile = new AMSAFile(); afile.addJVSuffix(
+      // * jalview.bin.Cache.getDefault("AMSA_JVSUFFIX", true)); }
+      // */
 
-    try
-    {
-      AlignFile afile = null;
-
-      if (format.equalsIgnoreCase("FASTA"))
-      {
-        afile = new FastaFile();
-        afile.addJVSuffix(jalview.bin.Cache.getDefault("FASTA_JVSUFFIX",
-                true));
-      }
-      else if (format.equalsIgnoreCase("MSF"))
-      {
-        afile = new MSFfile();
-        afile.addJVSuffix(jalview.bin.Cache
-                .getDefault("MSF_JVSUFFIX", true));
-      }
-      else if (format.equalsIgnoreCase("PileUp"))
-      {
-        afile = new PileUpfile();
-        afile.addJVSuffix(jalview.bin.Cache.getDefault("PILEUP_JVSUFFIX",
-                true));
-      }
-      else if (format.equalsIgnoreCase("CLUSTAL"))
-      {
-        afile = new ClustalFile();
-        afile.addJVSuffix(jalview.bin.Cache.getDefault("CLUSTAL_JVSUFFIX",
-                true));
-      }
-      else if (format.equalsIgnoreCase("BLC"))
-      {
-        afile = new BLCFile();
-        afile.addJVSuffix(jalview.bin.Cache
-                .getDefault("BLC_JVSUFFIX", true));
-      }
-      else if (format.equalsIgnoreCase("PIR"))
-      {
-        afile = new PIRFile();
-        afile.addJVSuffix(jalview.bin.Cache
-                .getDefault("PIR_JVSUFFIX", true));
-      }
-      else if (format.equalsIgnoreCase("PFAM"))
-      {
-        afile = new PfamFile();
-        afile.addJVSuffix(jalview.bin.Cache.getDefault("PFAM_JVSUFFIX",
-                true));
-      }
-      /*
-       * amsa is not supported by this function - it requires an alignment
-       * rather than a sequence vector else if (format.equalsIgnoreCase("AMSA"))
-       * { afile = new AMSAFile(); afile.addJVSuffix(
-       * jalview.bin.Cache.getDefault("AMSA_JVSUFFIX", true)); }
-       */
-
-      afile.setSeqs(seqs);
-      String afileresp = afile.print();
-      if (afile.hasWarningMessage())
-      {
-        System.err.println("Warning raised when writing as " + format
-                + " : " + afile.getWarningMessage());
-      }
-      return afileresp;
-    } catch (Exception e)
-    {
-      System.err.println("Failed to write alignment as a '" + format
-              + "' file\n");
-      e.printStackTrace();
-    }
-
-    return null;
+//      afile.setSeqs(seqs);
+//      String afileresp = afile.print();
+//      if (afile.hasWarningMessage())
+//      {
+//        System.err.println("Warning raised when writing as " + format
+//                + " : " + afile.getWarningMessage());
+//      }
+//      return afileresp;
+//    } catch (Exception e)
+//    {
+//      System.err.println("Failed to write alignment as a '" + format
+//              + "' file\n");
+//      e.printStackTrace();
+//    }
+//
+//    return null;
   }
 
-  public boolean getCacheSuffixDefault(String format)
+  public boolean getCacheSuffixDefault(FileFormatI format)
   {
-    if (isValidFormat(format))
-    {
-      return jalview.bin.Cache.getDefault(format.toUpperCase()
-              + "_JVSUFFIX", true);
-    }
-    return false;
+    return Cache.getDefault(format.toString() + "_JVSUFFIX", true);
   }
 
-  public String formatSequences(String format, AlignmentI alignment,
+  public String formatSequences(FileFormatI format, AlignmentI alignment,
           String[] omitHidden, int[] exportRange, ColumnSelection colSel)
   {
     return formatSequences(format, alignment, omitHidden, exportRange,
             getCacheSuffixDefault(format), colSel, null);
   }
 
-  public String formatSequences(String format, AlignmentI alignment,
-          String[] omitHidden, int[] exportRange, ColumnSelection colSel,
-          SequenceGroup sgp)
-  {
-    return formatSequences(format, alignment, omitHidden, exportRange,
-            getCacheSuffixDefault(format), colSel, sgp);
-  }
-
   /**
    * hack function to replace seuqences with visible sequence strings before
    * generating a string of the alignment in the given format.
@@ -262,7 +254,7 @@ public class FormatAdapter extends AppletFormatAdapter
    *          defines hidden columns that are edited out of annotation
    * @return string representation of the alignment formatted as format
    */
-  public String formatSequences(String format, AlignmentI alignment,
+  public String formatSequences(FileFormatI format, AlignmentI alignment,
           String[] omitHidden, int[] exportRange, boolean suffix,
           ColumnSelection colSel)
   {
@@ -270,9 +262,9 @@ public class FormatAdapter extends AppletFormatAdapter
             suffix, colSel, null);
   }
 
-  public String formatSequences(String format, AlignmentI alignment,
+  public String formatSequences(FileFormatI format, AlignmentI alignment,
           String[] omitHidden, int[] exportRange, boolean suffix,
-          ColumnSelection colSel, jalview.datamodel.SequenceGroup selgp)
+          ColumnSelection colSel, SequenceGroup selgp)
   {
     if (omitHidden != null)
     {
@@ -305,26 +297,20 @@ public class FormatAdapter extends AppletFormatAdapter
     return this.formatSequences(format, alignment, suffix);
   }
 
-  /**
-   * validate format is valid for IO in Application. This is basically the
-   * AppletFormatAdapter.isValidFormat call with additional checks for
-   * Application only formats like 'Jalview'.
-   * 
-   * @param format
-   *          a format string to be compared with list of readable or writable
-   *          formats (READABLE_FORMATS or WRITABLE_FORMATS)
-   * @param forwriting
-   *          when true, format is checked against list of writable formats.
-   * @return true if format is valid
-   */
-  public static final boolean isValidIOFormat(String format,
-          boolean forwriting)
+  @Override
+  public AlignmentI readFile(String file, DataSourceType sourceType,
+          FileFormatI fileFormat) throws IOException
   {
-    if (format.equalsIgnoreCase("jalview"))
-    {
-      return true;
-    }
-    return AppletFormatAdapter.isValidFormat(format, forwriting);
+    AlignmentI al = super.readFile(file, sourceType, fileFormat);
+    return al;
+  }
+
+  @Override
+  public AlignmentI readFromFile(FileParse source, FileFormatI format)
+          throws IOException
+  {
+    AlignmentI al = super.readFromFile(source, format);
+    return al;
   }
 
   /**
@@ -336,11 +322,19 @@ public class FormatAdapter extends AppletFormatAdapter
    *          alignment panel originating the view
    * @return String containing flat file
    */
-  public String formatSequences(String format, AlignmentViewPanel ap,
+  public String formatSequences(FileFormatI format, AlignmentViewPanel ap,
           boolean selectedOnly)
   {
     return formatSequences(format, getCacheSuffixDefault(format), ap,
             selectedOnly);
   }
 
+  public AlignmentI readFromFile(AlignmentFileI source, FileFormatI format)
+          throws IOException
+  {
+    FileParse fp = new FileParse(source.getInFile(),
+            source.getDataSourceType());
+    return readFromFile(fp, format);
+  }
+
 }
index df0dc06..b0ca25b 100755 (executable)
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- * 
- * This file is part of Jalview.
- * 
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *  
- * Jalview is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty 
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
- * PURPOSE.  See the GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
 package jalview.io;
 
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignViewport;
+import jalview.api.AlignExportSettingI;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentExportData;
+import jalview.exceptions.NoFileSelectedException;
 import jalview.gui.AlignmentPanel;
-import jalview.gui.FeatureRenderer;
-import jalview.gui.SequenceRenderer;
+import jalview.gui.IProgressIndicator;
 import jalview.util.MessageManager;
 
-import java.awt.Color;
-import java.awt.Font;
-import java.io.PrintWriter;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Objects;
 
-public class HTMLOutput
+public abstract class HTMLOutput implements Runnable
 {
-  AlignViewport av;
+  protected AlignmentPanel ap;
 
-  SequenceRenderer sr;
+  protected long pSessionId;
 
-  jalview.renderer.seqfeatures.FeatureRenderer fr;
+  protected IProgressIndicator pIndicator;
 
-  Color color;
+  protected File generatedFile;
 
-  public HTMLOutput(AlignmentPanel ap, SequenceRenderer sr,
-          FeatureRenderer fr1)
+  public HTMLOutput(AlignmentPanel ap)
   {
-    this.av = ap.av;
-    this.sr = sr;
-
-    fr = new FeatureRenderer(ap);
-    fr.transferSettings(fr1);
-
-    JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "html" }, new String[] { "HTML files" },
-            "HTML files");
-
-    chooser.setFileView(new JalviewFileView());
-    chooser.setDialogTitle(MessageManager.getString("label.save_as_html"));
-    chooser.setToolTipText(MessageManager.getString("action.save"));
-
-    int value = chooser.showSaveDialog(null);
-
-    if (value == JalviewFileChooser.APPROVE_OPTION)
+    if (ap != null)
     {
-      String choice = chooser.getSelectedFile().getPath();
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
-              .getSelectedFile().getParent());
-
-      try
-      {
-        PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
-                choice));
-        out.println("<HTML>");
-        out.println("<style type=\"text/css\">");
-        out.println("<!--");
-        out.print("td {font-family: \"" + av.getFont().getFamily()
-                + "\", \"" + av.getFont().getName() + "\", mono; "
-                + "font-size: " + av.getFont().getSize() + "px; ");
-
-        if (av.getFont().getStyle() == Font.BOLD)
-        {
-          out.print("font-weight: BOLD; ");
-        }
-
-        if (av.getFont().getStyle() == Font.ITALIC)
-        {
-          out.print("font-style: italic; ");
-        }
-
-        out.println("text-align: center; }");
-
-        out.println("-->");
-        out.println("</style>");
-        out.println("<BODY>");
-
-        if (av.getWrapAlignment())
-        {
-          drawWrappedAlignment(out);
-        }
-        else
-        {
-          drawUnwrappedAlignment(out);
-        }
-
-        out.println("\n</body>\n</html>");
-        out.close();
-        jalview.util.BrowserLauncher.openURL("file:///" + choice);
-      } catch (Exception ex)
-      {
-        ex.printStackTrace();
-      }
+      this.ap = ap;
+      this.pIndicator = ap.alignFrame;
     }
   }
 
-  void drawUnwrappedAlignment(PrintWriter out)
+  public String getBioJSONData()
   {
-    out.println("<table border=\"1\"><tr><td>\n");
-    out.println("<table border=\"0\"  cellpadding=\"0\" cellspacing=\"0\">\n");
-
-    // ////////////
-    SequenceI seq;
-    AlignmentI alignment = av.getAlignment();
-
-    // draws the top row, the measure rule
-    out.println("<tr><td colspan=\"6\"></td>");
-
-    int i = 0;
+    return getBioJSONData(null);
+  }
 
-    for (i = 10; i < (alignment.getWidth() - 10); i += 10)
+  public String getBioJSONData(AlignExportSettingI exportSettings)
+  {
+    if (!isEmbedData())
     {
-      out.println("<td colspan=\"9\">" + i + "<br>|</td><td></td>");
+      return null;
     }
-
-    out.println("<td colspan=\"3\"></td><td colspan=\"3\">" + i
-            + "<br>|</td>");
-    out.println("</tr>");
-
-    for (i = 0; i < alignment.getHeight(); i++)
+    if (exportSettings == null)
     {
-      seq = alignment.getSequenceAt(i);
-
-      String id = seq.getDisplayId(av.getShowJVSuffix());
-
-      out.println("<tr><td nowrap>" + id + "&nbsp;&nbsp;</td>");
-
-      for (int res = 0; res < seq.getLength(); res++)
+      exportSettings = new AlignExportSettingI()
       {
-        if (!jalview.util.Comparison.isGap(seq.getCharAt(res)))
+        @Override
+        public boolean isExportHiddenSequences()
         {
-          color = sr.getResidueBoxColour(seq, res);
+          return true;
+        }
 
-          color = fr.findFeatureColour(color, seq, res);
+        @Override
+        public boolean isExportHiddenColumns()
+        {
+          return true;
         }
-        else
+
+        @Override
+        public boolean isExportAnnotations()
         {
-          color = Color.white;
+          return true;
         }
 
-        if (color.getRGB() < -1)
+        @Override
+        public boolean isExportFeatures()
         {
-          out.println("<td bgcolor=\"#"
-                  + jalview.util.Format.getHexString(color) + "\">"
-                  + seq.getCharAt(res) + "</td>");
+          return true;
         }
-        else
+
+        @Override
+        public boolean isExportGroups()
         {
-          out.println("<td>" + seq.getCharAt(res) + "</td>");
+          return true;
         }
-      }
 
-      out.println("</tr>");
+        @Override
+        public boolean isCancelled()
+        {
+          return false;
+        }
+      };
     }
-
-    // ////////////
-    out.println("</table>");
-    out.println("</td></tr></table>");
+    AlignmentExportData exportData = jalview.gui.AlignFrame
+            .getAlignmentForExport(FileFormat.Json,
+                    ap.getAlignViewport(), exportSettings);
+    String bioJSON = new FormatAdapter(ap, exportData.getSettings())
+            .formatSequences(FileFormat.Json, exportData.getAlignment(),
+                    exportData.getOmitHidden(), exportData
+                            .getStartEndPostions(), ap.getAlignViewport()
+                            .getColumnSelection());
+    return bioJSON;
   }
 
-  void drawWrappedAlignment(PrintWriter out)
+  /**
+   * Read a template file content as string
+   * 
+   * @param file
+   *          - the file to be read
+   * @return File content as String
+   * @throws IOException
+   */
+  public static String readFileAsString(File file) throws IOException
   {
-    // //////////////////////////////////
-    // / How many sequences and residues can we fit on a printable page?
-    AlignmentI al = av.getAlignment();
-    SequenceI seq;
-    String r;
-    String g;
-    String b;
-
-    out.println("<table border=\"1\"><tr><td>\n");
-    out.println("<table border=\"0\"  cellpadding=\"0\" cellspacing=\"0\">\n");
-
-    for (int startRes = 0; startRes < al.getWidth(); startRes += av
-            .getWrappedWidth())
+    InputStreamReader isReader = null;
+    BufferedReader buffReader = null;
+    StringBuilder sb = new StringBuilder();
+    Objects.requireNonNull(file, "File must not be null!");
+    @SuppressWarnings("deprecation")
+    URL url = file.toURL();
+    if (url != null)
     {
-      int endRes = startRes + av.getWrappedWidth();
-
-      if (endRes > al.getWidth())
-      {
-        endRes = al.getWidth();
-      }
-
-      if (av.getScaleAboveWrapped())
+      try
       {
-        out.println("<tr>");
-
-        if (av.getScaleLeftWrapped())
+        isReader = new InputStreamReader(url.openStream());
+        buffReader = new BufferedReader(isReader);
+        String line;
+        String lineSeparator = System.getProperty("line.separator");
+        while ((line = buffReader.readLine()) != null)
         {
-          out.println("<td colspan=\"7\">&nbsp;</td>");
+          sb.append(line).append(lineSeparator);
         }
-        else
-        {
-          out.println("<td colspan=\"6\">&nbsp;</td>");
-        }
-
-        for (int i = startRes + 10; i < endRes; i += 10)
-        {
-          out.println("<td colspan=\"9\">" + i + "<br>|</td><td></td>");
-        }
-
-        out.println("</tr>");
-      }
-
-      int startPos, endPos;
-      for (int s = 0; s < al.getHeight(); s++)
+  
+      } catch (Exception ex)
       {
-        out.println("<tr>");
-        seq = al.getSequenceAt(s);
-
-        startPos = seq.findPosition(startRes);
-        endPos = seq.findPosition(endRes) - 1;
-
-        String id = seq.getDisplayId(av.getShowJVSuffix());
-
-        out.println("<td nowrap>" + id + "&nbsp;&nbsp;</td>");
-
-        if (av.getScaleLeftWrapped())
-        {
-          if (startPos > seq.getEnd() || endPos == 0)
-          {
-            out.println("<td nowrap>&nbsp;</td>");
-          }
-          else
-          {
-            out.println("<td nowrap>" + startPos + "&nbsp;&nbsp;</td>");
-          }
-        }
-
-        for (int res = startRes; res < endRes; res++)
-        {
-          if (!jalview.util.Comparison.isGap(seq.getCharAt(res)))
-          {
-            color = sr.getResidueBoxColour(seq, res);
-
-            color = fr.findFeatureColour(color, seq, res);
-          }
-          else
-          {
-            color = Color.white;
-          }
-
-          if (color.getRGB() < -1)
-          {
-            out.println("<td bgcolor=\"#"
-                    + jalview.util.Format.getHexString(color) + "\">"
-                    + seq.getCharAt(res) + "</td>");
-          }
-          else
-          {
-            out.println("<td>" + seq.getCharAt(res) + "</td>");
-          }
-
-        }
-
-        if (av.getScaleRightWrapped()
-                && endRes < startRes + av.getWrappedWidth())
+        ex.printStackTrace();
+      } finally
+      {
+        if (isReader != null)
         {
-          out.println("<td colspan=\""
-                  + (startRes + av.getWrappedWidth() - endRes) + "\">"
-                  + "&nbsp;&nbsp;</td>");
+          isReader.close();
         }
-
-        if (av.getScaleRightWrapped() && startPos < endPos)
+  
+        if (buffReader != null)
         {
-          out.println("<td nowrap>&nbsp;" + endPos + "&nbsp;&nbsp;</td>");
+          buffReader.close();
         }
-
-        out.println("</tr>");
-      }
-
-      if (endRes < al.getWidth())
-      {
-        out.println("<tr><td height=\"5\"></td></tr>");
       }
     }
-
-    out.println("</table>");
-    out.println("</table>");
+    return sb.toString();
   }
 
   public static String getImageMapHTML()
@@ -386,4 +232,120 @@ public class HTMLOutput
                     + "initToolTips(); //--></script>\n");
 
   }
-}
+
+  public String getOutputFile() throws NoFileSelectedException
+  {
+    String selectedFile = null;
+    if (pIndicator != null && !isHeadless())
+    {
+      pIndicator.setProgressBar(MessageManager.formatMessage(
+              "status.waiting_for_user_to_select_output_file", "HTML"),
+              pSessionId);
+    }
+
+    JalviewFileChooser jvFileChooser = new JalviewFileChooser(
+            Cache.getProperty("LAST_DIRECTORY"), "html", "HTML files");
+    jvFileChooser.setFileView(new JalviewFileView());
+
+    jvFileChooser.setDialogTitle(MessageManager
+            .getString("label.save_as_html"));
+    jvFileChooser.setToolTipText(MessageManager.getString("action.save"));
+
+    int fileChooserOpt = jvFileChooser.showSaveDialog(null);
+    if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
+    {
+      jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
+              .getSelectedFile().getParent());
+      selectedFile = jvFileChooser.getSelectedFile().getPath();
+    }
+    else
+    {
+      throw new NoFileSelectedException("No file was selected.");
+    }
+    return selectedFile;
+  }
+
+  protected void setProgressMessage(String message)
+  {
+    if (pIndicator != null && !isHeadless())
+    {
+      pIndicator.setProgressBar(message, pSessionId);
+    }
+    else
+    {
+      System.out.println(message);
+    }
+  }
+
+  /**
+   * Answers true if HTML export is invoke in headless mode or false otherwise
+   * 
+   * @return
+   */
+  protected boolean isHeadless()
+  {
+    return System.getProperty("java.awt.headless") != null
+            && System.getProperty("java.awt.headless").equals("true");
+  }
+
+  /**
+   * This method provides implementation of consistent behaviour which should
+   * occur before a HTML file export. It MUST be called at the start of the
+   * exportHTML() method implementation.
+   */
+  protected void exportStarted()
+  {
+    pSessionId = System.currentTimeMillis();
+  }
+
+  /**
+   * This method provides implementation of consistent behaviour which should
+   * occur after a HTML file export. It MUST be called at the end of the
+   * exportHTML() method implementation.
+   */
+  protected void exportCompleted()
+  {
+    if (isLaunchInBrowserAfterExport() && !isHeadless())
+    {
+      try
+      {
+        jalview.util.BrowserLauncher
+                .openURL("file:///" + getExportedFile());
+      } catch (IOException e)
+      {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  /**
+   * if this answers true then BioJSON data will be embedded to the exported
+   * HTML file otherwise it won't be embedded.
+   * 
+   * @return
+   */
+  public abstract boolean isEmbedData();
+
+  /**
+   * if this answers true then the generated HTML file is opened for viewing in
+   * a browser after its generation otherwise it won't be opened in a browser
+   * 
+   * @return
+   */
+  public abstract boolean isLaunchInBrowserAfterExport();
+
+  /**
+   * handle to the generated HTML file
+   * 
+   * @return
+   */
+  public abstract File getExportedFile();
+
+  /**
+   * This is the main method to handle the HTML generation.
+   * 
+   * @param outputFile
+   *          the file path of the generated HTML
+   */
+  public abstract void exportHTML(String outputFile);
+}
\ No newline at end of file
index e31e78d..af3fb5d 100644 (file)
@@ -60,9 +60,10 @@ public class HtmlFile extends AlignFile implements ComplexAlignFile
     super(source);
   }
 
-  public HtmlFile(String inFile, String type) throws IOException
+  public HtmlFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   @Override
@@ -119,7 +120,7 @@ public class HtmlFile extends AlignFile implements ComplexAlignFile
   }
 
   @Override
-  public String print()
+  public String print(SequenceI[] sqs, boolean jvsuffix)
   {
     throw new UnsupportedOperationException(
             "Print method of HtmlFile is not supported!");
index 68173ff..3fb3cf2 100644 (file)
  */
 package jalview.io;
 
-import jalview.api.AlignExportSettingI;
-import jalview.api.FeatureRenderer;
-import jalview.datamodel.AlignmentExportData;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignViewport;
+import jalview.exceptions.NoFileSelectedException;
 import jalview.gui.AlignmentPanel;
 import jalview.gui.HTMLOptions;
-import jalview.gui.IProgressIndicator;
 import jalview.gui.OOMWarning;
 import jalview.math.AlignmentDimension;
 import jalview.util.MessageManager;
 
-import java.awt.Color;
-import java.awt.FontMetrics;
 import java.awt.Graphics;
-import java.awt.print.Printable;
 import java.awt.print.PrinterException;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.IOException;
 
 import org.jfree.graphics2d.svg.SVGGraphics2D;
 import org.jfree.graphics2d.svg.SVGHints;
 
-public class HtmlSvgOutput
+public class HtmlSvgOutput extends HTMLOutput
 {
-  AlignViewport av;
 
-  FeatureRenderer fr;
 
-  AlignmentPanel ap;
-
-  private IProgressIndicator pIndicator;
-
-  private long pSessionId;
-
-  private boolean headless;
-
-  public HtmlSvgOutput(File file, AlignmentPanel ap)
+  public HtmlSvgOutput(AlignmentPanel ap)
   {
-    this.av = ap.av;
-    this.ap = ap;
-    fr = ap.cloneFeatureRenderer();
-    generateHtmlSvgOutput(file);
+    super(ap);
   }
 
-  public void generateHtmlSvgOutput(File file)
+  @Override
+  public void exportHTML(String outputFile)
   {
-    pIndicator = ap.alignFrame;
-    pSessionId = System.currentTimeMillis();
+    exportStarted();
     try
     {
-      headless = (System.getProperty("java.awt.headless") != null && System
-              .getProperty("java.awt.headless").equals("true"));
-      if (file == null)
+      if (outputFile == null)
       {
-        setProgressMessage(MessageManager.formatMessage(
-                "status.waiting_for_user_to_select_output_file", "HTML"));
-        JalviewFileChooser chooser = getHTMLChooser();
-        chooser.setFileView(new jalview.io.JalviewFileView());
-        chooser.setDialogTitle(ap.alignFrame.getTitle());
-        chooser.setToolTipText(MessageManager.getString("action.save"));
-        int value = chooser.showSaveDialog(ap.alignFrame);
-
-        if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
-        {
-          jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
-                  .getSelectedFile().getParent());
-          file = chooser.getSelectedFile();
-          ap.alignFrame.repaint();
-        }
-        else
-        {
-          setProgressMessage(MessageManager.formatMessage(
-                  "status.cancelled_image_export_operation", "HTML"));
-          return;
-        }
+        outputFile = getOutputFile();
       }
+      generatedFile = new File(outputFile);
+    } catch (NoFileSelectedException e)
+    {
+      setProgressMessage(MessageManager.formatMessage(
+              "status.cancelled_image_export_operation", "HTML"));
+      return;
     } catch (Exception e)
     {
-      pIndicator.setProgressBar(MessageManager.formatMessage(
-              "info.error_creating_file", "HTML"), pSessionId);
+      setProgressMessage(MessageManager.formatMessage(
+              "info.error_creating_file", "HTML"));
       e.printStackTrace();
       return;
     }
-    final File fileX = file;
-    new Thread()
-    {
-      @Override
-      public void run()
-      {
-        try
-        {
-          setProgressMessage(null);
-          setProgressMessage(MessageManager.formatMessage(
-                  "status.exporting_alignment_as_x_file", "HTML"));
-          AlignmentDimension aDimension = ap.getAlignmentDimension();
-          SVGGraphics2D g1 = new SVGGraphics2D(aDimension.getWidth(),
-                  aDimension.getHeight());
-          SVGGraphics2D g2 = new SVGGraphics2D(aDimension.getWidth(),
-                  aDimension.getHeight());
-
-          String renderStyle = jalview.bin.Cache.getDefault(
-                  "HTML_RENDERING", "Prompt each time");
-
-          // If we need to prompt, and if the GUI is visible then
-          // Prompt for rendering style
-          if (renderStyle.equalsIgnoreCase("Prompt each time")
-                  && !(System.getProperty("java.awt.headless") != null && System
-                          .getProperty("java.awt.headless").equals("true")))
-          {
-            HTMLOptions svgOption = new HTMLOptions();
-            renderStyle = svgOption.getValue();
-
-            if (renderStyle == null || svgOption.cancelled)
-            {
-              setProgressMessage(MessageManager.formatMessage(
-                      "status.cancelled_image_export_operation", "HTML"));
-              return;
-            }
-          }
-
-          if (renderStyle.equalsIgnoreCase("Lineart"))
-          {
-            g1.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
-                    SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
-            g2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
-                    SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
-          }
-          printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
-                  g1, g2);
-
-          String titleSvgData = g1.getSVGDocument();
-          String alignSvgData = g2.getSVGDocument();
-          String jsonData = null;
-          boolean isEmbbedBioJSON = Boolean.valueOf(jalview.bin.Cache
-                  .getDefault("EXPORT_EMBBED_BIOJSON", "true"));
-          if (isEmbbedBioJSON)
-          {
-            AlignExportSettingI exportSettings = new AlignExportSettingI()
-            {
-              @Override
-              public boolean isExportHiddenSequences()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isExportHiddenColumns()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isExportAnnotations()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isExportFeatures()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isExportGroups()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isCancelled()
-              {
-                return false;
-              }
-
-            };
-            AlignmentExportData exportData = jalview.gui.AlignFrame
-                    .getAlignmentForExport(JSONFile.FILE_DESC, av,
-                            exportSettings);
-            jsonData = new FormatAdapter(ap, exportData.getSettings())
-                    .formatSequences(JSONFile.FILE_DESC,
-                            exportData.getAlignment(),
-                            exportData.getOmitHidden(),
-                            exportData.getStartEndPostions(),
-                            av.getColumnSelection());
-          }
-          String htmlData = getHtml(titleSvgData, alignSvgData, jsonData);
-          FileOutputStream out = new FileOutputStream(fileX);
-          out.write(htmlData.getBytes());
-          out.flush();
-          out.close();
-          if (!(System.getProperty("java.awt.headless") != null && System
-                  .getProperty("java.awt.headless").equals("true")))
-          {
-            jalview.util.BrowserLauncher.openURL("file:///" + fileX);
-          }
-        } catch (OutOfMemoryError err)
-        {
-          System.out.println("########################\n"
-                  + "OUT OF MEMORY " + fileX + "\n"
-                  + "########################");
-          new OOMWarning("Creating Image for " + fileX, err);
-        } catch (Exception e)
-        {
-          e.printStackTrace();
-          pIndicator.setProgressBar(MessageManager.formatMessage(
-                  "info.error_creating_file", "HTML"), pSessionId);
-        }
-        setProgressMessage(MessageManager.formatMessage(
-                "status.export_complete", "HTML"));
-      }
-    }.start();
-
-  }
-
-  private void setProgressMessage(String message)
-  {
-    if (pIndicator != null && !headless)
-    {
-      pIndicator.setProgressBar(message, pSessionId);
-    }
-    else
-    {
-      System.out.println(message);
-    }
+    new Thread(this).start();
   }
 
-  static JalviewFileChooser getHTMLChooser()
+  public int printUnwrapped(int pwidth, int pheight, int pi,
+          Graphics idGraphics, Graphics alignmentGraphics)
+          throws PrinterException
   {
-    return new jalview.io.JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "html" },
-            new String[] { "Hypertext Markup Language" },
-            "Hypertext Markup Language");
+    return ap.printUnwrapped(pwidth, pheight, pi, idGraphics,
+            alignmentGraphics);
   }
 
-  public int printUnwrapped(int pwidth, int pheight, int pi, Graphics... pg)
+  public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg)
           throws PrinterException
   {
-    int idWidth = ap.getVisibleIdWidth(false);
-    FontMetrics fm = ap.getFontMetrics(av.getFont());
-    int scaleHeight = av.getCharHeight() + fm.getDescent();
-
-    pg[0].setColor(Color.white);
-    pg[0].fillRect(0, 0, pwidth, pheight);
-    pg[0].setFont(av.getFont());
-
-    // //////////////////////////////////
-    // / How many sequences and residues can we fit on a printable page?
-    int totalRes = (pwidth - idWidth) / av.getCharWidth();
-    int totalSeq = (pheight - scaleHeight) / av.getCharHeight() - 1;
-    int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;
-
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int startRes;
-
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int endRes;
-
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int startSeq;
-
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int endSeq;
-    startRes = (pi % pagesWide) * totalRes;
-    endRes = (startRes + totalRes) - 1;
-
-    if (endRes > (av.getAlignment().getWidth() - 1))
-    {
-      endRes = av.getAlignment().getWidth() - 1;
-    }
-    startSeq = (pi / pagesWide) * totalSeq;
-    endSeq = startSeq + totalSeq;
-    if (endSeq > av.getAlignment().getHeight())
-    {
-      endSeq = av.getAlignment().getHeight();
-    }
-    int pagesHigh = ((av.getAlignment().getHeight() / totalSeq) + 1)
-            * pheight;
-    if (av.isShowAnnotation())
-    {
-      pagesHigh += ap.getAnnotationPanel().adjustPanelHeight() + 3;
-    }
-    pagesHigh /= pheight;
-    if (pi >= (pagesWide * pagesHigh))
-    {
-      return Printable.NO_SUCH_PAGE;
-    }
-
-    // draw Scale
-    pg[1].translate(0, 0);
-    ap.getScalePanel().drawScale(pg[1], startRes, endRes, pwidth - idWidth,
-            scaleHeight);
-    pg[1].translate(-idWidth, scaleHeight);
-
-    // //////////////
-    // Draw the ids
-    Color currentColor = null;
-    Color currentTextColor = null;
-    pg[0].translate(0, scaleHeight);
-    pg[0].setFont(ap.getIdPanel().getIdCanvas().getIdfont());
-    SequenceI seq;
-    for (int i = startSeq; i < endSeq; i++)
-    {
-      seq = av.getAlignment().getSequenceAt(i);
-      if ((av.getSelectionGroup() != null)
-              && av.getSelectionGroup().getSequences(null).contains(seq))
-      {
-        currentColor = Color.gray;
-        currentTextColor = Color.black;
-      }
-      else
-      {
-        currentColor = av.getSequenceColour(seq);
-        currentTextColor = Color.black;
-      }
-      pg[0].setColor(currentColor);
-      pg[0].fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth,
-              av.getCharHeight());
-      pg[0].setColor(currentTextColor);
-      int xPos = 0;
-      if (av.isRightAlignIds())
-      {
-        fm = pg[0].getFontMetrics();
-        xPos = idWidth
-                - fm.stringWidth(seq.getDisplayId(av.getShowJVSuffix()))
-                - 4;
-      }
-      pg[0].drawString(seq.getDisplayId(av.getShowJVSuffix()), xPos,
-              (((i - startSeq) * av.getCharHeight()) + av.getCharHeight())
-                      - (av.getCharHeight() / 5));
-    }
-    pg[0].setFont(av.getFont());
-    pg[0].translate(idWidth, 0);
-
-    // draw main sequence panel
-    pg[1].translate(idWidth, 0);
-    ap.getSeqPanel().seqCanvas.drawPanel(pg[1], startRes, endRes, startSeq,
-            endSeq, 0);
-    if (av.isShowAnnotation() && (endSeq == av.getAlignment().getHeight()))
-    {
-      // draw annotation label - need to offset for current scroll position
-      int offset = -ap.getAlabels().getScrollOffset();
-      pg[0].translate(0, offset);
-      pg[0].translate(-idWidth - 3,
-              (endSeq - startSeq) * av.getCharHeight() + 3);
-      ap.getAlabels().drawComponent(pg[0], idWidth);
-      pg[0].translate(idWidth + 3, 0);
-      pg[0].translate(0, -offset);
-
-      // draw annotation - need to offset for current scroll position
-      pg[1].translate(0, offset);
-      pg[1].translate(-idWidth - 3,
-              (endSeq - startSeq) * av.getCharHeight() + 3);
-      pg[1].translate(idWidth + 3, 0);
-      ap.getAnnotationPanel().renderer.drawComponent(
-              ap.getAnnotationPanel(), av, pg[1], -1, startRes, endRes + 1);
-      pg[1].translate(0, -offset);
-    }
-
-    return Printable.PAGE_EXISTS;
+    return ap.printWrappedAlignment(pwidth, pheight, pi, pg[0]);
   }
 
   private String getHtml(String titleSvg, String alignmentSvg,
-          String jsonData)
+          String jsonData, boolean wrapped)
   {
     StringBuilder htmlSvg = new StringBuilder();
     htmlSvg.append("<html>\n");
@@ -429,8 +126,9 @@ public class HtmlSvgOutput
               + ".facebox_hide { z-index:-100; }\n"
               + ".facebox_overlayBG { background-color: #000;  z-index: 99;  }");
     }
-
     htmlSvg.append("</style>");
+    if (!wrapped)
+    {
     htmlSvg.append("<div class=\"main-container\" \n>");
     htmlSvg.append("<div class=\"titlex\">\n");
     htmlSvg.append("<div class=\"sub-category-container\"> \n");
@@ -451,9 +149,16 @@ public class HtmlSvgOutput
             + "subCatContainer.scrollTop($(this).scrollTop());\n});\n");
 
     htmlSvg.append("</script>\n");
+    }
+    else
+    {
+      htmlSvg.append("<div>\n")
+              .append(alignmentSvg).append("</div>");
+      htmlSvg.append("<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
+              + "<script language=\"JavaScript\" type=\"text/javascript\"  src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n");
+    }
 
     // javascript for launching file in Jalview
-
     htmlSvg.append("<script language=\"JavaScript\">\n");
     htmlSvg.append("function openJalviewUsingCurrentUrl(){\n");
     htmlSvg.append("    var json = JSON.parse(document.getElementById(\"seqData\").innerHTML);\n");
@@ -478,269 +183,115 @@ public class HtmlSvgOutput
     htmlSvg.append("    document.body.removeChild(myForm);\n");
     htmlSvg.append("}\n");
 
-    // jquery facebox for displaying raw BioJSON data");
     if (jsonData != null)
     {
-      htmlSvg.append("/* Facebox (for jQuery)\n");
-      htmlSvg.append("* version: 1.3\n");
-      htmlSvg.append(" * @requires jQuery v1.2 or later\n");
-      htmlSvg.append(" * @homepage https://github.com/defunkt/facebox\n");
-      htmlSvg.append(" * Licensed under the MIT:\n");
-      htmlSvg.append(" *   http://www.opensource.org/licenses/mit-license.php\n");
-      htmlSvg.append(" * Copyright Forever Chris Wanstrath, Kyle Neath\n");
-      htmlSvg.append(" * Usage:\n");
-      htmlSvg.append(" *  jQuery(document).ready(function() {\n");
-      htmlSvg.append(" *    jQuery('a[rel*=facebox]').facebox()\n");
-      htmlSvg.append(" *  })\n");
-      htmlSvg.append(" *  <a href=\"#terms\" rel=\"facebox\">Terms</a>\n");
-      htmlSvg.append(" *    Loads the #terms div in the box\n");
-      htmlSvg.append(" *  <a href=\"terms.html\" rel=\"facebox\">Terms</a>\n");
-      htmlSvg.append(" *    Loads the terms.html page in the box\n");
-      htmlSvg.append(" *  <a href=\"terms.png\" rel=\"facebox\">Terms</a>\n");
-      htmlSvg.append(" *    Loads the terms.png image in the box\n");
-      htmlSvg.append(" *  You can also use it programmatically:\n");
-      htmlSvg.append(" *    jQuery.facebox('some html')\n");
-      htmlSvg.append(" *    jQuery.facebox('some html', 'my-groovy-style')\n");
-      htmlSvg.append(" *  The above will open a facebox with \"some html\" as the content.\n");
-      htmlSvg.append(" *    jQuery.facebox(function($) {\n");
-      htmlSvg.append(" *      $.get('blah.html', function(data) { $.facebox(data) })\n");
-      htmlSvg.append(" *    })\n");
-      htmlSvg.append(" *  The above will show a loading screen before the passed function is called,\n");
-      htmlSvg.append(" *  allowing for a better ajaxy experience.\n");
-      htmlSvg.append(" *  The facebox function can also display an ajax page, an image, or the contents of a div:\n");
-      htmlSvg.append(" *    jQuery.facebox({ ajax: 'remote.html' })\n");
-      htmlSvg.append(" *    jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')\n");
-      htmlSvg.append(" *    jQuery.facebox({ image: 'stairs.jpg' })\n");
-      htmlSvg.append(" *    jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')\n");
-      htmlSvg.append(" *    jQuery.facebox({ div: '#box' })\n");
-      htmlSvg.append(" *    jQuery.facebox({ div: '#box' }, 'my-groovy-style')\n");
-      htmlSvg.append(" *    Want to close the facebox?  Trigger the 'close.facebox' document event:\n");
-      htmlSvg.append(" *    jQuery(document).trigger('close.facebox')\n");
-      htmlSvg.append(" *  Facebox also has a bunch of other hooks:\n");
-      htmlSvg.append(" *    loading.facebox\n");
-      htmlSvg.append(" *    beforeReveal.facebox\n");
-      htmlSvg.append(" *    reveal.facebox (aliased as 'afterReveal.facebox')\n");
-      htmlSvg.append(" *    init.facebox\n");
-      htmlSvg.append(" *    afterClose.facebox\n");
-      htmlSvg.append(" *  Simply bind a function to any of these hooks:\n");
-      htmlSvg.append(" *   $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })\n");
-      htmlSvg.append(" *\n");
-      htmlSvg.append(" */\n");
-      htmlSvg.append("(function($) {\n");
-      htmlSvg.append("  $.facebox = function(data, klass) {\n");
-      htmlSvg.append("    $.facebox.loading()\n");
-      htmlSvg.append("    if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)\n");
-      htmlSvg.append("    else if (data.image) fillFaceboxFromImage(data.image, klass)\n");
-      htmlSvg.append("    else if (data.div) fillFaceboxFromHref(data.div, klass)\n");
-      htmlSvg.append("    else if ($.isFunction(data)) data.call($)\n");
-      htmlSvg.append("    else $.facebox.reveal(data, klass)\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  $.extend($.facebox, {\n");
-      htmlSvg.append("    settings: {\n");
-      htmlSvg.append("      opacity      : 0.2,\n");
-      htmlSvg.append("      overlay      : true,\n");
-      htmlSvg.append("      loadingImage : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/loading.gif',\n");
-      htmlSvg.append("      closeImage   : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png',\n");
-      htmlSvg.append("      imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ],\n");
-      htmlSvg.append("      faceboxHtml  : '<div  id=\"facebox\" style=\"display:none; width: 95%; height: 85%; overflow: auto;\"> ");
-      htmlSvg.append("      <div class=\"popup\"> ");
-      htmlSvg.append("        <div class=\"content\"> ");
-      htmlSvg.append("        </div> ");
-      htmlSvg.append("        <a href=\"#\" class=\"close\"></a> ");
-      htmlSvg.append("      </div> ");
-      htmlSvg.append("    </div>'\n");
-      htmlSvg.append("    },      \n");
-      htmlSvg.append("    loading: function() {\n");
-      htmlSvg.append("      init()\n");
-      htmlSvg.append("      if ($('#facebox .loading').length == 1) return true\n");
-      htmlSvg.append("      showOverlay()      \n");
-      htmlSvg.append("      $('#facebox .content').empty().\n");
-      htmlSvg.append("        append('<div class=\"loading\"><img src=\"'+$.facebox.settings.loadingImage+'\"/></div>')\n");
-      htmlSvg.append("      $('#facebox').show().css({\n");
-      htmlSvg.append("        top:    getPageScroll()[1] + (getPageHeight() / 10),\n");
-      htmlSvg.append("        left:    $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2)\n");
-      htmlSvg.append("      })      \n");
-      htmlSvg.append("      $(document).bind('keydown.facebox', function(e) {\n");
-      htmlSvg.append("       if (e.keyCode == 27) $.facebox.close()\n");
-      htmlSvg.append("        return true\n");
-      htmlSvg.append("      })\n");
-      htmlSvg.append("      $(document).trigger('loading.facebox')\n");
-      htmlSvg.append("    },\n");
-      htmlSvg.append("    reveal: function(data, klass) {\n");
-      htmlSvg.append("      $(document).trigger('beforeReveal.facebox')\n");
-      htmlSvg.append("      if (klass) $('#facebox .content').addClass(klass)\n");
-      htmlSvg.append("      $('#facebox .content').empty().append('<pre><code>'+JSON.stringify(JSON.parse(data),null,4)+'</pre></code>')\n");
-      htmlSvg.append("      $('#facebox .popup').children().fadeIn('normal')\n");
-      htmlSvg.append("      $('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2))\n");
-      htmlSvg.append("      $(document).trigger('reveal.facebox').trigger('afterReveal.facebox')\n");
-      htmlSvg.append("    },      \n");
-      htmlSvg.append("    close: function() {\n");
-      htmlSvg.append("      $(document).trigger('close.facebox')\n");
-      htmlSvg.append("      return false\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("  })\n");
-      htmlSvg.append("  $.fn.facebox = function(settings) {\n");
-      htmlSvg.append("    if ($(this).length == 0) return    \n");
-      htmlSvg.append("    init(settings)      \n");
-      htmlSvg.append("    function clickHandler() {\n");
-      htmlSvg.append("      $.facebox.loading(true)      \n");
-      htmlSvg.append("      // support for rel=\"facebox.inline_popup\" syntax, to add a class\n");
-      htmlSvg.append("      // also supports deprecated \"facebox[.inline_popup]\" syntax\n");
-      htmlSvg.append("      var klass = this.rel.match(/facebox\\[?\\.(\\w+)\\]?/)\n");
-      htmlSvg.append("      if (klass) klass = klass[1]\n");
-      htmlSvg.append("      fillFaceboxFromHref(this.href, klass)\n");
-      htmlSvg.append("      return false\n");
-      htmlSvg.append("    }      \n");
-      htmlSvg.append("    return this.bind('click.facebox', clickHandler)\n");
-      htmlSvg.append("  }\n");
-      htmlSvg.append("  // called one time to setup facebox on this page\n");
-      htmlSvg.append("  function init(settings) {\n");
-      htmlSvg.append("    if ($.facebox.settings.inited) return true\n");
-      htmlSvg.append("    else $.facebox.settings.inited = true\n");
-      htmlSvg.append("    $(document).trigger('init.facebox')\n");
-      htmlSvg.append("    makeCompatible()\n");
-      htmlSvg.append("    var imageTypes = $.facebox.settings.imageTypes.join('|')\n");
-      htmlSvg.append("    $.facebox.settings.imageTypesRegexp = new RegExp('\\\\.(' + imageTypes + ')(\\\\?.*)?$', 'i')\n");
-
-      htmlSvg.append("    if (settings) $.extend($.facebox.settings, settings)\n");
-      htmlSvg.append("    $('body').append($.facebox.settings.faceboxHtml)\n");
-
-      htmlSvg.append("    var preload = [ new Image(), new Image() ]\n");
-      htmlSvg.append("    preload[0].src = $.facebox.settings.closeImage\n");
-      htmlSvg.append("    preload[1].src = $.facebox.settings.loadingImage\n");
-
-      htmlSvg.append("    $('#facebox').find('.b:first, .bl').each(function() {\n");
-      htmlSvg.append("      preload.push(new Image())\n");
-      htmlSvg.append("      preload.slice(-1).src = $(this).css('background-image').replace(/url\\((.+)\\)/, '$1')\n");
-      htmlSvg.append("    })\n");
-
-      htmlSvg.append("    $('#facebox .close')\n");
-      htmlSvg.append("      .click($.facebox.close)\n");
-      htmlSvg.append("      .append('<img src=\"'\n");
-      htmlSvg.append("              + $.facebox.settings.closeImage\n");
-      htmlSvg.append("              + '\" class=\"close_image\" title=\"close\">')\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  // getPageScroll() by quirksmode.com\n");
-      htmlSvg.append("  function getPageScroll() {\n");
-      htmlSvg.append("    var xScroll, yScroll;\n");
-      htmlSvg.append("    if (self.pageYOffset) {\n");
-      htmlSvg.append("      yScroll = self.pageYOffset;\n");
-      htmlSvg.append("      xScroll = self.pageXOffset;\n");
-      htmlSvg.append("    } else if (document.documentElement && document.documentElement.scrollTop) {     // Explorer 6 Strict\n");
-      htmlSvg.append("      yScroll = document.documentElement.scrollTop;\n");
-      htmlSvg.append("      xScroll = document.documentElement.scrollLeft;\n");
-      htmlSvg.append("    } else if (document.body) {// all other Explorers\n");
-      htmlSvg.append("      yScroll = document.body.scrollTop;\n");
-      htmlSvg.append("      xScroll = document.body.scrollLeft;\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("    return new Array(xScroll,yScroll)\n");
-      htmlSvg.append("  }\n");
-
-      // Adapted from getPageSize() by quirksmode.com");
-      htmlSvg.append("  function getPageHeight() {\n");
-      htmlSvg.append("    var windowHeight\n");
-      htmlSvg.append("    if (self.innerHeight) {    // all except Explorer\n");
-      htmlSvg.append("      windowHeight = self.innerHeight;\n");
-      htmlSvg.append("    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode\n");
-      htmlSvg.append("      windowHeight = document.documentElement.clientHeight;\n");
-      htmlSvg.append("    } else if (document.body) { // other Explorers\n");
-      htmlSvg.append("      windowHeight = document.body.clientHeight;\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("    return windowHeight\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  // Backwards compatibility\n");
-      htmlSvg.append("  function makeCompatible() {\n");
-      htmlSvg.append("    var $s = $.facebox.settings      \n");
-      htmlSvg.append("    $s.loadingImage = $s.loading_image || $s.loadingImage\n");
-      htmlSvg.append("    $s.closeImage = $s.close_image || $s.closeImage\n");
-      htmlSvg.append("    $s.imageTypes = $s.image_types || $s.imageTypes\n");
-      htmlSvg.append("    $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  // Figures out what you want to display and displays it\n");
-      htmlSvg.append("  // formats are:\n");
-      htmlSvg.append("  //     div: #id\n");
-      htmlSvg.append("  //   image: blah.extension\n");
-      htmlSvg.append("  //    ajax: anything else\n");
-      htmlSvg.append("  function fillFaceboxFromHref(href, klass) {\n");
-      htmlSvg.append("    // div\n");
-      htmlSvg.append("    if (href.match(/#/)) {\n");
-      htmlSvg.append("      var url    = window.location.href.split('#')[0]\n");
-      htmlSvg.append("      var target = href.replace(url,'')\n");
-      htmlSvg.append("      if (target == '#') return\n");
-      htmlSvg.append("      $.facebox.reveal($(target).html(), klass)\n");
-
-      htmlSvg.append("    // image\n");
-      htmlSvg.append("    } else if (href.match($.facebox.settings.imageTypesRegexp)) {\n");
-      htmlSvg.append("      fillFaceboxFromImage(href, klass)\n");
-      htmlSvg.append("    // ajax\n");
-      htmlSvg.append("    } else {\n");
-      htmlSvg.append("      fillFaceboxFromAjax(href, klass)\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  function fillFaceboxFromImage(href, klass) {\n");
-      htmlSvg.append("    var image = new Image()\n");
-      htmlSvg.append("    image.onload = function() {\n");
-      htmlSvg.append("      $.facebox.reveal('<div class=\"image\"><img src=\"' + image.src + '\" /></div>', klass)\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("    image.src = href\n");
-      htmlSvg.append("   }\n");
-
-      htmlSvg.append("  function fillFaceboxFromAjax(href, klass) {\n");
-      htmlSvg.append("    $.facebox.jqxhr = $.get(href, function(data) { $.facebox.reveal(data, klass) })\n");
-      htmlSvg.append("  }\n");
+      // JQuery FaceBox for displaying raw BioJSON data");
+      File faceBoxJsFile = new File("examples/javascript/facebox-1.3.js");
+      try
+      {
+        htmlSvg.append(HTMLOutput.readFileAsString(faceBoxJsFile));
+      } catch (IOException e)
+      {
+        e.printStackTrace();
+      }
+    }
 
-      htmlSvg.append("  function skipOverlay() {\n");
-      htmlSvg.append("    return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null\n");
-      htmlSvg.append("  }\n");
+    htmlSvg.append("</script>\n");
+    htmlSvg.append("</html>");
+    return htmlSvg.toString();
+  }
 
-      htmlSvg.append("  function showOverlay() {\n");
-      htmlSvg.append("    if (skipOverlay()) return\n");
+  @Override
+  public boolean isEmbedData()
+  {
+    return Boolean.valueOf(jalview.bin.Cache.getDefault(
+            "EXPORT_EMBBED_BIOJSON", "true"));
+  }
 
-      htmlSvg.append("    if ($('#facebox_overlay').length == 0)\n");
-      htmlSvg.append("      $(\"body\").append('<div id=\"facebox_overlay\" class=\"facebox_hide\"></div>')\n");
+  @Override
+  public boolean isLaunchInBrowserAfterExport()
+  {
+    return true;
+  }
 
-      htmlSvg.append("    $('#facebox_overlay').hide().addClass(\"facebox_overlayBG\")\n");
-      htmlSvg.append("      .css('opacity', $.facebox.settings.opacity)\n");
-      htmlSvg.append("      .click(function() { $(document).trigger('close.facebox') })\n");
-      htmlSvg.append("       .fadeIn(200)\n");
-      htmlSvg.append("    return false\n");
-      htmlSvg.append("  }\n");
+  @Override
+  public File getExportedFile()
+  {
+    return generatedFile;
+  }
 
-      htmlSvg.append("  function hideOverlay() {\n");
-      htmlSvg.append("    if (skipOverlay()) return      \n");
-      htmlSvg.append("    $('#facebox_overlay').fadeOut(200, function(){\n");
-      htmlSvg.append("      $(\"#facebox_overlay\").removeClass(\"facebox_overlayBG\")\n");
-      htmlSvg.append("      $(\"#facebox_overlay\").addClass(\"facebox_hide\")\n");
-      htmlSvg.append("      $(\"#facebox_overlay\").remove()\n");
-      htmlSvg.append("    })      \n");
-      htmlSvg.append("    return false\n");
-      htmlSvg.append("  }\n");
+  @Override
+  public void run()
+  {
+    try
+    {
+      setProgressMessage(null);
+      setProgressMessage(MessageManager.formatMessage(
+              "status.exporting_alignment_as_x_file", "HTML"));
+      AlignmentDimension aDimension = ap.getAlignmentDimension();
+      SVGGraphics2D idPanelGraphics = new SVGGraphics2D(
+              aDimension.getWidth(), aDimension.getHeight());
+      SVGGraphics2D alignPanelGraphics = new SVGGraphics2D(
+              aDimension.getWidth(), aDimension.getHeight());
+
+      String renderStyle = jalview.bin.Cache.getDefault("HTML_RENDERING",
+              "Prompt each time");
+
+      // If we need to prompt, and if the GUI is visible then
+      // Prompt for rendering style
+      if (renderStyle.equalsIgnoreCase("Prompt each time") && !isHeadless())
+      {
+        HTMLOptions svgOption = new HTMLOptions();
+        renderStyle = svgOption.getValue();
 
-      htmlSvg.append("  $(document).bind('close.facebox', function() {\n");
-      htmlSvg.append("    if ($.facebox.jqxhr) {\n");
-      htmlSvg.append("      $.facebox.jqxhr.abort()\n");
-      htmlSvg.append("      $.facebox.jqxhr = null\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("    $(document).unbind('keydown.facebox')\n");
-      htmlSvg.append("    $('#facebox').fadeOut(function() {\n");
-      htmlSvg.append("      $('#facebox .content').removeClass().addClass('content')\n");
-      htmlSvg.append("      $('#facebox .loading').remove()\n");
-      htmlSvg.append("      $(document).trigger('afterClose.facebox')\n");
-      htmlSvg.append("    })\n");
-      htmlSvg.append("    hideOverlay()\n");
-      htmlSvg.append("  })\n");
+        if (renderStyle == null || svgOption.cancelled)
+        {
+          setProgressMessage(MessageManager.formatMessage(
+                  "status.cancelled_image_export_operation", "HTML"));
+          return;
+        }
+      }
 
-      htmlSvg.append("})(jQuery);\n");
+      if (renderStyle.equalsIgnoreCase("Lineart"))
+      {
+        idPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
+                SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
+        alignPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
+                SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
+      }
+      if (ap.av.getWrapAlignment())
+      {
+        printWrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
+                alignPanelGraphics);
+      }
+      else
+      {
+        printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
+                idPanelGraphics, alignPanelGraphics);
+      }
 
+      String idPanelSvgData = idPanelGraphics.getSVGDocument();
+      String alignPanelSvgData = alignPanelGraphics.getSVGDocument();
+      String jsonData = getBioJSONData();
+      String htmlData = getHtml(idPanelSvgData, alignPanelSvgData,
+              jsonData, ap.av.getWrapAlignment());
+      FileOutputStream out = new FileOutputStream(generatedFile);
+      out.write(htmlData.getBytes());
+      out.flush();
+      out.close();
+      setProgressMessage(MessageManager.formatMessage(
+              "status.export_complete", "HTML"));
+      exportCompleted();
+    } catch (OutOfMemoryError err)
+    {
+      System.out.println("########################\n" + "OUT OF MEMORY "
+              + generatedFile + "\n" + "########################");
+      new OOMWarning("Creating Image for " + generatedFile, err);
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+      setProgressMessage(MessageManager.formatMessage(
+              "info.error_creating_file", "HTML"));
     }
-
-    htmlSvg.append("</script>\n");
-    htmlSvg.append("</html>");
-    return htmlSvg.toString();
   }
 }
index deae9ae..72a1155 100755 (executable)
@@ -30,8 +30,6 @@ import java.io.IOException;
  */
 public class IdentifyFile
 {
-  public static final String FeaturesFile = "GFF or Jalview features";
-
   /**
    * Identify a datasource's file content.
    *
@@ -39,18 +37,18 @@ public class IdentifyFile
    *       instead.
    *
    * @param file
-   *          DOCUMENT ME!
-   * @param protocol
-   *          DOCUMENT ME!
-   * @return ID String
+   * @param sourceType
+   * @return
+   * @throws FileFormatException
    */
-  public String identify(String file, String protocol)
+  public FileFormatI identify(String file, DataSourceType sourceType)
+          throws FileFormatException
   {
     String emessage = "UNIDENTIFIED FILE PARSING ERROR";
     FileParse parser = null;
     try
     {
-      parser = new FileParse(file, protocol);
+      parser = new FileParse(file, sourceType);
       if (parser.isValid())
       {
         return identify(parser);
@@ -63,15 +61,22 @@ public class IdentifyFile
     }
     if (parser != null)
     {
-      return parser.errormessage;
+      throw new FileFormatException(parser.errormessage);
     }
-    return emessage;
+    throw new FileFormatException(emessage);
+  }
+
+  public FileFormatI identify(FileParse source) throws FileFormatException
+  {
+    return identify(source, true);
+    // preserves original behaviour prior to version 2.3
   }
 
-  public String identify(FileParse source)
+  public FileFormatI identify(AlignmentFileI file, boolean closeSource)
+          throws IOException
   {
-    return identify(source, true); // preserves original behaviour prior to
-    // version 2.3
+    FileParse fp = new FileParse(file.getInFile(), file.getDataSourceType());
+    return identify(fp, closeSource);
   }
 
   /**
@@ -80,11 +85,13 @@ public class IdentifyFile
    *
    * @param source
    * @param closeSource
-   * @return filetype string
+   * @return (best guess at) file format
+   * @throws FileFormatException
    */
-  public String identify(FileParse source, boolean closeSource)
+  public FileFormatI identify(FileParse source, boolean closeSource)
+          throws FileFormatException
   {
-    String reply = "PFAM";
+    FileFormatI reply = FileFormat.Pfam;
     String data;
     int bytesRead = 0;
     int trimmedLength = 0;
@@ -123,12 +130,12 @@ public class IdentifyFile
             if (fileStr.lastIndexOf(".jar") > -1
                     || fileStr.lastIndexOf(".zip") > -1)
             {
-              reply = "Jalview";
+              reply = FileFormat.Jalview;
             }
           }
           if (!lineswereskipped && data.startsWith("PK"))
           {
-            reply = "Jalview"; // archive.
+            reply = FileFormat.Jalview; // archive.
             break;
           }
         }
@@ -137,24 +144,24 @@ public class IdentifyFile
         if (data.startsWith("##GFF-VERSION"))
         {
           // GFF - possibly embedded in a Jalview features file!
-          reply = FeaturesFile;
+          reply = FileFormat.Features;
           break;
         }
         if (looksLikeFeatureData(data))
         {
-          reply = FeaturesFile;
+          reply = FileFormat.Features;
           break;
         }
         if (data.indexOf("# STOCKHOLM") > -1)
         {
-          reply = "STH";
+          reply = FileFormat.Stockholm;
           break;
         }
         if (data.indexOf("_ENTRY.ID") > -1
                 || data.indexOf("_AUDIT_AUTHOR.NAME") > -1
                 || data.indexOf("_ATOM_SITE.") > -1)
         {
-          reply = "mmCIF";
+          reply = FileFormat.MMCif;
           break;
         }
         // if (data.indexOf(">") > -1)
@@ -166,14 +173,14 @@ public class IdentifyFile
           {
             // watch for PIR file attributes
             checkPIR = true;
-            reply = "PIR";
+            reply = FileFormat.PIR;
           }
           // could also be BLC file, read next line to confirm
           data = source.nextLine();
 
           if (data.indexOf(">") > -1)
           {
-            reply = "BLC";
+            reply = FileFormat.BLC;
           }
           else
           {
@@ -190,18 +197,19 @@ public class IdentifyFile
             {
               if (c1 == 0 && c1 == data2.indexOf("*"))
               {
-                reply = "BLC";
+                reply = FileFormat.BLC;
               }
               else
               {
-                reply = "FASTA"; // possibly a bad choice - may be recognised as
+                reply = FileFormat.Fasta; // possibly a bad choice - may be
+                                          // recognised as
                 // PIR
               }
               // otherwise can still possibly be a PIR file
             }
             else
             {
-              reply = "FASTA";
+              reply = FileFormat.Fasta;
               // TODO : AMSA File is indicated if there is annotation in the
               // FASTA file - but FASTA will automatically generate this at the
               // mo.
@@ -238,12 +246,12 @@ public class IdentifyFile
             }
             if (starterm)
             {
-              reply = "PIR";
+              reply = FileFormat.PIR;
               break;
             }
             else
             {
-              reply = "FASTA"; // probably a bad choice!
+              reply = FileFormat.Fasta; // probably a bad choice!
             }
           }
           // read as a FASTA (probably)
@@ -256,19 +264,19 @@ public class IdentifyFile
           String upper = data.toUpperCase();
           if (upper.substring(lessThan).startsWith("<HTML"))
           {
-            reply = HtmlFile.FILE_DESC;
+            reply = FileFormat.Html;
             break;
           }
           if (upper.substring(lessThan).startsWith("<RNAML"))
           {
-            reply = "RNAML";
+            reply = FileFormat.Rnaml;
             break;
           }
         }
 
         if (data.indexOf("{\"") > -1)
         {
-          reply = JSONFile.FILE_DESC;
+          reply = FileFormat.Json;
           break;
         }
         if ((data.length() < 1) || (data.indexOf("#") == 0))
@@ -279,7 +287,7 @@ public class IdentifyFile
 
         if (data.indexOf("PILEUP") > -1)
         {
-          reply = "PileUp";
+          reply = FileFormat.Pileup;
 
           break;
         }
@@ -288,32 +296,32 @@ public class IdentifyFile
                 || ((data.indexOf("!!") > -1) && (data.indexOf("!!") < data
                         .indexOf("_MULTIPLE_ALIGNMENT "))))
         {
-          reply = "MSF";
+          reply = FileFormat.MSF;
 
           break;
         }
         else if (data.indexOf("CLUSTAL") > -1)
         {
-          reply = "CLUSTAL";
+          reply = FileFormat.Clustal;
 
           break;
         }
 
         else if (data.indexOf("HEADER") == 0 || data.indexOf("ATOM") == 0)
         {
-          reply = "PDB";
+          reply = FileFormat.PDB;
           break;
         }
         else if (data.matches("\\s*\\d+\\s+\\d+\\s*"))
         {
-          reply = PhylipFile.FILE_DESC;
+          reply = FileFormat.Phylip;
           break;
         }
         else
         {
           if (!lineswereskipped && looksLikeJnetData(data))
           {
-            reply = "JnetFile";
+            reply = FileFormat.Jnet;
             break;
           }
         }
@@ -332,14 +340,15 @@ public class IdentifyFile
     } catch (Exception ex)
     {
       System.err.println("File Identification failed!\n" + ex);
-      return source.errormessage;
+      throw new FileFormatException(source.errormessage);
     }
     if (trimmedLength == 0)
     {
       System.err
               .println("File Identification failed! - Empty file was read.");
-      return "EMPTY DATA FILE";
+      throw new FileFormatException("EMPTY DATA FILE");
     }
+    System.out.println("File format identified as " + reply.toString());
     return reply;
   }
 
@@ -393,11 +402,19 @@ public class IdentifyFile
 
   public static void main(String[] args)
   {
-
     for (int i = 0; args != null && i < args.length; i++)
     {
       IdentifyFile ider = new IdentifyFile();
-      String type = ider.identify(args[i], AppletFormatAdapter.FILE);
+      FileFormatI type = null;
+      try
+      {
+        type = ider.identify(args[i], DataSourceType.FILE);
+      } catch (FileFormatException e)
+      {
+        System.err.println(String.format(
+                "Error '%s' identifying file type for %s", args[i],
+                e.getMessage()));
+      }
       System.out.println("Type of " + args[i] + " is " + type);
     }
     if (args == null || args.length == 0)
index ddb2ddc..fd971fd 100755 (executable)
@@ -70,15 +70,16 @@ public class JPredFile extends AlignFile
    * 
    * @param inFile
    *          DOCUMENT ME!
-   * @param type
+   * @param sourceType
    *          DOCUMENT ME!
    * 
    * @throws IOException
    *           DOCUMENT ME!
    */
-  public JPredFile(String inFile, String type) throws IOException
+  public JPredFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public JPredFile(FileParse source) throws IOException
@@ -130,6 +131,7 @@ public class JPredFile extends AlignFile
   /**
    * DOCUMENT ME!
    */
+  @Override
   public void initData()
   {
     super.initData();
@@ -141,6 +143,7 @@ public class JPredFile extends AlignFile
   /**
    * parse a JPred concise file into a sequence-alignment like object.
    */
+  @Override
   public void parse() throws IOException
   {
     // JBPNote log.System.out.println("all read in ");
@@ -205,7 +208,7 @@ public class JPredFile extends AlignFile
             ascore = symbols.nextToken();
 
             Float score = new Float(ascore);
-            scores.addElement((Object) score);
+            scores.addElement(score);
           }
 
           Scores.put(id, scores);
@@ -217,15 +220,15 @@ public class JPredFile extends AlignFile
           for (int j = 0; j < i; j++)
           {
             scores.setElementAt(
-                    (Object) ((Float) scores.elementAt(j)).toString(), j);
+                    ((Float) scores.elementAt(j)).toString(), j);
           }
 
-          scores.addElement((Object) ascore);
+          scores.addElement(ascore);
 
           while (symbols.hasMoreTokens())
           {
             ascore = symbols.nextToken();
-            scores.addElement((Object) ascore);
+            scores.addElement(ascore);
           }
 
           Scores.put(id, scores);
@@ -265,7 +268,9 @@ public class JPredFile extends AlignFile
           }
 
           if (QuerySeqPosition == -1)
+          {
             QuerySeqPosition = ids.size();
+          }
           ids.addElement(name);
           noSeqs++;
         }
@@ -278,7 +283,7 @@ public class JPredFile extends AlignFile
 
           seq_entries.addElement(newseq.toString());
           ids.addElement(id);
-          Symscores.put((Object) id, (Object) new Integer(ids.size() - 1));
+          Symscores.put(id, new Integer(ids.size() - 1));
         }
       }
     }
@@ -350,7 +355,8 @@ public class JPredFile extends AlignFile
    * 
    * @return String
    */
-  public String print()
+  @Override
+  public String print(SequenceI[] sqs, boolean jvsuffix)
   {
     return "Not Supported";
   }
@@ -365,13 +371,13 @@ public class JPredFile extends AlignFile
   {
     try
     {
-      JPredFile blc = new JPredFile(args[0], "File");
+      JPredFile jpred = new JPredFile(args[0], DataSourceType.FILE);
 
-      for (int i = 0; i < blc.seqs.size(); i++)
+      for (int i = 0; i < jpred.seqs.size(); i++)
       {
-        System.out.println(((Sequence) blc.seqs.elementAt(i)).getName()
+        System.out.println(((Sequence) jpred.seqs.elementAt(i)).getName()
                 + "\n"
-                + ((Sequence) blc.seqs.elementAt(i)).getSequenceAsString()
+                + ((Sequence) jpred.seqs.elementAt(i)).getSequenceAsString()
                 + "\n");
       }
     } catch (java.io.IOException e)
@@ -402,7 +408,7 @@ public class JPredFile extends AlignFile
     }
     // check that no stray annotations have been added at the end.
     {
-      SequenceI sq = (SequenceI) seqs.elementAt(j - 1);
+      SequenceI sq = seqs.elementAt(j - 1);
       if (sq.getName().toUpperCase().startsWith("JPRED"))
       {
         annotSeqs.addElement(sq);
index 653c071..7a12076 100644 (file)
@@ -71,10 +71,6 @@ public class JSONFile extends AlignFile implements ComplexAlignFile
 
   private String application = "Jalview";
 
-  public static final String FILE_EXT = "json";
-
-  public static final String FILE_DESC = "JSON";
-
   private String globalColourScheme;
 
   private boolean showSeqFeatures;
@@ -105,9 +101,10 @@ public class JSONFile extends AlignFile implements ComplexAlignFile
     super(source);
   }
 
-  public JSONFile(String inFile, String type) throws IOException
+  public JSONFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   @Override
@@ -118,7 +115,7 @@ public class JSONFile extends AlignFile implements ComplexAlignFile
   }
 
   @Override
-  public String print()
+  public String print(SequenceI[] sqs, boolean jvsuffix)
   {
     String jsonOutput = null;
     try
@@ -171,7 +168,7 @@ public class JSONFile extends AlignFile implements ComplexAlignFile
       }
 
       int count = 0;
-      for (SequenceI seq : seqs)
+      for (SequenceI seq : sqs)
       {
         StringBuilder name = new StringBuilder();
         name.append(seq.getName()).append("/").append(seq.getStart())
@@ -228,7 +225,7 @@ public class JSONFile extends AlignFile implements ComplexAlignFile
       if (exportSettings.isExportFeatures())
       {
         jsonAlignmentPojo
-                .setSeqFeatures(sequenceFeatureToJsonPojo(seqs, fr));
+                .setSeqFeatures(sequenceFeatureToJsonPojo(sqs, fr));
       }
 
       if (exportSettings.isExportGroups() && seqGroups != null
@@ -318,11 +315,16 @@ public class JSONFile extends AlignFile implements ComplexAlignFile
   }
 
   public List<SequenceFeaturesPojo> sequenceFeatureToJsonPojo(
-          List<SequenceI> seqs, FeatureRenderer fr)
+          SequenceI[] sqs, FeatureRenderer fr)
   {
     displayedFeatures = (fr == null) ? null : fr.getFeaturesDisplayed();
     List<SequenceFeaturesPojo> sequenceFeaturesPojo = new ArrayList<SequenceFeaturesPojo>();
-    for (SequenceI seq : seqs)
+    if (sqs == null)
+    {
+      return sequenceFeaturesPojo;
+    }
+
+    for (SequenceI seq : sqs)
     {
       SequenceI dataSetSequence = seq.getDatasetSequence();
       SequenceFeature[] seqFeatures = (dataSetSequence == null) ? null
index 1ea6795..7ccdaa9 100755 (executable)
@@ -21,6 +21,7 @@
 //////////////////////////////////////////////////////////////////
 package jalview.io;
 
+import jalview.gui.JvOptionPane;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 
@@ -31,16 +32,18 @@ import java.awt.HeadlessException;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
 import javax.swing.DefaultListCellRenderer;
 import javax.swing.JFileChooser;
 import javax.swing.JList;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.SpringLayout;
+import javax.swing.plaf.basic.BasicFileChooserUI;
 
 /**
  * Enhanced file chooser dialog box.
@@ -53,12 +56,106 @@ import javax.swing.SpringLayout;
  */
 public class JalviewFileChooser extends JFileChooser
 {
+  /**
+   * Factory method to return a file chooser that offers readable alignment file
+   * formats
+   * 
+   * @param directory
+   * @param selected
+   * @return
+   */
+  public static JalviewFileChooser forRead(String directory, String selected)
+  {
+    List<String> extensions = new ArrayList<String>();
+    List<String> descs = new ArrayList<String>();
+    for (FileFormatI format : FileFormat.values())
+    {
+      if (format.isReadable())
+      {
+        extensions.add(format.getExtensions());
+        descs.add(format.toString());
+      }
+    }
+    return new JalviewFileChooser(directory,
+            extensions.toArray(new String[extensions.size()]),
+            descs.toArray(new String[descs.size()]), selected, true);
+  }
+
+  /**
+   * Factory method to return a file chooser that offers writable alignment file
+   * formats
+   * 
+   * @param directory
+   * @param selected
+   * @return
+   */
+  public static JalviewFileChooser forWrite(String directory,
+          String selected)
+  {
+    // TODO in Java 8, forRead and forWrite can be a single method
+    // with a lambda expression parameter for isReadable/isWritable
+    List<String> extensions = new ArrayList<String>();
+    List<String> descs = new ArrayList<String>();
+    for (FileFormatI format : FileFormat.values())
+    {
+      if (format.isWritable())
+      {
+        extensions.add(format.getExtensions());
+        descs.add(format.toString());
+      }
+    }
+    return new JalviewFileChooser(directory,
+            extensions.toArray(new String[extensions.size()]),
+            descs.toArray(new String[descs.size()]), selected, false);
+  }
+
   public JalviewFileChooser(String dir)
   {
     super(safePath(dir));
     setAccessory(new RecentlyOpened());
   }
 
+  public JalviewFileChooser(String dir, String[] suffix, String[] desc,
+          String selected)
+  {
+    this(dir, suffix, desc, selected, true);
+  }
+
+  /**
+   * Constructor for a single choice of file extension and description
+   * 
+   * @param dir
+   * @param extension
+   * @param desc
+   */
+  public JalviewFileChooser(String dir, String extension, String desc)
+  {
+    // TODO inline dir as Cache.getProperty("LAST_DIRECTORY") ? if applet
+    // builds ok
+    this(dir, new String[] { extension }, new String[] { desc }, desc,
+            true);
+  }
+
+  JalviewFileChooser(String dir, String[] extensions, String[] descs,
+          String selected, boolean allFiles)
+  {
+    super(safePath(dir));
+    if (extensions.length == descs.length)
+    {
+      List<String[]> formats = new ArrayList<String[]>();
+      for (int i = 0; i < extensions.length; i++)
+      {
+        formats.add(new String[] { extensions[i], descs[i] });
+      }
+      init(formats, selected, allFiles);
+    }
+    else
+    {
+      System.err.println("JalviewFileChooser arguments mismatch: "
+              + extensions + ", " + descs);
+    }
+  }
+
   private static File safePath(String dir)
   {
     if (dir == null)
@@ -74,35 +171,28 @@ public class JalviewFileChooser extends JFileChooser
     return f;
   }
 
-  public JalviewFileChooser(String dir, String[] suffix, String[] desc,
-          String selected, boolean selectAll)
-  {
-    super(safePath(dir));
-    init(suffix, desc, selected, selectAll);
-  }
-
-  public JalviewFileChooser(String dir, String[] suffix, String[] desc,
-          String selected)
-  {
-    super(safePath(dir));
-    init(suffix, desc, selected, true);
-  }
-
-  void init(String[] suffix, String[] desc, String selected,
-          boolean selectAll)
+  /**
+   * 
+   * @param formats
+   *          a list of {extensions, description} for each file format
+   * @param selected
+   * @param allFiles
+   *          if true, 'any format' option is included
+   */
+  void init(List<String[]> formats, String selected, boolean allFiles)
   {
 
     JalviewFileFilter chosen = null;
 
     // SelectAllFilter needs to be set first before adding further
     // file filters to fix bug on Mac OSX
-    setAcceptAllFileFilterUsed(selectAll);
+    setAcceptAllFileFilterUsed(allFiles);
 
-    for (int i = 0; i < suffix.length; i++)
+    for (String[] format : formats)
     {
-      JalviewFileFilter jvf = new JalviewFileFilter(suffix[i], desc[i]);
+      JalviewFileFilter jvf = new JalviewFileFilter(format[0], format[1]);
       addChoosableFileFilter(jvf);
-      if ((selected != null) && selected.equalsIgnoreCase(desc[i]))
+      if ((selected != null) && selected.equalsIgnoreCase(format[1]))
       {
         chosen = jvf;
       }
@@ -123,10 +213,10 @@ public class JalviewFileChooser extends JFileChooser
 
     try
     {
-      if (getUI() instanceof javax.swing.plaf.basic.BasicFileChooserUI)
+      if (getUI() instanceof BasicFileChooserUI)
       {
-        final javax.swing.plaf.basic.BasicFileChooserUI ui = (javax.swing.plaf.basic.BasicFileChooserUI) getUI();
-        final String name = ui.getFileName().trim();
+        final BasicFileChooserUI fcui = (BasicFileChooserUI) getUI();
+        final String name = fcui.getFileName().trim();
 
         if ((name == null) || (name.length() == 0))
         {
@@ -138,10 +228,10 @@ public class JalviewFileChooser extends JFileChooser
           @Override
           public void run()
           {
-            String currentName = ui.getFileName();
+            String currentName = fcui.getFileName();
             if ((currentName == null) || (currentName.length() == 0))
             {
-              ui.setFileName(name);
+              fcui.setFileName(name);
             }
           }
         });
@@ -153,49 +243,39 @@ public class JalviewFileChooser extends JFileChooser
     }
   }
 
-  public String getSelectedFormat()
+  /**
+   * Returns the selected file format, or null if none selected
+   * 
+   * @return
+   */
+  public FileFormatI getSelectedFormat()
   {
     if (getFileFilter() == null)
     {
       return null;
     }
 
+    /*
+     * logic here depends on option description being formatted as 
+     * formatName (extension, extension...)
+     * or the 'no option selected' value
+     * All Files
+     * @see JalviewFileFilter.getDescription
+     */
     String format = getFileFilter().getDescription();
-
-    if (format.toUpperCase().startsWith("JALVIEW"))
-    {
-      format = "Jalview";
-    }
-    else if (format.toUpperCase().startsWith("FASTA"))
+    int parenPos = format.indexOf("(");
+    if (parenPos > 0)
     {
-      format = "FASTA";
-    }
-    else if (format.toUpperCase().startsWith("MSF"))
-    {
-      format = "MSF";
-    }
-    else if (format.toUpperCase().startsWith("CLUSTAL"))
-    {
-      format = "CLUSTAL";
-    }
-    else if (format.toUpperCase().startsWith("BLC"))
-    {
-      format = "BLC";
-    }
-    else if (format.toUpperCase().startsWith("PIR"))
-    {
-      format = "PIR";
-    }
-    else if (format.toUpperCase().startsWith("PFAM"))
-    {
-      format = "PFAM";
-    }
-    else if (format.toUpperCase().startsWith(PhylipFile.FILE_DESC))
-    {
-      format = PhylipFile.FILE_DESC;
+      format = format.substring(0, parenPos).trim();
+      try
+      {
+        return FileFormat.valueOf(format);
+      } catch (IllegalArgumentException e)
+      {
+        System.err.println("Unexpected format: " + format);
+      }
     }
-
-    return format;
+    return null;
   }
 
   @Override
@@ -223,12 +303,12 @@ public class JalviewFileChooser extends JFileChooser
     if ((ret == JalviewFileChooser.APPROVE_OPTION)
             && getSelectedFile().exists())
     {
-      int confirm = JOptionPane.showConfirmDialog(parent,
+      int confirm = JvOptionPane.showConfirmDialog(parent,
               MessageManager.getString("label.overwrite_existing_file"),
               MessageManager.getString("label.file_already_exists"),
-              JOptionPane.YES_NO_OPTION);
+              JvOptionPane.YES_NO_OPTION);
 
-      if (confirm != JOptionPane.YES_OPTION)
+      if (confirm != JvOptionPane.YES_OPTION)
       {
         ret = JalviewFileChooser.CANCEL_OPTION;
       }
index 4cef26d..3461110 100755 (executable)
@@ -21,7 +21,9 @@
 package jalview.io;
 
 import java.io.File;
-import java.util.Hashtable;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.swing.Icon;
 import javax.swing.ImageIcon;
@@ -29,64 +31,70 @@ import javax.swing.filechooser.FileView;
 
 public class JalviewFileView extends FileView
 {
-  static Hashtable alignSuffix = new Hashtable();
+  private static Map<String, String> extensions;
 
-  static
+  private static Map<String, ImageIcon> icons;
+
+  private void loadExtensions()
   {
-    // TODO: these names should come from the FormatAdapter lists for
-    // readable/writable extensions
-    alignSuffix.put("amsa", "AMSA file");
-    alignSuffix.put("fasta", "Fasta file");
-    alignSuffix.put("fa", "Fasta file");
-    alignSuffix.put("fastq", "Fasta file");
-    alignSuffix.put("mfa", "Fasta file");
-    alignSuffix.put("blc", "BLC file");
-    alignSuffix.put("msf", "MSF file");
-    alignSuffix.put("pfam", "PFAM file");
-    alignSuffix.put("aln", "Clustal file");
-    alignSuffix.put("pir", "PIR file");
-    alignSuffix.put("jar", "Jalview Project file (old)");
-    alignSuffix.put("jvp", "Jalview Project file");
-    alignSuffix.put("amsa", "AMSA file");
-    alignSuffix.put("sto", "Stockholm File");
-    alignSuffix.put("stk", "Stockholm File");
-    alignSuffix.put("sto", "Stockholm File");
+    extensions = new HashMap<String, String>();
+    for (FileFormatI ff : FileFormat.values())
+    {
+      String desc = ff.toString() + " file";
+      String exts = ff.getExtensions();
+      for (String ext : exts.split(","))
+      {
+        extensions.put(ext.trim().toLowerCase(), desc
+                + ("jar".equals(ext) ? " (old)" : ""));
+      }
+    }
   }
 
+  @Override
   public String getTypeDescription(File f)
   {
     String extension = getExtension(f);
-    String type = null;
-
+    String type = getDescriptionForExtension(extension);
     if (extension != null)
     {
-      if (alignSuffix.containsKey(extension))
+      if (extensions.containsKey(extension))
       {
-        type = alignSuffix.get(extension).toString();
+        type = extensions.get(extension).toString();
       }
     }
 
     return type;
   }
 
+  private String getDescriptionForExtension(String extension)
+  {
+    synchronized (this)
+    {
+      if (extensions == null)
+      {
+        loadExtensions();
+      }
+    }
+    return extensions.get(extension);
+  }
+
+  @Override
   public Icon getIcon(File f)
   {
     String extension = getExtension(f);
     Icon icon = null;
 
-    if (extension != null)
+    if (getDescriptionForExtension(extension) != null)
     {
-      if (alignSuffix.containsKey(extension))
-      {
-        icon = createImageIcon("/images/file.png");
-      }
+      icon = getImageIcon("/images/file.png");
     }
 
     return icon;
   }
 
-  /*
-   * Get the extension of a file.
+  /**
+   * Returns the extension of a file (part of the name after the last period),
+   * in lower case, or null if the name ends in or does not include a period.
    */
   public static String getExtension(File f)
   {
@@ -102,22 +110,44 @@ public class JalviewFileView extends FileView
     return ext;
   }
 
-  /** Returns an ImageIcon, or null if the path was invalid. */
-  protected static ImageIcon createImageIcon(String path)
+  /**
+   * Returns an ImageIcon, or null if the file was not found
+   * 
+   * @param filePath
+   */
+  protected ImageIcon getImageIcon(String filePath)
   {
-    java.net.URL imgURL = JalviewFileView.class.getResource(path);
-
-    if (imgURL != null)
+    /*
+     * we reuse a single icon object per path here
+     */
+    synchronized (this)
     {
-      return new ImageIcon(imgURL);
+      if (icons == null)
+      {
+        icons = new HashMap<String, ImageIcon>();
+      }
+      if (!icons.containsKey(filePath))
+      {
+        ImageIcon icon = null;
+        URL imgURL = JalviewFileView.class.getResource(filePath);
+        if (imgURL != null)
+        {
+          icon = new ImageIcon(imgURL);
+        }
+        else
+        {
+          System.err
+                  .println("JalviewFileView.createImageIcon: Couldn't find file: "
+                          + filePath);
+        }
+        icons.put(filePath, icon);
+      }
     }
-    else
-    {
-      System.err
-              .println("JalviewFileView.createImageIcon: Couldn't find file: "
-                      + path);
 
-      return null;
-    }
+    /*
+     * return the image from the table (which may be null if
+     * icon creation failed)
+     */
+    return icons.get(filePath);
   }
 }
index d5593e3..3feae5d 100755 (executable)
@@ -192,13 +192,13 @@ public class JnetAnnotationMaker
           if (id.equals("JNETCONF"))
           {
             annot = new AlignmentAnnotation(preds[i].getName(),
-                    "JNet Output", annotations, 0f, 10f,
+                    "JPred Output", annotations, 0f, 10f,
                     AlignmentAnnotation.BAR_GRAPH);
           }
           else
           {
             annot = new AlignmentAnnotation(preds[i].getName(),
-                    "JNet Output", annotations);
+                    "JPred Output", annotations);
           }
 
           if (seqRef != null)
index 7e46978..f379724 100755 (executable)
@@ -58,7 +58,7 @@ public class MSFfile extends AlignFile
    * @throws IOException
    *           DOCUMENT ME!
    */
-  public MSFfile(String inFile, String type) throws IOException
+  public MSFfile(String inFile, DataSourceType type) throws IOException
   {
     super(inFile, type);
   }
@@ -216,7 +216,8 @@ public class MSFfile extends AlignFile
    * 
    * @return DOCUMENT ME!
    */
-  public String print(SequenceI[] sqs)
+  @Override
+  public String print(SequenceI[] sqs, boolean jvSuffix)
   {
 
     boolean is_NA = Comparison.isNucleotide(sqs);
@@ -307,7 +308,7 @@ public class MSFfile extends AlignFile
     while ((i < s.length) && (s[i] != null))
     {
 
-      nameBlock[i] = new String("  Name: " + printId(s[i]) + " ");
+      nameBlock[i] = new String("  Name: " + printId(s[i], jvSuffix) + " ");
 
       idBlock[i] = new String("Len: "
               + maxLenpad.form(s[i].getSequence().length) + "  Check: "
@@ -359,7 +360,7 @@ public class MSFfile extends AlignFile
 
       while ((j < s.length) && (s[j] != null))
       {
-        String name = printId(s[j]);
+        String name = printId(s[j], jvSuffix);
 
         out.append(new Format("%-" + maxid + "s").form(name + " "));
 
@@ -407,15 +408,4 @@ public class MSFfile extends AlignFile
 
     return out.toString();
   }
-
-  /**
-   * DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
-   */
-  @Override
-  public String print()
-  {
-    return print(getSeqsAsArray());
-  }
 }
index ab3c37c..765ea95 100755 (executable)
@@ -110,7 +110,7 @@ public class NewickFile extends FileParse
    */
   public NewickFile(String inStr) throws IOException
   {
-    super(inStr, "Paste");
+    super(inStr, DataSourceType.PASTE);
   }
 
   /**
@@ -118,15 +118,16 @@ public class NewickFile extends FileParse
    * 
    * @param inFile
    *          DOCUMENT ME!
-   * @param type
+   * @param protocol
    *          DOCUMENT ME!
    * 
    * @throws IOException
    *           DOCUMENT ME!
    */
-  public NewickFile(String inFile, String type) throws IOException
+  public NewickFile(String inFile, DataSourceType protocol)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, protocol);
   }
 
   public NewickFile(FileParse source) throws IOException
@@ -966,7 +967,7 @@ public class NewickFile extends FileParse
       treefile.close();
       System.out.println("Read file :\n");
 
-      NewickFile trf = new NewickFile(args[0], "File");
+      NewickFile trf = new NewickFile(args[0], DataSourceType.FILE);
       trf.parse();
       System.out.println("Original file :\n");
 
index 5f5c23c..d9ed516 100755 (executable)
@@ -22,6 +22,7 @@ package jalview.io;
 
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
 
 import java.io.IOException;
 import java.util.Vector;
@@ -36,9 +37,10 @@ public class PIRFile extends AlignFile
   {
   }
 
-  public PIRFile(String inFile, String type) throws IOException
+  public PIRFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public PIRFile(FileParse source) throws IOException
@@ -102,14 +104,9 @@ public class PIRFile extends AlignFile
   }
 
   @Override
-  public String print()
+  public String print(SequenceI[] s, boolean jvsuffix)
   {
-    return print(getSeqsAsArray());
-  }
-
-  public String print(SequenceI[] s)
-  {
-    boolean is_NA = jalview.util.Comparison.isNucleotide(s);
+    boolean is_NA = Comparison.isNucleotide(s);
     int len = 72;
     StringBuffer out = new StringBuffer();
     int i = 0;
@@ -161,7 +158,7 @@ public class PIRFile extends AlignFile
         }
         else
         {
-          out.append(">P1;" + printId(s[i]));
+          out.append(">P1;" + printId(s[i], jvsuffix));
           out.append(newline);
           if (s[i].getDescription() != null)
           {
index e71bb4b..bc22fae 100755 (executable)
@@ -36,9 +36,10 @@ public class PfamFile extends AlignFile
   {
   }
 
-  public PfamFile(String inFile, String type) throws IOException
+  public PfamFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public PfamFile(FileParse source) throws IOException
@@ -142,7 +143,8 @@ public class PfamFile extends AlignFile
     }
   }
 
-  public String print(SequenceI[] s)
+  @Override
+  public String print(SequenceI[] s, boolean jvsuffix)
   {
     StringBuffer out = new StringBuffer("");
 
@@ -153,7 +155,7 @@ public class PfamFile extends AlignFile
 
     while ((i < s.length) && (s[i] != null))
     {
-      String tmp = printId(s[i]);
+      String tmp = printId(s[i], jvsuffix);
 
       if (s[i].getSequence().length > max)
       {
@@ -177,7 +179,8 @@ public class PfamFile extends AlignFile
 
     while ((j < s.length) && (s[j] != null))
     {
-      out.append(new Format("%-" + maxid + "s").form(printId(s[j]) + " "));
+      out.append(new Format("%-" + maxid + "s")
+              .form(printId(s[j], jvsuffix) + " "));
 
       out.append(s[j].getSequenceAsString());
       out.append(newline);
@@ -188,10 +191,4 @@ public class PfamFile extends AlignFile
 
     return out.toString();
   }
-
-  @Override
-  public String print()
-  {
-    return print(getSeqsAsArray());
-  }
 }
index 8e01c88..e8fe7e9 100644 (file)
@@ -59,9 +59,6 @@ import java.io.IOException;
 public class PhylipFile extends AlignFile
 {
 
-  // Define file extension and description to save repeating it elsewhere
-  public static final String FILE_EXT = "phy";
-
   public static final String FILE_DESC = "PHYLIP";
 
   /**
@@ -85,13 +82,14 @@ public class PhylipFile extends AlignFile
 
   /**
    * @param inFile
-   * @param type
+   * @param sourceType
    * @throws IOException
    * @see {@link AlignFile#AlignFile(FileParse)}
    */
-  public PhylipFile(String inFile, String type) throws IOException
+  public PhylipFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   /**
@@ -242,15 +240,15 @@ public class PhylipFile extends AlignFile
    * @see {@link AlignFile#print()}
    */
   @Override
-  public String print()
+  public String print(SequenceI[] sqs, boolean jvsuffix)
   {
 
-    StringBuffer sb = new StringBuffer(Integer.toString(seqs.size()));
+    StringBuffer sb = new StringBuffer(Integer.toString(sqs.length));
     sb.append(" ");
     // if there are no sequences, then define the number of characters as 0
     sb.append(
-            (seqs.size() > 0) ? Integer
-                    .toString(seqs.get(0).getSequence().length) : "0")
+            (sqs.length > 0) ? Integer.toString(sqs[0].getSequence().length)
+                    : "0")
             .append(newline);
 
     // Due to how IO is handled, there doesn't appear to be a way to store
@@ -262,7 +260,7 @@ public class PhylipFile extends AlignFile
     int numInterleavedColumns = 60;
 
     int sequenceLength = 0;
-    for (SequenceI s : seqs)
+    for (SequenceI s : sqs)
     {
 
       // ensure name is only 10 characters
@@ -313,7 +311,7 @@ public class PhylipFile extends AlignFile
         // add blank line to separate this matrix from previous
         sb.append(newline);
         int start = i * numInterleavedColumns;
-        for (SequenceI s : seqs)
+        for (SequenceI s : sqs)
         {
           sb.append(
                   s.getSequence(start, Math.min(start
index 79c6531..84be72c 100755 (executable)
@@ -55,15 +55,16 @@ public class PileUpfile extends MSFfile
    * 
    * @param inFile
    *          DOCUMENT ME!
-   * @param type
+   * @param sourceType
    *          DOCUMENT ME!
    * 
    * @throws IOException
    *           DOCUMENT ME!
    */
-  public PileUpfile(String inFile, String type) throws IOException
+  public PileUpfile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public PileUpfile(FileParse source) throws IOException
@@ -71,19 +72,8 @@ public class PileUpfile extends MSFfile
     super(source);
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
-   */
-  @Override
-  public String print()
-  {
-    return print(getSeqsAsArray());
-  }
-
   @Override
-  public String print(SequenceI[] s)
+  public String print(SequenceI[] s, boolean jvsuffix)
   {
     StringBuffer out = new StringBuffer("PileUp");
     out.append(newline);
@@ -112,7 +102,8 @@ public class PileUpfile extends MSFfile
     while ((i < s.length) && (s[i] != null))
     {
       String seq = s[i].getSequenceAsString();
-      out.append(" Name: " + printId(s[i]) + " oo  Len:  " + seq.length()
+      out.append(" Name: " + printId(s[i], jvsuffix) + " oo  Len:  "
+              + seq.length()
               + "  Check:  " + checksums[i] + "  Weight:  1.00");
       out.append(newline);
 
@@ -151,7 +142,7 @@ public class PileUpfile extends MSFfile
 
       while ((j < s.length) && (s[j] != null))
       {
-        String name = printId(s[j]);
+        String name = printId(s[j], jvsuffix);
 
         out.append(new Format("%-" + maxid + "s").form(name + " "));
 
index f48f825..eb623d3 100644 (file)
@@ -54,7 +54,7 @@ public class RnamlFile extends AlignFile
 
   }
 
-  public RnamlFile(String inFile, String type) throws IOException
+  public RnamlFile(String inFile, DataSourceType type) throws IOException
   {
     super(inFile, type);
 
@@ -195,16 +195,10 @@ public class RnamlFile extends AlignFile
     setSeqs(sqs);
   }
 
-  public static String print(SequenceI[] s)
-  {
-    return "not yet implemented";
-  }
-
   @Override
-  public String print()
+  public String print(SequenceI[] s, boolean jvSuffix)
   {
-    System.out.print("print :");
-    return print(getSeqsAsArray());
+    return "not yet implemented";
   }
 
   public List<RNA> getRNA()
index 07b88bf..6c8f40f 100644 (file)
 package jalview.io;
 
 import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.io.gff.GffConstants;
-import jalview.util.DBRefUtils;
+import jalview.util.MessageManager;
 import jalview.util.UrlLink;
 
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -38,8 +42,69 @@ import java.util.Map;
  */
 public class SequenceAnnotationReport
 {
+  private static final String COMMA = ",";
+
+  private static final String ELLIPSIS = "...";
+
+  private static final int MAX_REFS_PER_SOURCE = 4;
+
+  private static final int MAX_SOURCES = 40;
+
+  private static final String[][] PRIMARY_SOURCES = new String[][] {
+      DBRefSource.CODINGDBS, DBRefSource.DNACODINGDBS,
+      DBRefSource.PROTEINDBS };
+
   final String linkImageURL;
 
+  /*
+   * Comparator to order DBRefEntry by Source + accession id (case-insensitive)
+   */
+  private static Comparator<DBRefEntry> comparator = new Comparator<DBRefEntry>()
+  {
+
+    @Override
+    public int compare(DBRefEntry ref1, DBRefEntry ref2)
+    {
+      String s1 = ref1.getSource();
+      String s2 = ref2.getSource();
+      boolean s1Primary = isPrimarySource(s1);
+      boolean s2Primary = isPrimarySource(s2);
+      if (s1Primary && !s2Primary)
+      {
+        return -1;
+      }
+      if (!s1Primary && s2Primary)
+      {
+        return 1;
+      }
+      int comp = s1 == null ? -1 : (s2 == null ? 1 : s1
+              .compareToIgnoreCase(s2));
+      if (comp == 0)
+      {
+        String a1 = ref1.getAccessionId();
+        String a2 = ref2.getAccessionId();
+        comp = a1 == null ? -1 : (a2 == null ? 1 : a1
+                .compareToIgnoreCase(a2));
+      }
+      return comp;
+    }
+
+    private boolean isPrimarySource(String source)
+    {
+      for (String[] primary : PRIMARY_SOURCES)
+      {
+        for (String s : primary)
+        {
+          if (source.equals(s))
+          {
+            return true;
+          }
+        }
+      }
+      return false;
+    }
+  };
+
   public SequenceAnnotationReport(String linkImageURL)
   {
     this.linkImageURL = linkImageURL;
@@ -48,37 +113,35 @@ public class SequenceAnnotationReport
   /**
    * Append text for the list of features to the tooltip
    * 
-   * @param tooltipText2
+   * @param sb
    * @param rpos
    * @param features
    * @param minmax
    */
-  public void appendFeatures(final StringBuffer tooltipText2, int rpos,
+  public void appendFeatures(final StringBuilder sb, int rpos,
           List<SequenceFeature> features, Map<String, float[][]> minmax)
   {
     if (features != null)
     {
       for (SequenceFeature feature : features)
       {
-        appendFeature(tooltipText2, rpos, minmax, feature);
+        appendFeature(sb, rpos, minmax, feature);
       }
     }
   }
 
   /**
-   * Appends text for one sequence feature to the string buffer
+   * Appends the feature at rpos to the given buffer
    * 
    * @param sb
    * @param rpos
    * @param minmax
-   *          {{min, max}, {min, max}} positional and non-positional feature
-   *          scores for this type
    * @param feature
    */
-  void appendFeature(final StringBuffer sb, int rpos,
+  void appendFeature(final StringBuilder sb, int rpos,
           Map<String, float[][]> minmax, SequenceFeature feature)
   {
-    if ("disulfide bond".equals(feature.getType()))
+    if (feature.isContactFeature())
     {
       if (feature.getBegin() == rpos || feature.getEnd() == rpos)
       {
@@ -86,7 +149,8 @@ public class SequenceAnnotationReport
         {
           sb.append("<br>");
         }
-        sb.append("disulfide bond ").append(feature.getBegin()).append(":")
+        sb.append(feature.getType()).append(" ").append(feature.getBegin())
+                .append(":")
                 .append(feature.getEnd());
       }
     }
@@ -108,7 +172,7 @@ public class SequenceAnnotationReport
         }
         if (feature.begin != feature.end)
         {
-          sb.append(" " + feature.end);
+          sb.append(" ").append(feature.end);
         }
 
         if (feature.getDescription() != null
@@ -116,13 +180,12 @@ public class SequenceAnnotationReport
         {
           String tmpString = feature.getDescription();
           String tmp2up = tmpString.toUpperCase();
-          final int startTag = tmp2up.indexOf("<HTML>");
+          int startTag = tmp2up.indexOf("<HTML>");
           if (startTag > -1)
           {
             tmpString = tmpString.substring(startTag + 6);
             tmp2up = tmp2up.substring(startTag + 6);
           }
-          // TODO strips off </body> but not <body> - is that intended?
           int endTag = tmp2up.indexOf("</BODY>");
           if (endTag > -1)
           {
@@ -147,7 +210,9 @@ public class SequenceAnnotationReport
               // be used, so we must remove < > symbols
               tmpString = tmpString.replaceAll("<", "&lt;");
               tmpString = tmpString.replaceAll(">", "&gt;");
-              sb.append("; ").append(tmpString);
+
+              sb.append("; ");
+              sb.append(tmpString);
             }
             else
             {
@@ -155,11 +220,7 @@ public class SequenceAnnotationReport
             }
           }
         }
-
-        /*
-         * score should be shown if there is one, and min != max
-         * for this feature type (e.g. not all 0)
-         */
+        // check score should be shown
         if (!Float.isNaN(feature.getScore()))
         {
           float[][] rng = (minmax == null) ? null : minmax.get(feature
@@ -182,7 +243,6 @@ public class SequenceAnnotationReport
         }
       }
     }
-    appendLinks(sb, feature);
   }
 
   /**
@@ -206,16 +266,17 @@ public class SequenceAnnotationReport
         {
           try
           {
-            for (String[] urllink : createLinksFrom(null, urlstring))
+            for (List<String> urllink : createLinksFrom(null, urlstring))
             {
               sb.append("<br/> <a href=\""
-                      + urllink[3]
+                      + urllink.get(3)
                       + "\" target=\""
-                      + urllink[0]
+                      + urllink.get(0)
                       + "\">"
-                      + (urllink[0].toLowerCase().equals(
-                              urllink[1].toLowerCase()) ? urllink[0]
-                              : (urllink[0] + ":" + urllink[1]))
+                      + (urllink.get(0).toLowerCase()
+                              .equals(urllink.get(1).toLowerCase()) ? urllink
+                              .get(0) : (urllink.get(0) + ":" + urllink
+                              .get(1)))
                       + "</a></br>");
             }
           } catch (Exception x)
@@ -234,146 +295,60 @@ public class SequenceAnnotationReport
    * 
    * @param seq
    * @param link
-   * @return String[][] { String[] { link target, link label, dynamic component
-   *         inserted (if any), url }}
+   * @return Collection< List<String> > { List<String> { link target, link
+   *         label, dynamic component inserted (if any), url }}
    */
-  String[][] createLinksFrom(SequenceI seq, String link)
+  Collection<List<String>> createLinksFrom(SequenceI seq, String link)
   {
-    List<String[]> urlSets = new ArrayList<String[]>();
-    List<String> uniques = new ArrayList<String>();
+    Map<String, List<String>> urlSets = new LinkedHashMap<String, List<String>>();
     UrlLink urlLink = new UrlLink(link);
     if (!urlLink.isValid())
     {
       System.err.println(urlLink.getInvalidMessage());
       return null;
     }
-    if (seq != null && urlLink.isDynamic())
-    {
-      urlSets.addAll(createDynamicLinks(seq, urlLink, uniques));
-    }
-    else
-    {
-      String target = urlLink.getTarget();
-      String label = urlLink.getLabel();
-      String unq = label + "|" + urlLink.getUrl_prefix();
-      if (!uniques.contains(unq))
-      {
-        uniques.add(unq);
-        urlSets.add(new String[] { target, label, null,
-            urlLink.getUrl_prefix() });
-      }
-    }
 
-    return urlSets.toArray(new String[][] {});
-  }
+    urlLink.createLinksFromSeq(seq, urlSets);
 
-  /**
-   * Formats and returns a list of dynamic href links
-   * 
-   * @param seq
-   * @param urlLink
-   * @param uniques
-   */
-  List<String[]> createDynamicLinks(SequenceI seq, UrlLink urlLink,
-          List<String> uniques)
-  {
-    List<String[]> result = new ArrayList<String[]>();
-    final String target = urlLink.getTarget();
-    final String label = urlLink.getLabel();
-
-    // collect matching db-refs
-    DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
-            new String[] { target });
-    // collect id string too
-    String id = seq.getName();
-    String descr = seq.getDescription();
-    if (descr != null && descr.length() < 1)
-    {
-      descr = null;
-    }
-    if (dbr != null)
-    {
-      for (int r = 0; r < dbr.length; r++)
-      {
-        if (id != null && dbr[r].getAccessionId().equals(id))
-        {
-          // suppress duplicate link creation for the bare sequence ID
-          // string with this link
-          id = null;
-        }
-        // create Bare ID link for this URL
-        String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
-        if (urls != null)
-        {
-          for (int u = 0; u < urls.length; u += 2)
-          {
-            String unq = urls[u] + "|" + urls[u + 1];
-            if (!uniques.contains(unq))
-            {
-              result.add(new String[] { target, label, urls[u], urls[u + 1] });
-              uniques.add(unq);
-            }
-          }
-        }
-      }
-    }
-    if (id != null)
-    {
-      // create Bare ID link for this URL
-      String[] urls = urlLink.makeUrls(id, true);
-      if (urls != null)
-      {
-        for (int u = 0; u < urls.length; u += 2)
-        {
-          String unq = urls[u] + "|" + urls[u + 1];
-          if (!uniques.contains(unq))
-          {
-            result.add(new String[] { target, label, urls[u], urls[u + 1] });
-            uniques.add(unq);
-          }
-        }
-      }
-    }
-    if (descr != null && urlLink.getRegexReplace() != null)
-    {
-      // create link for this URL from description only if regex matches
-      String[] urls = urlLink.makeUrls(descr, true);
-      if (urls != null)
-      {
-        for (int u = 0; u < urls.length; u += 2)
-        {
-          String unq = urls[u] + "|" + urls[u + 1];
-          if (!uniques.contains(unq))
-          {
-            result.add(new String[] { target, label, urls[u], urls[u + 1] });
-            uniques.add(unq);
-          }
-        }
-      }
-    }
-    return result;
+    return urlSets.values();
   }
 
-  public void createSequenceAnnotationReport(final StringBuffer tip,
+  public void createSequenceAnnotationReport(final StringBuilder tip,
           SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
           Map<String, float[][]> minmax)
   {
     createSequenceAnnotationReport(tip, sequence, showDbRefs, showNpFeats,
-            true, minmax);
+            minmax, false);
   }
 
-  public void createSequenceAnnotationReport(final StringBuffer tip,
+  /**
+   * Builds an html formatted report of sequence details and appends it to the
+   * provided buffer.
+   * 
+   * @param sb
+   *          buffer to append report to
+   * @param sequence
+   *          the sequence the report is for
+   * @param showDbRefs
+   *          whether to include database references for the sequence
+   * @param showNpFeats
+   *          whether to include non-positional sequence features
+   * @param minmax
+   * @param summary
+   * @return
+   */
+  int createSequenceAnnotationReport(final StringBuilder sb,
           SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
-          boolean tableWrap, Map<String, float[][]> minmax)
+          Map<String, float[][]> minmax, boolean summary)
   {
     String tmp;
-    tip.append("<i>");
+    sb.append("<i>");
 
     int maxWidth = 0;
     if (sequence.getDescription() != null)
     {
       tmp = sequence.getDescription();
-      tip.append("<br>" + tmp);
+      sb.append("<br>").append(tmp);
       maxWidth = Math.max(maxWidth, tmp.length());
     }
     SequenceI ds = sequence;
@@ -384,16 +359,81 @@ public class SequenceAnnotationReport
     DBRefEntry[] dbrefs = ds.getDBRefs();
     if (showDbRefs && dbrefs != null)
     {
-      for (int i = 0; i < dbrefs.length; i++)
+      // note this sorts the refs held on the sequence!
+      Arrays.sort(dbrefs, comparator);
+      boolean ellipsis = false;
+      String source = null;
+      String lastSource = null;
+      int countForSource = 0;
+      int sourceCount = 0;
+      boolean moreSources = false;
+      int lineLength = 0;
+
+      for (DBRefEntry ref : dbrefs)
+      {
+        source = ref.getSource();
+        if (source == null)
+        {
+          // shouldn't happen
+          continue;
+        }
+        boolean sourceChanged = !source.equals(lastSource);
+        if (sourceChanged)
+        {
+          lineLength = 0;
+          countForSource = 0;
+          sourceCount++;
+        }
+        if (sourceCount > MAX_SOURCES && summary)
+        {
+          ellipsis = true;
+          moreSources = true;
+          break;
+        }
+        lastSource = source;
+        countForSource++;
+        if (countForSource == 1 || !summary)
+        {
+          sb.append("<br>");
+        }
+        if (countForSource <= MAX_REFS_PER_SOURCE || !summary)
+        {
+          String accessionId = ref.getAccessionId();
+          lineLength += accessionId.length() + 1;
+          if (countForSource > 1 && summary)
+          {
+            sb.append(", ").append(accessionId);
+            lineLength++;
+          }
+          else
+          {
+            sb.append(source).append(" ").append(accessionId);
+            lineLength += source.length();
+          }
+          maxWidth = Math.max(maxWidth, lineLength);
+        }
+        if (countForSource == MAX_REFS_PER_SOURCE && summary)
+        {
+          sb.append(COMMA).append(ELLIPSIS);
+          ellipsis = true;
+        }
+      }
+      if (moreSources)
+      {
+        sb.append("<br>").append(ELLIPSIS).append(COMMA).append(source)
+                .append(COMMA).append(ELLIPSIS);
+      }
+      if (ellipsis)
       {
-        tip.append("<br>");
-        tmp = dbrefs[i].getSource() + " " + dbrefs[i].getAccessionId();
-        tip.append(tmp);
-        maxWidth = Math.max(maxWidth, tmp.length());
+        sb.append("<br>(");
+        sb.append(MessageManager.getString("label.output_seq_details"));
+        sb.append(")");
       }
     }
 
-    // ADD NON POSITIONAL SEQUENCE INFO
+    /*
+     * add non-positional features if wanted
+     */
     SequenceFeature[] features = sequence.getSequenceFeatures();
     if (showNpFeats && features != null)
     {
@@ -401,21 +441,29 @@ public class SequenceAnnotationReport
       {
         if (features[i].begin == 0 && features[i].end == 0)
         {
-          int sz = -tip.length();
-          List<SequenceFeature> tfeat = new ArrayList<SequenceFeature>();
-          tfeat.add(features[i]);
-          appendFeatures(tip, 0, tfeat, minmax);
-          sz += tip.length();
+          int sz = -sb.length();
+          appendFeature(sb, 0, minmax, features[i]);
+          sz += sb.length();
           maxWidth = Math.max(maxWidth, sz);
         }
       }
     }
+    sb.append("</i>");
+    return maxWidth;
+  }
+
+  public void createTooltipAnnotationReport(final StringBuilder tip,
+          SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
+          Map<String, float[][]> minmax)
+  {
+    int maxWidth = createSequenceAnnotationReport(tip, sequence,
+            showDbRefs, showNpFeats, minmax, true);
 
-    if (tableWrap && maxWidth > 60)
+    if (maxWidth > 60)
     {
-      tip.insert(0, "<table width=350 border=0><tr><td><i>");
-      tip.append("</i></td></tr></table>");
+      // ? not sure this serves any useful purpose
+      // tip.insert(0, "<table width=350 border=0><tr><td>");
+      // tip.append("</td></tr></table>");
     }
-
   }
 }
index f4dc5a2..1b72545 100644 (file)
@@ -51,9 +51,10 @@ public class SimpleBlastFile extends AlignFile
   {
   }
 
-  public SimpleBlastFile(String inFile, String type) throws IOException
+  public SimpleBlastFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public SimpleBlastFile(FileParse source) throws IOException
@@ -61,6 +62,7 @@ public class SimpleBlastFile extends AlignFile
     super(source);
   }
 
+  @Override
   public void initData()
   {
     super.initData();
@@ -69,6 +71,7 @@ public class SimpleBlastFile extends AlignFile
     seqids = new Vector();
   }
 
+  @Override
   public void parse() throws IOException
   {
     String line;
@@ -286,13 +289,9 @@ public class SimpleBlastFile extends AlignFile
     }
   }
 
-  public String print(SequenceI[] s)
+  @Override
+  public String print(SequenceI[] sqs, boolean jvsuffix)
   {
     return new String("Not Implemented.");
   }
-
-  public String print()
-  {
-    return print(getSeqsAsArray());
-  }
 }
index 27be358..2061f29 100644 (file)
@@ -97,7 +97,8 @@ public class StockholmFile extends AlignFile
     this.al = al;
   }
 
-  public StockholmFile(String inFile, String type) throws IOException
+  public StockholmFile(String inFile, DataSourceType type)
+          throws IOException
   {
     super(inFile, type);
   }
@@ -880,8 +881,13 @@ public class StockholmFile extends AlignFile
     return annot;
   }
 
-  public String print(SequenceI[] s)
+  @Override
+  public String print(SequenceI[] s, boolean jvSuffix)
   {
+    out = new StringBuffer();
+    out.append("# STOCKHOLM 1.0");
+    out.append(newline);
+
     // find max length of id
     int max = 0;
     int maxid = 0;
@@ -889,7 +895,7 @@ public class StockholmFile extends AlignFile
     Hashtable dataRef = null;
     while ((in < s.length) && (s[in] != null))
     {
-      String tmp = printId(s[in]);
+      String tmp = printId(s[in], jvSuffix);
       if (s[in].getSequence().length > max)
       {
         max = s[in].getSequence().length;
@@ -986,7 +992,7 @@ public class StockholmFile extends AlignFile
 
             // out.append("#=GR ");
             out.append(new Format("%-" + maxid + "s").form("#=GR "
-                    + printId(s[i]) + " " + key + " "));
+                    + printId(s[i], jvSuffix) + " " + key + " "));
             ann = alAnot[j].annotations;
             boolean isrna = alAnot[j].isValidStruc();
             String seq = "";
@@ -1000,7 +1006,8 @@ public class StockholmFile extends AlignFile
         }
       }
 
-      out.append(new Format("%-" + maxid + "s").form(printId(s[i]) + " "));
+      out.append(new Format("%-" + maxid + "s")
+              .form(printId(s[i], jvSuffix) + " "));
       out.append(s[i].getSequenceAsString());
       out.append(newline);
       i++;
@@ -1053,6 +1060,10 @@ public class StockholmFile extends AlignFile
         out.append(newline);
       }
     }
+
+    out.append("//");
+    out.append(newline);
+
     return out.toString();
   }
 
@@ -1105,13 +1116,12 @@ public class StockholmFile extends AlignFile
     return seq;
   }
 
-  @Override
   public String print()
   {
     out = new StringBuffer();
     out.append("# STOCKHOLM 1.0");
     out.append(newline);
-    print(getSeqsAsArray());
+    print(getSeqsAsArray(), false);
 
     out.append("//");
     out.append(newline);
index 26c202c..7fe17c8 100644 (file)
@@ -42,7 +42,6 @@ import MCview.PDBChain;
 
 public abstract class StructureFile extends AlignFile
 {
-
   private String id;
 
   private PDBEntry.Type dbRefType;
@@ -69,9 +68,10 @@ public abstract class StructureFile extends AlignFile
 
   private boolean pdbIdAvailable;
 
-  public StructureFile(String inFile, String type) throws IOException
+  public StructureFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public StructureFile(FileParse fp) throws IOException
@@ -99,9 +99,9 @@ public abstract class StructureFile extends AlignFile
   }
 
   public StructureFile(boolean parseImmediately, String dataObject,
-          String type) throws IOException
+          DataSourceType sourceType) throws IOException
   {
-    super(parseImmediately, dataObject, type);
+    super(parseImmediately, dataObject, sourceType);
   }
 
   public StructureFile(boolean a, FileParse fp) throws IOException
@@ -195,7 +195,7 @@ public abstract class StructureFile extends AlignFile
                 new Object[] {});
         AlignmentI al = ((AlignmentI) cl.getMethod("getRNAMLFor",
                 new Class[] { FileParse.class }).invoke(annotate3d,
-                new Object[] { new FileParse(getDataName(), type) }));
+                new Object[] { new FileParse(getDataName(), dataSourceType) }));
         for (SequenceI sq : al.getSequences())
         {
           if (sq.getDatasetSequence() != null)
@@ -304,10 +304,8 @@ public abstract class StructureFile extends AlignFile
       Class cl = Class.forName("jalview.ext.jmol.JmolParser");
       if (cl != null)
       {
-        final Constructor constructor = cl
-                .getConstructor(new Class[] { FileParse.class });
-        final Object[] args = new Object[] { new FileParse(getDataName(),
-                type) };
+        final Constructor constructor = cl.getConstructor(new Class[] {FileParse.class });
+        final Object[] args = new Object[] { new FileParse(getDataName(), dataSourceType) };
 
         StructureImportSettings.setShowSeqFeatures(false);
         StructureImportSettings.setVisibleChainAnnotation(false);
index 07d7be4..c3ec951 100644 (file)
@@ -91,9 +91,10 @@ import java.util.regex.Pattern;
  */
 public class TCoffeeScoreFile extends AlignFile
 {
-  public TCoffeeScoreFile(String inFile, String type) throws IOException
+  public TCoffeeScoreFile(String inFile, DataSourceType fileSourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, fileSourceType);
 
   }
 
@@ -213,6 +214,7 @@ public class TCoffeeScoreFile extends AlignFile
     return result;
   }
 
+  @Override
   public void parse() throws IOException
   {
     /*
@@ -643,7 +645,7 @@ public class TCoffeeScoreFile extends AlignFile
   }
 
   @Override
-  public String print()
+  public String print(SequenceI[] sqs, boolean jvsuffix)
   {
     // TODO Auto-generated method stub
     return "Not valid.";
index 9d9b940..55e72eb 100755 (executable)
@@ -27,6 +27,7 @@ import jalview.datamodel.Sequence;
 import jalview.gui.AlignmentPanel;
 import jalview.gui.CutAndPasteTransfer;
 import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
 import jalview.util.MessageManager;
 
 import java.util.ArrayList;
@@ -35,7 +36,6 @@ import java.util.StringTokenizer;
 import java.util.Vector;
 
 import javax.swing.ImageIcon;
-import javax.swing.JOptionPane;
 
 import uk.ac.ebi.www.Data;
 import uk.ac.ebi.www.InputParams;
@@ -150,11 +150,11 @@ public class WSWUBlastClient
   {
     // This must be outside the run() body as java 1.5
     // will not return any value from the OptionPane to the expired thread.
-    int reply = JOptionPane.showConfirmDialog(Desktop.desktop,
+    int reply = JvOptionPane.showConfirmDialog(Desktop.desktop,
             "Automatically update suggested ids?",
-            "Auto replace sequence ids", JOptionPane.YES_NO_OPTION);
+            "Auto replace sequence ids", JvOptionPane.YES_NO_OPTION);
 
-    if (reply == JOptionPane.YES_OPTION)
+    if (reply == JvOptionPane.YES_OPTION)
     {
       Enumeration keys = suggestedIds.elements();
       while (keys.hasMoreElements())
@@ -211,6 +211,7 @@ public class WSWUBlastClient
       }
     }
 
+    @Override
     public void run()
     {
       while (jobsRunning > 0)
@@ -250,6 +251,7 @@ public class WSWUBlastClient
       this.sequence = sequence;
     }
 
+    @Override
     public void run()
     {
       StartJob();
index 71999f0..138fef7 100644 (file)
@@ -23,6 +23,7 @@ package jalview.io.packed;
 import jalview.api.FeatureColourI;
 import jalview.datamodel.AlignmentI;
 import jalview.io.AppletFormatAdapter;
+import jalview.io.FileFormatI;
 import jalview.io.FileParse;
 import jalview.io.FormatAdapter;
 import jalview.io.IdentifyFile;
@@ -64,7 +65,7 @@ public class ParsePackedSet
       FileParse src = dta.getDataSource();
       if (dta.getType().equals(DataProvider.JvDataType.ALIGNMENT))
       {
-        String fmt = null;
+        FileFormatI fmt = null;
         try
         {
           fmt = new IdentifyFile().identify(src, false);
@@ -76,32 +77,24 @@ public class ParsePackedSet
 
         if (fmt != null)
         {
-          if (!FormatAdapter.isValidIOFormat(fmt, false))
+          // parse the alignment
+          AlignmentI al = null;
+          try
           {
-            errmsg = fmt;
-            exerror = null;
+            al = new FormatAdapter().readFromFile(src, fmt);
+          } catch (Exception e)
+          {
+            errmsg = "Failed to parse alignment from result set";
+            exerror = e;
           }
-          else
+          if (al != null)
           {
-            // parse the alignment
-            AlignmentI al = null;
-            try
-            {
-              al = new FormatAdapter().readFromFile(src, fmt);
-            } catch (Exception e)
-            {
-              errmsg = "Failed to parse alignment from result set";
-              exerror = e;
-            }
-            if (al != null)
-            {
-              // deuniquify and construct/merge additional dataset entries if
-              // necessary.
-              context.addAlignment(al);
-              context.updateSetModified(true);
-              rslt.add(al);
-              deuniquify = true;
-            }
+            // deuniquify and construct/merge additional dataset entries if
+            // necessary.
+            context.addAlignment(al);
+            context.updateSetModified(true);
+            rslt.add(al);
+            deuniquify = true;
           }
         }
       }
index bf02e9e..072754e 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.jbgui;
 
+import jalview.io.FileFormatI;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -69,20 +70,11 @@ public abstract class GAlignExportSettings extends JPanel
           showDialog;
 
   public GAlignExportSettings(boolean hasHiddenSeq, boolean hasHiddenCols,
-          String alignFileFormat)
+          FileFormatI format)
   {
     this.hasHiddenSeq = hasHiddenSeq;
     this.hasHiddenCols = hasHiddenCols;
-    String[] complexFormats = { "JSON", "HTML" };
-
-    for (String format : complexFormats)
-    {
-      if (format.equalsIgnoreCase(alignFileFormat))
-      {
-        this.isComplexAlignFile = true;
-        break;
-      }
-    }
+    this.isComplexAlignFile = format.isComplexAlignFile();
     if (this.hasHiddenCols || this.hasHiddenSeq || this.isComplexAlignFile)
     {
       this.showDialog = true;
@@ -111,6 +103,7 @@ public abstract class GAlignExportSettings extends JPanel
 
     chkAll.addItemListener(new ItemListener()
     {
+      @Override
       public void itemStateChanged(ItemEvent e)
       {
         checkAllAction();
@@ -119,6 +112,7 @@ public abstract class GAlignExportSettings extends JPanel
 
     btnOk.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         ok_actionPerformed(e);
@@ -127,6 +121,7 @@ public abstract class GAlignExportSettings extends JPanel
 
     btnCancel.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         cancel_actionPerformed(e);
index 6b94559..981da3b 100755 (executable)
@@ -23,8 +23,10 @@ package jalview.jbgui;
 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.api.SplitContainerI;
 import jalview.bin.Cache;
+import jalview.gui.JvOptionPane;
 import jalview.gui.JvSwingUtils;
 import jalview.gui.Preferences;
+import jalview.io.FileFormat;
 import jalview.schemes.ColourSchemeProperty;
 import jalview.util.MessageManager;
 
@@ -50,7 +52,6 @@ import javax.swing.JLabel;
 import javax.swing.JMenu;
 import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JRadioButtonMenuItem;
 import javax.swing.JTabbedPane;
@@ -244,10 +245,9 @@ public class GAlignFrame extends JInternalFrame
       setJMenuBar(alignFrameMenuBar);
 
       // dynamically fill save as menu with available formats
-      for (int i = 0; i < jalview.io.FormatAdapter.WRITEABLE_FORMATS.length; i++)
+      for (String ff : FileFormat.getWritableFormats(true))
       {
-        JMenuItem item = new JMenuItem(
-                jalview.io.FormatAdapter.WRITEABLE_FORMATS[i]);
+        JMenuItem item = new JMenuItem(ff);
 
         item.addActionListener(new ActionListener()
         {
@@ -314,13 +314,13 @@ public class GAlignFrame extends JInternalFrame
           {
             radioItem.removeActionListener(radioItem.getActionListeners()[0]);
 
-            int option = JOptionPane.showInternalConfirmDialog(
+            int option = JvOptionPane.showInternalConfirmDialog(
                     jalview.gui.Desktop.desktop, MessageManager
                             .getString("label.remove_from_default_list"),
                     MessageManager
                             .getString("label.remove_user_defined_colour"),
-                    JOptionPane.YES_NO_OPTION);
-            if (option == JOptionPane.YES_OPTION)
+                    JvOptionPane.YES_NO_OPTION);
+            if (option == JvOptionPane.YES_OPTION)
             {
               jalview.gui.UserDefinedColours
                       .removeColourFromDefaults(radioItem.getText());
@@ -2181,6 +2181,19 @@ public class GAlignFrame extends JInternalFrame
         alignmentProperties();
       }
     });
+    JMenuItem selectHighlighted = new JMenuItem(
+            MessageManager.getString("action.select_highlighted_columns"));
+    selectHighlighted.setToolTipText(MessageManager
+            .getString("tooltip.select_highlighted_columns"));
+    al = new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent actionEvent)
+      {
+        selectHighlightedColumns_actionPerformed(actionEvent);
+      }
+    };
+    selectHighlighted.addActionListener(al);
     JMenu tooltipSettingsMenu = new JMenu(
             MessageManager.getString("label.sequence_id_tooltip"));
     JMenu autoAnnMenu = new JMenu(
@@ -2306,7 +2319,7 @@ public class GAlignFrame extends JInternalFrame
     colourMenu.add(buriedColour);
     colourMenu.add(nucleotideColour);
     colourMenu.add(purinePyrimidineColour);
-    colourMenu.add(RNAInteractionColour);
+    // colourMenu.add(RNAInteractionColour);
     // colourMenu.add(covariationColour);
     colourMenu.add(tcoffeeColour);
     colourMenu.add(userDefinedColour);
@@ -2382,12 +2395,20 @@ public class GAlignFrame extends JInternalFrame
     selectMenu.add(grpsFromSelection);
     selectMenu.add(deleteGroups);
     selectMenu.add(annotationColumn);
+    selectMenu.add(selectHighlighted);
     // TODO - determine if the listenToViewSelections button is needed : see bug
     // JAL-574
     // selectMenu.addSeparator();
     // selectMenu.add(listenToViewSelections);
   }
 
+  protected void selectHighlightedColumns_actionPerformed(
+          ActionEvent actionEvent)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
   /**
    * Generate the reverse sequence (or reverse complement if the flag is true)
    * and add it to the alignment
index d22fd88..63ecdaf 100755 (executable)
@@ -21,6 +21,7 @@
 package jalview.jbgui;
 
 import jalview.api.AlignmentViewPanel;
+import jalview.io.FileFormatException;
 import jalview.util.MessageManager;
 
 import java.awt.FlowLayout;
@@ -157,6 +158,7 @@ public class GDesktop extends JFrame
     inputLocalFileMenuItem
             .addActionListener(new java.awt.event.ActionListener()
             {
+              @Override
               public void actionPerformed(ActionEvent e)
               {
                 inputLocalFileMenuItem_actionPerformed(null);
@@ -165,9 +167,16 @@ public class GDesktop extends JFrame
     inputURLMenuItem.setText(MessageManager.getString("label.from_url"));
     inputURLMenuItem.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
-        inputURLMenuItem_actionPerformed(null);
+        try
+        {
+          inputURLMenuItem_actionPerformed(null);
+        } catch (FileFormatException e1)
+        {
+          System.err.println("Error loading from URL: " + e1.getMessage());
+        }
       }
     });
     inputTextboxMenuItem.setText(MessageManager
@@ -175,6 +184,7 @@ public class GDesktop extends JFrame
     inputTextboxMenuItem
             .addActionListener(new java.awt.event.ActionListener()
             {
+              @Override
               public void actionPerformed(ActionEvent e)
               {
                 inputTextboxMenuItem_actionPerformed(null);
@@ -183,6 +193,7 @@ public class GDesktop extends JFrame
     quit.setText(MessageManager.getString("action.quit"));
     quit.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         quit();
@@ -191,6 +202,7 @@ public class GDesktop extends JFrame
     aboutMenuItem.setText(MessageManager.getString("label.about"));
     aboutMenuItem.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         aboutMenuItem_actionPerformed(e);
@@ -203,6 +215,7 @@ public class GDesktop extends JFrame
     documentationMenuItem
             .addActionListener(new java.awt.event.ActionListener()
             {
+              @Override
               public void actionPerformed(ActionEvent e)
               {
                 documentationMenuItem_actionPerformed(e);
@@ -213,6 +226,7 @@ public class GDesktop extends JFrame
     preferences.setText(MessageManager.getString("label.preferences"));
     preferences.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         preferences_actionPerformed(e);
@@ -222,6 +236,7 @@ public class GDesktop extends JFrame
     saveState.setText(MessageManager.getString("action.save_project"));
     saveState.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         saveState_actionPerformed(e);
@@ -230,6 +245,7 @@ public class GDesktop extends JFrame
     loadState.setText(MessageManager.getString("action.load_project"));
     loadState.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         loadState_actionPerformed(e);
@@ -241,6 +257,7 @@ public class GDesktop extends JFrame
     vamsasStart.setVisible(false);
     vamsasStart.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         vamsasStart_actionPerformed(e);
@@ -251,6 +268,7 @@ public class GDesktop extends JFrame
     vamsasImport.setVisible(false);
     vamsasImport.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         vamsasImport_actionPerformed(e);
@@ -261,6 +279,7 @@ public class GDesktop extends JFrame
     vamsasSave.setVisible(false);
     vamsasSave.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         vamsasSave_actionPerformed(e);
@@ -270,6 +289,7 @@ public class GDesktop extends JFrame
             .getString("action.fetch_sequences"));
     inputSequence.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         inputSequence_actionPerformed(e);
@@ -280,6 +300,7 @@ public class GDesktop extends JFrame
     vamsasStop.setVisible(false);
     vamsasStop.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         vamsasStop_actionPerformed(e);
@@ -288,6 +309,7 @@ public class GDesktop extends JFrame
     closeAll.setText(MessageManager.getString("action.close_all"));
     closeAll.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         closeAll_actionPerformed(e);
@@ -297,6 +319,7 @@ public class GDesktop extends JFrame
             .getString("action.raise_associated_windows"));
     raiseRelated.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         raiseRelated_actionPerformed(e);
@@ -306,6 +329,7 @@ public class GDesktop extends JFrame
             .getString("action.minimize_associated_windows"));
     minimizeAssociated.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         minimizeAssociated_actionPerformed(e);
@@ -315,6 +339,7 @@ public class GDesktop extends JFrame
             .getString("label.collect_garbage"));
     garbageCollect.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         garbageCollect_actionPerformed(e);
@@ -324,6 +349,7 @@ public class GDesktop extends JFrame
             .getString("label.show_memory_usage"));
     showMemusage.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         showMemusage_actionPerformed(e);
@@ -333,6 +359,7 @@ public class GDesktop extends JFrame
             .setText(MessageManager.getString("label.show_java_console"));
     showConsole.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         showConsole_actionPerformed(e);
@@ -341,6 +368,7 @@ public class GDesktop extends JFrame
     showNews.setText(MessageManager.getString("label.show_jalview_news"));
     showNews.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         showNews_actionPerformed(e);
@@ -349,6 +377,7 @@ public class GDesktop extends JFrame
     snapShotWindow.setText(MessageManager.getString("label.take_snapshot"));
     snapShotWindow.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         snapShotWindow_actionPerformed(e);
@@ -446,9 +475,10 @@ public class GDesktop extends JFrame
    * 
    * @param e
    *          DOCUMENT ME!
+   * @throws FileFormatException
    */
   protected void inputURLMenuItem_actionPerformed(
-          jalview.gui.AlignViewport av)
+          jalview.gui.AlignViewport av) throws FileFormatException
   {
   }
 
index df09a61..fef4568 100755 (executable)
@@ -21,6 +21,8 @@
 package jalview.jbgui;
 
 import jalview.datamodel.AlignmentI;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 import jalview.util.MessageManager;
 
@@ -99,6 +101,7 @@ public class GFinder extends JPanel
     findAll.setText(MessageManager.getString("action.find_all"));
     findAll.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         findAll_actionPerformed(e);
@@ -108,6 +111,7 @@ public class GFinder extends JPanel
     findNext.setText(MessageManager.getString("action.find_next"));
     findNext.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         findNext_actionPerformed(e);
@@ -123,6 +127,7 @@ public class GFinder extends JPanel
     createNewGroup.setText(MessageManager.getString("label.new_feature"));
     createNewGroup.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         createNewGroup_actionPerformed(e);
@@ -133,6 +138,7 @@ public class GFinder extends JPanel
     textfield.setLineWrap(true);
     textfield.addCaretListener(new CaretListener()
     {
+      @Override
       public void caretUpdate(CaretEvent e)
       {
         textfield_caretUpdate(e);
@@ -140,6 +146,7 @@ public class GFinder extends JPanel
     });
     textfield.addKeyListener(new java.awt.event.KeyAdapter()
     {
+      @Override
       public void keyPressed(KeyEvent e)
       {
         textfield_keyPressed(e);
@@ -207,13 +214,15 @@ public class GFinder extends JPanel
     {
       SwingUtilities.invokeLater(new Runnable()
       {
+        @Override
         public void run()
         {
           String str = textfield.getText();
           AlignmentI al = null;
           try
           {
-            al = new FormatAdapter().readFile(str, "Paste", "FASTA");
+            al = new FormatAdapter().readFile(str, DataSourceType.PASTE,
+                    FileFormat.Fasta);
           } catch (Exception ex)
           {
           }
index 46580a2..dbce5f3 100755 (executable)
@@ -20,6 +20,7 @@
  */
 package jalview.jbgui;
 
+import jalview.gui.JvOptionPane;
 import jalview.gui.JvSwingUtils;
 import jalview.util.MessageManager;
 import jalview.util.UrlLink;
@@ -35,7 +36,6 @@ import java.awt.event.KeyEvent;
 
 import javax.swing.BorderFactory;
 import javax.swing.JLabel;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
 import javax.swing.SwingConstants;
@@ -60,16 +60,18 @@ public class GSequenceLink extends Panel
     nameTB.setBounds(new Rectangle(77, 10, 310, 23));
     nameTB.addKeyListener(new KeyAdapter()
     {
+      @Override
       public void keyTyped(KeyEvent e)
       {
         nameTB_keyTyped(e);
       }
     });
     urlTB.setFont(JvSwingUtils.getLabelFont());
-    urlTB.setText("http://www.");
+    urlTB.setText("http://");
     urlTB.setBounds(new Rectangle(78, 40, 309, 23));
     urlTB.addKeyListener(new KeyAdapter()
     {
+      @Override
       public void keyTyped(KeyEvent e)
       {
         urlTB_keyTyped(e);
@@ -88,7 +90,20 @@ public class GSequenceLink extends Panel
     jLabel3.setBounds(new Rectangle(21, 72, 351, 15));
     jLabel4.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
     jLabel4.setText(MessageManager.getString("label.use_sequence_id_2"));
-    jLabel4.setBounds(new Rectangle(21, 93, 351, 15));
+    jLabel4.setBounds(new Rectangle(21, 88, 351, 15));
+    jLabel5.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+    jLabel5.setText(MessageManager.getString("label.use_sequence_id_3"));
+    jLabel5.setBounds(new Rectangle(21, 106, 351, 15));
+
+    String lastLabel = MessageManager.getString("label.use_sequence_id_4");
+    if (lastLabel.length() > 0)
+    {
+      // e.g. Spanish version has longer text
+      jLabel6.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+      jLabel6.setText(lastLabel);
+      jLabel6.setBounds(new Rectangle(21, 122, 351, 15));
+    }
+
     jPanel1.setBorder(BorderFactory.createEtchedBorder());
     jPanel1.setLayout(null);
     jPanel1.add(jLabel1);
@@ -97,11 +112,21 @@ public class GSequenceLink extends Panel
     jPanel1.add(jLabel2);
     jPanel1.add(jLabel3);
     jPanel1.add(jLabel4);
+    jPanel1.add(jLabel5);
+
+    int height = 130;
+    if (lastLabel.length() > 0)
+    {
+      jPanel1.add(jLabel6);
+      height = 146;
+    }
+
     this.add(jPanel1, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
             GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
-                    5, 4, 6, 5), 390, 130));
+                    5, 4, 6, 5), 390, height));
   }
 
+  @Override
   public void setName(String name)
   {
     nameTB.setText(name);
@@ -112,6 +137,7 @@ public class GSequenceLink extends Panel
     urlTB.setText(url);
   }
 
+  @Override
   public String getName()
   {
     return nameTB.getText();
@@ -130,10 +156,10 @@ public class GSequenceLink extends Panel
       return true;
     }
 
-    JOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,
+    JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,
             MessageManager.getString("warn.url_must_contain"),
             MessageManager.getString("label.invalid_url"),
-            JOptionPane.WARNING_MESSAGE);
+            JvOptionPane.WARNING_MESSAGE);
     return false;
   }
 
@@ -149,6 +175,10 @@ public class GSequenceLink extends Panel
 
   JLabel jLabel4 = new JLabel();
 
+  JLabel jLabel5 = new JLabel();
+
+  JLabel jLabel6 = new JLabel();
+
   JPanel jPanel1 = new JPanel();
 
   GridBagLayout gridBagLayout1 = new GridBagLayout();
index 3fdcb3b..a0e530c 100644 (file)
@@ -28,6 +28,7 @@ import jalview.api.AlignViewportI;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.ProfilesI;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
 import jalview.util.Platform;
@@ -73,7 +74,7 @@ public class AnnotationRenderer
 
   private ColumnSelection columnSelection;
 
-  private Hashtable[] hconsensus;
+  private ProfilesI hconsensus;
 
   private Hashtable[] complementConsensus;
 
@@ -351,7 +352,7 @@ public class AnnotationRenderer
       {
         // TODO? group consensus for cDNA complement
         return AAFrequency.extractProfile(
-                aa.groupRef.consensusData[column],
+                aa.groupRef.consensusData.get(column),
                 aa.groupRef.getIgnoreGapsConsensus());
       }
       // TODO extend annotation row to enable dynamic and static profile data to
@@ -365,7 +366,8 @@ public class AnnotationRenderer
         }
         else
         {
-          return AAFrequency.extractProfile(hconsensus[column],
+          return AAFrequency.extractProfile(
+hconsensus.get(column),
                   av_ignoreGapsConsensus);
         }
       }
index b007365..9e0089f 100644 (file)
@@ -188,15 +188,20 @@ public class FeatureRenderer extends FeatureRendererModel
   }
 
   /**
-   * This is used by the Molecule Viewer and Overview to get the accurate colour
-   * of the rendered sequence
+   * This is used by Structure Viewers and the Overview Window to get the
+   * feature colour of the rendered sequence, returned as an RGB value
+   * 
+   * @param defaultColour
+   * @param seq
+   * @param column
+   * @return
    */
-  public synchronized int findFeatureColour(int initialCol,
+  public synchronized int findFeatureColour(int defaultColour,
           final SequenceI seq, int column)
   {
     if (!av.isShowSequenceFeatures())
     {
-      return initialCol;
+      return defaultColour;
     }
 
     SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures();
@@ -223,7 +228,7 @@ public class FeatureRenderer extends FeatureRendererModel
 
     if (lastSequenceFeatures == null || sfSize == 0)
     {
-      return initialCol;
+      return defaultColour;
     }
 
     if (jalview.util.Comparison.isGap(lastSeq.getCharAt(column)))
@@ -244,7 +249,7 @@ public class FeatureRenderer extends FeatureRendererModel
 
     if (offscreenImage != null)
     {
-      offscreenImage.setRGB(0, 0, initialCol);
+      offscreenImage.setRGB(0, 0, defaultColour);
       drawSequence(offscreenImage.getGraphics(), lastSeq, column, column, 0);
 
       return offscreenImage.getRGB(0, 0);
@@ -255,7 +260,7 @@ public class FeatureRenderer extends FeatureRendererModel
 
       if (currentColour == null)
       {
-        return initialCol;
+        return defaultColour;
       }
       else
       {
@@ -275,6 +280,19 @@ public class FeatureRenderer extends FeatureRendererModel
 
   int epos;
 
+  /**
+   * Draws the sequence on the graphics context, or just determines the colour
+   * that would be drawn (if flag offscreenrender is true).
+   * 
+   * @param g
+   * @param seq
+   * @param start
+   *          start column (or sequence position in offscreenrender mode)
+   * @param end
+   *          end column (not used in offscreenrender mode)
+   * @param y1
+   *          vertical offset at which to draw on the graphics
+   */
   public synchronized void drawSequence(Graphics g, final SequenceI seq,
           int start, int end, int y1)
   {
@@ -312,12 +330,10 @@ public class FeatureRenderer extends FeatureRendererModel
     }
 
     sfSize = lastSequenceFeatures.length;
-    String type;
     for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++)
     {
-      type = renderOrder[renderIndex];
-
-      if (type == null || !showFeatureOfType(type))
+      String type = renderOrder[renderIndex];
+      if (!showFeatureOfType(type))
       {
         continue;
       }
@@ -332,16 +348,16 @@ public class FeatureRenderer extends FeatureRendererModel
           continue;
         }
 
-        if (featureGroups != null
-                && sequenceFeature.featureGroup != null
-                && sequenceFeature.featureGroup.length() != 0
-                && featureGroups.containsKey(sequenceFeature.featureGroup)
-                && !featureGroups.get(sequenceFeature.featureGroup)
-                        .booleanValue())
+        if (featureGroupNotShown(sequenceFeature))
         {
           continue;
         }
 
+        /*
+         * check feature overlaps the visible part of the alignment, 
+         * unless doing offscreenRender (to the Overview window or a 
+         * structure viewer) which is not limited 
+         */
         if (!offscreenRender
                 && (sequenceFeature.getBegin() > epos || sequenceFeature
                         .getEnd() < spos))
@@ -349,35 +365,43 @@ public class FeatureRenderer extends FeatureRendererModel
           continue;
         }
 
+        Color featureColour = getColour(sequenceFeature);
+        boolean isContactFeature = sequenceFeature.isContactFeature();
+
         if (offscreenRender && offscreenImage == null)
         {
-          if (sequenceFeature.begin <= start
-                  && sequenceFeature.end >= start)
+          /*
+           * offscreen mode with no image (image is only needed if transparency 
+           * is applied to feature colours) - just check feature is rendered at 
+           * the requested position (start == sequence position in this mode)
+           */
+          boolean featureIsAtPosition = sequenceFeature.begin <= start
+                  && sequenceFeature.end >= start;
+          if (isContactFeature)
+          {
+            featureIsAtPosition = sequenceFeature.begin == start
+                    || sequenceFeature.end == start;
+          }
+          if (featureIsAtPosition)
           {
             // 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(sequenceFeature).getRGB());
+            currentColour = new Integer(featureColour.getRGB());
             // used to be retreived from av.featuresDisplayed
             // currentColour = av.featuresDisplayed
             // .get(sequenceFeatures[sfindex].type);
 
           }
         }
-        else if (sequenceFeature.type.equals("disulfide bond"))
+        else if (isContactFeature)
         {
           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);
+                  seq.findIndex(sequenceFeature.begin) - 1, featureColour,
+                  start, end, y1);
           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);
+                  seq.findIndex(sequenceFeature.end) - 1, featureColour,
+                  start, end, y1);
 
         }
         else if (showFeature(sequenceFeature))
@@ -388,19 +412,17 @@ public class FeatureRenderer extends FeatureRendererModel
             renderScoreFeature(g, seq,
                     seq.findIndex(sequenceFeature.begin) - 1,
                     seq.findIndex(sequenceFeature.end) - 1,
-                    getColour(sequenceFeature), start, end, y1,
+                    featureColour, start, end, y1,
                     normaliseScore(sequenceFeature));
           }
           else
           {
             renderFeature(g, seq, seq.findIndex(sequenceFeature.begin) - 1,
                     seq.findIndex(sequenceFeature.end) - 1,
-                    getColour(sequenceFeature), start, end, y1);
+                    featureColour, start, end, y1);
           }
         }
-
       }
-
     }
 
     if (transparency != 1.0f && g != null)
@@ -412,6 +434,24 @@ public class FeatureRenderer extends FeatureRendererModel
   }
 
   /**
+   * Answers true if the feature belongs to a feature group which is not
+   * currently displayed, else false
+   * 
+   * @param sequenceFeature
+   * @return
+   */
+  protected boolean featureGroupNotShown(
+          final SequenceFeature sequenceFeature)
+  {
+    return featureGroups != null
+            && sequenceFeature.featureGroup != null
+            && sequenceFeature.featureGroup.length() != 0
+            && featureGroups.containsKey(sequenceFeature.featureGroup)
+            && !featureGroups.get(sequenceFeature.featureGroup)
+                    .booleanValue();
+  }
+
+  /**
    * Called when alignment in associated view has new/modified features to
    * discover and display.
    * 
index 9d09259..c47f171 100755 (executable)
  */
 package jalview.schemes;
 
-import jalview.analysis.AAFrequency;
 import jalview.datamodel.AnnotatedCollectionI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
 
 import java.awt.Color;
 import java.util.Map;
 
 public class Blosum62ColourScheme extends ResidueColourScheme
 {
+  private static final Color LIGHT_BLUE = new Color(204, 204, 255);
+  private static final Color DARK_BLUE = new Color(154, 154, 255);
+
   public Blosum62ColourScheme()
   {
     super();
@@ -44,7 +47,7 @@ public class Blosum62ColourScheme extends ResidueColourScheme
       res -= ('a' - 'A');
     }
 
-    if (consensus == null || j >= consensus.length || consensus[j] == null
+    if (consensus == null || consensus.get(j) == null
             || (threshold != 0 && !aboveThreshold(res, j)))
     {
       return Color.white;
@@ -52,14 +55,16 @@ public class Blosum62ColourScheme extends ResidueColourScheme
 
     Color currentColour;
 
-    if (!jalview.util.Comparison.isGap(res))
+    if (!Comparison.isGap(res))
     {
-      String max = (String) consensus[j].get(AAFrequency.MAXRESIDUE);
+      /*
+       * test if this is the consensus (or joint consensus) residue
+       */
+      String max = consensus.get(j).getModalResidue();
 
       if (max.indexOf(res) > -1)
       {
-        // TODO use a constant here?
-        currentColour = new Color(154, 154, 255);
+        currentColour = DARK_BLUE;
       }
       else
       {
@@ -74,8 +79,7 @@ public class Blosum62ColourScheme extends ResidueColourScheme
 
         if (c > 0)
         {
-          // TODO use a constant here?
-          currentColour = new Color(204, 204, 255);
+          currentColour = LIGHT_BLUE;
         }
         else
         {
index effdf59..da99a4a 100755 (executable)
@@ -21,6 +21,7 @@
 package jalview.schemes;
 
 import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
 
@@ -52,7 +53,7 @@ public interface ColourSchemeI
   /**
    * assign the given consensus profile for the colourscheme
    */
-  public void setConsensus(java.util.Hashtable[] h);
+  public void setConsensus(ProfilesI hconsensus);
 
   /**
    * assign the given conservation to the colourscheme
index eac467a..35be31b 100644 (file)
@@ -21,8 +21,7 @@
 package jalview.schemes;
 
 import jalview.analysis.Conservation;
-
-import java.util.Hashtable;
+import jalview.datamodel.ProfilesI;
 
 /**
  * Colourscheme that takes its colours from some other colourscheme
@@ -41,7 +40,7 @@ public class FollowerColourScheme extends ResidueColourScheme
   }
 
   @Override
-  public void setConsensus(Hashtable[] consensus)
+  public void setConsensus(ProfilesI consensus)
   {
     if (colourScheme != null)
     {
index 9dd763d..0ad5b5c 100755 (executable)
  */
 package jalview.schemes;
 
-import jalview.analysis.AAFrequency;
+import jalview.datamodel.ProfileI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
 
 import java.awt.Color;
 
@@ -48,7 +49,7 @@ public class PIDColourScheme extends ResidueColourScheme
       c -= ('a' - 'A');
     }
 
-    if (consensus == null || j >= consensus.length || consensus[j] == null)
+    if (consensus == null || consensus.get(j) == null)
     {
       return Color.white;
     }
@@ -62,25 +63,24 @@ public class PIDColourScheme extends ResidueColourScheme
 
     double sc = 0;
 
-    if (consensus.length <= j)
-    {
-      return Color.white;
-    }
 
-    if ((Integer
-            .parseInt(consensus[j].get(AAFrequency.MAXCOUNT).toString()) != -1)
-            && consensus[j].contains(String.valueOf(c)))
+    /*
+     * test whether this is the consensus (or joint consensus) residue
+     */
+    ProfileI profile = consensus.get(j);
+    boolean matchesConsensus = profile.getModalResidue().contains(
+            String.valueOf(c));
+    if (matchesConsensus)
     {
-      sc = ((Float) consensus[j].get(ignoreGaps)).floatValue();
+      sc = profile.getPercentageIdentity(ignoreGaps);
 
-      if (!jalview.util.Comparison.isGap(c))
+      if (!Comparison.isGap(c))
       {
         for (int i = 0; i < thresholds.length; i++)
         {
           if (sc > thresholds[i])
           {
             currentColour = pidColours[i];
-
             break;
           }
         }
index bca98cf..f6b7c5e 100755 (executable)
  */
 package jalview.schemes;
 
-import jalview.analysis.AAFrequency;
 import jalview.analysis.Conservation;
 import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
+import jalview.util.Comparison;
 import jalview.util.MessageManager;
 
 import java.awt.Color;
-import java.util.Hashtable;
 import java.util.Map;
 
 /**
@@ -48,17 +50,21 @@ public class ResidueColourScheme implements ColourSchemeI
   int threshold = 0;
 
   /* Set when threshold colouring to either pid_gaps or pid_nogaps */
-  protected String ignoreGaps = AAFrequency.PID_GAPS;
+  protected boolean ignoreGaps = false;
 
-  /** Consenus as a hashtable array */
-  Hashtable[] consensus;
+  /*
+   * Consensus data indexed by column
+   */
+  ProfilesI consensus;
 
-  /** Conservation string as a char array */
+  /*
+   * Conservation string as a char array 
+   */
   char[] conservation;
 
-  int conservationLength = 0;
-
-  /** DOCUMENT ME!! */
+  /*
+   * The conservation slider percentage setting 
+   */
   int inc = 30;
 
   /**
@@ -100,6 +106,7 @@ public class ResidueColourScheme implements ColourSchemeI
   /**
    * Find a colour without an index in a sequence
    */
+  @Override
   public Color findColour(char c)
   {
     return colors == null ? Color.white : colors[symbolIndex[c]];
@@ -133,58 +140,63 @@ public class ResidueColourScheme implements ColourSchemeI
    * 
    * @return Returns the percentage threshold
    */
+  @Override
   public int getThreshold()
   {
     return threshold;
   }
 
   /**
-   * DOCUMENT ME!
+   * Sets the percentage consensus threshold value, and whether gaps are ignored
+   * in percentage identity calculation
    * 
-   * @param ct
-   *          DOCUMENT ME!
+   * @param consensusThreshold
+   * @param ignoreGaps
    */
-  public void setThreshold(int ct, boolean ignoreGaps)
+  @Override
+  public void setThreshold(int consensusThreshold, boolean ignoreGaps)
   {
-    threshold = ct;
-    if (ignoreGaps)
-    {
-      this.ignoreGaps = AAFrequency.PID_NOGAPS;
-    }
-    else
-    {
-      this.ignoreGaps = AAFrequency.PID_GAPS;
-    }
+    threshold = consensusThreshold;
+    this.ignoreGaps = ignoreGaps;
   }
 
   /**
-   * DOCUMENT ME!
+   * Answers true if there is a consensus profile for the specified column, and
+   * the given residue matches the consensus (or joint consensus) residue for
+   * the column, and the percentage identity for the profile is equal to or
+   * greater than the current threshold; else answers false. The percentage
+   * calculation depends on whether or not we are ignoring gapped sequences.
    * 
-   * @param s
-   *          DOCUMENT ME!
-   * @param j
-   *          DOCUMENT ME!
+   * @param residue
+   * @param column
+   *          (index into consensus profiles)
    * 
-   * @return DOCUMENT ME!
+   * @return
+   * @see #setThreshold(int, boolean)
    */
-  public boolean aboveThreshold(char c, int j)
+  public boolean aboveThreshold(char residue, int column)
   {
-    if ('a' <= c && c <= 'z')
+    if ('a' <= residue && residue <= 'z')
     {
       // TO UPPERCASE !!!
       // Faster than toUpperCase
-      c -= ('a' - 'A');
+      residue -= ('a' - 'A');
     }
 
-    if (consensus == null || consensus.length < j || consensus[j] == null)
+    if (consensus == null)
     {
       return false;
     }
 
-    if ((((Integer) consensus[j].get(AAFrequency.MAXCOUNT)).intValue() != -1)
-            && consensus[j].contains(String.valueOf(c)))
+    ProfileI profile = consensus.get(column);
+
+    /*
+     * test whether this is the consensus (or joint consensus) residue
+     */
+    if (profile != null
+            && profile.getModalResidue().contains(String.valueOf(residue)))
     {
-      if (((Float) consensus[j].get(ignoreGaps)).floatValue() >= threshold)
+      if (profile.getPercentageIdentity(ignoreGaps) >= threshold)
       {
         return true;
       }
@@ -193,6 +205,7 @@ public class ResidueColourScheme implements ColourSchemeI
     return false;
   }
 
+  @Override
   public boolean conservationApplied()
   {
     return conservationColouring;
@@ -204,11 +217,13 @@ public class ResidueColourScheme implements ColourSchemeI
     conservationColouring = conservationApplied;
   }
 
+  @Override
   public void setConservationInc(int i)
   {
     inc = i;
   }
 
+  @Override
   public int getConservationInc()
   {
     return inc;
@@ -220,7 +235,8 @@ public class ResidueColourScheme implements ColourSchemeI
    * @param consensus
    *          DOCUMENT ME!
    */
-  public void setConsensus(Hashtable[] consensus)
+  @Override
+  public void setConsensus(ProfilesI consensus)
   {
     if (consensus == null)
     {
@@ -230,6 +246,7 @@ public class ResidueColourScheme implements ColourSchemeI
     this.consensus = consensus;
   }
 
+  @Override
   public void setConservation(Conservation cons)
   {
     if (cons == null)
@@ -240,73 +257,70 @@ public class ResidueColourScheme implements ColourSchemeI
     else
     {
       conservationColouring = true;
-      int i, iSize = cons.getConsSequence().getLength();
+      int iSize = cons.getConsSequence().getLength();
       conservation = new char[iSize];
-      for (i = 0; i < iSize; i++)
+      for (int i = 0; i < iSize; i++)
       {
         conservation[i] = cons.getConsSequence().getCharAt(i);
       }
-      conservationLength = conservation.length;
     }
 
   }
 
   /**
-   * DOCUMENT ME!
+   * Applies a combination of column conservation score, and conservation
+   * percentage slider, to 'bleach' out the residue colours towards white.
+   * <p>
+   * If a column is fully conserved (identical residues, conservation score 11,
+   * shown as *), or all 10 physico-chemical properties are conserved
+   * (conservation score 10, shown as +), then the colour is left unchanged.
+   * <p>
+   * Otherwise a 'bleaching' factor is computed and applied to the colour. This
+   * is designed to fade colours for scores of 0-9 completely to white at slider
+   * positions ranging from 18% - 100% respectively.
    * 
-   * @param s
-   *          DOCUMENT ME!
-   * @param i
-   *          DOCUMENT ME!
+   * @param currentColour
+   * @param column
    * 
-   * @return DOCUMENT ME!
+   * @return bleached (or unmodified) colour
    */
-
-  Color applyConservation(Color currentColour, int i)
+  Color applyConservation(Color currentColour, int column)
   {
+    if (conservation == null || conservation.length <= column)
+    {
+      return currentColour;
+    }
+    char conservationScore = conservation[column];
+
+    /*
+     * if residues are fully conserved (* or 11), or all properties
+     * are conserved (+ or 10), leave colour unchanged
+     */
+    if (conservationScore == '*' || conservationScore == '+'
+            || conservationScore == (char) 10
+            || conservationScore == (char) 11)
+    {
+      return currentColour;
+    }
 
-    if ((conservationLength > i) && (conservation[i] != '*')
-            && (conservation[i] != '+'))
+    if (Comparison.isGap(conservationScore))
     {
-      if (jalview.util.Comparison.isGap(conservation[i]))
-      {
-        currentColour = Color.white;
-      }
-      else
-      {
-        float t = 11 - (conservation[i] - '0');
-        if (t == 0)
-        {
-          return Color.white;
-        }
-
-        int red = currentColour.getRed();
-        int green = currentColour.getGreen();
-        int blue = currentColour.getBlue();
-
-        int dr = 255 - red;
-        int dg = 255 - green;
-        int db = 255 - blue;
-
-        dr *= t / 10f;
-        dg *= t / 10f;
-        db *= t / 10f;
-
-        red += (inc / 20f) * dr;
-        green += (inc / 20f) * dg;
-        blue += (inc / 20f) * db;
-
-        if (red > 255 || green > 255 || blue > 255)
-        {
-          currentColour = Color.white;
-        }
-        else
-        {
-          currentColour = new Color(red, green, blue);
-        }
-      }
+      return Color.white;
     }
-    return currentColour;
+
+    /*
+     * convert score 0-9 to a bleaching factor 1.1 - 0.2
+     */
+    float bleachFactor = (11 - (conservationScore - '0')) / 10f;
+
+    /*
+     * scale this up by 0-5 (percentage slider / 20)
+     * as a result, scores of:         0  1  2  3  4  5  6  7  8  9
+     * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100%
+     */
+    bleachFactor *= (inc / 20f);
+
+    return ColorUtils.bleachColour(currentColour, bleachFactor);
   }
 
   @Override
index 90a7952..4d46279 100755 (executable)
@@ -222,10 +222,14 @@ public class ResidueProperties
     purinepyrimidineIndex['n'] = 2;
   }
 
+  private static final Integer ONE = Integer.valueOf(1);
+
+  private static final Integer ZERO = Integer.valueOf(0);
+
   static
   {
-    aa3Hash.put("ALA", Integer.valueOf(0));
-    aa3Hash.put("ARG", Integer.valueOf(1));
+    aa3Hash.put("ALA", ZERO);
+    aa3Hash.put("ARG", ONE);
     aa3Hash.put("ASN", Integer.valueOf(2));
     aa3Hash.put("ASP", Integer.valueOf(3)); // D
     aa3Hash.put("CYS", Integer.valueOf(4));
@@ -910,267 +914,267 @@ public class ResidueProperties
 
   static
   {
-    hydrophobic.put("I", Integer.valueOf(1));
-    hydrophobic.put("L", Integer.valueOf(1));
-    hydrophobic.put("V", Integer.valueOf(1));
-    hydrophobic.put("C", Integer.valueOf(1));
-    hydrophobic.put("A", Integer.valueOf(1));
-    hydrophobic.put("G", Integer.valueOf(1));
-    hydrophobic.put("M", Integer.valueOf(1));
-    hydrophobic.put("F", Integer.valueOf(1));
-    hydrophobic.put("Y", Integer.valueOf(1));
-    hydrophobic.put("W", Integer.valueOf(1));
-    hydrophobic.put("H", Integer.valueOf(1));
-    hydrophobic.put("K", Integer.valueOf(1));
-    hydrophobic.put("X", Integer.valueOf(1));
-    hydrophobic.put("-", Integer.valueOf(1));
-    hydrophobic.put("*", Integer.valueOf(1));
-    hydrophobic.put("R", Integer.valueOf(0));
-    hydrophobic.put("E", Integer.valueOf(0));
-    hydrophobic.put("Q", Integer.valueOf(0));
-    hydrophobic.put("D", Integer.valueOf(0));
-    hydrophobic.put("N", Integer.valueOf(0));
-    hydrophobic.put("S", Integer.valueOf(0));
-    hydrophobic.put("T", Integer.valueOf(0));
-    hydrophobic.put("P", Integer.valueOf(0));
+    hydrophobic.put("I", ONE);
+    hydrophobic.put("L", ONE);
+    hydrophobic.put("V", ONE);
+    hydrophobic.put("C", ONE);
+    hydrophobic.put("A", ONE);
+    hydrophobic.put("G", ONE);
+    hydrophobic.put("M", ONE);
+    hydrophobic.put("F", ONE);
+    hydrophobic.put("Y", ONE);
+    hydrophobic.put("W", ONE);
+    hydrophobic.put("H", ONE);
+    hydrophobic.put("K", ONE);
+    hydrophobic.put("X", ONE);
+    hydrophobic.put("-", ONE);
+    hydrophobic.put("*", ONE);
+    hydrophobic.put("R", ZERO);
+    hydrophobic.put("E", ZERO);
+    hydrophobic.put("Q", ZERO);
+    hydrophobic.put("D", ZERO);
+    hydrophobic.put("N", ZERO);
+    hydrophobic.put("S", ZERO);
+    hydrophobic.put("T", ONE);
+    hydrophobic.put("P", ZERO);
   }
 
   static
   {
-    polar.put("Y", Integer.valueOf(1));
-    polar.put("W", Integer.valueOf(1));
-    polar.put("H", Integer.valueOf(1));
-    polar.put("K", Integer.valueOf(1));
-    polar.put("R", Integer.valueOf(1));
-    polar.put("E", Integer.valueOf(1));
-    polar.put("Q", Integer.valueOf(1));
-    polar.put("D", Integer.valueOf(1));
-    polar.put("N", Integer.valueOf(1));
-    polar.put("S", Integer.valueOf(1));
-    polar.put("T", Integer.valueOf(1));
-    polar.put("X", Integer.valueOf(1));
-    polar.put("-", Integer.valueOf(1));
-    polar.put("*", Integer.valueOf(1));
-    polar.put("I", Integer.valueOf(0));
-    polar.put("L", Integer.valueOf(0));
-    polar.put("V", Integer.valueOf(0));
-    polar.put("C", Integer.valueOf(0));
-    polar.put("A", Integer.valueOf(0));
-    polar.put("G", Integer.valueOf(0));
-    polar.put("M", Integer.valueOf(0));
-    polar.put("F", Integer.valueOf(0));
-    polar.put("P", Integer.valueOf(0));
+    polar.put("Y", ONE);
+    polar.put("W", ONE);
+    polar.put("H", ONE);
+    polar.put("K", ONE);
+    polar.put("R", ONE);
+    polar.put("E", ONE);
+    polar.put("Q", ONE);
+    polar.put("D", ONE);
+    polar.put("N", ONE);
+    polar.put("S", ONE);
+    polar.put("T", ONE);
+    polar.put("X", ONE);
+    polar.put("-", ONE);
+    polar.put("*", ONE);
+    polar.put("I", ZERO);
+    polar.put("L", ZERO);
+    polar.put("V", ZERO);
+    polar.put("C", ZERO);
+    polar.put("A", ZERO);
+    polar.put("G", ZERO);
+    polar.put("M", ZERO);
+    polar.put("F", ZERO);
+    polar.put("P", ZERO);
   }
 
   static
   {
-    small.put("I", Integer.valueOf(0));
-    small.put("L", Integer.valueOf(0));
-    small.put("V", Integer.valueOf(1));
-    small.put("C", Integer.valueOf(1));
-    small.put("A", Integer.valueOf(1));
-    small.put("G", Integer.valueOf(1));
-    small.put("M", Integer.valueOf(0));
-    small.put("F", Integer.valueOf(0));
-    small.put("Y", Integer.valueOf(0));
-    small.put("W", Integer.valueOf(0));
-    small.put("H", Integer.valueOf(0));
-    small.put("K", Integer.valueOf(0));
-    small.put("R", Integer.valueOf(0));
-    small.put("E", Integer.valueOf(0));
-    small.put("Q", Integer.valueOf(0));
-    small.put("D", Integer.valueOf(1));
-    small.put("N", Integer.valueOf(1));
-    small.put("S", Integer.valueOf(1));
-    small.put("T", Integer.valueOf(1));
-    small.put("P", Integer.valueOf(1));
-    small.put("-", Integer.valueOf(1));
-    small.put("*", Integer.valueOf(1));
+    small.put("I", ZERO);
+    small.put("L", ZERO);
+    small.put("V", ONE);
+    small.put("C", ONE);
+    small.put("A", ONE);
+    small.put("G", ONE);
+    small.put("M", ZERO);
+    small.put("F", ZERO);
+    small.put("Y", ZERO);
+    small.put("W", ZERO);
+    small.put("H", ZERO);
+    small.put("K", ZERO);
+    small.put("R", ZERO);
+    small.put("E", ZERO);
+    small.put("Q", ZERO);
+    small.put("D", ONE);
+    small.put("N", ONE);
+    small.put("S", ONE);
+    small.put("T", ONE);
+    small.put("P", ONE);
+    small.put("-", ONE);
+    small.put("*", ONE);
   }
 
   static
   {
-    positive.put("I", Integer.valueOf(0));
-    positive.put("L", Integer.valueOf(0));
-    positive.put("V", Integer.valueOf(0));
-    positive.put("C", Integer.valueOf(0));
-    positive.put("A", Integer.valueOf(0));
-    positive.put("G", Integer.valueOf(0));
-    positive.put("M", Integer.valueOf(0));
-    positive.put("F", Integer.valueOf(0));
-    positive.put("Y", Integer.valueOf(0));
-    positive.put("W", Integer.valueOf(0));
-    positive.put("H", Integer.valueOf(1));
-    positive.put("K", Integer.valueOf(1));
-    positive.put("R", Integer.valueOf(1));
-    positive.put("E", Integer.valueOf(0));
-    positive.put("Q", Integer.valueOf(0));
-    positive.put("D", Integer.valueOf(0));
-    positive.put("N", Integer.valueOf(0));
-    positive.put("S", Integer.valueOf(0));
-    positive.put("T", Integer.valueOf(0));
-    positive.put("P", Integer.valueOf(0));
-    positive.put("-", Integer.valueOf(1));
-    positive.put("*", Integer.valueOf(1));
+    positive.put("I", ZERO);
+    positive.put("L", ZERO);
+    positive.put("V", ZERO);
+    positive.put("C", ZERO);
+    positive.put("A", ZERO);
+    positive.put("G", ZERO);
+    positive.put("M", ZERO);
+    positive.put("F", ZERO);
+    positive.put("Y", ZERO);
+    positive.put("W", ZERO);
+    positive.put("H", ONE);
+    positive.put("K", ONE);
+    positive.put("R", ONE);
+    positive.put("E", ZERO);
+    positive.put("Q", ZERO);
+    positive.put("D", ZERO);
+    positive.put("N", ZERO);
+    positive.put("S", ZERO);
+    positive.put("T", ZERO);
+    positive.put("P", ZERO);
+    positive.put("-", ONE);
+    positive.put("*", ONE);
   }
 
   static
   {
-    negative.put("I", Integer.valueOf(0));
-    negative.put("L", Integer.valueOf(0));
-    negative.put("V", Integer.valueOf(0));
-    negative.put("C", Integer.valueOf(0));
-    negative.put("A", Integer.valueOf(0));
-    negative.put("G", Integer.valueOf(0));
-    negative.put("M", Integer.valueOf(0));
-    negative.put("F", Integer.valueOf(0));
-    negative.put("Y", Integer.valueOf(0));
-    negative.put("W", Integer.valueOf(0));
-    negative.put("H", Integer.valueOf(0));
-    negative.put("K", Integer.valueOf(0));
-    negative.put("R", Integer.valueOf(0));
-    negative.put("E", Integer.valueOf(1));
-    negative.put("Q", Integer.valueOf(0));
-    negative.put("D", Integer.valueOf(1));
-    negative.put("N", Integer.valueOf(0));
-    negative.put("S", Integer.valueOf(0));
-    negative.put("T", Integer.valueOf(0));
-    negative.put("P", Integer.valueOf(0));
-    negative.put("-", Integer.valueOf(1));
-    negative.put("*", Integer.valueOf(1));
+    negative.put("I", ZERO);
+    negative.put("L", ZERO);
+    negative.put("V", ZERO);
+    negative.put("C", ZERO);
+    negative.put("A", ZERO);
+    negative.put("G", ZERO);
+    negative.put("M", ZERO);
+    negative.put("F", ZERO);
+    negative.put("Y", ZERO);
+    negative.put("W", ZERO);
+    negative.put("H", ZERO);
+    negative.put("K", ZERO);
+    negative.put("R", ZERO);
+    negative.put("E", ONE);
+    negative.put("Q", ZERO);
+    negative.put("D", ONE);
+    negative.put("N", ZERO);
+    negative.put("S", ZERO);
+    negative.put("T", ZERO);
+    negative.put("P", ZERO);
+    negative.put("-", ONE);
+    negative.put("*", ONE);
   }
 
   static
   {
-    charged.put("I", Integer.valueOf(0));
-    charged.put("L", Integer.valueOf(0));
-    charged.put("V", Integer.valueOf(0));
-    charged.put("C", Integer.valueOf(0));
-    charged.put("A", Integer.valueOf(0));
-    charged.put("G", Integer.valueOf(0));
-    charged.put("M", Integer.valueOf(0));
-    charged.put("F", Integer.valueOf(0));
-    charged.put("Y", Integer.valueOf(0));
-    charged.put("W", Integer.valueOf(0));
-    charged.put("H", Integer.valueOf(1));
-    charged.put("K", Integer.valueOf(1));
-    charged.put("R", Integer.valueOf(1));
-    charged.put("E", Integer.valueOf(1));
-    charged.put("Q", Integer.valueOf(0));
-    charged.put("D", Integer.valueOf(1));
-    charged.put("N", Integer.valueOf(0)); // Asparagine is polar but not
+    charged.put("I", ZERO);
+    charged.put("L", ZERO);
+    charged.put("V", ZERO);
+    charged.put("C", ZERO);
+    charged.put("A", ZERO);
+    charged.put("G", ZERO);
+    charged.put("M", ZERO);
+    charged.put("F", ZERO);
+    charged.put("Y", ZERO);
+    charged.put("W", ZERO);
+    charged.put("H", ONE);
+    charged.put("K", ONE);
+    charged.put("R", ONE);
+    charged.put("E", ONE);
+    charged.put("Q", ZERO);
+    charged.put("D", ONE);
+    charged.put("N", ZERO); // Asparagine is polar but not
                                           // charged.
     // Alternative would be charged and
     // negative (in basic form)?
-    charged.put("S", Integer.valueOf(0));
-    charged.put("T", Integer.valueOf(0));
-    charged.put("P", Integer.valueOf(0));
-    charged.put("-", Integer.valueOf(1));
-    charged.put("*", Integer.valueOf(1));
+    charged.put("S", ZERO);
+    charged.put("T", ZERO);
+    charged.put("P", ZERO);
+    charged.put("-", ONE);
+    charged.put("*", ONE);
   }
 
   static
   {
-    aromatic.put("I", Integer.valueOf(0));
-    aromatic.put("L", Integer.valueOf(0));
-    aromatic.put("V", Integer.valueOf(0));
-    aromatic.put("C", Integer.valueOf(0));
-    aromatic.put("A", Integer.valueOf(0));
-    aromatic.put("G", Integer.valueOf(0));
-    aromatic.put("M", Integer.valueOf(0));
-    aromatic.put("F", Integer.valueOf(1));
-    aromatic.put("Y", Integer.valueOf(1));
-    aromatic.put("W", Integer.valueOf(1));
-    aromatic.put("H", Integer.valueOf(1));
-    aromatic.put("K", Integer.valueOf(0));
-    aromatic.put("R", Integer.valueOf(0));
-    aromatic.put("E", Integer.valueOf(0));
-    aromatic.put("Q", Integer.valueOf(0));
-    aromatic.put("D", Integer.valueOf(0));
-    aromatic.put("N", Integer.valueOf(0));
-    aromatic.put("S", Integer.valueOf(0));
-    aromatic.put("T", Integer.valueOf(0));
-    aromatic.put("P", Integer.valueOf(0));
-    aromatic.put("-", Integer.valueOf(1));
-    aromatic.put("*", Integer.valueOf(1));
+    aromatic.put("I", ZERO);
+    aromatic.put("L", ZERO);
+    aromatic.put("V", ZERO);
+    aromatic.put("C", ZERO);
+    aromatic.put("A", ZERO);
+    aromatic.put("G", ZERO);
+    aromatic.put("M", ZERO);
+    aromatic.put("F", ONE);
+    aromatic.put("Y", ONE);
+    aromatic.put("W", ONE);
+    aromatic.put("H", ONE);
+    aromatic.put("K", ZERO);
+    aromatic.put("R", ZERO);
+    aromatic.put("E", ZERO);
+    aromatic.put("Q", ZERO);
+    aromatic.put("D", ZERO);
+    aromatic.put("N", ZERO);
+    aromatic.put("S", ZERO);
+    aromatic.put("T", ZERO);
+    aromatic.put("P", ZERO);
+    aromatic.put("-", ONE);
+    aromatic.put("*", ONE);
   }
 
   static
   {
-    aliphatic.put("I", Integer.valueOf(1));
-    aliphatic.put("L", Integer.valueOf(1));
-    aliphatic.put("V", Integer.valueOf(1));
-    aliphatic.put("C", Integer.valueOf(0));
-    aliphatic.put("A", Integer.valueOf(0));
-    aliphatic.put("G", Integer.valueOf(0));
-    aliphatic.put("M", Integer.valueOf(0));
-    aliphatic.put("F", Integer.valueOf(0));
-    aliphatic.put("Y", Integer.valueOf(0));
-    aliphatic.put("W", Integer.valueOf(0));
-    aliphatic.put("H", Integer.valueOf(0));
-    aliphatic.put("K", Integer.valueOf(0));
-    aliphatic.put("R", Integer.valueOf(0));
-    aliphatic.put("E", Integer.valueOf(0));
-    aliphatic.put("Q", Integer.valueOf(0));
-    aliphatic.put("D", Integer.valueOf(0));
-    aliphatic.put("N", Integer.valueOf(0));
-    aliphatic.put("S", Integer.valueOf(0));
-    aliphatic.put("T", Integer.valueOf(0));
-    aliphatic.put("P", Integer.valueOf(0));
-    aliphatic.put("-", Integer.valueOf(1));
-    aliphatic.put("*", Integer.valueOf(1));
+    aliphatic.put("I", ONE);
+    aliphatic.put("L", ONE);
+    aliphatic.put("V", ONE);
+    aliphatic.put("C", ZERO);
+    aliphatic.put("A", ZERO);
+    aliphatic.put("G", ZERO);
+    aliphatic.put("M", ZERO);
+    aliphatic.put("F", ZERO);
+    aliphatic.put("Y", ZERO);
+    aliphatic.put("W", ZERO);
+    aliphatic.put("H", ZERO);
+    aliphatic.put("K", ZERO);
+    aliphatic.put("R", ZERO);
+    aliphatic.put("E", ZERO);
+    aliphatic.put("Q", ZERO);
+    aliphatic.put("D", ZERO);
+    aliphatic.put("N", ZERO);
+    aliphatic.put("S", ZERO);
+    aliphatic.put("T", ZERO);
+    aliphatic.put("P", ZERO);
+    aliphatic.put("-", ONE);
+    aliphatic.put("*", ONE);
   }
 
   static
   {
-    tiny.put("I", Integer.valueOf(0));
-    tiny.put("L", Integer.valueOf(0));
-    tiny.put("V", Integer.valueOf(0));
-    tiny.put("C", Integer.valueOf(0));
-    tiny.put("A", Integer.valueOf(1));
-    tiny.put("G", Integer.valueOf(1));
-    tiny.put("M", Integer.valueOf(0));
-    tiny.put("F", Integer.valueOf(0));
-    tiny.put("Y", Integer.valueOf(0));
-    tiny.put("W", Integer.valueOf(0));
-    tiny.put("H", Integer.valueOf(0));
-    tiny.put("K", Integer.valueOf(0));
-    tiny.put("R", Integer.valueOf(0));
-    tiny.put("E", Integer.valueOf(0));
-    tiny.put("Q", Integer.valueOf(0));
-    tiny.put("D", Integer.valueOf(0));
-    tiny.put("N", Integer.valueOf(0));
-    tiny.put("S", Integer.valueOf(1));
-    tiny.put("T", Integer.valueOf(0));
-    tiny.put("P", Integer.valueOf(0));
-    tiny.put("-", Integer.valueOf(1));
-    tiny.put("*", Integer.valueOf(1));
+    tiny.put("I", ZERO);
+    tiny.put("L", ZERO);
+    tiny.put("V", ZERO);
+    tiny.put("C", ZERO);
+    tiny.put("A", ONE);
+    tiny.put("G", ONE);
+    tiny.put("M", ZERO);
+    tiny.put("F", ZERO);
+    tiny.put("Y", ZERO);
+    tiny.put("W", ZERO);
+    tiny.put("H", ZERO);
+    tiny.put("K", ZERO);
+    tiny.put("R", ZERO);
+    tiny.put("E", ZERO);
+    tiny.put("Q", ZERO);
+    tiny.put("D", ZERO);
+    tiny.put("N", ZERO);
+    tiny.put("S", ONE);
+    tiny.put("T", ZERO);
+    tiny.put("P", ZERO);
+    tiny.put("-", ONE);
+    tiny.put("*", ONE);
   }
 
   static
   {
-    proline.put("I", Integer.valueOf(0));
-    proline.put("L", Integer.valueOf(0));
-    proline.put("V", Integer.valueOf(0));
-    proline.put("C", Integer.valueOf(0));
-    proline.put("A", Integer.valueOf(0));
-    proline.put("G", Integer.valueOf(0));
-    proline.put("M", Integer.valueOf(0));
-    proline.put("F", Integer.valueOf(0));
-    proline.put("Y", Integer.valueOf(0));
-    proline.put("W", Integer.valueOf(0));
-    proline.put("H", Integer.valueOf(0));
-    proline.put("K", Integer.valueOf(0));
-    proline.put("R", Integer.valueOf(0));
-    proline.put("E", Integer.valueOf(0));
-    proline.put("Q", Integer.valueOf(0));
-    proline.put("D", Integer.valueOf(0));
-    proline.put("N", Integer.valueOf(0));
-    proline.put("S", Integer.valueOf(0));
-    proline.put("T", Integer.valueOf(0));
-    proline.put("P", Integer.valueOf(1));
-    proline.put("-", Integer.valueOf(1));
-    proline.put("*", Integer.valueOf(1));
+    proline.put("I", ZERO);
+    proline.put("L", ZERO);
+    proline.put("V", ZERO);
+    proline.put("C", ZERO);
+    proline.put("A", ZERO);
+    proline.put("G", ZERO);
+    proline.put("M", ZERO);
+    proline.put("F", ZERO);
+    proline.put("Y", ZERO);
+    proline.put("W", ZERO);
+    proline.put("H", ZERO);
+    proline.put("K", ZERO);
+    proline.put("R", ZERO);
+    proline.put("E", ZERO);
+    proline.put("Q", ZERO);
+    proline.put("D", ZERO);
+    proline.put("N", ZERO);
+    proline.put("S", ZERO);
+    proline.put("T", ZERO);
+    proline.put("P", ONE);
+    proline.put("-", ONE);
+    proline.put("*", ONE);
   }
 
   static
index 771b8a0..81ff739 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.structure;
 
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceI;
 
 public interface SequenceListener
@@ -27,7 +28,7 @@ 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);
+  public void highlightSequence(SearchResultsI results);
 
   // TODO remove this? never called
   public void updateColours(SequenceI sequence, int index);
index 6254b43..9662fee 100644 (file)
@@ -121,9 +121,9 @@ public class StructureImportSettings
     StructureImportSettings.showSeqFeatures = showSeqFeatures;
   }
 
-  public static String getDefaultStructureFileFormat()
+  public static PDBEntry.Type getDefaultStructureFileFormat()
   {
-    return defaultStructureFileFormat.toString();
+    return defaultStructureFileFormat;
   }
 
   public static void setDefaultStructureFileFormat(
index 7e691be..65fd5e7 100644 (file)
@@ -31,10 +31,11 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JmolParser;
 import jalview.gui.IProgressIndicator;
-import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
 import jalview.io.StructureFile;
 import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
@@ -322,7 +323,7 @@ public class StructureSelectionManager
    * @return null or the structure data parsed as a pdb file
    */
   synchronized public StructureFile setMapping(SequenceI[] sequence,
-          String[] targetChains, String pdbFile, String protocol)
+          String[] targetChains, String pdbFile, DataSourceType protocol)
   {
     return setMapping(true, sequence, targetChains, pdbFile, protocol);
   }
@@ -341,13 +342,13 @@ public class StructureSelectionManager
    *          (may be nill, individual elements may be nill)
    * @param pdbFile
    *          - structure data resource
-   * @param protocol
+   * @param sourceType
    *          - how to resolve data from resource
    * @return null or the structure data parsed as a pdb file
    */
   synchronized public StructureFile setMapping(boolean forStructureView,
           SequenceI[] sequenceArray, String[] targetChainIds,
-          String pdbFile, String protocol)
+          String pdbFile, DataSourceType sourceType)
   {
     /*
      * There will be better ways of doing this in the future, for now we'll use
@@ -383,15 +384,15 @@ public class StructureSelectionManager
     boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
     try
     {
-      pdb = new JmolParser(pdbFile, protocol);
+      pdb = new JmolParser(pdbFile, sourceType);
 
       if (pdb.getId() != null && pdb.getId().trim().length() > 0
-              && AppletFormatAdapter.FILE.equals(protocol))
+              && DataSourceType.FILE == sourceType)
       {
         registerPDBFile(pdb.getId().trim(), pdbFile);
       }
       // if PDBId is unavailable then skip SIFTS mapping execution path
-      isMapUsingSIFTs = pdb.isPPDBIdAvailable();
+      isMapUsingSIFTs = isMapUsingSIFTs && pdb.isPPDBIdAvailable();
 
     } catch (Exception ex)
     {
@@ -490,12 +491,12 @@ public class StructureSelectionManager
         continue;
       }
 
-      if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
+      if (sourceType == DataSourceType.PASTE)
       {
         pdbFile = "INLINE" + pdb.getId();
       }
 
-      ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
+      List<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
       if (isMapUsingSIFTs && seq.isProtein())
       {
         setProgressBar(null);
@@ -533,7 +534,7 @@ public class StructureSelectionManager
         }
         else
         {
-          ArrayList<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
+          List<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
           for (PDBChain chain : pdb.getChains())
           {
             try
@@ -805,7 +806,7 @@ public class StructureSelectionManager
       return;
     }
 
-    SearchResults results = new SearchResults();
+    SearchResultsI results = new SearchResults();
     for (AtomSpec atom : atoms)
     {
       SequenceI lastseq = null;
@@ -855,7 +856,7 @@ public class StructureSelectionManager
   {
     boolean hasSequenceListeners = handlingVamsasMo
             || !seqmappings.isEmpty();
-    SearchResults results = null;
+    SearchResultsI results = null;
     if (seqPos == -1)
     {
       seqPos = seq.findPosition(indexpos);
index b00f1bc..063eacf 100644 (file)
 package jalview.structures.models;
 
 import jalview.api.StructureSelectionManagerProvider;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
 import jalview.structure.AtomSpec;
 import jalview.structure.StructureListener;
 import jalview.structure.StructureMapping;
@@ -70,7 +72,7 @@ public abstract class AAStructureBindingModel extends
   /*
    * datasource protocol for access to PDBEntrylatest
    */
-  String protocol = null;
+  DataSourceType protocol = null;
 
   protected boolean colourBySequence = true;
 
@@ -135,19 +137,14 @@ public abstract class AAStructureBindingModel extends
    * @param protocol
    */
   public AAStructureBindingModel(StructureSelectionManager ssm,
-          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
-          String protocol)
+          PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
+          DataSourceType protocol)
   {
     this.ssm = ssm;
     this.sequence = sequenceIs;
     this.nucleotide = Comparison.isNucleotide(sequenceIs);
-    this.chains = chains;
     this.pdbEntry = pdbentry;
     this.protocol = protocol;
-    if (chains == null)
-    {
-      this.chains = new String[pdbentry.length][];
-    }
   }
 
   public StructureSelectionManager getSsm()
@@ -207,7 +204,7 @@ public abstract class AAStructureBindingModel extends
     return chains;
   }
 
-  public String getProtocol()
+  public DataSourceType getProtocol()
   {
     return protocol;
   }
@@ -674,4 +671,21 @@ public abstract class AAStructureBindingModel extends
   {
     this.finishedInit = fi;
   }
+
+  /**
+   * Returns a list of chains mapped in this viewer.
+   * 
+   * @return
+   */
+  public abstract List<String> getChainNames();
+
+  /**
+   * Returns the Jalview panel hosting the structure viewer (if any)
+   * 
+   * @return
+   */
+  public JalviewStructureDisplayI getViewer()
+  {
+    return null;
+  }
 }
index 31d1ded..525bfdb 100644 (file)
@@ -142,4 +142,53 @@ public class ColorUtils
             * (maxColour.getBlue() - minColour.getBlue());
     return new Color(r / 255, g / 255, b / 255);
   }
+
+  /**
+   * 'Fades' the given colour towards white by the specified proportion. A
+   * factor of 1 or more results in White, a factor of 0 leaves the colour
+   * unchanged, and a factor between 0 and 1 results in a proportionate change
+   * of RGB values towards (255, 255, 255).
+   * <p>
+   * A negative bleachFactor can be specified to darken the colour towards Black
+   * (0, 0, 0).
+   * 
+   * @param colour
+   * @param bleachFactor
+   * @return
+   */
+  public static Color bleachColour(Color colour, float bleachFactor)
+  {
+    if (bleachFactor >= 1f)
+    {
+      return Color.WHITE;
+    }
+    if (bleachFactor <= -1f)
+    {
+      return Color.BLACK;
+    }
+    if (bleachFactor == 0f)
+    {
+      return colour;
+    }
+
+    int red = colour.getRed();
+    int green = colour.getGreen();
+    int blue = colour.getBlue();
+
+    if (bleachFactor > 0)
+    {
+      red += (255 - red) * bleachFactor;
+      green += (255 - green) * bleachFactor;
+      blue += (255 - blue) * bleachFactor;
+      return new Color(red, green, blue);
+    }
+    else
+    {
+      float factor = 1 + bleachFactor;
+      red *= factor;
+      green *= factor;
+      blue *= factor;
+      return new Color(red, green, blue);
+    }
+  }
 }
index 0beb45b..1326647 100644 (file)
@@ -415,4 +415,29 @@ public class Comparison
             .size()]);
     return isNucleotide(oneDArray);
   }
+
+  /**
+   * Compares two residues either case sensitively or case insensitively
+   * depending on the caseSensitive flag
+   * 
+   * @param c1
+   *          first char
+   * @param c2
+   *          second char to compare with
+   * @param caseSensitive
+   *          if true comparison will be case sensitive otherwise its not
+   * @return
+   */
+  public static boolean isSameResidue(char c1, char c2,
+          boolean caseSensitive)
+  {
+    if (caseSensitive)
+    {
+      return (c1 == c2);
+    }
+    else
+    {
+      return Character.toUpperCase(c1) == Character.toUpperCase(c2);
+    }
+  }
 }
index e6aa472..04cb75e 100755 (executable)
@@ -100,14 +100,14 @@ public class DBRefUtils
     HashSet<String> srcs = new HashSet<String>();
     for (String src : sources)
     {
-      srcs.add(src);
+      srcs.add(src.toUpperCase());
     }
 
     List<DBRefEntry> res = new ArrayList<DBRefEntry>();
     for (DBRefEntry dbr : dbrefs)
     {
       String source = getCanonicalName(dbr.getSource());
-      if (srcs.contains(source))
+      if (srcs.contains(source.toUpperCase()))
       {
         res.add(dbr);
       }
index d14e4ad..389afcd 100755 (executable)
@@ -26,6 +26,8 @@
  */
 package jalview.util;
 
+import java.util.Arrays;
+
 /**
  * DOCUMENT ME!
  * 
@@ -664,30 +666,22 @@ public class Format
   }
 
   /**
-   * DOCUMENT ME!
+   * Returns a string consisting of n repeats of character c
    * 
    * @param c
-   *          DOCUMENT ME!
    * @param n
-   *          DOCUMENT ME!
    * 
-   * @return DOCUMENT ME!
+   * @return
    */
-  private static String repeat(char c, int n)
+  static String repeat(char c, int n)
   {
     if (n <= 0)
     {
       return "";
     }
-
-    StringBuffer s = new StringBuffer(n);
-
-    for (int i = 0; i < n; i++)
-    {
-      s.append(c);
-    }
-
-    return s.toString();
+    char[] chars = new char[n];
+    Arrays.fill(chars, c);
+    return new String(chars);
   }
 
   /**
@@ -947,4 +941,49 @@ public class Format
   {
     return formatString;
   }
+
+  /**
+   * Bespoke method to format percentage float value to the specified number of
+   * decimal places. Avoids use of general-purpose format parsers as a
+   * processing hotspot.
+   * 
+   * @param sb
+   * @param value
+   * @param dp
+   */
+  public static void appendPercentage(StringBuilder sb, float value, int dp)
+  {
+    /*
+     * rounding first
+     */
+    double d = value;
+    long factor = 1L;
+    for (int i = 0; i < dp; i++)
+    {
+      factor *= 10;
+    }
+    d *= factor;
+    d += 0.5;
+
+    /*
+     * integer part
+     */
+    value = (float) (d / factor);
+    sb.append((long) value);
+
+    /*
+     * decimal places
+     */
+    if (dp > 0)
+    {
+      sb.append(".");
+      while (dp > 0)
+      {
+        value = value - (int) value;
+        value *= 10;
+        sb.append((int) value);
+        dp--;
+      }
+    }
+  }
 }
index 9532230..8f8af54 100755 (executable)
@@ -20,6 +20,7 @@
  */
 package jalview.util;
 
+import jalview.bin.Cache;
 import jalview.bin.Jalview;
 import jalview.gui.EPSOptions;
 import jalview.gui.IProgressIndicator;
@@ -42,6 +43,22 @@ import org.jibble.epsgraphics.EpsGraphics2D;
 
 public class ImageMaker
 {
+  public static final String SVG_DESCRIPTION = "Scalable Vector Graphics";
+
+  public static final String SVG_EXTENSION = "svg";
+
+  public static final String EPS_DESCRIPTION = "Encapsulated Postscript";
+
+  public static final String EPS_EXTENSION = "eps";
+
+  public static final String PNG_EXTENSION = "png";
+
+  public static final String PNG_DESCRIPTION = "Portable  network graphics";
+
+  public static final String HTML_EXTENSION = "html";
+
+  public static final String HTML_DESCRIPTION = "Hypertext Markup Language";
+
   EpsGraphics2D pg;
 
   SVGGraphics2D g2;
@@ -181,7 +198,7 @@ public class ImageMaker
         out.close();
         break;
       case PNG:
-        ImageIO.write(bi, "png", out);
+        ImageIO.write(bi, PNG_EXTENSION, out);
         out.flush();
         out.close();
         break;
@@ -293,11 +310,8 @@ public class ImageMaker
     {
       return null;
     }
-    return new jalview.io.JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "png" },
-            new String[] { "Portable network graphics" },
-            "Portable network graphics");
+    return new JalviewFileChooser(Cache.getProperty("LAST_DIRECTORY"),
+            PNG_EXTENSION, PNG_DESCRIPTION);
   }
 
   static JalviewFileChooser getEPSChooser()
@@ -306,11 +320,8 @@ public class ImageMaker
     {
       return null;
     }
-    return new jalview.io.JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "eps" },
-            new String[] { "Encapsulated Postscript" },
-            "Encapsulated Postscript");
+    return new JalviewFileChooser(Cache.getProperty("LAST_DIRECTORY"),
+            EPS_EXTENSION, EPS_DESCRIPTION);
   }
 
   private void setProgressMessage(String message)
@@ -327,10 +338,7 @@ public class ImageMaker
     {
       return null;
     }
-    return new jalview.io.JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "svg" },
-            new String[] { "Scalable Vector Graphics" },
-            "Scalable Vector Graphics");
+    return new JalviewFileChooser(Cache.getProperty("LAST_DIRECTORY"),
+            SVG_EXTENSION, SVG_DESCRIPTION);
   }
 }
index 1fe452d..f35339c 100644 (file)
@@ -31,8 +31,9 @@ import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentOrder;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -194,7 +195,7 @@ public final class MappingUtils
       /*
        * Determine all mappings from this position to mapped sequences.
        */
-      SearchResults sr = buildSearchResults(seq, seqpos, mappings);
+      SearchResultsI sr = buildSearchResults(seq, seqpos, mappings);
 
       if (!sr.isEmpty())
       {
@@ -266,10 +267,10 @@ public final class MappingUtils
    * @param seqmappings
    * @return
    */
-  public static SearchResults buildSearchResults(SequenceI seq, int index,
+  public static SearchResultsI buildSearchResults(SequenceI seq, int index,
           List<AlignedCodonFrame> seqmappings)
   {
-    SearchResults results = new SearchResults();
+    SearchResultsI results = new SearchResults();
     addSearchResults(results, seq, index, seqmappings);
     return results;
   }
@@ -283,7 +284,7 @@ public final class MappingUtils
    * @param index
    * @param seqmappings
    */
-  public static void addSearchResults(SearchResults results, SequenceI seq,
+  public static void addSearchResults(SearchResultsI results, SequenceI seq,
           int index, List<AlignedCodonFrame> seqmappings)
   {
     if (index >= seq.getStart() && index <= seq.getEnd())
@@ -376,15 +377,15 @@ public final class MappingUtils
                */
               List<AlignedCodonFrame> mapping = Arrays
                       .asList(new AlignedCodonFrame[] { acf });
-              SearchResults sr = buildSearchResults(selected,
+              SearchResultsI sr = buildSearchResults(selected,
                       startResiduePos, mapping);
-              for (Match m : sr.getResults())
+              for (SearchResultMatchI m : sr.getResults())
               {
                 mappedStartResidue = m.getStart();
                 mappedEndResidue = m.getEnd();
               }
               sr = buildSearchResults(selected, endResiduePos, mapping);
-              for (Match m : sr.getResults())
+              for (SearchResultMatchI m : sr.getResults())
               {
                 mappedStartResidue = Math.min(mappedStartResidue,
                         m.getStart());
@@ -647,8 +648,8 @@ public final class MappingUtils
        * Get the residue position and find the mapped position.
        */
       int residuePos = fromSeq.findPosition(col);
-      SearchResults sr = buildSearchResults(fromSeq, residuePos, mappings);
-      for (Match m : sr.getResults())
+      SearchResultsI sr = buildSearchResults(fromSeq, residuePos, mappings);
+      for (SearchResultMatchI m : sr.getResults())
       {
         int mappedStartResidue = m.getStart();
         int mappedEndResidue = m.getEnd();
index 3fb384f..49dc7ff 100644 (file)
@@ -30,6 +30,10 @@ import java.awt.event.MouseEvent;
  */
 public class Platform
 {
+  private static Boolean isAMac = null;
+
+  private static Boolean isHeadless = null;
+
   /**
    * sorry folks - Macs really are different
    * 
@@ -37,15 +41,21 @@ public class Platform
    */
   public static boolean isAMac()
   {
-    return java.lang.System.getProperty("os.name").indexOf("Mac") > -1;
+    if (isAMac == null)
+    {
+      isAMac = System.getProperty("os.name").indexOf("Mac") > -1;
+    }
+    return isAMac.booleanValue();
 
   }
 
   public static boolean isHeadless()
   {
-    String hdls = java.lang.System.getProperty("java.awt.headless");
-
-    return hdls != null && hdls.equals("true");
+    if (isHeadless == null)
+    {
+      isHeadless = "true".equals(System.getProperty("java.awt.headless"));
+    }
+    return isHeadless;
   }
 
   /**
@@ -89,8 +99,28 @@ public class Platform
    */
   public static boolean isControlDown(MouseEvent e)
   {
-    if (isAMac())
+    boolean aMac = isAMac();
+    return isControlDown(e, aMac);
+  }
+
+  /**
+   * Overloaded version of method (to allow unit testing)
+   * 
+   * @param e
+   * @param aMac
+   * @return
+   */
+  protected static boolean isControlDown(MouseEvent e, boolean aMac)
+  {
+    if (aMac)
     {
+      /*
+       * answer false for right mouse button
+       */
+      if (e.isPopupTrigger())
+      {
+        return false;
+      }
       return (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() & e
               .getModifiers()) != 0;
       // could we use e.isMetaDown() here?
diff --git a/src/jalview/util/SparseCount.java b/src/jalview/util/SparseCount.java
new file mode 100644 (file)
index 0000000..7fd9792
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+import jalview.ext.android.SparseIntArray;
+import jalview.ext.android.SparseShortArray;
+
+/**
+ * A class to count occurrences of characters with minimal memory footprint.
+ * Sparse arrays of short values are used to hold the counts, with automatic
+ * promotion to arrays of int if any count exceeds the maximum value for a
+ * short.
+ * 
+ * @author gmcarstairs
+ *
+ */
+public class SparseCount
+{
+  private static final int DEFAULT_PROFILE_SIZE = 2;
+
+  /*
+   * array of keys (chars) and values (counts)
+   * held either as shorts or (if shorts overflow) as ints 
+   */
+  private SparseShortArray shortProfile;
+
+  private SparseIntArray intProfile;
+
+  /*
+   * flag is set true after short overflow occurs
+   */
+  private boolean useInts;
+
+  /**
+   * Constructor which initially creates a new sparse array of short values to
+   * hold counts.
+   * 
+   * @param profileSize
+   */
+  public SparseCount(int profileSize)
+  {
+    this.shortProfile = new SparseShortArray(profileSize);
+  }
+
+  /**
+   * Constructor which allocates an initial count array for only two distinct
+   * values (the array will grow if needed)
+   */
+  public SparseCount()
+  {
+    this(DEFAULT_PROFILE_SIZE);
+  }
+
+  /**
+   * Adds the given value for the given key (or sets the initial value), and
+   * returns the new value
+   * 
+   * @param key
+   * @param value
+   */
+  public int add(int key, int value)
+  {
+    int newValue = 0;
+    if (useInts)
+    {
+      newValue = intProfile.add(key, value);
+    }
+    else
+    {
+      try {
+        newValue = shortProfile.add(key, value);
+      } catch (ArithmeticException e) {
+        handleOverflow();
+        newValue = intProfile.add(key, value);
+      }
+    }
+    return newValue;
+  }
+
+  /**
+   * Switch from counting shorts to counting ints
+   */
+  synchronized void handleOverflow()
+  {
+    int size = shortProfile.size();
+    intProfile = new SparseIntArray(size);
+    for (int i = 0; i < size; i++)
+    {
+      short key = shortProfile.keyAt(i);
+      short value = shortProfile.valueAt(i);
+      intProfile.put(key, value);
+    }
+    shortProfile = null;
+    useInts = true;
+  }
+
+  /**
+   * Returns the size of the profile (number of distinct items counted)
+   * 
+   * @return
+   */
+  public int size()
+  {
+    return useInts ? intProfile.size() : shortProfile.size();
+  }
+
+  /**
+   * Returns the value for the key (zero if no such key)
+   * 
+   * @param key
+   * @return
+   */
+  public int get(int key)
+  {
+    return useInts ? intProfile.get(key) : shortProfile.get(key);
+  }
+
+  /**
+   * Sets the value for the given key
+   * 
+   * @param key
+   * @param value
+   */
+  public void put(int key, int value)
+  {
+    if (useInts)
+    {
+      intProfile.put(key, value);
+    }
+    else
+    {
+      shortProfile.put(key, value);
+    }
+  }
+
+  public int keyAt(int k)
+  {
+    return useInts ? intProfile.keyAt(k) : shortProfile.keyAt(k);
+  }
+
+  public int valueAt(int k)
+  {
+    return useInts ? intProfile.valueAt(k) : shortProfile.valueAt(k);
+  }
+
+  /**
+   * Answers true if this object wraps arrays of int values, false if using
+   * short values
+   * 
+   * @return
+   */
+  boolean isUsingInt()
+  {
+    return useInts;
+  }
+}
diff --git a/src/jalview/util/UrlConstants.java b/src/jalview/util/UrlConstants.java
new file mode 100644 (file)
index 0000000..1910bff
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+/**
+ * A class to hold constants relating to Url links used in Jalview
+ */
+public class UrlConstants
+{
+
+  /*
+   * Sequence ID string
+   */
+  public static final String DB_ACCESSION = "DB_ACCESSION";
+
+  /*
+   * Sequence Name string
+   */
+  public static final String SEQUENCE_ID = "SEQUENCE_ID";
+
+  /*
+   * Default sequence URL link string for EMBL-EBI search
+   */
+  public static final String EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+
+  /*
+   * Default sequence URL link string for SRS 
+   */
+  public static final String SRS_STRING = "SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry";
+
+  /*
+   * not instantiable
+   */
+  private UrlConstants()
+  {
+  }
+}
index 4297090..3ee6432 100644 (file)
  */
 package jalview.util;
 
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.SequenceI;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
 import java.util.Vector;
 
 public class UrlLink
@@ -30,17 +39,33 @@ public class UrlLink
    * Jalview 2.4 extension allows regular expressions to be used to parse ID
    * strings and replace the result in the URL. Regex's operate on the whole ID
    * string given to the matchURL method, if no regex is supplied, then only
-   * text following the first pipe symbol will be susbstituted. Usage
+   * text following the first pipe symbol will be substituted. Usage
    * documentation todo.
    */
-  private String url_suffix, url_prefix, target, label, regexReplace;
+
+  // Internal constants
+  private static final String SEP = "|";
+
+  private static final String DELIM = "$";
+
+  private String urlSuffix;
+
+  private String urlPrefix;
+
+  private String target;
+
+  private String label;
+
+  private String regexReplace;
 
   private boolean dynamic = false;
 
+  private boolean usesDBaccession = false;
+
   private String invalidMessage = null;
 
   /**
-   * parse the given linkString of the form '<label>|<url>' into parts url may
+   * parse the given linkString of the form '<label>SEP<url>' into parts url may
    * contain a string $SEQUENCE_ID<=optional regex=>$ where <=optional regex=>
    * must be of the form =/<perl style regex>/=$
    * 
@@ -48,81 +73,37 @@ public class UrlLink
    */
   public UrlLink(String link)
   {
-    int sep = link.indexOf("|"), psqid = link.indexOf("$SEQUENCE_ID");
+    int sep = link.indexOf(SEP);
+    int psqid = link.indexOf(DELIM + DB_ACCESSION);
+    int nsqid = link.indexOf(DELIM + SEQUENCE_ID);
     if (psqid > -1)
     {
       dynamic = true;
-      int p = sep;
-      do
-      {
-        sep = p;
-        p = link.indexOf("|", sep + 1);
-      } while (p > sep && p < psqid);
-      // Assuming that the URL itself does not contain any '|' symbols
-      // sep now contains last pipe symbol position prior to any regex symbols
-      label = link.substring(0, sep);
-      if (label.indexOf("|") > -1)
-      {
-        // | terminated database name / www target at start of Label
-        target = label.substring(0, label.indexOf("|"));
-      }
-      else if (label.indexOf(" ") > 2)
-      {
-        // space separated Label - matches database name
-        target = label.substring(0, label.indexOf(" "));
-      }
-      else
-      {
-        target = label;
-      }
-      // Parse URL : Whole URL string first
-      url_prefix = link.substring(sep + 1, psqid);
-      if (link.indexOf("$SEQUENCE_ID=/") == psqid
-              && (p = link.indexOf("/=$", psqid + 14)) > psqid + 14)
-      {
-        // Extract Regex and suffix
-        url_suffix = link.substring(p + 3);
-        regexReplace = link.substring(psqid + 14, p);
-        try
-        {
-          com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex.perlCode("/"
-                  + regexReplace + "/");
-          if (rg == null)
-          {
-            invalidMessage = "Invalid Regular Expression : '"
-                    + regexReplace + "'\n";
-          }
-        } catch (Exception e)
-        {
-          invalidMessage = "Invalid Regular Expression : '" + regexReplace
-                  + "'\n";
-        }
-      }
-      else
-      {
-        regexReplace = null;
-        // verify format is really correct.
-        if (link.indexOf("$SEQUENCE_ID$") == psqid)
-        {
-          url_suffix = link.substring(psqid + 13);
-          regexReplace = null;
-        }
-        else
-        {
-          invalidMessage = "Warning: invalid regex structure for URL link : "
-                  + link;
-        }
-      }
+      usesDBaccession = true;
+
+      sep = parseTargetAndLabel(sep, psqid, link);
+
+      parseUrl(link, DB_ACCESSION, psqid, sep);
+    }
+    else if (nsqid > -1)
+    {
+      dynamic = true;
+      sep = parseTargetAndLabel(sep, nsqid, link);
+
+      parseUrl(link, SEQUENCE_ID, nsqid, sep);
     }
     else
     {
       target = link.substring(0, sep);
-      label = link.substring(0, sep = link.lastIndexOf("|"));
-      url_prefix = link.substring(sep + 1);
+      sep = link.lastIndexOf(SEP);
+      label = link.substring(0, sep);
+      urlPrefix = link.substring(sep + 1).trim();
       regexReplace = null; // implies we trim any prefix if necessary //
-      // regexReplace=".*\\|?(.*)";
-      url_suffix = null;
+      urlSuffix = null;
     }
+
+    label = label.trim();
+    target = target.trim();
   }
 
   /**
@@ -130,7 +111,7 @@ public class UrlLink
    */
   public String getUrl_suffix()
   {
-    return url_suffix;
+    return urlSuffix;
   }
 
   /**
@@ -138,7 +119,7 @@ public class UrlLink
    */
   public String getUrl_prefix()
   {
-    return url_prefix;
+    return urlPrefix;
   }
 
   /**
@@ -185,6 +166,34 @@ public class UrlLink
   }
 
   /**
+   * 
+   * @return whether link is dynamic
+   */
+  public boolean isDynamic()
+  {
+    return dynamic;
+  }
+
+  /**
+   * 
+   * @return whether link uses DB Accession id
+   */
+  public boolean usesDBAccession()
+  {
+    return usesDBaccession;
+  }
+
+  /**
+   * Set the label
+   * 
+   * @param newlabel
+   */
+  public void setLabel(String newlabel)
+  {
+    this.label = newlabel;
+  }
+
+  /**
    * return one or more URL strings by applying regex to the given idstring
    * 
    * @param idstring
@@ -209,7 +218,7 @@ public class UrlLink
           {
             // take whole regex
             return new String[] { rg.stringMatched(),
-                url_prefix + rg.stringMatched() + url_suffix };
+                urlPrefix + rg.stringMatched() + urlSuffix };
           } /*
              * else if (ns==1) { // take only subgroup match return new String[]
              * { rg.stringMatched(1), url_prefix+rg.stringMatched(1)+url_suffix
@@ -250,7 +259,7 @@ public class UrlLink
                 if (mtch.length() > 0)
                 {
                   subs.addElement(mtch);
-                  subs.addElement(url_prefix + mtch + url_suffix);
+                  subs.addElement(urlPrefix + mtch + urlSuffix);
                 }
                 s = r;
               }
@@ -259,8 +268,8 @@ public class UrlLink
                 if (rg.matchedFrom(s) > -1)
                 {
                   subs.addElement(rg.stringMatched(s));
-                  subs.addElement(url_prefix + rg.stringMatched(s)
-                          + url_suffix);
+                  subs.addElement(urlPrefix + rg.stringMatched(s)
+                          + urlSuffix);
                 }
                 s++;
               }
@@ -281,29 +290,254 @@ public class UrlLink
         }
       }
       /* Otherwise - trim off any 'prefix' - pre 2.4 Jalview behaviour */
-      if (idstring.indexOf("|") > -1)
+      if (idstring.indexOf(SEP) > -1)
       {
-        idstring = idstring.substring(idstring.lastIndexOf("|") + 1);
+        idstring = idstring.substring(idstring.lastIndexOf(SEP) + 1);
       }
 
       // just return simple url substitution.
-      return new String[] { idstring, url_prefix + idstring + url_suffix };
+      return new String[] { idstring, urlPrefix + idstring + urlSuffix };
     }
     else
     {
-      return new String[] { "", url_prefix };
+      return new String[] { "", urlPrefix };
     }
   }
 
+  @Override
   public String toString()
   {
+    String var = (usesDBaccession ? DB_ACCESSION : SEQUENCE_ID);
+
     return label
-            + "|"
-            + url_prefix
-            + (dynamic ? ("$SEQUENCE_ID" + ((regexReplace != null) ? "="
-                    + regexReplace + "=$" : "$")) : "")
-            + ((url_suffix == null) ? "" : url_suffix);
+            + SEP
+            + urlPrefix
+            + (dynamic ? (DELIM + var + ((regexReplace != null) ? "="
+                    + regexReplace + "=" + DELIM : DELIM)) : "")
+            + ((urlSuffix == null) ? "" : urlSuffix);
+  }
+
+  /**
+   * 
+   * @param firstSep
+   *          Location of first occurrence of separator in link string
+   * @param psqid
+   *          Position of sequence id or name in link string
+   * @param link
+   *          Link string containing database name and url
+   * @return Position of last separator symbol prior to any regex symbols
+   */
+  protected int parseTargetAndLabel(int firstSep, int psqid, String link)
+  {
+    int p = firstSep;
+    int sep = firstSep;
+    do
+    {
+      sep = p;
+      p = link.indexOf(SEP, sep + 1);
+    } while (p > sep && p < psqid);
+    // Assuming that the URL itself does not contain any SEP symbols
+    // sep now contains last pipe symbol position prior to any regex symbols
+    label = link.substring(0, sep);
+    if (label.indexOf(SEP) > -1)
+    {
+      // SEP terminated database name / www target at start of Label
+      target = label.substring(0, label.indexOf(SEP));
+    }
+    else if (label.indexOf(" ") > 2)
+    {
+      // space separated Label - matches database name
+      target = label.substring(0, label.indexOf(" "));
+    }
+    else
+    {
+      target = label;
+    }
+    return sep;
+  }
+
+  /**
+   * Parse the URL part of the link string
+   * 
+   * @param link
+   *          Link string containing database name and url
+   * @param varName
+   *          Name of variable in url string (e.g. SEQUENCE_ID, SEQUENCE_NAME)
+   * @param sqidPos
+   *          Position of id or name in link string
+   * @param sep
+   *          Position of separator in link string
+   */
+  protected void parseUrl(String link, String varName, int sqidPos, int sep)
+  {
+    urlPrefix = link.substring(sep + 1, sqidPos).trim();
+
+    // delimiter at start of regex: e.g. $SEQUENCE_ID=/
+    String startDelimiter = DELIM + varName + "=/";
+
+    // delimiter at end of regex: /=$
+    String endDelimiter = "/=" + DELIM;
+
+    int startLength = startDelimiter.length();
+
+    // Parse URL : Whole URL string first
+    int p = link.indexOf(endDelimiter, sqidPos + startLength);
+
+    if (link.indexOf(startDelimiter) == sqidPos
+            && (p > sqidPos + startLength))
+    {
+      // Extract Regex and suffix
+      urlSuffix = link.substring(p + endDelimiter.length());
+      regexReplace = link.substring(sqidPos + startLength, p);
+      try
+      {
+        com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex.perlCode("/"
+                + regexReplace + "/");
+        if (rg == null)
+        {
+          invalidMessage = "Invalid Regular Expression : '" + regexReplace
+                  + "'\n";
+        }
+      } catch (Exception e)
+      {
+        invalidMessage = "Invalid Regular Expression : '" + regexReplace
+                + "'\n";
+      }
+    }
+    else
+    {
+      // no regex
+      regexReplace = null;
+      // verify format is really correct.
+      if (link.indexOf(DELIM + varName + DELIM) == sqidPos)
+      {
+        urlSuffix = link.substring(sqidPos + startLength - 1);
+        regexReplace = null;
+      }
+      else
+      {
+        invalidMessage = "Warning: invalid regex structure for URL link : "
+                + link;
+      }
+    }
+  }
+
+  /**
+   * Create a set of URL links for a sequence
+   * 
+   * @param seq
+   *          The sequence to create links for
+   * @param linkset
+   *          Map of links: key = id + SEP + link, value = [target, label, id,
+   *          link]
+   */
+  public void createLinksFromSeq(final SequenceI seq,
+          Map<String, List<String>> linkset)
+  {
+    if (seq != null && dynamic)
+    {
+      createDynamicLinks(seq, linkset);
+    }
+    else
+    {
+      createStaticLink(linkset);
+    }
+  }
+
+  /**
+   * Create a static URL link
+   * 
+   * @param linkset
+   *          Map of links: key = id + SEP + link, value = [target, label, id,
+   *          link]
+   */
+  protected void createStaticLink(Map<String, List<String>> linkset)
+  {
+    if (!linkset.containsKey(label + SEP + getUrl_prefix()))
+    {
+      // Add a non-dynamic link
+      linkset.put(label + SEP + getUrl_prefix(),
+              Arrays.asList(target, label, null, getUrl_prefix()));
+    }
+  }
+
+  /**
+   * Create dynamic URL links
+   * 
+   * @param seq
+   *          The sequence to create links for
+   * @param linkset
+   *          Map of links: key = id + SEP + link, value = [target, label, id,
+   *          link]
+   */
+  protected void createDynamicLinks(final SequenceI seq,
+          Map<String, List<String>> linkset)
+  {
+    // collect id string too
+    String id = seq.getName();
+    String descr = seq.getDescription();
+    if (descr != null && descr.length() < 1)
+    {
+      descr = null;
+    }
+
+    if (usesDBAccession()) // link is ID
+    {
+      // collect matching db-refs
+      DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
+              new String[] { target });
+
+      // if there are any dbrefs which match up with the link
+      if (dbr != null)
+      {
+        for (int r = 0; r < dbr.length; r++)
+        {
+          // create Bare ID link for this URL
+          createBareURLLink(dbr[r].getAccessionId(), true, linkset);
+        }
+      }
+    }
+    else if (!usesDBAccession() && id != null) // link is name
+    {
+      // create Bare ID link for this URL
+      createBareURLLink(id, false, linkset);
+    }
+
+    // Create urls from description but only for URL links which are regex
+    // links
+    if (descr != null && getRegexReplace() != null)
+    {
+      // create link for this URL from description where regex matches
+      createBareURLLink(descr, false, linkset);
+    }
+  }
 
+  /*
+   * Create a bare URL Link
+   * Returns map where key = id + SEP + link, and value = [target, label, id, link]
+   */
+  protected void createBareURLLink(String id, Boolean combineLabel,
+          Map<String, List<String>> linkset)
+  {
+    String[] urls = makeUrls(id, true);
+    if (urls != null)
+    {
+      for (int u = 0; u < urls.length; u += 2)
+      {
+        if (!linkset.containsKey(urls[u] + SEP + urls[u + 1]))
+        {
+          String thisLabel = label;
+          if (combineLabel)
+          {
+            // incorporate label with idstring
+            thisLabel = label + SEP + urls[u];
+          }
+
+          linkset.put(urls[u] + SEP + urls[u + 1],
+                  Arrays.asList(target, thisLabel, urls[u], urls[u + 1]));
+        }
+      }
+    }
   }
 
   private static void testUrls(UrlLink ul, String idstring, String[] urls)
@@ -341,7 +575,8 @@ public class UrlLink
      * "PF3|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/PFAM:(.+)/=$"
      * , "NOTFER|http://notfer.org/$SEQUENCE_ID=/(?<!\\s)(.+)/=$",
      */
-    "NESTED|http://nested/$SEQUENCE_ID=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
+    "NESTED|http://nested/$" + DB_ACCESSION
+            + "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
     String[] idstrings = new String[] {
     /*
      * //"LGUL_human", //"QWIQW_123123", "uniprot|why_do+_12313_foo",
@@ -382,15 +617,4 @@ public class UrlLink
       }
     }
   }
-
-  public boolean isDynamic()
-  {
-    // TODO Auto-generated method stub
-    return dynamic;
-  }
-
-  public void setLabel(String newlabel)
-  {
-    this.label = newlabel;
-  }
 }
index c1c88c1..fecccb0 100644 (file)
@@ -36,7 +36,8 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenSequences;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceGroup;
@@ -700,7 +701,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   /**
    * results of alignment consensus analysis for visible portion of view
    */
-  protected Hashtable[] hconsensus = null;
+  protected ProfilesI hconsensus = null;
 
   /**
    * results of cDNA complement consensus visible portion of view
@@ -734,7 +735,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public void setSequenceConsensusHash(Hashtable[] hconsensus)
+  public void setSequenceConsensusHash(ProfilesI hconsensus)
   {
     this.hconsensus = hconsensus;
   }
@@ -746,7 +747,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public Hashtable[] getSequenceConsensusHash()
+  public ProfilesI getSequenceConsensusHash()
   {
     return hconsensus;
   }
@@ -939,7 +940,9 @@ public abstract class AlignmentViewport implements AlignViewportI,
     groupConservation = null;
     hconsensus = null;
     hcomplementConsensus = null;
-    // TODO removed listeners from changeSupport?
+    // colour scheme may hold reference to consensus
+    globalColourScheme = null;
+    // TODO remove listeners from changeSupport?
     changeSupport = null;
     setAlignment(null);
   }
@@ -1864,7 +1867,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
       cs.setConsensus(hconsensus);
       if (cs.conservationApplied())
       {
-        cs.setConservation(Conservation.calculateConservation("All", 3,
+        cs.setConservation(Conservation.calculateConservation("All",
                 alignment.getSequences(), 0, alignment.getWidth(), false,
                 getConsPercGaps(), false));
       }
@@ -2715,7 +2718,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    *          the SearchResults to add to
    * @return the offset (below top of visible region) of the matched sequence
    */
-  protected int findComplementScrollTarget(SearchResults sr)
+  protected int findComplementScrollTarget(SearchResultsI sr)
   {
     final AlignViewportI complement = getCodingComplement();
     if (complement == null || !complement.isFollowHighlight())
@@ -2822,6 +2825,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    */
   private boolean selectionIsDefinedGroup = false;
 
+
   @Override
   public boolean isSelectionDefinedGroup()
   {
@@ -2845,4 +2849,27 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return selectionGroup.getContext() == alignment
             || selectionIsDefinedGroup;
   }
+
+  /**
+   * null, or currently highlighted results on this view
+   */
+  private SearchResultsI searchResults = null;
+
+  @Override
+  public boolean hasSearchResults()
+  {
+    return searchResults != null;
+  }
+
+  @Override
+  public void setSearchResults(SearchResultsI results)
+  {
+    searchResults = results;
+  }
+
+  @Override
+  public SearchResultsI getSearchResults()
+  {
+    return searchResults;
+  }
 }
index 4ac4804..c1ad465 100644 (file)
@@ -288,8 +288,12 @@ public abstract class FeatureRendererModel implements
           continue;
         }
 
-        if ((features[i].getBegin() <= res)
-                && (features[i].getEnd() >= res))
+        // check if start/end are at res, and if not a contact feature, that res
+        // lies between start and end
+        if ((features[i].getBegin() == res || features[i].getEnd() == res)
+                || (!features[i].isContactFeature()
+                        && (features[i].getBegin() < res) && (features[i]
+                        .getEnd() >= res)))
         {
           tmp.add(features[i]);
         }
@@ -564,9 +568,16 @@ public abstract class FeatureRendererModel implements
     return fc.isColored(sequenceFeature);
   }
 
+  /**
+   * Answers true if the feature type is currently selected to be displayed,
+   * else false
+   * 
+   * @param type
+   * @return
+   */
   protected boolean showFeatureOfType(String type)
   {
-    return av.getFeaturesDisplayed().isVisible(type);
+    return type == null ? false : av.getFeaturesDisplayed().isVisible(type);
   }
 
   @Override
index 529df6f..431fbec 100644 (file)
@@ -96,7 +96,6 @@ public class ComplementConsensusThread extends ConsensusThread
    * @param consensusData
    *          the computed consensus data
    */
-  @Override
   protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
           Hashtable[] consensusData)
   {
@@ -104,4 +103,16 @@ public class ComplementConsensusThread extends ConsensusThread
             alignViewport.isShowSequenceLogo(), getSequences().length);
   }
 
+  @Override
+  public void updateResultAnnotation(boolean immediate)
+  {
+    AlignmentAnnotation consensus = getConsensusAnnotation();
+    Hashtable[] hconsensus = getViewportConsensus();
+    if (immediate || !calcMan.isWorking(this) && consensus != null
+            && hconsensus != null)
+    {
+      deriveConsensus(consensus, hconsensus);
+    }
+  }
+
 }
index 5f0ec84..debe45d 100644 (file)
@@ -26,11 +26,10 @@ import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ColourSchemeI;
 
-import java.util.Hashtable;
-
 public class ConsensusThread extends AlignCalcWorker
 {
   public ConsensusThread(AlignViewportI alignViewport,
@@ -125,10 +124,11 @@ public class ConsensusThread extends AlignCalcWorker
    */
   protected void computeConsensus(AlignmentI alignment)
   {
-    Hashtable[] hconsensus = new Hashtable[alignment.getWidth()];
 
     SequenceI[] aseqs = getSequences();
-    AAFrequency.calculate(aseqs, 0, alignment.getWidth(), hconsensus, true);
+    int width = alignment.getWidth();
+    ProfilesI hconsensus = AAFrequency.calculate(aseqs, width, 0,
+            width, true);
 
     alignViewport.setSequenceConsensusHash(hconsensus);
     setColourSchemeConsensus(hconsensus);
@@ -145,7 +145,7 @@ public class ConsensusThread extends AlignCalcWorker
   /**
    * @param hconsensus
    */
-  protected void setColourSchemeConsensus(Hashtable[] hconsensus)
+  protected void setColourSchemeConsensus(ProfilesI hconsensus)
   {
     ColourSchemeI globalColourScheme = alignViewport
             .getGlobalColourScheme();
@@ -178,7 +178,7 @@ public class ConsensusThread extends AlignCalcWorker
   public void updateResultAnnotation(boolean immediate)
   {
     AlignmentAnnotation consensus = getConsensusAnnotation();
-    Hashtable[] hconsensus = getViewportConsensus();
+    ProfilesI hconsensus = (ProfilesI) getViewportConsensus();
     if (immediate || !calcMan.isWorking(this) && consensus != null
             && hconsensus != null)
     {
@@ -192,15 +192,18 @@ public class ConsensusThread extends AlignCalcWorker
    * 
    * @param consensusAnnotation
    *          the annotation to be populated
-   * @param consensusData
+   * @param hconsensus
    *          the computed consensus data
    */
   protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
-          Hashtable[] consensusData)
+          ProfilesI hconsensus)
   {
+
     long nseq = getSequences().length;
-    AAFrequency.completeConsensus(consensusAnnotation, consensusData, 0,
-            consensusData.length, alignViewport.isIgnoreGapsConsensus(),
+    AAFrequency.completeConsensus(consensusAnnotation, hconsensus,
+            hconsensus.getStartColumn(),
+            hconsensus.getEndColumn() + 1,
+            alignViewport.isIgnoreGapsConsensus(),
             alignViewport.isShowSequenceLogo(), nseq);
   }
 
@@ -209,8 +212,9 @@ public class ConsensusThread extends AlignCalcWorker
    * 
    * @return
    */
-  protected Hashtable[] getViewportConsensus()
+  protected Object getViewportConsensus()
   {
+    // TODO convert ComplementConsensusThread to use Profile
     return alignViewport.getSequenceConsensusHash();
   }
 }
index 11ec521..e71c4f5 100644 (file)
@@ -94,7 +94,7 @@ public class ConservationThread extends AlignCalcWorker
       }
       try
       {
-        cons = Conservation.calculateConservation("All", 3,
+        cons = Conservation.calculateConservation("All",
                 alignment.getSequences(), 0, alWidth - 1, false,
                 ConsPercGaps, quality != null);
       } catch (IndexOutOfBoundsException x)
index 7e069e3..676a4b6 100644 (file)
@@ -28,6 +28,7 @@ import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
 import jalview.gui.FeatureSettings;
+import jalview.gui.JvOptionPane;
 import jalview.util.DBRefUtils;
 import jalview.util.MessageManager;
 import jalview.util.UrlLink;
@@ -46,8 +47,6 @@ import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
-import javax.swing.JOptionPane;
-
 import org.biodas.jdas.client.FeaturesClient;
 import org.biodas.jdas.client.adapters.features.DasGFFAdapter;
 import org.biodas.jdas.client.adapters.features.DasGFFAdapter.GFFAdapter;
@@ -200,21 +199,21 @@ public class DasSequenceFeatureFetcher
     if (checkDbrefs && refCount < sequences.length && uniprotCount > 0)
     {
 
-      int reply = JOptionPane.YES_OPTION;
+      int reply = JvOptionPane.YES_OPTION;
       if (promptFetchDbrefs)
       {
-        reply = JOptionPane
+        reply = JvOptionPane
                 .showInternalConfirmDialog(
                         Desktop.desktop,
                         MessageManager
                                 .getString("info.you_want_jalview_to_find_uniprot_accessions"),
                         MessageManager
                                 .getString("label.find_uniprot_accession_ids"),
-                        JOptionPane.YES_NO_OPTION,
-                        JOptionPane.QUESTION_MESSAGE);
+                        JvOptionPane.YES_NO_OPTION,
+                        JvOptionPane.QUESTION_MESSAGE);
       }
 
-      if (reply == JOptionPane.YES_OPTION)
+      if (reply == JvOptionPane.YES_OPTION)
       {
         Thread thread = new Thread(new FetchDBRefs());
         thread.start();
index b139574..b2fb808 100644 (file)
@@ -64,7 +64,7 @@ public abstract class EmblXmlSource extends EbiFileRetrievedProxy
     {
       reply = dbFetch.fetchDataAsFile(
               emprefx.toLowerCase() + ":" + query.trim(), "display=xml",
-              ".xml");
+              "xml");
     } catch (Exception e)
     {
       stopQuery();
index 11fe95e..982c399 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
  * Copyright (C) $$Year-Rel$$ The Jalview Authors
@@ -28,12 +29,16 @@ import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
 import jalview.io.PDBFeatureSettings;
 import jalview.structure.StructureImportSettings;
 import jalview.util.MessageManager;
 import jalview.ws.ebi.EBIFetchClient;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -137,13 +142,19 @@ public class Pdb extends EbiFileRetrievedProxy
       stopQuery();
       return null;
     }
-    String ext = StructureImportSettings.getDefaultStructureFileFormat()
-            .equalsIgnoreCase(Type.MMCIF.toString()) ? ".cif" : ".xml";
+
+    /*
+     * ensure that an mmCIF format structure file is saved with extension.cif,
+     * because the Chimera "open" command recognises this extension
+     */
+    Type pdbFileFormat = StructureImportSettings
+            .getDefaultStructureFileFormat();
+    String ext = pdbFileFormat.getExtension();
+    String fetchFormat = pdbFileFormat.getFormat();
+
     EBIFetchClient ebi = new EBIFetchClient();
-    file = ebi.fetchDataAsFile(
-            "pdb:" + id,
-            StructureImportSettings.getDefaultStructureFileFormat()
-                    .toLowerCase(), ext).getAbsolutePath();
+    File tmpFile = ebi.fetchDataAsFile("pdb:" + id, fetchFormat, ext);
+    file = tmpFile.getAbsolutePath();
     stopQuery();
     if (file == null)
     {
@@ -151,10 +162,11 @@ public class Pdb extends EbiFileRetrievedProxy
     }
     try
     {
-
+      // todo get rid of Type and use FileFormatI instead?
+      FileFormatI fileFormat = (pdbFileFormat == Type.PDB) ? FileFormat.PDB
+              : FileFormat.MMCif;
       pdbAlignment = new FormatAdapter().readFile(file,
-              jalview.io.AppletFormatAdapter.FILE,
-              StructureImportSettings.getDefaultStructureFileFormat());
+              DataSourceType.FILE, fileFormat);
       if (pdbAlignment != null)
       {
         List<SequenceI> toremove = new ArrayList<SequenceI>();
index 9acaa96..941bf1a 100644 (file)
@@ -23,6 +23,8 @@ package jalview.ws.dbsources;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 
 import com.stevesoft.pat.Regex;
@@ -119,8 +121,8 @@ abstract public class Pfam extends Xfam
     // retrieved.
     startQuery();
     AlignmentI rcds = new FormatAdapter().readFile(getXFAMURL()
-            + queries.trim().toUpperCase(), jalview.io.FormatAdapter.URL,
-            "STH");
+            + queries.trim().toUpperCase(), DataSourceType.URL,
+            FileFormat.Stockholm);
     for (int s = 0, sNum = rcds.getHeight(); s < sNum; s++)
     {
       rcds.getSequenceAt(s).addDBRef(new DBRefEntry(DBRefSource.PFAM,
index b6f53cd..3afe8ec 100644 (file)
@@ -165,7 +165,7 @@ public class Uniprot extends DbSourceProxyImpl
       // uniprotxml parameter required since december 2007
       // uniprotkb dbname changed introduced december 2008
       File file = ebi.fetchDataAsFile("uniprotkb:" + queries, "uniprotxml",
-              ".xml");
+              "xml");
       Vector<UniprotEntry> entries = getUniprotEntries(new FileReader(file));
 
       if (entries != null)
index 6cc383d..3554f01 100644 (file)
@@ -22,6 +22,8 @@ package jalview.ws.dbsources;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 import jalview.ws.seqfetcher.DbSourceProxyImpl;
 
@@ -56,7 +58,7 @@ public abstract class Xfam extends DbSourceProxyImpl
     // TODO: trap HTTP 404 exceptions and return null
     AlignmentI rcds = new FormatAdapter().readFile(getXFAMURL()
             + queries.trim().toUpperCase() + getXFAMURLSUFFIX(),
-            jalview.io.FormatAdapter.URL, "STH");
+            DataSourceType.URL, FileFormat.Stockholm);
     for (int s = 0, sNum = rcds.getHeight(); s < sNum; s++)
     {
       rcds.getSequenceAt(s).addDBRef(new DBRefEntry(getXfamSource(),
index f6928c4..3e8c55e 100644 (file)
@@ -91,7 +91,7 @@ public class EBIFetchClient
    * @param format
    *          the format wanted
    * @param extension
-   *          for the temporary file to hold response
+   *          for the temporary file to hold response (without separator)
    * @return the file holding the response
    * @throws OutOfMemoryError
    */
@@ -102,7 +102,7 @@ public class EBIFetchClient
     File outFile = null;
     try
     {
-      outFile = File.createTempFile("jalview", ext);
+      outFile = File.createTempFile("jalview", "." + ext);
       outFile.deleteOnExit();
       fetchData(ids, format, outFile);
       if (outFile.length() == 0)
index 8c30c69..bae0357 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.ws.jws1;
 
 import jalview.datamodel.AlignmentI;
+import jalview.io.FileFormat;
 import jalview.io.FileParse;
 import jalview.io.FormatAdapter;
 import jalview.io.InputStreamParser;
@@ -86,7 +87,8 @@ public class Annotate3D
       while (r.hasNext())
       {
         FileParse fp = new InputStreamParser(r.next(), source.getDataName());
-        AlignmentI nal = new FormatAdapter().readFromFile(fp, "RNAML");
+        AlignmentI nal = new FormatAdapter().readFromFile(fp,
+                FileFormat.Rnaml);
         if (al == null)
         {
           al = nal;
index b30f6cb..ba4054e 100644 (file)
  */
 package jalview.ws.jws1;
 
+import jalview.gui.JvOptionPane;
 import jalview.util.MessageManager;
 
 import java.util.Hashtable;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
-import javax.swing.JOptionPane;
-
 import ext.vamsas.IRegistry;
 import ext.vamsas.IRegistryServiceLocator;
 import ext.vamsas.RegistryServiceSoapBindingStub;
@@ -255,11 +254,11 @@ public class Discoverer implements Runnable
       {
         if (jalview.gui.Desktop.desktop != null)
         {
-          JOptionPane.showMessageDialog(jalview.gui.Desktop.desktop,
+          JvOptionPane.showMessageDialog(jalview.gui.Desktop.desktop,
                   MessageManager.getString("label.set_proxy_settings"),
                   MessageManager
                           .getString("label.proxy_authorization_failed"),
-                  JOptionPane.WARNING_MESSAGE);
+                  JvOptionPane.WARNING_MESSAGE);
         }
       }
       else
index b20a100..65847e6 100644 (file)
@@ -27,6 +27,7 @@ import jalview.datamodel.SeqCigar;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
 import jalview.gui.WebserviceInfo;
 import jalview.util.MessageManager;
 
@@ -36,7 +37,6 @@ import java.util.Hashtable;
 
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 
 import ext.vamsas.Jpred;
 import ext.vamsas.JpredServiceLocator;
@@ -323,7 +323,7 @@ public class JPredClient extends WS1Client
 
     } catch (Exception ex)
     {
-      JOptionPane
+      JvOptionPane
               .showMessageDialog(
                       Desktop.desktop,
                       MessageManager
@@ -332,7 +332,7 @@ public class JPredClient extends WS1Client
                                       new String[] { WebServiceName, WsURL }),
                       MessageManager
                               .getString("label.internal_jalview_error"),
-                      JOptionPane.WARNING_MESSAGE);
+                      JvOptionPane.WARNING_MESSAGE);
       wsInfo.setProgressText(MessageManager
               .formatMessage(
                       "label.secondary_structure_prediction_service_couldnt_be_located",
index 8299e3c..4e5cadc 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.ws.jws1;
 
 import jalview.analysis.AlignSeq;
+import jalview.analysis.SeqsetUtils;
 import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
@@ -31,7 +32,13 @@ import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
 import jalview.gui.WebserviceInfo;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
+import jalview.io.IdentifyFile;
+import jalview.io.JPredFile;
+import jalview.io.JnetAnnotationMaker;
+import jalview.io.PileUpfile;
 import jalview.util.Comparison;
 import jalview.util.MessageManager;
 import jalview.ws.AWsJob;
@@ -71,6 +78,7 @@ class JPredThread extends JWS1Thread implements WSClientI
      * @return true if getResultSet will return a valid alignment and prediction
      *         result.
      */
+    @Override
     public boolean hasResults()
     {
       if (subjobComplete && result != null && result.isFinished()
@@ -82,6 +90,7 @@ class JPredThread extends JWS1Thread implements WSClientI
       return false;
     }
 
+    @Override
     public boolean hasValidInput()
     {
       if (sequence != null)
@@ -110,23 +119,23 @@ class JPredThread extends JWS1Thread implements WSClientI
 
       JpredResult result = (JpredResult) this.result;
 
-      jalview.bin.Cache.log.debug("Parsing output from JNet job.");
+      Cache.log.debug("Parsing output from JNet job.");
       // JPredFile prediction = new JPredFile("C:/JalviewX/files/jpred.txt",
       // "File");
-      jalview.io.JPredFile prediction = new jalview.io.JPredFile(
-              result.getPredfile(), "Paste");
+      JPredFile prediction = new JPredFile(
+              result.getPredfile(), DataSourceType.PASTE);
       SequenceI[] preds = prediction.getSeqsAsArray();
-      jalview.bin.Cache.log.debug("Got prediction profile.");
+      Cache.log.debug("Got prediction profile.");
 
       if ((this.msa != null) && (result.getAligfile() != null))
       {
-        jalview.bin.Cache.log.debug("Getting associated alignment.");
+        Cache.log.debug("Getting associated alignment.");
         // we ignore the returned alignment if we only predicted on a single
         // sequence
-        String format = new jalview.io.IdentifyFile().identify(
-                result.getAligfile(), "Paste");
+        FileFormatI format = new IdentifyFile().identify(
+                result.getAligfile(), DataSourceType.PASTE);
 
-        if (jalview.io.FormatAdapter.isValidFormat(format))
+        if (format != null)
         {
           SequenceI sqs[];
           if (predMap != null)
@@ -140,14 +149,14 @@ class JPredThread extends JWS1Thread implements WSClientI
           else
           {
             al = new FormatAdapter().readFile(result.getAligfile(),
-                    "Paste", format);
+                    DataSourceType.PASTE, format);
             sqs = new SequenceI[al.getHeight()];
 
             for (int i = 0, j = al.getHeight(); i < j; i++)
             {
               sqs[i] = al.getSequenceAt(i);
             }
-            if (!jalview.analysis.SeqsetUtils.deuniquify(SequenceInfo, sqs))
+            if (!SeqsetUtils.deuniquify(SequenceInfo, sqs))
             {
               throw (new Exception(
                       MessageManager
@@ -164,7 +173,7 @@ class JPredThread extends JWS1Thread implements WSClientI
           {
             al.setDataset(null);
           }
-          jalview.io.JnetAnnotationMaker.add_annotation(prediction, al,
+          JnetAnnotationMaker.add_annotation(prediction, al,
                   FirstSeq, false, predMap);
 
         }
@@ -172,7 +181,7 @@ class JPredThread extends JWS1Thread implements WSClientI
         {
           throw (new Exception(MessageManager.formatMessage(
                   "exception.unknown_format_for_file", new String[] {
-                      format, result.getAligfile() })));
+                      format.toString(), result.getAligfile() })));
         }
       }
       else
@@ -355,8 +364,8 @@ class JPredThread extends JWS1Thread implements WSClientI
         if (msf.length > 1)
         {
           msa = new vamsas.objects.simple.Msfalignment();
-          jalview.io.PileUpfile pileup = new jalview.io.PileUpfile();
-          msa.setMsf(pileup.print(msf));
+          PileUpfile pileup = new PileUpfile();
+          msa.setMsf(pileup.print(msf, true));
         }
       }
     }
@@ -420,6 +429,7 @@ class JPredThread extends JWS1Thread implements WSClientI
     }
   }
 
+  @Override
   public void StartJob(AWsJob j)
   {
     if (!(j instanceof JPredJob))
@@ -502,6 +512,7 @@ class JPredThread extends JWS1Thread implements WSClientI
     }
   }
 
+  @Override
   public void parseResult()
   {
     int results = 0; // number of result sets received
@@ -529,6 +540,7 @@ class JPredThread extends JWS1Thread implements WSClientI
       wsInfo.showResultsNewFrame
               .addActionListener(new java.awt.event.ActionListener()
               {
+                @Override
                 public void actionPerformed(java.awt.event.ActionEvent evt)
                 {
                   displayResults(true);
@@ -537,6 +549,7 @@ class JPredThread extends JWS1Thread implements WSClientI
       wsInfo.mergeResults
               .addActionListener(new java.awt.event.ActionListener()
               {
+                @Override
                 public void actionPerformed(java.awt.event.ActionEvent evt)
                 {
                   displayResults(false);
@@ -652,21 +665,25 @@ class JPredThread extends JWS1Thread implements WSClientI
     }
   }
 
+  @Override
   public void pollJob(AWsJob job) throws Exception
   {
     ((JPredJob) job).result = server.getresult(job.getJobId());
   }
 
+  @Override
   public boolean isCancellable()
   {
     return false;
   }
 
+  @Override
   public void cancelJob()
   {
     throw new Error(MessageManager.getString("error.implementation_error"));
   }
 
+  @Override
   public boolean canMergeResults()
   {
     return false;
index aad72b1..5ea553e 100644 (file)
@@ -24,6 +24,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
 import jalview.gui.WebserviceInfo;
 import jalview.util.MessageManager;
 
@@ -32,7 +33,6 @@ import java.awt.event.ActionListener;
 
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 
 import ext.vamsas.MuscleWSServiceLocator;
 import ext.vamsas.MuscleWSSoapBindingStub;
@@ -78,22 +78,22 @@ public class MsaWSClient extends WS1Client
     alignFrame = _alignFrame;
     if (!sh.getAbstractName().equals("MsaWS"))
     {
-      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.service_called_is_not_msa_service",
                       new String[] { sh.getName() }), MessageManager
               .getString("label.internal_jalview_error"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
 
       return;
     }
 
     if ((wsInfo = setWebService(sh)) == null)
     {
-      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.msa_service_is_unknown",
                       new String[] { sh.getName() }), MessageManager
               .getString("label.internal_jalview_error"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
 
       return;
     }
index 7665fec..92d17e8 100644 (file)
@@ -24,6 +24,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
 import jalview.gui.WebserviceInfo;
 import jalview.util.MessageManager;
 
@@ -37,7 +38,6 @@ import java.util.Vector;
 
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 
 import ext.vamsas.SeqSearchServiceLocator;
 import ext.vamsas.SeqSearchServiceSoapBindingStub;
@@ -84,23 +84,23 @@ public class SeqSearchWSClient extends WS1Client
     // name to service client name
     if (!sh.getAbstractName().equals(this.getServiceActionKey()))
     {
-      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
               .formatMessage(
                       "label.service_called_is_not_seq_search_service",
                       new String[] { sh.getName() }), MessageManager
               .getString("label.internal_jalview_error"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
 
       return;
     }
 
     if ((wsInfo = setWebService(sh)) == null)
     {
-      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.seq_search_service_is_unknown",
                       new String[] { sh.getName() }), MessageManager
               .getString("label.internal_jalview_error"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
 
       return;
     }
index 70056a6..b14917e 100644 (file)
@@ -209,7 +209,7 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
           if (inFile != null && inFile.length() > 0)
           {
             new jalview.io.AnnotationFile().readAnnotationFile(al, inFile,
-                    jalview.io.AppletFormatAdapter.PASTE);
+                    jalview.io.DataSourceType.PASTE);
           }
         } catch (Exception e)
         {
@@ -225,7 +225,7 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
           if (inFile != null && inFile.length() > 0)
           {
             jalview.io.FeaturesFile ff = new jalview.io.FeaturesFile(
-                    inFile, jalview.io.AppletFormatAdapter.PASTE);
+                    inFile, jalview.io.DataSourceType.PASTE);
             ff.parse(al, featureColours, false);
           }
         } catch (Exception e)
@@ -242,7 +242,7 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
           if (inFile != null && inFile.length() > 0)
           {
             nf = new jalview.io.NewickFile(inFile,
-                    jalview.io.AppletFormatAdapter.PASTE);
+                    jalview.io.DataSourceType.PASTE);
             if (!nf.isValid())
             {
               nf.close();
index 8fa118d..b723059 100644 (file)
@@ -24,6 +24,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
 import jalview.gui.JvSwingUtils;
 import jalview.util.MessageManager;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
@@ -37,7 +38,6 @@ import java.util.List;
 
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 import javax.swing.ToolTipManager;
 
 import compbio.data.msa.MsaWS;
@@ -107,22 +107,22 @@ public class MsaWSClient extends Jws2Client
     if (!(sh.service instanceof MsaWS))
     {
       // redundant at mo - but may change
-      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.service_called_is_not_msa_service",
                       new String[] { sh.serviceType }), MessageManager
               .getString("label.internal_jalview_error"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
 
       return;
     }
     server = (MsaWS) sh.service;
     if ((wsInfo = setWebService(sh, false)) == null)
     {
-      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.msa_service_is_unknown",
                       new String[] { sh.serviceType }), MessageManager
               .getString("label.internal_jalview_error"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
 
       return;
     }
@@ -180,10 +180,10 @@ public class MsaWSClient extends Jws2Client
     }
     else
     {
-      JOptionPane.showMessageDialog(alignFrame,
+      JvOptionPane.showMessageDialog(alignFrame,
               MessageManager.getString("info.invalid_msa_input_mininfo"),
               MessageManager.getString("info.invalid_msa_notenough"),
-              JOptionPane.INFORMATION_MESSAGE);
+              JvOptionPane.INFORMATION_MESSAGE);
       wsInfo.setVisible(false);
     }
   }
index 2af31bb..4702686 100644 (file)
@@ -67,9 +67,9 @@ public class SequenceAnnotationWSClient extends Jws2Client
     // dan changed! dan test. comment out if conditional
     // if (alignFrame.getViewport().getAlignment().isNucleotide())
     // {
-    // JOptionPane.showMessageDialog(Desktop.desktop, sh.serviceType
+    // JvOptionPane.showMessageDialog(Desktop.desktop, sh.serviceType
     // + " can only be used\nfor amino acid alignments.",
-    // "Wrong type of sequences!", JOptionPane.WARNING_MESSAGE);
+    // "Wrong type of sequences!", JvOptionPane.WARNING_MESSAGE);
     // return;
     //
     // }
index 1fb9259..7fbae89 100644 (file)
@@ -26,6 +26,7 @@ import jalview.gui.AlignFrame;
 import jalview.gui.AlignViewport;
 import jalview.gui.AlignmentPanel;
 import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
 import jalview.gui.WebserviceInfo;
 import jalview.io.packed.DataProvider.JvDataType;
 import jalview.util.MessageManager;
@@ -40,7 +41,6 @@ import java.util.Vector;
 
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
 import javax.swing.event.MenuEvent;
 import javax.swing.event.MenuListener;
 
@@ -324,7 +324,7 @@ public class RestClient extends WSClient implements WSClientI,
     else
     {
       // TODO: try to tell the user why the job couldn't be started.
-      JOptionPane
+      JvOptionPane
               .showMessageDialog(
                       Desktop.desktop,
                       (jobsthread.hasWarnings() ? jobsthread.getWarnings()
@@ -332,7 +332,7 @@ public class RestClient extends WSClient implements WSClientI,
                                       .getString("label.job_couldnt_be_started_check_input")),
                       MessageManager
                               .getString("label.unable_start_web_service_analysis"),
-                      JOptionPane.WARNING_MESSAGE);
+                      JvOptionPane.WARNING_MESSAGE);
     }
   }
 
index 18c1ad0..08a242d 100644 (file)
@@ -21,6 +21,9 @@
 package jalview.ws.rest.params;
 
 import jalview.datamodel.AlignmentI;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
+import jalview.io.FormatAdapter;
 import jalview.ws.params.OptionI;
 import jalview.ws.params.simple.BooleanOption;
 import jalview.ws.params.simple.Option;
@@ -35,7 +38,6 @@ import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 import org.apache.http.entity.mime.content.ContentBody;
@@ -55,7 +57,7 @@ public class Alignment extends InputType
     super(new Class[] { AlignmentI.class });
   }
 
-  String format = "FASTA";
+  FileFormatI format = FileFormat.Fasta;
 
   molType type;
 
@@ -79,7 +81,7 @@ public class Alignment extends InputType
         PrintWriter pw = new PrintWriter(
                 new OutputStreamWriter(new BufferedOutputStream(
                         new FileOutputStream(fa)), "UTF-8"));
-        pw.append(new jalview.io.FormatAdapter().formatSequences(format,
+        pw.append(new FormatAdapter().formatSequences(format,
                 alignment, jvsuffix));
         pw.close();
         return new FileBody(fa, "text/plain");
@@ -91,7 +93,7 @@ public class Alignment extends InputType
     }
     else
     {
-      jalview.io.FormatAdapter fa = new jalview.io.FormatAdapter();
+      FormatAdapter fa = new FormatAdapter();
       fa.setNewlineString("\r\n");
       return new StringBody(
               (fa.formatSequences(format, alignment, jvsuffix)));
@@ -115,12 +117,10 @@ public class Alignment extends InputType
     {
       prms.add("jvsuffix");
     }
-    ;
     if (writeAsFile)
     {
       prms.add("writeasfile");
     }
-    ;
     return prms;
   }
 
@@ -147,9 +147,9 @@ public class Alignment extends InputType
 
     if (tok.startsWith("format"))
     {
-      for (String fmt : jalview.io.FormatAdapter.WRITEABLE_FORMATS)
+      for (FileFormatI fmt : FileFormat.values())
       {
-        if (val.equalsIgnoreCase(fmt))
+        if (fmt.isWritable() && val.equalsIgnoreCase(fmt.toString()))
         {
           format = fmt;
           return true;
@@ -157,9 +157,12 @@ public class Alignment extends InputType
       }
       warnings.append("Invalid alignment format '" + val
               + "'. Must be one of (");
-      for (String fmt : jalview.io.FormatAdapter.WRITEABLE_FORMATS)
+      for (FileFormatI fmt : FileFormat.values())
       {
-        warnings.append(" " + fmt);
+        if (fmt.isWritable())
+        {
+          warnings.append(" " + fmt).toString();
+        }
       }
       warnings.append(")\n");
     }
@@ -194,13 +197,28 @@ public class Alignment extends InputType
             "Append jalview style /start-end suffix to ID", false, false,
             writeAsFile, null));
 
-    lst.add(new Option("format", "Alignment upload format", true, "FASTA",
-            format, Arrays
-                    .asList(jalview.io.FormatAdapter.WRITEABLE_FORMATS),
+    lst.add(new Option("format", "Alignment upload format", true,
+            FileFormat.Fasta.toString(), format.toString(), getWritableFormats(),
             null));
     lst.add(createMolTypeOption("type", "Sequence type", false, type, null));
 
     return lst;
   }
 
+  /**
+   * @return
+   */
+  protected List<String> getWritableFormats()
+  {
+    List<String> formats = new ArrayList<String>();
+    for (FileFormatI ff : FileFormat.values())
+    {
+      if (ff.isWritable())
+      {
+        formats.add(ff.toString());
+      }
+    }
+    return formats;
+  }
+
 }
index 5bed720..2fcf501 100644 (file)
@@ -22,6 +22,8 @@ package jalview.ws.seqfetcher;
 
 import jalview.api.FeatureSettingsModelI;
 import jalview.datamodel.AlignmentI;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
 import jalview.io.IdentifyFile;
 
@@ -92,10 +94,12 @@ public abstract class DbSourceProxyImpl implements DbSourceProxy
   protected AlignmentI parseResult(String result) throws Exception
   {
     AlignmentI sequences = null;
-    String format = new IdentifyFile().identify(result, "Paste");
-    if (FormatAdapter.isValidFormat(format))
+    FileFormatI format = new IdentifyFile().identify(result,
+            DataSourceType.PASTE);
+    if (format != null)
     {
-      sequences = new FormatAdapter().readFile(result.toString(), "Paste",
+      sequences = new FormatAdapter().readFile(result.toString(),
+              DataSourceType.PASTE,
               format);
     }
     return sequences;
index acca50f..c11302c 100644 (file)
@@ -29,6 +29,7 @@ import jalview.datamodel.SequenceI;
 import jalview.io.StructureFile;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureMapping;
+import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.Format;
 import jalview.xml.binding.sifts.Entry;
@@ -211,6 +212,10 @@ public class SiftsClient implements SiftsClientI
           return new File(siftsFileName);
         }
       }
+      else
+      {
+        return siftsFile;
+      }
     }
     try
     {
@@ -510,13 +515,13 @@ public class SiftsClient implements SiftsClientI
     if (os != null)
     {
       MappingOutputPojo mop = new MappingOutputPojo();
-      mop.setSeqStart(pdbStart);
-      mop.setSeqEnd(pdbEnd);
+      mop.setSeqStart(seqStart);
+      mop.setSeqEnd(seqEnd);
       mop.setSeqName(seq.getName());
       mop.setSeqResidue(matchedSeq);
 
-      mop.setStrStart(seqStart);
-      mop.setStrEnd(seqEnd);
+      mop.setStrStart(pdbStart);
+      mop.setStrEnd(pdbEnd);
       mop.setStrName(structId);
       mop.setStrResidue(targetStrucSeqs.toString());
 
@@ -826,6 +831,10 @@ public class SiftsClient implements SiftsClientI
 
     if (sPojo[0].entityId != null)
     {
+      if (sPojo[0].pid < 1)
+      {
+        return null;
+      }
       for (Entity entity : entities)
       {
         if (!entity.getEntityId().equalsIgnoreCase(sPojo[0].entityId))
@@ -1000,8 +1009,10 @@ public class SiftsClient implements SiftsClientI
         {
           if ((i + (j * len)) < seqRes.length())
           {
-            if (seqRes.charAt(i + (j * len)) == strRes
-                    .charAt(i + (j * len))
+            boolean sameChar = Comparison.isSameResidue(
+                    seqRes.charAt(i + (j * len)),
+                    strRes.charAt(i + (j * len)), false);
+            if (sameChar
                     && !jalview.util.Comparison.isGap(seqRes.charAt(i
                             + (j * len))))
             {
index 21a79fe..2d11fb5 100644 (file)
@@ -22,12 +22,22 @@ package MCview;
 
 import static org.testng.AssertJUnit.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AtomTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test the constructor that parses a PDB file format ATOM line. Fields are in
    * fixed column positions
index 28b995c..aa29ad0 100644 (file)
@@ -22,11 +22,21 @@ package MCview;
 
 import static org.testng.AssertJUnit.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class BondTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testTranslate()
   {
index 0406128..7132939 100644 (file)
@@ -30,6 +30,7 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.TaylorColourScheme;
 import jalview.structure.StructureImportSettings;
@@ -37,11 +38,20 @@ import jalview.structure.StructureImportSettings;
 import java.awt.Color;
 import java.util.Vector;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class PDBChainTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   PDBChain c;
 
   final Atom a1 = new Atom(1f, 2f, 3f);
index 2863643..c07c62e 100644 (file)
@@ -33,17 +33,27 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.structure.StructureImportSettings;
 
 import java.io.IOException;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class PDBfileTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testIsRna()
   {
@@ -73,7 +83,7 @@ public class PDBfileTest
      * Constructor with file path performs parse()
      */
     PDBfile pf = new PDBfile(false, false, false, "examples/3W5V.pdb",
-            AppletFormatAdapter.FILE);
+            DataSourceType.FILE);
 
     assertEquals("3W5V", pf.getId());
     // verify no alignment annotations created
@@ -149,7 +159,7 @@ public class PDBfileTest
   public void testParse_withAnnotations_noSS() throws IOException
   {
     PDBfile pf = new PDBfile(true, false, false, "examples/3W5V.pdb",
-            AppletFormatAdapter.FILE);
+            DataSourceType.FILE);
 
     AlignmentAnnotation[] anns = getAlignmentAnnotations(pf);
     assertEquals(4, anns.length);
@@ -207,7 +217,7 @@ public class PDBfileTest
   public void testParse_withJmol_noAnnotations() throws IOException
   {
     PDBfile pf = new PDBfile(false, true, false, "examples/3W5V.pdb",
-            AppletFormatAdapter.FILE);
+            DataSourceType.FILE);
 
     /*
      * alignment annotations _are_ created anyway (in
@@ -237,7 +247,7 @@ public class PDBfileTest
           throws IOException
   {
     PDBfile pf = new PDBfile(true, true, false, "examples/3W5V.pdb",
-            AppletFormatAdapter.FILE);
+            DataSourceType.FILE);
 
     /*
      * Alignment annotations for TempFactor, SecStruct, per sequence (chain)
@@ -295,7 +305,7 @@ public class PDBfileTest
     // TODO requires a mock for Annotate3D processing
     // and/or run as an integration test
     PDBfile pf = new PDBfile(true, true, true, "examples/2GIS.pdb",
-            AppletFormatAdapter.FILE);
+            DataSourceType.FILE);
   }
 
   /**
@@ -311,8 +321,6 @@ public class PDBfileTest
     return al.getAlignmentAnnotation();
   }
 
-  // @formatter:on
-
   @BeforeMethod(alwaysRun = true)
   public void setUp()
   {
index 5733068..0acd681 100644 (file)
@@ -23,13 +23,23 @@ package MCview;
 import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertSame;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Vector;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ResidueTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testFindAtom()
   {
index eff6bbf..75fb39e 100644 (file)
@@ -23,65 +23,74 @@ package jalview.analysis;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
-import java.util.Hashtable;
-
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.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;
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
 
   @Test(groups = { "Functional" })
   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 seq1 = new Sequence("Seq1", "CAG-T");
+    SequenceI seq2 = new Sequence("Seq2", "CAC-T");
+    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);
+    int width = seq1.getLength();
+    ProfilesI result = AAFrequency.calculate(seqs, width, 0, width,
+            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));
+    ProfileI col = result.get(0);
+    assertEquals(100f, col.getPercentageIdentity(false));
+    assertEquals(100f, col.getPercentageIdentity(true));
+    assertEquals(4, col.getMaxCount());
+    assertEquals("C", col.getModalResidue());
+    assertNull(col.getCounts());
 
     // 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 = result.get(1);
+    assertEquals(75f, col.getPercentageIdentity(false));
+    assertEquals(100f, col.getPercentageIdentity(true));
+    assertEquals(3, col.getMaxCount());
+    assertEquals("A", col.getModalResidue());
 
     // 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));
+    col = result.get(2);
+    assertEquals(25f, col.getPercentageIdentity(false));
+    assertEquals(50f, col.getPercentageIdentity(true));
+    assertEquals(1, col.getMaxCount());
+    assertEquals("CG", col.getModalResidue());
+
+    // col 3 is all gaps
+    col = result.get(3);
+    assertEquals(0f, col.getPercentageIdentity(false));
+    assertEquals(0f, col.getPercentageIdentity(true));
+    assertEquals(0, col.getMaxCount());
+    assertEquals("", col.getModalResidue());
+
+    // col 4 is 75% T 25% G
+    col = result.get(4);
+    assertEquals(75f, col.getPercentageIdentity(false));
+    assertEquals(75f, col.getPercentageIdentity(true));
+    assertEquals(3, col.getMaxCount());
+    assertEquals("T", col.getModalResidue());
   }
 
   @Test(groups = { "Functional" })
@@ -92,33 +101,34 @@ public class AAFrequencyTest
     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]);
+    int width = seq1.getLength();
+    ProfilesI result = AAFrequency.calculate(seqs, width, 0, width,
+            true);
+
+    ProfileI profile = result.get(0);
+    assertEquals(4, profile.getCounts().getCount('C'));
+    assertEquals(4, profile.getHeight());
+    assertEquals(4, profile.getNonGapped());
+
+    profile = result.get(1);
+    assertEquals(3, profile.getCounts().getCount('A'));
+    assertEquals(4, profile.getHeight());
+    assertEquals(3, profile.getNonGapped());
+
+    profile = result.get(2);
+    assertEquals(1, profile.getCounts().getCount('C'));
+    assertEquals(1, profile.getCounts().getCount('G'));
+    assertEquals(4, profile.getHeight());
+    assertEquals(2, profile.getNonGapped());
+
+    profile = result.get(3);
+    assertEquals(3, profile.getCounts().getCount('T'));
+    assertEquals(1, profile.getCounts().getCount('G'));
+    assertEquals(4, profile.getHeight());
+    assertEquals(4, profile.getNonGapped());
   }
 
-  @Test(groups = { "Functional" })
+  @Test(groups = { "Functional" }, enabled = false)
   public void testCalculate_withProfileTiming()
   {
     SequenceI seq1 = new Sequence("Seq1", "CAGT");
@@ -126,27 +136,100 @@ public class AAFrequencyTest
     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);
+    // ensure class loaded and initialised
+    int width = seq1.getLength();
+    AAFrequency.calculate(seqs, width, 0, width, true);
+
     int reps = 100000;
     long start = System.currentTimeMillis();
     for (int i = 0; i < reps; i++)
     {
-      AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
+      AAFrequency.calculate(seqs, width, 0, width, true);
     }
     System.out.println(System.currentTimeMillis() - start);
   }
 
+  /**
+   * Test generation of consensus annotation with options 'include gaps'
+   * (profile percentages are of all sequences, whether gapped or not), and
+   * 'show logo' (the full profile with all residue percentages is reported in
+   * the description for the tooltip)
+   */
   @Test(groups = { "Functional" })
-  public void testGetPercentageFormat()
+  public void testCompleteConsensus_includeGaps_showLogo()
   {
-    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());
+    /*
+     * first compute the profiles
+     */
+    SequenceI seq1 = new Sequence("Seq1", "CAG-T");
+    SequenceI seq2 = new Sequence("Seq2", "CAC-T");
+    SequenceI seq3 = new Sequence("Seq3", "C---G");
+    SequenceI seq4 = new Sequence("Seq4", "CA--t");
+    SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
+    int width = seq1.getLength();
+    ProfilesI profiles = AAFrequency.calculate(seqs, width, 0, width, true);
+
+    AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
+            "PID", new Annotation[width]);
+    AAFrequency
+            .completeConsensus(consensus, profiles, 0, 5, false, true, 4);
+
+    Annotation ann = consensus.annotations[0];
+    assertEquals("C 100%", ann.description);
+    assertEquals("C", ann.displayCharacter);
+    ann = consensus.annotations[1];
+    assertEquals("A 75%", ann.description);
+    assertEquals("A", ann.displayCharacter);
+    ann = consensus.annotations[2];
+    assertEquals("C 25%; G 25%", ann.description);
+    assertEquals("+", ann.displayCharacter);
+    ann = consensus.annotations[3];
+    assertEquals("", ann.description);
+    assertEquals("-", ann.displayCharacter);
+    ann = consensus.annotations[4];
+    assertEquals("T 75%; G 25%", ann.description);
+    assertEquals("T", ann.displayCharacter);
+  }
+
+  /**
+   * Test generation of consensus annotation with options 'ignore gaps' (profile
+   * percentages are of the non-gapped sequences) and 'no logo' (only the modal
+   * residue[s] percentage is reported in the description for the tooltip)
+   */
+  @Test(groups = { "Functional" })
+  public void testCompleteConsensus_ignoreGaps_noLogo()
+  {
+    /*
+     * first compute the profiles
+     */
+    SequenceI seq1 = new Sequence("Seq1", "CAG-T");
+    SequenceI seq2 = new Sequence("Seq2", "CAC-T");
+    SequenceI seq3 = new Sequence("Seq3", "C---G");
+    SequenceI seq4 = new Sequence("Seq4", "CA--t");
+    SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
+    int width = seq1.getLength();
+    ProfilesI profiles = AAFrequency.calculate(seqs, width, 0, width, true);
+  
+    AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
+            "PID", new Annotation[width]);
+    AAFrequency
+            .completeConsensus(consensus, profiles, 0, 5, true, false, 4);
+  
+    Annotation ann = consensus.annotations[0];
+    assertEquals("C 100%", ann.description);
+    assertEquals("C", ann.displayCharacter);
+    ann = consensus.annotations[1];
+    assertEquals("A 100%", ann.description);
+    assertEquals("A", ann.displayCharacter);
+    ann = consensus.annotations[2];
+    assertEquals("[CG] 50%", ann.description);
+    assertEquals("+", ann.displayCharacter);
+    ann = consensus.annotations[3];
+    assertEquals("", ann.description);
+    assertEquals("-", ann.displayCharacter);
+    ann = consensus.annotations[4];
+    assertEquals("T 75%", ann.description);
+    assertEquals("T", ann.displayCharacter);
   }
 }
index 53f64e3..4cb5329 100644 (file)
@@ -23,10 +23,21 @@ package jalview.analysis;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AlignSeqTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testExtractGaps()
   {
index c3191e8..f41262c 100644 (file)
@@ -28,7 +28,9 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -38,11 +40,20 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class AlignmentAnnotationUtilsTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   // 4 sequences x 13 positions
   final static String EOL = "\n";
 
@@ -142,7 +153,7 @@ public class AlignmentAnnotationUtilsTest
   public void setUp() throws IOException
   {
     alignment = new jalview.io.FormatAdapter().readFile(TEST_DATA,
-            AppletFormatAdapter.PASTE, "FASTA");
+            DataSourceType.PASTE, FileFormat.Fasta);
 
     AlignmentAnnotation[] anns = new AlignmentAnnotation[SEQ_ANN_COUNT];
     for (int i = 0; i < anns.length; i++)
index 4aed7e7..bada3ca 100644 (file)
@@ -35,12 +35,16 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.Mapping;
-import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
 import jalview.util.MapList;
 import jalview.util.MappingUtils;
@@ -53,10 +57,19 @@ import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AlignmentUtilsTests
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   public static Sequence ts = new Sequence("short",
           "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm");
 
@@ -69,14 +82,15 @@ public class AlignmentUtilsTests
       SequenceI s1 = ts.deriveSequence().getSubSequence(i, i + 7);
       al.addSequence(s1);
     }
-    System.out.println(new AppletFormatAdapter().formatSequences("Clustal",
+    System.out.println(new AppletFormatAdapter().formatSequences(
+            FileFormat.Clustal,
             al, true));
     for (int flnk = -1; flnk < 25; flnk++)
     {
       AlignmentI exp = AlignmentUtils.expandContext(al, flnk);
       System.out.println("\nFlank size: " + flnk);
       System.out.println(new AppletFormatAdapter().formatSequences(
-              "Clustal", exp, true));
+              FileFormat.Clustal, exp, true));
       if (flnk == -1)
       {
         /*
@@ -209,7 +223,7 @@ public class AlignmentUtilsTests
   {
     final String data = ">Seq1Name\nKQYL\n" + ">Seq2Name\nRFPW\n"
             + ">Seq1Name\nABCD\n";
-    AlignmentI al = loadAlignment(data, "FASTA");
+    AlignmentI al = loadAlignment(data, FileFormat.Fasta);
     Map<String, List<SequenceI>> map = AlignmentUtils
             .getSequencesByName(al);
     assertEquals(2, map.keySet().size());
@@ -229,11 +243,11 @@ public class AlignmentUtilsTests
    * @return
    * @throws IOException
    */
-  protected AlignmentI loadAlignment(final String data, String format)
+  protected AlignmentI loadAlignment(final String data, FileFormatI format)
           throws IOException
   {
     AlignmentI a = new FormatAdapter().readFile(data,
-            AppletFormatAdapter.PASTE, format);
+            DataSourceType.PASTE, format);
     a.setDataset(null);
     return a;
   }
@@ -1119,9 +1133,9 @@ public class AlignmentUtilsTests
     assertEquals(1, mappings.size());
 
     // map G to GGG
-    SearchResults sr = MappingUtils.buildSearchResults(pep1, 1, mappings);
+    SearchResultsI sr = MappingUtils.buildSearchResults(pep1, 1, mappings);
     assertEquals(1, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertSame(cds1Dss, m.getSequence());
     assertEquals(1, m.getStart());
     assertEquals(3, m.getEnd());
@@ -1650,10 +1664,10 @@ public class AlignmentUtilsTests
     List<AlignedCodonFrame> pep1CdsMappings = MappingUtils
             .findMappingsForSequence(cds.getSequenceAt(0), pep1Mappings);
     assertEquals(1, pep1CdsMappings.size());
-    SearchResults sr = MappingUtils.buildSearchResults(pep1, 1,
+    SearchResultsI sr = MappingUtils.buildSearchResults(pep1, 1,
             pep1CdsMappings);
     assertEquals(1, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertEquals(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence());
     assertEquals(1, m.getStart());
     assertEquals(3, m.getEnd());
@@ -2388,9 +2402,9 @@ public class AlignmentUtilsTests
     assertEquals(1, mappings.size());
 
     // map G to GGG
-    SearchResults sr = MappingUtils.buildSearchResults(pep3, 1, mappings);
+    SearchResultsI sr = MappingUtils.buildSearchResults(pep3, 1, mappings);
     assertEquals(1, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertSame(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence());
     assertEquals(1, m.getStart());
     assertEquals(3, m.getEnd());
index 9dd2972..1c5a7f9 100644 (file)
@@ -27,16 +27,26 @@ import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class AnnotationSorterTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private static final int NUM_SEQS = 6;
 
   private static final int NUM_ANNS = 7;
index 38ee3fe..b66c499 100644 (file)
@@ -23,13 +23,23 @@ package jalview.analysis;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Arrays;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class CodingUtilsTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testDecodeCodon()
   {
diff --git a/test/jalview/analysis/ConservationTest.java b/test/jalview/analysis/ConservationTest.java
new file mode 100644 (file)
index 0000000..fb58655
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.analysis;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ConservationTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
+  public void testRecordConservation()
+  {
+    Map<String, Integer> resultMap = new HashMap<String, Integer>();
+
+    // V is hydrophobic, aliphatic, small
+    Conservation.recordConservation(resultMap, "V");
+    assertEquals(resultMap.get("hydrophobic").intValue(), 1);
+    assertEquals(resultMap.get("aliphatic").intValue(), 1);
+    assertEquals(resultMap.get("small").intValue(), 1);
+    assertEquals(resultMap.get("tiny").intValue(), 0);
+    assertEquals(resultMap.get("polar").intValue(), 0);
+    assertEquals(resultMap.get("charged").intValue(), 0);
+
+    // now add S: not hydrophobic, small, tiny, polar, not aliphatic
+    Conservation.recordConservation(resultMap, "s");
+    assertEquals(resultMap.get("hydrophobic").intValue(), -1);
+    assertEquals(resultMap.get("aliphatic").intValue(), -1);
+    assertEquals(resultMap.get("small").intValue(), 1);
+    assertEquals(resultMap.get("tiny").intValue(), -1);
+    assertEquals(resultMap.get("polar").intValue(), -1);
+    assertEquals(resultMap.get("charged").intValue(), 0);
+  }
+
+  @Test(groups = "Functional")
+  public void testCountConservationAndGaps()
+  {
+    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    seqs.add(new Sequence("seq1", "VGnY")); // not case sensitive
+    seqs.add(new Sequence("seq2", "-G-y"));
+    seqs.add(new Sequence("seq3", "VG-Y"));
+    seqs.add(new Sequence("seq4", "VGNW"));
+
+    Conservation cons = new Conservation("", seqs, 0, 50);
+    int[] counts = cons.countConservationAndGaps(0);
+    assertEquals(counts[0], 1); // conserved
+    assertEquals(counts[1], 1); // gap count
+    counts = cons.countConservationAndGaps(1);
+    assertEquals(counts[0], 1);
+    assertEquals(counts[1], 0);
+    counts = cons.countConservationAndGaps(2);
+    assertEquals(counts[0], 1);
+    assertEquals(counts[1], 2);
+    counts = cons.countConservationAndGaps(3);
+    assertEquals(counts[0], 0); // not conserved
+    assertEquals(counts[1], 0);
+  }
+
+  @Test(groups = "Functional")
+  public void testCalculate_noThreshold()
+  {
+    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    seqs.add(new Sequence("seq1", "VGIV-N"));
+    seqs.add(new Sequence("seq2", "V-iL-N")); // not case sensitive
+    seqs.add(new Sequence("seq3", "V-IW-N"));
+    seqs.add(new Sequence("seq4", "VGLH-L"));
+
+    Conservation cons = new Conservation("", 0, seqs, 0, 5);
+    cons.calculate();
+
+    /*
+     * column 0: all V (hydrophobic/aliphatic/small)
+     */
+    Map<String, Integer> colCons = cons.total[0];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+
+    /*
+     * column 1: all G (hydrophobic/small/tiny)
+     * gaps take default value of property present
+     */
+    colCons = cons.total[1];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), -1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 1);
+    assertEquals(colCons.get("proline").intValue(), -1);
+    assertEquals(colCons.get("charged").intValue(), -1);
+    assertEquals(colCons.get("negative").intValue(), -1);
+    assertEquals(colCons.get("polar").intValue(), -1);
+    assertEquals(colCons.get("positive").intValue(), -1);
+    assertEquals(colCons.get("aromatic").intValue(), -1);
+
+    /*
+     * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
+     */
+    colCons = cons.total[2];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 0);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+
+    /*
+     * column 3: VLWH all hydrophobic, none is tiny, negative or proline
+     */
+    colCons = cons.total[3];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), -1);
+    assertEquals(colCons.get("small").intValue(), -1);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), -1);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), -1);
+    assertEquals(colCons.get("positive").intValue(), -1);
+    assertEquals(colCons.get("aromatic").intValue(), -1);
+
+    /*
+     * column 4: all gaps - counted as having all properties
+     */
+    colCons = cons.total[4];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 1);
+    assertEquals(colCons.get("proline").intValue(), 1);
+    assertEquals(colCons.get("charged").intValue(), 1);
+    assertEquals(colCons.get("negative").intValue(), 1);
+    assertEquals(colCons.get("polar").intValue(), 1);
+    assertEquals(colCons.get("positive").intValue(), 1);
+    assertEquals(colCons.get("aromatic").intValue(), 1);
+
+    /*
+     * column 5: N (small polar) and L (aliphatic hydrophobic) 
+     * have nothing in common!
+     */
+    colCons = cons.total[5];
+    assertEquals(colCons.get("hydrophobic").intValue(), -1);
+    assertEquals(colCons.get("aliphatic").intValue(), -1);
+    assertEquals(colCons.get("small").intValue(), -1);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), -1);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+  }
+
+  /**
+   * Test for the case whether the number of non-gapped sequences in a column
+   * has to be above a threshold
+   */
+  @Test(groups = "Functional")
+  public void testCalculate_threshold()
+  {
+    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    seqs.add(new Sequence("seq1", "VGIV-"));
+    seqs.add(new Sequence("seq2", "V-iL-")); // not case sensitive
+    seqs.add(new Sequence("seq3", "V-IW-"));
+    seqs.add(new Sequence("seq4", "VGLH-"));
+    seqs.add(new Sequence("seq5", "VGLH-"));
+  
+    /*
+     * threshold 50% means a residue has to occur 3 or more times
+     * in a column to be counted for conservation
+     */
+    // TODO: ConservationThread uses a value of 3
+    // calculateConservation states it is the minimum number of sequences
+    // but it is treated as percentage threshold in calculate() ?
+    Conservation cons = new Conservation("", 50, seqs, 0, 4);
+    cons.calculate();
+  
+    /*
+     * column 0: all V (hydrophobic/aliphatic/small)
+     */
+    Map<String, Integer> colCons = cons.total[0];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+  
+    /*
+     * column 1: all G (hydrophobic/small/tiny)
+     * gaps are ignored as not above threshold
+     */
+    colCons = cons.total[1];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 0);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 1);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+  
+    /*
+     * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
+     */
+    colCons = cons.total[2];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 0);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+  
+    /*
+     * column 3: nothing above threshold
+     */
+    colCons = cons.total[3];
+    assertTrue(colCons.isEmpty());
+  
+    /*
+     * column 4: all gaps - counted as having all properties
+     */
+    colCons = cons.total[4];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 1);
+    assertEquals(colCons.get("proline").intValue(), 1);
+    assertEquals(colCons.get("charged").intValue(), 1);
+    assertEquals(colCons.get("negative").intValue(), 1);
+    assertEquals(colCons.get("polar").intValue(), 1);
+    assertEquals(colCons.get("positive").intValue(), 1);
+    assertEquals(colCons.get("aromatic").intValue(), 1);
+  }
+
+  /**
+   * Test the method that derives the conservation 'sequence' and the mouseover
+   * tooltips from the computed conservation
+   */
+  @Test(groups = "Functional")
+  public void testVerdict()
+  {
+    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    seqs.add(new Sequence("seq1", "VGIVV-H"));
+    seqs.add(new Sequence("seq2", "VGILL-H"));
+    seqs.add(new Sequence("seq3", "VGIW--R"));
+    seqs.add(new Sequence("seq4", "VGLHH--"));
+    seqs.add(new Sequence("seq5", "VGLHH-R"));
+    seqs.add(new Sequence("seq6", "VGLHH--"));
+    seqs.add(new Sequence("seq7", "VGLHH-R"));
+    seqs.add(new Sequence("seq8", "VGLHH-R"));
+
+    // calculate with no threshold
+    Conservation cons = new Conservation("", 0, seqs, 0, 6);
+    cons.calculate();
+    // positive and negative conservation where <25% gaps in columns
+    cons.verdict(false, 25);
+
+    /*
+     * verify conservation 'sequence'
+     * cols 0 fully conserved and above threshold (*)
+     * col 2 properties fully conserved (+)
+     * col 3 VLWH 1 positively and 3 negatively conserved properties
+     * col 4 has 1 positively conserved property, but because gap contributes a
+     * 'positive' for all properties, no negative conservation is counted
+     * col 5 is all gaps
+     * col 6 has 25% gaps so fails threshold test
+     */
+    assertEquals(cons.getConsSequence().getSequenceAsString(), "**+41--");
+
+    /*
+     * verify tooltips; conserved properties are sorted alphabetically within
+     * positive followed by negative
+     */
+    assertEquals(
+            cons.getTooltip(0),
+            "aliphatic hydrophobic small !aromatic !charged !negative !polar !positive !proline !tiny");
+    assertEquals(
+            cons.getTooltip(1),
+            "hydrophobic small tiny !aliphatic !aromatic !charged !negative !polar !positive !proline");
+    assertEquals(
+            cons.getTooltip(2),
+            "aliphatic hydrophobic !aromatic !charged !negative !polar !positive !proline !small !tiny");
+    assertEquals(cons.getTooltip(3), "hydrophobic !negative !proline !tiny");
+    assertEquals(cons.getTooltip(4), "hydrophobic");
+    assertEquals(cons.getTooltip(5), "");
+    assertEquals(cons.getTooltip(6), "");
+  }
+}
index a85dcef..95be1ff 100644 (file)
@@ -37,6 +37,7 @@ import jalview.datamodel.Mapping;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.util.DBRefUtils;
 import jalview.util.MapList;
 import jalview.ws.SequenceFetcher;
@@ -46,10 +47,19 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class CrossRefTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testFindXDbRefs()
   {
index 69e5c23..60dd929 100644 (file)
@@ -24,11 +24,14 @@ import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.io.FastaFile;
 
 import java.util.Arrays;
 import java.util.Random;
 
+import org.testng.annotations.BeforeClass;
+
 /**
  * Generates, and outputs in Fasta format, a random DNA alignment for given
  * sequence length and count. Will regenerate the same alignment each time if
@@ -50,6 +53,14 @@ import java.util.Random;
  */
 public class DnaAlignmentGenerator
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private static final char GAP = '-';
 
   private static final char ZERO = '0';
@@ -58,6 +69,7 @@ public class DnaAlignmentGenerator
 
   private Random random;
 
+
   /**
    * Outputs a DNA 'alignment' where each position is a random choice from
    * 'GTCA-'.
@@ -83,7 +95,7 @@ public class DnaAlignmentGenerator
             + " bases with " + gapPercentage + "% gaps and "
             + changePercentage + "% mutations (random seed = " + randomSeed
             + ")");
-    System.out.println(new FastaFile().print(al.getSequencesArray()));
+    System.out.println(new FastaFile().print(al.getSequencesArray(), true));
   }
 
   /**
index 1851517..cd5d3ca 100644 (file)
@@ -32,14 +32,25 @@ import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignViewport;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 
 import java.io.IOException;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class DnaTest
 {
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   // @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"
@@ -120,8 +131,8 @@ public class DnaTest
           throws IOException
   {
     AlignmentI alf = new FormatAdapter().readFile(
-            JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE,
-            "FASTA");
+            JAL_1312_example_align_fasta, DataSourceType.PASTE,
+            FileFormat.Fasta);
     ColumnSelection cs = new ColumnSelection();
     AlignViewportI av = new AlignViewport(alf, cs);
     Dna dna = new Dna(av, new int[] { 0, alf.getWidth() - 1 });
@@ -141,8 +152,8 @@ public class DnaTest
           throws IOException
   {
     AlignmentI alf = new FormatAdapter().readFile(
-            JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE,
-            "FASTA");
+            JAL_1312_example_align_fasta, DataSourceType.PASTE,
+            FileFormat.Fasta);
     int vwidth = 15;
     for (int ipos = 0; ipos + vwidth < alf.getWidth(); ipos += vwidth)
     {
@@ -176,7 +187,7 @@ public class DnaTest
   public void testTranslateCdna_simple() throws IOException
   {
     AlignmentI alf = new FormatAdapter().readFile(fasta,
-            FormatAdapter.PASTE, "FASTA");
+            DataSourceType.PASTE, FileFormat.Fasta);
     ColumnSelection cs = new ColumnSelection();
     AlignViewportI av = new AlignViewport(alf, cs);
     Dna dna = new Dna(av, new int[] { 0, alf.getWidth() - 1 });
@@ -196,8 +207,8 @@ public class DnaTest
   public void testTranslateCdna_hiddenColumns() throws IOException
   {
     AlignmentI alf = new FormatAdapter().readFile(fasta,
-            FormatAdapter.PASTE, "FASTA");
-    ColumnSelection cs = new jalview.datamodel.ColumnSelection();
+            DataSourceType.PASTE, FileFormat.Fasta);
+    ColumnSelection cs = new 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
diff --git a/test/jalview/analysis/FinderTest.java b/test/jalview/analysis/FinderTest.java
new file mode 100644 (file)
index 0000000..d7a509f
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.analysis;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.Sequence;
+import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class FinderTest
+{
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  private AlignFrame af;
+
+  private AlignmentI al;
+
+  @BeforeClass(groups = "Functional")
+  public void setUp()
+  {
+    String seqData = "seq1 ABCD--EF-GHI\n" + "seq2 A--BCDefHI\n"
+            + "seq3 --bcdEFH\n" + "seq4 aa---aMMMMMaaa\n";
+    af = new FileLoader().LoadFileWaitTillLoaded(seqData,
+            DataSourceType.PASTE);
+    al = af.getViewport().getAlignment();
+  }
+
+  /**
+   * Test for find all matches of a regular expression
+   */
+  @Test(groups = "Functional")
+  public void testFindAll_regex()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+    f.find("E.H"); // 'E, any character, H'
+
+    // should match seq2 efH and seq3 EFH
+    SearchResultsI sr = f.getSearchResults();
+    assertEquals(sr.getSize(), 2);
+    List<SearchResultMatchI> matches = sr.getResults();
+    assertSame(al.getSequenceAt(1), matches.get(0).getSequence());
+    assertSame(al.getSequenceAt(2), matches.get(1).getSequence());
+    assertEquals(matches.get(0).getStart(), 5);
+    assertEquals(matches.get(0).getEnd(), 7);
+    assertEquals(matches.get(1).getStart(), 4);
+    assertEquals(matches.get(1).getEnd(), 6);
+  }
+
+  /**
+   * Test for (undocumented) find residue by position
+   */
+  @Test(groups = "Functional")
+  public void testFind_residueNumber()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+    f.find("9");
+
+    // seq1 and seq4 have 9 residues; no match in other sequences
+    SearchResultsI sr = f.getSearchResults();
+    assertEquals(sr.getSize(), 2);
+    List<SearchResultMatchI> matches = sr.getResults();
+    assertSame(al.getSequenceAt(0), matches.get(0).getSequence());
+    assertSame(al.getSequenceAt(3), matches.get(1).getSequence());
+    assertEquals(matches.get(0).getStart(), 9);
+    assertEquals(matches.get(0).getEnd(), 9);
+    assertEquals(matches.get(1).getStart(), 9);
+    assertEquals(matches.get(1).getEnd(), 9);
+  }
+
+  /**
+   * Test for find next action
+   */
+  @Test(groups = "Functional")
+  public void testFindNext()
+  {
+    /*
+     * start at second sequence; resIndex of -1
+     * means sequence id / description is searched
+     */
+    Finder f = new Finder(al, null, 1, -1);
+    f.find("e"); // matches id
+
+    assertTrue(f.getSearchResults().isEmpty());
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al.getSequenceAt(1));
+
+    // resIndex is now 0 - for use in next find next
+    assertEquals(f.getResIndex(), 0);
+    f = new Finder(al, null, 1, 0);
+    f.find("e"); // matches in sequence
+    assertTrue(f.getIdMatch().isEmpty());
+    assertEquals(f.getSearchResults().getSize(), 1);
+    List<SearchResultMatchI> matches = f.getSearchResults().getResults();
+    assertEquals(matches.get(0).getStart(), 5);
+    assertEquals(matches.get(0).getEnd(), 5);
+    assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
+    // still in the second sequence
+    assertEquals(f.getSeqIndex(), 1);
+    // next residue position to search from is 5
+    // (used as base 0 by RegEx so the same as 6 if base 1)
+    assertEquals(f.getResIndex(), 5);
+
+    // find next from end of sequence - finds next sequence id
+    f = new Finder(al, null, 1, 5);
+    f.find("e");
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al.getSequenceAt(2));
+  }
+
+  /**
+   * Test for matching within sequence descriptions
+   */
+  @Test(groups = "Functional")
+  public void testFindAll_inDescription()
+  {
+    AlignmentI al2 = new Alignment(al);
+    al2.getSequenceAt(0).setDescription("BRAF");
+    al2.getSequenceAt(1).setDescription("braf");
+    Finder f = new Finder(al2, null);
+    f.setFindAll(true);
+    f.setIncludeDescription(true);
+
+    f.find("rAF");
+    assertEquals(f.getIdMatch().size(), 2);
+    assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
+    assertSame(f.getIdMatch().get(1), al2.getSequenceAt(1));
+    assertTrue(f.getSearchResults().isEmpty());
+
+    /*
+     * case sensitive
+     */
+    f = new Finder(al2, null);
+    f.setFindAll(true);
+    f.setCaseSensitive(true);
+    f.setIncludeDescription(true);
+
+    f.find("RAF");
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
+    assertTrue(f.getSearchResults().isEmpty());
+
+    /*
+     * match sequence id, description and sequence!
+     */
+    al2.getSequenceAt(0).setDescription("the efh sequence");
+    al2.getSequenceAt(0).setName("mouseEFHkinase");
+    al2.getSequenceAt(1).setName("humanEFHkinase");
+    f = new Finder(al2, null);
+    f.setFindAll(true);
+    f.setIncludeDescription(true);
+
+    /*
+     * sequence matches should have no duplicates
+     */
+    f.find("EFH");
+    assertEquals(f.getIdMatch().size(), 2);
+    assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
+    assertSame(f.getIdMatch().get(1), al2.getSequenceAt(1));
+
+    assertEquals(f.getSearchResults().getSize(), 2);
+    SearchResultMatchI match = f.getSearchResults().getResults().get(0);
+    assertSame(al2.getSequenceAt(1), match.getSequence());
+    assertEquals(5, match.getStart());
+    assertEquals(7, match.getEnd());
+    match = f.getSearchResults().getResults().get(1);
+    assertSame(al2.getSequenceAt(2), match.getSequence());
+    assertEquals(4, match.getStart());
+    assertEquals(6, match.getEnd());
+  }
+
+  /**
+   * Test for matching within sequence ids
+   */
+  @Test(groups = "Functional")
+  public void testFindAll_sequenceIds()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+
+    /*
+     * case insensitive
+     */
+    f.find("SEQ1");
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al.getSequenceAt(0));
+    assertTrue(f.getSearchResults().isEmpty());
+
+    /*
+     * case sensitive
+     */
+    f = new Finder(al, null);
+    f.setFindAll(true);
+    f.setCaseSensitive(true);
+    f.find("SEQ1");
+    assertTrue(f.getSearchResults().isEmpty());
+
+    /*
+     * match both sequence id and sequence
+     */
+    AlignmentI al2 = new Alignment(al);
+    al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
+    f = new Finder(al2, null);
+    f.setFindAll(true);
+    f.find("ABZ");
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al2.getSequenceAt(4));
+    assertEquals(f.getSearchResults().getSize(), 2);
+    SearchResultMatchI match = f.getSearchResults().getResults().get(0);
+    assertSame(al2.getSequenceAt(4), match.getSequence());
+    assertEquals(4, match.getStart());
+    assertEquals(6, match.getEnd());
+    match = f.getSearchResults().getResults().get(1);
+    assertSame(al2.getSequenceAt(4), match.getSequence());
+    assertEquals(10, match.getStart());
+    assertEquals(12, match.getEnd());
+  }
+
+  /**
+   * Test finding all matches of a sequence pattern in an alignment
+   */
+  @Test(groups = "Functional")
+  public void testFindAll_simpleMatch()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+
+    /*
+     * case insensitive first
+     */
+    f.find("EfH");
+    SearchResultsI searchResults = f.getSearchResults();
+    assertEquals(searchResults.getSize(), 2);
+    SearchResultMatchI match = searchResults.getResults().get(0);
+    assertSame(al.getSequenceAt(1), match.getSequence());
+    assertEquals(5, match.getStart());
+    assertEquals(7, match.getEnd());
+    match = searchResults.getResults().get(1);
+    assertSame(al.getSequenceAt(2), match.getSequence());
+    assertEquals(4, match.getStart());
+    assertEquals(6, match.getEnd());
+
+    /*
+     * case sensitive
+     */
+    f = new Finder(al, null);
+    f.setFindAll(true);
+    f.setCaseSensitive(true);
+    f.find("BC");
+    searchResults = f.getSearchResults();
+    assertEquals(searchResults.getSize(), 2);
+    match = searchResults.getResults().get(0);
+    assertSame(al.getSequenceAt(0), match.getSequence());
+    assertEquals(2, match.getStart());
+    assertEquals(3, match.getEnd());
+    match = searchResults.getResults().get(1);
+    assertSame(al.getSequenceAt(1), match.getSequence());
+    assertEquals(2, match.getStart());
+    assertEquals(3, match.getEnd());
+  }
+
+  /**
+   * Test for JAL-2302 to verify that sub-matches are not included in a find all
+   * result
+   */
+  @Test(groups = "Functional")
+  public void testFind_maximalResultOnly()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+    f.find("M+");
+    SearchResultsI searchResults = f.getSearchResults();
+    assertEquals(searchResults.getSize(), 1);
+    SearchResultMatchI match = searchResults.getResults().get(0);
+    assertSame(al.getSequenceAt(3), match.getSequence());
+    assertEquals(4, match.getStart()); // dataset sequence positions
+    assertEquals(8, match.getEnd()); // base 1
+  }
+}
index cea8ae4..184f9fb 100644 (file)
@@ -26,14 +26,23 @@ import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.util.Arrays;
 
 import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class GroupingTest
 {
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   Sequence s1 = new Sequence("s1", "AAAADDDDEEEE");
 
   Sequence s2 = new Sequence("s2", "AAAADDDDEEEE");
index d692bbb..cd253e0 100644 (file)
@@ -28,15 +28,24 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class ParsePropertiesTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private Alignment al;
 
   private ParseProperties pp;
index 9d35a19..814d2d4 100644 (file)
@@ -27,13 +27,23 @@ import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.AssertJUnit.fail;
 
 import jalview.analysis.SecStrConsensus.SimpleBP;
+import jalview.gui.JvOptionPane;
 
 import java.util.Vector;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class RnaTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testGetSimpleBPs() throws WUSSParseException
   {
index b4d079a..11cb10c 100644 (file)
@@ -25,10 +25,12 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.util.Hashtable;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 /**
@@ -37,6 +39,15 @@ import org.testng.annotations.Test;
  */
 public class SeqsetUtilsTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+
   /**
    * test for JAL-2046 bug - duplication of sequence features on reconstructed
    * alignment
index b071080..bbed9d3 100644 (file)
@@ -25,12 +25,22 @@ import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.analysis.SequenceIdMatcher.SeqIdName;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class SequenceIdMatcherTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+
   /**
    * Test the method that checks for one sequence id starting with the other,
    * followed by an 'allowed' separator character
index 43ebd63..9fc88ea 100644 (file)
@@ -26,9 +26,11 @@ import static org.testng.AssertJUnit.assertNull;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.io.PrintStream;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -41,6 +43,13 @@ import org.testng.annotations.Test;
 public class TestAlignSeq
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   SequenceI s1, s2, s3;
 
   /**
index 309790f..66eb5a5 100644 (file)
@@ -24,14 +24,26 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.io.FileLoader;
-import jalview.io.FormatAdapter;
+
+import java.util.Arrays;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class FeatureScoreModelTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   public static String alntestFile = "FER1_MESCR/72-76 DVYIL\nFER1_SPIOL/71-75 DVYIL\nFER3_RAPSA/21-25 DVYVL\nFER1_MAIZE/73-77 DVYIL\n";
 
   int[] sf1 = new int[] { 74, 74, 73, 73, 23, 23, -1, -1 };
@@ -43,7 +55,7 @@ public class FeatureScoreModelTest
   public AlignFrame getTestAlignmentFrame()
   {
     AlignFrame alf = new FileLoader(false).LoadFileWaitTillLoaded(
-            alntestFile, FormatAdapter.PASTE);
+            alntestFile, DataSourceType.PASTE);
     AlignmentI al = alf.getViewport().getAlignment();
     Assert.assertEquals(al.getHeight(), 4);
     Assert.assertEquals(al.getWidth(), 5);
@@ -137,4 +149,45 @@ public class FeatureScoreModelTest
               + "(" + s + ") should still be distinct from FER1_MAIZE (3)");
     }
   }
+
+  /**
+   * Check findFeatureAt doesn't return contact features except at contact
+   * points TODO:move to under the FeatureRendererModel test suite
+   */
+  @Test(groups = { "Functional" })
+  public void testFindFeatureAt_PointFeature() throws Exception
+  {
+    String alignment = "a CCCCCCGGGGGGCCCCCC\n" + "b CCCCCCGGGGGGCCCCCC\n"
+            + "c CCCCCCGGGGGGCCCCCC\n";
+    AlignFrame af = new jalview.io.FileLoader(false)
+            .LoadFileWaitTillLoaded(alignment, DataSourceType.PASTE);
+    SequenceI aseq = af.getViewport().getAlignment().getSequenceAt(0);
+    SequenceFeature sf = null;
+    sf = new SequenceFeature("disulphide bond", "", 2, 5, Float.NaN, "");
+    aseq.addSequenceFeature(sf);
+    Assert.assertTrue(sf.isContactFeature());
+    af.refreshFeatureUI(true);
+    af.getFeatureRenderer().setAllVisible(Arrays.asList("disulphide bond"));
+    Assert.assertEquals(af.getFeatureRenderer().getDisplayedFeatureTypes()
+            .size(), 1, "Should be just one feature type displayed");
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 1)
+            .size(), 0);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 2)
+            .size(), 1);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 3)
+            .size(), 0);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 4)
+            .size(), 0);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 5)
+            .size(), 1);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 6)
+            .size(), 0);
+  }
+
 }
index 20e43b8..0485db7 100644 (file)
@@ -25,10 +25,21 @@ import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ArgsParserTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testGetValue()
   {
index 803139f..e762dd5 100644 (file)
@@ -22,6 +22,8 @@ package jalview.bin;
 
 import static org.testng.AssertJUnit.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
@@ -32,6 +34,14 @@ import org.testng.annotations.Test;
 
 public class CacheTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private Locale locale;
 
   @BeforeClass(alwaysRun = true)
index b85536e..69a3ef7 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.bin;
 
+import jalview.gui.JvOptionPane;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
@@ -28,6 +30,7 @@ import java.util.ArrayList;
 
 import org.testng.Assert;
 import org.testng.FileAssert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -35,6 +38,23 @@ import org.testng.annotations.Test;
 public class CommandLineOperations
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  private static final int TEST_TIMEOUT = 4500; // Note longer timeout needed on
+                                                // full test run than on
+                                                // individual tests
+
+  private static final int SETUP_TIMEOUT = 9000;
+
+  private static final int MINFILESIZE_SMALL = 2096;
+
+  private static final int MINFILESIZE_BIG = 4096;
+
   private ArrayList<String> successfulCMDs = new ArrayList<String>();
 
   /***
@@ -60,6 +80,7 @@ public class CommandLineOperations
       this.process = process;
     }
 
+    @Override
     public void run()
     {
       try
@@ -142,7 +163,7 @@ public class CommandLineOperations
     String cmds = "nodisplay -open examples/uniref50.fa -sortbytree -props FILE -colour zappo "
             + "-jabaws http://www.compbio.dundee.ac.uk/jabaws -nosortbytree -dasserver nickname=www.test.com "
             + "-features examples/testdata/plantfdx.features -annotations examples/testdata/plantfdx.annotations -tree examples/testdata/uniref50_test_tree";
-    Worker worker = jalviewDesktopRunner(true, cmds, 9000);
+    Worker worker = jalviewDesktopRunner(true, cmds, SETUP_TIMEOUT);
     String ln = null;
     while ((ln = worker.getOutputReader().readLine()) != null)
     {
@@ -155,7 +176,7 @@ public class CommandLineOperations
   public void setUpForCommandLineInputOperations() throws IOException
   {
     String cmds = "-open examples/uniref50.fa -noquestionnaire -nousagestats";
-    Worker worker = jalviewDesktopRunner(false, cmds, 9000);
+    Worker worker = jalviewDesktopRunner(false, cmds, SETUP_TIMEOUT);
     String ln = null;
     int count = 0;
     while ((ln = worker.getErrorReader().readLine()) != null)
@@ -204,7 +225,8 @@ public class CommandLineOperations
       worker.process.destroy();
       Assert.fail("Jalview did not exit after "
               + type
-              + " generation (try running test again to verify - timeout at 9000ms). ["
+              + " generation (try running test again to verify - timeout at "
+              + SETUP_TIMEOUT + "ms). ["
               + harg + "]");
     }
     new File(fileName).delete();
@@ -252,36 +274,36 @@ public class CommandLineOperations
   {
     return new Object[][] {
         { "nodisplay -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", true, 4096, 4000 },
+            "test_uniref50_out.eps", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "nodisplay -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", false, 4096, 4000 },
+            "test_uniref50_out.eps", false, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "nogui -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", true, 4096, 4000 },
+            "test_uniref50_out.eps", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "nogui -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", false, 4096, 4000 },
+            "test_uniref50_out.eps", false, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", true, 4096, 4000 },
+            "test_uniref50_out.eps", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -svg",
-            "test_uniref50_out.svg", false, 4096, 3000 },
+            "test_uniref50_out.svg", false, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -png",
-            "test_uniref50_out.png", true, 4096, 3000 },
+            "test_uniref50_out.png", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -html",
-            "test_uniref50_out.html", true, 4096, 3000 },
+            "test_uniref50_out.html", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -fasta",
-            "test_uniref50_out.mfa", true, 2096, 3000 },
+            "test_uniref50_out.mfa", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -clustal",
-            "test_uniref50_out.aln", true, 2096, 3000 },
+            "test_uniref50_out.aln", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -msf",
-            "test_uniref50_out.msf", true, 2096, 3000 },
+            "test_uniref50_out.msf", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -pileup",
-            "test_uniref50_out.aln", true, 2096, 3000 },
+            "test_uniref50_out.aln", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -pir",
-            "test_uniref50_out.pir", true, 2096, 3000 },
+            "test_uniref50_out.pir", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -pfam",
-            "test_uniref50_out.pfam", true, 2096, 3000 },
+            "test_uniref50_out.pfam", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -blc",
-            "test_uniref50_out.blc", true, 2096, 3000 },
+            "test_uniref50_out.blc", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -jalview",
-            "test_uniref50_out.jvp", true, 2096, 3000 }, };
+            "test_uniref50_out.jvp", true, MINFILESIZE_SMALL, TEST_TIMEOUT }, };
   }
 }
index 8276300..07e1b25 100644 (file)
@@ -23,13 +23,23 @@ package jalview.bin;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Arrays;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class JalviewLiteTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testSeparatorListToArray()
   {
index 7fb80fb..3223042 100644 (file)
@@ -29,9 +29,11 @@ import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -44,6 +46,13 @@ import org.testng.annotations.Test;
 public class EditCommandTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private EditCommand testee;
 
   private SequenceI[] seqs;
index d593d41..70c54fb 100644 (file)
@@ -26,7 +26,9 @@ import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -38,6 +40,14 @@ import org.testng.annotations.Test;
  */
 public class TrimRegionCommandTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private AlignmentI al;
 
   @BeforeMethod(alwaysRun = true)
index 7fd8965..2e89b0e 100644 (file)
@@ -23,24 +23,42 @@ package jalview.controller;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.analysis.Finder;
+import jalview.api.AlignViewControllerI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
 
+import java.util.Arrays;
 import java.util.BitSet;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AlignViewControllerTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testFindColumnsWithFeature()
   {
-    SequenceI seq1 = new Sequence("seq1", "aMMMaaaaaaaaaaaaaaaa");
-    SequenceI seq2 = new Sequence("seq2", "aaaMMMMMMMaaaaaaaaaa");
-    SequenceI seq3 = new Sequence("seq3", "aaaaaaaaaaMMMMMaaaaa");
-    SequenceI seq4 = new Sequence("seq3", "aaaaaaaaaaaaaaaaaaaa");
+    SequenceI seq1 = new Sequence("seq1", "-a-MMMaaaaaaaaaaaaaaaa");
+    SequenceI seq2 = new Sequence("seq2", "aa--aMM-MMMMMaaaaaaaaaa");
+    SequenceI seq3 = new Sequence("seq3", "abcab-caD-aaMMMMMaaaaa");
+    SequenceI seq4 = new Sequence("seq4", "abc--abcaaaaaaaaaaaaaa");
 
     /*
      * features start/end are base 1
@@ -53,13 +71,16 @@ public class AlignViewControllerTest
             null));
     seq3.addSequenceFeature(new SequenceFeature("Metal", "desc", 11, 15,
             0f, null));
+    // disulfide bond is a 'contact feature' - only select its 'start' and 'end'
+    seq3.addSequenceFeature(new SequenceFeature("disulfide bond", "desc", 8, 12,
+            0f, null));
 
     /*
-     * select the first three columns --> Metal in seq1 2-3
+     * select the first five columns --> Metal in seq1 cols 4-5
      */
     SequenceGroup sg = new SequenceGroup();
     sg.setStartRes(0); // base 0
-    sg.setEndRes(2);
+    sg.setEndRes(4);
     sg.addSequence(seq1, false);
     sg.addSequence(seq2, false);
     sg.addSequence(seq3, false);
@@ -70,36 +91,37 @@ public class AlignViewControllerTest
             bs);
     assertEquals(1, seqCount);
     assertEquals(2, bs.cardinality());
-    assertTrue(bs.get(1));
-    assertTrue(bs.get(2));
+    assertTrue(bs.get(3)); // base 0
+    assertTrue(bs.get(4));
 
     /*
-     * select the first four columns: Metal in seq1 2:4, seq2 4:4
+     * select the first seven columns: Metal in seq1 cols 4-6, seq2 cols 6-7 
      */
-    sg.setEndRes(3);
+    sg.setEndRes(6);
     bs.clear();
     seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
     assertEquals(2, seqCount);
-    assertEquals(3, bs.cardinality());
-    assertTrue(bs.get(1));
-    assertTrue(bs.get(2));
+    assertEquals(4, bs.cardinality());
     assertTrue(bs.get(3));
+    assertTrue(bs.get(4));
+    assertTrue(bs.get(5));
+    assertTrue(bs.get(6));
 
     /*
-     * select column 11: Metal in seq3 only
+     * select column 14: Metal in seq3 only
      */
-    sg.setStartRes(10);
-    sg.setEndRes(10);
+    sg.setStartRes(13);
+    sg.setEndRes(13);
     bs.clear();
     seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
     assertEquals(1, seqCount);
     assertEquals(1, bs.cardinality());
-    assertTrue(bs.get(10));
+    assertTrue(bs.get(13));
 
     /*
-     * select columns 16-20: no Metal feature
+     * select columns 18-20: no Metal feature
      */
-    sg.setStartRes(15);
+    sg.setStartRes(17);
     sg.setEndRes(19);
     bs.clear();
     seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
@@ -107,6 +129,30 @@ public class AlignViewControllerTest
     assertEquals(0, bs.cardinality());
 
     /*
+     * columns 11-13 should not match disulfide bond at 8/12
+     */
+    sg.setStartRes(10);
+    sg.setEndRes(12);
+    bs.clear();
+    seqCount = AlignViewController.findColumnsWithFeature("disulfide bond",
+            sg, bs);
+    assertEquals(0, seqCount);
+    assertEquals(0, bs.cardinality());
+
+    /*
+     * columns 6-18 should match disulfide bond at columns 9, 14
+     */
+    sg.setStartRes(5);
+    sg.setEndRes(17);
+    bs.clear();
+    seqCount = AlignViewController.findColumnsWithFeature("disulfide bond",
+            sg, bs);
+    assertEquals(1, seqCount);
+    assertEquals(2, bs.cardinality());
+    assertTrue(bs.get(8));
+    assertTrue(bs.get(13));
+
+    /*
      * look for a feature that isn't there
      */
     sg.setStartRes(0);
@@ -116,4 +162,53 @@ public class AlignViewControllerTest
     assertEquals(0, seqCount);
     assertEquals(0, bs.cardinality());
   }
+
+  /**
+   * shameless copy of test data from findFeature for testing mark columns from
+   * highlight
+   */
+  @Test(groups = "Functional")
+  public void testSelectColumnsWithHighlight()
+  {
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "seq1 aMMMaaaaaaaaaaaaaaaa\n" + "seq2 aaaMMMMMMMaaaaaaaaaa\n"
+                    + "seq3 aaaaaaaaaaMMMMMaaaaa\n"
+                    + "seq4 aaaaaaaaaaaaaaaaaaaa\n", DataSourceType.PASTE);
+
+    SearchResultsI sr = new SearchResults();
+    SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
+    SequenceI seq1 = sqs[0];
+    SequenceI seq2 = sqs[1];
+    SequenceI seq3 = sqs[2];
+    SequenceI seq4 = sqs[3];
+
+    /*
+     * features start/end are base 1
+     */
+    sr.addResult(seq1, 2, 4);
+    sr.addResult(seq2, 4, 10);
+    sr.addResult(seq3, 11, 15);
+
+    /*
+     *  test Match/Find works first
+     */
+    Finder f = new Finder(af.getViewport().getAlignment(), null);
+    f.setFindAll(true);
+    f.setCaseSensitive(true);
+    f.find("M+");
+    assertEquals(
+            "Finder found different set of results to manually created SearchResults",
+            sr, f.getSearchResults());
+
+    /*
+     * now check simple mark columns from find operation
+     */
+    af.getViewport().setSearchResults(sr);
+    AlignViewControllerI avc = af.avc;
+
+    avc.markHighlightedColumns(false, false, false);
+    assertTrue("Didn't select highlighted columns", Arrays.deepEquals(af
+            .getViewport().getColumnSelection().getSelectedRanges()
+            .toArray(), new int[][] { { 1, 14 } }));
+  }
 }
index 2e0793e..fb4073a 100644 (file)
@@ -27,16 +27,25 @@ import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
 
+import jalview.gui.JvOptionPane;
 import jalview.util.MapList;
 
 import java.util.Arrays;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AlignedCodonFrameTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test the method that locates the first aligned sequence that has a mapping.
    */
index cc87f29..dd3ec7c 100644 (file)
@@ -23,11 +23,13 @@ package jalview.datamodel;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 
+import jalview.gui.JvOptionPane;
 import jalview.util.MapList;
 
 import java.util.Iterator;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 /**
@@ -38,6 +40,14 @@ import org.testng.annotations.Test;
  */
 public class AlignedCodonIteratorTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test normal case for iterating over aligned codons.
    */
index 29d6801..36f06f1 100644 (file)
@@ -24,11 +24,21 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AlignedCodonTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testEquals()
   {
index 1aff519..a2c6256 100644 (file)
@@ -24,12 +24,23 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 
 import jalview.analysis.AlignSeq;
+import jalview.gui.JvOptionPane;
 import jalview.io.AppletFormatAdapter;
+import jalview.io.FileFormat;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AlignmentAnnotationTests
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testCopyConstructor()
   {
@@ -119,7 +130,8 @@ public class AlignmentAnnotationTests
     alSeq2.setEnd(sqTo.getStart() + align.getSeq2End() - 1);
     alSeq2.setDatasetSequence(sqTo);
     System.out.println(new AppletFormatAdapter()
-            .formatSequences("STH", new Alignment(new SequenceI[] { sqFrom,
+.formatSequences(
+            FileFormat.Stockholm, new Alignment(new SequenceI[] { sqFrom,
                 alSeq1, sqTo, alSeq2 }), true));
 
     Mapping mp = align.getMappingFromS1(false);
@@ -143,7 +155,8 @@ public class AlignmentAnnotationTests
     AlignmentI all = new Alignment(new SequenceI[] { alSeq1, alSeq2 });
     all.addAnnotation(almap1);
     all.addAnnotation(almap2);
-    System.out.println(new AppletFormatAdapter().formatSequences("STH",
+    System.out.println(new AppletFormatAdapter().formatSequences(
+            FileFormat.Stockholm,
             all, true));
 
     for (int p = 0; p < alSeq1.getLength(); p++)
@@ -280,4 +293,4 @@ public class AlignmentAnnotationTests
               ann.getDefaultRnaHelixSymbol(i));
     }
   }
-}
\ No newline at end of file
+}
index 7958e9b..d2f4b4d 100644 (file)
@@ -28,7 +28,10 @@ import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
 import jalview.util.MapList;
 
@@ -39,6 +42,7 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -50,6 +54,14 @@ import org.testng.annotations.Test;
  */
 public class AlignmentTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   // @formatter:off
   private static final String TEST_DATA = 
           "# STOCKHOLM 1.0\n" +
@@ -94,11 +106,11 @@ public class AlignmentTest
    * @return
    * @throws IOException
    */
-  protected AlignmentI loadAlignment(final String data, String format)
+  protected AlignmentI loadAlignment(final String data, FileFormatI format)
           throws IOException
   {
-    AlignmentI a = new FormatAdapter().readFile(data,
-            AppletFormatAdapter.PASTE, format);
+    AlignmentI a = new FormatAdapter().readFile(data, DataSourceType.PASTE,
+            format);
     a.setDataset(null);
     return a;
   }
@@ -577,7 +589,7 @@ public class AlignmentTest
   @BeforeMethod(alwaysRun = true)
   public void setUp() throws IOException
   {
-    al = loadAlignment(TEST_DATA, "STH");
+    al = loadAlignment(TEST_DATA, FileFormat.Stockholm);
     int i = 0;
     for (AlignmentAnnotation ann : al.getAlignmentAnnotation())
     {
@@ -643,9 +655,9 @@ public class AlignmentTest
   public void testAlignAs_dnaAsDna() throws IOException
   {
     // aligned cDNA:
-    AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA");
+    AlignmentI al1 = loadAlignment(CDNA_SEQS_1, FileFormat.Fasta);
     // unaligned cDNA:
-    AlignmentI al2 = loadAlignment(CDNA_SEQS_2, "FASTA");
+    AlignmentI al2 = loadAlignment(CDNA_SEQS_2, FileFormat.Fasta);
 
     /*
      * Make mappings between sequences. The 'aligned cDNA' is playing the role
@@ -669,8 +681,8 @@ public class AlignmentTest
   public void testAlignAs_proteinAsCdna() throws IOException
   {
     // see also AlignmentUtilsTests
-    AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA");
-    AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA");
+    AlignmentI al1 = loadAlignment(CDNA_SEQS_1, FileFormat.Fasta);
+    AlignmentI al2 = loadAlignment(AA_SEQS_1, FileFormat.Fasta);
     makeMappings(al1, al2);
 
     // Fudge - alignProteinAsCdna expects mappings to be on protein
@@ -693,8 +705,8 @@ public class AlignmentTest
     /*
      * Load alignments and add mappings for cDNA to protein
      */
-    AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA");
-    AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA");
+    AlignmentI al1 = loadAlignment(CDNA_SEQS_1, FileFormat.Fasta);
+    AlignmentI al2 = loadAlignment(AA_SEQS_1, FileFormat.Fasta);
     makeMappings(al1, al2);
 
     /*
@@ -750,8 +762,8 @@ public class AlignmentTest
      * Load alignments and add mappings from nucleotide to protein (or from
      * first to second if both the same type)
      */
-    AlignmentI al1 = loadAlignment(fromSeqs, "FASTA");
-    AlignmentI al2 = loadAlignment(toSeqs, "FASTA");
+    AlignmentI al1 = loadAlignment(fromSeqs, FileFormat.Fasta);
+    AlignmentI al2 = loadAlignment(toSeqs, FileFormat.Fasta);
     makeMappings(al1, al2);
 
     /*
@@ -808,9 +820,9 @@ public class AlignmentTest
     String dna1 = "A-Aa-gG-GCC-cT-TT";
     String dna2 = "c--CCGgg-TT--T-AA-A";
     AlignmentI al1 = loadAlignment(">Dna1/6-17\n" + dna1
-            + "\n>Dna2/20-31\n" + dna2 + "\n", "FASTA");
+            + "\n>Dna2/20-31\n" + dna2 + "\n", FileFormat.Fasta);
     AlignmentI al2 = loadAlignment(
-            ">Pep1/7-9\n-P--YK\n>Pep2/11-13\nG-T--F\n", "FASTA");
+            ">Pep1/7-9\n-P--YK\n>Pep2/11-13\nG-T--F\n", FileFormat.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
@@ -850,7 +862,7 @@ public class AlignmentTest
   @Test(groups = "Functional")
   public void testCopyConstructor() throws IOException
   {
-    AlignmentI protein = loadAlignment(AA_SEQS_1, FormatAdapter.PASTE);
+    AlignmentI protein = loadAlignment(AA_SEQS_1, FileFormat.Fasta);
     // create sequence and alignment datasets
     protein.setDataset(null);
     AlignedCodonFrame acf = new AlignedCodonFrame();
@@ -887,7 +899,7 @@ public class AlignmentTest
   public void testCreateDatasetAlignment() throws IOException
   {
     AlignmentI protein = new FormatAdapter().readFile(AA_SEQS_1,
-            AppletFormatAdapter.PASTE, "FASTA");
+            DataSourceType.PASTE, FileFormat.Fasta);
     /*
      * create a dataset sequence on first sequence
      * leave the second without one
index 3d09f9f..594d6e6 100644 (file)
@@ -22,10 +22,21 @@ package jalview.datamodel;
 
 import static org.testng.Assert.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AlignmentViewTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testGetVisibleAlignmentGapChar()
   {
index ec528c5..a9ad4c2 100644 (file)
@@ -26,17 +26,27 @@ import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.AssertJUnit.fail;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.Collections;
 import java.util.ConcurrentModificationException;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ColumnSelectionTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testAddElement()
   {
diff --git a/test/jalview/datamodel/ConcurrentModificationTest.java b/test/jalview/datamodel/ConcurrentModificationTest.java
new file mode 100644 (file)
index 0000000..5ae403e
--- /dev/null
@@ -0,0 +1,224 @@
+package jalview.datamodel;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.List;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Not a test of code specific to Jalview, but some tests to verify Java
+ * behaviour under certain scenarios of concurrent modification of iterated
+ * lists or arrays
+ */
+public class ConcurrentModificationTest
+{
+  static int MAX = 10;
+
+  int[] intArray;
+
+  List<Integer> intList;
+
+  /**
+   * Setup: populate array and list with values 0,...,9
+   */
+  @BeforeMethod()
+  public void setUp()
+  {
+    intArray = new int[MAX];
+    intList = new ArrayList<Integer>();
+    for (int i = 0; i < MAX; i++)
+    {
+      intArray[i] = i;
+      intList.add(i);
+    }
+  }
+
+  /**
+   * Sanity check of values if no 'interference'
+   */
+  @Test
+  public void test_nullCase()
+  {
+    /*
+     * array iteration
+     */
+    int j = 0;
+    for (int i : intArray)
+    {
+      assertEquals(i, j);
+      j++;
+    }
+
+    /*
+     * list iteration
+     */
+    j = 0;
+    for (int i : intList)
+    {
+      assertEquals(i, j);
+      j++;
+    }
+  }
+
+  /**
+   * Test for the case where the array is reallocated and enlarged during the
+   * iteration. The for loop iteration is not affected.
+   */
+  @Test
+  public void testEnhancedForLoop_arrayExtended()
+  {
+    int j = 0;
+    for (int i : intArray)
+    {
+      if (j == 5)
+      {
+        intArray = new int[MAX + 1];
+      }
+      assertEquals(i, j);
+      j++;
+    }
+    assertEquals(j, MAX);
+  }
+
+  /**
+   * Test for the case where the array is nulled during the iteration. The for
+   * loop iteration is not affected.
+   */
+  @Test
+  public void testEnhancedForLoop_arrayNulled()
+  {
+    int j = 0;
+    for (int i : intArray)
+    {
+      if (j == 5)
+      {
+        intArray = null;
+      }
+      assertEquals(i, j);
+      j++;
+    }
+    assertEquals(j, MAX);
+  }
+
+  /**
+   * Test for the case where a value is changed before the iteration reaches it.
+   * The iteration reads the new value.
+   * <p>
+   * This is analagous to Jalview's consensus thread modifying entries in the
+   * AlignmentAnnotation.annotations array of Annotation[] while it is being
+   * read.
+   */
+  @Test
+  public void testEnhancedForLoop_arrayModified()
+  {
+    int j = 0;
+    for (int i : intArray)
+    {
+      if (j == 5)
+      {
+        intArray[5] = -1;
+        intArray[6] = -2;
+      }
+      /*
+       * the value 'just read' by the for loop is not affected;
+       * the next value read is affected
+       */
+      int expected = j == 6 ? -2 : j;
+      assertEquals(i, expected);
+      j++;
+    }
+    assertEquals(j, MAX);
+  }
+
+  /**
+   * Test for the case where a list entry is added during the iteration.
+   */
+  @Test
+  public void testEnhancedForLoop_listExtended()
+  {
+    int j = 0;
+    try
+    {
+      for (int i : intList)
+      {
+        if (j == 5)
+        {
+          intList.add(MAX + 1);
+        }
+        assertEquals(i, j);
+        j++;
+      }
+    } catch (ConcurrentModificationException e)
+    {
+      /*
+       * exception occurs on next loop iteration after 'concurrent'
+       * modification
+       */
+      assertEquals(j, 6);
+      return;
+    }
+    fail("Expected exception");
+  }
+
+  /**
+   * Test for the case where a list entry is modified during the iteration. No
+   * exception occurs.
+   */
+  @Test
+  public void testEnhancedForLoop_listModified()
+  {
+    int j = 0;
+    for (int i : intList)
+    {
+      if (j == 5)
+      {
+        intList.set(5, -1);
+        intList.set(6, -2);
+      }
+
+      /*
+       * the value 'just read' is not affected, the next value
+       * is read as modified, no exception
+       */
+      int expected = j == 6 ? -2 : j;
+      assertEquals(i, expected);
+      j++;
+    }
+    assertEquals(j, MAX);
+  }
+
+  /**
+   * Test for the case where the list is recreated during the iteration.
+   */
+  @Test
+  public void testEnhancedForLoop_listRenewed()
+  {
+    Object theList = intList;
+    int j = 0;
+    for (int i : intList)
+    {
+      if (j == 5)
+      {
+        /*
+         * recreate a new List object
+         */
+        setUp();
+        assertNotSame(theList, intList);
+      }
+      assertEquals(i, j);
+      j++;
+    }
+
+    /*
+     * no exception in the for loop; changing the object intList refers to
+     * does not affect the loop's iteration over the original object
+     */
+    assertEquals(j, MAX);
+  }
+}
index 87e7082..c8f998b 100644 (file)
@@ -25,13 +25,22 @@ import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
 import jalview.util.MapList;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class DBRefEntryTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Tests for the method that compares equality of reference (but not mapping)
    */
index 42fc58b..cae3536 100644 (file)
@@ -30,15 +30,25 @@ import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
 
 import jalview.gui.AlignViewport;
+import jalview.gui.JvOptionPane;
 
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
 @Test(singleThreaded = true)
 public class HiddenSequencesTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   static int SEQ_COUNT = 10;
 
   SequenceI[] seqs;
index b326d90..d739369 100644 (file)
@@ -23,10 +23,12 @@ package jalview.datamodel;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertSame;
 
+import jalview.gui.JvOptionPane;
 import jalview.util.MapList;
 
 import java.util.Arrays;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 /**
@@ -34,6 +36,14 @@ import org.testng.annotations.Test;
  */
 public class MappingTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * trite test of the intersectVisContigs method for a simple DNA -> Protein
    * exon map and a range of visContigs
index a7b28a7..f6a1116 100644 (file)
@@ -23,13 +23,21 @@ package jalview.datamodel;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertSame;
 
-import jalview.datamodel.MappingType;
+import jalview.gui.JvOptionPane;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class MappingTypeTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testGetInverse()
   {
index 6f3c7a9..e7d04d7 100644 (file)
@@ -24,27 +24,27 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
-import jalview.datamodel.SearchResults.Match;
+import jalview.gui.JvOptionPane;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class MatchTest
 {
 
-  @Test(groups = { "Functional" })
-  public void testToString()
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
   {
-    SequenceI seq = new Sequence("", "abcdefghijklm");
-    Match m = new SearchResults().new Match(seq, 3, 5);
-    assertEquals("2cde", m.toString());
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
   }
 
   @Test(groups = { "Functional" })
-  public void testGetCharacters()
+  public void testToString()
   {
-    SequenceI seq = new Sequence("", "abcdefghijklm");
-    Match m = new SearchResults().new Match(seq, 3, 5);
-    assertEquals("cde", m.getCharacters());
+    SequenceI seq = new Sequence("Seq1", "abcdefghijklm");
+    SearchResultMatchI m = new SearchResults().new Match(seq, 3, 5);
+    assertEquals("Seq1/3-5", m.toString());
   }
 
   @Test(groups = { "Functional" })
@@ -52,8 +52,8 @@ public class MatchTest
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
     SequenceI seq2 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     assertFalse(sr1.equals(null));
     assertFalse(sr1.equals(seq1));
@@ -72,7 +72,7 @@ public class MatchTest
     /*
      * same match but on different sequences - not equal
      */
-    SearchResults sr3 = new SearchResults();
+    SearchResultsI sr3 = new SearchResults();
     sr3.addResult(seq2, 1, 1);
     assertFalse(sr1.equals(sr3));
     assertFalse(sr3.equals(sr1));
index e9d5cb2..cf4294e 100644 (file)
@@ -31,15 +31,24 @@ import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
 import jalview.datamodel.PDBEntry.Type;
+import jalview.gui.JvOptionPane;
 
 //import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class PDBEntryTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @BeforeMethod(alwaysRun = true)
   public void setUp() throws Exception
   {
diff --git a/test/jalview/datamodel/ResidueCountTest.java b/test/jalview/datamodel/ResidueCountTest.java
new file mode 100644 (file)
index 0000000..4eb6dbf
--- /dev/null
@@ -0,0 +1,442 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.datamodel;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.ResidueCount.SymbolCounts;
+import jalview.gui.JvOptionPane;
+
+import org.junit.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ResidueCountTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  /**
+   * Test a mix of add and put for nucleotide counting
+   */
+  @Test(groups = "Functional")
+  public void test_countNucleotide()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    assertEquals(rc.getCount('A'), 0);
+    assertEquals(rc.getGapCount(), 0);
+    // add then add
+    assertEquals(rc.add('A'), 1);
+    assertEquals(rc.add('a'), 2);
+    // put then add
+    rc.put('g', 3);
+    assertEquals(rc.add('G'), 4);
+    // add then put
+    assertEquals(rc.add('c'), 1);
+    rc.put('C', 4);
+    assertEquals(rc.add('N'), 1);
+
+    assertEquals(rc.getCount('a'), 2);
+    assertEquals(rc.getCount('A'), 2);
+    assertEquals(rc.getCount('G'), 4);
+    assertEquals(rc.getCount('c'), 4);
+    assertEquals(rc.getCount('T'), 0); // never seen
+    assertEquals(rc.getCount('N'), 1);
+    assertEquals(rc.getCount('?'), 0);
+    assertEquals(rc.getCount('-'), 0);
+
+    assertFalse(rc.isCountingInts());
+    assertFalse(rc.isUsingOtherData());
+  }
+
+  /**
+   * Test adding to gap count (either using addGap or add)
+   */
+  @Test(groups = "Functional")
+  public void testAddGap()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    rc.addGap();
+    rc.add('-');
+    rc.add('.');
+    rc.add(' ');
+    
+    assertEquals(rc.getGapCount(), 4);
+    assertEquals(rc.getCount(' '), 4);
+    assertEquals(rc.getCount('-'), 4);
+    assertEquals(rc.getCount('.'), 4);
+    assertFalse(rc.isUsingOtherData());
+    assertFalse(rc.isCountingInts());
+  }
+
+  @Test(groups = "Functional")
+  public void testOverflow()
+  {
+    /*
+     * overflow from add
+     */
+    ResidueCount rc = new ResidueCount(true);
+    rc.addGap();
+    rc.put('A', Short.MAX_VALUE - 1);
+    assertFalse(rc.isCountingInts());
+    rc.add('A');
+    assertFalse(rc.isCountingInts());
+    rc.add('A');
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('a'), Short.MAX_VALUE + 1);
+    rc.add('A');
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('a'), Short.MAX_VALUE + 2);
+    assertEquals(rc.getGapCount(), 1);
+    rc.addGap();
+    assertEquals(rc.getGapCount(), 2);
+
+    /*
+     * overflow from put
+     */
+    rc = new ResidueCount(true);
+    rc.put('G', Short.MAX_VALUE + 1);
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('g'), Short.MAX_VALUE + 1);
+    rc.put('G', 1);
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('g'), 1);
+
+    /*
+     * underflow from put
+     */
+    rc = new ResidueCount(true);
+    rc.put('G', Short.MIN_VALUE - 1);
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('g'), Short.MIN_VALUE - 1);
+  }
+
+  /**
+   * Test a mix of add and put for peptide counting
+   */
+  @Test(groups = "Functional")
+  public void test_countPeptide()
+  {
+    ResidueCount rc = new ResidueCount(false);
+    rc.put('q', 4);
+    rc.add('Q');
+    rc.add('X');
+    rc.add('x');
+    rc.add('W');
+    rc.put('w', 7);
+    rc.put('m', 12);
+    rc.put('M', 13);
+
+    assertEquals(rc.getCount('q'), 5);
+    assertEquals(rc.getCount('X'), 2);
+    assertEquals(rc.getCount('W'), 7);
+    assertEquals(rc.getCount('m'), 13);
+    assertEquals(rc.getCount('G'), 0);
+    assertEquals(rc.getCount('-'), 0);
+
+    assertFalse(rc.isCountingInts());
+    assertFalse(rc.isUsingOtherData());
+  }
+
+  @Test(groups = "Functional")
+  public void test_unexpectedPeptide()
+  {
+    ResidueCount rc = new ResidueCount(false);
+    // expected characters (upper or lower case):
+    String aas = "ACDEFGHIKLMNPQRSTVWXY";
+    String lower = aas.toLowerCase();
+    for (int i = 0; i < aas.length(); i++)
+    {
+      rc.put(aas.charAt(i), i);
+      rc.add(lower.charAt(i));
+    }
+    for (int i = 0; i < aas.length(); i++)
+    {
+      assertEquals(rc.getCount(aas.charAt(i)), i + 1);
+    }
+    assertFalse(rc.isUsingOtherData());
+
+    rc.put('J', 4);
+    assertTrue(rc.isUsingOtherData());
+    assertEquals(rc.getCount('J'), 4);
+    rc.add('j');
+    assertEquals(rc.getCount('J'), 5);
+  }
+
+  @Test(groups = "Functional")
+  public void test_unexpectedNucleotide()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    // expected characters (upper or lower case):
+    String nucs = "ACGTUN";
+    String lower = nucs.toLowerCase();
+    for (int i = 0; i < nucs.length(); i++)
+    {
+      rc.put(nucs.charAt(i), i);
+      rc.add(lower.charAt(i));
+    }
+    for (int i = 0; i < nucs.length(); i++)
+    {
+      assertEquals(rc.getCount(nucs.charAt(i)), i + 1);
+    }
+    assertFalse(rc.isUsingOtherData());
+
+    rc.add('J');
+    assertTrue(rc.isUsingOtherData());
+  }
+
+  @Test(groups = "Functional")
+  public void testGetModalCount()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    rc.add('c');
+    rc.add('g');
+    rc.add('c');
+    assertEquals(rc.getModalCount(), 2);
+
+    // modal count is in the 'short overflow' counts
+    rc = new ResidueCount();
+    rc.add('c');
+    rc.put('g', Short.MAX_VALUE);
+    rc.add('G');
+    assertEquals(rc.getModalCount(), Short.MAX_VALUE + 1);
+
+    // modal count is in the 'other data' counts
+    rc = new ResidueCount(false);
+    rc.add('Q');
+    rc.add('{');
+    rc.add('{');
+    assertEquals(rc.getModalCount(), 2);
+
+    // verify modal count excludes gap
+    rc = new ResidueCount();
+    rc.add('Q');
+    rc.add('P');
+    rc.add('Q');
+    rc.addGap();
+    rc.addGap();
+    rc.addGap();
+    assertEquals(rc.getModalCount(), 2);
+  }
+
+  @Test(groups = "Functional")
+  public void testGetResiduesForCount()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    rc.add('c');
+    rc.add('g');
+    rc.add('c');
+    assertEquals(rc.getResiduesForCount(2), "C");
+    assertEquals(rc.getResiduesForCount(1), "G");
+    assertEquals(rc.getResiduesForCount(3), "");
+    assertEquals(rc.getResiduesForCount(0), "");
+    assertEquals(rc.getResiduesForCount(-1), "");
+
+    // modal count is in the 'short overflow' counts
+    rc = new ResidueCount(true);
+    rc.add('c');
+    rc.put('g', Short.MAX_VALUE);
+    rc.add('G');
+    assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "G");
+    assertEquals(rc.getResiduesForCount(1), "C");
+
+    // peptide modal count is in the 'short overflow' counts
+    rc = new ResidueCount(false);
+    rc.add('c');
+    rc.put('p', Short.MAX_VALUE);
+    rc.add('P');
+    assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "P");
+    assertEquals(rc.getResiduesForCount(1), "C");
+  
+    // modal count is in the 'other data' counts
+    rc = new ResidueCount();
+    rc.add('Q');
+    rc.add('{');
+    rc.add('{');
+    assertEquals(rc.getResiduesForCount(1), "Q");
+    assertEquals(rc.getResiduesForCount(2), "{");
+
+    // residues share modal count
+    rc = new ResidueCount();
+    rc.add('G');
+    rc.add('G');
+    rc.add('c');
+    rc.add('C');
+    rc.add('U');
+    assertEquals(rc.getResiduesForCount(1), "U");
+    assertEquals(rc.getResiduesForCount(2), "CG");
+
+    // expected and unexpected symbols share modal count
+    rc = new ResidueCount();
+    rc.add('G');
+    rc.add('t');
+    rc.add('[');
+    rc.add('[');
+    rc.add('t');
+    rc.add('G');
+    rc.add('c');
+    rc.add('C');
+    rc.add('U');
+    assertEquals(rc.getResiduesForCount(1), "U");
+    assertEquals(rc.getResiduesForCount(2), "CGT[");
+  }
+
+  @Test(groups = "Functional")
+  public void testGetSymbolCounts_nucleotide()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    rc.add('g');
+    rc.add('c');
+    rc.add('G');
+    rc.add('J'); // 'otherData'
+    rc.add('g');
+    rc.add('N');
+    rc.put('[', 0); // 'otherdata'
+
+    SymbolCounts sc = rc.getSymbolCounts();
+    Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'J', '[' },
+            sc.symbols);
+    Assert.assertArrayEquals(new int[] { 1, 3, 1, 1, 0 }, sc.values);
+
+    // now with overflow to int counts
+    rc.put('U', Short.MAX_VALUE);
+    rc.add('u');
+    sc = rc.getSymbolCounts();
+    Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'U', 'J', '[' },
+            sc.symbols);
+    Assert.assertArrayEquals(new int[] { 1, 3, 1, 32768, 1, 0 }, sc.values);
+  }
+
+  @Test(groups = "Functional")
+  public void testGetSymbolCounts_peptide()
+  {
+    ResidueCount rc = new ResidueCount(false);
+    rc.add('W');
+    rc.add('q');
+    rc.add('W');
+    rc.add('Z'); // 'otherData'
+    rc.add('w');
+    rc.add('L');
+
+    SymbolCounts sc = rc.getSymbolCounts();
+    Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
+    Assert.assertArrayEquals(new int[] { 1, 1, 3, 1 }, sc.values);
+
+    // now with overflow to int counts
+    rc.put('W', Short.MAX_VALUE);
+    rc.add('W');
+    sc = rc.getSymbolCounts();
+    Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
+    Assert.assertArrayEquals(new int[] { 1, 1, 32768, 1 }, sc.values);
+  }
+
+  @Test(groups = "Functional")
+  public void testToString()
+  {
+    ResidueCount rc = new ResidueCount();
+    rc.add('q');
+    rc.add('c');
+    rc.add('Q');
+    assertEquals(rc.toString(), "[ C:1 Q:2 ]");
+
+    // add 'other data'
+    rc.add('{');
+    assertEquals(rc.toString(), "[ C:1 Q:2 {:1 ]");
+
+    // switch from short to int counting:
+    rc.put('G', Short.MAX_VALUE);
+    rc.add('g');
+    assertEquals(rc.toString(), "[ C:1 G:32768 Q:2 {:1 ]");
+  }
+
+  @Test(groups = "Functional")
+  public void testGetTooltip()
+  {
+    ResidueCount rc = new ResidueCount();
+
+    // no counts!
+    assertEquals(rc.getTooltip(20, 1), "");
+
+    /*
+     * count 7 C, 6 K, 7 Q, 10 P, 9 W, 1 F (total 40)
+     */
+    for (int i = 0; i < 7; i++)
+    {
+      rc.add('c');
+      rc.add('q');
+    }
+    for (int i = 0; i < 10; i++)
+    {
+      rc.add('p');
+    }
+    for (int i = 0; i < 9; i++)
+    {
+      rc.add('W');
+    }
+    for (int i = 0; i < 6; i++)
+    {
+      rc.add('K');
+    }
+    rc.add('F');
+    
+    /*
+     * percentages are rounded (0.5 rounded up)
+     * 10/40 9/40 7/40 6/40 1/40
+     */
+    assertEquals(rc.getTooltip(40, 0),
+            "P 25%; W 23%; C 18%; Q 18%; K 15%; F 3%");
+
+    rc.add('Q');
+    /*
+     * 10/30 9/30 8/30 7/30 6/30 1/30
+     */
+    assertEquals(rc.getTooltip(30, 1),
+            "P 33.3%; W 30.0%; Q 26.7%; C 23.3%; K 20.0%; F 3.3%");
+  }
+
+  @Test(groups = "Functional")
+  public void testPut()
+  {
+    ResidueCount rc = new ResidueCount();
+    rc.put('q', 3);
+    assertEquals(rc.getCount('Q'), 3);
+    rc.put(' ', 4);
+    assertEquals(rc.getGapCount(), 4);
+    rc.put('.', 5);
+    assertEquals(rc.getGapCount(), 5);
+    rc.put('-', 6);
+    assertEquals(rc.getGapCount(), 6);
+
+    rc.put('?', 5);
+    assertEquals(rc.getCount('?'), 5);
+    rc.put('?', 6);
+    rc.put('!', 7);
+    assertEquals(rc.getCount('?'), 6);
+    assertEquals(rc.getCount('!'), 7);
+  }
+}
index f9a0a4f..f1a6e20 100644 (file)
@@ -25,49 +25,45 @@ import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
-import jalview.datamodel.SearchResults.Match;
+import jalview.gui.JvOptionPane;
 
+import java.util.BitSet;
+
+import org.junit.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class SearchResultsTest
 {
 
-  @Test(groups = { "Functional" })
-  public void testToString()
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
   {
-    SequenceI seq = new Sequence("", "abcdefghijklm");
-    SearchResults sr = new SearchResults();
-    sr.addResult(seq, 1, 1);
-    assertEquals("0a", sr.toString());
-    sr.addResult(seq, 3, 5);
-    assertEquals("0a2cde", sr.toString());
-
-    seq = new Sequence("", "pqrstuvwxy");
-    sr.addResult(seq, 6, 7);
-    assertEquals("0a2cde5uv", sr.toString());
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
   }
 
   @Test(groups = { "Functional" })
-  public void testGetCharacters()
+  public void testToString()
   {
-    SequenceI seq = new Sequence("", "abcdefghijklm");
-    SearchResults sr = new SearchResults();
+    SequenceI seq = new Sequence("Seq1", "abcdefghijklm");
+    SearchResultsI sr = new SearchResults();
     sr.addResult(seq, 1, 1);
-    assertEquals("a", sr.getCharacters());
+    assertEquals("[Seq1/1-1]", sr.toString());
     sr.addResult(seq, 3, 5);
-    assertEquals("acde", sr.getCharacters());
+    assertEquals("[Seq1/1-1, Seq1/3-5]", sr.toString());
 
-    seq = new Sequence("", "pqrstuvwxy");
+    seq = new Sequence("Seq2", "pqrstuvwxy");
     sr.addResult(seq, 6, 7);
-    assertEquals("acdeuv", sr.getCharacters());
+    assertEquals("[Seq1/1-1, Seq1/3-5, Seq2/6-7]", sr.toString());
   }
 
   @Test(groups = { "Functional" })
   public void testEquals()
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     assertFalse(sr1.equals(null)); // null object
     assertFalse(sr1.equals(seq1)); // wrong type
@@ -76,7 +72,7 @@ public class SearchResultsTest
     assertTrue(sr2.equals(sr1)); // reflexive
 
     /*
-     * only one result is not empty
+     * if only one result is not empty
      */
     sr1.addResult(seq1, 1, 1);
     assertTrue(sr1.equals(sr1));
@@ -111,8 +107,8 @@ public class SearchResultsTest
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
     SequenceI seq2 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     sr1.addResult(seq1, 1, 1);
     sr2.addResult(seq2, 1, 1);
@@ -127,8 +123,8 @@ public class SearchResultsTest
   public void testEquals_orderDiffers()
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     sr1.addResult(seq1, 1, 1);
     sr1.addResult(seq1, 2, 2);
@@ -145,8 +141,8 @@ public class SearchResultsTest
   public void testHashcode()
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     /*
      * both empty
@@ -178,7 +174,7 @@ public class SearchResultsTest
   public void testMatchConstructor()
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
-    Match m = new SearchResults().new Match(seq1, 2, 5);
+    SearchResultMatchI m = new SearchResults().new Match(seq1, 2, 5);
     assertSame(seq1, m.getSequence());
     assertEquals(2, m.getStart());
     assertEquals(5, m.getEnd());
@@ -189,4 +185,87 @@ public class SearchResultsTest
     assertEquals(2, m.getStart());
     assertEquals(5, m.getEnd());
   }
+
+  /**
+   * test markColumns for creating column selections
+   */
+  @Test(groups = { "Functional" })
+  public void testMarkColumns()
+  {
+    int marked = 0;
+    SequenceI seq1 = new Sequence("", "abcdefghijklm");
+    SequenceI seq2 = new Sequence("", "abcdefghijklm");
+    SequenceGroup s1g=new SequenceGroup(), s2g=new SequenceGroup(), sallg=new SequenceGroup();
+    s1g.addSequence(seq1, false);
+    s2g.addSequence(seq2, false);
+    sallg.addSequence(seq1, false);
+    sallg.addSequence(seq2, false);
+    
+    SearchResultsI sr = new SearchResults();
+    BitSet bs = new BitSet();
+    
+    SearchResultMatchI srm = null;
+    srm = sr.addResult(seq1, 1, 1);
+    Assert.assertNotNull("addResult didn't return Match", srm);
+    srm = sr.addResult(seq2, 1, 2);
+    assertEquals("Sequence reference not set", seq2, srm.getSequence());
+    assertEquals("match start incorrect", 1, srm.getStart());
+    assertEquals("match end incorrect", 2, srm.getEnd());
+    
+    // set start/end range for groups to cover matches
+
+    s1g.setStartRes(0);
+    s1g.setEndRes(5);
+    s2g.setStartRes(0);
+    s2g.setEndRes(5);
+    sallg.setStartRes(0);
+    sallg.setEndRes(5);
+
+    /*
+     * just seq1
+     */
+    marked = sr.markColumns(s1g, bs);
+    // check the bitset cardinality before checking the return value
+    assertEquals("Didn't mark expected number", 1, bs.cardinality());
+    assertEquals("Didn't return count of number of bits marked", 1, marked);
+    assertTrue("Didn't mark expected position", bs.get(0));
+    // now check return value for marking the same again
+    assertEquals(
+            "Didn't count number of bits marked for existing marked set",
+            0,
+            sr.markColumns(s1g, bs));
+    bs.clear();
+    
+    /*
+     * just seq2
+     */
+    marked = sr.markColumns(s2g, bs);
+    assertEquals("Didn't mark expected number", 2, bs.cardinality());
+    assertEquals("Didn't return count of number of bits marked", 2, marked);
+    assertTrue("Didn't mark expected position (1)", bs.get(0));
+    assertTrue("Didn't mark expected position (2)", bs.get(1));
+    
+    /*
+     * both seq1 and seq2 
+     * should be same as seq2
+     */
+    BitSet allbs = new BitSet();
+    assertEquals(2, sr.markColumns(sallg, allbs));
+    assertEquals(bs, allbs);
+
+    // now check range selection
+
+    /*
+     * limit s2g to just the second column, sallg to the first column
+     */
+    s2g.setStartRes(1);
+    s2g.setEndRes(1);
+    sallg.setEndRes(0);
+    BitSet tbs = new BitSet();
+    assertEquals("Group start/end didn't select columns to mark",1, sr.markColumns(s2g, tbs));
+    assertEquals("Group start/end didn't select columns to mark", 1, sr.markColumns(sallg, tbs));
+    assertEquals(
+            "Didn't set expected number of columns in total for two successive marks",
+            2, tbs.cardinality());
+  }
 }
index bb6581f..ab25aa6 100644 (file)
@@ -23,8 +23,10 @@ package jalview.datamodel;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 
+import jalview.gui.JvOptionPane;
 import jalview.util.Comparison;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 /**
@@ -32,6 +34,14 @@ import org.testng.annotations.Test;
  */
 public class SeqCigarTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testFindPosition()
   {
index e263843..fa7602b 100644 (file)
@@ -23,11 +23,22 @@ package jalview.datamodel;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 @Test
 public class SequenceDummyTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * test for become method
    */
index 2ec824d..2da8918 100644 (file)
@@ -26,10 +26,21 @@ import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class SequenceFeatureTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testCopyConstructor()
   {
@@ -112,56 +123,83 @@ public class SequenceFeatureTest
     assertEquals(sf1.hashCode(), sf2.hashCode());
 
     // changing type breaks equals:
+    String restores = sf2.getType();
     sf2.setType("Type");
     assertFalse(sf1.equals(sf2));
+    sf2.setType(restores);
 
     // changing description breaks equals:
-    sf2.setType("type");
+    restores = sf2.getDescription();
     sf2.setDescription("Desc");
     assertFalse(sf1.equals(sf2));
+    sf2.setDescription(restores);
+
+    // changing score breaks equals:
+    float restoref = sf2.getScore();
+    sf2.setScore(12.4f);
+    assertFalse(sf1.equals(sf2));
+    sf2.setScore(restoref);
+
+    // NaN doesn't match a number
+    restoref = sf2.getScore();
+    sf2.setScore(Float.NaN);
+    assertFalse(sf1.equals(sf2));
+
+    // NaN matches NaN
+    sf1.setScore(Float.NaN);
+    assertTrue(sf1.equals(sf2));
+    sf1.setScore(restoref);
+    sf2.setScore(restoref);
 
     // changing start position breaks equals:
-    sf2.setDescription("desc");
+    int restorei = sf2.getBegin();
     sf2.setBegin(21);
     assertFalse(sf1.equals(sf2));
+    sf2.setBegin(restorei);
 
     // changing end position breaks equals:
-    sf2.setBegin(22);
+    restorei = sf2.getEnd();
     sf2.setEnd(32);
     assertFalse(sf1.equals(sf2));
+    sf2.setEnd(restorei);
 
     // changing feature group breaks equals:
-    sf2.setEnd(33);
+    restores = sf2.getFeatureGroup();
     sf2.setFeatureGroup("Group");
     assertFalse(sf1.equals(sf2));
+    sf2.setFeatureGroup(restores);
 
     // changing ID breaks equals:
-    sf2.setFeatureGroup("group");
+    restores = (String) sf2.getValue("ID");
     sf2.setValue("ID", "id2");
     assertFalse(sf1.equals(sf2));
+    sf2.setValue("ID", restores);
 
     // changing Name breaks equals:
-    sf2.setValue("ID", "id");
+    restores = (String) sf2.getValue("Name");
     sf2.setValue("Name", "Name");
     assertFalse(sf1.equals(sf2));
+    sf2.setValue("Name", restores);
 
     // changing Parent breaks equals:
-    sf2.setValue("Name", "name");
+    restores = (String) sf1.getValue("Parent");
     sf1.setValue("Parent", "Parent");
     assertFalse(sf1.equals(sf2));
+    sf1.setValue("Parent", restores);
 
     // changing strand breaks equals:
-    sf1.setValue("Parent", "parent");
+    restorei = sf2.getStrand();
     sf2.setStrand("-");
     assertFalse(sf1.equals(sf2));
+    sf2.setStrand(restorei == 1 ? "+" : "-");
 
     // changing phase breaks equals:
-    sf2.setStrand("+");
+    restores = sf1.getPhase();
     sf1.setPhase("2");
     assertFalse(sf1.equals(sf2));
+    sf1.setPhase(restores);
 
     // restore equality as sanity check:
-    sf1.setPhase("1");
     assertTrue(sf1.equals(sf2));
     assertTrue(sf2.equals(sf1));
     assertEquals(sf1.hashCode(), sf2.hashCode());
@@ -170,4 +208,24 @@ public class SequenceFeatureTest
     sf1.setStatus("new");
     assertTrue(sf1.equals(sf2));
   }
+
+  @Test(groups = { "Functional" })
+  public void testIsContactFeature()
+  {
+    SequenceFeature sf = new SequenceFeature("type", "desc", 22, 33, 12.5f,
+            "group");
+    assertFalse(sf.isContactFeature());
+    sf.setType("");
+    assertFalse(sf.isContactFeature());
+    sf.setType(null);
+    assertFalse(sf.isContactFeature());
+    sf.setType("Disulfide Bond");
+    assertTrue(sf.isContactFeature());
+    sf.setType("disulfide bond");
+    assertTrue(sf.isContactFeature());
+    sf.setType("Disulphide Bond");
+    assertTrue(sf.isContactFeature());
+    sf.setType("disulphide bond");
+    assertTrue(sf.isContactFeature());
+  }
 }
index 065bed7..08e6f7d 100644 (file)
@@ -29,6 +29,7 @@ import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
 
 import jalview.datamodel.PDBEntry.Type;
+import jalview.gui.JvOptionPane;
 import jalview.util.MapList;
 
 import java.io.File;
@@ -38,11 +39,20 @@ import java.util.List;
 import java.util.Vector;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class SequenceTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   Sequence seq;
 
   @BeforeMethod(alwaysRun = true)
index 8ed5cc4..4672574 100644 (file)
@@ -28,16 +28,26 @@ import jalview.analysis.SequenceIdMatcher;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.util.MapList;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class EmblEntryTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testGetCdsRanges()
   {
index 906436f..7510de1 100644 (file)
@@ -24,14 +24,23 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 
 import jalview.datamodel.DBRefEntry;
+import jalview.gui.JvOptionPane;
 
 import java.util.Vector;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class EmblFileTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testGetEmblFile()
   {
diff --git a/test/jalview/ext/android/SparseIntArrayTest.java b/test/jalview/ext/android/SparseIntArrayTest.java
new file mode 100644 (file)
index 0000000..d9ed73d
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ext.android;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/*
+ * Tests for SparseIntArray. Unlike SparseShortArray, SparseIntArray does not throw
+ * any exception for overflow.
+ */
+public class SparseIntArrayTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
+  public void testPut()
+  {
+    SparseIntArray counter = new SparseIntArray();
+
+    /*
+     * either key or value may be in the range of int
+     */
+    counter.put(Integer.MAX_VALUE, Integer.MIN_VALUE);
+    counter.put(Integer.MIN_VALUE, Integer.MAX_VALUE);
+    assertEquals(counter.get(Integer.MAX_VALUE), Integer.MIN_VALUE);
+    assertEquals(counter.get(Integer.MIN_VALUE), Integer.MAX_VALUE);
+  }
+
+  @Test(groups = "Functional")
+  public void testAdd()
+  {
+    SparseIntArray counter = new SparseIntArray();
+  
+    assertEquals(counter.add('P', 2), 2);
+    assertEquals(counter.add('P', 3), 5);
+    counter.put('Q', 7);
+    assertEquals(counter.add('Q', 4), 11);
+
+    counter.put('x', Integer.MAX_VALUE);
+    try
+    {
+      counter.add('x', 1);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+  
+    counter.put('y', Integer.MIN_VALUE);
+    try
+    {
+      counter.add('y', -1);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+  }
+
+  @Test(groups = "Functional")
+  public void testCheckOverflow()
+  {
+    // things that don't overflow:
+    SparseIntArray.checkOverflow(Integer.MAX_VALUE, 0);
+    SparseIntArray.checkOverflow(Integer.MAX_VALUE, -1);
+    SparseIntArray.checkOverflow(Integer.MAX_VALUE, Integer.MIN_VALUE);
+    SparseIntArray.checkOverflow(Integer.MAX_VALUE, -Integer.MAX_VALUE);
+    SparseIntArray.checkOverflow(0, -Integer.MAX_VALUE);
+    SparseIntArray.checkOverflow(0, Integer.MIN_VALUE);
+    SparseIntArray.checkOverflow(Integer.MIN_VALUE, 0);
+    SparseIntArray.checkOverflow(Integer.MIN_VALUE, 1);
+    SparseIntArray.checkOverflow(Integer.MIN_VALUE, Integer.MAX_VALUE);
+
+    // and some that do
+    try
+    {
+      SparseIntArray.checkOverflow(Integer.MAX_VALUE, 1);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(Integer.MAX_VALUE - 1, 2);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(1, Integer.MAX_VALUE);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(Integer.MIN_VALUE, -1);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(Integer.MIN_VALUE + 1, -2);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(-1, Integer.MIN_VALUE);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+  }
+
+}
diff --git a/test/jalview/ext/android/SparseShortArrayTest.java b/test/jalview/ext/android/SparseShortArrayTest.java
new file mode 100644 (file)
index 0000000..034368f
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ext.android;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class SparseShortArrayTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
+  public void testPut()
+  {
+    SparseShortArray counter = new SparseShortArray();
+
+    /*
+     * either key or value may be in the range of short
+     */
+    counter.put(Short.MAX_VALUE, Short.MIN_VALUE);
+    counter.put(Short.MIN_VALUE, Short.MAX_VALUE);
+
+    // put a too large value
+    try
+    {
+      counter.put(0, Short.MAX_VALUE + 1);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+
+    // put a too small value
+    try
+    {
+      counter.put(1, Short.MIN_VALUE - 1);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+
+    // put a too large key
+    try
+    {
+      counter.put(Short.MAX_VALUE + 1, 0);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+
+    // put a too small key
+    try
+    {
+      counter.put(Short.MIN_VALUE - 1, 2);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+  }
+
+  @Test(groups = "Functional")
+  public void testAdd()
+  {
+    SparseShortArray counter = new SparseShortArray();
+  
+    assertEquals(counter.add('P', 2), 2);
+    assertEquals(counter.add('P', 3), 5);
+    counter.put('Q', 7);
+    assertEquals(counter.add('Q', 4), 11);
+
+    // increment giving overflow
+    counter.put('x', Short.MAX_VALUE);
+    try
+    {
+      counter.add('x', 1);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+  
+    // decrement giving underflow
+    counter.put('y', Short.MIN_VALUE);
+    try
+    {
+      counter.add('y', -1);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+  }
+}
index 95d371a..fb0204b 100644 (file)
@@ -28,6 +28,7 @@ import static org.testng.AssertJUnit.assertTrue;
 import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.io.gff.SequenceOntologyFactory;
 import jalview.io.gff.SequenceOntologyLite;
 import jalview.util.MapList;
@@ -41,6 +42,14 @@ import org.testng.annotations.Test;
 
 public class EnsemblCdnaTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @BeforeClass(alwaysRun = true)
   public void setUp()
   {
index c644e83..b7f9f8d 100644 (file)
@@ -27,6 +27,7 @@ import static org.testng.AssertJUnit.assertTrue;
 import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.io.gff.SequenceOntologyFactory;
 import jalview.io.gff.SequenceOntologyLite;
 import jalview.util.MapList;
@@ -40,6 +41,14 @@ import org.testng.annotations.Test;
 
 public class EnsemblCdsTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @BeforeClass(alwaysRun = true)
   public void setUp()
   {
index 33bb189..6cfd85b 100644 (file)
@@ -29,6 +29,7 @@ import jalview.api.FeatureSettingsModelI;
 import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.io.gff.SequenceOntologyFactory;
 import jalview.io.gff.SequenceOntologyLite;
 import jalview.util.MapList;
@@ -42,6 +43,14 @@ import org.testng.annotations.Test;
 
 public class EnsemblGeneTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @BeforeClass(alwaysRun = true)
   public void setUp()
   {
index 991cd96..654797c 100644 (file)
@@ -27,6 +27,7 @@ import static org.testng.AssertJUnit.assertTrue;
 import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.io.gff.SequenceOntologyFactory;
 import jalview.io.gff.SequenceOntologyLite;
 import jalview.util.MapList;
@@ -39,6 +40,14 @@ import org.testng.annotations.Test;
 
 public class EnsemblGenomeTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @BeforeClass(alwaysRun = true)
   public void setUp()
   {
index d44a82b..f6a4c8c 100644 (file)
@@ -22,12 +22,22 @@ package jalview.ext.ensembl;
 
 import static org.testng.AssertJUnit.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class EnsemblProteinTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testIsValidReference() throws Exception
   {
index d3a6e32..e977233 100644 (file)
@@ -28,7 +28,8 @@ import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.io.FastaFile;
 import jalview.io.FileParse;
 import jalview.io.gff.SequenceOntologyFactory;
@@ -45,6 +46,14 @@ import org.testng.annotations.Test;
 
 public class EnsemblSeqProxyTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private static final Object[][] allSeqs = new Object[][] {
       {
           new EnsemblProtein(),
@@ -150,7 +159,7 @@ public class EnsemblSeqProxyTest
     FileParse fp = proxy.getSequenceReader(Arrays
             .asList(new String[] { sq }));
     SequenceI[] sqs = new FastaFile(fp).getSeqsAsArray();
-    FastaFile trueRes = new FastaFile(fastasq, AppletFormatAdapter.PASTE);
+    FastaFile trueRes = new FastaFile(fastasq, DataSourceType.PASTE);
     SequenceI[] trueSqs = trueRes.getSeqsAsArray();
     Assert.assertEquals(sqs.length, trueSqs.length,
             "Different number of sequences retrieved for query " + sq);
index 9ef2843..9cc6627 100644 (file)
@@ -24,6 +24,7 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 
 import jalview.datamodel.DBRefEntry;
+import jalview.gui.JvOptionPane;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -31,10 +32,19 @@ import java.io.StringReader;
 import java.net.URL;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class EnsemblXrefTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   //@formatter:off
   private static final String JSON = 
           "[{\"primary_id\":\"CCDS5863\",\"dbname\":\"CCDS\"}," +
index f8c53b0..350b599 100644 (file)
 package jalview.ext.htsjdk;
 
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.io.File;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 /**
@@ -33,7 +35,15 @@ import org.testng.annotations.Test;
  */
 public class TestHtsContigDb
 {
-  @Test
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
   public final void testHTSReferenceSequence() throws Exception
   {
     HtsContigDb remmadb = new HtsContigDb("REEMADB", new File(
index 89ab580..439e188 100644 (file)
@@ -25,15 +25,24 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 import jalview.gui.SequenceRenderer;
 import jalview.structure.StructureMappingcommandSet;
 import jalview.structure.StructureSelectionManager;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class JmolCommandsTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testGetColourBySequenceCommand_noFeatures()
   {
index b2d3253..131ef41 100644 (file)
@@ -29,7 +29,8 @@ import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.io.FileLoader;
 import jalview.structure.StructureImportSettings;
 import jalview.structure.StructureImportSettings.StructureParser;
@@ -37,6 +38,7 @@ import jalview.structure.StructureImportSettings.StructureParser;
 import java.util.Vector;
 
 import org.jmol.c.STR;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -48,6 +50,14 @@ import MCview.PDBfile;
  */
 public class JmolParserTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /*
    * 1GAQ has been reduced to alpha carbons only
    * 1QCF is the full PDB file including headers, HETATM etc
@@ -105,8 +115,7 @@ public class JmolParserTest
     for (String f : testFile)
     {
       FileLoader fl = new jalview.io.FileLoader(false);
-      AlignFrame af = fl
-              .LoadFileWaitTillLoaded(f, AppletFormatAdapter.FILE);
+      AlignFrame af = fl.LoadFileWaitTillLoaded(f, DataSourceType.FILE);
       validateSecStrRows(af.getViewport().getAlignment());
     }
   }
@@ -117,8 +126,8 @@ public class JmolParserTest
     for (String pdbStr : testFile)
     {
       PDBfile mctest = new PDBfile(false, false, false, pdbStr,
-              AppletFormatAdapter.FILE);
-      JmolParser jtest = new JmolParser(pdbStr, AppletFormatAdapter.FILE);
+              DataSourceType.FILE);
+      JmolParser jtest = new JmolParser(pdbStr, DataSourceType.FILE);
       Vector<SequenceI> seqs = jtest.getSeqs(), mcseqs = mctest.getSeqs();
 
       assertTrue(
@@ -184,9 +193,8 @@ public class JmolParserTest
   public void testParse_missingResidues() throws Exception
   {
     PDBfile mctest = new PDBfile(false, false, false,
-            pastePDBDataWithChainBreak, AppletFormatAdapter.PASTE);
-    JmolParser jtest = new JmolParser(pastePDBDataWithChainBreak,
-            AppletFormatAdapter.PASTE);
+            pastePDBDataWithChainBreak, DataSourceType.PASTE);
+    JmolParser jtest = new JmolParser(pastePDBDataWithChainBreak, DataSourceType.PASTE);
     Vector<SequenceI> seqs = jtest.getSeqs();
     Vector<SequenceI> mcseqs = mctest.getSeqs();
 
@@ -207,9 +215,9 @@ public class JmolParserTest
   public void testParse_alternativeResidues() throws Exception
   {
     PDBfile mctest = new PDBfile(false, false, false, pdbWithAltLoc,
-            AppletFormatAdapter.PASTE);
+            DataSourceType.PASTE);
     JmolParser jtest = new JmolParser(pdbWithAltLoc,
-            AppletFormatAdapter.PASTE);
+            DataSourceType.PASTE);
     Vector<SequenceI> seqs = jtest.getSeqs();
     Vector<SequenceI> mcseqs = mctest.getSeqs();
 
@@ -258,7 +266,7 @@ public class JmolParserTest
      * reads a local structure
      */
     structureData = new JmolParser("examples/testdata/localstruct.pdb",
-            AppletFormatAdapter.FILE);
+            DataSourceType.FILE);
     assertNotNull(structureData);
     /*
      * local structure files should yield a false ID based on the filename
index 10224fa..959ecab 100644 (file)
@@ -26,10 +26,11 @@ import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 import jalview.gui.Preferences;
 import jalview.gui.StructureViewer;
 import jalview.gui.StructureViewer.ViewerType;
-import jalview.io.FormatAdapter;
+import jalview.io.DataSourceType;
 
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -39,6 +40,13 @@ import org.testng.annotations.Test;
 public class JmolViewerTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * @throws java.lang.Exception
    */
@@ -65,7 +73,7 @@ public class JmolViewerTest
     Cache.setProperty(Preferences.STRUCTURE_DISPLAY, ViewerType.JMOL.name());
     String inFile = "examples/1gaq.txt";
     AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
-            inFile, FormatAdapter.FILE);
+            inFile, DataSourceType.FILE);
     assertTrue("Didn't read input file " + inFile, af != null);
     for (SequenceI sq : af.getViewport().getAlignment().getSequences())
     {
index 254e082..d285b04 100644 (file)
@@ -21,7 +21,8 @@
 package jalview.ext.jmol;
 
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 
 import java.io.File;
 import java.io.IOException;
@@ -29,6 +30,8 @@ import java.util.HashSet;
 import java.util.Set;
 import java.util.Vector;
 
+import org.testng.annotations.BeforeClass;
+
 import MCview.PDBfile;
 
 /**
@@ -43,6 +46,13 @@ import MCview.PDBfile;
 public class JmolVsJalviewPDBParserEndToEndTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   public static void main(String[] args)
   {
     if (args == null || args[0] == null)
@@ -71,9 +81,8 @@ public class JmolVsJalviewPDBParserEndToEndTest
       JmolParser jtest = null;
       try
       {
-        mctest = new PDBfile(false, false, false, testFile,
-                AppletFormatAdapter.FILE);
-        jtest = new JmolParser(testFile, AppletFormatAdapter.FILE);
+        mctest = new PDBfile(false, false, false, testFile, DataSourceType.FILE);
+        jtest = new JmolParser(testFile, DataSourceType.FILE);
       } catch (IOException e)
       {
         System.err.println("Exception thrown while parsing : " + pdbStr);
index 4110863..85fc039 100644 (file)
@@ -24,7 +24,10 @@ import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.io.FastaFile;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 
 import java.io.BufferedReader;
@@ -34,6 +37,7 @@ import java.util.Iterator;
 
 import org.testng.Assert;
 import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import MCview.PDBfile;
@@ -43,6 +47,13 @@ import compbio.util.FileUtil;
 public class TestAnnotate3D
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Network" }, enabled = true)
   public void test1GIDbyId() throws Exception
   {
@@ -101,7 +112,7 @@ public class TestAnnotate3D
   public void testPDBfileVsRNAML() throws Exception
   {
     PDBfile pdbf = new PDBfile(true, false, true, "examples/2GIS.pdb",
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
     Assert.assertTrue(pdbf.isValid());
     // Comment - should add new FileParse constructor like new FileParse(Reader
     // ..). for direct reading
@@ -128,7 +139,7 @@ public class TestAnnotate3D
       assertTrue("No data returned by Annotate3D", sb.length() > 0);
       final String lines = sb.toString();
       AlignmentI al = new FormatAdapter().readFile(lines,
-              FormatAdapter.PASTE, "RNAML");
+              DataSourceType.PASTE, FileFormat.Rnaml);
       if (al == null || al.getHeight() == 0)
       {
         System.out.println(lines);
@@ -156,11 +167,11 @@ public class TestAnnotate3D
             {
               AssertJUnit
                       .fail("Couldn't find this sequence in original input:\n"
-                              + new FastaFile()
-                                      .print(new SequenceI[] { sq })
+                              + new FastaFile().print(
+                                      new SequenceI[] { sq }, true)
                               + "\n\nOriginal input:\n"
-                              + new FastaFile().print(pdbf.getSeqsAsArray())
-                              + "\n");
+                              + new FastaFile().print(
+                                      pdbf.getSeqsAsArray(), true) + "\n");
             }
           }
         }
index 29c7d16..d0ea751 100644 (file)
@@ -23,16 +23,27 @@ package jalview.ext.rbvi.chimera;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
 import java.awt.Color;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ChimeraCommandsTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testAddColourRange()
   {
index a5393ec..4d904cf 100644 (file)
@@ -23,6 +23,9 @@ package jalview.ext.rbvi.chimera;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import ext.edu.ucsf.rbvi.strucviz2.ChimeraManager;
@@ -31,6 +34,13 @@ import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
 public class ChimeraConnect
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testLaunchAndExit()
   {
index 93a98b8..f4fb40b 100644 (file)
@@ -27,10 +27,11 @@ import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 import jalview.gui.Preferences;
 import jalview.gui.StructureViewer;
 import jalview.gui.StructureViewer.ViewerType;
-import jalview.io.FormatAdapter;
+import jalview.io.DataSourceType;
 
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -40,6 +41,13 @@ import org.testng.annotations.Test;
 public class JalviewChimeraView
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * @throws java.lang.Exception
    */
@@ -67,7 +75,7 @@ public class JalviewChimeraView
             ViewerType.CHIMERA.name());
     String inFile = "examples/1gaq.txt";
     AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
-            inFile, FormatAdapter.FILE);
+            inFile, DataSourceType.FILE);
     assertTrue("Didn't read input file " + inFile, af != null);
     for (SequenceI sq : af.getViewport().getAlignment().getSequences())
     {
index 1bc802e..b76a295 100644 (file)
@@ -23,6 +23,7 @@ package jalview.ext.so;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
 import jalview.io.gff.SequenceOntologyI;
 
 import org.testng.annotations.BeforeClass;
@@ -30,6 +31,14 @@ import org.testng.annotations.Test;
 
 public class SequenceOntologyTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private SequenceOntologyI so;
 
   @BeforeClass(alwaysRun = true)
index b751b77..44fe8d0 100644 (file)
@@ -22,17 +22,27 @@ package jalview.fts.core;
 
 import jalview.fts.api.FTSDataColumnI;
 import jalview.fts.api.FTSDataColumnI.FTSDataColumnGroupI;
+import jalview.gui.JvOptionPane;
 
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class FTSRestClientTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private FTSRestClient ftsRestClient;
 
   @BeforeMethod(alwaysRun = true)
index 69792bb..901bffc 100644 (file)
@@ -23,16 +23,26 @@ package jalview.fts.service.pdb;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
 import javax.swing.JInternalFrame;
 import javax.swing.JTextField;
 
 import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class PDBFTSPanelTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @BeforeMethod(alwaysRun = true)
   public void setUp() throws Exception
   {
index 8faec58..bbd45aa 100644 (file)
@@ -26,6 +26,7 @@ import static org.testng.AssertJUnit.assertTrue;
 import jalview.fts.api.FTSDataColumnI;
 import jalview.fts.core.FTSRestRequest;
 import jalview.fts.core.FTSRestResponse;
+import jalview.gui.JvOptionPane;
 
 import java.io.BufferedReader;
 import java.io.FileReader;
@@ -42,6 +43,7 @@ import org.json.simple.parser.JSONParser;
 import org.json.simple.parser.ParseException;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -54,6 +56,13 @@ import com.sun.jersey.api.client.config.DefaultClientConfig;
 public class PDBFTSRestClientTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @BeforeMethod(alwaysRun = true)
   public void setUp() throws Exception
   {
index 316d9af..60db9dd 100644 (file)
@@ -32,12 +32,20 @@ import jalview.datamodel.SequenceI;
 
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AlignFrameTest
 {
 
-  @Test
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
   public void testHideFeatureColumns()
   {
     SequenceI seq1 = new Sequence("Seq1", "ABCDEFGHIJ");
index d7b26b0..5695b15 100644 (file)
@@ -35,10 +35,12 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
 import jalview.io.FileLoader;
-import jalview.io.FormatAdapter;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.PIDColourScheme;
 import jalview.structure.StructureSelectionManager;
@@ -54,6 +56,13 @@ import org.testng.annotations.Test;
 public class AlignViewportTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   AlignmentI al;
 
   AlignViewport testee;
@@ -138,7 +147,7 @@ public class AlignViewportTest
      * alignment with reference to mappings
      */
     AlignFrame af1 = new FileLoader().LoadFileWaitTillLoaded(
-            ">Seq1\nCAGT\n", FormatAdapter.PASTE);
+            ">Seq1\nCAGT\n", DataSourceType.PASTE);
 
     SequenceI s1 = af1.getViewport().getAlignment().getSequenceAt(0);
     AlignedCodonFrame acf1 = new AlignedCodonFrame();
@@ -187,9 +196,9 @@ public class AlignViewportTest
     ssm.resetAll();
 
     AlignFrame af1 = new FileLoader().LoadFileWaitTillLoaded(
-            ">Seq1\nRSVQ\n", FormatAdapter.PASTE);
+            ">Seq1\nRSVQ\n", DataSourceType.PASTE);
     AlignFrame af2 = new FileLoader().LoadFileWaitTillLoaded(
-            ">Seq2\nDGEL\n", FormatAdapter.PASTE);
+            ">Seq2\nDGEL\n", DataSourceType.PASTE);
     SequenceI cs1 = new Sequence("cseq1", "CCCGGGTTTAAA");
     SequenceI cs2 = new Sequence("cseq2", "CTTGAGTCTAGA");
     SequenceI s1 = af1.getViewport().getAlignment().getSequenceAt(0);
@@ -250,9 +259,9 @@ public class AlignViewportTest
     ssm.resetAll();
 
     AlignFrame af1 = new FileLoader().LoadFileWaitTillLoaded(
-            ">Seq1\nRSVQ\n", FormatAdapter.PASTE);
+            ">Seq1\nRSVQ\n", DataSourceType.PASTE);
     AlignFrame af2 = new FileLoader().LoadFileWaitTillLoaded(
-            ">Seq2\nDGEL\n", FormatAdapter.PASTE);
+            ">Seq2\nDGEL\n", DataSourceType.PASTE);
     SequenceI cs1 = new Sequence("cseq1", "CCCGGGTTTAAA");
     SequenceI cs2 = new Sequence("cseq2", "CTTGAGTCTAGA");
     SequenceI s1 = af1.getViewport().getAlignment().getSequenceAt(0);
@@ -319,7 +328,7 @@ public class AlignViewportTest
     Cache.applicationProperties.setProperty("SHOW_IDENTITY",
             Boolean.FALSE.toString());
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
-            "examples/uniref50.fa", FormatAdapter.FILE);
+            "examples/uniref50.fa", DataSourceType.FILE);
     AlignmentAnnotation[] anns = af.viewport.getAlignment()
             .getAlignmentAnnotation();
     assertNotNull("No annotations found", anns);
@@ -338,15 +347,37 @@ public class AlignViewportTest
     /*
      * test for JAL-2283 don't inadvertently turn on colour by conservation
      */
-    Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
-            Boolean.TRUE.toString());
-    Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
-            Boolean.FALSE.toString());
     Cache.applicationProperties.setProperty("DEFAULT_COLOUR_PROT", "NONE");
+    Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+            Boolean.TRUE.toString());
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
-            "examples/uniref50.fa", FormatAdapter.FILE);
+            "examples/uniref50.fa", DataSourceType.FILE);
     ColourSchemeI cs = new PIDColourScheme();
     af.getViewport().setGlobalColourScheme(cs);
     assertFalse(cs.conservationApplied());
   }
+
+  @Test(groups = { "Functional" })
+  public void testSetGetHasSearchResults()
+  {
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
+    SearchResultsI sr = new SearchResults();
+    SequenceI s1 = af.getViewport().getAlignment().getSequenceAt(0);
+
+    // create arbitrary range on first sequence
+    sr.addResult(s1, s1.getStart() + 10, s1.getStart() + 15);
+
+    // test set
+    af.getViewport().setSearchResults(sr);
+    // has -> true
+    assertTrue(af.getViewport().hasSearchResults());
+    // get == original
+    assertEquals(sr, af.getViewport().getSearchResults());
+
+    // set(null) results in has -> false
+
+    af.getViewport().setSearchResults(null);
+    assertFalse(af.getViewport().hasSearchResults());
+  }
 }
index 6621a94..38c1855 100644 (file)
@@ -31,7 +31,9 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FormatAdapter;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -46,6 +48,7 @@ import java.util.List;
 import javax.swing.JButton;
 import javax.swing.JPanel;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -57,6 +60,14 @@ import org.testng.annotations.Test;
  */
 public class AnnotationChooserTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   // 4 sequences x 13 positions
   final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n"
           + "TIETHKEAELVG-\n"
@@ -86,8 +97,8 @@ public class AnnotationChooserTest
     Cache.applicationProperties.setProperty("SHOW_CONSERVATION", TRUE);
     Cache.applicationProperties.setProperty("SHOW_IDENTITY", TRUE);
 
-    AlignmentI al = new jalview.io.FormatAdapter().readFile(TEST_DATA,
-            AppletFormatAdapter.PASTE, "FASTA");
+    AlignmentI al = new FormatAdapter().readFile(TEST_DATA,
+            DataSourceType.PASTE, FileFormat.Fasta);
     af = new AlignFrame(al, 700, 500);
     parentPanel = new AlignmentPanel(af, af.getViewport());
     addAnnotations();
index 5bc0ddf..17dbf5f 100644 (file)
@@ -24,11 +24,20 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertSame;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AppVarnaTest
 {
-  @Test
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
   public void testReplaceOddGaps()
   {
     String struct = "{(<]}>)";
index 355fdc3..57d561e 100644 (file)
@@ -24,11 +24,19 @@ import java.awt.Canvas;
 import java.awt.Font;
 import java.awt.FontMetrics;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class FontChooserTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Not a real test as it runs no methods on FontChooser and makes no
    * assertions, but this method writes to sysout the names of any (currently
index 26132b9..d2188db 100644 (file)
@@ -30,10 +30,19 @@ import javax.help.HelpSet;
 import javax.help.HelpSetException;
 import javax.help.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class HelpTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void checkHelpTargets() throws HelpSetException
   {
index 489fe4f..87ceed8 100644 (file)
@@ -39,6 +39,13 @@ public class JAL1353bugdemo
 {
 
   @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @BeforeClass(alwaysRun = true)
   public static void setUpBeforeClass() throws Exception
   {
   }
diff --git a/test/jalview/gui/JvOptionPaneTest.java b/test/jalview/gui/JvOptionPaneTest.java
new file mode 100644 (file)
index 0000000..02e3b65
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.gui;
+
+import java.awt.Component;
+import java.awt.Dimension;
+
+import javax.swing.Icon;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class JvOptionPaneTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  Component parentComponent = null;
+
+  String message = "Hello World!";
+
+  String title = "Title";
+
+  int optionType = JvOptionPane.OK_CANCEL_OPTION;
+
+  int messageType = JvOptionPane.INFORMATION_MESSAGE;
+
+  Icon icon = null;
+
+  Object initialSelectionValue = null;
+
+  Object[] selectionValues = null;
+
+
+  @Test(groups = { "Functional" })
+  public void showConfirmDialogFamilyTest()
+  {
+    JvOptionPane.showConfirmDialog(parentComponent, message);
+    JvOptionPane.showConfirmDialog(parentComponent, message, title,
+            optionType);
+    JvOptionPane.showConfirmDialog(parentComponent, message, title,
+            optionType, messageType);
+    JvOptionPane.showConfirmDialog(parentComponent, message, title,
+            optionType, messageType, icon);
+    Assert.assertTrue(true);
+  }
+
+  @Test(groups = { "Functional" })
+  public void showInputDialogFamilyTest()
+  {
+    JvOptionPane.showInputDialog(message);
+    JvOptionPane.showInputDialog(parentComponent, message);
+    JvOptionPane.showInputDialog(message, initialSelectionValue);
+    JvOptionPane.showInputDialog(parentComponent, message,
+            initialSelectionValue);
+    JvOptionPane.showInputDialog(parentComponent, message, title,
+            messageType);
+    JvOptionPane.showInputDialog(parentComponent, message, title,
+            messageType, icon, selectionValues, initialSelectionValue);
+    Assert.assertTrue(true);
+  }
+
+  @Test(groups = { "Functional" })
+  public void showMessageDialogFamilyTest()
+  {
+    JvOptionPane.showMessageDialog(parentComponent, message);
+    JvOptionPane.showMessageDialog(parentComponent, message, title,
+            messageType);
+    JvOptionPane.showMessageDialog(parentComponent, message, title,
+            messageType, icon);
+    Assert.assertTrue(true);
+  }
+
+  @Test(groups = { "Functional" })
+  public void showInternalMessageDialogFamilyTest()
+  {
+    JvOptionPane.showInternalMessageDialog(parentComponent, message);
+    JvOptionPane.showInternalMessageDialog(parentComponent, message, title,
+            messageType);
+    JvOptionPane.showInternalMessageDialog(parentComponent, message, title,
+            messageType, icon);
+    Assert.assertTrue(true);
+  }
+
+  @Test(groups = { "Functional" })
+  public void showInternalConfirmDialogFamilyTest()
+  {
+    JvOptionPane.showInternalConfirmDialog(parentComponent, message, title,
+            optionType);
+    JvOptionPane.showInternalConfirmDialog(parentComponent, message, title,
+            optionType, messageType);
+
+    JvOptionPane.showInternalConfirmDialog(getDummyDesktopPane(), message);
+
+    JvOptionPane.showInternalConfirmDialog(getDummyDesktopPane(), message,
+            title, optionType, messageType, icon);
+    JvOptionPane.showInternalInputDialog(getDummyDesktopPane(), message);
+    JvOptionPane.showInternalInputDialog(getDummyDesktopPane(), message,
+            title, messageType);
+    JvOptionPane.showInternalInputDialog(getDummyDesktopPane(), message,
+            title, messageType, icon, selectionValues,
+            initialSelectionValue);
+    Assert.assertTrue(true);
+
+  }
+
+  private JDesktopPane getDummyDesktopPane()
+  {
+    JFrame frame = new JFrame("Dummy JDesktopPane");
+    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    @SuppressWarnings("serial")
+    JDesktopPane jdpDesktop = new JDesktopPane()
+    {
+      @Override
+      public Dimension getPreferredSize()
+      {
+        return new Dimension(400, 300);
+      }
+    };
+    frame.setContentPane(jdpDesktop);
+    JPanel panel = new JPanel();
+    panel.setBounds(0, 0, 400, 300);
+    jdpDesktop.add(panel);
+    frame.pack();
+    frame.setVisible(true);
+    panel.setVisible(true);
+    return jdpDesktop;
+  }
+}
index f1358d8..5e65cc2 100644 (file)
@@ -25,11 +25,19 @@ import static org.testng.AssertJUnit.assertFalse;
 
 import javax.swing.JScrollBar;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class JvSwingUtilsTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testGetScrollBarProportion()
   {
index 212bcce..5167eb3 100644 (file)
@@ -36,11 +36,20 @@ import java.util.Map;
 import javax.swing.JPanel;
 
 import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class PaintRefresherTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   // TODO would prefer PaintRefresher to be a single rather than static
   @BeforeMethod(alwaysRun = true)
   public void setUp()
index edf3202..922d457 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.gui;
 
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
@@ -27,8 +29,12 @@ import static org.testng.AssertJUnit.assertTrue;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 import jalview.util.MessageManager;
 
@@ -42,11 +48,20 @@ import javax.swing.JMenuItem;
 import javax.swing.JPopupMenu;
 import javax.swing.JSeparator;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class PopupMenuTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   // 4 sequences x 13 positions
   final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n"
           + "TIETHKEAELVG-\n"
@@ -66,7 +81,7 @@ public class PopupMenuTest
   public void setUp() throws IOException
   {
     alignment = new FormatAdapter().readFile(TEST_DATA,
-            AppletFormatAdapter.PASTE, "FASTA");
+            DataSourceType.PASTE, FileFormat.Fasta);
     AlignFrame af = new AlignFrame(alignment, 700, 500);
     parentPanel = new AlignmentPanel(af, af.getViewport());
     testee = new PopupMenu(parentPanel, null, null);
@@ -440,4 +455,105 @@ public class PopupMenuTest
     assertEquals(JSeparator.HORIZONTAL,
             ((JSeparator) hideOptions[1]).getOrientation());
   }
+
+  /**
+   * Test for adding feature links
+   */
+  @Test(groups = { "Functional" })
+  public void testAddFeatureLinks()
+  {
+    // sequences from the alignment
+    List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
+
+    // create list of links and list of DBRefs
+    List<String> links = new ArrayList<String>();
+    List<DBRefEntry> refs = new ArrayList<DBRefEntry>();
+
+    // links as might be added into Preferences | Connections dialog
+    links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
+            + SEQUENCE_ID + "$");
+    links.add("UNIPROT | http://www.uniprot.org/uniprot/$" + DB_ACCESSION
+            + "$");
+    links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$"
+            + DB_ACCESSION + "$");
+    // Gene3D entry tests for case (in)sensitivity
+    links.add("Gene3D | http://gene3d.biochem.ucl.ac.uk/Gene3D/search?sterm=$"
+            + DB_ACCESSION + "$&mode=protein");
+
+    // make seq0 dbrefs
+    refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR001041"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR006058"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR012675"));
+    
+    // make seq1 dbrefs
+    refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "Q9ZTS2"));
+    refs.add(new DBRefEntry("GENE3D", "1", "3.10.20.30"));
+
+    // add all the dbrefs to the sequences: Uniprot 1 each, Interpro all 3 to
+    // seq0, Gene3D to seq1
+    seqs.get(0).addDBRef(refs.get(0));
+
+    seqs.get(0).addDBRef(refs.get(1));
+    seqs.get(0).addDBRef(refs.get(2));
+    seqs.get(0).addDBRef(refs.get(3));
+    
+    seqs.get(1).addDBRef(refs.get(4));
+    seqs.get(1).addDBRef(refs.get(5));
+    
+    // get the Popup Menu for first sequence
+    testee = new PopupMenu(parentPanel, (Sequence) seqs.get(0), links);
+    Component[] seqItems = testee.sequenceMenu.getMenuComponents();
+    JMenu linkMenu = (JMenu) seqItems[6];
+    Component[] linkItems = linkMenu.getMenuComponents();
+    
+    // check the number of links are the expected number
+    assertEquals(5, linkItems.length);
+
+    // first entry is EMBL-EBI which just uses sequence id not accession id?
+    assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText());
+
+    // sequence id for each link should match corresponding DB accession id
+    for (int i = 1; i < 4; i++)
+    {
+      assertEquals(refs.get(i - 1).getSource(), ((JMenuItem) linkItems[i])
+              .getText().split("\\|")[0]);
+      assertEquals(refs.get(i - 1).getAccessionId(),
+              ((JMenuItem) linkItems[i])
+              .getText().split("\\|")[1]);
+    }
+
+    // get the Popup Menu for second sequence
+    testee = new PopupMenu(parentPanel, (Sequence) seqs.get(1), links);
+    seqItems = testee.sequenceMenu.getMenuComponents();
+    linkMenu = (JMenu) seqItems[6];
+    linkItems = linkMenu.getMenuComponents();
+    
+    // check the number of links are the expected number
+    assertEquals(3, linkItems.length);
+
+    // first entry is EMBL-EBI which just uses sequence id not accession id?
+    assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText());
+
+    // sequence id for each link should match corresponding DB accession id
+    for (int i = 1; i < 3; i++)
+    {
+      assertEquals(refs.get(i + 3).getSource(), ((JMenuItem) linkItems[i])
+              .getText().split("\\|")[0].toUpperCase());
+      assertEquals(refs.get(i + 3).getAccessionId(),
+              ((JMenuItem) linkItems[i]).getText().split("\\|")[1]);
+    }
+
+    // if there are no valid links the Links submenu is disabled
+    List<String> nomatchlinks = new ArrayList<String>();
+    nomatchlinks.add("NOMATCH | http://www.uniprot.org/uniprot/$"
+            + DB_ACCESSION + "$");
+
+    testee = new PopupMenu(parentPanel, (Sequence) seqs.get(0),
+            nomatchlinks);
+    seqItems = testee.sequenceMenu.getMenuComponents();
+    linkMenu = (JMenu) seqItems[6];
+    assertFalse(linkMenu.isEnabled());
+
+  }
 }
index 4346420..a1715e9 100644 (file)
@@ -31,11 +31,19 @@ import javax.swing.JLabel;
 import javax.swing.JPanel;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ProgressBarTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private JPanel statusPanel;
 
   private JLabel statusBar;
index aa3b756..81289b0 100644 (file)
@@ -30,11 +30,19 @@ import jalview.schemes.ZappoColourScheme;
 
 import java.awt.Color;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class SequenceRendererTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testGetResidueBoxColour_zappo()
   {
index 446d32d..b7eef0f 100644 (file)
@@ -33,11 +33,20 @@ import jalview.jbgui.GStructureChooser.FilterOption;
 import java.util.Vector;
 
 import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class StructureChooserTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   Sequence seq;
 
   @BeforeMethod(alwaysRun = true)
index f8e9133..c1c1d5c 100644 (file)
@@ -6,10 +6,19 @@ import static org.testng.Assert.assertNull;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class StructureViewerTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testGetUniquePdbFiles()
   {
diff --git a/test/jalview/io/3ucu.cif b/test/jalview/io/3ucu.cif
new file mode 100644 (file)
index 0000000..5255f53
--- /dev/null
@@ -0,0 +1,4828 @@
+data_3UCU
+#
+_entry.id       3UCU
+#
+_citation.id                            primary
+_citation.title                         "Structural and biochemical characterization of linear dinucleotide analogues bound to the c-di-GMP-I aptamer."
+_citation.journal_abbrev                Biochemistry
+_citation.journal_volume                51
+_citation.page_first                    425
+_citation.page_last                     432
+_citation.year                          2012
+_citation.journal_id_ASTM               BICHAW
+_citation.country                       US
+_citation.journal_id_ISSN               0006-2960
+_citation.journal_id_CSD                0033
+_citation.book_publisher                ?
+_citation.pdbx_database_id_PubMed       22148472
+_citation.pdbx_database_id_DOI          10.1021/bi2016662
+#
+loop_
+_citation_author.citation_id       
+_citation_author.name              
+_citation_author.ordinal           
+primary "Smith, K.D." 1
+primary "Lipchock, S.V." 2
+primary "Strobel, S.A." 3
+#
+_cell.entry_id               3UCU
+_cell.length_a               49.088
+_cell.length_b               45.350
+_cell.length_c               77.243
+_cell.angle_alpha            90.00
+_cell.angle_beta             96.24
+_cell.angle_gamma            90.00
+_cell.Z_PDB                  2
+_cell.pdbx_unique_axis       ?
+_cell.length_a_esd           ?
+_cell.length_b_esd           ?
+_cell.length_c_esd           ?
+_cell.angle_alpha_esd        ?
+_cell.angle_beta_esd         ?
+_cell.angle_gamma_esd        ?
+#
+_symmetry.entry_id                             3UCU
+_symmetry.space_group_name_H-M                 "P 1 21 1"
+_symmetry.pdbx_full_space_group_name_H-M       ?
+_symmetry.cell_setting                         ?
+_symmetry.Int_Tables_number                    ?
+_symmetry.space_group_name_Hall                ?
+#
+loop_
+_entity.id                             
+_entity.type                           
+_entity.src_method                     
+_entity.pdbx_description               
+_entity.formula_weight                 
+_entity.pdbx_number_of_molecules       
+_entity.details                        
+_entity.pdbx_mutation                  
+_entity.pdbx_fragment                  
+_entity.pdbx_ec                        
+1 polymer man "U1 small nuclear ribonucleoprotein A" 11340.407 1 ? "Y31H, Q36R" "RNA binding domain, UNP residues 1-98" ?
+2 polymer syn "RNA (92-MER)" 29942.965 1 "c-di-GMP-I riboswitch" ? ? ?
+3 polymer syn "diguanosine monophosphate" 645.458 1 ? ? ? ?
+4 non-polymer syn "MAGNESIUM ION" 24.305 1 ? ? ? ?
+5 water nat water 18.015 14 ? ? ? ?
+#
+loop_
+_entity_keywords.entity_id       
+_entity_keywords.text            
+1 ?
+2 ?
+3 ?
+4 ?
+5 ?
+#
+loop_
+_entity_name_com.entity_id       
+_entity_name_com.name            
+1 "U1 snRNP A, U1-A, U1A"
+2 ?
+3 ?
+4 ?
+5 ?
+#
+loop_
+_entity_poly.entity_id                          
+_entity_poly.type                               
+_entity_poly.nstd_linkage                       
+_entity_poly.nstd_monomer                       
+_entity_poly.pdbx_seq_one_letter_code           
+_entity_poly.pdbx_seq_one_letter_code_can       
+_entity_poly.pdbx_strand_id                     
+1 polypeptide(L) no no 
+;MAVPETRPNHTIYINNLNEKIKKDELKKSLHAIFSRFGQILDILVSRSLKMRGQAFVIFKEVSSATNALRSMQGFPFYDK
+PMRIQYAKTDSDIIAKMK
+;
+;MAVPETRPNHTIYINNLNEKIKKDELKKSLHAIFSRFGQILDILVSRSLKMRGQAFVIFKEVSSATNALRSMQGFPFYDK
+PMRIQYAKTDSDIIAKMK
+;
+ P
+2 polyribonucleotide no yes 
+;(GTP)GUCACGCACAGGGCAAACCAUUCGAAAGAGUGGGACGCAAAGCCUCCGGCCUAAACCAUUGCACUCCGGUAGGUA
+GCGGGGUUACCGAUGG
+;
+;GGUCACGCACAGGGCAAACCAUUCGAAAGAGUGGGACGCAAAGCCUCCGGCCUAAACCAUUGCACUCCGGUAGGUAGCGG
+GGUUACCGAUGG
+;
+ R
+3 polyribonucleotide no no GG GG A
+#
+loop_
+_entity_poly_seq.entity_id       
+_entity_poly_seq.num             
+_entity_poly_seq.mon_id          
+_entity_poly_seq.hetero          
+1 1 MET n
+1 2 ALA n
+1 3 VAL n
+1 4 PRO n
+1 5 GLU n
+1 6 THR n
+1 7 ARG n
+1 8 PRO n
+1 9 ASN n
+1 10 HIS n
+1 11 THR n
+1 12 ILE n
+1 13 TYR n
+1 14 ILE n
+1 15 ASN n
+1 16 ASN n
+1 17 LEU n
+1 18 ASN n
+1 19 GLU n
+1 20 LYS n
+1 21 ILE n
+1 22 LYS n
+1 23 LYS n
+1 24 ASP n
+1 25 GLU n
+1 26 LEU n
+1 27 LYS n
+1 28 LYS n
+1 29 SER n
+1 30 LEU n
+1 31 HIS n
+1 32 ALA n
+1 33 ILE n
+1 34 PHE n
+1 35 SER n
+1 36 ARG n
+1 37 PHE n
+1 38 GLY n
+1 39 GLN n
+1 40 ILE n
+1 41 LEU n
+1 42 ASP n
+1 43 ILE n
+1 44 LEU n
+1 45 VAL n
+1 46 SER n
+1 47 ARG n
+1 48 SER n
+1 49 LEU n
+1 50 LYS n
+1 51 MET n
+1 52 ARG n
+1 53 GLY n
+1 54 GLN n
+1 55 ALA n
+1 56 PHE n
+1 57 VAL n
+1 58 ILE n
+1 59 PHE n
+1 60 LYS n
+1 61 GLU n
+1 62 VAL n
+1 63 SER n
+1 64 SER n
+1 65 ALA n
+1 66 THR n
+1 67 ASN n
+1 68 ALA n
+1 69 LEU n
+1 70 ARG n
+1 71 SER n
+1 72 MET n
+1 73 GLN n
+1 74 GLY n
+1 75 PHE n
+1 76 PRO n
+1 77 PHE n
+1 78 TYR n
+1 79 ASP n
+1 80 LYS n
+1 81 PRO n
+1 82 MET n
+1 83 ARG n
+1 84 ILE n
+1 85 GLN n
+1 86 TYR n
+1 87 ALA n
+1 88 LYS n
+1 89 THR n
+1 90 ASP n
+1 91 SER n
+1 92 ASP n
+1 93 ILE n
+1 94 ILE n
+1 95 ALA n
+1 96 LYS n
+1 97 MET n
+1 98 LYS n
+2 1 GTP n
+2 2 G n
+2 3 U n
+2 4 C n
+2 5 A n
+2 6 C n
+2 7 G n
+2 8 C n
+2 9 A n
+2 10 C n
+2 11 A n
+2 12 G n
+2 13 G n
+2 14 G n
+2 15 C n
+2 16 A n
+2 17 A n
+2 18 A n
+2 19 C n
+2 20 C n
+2 21 A n
+2 22 U n
+2 23 U n
+2 24 C n
+2 25 G n
+2 26 A n
+2 27 A n
+2 28 A n
+2 29 G n
+2 30 A n
+2 31 G n
+2 32 U n
+2 33 G n
+2 34 G n
+2 35 G n
+2 36 A n
+2 37 C n
+2 38 G n
+2 39 C n
+2 40 A n
+2 41 A n
+2 42 A n
+2 43 G n
+2 44 C n
+2 45 C n
+2 46 U n
+2 47 C n
+2 48 C n
+2 49 G n
+2 50 G n
+2 51 C n
+2 52 C n
+2 53 U n
+2 54 A n
+2 55 A n
+2 56 A n
+2 57 C n
+2 58 C n
+2 59 A n
+2 60 U n
+2 61 U n
+2 62 G n
+2 63 C n
+2 64 A n
+2 65 C n
+2 66 U n
+2 67 C n
+2 68 C n
+2 69 G n
+2 70 G n
+2 71 U n
+2 72 A n
+2 73 G n
+2 74 G n
+2 75 U n
+2 76 A n
+2 77 G n
+2 78 C n
+2 79 G n
+2 80 G n
+2 81 G n
+2 82 G n
+2 83 U n
+2 84 U n
+2 85 A n
+2 86 C n
+2 87 C n
+2 88 G n
+2 89 A n
+2 90 U n
+2 91 G n
+2 92 G n
+3 1 G n
+3 2 G n
+#
+_entity_src_gen.entity_id                              1
+_entity_src_gen.gene_src_common_name                   human
+_entity_src_gen.gene_src_genus                         ?
+_entity_src_gen.pdbx_gene_src_gene                     SNRPA
+_entity_src_gen.gene_src_species                       ?
+_entity_src_gen.gene_src_strain                        ?
+_entity_src_gen.gene_src_tissue                        ?
+_entity_src_gen.gene_src_tissue_fraction               ?
+_entity_src_gen.gene_src_details                       ?
+_entity_src_gen.pdbx_gene_src_fragment                 ?
+_entity_src_gen.pdbx_gene_src_scientific_name          "Homo sapiens"
+_entity_src_gen.pdbx_gene_src_ncbi_taxonomy_id         9606
+_entity_src_gen.pdbx_gene_src_variant                  ?
+_entity_src_gen.pdbx_gene_src_cell_line                ?
+_entity_src_gen.pdbx_gene_src_atcc                     ?
+_entity_src_gen.pdbx_gene_src_organ                    ?
+_entity_src_gen.pdbx_gene_src_organelle                ?
+_entity_src_gen.pdbx_gene_src_cell                     ?
+_entity_src_gen.pdbx_gene_src_cellular_location        ?
+_entity_src_gen.host_org_common_name                   ?
+_entity_src_gen.pdbx_host_org_scientific_name          "Escherichia coli"
+_entity_src_gen.pdbx_host_org_ncbi_taxonomy_id         511693
+_entity_src_gen.host_org_genus                         ?
+_entity_src_gen.pdbx_host_org_gene                     ?
+_entity_src_gen.pdbx_host_org_organ                    ?
+_entity_src_gen.host_org_species                       ?
+_entity_src_gen.pdbx_host_org_tissue                   ?
+_entity_src_gen.pdbx_host_org_tissue_fraction          ?
+_entity_src_gen.pdbx_host_org_strain                   BL21
+_entity_src_gen.pdbx_host_org_variant                  ?
+_entity_src_gen.pdbx_host_org_cell_line                ?
+_entity_src_gen.pdbx_host_org_atcc                     ?
+_entity_src_gen.pdbx_host_org_culture_collection       ?
+_entity_src_gen.pdbx_host_org_cell                     ?
+_entity_src_gen.pdbx_host_org_organelle                ?
+_entity_src_gen.pdbx_host_org_cellular_location        ?
+_entity_src_gen.pdbx_host_org_vector_type              plasmid
+_entity_src_gen.pdbx_host_org_vector                   ?
+_entity_src_gen.plasmid_name                           pET11
+_entity_src_gen.plasmid_details                        ?
+_entity_src_gen.pdbx_description                       ?
+#
+_pdbx_entity_src_syn.entity_id                  2
+_pdbx_entity_src_syn.organism_scientific        ?
+_pdbx_entity_src_syn.organism_common_name       ?
+_pdbx_entity_src_syn.ncbi_taxonomy_id           ?
+_pdbx_entity_src_syn.details                    "in vitro transcribed RNA transcript"
+#
+loop_
+_struct_ref.id                             
+_struct_ref.db_name                        
+_struct_ref.db_code                        
+_struct_ref.pdbx_db_accession              
+_struct_ref.entity_id                      
+_struct_ref.pdbx_seq_one_letter_code       
+_struct_ref.pdbx_align_begin               
+_struct_ref.biol_id                        
+1 UNP SNRPA_HUMAN P09012 1 
+;MAVPETRPNHTIYINNLNEKIKKDELKKSLYAIFSQFGQILDILVSRSLKMRGQAFVIFK 
+EVSSATNALRSMQGFPFYDKPMRIQYAKTDSDIIAKMK
+;
+ 1 .
+2 PDB 3UCU 3UCU 2 ? ? .
+3 PDB 3UCU 3UCU 3 ? ? .
+#
+loop_
+_struct_ref_seq.align_id                          
+_struct_ref_seq.ref_id                            
+_struct_ref_seq.pdbx_PDB_id_code                  
+_struct_ref_seq.pdbx_strand_id                    
+_struct_ref_seq.seq_align_beg                     
+_struct_ref_seq.pdbx_seq_align_beg_ins_code       
+_struct_ref_seq.seq_align_end                     
+_struct_ref_seq.pdbx_seq_align_end_ins_code       
+_struct_ref_seq.pdbx_db_accession                 
+_struct_ref_seq.db_align_beg                      
+_struct_ref_seq.db_align_end                      
+_struct_ref_seq.pdbx_auth_seq_align_beg           
+_struct_ref_seq.pdbx_auth_seq_align_end           
+1 1 3UCU P 1 ? 98 ? P09012 1 98 1 98
+2 2 3UCU R 1 ? 92 ? 3UCU 8 98 8 98
+3 3 3UCU A 1 ? 2 ? 3UCU 1 2 1 2
+#
+loop_
+_struct_ref_seq_dif.align_id                         
+_struct_ref_seq_dif.pdbx_pdb_id_code                 
+_struct_ref_seq_dif.mon_id                           
+_struct_ref_seq_dif.pdbx_pdb_strand_id               
+_struct_ref_seq_dif.seq_num                          
+_struct_ref_seq_dif.pdbx_pdb_ins_code                
+_struct_ref_seq_dif.pdbx_seq_db_name                 
+_struct_ref_seq_dif.pdbx_seq_db_accession_code       
+_struct_ref_seq_dif.db_mon_id                        
+_struct_ref_seq_dif.pdbx_seq_db_seq_num              
+_struct_ref_seq_dif.details                          
+_struct_ref_seq_dif.pdbx_auth_seq_num                
+_struct_ref_seq_dif.pdbx_ordinal                     
+1 3UCU HIS P 31 ? UNP P09012 TYR 31 "Engineered mutation" 31 1
+1 3UCU ARG P 36 ? UNP P09012 GLN 36 "Engineered mutation" 36 2
+#
+loop_
+_chem_comp.id                   
+_chem_comp.type                 
+_chem_comp.mon_nstd_flag        
+_chem_comp.name                 
+_chem_comp.pdbx_synonyms        
+_chem_comp.formula              
+_chem_comp.formula_weight       
+ARG "L-peptide linking" y ARGININE ? "C6 H15 N4 O2 1" 175.210
+PRO "L-peptide linking" y PROLINE ? "C5 H9 N O2" 115.132
+ASN "L-peptide linking" y ASPARAGINE ? "C4 H8 N2 O3" 132.119
+HIS "L-peptide linking" y HISTIDINE ? "C6 H10 N3 O2 1" 156.164
+THR "L-peptide linking" y THREONINE ? "C4 H9 N O3" 119.120
+ILE "L-peptide linking" y ISOLEUCINE ? "C6 H13 N O2" 131.174
+TYR "L-peptide linking" y TYROSINE ? "C9 H11 N O3" 181.191
+LEU "L-peptide linking" y LEUCINE ? "C6 H13 N O2" 131.174
+GLU "L-peptide linking" y "GLUTAMIC ACID" ? "C5 H9 N O4" 147.130
+LYS "L-peptide linking" y LYSINE ? "C6 H15 N2 O2 1" 147.197
+ASP "L-peptide linking" y "ASPARTIC ACID" ? "C4 H7 N O4" 133.104
+SER "L-peptide linking" y SERINE ? "C3 H7 N O3" 105.093
+ALA "L-peptide linking" y ALANINE ? "C3 H7 N O2" 89.094
+PHE "L-peptide linking" y PHENYLALANINE ? "C9 H11 N O2" 165.191
+GLY "PEPTIDE LINKING" y GLYCINE ? "C2 H5 N O2" 75.067
+GLN "L-peptide linking" y GLUTAMINE ? "C5 H10 N2 O3" 146.146
+VAL "L-peptide linking" y VALINE ? "C5 H11 N O2" 117.147
+MET "L-peptide linking" y METHIONINE ? "C5 H11 N O2 S" 149.207
+GTP "RNA linking" n "GUANOSINE-5'-TRIPHOSPHATE" ? "C10 H16 N5 O14 P3" 523.183
+G "RNA linking" y "GUANOSINE-5'-MONOPHOSPHATE" ? "C10 H14 N5 O8 P" 363.223
+U "RNA linking" y "URIDINE-5'-MONOPHOSPHATE" ? "C9 H13 N2 O9 P" 324.183
+C "RNA linking" y "CYTIDINE-5'-MONOPHOSPHATE" ? "C9 H14 N3 O8 P" 323.199
+A "RNA linking" y "ADENOSINE-5'-MONOPHOSPHATE" ? "C10 H14 N5 O7 P" 347.224
+MG NON-POLYMER . "MAGNESIUM ION" ? "MG 2" 24.305
+HOH NON-POLYMER . WATER ? "H2 O" 18.015
+#
+_exptl.entry_id              3UCU
+_exptl.method                "X-ray diffraction"
+_exptl.crystals_number       1
+#
+_exptl_crystal.id                        1
+_exptl_crystal.density_meas              ?
+_exptl_crystal.density_Matthews          2.04
+_exptl_crystal.density_percent_sol       39.66
+_exptl_crystal.description               ?
+_exptl_crystal.F_000                     ?
+_exptl_crystal.preparation               ?
+#
+_exptl_crystal_grow.crystal_id          1
+_exptl_crystal_grow.method              "VAPOR DIFFUSION, HANGING DROP"
+_exptl_crystal_grow.temp                298
+_exptl_crystal_grow.temp_details        ?
+_exptl_crystal_grow.pH                  6
+_exptl_crystal_grow.pdbx_details        "24% PEG550mme, 50 mM MES, pH 6.0, 5 mM MgSO4, 300 mM NaCl, VAPOR DIFFUSION, HANGING DROP, temperature 298K"
+_exptl_crystal_grow.pdbx_pH_range       ?
+#
+_diffrn.id                         1
+_diffrn.ambient_temp               100
+_diffrn.ambient_temp_details       ?
+_diffrn.crystal_id                 1
+#
+_diffrn_detector.diffrn_id                  1
+_diffrn_detector.detector                   CCD
+_diffrn_detector.type                       "ADSC QUANTUM 315"
+_diffrn_detector.pdbx_collection_date       2009-10-01
+_diffrn_detector.details                    ?
+#
+_diffrn_radiation.diffrn_id                            1
+_diffrn_radiation.wavelength_id                        1
+_diffrn_radiation.pdbx_monochromatic_or_laue_m_l       M
+_diffrn_radiation.monochromator                        Si(111)
+_diffrn_radiation.pdbx_diffrn_protocol                 "Single wavelength"
+_diffrn_radiation.pdbx_scattering_type                 x-ray
+#
+_diffrn_radiation_wavelength.id               1
+_diffrn_radiation_wavelength.wavelength       1.1
+_diffrn_radiation_wavelength.wt               1.0
+#
+_diffrn_source.diffrn_id                       1
+_diffrn_source.source                          Synchrotron
+_diffrn_source.type                            "NSLS BEAMLINE X25"
+_diffrn_source.pdbx_synchrotron_site           NSLS
+_diffrn_source.pdbx_synchrotron_beamline       X25
+_diffrn_source.pdbx_wavelength                 ?
+_diffrn_source.pdbx_wavelength_list            1.1
+#
+_reflns.entry_id                         3UCU
+_reflns.observed_criterion_sigma_I       2.0
+_reflns.observed_criterion_sigma_F       2.0
+_reflns.d_resolution_low                 50
+_reflns.d_resolution_high                2.8
+_reflns.number_obs                       8584
+_reflns.number_all                       8612
+_reflns.percent_possible_obs             99.7
+_reflns.pdbx_Rmerge_I_obs                0.086
+_reflns.pdbx_Rsym_value                  ?
+_reflns.pdbx_netI_over_sigmaI            21.8
+_reflns.B_iso_Wilson_estimate            ?
+_reflns.pdbx_redundancy                  7.0
+_reflns.R_free_details                   ?
+_reflns.limit_h_max                      ?
+_reflns.limit_h_min                      ?
+_reflns.limit_k_max                      ?
+_reflns.limit_k_min                      ?
+_reflns.limit_l_max                      ?
+_reflns.limit_l_min                      ?
+_reflns.observed_criterion_F_max         ?
+_reflns.observed_criterion_F_min         ?
+_reflns.pdbx_chi_squared                 ?
+_reflns.pdbx_scaling_rejects             ?
+_reflns.pdbx_ordinal                     1
+_reflns.pdbx_diffrn_id                   1
+#
+_reflns_shell.d_res_high                 2.80
+_reflns_shell.d_res_low                  2.85
+_reflns_shell.percent_possible_all       99.8
+_reflns_shell.Rmerge_I_obs               0.85
+_reflns_shell.pdbx_Rsym_value            ?
+_reflns_shell.meanI_over_sigI_obs        2.3
+_reflns_shell.pdbx_redundancy            6.6
+_reflns_shell.percent_possible_obs       ?
+_reflns_shell.number_unique_all          ?
+_reflns_shell.number_measured_all        ?
+_reflns_shell.number_measured_obs        ?
+_reflns_shell.number_unique_obs          ?
+_reflns_shell.pdbx_chi_squared           ?
+_reflns_shell.pdbx_ordinal               1
+_reflns_shell.pdbx_diffrn_id             1
+#
+_computing.entry_id                               3UCU
+_computing.pdbx_data_reduction_ii                 HKL-2000
+_computing.pdbx_data_reduction_ds                 HKL-2000
+_computing.data_collection                        CBASS
+_computing.structure_solution                     Phaser
+_computing.structure_refinement                   REFMAC5
+_computing.pdbx_structure_refinement_method       ?
+#
+_refine.entry_id                                   3UCU
+_refine.ls_number_reflns_obs                       8150
+_refine.ls_number_reflns_all                       8150
+_refine.pdbx_ls_sigma_I                            ?
+_refine.pdbx_ls_sigma_F                            ?
+_refine.pdbx_data_cutoff_high_absF                 ?
+_refine.pdbx_data_cutoff_low_absF                  ?
+_refine.pdbx_data_cutoff_high_rms_absF             ?
+_refine.ls_d_res_low                               ?
+_refine.ls_d_res_high                              2.8
+_refine.ls_percent_reflns_obs                      98.73
+_refine.ls_R_factor_obs                            0.21709
+_refine.ls_R_factor_all                            0.21709
+_refine.ls_R_factor_R_work                         0.21486
+_refine.ls_R_factor_R_free                         0.26208
+_refine.ls_R_factor_R_free_error                   ?
+_refine.ls_R_factor_R_free_error_details           ?
+_refine.ls_percent_reflns_R_free                   4.7
+_refine.ls_number_reflns_R_free                    406
+_refine.ls_number_parameters                       ?
+_refine.ls_number_restraints                       ?
+_refine.occupancy_min                              ?
+_refine.occupancy_max                              ?
+_refine.correlation_coeff_Fo_to_Fc                 0.942
+_refine.correlation_coeff_Fo_to_Fc_free            0.911
+_refine.B_iso_mean                                 62.151
+_refine.aniso_B[1][1]                              2.72
+_refine.aniso_B[2][2]                              -5.60
+_refine.aniso_B[3][3]                              3.88
+_refine.aniso_B[1][2]                              0.00
+_refine.aniso_B[1][3]                              4.57
+_refine.aniso_B[2][3]                              -0.00
+_refine.solvent_model_details                      MASK
+_refine.solvent_model_param_ksol                   ?
+_refine.solvent_model_param_bsol                   ?
+_refine.pdbx_solvent_vdw_probe_radii               1.40
+_refine.pdbx_solvent_ion_probe_radii               0.80
+_refine.pdbx_solvent_shrinkage_radii               0.80
+_refine.pdbx_ls_cross_valid_method                 THROUGHOUT
+_refine.details                                    "HYDROGENS HAVE BEEN ADDED IN THE RIDING POSITIONS"
+_refine.pdbx_starting_model                        ?
+_refine.pdbx_method_to_determine_struct            "MOLECULAR REPLACEMENT"
+_refine.pdbx_isotropic_thermal_model               ?
+_refine.pdbx_stereochemistry_target_values         "MAXIMUM LIKELIHOOD"
+_refine.pdbx_stereochem_target_val_spec_case       ?
+_refine.pdbx_R_Free_selection_details              RANDOM
+_refine.pdbx_overall_ESU_R_Free                    0.433
+_refine.overall_SU_ML                              0.380
+_refine.pdbx_overall_phase_error                   ?
+_refine.overall_SU_B                               19.510
+_refine.overall_SU_R_Cruickshank_DPI               ?
+_refine.ls_redundancy_reflns_obs                   ?
+_refine.B_iso_min                                  ?
+_refine.B_iso_max                                  ?
+_refine.overall_SU_R_free                          ?
+_refine.ls_wR_factor_R_free                        ?
+_refine.ls_wR_factor_R_work                        ?
+_refine.overall_FOM_free_R_set                     ?
+_refine.overall_FOM_work_R_set                     ?
+_refine.pdbx_diffrn_id                             1
+_refine.pdbx_refine_id                             "X-ray diffraction"
+_refine.pdbx_overall_ESU_R                         ?
+#
+_refine_hist.pdbx_refine_id                       "X-ray diffraction"
+_refine_hist.cycle_id                             LAST
+_refine_hist.pdbx_number_atoms_protein            712
+_refine_hist.pdbx_number_atoms_nucleic_acid       2031
+_refine_hist.pdbx_number_atoms_ligand             1
+_refine_hist.number_atoms_solvent                 14
+_refine_hist.number_atoms_total                   2758
+_refine_hist.d_res_high                           2.8
+_refine_hist.d_res_low                            .
+#
+loop_
+_refine_ls_restr.type                          
+_refine_ls_restr.dev_ideal                     
+_refine_ls_restr.dev_ideal_target              
+_refine_ls_restr.weight                        
+_refine_ls_restr.number                        
+_refine_ls_restr.pdbx_restraint_function       
+_refine_ls_restr.pdbx_refine_id                
+r_bond_refined_d 0.006 0.021 ? 3002 ? "X-ray diffraction"
+r_angle_refined_deg 1.038 2.775 ? 4526 ? "X-ray diffraction"
+r_dihedral_angle_1_deg 4.492 5.000 ? 86 ? "X-ray diffraction"
+r_dihedral_angle_2_deg 33.872 23.235 ? 34 ? "X-ray diffraction"
+r_dihedral_angle_3_deg 15.786 15.000 ? 144 ? "X-ray diffraction"
+r_dihedral_angle_4_deg 14.062 15.000 ? 6 ? "X-ray diffraction"
+r_chiral_restr 0.055 0.200 ? 575 ? "X-ray diffraction"
+r_gen_planes_refined 0.002 0.020 ? 1519 ? "X-ray diffraction"
+r_mcbond_it 1.210 6.000 ? 434 ? "X-ray diffraction"
+r_mcangle_it 2.149 8.000 ? 703 ? "X-ray diffraction"
+r_scbond_it 1.331 6.000 ? 2568 ? "X-ray diffraction"
+r_scangle_it 2.184 8.000 ? 3822 ? "X-ray diffraction"
+#
+_refine_ls_shell.pdbx_total_number_of_bins_used       20
+_refine_ls_shell.d_res_high                           2.785
+_refine_ls_shell.d_res_low                            2.857
+_refine_ls_shell.number_reflns_R_work                 530
+_refine_ls_shell.R_factor_R_work                      0.420
+_refine_ls_shell.percent_reflns_obs                   88.80
+_refine_ls_shell.R_factor_R_free                      0.444
+_refine_ls_shell.R_factor_R_free_error                ?
+_refine_ls_shell.percent_reflns_R_free                ?
+_refine_ls_shell.number_reflns_R_free                 33
+_refine_ls_shell.number_reflns_all                    ?
+_refine_ls_shell.R_factor_all                         ?
+_refine_ls_shell.number_reflns_obs                    566
+_refine_ls_shell.redundancy_reflns_obs                ?
+_refine_ls_shell.pdbx_refine_id                       "X-ray diffraction"
+#
+_struct.entry_id                      3UCU
+_struct.title                         "The c-di-GMP-I riboswitch bound to pGpG"
+_struct.pdbx_descriptor               "U1 small nuclear ribonucleoprotein A/RNA"
+_struct.pdbx_model_details            ?
+_struct.pdbx_CASP_flag                ?
+_struct.pdbx_model_type_details       ?
+#
+_struct_keywords.entry_id            3UCU
+_struct_keywords.pdbx_keywords       "SIGNALING PROTEIN/RNA"
+_struct_keywords.text                "riboswitch, SIGNALING PROTEIN-RNA complex"
+#
+loop_
+_struct_asym.id                                
+_struct_asym.pdbx_blank_PDB_chainid_flag       
+_struct_asym.pdbx_modified                     
+_struct_asym.entity_id                         
+_struct_asym.details                           
+A N N 1 ?
+B N N 2 ?
+C N N 3 ?
+D N N 4 ?
+E N N 5 ?
+F N N 5 ?
+G N N 5 ?
+#
+_struct_biol.id            1
+_struct_biol.details       "THE PROTEIN IS NOT BIOLOGICALLY RELEVANT AND HAS BEEN USED AS A CRYSTALLIZATION CHAPERONE."
+#
+loop_
+_struct_conf.conf_type_id                
+_struct_conf.id                          
+_struct_conf.pdbx_PDB_helix_id           
+_struct_conf.beg_label_comp_id           
+_struct_conf.beg_label_asym_id           
+_struct_conf.beg_label_seq_id            
+_struct_conf.pdbx_beg_PDB_ins_code       
+_struct_conf.end_label_comp_id           
+_struct_conf.end_label_asym_id           
+_struct_conf.end_label_seq_id            
+_struct_conf.pdbx_end_PDB_ins_code       
+_struct_conf.beg_auth_comp_id            
+_struct_conf.beg_auth_asym_id            
+_struct_conf.beg_auth_seq_id             
+_struct_conf.end_auth_comp_id            
+_struct_conf.end_auth_asym_id            
+_struct_conf.end_auth_seq_id             
+_struct_conf.pdbx_PDB_helix_class        
+_struct_conf.details                     
+_struct_conf.pdbx_PDB_helix_length       
+HELX_P HELX_P1 1 LYS A 22 ? SER A 35 ? LYS P 22 SER P 35 1 ? 14
+HELX_P HELX_P2 2 GLU A 61 ? GLN A 73 ? GLU P 61 GLN P 73 1 ? 13
+#
+_struct_conf_type.id              HELX_P
+_struct_conf_type.criteria        ?
+_struct_conf_type.reference       ?
+#
+loop_
+_struct_conn.id                                
+_struct_conn.conn_type_id                      
+_struct_conn.pdbx_PDB_id                       
+_struct_conn.ptnr1_label_asym_id               
+_struct_conn.ptnr1_label_comp_id               
+_struct_conn.ptnr1_label_seq_id                
+_struct_conn.ptnr1_label_atom_id               
+_struct_conn.pdbx_ptnr1_label_alt_id           
+_struct_conn.pdbx_ptnr1_PDB_ins_code           
+_struct_conn.pdbx_ptnr1_standard_comp_id       
+_struct_conn.ptnr1_symmetry                    
+_struct_conn.ptnr2_label_asym_id               
+_struct_conn.ptnr2_label_comp_id               
+_struct_conn.ptnr2_label_seq_id                
+_struct_conn.ptnr2_label_atom_id               
+_struct_conn.pdbx_ptnr2_label_alt_id           
+_struct_conn.pdbx_ptnr2_PDB_ins_code           
+_struct_conn.ptnr1_auth_asym_id                
+_struct_conn.ptnr1_auth_comp_id                
+_struct_conn.ptnr1_auth_seq_id                 
+_struct_conn.ptnr2_auth_asym_id                
+_struct_conn.ptnr2_auth_comp_id                
+_struct_conn.ptnr2_auth_seq_id                 
+_struct_conn.ptnr2_symmetry                    
+_struct_conn.pdbx_ptnr3_label_atom_id          
+_struct_conn.pdbx_ptnr3_label_seq_id           
+_struct_conn.pdbx_ptnr3_label_comp_id          
+_struct_conn.pdbx_ptnr3_label_asym_id          
+_struct_conn.pdbx_ptnr3_label_alt_id           
+_struct_conn.pdbx_ptnr3_PDB_ins_code           
+_struct_conn.details                           
+_struct_conn.pdbx_dist_value                   
+_struct_conn.pdbx_value_order                  
+covale1 covale ? B GTP 1 "O3'" ? ? ? 1_555 B G 2 P ? ? R GTP 8 R G 9 1_555 ? ? ? ? ? ? ? 1.600 ?
+covale2 covale ? B C 58 "O3'" ? ? ? 1_555 B A 59 P ? ? R C 65 R A 660 1_555 ? ? ? ? ? ? ? 1.605 ?
+metalc1 metalc ? D MG . MG ? ? ? 1_555 G HOH . O ? ? R MG 1 A HOH 3 1_555 ? ? ? ? ? ? ? 2.176 ?
+metalc2 metalc ? D MG . MG ? ? ? 1_555 F HOH . O ? ? R MG 1 R HOH 676 1_555 ? ? ? ? ? ? ? 2.179 ?
+metalc3 metalc ? D MG . MG ? ? ? 1_555 F HOH . O ? ? R MG 1 R HOH 673 1_555 ? ? ? ? ? ? ? 2.179 ?
+metalc4 metalc ? D MG . MG ? ? ? 1_555 F HOH . O ? ? R MG 1 R HOH 674 1_555 ? ? ? ? ? ? ? 2.180 ?
+metalc5 metalc ? D MG . MG ? ? ? 1_555 F HOH . O ? ? R MG 1 R HOH 675 1_555 ? ? ? ? ? ? ? 2.182 ?
+mismat1 mismat ? B A 5 ? ? ? ? 1_555 B G 91 ? ? ? R A 12 R G 97 1_555 ? ? ? ? ? ? ? ? ?
+mismat2 mismat ? B G 7 ? ? ? ? 1_555 B A 9 ? ? ? R G 14 R A 16 1_555 ? ? ? ? ? ? ? ? ?
+mismat3 mismat ? B A 9 ? ? ? ? 1_555 B C 87 ? ? ? R A 16 R C 93 1_555 ? ? ? ? ? ? ? ? ?
+mismat4 mismat ? B C 10 ? ? ? ? 1_555 B C 87 ? ? ? R C 17 R C 93 1_555 ? ? ? ? ? ? ? ? ?
+mismat5 mismat ? B G 12 ? ? ? ? 1_555 B A 40 ? ? ? R G 19 R A 47 1_555 ? ? ? ? ? ? ? ? ?
+mismat6 mismat ? B G 13 ? ? ? ? 1_555 C G 1 ? ? ? R G 20 A G 1 1_555 ? ? ? ? ? ? ? ? ?
+mismat7 mismat ? B A 16 ? ? ? ? 1_555 B C 37 ? ? ? R A 23 R C 44 1_555 ? ? ? ? ? ? ? ? ?
+mismat8 mismat ? B A 18 ? ? ? ? 1_555 B G 35 ? ? ? R A 25 R G 42 1_555 ? ? ? ? ? ? ? ? ?
+mismat9 mismat ? B U 22 ? ? ? ? 1_555 B G 31 ? ? ? R U 29 R G 38 1_555 ? ? ? ? ? ? ? ? ?
+mismat10 mismat ? B G 25 ? ? ? ? 1_555 B A 28 ? ? ? R G 32 R A 35 1_555 ? ? ? ? ? ? ? ? ?
+mismat11 mismat ? B A 28 ? ? ? ? 1_555 B G 73 ? ? ? R A 35 R G 79 1_555 ? ? ? ? ? ? ? ? ?
+mismat12 mismat ? B G 38 ? ? ? ? 1_555 B A 42 ? ? ? R G 45 R A 49 1_555 ? ? ? ? ? ? ? ? ?
+mismat13 mismat ? B G 43 ? ? ? ? 1_555 B U 83 ? ? ? R G 50 R U 89 1_555 ? ? ? ? ? ? ? ? ?
+mismat14 mismat ? B U 46 ? ? ? ? 1_555 B C 48 ? ? ? R U 53 R C 55 1_555 ? ? ? ? ? ? ? ? ?
+mismat15 mismat ? B C 47 ? ? ? ? 1_555 B A 76 ? ? ? R C 54 R A 82 1_555 ? ? ? ? ? ? ? ? ?
+mismat16 mismat ? B G 50 ? ? ? ? 1_555 B U 75 ? ? ? R G 57 R U 81 1_555 ? ? ? ? ? ? ? ? ?
+mismat17 mismat ? B A 54 ? ? ? ? 1_555 B A 55 ? ? ? R A 61 R A 62 1_555 ? ? ? ? ? ? ? ? ?
+mismat18 mismat ? B G 88 ? ? ? ? 1_555 B A 89 ? ? ? R G 94 R A 95 1_555 ? ? ? ? ? ? ? ? ?
+hydrog1 hydrog ? B C 4 N3 ? ? ? 1_555 B G 92 N1 ? ? R C 11 R G 98 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog2 hydrog ? B C 4 N4 ? ? ? 1_555 B G 92 O6 ? ? R C 11 R G 98 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog3 hydrog ? B C 4 O2 ? ? ? 1_555 B G 92 N2 ? ? R C 11 R G 98 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog4 hydrog ? B A 5 N1 ? ? ? 1_555 B G 91 N1 ? ? R A 12 R G 97 1_555 ? ? ? ? ? ? TYPE_8_PAIR ? ?
+hydrog5 hydrog ? B A 5 N6 ? ? ? 1_555 B G 91 O6 ? ? R A 12 R G 97 1_555 ? ? ? ? ? ? TYPE_8_PAIR ? ?
+hydrog6 hydrog ? B C 6 N3 ? ? ? 1_555 B G 88 N1 ? ? R C 13 R G 94 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog7 hydrog ? B C 6 N4 ? ? ? 1_555 B G 88 O6 ? ? R C 13 R G 94 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog8 hydrog ? B C 6 O2 ? ? ? 1_555 B G 88 N2 ? ? R C 13 R G 94 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog9 hydrog ? B G 7 N2 ? ? ? 1_555 B A 9 N7 ? ? R G 14 R A 16 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+hydrog10 hydrog ? B G 7 N1 ? ? ? 1_555 B C 87 N3 ? ? R G 14 R C 93 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog11 hydrog ? B G 7 N2 ? ? ? 1_555 B C 87 O2 ? ? R G 14 R C 93 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog12 hydrog ? B G 7 O6 ? ? ? 1_555 B C 87 N4 ? ? R G 14 R C 93 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog13 hydrog ? B A 9 N6 ? ? ? 1_555 B C 87 O2 ? ? R A 16 R C 93 1_555 ? ? ? ? ? ? "A-C MISPAIR" ? ?
+hydrog14 hydrog ? B C 10 N4 ? ? ? 1_555 B C 87 O2 ? ? R C 17 R C 93 1_555 ? ? ? ? ? ? "C-C MISPAIR" ? ?
+hydrog15 hydrog ? B C 10 N4 ? ? ? 1_555 C G 2 N3 ? ? R C 17 A G 2 1_555 ? ? ? ? ? ? "C-G PAIR" ? ?
+hydrog16 hydrog ? B G 12 O6 ? ? ? 1_555 B A 40 N6 ? ? R G 19 R A 47 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+hydrog17 hydrog ? B G 13 N1 ? ? ? 1_555 C G 1 N7 ? ? R G 20 A G 1 1_555 ? ? ? ? ? ? TYPE_7_PAIR ? ?
+hydrog18 hydrog ? B G 13 N2 ? ? ? 1_555 C G 1 O6 ? ? R G 20 A G 1 1_555 ? ? ? ? ? ? TYPE_7_PAIR ? ?
+hydrog19 hydrog ? B G 14 N1 ? ? ? 1_555 B C 39 N3 ? ? R G 21 R C 46 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog20 hydrog ? B G 14 N2 ? ? ? 1_555 B C 39 O2 ? ? R G 21 R C 46 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog21 hydrog ? B G 14 O6 ? ? ? 1_555 B C 39 N4 ? ? R G 21 R C 46 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog22 hydrog ? B C 15 N3 ? ? ? 1_555 B G 38 N1 ? ? R C 22 R G 45 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog23 hydrog ? B C 15 N4 ? ? ? 1_555 B G 38 O6 ? ? R C 22 R G 45 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog24 hydrog ? B C 15 O2 ? ? ? 1_555 B G 38 N2 ? ? R C 22 R G 45 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog25 hydrog ? B A 16 N3 ? ? ? 1_555 B C 37 N4 ? ? R A 23 R C 44 1_555 ? ? ? ? ? ? "A-C MISPAIR" ? ?
+hydrog26 hydrog ? B A 18 N6 ? ? ? 1_555 B G 35 N3 ? ? R A 25 R G 42 1_555 ? ? ? ? ? ? TYPE_11_PAIR ? ?
+hydrog27 hydrog ? B A 18 N7 ? ? ? 1_555 B G 35 N2 ? ? R A 25 R G 42 1_555 ? ? ? ? ? ? TYPE_11_PAIR ? ?
+hydrog28 hydrog ? B C 19 N3 ? ? ? 1_555 B G 34 N1 ? ? R C 26 R G 41 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog29 hydrog ? B C 19 N4 ? ? ? 1_555 B G 34 O6 ? ? R C 26 R G 41 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog30 hydrog ? B C 19 O2 ? ? ? 1_555 B G 34 N2 ? ? R C 26 R G 41 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog31 hydrog ? B C 20 N3 ? ? ? 1_555 B G 33 N1 ? ? R C 27 R G 40 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog32 hydrog ? B C 20 N4 ? ? ? 1_555 B G 33 O6 ? ? R C 27 R G 40 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog33 hydrog ? B C 20 O2 ? ? ? 1_555 B G 33 N2 ? ? R C 27 R G 40 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog34 hydrog ? B A 21 N1 ? ? ? 1_555 B U 32 N3 ? ? R A 28 R U 39 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog35 hydrog ? B A 21 N6 ? ? ? 1_555 B U 32 O4 ? ? R A 28 R U 39 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog36 hydrog ? B U 22 N3 ? ? ? 1_555 B G 31 O6 ? ? R U 29 R G 38 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog37 hydrog ? B U 22 O2 ? ? ? 1_555 B G 31 N1 ? ? R U 29 R G 38 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog38 hydrog ? B U 23 N3 ? ? ? 1_555 B A 30 N1 ? ? R U 30 R A 37 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog39 hydrog ? B U 23 O4 ? ? ? 1_555 B A 30 N6 ? ? R U 30 R A 37 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog40 hydrog ? B C 24 N3 ? ? ? 1_555 B G 29 N1 ? ? R C 31 R G 36 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog41 hydrog ? B C 24 N4 ? ? ? 1_555 B G 29 O6 ? ? R C 31 R G 36 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog42 hydrog ? B C 24 O2 ? ? ? 1_555 B G 29 N2 ? ? R C 31 R G 36 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog43 hydrog ? B G 25 N2 ? ? ? 1_555 B A 28 N7 ? ? R G 32 R A 35 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+hydrog44 hydrog ? B A 28 N3 ? ? ? 1_555 B G 73 N2 ? ? R A 35 R G 79 1_555 ? ? ? ? ? ? "A-G MISPAIR" ? ?
+hydrog45 hydrog ? B C 37 N3 ? ? ? 1_555 B G 77 N1 ? ? R C 44 R G 83 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog46 hydrog ? B C 37 N4 ? ? ? 1_555 B G 77 O6 ? ? R C 44 R G 83 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog47 hydrog ? B C 37 O2 ? ? ? 1_555 B G 77 N2 ? ? R C 44 R G 83 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog48 hydrog ? B G 38 N2 ? ? ? 1_555 B A 42 N3 ? ? R G 45 R A 49 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+hydrog49 hydrog ? B A 41 N6 ? ? ? 1_555 B U 84 O2 ? ? R A 48 R U 90 1_555 ? ? ? ? ? ? "REVERSED HOOGSTEEN" ? ?
+hydrog50 hydrog ? B A 41 N7 ? ? ? 1_555 B U 84 N3 ? ? R A 48 R U 90 1_555 ? ? ? ? ? ? "REVERSED HOOGSTEEN" ? ?
+hydrog51 hydrog ? B G 43 N1 ? ? ? 1_555 B U 83 O2 ? ? R G 50 R U 89 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog52 hydrog ? B G 43 O6 ? ? ? 1_555 B U 83 N3 ? ? R G 50 R U 89 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog53 hydrog ? B C 44 N3 ? ? ? 1_555 B G 82 N1 ? ? R C 51 R G 88 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog54 hydrog ? B C 44 N4 ? ? ? 1_555 B G 82 O6 ? ? R C 51 R G 88 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog55 hydrog ? B C 44 O2 ? ? ? 1_555 B G 82 N2 ? ? R C 51 R G 88 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog56 hydrog ? B C 45 N3 ? ? ? 1_555 B G 81 N1 ? ? R C 52 R G 87 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog57 hydrog ? B C 45 N4 ? ? ? 1_555 B G 81 O6 ? ? R C 52 R G 87 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog58 hydrog ? B C 45 O2 ? ? ? 1_555 B G 81 N2 ? ? R C 52 R G 87 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog59 hydrog ? B U 46 O2 ? ? ? 1_555 B C 48 N4 ? ? R U 53 R C 55 1_555 ? ? ? ? ? ? "U-C MISPAIR" ? ?
+hydrog60 hydrog ? B C 47 N4 ? ? ? 1_555 B A 76 N1 ? ? R C 54 R A 82 1_555 ? ? ? ? ? ? "C-A MISPAIR" ? ?
+hydrog61 hydrog ? B C 47 N3 ? ? ? 1_555 B G 80 N1 ? ? R C 54 R G 86 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog62 hydrog ? B C 47 N4 ? ? ? 1_555 B G 80 O6 ? ? R C 54 R G 86 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog63 hydrog ? B C 47 O2 ? ? ? 1_555 B G 80 N2 ? ? R C 54 R G 86 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog64 hydrog ? B C 48 N3 ? ? ? 1_555 B G 79 N1 ? ? R C 55 R G 85 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog65 hydrog ? B C 48 N4 ? ? ? 1_555 B G 79 O6 ? ? R C 55 R G 85 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog66 hydrog ? B C 48 O2 ? ? ? 1_555 B G 79 N2 ? ? R C 55 R G 85 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog67 hydrog ? B G 49 N1 ? ? ? 1_555 B C 78 N3 ? ? R G 56 R C 84 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog68 hydrog ? B G 49 N2 ? ? ? 1_555 B C 78 O2 ? ? R G 56 R C 84 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog69 hydrog ? B G 49 O6 ? ? ? 1_555 B C 78 N4 ? ? R G 56 R C 84 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog70 hydrog ? B G 50 N1 ? ? ? 1_555 B U 75 O2 ? ? R G 57 R U 81 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog71 hydrog ? B G 50 O6 ? ? ? 1_555 B U 75 N3 ? ? R G 57 R U 81 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog72 hydrog ? B C 51 N3 ? ? ? 1_555 B G 74 N1 ? ? R C 58 R G 80 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog73 hydrog ? B C 51 N4 ? ? ? 1_555 B G 74 O6 ? ? R C 58 R G 80 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog74 hydrog ? B C 51 O2 ? ? ? 1_555 B G 74 N2 ? ? R C 58 R G 80 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog75 hydrog ? B C 52 N3 ? ? ? 1_555 B G 73 N1 ? ? R C 59 R G 79 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog76 hydrog ? B C 52 N4 ? ? ? 1_555 B G 73 O6 ? ? R C 59 R G 79 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog77 hydrog ? B C 52 O2 ? ? ? 1_555 B G 73 N2 ? ? R C 59 R G 79 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog78 hydrog ? B U 53 N3 ? ? ? 1_555 B A 72 N1 ? ? R U 60 R A 78 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog79 hydrog ? B U 53 O4 ? ? ? 1_555 B A 72 N6 ? ? R U 60 R A 78 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog80 hydrog ? B A 54 N3 ? ? ? 1_555 B A 55 N6 ? ? R A 61 R A 62 1_555 ? ? ? ? ? ? "A-A MISPAIR" ? ?
+hydrog81 hydrog ? B A 54 N1 ? ? ? 1_555 B U 71 N3 ? ? R A 61 R U 77 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog82 hydrog ? B A 54 N6 ? ? ? 1_555 B U 71 O4 ? ? R A 61 R U 77 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog83 hydrog ? B A 56 N6 ? ? ? 1_555 B U 71 O2 ? ? R A 63 R U 77 1_555 ? ? ? ? ? ? "A-U PAIR" ? ?
+hydrog84 hydrog ? B C 57 N3 ? ? ? 1_555 B G 70 N1 ? ? R C 64 R G 76 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog85 hydrog ? B C 57 N4 ? ? ? 1_555 B G 70 O6 ? ? R C 64 R G 76 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog86 hydrog ? B C 57 O2 ? ? ? 1_555 B G 70 N2 ? ? R C 64 R G 76 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog87 hydrog ? B C 58 N3 ? ? ? 1_555 B G 69 N1 ? ? R C 65 R G 75 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog88 hydrog ? B C 58 N4 ? ? ? 1_555 B G 69 O6 ? ? R C 65 R G 75 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog89 hydrog ? B C 58 O2 ? ? ? 1_555 B G 69 N2 ? ? R C 65 R G 75 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog90 hydrog ? B C 86 N3 ? ? ? 1_555 C G 2 N1 ? ? R C 92 A G 2 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog91 hydrog ? B C 86 N4 ? ? ? 1_555 C G 2 O6 ? ? R C 92 A G 2 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog92 hydrog ? B C 86 O2 ? ? ? 1_555 C G 2 N2 ? ? R C 92 A G 2 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog93 hydrog ? B G 88 N2 ? ? ? 1_555 B A 89 N1 ? ? R G 94 R A 95 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+#
+loop_
+_struct_conn_type.id              
+_struct_conn_type.criteria        
+_struct_conn_type.reference       
+covale ? ?
+metalc ? ?
+hydrog "For hydrogen bonding between nucleic acid bases, donor to acceptor distance of 2.2 -3.5 Angstroms was used." ?
+mismat ? ?
+#
+_struct_sheet.id                   A
+_struct_sheet.type                 ?
+_struct_sheet.number_strands       4
+_struct_sheet.details              ?
+#
+loop_
+_struct_sheet_order.sheet_id         
+_struct_sheet_order.range_id_1       
+_struct_sheet_order.range_id_2       
+_struct_sheet_order.offset           
+_struct_sheet_order.sense            
+A 1 2 ? anti-parallel
+A 2 3 ? anti-parallel
+A 3 4 ? anti-parallel
+#
+loop_
+_struct_sheet_range.sheet_id                    
+_struct_sheet_range.id                          
+_struct_sheet_range.beg_label_comp_id           
+_struct_sheet_range.beg_label_asym_id           
+_struct_sheet_range.beg_label_seq_id            
+_struct_sheet_range.pdbx_beg_PDB_ins_code       
+_struct_sheet_range.end_label_comp_id           
+_struct_sheet_range.end_label_asym_id           
+_struct_sheet_range.end_label_seq_id            
+_struct_sheet_range.pdbx_end_PDB_ins_code       
+_struct_sheet_range.symmetry                    
+_struct_sheet_range.beg_auth_comp_id            
+_struct_sheet_range.beg_auth_asym_id            
+_struct_sheet_range.beg_auth_seq_id             
+_struct_sheet_range.end_auth_comp_id            
+_struct_sheet_range.end_auth_asym_id            
+_struct_sheet_range.end_auth_seq_id             
+A 1 ILE A 40 ? LEU A 44 ? ? ILE P 40 LEU P 44
+A 2 ALA A 55 ? PHE A 59 ? ? ALA P 55 PHE P 59
+A 3 THR A 11 ? ASN A 15 ? ? THR P 11 ASN P 15
+A 4 ARG A 83 ? TYR A 86 ? ? ARG P 83 TYR P 86
+#
+loop_
+_pdbx_struct_sheet_hbond.sheet_id                    
+_pdbx_struct_sheet_hbond.range_id_1                  
+_pdbx_struct_sheet_hbond.range_id_2                  
+_pdbx_struct_sheet_hbond.range_1_label_atom_id       
+_pdbx_struct_sheet_hbond.range_1_label_comp_id       
+_pdbx_struct_sheet_hbond.range_1_label_asym_id       
+_pdbx_struct_sheet_hbond.range_1_label_seq_id        
+_pdbx_struct_sheet_hbond.range_1_PDB_ins_code        
+_pdbx_struct_sheet_hbond.range_1_auth_atom_id        
+_pdbx_struct_sheet_hbond.range_1_auth_comp_id        
+_pdbx_struct_sheet_hbond.range_1_auth_asym_id        
+_pdbx_struct_sheet_hbond.range_1_auth_seq_id         
+_pdbx_struct_sheet_hbond.range_2_label_atom_id       
+_pdbx_struct_sheet_hbond.range_2_label_comp_id       
+_pdbx_struct_sheet_hbond.range_2_label_asym_id       
+_pdbx_struct_sheet_hbond.range_2_label_seq_id        
+_pdbx_struct_sheet_hbond.range_2_PDB_ins_code        
+_pdbx_struct_sheet_hbond.range_2_auth_atom_id        
+_pdbx_struct_sheet_hbond.range_2_auth_comp_id        
+_pdbx_struct_sheet_hbond.range_2_auth_asym_id        
+_pdbx_struct_sheet_hbond.range_2_auth_seq_id         
+A 1 2 N LEU A 44 ? N LEU P 44 O PHE A 56 ? O PHE P 56
+A 2 3 O ALA A 55 ? O ALA P 55 N ILE A 14 ? N ILE P 14
+A 3 4 N TYR A 13 ? N TYR P 13 O GLN A 85 ? O GLN P 85
+#
+_struct_site.id                       AC1
+_struct_site.details                  "BINDING SITE FOR RESIDUE MG R 1"
+_struct_site.pdbx_evidence_code       SOFTWARE
+#
+loop_
+_struct_site_gen.id                       
+_struct_site_gen.site_id                  
+_struct_site_gen.pdbx_num_res             
+_struct_site_gen.label_comp_id            
+_struct_site_gen.label_asym_id            
+_struct_site_gen.label_seq_id             
+_struct_site_gen.pdbx_auth_ins_code       
+_struct_site_gen.auth_comp_id             
+_struct_site_gen.auth_asym_id             
+_struct_site_gen.auth_seq_id              
+_struct_site_gen.label_atom_id            
+_struct_site_gen.label_alt_id             
+_struct_site_gen.symmetry                 
+_struct_site_gen.details                  
+1 AC1 7 HOH G . ? HOH A 3 . . 1_555 ?
+2 AC1 7 A B 40 ? A R 47 . . 1_555 ?
+3 AC1 7 A B 41 ? A R 48 . . 1_555 ?
+4 AC1 7 HOH F . ? HOH R 673 . . 1_555 ?
+5 AC1 7 HOH F . ? HOH R 674 . . 1_555 ?
+6 AC1 7 HOH F . ? HOH R 675 . . 1_555 ?
+7 AC1 7 HOH F . ? HOH R 676 . . 1_555 ?
+#
+_atom_sites.entry_id                        3UCU
+_atom_sites.Cartn_transform_axes            ?
+_atom_sites.fract_transf_matrix[1][1]       0.020372
+_atom_sites.fract_transf_matrix[1][2]       0.000000
+_atom_sites.fract_transf_matrix[1][3]       0.002227
+_atom_sites.fract_transf_matrix[2][1]       -0.000000
+_atom_sites.fract_transf_matrix[2][2]       0.022051
+_atom_sites.fract_transf_matrix[2][3]       0.000000
+_atom_sites.fract_transf_matrix[3][1]       0.000000
+_atom_sites.fract_transf_matrix[3][2]       -0.000000
+_atom_sites.fract_transf_matrix[3][3]       0.013023
+_atom_sites.fract_transf_vector[1]          0.00000
+_atom_sites.fract_transf_vector[2]          0.00000
+_atom_sites.fract_transf_vector[3]          0.00000
+#
+loop_
+_atom_type.symbol       
+N
+C
+O
+S
+P
+MG
+#
+loop_
+_atom_site.group_PDB                
+_atom_site.id                       
+_atom_site.type_symbol              
+_atom_site.label_atom_id            
+_atom_site.label_alt_id             
+_atom_site.label_comp_id            
+_atom_site.label_asym_id            
+_atom_site.label_entity_id          
+_atom_site.label_seq_id             
+_atom_site.pdbx_PDB_ins_code        
+_atom_site.Cartn_x                  
+_atom_site.Cartn_y                  
+_atom_site.Cartn_z                  
+_atom_site.occupancy                
+_atom_site.B_iso_or_equiv           
+_atom_site.Cartn_x_esd              
+_atom_site.Cartn_y_esd              
+_atom_site.Cartn_z_esd              
+_atom_site.occupancy_esd            
+_atom_site.B_iso_or_equiv_esd       
+_atom_site.pdbx_formal_charge       
+_atom_site.auth_seq_id              
+_atom_site.auth_comp_id             
+_atom_site.auth_asym_id             
+_atom_site.auth_atom_id             
+_atom_site.pdbx_PDB_model_num       
+_atom_site.pdbe_label_seq_id        
+ATOM 1 N N . ARG A 1 7 ? 3.282 29.355 -6.805 1.00 77.39 ? ? ? ? ? ? 7 ARG P N 1 7
+ATOM 2 C CA . ARG A 1 7 ? 3.842 27.969 -6.824 1.00 76.12 ? ? ? ? ? ? 7 ARG P CA 1 7
+ATOM 3 C C . ARG A 1 7 ? 5.170 27.792 -6.062 1.00 74.61 ? ? ? ? ? ? 7 ARG P C 1 7
+ATOM 4 O O . ARG A 1 7 ? 5.300 26.839 -5.293 1.00 74.64 ? ? ? ? ? ? 7 ARG P O 1 7
+ATOM 5 C CB . ARG A 1 7 ? 3.967 27.446 -8.260 1.00 76.94 ? ? ? ? ? ? 7 ARG P CB 1 7
+ATOM 6 C CG . ARG A 1 7 ? 2.734 26.712 -8.767 1.00 77.92 ? ? ? ? ? ? 7 ARG P CG 1 7
+ATOM 7 C CD . ARG A 1 7 ? 3.102 25.692 -9.840 1.00 78.78 ? ? ? ? ? ? 7 ARG P CD 1 7
+ATOM 8 N NE . ARG A 1 7 ? 4.202 24.827 -9.411 1.00 79.23 ? ? ? ? ? ? 7 ARG P NE 1 7
+ATOM 9 C CZ . ARG A 1 7 ? 4.780 23.898 -10.169 1.00 80.34 ? ? ? ? ? ? 7 ARG P CZ 1 7
+ATOM 10 N NH1 . ARG A 1 7 ? 4.370 23.689 -11.415 1.00 80.85 ? ? ? ? ? ? 7 ARG P NH1 1 7
+ATOM 11 N NH2 . ARG A 1 7 ? 5.774 23.173 -9.676 1.00 80.08 ? ? ? ? ? ? 7 ARG P NH2 1 7
+ATOM 12 N N . PRO A 1 8 ? 6.156 28.698 -6.267 1.00 73.28 ? ? ? ? ? ? 8 PRO P N 1 8
+ATOM 13 C CA . PRO A 1 8 ? 7.454 28.531 -5.598 1.00 72.17 ? ? ? ? ? ? 8 PRO P CA 1 8
+ATOM 14 C C . PRO A 1 8 ? 7.404 28.719 -4.080 1.00 71.22 ? ? ? ? ? ? 8 PRO P C 1 8
+ATOM 15 O O . PRO A 1 8 ? 6.475 29.336 -3.559 1.00 71.67 ? ? ? ? ? ? 8 PRO P O 1 8
+ATOM 16 C CB . PRO A 1 8 ? 8.317 29.623 -6.235 1.00 72.40 ? ? ? ? ? ? 8 PRO P CB 1 8
+ATOM 17 C CG . PRO A 1 8 ? 7.351 30.654 -6.669 1.00 73.06 ? ? ? ? ? ? 8 PRO P CG 1 8
+ATOM 18 C CD . PRO A 1 8 ? 6.155 29.890 -7.137 1.00 73.11 ? ? ? ? ? ? 8 PRO P CD 1 8
+ATOM 19 N N . ASN A 1 9 ? 8.414 28.190 -3.391 1.00 70.44 ? ? ? ? ? ? 9 ASN P N 1 9
+ATOM 20 C CA . ASN A 1 9 ? 8.463 28.184 -1.929 1.00 69.18 ? ? ? ? ? ? 9 ASN P CA 1 9
+ATOM 21 C C . ASN A 1 9 ? 9.904 28.146 -1.414 1.00 68.38 ? ? ? ? ? ? 9 ASN P C 1 9
+ATOM 22 O O . ASN A 1 9 ? 10.807 27.696 -2.122 1.00 69.28 ? ? ? ? ? ? 9 ASN P O 1 9
+ATOM 23 C CB . ASN A 1 9 ? 7.688 26.974 -1.393 1.00 69.51 ? ? ? ? ? ? 9 ASN P CB 1 9
+ATOM 24 C CG . ASN A 1 9 ? 7.174 27.177 0.021 1.00 69.76 ? ? ? ? ? ? 9 ASN P CG 1 9
+ATOM 25 O OD1 . ASN A 1 9 ? 7.804 27.848 0.839 1.00 71.77 ? ? ? ? ? ? 9 ASN P OD1 1 9
+ATOM 26 N ND2 . ASN A 1 9 ? 6.020 26.590 0.315 1.00 68.93 ? ? ? ? ? ? 9 ASN P ND2 1 9
+ATOM 27 N N . HIS A 1 10 ? 10.109 28.617 -0.184 1.00 66.82 ? ? ? ? ? ? 10 HIS P N 1 10
+ATOM 28 C CA . HIS A 1 10 ? 11.412 28.538 0.486 1.00 66.08 ? ? ? ? ? ? 10 HIS P CA 1 10
+ATOM 29 C C . HIS A 1 10 ? 11.863 27.090 0.668 1.00 65.03 ? ? ? ? ? ? 10 HIS P C 1 10
+ATOM 30 O O . HIS A 1 10 ? 13.062 26.797 0.685 1.00 64.70 ? ? ? ? ? ? 10 HIS P O 1 10
+ATOM 31 C CB . HIS A 1 10 ? 11.351 29.199 1.865 1.00 67.33 ? ? ? ? ? ? 10 HIS P CB 1 10
+ATOM 32 C CG . HIS A 1 10 ? 11.091 30.670 1.825 1.00 67.56 ? ? ? ? ? ? 10 HIS P CG 1 10
+ATOM 33 N ND1 . HIS A 1 10 ? 12.103 31.603 1.849 1.00 68.36 ? ? ? ? ? ? 10 HIS P ND1 1 10
+ATOM 34 C CD2 . HIS A 1 10 ? 9.933 31.370 1.779 1.00 68.42 ? ? ? ? ? ? 10 HIS P CD2 1 10
+ATOM 35 C CE1 . HIS A 1 10 ? 11.581 32.816 1.812 1.00 68.48 ? ? ? ? ? ? 10 HIS P CE1 1 10
+ATOM 36 N NE2 . HIS A 1 10 ? 10.267 32.703 1.768 1.00 68.45 ? ? ? ? ? ? 10 HIS P NE2 1 10
+ATOM 37 N N . THR A 1 11 ? 10.887 26.198 0.814 1.00 63.00 ? ? ? ? ? ? 11 THR P N 1 11
+ATOM 38 C CA . THR A 1 11 ? 11.134 24.790 1.084 1.00 60.82 ? ? ? ? ? ? 11 THR P CA 1 11
+ATOM 39 C C . THR A 1 11 ? 10.971 23.958 -0.184 1.00 59.43 ? ? ? ? ? ? 11 THR P C 1 11
+ATOM 40 O O . THR A 1 11 ? 10.107 24.239 -1.015 1.00 60.52 ? ? ? ? ? ? 11 THR P O 1 11
+ATOM 41 C CB . THR A 1 11 ? 10.176 24.268 2.176 1.00 61.19 ? ? ? ? ? ? 11 THR P CB 1 11
+ATOM 42 O OG1 . THR A 1 11 ? 10.174 25.178 3.283 1.00 61.69 ? ? ? ? ? ? 11 THR P OG1 1 11
+ATOM 43 C CG2 . THR A 1 11 ? 10.598 22.888 2.666 1.00 61.40 ? ? ? ? ? ? 11 THR P CG2 1 11
+ATOM 44 N N . ILE A 1 12 ? 11.819 22.943 -0.327 1.00 57.83 ? ? ? ? ? ? 12 ILE P N 1 12
+ATOM 45 C CA . ILE A 1 12 ? 11.712 21.984 -1.424 1.00 55.69 ? ? ? ? ? ? 12 ILE P CA 1 12
+ATOM 46 C C . ILE A 1 12 ? 11.417 20.580 -0.902 1.00 55.32 ? ? ? ? ? ? 12 ILE P C 1 12
+ATOM 47 O O . ILE A 1 12 ? 11.992 20.134 0.097 1.00 54.83 ? ? ? ? ? ? 12 ILE P O 1 12
+ATOM 48 C CB . ILE A 1 12 ? 12.966 21.974 -2.332 1.00 55.89 ? ? ? ? ? ? 12 ILE P CB 1 12
+ATOM 49 C CG1 . ILE A 1 12 ? 14.249 21.850 -1.499 1.00 55.80 ? ? ? ? ? ? 12 ILE P CG1 1 12
+ATOM 50 C CG2 . ILE A 1 12 ? 12.995 23.227 -3.206 1.00 55.63 ? ? ? ? ? ? 12 ILE P CG2 1 12
+ATOM 51 C CD1 . ILE A 1 12 ? 15.436 21.305 -2.266 1.00 56.47 ? ? ? ? ? ? 12 ILE P CD1 1 12
+ATOM 52 N N . TYR A 1 13 ? 10.503 19.900 -1.586 1.00 53.47 ? ? ? ? ? ? 13 TYR P N 1 13
+ATOM 53 C CA . TYR A 1 13 ? 10.067 18.570 -1.201 1.00 51.15 ? ? ? ? ? ? 13 TYR P CA 1 13
+ATOM 54 C C . TYR A 1 13 ? 10.810 17.526 -2.014 1.00 51.67 ? ? ? ? ? ? 13 TYR P C 1 13
+ATOM 55 O O . TYR A 1 13 ? 10.506 17.307 -3.189 1.00 52.90 ? ? ? ? ? ? 13 TYR P O 1 13
+ATOM 56 C CB . TYR A 1 13 ? 8.559 18.430 -1.407 1.00 50.24 ? ? ? ? ? ? 13 TYR P CB 1 13
+ATOM 57 C CG . TYR A 1 13 ? 7.995 17.085 -1.013 1.00 48.48 ? ? ? ? ? ? 13 TYR P CG 1 13
+ATOM 58 C CD1 . TYR A 1 13 ? 7.675 16.810 0.310 1.00 48.54 ? ? ? ? ? ? 13 TYR P CD1 1 13
+ATOM 59 C CD2 . TYR A 1 13 ? 7.772 16.095 -1.965 1.00 49.30 ? ? ? ? ? ? 13 TYR P CD2 1 13
+ATOM 60 C CE1 . TYR A 1 13 ? 7.156 15.581 0.683 1.00 50.28 ? ? ? ? ? ? 13 TYR P CE1 1 13
+ATOM 61 C CE2 . TYR A 1 13 ? 7.251 14.859 -1.605 1.00 50.24 ? ? ? ? ? ? 13 TYR P CE2 1 13
+ATOM 62 C CZ . TYR A 1 13 ? 6.943 14.610 -0.278 1.00 50.26 ? ? ? ? ? ? 13 TYR P CZ 1 13
+ATOM 63 O OH . TYR A 1 13 ? 6.426 13.392 0.097 1.00 51.27 ? ? ? ? ? ? 13 TYR P OH 1 13
+ATOM 64 N N . ILE A 1 14 ? 11.790 16.891 -1.380 1.00 52.72 ? ? ? ? ? ? 14 ILE P N 1 14
+ATOM 65 C CA . ILE A 1 14 ? 12.554 15.824 -2.020 1.00 53.08 ? ? ? ? ? ? 14 ILE P CA 1 14
+ATOM 66 C C . ILE A 1 14 ? 11.854 14.493 -1.781 1.00 54.93 ? ? ? ? ? ? 14 ILE P C 1 14
+ATOM 67 O O . ILE A 1 14 ? 11.422 14.189 -0.665 1.00 54.75 ? ? ? ? ? ? 14 ILE P O 1 14
+ATOM 68 C CB . ILE A 1 14 ? 14.018 15.793 -1.539 1.00 50.75 ? ? ? ? ? ? 14 ILE P CB 1 14
+ATOM 69 C CG1 . ILE A 1 14 ? 14.691 17.129 -1.849 1.00 49.83 ? ? ? ? ? ? 14 ILE P CG1 1 14
+ATOM 70 C CG2 . ILE A 1 14 ? 14.786 14.670 -2.221 1.00 50.96 ? ? ? ? ? ? 14 ILE P CG2 1 14
+ATOM 71 C CD1 . ILE A 1 14 ? 15.762 17.515 -0.872 1.00 51.18 ? ? ? ? ? ? 14 ILE P CD1 1 14
+ATOM 72 N N . ASN A 1 15 ? 11.749 13.714 -2.851 1.00 56.95 ? ? ? ? ? ? 15 ASN P N 1 15
+ATOM 73 C CA . ASN A 1 15 ? 10.951 12.501 -2.872 1.00 60.17 ? ? ? ? ? ? 15 ASN P CA 1 15
+ATOM 74 C C . ASN A 1 15 ? 11.800 11.318 -3.327 1.00 60.77 ? ? ? ? ? ? 15 ASN P C 1 15
+ATOM 75 O O . ASN A 1 15 ? 12.890 11.509 -3.876 1.00 62.14 ? ? ? ? ? ? 15 ASN P O 1 15
+ATOM 76 C CB . ASN A 1 15 ? 9.773 12.710 -3.831 1.00 63.33 ? ? ? ? ? ? 15 ASN P CB 1 15
+ATOM 77 C CG . ASN A 1 15 ? 8.558 11.882 -3.469 1.00 66.30 ? ? ? ? ? ? 15 ASN P CG 1 15
+ATOM 78 O OD1 . ASN A 1 15 ? 7.895 11.324 -4.348 1.00 68.07 ? ? ? ? ? ? 15 ASN P OD1 1 15
+ATOM 79 N ND2 . ASN A 1 15 ? 8.248 11.806 -2.178 1.00 66.31 ? ? ? ? ? ? 15 ASN P ND2 1 15
+ATOM 80 N N . ASN A 1 16 ? 11.303 10.104 -3.092 1.00 59.64 ? ? ? ? ? ? 16 ASN P N 1 16
+ATOM 81 C CA . ASN A 1 16 ? 11.931 8.883 -3.602 1.00 60.22 ? ? ? ? ? ? 16 ASN P CA 1 16
+ATOM 82 C C . ASN A 1 16 ? 13.369 8.685 -3.083 1.00 60.60 ? ? ? ? ? ? 16 ASN P C 1 16
+ATOM 83 O O . ASN A 1 16 ? 14.333 8.496 -3.867 1.00 62.95 ? ? ? ? ? ? 16 ASN P O 1 16
+ATOM 84 C CB . ASN A 1 16 ? 11.875 8.863 -5.143 1.00 59.98 ? ? ? ? ? ? 16 ASN P CB 1 16
+ATOM 85 C CG . ASN A 1 16 ? 12.281 7.527 -5.734 1.00 59.13 ? ? ? ? ? ? 16 ASN P CG 1 16
+ATOM 86 O OD1 . ASN A 1 16 ? 11.670 6.497 -5.452 1.00 58.94 ? ? ? ? ? ? 16 ASN P OD1 1 16
+ATOM 87 N ND2 . ASN A 1 16 ? 13.318 7.540 -6.566 1.00 58.95 ? ? ? ? ? ? 16 ASN P ND2 1 16
+ATOM 88 N N . LEU A 1 17 ? 13.500 8.729 -1.751 1.00 59.36 ? ? ? ? ? ? 17 LEU P N 1 17
+ATOM 89 C CA . LEU A 1 17 ? 14.815 8.588 -1.120 1.00 57.68 ? ? ? ? ? ? 17 LEU P CA 1 17
+ATOM 90 C C . LEU A 1 17 ? 15.016 7.195 -0.544 1.00 58.55 ? ? ? ? ? ? 17 LEU P C 1 17
+ATOM 91 O O . LEU A 1 17 ? 14.056 6.541 -0.131 1.00 58.44 ? ? ? ? ? ? 17 LEU P O 1 17
+ATOM 92 C CB . LEU A 1 17 ? 14.993 9.624 -0.009 1.00 54.86 ? ? ? ? ? ? 17 LEU P CB 1 17
+ATOM 93 C CG . LEU A 1 17 ? 15.024 11.105 -0.383 1.00 54.27 ? ? ? ? ? ? 17 LEU P CG 1 17
+ATOM 94 C CD1 . LEU A 1 17 ? 14.809 11.960 0.857 1.00 53.68 ? ? ? ? ? ? 17 LEU P CD1 1 17
+ATOM 95 C CD2 . LEU A 1 17 ? 16.327 11.467 -1.075 1.00 53.69 ? ? ? ? ? ? 17 LEU P CD2 1 17
+ATOM 96 N N . ASN A 1 18 ? 16.272 6.752 -0.523 1.00 59.90 ? ? ? ? ? ? 18 ASN P N 1 18
+ATOM 97 C CA . ASN A 1 18 ? 16.646 5.501 0.123 1.00 60.60 ? ? ? ? ? ? 18 ASN P CA 1 18
+ATOM 98 C C . ASN A 1 18 ? 16.255 5.552 1.595 1.00 62.35 ? ? ? ? ? ? 18 ASN P C 1 18
+ATOM 99 O O . ASN A 1 18 ? 16.767 6.371 2.362 1.00 62.63 ? ? ? ? ? ? 18 ASN P O 1 18
+ATOM 100 C CB . ASN A 1 18 ? 18.149 5.251 -0.034 1.00 61.17 ? ? ? ? ? ? 18 ASN P CB 1 18
+ATOM 101 C CG . ASN A 1 18 ? 18.556 3.824 0.318 1.00 61.79 ? ? ? ? ? ? 18 ASN P CG 1 18
+ATOM 102 O OD1 . ASN A 1 18 ? 17.827 3.093 0.995 1.00 62.04 ? ? ? ? ? ? 18 ASN P OD1 1 18
+ATOM 103 N ND2 . ASN A 1 18 ? 19.738 3.425 -0.141 1.00 61.43 ? ? ? ? ? ? 18 ASN P ND2 1 18
+ATOM 104 N N . GLU A 1 19 ? 15.333 4.675 1.976 1.00 64.29 ? ? ? ? ? ? 19 GLU P N 1 19
+ATOM 105 C CA . GLU A 1 19 ? 14.754 4.686 3.317 1.00 64.71 ? ? ? ? ? ? 19 GLU P CA 1 19
+ATOM 106 C C . GLU A 1 19 ? 15.668 4.026 4.346 1.00 65.51 ? ? ? ? ? ? 19 GLU P C 1 19
+ATOM 107 O O . GLU A 1 19 ? 15.414 4.101 5.552 1.00 66.45 ? ? ? ? ? ? 19 GLU P O 1 19
+ATOM 108 C CB . GLU A 1 19 ? 13.382 4.011 3.302 1.00 64.85 ? ? ? ? ? ? 19 GLU P CB 1 19
+ATOM 109 C CG . GLU A 1 19 ? 12.405 4.625 2.305 1.00 66.67 ? ? ? ? ? ? 19 GLU P CG 1 19
+ATOM 110 C CD . GLU A 1 19 ? 11.296 3.672 1.902 1.00 68.11 ? ? ? ? ? ? 19 GLU P CD 1 19
+ATOM 111 O OE1 . GLU A 1 19 ? 10.483 3.295 2.773 1.00 68.88 ? ? ? ? ? ? 19 GLU P OE1 1 19
+ATOM 112 O OE2 . GLU A 1 19 ? 11.233 3.305 0.709 1.00 69.92 ? ? ? ? ? ? 19 GLU P OE2 1 19
+ATOM 113 N N . LYS A 1 20 ? 16.737 3.395 3.864 1.00 66.19 ? ? ? ? ? ? 20 LYS P N 1 20
+ATOM 114 C CA . LYS A 1 20 ? 17.672 2.671 4.726 1.00 66.48 ? ? ? ? ? ? 20 LYS P CA 1 20
+ATOM 115 C C . LYS A 1 20 ? 18.696 3.579 5.407 1.00 66.60 ? ? ? ? ? ? 20 LYS P C 1 20
+ATOM 116 O O . LYS A 1 20 ? 19.346 3.172 6.373 1.00 66.83 ? ? ? ? ? ? 20 LYS P O 1 20
+ATOM 117 C CB . LYS A 1 20 ? 18.375 1.557 3.945 1.00 66.85 ? ? ? ? ? ? 20 LYS P CB 1 20
+ATOM 118 C CG . LYS A 1 20 ? 17.452 0.418 3.544 1.00 69.82 ? ? ? ? ? ? 20 LYS P CG 1 20
+ATOM 119 C CD . LYS A 1 20 ? 18.193 -0.907 3.474 1.00 72.14 ? ? ? ? ? ? 20 LYS P CD 1 20
+ATOM 120 C CE . LYS A 1 20 ? 17.218 -2.078 3.535 1.00 73.89 ? ? ? ? ? ? 20 LYS P CE 1 20
+ATOM 121 N NZ . LYS A 1 20 ? 17.905 -3.370 3.828 1.00 74.59 ? ? ? ? ? ? 20 LYS P NZ 1 20
+ATOM 122 N N . ILE A 1 21 ? 18.826 4.806 4.908 1.00 66.63 ? ? ? ? ? ? 21 ILE P N 1 21
+ATOM 123 C CA . ILE A 1 21 ? 19.771 5.776 5.463 1.00 67.18 ? ? ? ? ? ? 21 ILE P CA 1 21
+ATOM 124 C C . ILE A 1 21 ? 19.315 6.224 6.848 1.00 67.73 ? ? ? ? ? ? 21 ILE P C 1 21
+ATOM 125 O O . ILE A 1 21 ? 18.141 6.538 7.050 1.00 67.09 ? ? ? ? ? ? 21 ILE P O 1 21
+ATOM 126 C CB . ILE A 1 21 ? 19.937 7.035 4.553 1.00 66.89 ? ? ? ? ? ? 21 ILE P CB 1 21
+ATOM 127 C CG1 . ILE A 1 21 ? 19.962 6.669 3.061 1.00 66.21 ? ? ? ? ? ? 21 ILE P CG1 1 21
+ATOM 128 C CG2 . ILE A 1 21 ? 21.169 7.851 4.959 1.00 67.31 ? ? ? ? ? ? 21 ILE P CG2 1 21
+ATOM 129 C CD1 . ILE A 1 21 ? 21.055 5.705 2.649 1.00 67.59 ? ? ? ? ? ? 21 ILE P CD1 1 21
+ATOM 130 N N . LYS A 1 22 ? 20.246 6.244 7.797 1.00 70.10 ? ? ? ? ? ? 22 LYS P N 1 22
+ATOM 131 C CA . LYS A 1 22 ? 19.963 6.749 9.136 1.00 72.14 ? ? ? ? ? ? 22 LYS P CA 1 22
+ATOM 132 C C . LYS A 1 22 ? 19.669 8.247 9.097 1.00 72.02 ? ? ? ? ? ? 22 LYS P C 1 22
+ATOM 133 O O . LYS A 1 22 ? 20.360 9.011 8.414 1.00 72.88 ? ? ? ? ? ? 22 LYS P O 1 22
+ATOM 134 C CB . LYS A 1 22 ? 21.121 6.452 10.095 1.00 73.72 ? ? ? ? ? ? 22 LYS P CB 1 22
+ATOM 135 C CG . LYS A 1 22 ? 21.105 5.048 10.685 1.00 75.74 ? ? ? ? ? ? 22 LYS P CG 1 22
+ATOM 136 C CD . LYS A 1 22 ? 21.957 4.974 11.948 1.00 77.58 ? ? ? ? ? ? 22 LYS P CD 1 22
+ATOM 137 C CE . LYS A 1 22 ? 21.768 3.651 12.675 1.00 78.80 ? ? ? ? ? ? 22 LYS P CE 1 22
+ATOM 138 N NZ . LYS A 1 22 ? 22.372 3.667 14.040 1.00 79.25 ? ? ? ? ? ? 22 LYS P NZ 1 22
+ATOM 139 N N . LYS A 1 23 ? 18.632 8.646 9.831 1.00 71.68 ? ? ? ? ? ? 23 LYS P N 1 23
+ATOM 140 C CA . LYS A 1 23 ? 18.194 10.041 9.936 1.00 71.22 ? ? ? ? ? ? 23 LYS P CA 1 23
+ATOM 141 C C . LYS A 1 23 ? 19.358 11.042 10.014 1.00 70.30 ? ? ? ? ? ? 23 LYS P C 1 23
+ATOM 142 O O . LYS A 1 23 ? 19.318 12.117 9.383 1.00 70.36 ? ? ? ? ? ? 23 LYS P O 1 23
+ATOM 143 C CB . LYS A 1 23 ? 17.264 10.196 11.149 1.00 72.38 ? ? ? ? ? ? 23 LYS P CB 1 23
+ATOM 144 C CG . LYS A 1 23 ? 16.655 11.578 11.342 1.00 73.48 ? ? ? ? ? ? 23 LYS P CG 1 23
+ATOM 145 C CD . LYS A 1 23 ? 15.606 11.566 12.447 1.00 74.43 ? ? ? ? ? ? 23 LYS P CD 1 23
+ATOM 146 C CE . LYS A 1 23 ? 15.165 12.983 12.792 1.00 75.99 ? ? ? ? ? ? 23 LYS P CE 1 23
+ATOM 147 N NZ . LYS A 1 23 ? 13.907 13.014 13.592 1.00 75.30 ? ? ? ? ? ? 23 LYS P NZ 1 23
+ATOM 148 N N . ASP A 1 24 ? 20.391 10.672 10.780 1.00 69.62 ? ? ? ? ? ? 24 ASP P N 1 24
+ATOM 149 C CA . ASP A 1 24 ? 21.549 11.539 11.002 1.00 68.79 ? ? ? ? ? ? 24 ASP P CA 1 24
+ATOM 150 C C . ASP A 1 24 ? 22.321 11.767 9.710 1.00 67.58 ? ? ? ? ? ? 24 ASP P C 1 24
+ATOM 151 O O . ASP A 1 24 ? 22.617 12.908 9.356 1.00 66.30 ? ? ? ? ? ? 24 ASP P O 1 24
+ATOM 152 C CB . ASP A 1 24 ? 22.481 10.937 12.062 1.00 70.00 ? ? ? ? ? ? 24 ASP P CB 1 24
+ATOM 153 C CG . ASP A 1 24 ? 21.732 10.415 13.272 1.00 70.21 ? ? ? ? ? ? 24 ASP P CG 1 24
+ATOM 154 O OD1 . ASP A 1 24 ? 21.278 11.236 14.097 1.00 69.90 ? ? ? ? ? ? 24 ASP P OD1 1 24
+ATOM 155 O OD2 . ASP A 1 24 ? 21.602 9.178 13.398 1.00 71.39 ? ? ? ? ? ? 24 ASP P OD2 1 24
+ATOM 156 N N . GLU A 1 25 ? 22.637 10.675 9.016 1.00 66.70 ? ? ? ? ? ? 25 GLU P N 1 25
+ATOM 157 C CA . GLU A 1 25 ? 23.394 10.734 7.769 1.00 67.02 ? ? ? ? ? ? 25 GLU P CA 1 25
+ATOM 158 C C . GLU A 1 25 ? 22.588 11.404 6.661 1.00 65.66 ? ? ? ? ? ? 25 GLU P C 1 25
+ATOM 159 O O . GLU A 1 25 ? 23.133 12.180 5.873 1.00 63.20 ? ? ? ? ? ? 25 GLU P O 1 25
+ATOM 160 C CB . GLU A 1 25 ? 23.836 9.334 7.330 1.00 70.58 ? ? ? ? ? ? 25 GLU P CB 1 25
+ATOM 161 C CG . GLU A 1 25 ? 24.819 8.646 8.277 1.00 75.58 ? ? ? ? ? ? 25 GLU P CG 1 25
+ATOM 162 C CD . GLU A 1 25 ? 26.128 9.411 8.450 1.00 78.43 ? ? ? ? ? ? 25 GLU P CD 1 25
+ATOM 163 O OE1 . GLU A 1 25 ? 26.717 9.841 7.433 1.00 79.52 ? ? ? ? ? ? 25 GLU P OE1 1 25
+ATOM 164 O OE2 . GLU A 1 25 ? 26.572 9.575 9.608 1.00 80.01 ? ? ? ? ? ? 25 GLU P OE2 1 25
+ATOM 165 N N . LEU A 1 26 ? 21.290 11.106 6.620 1.00 64.01 ? ? ? ? ? ? 26 LEU P N 1 26
+ATOM 166 C CA . LEU A 1 26 ? 20.392 11.665 5.615 1.00 63.38 ? ? ? ? ? ? 26 LEU P CA 1 26
+ATOM 167 C C . LEU A 1 26 ? 20.417 13.198 5.622 1.00 63.82 ? ? ? ? ? ? 26 LEU P C 1 26
+ATOM 168 O O . LEU A 1 26 ? 20.719 13.815 4.598 1.00 62.41 ? ? ? ? ? ? 26 LEU P O 1 26
+ATOM 169 C CB . LEU A 1 26 ? 18.969 11.115 5.796 1.00 62.60 ? ? ? ? ? ? 26 LEU P CB 1 26
+ATOM 170 C CG . LEU A 1 26 ? 17.858 11.397 4.770 1.00 61.96 ? ? ? ? ? ? 26 LEU P CG 1 26
+ATOM 171 C CD1 . LEU A 1 26 ? 18.338 11.310 3.321 1.00 61.38 ? ? ? ? ? ? 26 LEU P CD1 1 26
+ATOM 172 C CD2 . LEU A 1 26 ? 16.693 10.441 4.996 1.00 61.28 ? ? ? ? ? ? 26 LEU P CD2 1 26
+ATOM 173 N N . LYS A 1 27 ? 20.127 13.802 6.775 1.00 64.51 ? ? ? ? ? ? 27 LYS P N 1 27
+ATOM 174 C CA . LYS A 1 27 ? 20.209 15.258 6.925 1.00 66.21 ? ? ? ? ? ? 27 LYS P CA 1 27
+ATOM 175 C C . LYS A 1 27 ? 21.602 15.751 6.537 1.00 67.46 ? ? ? ? ? ? 27 LYS P C 1 27
+ATOM 176 O O . LYS A 1 27 ? 21.742 16.634 5.684 1.00 67.87 ? ? ? ? ? ? 27 LYS P O 1 27
+ATOM 177 C CB . LYS A 1 27 ? 19.886 15.694 8.359 1.00 66.81 ? ? ? ? ? ? 27 LYS P CB 1 27
+ATOM 178 C CG . LYS A 1 27 ? 18.460 15.421 8.808 1.00 68.72 ? ? ? ? ? ? 27 LYS P CG 1 27
+ATOM 179 C CD . LYS A 1 27 ? 18.100 16.247 10.033 1.00 69.14 ? ? ? ? ? ? 27 LYS P CD 1 27
+ATOM 180 C CE . LYS A 1 27 ? 16.707 15.901 10.539 1.00 70.46 ? ? ? ? ? ? 27 LYS P CE 1 27
+ATOM 181 N NZ . LYS A 1 27 ? 16.140 16.984 11.392 1.00 70.41 ? ? ? ? ? ? 27 LYS P NZ 1 27
+ATOM 182 N N . LYS A 1 28 ? 22.617 15.148 7.160 1.00 67.07 ? ? ? ? ? ? 28 LYS P N 1 28
+ATOM 183 C CA . LYS A 1 28 ? 24.022 15.482 6.944 1.00 65.95 ? ? ? ? ? ? 28 LYS P CA 1 28
+ATOM 184 C C . LYS A 1 28 ? 24.361 15.546 5.452 1.00 63.96 ? ? ? ? ? ? 28 LYS P C 1 28
+ATOM 185 O O . LYS A 1 28 ? 24.862 16.563 4.970 1.00 62.21 ? ? ? ? ? ? 28 LYS P O 1 28
+ATOM 186 C CB . LYS A 1 28 ? 24.910 14.456 7.657 1.00 68.03 ? ? ? ? ? ? 28 LYS P CB 1 28
+ATOM 187 C CG . LYS A 1 28 ? 26.276 14.965 8.094 1.00 69.74 ? ? ? ? ? ? 28 LYS P CG 1 28
+ATOM 188 C CD . LYS A 1 28 ? 27.231 13.799 8.328 1.00 71.03 ? ? ? ? ? ? 28 LYS P CD 1 28
+ATOM 189 C CE . LYS A 1 28 ? 28.535 14.239 8.983 1.00 71.65 ? ? ? ? ? ? 28 LYS P CE 1 28
+ATOM 190 N NZ . LYS A 1 28 ? 28.434 14.278 10.470 1.00 71.45 ? ? ? ? ? ? 28 LYS P NZ 1 28
+ATOM 191 N N . SER A 1 29 ? 24.062 14.465 4.732 1.00 62.97 ? ? ? ? ? ? 29 SER P N 1 29
+ATOM 192 C CA . SER A 1 29 ? 24.323 14.378 3.292 1.00 62.46 ? ? ? ? ? ? 29 SER P CA 1 29
+ATOM 193 C C . SER A 1 29 ? 23.541 15.422 2.495 1.00 63.18 ? ? ? ? ? ? 29 SER P C 1 29
+ATOM 194 O O . SER A 1 29 ? 24.109 16.091 1.634 1.00 65.29 ? ? ? ? ? ? 29 SER P O 1 29
+ATOM 195 C CB . SER A 1 29 ? 24.013 12.978 2.765 1.00 61.42 ? ? ? ? ? ? 29 SER P CB 1 29
+ATOM 196 O OG . SER A 1 29 ? 24.614 11.985 3.572 1.00 61.08 ? ? ? ? ? ? 29 SER P OG 1 29
+ATOM 197 N N . LEU A 1 30 ? 22.248 15.563 2.787 1.00 62.10 ? ? ? ? ? ? 30 LEU P N 1 30
+ATOM 198 C CA . LEU A 1 30 ? 21.409 16.567 2.125 1.00 60.90 ? ? ? ? ? ? 30 LEU P CA 1 30
+ATOM 199 C C . LEU A 1 30 ? 21.945 17.979 2.342 1.00 61.95 ? ? ? ? ? ? 30 LEU P C 1 30
+ATOM 200 O O . LEU A 1 30 ? 21.902 18.811 1.435 1.00 60.80 ? ? ? ? ? ? 30 LEU P O 1 30
+ATOM 201 C CB . LEU A 1 30 ? 19.957 16.473 2.603 1.00 57.93 ? ? ? ? ? ? 30 LEU P CB 1 30
+ATOM 202 C CG . LEU A 1 30 ? 19.133 15.272 2.128 1.00 55.91 ? ? ? ? ? ? 30 LEU P CG 1 30
+ATOM 203 C CD1 . LEU A 1 30 ? 17.927 15.085 3.022 1.00 56.03 ? ? ? ? ? ? 30 LEU P CD1 1 30
+ATOM 204 C CD2 . LEU A 1 30 ? 18.708 15.406 0.675 1.00 54.70 ? ? ? ? ? ? 30 LEU P CD2 1 30
+ATOM 205 N N . HIS A 1 31 ? 22.454 18.234 3.544 1.00 64.40 ? ? ? ? ? ? 31 HIS P N 1 31
+ATOM 206 C CA . HIS A 1 31 ? 23.106 19.499 3.862 1.00 66.73 ? ? ? ? ? ? 31 HIS P CA 1 31
+ATOM 207 C C . HIS A 1 31 ? 24.406 19.639 3.078 1.00 67.17 ? ? ? ? ? ? 31 HIS P C 1 31
+ATOM 208 O O . HIS A 1 31 ? 24.723 20.717 2.572 1.00 67.39 ? ? ? ? ? ? 31 HIS P O 1 31
+ATOM 209 C CB . HIS A 1 31 ? 23.382 19.600 5.364 1.00 68.23 ? ? ? ? ? ? 31 HIS P CB 1 31
+ATOM 210 C CG . HIS A 1 31 ? 23.744 20.978 5.820 1.00 70.27 ? ? ? ? ? ? 31 HIS P CG 1 31
+ATOM 211 N ND1 . HIS A 1 31 ? 22.812 21.870 6.306 1.00 71.21 ? ? ? ? ? ? 31 HIS P ND1 1 31
+ATOM 212 C CD2 . HIS A 1 31 ? 24.936 21.620 5.862 1.00 71.57 ? ? ? ? ? ? 31 HIS P CD2 1 31
+ATOM 213 C CE1 . HIS A 1 31 ? 23.413 23.002 6.626 1.00 72.11 ? ? ? ? ? ? 31 HIS P CE1 1 31
+ATOM 214 N NE2 . HIS A 1 31 ? 24.703 22.876 6.367 1.00 72.30 ? ? ? ? ? ? 31 HIS P NE2 1 31
+ATOM 215 N N . ALA A 1 32 ? 25.144 18.537 2.969 1.00 66.61 ? ? ? ? ? ? 32 ALA P N 1 32
+ATOM 216 C CA . ALA A 1 32 ? 26.419 18.518 2.258 1.00 67.14 ? ? ? ? ? ? 32 ALA P CA 1 32
+ATOM 217 C C . ALA A 1 32 ? 26.266 18.676 0.740 1.00 67.12 ? ? ? ? ? ? 32 ALA P C 1 32
+ATOM 218 O O . ALA A 1 32 ? 27.247 18.914 0.036 1.00 68.42 ? ? ? ? ? ? 32 ALA P O 1 32
+ATOM 219 C CB . ALA A 1 32 ? 27.182 17.242 2.587 1.00 67.01 ? ? ? ? ? ? 32 ALA P CB 1 32
+ATOM 220 N N . ILE A 1 33 ? 25.038 18.551 0.245 1.00 66.22 ? ? ? ? ? ? 33 ILE P N 1 33
+ATOM 221 C CA . ILE A 1 33 ? 24.779 18.577 -1.192 1.00 66.21 ? ? ? ? ? ? 33 ILE P CA 1 33
+ATOM 222 C C . ILE A 1 33 ? 24.008 19.825 -1.634 1.00 65.72 ? ? ? ? ? ? 33 ILE P C 1 33
+ATOM 223 O O . ILE A 1 33 ? 24.216 20.325 -2.741 1.00 65.62 ? ? ? ? ? ? 33 ILE P O 1 33
+ATOM 224 C CB . ILE A 1 33 ? 24.048 17.279 -1.653 1.00 67.78 ? ? ? ? ? ? 33 ILE P CB 1 33
+ATOM 225 C CG1 . ILE A 1 33 ? 24.893 16.028 -1.351 1.00 69.97 ? ? ? ? ? ? 33 ILE P CG1 1 33
+ATOM 226 C CG2 . ILE A 1 33 ? 23.676 17.329 -3.132 1.00 67.72 ? ? ? ? ? ? 33 ILE P CG2 1 33
+ATOM 227 C CD1 . ILE A 1 33 ? 26.364 16.077 -1.816 1.00 72.17 ? ? ? ? ? ? 33 ILE P CD1 1 33
+ATOM 228 N N . PHE A 1 34 ? 23.136 20.329 -0.764 1.00 65.46 ? ? ? ? ? ? 34 PHE P N 1 34
+ATOM 229 C CA . PHE A 1 34 ? 22.262 21.453 -1.108 1.00 64.57 ? ? ? ? ? ? 34 PHE P CA 1 34
+ATOM 230 C C . PHE A 1 34 ? 22.737 22.822 -0.613 1.00 65.26 ? ? ? ? ? ? 34 PHE P C 1 34
+ATOM 231 O O . PHE A 1 34 ? 22.223 23.850 -1.063 1.00 65.25 ? ? ? ? ? ? 34 PHE P O 1 34
+ATOM 232 C CB . PHE A 1 34 ? 20.830 21.192 -0.622 1.00 62.75 ? ? ? ? ? ? 34 PHE P CB 1 34
+ATOM 233 C CG . PHE A 1 34 ? 20.070 20.209 -1.468 1.00 60.53 ? ? ? ? ? ? 34 PHE P CG 1 34
+ATOM 234 C CD1 . PHE A 1 34 ? 19.527 20.596 -2.691 1.00 59.24 ? ? ? ? ? ? 34 PHE P CD1 1 34
+ATOM 235 C CD2 . PHE A 1 34 ? 19.892 18.899 -1.041 1.00 59.15 ? ? ? ? ? ? 34 PHE P CD2 1 34
+ATOM 236 C CE1 . PHE A 1 34 ? 18.825 19.691 -3.479 1.00 57.79 ? ? ? ? ? ? 34 PHE P CE1 1 34
+ATOM 237 C CE2 . PHE A 1 34 ? 19.189 17.987 -1.823 1.00 58.66 ? ? ? ? ? ? 34 PHE P CE2 1 34
+ATOM 238 C CZ . PHE A 1 34 ? 18.654 18.385 -3.044 1.00 57.78 ? ? ? ? ? ? 34 PHE P CZ 1 34
+ATOM 239 N N . SER A 1 35 ? 23.711 22.838 0.298 1.00 66.13 ? ? ? ? ? ? 35 SER P N 1 35
+ATOM 240 C CA . SER A 1 35 ? 24.194 24.093 0.898 1.00 67.08 ? ? ? ? ? ? 35 SER P CA 1 35
+ATOM 241 C C . SER A 1 35 ? 24.891 25.020 -0.097 1.00 65.70 ? ? ? ? ? ? 35 SER P C 1 35
+ATOM 242 O O . SER A 1 35 ? 25.042 26.215 0.164 1.00 66.47 ? ? ? ? ? ? 35 SER P O 1 35
+ATOM 243 C CB . SER A 1 35 ? 25.109 23.824 2.099 1.00 68.50 ? ? ? ? ? ? 35 SER P CB 1 35
+ATOM 244 O OG . SER A 1 35 ? 26.304 23.176 1.701 1.00 71.12 ? ? ? ? ? ? 35 SER P OG 1 35
+ATOM 245 N N . ARG A 1 36 ? 25.302 24.467 -1.236 1.00 64.91 ? ? ? ? ? ? 36 ARG P N 1 36
+ATOM 246 C CA . ARG A 1 36 ? 25.956 25.244 -2.286 1.00 64.08 ? ? ? ? ? ? 36 ARG P CA 1 36
+ATOM 247 C C . ARG A 1 36 ? 24.983 26.130 -3.070 1.00 63.63 ? ? ? ? ? ? 36 ARG P C 1 36
+ATOM 248 O O . ARG A 1 36 ? 25.395 26.887 -3.952 1.00 64.13 ? ? ? ? ? ? 36 ARG P O 1 36
+ATOM 249 C CB . ARG A 1 36 ? 26.751 24.332 -3.232 1.00 65.69 ? ? ? ? ? ? 36 ARG P CB 1 36
+ATOM 250 C CG . ARG A 1 36 ? 25.968 23.181 -3.854 1.00 67.06 ? ? ? ? ? ? 36 ARG P CG 1 36
+ATOM 251 C CD . ARG A 1 36 ? 26.789 22.490 -4.938 1.00 68.94 ? ? ? ? ? ? 36 ARG P CD 1 36
+ATOM 252 N NE . ARG A 1 36 ? 26.791 23.249 -6.190 1.00 70.61 ? ? ? ? ? ? 36 ARG P NE 1 36
+ATOM 253 C CZ . ARG A 1 36 ? 26.169 22.870 -7.306 1.00 71.80 ? ? ? ? ? ? 36 ARG P CZ 1 36
+ATOM 254 N NH1 . ARG A 1 36 ? 26.229 23.632 -8.390 1.00 71.50 ? ? ? ? ? ? 36 ARG P NH1 1 36
+ATOM 255 N NH2 . ARG A 1 36 ? 25.495 21.728 -7.350 1.00 72.57 ? ? ? ? ? ? 36 ARG P NH2 1 36
+ATOM 256 N N . PHE A 1 37 ? 23.697 26.033 -2.744 1.00 62.13 ? ? ? ? ? ? 37 PHE P N 1 37
+ATOM 257 C CA . PHE A 1 37 ? 22.666 26.814 -3.422 1.00 60.59 ? ? ? ? ? ? 37 PHE P CA 1 37
+ATOM 258 C C . PHE A 1 37 ? 22.213 28.016 -2.599 1.00 62.21 ? ? ? ? ? ? 37 PHE P C 1 37
+ATOM 259 O O . PHE A 1 37 ? 21.757 29.017 -3.154 1.00 62.93 ? ? ? ? ? ? 37 PHE P O 1 37
+ATOM 260 C CB . PHE A 1 37 ? 21.470 25.929 -3.775 1.00 57.92 ? ? ? ? ? ? 37 PHE P CB 1 37
+ATOM 261 C CG . PHE A 1 37 ? 21.791 24.843 -4.759 1.00 56.27 ? ? ? ? ? ? 37 PHE P CG 1 37
+ATOM 262 C CD1 . PHE A 1 37 ? 21.945 25.133 -6.110 1.00 55.82 ? ? ? ? ? ? 37 PHE P CD1 1 37
+ATOM 263 C CD2 . PHE A 1 37 ? 21.939 23.527 -4.337 1.00 55.93 ? ? ? ? ? ? 37 PHE P CD2 1 37
+ATOM 264 C CE1 . PHE A 1 37 ? 22.242 24.130 -7.023 1.00 55.73 ? ? ? ? ? ? 37 PHE P CE1 1 37
+ATOM 265 C CE2 . PHE A 1 37 ? 22.234 22.515 -5.246 1.00 55.14 ? ? ? ? ? ? 37 PHE P CE2 1 37
+ATOM 266 C CZ . PHE A 1 37 ? 22.386 22.818 -6.590 1.00 55.40 ? ? ? ? ? ? 37 PHE P CZ 1 37
+ATOM 267 N N . GLY A 1 38 ? 22.351 27.911 -1.279 1.00 63.47 ? ? ? ? ? ? 38 GLY P N 1 38
+ATOM 268 C CA . GLY A 1 38 ? 21.933 28.963 -0.356 1.00 64.83 ? ? ? ? ? ? 38 GLY P CA 1 38
+ATOM 269 C C . GLY A 1 38 ? 21.995 28.505 1.087 1.00 66.45 ? ? ? ? ? ? 38 GLY P C 1 38
+ATOM 270 O O . GLY A 1 38 ? 22.129 27.311 1.364 1.00 66.85 ? ? ? ? ? ? 38 GLY P O 1 38
+ATOM 271 N N . GLN A 1 39 ? 21.897 29.460 2.007 1.00 68.03 ? ? ? ? ? ? 39 GLN P N 1 39
+ATOM 272 C CA . GLN A 1 39 ? 21.910 29.174 3.442 1.00 69.07 ? ? ? ? ? ? 39 GLN P CA 1 39
+ATOM 273 C C . GLN A 1 39 ? 20.644 28.413 3.830 1.00 68.49 ? ? ? ? ? ? 39 GLN P C 1 39
+ATOM 274 O O . GLN A 1 39 ? 19.545 28.752 3.383 1.00 69.87 ? ? ? ? ? ? 39 GLN P O 1 39
+ATOM 275 C CB . GLN A 1 39 ? 22.028 30.471 4.252 1.00 70.75 ? ? ? ? ? ? 39 GLN P CB 1 39
+ATOM 276 C CG . GLN A 1 39 ? 23.298 31.299 3.975 1.00 74.26 ? ? ? ? ? ? 39 GLN P CG 1 39
+ATOM 277 C CD . GLN A 1 39 ? 23.243 32.107 2.670 1.00 74.93 ? ? ? ? ? ? 39 GLN P CD 1 39
+ATOM 278 O OE1 . GLN A 1 39 ? 22.190 32.250 2.044 1.00 75.34 ? ? ? ? ? ? 39 GLN P OE1 1 39
+ATOM 279 N NE2 . GLN A 1 39 ? 24.389 32.640 2.266 1.00 75.22 ? ? ? ? ? ? 39 GLN P NE2 1 39
+ATOM 280 N N . ILE A 1 40 ? 20.804 27.380 4.650 1.00 65.88 ? ? ? ? ? ? 40 ILE P N 1 40
+ATOM 281 C CA . ILE A 1 40 ? 19.679 26.533 5.034 1.00 65.76 ? ? ? ? ? ? 40 ILE P CA 1 40
+ATOM 282 C C . ILE A 1 40 ? 19.252 26.794 6.475 1.00 67.11 ? ? ? ? ? ? 40 ILE P C 1 40
+ATOM 283 O O . ILE A 1 40 ? 20.080 26.790 7.389 1.00 67.67 ? ? ? ? ? ? 40 ILE P O 1 40
+ATOM 284 C CB . ILE A 1 40 ? 19.998 25.032 4.816 1.00 64.90 ? ? ? ? ? ? 40 ILE P CB 1 40
+ATOM 285 C CG1 . ILE A 1 40 ? 20.232 24.754 3.326 1.00 64.01 ? ? ? ? ? ? 40 ILE P CG1 1 40
+ATOM 286 C CG2 . ILE A 1 40 ? 18.876 24.143 5.364 1.00 63.92 ? ? ? ? ? ? 40 ILE P CG2 1 40
+ATOM 287 C CD1 . ILE A 1 40 ? 21.022 23.496 3.039 1.00 63.60 ? ? ? ? ? ? 40 ILE P CD1 1 40
+ATOM 288 N N . LEU A 1 41 ? 17.955 27.030 6.661 1.00 68.35 ? ? ? ? ? ? 41 LEU P N 1 41
+ATOM 289 C CA . LEU A 1 41 ? 17.369 27.212 7.987 1.00 70.51 ? ? ? ? ? ? 41 LEU P CA 1 41
+ATOM 290 C C . LEU A 1 41 ? 17.447 25.908 8.782 1.00 71.19 ? ? ? ? ? ? 41 LEU P C 1 41
+ATOM 291 O O . LEU A 1 41 ? 18.153 25.826 9.789 1.00 72.12 ? ? ? ? ? ? 41 LEU P O 1 41
+ATOM 292 C CB . LEU A 1 41 ? 15.913 27.684 7.872 1.00 71.76 ? ? ? ? ? ? 41 LEU P CB 1 41
+ATOM 293 C CG . LEU A 1 41 ? 15.569 29.180 7.807 1.00 72.63 ? ? ? ? ? ? 41 LEU P CG 1 41
+ATOM 294 C CD1 . LEU A 1 41 ? 16.293 29.912 6.691 1.00 72.37 ? ? ? ? ? ? 41 LEU P CD1 1 41
+ATOM 295 C CD2 . LEU A 1 41 ? 14.063 29.363 7.656 1.00 73.26 ? ? ? ? ? ? 41 LEU P CD2 1 41
+ATOM 296 N N . ASP A 1 42 ? 16.721 24.896 8.314 1.00 70.65 ? ? ? ? ? ? 42 ASP P N 1 42
+ATOM 297 C CA . ASP A 1 42 ? 16.770 23.559 8.891 1.00 70.54 ? ? ? ? ? ? 42 ASP P CA 1 42
+ATOM 298 C C . ASP A 1 42 ? 16.354 22.551 7.830 1.00 69.26 ? ? ? ? ? ? 42 ASP P C 1 42
+ATOM 299 O O . ASP A 1 42 ? 15.696 22.907 6.852 1.00 69.42 ? ? ? ? ? ? 42 ASP P O 1 42
+ATOM 300 C CB . ASP A 1 42 ? 15.847 23.459 10.115 1.00 72.25 ? ? ? ? ? ? 42 ASP P CB 1 42
+ATOM 301 C CG . ASP A 1 42 ? 16.182 22.270 11.017 1.00 73.64 ? ? ? ? ? ? 42 ASP P CG 1 42
+ATOM 302 O OD1 . ASP A 1 42 ? 17.379 22.044 11.311 1.00 74.48 ? ? ? ? ? ? 42 ASP P OD1 1 42
+ATOM 303 O OD2 . ASP A 1 42 ? 15.240 21.566 11.443 1.00 72.67 ? ? ? ? ? ? 42 ASP P OD2 1 42
+ATOM 304 N N . ILE A 1 43 ? 16.755 21.297 8.015 1.00 67.83 ? ? ? ? ? ? 43 ILE P N 1 43
+ATOM 305 C CA . ILE A 1 43 ? 16.316 20.217 7.143 1.00 66.49 ? ? ? ? ? ? 43 ILE P CA 1 43
+ATOM 306 C C . ILE A 1 43 ? 15.410 19.268 7.923 1.00 66.22 ? ? ? ? ? ? 43 ILE P C 1 43
+ATOM 307 O O . ILE A 1 43 ? 15.827 18.669 8.916 1.00 66.44 ? ? ? ? ? ? 43 ILE P O 1 43
+ATOM 308 C CB . ILE A 1 43 ? 17.506 19.458 6.509 1.00 66.63 ? ? ? ? ? ? 43 ILE P CB 1 43
+ATOM 309 C CG1 . ILE A 1 43 ? 18.313 20.399 5.609 1.00 66.94 ? ? ? ? ? ? 43 ILE P CG1 1 43
+ATOM 310 C CG2 . ILE A 1 43 ? 17.013 18.246 5.718 1.00 66.60 ? ? ? ? ? ? 43 ILE P CG2 1 43
+ATOM 311 C CD1 . ILE A 1 43 ? 19.555 19.774 4.999 1.00 67.64 ? ? ? ? ? ? 43 ILE P CD1 1 43
+ATOM 312 N N . LEU A 1 44 ? 14.166 19.151 7.470 1.00 66.04 ? ? ? ? ? ? 44 LEU P N 1 44
+ATOM 313 C CA . LEU A 1 44 ? 13.185 18.297 8.122 1.00 66.09 ? ? ? ? ? ? 44 LEU P CA 1 44
+ATOM 314 C C . LEU A 1 44 ? 13.199 16.900 7.517 1.00 65.09 ? ? ? ? ? ? 44 LEU P C 1 44
+ATOM 315 O O . LEU A 1 44 ? 12.866 16.717 6.346 1.00 65.42 ? ? ? ? ? ? 44 LEU P O 1 44
+ATOM 316 C CB . LEU A 1 44 ? 11.781 18.910 8.023 1.00 68.08 ? ? ? ? ? ? 44 LEU P CB 1 44
+ATOM 317 C CG . LEU A 1 44 ? 11.299 19.984 9.013 1.00 69.60 ? ? ? ? ? ? 44 LEU P CG 1 44
+ATOM 318 C CD1 . LEU A 1 44 ? 11.063 19.395 10.405 1.00 71.01 ? ? ? ? ? ? 44 LEU P CD1 1 44
+ATOM 319 C CD2 . LEU A 1 44 ? 12.223 21.203 9.084 1.00 69.42 ? ? ? ? ? ? 44 LEU P CD2 1 44
+ATOM 320 N N . VAL A 1 45 ? 13.601 15.923 8.324 1.00 63.60 ? ? ? ? ? ? 45 VAL P N 1 45
+ATOM 321 C CA . VAL A 1 45 ? 13.624 14.522 7.916 1.00 62.92 ? ? ? ? ? ? 45 VAL P CA 1 45
+ATOM 322 C C . VAL A 1 45 ? 13.030 13.667 9.032 1.00 63.65 ? ? ? ? ? ? 45 VAL P C 1 45
+ATOM 323 O O . VAL A 1 45 ? 13.415 13.797 10.193 1.00 65.60 ? ? ? ? ? ? 45 VAL P O 1 45
+ATOM 324 C CB . VAL A 1 45 ? 15.067 14.041 7.588 1.00 61.93 ? ? ? ? ? ? 45 VAL P CB 1 45
+ATOM 325 C CG1 . VAL A 1 45 ? 15.094 12.549 7.326 1.00 61.28 ? ? ? ? ? ? 45 VAL P CG1 1 45
+ATOM 326 C CG2 . VAL A 1 45 ? 15.631 14.786 6.391 1.00 61.76 ? ? ? ? ? ? 45 VAL P CG2 1 45
+ATOM 327 N N . SER A 1 46 ? 12.083 12.804 8.677 1.00 64.18 ? ? ? ? ? ? 46 SER P N 1 46
+ATOM 328 C CA . SER A 1 46 ? 11.467 11.892 9.636 1.00 64.69 ? ? ? ? ? ? 46 SER P CA 1 46
+ATOM 329 C C . SER A 1 46 ? 11.265 10.524 8.994 1.00 65.06 ? ? ? ? ? ? 46 SER P C 1 46
+ATOM 330 O O . SER A 1 46 ? 11.017 10.431 7.791 1.00 65.32 ? ? ? ? ? ? 46 SER P O 1 46
+ATOM 331 C CB . SER A 1 46 ? 10.138 12.459 10.132 1.00 65.49 ? ? ? ? ? ? 46 SER P CB 1 46
+ATOM 332 O OG . SER A 1 46 ? 9.620 11.684 11.196 1.00 66.95 ? ? ? ? ? ? 46 SER P OG 1 46
+ATOM 333 N N . ARG A 1 47 ? 11.372 9.468 9.795 1.00 66.39 ? ? ? ? ? ? 47 ARG P N 1 47
+ATOM 334 C CA . ARG A 1 47 ? 11.339 8.099 9.267 1.00 67.79 ? ? ? ? ? ? 47 ARG P CA 1 47
+ATOM 335 C C . ARG A 1 47 ? 10.098 7.293 9.660 1.00 68.16 ? ? ? ? ? ? 47 ARG P C 1 47
+ATOM 336 O O . ARG A 1 47 ? 10.147 6.061 9.729 1.00 69.44 ? ? ? ? ? ? 47 ARG P O 1 47
+ATOM 337 C CB . ARG A 1 47 ? 12.621 7.346 9.641 1.00 68.54 ? ? ? ? ? ? 47 ARG P CB 1 47
+ATOM 338 C CG . ARG A 1 47 ? 13.850 7.809 8.870 1.00 70.75 ? ? ? ? ? ? 47 ARG P CG 1 47
+ATOM 339 C CD . ARG A 1 47 ? 15.100 7.063 9.303 1.00 71.97 ? ? ? ? ? ? 47 ARG P CD 1 47
+ATOM 340 N NE . ARG A 1 47 ? 15.141 5.702 8.772 1.00 73.06 ? ? ? ? ? ? 47 ARG P NE 1 47
+ATOM 341 C CZ . ARG A 1 47 ? 16.059 4.796 9.094 1.00 74.07 ? ? ? ? ? ? 47 ARG P CZ 1 47
+ATOM 342 N NH1 . ARG A 1 47 ? 17.026 5.093 9.956 1.00 74.03 ? ? ? ? ? ? 47 ARG P NH1 1 47
+ATOM 343 N NH2 . ARG A 1 47 ? 16.010 3.585 8.552 1.00 74.22 ? ? ? ? ? ? 47 ARG P NH2 1 47
+ATOM 344 N N . SER A 1 48 ? 8.990 7.987 9.905 1.00 67.76 ? ? ? ? ? ? 48 SER P N 1 48
+ATOM 345 C CA . SER A 1 48 ? 7.708 7.329 10.147 1.00 66.74 ? ? ? ? ? ? 48 SER P CA 1 48
+ATOM 346 C C . SER A 1 48 ? 7.106 6.881 8.820 1.00 67.60 ? ? ? ? ? ? 48 SER P C 1 48
+ATOM 347 O O . SER A 1 48 ? 7.478 7.395 7.766 1.00 68.37 ? ? ? ? ? ? 48 SER P O 1 48
+ATOM 348 C CB . SER A 1 48 ? 6.749 8.262 10.891 1.00 66.41 ? ? ? ? ? ? 48 SER P CB 1 48
+ATOM 349 O OG . SER A 1 48 ? 6.604 9.499 10.219 1.00 64.76 ? ? ? ? ? ? 48 SER P OG 1 48
+ATOM 350 N N . LEU A 1 49 ? 6.178 5.926 8.878 1.00 68.66 ? ? ? ? ? ? 49 LEU P N 1 49
+ATOM 351 C CA . LEU A 1 49 ? 5.533 5.365 7.682 1.00 68.33 ? ? ? ? ? ? 49 LEU P CA 1 49
+ATOM 352 C C . LEU A 1 49 ? 5.019 6.444 6.726 1.00 68.08 ? ? ? ? ? ? 49 LEU P C 1 49
+ATOM 353 O O . LEU A 1 49 ? 5.067 6.285 5.507 1.00 67.25 ? ? ? ? ? ? 49 LEU P O 1 49
+ATOM 354 C CB . LEU A 1 49 ? 4.383 4.439 8.090 1.00 68.60 ? ? ? ? ? ? 49 LEU P CB 1 49
+ATOM 355 C CG . LEU A 1 49 ? 3.707 3.606 6.996 1.00 69.29 ? ? ? ? ? ? 49 LEU P CG 1 49
+ATOM 356 C CD1 . LEU A 1 49 ? 4.452 2.304 6.765 1.00 69.11 ? ? ? ? ? ? 49 LEU P CD1 1 49
+ATOM 357 C CD2 . LEU A 1 49 ? 2.254 3.329 7.353 1.00 70.29 ? ? ? ? ? ? 49 LEU P CD2 1 49
+ATOM 358 N N . LYS A 1 50 ? 4.539 7.539 7.303 1.00 69.37 ? ? ? ? ? ? 50 LYS P N 1 50
+ATOM 359 C CA . LYS A 1 50 ? 3.982 8.657 6.556 1.00 70.58 ? ? ? ? ? ? 50 LYS P CA 1 50
+ATOM 360 C C . LYS A 1 50 ? 5.077 9.592 6.033 1.00 69.87 ? ? ? ? ? ? 50 LYS P C 1 50
+ATOM 361 O O . LYS A 1 50 ? 4.845 10.381 5.116 1.00 69.14 ? ? ? ? ? ? 50 LYS P O 1 50
+ATOM 362 C CB . LYS A 1 50 ? 3.025 9.433 7.468 1.00 72.95 ? ? ? ? ? ? 50 LYS P CB 1 50
+ATOM 363 C CG . LYS A 1 50 ? 1.919 10.186 6.754 1.00 75.40 ? ? ? ? ? ? 50 LYS P CG 1 50
+ATOM 364 C CD . LYS A 1 50 ? 1.063 10.945 7.753 1.00 76.49 ? ? ? ? ? ? 50 LYS P CD 1 50
+ATOM 365 C CE . LYS A 1 50 ? -0.052 11.706 7.059 1.00 77.39 ? ? ? ? ? ? 50 LYS P CE 1 50
+ATOM 366 N NZ . LYS A 1 50 ? -0.787 12.572 8.019 1.00 78.07 ? ? ? ? ? ? 50 LYS P NZ 1 50
+ATOM 367 N N . MET A 1 51 ? 6.270 9.495 6.614 1.00 68.96 ? ? ? ? ? ? 51 MET P N 1 51
+ATOM 368 C CA . MET A 1 51 ? 7.346 10.447 6.331 1.00 69.07 ? ? ? ? ? ? 51 MET P CA 1 51
+ATOM 369 C C . MET A 1 51 ? 8.580 9.842 5.655 1.00 68.01 ? ? ? ? ? ? 51 MET P C 1 51
+ATOM 370 O O . MET A 1 51 ? 9.479 10.574 5.239 1.00 68.98 ? ? ? ? ? ? 51 MET P O 1 51
+ATOM 371 C CB . MET A 1 51 ? 7.755 11.167 7.617 1.00 70.99 ? ? ? ? ? ? 51 MET P CB 1 51
+ATOM 372 C CG . MET A 1 51 ? 6.684 12.088 8.186 1.00 72.46 ? ? ? ? ? ? 51 MET P CG 1 51
+ATOM 373 S SD . MET A 1 51 ? 6.282 13.463 7.091 1.00 75.65 ? ? ? ? ? ? 51 MET P SD 1 51
+ATOM 374 C CE . MET A 1 51 ? 7.805 14.414 7.159 1.00 74.62 ? ? ? ? ? ? 51 MET P CE 1 51
+ATOM 375 N N . ARG A 1 52 ? 8.606 8.515 5.538 1.00 65.85 ? ? ? ? ? ? 52 ARG P N 1 52
+ATOM 376 C CA . ARG A 1 52 ? 9.739 7.783 4.964 1.00 63.78 ? ? ? ? ? ? 52 ARG P CA 1 52
+ATOM 377 C C . ARG A 1 52 ? 10.053 8.171 3.523 1.00 62.25 ? ? ? ? ? ? 52 ARG P C 1 52
+ATOM 378 O O . ARG A 1 52 ? 9.146 8.426 2.730 1.00 63.55 ? ? ? ? ? ? 52 ARG P O 1 52
+ATOM 379 C CB . ARG A 1 52 ? 9.489 6.277 5.051 1.00 65.46 ? ? ? ? ? ? 52 ARG P CB 1 52
+ATOM 380 C CG . ARG A 1 52 ? 9.761 5.709 6.425 1.00 68.07 ? ? ? ? ? ? 52 ARG P CG 1 52
+ATOM 381 C CD . ARG A 1 52 ? 9.093 4.366 6.656 1.00 68.80 ? ? ? ? ? ? 52 ARG P CD 1 52
+ATOM 382 N NE . ARG A 1 52 ? 9.089 4.040 8.082 1.00 69.38 ? ? ? ? ? ? 52 ARG P NE 1 52
+ATOM 383 C CZ . ARG A 1 52 ? 8.948 2.818 8.586 1.00 69.95 ? ? ? ? ? ? 52 ARG P CZ 1 52
+ATOM 384 N NH1 . ARG A 1 52 ? 8.797 1.769 7.787 1.00 70.80 ? ? ? ? ? ? 52 ARG P NH1 1 52
+ATOM 385 N NH2 . ARG A 1 52 ? 8.962 2.643 9.900 1.00 71.50 ? ? ? ? ? ? 52 ARG P NH2 1 52
+ATOM 386 N N . GLY A 1 53 ? 11.345 8.216 3.203 1.00 59.84 ? ? ? ? ? ? 53 GLY P N 1 53
+ATOM 387 C CA . GLY A 1 53 ? 11.820 8.506 1.846 1.00 57.52 ? ? ? ? ? ? 53 GLY P CA 1 53
+ATOM 388 C C . GLY A 1 53 ? 11.596 9.933 1.380 1.00 55.96 ? ? ? ? ? ? 53 GLY P C 1 53
+ATOM 389 O O . GLY A 1 53 ? 11.617 10.211 0.182 1.00 56.35 ? ? ? ? ? ? 53 GLY P O 1 53
+ATOM 390 N N . GLN A 1 54 ? 11.395 10.841 2.331 1.00 55.63 ? ? ? ? ? ? 54 GLN P N 1 54
+ATOM 391 C CA . GLN A 1 54 ? 11.038 12.225 2.026 1.00 55.28 ? ? ? ? ? ? 54 GLN P CA 1 54
+ATOM 392 C C . GLN A 1 54 ? 11.924 13.212 2.780 1.00 53.06 ? ? ? ? ? ? 54 GLN P C 1 54
+ATOM 393 O O . GLN A 1 54 ? 12.485 12.875 3.823 1.00 51.99 ? ? ? ? ? ? 54 GLN P O 1 54
+ATOM 394 C CB . GLN A 1 54 ? 9.564 12.472 2.368 1.00 56.99 ? ? ? ? ? ? 54 GLN P CB 1 54
+ATOM 395 C CG . GLN A 1 54 ? 8.597 11.512 1.686 1.00 58.64 ? ? ? ? ? ? 54 GLN P CG 1 54
+ATOM 396 C CD . GLN A 1 54 ? 7.285 11.371 2.427 1.00 60.02 ? ? ? ? ? ? 54 GLN P CD 1 54
+ATOM 397 O OE1 . GLN A 1 54 ? 6.492 12.312 2.499 1.00 62.25 ? ? ? ? ? ? 54 GLN P OE1 1 54
+ATOM 398 N NE2 . GLN A 1 54 ? 7.041 10.186 2.973 1.00 59.54 ? ? ? ? ? ? 54 GLN P NE2 1 54
+ATOM 399 N N . ALA A 1 55 ? 12.043 14.428 2.248 1.00 51.60 ? ? ? ? ? ? 55 ALA P N 1 55
+ATOM 400 C CA . ALA A 1 55 ? 12.855 15.476 2.874 1.00 50.86 ? ? ? ? ? ? 55 ALA P CA 1 55
+ATOM 401 C C . ALA A 1 55 ? 12.371 16.890 2.566 1.00 51.02 ? ? ? ? ? ? 55 ALA P C 1 55
+ATOM 402 O O . ALA A 1 55 ? 12.000 17.207 1.434 1.00 51.77 ? ? ? ? ? ? 55 ALA P O 1 55
+ATOM 403 C CB . ALA A 1 55 ? 14.317 15.328 2.479 1.00 50.85 ? ? ? ? ? ? 55 ALA P CB 1 55
+ATOM 404 N N . PHE A 1 56 ? 12.394 17.736 3.592 1.00 51.48 ? ? ? ? ? ? 56 PHE P N 1 56
+ATOM 405 C CA . PHE A 1 56 ? 12.088 19.151 3.449 1.00 52.22 ? ? ? ? ? ? 56 PHE P CA 1 56
+ATOM 406 C C . PHE A 1 56 ? 13.344 19.973 3.710 1.00 51.54 ? ? ? ? ? ? 56 PHE P C 1 56
+ATOM 407 O O . PHE A 1 56 ? 13.870 19.971 4.825 1.00 53.03 ? ? ? ? ? ? 56 PHE P O 1 56
+ATOM 408 C CB . PHE A 1 56 ? 10.980 19.565 4.424 1.00 53.24 ? ? ? ? ? ? 56 PHE P CB 1 56
+ATOM 409 C CG . PHE A 1 56 ? 9.632 18.989 4.094 1.00 55.48 ? ? ? ? ? ? 56 PHE P CG 1 56
+ATOM 410 C CD1 . PHE A 1 56 ? 9.241 17.754 4.609 1.00 56.61 ? ? ? ? ? ? 56 PHE P CD1 1 56
+ATOM 411 C CD2 . PHE A 1 56 ? 8.748 19.685 3.275 1.00 55.66 ? ? ? ? ? ? 56 PHE P CD2 1 56
+ATOM 412 C CE1 . PHE A 1 56 ? 7.992 17.216 4.304 1.00 56.49 ? ? ? ? ? ? 56 PHE P CE1 1 56
+ATOM 413 C CE2 . PHE A 1 56 ? 7.498 19.158 2.964 1.00 55.83 ? ? ? ? ? ? 56 PHE P CE2 1 56
+ATOM 414 C CZ . PHE A 1 56 ? 7.119 17.920 3.482 1.00 56.89 ? ? ? ? ? ? 56 PHE P CZ 1 56
+ATOM 415 N N . VAL A 1 57 ? 13.829 20.660 2.678 1.00 49.70 ? ? ? ? ? ? 57 VAL P N 1 57
+ATOM 416 C CA . VAL A 1 57 ? 14.964 21.566 2.821 1.00 49.92 ? ? ? ? ? ? 57 VAL P CA 1 57
+ATOM 417 C C . VAL A 1 57 ? 14.473 23.008 2.748 1.00 51.04 ? ? ? ? ? ? 57 VAL P C 1 57
+ATOM 418 O O . VAL A 1 57 ? 14.019 23.462 1.696 1.00 50.95 ? ? ? ? ? ? 57 VAL P O 1 57
+ATOM 419 C CB . VAL A 1 57 ? 16.049 21.320 1.745 1.00 49.85 ? ? ? ? ? ? 57 VAL P CB 1 57
+ATOM 420 C CG1 . VAL A 1 57 ? 17.189 22.317 1.895 1.00 50.58 ? ? ? ? ? ? 57 VAL P CG1 1 57
+ATOM 421 C CG2 . VAL A 1 57 ? 16.586 19.904 1.840 1.00 49.81 ? ? ? ? ? ? 57 VAL P CG2 1 57
+ATOM 422 N N . ILE A 1 58 ? 14.564 23.717 3.871 1.00 51.65 ? ? ? ? ? ? 58 ILE P N 1 58
+ATOM 423 C CA . ILE A 1 58 ? 14.102 25.102 3.954 1.00 52.28 ? ? ? ? ? ? 58 ILE P CA 1 58
+ATOM 424 C C . ILE A 1 58 ? 15.261 26.072 3.744 1.00 53.40 ? ? ? ? ? ? 58 ILE P C 1 58
+ATOM 425 O O . ILE A 1 58 ? 16.260 26.027 4.463 1.00 55.73 ? ? ? ? ? ? 58 ILE P O 1 58
+ATOM 426 C CB . ILE A 1 58 ? 13.404 25.408 5.304 1.00 51.18 ? ? ? ? ? ? 58 ILE P CB 1 58
+ATOM 427 C CG1 . ILE A 1 58 ? 12.446 24.278 5.697 1.00 50.88 ? ? ? ? ? ? 58 ILE P CG1 1 58
+ATOM 428 C CG2 . ILE A 1 58 ? 12.662 26.741 5.230 1.00 52.22 ? ? ? ? ? ? 58 ILE P CG2 1 58
+ATOM 429 C CD1 . ILE A 1 58 ? 11.880 24.403 7.103 1.00 51.34 ? ? ? ? ? ? 58 ILE P CD1 1 58
+ATOM 430 N N . PHE A 1 59 ? 15.116 26.948 2.756 1.00 55.12 ? ? ? ? ? ? 59 PHE P N 1 59
+ATOM 431 C CA . PHE A 1 59 ? 16.137 27.943 2.443 1.00 57.70 ? ? ? ? ? ? 59 PHE P CA 1 59
+ATOM 432 C C . PHE A 1 59 ? 15.776 29.311 3.011 1.00 59.81 ? ? ? ? ? ? 59 PHE P C 1 59
+ATOM 433 O O . PHE A 1 59 ? 14.606 29.583 3.290 1.00 59.92 ? ? ? ? ? ? 59 PHE P O 1 59
+ATOM 434 C CB . PHE A 1 59 ? 16.315 28.059 0.927 1.00 56.34 ? ? ? ? ? ? 59 PHE P CB 1 59
+ATOM 435 C CG . PHE A 1 59 ? 16.958 26.859 0.293 1.00 55.66 ? ? ? ? ? ? 59 PHE P CG 1 59
+ATOM 436 C CD1 . PHE A 1 59 ? 18.343 26.772 0.185 1.00 55.51 ? ? ? ? ? ? 59 PHE P CD1 1 59
+ATOM 437 C CD2 . PHE A 1 59 ? 16.181 25.822 -0.210 1.00 55.01 ? ? ? ? ? ? 59 PHE P CD2 1 59
+ATOM 438 C CE1 . PHE A 1 59 ? 18.945 25.663 -0.408 1.00 55.30 ? ? ? ? ? ? 59 PHE P CE1 1 59
+ATOM 439 C CE2 . PHE A 1 59 ? 16.771 24.712 -0.808 1.00 55.15 ? ? ? ? ? ? 59 PHE P CE2 1 59
+ATOM 440 C CZ . PHE A 1 59 ? 18.157 24.631 -0.905 1.00 54.59 ? ? ? ? ? ? 59 PHE P CZ 1 59
+ATOM 441 N N . LYS A 1 60 ? 16.786 30.166 3.181 1.00 62.92 ? ? ? ? ? ? 60 LYS P N 1 60
+ATOM 442 C CA . LYS A 1 60 ? 16.564 31.576 3.498 1.00 64.82 ? ? ? ? ? ? 60 LYS P CA 1 60
+ATOM 443 C C . LYS A 1 60 ? 15.810 32.248 2.362 1.00 65.30 ? ? ? ? ? ? 60 LYS P C 1 60
+ATOM 444 O O . LYS A 1 60 ? 14.854 32.985 2.593 1.00 65.12 ? ? ? ? ? ? 60 LYS P O 1 60
+ATOM 445 C CB . LYS A 1 60 ? 17.887 32.312 3.729 1.00 67.05 ? ? ? ? ? ? 60 LYS P CB 1 60
+ATOM 446 C CG . LYS A 1 60 ? 18.379 32.322 5.167 1.00 68.90 ? ? ? ? ? ? 60 LYS P CG 1 60
+ATOM 447 C CD . LYS A 1 60 ? 19.448 33.392 5.363 1.00 71.74 ? ? ? ? ? ? 60 LYS P CD 1 60
+ATOM 448 C CE . LYS A 1 60 ? 20.033 33.373 6.776 1.00 73.73 ? ? ? ? ? ? 60 LYS P CE 1 60
+ATOM 449 N NZ . LYS A 1 60 ? 21.063 32.308 6.968 1.00 74.60 ? ? ? ? ? ? 60 LYS P NZ 1 60
+ATOM 450 N N . GLU A 1 61 ? 16.239 31.971 1.134 1.00 66.25 ? ? ? ? ? ? 61 GLU P N 1 61
+ATOM 451 C CA . GLU A 1 61 ? 15.692 32.627 -0.047 1.00 66.70 ? ? ? ? ? ? 61 GLU P CA 1 61
+ATOM 452 C C . GLU A 1 61 ? 15.037 31.640 -1.006 1.00 66.84 ? ? ? ? ? ? 61 GLU P C 1 61
+ATOM 453 O O . GLU A 1 61 ? 15.579 30.564 -1.267 1.00 67.07 ? ? ? ? ? ? 61 GLU P O 1 61
+ATOM 454 C CB . GLU A 1 61 ? 16.794 33.409 -0.758 1.00 67.58 ? ? ? ? ? ? 61 GLU P CB 1 61
+ATOM 455 C CG . GLU A 1 61 ? 17.429 34.489 0.112 1.00 69.78 ? ? ? ? ? ? 61 GLU P CG 1 61
+ATOM 456 C CD . GLU A 1 61 ? 18.677 35.086 -0.502 1.00 70.73 ? ? ? ? ? ? 61 GLU P CD 1 61
+ATOM 457 O OE1 . GLU A 1 61 ? 19.654 35.309 0.246 1.00 71.11 ? ? ? ? ? ? 61 GLU P OE1 1 61
+ATOM 458 O OE2 . GLU A 1 61 ? 18.683 35.328 -1.729 1.00 71.63 ? ? ? ? ? ? 61 GLU P OE2 1 61
+ATOM 459 N N . VAL A 1 62 ? 13.869 32.021 -1.523 1.00 67.50 ? ? ? ? ? ? 62 VAL P N 1 62
+ATOM 460 C CA . VAL A 1 62 ? 13.124 31.217 -2.504 1.00 68.34 ? ? ? ? ? ? 62 VAL P CA 1 62
+ATOM 461 C C . VAL A 1 62 ? 13.938 31.014 -3.785 1.00 69.51 ? ? ? ? ? ? 62 VAL P C 1 62
+ATOM 462 O O . VAL A 1 62 ? 13.882 29.949 -4.401 1.00 69.69 ? ? ? ? ? ? 62 VAL P O 1 62
+ATOM 463 C CB . VAL A 1 62 ? 11.750 31.861 -2.859 1.00 67.33 ? ? ? ? ? ? 62 VAL P CB 1 62
+ATOM 464 C CG1 . VAL A 1 62 ? 10.998 31.023 -3.892 1.00 66.61 ? ? ? ? ? ? 62 VAL P CG1 1 62
+ATOM 465 C CG2 . VAL A 1 62 ? 10.899 32.049 -1.615 1.00 65.99 ? ? ? ? ? ? 62 VAL P CG2 1 62
+ATOM 466 N N . SER A 1 63 ? 14.691 32.040 -4.174 1.00 70.80 ? ? ? ? ? ? 63 SER P N 1 63
+ATOM 467 C CA . SER A 1 63 ? 15.532 31.980 -5.366 1.00 72.94 ? ? ? ? ? ? 63 SER P CA 1 63
+ATOM 468 C C . SER A 1 63 ? 16.560 30.851 -5.278 1.00 73.51 ? ? ? ? ? ? 63 SER P C 1 63
+ATOM 469 O O . SER A 1 63 ? 16.797 30.148 -6.261 1.00 74.86 ? ? ? ? ? ? 63 SER P O 1 63
+ATOM 470 C CB . SER A 1 63 ? 16.226 33.323 -5.601 1.00 73.36 ? ? ? ? ? ? 63 SER P CB 1 63
+ATOM 471 O OG . SER A 1 63 ? 16.988 33.704 -4.470 1.00 75.33 ? ? ? ? ? ? 63 SER P OG 1 63
+ATOM 472 N N . SER A 1 64 ? 17.153 30.678 -4.097 1.00 73.28 ? ? ? ? ? ? 64 SER P N 1 64
+ATOM 473 C CA . SER A 1 64 ? 18.118 29.607 -3.863 1.00 73.78 ? ? ? ? ? ? 64 SER P CA 1 64
+ATOM 474 C C . SER A 1 64 ? 17.442 28.233 -3.872 1.00 74.09 ? ? ? ? ? ? 64 SER P C 1 64
+ATOM 475 O O . SER A 1 64 ? 18.055 27.233 -4.255 1.00 74.55 ? ? ? ? ? ? 64 SER P O 1 64
+ATOM 476 C CB . SER A 1 64 ? 18.878 29.833 -2.553 1.00 74.22 ? ? ? ? ? ? 64 SER P CB 1 64
+ATOM 477 O OG . SER A 1 64 ? 18.035 29.680 -1.428 1.00 76.33 ? ? ? ? ? ? 64 SER P OG 1 64
+ATOM 478 N N . ALA A 1 65 ? 16.179 28.194 -3.450 1.00 73.75 ? ? ? ? ? ? 65 ALA P N 1 65
+ATOM 479 C CA . ALA A 1 65 ? 15.363 26.983 -3.538 1.00 72.77 ? ? ? ? ? ? 65 ALA P CA 1 65
+ATOM 480 C C . ALA A 1 65 ? 15.023 26.666 -4.991 1.00 72.62 ? ? ? ? ? ? 65 ALA P C 1 65
+ATOM 481 O O . ALA A 1 65 ? 14.969 25.499 -5.379 1.00 73.18 ? ? ? ? ? ? 65 ALA P O 1 65
+ATOM 482 C CB . ALA A 1 65 ? 14.090 27.137 -2.721 1.00 71.97 ? ? ? ? ? ? 65 ALA P CB 1 65
+ATOM 483 N N . THR A 1 66 ? 14.800 27.716 -5.780 1.00 72.37 ? ? ? ? ? ? 66 THR P N 1 66
+ATOM 484 C CA . THR A 1 66 ? 14.475 27.594 -7.201 1.00 71.59 ? ? ? ? ? ? 66 THR P CA 1 66
+ATOM 485 C C . THR A 1 66 ? 15.646 27.000 -7.979 1.00 70.84 ? ? ? ? ? ? 66 THR P C 1 66
+ATOM 486 O O . THR A 1 66 ? 15.458 26.130 -8.831 1.00 69.83 ? ? ? ? ? ? 66 THR P O 1 66
+ATOM 487 C CB . THR A 1 66 ? 14.083 28.966 -7.804 1.00 72.05 ? ? ? ? ? ? 66 THR P CB 1 66
+ATOM 488 O OG1 . THR A 1 66 ? 13.075 29.579 -6.991 1.00 72.70 ? ? ? ? ? ? 66 THR P OG1 1 66
+ATOM 489 C CG2 . THR A 1 66 ? 13.555 28.812 -9.229 1.00 71.59 ? ? ? ? ? ? 66 THR P CG2 1 66
+ATOM 490 N N . ASN A 1 67 ? 16.852 27.471 -7.672 1.00 70.47 ? ? ? ? ? ? 67 ASN P N 1 67
+ATOM 491 C CA . ASN A 1 67 ? 18.058 26.971 -8.319 1.00 70.79 ? ? ? ? ? ? 67 ASN P CA 1 67
+ATOM 492 C C . ASN A 1 67 ? 18.331 25.519 -7.955 1.00 69.83 ? ? ? ? ? ? 67 ASN P C 1 67
+ATOM 493 O O . ASN A 1 67 ? 18.590 24.702 -8.834 1.00 70.19 ? ? ? ? ? ? 67 ASN P O 1 67
+ATOM 494 C CB . ASN A 1 67 ? 19.262 27.854 -7.983 1.00 71.93 ? ? ? ? ? ? 67 ASN P CB 1 67
+ATOM 495 C CG . ASN A 1 67 ? 19.121 29.272 -8.523 1.00 73.48 ? ? ? ? ? ? 67 ASN P CG 1 67
+ATOM 496 O OD1 . ASN A 1 67 ? 18.128 29.618 -9.170 1.00 72.43 ? ? ? ? ? ? 67 ASN P OD1 1 67
+ATOM 497 N ND2 . ASN A 1 67 ? 20.123 30.103 -8.253 1.00 75.22 ? ? ? ? ? ? 67 ASN P ND2 1 67
+ATOM 498 N N . ALA A 1 68 ? 18.239 25.207 -6.662 1.00 69.11 ? ? ? ? ? ? 68 ALA P N 1 68
+ATOM 499 C CA . ALA A 1 68 ? 18.466 23.854 -6.140 1.00 68.14 ? ? ? ? ? ? 68 ALA P CA 1 68
+ATOM 500 C C . ALA A 1 68 ? 17.574 22.801 -6.797 1.00 68.29 ? ? ? ? ? ? 68 ALA P C 1 68
+ATOM 501 O O . ALA A 1 68 ? 18.025 21.692 -7.086 1.00 67.81 ? ? ? ? ? ? 68 ALA P O 1 68
+ATOM 502 C CB . ALA A 1 68 ? 18.282 23.836 -4.629 1.00 67.95 ? ? ? ? ? ? 68 ALA P CB 1 68
+ATOM 503 N N . LEU A 1 69 ? 16.312 23.160 -7.026 1.00 69.27 ? ? ? ? ? ? 69 LEU P N 1 69
+ATOM 504 C CA . LEU A 1 69 ? 15.340 22.281 -7.674 1.00 69.95 ? ? ? ? ? ? 69 LEU P CA 1 69
+ATOM 505 C C . LEU A 1 69 ? 15.719 22.050 -9.130 1.00 71.53 ? ? ? ? ? ? 69 LEU P C 1 69
+ATOM 506 O O . LEU A 1 69 ? 15.865 20.909 -9.568 1.00 72.31 ? ? ? ? ? ? 69 LEU P O 1 69
+ATOM 507 C CB . LEU A 1 69 ? 13.930 22.886 -7.578 1.00 68.95 ? ? ? ? ? ? 69 LEU P CB 1 69
+ATOM 508 C CG . LEU A 1 69 ? 12.708 22.127 -8.115 1.00 68.62 ? ? ? ? ? ? 69 LEU P CG 1 69
+ATOM 509 C CD1 . LEU A 1 69 ? 11.455 22.552 -7.366 1.00 68.96 ? ? ? ? ? ? 69 LEU P CD1 1 69
+ATOM 510 C CD2 . LEU A 1 69 ? 12.511 22.311 -9.617 1.00 68.65 ? ? ? ? ? ? 69 LEU P CD2 1 69
+ATOM 511 N N . ARG A 1 70 ? 15.876 23.145 -9.870 1.00 73.08 ? ? ? ? ? ? 70 ARG P N 1 70
+ATOM 512 C CA . ARG A 1 70 ? 16.155 23.088 -11.298 1.00 74.41 ? ? ? ? ? ? 70 ARG P CA 1 70
+ATOM 513 C C . ARG A 1 70 ? 17.530 22.486 -11.599 1.00 75.37 ? ? ? ? ? ? 70 ARG P C 1 70
+ATOM 514 O O . ARG A 1 70 ? 17.700 21.795 -12.607 1.00 75.39 ? ? ? ? ? ? 70 ARG P O 1 70
+ATOM 515 C CB . ARG A 1 70 ? 15.986 24.477 -11.931 1.00 75.27 ? ? ? ? ? ? 70 ARG P CB 1 70
+ATOM 516 C CG . ARG A 1 70 ? 14.540 24.779 -12.343 1.00 76.61 ? ? ? ? ? ? 70 ARG P CG 1 70
+ATOM 517 C CD . ARG A 1 70 ? 14.132 26.241 -12.128 1.00 78.28 ? ? ? ? ? ? 70 ARG P CD 1 70
+ATOM 518 N NE . ARG A 1 70 ? 14.722 27.167 -13.100 1.00 79.62 ? ? ? ? ? ? 70 ARG P NE 1 70
+ATOM 519 C CZ . ARG A 1 70 ? 14.294 28.411 -13.320 1.00 79.79 ? ? ? ? ? ? 70 ARG P CZ 1 70
+ATOM 520 N NH1 . ARG A 1 70 ? 13.256 28.901 -12.652 1.00 80.16 ? ? ? ? ? ? 70 ARG P NH1 1 70
+ATOM 521 N NH2 . ARG A 1 70 ? 14.902 29.170 -14.221 1.00 80.30 ? ? ? ? ? ? 70 ARG P NH2 1 70
+ATOM 522 N N . SER A 1 71 ? 18.491 22.722 -10.705 1.00 75.79 ? ? ? ? ? ? 71 SER P N 1 71
+ATOM 523 C CA . SER A 1 71 ? 19.872 22.276 -10.908 1.00 76.68 ? ? ? ? ? ? 71 SER P CA 1 71
+ATOM 524 C C . SER A 1 71 ? 20.121 20.816 -10.532 1.00 77.22 ? ? ? ? ? ? 71 SER P C 1 71
+ATOM 525 O O . SER A 1 71 ? 21.059 20.199 -11.042 1.00 78.31 ? ? ? ? ? ? 71 SER P O 1 71
+ATOM 526 C CB . SER A 1 71 ? 20.852 23.173 -10.147 1.00 76.18 ? ? ? ? ? ? 71 SER P CB 1 71
+ATOM 527 O OG . SER A 1 71 ? 20.682 24.535 -10.506 1.00 77.09 ? ? ? ? ? ? 71 SER P OG 1 71
+ATOM 528 N N . MET A 1 72 ? 19.292 20.264 -9.649 1.00 77.19 ? ? ? ? ? ? 72 MET P N 1 72
+ATOM 529 C CA . MET A 1 72 ? 19.538 18.914 -9.136 1.00 76.71 ? ? ? ? ? ? 72 MET P CA 1 72
+ATOM 530 C C . MET A 1 72 ? 18.343 17.947 -9.154 1.00 76.58 ? ? ? ? ? ? 72 MET P C 1 72
+ATOM 531 O O . MET A 1 72 ? 18.313 16.933 -8.359 1.00 75.50 ? ? ? ? ? ? 72 MET P O 1 72
+ATOM 532 C CB . MET A 1 72 ? 20.158 18.976 -7.739 1.00 77.03 ? ? ? ? ? ? 72 MET P CB 1 72
+ATOM 533 C CG . MET A 1 72 ? 21.659 19.136 -7.768 1.00 78.13 ? ? ? ? ? ? 72 MET P CG 1 72
+ATOM 534 S SD . MET A 1 72 ? 22.386 18.963 -6.138 1.00 80.36 ? ? ? ? ? ? 72 MET P SD 1 72
+ATOM 535 C CE . MET A 1 72 ? 24.116 18.765 -6.562 1.00 81.61 ? ? ? ? ? ? 72 MET P CE 1 72
+ATOM 536 N N . GLN A 1 73 ? 17.377 18.244 -10.069 1.00 77.39 ? ? ? ? ? ? 73 GLN P N 1 73
+ATOM 537 C CA . GLN A 1 73 ? 16.236 17.333 -10.223 1.00 78.05 ? ? ? ? ? ? 73 GLN P CA 1 73
+ATOM 538 C C . GLN A 1 73 ? 16.685 16.089 -10.985 1.00 78.05 ? ? ? ? ? ? 73 GLN P C 1 73
+ATOM 539 O O . GLN A 1 73 ? 17.300 16.195 -12.048 1.00 77.97 ? ? ? ? ? ? 73 GLN P O 1 73
+ATOM 540 C CB . GLN A 1 73 ? 15.086 18.020 -10.964 1.00 78.23 ? ? ? ? ? ? 73 GLN P CB 1 73
+ATOM 541 C CG . GLN A 1 73 ? 13.720 17.913 -10.273 1.00 79.31 ? ? ? ? ? ? 73 GLN P CG 1 73
+ATOM 542 C CD . GLN A 1 73 ? 13.085 16.525 -10.335 1.00 79.89 ? ? ? ? ? ? 73 GLN P CD 1 73
+ATOM 543 O OE1 . GLN A 1 73 ? 13.680 15.564 -10.825 1.00 80.91 ? ? ? ? ? ? 73 GLN P OE1 1 73
+ATOM 544 N NE2 . GLN A 1 73 ? 11.861 16.424 -9.833 1.00 80.00 ? ? ? ? ? ? 73 GLN P NE2 1 73
+ATOM 545 N N . GLY A 1 74 ? 16.390 14.916 -10.427 1.00 78.16 ? ? ? ? ? ? 74 GLY P N 1 74
+ATOM 546 C CA . GLY A 1 74 ? 16.762 13.639 -11.042 1.00 78.21 ? ? ? ? ? ? 74 GLY P CA 1 74
+ATOM 547 C C . GLY A 1 74 ? 18.062 13.044 -10.523 1.00 77.68 ? ? ? ? ? ? 74 GLY P C 1 74
+ATOM 548 O O . GLY A 1 74 ? 18.272 11.834 -10.615 1.00 78.32 ? ? ? ? ? ? 74 GLY P O 1 74
+ATOM 549 N N . PHE A 1 75 ? 18.925 13.903 -9.980 1.00 76.74 ? ? ? ? ? ? 75 PHE P N 1 75
+ATOM 550 C CA . PHE A 1 75 ? 20.240 13.526 -9.446 1.00 77.20 ? ? ? ? ? ? 75 PHE P CA 1 75
+ATOM 551 C C . PHE A 1 75 ? 20.203 12.243 -8.600 1.00 76.71 ? ? ? ? ? ? 75 PHE P C 1 75
+ATOM 552 O O . PHE A 1 75 ? 19.464 12.170 -7.614 1.00 75.98 ? ? ? ? ? ? 75 PHE P O 1 75
+ATOM 553 C CB . PHE A 1 75 ? 20.806 14.692 -8.622 1.00 77.88 ? ? ? ? ? ? 75 PHE P CB 1 75
+ATOM 554 C CG . PHE A 1 75 ? 22.297 14.643 -8.417 1.00 79.00 ? ? ? ? ? ? 75 PHE P CG 1 75
+ATOM 555 C CD1 . PHE A 1 75 ? 23.151 15.331 -9.276 1.00 79.61 ? ? ? ? ? ? 75 PHE P CD1 1 75
+ATOM 556 C CD2 . PHE A 1 75 ? 22.848 13.938 -7.349 1.00 79.27 ? ? ? ? ? ? 75 PHE P CD2 1 75
+ATOM 557 C CE1 . PHE A 1 75 ? 24.534 15.303 -9.084 1.00 80.20 ? ? ? ? ? ? 75 PHE P CE1 1 75
+ATOM 558 C CE2 . PHE A 1 75 ? 24.229 13.900 -7.150 1.00 79.39 ? ? ? ? ? ? 75 PHE P CE2 1 75
+ATOM 559 C CZ . PHE A 1 75 ? 25.073 14.585 -8.017 1.00 79.98 ? ? ? ? ? ? 75 PHE P CZ 1 75
+ATOM 560 N N . PRO A 1 76 ? 20.990 11.222 -8.999 1.00 76.70 ? ? ? ? ? ? 76 PRO P N 1 76
+ATOM 561 C CA . PRO A 1 76 ? 21.116 9.972 -8.246 1.00 76.59 ? ? ? ? ? ? 76 PRO P CA 1 76
+ATOM 562 C C . PRO A 1 76 ? 21.790 10.183 -6.891 1.00 75.90 ? ? ? ? ? ? 76 PRO P C 1 76
+ATOM 563 O O . PRO A 1 76 ? 22.881 10.757 -6.815 1.00 75.94 ? ? ? ? ? ? 76 PRO P O 1 76
+ATOM 564 C CB . PRO A 1 76 ? 21.990 9.097 -9.153 1.00 76.82 ? ? ? ? ? ? 76 PRO P CB 1 76
+ATOM 565 C CG . PRO A 1 76 ? 21.821 9.672 -10.511 1.00 77.27 ? ? ? ? ? ? 76 PRO P CG 1 76
+ATOM 566 C CD . PRO A 1 76 ? 21.701 11.145 -10.288 1.00 77.15 ? ? ? ? ? ? 76 PRO P CD 1 76
+ATOM 567 N N . PHE A 1 77 ? 21.129 9.700 -5.841 1.00 74.72 ? ? ? ? ? ? 77 PHE P N 1 77
+ATOM 568 C CA . PHE A 1 77 ? 21.515 9.960 -4.458 1.00 72.57 ? ? ? ? ? ? 77 PHE P CA 1 77
+ATOM 569 C C . PHE A 1 77 ? 21.297 8.693 -3.629 1.00 71.11 ? ? ? ? ? ? 77 PHE P C 1 77
+ATOM 570 O O . PHE A 1 77 ? 20.155 8.282 -3.395 1.00 68.54 ? ? ? ? ? ? 77 PHE P O 1 77
+ATOM 571 C CB . PHE A 1 77 ? 20.676 11.120 -3.918 1.00 72.34 ? ? ? ? ? ? 77 PHE P CB 1 77
+ATOM 572 C CG . PHE A 1 77 ? 21.122 11.635 -2.586 1.00 72.37 ? ? ? ? ? ? 77 PHE P CG 1 77
+ATOM 573 C CD1 . PHE A 1 77 ? 22.336 12.300 -2.451 1.00 72.45 ? ? ? ? ? ? 77 PHE P CD1 1 77
+ATOM 574 C CD2 . PHE A 1 77 ? 20.310 11.486 -1.468 1.00 72.33 ? ? ? ? ? ? 77 PHE P CD2 1 77
+ATOM 575 C CE1 . PHE A 1 77 ? 22.745 12.788 -1.217 1.00 73.06 ? ? ? ? ? ? 77 PHE P CE1 1 77
+ATOM 576 C CE2 . PHE A 1 77 ? 20.707 11.975 -0.231 1.00 73.27 ? ? ? ? ? ? 77 PHE P CE2 1 77
+ATOM 577 C CZ . PHE A 1 77 ? 21.929 12.627 -0.105 1.00 73.40 ? ? ? ? ? ? 77 PHE P CZ 1 77
+ATOM 578 N N . TYR A 1 78 ? 22.401 8.088 -3.190 1.00 69.87 ? ? ? ? ? ? 78 TYR P N 1 78
+ATOM 579 C CA . TYR A 1 78 ? 22.399 6.757 -2.575 1.00 69.55 ? ? ? ? ? ? 78 TYR P CA 1 78
+ATOM 580 C C . TYR A 1 78 ? 21.743 5.741 -3.510 1.00 71.10 ? ? ? ? ? ? 78 TYR P C 1 78
+ATOM 581 O O . TYR A 1 78 ? 20.803 5.042 -3.121 1.00 70.76 ? ? ? ? ? ? 78 TYR P O 1 78
+ATOM 582 C CB . TYR A 1 78 ? 21.700 6.758 -1.209 1.00 67.92 ? ? ? ? ? ? 78 TYR P CB 1 78
+ATOM 583 C CG . TYR A 1 78 ? 22.436 7.489 -0.110 1.00 66.15 ? ? ? ? ? ? 78 TYR P CG 1 78
+ATOM 584 C CD1 . TYR A 1 78 ? 23.514 6.900 0.547 1.00 65.85 ? ? ? ? ? ? 78 TYR P CD1 1 78
+ATOM 585 C CD2 . TYR A 1 78 ? 22.039 8.761 0.291 1.00 65.44 ? ? ? ? ? ? 78 TYR P CD2 1 78
+ATOM 586 C CE1 . TYR A 1 78 ? 24.183 7.566 1.568 1.00 65.00 ? ? ? ? ? ? 78 TYR P CE1 1 78
+ATOM 587 C CE2 . TYR A 1 78 ? 22.706 9.436 1.308 1.00 65.15 ? ? ? ? ? ? 78 TYR P CE2 1 78
+ATOM 588 C CZ . TYR A 1 78 ? 23.777 8.832 1.941 1.00 64.50 ? ? ? ? ? ? 78 TYR P CZ 1 78
+ATOM 589 O OH . TYR A 1 78 ? 24.438 9.492 2.950 1.00 63.15 ? ? ? ? ? ? 78 TYR P OH 1 78
+ATOM 590 N N . ASP A 1 79 ? 22.242 5.689 -4.747 1.00 73.33 ? ? ? ? ? ? 79 ASP P N 1 79
+ATOM 591 C CA . ASP A 1 79 ? 21.730 4.804 -5.808 1.00 74.53 ? ? ? ? ? ? 79 ASP P CA 1 79
+ATOM 592 C C . ASP A 1 79 ? 20.236 5.014 -6.150 1.00 73.85 ? ? ? ? ? ? 79 ASP P C 1 79
+ATOM 593 O O . ASP A 1 79 ? 19.592 4.131 -6.724 1.00 73.76 ? ? ? ? ? ? 79 ASP P O 1 79
+ATOM 594 C CB . ASP A 1 79 ? 22.039 3.328 -5.488 1.00 75.93 ? ? ? ? ? ? 79 ASP P CB 1 79
+ATOM 595 C CG . ASP A 1 79 ? 22.074 2.443 -6.732 1.00 77.34 ? ? ? ? ? ? 79 ASP P CG 1 79
+ATOM 596 O OD1 . ASP A 1 79 ? 22.408 2.944 -7.831 1.00 77.86 ? ? ? ? ? ? 79 ASP P OD1 1 79
+ATOM 597 O OD2 . ASP A 1 79 ? 21.771 1.236 -6.605 1.00 77.54 ? ? ? ? ? ? 79 ASP P OD2 1 79
+ATOM 598 N N . LYS A 1 80 ? 19.696 6.182 -5.803 1.00 73.73 ? ? ? ? ? ? 80 LYS P N 1 80
+ATOM 599 C CA . LYS A 1 80 ? 18.301 6.518 -6.110 1.00 73.49 ? ? ? ? ? ? 80 LYS P CA 1 80
+ATOM 600 C C . LYS A 1 80 ? 18.146 7.961 -6.599 1.00 74.26 ? ? ? ? ? ? 80 LYS P C 1 80
+ATOM 601 O O . LYS A 1 80 ? 18.685 8.886 -5.985 1.00 73.92 ? ? ? ? ? ? 80 LYS P O 1 80
+ATOM 602 C CB . LYS A 1 80 ? 17.389 6.271 -4.903 1.00 72.16 ? ? ? ? ? ? 80 LYS P CB 1 80
+ATOM 603 C CG . LYS A 1 80 ? 16.982 4.816 -4.711 1.00 72.11 ? ? ? ? ? ? 80 LYS P CG 1 80
+ATOM 604 C CD . LYS A 1 80 ? 15.839 4.673 -3.718 1.00 71.48 ? ? ? ? ? ? 80 LYS P CD 1 80
+ATOM 605 C CE . LYS A 1 80 ? 14.502 5.031 -4.348 1.00 71.99 ? ? ? ? ? ? 80 LYS P CE 1 80
+ATOM 606 N NZ . LYS A 1 80 ? 13.403 5.043 -3.345 1.00 73.15 ? ? ? ? ? ? 80 LYS P NZ 1 80
+ATOM 607 N N . PRO A 1 81 ? 17.397 8.156 -7.704 1.00 74.32 ? ? ? ? ? ? 81 PRO P N 1 81
+ATOM 608 C CA . PRO A 1 81 ? 17.201 9.495 -8.254 1.00 73.20 ? ? ? ? ? ? 81 PRO P CA 1 81
+ATOM 609 C C . PRO A 1 81 ? 16.276 10.331 -7.376 1.00 72.45 ? ? ? ? ? ? 81 PRO P C 1 81
+ATOM 610 O O . PRO A 1 81 ? 15.177 9.889 -7.029 1.00 71.86 ? ? ? ? ? ? 81 PRO P O 1 81
+ATOM 611 C CB . PRO A 1 81 ? 16.554 9.225 -9.615 1.00 73.27 ? ? ? ? ? ? 81 PRO P CB 1 81
+ATOM 612 C CG . PRO A 1 81 ? 15.848 7.926 -9.447 1.00 73.64 ? ? ? ? ? ? 81 PRO P CG 1 81
+ATOM 613 C CD . PRO A 1 81 ? 16.650 7.130 -8.459 1.00 74.15 ? ? ? ? ? ? 81 PRO P CD 1 81
+ATOM 614 N N . MET A 1 82 ? 16.734 11.523 -7.009 1.00 72.19 ? ? ? ? ? ? 82 MET P N 1 82
+ATOM 615 C CA . MET A 1 82 ? 15.919 12.453 -6.239 1.00 72.11 ? ? ? ? ? ? 82 MET P CA 1 82
+ATOM 616 C C . MET A 1 82 ? 14.759 12.967 -7.083 1.00 72.34 ? ? ? ? ? ? 82 MET P C 1 82
+ATOM 617 O O . MET A 1 82 ? 14.875 13.085 -8.305 1.00 72.60 ? ? ? ? ? ? 82 MET P O 1 82
+ATOM 618 C CB . MET A 1 82 ? 16.769 13.620 -5.733 1.00 71.74 ? ? ? ? ? ? 82 MET P CB 1 82
+ATOM 619 C CG . MET A 1 82 ? 17.663 13.272 -4.551 1.00 71.59 ? ? ? ? ? ? 82 MET P CG 1 82
+ATOM 620 S SD . MET A 1 82 ? 18.623 14.674 -3.937 1.00 71.26 ? ? ? ? ? ? 82 MET P SD 1 82
+ATOM 621 C CE . MET A 1 82 ? 20.010 14.674 -5.066 1.00 71.25 ? ? ? ? ? ? 82 MET P CE 1 82
+ATOM 622 N N . ARG A 1 83 ? 13.635 13.249 -6.430 1.00 72.88 ? ? ? ? ? ? 83 ARG P N 1 83
+ATOM 623 C CA . ARG A 1 83 ? 12.481 13.836 -7.103 1.00 74.28 ? ? ? ? ? ? 83 ARG P CA 1 83
+ATOM 624 C C . ARG A 1 83 ? 12.070 15.115 -6.384 1.00 73.25 ? ? ? ? ? ? 83 ARG P C 1 83
+ATOM 625 O O . ARG A 1 83 ? 11.290 15.089 -5.429 1.00 74.77 ? ? ? ? ? ? 83 ARG P O 1 83
+ATOM 626 C CB . ARG A 1 83 ? 11.314 12.840 -7.184 1.00 77.26 ? ? ? ? ? ? 83 ARG P CB 1 83
+ATOM 627 C CG . ARG A 1 83 ? 11.616 11.564 -7.975 1.00 80.64 ? ? ? ? ? ? 83 ARG P CG 1 83
+ATOM 628 C CD . ARG A 1 83 ? 11.611 11.798 -9.487 1.00 82.60 ? ? ? ? ? ? 83 ARG P CD 1 83
+ATOM 629 N NE . ARG A 1 83 ? 12.506 10.879 -10.193 1.00 84.36 ? ? ? ? ? ? 83 ARG P NE 1 83
+ATOM 630 C CZ . ARG A 1 83 ? 12.192 9.637 -10.559 1.00 85.59 ? ? ? ? ? ? 83 ARG P CZ 1 83
+ATOM 631 N NH1 . ARG A 1 83 ? 10.994 9.129 -10.292 1.00 85.97 ? ? ? ? ? ? 83 ARG P NH1 1 83
+ATOM 632 N NH2 . ARG A 1 83 ? 13.087 8.893 -11.197 1.00 85.96 ? ? ? ? ? ? 83 ARG P NH2 1 83
+ATOM 633 N N . ILE A 1 84 ? 12.614 16.234 -6.848 1.00 70.68 ? ? ? ? ? ? 84 ILE P N 1 84
+ATOM 634 C CA . ILE A 1 84 ? 12.389 17.524 -6.207 1.00 68.59 ? ? ? ? ? ? 84 ILE P CA 1 84
+ATOM 635 C C . ILE A 1 84 ? 11.180 18.243 -6.802 1.00 68.25 ? ? ? ? ? ? 84 ILE P C 1 84
+ATOM 636 O O . ILE A 1 84 ? 11.027 18.329 -8.021 1.00 68.71 ? ? ? ? ? ? 84 ILE P O 1 84
+ATOM 637 C CB . ILE A 1 84 ? 13.643 18.437 -6.297 1.00 68.14 ? ? ? ? ? ? 84 ILE P CB 1 84
+ATOM 638 C CG1 . ILE A 1 84 ? 14.920 17.630 -6.026 1.00 67.86 ? ? ? ? ? ? 84 ILE P CG1 1 84
+ATOM 639 C CG2 . ILE A 1 84 ? 13.520 19.619 -5.329 1.00 68.05 ? ? ? ? ? ? 84 ILE P CG2 1 84
+ATOM 640 C CD1 . ILE A 1 84 ? 16.214 18.332 -6.419 1.00 67.21 ? ? ? ? ? ? 84 ILE P CD1 1 84
+ATOM 641 N N . GLN A 1 85 ? 10.319 18.734 -5.919 1.00 68.10 ? ? ? ? ? ? 85 GLN P N 1 85
+ATOM 642 C CA . GLN A 1 85 ? 9.235 19.639 -6.281 1.00 69.41 ? ? ? ? ? ? 85 GLN P CA 1 85
+ATOM 643 C C . GLN A 1 85 ? 9.021 20.614 -5.123 1.00 70.51 ? ? ? ? ? ? 85 GLN P C 1 85
+ATOM 644 O O . GLN A 1 85 ? 9.499 20.373 -4.015 1.00 71.01 ? ? ? ? ? ? 85 GLN P O 1 85
+ATOM 645 C CB . GLN A 1 85 ? 7.950 18.867 -6.612 1.00 69.26 ? ? ? ? ? ? 85 GLN P CB 1 85
+ATOM 646 C CG . GLN A 1 85 ? 7.436 17.958 -5.495 1.00 69.64 ? ? ? ? ? ? 85 GLN P CG 1 85
+ATOM 647 C CD . GLN A 1 85 ? 6.210 17.141 -5.888 1.00 68.19 ? ? ? ? ? ? 85 GLN P CD 1 85
+ATOM 648 O OE1 . GLN A 1 85 ? 5.755 16.289 -5.123 1.00 66.95 ? ? ? ? ? ? 85 GLN P OE1 1 85
+ATOM 649 N NE2 . GLN A 1 85 ? 5.671 17.398 -7.074 1.00 67.51 ? ? ? ? ? ? 85 GLN P NE2 1 85
+ATOM 650 N N . TYR A 1 86 ? 8.322 21.716 -5.380 1.00 71.54 ? ? ? ? ? ? 86 TYR P N 1 86
+ATOM 651 C CA . TYR A 1 86 ? 8.063 22.717 -4.347 1.00 72.64 ? ? ? ? ? ? 86 TYR P CA 1 86
+ATOM 652 C C . TYR A 1 86 ? 7.132 22.208 -3.252 1.00 73.71 ? ? ? ? ? ? 86 TYR P C 1 86
+ATOM 653 O O . TYR A 1 86 ? 6.305 21.319 -3.484 1.00 73.77 ? ? ? ? ? ? 86 TYR P O 1 86
+ATOM 654 C CB . TYR A 1 86 ? 7.464 23.985 -4.959 1.00 74.07 ? ? ? ? ? ? 86 TYR P CB 1 86
+ATOM 655 C CG . TYR A 1 86 ? 8.466 24.894 -5.629 1.00 74.93 ? ? ? ? ? ? 86 TYR P CG 1 86
+ATOM 656 C CD1 . TYR A 1 86 ? 9.476 25.515 -4.893 1.00 75.09 ? ? ? ? ? ? 86 TYR P CD1 1 86
+ATOM 657 C CD2 . TYR A 1 86 ? 8.393 25.150 -6.997 1.00 75.01 ? ? ? ? ? ? 86 TYR P CD2 1 86
+ATOM 658 C CE1 . TYR A 1 86 ? 10.394 26.355 -5.503 1.00 75.42 ? ? ? ? ? ? 86 TYR P CE1 1 86
+ATOM 659 C CE2 . TYR A 1 86 ? 9.305 25.988 -7.617 1.00 76.04 ? ? ? ? ? ? 86 TYR P CE2 1 86
+ATOM 660 C CZ . TYR A 1 86 ? 10.302 26.587 -6.864 1.00 76.45 ? ? ? ? ? ? 86 TYR P CZ 1 86
+ATOM 661 O OH . TYR A 1 86 ? 11.207 27.420 -7.474 1.00 77.07 ? ? ? ? ? ? 86 TYR P OH 1 86
+ATOM 662 N N . ALA A 1 87 ? 7.278 22.779 -2.059 1.00 73.67 ? ? ? ? ? ? 87 ALA P N 1 87
+ATOM 663 C CA . ALA A 1 87 ? 6.354 22.531 -0.962 1.00 74.48 ? ? ? ? ? ? 87 ALA P CA 1 87
+ATOM 664 C C . ALA A 1 87 ? 5.014 23.200 -1.264 1.00 75.95 ? ? ? ? ? ? 87 ALA P C 1 87
+ATOM 665 O O . ALA A 1 87 ? 4.978 24.268 -1.889 1.00 76.31 ? ? ? ? ? ? 87 ALA P O 1 87
+ATOM 666 C CB . ALA A 1 87 ? 6.931 23.055 0.342 1.00 74.00 ? ? ? ? ? ? 87 ALA P CB 1 87
+ATOM 667 N N . LYS A 1 88 ? 3.919 22.560 -0.828 1.00 78.69 ? ? ? ? ? ? 88 LYS P N 1 88
+ATOM 668 C CA . LYS A 1 88 ? 2.572 23.092 -1.037 1.00 80.61 ? ? ? ? ? ? 88 LYS P CA 1 88
+ATOM 669 C C . LYS A 1 88 ? 2.330 24.286 -0.122 1.00 82.43 ? ? ? ? ? ? 88 LYS P C 1 88
+ATOM 670 O O . LYS A 1 88 ? 1.979 25.389 -0.583 1.00 81.29 ? ? ? ? ? ? 88 LYS P O 1 88
+ATOM 671 C CB . LYS A 1 88 ? 1.525 22.013 -0.748 1.00 81.34 ? ? ? ? ? ? 88 LYS P CB 1 88
+ATOM 672 C CG . LYS A 1 88 ? 1.591 20.802 -1.669 1.00 82.53 ? ? ? ? ? ? 88 LYS P CG 1 88
+ATOM 673 C CD . LYS A 1 88 ? 0.630 19.716 -1.206 1.00 82.77 ? ? ? ? ? ? 88 LYS P CD 1 88
+ATOM 674 C CE . LYS A 1 88 ? 0.687 18.501 -2.122 1.00 83.16 ? ? ? ? ? ? 88 LYS P CE 1 88
+ATOM 675 N NZ . LYS A 1 88 ? -0.109 17.366 -1.577 1.00 83.03 ? ? ? ? ? ? 88 LYS P NZ 1 88
+ATOM 676 N N . THR A 1 89 ? 2.532 24.035 1.184 1.00 86.65 ? ? ? ? ? ? 89 THR P N 1 89
+ATOM 677 C CA . THR A 1 89 ? 2.326 25.040 2.223 1.00 91.29 ? ? ? ? ? ? 89 THR P CA 1 89
+ATOM 678 C C . THR A 1 89 ? 3.624 25.012 3.064 1.00 93.56 ? ? ? ? ? ? 89 THR P C 1 89
+ATOM 679 O O . THR A 1 89 ? 4.263 23.915 3.201 1.00 95.63 ? ? ? ? ? ? 89 THR P O 1 89
+ATOM 680 C CB . THR A 1 89 ? 1.170 24.605 3.188 1.00 91.85 ? ? ? ? ? ? 89 THR P CB 1 89
+ATOM 681 O OG1 . THR A 1 89 ? 1.659 23.561 4.098 1.00 92.96 ? ? ? ? ? ? 89 THR P OG1 1 89
+ATOM 682 C CG2 . THR A 1 89 ? -0.048 24.085 2.409 1.00 91.80 ? ? ? ? ? ? 89 THR P CG2 1 89
+ATOM 683 N N . ASP A 1 90 ? 4.015 26.200 3.638 1.00 94.83 ? ? ? ? ? ? 90 ASP P N 1 90
+ATOM 684 C CA . ASP A 1 90 ? 5.263 26.232 4.415 1.00 96.77 ? ? ? ? ? ? 90 ASP P CA 1 90
+ATOM 685 C C . ASP A 1 90 ? 5.010 26.968 5.761 1.00 96.82 ? ? ? ? ? ? 90 ASP P C 1 90
+ATOM 686 O O . ASP A 1 90 ? 4.706 28.166 5.811 1.00 97.65 ? ? ? ? ? ? 90 ASP P O 1 90
+ATOM 687 C CB . ASP A 1 90 ? 6.318 27.053 3.601 1.00 98.64 ? ? ? ? ? ? 90 ASP P CB 1 90
+ATOM 688 C CG . ASP A 1 90 ? 7.490 27.588 4.452 1.00 100.17 ? ? ? ? ? ? 90 ASP P CG 1 90
+ATOM 689 O OD1 . ASP A 1 90 ? 8.159 26.774 5.157 1.00 100.67 ? ? ? ? ? ? 90 ASP P OD1 1 90
+ATOM 690 O OD2 . ASP A 1 90 ? 7.750 28.827 4.396 1.00 101.43 ? ? ? ? ? ? 90 ASP P OD2 1 90
+ATOM 691 N N . SER A 1 91 ? 5.112 26.167 6.846 1.00 96.55 ? ? ? ? ? ? 91 SER P N 1 91
+ATOM 692 C CA . SER A 1 91 ? 5.073 26.712 8.219 1.00 96.88 ? ? ? ? ? ? 91 SER P CA 1 91
+ATOM 693 C C . SER A 1 91 ? 6.514 27.054 8.624 1.00 96.62 ? ? ? ? ? ? 91 SER P C 1 91
+ATOM 694 O O . SER A 1 91 ? 7.505 26.742 7.859 1.00 96.50 ? ? ? ? ? ? 91 SER P O 1 91
+ATOM 695 C CB . SER A 1 91 ? 4.458 25.701 9.201 1.00 97.01 ? ? ? ? ? ? 91 SER P CB 1 91
+ATOM 696 O OG . SER A 1 91 ? 4.501 26.191 10.550 1.00 96.14 ? ? ? ? ? ? 91 SER P OG 1 91
+ATOM 697 N N . ASP A 1 92 ? 6.617 27.687 9.827 1.00 96.09 ? ? ? ? ? ? 92 ASP P N 1 92
+ATOM 698 C CA . ASP A 1 92 ? 7.916 28.243 10.265 1.00 96.41 ? ? ? ? ? ? 92 ASP P CA 1 92
+ATOM 699 C C . ASP A 1 92 ? 8.195 29.522 9.462 1.00 97.21 ? ? ? ? ? ? 92 ASP P C 1 92
+ATOM 700 O O . ASP A 1 92 ? 7.266 30.141 8.927 1.00 97.34 ? ? ? ? ? ? 92 ASP P O 1 92
+ATOM 701 C CB . ASP A 1 92 ? 9.045 27.210 10.088 1.00 96.12 ? ? ? ? ? ? 92 ASP P CB 1 92
+ATOM 702 C CG . ASP A 1 92 ? 10.218 27.458 11.014 1.00 96.39 ? ? ? ? ? ? 92 ASP P CG 1 92
+ATOM 703 O OD1 . ASP A 1 92 ? 10.147 27.037 12.188 1.00 96.84 ? ? ? ? ? ? 92 ASP P OD1 1 92
+ATOM 704 O OD2 . ASP A 1 92 ? 11.215 28.064 10.564 1.00 96.10 ? ? ? ? ? ? 92 ASP P OD2 1 92
+ATOM 705 N N . ILE A 1 93 ? 9.465 29.912 9.378 1.00 97.36 ? ? ? ? ? ? 93 ILE P N 1 93
+ATOM 706 C CA . ILE A 1 93 ? 9.858 31.124 8.662 1.00 97.66 ? ? ? ? ? ? 93 ILE P CA 1 93
+ATOM 707 C C . ILE A 1 93 ? 10.452 30.788 7.287 1.00 96.98 ? ? ? ? ? ? 93 ILE P C 1 93
+ATOM 708 O O . ILE A 1 93 ? 9.720 30.563 6.320 1.00 94.99 ? ? ? ? ? ? 93 ILE P O 1 93
+ATOM 709 C CB . ILE A 1 93 ? 10.845 31.970 9.507 1.00 98.20 ? ? ? ? ? ? 93 ILE P CB 1 93
+ATOM 710 C CG1 . ILE A 1 93 ? 10.111 32.605 10.695 1.00 98.87 ? ? ? ? ? ? 93 ILE P CG1 1 93
+ATOM 711 C CG2 . ILE A 1 93 ? 11.518 33.037 8.657 1.00 97.94 ? ? ? ? ? ? 93 ILE P CG2 1 93
+ATOM 712 C CD1 . ILE A 1 93 ? 11.016 33.035 11.843 1.00 99.64 ? ? ? ? ? ? 93 ILE P CD1 1 93
+ATOM 713 P PG . GTP B 2 1 ? 0.140 -8.175 68.585 1.00 101.58 ? ? ? ? ? ? 8 GTP R PG 1 1
+ATOM 714 O O1G . GTP B 2 1 ? 0.190 -6.803 67.948 1.00 101.50 ? ? ? ? ? ? 8 GTP R O1G 1 1
+ATOM 715 O O2G . GTP B 2 1 ? 1.348 -8.374 69.479 1.00 101.57 ? ? ? ? ? ? 8 GTP R O2G 1 1
+ATOM 716 O O3G . GTP B 2 1 ? -1.133 -8.320 69.389 1.00 101.02 ? ? ? ? ? ? 8 GTP R O3G 1 1
+ATOM 717 O O3B . GTP B 2 1 ? 0.173 -9.259 67.393 1.00 99.61 ? ? ? ? ? ? 8 GTP R O3B 1 1
+ATOM 718 P PB . GTP B 2 1 ? -0.723 -10.597 67.460 1.00 98.43 ? ? ? ? ? ? 8 GTP R PB 1 1
+ATOM 719 O O1B . GTP B 2 1 ? -2.146 -10.275 67.056 1.00 97.77 ? ? ? ? ? ? 8 GTP R O1B 1 1
+ATOM 720 O O2B . GTP B 2 1 ? -0.672 -11.233 68.832 1.00 98.31 ? ? ? ? ? ? 8 GTP R O2B 1 1
+ATOM 721 O O3A . GTP B 2 1 ? -0.024 -11.546 66.359 1.00 94.67 ? ? ? ? ? ? 8 GTP R O3A 1 1
+ATOM 722 P PA . GTP B 2 1 ? 1.557 -11.859 66.400 1.00 90.76 ? ? ? ? ? ? 8 GTP R PA 1 1
+ATOM 723 O O1A . GTP B 2 1 ? 2.175 -11.300 67.662 1.00 90.52 ? ? ? ? ? ? 8 GTP R O1A 1 1
+ATOM 724 O O2A . GTP B 2 1 ? 2.255 -11.317 65.173 1.00 90.62 ? ? ? ? ? ? 8 GTP R O2A 1 1
+ATOM 725 O "O5'" . GTP B 2 1 ? 1.598 -13.469 66.440 1.00 86.77 ? ? ? ? ? ? 8 GTP R "O5'" 1 1
+ATOM 726 C "C5'" . GTP B 2 1 ? 1.644 -14.206 65.241 1.00 80.20 ? ? ? ? ? ? 8 GTP R "C5'" 1 1
+ATOM 727 C "C4'" . GTP B 2 1 ? 0.775 -15.458 65.309 1.00 75.66 ? ? ? ? ? ? 8 GTP R "C4'" 1 1
+ATOM 728 O "O4'" . GTP B 2 1 ? -0.224 -15.412 66.315 1.00 73.25 ? ? ? ? ? ? 8 GTP R "O4'" 1 1
+ATOM 729 C "C3'" . GTP B 2 1 ? 0.001 -15.623 64.018 1.00 73.91 ? ? ? ? ? ? 8 GTP R "C3'" 1 1
+ATOM 730 O "O3'" . GTP B 2 1 ? 0.769 -16.223 63.006 1.00 72.21 ? ? ? ? ? ? 8 GTP R "O3'" 1 1
+ATOM 731 C "C2'" . GTP B 2 1 ? -1.219 -16.416 64.424 1.00 72.23 ? ? ? ? ? ? 8 GTP R "C2'" 1 1
+ATOM 732 O "O2'" . GTP B 2 1 ? -0.928 -17.795 64.430 1.00 72.32 ? ? ? ? ? ? 8 GTP R "O2'" 1 1
+ATOM 733 C "C1'" . GTP B 2 1 ? -1.470 -15.916 65.840 1.00 69.93 ? ? ? ? ? ? 8 GTP R "C1'" 1 1
+ATOM 734 N N9 . GTP B 2 1 ? -2.500 -14.842 65.861 1.00 65.33 ? ? ? ? ? ? 8 GTP R N9 1 1
+ATOM 735 C C8 . GTP B 2 1 ? -2.371 -13.634 66.502 1.00 64.07 ? ? ? ? ? ? 8 GTP R C8 1 1
+ATOM 736 N N7 . GTP B 2 1 ? -3.492 -12.901 66.320 1.00 60.73 ? ? ? ? ? ? 8 GTP R N7 1 1
+ATOM 737 C C5 . GTP B 2 1 ? -4.351 -13.619 65.569 1.00 59.04 ? ? ? ? ? ? 8 GTP R C5 1 1
+ATOM 738 C C6 . GTP B 2 1 ? -5.628 -13.335 65.099 1.00 56.79 ? ? ? ? ? ? 8 GTP R C6 1 1
+ATOM 739 O O6 . GTP B 2 1 ? -6.156 -12.258 65.364 1.00 55.11 ? ? ? ? ? ? 8 GTP R O6 1 1
+ATOM 740 N N1 . GTP B 2 1 ? -6.300 -14.269 64.337 1.00 55.42 ? ? ? ? ? ? 8 GTP R N1 1 1
+ATOM 741 C C2 . GTP B 2 1 ? -5.696 -15.476 64.046 1.00 56.18 ? ? ? ? ? ? 8 GTP R C2 1 1
+ATOM 742 N N2 . GTP B 2 1 ? -6.339 -16.375 63.311 1.00 54.79 ? ? ? ? ? ? 8 GTP R N2 1 1
+ATOM 743 N N3 . GTP B 2 1 ? -4.423 -15.752 64.517 1.00 58.75 ? ? ? ? ? ? 8 GTP R N3 1 1
+ATOM 744 C C4 . GTP B 2 1 ? -3.751 -14.841 65.272 1.00 61.17 ? ? ? ? ? ? 8 GTP R C4 1 1
+ATOM 745 P P . G B 2 2 ? 1.092 -15.405 61.669 1.00 71.32 ? ? ? ? ? ? 9 G R P 1 2
+ATOM 746 O OP1 . G B 2 2 ? 2.304 -16.004 61.050 1.00 71.77 ? ? ? ? ? ? 9 G R OP1 1 2
+ATOM 747 O OP2 . G B 2 2 ? 1.080 -13.952 62.005 1.00 70.00 ? ? ? ? ? ? 9 G R OP2 1 2
+ATOM 748 O "O5'" . G B 2 2 ? -0.185 -15.699 60.753 1.00 68.84 ? ? ? ? ? ? 9 G R "O5'" 1 2
+ATOM 749 C "C5'" . G B 2 2 ? -0.533 -17.036 60.402 1.00 66.18 ? ? ? ? ? ? 9 G R "C5'" 1 2
+ATOM 750 C "C4'" . G B 2 2 ? -1.948 -17.101 59.859 1.00 63.74 ? ? ? ? ? ? 9 G R "C4'" 1 2
+ATOM 751 O "O4'" . G B 2 2 ? -2.894 -16.771 60.907 1.00 62.47 ? ? ? ? ? ? 9 G R "O4'" 1 2
+ATOM 752 C "C3'" . G B 2 2 ? -2.285 -16.078 58.784 1.00 62.80 ? ? ? ? ? ? 9 G R "C3'" 1 2
+ATOM 753 O "O3'" . G B 2 2 ? -1.756 -16.429 57.509 1.00 61.79 ? ? ? ? ? ? 9 G R "O3'" 1 2
+ATOM 754 C "C2'" . G B 2 2 ? -3.807 -16.126 58.818 1.00 61.27 ? ? ? ? ? ? 9 G R "C2'" 1 2
+ATOM 755 O "O2'" . G B 2 2 ? -4.345 -17.255 58.154 1.00 62.11 ? ? ? ? ? ? 9 G R "O2'" 1 2
+ATOM 756 C "C1'" . G B 2 2 ? -4.058 -16.199 60.324 1.00 59.67 ? ? ? ? ? ? 9 G R "C1'" 1 2
+ATOM 757 N N9 . G B 2 2 ? -4.368 -14.890 60.915 1.00 55.85 ? ? ? ? ? ? 9 G R N9 1 2
+ATOM 758 C C8 . G B 2 2 ? -3.600 -14.131 61.770 1.00 54.67 ? ? ? ? ? ? 9 G R C8 1 2
+ATOM 759 N N7 . G B 2 2 ? -4.161 -13.003 62.124 1.00 52.55 ? ? ? ? ? ? 9 G R N7 1 2
+ATOM 760 C C5 . G B 2 2 ? -5.381 -13.006 61.462 1.00 52.49 ? ? ? ? ? ? 9 G R C5 1 2
+ATOM 761 C C6 . G B 2 2 ? -6.431 -12.048 61.449 1.00 52.41 ? ? ? ? ? ? 9 G R C6 1 2
+ATOM 762 O O6 . G B 2 2 ? -6.502 -10.961 62.040 1.00 52.44 ? ? ? ? ? ? 9 G R O6 1 2
+ATOM 763 N N1 . G B 2 2 ? -7.495 -12.447 60.641 1.00 53.56 ? ? ? ? ? ? 9 G R N1 1 2
+ATOM 764 C C2 . G B 2 2 ? -7.543 -13.626 59.928 1.00 53.90 ? ? ? ? ? ? 9 G R C2 1 2
+ATOM 765 N N2 . G B 2 2 ? -8.649 -13.846 59.200 1.00 54.28 ? ? ? ? ? ? 9 G R N2 1 2
+ATOM 766 N N3 . G B 2 2 ? -6.570 -14.531 59.932 1.00 53.24 ? ? ? ? ? ? 9 G R N3 1 2
+ATOM 767 C C4 . G B 2 2 ? -5.522 -14.160 60.716 1.00 54.04 ? ? ? ? ? ? 9 G R C4 1 2
+ATOM 768 P P . U B 2 3 ? -1.279 -15.272 56.506 1.00 62.06 ? ? ? ? ? ? 10 U R P 1 3
+ATOM 769 O OP1 . U B 2 3 ? -0.780 -15.928 55.276 1.00 62.31 ? ? ? ? ? ? 10 U R OP1 1 3
+ATOM 770 O OP2 . U B 2 3 ? -0.389 -14.352 57.253 1.00 60.55 ? ? ? ? ? ? 10 U R OP2 1 3
+ATOM 771 O "O5'" . U B 2 3 ? -2.635 -14.489 56.154 1.00 59.94 ? ? ? ? ? ? 10 U R "O5'" 1 3
+ATOM 772 C "C5'" . U B 2 3 ? -3.637 -15.118 55.355 1.00 57.27 ? ? ? ? ? ? 10 U R "C5'" 1 3
+ATOM 773 C "C4'" . U B 2 3 ? -4.939 -14.343 55.380 1.00 56.27 ? ? ? ? ? ? 10 U R "C4'" 1 3
+ATOM 774 O "O4'" . U B 2 3 ? -5.333 -14.033 56.736 1.00 55.10 ? ? ? ? ? ? 10 U R "O4'" 1 3
+ATOM 775 C "C3'" . U B 2 3 ? -4.857 -12.979 54.725 1.00 57.13 ? ? ? ? ? ? 10 U R "C3'" 1 3
+ATOM 776 O "O3'" . U B 2 3 ? -4.968 -13.123 53.326 1.00 59.57 ? ? ? ? ? ? 10 U R "O3'" 1 3
+ATOM 777 C "C2'" . U B 2 3 ? -6.042 -12.242 55.344 1.00 55.44 ? ? ? ? ? ? 10 U R "C2'" 1 3
+ATOM 778 O "O2'" . U B 2 3 ? -7.281 -12.463 54.696 1.00 53.73 ? ? ? ? ? ? 10 U R "O2'" 1 3
+ATOM 779 C "C1'" . U B 2 3 ? -6.059 -12.812 56.759 1.00 53.94 ? ? ? ? ? ? 10 U R "C1'" 1 3
+ATOM 780 N N1 . U B 2 3 ? -5.456 -11.869 57.759 1.00 52.28 ? ? ? ? ? ? 10 U R N1 1 3
+ATOM 781 C C2 . U B 2 3 ? -6.149 -10.727 58.134 1.00 52.45 ? ? ? ? ? ? 10 U R C2 1 3
+ATOM 782 O O2 . U B 2 3 ? -7.251 -10.412 57.707 1.00 52.60 ? ? ? ? ? ? 10 U R O2 1 3
+ATOM 783 N N3 . U B 2 3 ? -5.493 -9.942 59.053 1.00 53.37 ? ? ? ? ? ? 10 U R N3 1 3
+ATOM 784 C C4 . U B 2 3 ? -4.249 -10.164 59.625 1.00 52.82 ? ? ? ? ? ? 10 U R C4 1 3
+ATOM 785 O O4 . U B 2 3 ? -3.807 -9.356 60.435 1.00 53.67 ? ? ? ? ? ? 10 U R O4 1 3
+ATOM 786 C C5 . U B 2 3 ? -3.584 -11.365 59.185 1.00 52.33 ? ? ? ? ? ? 10 U R C5 1 3
+ATOM 787 C C6 . U B 2 3 ? -4.203 -12.150 58.290 1.00 52.89 ? ? ? ? ? ? 10 U R C6 1 3
+ATOM 788 P P . C B 2 4 ? -4.133 -12.159 52.363 1.00 60.71 ? ? ? ? ? ? 11 C R P 1 4
+ATOM 789 O OP1 . C B 2 4 ? -4.286 -12.712 50.998 1.00 62.71 ? ? ? ? ? ? 11 C R OP1 1 4
+ATOM 790 O OP2 . C B 2 4 ? -2.776 -11.967 52.927 1.00 60.68 ? ? ? ? ? ? 11 C R OP2 1 4
+ATOM 791 O "O5'" . C B 2 4 ? -4.924 -10.770 52.473 1.00 60.32 ? ? ? ? ? ? 11 C R "O5'" 1 4
+ATOM 792 C "C5'" . C B 2 4 ? -6.256 -10.666 51.967 1.00 61.90 ? ? ? ? ? ? 11 C R "C5'" 1 4
+ATOM 793 C "C4'" . C B 2 4 ? -6.934 -9.390 52.428 1.00 62.56 ? ? ? ? ? ? 11 C R "C4'" 1 4
+ATOM 794 O "O4'" . C B 2 4 ? -7.099 -9.397 53.869 1.00 63.94 ? ? ? ? ? ? 11 C R "O4'" 1 4
+ATOM 795 C "C3'" . C B 2 4 ? -6.141 -8.119 52.178 1.00 63.04 ? ? ? ? ? ? 11 C R "C3'" 1 4
+ATOM 796 O "O3'" . C B 2 4 ? -6.256 -7.704 50.829 1.00 63.93 ? ? ? ? ? ? 11 C R "O3'" 1 4
+ATOM 797 C "C2'" . C B 2 4 ? -6.797 -7.155 53.162 1.00 62.84 ? ? ? ? ? ? 11 C R "C2'" 1 4
+ATOM 798 O "O2'" . C B 2 4 ? -8.042 -6.646 52.723 1.00 63.83 ? ? ? ? ? ? 11 C R "O2'" 1 4
+ATOM 799 C "C1'" . C B 2 4 ? -6.997 -8.068 54.368 1.00 62.60 ? ? ? ? ? ? 11 C R "C1'" 1 4
+ATOM 800 N N1 . C B 2 4 ? -5.895 -7.954 55.398 1.00 60.84 ? ? ? ? ? ? 11 C R N1 1 4
+ATOM 801 C C2 . C B 2 4 ? -5.949 -6.942 56.380 1.00 60.62 ? ? ? ? ? ? 11 C R C2 1 4
+ATOM 802 O O2 . C B 2 4 ? -6.898 -6.143 56.400 1.00 59.51 ? ? ? ? ? ? 11 C R O2 1 4
+ATOM 803 N N3 . C B 2 4 ? -4.944 -6.861 57.296 1.00 59.87 ? ? ? ? ? ? 11 C R N3 1 4
+ATOM 804 C C4 . C B 2 4 ? -3.924 -7.728 57.258 1.00 59.87 ? ? ? ? ? ? 11 C R C4 1 4
+ATOM 805 N N4 . C B 2 4 ? -2.961 -7.608 58.177 1.00 59.50 ? ? ? ? ? ? 11 C R N4 1 4
+ATOM 806 C C5 . C B 2 4 ? -3.846 -8.758 56.273 1.00 60.06 ? ? ? ? ? ? 11 C R C5 1 4
+ATOM 807 C C6 . C B 2 4 ? -4.840 -8.831 55.377 1.00 59.96 ? ? ? ? ? ? 11 C R C6 1 4
+ATOM 808 P P . A B 2 5 ? -5.012 -7.004 50.105 1.00 64.89 ? ? ? ? ? ? 12 A R P 1 5
+ATOM 809 O OP1 . A B 2 5 ? -5.176 -7.271 48.659 1.00 65.68 ? ? ? ? ? ? 12 A R OP1 1 5
+ATOM 810 O OP2 . A B 2 5 ? -3.751 -7.410 50.776 1.00 63.68 ? ? ? ? ? ? 12 A R OP2 1 5
+ATOM 811 O "O5'" . A B 2 5 ? -5.276 -5.446 50.393 1.00 63.76 ? ? ? ? ? ? 12 A R "O5'" 1 5
+ATOM 812 C "C5'" . A B 2 5 ? -4.347 -4.657 51.146 1.00 62.34 ? ? ? ? ? ? 12 A R "C5'" 1 5
+ATOM 813 C "C4'" . A B 2 5 ? -5.064 -3.579 51.943 1.00 61.88 ? ? ? ? ? ? 12 A R "C4'" 1 5
+ATOM 814 O "O4'" . A B 2 5 ? -5.574 -4.128 53.190 1.00 60.71 ? ? ? ? ? ? 12 A R "O4'" 1 5
+ATOM 815 C "C3'" . A B 2 5 ? -4.192 -2.402 52.357 1.00 61.61 ? ? ? ? ? ? 12 A R "C3'" 1 5
+ATOM 816 O "O3'" . A B 2 5 ? -4.270 -1.384 51.377 1.00 63.11 ? ? ? ? ? ? 12 A R "O3'" 1 5
+ATOM 817 C "C2'" . A B 2 5 ? -4.844 -1.962 53.664 1.00 61.04 ? ? ? ? ? ? 12 A R "C2'" 1 5
+ATOM 818 O "O2'" . A B 2 5 ? -6.018 -1.200 53.455 1.00 62.36 ? ? ? ? ? ? 12 A R "O2'" 1 5
+ATOM 819 C "C1'" . A B 2 5 ? -5.202 -3.306 54.285 1.00 58.98 ? ? ? ? ? ? 12 A R "C1'" 1 5
+ATOM 820 N N9 . A B 2 5 ? -4.097 -3.929 55.022 1.00 56.09 ? ? ? ? ? ? 12 A R N9 1 5
+ATOM 821 C C8 . A B 2 5 ? -3.455 -5.097 54.707 1.00 54.04 ? ? ? ? ? ? 12 A R C8 1 5
+ATOM 822 N N7 . A B 2 5 ? -2.496 -5.424 55.538 1.00 53.37 ? ? ? ? ? ? 12 A R N7 1 5
+ATOM 823 C C5 . A B 2 5 ? -2.501 -4.402 56.470 1.00 52.28 ? ? ? ? ? ? 12 A R C5 1 5
+ATOM 824 C C6 . A B 2 5 ? -1.714 -4.160 57.618 1.00 50.30 ? ? ? ? ? ? 12 A R C6 1 5
+ATOM 825 N N6 . A B 2 5 ? -0.736 -4.976 58.021 1.00 49.01 ? ? ? ? ? ? 12 A R N6 1 5
+ATOM 826 N N1 . A B 2 5 ? -1.971 -3.044 58.336 1.00 50.10 ? ? ? ? ? ? 12 A R N1 1 5
+ATOM 827 C C2 . A B 2 5 ? -2.952 -2.224 57.931 1.00 51.14 ? ? ? ? ? ? 12 A R C2 1 5
+ATOM 828 N N3 . A B 2 5 ? -3.758 -2.348 56.870 1.00 53.09 ? ? ? ? ? ? 12 A R N3 1 5
+ATOM 829 C C4 . A B 2 5 ? -3.482 -3.469 56.171 1.00 54.10 ? ? ? ? ? ? 12 A R C4 1 5
+ATOM 830 P P . C B 2 6 ? -2.972 -0.548 50.953 1.00 64.68 ? ? ? ? ? ? 13 C R P 1 6
+ATOM 831 O OP1 . C B 2 6 ? -3.427 0.475 49.985 1.00 65.38 ? ? ? ? ? ? 13 C R OP1 1 6
+ATOM 832 O OP2 . C B 2 6 ? -1.909 -1.502 50.562 1.00 64.52 ? ? ? ? ? ? 13 C R OP2 1 6
+ATOM 833 O "O5'" . C B 2 6 ? -2.505 0.167 52.307 1.00 62.85 ? ? ? ? ? ? 13 C R "O5'" 1 6
+ATOM 834 C "C5'" . C B 2 6 ? -3.252 1.244 52.868 1.00 61.05 ? ? ? ? ? ? 13 C R "C5'" 1 6
+ATOM 835 C "C4'" . C B 2 6 ? -2.678 1.621 54.220 1.00 60.77 ? ? ? ? ? ? 13 C R "C4'" 1 6
+ATOM 836 O "O4'" . C B 2 6 ? -2.723 0.482 55.116 1.00 59.20 ? ? ? ? ? ? 13 C R "O4'" 1 6
+ATOM 837 C "C3'" . C B 2 6 ? -1.206 1.997 54.193 1.00 60.65 ? ? ? ? ? ? 13 C R "C3'" 1 6
+ATOM 838 O "O3'" . C B 2 6 ? -1.059 3.351 53.815 1.00 62.13 ? ? ? ? ? ? 13 C R "O3'" 1 6
+ATOM 839 C "C2'" . C B 2 6 ? -0.783 1.746 55.636 1.00 59.30 ? ? ? ? ? ? 13 C R "C2'" 1 6
+ATOM 840 O "O2'" . C B 2 6 ? -1.145 2.793 56.518 1.00 60.09 ? ? ? ? ? ? 13 C R "O2'" 1 6
+ATOM 841 C "C1'" . C B 2 6 ? -1.582 0.489 55.959 1.00 56.30 ? ? ? ? ? ? 13 C R "C1'" 1 6
+ATOM 842 N N1 . C B 2 6 ? -0.809 -0.774 55.761 1.00 53.47 ? ? ? ? ? ? 13 C R N1 1 6
+ATOM 843 C C2 . C B 2 6 ? 0.156 -1.167 56.708 1.00 52.41 ? ? ? ? ? ? 13 C R C2 1 6
+ATOM 844 O O2 . C B 2 6 ? 0.369 -0.463 57.704 1.00 52.00 ? ? ? ? ? ? 13 C R O2 1 6
+ATOM 845 N N3 . C B 2 6 ? 0.839 -2.327 56.501 1.00 50.59 ? ? ? ? ? ? 13 C R N3 1 6
+ATOM 846 C C4 . C B 2 6 ? 0.591 -3.069 55.414 1.00 49.69 ? ? ? ? ? ? 13 C R C4 1 6
+ATOM 847 N N4 . C B 2 6 ? 1.286 -4.194 55.256 1.00 48.88 ? ? ? ? ? ? 13 C R N4 1 6
+ATOM 848 C C5 . C B 2 6 ? -0.382 -2.695 54.439 1.00 50.63 ? ? ? ? ? ? 13 C R C5 1 6
+ATOM 849 C C6 . C B 2 6 ? -1.048 -1.553 54.655 1.00 53.49 ? ? ? ? ? ? 13 C R C6 1 6
+ATOM 850 P P . G B 2 7 ? 0.258 3.812 53.042 1.00 63.38 ? ? ? ? ? ? 14 G R P 1 7
+ATOM 851 O OP1 . G B 2 7 ? -0.023 5.157 52.492 1.00 64.31 ? ? ? ? ? ? 14 G R OP1 1 7
+ATOM 852 O OP2 . G B 2 7 ? 0.701 2.724 52.141 1.00 63.46 ? ? ? ? ? ? 14 G R OP2 1 7
+ATOM 853 O "O5'" . G B 2 7 ? 1.338 3.926 54.216 1.00 63.49 ? ? ? ? ? ? 14 G R "O5'" 1 7
+ATOM 854 C "C5'" . G B 2 7 ? 1.260 4.992 55.158 1.00 64.52 ? ? ? ? ? ? 14 G R "C5'" 1 7
+ATOM 855 C "C4'" . G B 2 7 ? 2.336 4.838 56.216 1.00 64.74 ? ? ? ? ? ? 14 G R "C4'" 1 7
+ATOM 856 O "O4'" . G B 2 7 ? 2.379 3.456 56.656 1.00 63.78 ? ? ? ? ? ? 14 G R "O4'" 1 7
+ATOM 857 C "C3'" . G B 2 7 ? 3.749 5.197 55.766 1.00 66.62 ? ? ? ? ? ? 14 G R "C3'" 1 7
+ATOM 858 O "O3'" . G B 2 7 ? 4.409 5.948 56.790 1.00 71.46 ? ? ? ? ? ? 14 G R "O3'" 1 7
+ATOM 859 C "C2'" . G B 2 7 ? 4.413 3.839 55.521 1.00 64.82 ? ? ? ? ? ? 14 G R "C2'" 1 7
+ATOM 860 O "O2'" . G B 2 7 ? 5.802 3.826 55.801 1.00 67.05 ? ? ? ? ? ? 14 G R "O2'" 1 7
+ATOM 861 C "C1'" . G B 2 7 ? 3.678 2.922 56.495 1.00 61.77 ? ? ? ? ? ? 14 G R "C1'" 1 7
+ATOM 862 N N9 . G B 2 7 ? 3.560 1.545 56.015 1.00 57.07 ? ? ? ? ? ? 14 G R N9 1 7
+ATOM 863 C C8 . G B 2 7 ? 2.768 1.094 54.984 1.00 55.11 ? ? ? ? ? ? 14 G R C8 1 7
+ATOM 864 N N7 . G B 2 7 ? 2.865 -0.189 54.772 1.00 52.35 ? ? ? ? ? ? 14 G R N7 1 7
+ATOM 865 C C5 . G B 2 7 ? 3.779 -0.619 55.723 1.00 51.71 ? ? ? ? ? ? 14 G R C5 1 7
+ATOM 866 C C6 . G B 2 7 ? 4.283 -1.916 55.982 1.00 50.53 ? ? ? ? ? ? 14 G R C6 1 7
+ATOM 867 O O6 . G B 2 7 ? 4.013 -2.973 55.404 1.00 50.94 ? ? ? ? ? ? 14 G R O6 1 7
+ATOM 868 N N1 . G B 2 7 ? 5.193 -1.930 57.035 1.00 50.87 ? ? ? ? ? ? 14 G R N1 1 7
+ATOM 869 C C2 . G B 2 7 ? 5.571 -0.824 57.756 1.00 51.10 ? ? ? ? ? ? 14 G R C2 1 7
+ATOM 870 N N2 . G B 2 7 ? 6.463 -1.038 58.734 1.00 50.12 ? ? ? ? ? ? 14 G R N2 1 7
+ATOM 871 N N3 . G B 2 7 ? 5.107 0.401 57.523 1.00 52.48 ? ? ? ? ? ? 14 G R N3 1 7
+ATOM 872 C C4 . G B 2 7 ? 4.218 0.433 56.497 1.00 53.49 ? ? ? ? ? ? 14 G R C4 1 7
+ATOM 873 P P . C B 2 8 ? 4.504 7.550 56.750 1.00 74.77 ? ? ? ? ? ? 15 C R P 1 8
+ATOM 874 O OP1 . C B 2 8 ? 3.298 8.092 57.417 1.00 72.78 ? ? ? ? ? ? 15 C R OP1 1 8
+ATOM 875 O OP2 . C B 2 8 ? 4.830 7.991 55.373 1.00 74.51 ? ? ? ? ? ? 15 C R OP2 1 8
+ATOM 876 O "O5'" . C B 2 8 ? 5.802 7.805 57.658 1.00 75.53 ? ? ? ? ? ? 15 C R "O5'" 1 8
+ATOM 877 C "C5'" . C B 2 8 ? 5.926 8.978 58.464 1.00 78.77 ? ? ? ? ? ? 15 C R "C5'" 1 8
+ATOM 878 C "C4'" . C B 2 8 ? 6.004 8.652 59.950 1.00 80.45 ? ? ? ? ? ? 15 C R "C4'" 1 8
+ATOM 879 O "O4'" . C B 2 8 ? 4.666 8.490 60.476 1.00 81.15 ? ? ? ? ? ? 15 C R "O4'" 1 8
+ATOM 880 C "C3'" . C B 2 8 ? 6.740 7.368 60.316 1.00 81.19 ? ? ? ? ? ? 15 C R "C3'" 1 8
+ATOM 881 O "O3'" . C B 2 8 ? 8.103 7.650 60.564 1.00 81.63 ? ? ? ? ? ? 15 C R "O3'" 1 8
+ATOM 882 C "C2'" . C B 2 8 ? 6.059 6.904 61.598 1.00 81.69 ? ? ? ? ? ? 15 C R "C2'" 1 8
+ATOM 883 O "O2'" . C B 2 8 ? 6.754 7.330 62.754 1.00 81.39 ? ? ? ? ? ? 15 C R "O2'" 1 8
+ATOM 884 C "C1'" . C B 2 8 ? 4.671 7.545 61.529 1.00 82.56 ? ? ? ? ? ? 15 C R "C1'" 1 8
+ATOM 885 N N1 . C B 2 8 ? 3.565 6.550 61.303 1.00 84.70 ? ? ? ? ? ? 15 C R N1 1 8
+ATOM 886 C C2 . C B 2 8 ? 2.796 6.086 62.390 1.00 85.70 ? ? ? ? ? ? 15 C R C2 1 8
+ATOM 887 O O2 . C B 2 8 ? 3.027 6.496 63.536 1.00 85.87 ? ? ? ? ? ? 15 C R O2 1 8
+ATOM 888 N N3 . C B 2 8 ? 1.804 5.183 62.153 1.00 85.99 ? ? ? ? ? ? 15 C R N3 1 8
+ATOM 889 C C4 . C B 2 8 ? 1.568 4.750 60.910 1.00 85.66 ? ? ? ? ? ? 15 C R C4 1 8
+ATOM 890 N N4 . C B 2 8 ? 0.586 3.866 60.725 1.00 85.80 ? ? ? ? ? ? 15 C R N4 1 8
+ATOM 891 C C5 . C B 2 8 ? 2.332 5.208 59.795 1.00 85.77 ? ? ? ? ? ? 15 C R C5 1 8
+ATOM 892 C C6 . C B 2 8 ? 3.308 6.094 60.036 1.00 85.16 ? ? ? ? ? ? 15 C R C6 1 8
+ATOM 893 P P . A B 2 9 ? 9.197 7.523 59.408 1.00 81.98 ? ? ? ? ? ? 16 A R P 1 9
+ATOM 894 O OP1 . A B 2 9 ? 9.696 8.891 59.140 1.00 82.37 ? ? ? ? ? ? 16 A R OP1 1 9
+ATOM 895 O OP2 . A B 2 9 ? 8.630 6.726 58.298 1.00 82.89 ? ? ? ? ? ? 16 A R OP2 1 9
+ATOM 896 O "O5'" . A B 2 9 ? 10.350 6.664 60.115 1.00 83.24 ? ? ? ? ? ? 16 A R "O5'" 1 9
+ATOM 897 C "C5'" . A B 2 9 ? 10.122 5.307 60.481 1.00 86.50 ? ? ? ? ? ? 16 A R "C5'" 1 9
+ATOM 898 C "C4'" . A B 2 9 ? 10.025 5.146 61.988 1.00 89.36 ? ? ? ? ? ? 16 A R "C4'" 1 9
+ATOM 899 O "O4'" . A B 2 9 ? 8.672 4.755 62.345 1.00 90.33 ? ? ? ? ? ? 16 A R "O4'" 1 9
+ATOM 900 C "C3'" . A B 2 9 ? 10.926 4.065 62.574 1.00 90.38 ? ? ? ? ? ? 16 A R "C3'" 1 9
+ATOM 901 O "O3'" . A B 2 9 ? 12.203 4.596 62.932 1.00 91.82 ? ? ? ? ? ? 16 A R "O3'" 1 9
+ATOM 902 C "C2'" . A B 2 9 ? 10.139 3.609 63.800 1.00 91.00 ? ? ? ? ? ? 16 A R "C2'" 1 9
+ATOM 903 O "O2'" . A B 2 9 ? 10.348 4.429 64.935 1.00 91.41 ? ? ? ? ? ? 16 A R "O2'" 1 9
+ATOM 904 C "C1'" . A B 2 9 ? 8.696 3.719 63.315 1.00 91.59 ? ? ? ? ? ? 16 A R "C1'" 1 9
+ATOM 905 N N9 . A B 2 9 ? 8.165 2.471 62.747 1.00 92.84 ? ? ? ? ? ? 16 A R N9 1 9
+ATOM 906 C C8 . A B 2 9 ? 7.752 2.263 61.458 1.00 93.05 ? ? ? ? ? ? 16 A R C8 1 9
+ATOM 907 N N7 . A B 2 9 ? 7.322 1.047 61.220 1.00 92.93 ? ? ? ? ? ? 16 A R N7 1 9
+ATOM 908 C C5 . A B 2 9 ? 7.459 0.403 62.436 1.00 93.48 ? ? ? ? ? ? 16 A R C5 1 9
+ATOM 909 C C6 . A B 2 9 ? 7.176 -0.918 62.853 1.00 93.99 ? ? ? ? ? ? 16 A R C6 1 9
+ATOM 910 N N6 . A B 2 9 ? 6.673 -1.849 62.038 1.00 94.91 ? ? ? ? ? ? 16 A R N6 1 9
+ATOM 911 N N1 . A B 2 9 ? 7.429 -1.249 64.140 1.00 94.14 ? ? ? ? ? ? 16 A R N1 1 9
+ATOM 912 C C2 . A B 2 9 ? 7.932 -0.314 64.958 1.00 94.09 ? ? ? ? ? ? 16 A R C2 1 9
+ATOM 913 N N3 . A B 2 9 ? 8.239 0.956 64.679 1.00 94.11 ? ? ? ? ? ? 16 A R N3 1 9
+ATOM 914 C C4 . A B 2 9 ? 7.977 1.262 63.391 1.00 93.52 ? ? ? ? ? ? 16 A R C4 1 9
+ATOM 915 P P . C B 2 10 ? 13.534 3.706 62.814 1.00 93.25 ? ? ? ? ? ? 17 C R P 1 10
+ATOM 916 O OP1 . C B 2 10 ? 14.662 4.503 63.349 1.00 93.31 ? ? ? ? ? ? 17 C R OP1 1 10
+ATOM 917 O OP2 . C B 2 10 ? 13.610 3.188 61.430 1.00 92.50 ? ? ? ? ? ? 17 C R OP2 1 10
+ATOM 918 O "O5'" . C B 2 10 ? 13.259 2.455 63.783 1.00 95.03 ? ? ? ? ? ? 17 C R "O5'" 1 10
+ATOM 919 C "C5'" . C B 2 10 ? 13.312 2.558 65.212 1.00 97.15 ? ? ? ? ? ? 17 C R "C5'" 1 10
+ATOM 920 C "C4'" . C B 2 10 ? 12.938 1.241 65.875 1.00 98.38 ? ? ? ? ? ? 17 C R "C4'" 1 10
+ATOM 921 O "O4'" . C B 2 10 ? 11.607 0.833 65.468 1.00 98.65 ? ? ? ? ? ? 17 C R "O4'" 1 10
+ATOM 922 C "C3'" . C B 2 10 ? 13.838 0.074 65.499 1.00 99.25 ? ? ? ? ? ? 17 C R "C3'" 1 10
+ATOM 923 O "O3'" . C B 2 10 ? 14.931 0.008 66.393 1.00 100.43 ? ? ? ? ? ? 17 C R "O3'" 1 10
+ATOM 924 C "C2'" . C B 2 10 ? 12.934 -1.150 65.613 1.00 99.34 ? ? ? ? ? ? 17 C R "C2'" 1 10
+ATOM 925 O "O2'" . C B 2 10 ? 12.943 -1.730 66.903 1.00 98.94 ? ? ? ? ? ? 17 C R "O2'" 1 10
+ATOM 926 C "C1'" . C B 2 10 ? 11.557 -0.573 65.277 1.00 99.35 ? ? ? ? ? ? 17 C R "C1'" 1 10
+ATOM 927 N N1 . C B 2 10 ? 11.109 -0.885 63.870 1.00 99.84 ? ? ? ? ? ? 17 C R N1 1 10
+ATOM 928 C C2 . C B 2 10 ? 10.585 -2.154 63.548 1.00 99.68 ? ? ? ? ? ? 17 C R C2 1 10
+ATOM 929 O O2 . C B 2 10 ? 10.480 -3.031 64.414 1.00 99.42 ? ? ? ? ? ? 17 C R O2 1 10
+ATOM 930 N N3 . C B 2 10 ? 10.195 -2.398 62.269 1.00 100.14 ? ? ? ? ? ? 17 C R N3 1 10
+ATOM 931 C C4 . C B 2 10 ? 10.309 -1.449 61.335 1.00 100.55 ? ? ? ? ? ? 17 C R C4 1 10
+ATOM 932 N N4 . C B 2 10 ? 9.910 -1.742 60.093 1.00 101.27 ? ? ? ? ? ? 17 C R N4 1 10
+ATOM 933 C C5 . C B 2 10 ? 10.838 -0.158 61.636 1.00 100.21 ? ? ? ? ? ? 17 C R C5 1 10
+ATOM 934 C C6 . C B 2 10 ? 11.220 0.073 62.897 1.00 99.81 ? ? ? ? ? ? 17 C R C6 1 10
+ATOM 935 P P . A B 2 11 ? 16.406 -0.067 65.791 1.00 101.72 ? ? ? ? ? ? 18 A R P 1 11
+ATOM 936 O OP1 . A B 2 11 ? 17.355 0.159 66.908 1.00 101.76 ? ? ? ? ? ? 18 A R OP1 1 11
+ATOM 937 O OP2 . A B 2 11 ? 16.456 0.812 64.600 1.00 101.60 ? ? ? ? ? ? 18 A R OP2 1 11
+ATOM 938 O "O5'" . A B 2 11 ? 16.506 -1.585 65.289 1.00 101.21 ? ? ? ? ? ? 18 A R "O5'" 1 11
+ATOM 939 C "C5'" . A B 2 11 ? 16.893 -2.607 66.200 1.00 101.02 ? ? ? ? ? ? 18 A R "C5'" 1 11
+ATOM 940 C "C4'" . A B 2 11 ? 16.603 -3.987 65.646 1.00 100.63 ? ? ? ? ? ? 18 A R "C4'" 1 11
+ATOM 941 O "O4'" . A B 2 11 ? 15.218 -4.088 65.235 1.00 101.37 ? ? ? ? ? ? 18 A R "O4'" 1 11
+ATOM 942 C "C3'" . A B 2 11 ? 17.367 -4.358 64.387 1.00 100.17 ? ? ? ? ? ? 18 A R "C3'" 1 11
+ATOM 943 O "O3'" . A B 2 11 ? 18.709 -4.721 64.689 1.00 98.50 ? ? ? ? ? ? 18 A R "O3'" 1 11
+ATOM 944 C "C2'" . A B 2 11 ? 16.532 -5.530 63.879 1.00 100.89 ? ? ? ? ? ? 18 A R "C2'" 1 11
+ATOM 945 O "O2'" . A B 2 11 ? 16.819 -6.758 64.523 1.00 99.68 ? ? ? ? ? ? 18 A R "O2'" 1 11
+ATOM 946 C "C1'" . A B 2 11 ? 15.116 -5.056 64.204 1.00 102.34 ? ? ? ? ? ? 18 A R "C1'" 1 11
+ATOM 947 N N9 . A B 2 11 ? 14.471 -4.455 63.038 1.00 104.57 ? ? ? ? ? ? 18 A R N9 1 11
+ATOM 948 C C8 . A B 2 11 ? 14.257 -3.123 62.812 1.00 105.36 ? ? ? ? ? ? 18 A R C8 1 11
+ATOM 949 N N7 . A B 2 11 ? 13.660 -2.866 61.673 1.00 105.81 ? ? ? ? ? ? 18 A R N7 1 11
+ATOM 950 C C5 . A B 2 11 ? 13.475 -4.116 61.108 1.00 105.43 ? ? ? ? ? ? 18 A R C5 1 11
+ATOM 951 C C6 . A B 2 11 ? 12.891 -4.532 59.893 1.00 105.84 ? ? ? ? ? ? 18 A R C6 1 11
+ATOM 952 N N6 . A B 2 11 ? 12.377 -3.674 59.005 1.00 105.59 ? ? ? ? ? ? 18 A R N6 1 11
+ATOM 953 N N1 . A B 2 11 ? 12.864 -5.859 59.623 1.00 106.12 ? ? ? ? ? ? 18 A R N1 1 11
+ATOM 954 C C2 . A B 2 11 ? 13.383 -6.714 60.519 1.00 105.77 ? ? ? ? ? ? 18 A R C2 1 11
+ATOM 955 N N3 . A B 2 11 ? 13.954 -6.438 61.694 1.00 105.31 ? ? ? ? ? ? 18 A R N3 1 11
+ATOM 956 C C4 . A B 2 11 ? 13.970 -5.112 61.933 1.00 105.07 ? ? ? ? ? ? 18 A R C4 1 11
+ATOM 957 P P . G B 2 12 ? 19.864 -4.498 63.600 1.00 96.97 ? ? ? ? ? ? 19 G R P 1 12
+ATOM 958 O OP1 . G B 2 12 ? 21.168 -4.712 64.267 1.00 97.32 ? ? ? ? ? ? 19 G R OP1 1 12
+ATOM 959 O OP2 . G B 2 12 ? 19.602 -3.219 62.899 1.00 97.07 ? ? ? ? ? ? 19 G R OP2 1 12
+ATOM 960 O "O5'" . G B 2 12 ? 19.612 -5.686 62.565 1.00 93.61 ? ? ? ? ? ? 19 G R "O5'" 1 12
+ATOM 961 C "C5'" . G B 2 12 ? 19.789 -7.031 62.976 1.00 91.14 ? ? ? ? ? ? 19 G R "C5'" 1 12
+ATOM 962 C "C4'" . G B 2 12 ? 19.351 -7.959 61.867 1.00 89.62 ? ? ? ? ? ? 19 G R "C4'" 1 12
+ATOM 963 O "O4'" . G B 2 12 ? 17.934 -7.764 61.633 1.00 89.19 ? ? ? ? ? ? 19 G R "O4'" 1 12
+ATOM 964 C "C3'" . G B 2 12 ? 19.970 -7.674 60.506 1.00 89.18 ? ? ? ? ? ? 19 G R "C3'" 1 12
+ATOM 965 O "O3'" . G B 2 12 ? 21.299 -8.187 60.375 1.00 87.87 ? ? ? ? ? ? 19 G R "O3'" 1 12
+ATOM 966 C "C2'" . G B 2 12 ? 18.951 -8.316 59.567 1.00 89.10 ? ? ? ? ? ? 19 G R "C2'" 1 12
+ATOM 967 O "O2'" . G B 2 12 ? 19.051 -9.727 59.492 1.00 89.19 ? ? ? ? ? ? 19 G R "O2'" 1 12
+ATOM 968 C "C1'" . G B 2 12 ? 17.652 -7.886 60.248 1.00 88.55 ? ? ? ? ? ? 19 G R "C1'" 1 12
+ATOM 969 N N9 . G B 2 12 ? 17.128 -6.614 59.739 1.00 87.43 ? ? ? ? ? ? 19 G R N9 1 12
+ATOM 970 C C8 . G B 2 12 ? 17.424 -5.346 60.187 1.00 87.12 ? ? ? ? ? ? 19 G R C8 1 12
+ATOM 971 N N7 . G B 2 12 ? 16.808 -4.400 59.536 1.00 86.74 ? ? ? ? ? ? 19 G R N7 1 12
+ATOM 972 C C5 . G B 2 12 ? 16.050 -5.080 58.591 1.00 86.12 ? ? ? ? ? ? 19 G R C5 1 12
+ATOM 973 C C6 . G B 2 12 ? 15.173 -4.584 57.592 1.00 85.60 ? ? ? ? ? ? 19 G R C6 1 12
+ATOM 974 O O6 . G B 2 12 ? 14.882 -3.405 57.346 1.00 85.10 ? ? ? ? ? ? 19 G R O6 1 12
+ATOM 975 N N1 . G B 2 12 ? 14.600 -5.609 56.838 1.00 85.56 ? ? ? ? ? ? 19 G R N1 1 12
+ATOM 976 C C2 . G B 2 12 ? 14.849 -6.951 57.023 1.00 85.36 ? ? ? ? ? ? 19 G R C2 1 12
+ATOM 977 N N2 . G B 2 12 ? 14.210 -7.797 56.202 1.00 84.65 ? ? ? ? ? ? 19 G R N2 1 12
+ATOM 978 N N3 . G B 2 12 ? 15.671 -7.427 57.953 1.00 85.52 ? ? ? ? ? ? 19 G R N3 1 12
+ATOM 979 C C4 . G B 2 12 ? 16.238 -6.442 58.700 1.00 86.32 ? ? ? ? ? ? 19 G R C4 1 12
+ATOM 980 P P . G B 2 13 ? 22.572 -7.212 60.503 1.00 87.08 ? ? ? ? ? ? 20 G R P 1 13
+ATOM 981 O OP1 . G B 2 13 ? 23.679 -8.042 61.028 1.00 87.37 ? ? ? ? ? ? 20 G R OP1 1 13
+ATOM 982 O OP2 . G B 2 13 ? 22.190 -5.964 61.211 1.00 86.12 ? ? ? ? ? ? 20 G R OP2 1 13
+ATOM 983 O "O5'" . G B 2 13 ? 22.918 -6.816 58.994 1.00 83.80 ? ? ? ? ? ? 20 G R "O5'" 1 13
+ATOM 984 C "C5'" . G B 2 13 ? 22.315 -5.683 58.380 1.00 79.73 ? ? ? ? ? ? 20 G R "C5'" 1 13
+ATOM 985 C "C4'" . G B 2 13 ? 21.161 -6.153 57.518 1.00 76.53 ? ? ? ? ? ? 20 G R "C4'" 1 13
+ATOM 986 O "O4'" . G B 2 13 ? 19.916 -5.538 57.930 1.00 76.27 ? ? ? ? ? ? 20 G R "O4'" 1 13
+ATOM 987 C "C3'" . G B 2 13 ? 21.263 -5.858 56.034 1.00 73.78 ? ? ? ? ? ? 20 G R "C3'" 1 13
+ATOM 988 O "O3'" . G B 2 13 ? 22.152 -6.799 55.427 1.00 69.26 ? ? ? ? ? ? 20 G R "O3'" 1 13
+ATOM 989 C "C2'" . G B 2 13 ? 19.803 -6.053 55.631 1.00 74.20 ? ? ? ? ? ? 20 G R "C2'" 1 13
+ATOM 990 O "O2'" . G B 2 13 ? 19.439 -7.416 55.520 1.00 73.18 ? ? ? ? ? ? 20 G R "O2'" 1 13
+ATOM 991 C "C1'" . G B 2 13 ? 19.071 -5.410 56.803 1.00 75.04 ? ? ? ? ? ? 20 G R "C1'" 1 13
+ATOM 992 N N9 . G B 2 13 ? 18.769 -3.992 56.609 1.00 75.64 ? ? ? ? ? ? 20 G R N9 1 13
+ATOM 993 C C8 . G B 2 13 ? 19.372 -2.929 57.241 1.00 76.41 ? ? ? ? ? ? 20 G R C8 1 13
+ATOM 994 N N7 . G B 2 13 ? 18.903 -1.768 56.879 1.00 76.65 ? ? ? ? ? ? 20 G R N7 1 13
+ATOM 995 C C5 . G B 2 13 ? 17.923 -2.078 55.946 1.00 76.09 ? ? ? ? ? ? 20 G R C5 1 13
+ATOM 996 C C6 . G B 2 13 ? 17.069 -1.220 55.206 1.00 76.26 ? ? ? ? ? ? 20 G R C6 1 13
+ATOM 997 O O6 . G B 2 13 ? 17.019 0.020 55.239 1.00 75.92 ? ? ? ? ? ? 20 G R O6 1 13
+ATOM 998 N N1 . G B 2 13 ? 16.217 -1.939 54.362 1.00 75.80 ? ? ? ? ? ? 20 G R N1 1 13
+ATOM 999 C C2 . G B 2 13 ? 16.196 -3.314 54.251 1.00 74.64 ? ? ? ? ? ? 20 G R C2 1 13
+ATOM 1000 N N2 . G B 2 13 ? 15.308 -3.829 53.391 1.00 74.53 ? ? ? ? ? ? 20 G R N2 1 13
+ATOM 1001 N N3 . G B 2 13 ? 16.990 -4.126 54.939 1.00 74.10 ? ? ? ? ? ? 20 G R N3 1 13
+ATOM 1002 C C4 . G B 2 13 ? 17.827 -3.444 55.765 1.00 75.33 ? ? ? ? ? ? 20 G R C4 1 13
+ATOM 1003 P P . G B 2 14 ? 22.496 -6.740 53.864 1.00 65.21 ? ? ? ? ? ? 21 G R P 1 14
+ATOM 1004 O OP1 . G B 2 14 ? 23.510 -7.779 53.568 1.00 64.77 ? ? ? ? ? ? 21 G R OP1 1 14
+ATOM 1005 O OP2 . G B 2 14 ? 22.744 -5.329 53.482 1.00 65.68 ? ? ? ? ? ? 21 G R OP2 1 14
+ATOM 1006 O "O5'" . G B 2 14 ? 21.095 -7.180 53.240 1.00 61.98 ? ? ? ? ? ? 21 G R "O5'" 1 14
+ATOM 1007 C "C5'" . G B 2 14 ? 21.026 -7.844 52.009 1.00 57.17 ? ? ? ? ? ? 21 G R "C5'" 1 14
+ATOM 1008 C "C4'" . G B 2 14 ? 19.720 -7.523 51.321 1.00 54.12 ? ? ? ? ? ? 21 G R "C4'" 1 14
+ATOM 1009 O "O4'" . G B 2 14 ? 18.891 -6.638 52.109 1.00 53.25 ? ? ? ? ? ? 21 G R "O4'" 1 14
+ATOM 1010 C "C3'" . G B 2 14 ? 19.920 -6.725 50.060 1.00 52.50 ? ? ? ? ? ? 21 G R "C3'" 1 14
+ATOM 1011 O "O3'" . G B 2 14 ? 20.398 -7.592 49.063 1.00 52.31 ? ? ? ? ? ? 21 G R "O3'" 1 14
+ATOM 1012 C "C2'" . G B 2 14 ? 18.517 -6.195 49.809 1.00 51.43 ? ? ? ? ? ? 21 G R "C2'" 1 14
+ATOM 1013 O "O2'" . G B 2 14 ? 17.639 -7.159 49.261 1.00 48.28 ? ? ? ? ? ? 21 G R "O2'" 1 14
+ATOM 1014 C "C1'" . G B 2 14 ? 18.119 -5.825 51.238 1.00 51.47 ? ? ? ? ? ? 21 G R "C1'" 1 14
+ATOM 1015 N N9 . G B 2 14 ? 18.354 -4.423 51.593 1.00 50.42 ? ? ? ? ? ? 21 G R N9 1 14
+ATOM 1016 C C8 . G B 2 14 ? 19.201 -3.963 52.574 1.00 50.69 ? ? ? ? ? ? 21 G R C8 1 14
+ATOM 1017 N N7 . G B 2 14 ? 19.221 -2.665 52.689 1.00 50.57 ? ? ? ? ? ? 21 G R N7 1 14
+ATOM 1018 C C5 . G B 2 14 ? 18.329 -2.225 51.723 1.00 49.87 ? ? ? ? ? ? 21 G R C5 1 14
+ATOM 1019 C C6 . G B 2 14 ? 17.939 -0.902 51.382 1.00 51.06 ? ? ? ? ? ? 21 G R C6 1 14
+ATOM 1020 O O6 . G B 2 14 ? 18.330 0.162 51.897 1.00 50.76 ? ? ? ? ? ? 21 G R O6 1 14
+ATOM 1021 N N1 . G B 2 14 ? 17.007 -0.884 50.334 1.00 49.85 ? ? ? ? ? ? 21 G R N1 1 14
+ATOM 1022 C C2 . G B 2 14 ? 16.516 -2.015 49.706 1.00 48.94 ? ? ? ? ? ? 21 G R C2 1 14
+ATOM 1023 N N2 . G B 2 14 ? 15.625 -1.819 48.723 1.00 47.46 ? ? ? ? ? ? 21 G R N2 1 14
+ATOM 1024 N N3 . G B 2 14 ? 16.875 -3.258 50.023 1.00 47.98 ? ? ? ? ? ? 21 G R N3 1 14
+ATOM 1025 C C4 . G B 2 14 ? 17.783 -3.295 51.036 1.00 49.64 ? ? ? ? ? ? 21 G R C4 1 14
+ATOM 1026 P P . C B 2 15 ? 21.706 -7.130 48.274 1.00 50.29 ? ? ? ? ? ? 22 C R P 1 15
+ATOM 1027 O OP1 . C B 2 15 ? 22.378 -8.329 47.735 1.00 48.95 ? ? ? ? ? ? 22 C R OP1 1 15
+ATOM 1028 O OP2 . C B 2 15 ? 22.458 -6.195 49.141 1.00 51.24 ? ? ? ? ? ? 22 C R OP2 1 15
+ATOM 1029 O "O5'" . C B 2 15 ? 21.047 -6.302 47.076 1.00 50.36 ? ? ? ? ? ? 22 C R "O5'" 1 15
+ATOM 1030 C "C5'" . C B 2 15 ? 19.948 -6.853 46.341 1.00 47.32 ? ? ? ? ? ? 22 C R "C5'" 1 15
+ATOM 1031 C "C4'" . C B 2 15 ? 19.100 -5.745 45.754 1.00 47.19 ? ? ? ? ? ? 22 C R "C4'" 1 15
+ATOM 1032 O "O4'" . C B 2 15 ? 18.560 -4.915 46.812 1.00 47.51 ? ? ? ? ? ? 22 C R "O4'" 1 15
+ATOM 1033 C "C3'" . C B 2 15 ? 19.857 -4.761 44.879 1.00 46.49 ? ? ? ? ? ? 22 C R "C3'" 1 15
+ATOM 1034 O "O3'" . C B 2 15 ? 19.985 -5.287 43.572 1.00 46.54 ? ? ? ? ? ? 22 C R "O3'" 1 15
+ATOM 1035 C "C2'" . C B 2 15 ? 18.934 -3.552 44.912 1.00 46.86 ? ? ? ? ? ? 22 C R "C2'" 1 15
+ATOM 1036 O "O2'" . C B 2 15 ? 17.853 -3.638 44.004 1.00 49.26 ? ? ? ? ? ? 22 C R "O2'" 1 15
+ATOM 1037 C "C1'" . C B 2 15 ? 18.393 -3.590 46.336 1.00 45.86 ? ? ? ? ? ? 22 C R "C1'" 1 15
+ATOM 1038 N N1 . C B 2 15 ? 19.057 -2.602 47.243 1.00 44.65 ? ? ? ? ? ? 22 C R N1 1 15
+ATOM 1039 C C2 . C B 2 15 ? 18.775 -1.230 47.099 1.00 46.56 ? ? ? ? ? ? 22 C R C2 1 15
+ATOM 1040 O O2 . C B 2 15 ? 17.985 -0.849 46.221 1.00 46.87 ? ? ? ? ? ? 22 C R O2 1 15
+ATOM 1041 N N3 . C B 2 15 ? 19.384 -0.343 47.935 1.00 46.85 ? ? ? ? ? ? 22 C R N3 1 15
+ATOM 1042 C C4 . C B 2 15 ? 20.234 -0.778 48.874 1.00 45.89 ? ? ? ? ? ? 22 C R C4 1 15
+ATOM 1043 N N4 . C B 2 15 ? 20.802 0.134 49.669 1.00 45.82 ? ? ? ? ? ? 22 C R N4 1 15
+ATOM 1044 C C5 . C B 2 15 ? 20.534 -2.165 49.038 1.00 44.92 ? ? ? ? ? ? 22 C R C5 1 15
+ATOM 1045 C C6 . C B 2 15 ? 19.929 -3.030 48.210 1.00 44.89 ? ? ? ? ? ? 22 C R C6 1 15
+ATOM 1046 P P . A B 2 16 ? 21.343 -5.149 42.731 1.00 48.48 ? ? ? ? ? ? 23 A R P 1 16
+ATOM 1047 O OP1 . A B 2 16 ? 21.164 -5.965 41.507 1.00 46.89 ? ? ? ? ? ? 23 A R OP1 1 16
+ATOM 1048 O OP2 . A B 2 16 ? 22.500 -5.387 43.633 1.00 44.61 ? ? ? ? ? ? 23 A R OP2 1 16
+ATOM 1049 O "O5'" . A B 2 16 ? 21.373 -3.607 42.310 1.00 46.09 ? ? ? ? ? ? 23 A R "O5'" 1 16
+ATOM 1050 C "C5'" . A B 2 16 ? 20.287 -2.976 41.638 1.00 46.26 ? ? ? ? ? ? 23 A R "C5'" 1 16
+ATOM 1051 C "C4'" . A B 2 16 ? 20.423 -1.469 41.779 1.00 47.11 ? ? ? ? ? ? 23 A R "C4'" 1 16
+ATOM 1052 O "O4'" . A B 2 16 ? 20.405 -1.097 43.184 1.00 46.84 ? ? ? ? ? ? 23 A R "O4'" 1 16
+ATOM 1053 C "C3'" . A B 2 16 ? 21.729 -0.940 41.199 1.00 47.34 ? ? ? ? ? ? 23 A R "C3'" 1 16
+ATOM 1054 O "O3'" . A B 2 16 ? 21.480 0.182 40.378 1.00 47.33 ? ? ? ? ? ? 23 A R "O3'" 1 16
+ATOM 1055 C "C2'" . A B 2 16 ? 22.571 -0.585 42.423 1.00 48.10 ? ? ? ? ? ? 23 A R "C2'" 1 16
+ATOM 1056 O "O2'" . A B 2 16 ? 23.439 0.518 42.227 1.00 49.12 ? ? ? ? ? ? 23 A R "O2'" 1 16
+ATOM 1057 C "C1'" . A B 2 16 ? 21.510 -0.268 43.473 1.00 47.02 ? ? ? ? ? ? 23 A R "C1'" 1 16
+ATOM 1058 N N9 . A B 2 16 ? 22.052 -0.541 44.799 1.00 46.26 ? ? ? ? ? ? 23 A R N9 1 16
+ATOM 1059 C C8 . A B 2 16 ? 22.416 -1.753 45.317 1.00 46.49 ? ? ? ? ? ? 23 A R C8 1 16
+ATOM 1060 N N7 . A B 2 16 ? 22.904 -1.687 46.534 1.00 47.15 ? ? ? ? ? ? 23 A R N7 1 16
+ATOM 1061 C C5 . A B 2 16 ? 22.869 -0.336 46.832 1.00 47.56 ? ? ? ? ? ? 23 A R C5 1 16
+ATOM 1062 C C6 . A B 2 16 ? 23.253 0.406 47.970 1.00 47.67 ? ? ? ? ? ? 23 A R C6 1 16
+ATOM 1063 N N6 . A B 2 16 ? 23.764 -0.152 49.069 1.00 50.08 ? ? ? ? ? ? 23 A R N6 1 16
+ATOM 1064 N N1 . A B 2 16 ? 23.082 1.746 47.950 1.00 47.35 ? ? ? ? ? ? 23 A R N1 1 16
+ATOM 1065 C C2 . A B 2 16 ? 22.571 2.309 46.848 1.00 47.69 ? ? ? ? ? ? 23 A R C2 1 16
+ATOM 1066 N N3 . A B 2 16 ? 22.175 1.719 45.718 1.00 47.86 ? ? ? ? ? ? 23 A R N3 1 16
+ATOM 1067 C C4 . A B 2 16 ? 22.351 0.385 45.771 1.00 47.38 ? ? ? ? ? ? 23 A R C4 1 16
+ATOM 1068 P P . A B 2 17 ? 22.147 0.226 38.926 1.00 48.21 ? ? ? ? ? ? 24 A R P 1 17
+ATOM 1069 O OP1 . A B 2 17 ? 21.428 -0.731 38.055 1.00 47.98 ? ? ? ? ? ? 24 A R OP1 1 17
+ATOM 1070 O OP2 . A B 2 17 ? 23.618 0.143 39.097 1.00 44.91 ? ? ? ? ? ? 24 A R OP2 1 17
+ATOM 1071 O "O5'" . A B 2 17 ? 21.760 1.695 38.436 1.00 47.93 ? ? ? ? ? ? 24 A R "O5'" 1 17
+ATOM 1072 C "C5'" . A B 2 17 ? 20.397 2.030 38.201 1.00 46.67 ? ? ? ? ? ? 24 A R "C5'" 1 17
+ATOM 1073 C "C4'" . A B 2 17 ? 20.193 3.531 38.277 1.00 47.53 ? ? ? ? ? ? 24 A R "C4'" 1 17
+ATOM 1074 O "O4'" . A B 2 17 ? 20.319 3.997 39.645 1.00 47.25 ? ? ? ? ? ? 24 A R "O4'" 1 17
+ATOM 1075 C "C3'" . A B 2 17 ? 21.223 4.368 37.536 1.00 47.99 ? ? ? ? ? ? 24 A R "C3'" 1 17
+ATOM 1076 O "O3'" . A B 2 17 ? 20.939 4.374 36.152 1.00 49.41 ? ? ? ? ? ? 24 A R "O3'" 1 17
+ATOM 1077 C "C2'" . A B 2 17 ? 20.995 5.728 38.183 1.00 47.92 ? ? ? ? ? ? 24 A R "C2'" 1 17
+ATOM 1078 O "O2'" . A B 2 17 ? 19.850 6.397 37.695 1.00 48.99 ? ? ? ? ? ? 24 A R "O2'" 1 17
+ATOM 1079 C "C1'" . A B 2 17 ? 20.795 5.334 39.646 1.00 46.09 ? ? ? ? ? ? 24 A R "C1'" 1 17
+ATOM 1080 N N9 . A B 2 17 ? 22.032 5.417 40.424 1.00 43.36 ? ? ? ? ? ? 24 A R N9 1 17
+ATOM 1081 C C8 . A B 2 17 ? 22.684 4.393 41.055 1.00 43.62 ? ? ? ? ? ? 24 A R C8 1 17
+ATOM 1082 N N7 . A B 2 17 ? 23.781 4.759 41.675 1.00 43.25 ? ? ? ? ? ? 24 A R N7 1 17
+ATOM 1083 C C5 . A B 2 17 ? 23.855 6.119 41.434 1.00 42.22 ? ? ? ? ? ? 24 A R C5 1 17
+ATOM 1084 C C6 . A B 2 17 ? 24.791 7.101 41.818 1.00 43.42 ? ? ? ? ? ? 24 A R C6 1 17
+ATOM 1085 N N6 . A B 2 17 ? 25.871 6.833 42.561 1.00 45.49 ? ? ? ? ? ? 24 A R N6 1 17
+ATOM 1086 N N1 . A B 2 17 ? 24.576 8.375 41.413 1.00 44.01 ? ? ? ? ? ? 24 A R N1 1 17
+ATOM 1087 C C2 . A B 2 17 ? 23.497 8.643 40.664 1.00 42.83 ? ? ? ? ? ? 24 A R C2 1 17
+ATOM 1088 N N3 . A B 2 17 ? 22.552 7.800 40.241 1.00 42.38 ? ? ? ? ? ? 24 A R N3 1 17
+ATOM 1089 C C4 . A B 2 17 ? 22.788 6.544 40.665 1.00 42.02 ? ? ? ? ? ? 24 A R C4 1 17
+ATOM 1090 P P . A B 2 18 ? 22.089 4.110 35.069 1.00 51.29 ? ? ? ? ? ? 25 A R P 1 18
+ATOM 1091 O OP1 . A B 2 18 ? 21.412 4.070 33.752 1.00 51.01 ? ? ? ? ? ? 25 A R OP1 1 18
+ATOM 1092 O OP2 . A B 2 18 ? 22.956 2.990 35.506 1.00 49.03 ? ? ? ? ? ? 25 A R OP2 1 18
+ATOM 1093 O "O5'" . A B 2 18 ? 22.962 5.443 35.158 1.00 50.98 ? ? ? ? ? ? 25 A R "O5'" 1 18
+ATOM 1094 C "C5'" . A B 2 18 ? 22.414 6.692 34.749 1.00 47.94 ? ? ? ? ? ? 25 A R "C5'" 1 18
+ATOM 1095 C "C4'" . A B 2 18 ? 23.255 7.822 35.304 1.00 45.90 ? ? ? ? ? ? 25 A R "C4'" 1 18
+ATOM 1096 O "O4'" . A B 2 18 ? 23.315 7.712 36.744 1.00 43.54 ? ? ? ? ? ? 25 A R "O4'" 1 18
+ATOM 1097 C "C3'" . A B 2 18 ? 24.714 7.797 34.880 1.00 45.50 ? ? ? ? ? ? 25 A R "C3'" 1 18
+ATOM 1098 O "O3'" . A B 2 18 ? 24.878 8.394 33.604 1.00 44.28 ? ? ? ? ? ? 25 A R "O3'" 1 18
+ATOM 1099 C "C2'" . A B 2 18 ? 25.344 8.643 35.974 1.00 45.71 ? ? ? ? ? ? 25 A R "C2'" 1 18
+ATOM 1100 O "O2'" . A B 2 18 ? 25.135 10.027 35.764 1.00 49.08 ? ? ? ? ? ? 25 A R "O2'" 1 18
+ATOM 1101 C "C1'" . A B 2 18 ? 24.571 8.169 37.200 1.00 43.36 ? ? ? ? ? ? 25 A R "C1'" 1 18
+ATOM 1102 N N9 . A B 2 18 ? 25.240 7.106 37.950 1.00 42.28 ? ? ? ? ? ? 25 A R N9 1 18
+ATOM 1103 C C8 . A B 2 18 ? 24.838 5.805 38.108 1.00 41.66 ? ? ? ? ? ? 25 A R C8 1 18
+ATOM 1104 N N7 . A B 2 18 ? 25.647 5.081 38.853 1.00 40.50 ? ? ? ? ? ? 25 A R N7 1 18
+ATOM 1105 C C5 . A B 2 18 ? 26.652 5.967 39.208 1.00 42.42 ? ? ? ? ? ? 25 A R C5 1 18
+ATOM 1106 C C6 . A B 2 18 ? 27.822 5.834 39.995 1.00 43.38 ? ? ? ? ? ? 25 A R C6 1 18
+ATOM 1107 N N6 . A B 2 18 ? 28.192 4.693 40.587 1.00 44.62 ? ? ? ? ? ? 25 A R N6 1 18
+ATOM 1108 N N1 . A B 2 18 ? 28.613 6.919 40.149 1.00 42.85 ? ? ? ? ? ? 25 A R N1 1 18
+ATOM 1109 C C2 . A B 2 18 ? 28.251 8.066 39.560 1.00 42.93 ? ? ? ? ? ? 25 A R C2 1 18
+ATOM 1110 N N3 . A B 2 18 ? 27.178 8.315 38.804 1.00 41.24 ? ? ? ? ? ? 25 A R N3 1 18
+ATOM 1111 C C4 . A B 2 18 ? 26.413 7.219 38.663 1.00 41.86 ? ? ? ? ? ? 25 A R C4 1 18
+ATOM 1112 P P . C B 2 19 ? 25.881 7.756 32.535 1.00 43.87 ? ? ? ? ? ? 26 C R P 1 19
+ATOM 1113 O OP1 . C B 2 19 ? 25.924 8.672 31.372 1.00 45.22 ? ? ? ? ? ? 26 C R OP1 1 19
+ATOM 1114 O OP2 . C B 2 19 ? 25.530 6.337 32.323 1.00 43.11 ? ? ? ? ? ? 26 C R OP2 1 19
+ATOM 1115 O "O5'" . C B 2 19 ? 27.280 7.766 33.302 1.00 42.41 ? ? ? ? ? ? 26 C R "O5'" 1 19
+ATOM 1116 C "C5'" . C B 2 19 ? 28.029 8.954 33.428 1.00 42.47 ? ? ? ? ? ? 26 C R "C5'" 1 19
+ATOM 1117 C "C4'" . C B 2 19 ? 29.199 8.688 34.344 1.00 42.95 ? ? ? ? ? ? 26 C R "C4'" 1 19
+ATOM 1118 O "O4'" . C B 2 19 ? 28.701 8.197 35.611 1.00 44.10 ? ? ? ? ? ? 26 C R "O4'" 1 19
+ATOM 1119 C "C3'" . C B 2 19 ? 30.122 7.583 33.870 1.00 43.32 ? ? ? ? ? ? 26 C R "C3'" 1 19
+ATOM 1120 O "O3'" . C B 2 19 ? 31.055 8.076 32.906 1.00 42.98 ? ? ? ? ? ? 26 C R "O3'" 1 19
+ATOM 1121 C "C2'" . C B 2 19 ? 30.780 7.169 35.180 1.00 44.14 ? ? ? ? ? ? 26 C R "C2'" 1 19
+ATOM 1122 O "O2'" . C B 2 19 ? 31.797 8.067 35.579 1.00 45.74 ? ? ? ? ? ? 26 C R "O2'" 1 19
+ATOM 1123 C "C1'" . C B 2 19 ? 29.596 7.233 36.141 1.00 44.24 ? ? ? ? ? ? 26 C R "C1'" 1 19
+ATOM 1124 N N1 . C B 2 19 ? 28.882 5.914 36.346 1.00 44.11 ? ? ? ? ? ? 26 C R N1 1 19
+ATOM 1125 C C2 . C B 2 19 ? 29.416 4.951 37.225 1.00 44.20 ? ? ? ? ? ? 26 C R C2 1 19
+ATOM 1126 O O2 . C B 2 19 ? 30.471 5.186 37.825 1.00 45.68 ? ? ? ? ? ? 26 C R O2 1 19
+ATOM 1127 N N3 . C B 2 19 ? 28.759 3.771 37.398 1.00 43.48 ? ? ? ? ? ? 26 C R N3 1 19
+ATOM 1128 C C4 . C B 2 19 ? 27.623 3.534 36.735 1.00 43.64 ? ? ? ? ? ? 26 C R C4 1 19
+ATOM 1129 N N4 . C B 2 19 ? 27.013 2.364 36.935 1.00 43.97 ? ? ? ? ? ? 26 C R N4 1 19
+ATOM 1130 C C5 . C B 2 19 ? 27.060 4.491 35.835 1.00 43.52 ? ? ? ? ? ? 26 C R C5 1 19
+ATOM 1131 C C6 . C B 2 19 ? 27.714 5.650 35.678 1.00 43.68 ? ? ? ? ? ? 26 C R C6 1 19
+ATOM 1132 P P . C B 2 20 ? 31.556 7.144 31.693 1.00 39.78 ? ? ? ? ? ? 27 C R P 1 20
+ATOM 1133 O OP1 . C B 2 20 ? 32.323 8.022 30.791 1.00 39.80 ? ? ? ? ? ? 27 C R OP1 1 20
+ATOM 1134 O OP2 . C B 2 20 ? 30.417 6.356 31.160 1.00 36.35 ? ? ? ? ? ? 27 C R OP2 1 20
+ATOM 1135 O "O5'" . C B 2 20 ? 32.572 6.148 32.419 1.00 38.07 ? ? ? ? ? ? 27 C R "O5'" 1 20
+ATOM 1136 C "C5'" . C B 2 20 ? 33.723 6.671 33.085 1.00 39.59 ? ? ? ? ? ? 27 C R "C5'" 1 20
+ATOM 1137 C "C4'" . C B 2 20 ? 34.404 5.601 33.916 1.00 40.17 ? ? ? ? ? ? 27 C R "C4'" 1 20
+ATOM 1138 O "O4'" . C B 2 20 ? 33.530 5.176 34.989 1.00 41.08 ? ? ? ? ? ? 27 C R "O4'" 1 20
+ATOM 1139 C "C3'" . C B 2 20 ? 34.684 4.298 33.189 1.00 41.06 ? ? ? ? ? ? 27 C R "C3'" 1 20
+ATOM 1140 O "O3'" . C B 2 20 ? 35.819 4.403 32.341 1.00 41.21 ? ? ? ? ? ? 27 C R "O3'" 1 20
+ATOM 1141 C "C2'" . C B 2 20 ? 34.907 3.363 34.373 1.00 41.83 ? ? ? ? ? ? 27 C R "C2'" 1 20
+ATOM 1142 O "O2'" . C B 2 20 ? 36.171 3.525 34.987 1.00 44.59 ? ? ? ? ? ? 27 C R "O2'" 1 20
+ATOM 1143 C "C1'" . C B 2 20 ? 33.805 3.823 35.319 1.00 40.05 ? ? ? ? ? ? 27 C R "C1'" 1 20
+ATOM 1144 N N1 . C B 2 20 ? 32.559 2.968 35.259 1.00 38.33 ? ? ? ? ? ? 27 C R N1 1 20
+ATOM 1145 C C2 . C B 2 20 ? 32.548 1.722 35.912 1.00 38.95 ? ? ? ? ? ? 27 C R C2 1 20
+ATOM 1146 O O2 . C B 2 20 ? 33.554 1.340 36.520 1.00 40.74 ? ? ? ? ? ? 27 C R O2 1 20
+ATOM 1147 N N3 . C B 2 20 ? 31.428 0.953 35.864 1.00 38.42 ? ? ? ? ? ? 27 C R N3 1 20
+ATOM 1148 C C4 . C B 2 20 ? 30.351 1.380 35.200 1.00 37.42 ? ? ? ? ? ? 27 C R C4 1 20
+ATOM 1149 N N4 . C B 2 20 ? 29.283 0.579 35.186 1.00 37.14 ? ? ? ? ? ? 27 C R N4 1 20
+ATOM 1150 C C5 . C B 2 20 ? 30.331 2.642 34.527 1.00 36.89 ? ? ? ? ? ? 27 C R C5 1 20
+ATOM 1151 C C6 . C B 2 20 ? 31.443 3.391 34.584 1.00 37.84 ? ? ? ? ? ? 27 C R C6 1 20
+ATOM 1152 P P . A B 2 21 ? 35.931 3.458 31.055 1.00 43.40 ? ? ? ? ? ? 28 A R P 1 21
+ATOM 1153 O OP1 . A B 2 21 ? 37.136 3.860 30.290 1.00 41.89 ? ? ? ? ? ? 28 A R OP1 1 21
+ATOM 1154 O OP2 . A B 2 21 ? 34.605 3.427 30.388 1.00 41.02 ? ? ? ? ? ? 28 A R OP2 1 21
+ATOM 1155 O "O5'" . A B 2 21 ? 36.179 2.017 31.702 1.00 43.30 ? ? ? ? ? ? 28 A R "O5'" 1 21
+ATOM 1156 C "C5'" . A B 2 21 ? 37.436 1.648 32.245 1.00 45.08 ? ? ? ? ? ? 28 A R "C5'" 1 21
+ATOM 1157 C "C4'" . A B 2 21 ? 37.394 0.197 32.687 1.00 47.78 ? ? ? ? ? ? 28 A R "C4'" 1 21
+ATOM 1158 O "O4'" . A B 2 21 ? 36.372 0.060 33.704 1.00 48.75 ? ? ? ? ? ? 28 A R "O4'" 1 21
+ATOM 1159 C "C3'" . A B 2 21 ? 36.970 -0.821 31.636 1.00 49.28 ? ? ? ? ? ? 28 A R "C3'" 1 21
+ATOM 1160 O "O3'" . A B 2 21 ? 38.037 -1.180 30.768 1.00 50.48 ? ? ? ? ? ? 28 A R "O3'" 1 21
+ATOM 1161 C "C2'" . A B 2 21 ? 36.530 -1.977 32.528 1.00 50.10 ? ? ? ? ? ? 28 A R "C2'" 1 21
+ATOM 1162 O "O2'" . A B 2 21 ? 37.603 -2.745 33.037 1.00 51.40 ? ? ? ? ? ? 28 A R "O2'" 1 21
+ATOM 1163 C "C1'" . A B 2 21 ? 35.816 -1.239 33.655 1.00 49.12 ? ? ? ? ? ? 28 A R "C1'" 1 21
+ATOM 1164 N N9 . A B 2 21 ? 34.381 -1.148 33.405 1.00 49.16 ? ? ? ? ? ? 28 A R N9 1 21
+ATOM 1165 C C8 . A B 2 21 ? 33.703 -0.130 32.793 1.00 49.52 ? ? ? ? ? ? 28 A R C8 1 21
+ATOM 1166 N N7 . A B 2 21 ? 32.410 -0.333 32.696 1.00 50.33 ? ? ? ? ? ? 28 A R N7 1 21
+ATOM 1167 C C5 . A B 2 21 ? 32.229 -1.574 33.280 1.00 49.47 ? ? ? ? ? ? 28 A R C5 1 21
+ATOM 1168 C C6 . A B 2 21 ? 31.082 -2.366 33.495 1.00 49.83 ? ? ? ? ? ? 28 A R C6 1 21
+ATOM 1169 N N6 . A B 2 21 ? 29.853 -1.996 33.122 1.00 49.71 ? ? ? ? ? ? 28 A R N6 1 21
+ATOM 1170 N N1 . A B 2 21 ? 31.250 -3.562 34.102 1.00 50.49 ? ? ? ? ? ? 28 A R N1 1 21
+ATOM 1171 C C2 . A B 2 21 ? 32.482 -3.938 34.473 1.00 49.24 ? ? ? ? ? ? 28 A R C2 1 21
+ATOM 1172 N N3 . A B 2 21 ? 33.631 -3.277 34.327 1.00 48.13 ? ? ? ? ? ? 28 A R N3 1 21
+ATOM 1173 C C4 . A B 2 21 ? 33.434 -2.095 33.718 1.00 49.09 ? ? ? ? ? ? 28 A R C4 1 21
+ATOM 1174 P P . U B 2 22 ? 37.749 -1.562 29.235 1.00 51.88 ? ? ? ? ? ? 29 U R P 1 22
+ATOM 1175 O OP1 . U B 2 22 ? 39.065 -1.714 28.578 1.00 52.03 ? ? ? ? ? ? 29 U R OP1 1 22
+ATOM 1176 O OP2 . U B 2 22 ? 36.747 -0.632 28.667 1.00 50.95 ? ? ? ? ? ? 29 U R OP2 1 22
+ATOM 1177 O "O5'" . U B 2 22 ? 37.032 -2.985 29.327 1.00 52.23 ? ? ? ? ? ? 29 U R "O5'" 1 22
+ATOM 1178 C "C5'" . U B 2 22 ? 37.724 -4.155 29.742 1.00 51.27 ? ? ? ? ? ? 29 U R "C5'" 1 22
+ATOM 1179 C "C4'" . U B 2 22 ? 36.710 -5.241 30.046 1.00 51.64 ? ? ? ? ? ? 29 U R "C4'" 1 22
+ATOM 1180 O "O4'" . U B 2 22 ? 35.768 -4.729 31.021 1.00 51.20 ? ? ? ? ? ? 29 U R "O4'" 1 22
+ATOM 1181 C "C3'" . U B 2 22 ? 35.803 -5.623 28.888 1.00 51.62 ? ? ? ? ? ? 29 U R "C3'" 1 22
+ATOM 1182 O "O3'" . U B 2 22 ? 36.436 -6.515 27.977 1.00 53.54 ? ? ? ? ? ? 29 U R "O3'" 1 22
+ATOM 1183 C "C2'" . U B 2 22 ? 34.636 -6.260 29.639 1.00 50.64 ? ? ? ? ? ? 29 U R "C2'" 1 22
+ATOM 1184 O "O2'" . U B 2 22 ? 34.909 -7.570 30.098 1.00 48.36 ? ? ? ? ? ? 29 U R "O2'" 1 22
+ATOM 1185 C "C1'" . U B 2 22 ? 34.487 -5.298 30.814 1.00 49.41 ? ? ? ? ? ? 29 U R "C1'" 1 22
+ATOM 1186 N N1 . U B 2 22 ? 33.449 -4.230 30.577 1.00 49.14 ? ? ? ? ? ? 29 U R N1 1 22
+ATOM 1187 C C2 . U B 2 22 ? 32.119 -4.509 30.860 1.00 48.59 ? ? ? ? ? ? 29 U R C2 1 22
+ATOM 1188 O O2 . U B 2 22 ? 31.733 -5.578 31.298 1.00 47.71 ? ? ? ? ? ? 29 U R O2 1 22
+ATOM 1189 N N3 . U B 2 22 ? 31.237 -3.482 30.606 1.00 47.53 ? ? ? ? ? ? 29 U R N3 1 22
+ATOM 1190 C C4 . U B 2 22 ? 31.542 -2.224 30.111 1.00 48.35 ? ? ? ? ? ? 29 U R C4 1 22
+ATOM 1191 O O4 . U B 2 22 ? 30.646 -1.401 29.941 1.00 49.31 ? ? ? ? ? ? 29 U R O4 1 22
+ATOM 1192 C C5 . U B 2 22 ? 32.942 -2.002 29.841 1.00 48.45 ? ? ? ? ? ? 29 U R C5 1 22
+ATOM 1193 C C6 . U B 2 22 ? 33.819 -2.989 30.078 1.00 48.88 ? ? ? ? ? ? 29 U R C6 1 22
+ATOM 1194 P P . U B 2 23 ? 35.891 -6.612 26.473 1.00 55.92 ? ? ? ? ? ? 30 U R P 1 23
+ATOM 1195 O OP1 . U B 2 23 ? 36.885 -7.370 25.685 1.00 56.79 ? ? ? ? ? ? 30 U R OP1 1 23
+ATOM 1196 O OP2 . U B 2 23 ? 35.472 -5.266 26.026 1.00 56.02 ? ? ? ? ? ? 30 U R OP2 1 23
+ATOM 1197 O "O5'" . U B 2 23 ? 34.562 -7.489 26.615 1.00 55.88 ? ? ? ? ? ? 30 U R "O5'" 1 23
+ATOM 1198 C "C5'" . U B 2 23 ? 34.646 -8.880 26.907 1.00 54.03 ? ? ? ? ? ? 30 U R "C5'" 1 23
+ATOM 1199 C "C4'" . U B 2 23 ? 33.261 -9.453 27.111 1.00 52.65 ? ? ? ? ? ? 30 U R "C4'" 1 23
+ATOM 1200 O "O4'" . U B 2 23 ? 32.604 -8.723 28.174 1.00 53.98 ? ? ? ? ? ? 30 U R "O4'" 1 23
+ATOM 1201 C "C3'" . U B 2 23 ? 32.326 -9.267 25.931 1.00 52.84 ? ? ? ? ? ? 30 U R "C3'" 1 23
+ATOM 1202 O "O3'" . U B 2 23 ? 32.533 -10.276 24.969 1.00 53.35 ? ? ? ? ? ? 30 U R "O3'" 1 23
+ATOM 1203 C "C2'" . U B 2 23 ? 30.964 -9.386 26.601 1.00 53.57 ? ? ? ? ? ? 30 U R "C2'" 1 23
+ATOM 1204 O "O2'" . U B 2 23 ? 30.578 -10.727 26.842 1.00 53.89 ? ? ? ? ? ? 30 U R "O2'" 1 23
+ATOM 1205 C "C1'" . U B 2 23 ? 31.212 -8.649 27.915 1.00 53.68 ? ? ? ? ? ? 30 U R "C1'" 1 23
+ATOM 1206 N N1 . U B 2 23 ? 30.749 -7.219 27.876 1.00 53.17 ? ? ? ? ? ? 30 U R N1 1 23
+ATOM 1207 C C2 . U B 2 23 ? 29.401 -6.947 28.060 1.00 53.95 ? ? ? ? ? ? 30 U R C2 1 23
+ATOM 1208 O O2 . U B 2 23 ? 28.556 -7.801 28.260 1.00 53.72 ? ? ? ? ? ? 30 U R O2 1 23
+ATOM 1209 N N3 . U B 2 23 ? 29.064 -5.616 28.007 1.00 55.46 ? ? ? ? ? ? 30 U R N3 1 23
+ATOM 1210 C C4 . U B 2 23 ? 29.917 -4.547 27.788 1.00 55.95 ? ? ? ? ? ? 30 U R C4 1 23
+ATOM 1211 O O4 . U B 2 23 ? 29.461 -3.405 27.769 1.00 57.24 ? ? ? ? ? ? 30 U R O4 1 23
+ATOM 1212 C C5 . U B 2 23 ? 31.304 -4.906 27.600 1.00 54.11 ? ? ? ? ? ? 30 U R C5 1 23
+ATOM 1213 C C6 . U B 2 23 ? 31.658 -6.198 27.651 1.00 52.33 ? ? ? ? ? ? 30 U R C6 1 23
+ATOM 1214 P P . C B 2 24 ? 32.283 -9.967 23.422 1.00 52.17 ? ? ? ? ? ? 31 C R P 1 24
+ATOM 1215 O OP1 . C B 2 24 ? 32.848 -11.102 22.662 1.00 53.59 ? ? ? ? ? ? 31 C R OP1 1 24
+ATOM 1216 O OP2 . C B 2 24 ? 32.747 -8.594 23.131 1.00 54.12 ? ? ? ? ? ? 31 C R OP2 1 24
+ATOM 1217 O "O5'" . C B 2 24 ? 30.687 -9.957 23.300 1.00 52.70 ? ? ? ? ? ? 31 C R "O5'" 1 24
+ATOM 1218 C "C5'" . C B 2 24 ? 29.932 -11.153 23.477 1.00 53.71 ? ? ? ? ? ? 31 C R "C5'" 1 24
+ATOM 1219 C "C4'" . C B 2 24 ? 28.450 -10.857 23.618 1.00 53.63 ? ? ? ? ? ? 31 C R "C4'" 1 24
+ATOM 1220 O "O4'" . C B 2 24 ? 28.230 -9.974 24.745 1.00 54.03 ? ? ? ? ? ? 31 C R "O4'" 1 24
+ATOM 1221 C "C3'" . C B 2 24 ? 27.817 -10.070 22.484 1.00 54.65 ? ? ? ? ? ? 31 C R "C3'" 1 24
+ATOM 1222 O "O3'" . C B 2 24 ? 27.605 -10.864 21.320 1.00 56.43 ? ? ? ? ? ? 31 C R "O3'" 1 24
+ATOM 1223 C "C2'" . C B 2 24 ? 26.527 -9.592 23.151 1.00 54.06 ? ? ? ? ? ? 31 C R "C2'" 1 24
+ATOM 1224 O "O2'" . C B 2 24 ? 25.530 -10.586 23.275 1.00 53.49 ? ? ? ? ? ? 31 C R "O2'" 1 24
+ATOM 1225 C "C1'" . C B 2 24 ? 27.053 -9.208 24.529 1.00 53.46 ? ? ? ? ? ? 31 C R "C1'" 1 24
+ATOM 1226 N N1 . C B 2 24 ? 27.340 -7.732 24.675 1.00 53.11 ? ? ? ? ? ? 31 C R N1 1 24
+ATOM 1227 C C2 . C B 2 24 ? 26.282 -6.835 24.929 1.00 53.12 ? ? ? ? ? ? 31 C R C2 1 24
+ATOM 1228 O O2 . C B 2 24 ? 25.121 -7.255 25.028 1.00 52.24 ? ? ? ? ? ? 31 C R O2 1 24
+ATOM 1229 N N3 . C B 2 24 ? 26.559 -5.511 25.059 1.00 53.11 ? ? ? ? ? ? 31 C R N3 1 24
+ATOM 1230 C C4 . C B 2 24 ? 27.817 -5.073 24.947 1.00 53.09 ? ? ? ? ? ? 31 C R C4 1 24
+ATOM 1231 N N4 . C B 2 24 ? 28.030 -3.762 25.087 1.00 53.24 ? ? ? ? ? ? 31 C R N4 1 24
+ATOM 1232 C C5 . C B 2 24 ? 28.908 -5.959 24.691 1.00 52.72 ? ? ? ? ? ? 31 C R C5 1 24
+ATOM 1233 C C6 . C B 2 24 ? 28.625 -7.264 24.566 1.00 52.42 ? ? ? ? ? ? 31 C R C6 1 24
+ATOM 1234 P P . G B 2 25 ? 27.805 -10.204 19.869 1.00 57.68 ? ? ? ? ? ? 32 G R P 1 25
+ATOM 1235 O OP1 . G B 2 25 ? 27.654 -11.275 18.856 1.00 57.60 ? ? ? ? ? ? 32 G R OP1 1 25
+ATOM 1236 O OP2 . G B 2 25 ? 29.032 -9.374 19.887 1.00 55.05 ? ? ? ? ? ? 32 G R OP2 1 25
+ATOM 1237 O "O5'" . G B 2 25 ? 26.552 -9.219 19.755 1.00 56.53 ? ? ? ? ? ? 32 G R "O5'" 1 25
+ATOM 1238 C "C5'" . G B 2 25 ? 25.214 -9.713 19.775 1.00 56.44 ? ? ? ? ? ? 32 G R "C5'" 1 25
+ATOM 1239 C "C4'" . G B 2 25 ? 24.243 -8.552 19.860 1.00 57.18 ? ? ? ? ? ? 32 G R "C4'" 1 25
+ATOM 1240 O "O4'" . G B 2 25 ? 24.377 -7.870 21.133 1.00 57.36 ? ? ? ? ? ? 32 G R "O4'" 1 25
+ATOM 1241 C "C3'" . G B 2 25 ? 24.526 -7.412 18.899 1.00 58.50 ? ? ? ? ? ? 32 G R "C3'" 1 25
+ATOM 1242 O "O3'" . G B 2 25 ? 24.232 -7.740 17.545 1.00 60.15 ? ? ? ? ? ? 32 G R "O3'" 1 25
+ATOM 1243 C "C2'" . G B 2 25 ? 23.668 -6.311 19.510 1.00 57.04 ? ? ? ? ? ? 32 G R "C2'" 1 25
+ATOM 1244 O "O2'" . G B 2 25 ? 22.280 -6.522 19.345 1.00 59.42 ? ? ? ? ? ? 32 G R "O2'" 1 25
+ATOM 1245 C "C1'" . G B 2 25 ? 24.075 -6.490 20.971 1.00 55.51 ? ? ? ? ? ? 32 G R "C1'" 1 25
+ATOM 1246 N N9 . G B 2 25 ? 25.235 -5.664 21.304 1.00 53.55 ? ? ? ? ? ? 32 G R N9 1 25
+ATOM 1247 C C8 . G B 2 25 ? 26.554 -6.052 21.347 1.00 53.69 ? ? ? ? ? ? 32 G R C8 1 25
+ATOM 1248 N N7 . G B 2 25 ? 27.377 -5.089 21.658 1.00 53.73 ? ? ? ? ? ? 32 G R N7 1 25
+ATOM 1249 C C5 . G B 2 25 ? 26.554 -3.985 21.829 1.00 53.84 ? ? ? ? ? ? 32 G R C5 1 25
+ATOM 1250 C C6 . G B 2 25 ? 26.881 -2.650 22.174 1.00 54.54 ? ? ? ? ? ? 32 G R C6 1 25
+ATOM 1251 O O6 . G B 2 25 ? 28.007 -2.181 22.400 1.00 56.21 ? ? ? ? ? ? 32 G R O6 1 25
+ATOM 1252 N N1 . G B 2 25 ? 25.752 -1.829 22.248 1.00 52.91 ? ? ? ? ? ? 32 G R N1 1 25
+ATOM 1253 C C2 . G B 2 25 ? 24.465 -2.258 22.013 1.00 52.70 ? ? ? ? ? ? 32 G R C2 1 25
+ATOM 1254 N N2 . G B 2 25 ? 23.496 -1.339 22.126 1.00 53.64 ? ? ? ? ? ? 32 G R N2 1 25
+ATOM 1255 N N3 . G B 2 25 ? 24.147 -3.507 21.689 1.00 52.97 ? ? ? ? ? ? 32 G R N3 1 25
+ATOM 1256 C C4 . G B 2 25 ? 25.234 -4.319 21.614 1.00 53.66 ? ? ? ? ? ? 32 G R C4 1 25
+ATOM 1257 P P . A B 2 26 ? 25.364 -7.422 16.452 1.00 61.56 ? ? ? ? ? ? 33 A R P 1 26
+ATOM 1258 O OP1 . A B 2 26 ? 25.209 -8.395 15.347 1.00 60.83 ? ? ? ? ? ? 33 A R OP1 1 26
+ATOM 1259 O OP2 . A B 2 26 ? 26.673 -7.287 17.141 1.00 59.56 ? ? ? ? ? ? 33 A R OP2 1 26
+ATOM 1260 O "O5'" . A B 2 26 ? 24.923 -5.972 15.940 1.00 59.89 ? ? ? ? ? ? 33 A R "O5'" 1 26
+ATOM 1261 C "C5'" . A B 2 26 ? 25.897 -5.006 15.557 1.00 58.91 ? ? ? ? ? ? 33 A R "C5'" 1 26
+ATOM 1262 C "C4'" . A B 2 26 ? 25.212 -3.749 15.057 1.00 57.67 ? ? ? ? ? ? 33 A R "C4'" 1 26
+ATOM 1263 O "O4'" . A B 2 26 ? 24.090 -4.120 14.217 1.00 57.15 ? ? ? ? ? ? 33 A R "O4'" 1 26
+ATOM 1264 C "C3'" . A B 2 26 ? 24.622 -2.871 16.147 1.00 56.29 ? ? ? ? ? ? 33 A R "C3'" 1 26
+ATOM 1265 O "O3'" . A B 2 26 ? 25.604 -1.932 16.570 1.00 56.61 ? ? ? ? ? ? 33 A R "O3'" 1 26
+ATOM 1266 C "C2'" . A B 2 26 ? 23.457 -2.197 15.434 1.00 55.61 ? ? ? ? ? ? 33 A R "C2'" 1 26
+ATOM 1267 O "O2'" . A B 2 26 ? 23.855 -1.055 14.695 1.00 55.44 ? ? ? ? ? ? 33 A R "O2'" 1 26
+ATOM 1268 C "C1'" . A B 2 26 ? 22.981 -3.284 14.474 1.00 55.30 ? ? ? ? ? ? 33 A R "C1'" 1 26
+ATOM 1269 N N9 . A B 2 26 ? 21.864 -4.121 14.930 1.00 55.07 ? ? ? ? ? ? 33 A R N9 1 26
+ATOM 1270 C C8 . A B 2 26 ? 21.863 -5.482 15.079 1.00 54.80 ? ? ? ? ? ? 33 A R C8 1 26
+ATOM 1271 N N7 . A B 2 26 ? 20.720 -5.978 15.491 1.00 54.47 ? ? ? ? ? ? 33 A R N7 1 26
+ATOM 1272 C C5 . A B 2 26 ? 19.907 -4.868 15.616 1.00 54.13 ? ? ? ? ? ? 33 A R C5 1 26
+ATOM 1273 C C6 . A B 2 26 ? 18.564 -4.713 16.014 1.00 54.74 ? ? ? ? ? ? 33 A R C6 1 26
+ATOM 1274 N N6 . A B 2 26 ? 17.779 -5.732 16.372 1.00 55.74 ? ? ? ? ? ? 33 A R N6 1 26
+ATOM 1275 N N1 . A B 2 26 ? 18.047 -3.466 16.028 1.00 55.08 ? ? ? ? ? ? 33 A R N1 1 26
+ATOM 1276 C C2 . A B 2 26 ? 18.830 -2.439 15.671 1.00 55.44 ? ? ? ? ? ? 33 A R C2 1 26
+ATOM 1277 N N3 . A B 2 26 ? 20.104 -2.458 15.280 1.00 55.35 ? ? ? ? ? ? 33 A R N3 1 26
+ATOM 1278 C C4 . A B 2 26 ? 20.592 -3.714 15.273 1.00 54.75 ? ? ? ? ? ? 33 A R C4 1 26
+ATOM 1279 P P . A B 2 27 ? 25.899 -1.729 18.128 1.00 55.74 ? ? ? ? ? ? 34 A R P 1 27
+ATOM 1280 O OP1 . A B 2 27 ? 27.156 -0.961 18.279 1.00 54.88 ? ? ? ? ? ? 34 A R OP1 1 27
+ATOM 1281 O OP2 . A B 2 27 ? 25.781 -3.059 18.763 1.00 57.39 ? ? ? ? ? ? 34 A R OP2 1 27
+ATOM 1282 O "O5'" . A B 2 27 ? 24.665 -0.832 18.614 1.00 54.02 ? ? ? ? ? ? 34 A R "O5'" 1 27
+ATOM 1283 C "C5'" . A B 2 27 ? 24.456 0.481 18.090 1.00 52.80 ? ? ? ? ? ? 34 A R "C5'" 1 27
+ATOM 1284 C "C4'" . A B 2 27 ? 22.992 0.875 18.185 1.00 52.89 ? ? ? ? ? ? 34 A R "C4'" 1 27
+ATOM 1285 O "O4'" . A B 2 27 ? 22.172 -0.161 17.588 1.00 52.10 ? ? ? ? ? ? 34 A R "O4'" 1 27
+ATOM 1286 C "C3'" . A B 2 27 ? 22.445 1.015 19.600 1.00 53.41 ? ? ? ? ? ? 34 A R "C3'" 1 27
+ATOM 1287 O "O3'" . A B 2 27 ? 22.684 2.325 20.108 1.00 53.18 ? ? ? ? ? ? 34 A R "O3'" 1 27
+ATOM 1288 C "C2'" . A B 2 27 ? 20.954 0.743 19.413 1.00 53.05 ? ? ? ? ? ? 34 A R "C2'" 1 27
+ATOM 1289 O "O2'" . A B 2 27 ? 20.243 1.896 19.006 1.00 54.41 ? ? ? ? ? ? 34 A R "O2'" 1 27
+ATOM 1290 C "C1'" . A B 2 27 ? 20.940 -0.277 18.282 1.00 51.91 ? ? ? ? ? ? 34 A R "C1'" 1 27
+ATOM 1291 N N9 . A B 2 27 ? 20.731 -1.672 18.685 1.00 50.62 ? ? ? ? ? ? 34 A R N9 1 27
+ATOM 1292 C C8 . A B 2 27 ? 21.693 -2.623 18.898 1.00 51.25 ? ? ? ? ? ? 34 A R C8 1 27
+ATOM 1293 N N7 . A B 2 27 ? 21.222 -3.801 19.236 1.00 49.82 ? ? ? ? ? ? 34 A R N7 1 27
+ATOM 1294 C C5 . A B 2 27 ? 19.852 -3.617 19.243 1.00 49.76 ? ? ? ? ? ? 34 A R C5 1 27
+ATOM 1295 C C6 . A B 2 27 ? 18.774 -4.490 19.521 1.00 49.94 ? ? ? ? ? ? 34 A R C6 1 27
+ATOM 1296 N N6 . A B 2 27 ? 18.940 -5.773 19.859 1.00 49.41 ? ? ? ? ? ? 34 A R N6 1 27
+ATOM 1297 N N1 . A B 2 27 ? 17.515 -3.998 19.441 1.00 49.13 ? ? ? ? ? ? 34 A R N1 1 27
+ATOM 1298 C C2 . A B 2 27 ? 17.354 -2.711 19.106 1.00 49.13 ? ? ? ? ? ? 34 A R C2 1 27
+ATOM 1299 N N3 . A B 2 27 ? 18.290 -1.800 18.822 1.00 49.72 ? ? ? ? ? ? 34 A R N3 1 27
+ATOM 1300 C C4 . A B 2 27 ? 19.531 -2.314 18.908 1.00 49.62 ? ? ? ? ? ? 34 A R C4 1 27
+ATOM 1301 P P . A B 2 28 ? 22.801 2.583 21.687 1.00 53.86 ? ? ? ? ? ? 35 A R P 1 28
+ATOM 1302 O OP1 . A B 2 28 ? 23.178 4.002 21.865 1.00 53.79 ? ? ? ? ? ? 35 A R OP1 1 28
+ATOM 1303 O OP2 . A B 2 28 ? 23.645 1.520 22.280 1.00 53.01 ? ? ? ? ? ? 35 A R OP2 1 28
+ATOM 1304 O "O5'" . A B 2 28 ? 21.308 2.352 22.218 1.00 53.14 ? ? ? ? ? ? 35 A R "O5'" 1 28
+ATOM 1305 C "C5'" . A B 2 28 ? 20.402 3.437 22.382 1.00 52.47 ? ? ? ? ? ? 35 A R "C5'" 1 28
+ATOM 1306 C "C4'" . A B 2 28 ? 18.998 2.929 22.666 1.00 52.85 ? ? ? ? ? ? 35 A R "C4'" 1 28
+ATOM 1307 O "O4'" . A B 2 28 ? 18.675 1.828 21.776 1.00 51.59 ? ? ? ? ? ? 35 A R "O4'" 1 28
+ATOM 1308 C "C3'" . A B 2 28 ? 18.780 2.345 24.053 1.00 53.08 ? ? ? ? ? ? 35 A R "C3'" 1 28
+ATOM 1309 O "O3'" . A B 2 28 ? 18.546 3.363 25.014 1.00 55.52 ? ? ? ? ? ? 35 A R "O3'" 1 28
+ATOM 1310 C "C2'" . A B 2 28 ? 17.554 1.462 23.825 1.00 51.88 ? ? ? ? ? ? 35 A R "C2'" 1 28
+ATOM 1311 O "O2'" . A B 2 28 ? 16.329 2.169 23.769 1.00 50.77 ? ? ? ? ? ? 35 A R "O2'" 1 28
+ATOM 1312 C "C1'" . A B 2 28 ? 17.890 0.869 22.461 1.00 50.48 ? ? ? ? ? ? 35 A R "C1'" 1 28
+ATOM 1313 N N9 . A B 2 28 ? 18.635 -0.384 22.559 1.00 48.64 ? ? ? ? ? ? 35 A R N9 1 28
+ATOM 1314 C C8 . A B 2 28 ? 19.995 -0.546 22.610 1.00 49.70 ? ? ? ? ? ? 35 A R C8 1 28
+ATOM 1315 N N7 . A B 2 28 ? 20.384 -1.798 22.699 1.00 48.97 ? ? ? ? ? ? 35 A R N7 1 28
+ATOM 1316 C C5 . A B 2 28 ? 19.192 -2.508 22.711 1.00 46.90 ? ? ? ? ? ? 35 A R C5 1 28
+ATOM 1317 C C6 . A B 2 28 ? 18.911 -3.888 22.795 1.00 46.04 ? ? ? ? ? ? 35 A R C6 1 28
+ATOM 1318 N N6 . A B 2 28 ? 19.859 -4.832 22.882 1.00 46.58 ? ? ? ? ? ? 35 A R N6 1 28
+ATOM 1319 N N1 . A B 2 28 ? 17.612 -4.262 22.779 1.00 45.17 ? ? ? ? ? ? 35 A R N1 1 28
+ATOM 1320 C C2 . A B 2 28 ? 16.664 -3.315 22.691 1.00 45.35 ? ? ? ? ? ? 35 A R C2 1 28
+ATOM 1321 N N3 . A B 2 28 ? 16.805 -1.992 22.613 1.00 45.86 ? ? ? ? ? ? 35 A R N3 1 28
+ATOM 1322 C C4 . A B 2 28 ? 18.105 -1.650 22.628 1.00 46.96 ? ? ? ? ? ? 35 A R C4 1 28
+ATOM 1323 P P . G B 2 29 ? 19.511 3.530 26.284 1.00 58.20 ? ? ? ? ? ? 36 G R P 1 29
+ATOM 1324 O OP1 . G B 2 29 ? 18.775 4.376 27.253 1.00 57.99 ? ? ? ? ? ? 36 G R OP1 1 29
+ATOM 1325 O OP2 . G B 2 29 ? 20.855 3.939 25.807 1.00 55.69 ? ? ? ? ? ? 36 G R OP2 1 29
+ATOM 1326 O "O5'" . G B 2 29 ? 19.655 2.050 26.878 1.00 57.97 ? ? ? ? ? ? 36 G R "O5'" 1 29
+ATOM 1327 C "C5'" . G B 2 29 ? 18.560 1.412 27.534 1.00 57.83 ? ? ? ? ? ? 36 G R "C5'" 1 29
+ATOM 1328 C "C4'" . G B 2 29 ? 18.527 -0.076 27.225 1.00 57.14 ? ? ? ? ? ? 36 G R "C4'" 1 29
+ATOM 1329 O "O4'" . G B 2 29 ? 19.195 -0.379 25.969 1.00 56.01 ? ? ? ? ? ? 36 G R "O4'" 1 29
+ATOM 1330 C "C3'" . G B 2 29 ? 19.252 -0.970 28.216 1.00 56.29 ? ? ? ? ? ? 36 G R "C3'" 1 29
+ATOM 1331 O "O3'" . G B 2 29 ? 18.497 -1.147 29.413 1.00 54.08 ? ? ? ? ? ? 36 G R "O3'" 1 29
+ATOM 1332 C "C2'" . G B 2 29 ? 19.365 -2.246 27.386 1.00 56.82 ? ? ? ? ? ? 36 G R "C2'" 1 29
+ATOM 1333 O "O2'" . G B 2 29 ? 18.134 -2.940 27.256 1.00 58.92 ? ? ? ? ? ? 36 G R "O2'" 1 29
+ATOM 1334 C "C1'" . G B 2 29 ? 19.789 -1.662 26.038 1.00 53.98 ? ? ? ? ? ? 36 G R "C1'" 1 29
+ATOM 1335 N N9 . G B 2 29 ? 21.240 -1.527 25.870 1.00 51.24 ? ? ? ? ? ? 36 G R N9 1 29
+ATOM 1336 C C8 . G B 2 29 ? 21.969 -0.360 25.841 1.00 50.73 ? ? ? ? ? ? 36 G R C8 1 29
+ATOM 1337 N N7 . G B 2 29 ? 23.253 -0.536 25.681 1.00 48.03 ? ? ? ? ? ? 36 G R N7 1 29
+ATOM 1338 C C5 . G B 2 29 ? 23.393 -1.914 25.600 1.00 47.67 ? ? ? ? ? ? 36 G R C5 1 29
+ATOM 1339 C C6 . G B 2 29 ? 24.558 -2.703 25.430 1.00 46.74 ? ? ? ? ? ? 36 G R C6 1 29
+ATOM 1340 O O6 . G B 2 29 ? 25.729 -2.322 25.314 1.00 45.80 ? ? ? ? ? ? 36 G R O6 1 29
+ATOM 1341 N N1 . G B 2 29 ? 24.269 -4.067 25.399 1.00 46.80 ? ? ? ? ? ? 36 G R N1 1 29
+ATOM 1342 C C2 . G B 2 29 ? 23.003 -4.598 25.520 1.00 48.59 ? ? ? ? ? ? 36 G R C2 1 29
+ATOM 1343 N N2 . G B 2 29 ? 22.910 -5.934 25.471 1.00 48.06 ? ? ? ? ? ? 36 G R N2 1 29
+ATOM 1344 N N3 . G B 2 29 ? 21.900 -3.870 25.682 1.00 48.76 ? ? ? ? ? ? 36 G R N3 1 29
+ATOM 1345 C C4 . G B 2 29 ? 22.165 -2.538 25.714 1.00 49.31 ? ? ? ? ? ? 36 G R C4 1 29
+ATOM 1346 P P . A B 2 30 ? 19.268 -1.223 30.816 1.00 52.19 ? ? ? ? ? ? 37 A R P 1 30
+ATOM 1347 O OP1 . A B 2 30 ? 18.287 -1.000 31.901 1.00 52.56 ? ? ? ? ? ? 37 A R OP1 1 30
+ATOM 1348 O OP2 . A B 2 30 ? 20.468 -0.356 30.739 1.00 53.44 ? ? ? ? ? ? 37 A R OP2 1 30
+ATOM 1349 O "O5'" . A B 2 30 ? 19.758 -2.747 30.849 1.00 50.68 ? ? ? ? ? ? 37 A R "O5'" 1 30
+ATOM 1350 C "C5'" . A B 2 30 ? 18.810 -3.814 30.923 1.00 47.96 ? ? ? ? ? ? 37 A R "C5'" 1 30
+ATOM 1351 C "C4'" . A B 2 30 ? 19.407 -5.142 30.487 1.00 45.30 ? ? ? ? ? ? 37 A R "C4'" 1 30
+ATOM 1352 O "O4'" . A B 2 30 ? 20.061 -5.001 29.198 1.00 43.97 ? ? ? ? ? ? 37 A R "O4'" 1 30
+ATOM 1353 C "C3'" . A B 2 30 ? 20.502 -5.691 31.389 1.00 43.93 ? ? ? ? ? ? 37 A R "C3'" 1 30
+ATOM 1354 O "O3'" . A B 2 30 ? 19.963 -6.389 32.497 1.00 43.64 ? ? ? ? ? ? 37 A R "O3'" 1 30
+ATOM 1355 C "C2'" . A B 2 30 ? 21.231 -6.628 30.436 1.00 43.05 ? ? ? ? ? ? 37 A R "C2'" 1 30
+ATOM 1356 O "O2'" . A B 2 30 ? 20.541 -7.846 30.248 1.00 44.55 ? ? ? ? ? ? 37 A R "O2'" 1 30
+ATOM 1357 C "C1'" . A B 2 30 ? 21.228 -5.807 29.152 1.00 42.24 ? ? ? ? ? ? 37 A R "C1'" 1 30
+ATOM 1358 N N9 . A B 2 30 ? 22.415 -4.959 28.993 1.00 41.12 ? ? ? ? ? ? 37 A R N9 1 30
+ATOM 1359 C C8 . A B 2 30 ? 22.462 -3.591 29.039 1.00 41.53 ? ? ? ? ? ? 37 A R C8 1 30
+ATOM 1360 N N7 . A B 2 30 ? 23.662 -3.085 28.864 1.00 40.53 ? ? ? ? ? ? 37 A R N7 1 30
+ATOM 1361 C C5 . A B 2 30 ? 24.463 -4.195 28.689 1.00 39.80 ? ? ? ? ? ? 37 A R C5 1 30
+ATOM 1362 C C6 . A B 2 30 ? 25.847 -4.333 28.455 1.00 40.58 ? ? ? ? ? ? 37 A R C6 1 30
+ATOM 1363 N N6 . A B 2 30 ? 26.675 -3.287 28.360 1.00 39.26 ? ? ? ? ? ? 37 A R N6 1 30
+ATOM 1364 N N1 . A B 2 30 ? 26.346 -5.585 28.321 1.00 39.87 ? ? ? ? ? ? 37 A R N1 1 30
+ATOM 1365 C C2 . A B 2 30 ? 25.502 -6.622 28.415 1.00 41.00 ? ? ? ? ? ? 37 A R C2 1 30
+ATOM 1366 N N3 . A B 2 30 ? 24.183 -6.615 28.634 1.00 40.26 ? ? ? ? ? ? 37 A R N3 1 30
+ATOM 1367 C C4 . A B 2 30 ? 23.716 -5.360 28.764 1.00 40.22 ? ? ? ? ? ? 37 A R C4 1 30
+ATOM 1368 P P . G B 2 31 ? 20.801 -6.465 33.861 1.00 44.19 ? ? ? ? ? ? 38 G R P 1 31
+ATOM 1369 O OP1 . G B 2 31 ? 19.904 -7.043 34.886 1.00 44.89 ? ? ? ? ? ? 38 G R OP1 1 31
+ATOM 1370 O OP2 . G B 2 31 ? 21.425 -5.149 34.106 1.00 43.62 ? ? ? ? ? ? 38 G R OP2 1 31
+ATOM 1371 O "O5'" . G B 2 31 ? 21.993 -7.478 33.532 1.00 42.81 ? ? ? ? ? ? 38 G R "O5'" 1 31
+ATOM 1372 C "C5'" . G B 2 31 ? 21.780 -8.880 33.459 1.00 41.49 ? ? ? ? ? ? 38 G R "C5'" 1 31
+ATOM 1373 C "C4'" . G B 2 31 ? 23.070 -9.592 33.091 1.00 43.18 ? ? ? ? ? ? 38 G R "C4'" 1 31
+ATOM 1374 O "O4'" . G B 2 31 ? 23.612 -9.055 31.860 1.00 42.94 ? ? ? ? ? ? 38 G R "O4'" 1 31
+ATOM 1375 C "C3'" . G B 2 31 ? 24.221 -9.425 34.071 1.00 43.20 ? ? ? ? ? ? 38 G R "C3'" 1 31
+ATOM 1376 O "O3'" . G B 2 31 ? 24.055 -10.299 35.164 1.00 43.73 ? ? ? ? ? ? 38 G R "O3'" 1 31
+ATOM 1377 C "C2'" . G B 2 31 ? 25.407 -9.815 33.205 1.00 41.94 ? ? ? ? ? ? 38 G R "C2'" 1 31
+ATOM 1378 O "O2'" . G B 2 31 ? 25.520 -11.212 33.024 1.00 41.94 ? ? ? ? ? ? 38 G R "O2'" 1 31
+ATOM 1379 C "C1'" . G B 2 31 ? 25.026 -9.143 31.889 1.00 43.10 ? ? ? ? ? ? 38 G R "C1'" 1 31
+ATOM 1380 N N9 . G B 2 31 ? 25.602 -7.807 31.746 1.00 44.86 ? ? ? ? ? ? 38 G R N9 1 31
+ATOM 1381 C C8 . G B 2 31 ? 24.936 -6.604 31.741 1.00 45.13 ? ? ? ? ? ? 38 G R C8 1 31
+ATOM 1382 N N7 . G B 2 31 ? 25.720 -5.571 31.599 1.00 44.89 ? ? ? ? ? ? 38 G R N7 1 31
+ATOM 1383 C C5 . G B 2 31 ? 26.988 -6.123 31.511 1.00 45.32 ? ? ? ? ? ? 38 G R C5 1 31
+ATOM 1384 C C6 . G B 2 31 ? 28.243 -5.495 31.349 1.00 46.89 ? ? ? ? ? ? 38 G R C6 1 31
+ATOM 1385 O O6 . G B 2 31 ? 28.487 -4.287 31.253 1.00 50.65 ? ? ? ? ? ? 38 G R O6 1 31
+ATOM 1386 N N1 . G B 2 31 ? 29.288 -6.412 31.307 1.00 47.83 ? ? ? ? ? ? 38 G R N1 1 31
+ATOM 1387 C C2 . G B 2 31 ? 29.143 -7.776 31.406 1.00 47.49 ? ? ? ? ? ? 38 G R C2 1 31
+ATOM 1388 N N2 . G B 2 31 ? 30.275 -8.493 31.341 1.00 47.67 ? ? ? ? ? ? 38 G R N2 1 31
+ATOM 1389 N N3 . G B 2 31 ? 27.970 -8.384 31.552 1.00 45.77 ? ? ? ? ? ? 38 G R N3 1 31
+ATOM 1390 C C4 . G B 2 31 ? 26.938 -7.498 31.599 1.00 45.82 ? ? ? ? ? ? 38 G R C4 1 31
+ATOM 1391 P P . U B 2 32 ? 24.162 -9.740 36.657 1.00 44.51 ? ? ? ? ? ? 39 U R P 1 32
+ATOM 1392 O OP1 . U B 2 32 ? 23.503 -10.743 37.528 1.00 43.82 ? ? ? ? ? ? 39 U R OP1 1 32
+ATOM 1393 O OP2 . U B 2 32 ? 23.692 -8.336 36.680 1.00 44.11 ? ? ? ? ? ? 39 U R OP2 1 32
+ATOM 1394 O "O5'" . U B 2 32 ? 25.740 -9.730 36.933 1.00 42.60 ? ? ? ? ? ? 39 U R "O5'" 1 32
+ATOM 1395 C "C5'" . U B 2 32 ? 26.491 -10.927 36.778 1.00 43.07 ? ? ? ? ? ? 39 U R "C5'" 1 32
+ATOM 1396 C "C4'" . U B 2 32 ? 27.958 -10.640 36.533 1.00 44.22 ? ? ? ? ? ? 39 U R "C4'" 1 32
+ATOM 1397 O "O4'" . U B 2 32 ? 28.141 -9.947 35.275 1.00 43.57 ? ? ? ? ? ? 39 U R "O4'" 1 32
+ATOM 1398 C "C3'" . U B 2 32 ? 28.603 -9.687 37.523 1.00 46.48 ? ? ? ? ? ? 39 U R "C3'" 1 32
+ATOM 1399 O "O3'" . U B 2 32 ? 28.866 -10.319 38.765 1.00 46.94 ? ? ? ? ? ? 39 U R "O3'" 1 32
+ATOM 1400 C "C2'" . U B 2 32 ? 29.858 -9.288 36.758 1.00 45.68 ? ? ? ? ? ? 39 U R "C2'" 1 32
+ATOM 1401 O "O2'" . U B 2 32 ? 30.836 -10.311 36.728 1.00 46.72 ? ? ? ? ? ? 39 U R "O2'" 1 32
+ATOM 1402 C "C1'" . U B 2 32 ? 29.259 -9.079 35.370 1.00 44.61 ? ? ? ? ? ? 39 U R "C1'" 1 32
+ATOM 1403 N N1 . U B 2 32 ? 28.846 -7.656 35.102 1.00 45.89 ? ? ? ? ? ? 39 U R N1 1 32
+ATOM 1404 C C2 . U B 2 32 ? 29.813 -6.712 34.788 1.00 47.86 ? ? ? ? ? ? 39 U R C2 1 32
+ATOM 1405 O O2 . U B 2 32 ? 31.004 -6.959 34.716 1.00 48.89 ? ? ? ? ? ? 39 U R O2 1 32
+ATOM 1406 N N3 . U B 2 32 ? 29.338 -5.439 34.562 1.00 48.50 ? ? ? ? ? ? 39 U R N3 1 32
+ATOM 1407 C C4 . U B 2 32 ? 28.021 -5.019 34.612 1.00 48.94 ? ? ? ? ? ? 39 U R C4 1 32
+ATOM 1408 O O4 . U B 2 32 ? 27.750 -3.845 34.385 1.00 50.10 ? ? ? ? ? ? 39 U R O4 1 32
+ATOM 1409 C C5 . U B 2 32 ? 27.069 -6.052 34.940 1.00 48.62 ? ? ? ? ? ? 39 U R C5 1 32
+ATOM 1410 C C6 . U B 2 32 ? 27.508 -7.299 35.166 1.00 47.17 ? ? ? ? ? ? 39 U R C6 1 32
+ATOM 1411 P P . G B 2 33 ? 28.661 -9.463 40.100 1.00 46.70 ? ? ? ? ? ? 40 G R P 1 33
+ATOM 1412 O OP1 . G B 2 33 ? 28.707 -10.400 41.245 1.00 48.42 ? ? ? ? ? ? 40 G R OP1 1 33
+ATOM 1413 O OP2 . G B 2 33 ? 27.484 -8.579 39.938 1.00 45.90 ? ? ? ? ? ? 40 G R OP2 1 33
+ATOM 1414 O "O5'" . G B 2 33 ? 29.970 -8.542 40.100 1.00 48.32 ? ? ? ? ? ? 40 G R "O5'" 1 33
+ATOM 1415 C "C5'" . G B 2 33 ? 31.266 -9.105 40.315 1.00 48.50 ? ? ? ? ? ? 40 G R "C5'" 1 33
+ATOM 1416 C "C4'" . G B 2 33 ? 32.356 -8.056 40.164 1.00 49.16 ? ? ? ? ? ? 40 G R "C4'" 1 33
+ATOM 1417 O "O4'" . G B 2 33 ? 32.432 -7.604 38.786 1.00 49.52 ? ? ? ? ? ? 40 G R "O4'" 1 33
+ATOM 1418 C "C3'" . G B 2 33 ? 32.154 -6.765 40.944 1.00 48.95 ? ? ? ? ? ? 40 G R "C3'" 1 33
+ATOM 1419 O "O3'" . G B 2 33 ? 32.509 -6.919 42.303 1.00 50.51 ? ? ? ? ? ? 40 G R "O3'" 1 33
+ATOM 1420 C "C2'" . G B 2 33 ? 33.104 -5.839 40.195 1.00 48.68 ? ? ? ? ? ? 40 G R "C2'" 1 33
+ATOM 1421 O "O2'" . G B 2 33 ? 34.470 -6.059 40.491 1.00 48.19 ? ? ? ? ? ? 40 G R "O2'" 1 33
+ATOM 1422 C "C1'" . G B 2 33 ? 32.784 -6.231 38.758 1.00 48.39 ? ? ? ? ? ? 40 G R "C1'" 1 33
+ATOM 1423 N N9 . G B 2 33 ? 31.682 -5.434 38.216 1.00 48.51 ? ? ? ? ? ? 40 G R N9 1 33
+ATOM 1424 C C8 . G B 2 33 ? 30.376 -5.822 38.028 1.00 47.85 ? ? ? ? ? ? 40 G R C8 1 33
+ATOM 1425 N N7 . G B 2 33 ? 29.621 -4.883 37.528 1.00 48.63 ? ? ? ? ? ? 40 G R N7 1 33
+ATOM 1426 C C5 . G B 2 33 ? 30.475 -3.797 37.376 1.00 48.23 ? ? ? ? ? ? 40 G R C5 1 33
+ATOM 1427 C C6 . G B 2 33 ? 30.225 -2.489 36.882 1.00 48.37 ? ? ? ? ? ? 40 G R C6 1 33
+ATOM 1428 O O6 . G B 2 33 ? 29.156 -2.019 36.462 1.00 48.86 ? ? ? ? ? ? 40 G R O6 1 33
+ATOM 1429 N N1 . G B 2 33 ? 31.373 -1.694 36.900 1.00 47.02 ? ? ? ? ? ? 40 G R N1 1 33
+ATOM 1430 C C2 . G B 2 33 ? 32.606 -2.111 37.342 1.00 46.42 ? ? ? ? ? ? 40 G R C2 1 33
+ATOM 1431 N N2 . G B 2 33 ? 33.599 -1.216 37.286 1.00 46.60 ? ? ? ? ? ? 40 G R N2 1 33
+ATOM 1432 N N3 . G B 2 33 ? 32.852 -3.328 37.807 1.00 46.58 ? ? ? ? ? ? 40 G R N3 1 33
+ATOM 1433 C C4 . G B 2 33 ? 31.747 -4.119 37.800 1.00 48.20 ? ? ? ? ? ? 40 G R C4 1 33
+ATOM 1434 P P . G B 2 34 ? 31.803 -6.020 43.428 1.00 51.79 ? ? ? ? ? ? 41 G R P 1 34
+ATOM 1435 O OP1 . G B 2 34 ? 32.238 -6.556 44.736 1.00 50.89 ? ? ? ? ? ? 41 G R OP1 1 34
+ATOM 1436 O OP2 . G B 2 34 ? 30.356 -5.903 43.125 1.00 49.31 ? ? ? ? ? ? 41 G R OP2 1 34
+ATOM 1437 O "O5'" . G B 2 34 ? 32.464 -4.579 43.213 1.00 50.20 ? ? ? ? ? ? 41 G R "O5'" 1 34
+ATOM 1438 C "C5'" . G B 2 34 ? 33.840 -4.359 43.502 1.00 50.09 ? ? ? ? ? ? 41 G R "C5'" 1 34
+ATOM 1439 C "C4'" . G B 2 34 ? 34.306 -3.012 42.972 1.00 49.58 ? ? ? ? ? ? 41 G R "C4'" 1 34
+ATOM 1440 O "O4'" . G B 2 34 ? 34.019 -2.884 41.553 1.00 49.09 ? ? ? ? ? ? 41 G R "O4'" 1 34
+ATOM 1441 C "C3'" . G B 2 34 ? 33.620 -1.787 43.554 1.00 49.25 ? ? ? ? ? ? 41 G R "C3'" 1 34
+ATOM 1442 O "O3'" . G B 2 34 ? 34.098 -1.482 44.854 1.00 49.30 ? ? ? ? ? ? 41 G R "O3'" 1 34
+ATOM 1443 C "C2'" . G B 2 34 ? 34.043 -0.744 42.525 1.00 48.28 ? ? ? ? ? ? 41 G R "C2'" 1 34
+ATOM 1444 O "O2'" . G B 2 34 ? 35.415 -0.410 42.617 1.00 48.44 ? ? ? ? ? ? 41 G R "O2'" 1 34
+ATOM 1445 C "C1'" . G B 2 34 ? 33.779 -1.519 41.242 1.00 46.85 ? ? ? ? ? ? 41 G R "C1'" 1 34
+ATOM 1446 N N9 . G B 2 34 ? 32.419 -1.360 40.725 1.00 45.11 ? ? ? ? ? ? 41 G R N9 1 34
+ATOM 1447 C C8 . G B 2 34 ? 31.414 -2.297 40.746 1.00 44.97 ? ? ? ? ? ? 41 G R C8 1 34
+ATOM 1448 N N7 . G B 2 34 ? 30.299 -1.887 40.208 1.00 45.13 ? ? ? ? ? ? 41 G R N7 1 34
+ATOM 1449 C C5 . G B 2 34 ? 30.577 -0.591 39.798 1.00 44.76 ? ? ? ? ? ? 41 G R C5 1 34
+ATOM 1450 C C6 . G B 2 34 ? 29.745 0.356 39.145 1.00 45.41 ? ? ? ? ? ? 41 G R C6 1 34
+ATOM 1451 O O6 . G B 2 34 ? 28.562 0.230 38.792 1.00 45.47 ? ? ? ? ? ? 41 G R O6 1 34
+ATOM 1452 N N1 . G B 2 34 ? 30.412 1.556 38.903 1.00 44.98 ? ? ? ? ? ? 41 G R N1 1 34
+ATOM 1453 C C2 . G B 2 34 ? 31.720 1.805 39.249 1.00 44.31 ? ? ? ? ? ? 41 G R C2 1 34
+ATOM 1454 N N2 . G B 2 34 ? 32.189 3.020 38.933 1.00 44.23 ? ? ? ? ? ? 41 G R N2 1 34
+ATOM 1455 N N3 . G B 2 34 ? 32.511 0.925 39.859 1.00 43.72 ? ? ? ? ? ? 41 G R N3 1 34
+ATOM 1456 C C4 . G B 2 34 ? 31.878 -0.250 40.107 1.00 44.73 ? ? ? ? ? ? 41 G R C4 1 34
+ATOM 1457 P P . G B 2 35 ? 33.143 -0.770 45.924 1.00 51.11 ? ? ? ? ? ? 42 G R P 1 35
+ATOM 1458 O OP1 . G B 2 35 ? 34.010 -0.259 47.009 1.00 51.05 ? ? ? ? ? ? 42 G R OP1 1 35
+ATOM 1459 O OP2 . G B 2 35 ? 32.031 -1.698 46.228 1.00 51.32 ? ? ? ? ? ? 42 G R OP2 1 35
+ATOM 1460 O "O5'" . G B 2 35 ? 32.483 0.459 45.142 1.00 50.76 ? ? ? ? ? ? 42 G R "O5'" 1 35
+ATOM 1461 C "C5'" . G B 2 35 ? 33.118 1.726 45.039 1.00 50.33 ? ? ? ? ? ? 42 G R "C5'" 1 35
+ATOM 1462 C "C4'" . G B 2 35 ? 32.195 2.676 44.298 1.00 50.72 ? ? ? ? ? ? 42 G R "C4'" 1 35
+ATOM 1463 O "O4'" . G B 2 35 ? 31.640 2.016 43.131 1.00 48.78 ? ? ? ? ? ? 42 G R "O4'" 1 35
+ATOM 1464 C "C3'" . G B 2 35 ? 30.989 3.122 45.107 1.00 50.26 ? ? ? ? ? ? 42 G R "C3'" 1 35
+ATOM 1465 O "O3'" . G B 2 35 ? 31.354 4.266 45.871 1.00 51.31 ? ? ? ? ? ? 42 G R "O3'" 1 35
+ATOM 1466 C "C2'" . G B 2 35 ? 29.963 3.436 44.019 1.00 49.86 ? ? ? ? ? ? 42 G R "C2'" 1 35
+ATOM 1467 O "O2'" . G B 2 35 ? 30.077 4.753 43.515 1.00 51.59 ? ? ? ? ? ? 42 G R "O2'" 1 35
+ATOM 1468 C "C1'" . G B 2 35 ? 30.307 2.435 42.919 1.00 47.89 ? ? ? ? ? ? 42 G R "C1'" 1 35
+ATOM 1469 N N9 . G B 2 35 ? 29.436 1.259 42.894 1.00 45.85 ? ? ? ? ? ? 42 G R N9 1 35
+ATOM 1470 C C8 . G B 2 35 ? 29.644 0.068 43.546 1.00 45.91 ? ? ? ? ? ? 42 G R C8 1 35
+ATOM 1471 N N7 . G B 2 35 ? 28.701 -0.809 43.340 1.00 45.51 ? ? ? ? ? ? 42 G R N7 1 35
+ATOM 1472 C C5 . G B 2 35 ? 27.806 -0.163 42.499 1.00 43.67 ? ? ? ? ? ? 42 G R C5 1 35
+ATOM 1473 C C6 . G B 2 35 ? 26.584 -0.620 41.937 1.00 44.02 ? ? ? ? ? ? 42 G R C6 1 35
+ATOM 1474 O O6 . G B 2 35 ? 26.033 -1.723 42.075 1.00 43.11 ? ? ? ? ? ? 42 G R O6 1 35
+ATOM 1475 N N1 . G B 2 35 ? 25.986 0.349 41.135 1.00 43.67 ? ? ? ? ? ? 42 G R N1 1 35
+ATOM 1476 C C2 . G B 2 35 ? 26.507 1.603 40.910 1.00 43.58 ? ? ? ? ? ? 42 G R C2 1 35
+ATOM 1477 N N2 . G B 2 35 ? 25.791 2.408 40.110 1.00 44.89 ? ? ? ? ? ? 42 G R N2 1 35
+ATOM 1478 N N3 . G B 2 35 ? 27.647 2.038 41.433 1.00 41.86 ? ? ? ? ? ? 42 G R N3 1 35
+ATOM 1479 C C4 . G B 2 35 ? 28.245 1.111 42.216 1.00 42.98 ? ? ? ? ? ? 42 G R C4 1 35
+ATOM 1480 P P . A B 2 36 ? 30.465 4.786 47.100 1.00 52.33 ? ? ? ? ? ? 43 A R P 1 36
+ATOM 1481 O OP1 . A B 2 36 ? 31.357 5.592 47.961 1.00 53.58 ? ? ? ? ? ? 43 A R OP1 1 36
+ATOM 1482 O OP2 . A B 2 36 ? 29.712 3.644 47.664 1.00 52.58 ? ? ? ? ? ? 43 A R OP2 1 36
+ATOM 1483 O "O5'" . A B 2 36 ? 29.419 5.771 46.416 1.00 51.77 ? ? ? ? ? ? 43 A R "O5'" 1 36
+ATOM 1484 C "C5'" . A B 2 36 ? 28.291 6.189 47.152 1.00 52.46 ? ? ? ? ? ? 43 A R "C5'" 1 36
+ATOM 1485 C "C4'" . A B 2 36 ? 27.107 6.418 46.229 1.00 52.39 ? ? ? ? ? ? 43 A R "C4'" 1 36
+ATOM 1486 O "O4'" . A B 2 36 ? 26.932 5.274 45.353 1.00 50.60 ? ? ? ? ? ? 43 A R "O4'" 1 36
+ATOM 1487 C "C3'" . A B 2 36 ? 25.786 6.619 46.960 1.00 52.71 ? ? ? ? ? ? 43 A R "C3'" 1 36
+ATOM 1488 O "O3'" . A B 2 36 ? 25.046 7.652 46.335 1.00 55.18 ? ? ? ? ? ? 43 A R "O3'" 1 36
+ATOM 1489 C "C2'" . A B 2 36 ? 25.077 5.277 46.795 1.00 53.30 ? ? ? ? ? ? 43 A R "C2'" 1 36
+ATOM 1490 O "O2'" . A B 2 36 ? 23.668 5.412 46.769 1.00 54.56 ? ? ? ? ? ? 43 A R "O2'" 1 36
+ATOM 1491 C "C1'" . A B 2 36 ? 25.595 4.819 45.434 1.00 51.94 ? ? ? ? ? ? 43 A R "C1'" 1 36
+ATOM 1492 N N9 . A B 2 36 ? 25.561 3.371 45.210 1.00 50.70 ? ? ? ? ? ? 43 A R N9 1 36
+ATOM 1493 C C8 . A B 2 36 ? 24.875 2.734 44.212 1.00 50.32 ? ? ? ? ? ? 43 A R C8 1 36
+ATOM 1494 N N7 . A B 2 36 ? 25.004 1.430 44.217 1.00 49.68 ? ? ? ? ? ? 43 A R N7 1 36
+ATOM 1495 C C5 . A B 2 36 ? 25.836 1.189 45.295 1.00 50.21 ? ? ? ? ? ? 43 A R C5 1 36
+ATOM 1496 C C6 . A B 2 36 ? 26.363 -0.004 45.837 1.00 50.79 ? ? ? ? ? ? 43 A R C6 1 36
+ATOM 1497 N N6 . A B 2 36 ? 26.095 -1.208 45.326 1.00 49.84 ? ? ? ? ? ? 43 A R N6 1 36
+ATOM 1498 N N1 . A B 2 36 ? 27.174 0.088 46.920 1.00 52.32 ? ? ? ? ? ? 43 A R N1 1 36
+ATOM 1499 C C2 . A B 2 36 ? 27.437 1.304 47.428 1.00 51.59 ? ? ? ? ? ? 43 A R C2 1 36
+ATOM 1500 N N3 . A B 2 36 ? 26.996 2.494 47.001 1.00 51.17 ? ? ? ? ? ? 43 A R N3 1 36
+ATOM 1501 C C4 . A B 2 36 ? 26.194 2.372 45.922 1.00 50.16 ? ? ? ? ? ? 43 A R C4 1 36
+ATOM 1502 P P . C B 2 37 ? 25.237 9.201 46.692 1.00 57.03 ? ? ? ? ? ? 44 C R P 1 37
+ATOM 1503 O OP1 . C B 2 37 ? 26.222 9.752 45.727 1.00 56.12 ? ? ? ? ? ? 44 C R OP1 1 37
+ATOM 1504 O OP2 . C B 2 37 ? 25.474 9.358 48.148 1.00 56.22 ? ? ? ? ? ? 44 C R OP2 1 37
+ATOM 1505 O "O5'" . C B 2 37 ? 23.757 9.735 46.387 1.00 52.44 ? ? ? ? ? ? 44 C R "O5'" 1 37
+ATOM 1506 C "C5'" . C B 2 37 ? 23.516 10.797 45.483 1.00 48.40 ? ? ? ? ? ? 44 C R "C5'" 1 37
+ATOM 1507 C "C4'" . C B 2 37 ? 22.333 10.492 44.584 1.00 44.93 ? ? ? ? ? ? 44 C R "C4'" 1 37
+ATOM 1508 O "O4'" . C B 2 37 ? 22.527 9.245 43.881 1.00 44.65 ? ? ? ? ? ? 44 C R "O4'" 1 37
+ATOM 1509 C "C3'" . C B 2 37 ? 21.002 10.214 45.256 1.00 44.11 ? ? ? ? ? ? 44 C R "C3'" 1 37
+ATOM 1510 O "O3'" . C B 2 37 ? 20.425 11.371 45.832 1.00 44.49 ? ? ? ? ? ? 44 C R "O3'" 1 37
+ATOM 1511 C "C2'" . C B 2 37 ? 20.219 9.714 44.049 1.00 44.48 ? ? ? ? ? ? 44 C R "C2'" 1 37
+ATOM 1512 O "O2'" . C B 2 37 ? 19.804 10.730 43.161 1.00 45.65 ? ? ? ? ? ? 44 C R "O2'" 1 37
+ATOM 1513 C "C1'" . C B 2 37 ? 21.265 8.852 43.354 1.00 44.25 ? ? ? ? ? ? 44 C R "C1'" 1 37
+ATOM 1514 N N1 . C B 2 37 ? 21.016 7.375 43.529 1.00 43.78 ? ? ? ? ? ? 44 C R N1 1 37
+ATOM 1515 C C2 . C B 2 37 ? 19.950 6.749 42.847 1.00 42.83 ? ? ? ? ? ? 44 C R C2 1 37
+ATOM 1516 O O2 . C B 2 37 ? 19.214 7.405 42.099 1.00 41.60 ? ? ? ? ? ? 44 C R O2 1 37
+ATOM 1517 N N3 . C B 2 37 ? 19.746 5.418 43.026 1.00 42.89 ? ? ? ? ? ? 44 C R N3 1 37
+ATOM 1518 C C4 . C B 2 37 ? 20.551 4.718 43.833 1.00 43.67 ? ? ? ? ? ? 44 C R C4 1 37
+ATOM 1519 N N4 . C B 2 37 ? 20.313 3.410 43.972 1.00 44.22 ? ? ? ? ? ? 44 C R N4 1 37
+ATOM 1520 C C5 . C B 2 37 ? 21.637 5.328 44.536 1.00 43.51 ? ? ? ? ? ? 44 C R C5 1 37
+ATOM 1521 C C6 . C B 2 37 ? 21.829 6.642 44.358 1.00 43.72 ? ? ? ? ? ? 44 C R C6 1 37
+ATOM 1522 P P . G B 2 38 ? 19.380 11.223 47.042 1.00 45.07 ? ? ? ? ? ? 45 G R P 1 38
+ATOM 1523 O OP1 . G B 2 38 ? 19.337 12.529 47.735 1.00 41.50 ? ? ? ? ? ? 45 G R OP1 1 38
+ATOM 1524 O OP2 . G B 2 38 ? 19.689 9.972 47.783 1.00 43.11 ? ? ? ? ? ? 45 G R OP2 1 38
+ATOM 1525 O "O5'" . G B 2 38 ? 17.977 11.024 46.304 1.00 43.44 ? ? ? ? ? ? 45 G R "O5'" 1 38
+ATOM 1526 C "C5'" . G B 2 38 ? 16.994 10.169 46.858 1.00 43.41 ? ? ? ? ? ? 45 G R "C5'" 1 38
+ATOM 1527 C "C4'" . G B 2 38 ? 16.637 9.089 45.854 1.00 44.48 ? ? ? ? ? ? 45 G R "C4'" 1 38
+ATOM 1528 O "O4'" . G B 2 38 ? 17.831 8.359 45.475 1.00 44.34 ? ? ? ? ? ? 45 G R "O4'" 1 38
+ATOM 1529 C "C3'" . G B 2 38 ? 15.686 8.032 46.387 1.00 43.37 ? ? ? ? ? ? 45 G R "C3'" 1 38
+ATOM 1530 O "O3'" . G B 2 38 ? 14.328 8.451 46.218 1.00 42.53 ? ? ? ? ? ? 45 G R "O3'" 1 38
+ATOM 1531 C "C2'" . G B 2 38 ? 16.048 6.823 45.535 1.00 42.65 ? ? ? ? ? ? 45 G R "C2'" 1 38
+ATOM 1532 O "O2'" . G B 2 38 ? 15.456 6.887 44.256 1.00 42.86 ? ? ? ? ? ? 45 G R "O2'" 1 38
+ATOM 1533 C "C1'" . G B 2 38 ? 17.561 6.970 45.399 1.00 43.55 ? ? ? ? ? ? 45 G R "C1'" 1 38
+ATOM 1534 N N9 . G B 2 38 ? 18.374 6.268 46.403 1.00 44.12 ? ? ? ? ? ? 45 G R N9 1 38
+ATOM 1535 C C8 . G B 2 38 ? 19.247 6.824 47.314 1.00 43.89 ? ? ? ? ? ? 45 G R C8 1 38
+ATOM 1536 N N7 . G B 2 38 ? 19.846 5.956 48.083 1.00 42.13 ? ? ? ? ? ? 45 G R N7 1 38
+ATOM 1537 C C5 . G B 2 38 ? 19.341 4.740 47.653 1.00 42.81 ? ? ? ? ? ? 45 G R C5 1 38
+ATOM 1538 C C6 . G B 2 38 ? 19.618 3.431 48.112 1.00 44.14 ? ? ? ? ? ? 45 G R C6 1 38
+ATOM 1539 O O6 . G B 2 38 ? 20.391 3.095 49.024 1.00 45.94 ? ? ? ? ? ? 45 G R O6 1 38
+ATOM 1540 N N1 . G B 2 38 ? 18.898 2.464 47.403 1.00 44.37 ? ? ? ? ? ? 45 G R N1 1 38
+ATOM 1541 C C2 . G B 2 38 ? 18.012 2.738 46.383 1.00 44.72 ? ? ? ? ? ? 45 G R C2 1 38
+ATOM 1542 N N2 . G B 2 38 ? 17.398 1.695 45.808 1.00 44.15 ? ? ? ? ? ? 45 G R N2 1 38
+ATOM 1543 N N3 . G B 2 38 ? 17.745 3.963 45.948 1.00 44.64 ? ? ? ? ? ? 45 G R N3 1 38
+ATOM 1544 C C4 . G B 2 38 ? 18.442 4.911 46.622 1.00 43.43 ? ? ? ? ? ? 45 G R C4 1 38
+ATOM 1545 P P . C B 2 39 ? 13.264 8.018 47.333 1.00 42.35 ? ? ? ? ? ? 46 C R P 1 39
+ATOM 1546 O OP1 . C B 2 39 ? 11.995 8.754 47.122 1.00 38.48 ? ? ? ? ? ? 46 C R OP1 1 39
+ATOM 1547 O OP2 . C B 2 39 ? 13.968 8.074 48.638 1.00 42.04 ? ? ? ? ? ? 46 C R OP2 1 39
+ATOM 1548 O "O5'" . C B 2 39 ? 13.038 6.474 46.998 1.00 42.35 ? ? ? ? ? ? 46 C R "O5'" 1 39
+ATOM 1549 C "C5'" . C B 2 39 ? 12.257 6.057 45.884 1.00 42.72 ? ? ? ? ? ? 46 C R "C5'" 1 39
+ATOM 1550 C "C4'" . C B 2 39 ? 12.267 4.541 45.826 1.00 43.56 ? ? ? ? ? ? 46 C R "C4'" 1 39
+ATOM 1551 O "O4'" . C B 2 39 ? 13.642 4.107 45.882 1.00 43.58 ? ? ? ? ? ? 46 C R "O4'" 1 39
+ATOM 1552 C "C3'" . C B 2 39 ? 11.637 3.825 47.011 1.00 43.82 ? ? ? ? ? ? 46 C R "C3'" 1 39
+ATOM 1553 O "O3'" . C B 2 39 ? 10.237 3.694 46.849 1.00 44.65 ? ? ? ? ? ? 46 C R "O3'" 1 39
+ATOM 1554 C "C2'" . C B 2 39 ? 12.327 2.470 46.977 1.00 43.64 ? ? ? ? ? ? 46 C R "C2'" 1 39
+ATOM 1555 O "O2'" . C B 2 39 ? 11.742 1.570 46.058 1.00 46.61 ? ? ? ? ? ? 46 C R "O2'" 1 39
+ATOM 1556 C "C1'" . C B 2 39 ? 13.730 2.844 46.514 1.00 43.43 ? ? ? ? ? ? 46 C R "C1'" 1 39
+ATOM 1557 N N1 . C B 2 39 ? 14.734 2.898 47.622 1.00 41.58 ? ? ? ? ? ? 46 C R N1 1 39
+ATOM 1558 C C2 . C B 2 39 ? 15.249 1.701 48.143 1.00 42.96 ? ? ? ? ? ? 46 C R C2 1 39
+ATOM 1559 O O2 . C B 2 39 ? 14.870 0.617 47.677 1.00 43.48 ? ? ? ? ? ? 46 C R O2 1 39
+ATOM 1560 N N3 . C B 2 39 ? 16.159 1.760 49.152 1.00 43.65 ? ? ? ? ? ? 46 C R N3 1 39
+ATOM 1561 C C4 . C B 2 39 ? 16.546 2.943 49.633 1.00 43.09 ? ? ? ? ? ? 46 C R C4 1 39
+ATOM 1562 N N4 . C B 2 39 ? 17.441 2.953 50.626 1.00 43.69 ? ? ? ? ? ? 46 C R N4 1 39
+ATOM 1563 C C5 . C B 2 39 ? 16.030 4.170 49.113 1.00 43.36 ? ? ? ? ? ? 46 C R C5 1 39
+ATOM 1564 C C6 . C B 2 39 ? 15.136 4.101 48.121 1.00 41.05 ? ? ? ? ? ? 46 C R C6 1 39
+ATOM 1565 P P . A B 2 40 ? 9.259 4.280 47.969 1.00 44.44 ? ? ? ? ? ? 47 A R P 1 40
+ATOM 1566 O OP1 . A B 2 40 ? 8.289 5.159 47.280 1.00 43.91 ? ? ? ? ? ? 47 A R OP1 1 40
+ATOM 1567 O OP2 . A B 2 40 ? 10.102 4.809 49.066 1.00 43.82 ? ? ? ? ? ? 47 A R OP2 1 40
+ATOM 1568 O "O5'" . A B 2 40 ? 8.477 2.990 48.507 1.00 45.10 ? ? ? ? ? ? 47 A R "O5'" 1 40
+ATOM 1569 C "C5'" . A B 2 40 ? 9.176 1.947 49.190 1.00 46.36 ? ? ? ? ? ? 47 A R "C5'" 1 40
+ATOM 1570 C "C4'" . A B 2 40 ? 8.270 0.766 49.515 1.00 47.32 ? ? ? ? ? ? 47 A R "C4'" 1 40
+ATOM 1571 O "O4'" . A B 2 40 ? 8.989 -0.183 50.342 1.00 47.90 ? ? ? ? ? ? 47 A R "O4'" 1 40
+ATOM 1572 C "C3'" . A B 2 40 ? 7.010 1.057 50.317 1.00 47.66 ? ? ? ? ? ? 47 A R "C3'" 1 40
+ATOM 1573 O "O3'" . A B 2 40 ? 6.108 -0.014 50.173 1.00 48.86 ? ? ? ? ? ? 47 A R "O3'" 1 40
+ATOM 1574 C "C2'" . A B 2 40 ? 7.550 1.018 51.735 1.00 47.93 ? ? ? ? ? ? 47 A R "C2'" 1 40
+ATOM 1575 O "O2'" . A B 2 40 ? 6.521 0.826 52.682 1.00 49.51 ? ? ? ? ? ? 47 A R "O2'" 1 40
+ATOM 1576 C "C1'" . A B 2 40 ? 8.435 -0.222 51.646 1.00 47.50 ? ? ? ? ? ? 47 A R "C1'" 1 40
+ATOM 1577 N N9 . A B 2 40 ? 9.542 -0.298 52.602 1.00 47.73 ? ? ? ? ? ? 47 A R N9 1 40
+ATOM 1578 C C8 . A B 2 40 ? 10.145 0.737 53.264 1.00 47.31 ? ? ? ? ? ? 47 A R C8 1 40
+ATOM 1579 N N7 . A B 2 40 ? 11.122 0.359 54.054 1.00 48.47 ? ? ? ? ? ? 47 A R N7 1 40
+ATOM 1580 C C5 . A B 2 40 ? 11.166 -1.014 53.906 1.00 45.96 ? ? ? ? ? ? 47 A R C5 1 40
+ATOM 1581 C C6 . A B 2 40 ? 11.986 -2.006 54.482 1.00 46.35 ? ? ? ? ? ? 47 A R C6 1 40
+ATOM 1582 N N6 . A B 2 40 ? 12.957 -1.735 55.360 1.00 46.71 ? ? ? ? ? ? 47 A R N6 1 40
+ATOM 1583 N N1 . A B 2 40 ? 11.772 -3.292 54.123 1.00 47.25 ? ? ? ? ? ? 47 A R N1 1 40
+ATOM 1584 C C2 . A B 2 40 ? 10.796 -3.560 53.242 1.00 47.77 ? ? ? ? ? ? 47 A R C2 1 40
+ATOM 1585 N N3 . A B 2 40 ? 9.962 -2.710 52.636 1.00 47.19 ? ? ? ? ? ? 47 A R N3 1 40
+ATOM 1586 C C4 . A B 2 40 ? 10.202 -1.439 53.012 1.00 46.72 ? ? ? ? ? ? 47 A R C4 1 40
+ATOM 1587 P P . A B 2 41 ? 4.955 -0.091 49.076 1.00 51.51 ? ? ? ? ? ? 48 A R P 1 41
+ATOM 1588 O OP1 . A B 2 41 ? 5.265 0.820 47.948 1.00 51.90 ? ? ? ? ? ? 48 A R OP1 1 41
+ATOM 1589 O OP2 . A B 2 41 ? 3.646 0.007 49.757 1.00 52.49 ? ? ? ? ? ? 48 A R OP2 1 41
+ATOM 1590 O "O5'" . A B 2 41 ? 5.117 -1.628 48.662 1.00 51.05 ? ? ? ? ? ? 48 A R "O5'" 1 41
+ATOM 1591 C "C5'" . A B 2 41 ? 5.581 -2.012 47.387 1.00 48.96 ? ? ? ? ? ? 48 A R "C5'" 1 41
+ATOM 1592 C "C4'" . A B 2 41 ? 7.076 -2.256 47.406 1.00 47.63 ? ? ? ? ? ? 48 A R "C4'" 1 41
+ATOM 1593 O "O4'" . A B 2 41 ? 7.366 -3.557 47.994 1.00 47.54 ? ? ? ? ? ? 48 A R "O4'" 1 41
+ATOM 1594 C "C3'" . A B 2 41 ? 7.670 -2.294 46.000 1.00 48.38 ? ? ? ? ? ? 48 A R "C3'" 1 41
+ATOM 1595 O "O3'" . A B 2 41 ? 8.953 -1.683 45.942 1.00 47.50 ? ? ? ? ? ? 48 A R "O3'" 1 41
+ATOM 1596 C "C2'" . A B 2 41 ? 7.764 -3.785 45.722 1.00 47.48 ? ? ? ? ? ? 48 A R "C2'" 1 41
+ATOM 1597 O "O2'" . A B 2 41 ? 8.712 -4.111 44.727 1.00 47.73 ? ? ? ? ? ? 48 A R "O2'" 1 41
+ATOM 1598 C "C1'" . A B 2 41 ? 8.217 -4.251 47.099 1.00 46.30 ? ? ? ? ? ? 48 A R "C1'" 1 41
+ATOM 1599 N N9 . A B 2 41 ? 8.131 -5.703 47.214 1.00 44.07 ? ? ? ? ? ? 48 A R N9 1 41
+ATOM 1600 C C8 . A B 2 41 ? 7.038 -6.496 46.986 1.00 43.97 ? ? ? ? ? ? 48 A R C8 1 41
+ATOM 1601 N N7 . A B 2 41 ? 7.279 -7.776 47.136 1.00 43.91 ? ? ? ? ? ? 48 A R N7 1 41
+ATOM 1602 C C5 . A B 2 41 ? 8.622 -7.823 47.479 1.00 41.25 ? ? ? ? ? ? 48 A R C5 1 41
+ATOM 1603 C C6 . A B 2 41 ? 9.493 -8.888 47.778 1.00 40.57 ? ? ? ? ? ? 48 A R C6 1 41
+ATOM 1604 N N6 . A B 2 41 ? 9.103 -10.165 47.777 1.00 41.36 ? ? ? ? ? ? 48 A R N6 1 41
+ATOM 1605 N N1 . A B 2 41 ? 10.780 -8.596 48.082 1.00 41.01 ? ? ? ? ? ? 48 A R N1 1 41
+ATOM 1606 C C2 . A B 2 41 ? 11.169 -7.314 48.087 1.00 40.88 ? ? ? ? ? ? 48 A R C2 1 41
+ATOM 1607 N N3 . A B 2 41 ? 10.439 -6.228 47.823 1.00 41.29 ? ? ? ? ? ? 48 A R N3 1 41
+ATOM 1608 C C4 . A B 2 41 ? 9.166 -6.554 47.527 1.00 41.82 ? ? ? ? ? ? 48 A R C4 1 41
+ATOM 1609 P P . A B 2 42 ? 9.244 -0.667 44.749 1.00 47.34 ? ? ? ? ? ? 49 A R P 1 42
+ATOM 1610 O OP1 . A B 2 42 ? 9.187 0.705 45.299 1.00 47.04 ? ? ? ? ? ? 49 A R OP1 1 42
+ATOM 1611 O OP2 . A B 2 42 ? 8.388 -1.041 43.595 1.00 47.35 ? ? ? ? ? ? 49 A R OP2 1 42
+ATOM 1612 O "O5'" . A B 2 42 ? 10.757 -1.007 44.375 1.00 47.41 ? ? ? ? ? ? 49 A R "O5'" 1 42
+ATOM 1613 C "C5'" . A B 2 42 ? 11.069 -2.228 43.707 1.00 46.93 ? ? ? ? ? ? 49 A R "C5'" 1 42
+ATOM 1614 C "C4'" . A B 2 42 ? 12.558 -2.330 43.426 1.00 45.41 ? ? ? ? ? ? 49 A R "C4'" 1 42
+ATOM 1615 O "O4'" . A B 2 42 ? 12.939 -1.251 42.542 1.00 45.25 ? ? ? ? ? ? 49 A R "O4'" 1 42
+ATOM 1616 C "C3'" . A B 2 42 ? 13.487 -2.228 44.632 1.00 45.51 ? ? ? ? ? ? 49 A R "C3'" 1 42
+ATOM 1617 O "O3'" . A B 2 42 ? 14.614 -3.079 44.421 1.00 46.52 ? ? ? ? ? ? 49 A R "O3'" 1 42
+ATOM 1618 C "C2'" . A B 2 42 ? 13.887 -0.751 44.666 1.00 44.48 ? ? ? ? ? ? 49 A R "C2'" 1 42
+ATOM 1619 O "O2'" . A B 2 42 ? 15.206 -0.573 45.143 1.00 44.52 ? ? ? ? ? ? 49 A R "O2'" 1 42
+ATOM 1620 C "C1'" . A B 2 42 ? 13.820 -0.356 43.193 1.00 43.80 ? ? ? ? ? ? 49 A R "C1'" 1 42
+ATOM 1621 N N9 . A B 2 42 ? 13.351 0.999 42.903 1.00 42.51 ? ? ? ? ? ? 49 A R N9 1 42
+ATOM 1622 C C8 . A B 2 42 ? 12.136 1.356 42.382 1.00 42.71 ? ? ? ? ? ? 49 A R C8 1 42
+ATOM 1623 N N7 . A B 2 42 ? 11.991 2.649 42.202 1.00 41.67 ? ? ? ? ? ? 49 A R N7 1 42
+ATOM 1624 C C5 . A B 2 42 ? 13.195 3.175 42.631 1.00 40.69 ? ? ? ? ? ? 49 A R C5 1 42
+ATOM 1625 C C6 . A B 2 42 ? 13.685 4.495 42.700 1.00 40.78 ? ? ? ? ? ? 49 A R C6 1 42
+ATOM 1626 N N6 . A B 2 42 ? 12.985 5.567 42.328 1.00 41.62 ? ? ? ? ? ? 49 A R N6 1 42
+ATOM 1627 N N1 . A B 2 42 ? 14.931 4.682 43.177 1.00 41.13 ? ? ? ? ? ? 49 A R N1 1 42
+ATOM 1628 C C2 . A B 2 42 ? 15.643 3.613 43.564 1.00 42.39 ? ? ? ? ? ? 49 A R C2 1 42
+ATOM 1629 N N3 . A B 2 42 ? 15.294 2.325 43.544 1.00 41.56 ? ? ? ? ? ? 49 A R N3 1 42
+ATOM 1630 C C4 . A B 2 42 ? 14.047 2.172 43.061 1.00 41.16 ? ? ? ? ? ? 49 A R C4 1 42
+ATOM 1631 P P . G B 2 43 ? 14.830 -4.432 45.254 1.00 46.95 ? ? ? ? ? ? 50 G R P 1 43
+ATOM 1632 O OP1 . G B 2 43 ? 14.915 -4.082 46.690 1.00 47.70 ? ? ? ? ? ? 50 G R OP1 1 43
+ATOM 1633 O OP2 . G B 2 43 ? 15.952 -5.166 44.622 1.00 45.67 ? ? ? ? ? ? 50 G R OP2 1 43
+ATOM 1634 O "O5'" . G B 2 43 ? 13.472 -5.244 44.996 1.00 44.47 ? ? ? ? ? ? 50 G R "O5'" 1 43
+ATOM 1635 C "C5'" . G B 2 43 ? 13.208 -5.853 43.740 1.00 43.48 ? ? ? ? ? ? 50 G R "C5'" 1 43
+ATOM 1636 C "C4'" . G B 2 43 ? 13.210 -7.362 43.866 1.00 43.27 ? ? ? ? ? ? 50 G R "C4'" 1 43
+ATOM 1637 O "O4'" . G B 2 43 ? 12.263 -7.755 44.893 1.00 42.53 ? ? ? ? ? ? 50 G R "O4'" 1 43
+ATOM 1638 C "C3'" . G B 2 43 ? 12.767 -8.102 42.612 1.00 43.46 ? ? ? ? ? ? 50 G R "C3'" 1 43
+ATOM 1639 O "O3'" . G B 2 43 ? 13.883 -8.375 41.771 1.00 44.99 ? ? ? ? ? ? 50 G R "O3'" 1 43
+ATOM 1640 C "C2'" . G B 2 43 ? 12.169 -9.379 43.192 1.00 42.91 ? ? ? ? ? ? 50 G R "C2'" 1 43
+ATOM 1641 O "O2'" . G B 2 43 ? 13.156 -10.333 43.534 1.00 44.03 ? ? ? ? ? ? 50 G R "O2'" 1 43
+ATOM 1642 C "C1'" . G B 2 43 ? 11.483 -8.853 44.452 1.00 41.18 ? ? ? ? ? ? 50 G R "C1'" 1 43
+ATOM 1643 N N9 . G B 2 43 ? 10.107 -8.406 44.233 1.00 38.70 ? ? ? ? ? ? 50 G R N9 1 43
+ATOM 1644 C C8 . G B 2 43 ? 9.642 -7.114 44.307 1.00 37.65 ? ? ? ? ? ? 50 G R C8 1 43
+ATOM 1645 N N7 . G B 2 43 ? 8.365 -7.003 44.066 1.00 37.68 ? ? ? ? ? ? 50 G R N7 1 43
+ATOM 1646 C C5 . G B 2 43 ? 7.953 -8.303 43.810 1.00 36.40 ? ? ? ? ? ? 50 G R C5 1 43
+ATOM 1647 C C6 . G B 2 43 ? 6.671 -8.804 43.477 1.00 37.05 ? ? ? ? ? ? 50 G R C6 1 43
+ATOM 1648 O O6 . G B 2 43 ? 5.614 -8.173 43.342 1.00 37.59 ? ? ? ? ? ? 50 G R O6 1 43
+ATOM 1649 N N1 . G B 2 43 ? 6.674 -10.185 43.290 1.00 37.48 ? ? ? ? ? ? 50 G R N1 1 43
+ATOM 1650 C C2 . G B 2 43 ? 7.787 -10.980 43.413 1.00 38.03 ? ? ? ? ? ? 50 G R C2 1 43
+ATOM 1651 N N2 . G B 2 43 ? 7.598 -12.288 43.199 1.00 40.53 ? ? ? ? ? ? 50 G R N2 1 43
+ATOM 1652 N N3 . G B 2 43 ? 8.997 -10.524 43.721 1.00 37.80 ? ? ? ? ? ? 50 G R N3 1 43
+ATOM 1653 C C4 . G B 2 43 ? 9.012 -9.179 43.906 1.00 37.29 ? ? ? ? ? ? 50 G R C4 1 43
+ATOM 1654 P P . C B 2 44 ? 13.818 -8.093 40.194 1.00 45.41 ? ? ? ? ? ? 51 C R P 1 44
+ATOM 1655 O OP1 . C B 2 44 ? 15.136 -8.458 39.632 1.00 45.51 ? ? ? ? ? ? 51 C R OP1 1 44
+ATOM 1656 O OP2 . C B 2 44 ? 13.300 -6.720 40.000 1.00 47.90 ? ? ? ? ? ? 51 C R OP2 1 44
+ATOM 1657 O "O5'" . C B 2 44 ? 12.698 -9.100 39.649 1.00 44.83 ? ? ? ? ? ? 51 C R "O5'" 1 44
+ATOM 1658 C "C5'" . C B 2 44 ? 12.918 -10.507 39.627 1.00 45.29 ? ? ? ? ? ? 51 C R "C5'" 1 44
+ATOM 1659 C "C4'" . C B 2 44 ? 11.613 -11.268 39.472 1.00 45.75 ? ? ? ? ? ? 51 C R "C4'" 1 44
+ATOM 1660 O "O4'" . C B 2 44 ? 10.687 -10.934 40.536 1.00 46.23 ? ? ? ? ? ? 51 C R "O4'" 1 44
+ATOM 1661 C "C3'" . C B 2 44 ? 10.806 -10.940 38.227 1.00 46.47 ? ? ? ? ? ? 51 C R "C3'" 1 44
+ATOM 1662 O "O3'" . C B 2 44 ? 11.348 -11.575 37.091 1.00 46.60 ? ? ? ? ? ? 51 C R "O3'" 1 44
+ATOM 1663 C "C2'" . C B 2 44 ? 9.444 -11.508 38.603 1.00 46.63 ? ? ? ? ? ? 51 C R "C2'" 1 44
+ATOM 1664 O "O2'" . C B 2 44 ? 9.388 -12.921 38.525 1.00 49.14 ? ? ? ? ? ? 51 C R "O2'" 1 44
+ATOM 1665 C "C1'" . C B 2 44 ? 9.353 -11.058 40.056 1.00 45.84 ? ? ? ? ? ? 51 C R "C1'" 1 44
+ATOM 1666 N N1 . C B 2 44 ? 8.611 -9.763 40.221 1.00 45.10 ? ? ? ? ? ? 51 C R N1 1 44
+ATOM 1667 C C2 . C B 2 44 ? 7.210 -9.732 40.100 1.00 45.06 ? ? ? ? ? ? 51 C R C2 1 44
+ATOM 1668 O O2 . C B 2 44 ? 6.581 -10.768 39.859 1.00 43.14 ? ? ? ? ? ? 51 C R O2 1 44
+ATOM 1669 N N3 . C B 2 44 ? 6.567 -8.545 40.255 1.00 45.68 ? ? ? ? ? ? 51 C R N3 1 44
+ATOM 1670 C C4 . C B 2 44 ? 7.255 -7.430 40.520 1.00 44.03 ? ? ? ? ? ? 51 C R C4 1 44
+ATOM 1671 N N4 . C B 2 44 ? 6.568 -6.295 40.666 1.00 44.60 ? ? ? ? ? ? 51 C R N4 1 44
+ATOM 1672 C C5 . C B 2 44 ? 8.674 -7.434 40.648 1.00 43.53 ? ? ? ? ? ? 51 C R C5 1 44
+ATOM 1673 C C6 . C B 2 44 ? 9.299 -8.608 40.492 1.00 44.83 ? ? ? ? ? ? 51 C R C6 1 44
+ATOM 1674 P P . C B 2 45 ? 11.224 -10.860 35.670 1.00 47.31 ? ? ? ? ? ? 52 C R P 1 45
+ATOM 1675 O OP1 . C B 2 45 ? 12.072 -11.630 34.730 1.00 46.90 ? ? ? ? ? ? 52 C R OP1 1 45
+ATOM 1676 O OP2 . C B 2 45 ? 11.449 -9.404 35.844 1.00 45.44 ? ? ? ? ? ? 52 C R OP2 1 45
+ATOM 1677 O "O5'" . C B 2 45 ? 9.679 -11.078 35.300 1.00 46.82 ? ? ? ? ? ? 52 C R "O5'" 1 45
+ATOM 1678 C "C5'" . C B 2 45 ? 9.287 -12.186 34.497 1.00 46.25 ? ? ? ? ? ? 52 C R "C5'" 1 45
+ATOM 1679 C "C4'" . C B 2 45 ? 7.780 -12.268 34.376 1.00 45.47 ? ? ? ? ? ? 52 C R "C4'" 1 45
+ATOM 1680 O "O4'" . C B 2 45 ? 7.159 -11.805 35.606 1.00 43.62 ? ? ? ? ? ? 52 C R "O4'" 1 45
+ATOM 1681 C "C3'" . C B 2 45 ? 7.188 -11.377 33.298 1.00 46.15 ? ? ? ? ? ? 52 C R "C3'" 1 45
+ATOM 1682 O "O3'" . C B 2 45 ? 7.304 -11.973 32.000 1.00 47.35 ? ? ? ? ? ? 52 C R "O3'" 1 45
+ATOM 1683 C "C2'" . C B 2 45 ? 5.746 -11.267 33.781 1.00 44.90 ? ? ? ? ? ? 52 C R "C2'" 1 45
+ATOM 1684 O "O2'" . C B 2 45 ? 4.977 -12.401 33.430 1.00 43.53 ? ? ? ? ? ? 52 C R "O2'" 1 45
+ATOM 1685 C "C1'" . C B 2 45 ? 5.929 -11.169 35.302 1.00 43.74 ? ? ? ? ? ? 52 C R "C1'" 1 45
+ATOM 1686 N N1 . C B 2 45 ? 5.951 -9.755 35.839 1.00 42.95 ? ? ? ? ? ? 52 C R N1 1 45
+ATOM 1687 C C2 . C B 2 45 ? 4.769 -8.993 35.949 1.00 43.00 ? ? ? ? ? ? 52 C R C2 1 45
+ATOM 1688 O O2 . C B 2 45 ? 3.681 -9.470 35.612 1.00 44.02 ? ? ? ? ? ? 52 C R O2 1 45
+ATOM 1689 N N3 . C B 2 45 ? 4.840 -7.724 36.433 1.00 42.38 ? ? ? ? ? ? 52 C R N3 1 45
+ATOM 1690 C C4 . C B 2 45 ? 6.014 -7.206 36.804 1.00 42.74 ? ? ? ? ? ? 52 C R C4 1 45
+ATOM 1691 N N4 . C B 2 45 ? 6.030 -5.955 37.278 1.00 43.12 ? ? ? ? ? ? 52 C R N4 1 45
+ATOM 1692 C C5 . C B 2 45 ? 7.225 -7.954 36.708 1.00 42.43 ? ? ? ? ? ? 52 C R C5 1 45
+ATOM 1693 C C6 . C B 2 45 ? 7.144 -9.202 36.226 1.00 43.56 ? ? ? ? ? ? 52 C R C6 1 45
+ATOM 1694 P P . U B 2 46 ? 8.138 -11.249 30.828 1.00 48.68 ? ? ? ? ? ? 53 U R P 1 46
+ATOM 1695 O OP1 . U B 2 46 ? 8.489 -12.289 29.839 1.00 47.12 ? ? ? ? ? ? 53 U R OP1 1 46
+ATOM 1696 O OP2 . U B 2 46 ? 9.230 -10.441 31.421 1.00 48.44 ? ? ? ? ? ? 53 U R OP2 1 46
+ATOM 1697 O "O5'" . U B 2 46 ? 7.083 -10.220 30.199 1.00 49.66 ? ? ? ? ? ? 53 U R "O5'" 1 46
+ATOM 1698 C "C5'" . U B 2 46 ? 5.921 -10.671 29.502 1.00 54.40 ? ? ? ? ? ? 53 U R "C5'" 1 46
+ATOM 1699 C "C4'" . U B 2 46 ? 4.963 -9.523 29.198 1.00 57.53 ? ? ? ? ? ? 53 U R "C4'" 1 46
+ATOM 1700 O "O4'" . U B 2 46 ? 5.287 -8.340 29.980 1.00 58.88 ? ? ? ? ? ? 53 U R "O4'" 1 46
+ATOM 1701 C "C3'" . U B 2 46 ? 4.914 -9.062 27.740 1.00 59.19 ? ? ? ? ? ? 53 U R "C3'" 1 46
+ATOM 1702 O "O3'" . U B 2 46 ? 3.560 -8.799 27.368 1.00 61.47 ? ? ? ? ? ? 53 U R "O3'" 1 46
+ATOM 1703 C "C2'" . U B 2 46 ? 5.745 -7.780 27.752 1.00 59.32 ? ? ? ? ? ? 53 U R "C2'" 1 46
+ATOM 1704 O "O2'" . U B 2 46 ? 5.377 -6.857 26.745 1.00 57.74 ? ? ? ? ? ? 53 U R "O2'" 1 46
+ATOM 1705 C "C1'" . U B 2 46 ? 5.371 -7.220 29.121 1.00 59.06 ? ? ? ? ? ? 53 U R "C1'" 1 46
+ATOM 1706 N N1 . U B 2 46 ? 6.340 -6.249 29.712 1.00 58.09 ? ? ? ? ? ? 53 U R N1 1 46
+ATOM 1707 C C2 . U B 2 46 ? 5.859 -5.056 30.218 1.00 58.80 ? ? ? ? ? ? 53 U R C2 1 46
+ATOM 1708 O O2 . U B 2 46 ? 4.677 -4.755 30.201 1.00 58.05 ? ? ? ? ? ? 53 U R O2 1 46
+ATOM 1709 N N3 . U B 2 46 ? 6.820 -4.221 30.752 1.00 59.01 ? ? ? ? ? ? 53 U R N3 1 46
+ATOM 1710 C C4 . U B 2 46 ? 8.187 -4.464 30.825 1.00 60.61 ? ? ? ? ? ? 53 U R C4 1 46
+ATOM 1711 O O4 . U B 2 46 ? 8.943 -3.633 31.329 1.00 61.27 ? ? ? ? ? ? 53 U R O4 1 46
+ATOM 1712 C C5 . U B 2 46 ? 8.606 -5.731 30.274 1.00 60.10 ? ? ? ? ? ? 53 U R C5 1 46
+ATOM 1713 C C6 . U B 2 46 ? 7.688 -6.556 29.750 1.00 58.38 ? ? ? ? ? ? 53 U R C6 1 46
+ATOM 1714 P P . C B 2 47 ? 2.584 -9.951 26.828 1.00 64.91 ? ? ? ? ? ? 54 C R P 1 47
+ATOM 1715 O OP1 . C B 2 47 ? 2.979 -11.258 27.407 1.00 63.17 ? ? ? ? ? ? 54 C R OP1 1 47
+ATOM 1716 O OP2 . C B 2 47 ? 2.483 -9.798 25.359 1.00 65.09 ? ? ? ? ? ? 54 C R OP2 1 47
+ATOM 1717 O "O5'" . C B 2 47 ? 1.185 -9.501 27.460 1.00 65.30 ? ? ? ? ? ? 54 C R "O5'" 1 47
+ATOM 1718 C "C5'" . C B 2 47 ? 0.024 -10.322 27.343 1.00 66.07 ? ? ? ? ? ? 54 C R "C5'" 1 47
+ATOM 1719 C "C4'" . C B 2 47 ? -1.185 -9.644 27.967 1.00 66.39 ? ? ? ? ? ? 54 C R "C4'" 1 47
+ATOM 1720 O "O4'" . C B 2 47 ? -1.087 -9.717 29.411 1.00 65.78 ? ? ? ? ? ? 54 C R "O4'" 1 47
+ATOM 1721 C "C3'" . C B 2 47 ? -1.312 -8.159 27.662 1.00 66.72 ? ? ? ? ? ? 54 C R "C3'" 1 47
+ATOM 1722 O "O3'" . C B 2 47 ? -2.036 -7.964 26.455 1.00 67.66 ? ? ? ? ? ? 54 C R "O3'" 1 47
+ATOM 1723 C "C2'" . C B 2 47 ? -2.044 -7.617 28.886 1.00 66.13 ? ? ? ? ? ? 54 C R "C2'" 1 47
+ATOM 1724 O "O2'" . C B 2 47 ? -3.449 -7.770 28.809 1.00 66.82 ? ? ? ? ? ? 54 C R "O2'" 1 47
+ATOM 1725 C "C1'" . C B 2 47 ? -1.474 -8.487 30.002 1.00 65.57 ? ? ? ? ? ? 54 C R "C1'" 1 47
+ATOM 1726 N N1 . C B 2 47 ? -0.310 -7.864 30.746 1.00 65.06 ? ? ? ? ? ? 54 C R N1 1 47
+ATOM 1727 C C2 . C B 2 47 ? -0.545 -6.896 31.745 1.00 64.59 ? ? ? ? ? ? 54 C R C2 1 47
+ATOM 1728 O O2 . C B 2 47 ? -1.699 -6.547 32.019 1.00 64.26 ? ? ? ? ? ? 54 C R O2 1 47
+ATOM 1729 N N3 . C B 2 47 ? 0.512 -6.352 32.401 1.00 64.26 ? ? ? ? ? ? 54 C R N3 1 47
+ATOM 1730 C C4 . C B 2 47 ? 1.757 -6.733 32.100 1.00 64.92 ? ? ? ? ? ? 54 C R C4 1 47
+ATOM 1731 N N4 . C B 2 47 ? 2.760 -6.164 32.775 1.00 64.83 ? ? ? ? ? ? 54 C R N4 1 47
+ATOM 1732 C C5 . C B 2 47 ? 2.024 -7.713 31.093 1.00 64.53 ? ? ? ? ? ? 54 C R C5 1 47
+ATOM 1733 C C6 . C B 2 47 ? 0.975 -8.243 30.454 1.00 63.98 ? ? ? ? ? ? 54 C R C6 1 47
+ATOM 1734 P P . C B 2 48 ? -1.674 -6.723 25.517 1.00 68.81 ? ? ? ? ? ? 55 C R P 1 48
+ATOM 1735 O OP1 . C B 2 48 ? -2.447 -6.864 24.261 1.00 69.41 ? ? ? ? ? ? 55 C R OP1 1 48
+ATOM 1736 O OP2 . C B 2 48 ? -0.200 -6.603 25.448 1.00 67.86 ? ? ? ? ? ? 55 C R OP2 1 48
+ATOM 1737 O "O5'" . C B 2 48 ? -2.242 -5.482 26.358 1.00 69.07 ? ? ? ? ? ? 55 C R "O5'" 1 48
+ATOM 1738 C "C5'" . C B 2 48 ? -3.646 -5.221 26.427 1.00 69.11 ? ? ? ? ? ? 55 C R "C5'" 1 48
+ATOM 1739 C "C4'" . C B 2 48 ? -3.923 -3.891 27.104 1.00 69.61 ? ? ? ? ? ? 55 C R "C4'" 1 48
+ATOM 1740 O "O4'" . C B 2 48 ? -3.596 -3.997 28.516 1.00 69.65 ? ? ? ? ? ? 55 C R "O4'" 1 48
+ATOM 1741 C "C3'" . C B 2 48 ? -3.074 -2.716 26.634 1.00 70.13 ? ? ? ? ? ? 55 C R "C3'" 1 48
+ATOM 1742 O "O3'" . C B 2 48 ? -3.542 -2.139 25.412 1.00 71.13 ? ? ? ? ? ? 55 C R "O3'" 1 48
+ATOM 1743 C "C2'" . C B 2 48 ? -3.199 -1.771 27.825 1.00 69.72 ? ? ? ? ? ? 55 C R "C2'" 1 48
+ATOM 1744 O "O2'" . C B 2 48 ? -4.425 -1.063 27.857 1.00 70.48 ? ? ? ? ? ? 55 C R "O2'" 1 48
+ATOM 1745 C "C1'" . C B 2 48 ? -3.094 -2.756 28.991 1.00 68.89 ? ? ? ? ? ? 55 C R "C1'" 1 48
+ATOM 1746 N N1 . C B 2 48 ? -1.672 -2.897 29.486 1.00 67.73 ? ? ? ? ? ? 55 C R N1 1 48
+ATOM 1747 C C2 . C B 2 48 ? -1.115 -1.908 30.324 1.00 66.72 ? ? ? ? ? ? 55 C R C2 1 48
+ATOM 1748 O O2 . C B 2 48 ? -1.786 -0.928 30.673 1.00 66.06 ? ? ? ? ? ? 55 C R O2 1 48
+ATOM 1749 N N3 . C B 2 48 ? 0.167 -2.051 30.746 1.00 65.96 ? ? ? ? ? ? 55 C R N3 1 48
+ATOM 1750 C C4 . C B 2 48 ? 0.889 -3.110 30.372 1.00 66.12 ? ? ? ? ? ? 55 C R C4 1 48
+ATOM 1751 N N4 . C B 2 48 ? 2.144 -3.192 30.825 1.00 65.85 ? ? ? ? ? ? 55 C R N4 1 48
+ATOM 1752 C C5 . C B 2 48 ? 0.355 -4.127 29.520 1.00 66.17 ? ? ? ? ? ? 55 C R C5 1 48
+ATOM 1753 C C6 . C B 2 48 ? -0.912 -3.978 29.109 1.00 67.27 ? ? ? ? ? ? 55 C R C6 1 48
+ATOM 1754 P P . G B 2 49 ? -2.484 -1.496 24.388 1.00 71.07 ? ? ? ? ? ? 56 G R P 1 49
+ATOM 1755 O OP1 . G B 2 49 ? -3.206 -1.125 23.152 1.00 69.59 ? ? ? ? ? ? 56 G R OP1 1 49
+ATOM 1756 O OP2 . G B 2 49 ? -1.316 -2.403 24.306 1.00 72.26 ? ? ? ? ? ? 56 G R OP2 1 49
+ATOM 1757 O "O5'" . G B 2 49 ? -1.997 -0.169 25.135 1.00 70.09 ? ? ? ? ? ? 56 G R "O5'" 1 49
+ATOM 1758 C "C5'" . G B 2 49 ? -2.853 0.960 25.173 1.00 70.52 ? ? ? ? ? ? 56 G R "C5'" 1 49
+ATOM 1759 C "C4'" . G B 2 49 ? -2.377 1.985 26.182 1.00 70.37 ? ? ? ? ? ? 56 G R "C4'" 1 49
+ATOM 1760 O "O4'" . G B 2 49 ? -2.024 1.355 27.441 1.00 69.03 ? ? ? ? ? ? 56 G R "O4'" 1 49
+ATOM 1761 C "C3'" . G B 2 49 ? -1.099 2.727 25.832 1.00 71.29 ? ? ? ? ? ? 56 G R "C3'" 1 49
+ATOM 1762 O "O3'" . G B 2 49 ? -1.282 3.677 24.778 1.00 73.32 ? ? ? ? ? ? 56 G R "O3'" 1 49
+ATOM 1763 C "C2'" . G B 2 49 ? -0.848 3.381 27.187 1.00 70.15 ? ? ? ? ? ? 56 G R "C2'" 1 49
+ATOM 1764 O "O2'" . G B 2 49 ? -1.722 4.456 27.464 1.00 71.67 ? ? ? ? ? ? 56 G R "O2'" 1 49
+ATOM 1765 C "C1'" . G B 2 49 ? -1.125 2.211 28.132 1.00 68.21 ? ? ? ? ? ? 56 G R "C1'" 1 49
+ATOM 1766 N N9 . G B 2 49 ? 0.118 1.509 28.466 1.00 66.22 ? ? ? ? ? ? 56 G R N9 1 49
+ATOM 1767 C C8 . G B 2 49 ? 0.498 0.241 28.086 1.00 65.38 ? ? ? ? ? ? 56 G R C8 1 49
+ATOM 1768 N N7 . G B 2 49 ? 1.676 -0.105 28.526 1.00 63.88 ? ? ? ? ? ? 56 G R N7 1 49
+ATOM 1769 C C5 . G B 2 49 ? 2.112 1.006 29.239 1.00 63.04 ? ? ? ? ? ? 56 G R C5 1 49
+ATOM 1770 C C6 . G B 2 49 ? 3.322 1.229 29.944 1.00 62.11 ? ? ? ? ? ? 56 G R C6 1 49
+ATOM 1771 O O6 . G B 2 49 ? 4.279 0.457 30.079 1.00 60.80 ? ? ? ? ? ? 56 G R O6 1 49
+ATOM 1772 N N1 . G B 2 49 ? 3.373 2.494 30.533 1.00 61.90 ? ? ? ? ? ? 56 G R N1 1 49
+ATOM 1773 C C2 . G B 2 49 ? 2.370 3.432 30.446 1.00 62.39 ? ? ? ? ? ? 56 G R C2 1 49
+ATOM 1774 N N2 . G B 2 49 ? 2.583 4.598 31.071 1.00 62.64 ? ? ? ? ? ? 56 G R N2 1 49
+ATOM 1775 N N3 . G B 2 49 ? 1.233 3.238 29.788 1.00 62.60 ? ? ? ? ? ? 56 G R N3 1 49
+ATOM 1776 C C4 . G B 2 49 ? 1.168 2.009 29.209 1.00 63.77 ? ? ? ? ? ? 56 G R C4 1 49
+ATOM 1777 P P . G B 2 50 ? -0.085 4.016 23.757 1.00 75.33 ? ? ? ? ? ? 57 G R P 1 50
+ATOM 1778 O OP1 . G B 2 50 ? -0.597 5.022 22.796 1.00 74.12 ? ? ? ? ? ? 57 G R OP1 1 50
+ATOM 1779 O OP2 . G B 2 50 ? 0.475 2.738 23.256 1.00 74.57 ? ? ? ? ? ? 57 G R OP2 1 50
+ATOM 1780 O "O5'" . G B 2 50 ? 1.039 4.692 24.679 1.00 72.62 ? ? ? ? ? ? 57 G R "O5'" 1 50
+ATOM 1781 C "C5'" . G B 2 50 ? 0.908 6.045 25.089 1.00 70.25 ? ? ? ? ? ? 57 G R "C5'" 1 50
+ATOM 1782 C "C4'" . G B 2 50 ? 1.990 6.442 26.077 1.00 68.44 ? ? ? ? ? ? 57 G R "C4'" 1 50
+ATOM 1783 O "O4'" . G B 2 50 ? 2.130 5.455 27.130 1.00 67.93 ? ? ? ? ? ? 57 G R "O4'" 1 50
+ATOM 1784 C "C3'" . G B 2 50 ? 3.389 6.533 25.501 1.00 67.83 ? ? ? ? ? ? 57 G R "C3'" 1 50
+ATOM 1785 O "O3'" . G B 2 50 ? 3.544 7.750 24.788 1.00 67.62 ? ? ? ? ? ? 57 G R "O3'" 1 50
+ATOM 1786 C "C2'" . G B 2 50 ? 4.228 6.480 26.775 1.00 67.28 ? ? ? ? ? ? 57 G R "C2'" 1 50
+ATOM 1787 O "O2'" . G B 2 50 ? 4.245 7.701 27.493 1.00 67.41 ? ? ? ? ? ? 57 G R "O2'" 1 50
+ATOM 1788 C "C1'" . G B 2 50 ? 3.480 5.411 27.565 1.00 65.42 ? ? ? ? ? ? 57 G R "C1'" 1 50
+ATOM 1789 N N9 . G B 2 50 ? 3.992 4.050 27.384 1.00 62.94 ? ? ? ? ? ? 57 G R N9 1 50
+ATOM 1790 C C8 . G B 2 50 ? 3.357 3.008 26.749 1.00 61.94 ? ? ? ? ? ? 57 G R C8 1 50
+ATOM 1791 N N7 . G B 2 50 ? 4.045 1.901 26.738 1.00 61.98 ? ? ? ? ? ? 57 G R N7 1 50
+ATOM 1792 C C5 . G B 2 50 ? 5.214 2.221 27.415 1.00 62.24 ? ? ? ? ? ? 57 G R C5 1 50
+ATOM 1793 C C6 . G B 2 50 ? 6.345 1.415 27.723 1.00 62.49 ? ? ? ? ? ? 57 G R C6 1 50
+ATOM 1794 O O6 . G B 2 50 ? 6.537 0.220 27.442 1.00 63.27 ? ? ? ? ? ? 57 G R O6 1 50
+ATOM 1795 N N1 . G B 2 50 ? 7.322 2.129 28.421 1.00 61.21 ? ? ? ? ? ? 57 G R N1 1 50
+ATOM 1796 C C2 . G B 2 50 ? 7.215 3.454 28.781 1.00 61.37 ? ? ? ? ? ? 57 G R C2 1 50
+ATOM 1797 N N2 . G B 2 50 ? 8.253 3.973 29.450 1.00 60.62 ? ? ? ? ? ? 57 G R N2 1 50
+ATOM 1798 N N3 . G B 2 50 ? 6.161 4.217 28.502 1.00 61.88 ? ? ? ? ? ? 57 G R N3 1 50
+ATOM 1799 C C4 . G B 2 50 ? 5.198 3.542 27.820 1.00 62.34 ? ? ? ? ? ? 57 G R C4 1 50
+ATOM 1800 P P . C B 2 51 ? 4.331 7.764 23.394 1.00 66.82 ? ? ? ? ? ? 58 C R P 1 51
+ATOM 1801 O OP1 . C B 2 51 ? 4.146 9.102 22.794 1.00 64.78 ? ? ? ? ? ? 58 C R OP1 1 51
+ATOM 1802 O OP2 . C B 2 51 ? 3.955 6.551 22.628 1.00 65.42 ? ? ? ? ? ? 58 C R OP2 1 51
+ATOM 1803 O "O5'" . C B 2 51 ? 5.853 7.597 23.862 1.00 65.33 ? ? ? ? ? ? 58 C R "O5'" 1 51
+ATOM 1804 C "C5'" . C B 2 51 ? 6.470 8.558 24.720 1.00 63.15 ? ? ? ? ? ? 58 C R "C5'" 1 51
+ATOM 1805 C "C4'" . C B 2 51 ? 7.754 8.014 25.325 1.00 61.23 ? ? ? ? ? ? 58 C R "C4'" 1 51
+ATOM 1806 O "O4'" . C B 2 51 ? 7.477 6.872 26.179 1.00 60.71 ? ? ? ? ? ? 58 C R "O4'" 1 51
+ATOM 1807 C "C3'" . C B 2 51 ? 8.746 7.463 24.317 1.00 60.20 ? ? ? ? ? ? 58 C R "C3'" 1 51
+ATOM 1808 O "O3'" . C B 2 51 ? 9.461 8.522 23.692 1.00 59.53 ? ? ? ? ? ? 58 C R "O3'" 1 51
+ATOM 1809 C "C2'" . C B 2 51 ? 9.603 6.564 25.208 1.00 60.13 ? ? ? ? ? ? 58 C R "C2'" 1 51
+ATOM 1810 O "O2'" . C B 2 51 ? 10.540 7.271 26.001 1.00 59.39 ? ? ? ? ? ? 58 C R "O2'" 1 51
+ATOM 1811 C "C1'" . C B 2 51 ? 8.528 5.923 26.083 1.00 58.53 ? ? ? ? ? ? 58 C R "C1'" 1 51
+ATOM 1812 N N1 . C B 2 51 ? 7.995 4.611 25.552 1.00 57.48 ? ? ? ? ? ? 58 C R N1 1 51
+ATOM 1813 C C2 . C B 2 51 ? 8.740 3.421 25.706 1.00 57.42 ? ? ? ? ? ? 58 C R C2 1 51
+ATOM 1814 O O2 . C B 2 51 ? 9.839 3.447 26.275 1.00 58.14 ? ? ? ? ? ? 58 C R O2 1 51
+ATOM 1815 N N3 . C B 2 51 ? 8.236 2.254 25.218 1.00 56.01 ? ? ? ? ? ? 58 C R N3 1 51
+ATOM 1816 C C4 . C B 2 51 ? 7.048 2.239 24.601 1.00 56.24 ? ? ? ? ? ? 58 C R C4 1 51
+ATOM 1817 N N4 . C B 2 51 ? 6.590 1.069 24.143 1.00 55.00 ? ? ? ? ? ? 58 C R N4 1 51
+ATOM 1818 C C5 . C B 2 51 ? 6.273 3.430 24.436 1.00 56.57 ? ? ? ? ? ? 58 C R C5 1 51
+ATOM 1819 C C6 . C B 2 51 ? 6.779 4.573 24.918 1.00 56.66 ? ? ? ? ? ? 58 C R C6 1 51
+ATOM 1820 P P . C B 2 52 ? 9.970 8.372 22.178 1.00 58.04 ? ? ? ? ? ? 59 C R P 1 52
+ATOM 1821 O OP1 . C B 2 52 ? 10.457 9.700 21.742 1.00 56.37 ? ? ? ? ? ? 59 C R OP1 1 52
+ATOM 1822 O OP2 . C B 2 52 ? 8.936 7.670 21.381 1.00 56.88 ? ? ? ? ? ? 59 C R OP2 1 52
+ATOM 1823 O "O5'" . C B 2 52 ? 11.218 7.381 22.342 1.00 56.91 ? ? ? ? ? ? 59 C R "O5'" 1 52
+ATOM 1824 C "C5'" . C B 2 52 ? 12.373 7.793 23.078 1.00 54.79 ? ? ? ? ? ? 59 C R "C5'" 1 52
+ATOM 1825 C "C4'" . C B 2 52 ? 13.325 6.634 23.316 1.00 53.17 ? ? ? ? ? ? 59 C R "C4'" 1 52
+ATOM 1826 O "O4'" . C B 2 52 ? 12.666 5.587 24.069 1.00 51.92 ? ? ? ? ? ? 59 C R "O4'" 1 52
+ATOM 1827 C "C3'" . C B 2 52 ? 13.788 5.902 22.066 1.00 52.19 ? ? ? ? ? ? 59 C R "C3'" 1 52
+ATOM 1828 O "O3'" . C B 2 52 ? 14.813 6.614 21.401 1.00 52.04 ? ? ? ? ? ? 59 C R "O3'" 1 52
+ATOM 1829 C "C2'" . C B 2 52 ? 14.293 4.599 22.662 1.00 50.91 ? ? ? ? ? ? 59 C R "C2'" 1 52
+ATOM 1830 O "O2'" . C B 2 52 ? 15.539 4.726 23.317 1.00 52.45 ? ? ? ? ? ? 59 C R "O2'" 1 52
+ATOM 1831 C "C1'" . C B 2 52 ? 13.203 4.330 23.688 1.00 50.14 ? ? ? ? ? ? 59 C R "C1'" 1 52
+ATOM 1832 N N1 . C B 2 52 ? 12.117 3.425 23.184 1.00 47.53 ? ? ? ? ? ? 59 C R N1 1 52
+ATOM 1833 C C2 . C B 2 52 ? 12.376 2.054 23.009 1.00 47.46 ? ? ? ? ? ? 59 C R C2 1 52
+ATOM 1834 O O2 . C B 2 52 ? 13.499 1.589 23.268 1.00 46.61 ? ? ? ? ? ? 59 C R O2 1 52
+ATOM 1835 N N3 . C B 2 52 ? 11.370 1.256 22.561 1.00 47.15 ? ? ? ? ? ? 59 C R N3 1 52
+ATOM 1836 C C4 . C B 2 52 ? 10.166 1.769 22.294 1.00 46.45 ? ? ? ? ? ? 59 C R C4 1 52
+ATOM 1837 N N4 . C B 2 52 ? 9.216 0.940 21.853 1.00 47.76 ? ? ? ? ? ? 59 C R N4 1 52
+ATOM 1838 C C5 . C B 2 52 ? 9.887 3.157 22.462 1.00 46.52 ? ? ? ? ? ? 59 C R C5 1 52
+ATOM 1839 C C6 . C B 2 52 ? 10.880 3.936 22.905 1.00 46.27 ? ? ? ? ? ? 59 C R C6 1 52
+ATOM 1840 P P . U B 2 53 ? 14.852 6.617 19.804 1.00 51.39 ? ? ? ? ? ? 60 U R P 1 53
+ATOM 1841 O OP1 . U B 2 53 ? 15.893 7.589 19.399 1.00 49.66 ? ? ? ? ? ? 60 U R OP1 1 53
+ATOM 1842 O OP2 . U B 2 53 ? 13.469 6.751 19.281 1.00 49.84 ? ? ? ? ? ? 60 U R OP2 1 53
+ATOM 1843 O "O5'" . U B 2 53 ? 15.358 5.134 19.492 1.00 49.51 ? ? ? ? ? ? 60 U R "O5'" 1 53
+ATOM 1844 C "C5'" . U B 2 53 ? 16.729 4.827 19.687 1.00 49.76 ? ? ? ? ? ? 60 U R "C5'" 1 53
+ATOM 1845 C "C4'" . U B 2 53 ? 16.990 3.360 19.429 1.00 49.17 ? ? ? ? ? ? 60 U R "C4'" 1 53
+ATOM 1846 O "O4'" . U B 2 53 ? 15.995 2.556 20.099 1.00 48.61 ? ? ? ? ? ? 60 U R "O4'" 1 53
+ATOM 1847 C "C3'" . U B 2 53 ? 16.868 2.953 17.977 1.00 50.30 ? ? ? ? ? ? 60 U R "C3'" 1 53
+ATOM 1848 O "O3'" . U B 2 53 ? 18.092 3.224 17.328 1.00 53.67 ? ? ? ? ? ? 60 U R "O3'" 1 53
+ATOM 1849 C "C2'" . U B 2 53 ? 16.607 1.458 18.086 1.00 48.65 ? ? ? ? ? ? 60 U R "C2'" 1 53
+ATOM 1850 O "O2'" . U B 2 53 ? 17.800 0.717 18.227 1.00 47.72 ? ? ? ? ? ? 60 U R "O2'" 1 53
+ATOM 1851 C "C1'" . U B 2 53 ? 15.795 1.360 19.372 1.00 47.50 ? ? ? ? ? ? 60 U R "C1'" 1 53
+ATOM 1852 N N1 . U B 2 53 ? 14.331 1.139 19.159 1.00 46.04 ? ? ? ? ? ? 60 U R N1 1 53
+ATOM 1853 C C2 . U B 2 53 ? 13.900 -0.110 18.747 1.00 46.05 ? ? ? ? ? ? 60 U R C2 1 53
+ATOM 1854 O O2 . U B 2 53 ? 14.652 -1.046 18.538 1.00 46.35 ? ? ? ? ? ? 60 U R O2 1 53
+ATOM 1855 N N3 . U B 2 53 ? 12.539 -0.229 18.583 1.00 45.25 ? ? ? ? ? ? 60 U R N3 1 53
+ATOM 1856 C C4 . U B 2 53 ? 11.588 0.752 18.788 1.00 45.23 ? ? ? ? ? ? 60 U R C4 1 53
+ATOM 1857 O O4 . U B 2 53 ? 10.404 0.491 18.600 1.00 46.01 ? ? ? ? ? ? 60 U R O4 1 53
+ATOM 1858 C C5 . U B 2 53 ? 12.112 2.027 19.216 1.00 44.64 ? ? ? ? ? ? 60 U R C5 1 53
+ATOM 1859 C C6 . U B 2 53 ? 13.435 2.170 19.383 1.00 44.49 ? ? ? ? ? ? 60 U R C6 1 53
+ATOM 1860 P P . A B 2 54 ? 18.095 3.811 15.843 1.00 55.88 ? ? ? ? ? ? 61 A R P 1 54
+ATOM 1861 O OP1 . A B 2 54 ? 19.511 4.030 15.463 1.00 55.87 ? ? ? ? ? ? 61 A R OP1 1 54
+ATOM 1862 O OP2 . A B 2 54 ? 17.121 4.925 15.779 1.00 55.17 ? ? ? ? ? ? 61 A R OP2 1 54
+ATOM 1863 O "O5'" . A B 2 54 ? 17.499 2.607 14.985 1.00 56.08 ? ? ? ? ? ? 61 A R "O5'" 1 54
+ATOM 1864 C "C5'" . A B 2 54 ? 18.247 1.418 14.804 1.00 60.18 ? ? ? ? ? ? 61 A R "C5'" 1 54
+ATOM 1865 C "C4'" . A B 2 54 ? 17.368 0.397 14.120 1.00 63.58 ? ? ? ? ? ? 61 A R "C4'" 1 54
+ATOM 1866 O "O4'" . A B 2 54 ? 16.139 0.242 14.864 1.00 65.68 ? ? ? ? ? ? 61 A R "O4'" 1 54
+ATOM 1867 C "C3'" . A B 2 54 ? 16.953 0.786 12.708 1.00 65.51 ? ? ? ? ? ? 61 A R "C3'" 1 54
+ATOM 1868 O "O3'" . A B 2 54 ? 17.601 -0.087 11.816 1.00 67.99 ? ? ? ? ? ? 61 A R "O3'" 1 54
+ATOM 1869 C "C2'" . A B 2 54 ? 15.435 0.617 12.666 1.00 66.06 ? ? ? ? ? ? 61 A R "C2'" 1 54
+ATOM 1870 O "O2'" . A B 2 54 ? 14.996 -0.118 11.540 1.00 67.03 ? ? ? ? ? ? 61 A R "O2'" 1 54
+ATOM 1871 C "C1'" . A B 2 54 ? 15.150 -0.159 13.947 1.00 66.09 ? ? ? ? ? ? 61 A R "C1'" 1 54
+ATOM 1872 N N9 . A B 2 54 ? 13.830 0.121 14.502 1.00 66.27 ? ? ? ? ? ? 61 A R N9 1 54
+ATOM 1873 C C8 . A B 2 54 ? 13.390 1.277 15.092 1.00 67.06 ? ? ? ? ? ? 61 A R C8 1 54
+ATOM 1874 N N7 . A B 2 54 ? 12.139 1.229 15.490 1.00 66.93 ? ? ? ? ? ? 61 A R N7 1 54
+ATOM 1875 C C5 . A B 2 54 ? 11.735 -0.048 15.134 1.00 66.40 ? ? ? ? ? ? 61 A R C5 1 54
+ATOM 1876 C C6 . A B 2 54 ? 10.512 -0.736 15.276 1.00 66.60 ? ? ? ? ? ? 61 A R C6 1 54
+ATOM 1877 N N6 . A B 2 54 ? 9.431 -0.193 15.845 1.00 66.56 ? ? ? ? ? ? 61 A R N6 1 54
+ATOM 1878 N N1 . A B 2 54 ? 10.447 -2.007 14.807 1.00 66.86 ? ? ? ? ? ? 61 A R N1 1 54
+ATOM 1879 C C2 . A B 2 54 ? 11.529 -2.556 14.234 1.00 66.21 ? ? ? ? ? ? 61 A R C2 1 54
+ATOM 1880 N N3 . A B 2 54 ? 12.730 -2.006 14.047 1.00 66.53 ? ? ? ? ? ? 61 A R N3 1 54
+ATOM 1881 C C4 . A B 2 54 ? 12.765 -0.745 14.523 1.00 66.31 ? ? ? ? ? ? 61 A R C4 1 54
+ATOM 1882 P P . A B 2 55 ? 18.808 0.448 10.921 1.00 70.61 ? ? ? ? ? ? 62 A R P 1 55
+ATOM 1883 O OP1 . A B 2 55 ? 19.846 1.046 11.801 1.00 70.09 ? ? ? ? ? ? 62 A R OP1 1 55
+ATOM 1884 O OP2 . A B 2 55 ? 18.189 1.269 9.850 1.00 69.57 ? ? ? ? ? ? 62 A R OP2 1 55
+ATOM 1885 O "O5'" . A B 2 55 ? 19.363 -0.920 10.281 1.00 70.02 ? ? ? ? ? ? 62 A R "O5'" 1 55
+ATOM 1886 C "C5'" . A B 2 55 ? 20.685 -1.405 10.548 1.00 68.98 ? ? ? ? ? ? 62 A R "C5'" 1 55
+ATOM 1887 C "C4'" . A B 2 55 ? 20.806 -2.926 10.497 1.00 68.42 ? ? ? ? ? ? 62 A R "C4'" 1 55
+ATOM 1888 O "O4'" . A B 2 55 ? 20.652 -3.464 11.837 1.00 67.73 ? ? ? ? ? ? 62 A R "O4'" 1 55
+ATOM 1889 C "C3'" . A B 2 55 ? 19.780 -3.698 9.671 1.00 67.81 ? ? ? ? ? ? 62 A R "C3'" 1 55
+ATOM 1890 O "O3'" . A B 2 55 ? 20.150 -3.767 8.301 1.00 67.43 ? ? ? ? ? ? 62 A R "O3'" 1 55
+ATOM 1891 C "C2'" . A B 2 55 ? 19.794 -5.065 10.356 1.00 67.15 ? ? ? ? ? ? 62 A R "C2'" 1 55
+ATOM 1892 O "O2'" . A B 2 55 ? 20.926 -5.855 10.048 1.00 66.64 ? ? ? ? ? ? 62 A R "O2'" 1 55
+ATOM 1893 C "C1'" . A B 2 55 ? 19.851 -4.633 11.811 1.00 66.76 ? ? ? ? ? ? 62 A R "C1'" 1 55
+ATOM 1894 N N9 . A B 2 55 ? 18.531 -4.335 12.368 1.00 66.14 ? ? ? ? ? ? 62 A R N9 1 55
+ATOM 1895 C C8 . A B 2 55 ? 17.961 -3.103 12.531 1.00 65.50 ? ? ? ? ? ? 62 A R C8 1 55
+ATOM 1896 N N7 . A B 2 55 ? 16.762 -3.134 13.055 1.00 66.50 ? ? ? ? ? ? 62 A R N7 1 55
+ATOM 1897 C C5 . A B 2 55 ? 16.524 -4.481 13.248 1.00 65.38 ? ? ? ? ? ? 62 A R C5 1 55
+ATOM 1898 C C6 . A B 2 55 ? 15.419 -5.178 13.774 1.00 65.32 ? ? ? ? ? ? 62 A R C6 1 55
+ATOM 1899 N N6 . A B 2 55 ? 14.316 -4.565 14.213 1.00 65.36 ? ? ? ? ? ? 62 A R N6 1 55
+ATOM 1900 N N1 . A B 2 55 ? 15.494 -6.528 13.829 1.00 65.84 ? ? ? ? ? ? 62 A R N1 1 55
+ATOM 1901 C C2 . A B 2 55 ? 16.606 -7.135 13.385 1.00 65.92 ? ? ? ? ? ? 62 A R C2 1 55
+ATOM 1902 N N3 . A B 2 55 ? 17.708 -6.582 12.869 1.00 65.79 ? ? ? ? ? ? 62 A R N3 1 55
+ATOM 1903 C C4 . A B 2 55 ? 17.602 -5.240 12.828 1.00 65.71 ? ? ? ? ? ? 62 A R C4 1 55
+ATOM 1904 P P . A B 2 56 ? 19.022 -3.797 7.162 1.00 67.83 ? ? ? ? ? ? 63 A R P 1 56
+ATOM 1905 O OP1 . A B 2 56 ? 19.713 -3.744 5.853 1.00 68.70 ? ? ? ? ? ? 63 A R OP1 1 56
+ATOM 1906 O OP2 . A B 2 56 ? 18.003 -2.770 7.474 1.00 66.63 ? ? ? ? ? ? 63 A R OP2 1 56
+ATOM 1907 O "O5'" . A B 2 56 ? 18.365 -5.245 7.349 1.00 65.68 ? ? ? ? ? ? 63 A R "O5'" 1 56
+ATOM 1908 C "C5'" . A B 2 56 ? 19.118 -6.412 7.029 1.00 65.79 ? ? ? ? ? ? 63 A R "C5'" 1 56
+ATOM 1909 C "C4'" . A B 2 56 ? 18.365 -7.669 7.413 1.00 65.99 ? ? ? ? ? ? 63 A R "C4'" 1 56
+ATOM 1910 O "O4'" . A B 2 56 ? 18.059 -7.655 8.831 1.00 66.84 ? ? ? ? ? ? 63 A R "O4'" 1 56
+ATOM 1911 C "C3'" . A B 2 56 ? 17.002 -7.824 6.758 1.00 66.13 ? ? ? ? ? ? 63 A R "C3'" 1 56
+ATOM 1912 O "O3'" . A B 2 56 ? 17.132 -8.296 5.419 1.00 65.53 ? ? ? ? ? ? 63 A R "O3'" 1 56
+ATOM 1913 C "C2'" . A B 2 56 ? 16.341 -8.827 7.702 1.00 66.33 ? ? ? ? ? ? 63 A R "C2'" 1 56
+ATOM 1914 O "O2'" . A B 2 56 ? 16.763 -10.162 7.497 1.00 67.01 ? ? ? ? ? ? 63 A R "O2'" 1 56
+ATOM 1915 C "C1'" . A B 2 56 ? 16.823 -8.316 9.060 1.00 65.48 ? ? ? ? ? ? 63 A R "C1'" 1 56
+ATOM 1916 N N9 . A B 2 56 ? 15.866 -7.394 9.678 1.00 64.09 ? ? ? ? ? ? 63 A R N9 1 56
+ATOM 1917 C C8 . A B 2 56 ? 15.881 -6.026 9.629 1.00 64.16 ? ? ? ? ? ? 63 A R C8 1 56
+ATOM 1918 N N7 . A B 2 56 ? 14.890 -5.454 10.271 1.00 63.71 ? ? ? ? ? ? 63 A R N7 1 56
+ATOM 1919 C C5 . A B 2 56 ? 14.171 -6.521 10.773 1.00 62.63 ? ? ? ? ? ? 63 A R C5 1 56
+ATOM 1920 C C6 . A B 2 56 ? 12.999 -6.589 11.549 1.00 62.92 ? ? ? ? ? ? 63 A R C6 1 56
+ATOM 1921 N N6 . A B 2 56 ? 12.331 -5.507 11.959 1.00 63.55 ? ? ? ? ? ? 63 A R N6 1 56
+ATOM 1922 N N1 . A B 2 56 ? 12.535 -7.811 11.889 1.00 64.68 ? ? ? ? ? ? 63 A R N1 1 56
+ATOM 1923 C C2 . A B 2 56 ? 13.205 -8.897 11.477 1.00 65.12 ? ? ? ? ? ? 63 A R C2 1 56
+ATOM 1924 N N3 . A B 2 56 ? 14.318 -8.955 10.742 1.00 64.84 ? ? ? ? ? ? 63 A R N3 1 56
+ATOM 1925 C C4 . A B 2 56 ? 14.754 -7.723 10.418 1.00 63.46 ? ? ? ? ? ? 63 A R C4 1 56
+ATOM 1926 P P . C B 2 57 ? 16.202 -7.701 4.256 1.00 64.35 ? ? ? ? ? ? 64 C R P 1 57
+ATOM 1927 O OP1 . C B 2 57 ? 16.630 -8.322 2.979 1.00 64.74 ? ? ? ? ? ? 64 C R OP1 1 57
+ATOM 1928 O OP2 . C B 2 57 ? 16.158 -6.226 4.374 1.00 64.06 ? ? ? ? ? ? 64 C R OP2 1 57
+ATOM 1929 O "O5'" . C B 2 57 ? 14.762 -8.261 4.660 1.00 63.87 ? ? ? ? ? ? 64 C R "O5'" 1 57
+ATOM 1930 C "C5'" . C B 2 57 ? 14.475 -9.632 4.450 1.00 64.11 ? ? ? ? ? ? 64 C R "C5'" 1 57
+ATOM 1931 C "C4'" . C B 2 57 ? 13.188 -10.026 5.137 1.00 64.62 ? ? ? ? ? ? 64 C R "C4'" 1 57
+ATOM 1932 O "O4'" . C B 2 57 ? 13.264 -9.676 6.539 1.00 64.41 ? ? ? ? ? ? 64 C R "O4'" 1 57
+ATOM 1933 C "C3'" . C B 2 57 ? 11.952 -9.289 4.653 1.00 65.26 ? ? ? ? ? ? 64 C R "C3'" 1 57
+ATOM 1934 O "O3'" . C B 2 57 ? 11.474 -9.832 3.432 1.00 66.02 ? ? ? ? ? ? 64 C R "O3'" 1 57
+ATOM 1935 C "C2'" . C B 2 57 ? 11.004 -9.512 5.827 1.00 65.59 ? ? ? ? ? ? 64 C R "C2'" 1 57
+ATOM 1936 O "O2'" . C B 2 57 ? 10.404 -10.796 5.841 1.00 65.45 ? ? ? ? ? ? 64 C R "O2'" 1 57
+ATOM 1937 C "C1'" . C B 2 57 ? 11.971 -9.331 7.001 1.00 65.21 ? ? ? ? ? ? 64 C R "C1'" 1 57
+ATOM 1938 N N1 . C B 2 57 ? 11.972 -7.932 7.538 1.00 65.99 ? ? ? ? ? ? 64 C R N1 1 57
+ATOM 1939 C C2 . C B 2 57 ? 10.991 -7.563 8.469 1.00 65.89 ? ? ? ? ? ? 64 C R C2 1 57
+ATOM 1940 O O2 . C B 2 57 ? 10.156 -8.399 8.839 1.00 65.59 ? ? ? ? ? ? 64 C R O2 1 57
+ATOM 1941 N N3 . C B 2 57 ? 10.992 -6.288 8.943 1.00 66.88 ? ? ? ? ? ? 64 C R N3 1 57
+ATOM 1942 C C4 . C B 2 57 ? 11.912 -5.407 8.529 1.00 66.35 ? ? ? ? ? ? 64 C R C4 1 57
+ATOM 1943 N N4 . C B 2 57 ? 11.866 -4.171 9.035 1.00 66.67 ? ? ? ? ? ? 64 C R N4 1 57
+ATOM 1944 C C5 . C B 2 57 ? 12.920 -5.759 7.581 1.00 65.89 ? ? ? ? ? ? 64 C R C5 1 57
+ATOM 1945 C C6 . C B 2 57 ? 12.908 -7.017 7.120 1.00 66.49 ? ? ? ? ? ? 64 C R C6 1 57
+ATOM 1946 P P . C B 2 58 ? 10.835 -8.852 2.340 1.00 66.38 ? ? ? ? ? ? 65 C R P 1 58
+ATOM 1947 O OP1 . C B 2 58 ? 10.679 -9.605 1.076 1.00 65.39 ? ? ? ? ? ? 65 C R OP1 1 58
+ATOM 1948 O OP2 . C B 2 58 ? 11.591 -7.578 2.342 1.00 66.10 ? ? ? ? ? ? 65 C R OP2 1 58
+ATOM 1949 O "O5'" . C B 2 58 ? 9.402 -8.544 2.968 1.00 66.36 ? ? ? ? ? ? 65 C R "O5'" 1 58
+ATOM 1950 C "C5'" . C B 2 58 ? 8.415 -9.549 3.103 1.00 67.74 ? ? ? ? ? ? 65 C R "C5'" 1 58
+ATOM 1951 C "C4'" . C B 2 58 ? 7.214 -8.955 3.805 1.00 70.39 ? ? ? ? ? ? 65 C R "C4'" 1 58
+ATOM 1952 O "O4'" . C B 2 58 ? 7.605 -8.542 5.140 1.00 71.34 ? ? ? ? ? ? 65 C R "O4'" 1 58
+ATOM 1953 C "C3'" . C B 2 58 ? 6.693 -7.661 3.196 1.00 71.53 ? ? ? ? ? ? 65 C R "C3'" 1 58
+ATOM 1954 O "O3'" . C B 2 58 ? 5.913 -7.861 2.023 1.00 72.00 ? ? ? ? ? ? 65 C R "O3'" 1 58
+ATOM 1955 C "C2'" . C B 2 58 ? 5.917 -7.071 4.369 1.00 72.12 ? ? ? ? ? ? 65 C R "C2'" 1 58
+ATOM 1956 O "O2'" . C B 2 58 ? 4.665 -7.687 4.621 1.00 71.68 ? ? ? ? ? ? 65 C R "O2'" 1 58
+ATOM 1957 C "C1'" . C B 2 58 ? 6.905 -7.356 5.499 1.00 71.91 ? ? ? ? ? ? 65 C R "C1'" 1 58
+ATOM 1958 N N1 . C B 2 58 ? 7.867 -6.218 5.736 1.00 71.73 ? ? ? ? ? ? 65 C R N1 1 58
+ATOM 1959 C C2 . C B 2 58 ? 7.417 -5.018 6.319 1.00 72.06 ? ? ? ? ? ? 65 C R C2 1 58
+ATOM 1960 O O2 . C B 2 58 ? 6.235 -4.893 6.648 1.00 72.91 ? ? ? ? ? ? 65 C R O2 1 58
+ATOM 1961 N N3 . C B 2 58 ? 8.297 -4.006 6.525 1.00 72.19 ? ? ? ? ? ? 65 C R N3 1 58
+ATOM 1962 C C4 . C B 2 58 ? 9.573 -4.153 6.169 1.00 72.47 ? ? ? ? ? ? 65 C R C4 1 58
+ATOM 1963 N N4 . C B 2 58 ? 10.400 -3.130 6.389 1.00 73.39 ? ? ? ? ? ? 65 C R N4 1 58
+ATOM 1964 C C5 . C B 2 58 ? 10.058 -5.355 5.571 1.00 72.68 ? ? ? ? ? ? 65 C R C5 1 58
+ATOM 1965 C C6 . C B 2 58 ? 9.181 -6.348 5.378 1.00 72.24 ? ? ? ? ? ? 65 C R C6 1 58
+ATOM 1966 P P . A B 2 59 ? 6.157 -6.872 0.783 1.00 73.36 ? ? ? ? ? ? 660 A R P 1 59
+ATOM 1967 O OP1 . A B 2 59 ? 5.571 -7.487 -0.427 1.00 73.30 ? ? ? ? ? ? 660 A R OP1 1 59
+ATOM 1968 O OP2 . A B 2 59 ? 7.582 -6.473 0.770 1.00 73.48 ? ? ? ? ? ? 660 A R OP2 1 59
+ATOM 1969 O "O5'" . A B 2 59 ? 5.314 -5.575 1.184 1.00 72.74 ? ? ? ? ? ? 660 A R "O5'" 1 59
+ATOM 1970 C "C5'" . A B 2 59 ? 3.924 -5.665 1.449 1.00 72.25 ? ? ? ? ? ? 660 A R "C5'" 1 59
+ATOM 1971 C "C4'" . A B 2 59 ? 3.469 -4.486 2.286 1.00 72.01 ? ? ? ? ? ? 660 A R "C4'" 1 59
+ATOM 1972 O "O4'" . A B 2 59 ? 4.206 -4.450 3.534 1.00 72.01 ? ? ? ? ? ? 660 A R "O4'" 1 59
+ATOM 1973 C "C3'" . A B 2 59 ? 3.731 -3.125 1.668 1.00 71.66 ? ? ? ? ? ? 660 A R "C3'" 1 59
+ATOM 1974 O "O3'" . A B 2 59 ? 2.728 -2.794 0.719 1.00 71.28 ? ? ? ? ? ? 660 A R "O3'" 1 59
+ATOM 1975 C "C2'" . A B 2 59 ? 3.696 -2.244 2.911 1.00 72.75 ? ? ? ? ? ? 660 A R "C2'" 1 59
+ATOM 1976 O "O2'" . A B 2 59 ? 2.391 -2.003 3.403 1.00 73.27 ? ? ? ? ? ? 660 A R "O2'" 1 59
+ATOM 1977 C "C1'" . A B 2 59 ? 4.488 -3.108 3.886 1.00 73.07 ? ? ? ? ? ? 660 A R "C1'" 1 59
+ATOM 1978 N N9 . A B 2 59 ? 5.932 -2.849 3.820 1.00 74.15 ? ? ? ? ? ? 660 A R N9 1 59
+ATOM 1979 C C8 . A B 2 59 ? 6.898 -3.631 3.242 1.00 74.58 ? ? ? ? ? ? 660 A R C8 1 59
+ATOM 1980 N N7 . A B 2 59 ? 8.111 -3.139 3.332 1.00 74.48 ? ? ? ? ? ? 660 A R N7 1 59
+ATOM 1981 C C5 . A B 2 59 ? 7.937 -1.946 4.014 1.00 73.91 ? ? ? ? ? ? 660 A R C5 1 59
+ATOM 1982 C C6 . A B 2 59 ? 8.841 -0.942 4.432 1.00 73.43 ? ? ? ? ? ? 660 A R C6 1 59
+ATOM 1983 N N6 . A B 2 59 ? 10.158 -0.990 4.203 1.00 73.85 ? ? ? ? ? ? 660 A R N6 1 59
+ATOM 1984 N N1 . A B 2 59 ? 8.339 0.125 5.093 1.00 72.70 ? ? ? ? ? ? 660 A R N1 1 59
+ATOM 1985 C C2 . A B 2 59 ? 7.020 0.182 5.323 1.00 72.56 ? ? ? ? ? ? 660 A R C2 1 59
+ATOM 1986 N N3 . A B 2 59 ? 6.076 -0.697 4.981 1.00 73.34 ? ? ? ? ? ? 660 A R N3 1 59
+ATOM 1987 C C4 . A B 2 59 ? 6.600 -1.749 4.322 1.00 73.85 ? ? ? ? ? ? 660 A R C4 1 59
+ATOM 1988 P P . U B 2 60 ? 3.116 -2.005 -0.622 1.00 71.84 ? ? ? ? ? ? 661 U R P 1 60
+ATOM 1989 O OP1 . U B 2 60 ? 1.940 -2.052 -1.522 1.00 72.64 ? ? ? ? ? ? 661 U R OP1 1 60
+ATOM 1990 O OP2 . U B 2 60 ? 4.423 -2.496 -1.116 1.00 71.22 ? ? ? ? ? ? 661 U R OP2 1 60
+ATOM 1991 O "O5'" . U B 2 60 ? 3.316 -0.505 -0.100 1.00 70.01 ? ? ? ? ? ? 661 U R "O5'" 1 60
+ATOM 1992 C "C5'" . U B 2 60 ? 2.241 0.173 0.553 1.00 69.47 ? ? ? ? ? ? 661 U R "C5'" 1 60
+ATOM 1993 C "C4'" . U B 2 60 ? 2.741 1.356 1.359 1.00 68.25 ? ? ? ? ? ? 661 U R "C4'" 1 60
+ATOM 1994 O "O4'" . U B 2 60 ? 3.717 0.928 2.345 1.00 67.65 ? ? ? ? ? ? 661 U R "O4'" 1 60
+ATOM 1995 C "C3'" . U B 2 60 ? 3.497 2.388 0.545 1.00 67.97 ? ? ? ? ? ? 661 U R "C3'" 1 60
+ATOM 1996 O "O3'" . U B 2 60 ? 2.603 3.226 -0.163 1.00 67.88 ? ? ? ? ? ? 661 U R "O3'" 1 60
+ATOM 1997 C "C2'" . U B 2 60 ? 4.277 3.110 1.636 1.00 67.61 ? ? ? ? ? ? 661 U R "C2'" 1 60
+ATOM 1998 O "O2'" . U B 2 60 ? 3.480 4.008 2.389 1.00 68.00 ? ? ? ? ? ? 661 U R "O2'" 1 60
+ATOM 1999 C "C1'" . U B 2 60 ? 4.726 1.919 2.488 1.00 66.13 ? ? ? ? ? ? 661 U R "C1'" 1 60
+ATOM 2000 N N1 . U B 2 60 ? 6.093 1.375 2.098 1.00 63.66 ? ? ? ? ? ? 661 U R N1 1 60
+ATOM 2001 C C2 . U B 2 60 ? 7.240 2.057 2.492 1.00 62.13 ? ? ? ? ? ? 661 U R C2 1 60
+ATOM 2002 O O2 . U B 2 60 ? 7.224 3.083 3.152 1.00 61.93 ? ? ? ? ? ? 661 U R O2 1 60
+ATOM 2003 N N3 . U B 2 60 ? 8.430 1.491 2.089 1.00 59.95 ? ? ? ? ? ? 661 U R N3 1 60
+ATOM 2004 C C4 . U B 2 60 ? 8.596 0.338 1.343 1.00 59.19 ? ? ? ? ? ? 661 U R C4 1 60
+ATOM 2005 O O4 . U B 2 60 ? 9.725 -0.046 1.055 1.00 56.54 ? ? ? ? ? ? 661 U R O4 1 60
+ATOM 2006 C C5 . U B 2 60 ? 7.366 -0.317 0.968 1.00 60.54 ? ? ? ? ? ? 661 U R C5 1 60
+ATOM 2007 C C6 . U B 2 60 ? 6.194 0.212 1.350 1.00 61.70 ? ? ? ? ? ? 661 U R C6 1 60
+ATOM 2008 P P . U B 2 61 ? 2.902 3.522 -1.708 1.00 68.53 ? ? ? ? ? ? 662 U R P 1 61
+ATOM 2009 O OP1 . U B 2 61 ? 1.692 4.153 -2.287 1.00 68.43 ? ? ? ? ? ? 662 U R OP1 1 61
+ATOM 2010 O OP2 . U B 2 61 ? 3.464 2.303 -2.334 1.00 65.79 ? ? ? ? ? ? 662 U R OP2 1 61
+ATOM 2011 O "O5'" . U B 2 61 ? 4.059 4.620 -1.611 1.00 68.79 ? ? ? ? ? ? 662 U R "O5'" 1 61
+ATOM 2012 C "C5'" . U B 2 61 ? 3.740 5.916 -1.115 1.00 69.67 ? ? ? ? ? ? 662 U R "C5'" 1 61
+ATOM 2013 C "C4'" . U B 2 61 ? 4.317 6.999 -2.007 1.00 70.36 ? ? ? ? ? ? 662 U R "C4'" 1 61
+ATOM 2014 O "O4'" . U B 2 61 ? 5.749 6.834 -2.074 1.00 70.13 ? ? ? ? ? ? 662 U R "O4'" 1 61
+ATOM 2015 C "C3'" . U B 2 61 ? 3.808 7.049 -3.448 1.00 70.69 ? ? ? ? ? ? 662 U R "C3'" 1 61
+ATOM 2016 O "O3'" . U B 2 61 ? 3.355 8.374 -3.746 1.00 70.70 ? ? ? ? ? ? 662 U R "O3'" 1 61
+ATOM 2017 C "C2'" . U B 2 61 ? 5.016 6.625 -4.288 1.00 71.10 ? ? ? ? ? ? 662 U R "C2'" 1 61
+ATOM 2018 O "O2'" . U B 2 61 ? 5.059 7.286 -5.538 1.00 70.55 ? ? ? ? ? ? 662 U R "O2'" 1 61
+ATOM 2019 C "C1'" . U B 2 61 ? 6.192 7.029 -3.396 1.00 71.40 ? ? ? ? ? ? 662 U R "C1'" 1 61
+ATOM 2020 N N1 . U B 2 61 ? 7.458 6.232 -3.525 1.00 72.53 ? ? ? ? ? ? 662 U R N1 1 61
+ATOM 2021 C C2 . U B 2 61 ? 8.528 6.733 -4.252 1.00 73.18 ? ? ? ? ? ? 662 U R C2 1 61
+ATOM 2022 O O2 . U B 2 61 ? 8.520 7.804 -4.834 1.00 74.02 ? ? ? ? ? ? 662 U R O2 1 61
+ATOM 2023 N N3 . U B 2 61 ? 9.633 5.917 -4.283 1.00 72.80 ? ? ? ? ? ? 662 U R N3 1 61
+ATOM 2024 C C4 . U B 2 61 ? 9.783 4.683 -3.672 1.00 73.39 ? ? ? ? ? ? 662 U R C4 1 61
+ATOM 2025 O O4 . U B 2 61 ? 10.839 4.072 -3.794 1.00 74.02 ? ? ? ? ? ? 662 U R O4 1 61
+ATOM 2026 C C5 . U B 2 61 ? 8.638 4.230 -2.925 1.00 73.15 ? ? ? ? ? ? 662 U R C5 1 61
+ATOM 2027 C C6 . U B 2 61 ? 7.547 5.008 -2.880 1.00 72.98 ? ? ? ? ? ? 662 U R C6 1 61
+ATOM 2028 P P . G B 2 62 ? 1.990 8.935 -3.111 1.00 73.05 ? ? ? ? ? ? 663 G R P 1 62
+ATOM 2029 O OP1 . G B 2 62 ? 1.118 7.788 -2.774 1.00 73.27 ? ? ? ? ? ? 663 G R OP1 1 62
+ATOM 2030 O OP2 . G B 2 62 ? 1.486 10.008 -3.997 1.00 73.40 ? ? ? ? ? ? 663 G R OP2 1 62
+ATOM 2031 O "O5'" . G B 2 62 ? 2.431 9.638 -1.754 1.00 71.69 ? ? ? ? ? ? 663 G R "O5'" 1 62
+ATOM 2032 C "C5'" . G B 2 62 ? 1.438 9.866 -0.773 1.00 72.31 ? ? ? ? ? ? 663 G R "C5'" 1 62
+ATOM 2033 C "C4'" . G B 2 62 ? 2.016 9.625 0.603 1.00 72.96 ? ? ? ? ? ? 663 G R "C4'" 1 62
+ATOM 2034 O "O4'" . G B 2 62 ? 3.078 8.642 0.522 1.00 72.80 ? ? ? ? ? ? 663 G R "O4'" 1 62
+ATOM 2035 C "C3'" . G B 2 62 ? 2.679 10.849 1.201 1.00 73.11 ? ? ? ? ? ? 663 G R "C3'" 1 62
+ATOM 2036 O "O3'" . G B 2 62 ? 1.703 11.632 1.857 1.00 74.84 ? ? ? ? ? ? 663 G R "O3'" 1 62
+ATOM 2037 C "C2'" . G B 2 62 ? 3.680 10.224 2.163 1.00 72.69 ? ? ? ? ? ? 663 G R "C2'" 1 62
+ATOM 2038 O "O2'" . G B 2 62 ? 3.085 9.811 3.379 1.00 73.60 ? ? ? ? ? ? 663 G R "O2'" 1 62
+ATOM 2039 C "C1'" . G B 2 62 ? 4.147 9.001 1.374 1.00 71.67 ? ? ? ? ? ? 663 G R "C1'" 1 62
+ATOM 2040 N N9 . G B 2 62 ? 5.344 9.197 0.550 1.00 70.19 ? ? ? ? ? ? 663 G R N9 1 62
+ATOM 2041 C C8 . G B 2 62 ? 5.646 10.283 -0.241 1.00 69.50 ? ? ? ? ? ? 663 G R C8 1 62
+ATOM 2042 N N7 . G B 2 62 ? 6.783 10.180 -0.865 1.00 68.29 ? ? ? ? ? ? 663 G R N7 1 62
+ATOM 2043 C C5 . G B 2 62 ? 7.277 8.949 -0.468 1.00 67.98 ? ? ? ? ? ? 663 G R C5 1 62
+ATOM 2044 C C6 . G B 2 62 ? 8.481 8.295 -0.825 1.00 66.62 ? ? ? ? ? ? 663 G R C6 1 62
+ATOM 2045 O O6 . G B 2 62 ? 9.366 8.702 -1.585 1.00 64.99 ? ? ? ? ? ? 663 G R O6 1 62
+ATOM 2046 N N1 . G B 2 62 ? 8.610 7.051 -0.208 1.00 66.74 ? ? ? ? ? ? 663 G R N1 1 62
+ATOM 2047 C C2 . G B 2 62 ? 7.680 6.509 0.652 1.00 66.89 ? ? ? ? ? ? 663 G R C2 1 62
+ATOM 2048 N N2 . G B 2 62 ? 7.968 5.301 1.152 1.00 67.29 ? ? ? ? ? ? 663 G R N2 1 62
+ATOM 2049 N N3 . G B 2 62 ? 6.545 7.111 0.997 1.00 67.70 ? ? ? ? ? ? 663 G R N3 1 62
+ATOM 2050 C C4 . G B 2 62 ? 6.405 8.327 0.404 1.00 68.85 ? ? ? ? ? ? 663 G R C4 1 62
+ATOM 2051 P P . C B 2 63 ? 1.388 13.121 1.352 1.00 77.36 ? ? ? ? ? ? 664 C R P 1 63
+ATOM 2052 O OP1 . C B 2 63 ? 0.247 13.614 2.163 1.00 77.15 ? ? ? ? ? ? 664 C R OP1 1 63
+ATOM 2053 O OP2 . C B 2 63 ? 1.291 13.114 -0.128 1.00 75.72 ? ? ? ? ? ? 664 C R OP2 1 63
+ATOM 2054 O "O5'" . C B 2 63 ? 2.703 13.937 1.767 1.00 74.70 ? ? ? ? ? ? 664 C R "O5'" 1 63
+ATOM 2055 C "C5'" . C B 2 63 ? 3.071 14.011 3.145 1.00 71.98 ? ? ? ? ? ? 664 C R "C5'" 1 63
+ATOM 2056 C "C4'" . C B 2 63 ? 3.257 15.447 3.605 1.00 68.89 ? ? ? ? ? ? 664 C R "C4'" 1 63
+ATOM 2057 O "O4'" . C B 2 63 ? 4.112 16.148 2.668 1.00 66.34 ? ? ? ? ? ? 664 C R "O4'" 1 63
+ATOM 2058 C "C3'" . C B 2 63 ? 1.995 16.288 3.758 1.00 67.15 ? ? ? ? ? ? 664 C R "C3'" 1 63
+ATOM 2059 O "O3'" . C B 2 63 ? 2.144 17.037 4.962 1.00 69.06 ? ? ? ? ? ? 664 C R "O3'" 1 63
+ATOM 2060 C "C2'" . C B 2 63 ? 1.993 17.177 2.510 1.00 66.25 ? ? ? ? ? ? 664 C R "C2'" 1 63
+ATOM 2061 O "O2'" . C B 2 63 ? 1.416 18.448 2.746 1.00 65.72 ? ? ? ? ? ? 664 C R "O2'" 1 63
+ATOM 2062 C "C1'" . C B 2 63 ? 3.485 17.326 2.207 1.00 64.00 ? ? ? ? ? ? 664 C R "C1'" 1 63
+ATOM 2063 N N1 . C B 2 63 ? 3.886 17.517 0.762 1.00 60.59 ? ? ? ? ? ? 664 C R N1 1 63
+ATOM 2064 C C2 . C B 2 63 ? 4.339 18.773 0.315 1.00 58.54 ? ? ? ? ? ? 664 C R C2 1 63
+ATOM 2065 O O2 . C B 2 63 ? 4.388 19.729 1.098 1.00 57.97 ? ? ? ? ? ? 664 C R O2 1 63
+ATOM 2066 N N3 . C B 2 63 ? 4.710 18.917 -0.985 1.00 56.69 ? ? ? ? ? ? 664 C R N3 1 63
+ATOM 2067 C C4 . C B 2 63 ? 4.651 17.880 -1.824 1.00 55.57 ? ? ? ? ? ? 664 C R C4 1 63
+ATOM 2068 N N4 . C B 2 63 ? 5.027 18.086 -3.087 1.00 54.13 ? ? ? ? ? ? 664 C R N4 1 63
+ATOM 2069 C C5 . C B 2 63 ? 4.203 16.593 -1.398 1.00 56.43 ? ? ? ? ? ? 664 C R C5 1 63
+ATOM 2070 C C6 . C B 2 63 ? 3.839 16.460 -0.113 1.00 59.25 ? ? ? ? ? ? 664 C R C6 1 63
+ATOM 2071 P P . A B 2 64 ? 0.950 17.272 6.000 1.00 70.69 ? ? ? ? ? ? 665 A R P 1 64
+ATOM 2072 O OP1 . A B 2 64 ? -0.050 16.201 5.791 1.00 72.42 ? ? ? ? ? ? 665 A R OP1 1 64
+ATOM 2073 O OP2 . A B 2 64 ? 0.559 18.696 5.896 1.00 70.42 ? ? ? ? ? ? 665 A R OP2 1 64
+ATOM 2074 O "O5'" . A B 2 64 ? 1.610 17.095 7.448 1.00 71.51 ? ? ? ? ? ? 665 A R "O5'" 1 64
+ATOM 2075 C "C5'" . A B 2 64 ? 2.194 15.864 7.861 1.00 72.59 ? ? ? ? ? ? 665 A R "C5'" 1 64
+ATOM 2076 C "C4'" . A B 2 64 ? 3.682 16.048 8.091 1.00 73.87 ? ? ? ? ? ? 665 A R "C4'" 1 64
+ATOM 2077 O "O4'" . A B 2 64 ? 4.315 16.485 6.863 1.00 73.15 ? ? ? ? ? ? 665 A R "O4'" 1 64
+ATOM 2078 C "C3'" . A B 2 64 ? 4.043 17.130 9.096 1.00 75.09 ? ? ? ? ? ? 665 A R "C3'" 1 64
+ATOM 2079 O "O3'" . A B 2 64 ? 4.004 16.605 10.413 1.00 78.27 ? ? ? ? ? ? 665 A R "O3'" 1 64
+ATOM 2080 C "C2'" . A B 2 64 ? 5.457 17.517 8.677 1.00 73.86 ? ? ? ? ? ? 665 A R "C2'" 1 64
+ATOM 2081 O "O2'" . A B 2 64 ? 6.453 16.708 9.269 1.00 73.63 ? ? ? ? ? ? 665 A R "O2'" 1 64
+ATOM 2082 C "C1'" . A B 2 64 ? 5.430 17.308 7.161 1.00 72.50 ? ? ? ? ? ? 665 A R "C1'" 1 64
+ATOM 2083 N N9 . A B 2 64 ? 5.355 18.543 6.375 1.00 71.09 ? ? ? ? ? ? 665 A R N9 1 64
+ATOM 2084 C C8 . A B 2 64 ? 4.413 18.864 5.436 1.00 70.77 ? ? ? ? ? ? 665 A R C8 1 64
+ATOM 2085 N N7 . A B 2 64 ? 4.587 20.037 4.874 1.00 70.25 ? ? ? ? ? ? 665 A R N7 1 64
+ATOM 2086 C C5 . A B 2 64 ? 5.728 20.530 5.483 1.00 69.46 ? ? ? ? ? ? 665 A R C5 1 64
+ATOM 2087 C C6 . A B 2 64 ? 6.450 21.738 5.332 1.00 68.69 ? ? ? ? ? ? 665 A R C6 1 64
+ATOM 2088 N N6 . A B 2 64 ? 6.105 22.708 4.480 1.00 68.87 ? ? ? ? ? ? 665 A R N6 1 64
+ATOM 2089 N N1 . A B 2 64 ? 7.550 21.922 6.092 1.00 67.79 ? ? ? ? ? ? 665 A R N1 1 64
+ATOM 2090 C C2 . A B 2 64 ? 7.908 20.953 6.946 1.00 69.36 ? ? ? ? ? ? 665 A R C2 1 64
+ATOM 2091 N N3 . A B 2 64 ? 7.312 19.780 7.178 1.00 69.82 ? ? ? ? ? ? 665 A R N3 1 64
+ATOM 2092 C C4 . A B 2 64 ? 6.218 19.622 6.409 1.00 70.21 ? ? ? ? ? ? 665 A R C4 1 64
+ATOM 2093 P P . C B 2 65 ? 3.137 17.338 11.542 1.00 81.19 ? ? ? ? ? ? 666 C R P 1 65
+ATOM 2094 O OP1 . C B 2 65 ? 3.058 16.420 12.706 1.00 81.02 ? ? ? ? ? ? 666 C R OP1 1 65
+ATOM 2095 O OP2 . C B 2 65 ? 1.890 17.840 10.913 1.00 80.71 ? ? ? ? ? ? 666 C R OP2 1 65
+ATOM 2096 O "O5'" . C B 2 65 ? 4.051 18.591 11.938 1.00 80.24 ? ? ? ? ? ? 666 C R "O5'" 1 65
+ATOM 2097 C "C5'" . C B 2 65 ? 5.146 18.403 12.830 1.00 80.72 ? ? ? ? ? ? 666 C R "C5'" 1 65
+ATOM 2098 C "C4'" . C B 2 65 ? 6.048 19.620 12.884 1.00 80.88 ? ? ? ? ? ? 666 C R "C4'" 1 65
+ATOM 2099 O "O4'" . C B 2 65 ? 6.613 19.850 11.570 1.00 80.29 ? ? ? ? ? ? 666 C R "O4'" 1 65
+ATOM 2100 C "C3'" . C B 2 65 ? 5.350 20.931 13.222 1.00 81.64 ? ? ? ? ? ? 666 C R "C3'" 1 65
+ATOM 2101 O "O3'" . C B 2 65 ? 5.171 21.071 14.627 1.00 83.95 ? ? ? ? ? ? 666 C R "O3'" 1 65
+ATOM 2102 C "C2'" . C B 2 65 ? 6.297 21.962 12.615 1.00 80.07 ? ? ? ? ? ? 666 C R "C2'" 1 65
+ATOM 2103 O "O2'" . C B 2 65 ? 7.430 22.230 13.423 1.00 78.39 ? ? ? ? ? ? 666 C R "O2'" 1 65
+ATOM 2104 C "C1'" . C B 2 65 ? 6.691 21.244 11.321 1.00 78.65 ? ? ? ? ? ? 666 C R "C1'" 1 65
+ATOM 2105 N N1 . C B 2 65 ? 5.832 21.602 10.132 1.00 75.84 ? ? ? ? ? ? 666 C R N1 1 65
+ATOM 2106 C C2 . C B 2 65 ? 6.202 22.682 9.312 1.00 75.18 ? ? ? ? ? ? 666 C R C2 1 65
+ATOM 2107 O O2 . C B 2 65 ? 7.228 23.331 9.564 1.00 74.05 ? ? ? ? ? ? 666 C R O2 1 65
+ATOM 2108 N N3 . C B 2 65 ? 5.417 22.991 8.243 1.00 74.35 ? ? ? ? ? ? 666 C R N3 1 65
+ATOM 2109 C C4 . C B 2 65 ? 4.311 22.286 7.985 1.00 73.74 ? ? ? ? ? ? 666 C R C4 1 65
+ATOM 2110 N N4 . C B 2 65 ? 3.581 22.638 6.925 1.00 72.83 ? ? ? ? ? ? 666 C R N4 1 65
+ATOM 2111 C C5 . C B 2 65 ? 3.913 21.185 8.802 1.00 74.51 ? ? ? ? ? ? 666 C R C5 1 65
+ATOM 2112 C C6 . C B 2 65 ? 4.695 20.888 9.848 1.00 75.15 ? ? ? ? ? ? 666 C R C6 1 65
+ATOM 2113 P P . U B 2 66 ? 3.681 21.126 15.214 1.00 85.44 ? ? ? ? ? ? 667 U R P 1 66
+ATOM 2114 O OP1 . U B 2 66 ? 2.761 20.443 14.269 1.00 84.32 ? ? ? ? ? ? 667 U R OP1 1 66
+ATOM 2115 O OP2 . U B 2 66 ? 3.423 22.533 15.602 1.00 85.16 ? ? ? ? ? ? 667 U R OP2 1 66
+ATOM 2116 O "O5'" . U B 2 66 ? 3.803 20.244 16.545 1.00 83.25 ? ? ? ? ? ? 667 U R "O5'" 1 66
+ATOM 2117 C "C5'" . U B 2 66 ? 3.811 18.830 16.438 1.00 80.35 ? ? ? ? ? ? 667 U R "C5'" 1 66
+ATOM 2118 C "C4'" . U B 2 66 ? 3.961 18.177 17.795 1.00 78.41 ? ? ? ? ? ? 667 U R "C4'" 1 66
+ATOM 2119 O "O4'" . U B 2 66 ? 2.679 18.168 18.471 1.00 77.53 ? ? ? ? ? ? 667 U R "O4'" 1 66
+ATOM 2120 C "C3'" . U B 2 66 ? 4.400 16.726 17.709 1.00 78.17 ? ? ? ? ? ? 667 U R "C3'" 1 66
+ATOM 2121 O "O3'" . U B 2 66 ? 5.812 16.660 17.870 1.00 78.19 ? ? ? ? ? ? 667 U R "O3'" 1 66
+ATOM 2122 C "C2'" . U B 2 66 ? 3.652 16.047 18.853 1.00 77.56 ? ? ? ? ? ? 667 U R "C2'" 1 66
+ATOM 2123 O "O2'" . U B 2 66 ? 4.355 16.085 20.081 1.00 78.60 ? ? ? ? ? ? 667 U R "O2'" 1 66
+ATOM 2124 C "C1'" . U B 2 66 ? 2.374 16.873 18.964 1.00 75.82 ? ? ? ? ? ? 667 U R "C1'" 1 66
+ATOM 2125 N N1 . U B 2 66 ? 1.158 16.315 18.251 1.00 73.30 ? ? ? ? ? ? 667 U R N1 1 66
+ATOM 2126 C C2 . U B 2 66 ? 0.611 15.087 18.615 1.00 72.31 ? ? ? ? ? ? 667 U R C2 1 66
+ATOM 2127 O O2 . U B 2 66 ? 1.049 14.369 19.498 1.00 71.97 ? ? ? ? ? ? 667 U R O2 1 66
+ATOM 2128 N N3 . U B 2 66 ? -0.501 14.707 17.894 1.00 70.90 ? ? ? ? ? ? 667 U R N3 1 66
+ATOM 2129 C C4 . U B 2 66 ? -1.116 15.411 16.869 1.00 70.84 ? ? ? ? ? ? 667 U R C4 1 66
+ATOM 2130 O O4 . U B 2 66 ? -2.106 14.946 16.309 1.00 70.32 ? ? ? ? ? ? 667 U R O4 1 66
+ATOM 2131 C C5 . U B 2 66 ? -0.496 16.672 16.546 1.00 70.74 ? ? ? ? ? ? 667 U R C5 1 66
+ATOM 2132 C C6 . U B 2 66 ? 0.583 17.065 17.235 1.00 72.25 ? ? ? ? ? ? 667 U R C6 1 66
+ATOM 2133 P P . C B 2 67 ? 6.763 16.185 16.670 1.00 78.26 ? ? ? ? ? ? 668 C R P 1 67
+ATOM 2134 O OP1 . C B 2 67 ? 8.146 16.577 17.031 1.00 76.72 ? ? ? ? ? ? 668 C R OP1 1 67
+ATOM 2135 O OP2 . C B 2 67 ? 6.180 16.623 15.380 1.00 77.82 ? ? ? ? ? ? 668 C R OP2 1 67
+ATOM 2136 O "O5'" . C B 2 67 ? 6.628 14.595 16.719 1.00 74.82 ? ? ? ? ? ? 668 C R "O5'" 1 67
+ATOM 2137 C "C5'" . C B 2 67 ? 7.138 13.875 17.825 1.00 71.24 ? ? ? ? ? ? 668 C R "C5'" 1 67
+ATOM 2138 C "C4'" . C B 2 67 ? 6.244 12.691 18.113 1.00 69.21 ? ? ? ? ? ? 668 C R "C4'" 1 67
+ATOM 2139 O "O4'" . C B 2 67 ? 4.898 13.168 18.353 1.00 67.80 ? ? ? ? ? ? 668 C R "O4'" 1 67
+ATOM 2140 C "C3'" . C B 2 67 ? 6.038 11.725 16.960 1.00 68.63 ? ? ? ? ? ? 668 C R "C3'" 1 67
+ATOM 2141 O "O3'" . C B 2 67 ? 7.160 10.872 16.746 1.00 68.74 ? ? ? ? ? ? 668 C R "O3'" 1 67
+ATOM 2142 C "C2'" . C B 2 67 ? 4.806 10.982 17.464 1.00 68.15 ? ? ? ? ? ? 668 C R "C2'" 1 67
+ATOM 2143 O "O2'" . C B 2 67 ? 5.090 10.060 18.501 1.00 69.50 ? ? ? ? ? ? 668 C R "O2'" 1 67
+ATOM 2144 C "C1'" . C B 2 67 ? 3.978 12.151 17.996 1.00 66.35 ? ? ? ? ? ? 668 C R "C1'" 1 67
+ATOM 2145 N N1 . C B 2 67 ? 2.969 12.650 16.994 1.00 63.67 ? ? ? ? ? ? 668 C R N1 1 67
+ATOM 2146 C C2 . C B 2 67 ? 1.701 12.042 16.943 1.00 63.26 ? ? ? ? ? ? 668 C R C2 1 67
+ATOM 2147 O O2 . C B 2 67 ? 1.429 11.120 17.722 1.00 62.50 ? ? ? ? ? ? 668 C R O2 1 67
+ATOM 2148 N N3 . C B 2 67 ? 0.791 12.485 16.034 1.00 62.12 ? ? ? ? ? ? 668 C R N3 1 67
+ATOM 2149 C C4 . C B 2 67 ? 1.107 13.479 15.202 1.00 62.02 ? ? ? ? ? ? 668 C R C4 1 67
+ATOM 2150 N N4 . C B 2 67 ? 0.172 13.870 14.334 1.00 62.50 ? ? ? ? ? ? 668 C R N4 1 67
+ATOM 2151 C C5 . C B 2 67 ? 2.388 14.112 15.228 1.00 62.03 ? ? ? ? ? ? 668 C R C5 1 67
+ATOM 2152 C C6 . C B 2 67 ? 3.275 13.667 16.128 1.00 63.06 ? ? ? ? ? ? 668 C R C6 1 67
+ATOM 2153 P P . C B 2 68 ? 7.486 10.354 15.260 1.00 69.21 ? ? ? ? ? ? 669 C R P 1 68
+ATOM 2154 O OP1 . C B 2 68 ? 8.826 9.722 15.288 1.00 68.32 ? ? ? ? ? ? 669 C R OP1 1 68
+ATOM 2155 O OP2 . C B 2 68 ? 7.223 11.455 14.306 1.00 69.12 ? ? ? ? ? ? 669 C R OP2 1 68
+ATOM 2156 O "O5'" . C B 2 68 ? 6.369 9.235 15.009 1.00 66.96 ? ? ? ? ? ? 669 C R "O5'" 1 68
+ATOM 2157 C "C5'" . C B 2 68 ? 6.613 7.904 15.433 1.00 64.72 ? ? ? ? ? ? 669 C R "C5'" 1 68
+ATOM 2158 C "C4'" . C B 2 68 ? 5.330 7.149 15.717 1.00 63.48 ? ? ? ? ? ? 669 C R "C4'" 1 68
+ATOM 2159 O "O4'" . C B 2 68 ? 4.246 8.043 16.088 1.00 60.36 ? ? ? ? ? ? 669 C R "O4'" 1 68
+ATOM 2160 C "C3'" . C B 2 68 ? 4.746 6.406 14.528 1.00 63.85 ? ? ? ? ? ? 669 C R "C3'" 1 68
+ATOM 2161 O "O3'" . C B 2 68 ? 5.491 5.232 14.211 1.00 67.88 ? ? ? ? ? ? 669 C R "O3'" 1 68
+ATOM 2162 C "C2'" . C B 2 68 ? 3.356 6.105 15.079 1.00 60.09 ? ? ? ? ? ? 669 C R "C2'" 1 68
+ATOM 2163 O "O2'" . C B 2 68 ? 3.341 5.084 16.057 1.00 58.08 ? ? ? ? ? ? 669 C R "O2'" 1 68
+ATOM 2164 C "C1'" . C B 2 68 ? 3.010 7.453 15.707 1.00 57.11 ? ? ? ? ? ? 669 C R "C1'" 1 68
+ATOM 2165 N N1 . C B 2 68 ? 2.258 8.377 14.780 1.00 52.27 ? ? ? ? ? ? 669 C R N1 1 68
+ATOM 2166 C C2 . C B 2 68 ? 0.984 8.026 14.278 1.00 49.00 ? ? ? ? ? ? 669 C R C2 1 68
+ATOM 2167 O O2 . C B 2 68 ? 0.453 6.951 14.589 1.00 45.59 ? ? ? ? ? ? 669 C R O2 1 68
+ATOM 2168 N N3 . C B 2 68 ? 0.346 8.892 13.450 1.00 47.56 ? ? ? ? ? ? 669 C R N3 1 68
+ATOM 2169 C C4 . C B 2 68 ? 0.919 10.053 13.114 1.00 48.78 ? ? ? ? ? ? 669 C R C4 1 68
+ATOM 2170 N N4 . C B 2 68 ? 0.250 10.868 12.293 1.00 47.03 ? ? ? ? ? ? 669 C R N4 1 68
+ATOM 2171 C C5 . C B 2 68 ? 2.208 10.431 13.607 1.00 49.92 ? ? ? ? ? ? 669 C R C5 1 68
+ATOM 2172 C C6 . C B 2 68 ? 2.830 9.572 14.427 1.00 51.00 ? ? ? ? ? ? 669 C R C6 1 68
+ATOM 2173 P P . G B 2 69 ? 5.428 4.614 12.732 1.00 71.37 ? ? ? ? ? ? 75 G R P 1 69
+ATOM 2174 O OP1 . G B 2 69 ? 6.788 4.138 12.394 1.00 72.21 ? ? ? ? ? ? 75 G R OP1 1 69
+ATOM 2175 O OP2 . G B 2 69 ? 4.747 5.579 11.833 1.00 71.60 ? ? ? ? ? ? 75 G R OP2 1 69
+ATOM 2176 O "O5'" . G B 2 69 ? 4.492 3.328 12.921 1.00 71.76 ? ? ? ? ? ? 75 G R "O5'" 1 69
+ATOM 2177 C "C5'" . G B 2 69 ? 3.070 3.402 12.818 1.00 72.39 ? ? ? ? ? ? 75 G R "C5'" 1 69
+ATOM 2178 C "C4'" . G B 2 69 ? 2.505 2.198 12.085 1.00 72.32 ? ? ? ? ? ? 75 G R "C4'" 1 69
+ATOM 2179 O "O4'" . G B 2 69 ? 2.928 2.238 10.698 1.00 71.55 ? ? ? ? ? ? 75 G R "O4'" 1 69
+ATOM 2180 C "C3'" . G B 2 69 ? 2.982 0.829 12.554 1.00 72.22 ? ? ? ? ? ? 75 G R "C3'" 1 69
+ATOM 2181 O "O3'" . G B 2 69 ? 2.330 0.386 13.738 1.00 72.50 ? ? ? ? ? ? 75 G R "O3'" 1 69
+ATOM 2182 C "C2'" . G B 2 69 ? 2.611 -0.005 11.334 1.00 72.20 ? ? ? ? ? ? 75 G R "C2'" 1 69
+ATOM 2183 O "O2'" . G B 2 69 ? 1.225 -0.263 11.227 1.00 72.60 ? ? ? ? ? ? 75 G R "O2'" 1 69
+ATOM 2184 C "C1'" . G B 2 69 ? 3.106 0.916 10.224 1.00 71.83 ? ? ? ? ? ? 75 G R "C1'" 1 69
+ATOM 2185 N N9 . G B 2 69 ? 4.518 0.655 9.939 1.00 72.58 ? ? ? ? ? ? 75 G R N9 1 69
+ATOM 2186 C C8 . G B 2 69 ? 5.625 1.352 10.376 1.00 72.56 ? ? ? ? ? ? 75 G R C8 1 69
+ATOM 2187 N N7 . G B 2 69 ? 6.757 0.851 9.962 1.00 71.87 ? ? ? ? ? ? 75 G R N7 1 69
+ATOM 2188 C C5 . G B 2 69 ? 6.383 -0.253 9.205 1.00 72.03 ? ? ? ? ? ? 75 G R C5 1 69
+ATOM 2189 C C6 . G B 2 69 ? 7.173 -1.195 8.496 1.00 71.88 ? ? ? ? ? ? 75 G R C6 1 69
+ATOM 2190 O O6 . G B 2 69 ? 8.407 -1.233 8.396 1.00 71.72 ? ? ? ? ? ? 75 G R O6 1 69
+ATOM 2191 N N1 . G B 2 69 ? 6.391 -2.165 7.858 1.00 71.90 ? ? ? ? ? ? 75 G R N1 1 69
+ATOM 2192 C C2 . G B 2 69 ? 5.013 -2.213 7.903 1.00 71.17 ? ? ? ? ? ? 75 G R C2 1 69
+ATOM 2193 N N2 . G B 2 69 ? 4.417 -3.209 7.237 1.00 70.27 ? ? ? ? ? ? 75 G R N2 1 69
+ATOM 2194 N N3 . G B 2 69 ? 4.263 -1.338 8.562 1.00 71.45 ? ? ? ? ? ? 75 G R N3 1 69
+ATOM 2195 C C4 . G B 2 69 ? 5.009 -0.388 9.186 1.00 72.30 ? ? ? ? ? ? 75 G R C4 1 69
+ATOM 2196 P P . G B 2 70 ? 3.082 -0.613 14.742 1.00 72.31 ? ? ? ? ? ? 76 G R P 1 70
+ATOM 2197 O OP1 . G B 2 70 ? 2.235 -0.759 15.946 1.00 73.30 ? ? ? ? ? ? 76 G R OP1 1 70
+ATOM 2198 O OP2 . G B 2 70 ? 4.484 -0.167 14.903 1.00 72.40 ? ? ? ? ? ? 76 G R OP2 1 70
+ATOM 2199 O "O5'" . G B 2 70 ? 3.086 -1.999 13.940 1.00 72.44 ? ? ? ? ? ? 76 G R "O5'" 1 70
+ATOM 2200 C "C5'" . G B 2 70 ? 1.869 -2.705 13.702 1.00 72.32 ? ? ? ? ? ? 76 G R "C5'" 1 70
+ATOM 2201 C "C4'" . G B 2 70 ? 2.065 -3.816 12.686 1.00 72.84 ? ? ? ? ? ? 76 G R "C4'" 1 70
+ATOM 2202 O "O4'" . G B 2 70 ? 2.761 -3.308 11.519 1.00 73.09 ? ? ? ? ? ? 76 G R "O4'" 1 70
+ATOM 2203 C "C3'" . G B 2 70 ? 2.928 -4.972 13.162 1.00 73.20 ? ? ? ? ? ? 76 G R "C3'" 1 70
+ATOM 2204 O "O3'" . G B 2 70 ? 2.147 -5.923 13.861 1.00 73.40 ? ? ? ? ? ? 76 G R "O3'" 1 70
+ATOM 2205 C "C2'" . G B 2 70 ? 3.451 -5.545 11.852 1.00 73.38 ? ? ? ? ? ? 76 G R "C2'" 1 70
+ATOM 2206 O "O2'" . G B 2 70 ? 2.519 -6.398 11.214 1.00 75.40 ? ? ? ? ? ? 76 G R "O2'" 1 70
+ATOM 2207 C "C1'" . G B 2 70 ? 3.679 -4.275 11.037 1.00 72.95 ? ? ? ? ? ? 76 G R "C1'" 1 70
+ATOM 2208 N N9 . G B 2 70 ? 5.049 -3.756 11.134 1.00 71.95 ? ? ? ? ? ? 76 G R N9 1 70
+ATOM 2209 C C8 . G B 2 70 ? 5.462 -2.595 11.746 1.00 71.23 ? ? ? ? ? ? 76 G R C8 1 70
+ATOM 2210 N N7 . G B 2 70 ? 6.748 -2.390 11.673 1.00 70.22 ? ? ? ? ? ? 76 G R N7 1 70
+ATOM 2211 C C5 . G B 2 70 ? 7.225 -3.485 10.968 1.00 70.28 ? ? ? ? ? ? 76 G R C5 1 70
+ATOM 2212 C C6 . G B 2 70 ? 8.546 -3.814 10.576 1.00 70.42 ? ? ? ? ? ? 76 G R C6 1 70
+ATOM 2213 O O6 . G B 2 70 ? 9.585 -3.174 10.791 1.00 70.51 ? ? ? ? ? ? 76 G R O6 1 70
+ATOM 2214 N N1 . G B 2 70 ? 8.602 -5.016 9.868 1.00 70.17 ? ? ? ? ? ? 76 G R N1 1 70
+ATOM 2215 C C2 . G B 2 70 ? 7.511 -5.803 9.576 1.00 70.03 ? ? ? ? ? ? 76 G R C2 1 70
+ATOM 2216 N N2 . G B 2 70 ? 7.746 -6.927 8.885 1.00 69.97 ? ? ? ? ? ? 76 G R N2 1 70
+ATOM 2217 N N3 . G B 2 70 ? 6.268 -5.503 9.934 1.00 70.63 ? ? ? ? ? ? 76 G R N3 1 70
+ATOM 2218 C C4 . G B 2 70 ? 6.194 -4.335 10.626 1.00 71.07 ? ? ? ? ? ? 76 G R C4 1 70
+ATOM 2219 P P . U B 2 71 ? 2.713 -6.599 15.196 1.00 74.13 ? ? ? ? ? ? 77 U R P 1 71
+ATOM 2220 O OP1 . U B 2 71 ? 1.720 -7.616 15.612 1.00 74.26 ? ? ? ? ? ? 77 U R OP1 1 71
+ATOM 2221 O OP2 . U B 2 71 ? 3.118 -5.526 16.135 1.00 72.60 ? ? ? ? ? ? 77 U R OP2 1 71
+ATOM 2222 O "O5'" . U B 2 71 ? 4.050 -7.336 14.719 1.00 73.80 ? ? ? ? ? ? 77 U R "O5'" 1 71
+ATOM 2223 C "C5'" . U B 2 71 ? 4.029 -8.495 13.889 1.00 74.24 ? ? ? ? ? ? 77 U R "C5'" 1 71
+ATOM 2224 C "C4'" . U B 2 71 ? 5.443 -8.860 13.476 1.00 74.39 ? ? ? ? ? ? 77 U R "C4'" 1 71
+ATOM 2225 O "O4'" . U B 2 71 ? 5.985 -7.832 12.601 1.00 74.84 ? ? ? ? ? ? 77 U R "O4'" 1 71
+ATOM 2226 C "C3'" . U B 2 71 ? 6.454 -8.899 14.615 1.00 73.90 ? ? ? ? ? ? 77 U R "C3'" 1 71
+ATOM 2227 O "O3'" . U B 2 71 ? 6.376 -10.083 15.398 1.00 71.11 ? ? ? ? ? ? 77 U R "O3'" 1 71
+ATOM 2228 C "C2'" . U B 2 71 ? 7.757 -8.737 13.847 1.00 74.30 ? ? ? ? ? ? 77 U R "C2'" 1 71
+ATOM 2229 O "O2'" . U B 2 71 ? 8.099 -9.890 13.101 1.00 75.85 ? ? ? ? ? ? 77 U R "O2'" 1 71
+ATOM 2230 C "C1'" . U B 2 71 ? 7.346 -7.585 12.932 1.00 74.63 ? ? ? ? ? ? 77 U R "C1'" 1 71
+ATOM 2231 N N1 . U B 2 71 ? 7.492 -6.216 13.569 1.00 74.85 ? ? ? ? ? ? 77 U R N1 1 71
+ATOM 2232 C C2 . U B 2 71 ? 8.744 -5.634 13.714 1.00 75.56 ? ? ? ? ? ? 77 U R C2 1 71
+ATOM 2233 O O2 . U B 2 71 ? 9.786 -6.155 13.350 1.00 76.56 ? ? ? ? ? ? 77 U R O2 1 71
+ATOM 2234 N N3 . U B 2 71 ? 8.741 -4.392 14.310 1.00 75.42 ? ? ? ? ? ? 77 U R N3 1 71
+ATOM 2235 C C4 . U B 2 71 ? 7.641 -3.683 14.767 1.00 75.70 ? ? ? ? ? ? 77 U R C4 1 71
+ATOM 2236 O O4 . U B 2 71 ? 7.785 -2.579 15.280 1.00 76.39 ? ? ? ? ? ? 77 U R O4 1 71
+ATOM 2237 C C5 . U B 2 71 ? 6.377 -4.345 14.587 1.00 75.87 ? ? ? ? ? ? 77 U R C5 1 71
+ATOM 2238 C C6 . U B 2 71 ? 6.362 -5.550 14.008 1.00 75.21 ? ? ? ? ? ? 77 U R C6 1 71
+ATOM 2239 P P . A B 2 72 ? 6.322 -9.915 16.991 1.00 69.61 ? ? ? ? ? ? 78 A R P 1 72
+ATOM 2240 O OP1 . A B 2 72 ? 5.846 -11.191 17.566 1.00 69.08 ? ? ? ? ? ? 78 A R OP1 1 72
+ATOM 2241 O OP2 . A B 2 72 ? 5.613 -8.654 17.309 1.00 69.17 ? ? ? ? ? ? 78 A R OP2 1 72
+ATOM 2242 O "O5'" . A B 2 72 ? 7.855 -9.693 17.386 1.00 68.19 ? ? ? ? ? ? 78 A R "O5'" 1 72
+ATOM 2243 C "C5'" . A B 2 72 ? 8.850 -10.615 16.967 1.00 66.24 ? ? ? ? ? ? 78 A R "C5'" 1 72
+ATOM 2244 C "C4'" . A B 2 72 ? 10.207 -9.942 16.934 1.00 65.11 ? ? ? ? ? ? 78 A R "C4'" 1 72
+ATOM 2245 O "O4'" . A B 2 72 ? 10.159 -8.722 16.153 1.00 64.17 ? ? ? ? ? ? 78 A R "O4'" 1 72
+ATOM 2246 C "C3'" . A B 2 72 ? 10.704 -9.449 18.280 1.00 64.46 ? ? ? ? ? ? 78 A R "C3'" 1 72
+ATOM 2247 O "O3'" . A B 2 72 ? 11.184 -10.521 19.070 1.00 64.45 ? ? ? ? ? ? 78 A R "O3'" 1 72
+ATOM 2248 C "C2'" . A B 2 72 ? 11.810 -8.498 17.843 1.00 63.71 ? ? ? ? ? ? 78 A R "C2'" 1 72
+ATOM 2249 O "O2'" . A B 2 72 ? 12.999 -9.159 17.453 1.00 63.20 ? ? ? ? ? ? 78 A R "O2'" 1 72
+ATOM 2250 C "C1'" . A B 2 72 ? 11.138 -7.822 16.649 1.00 62.80 ? ? ? ? ? ? 78 A R "C1'" 1 72
+ATOM 2251 N N9 . A B 2 72 ? 10.505 -6.551 17.007 1.00 60.44 ? ? ? ? ? ? 78 A R N9 1 72
+ATOM 2252 C C8 . A B 2 72 ? 9.168 -6.291 17.131 1.00 59.67 ? ? ? ? ? ? 78 A R C8 1 72
+ATOM 2253 N N7 . A B 2 72 ? 8.897 -5.051 17.467 1.00 59.06 ? ? ? ? ? ? 78 A R N7 1 72
+ATOM 2254 C C5 . A B 2 72 ? 10.143 -4.454 17.575 1.00 58.42 ? ? ? ? ? ? 78 A R C5 1 72
+ATOM 2255 C C6 . A B 2 72 ? 10.556 -3.141 17.903 1.00 58.02 ? ? ? ? ? ? 78 A R C6 1 72
+ATOM 2256 N N6 . A B 2 72 ? 9.707 -2.150 18.199 1.00 56.38 ? ? ? ? ? ? 78 A R N6 1 72
+ATOM 2257 N N1 . A B 2 72 ? 11.886 -2.880 17.918 1.00 57.36 ? ? ? ? ? ? 78 A R N1 1 72
+ATOM 2258 C C2 . A B 2 72 ? 12.747 -3.865 17.624 1.00 57.20 ? ? ? ? ? ? 78 A R C2 1 72
+ATOM 2259 N N3 . A B 2 72 ? 12.476 -5.133 17.303 1.00 58.27 ? ? ? ? ? ? 78 A R N3 1 72
+ATOM 2260 C C4 . A B 2 72 ? 11.148 -5.366 17.296 1.00 58.98 ? ? ? ? ? ? 78 A R C4 1 72
+ATOM 2261 P P . G B 2 73 ? 10.928 -10.493 20.649 1.00 65.14 ? ? ? ? ? ? 79 G R P 1 73
+ATOM 2262 O OP1 . G B 2 73 ? 11.299 -11.829 21.174 1.00 63.61 ? ? ? ? ? ? 79 G R OP1 1 73
+ATOM 2263 O OP2 . G B 2 73 ? 9.574 -9.943 20.912 1.00 63.23 ? ? ? ? ? ? 79 G R OP2 1 73
+ATOM 2264 O "O5'" . G B 2 73 ? 11.984 -9.399 21.147 1.00 61.88 ? ? ? ? ? ? 79 G R "O5'" 1 73
+ATOM 2265 C "C5'" . G B 2 73 ? 13.378 -9.639 21.031 1.00 59.30 ? ? ? ? ? ? 79 G R "C5'" 1 73
+ATOM 2266 C "C4'" . G B 2 73 ? 14.145 -8.353 21.257 1.00 58.01 ? ? ? ? ? ? 79 G R "C4'" 1 73
+ATOM 2267 O "O4'" . G B 2 73 ? 13.671 -7.323 20.355 1.00 57.31 ? ? ? ? ? ? 79 G R "O4'" 1 73
+ATOM 2268 C "C3'" . G B 2 73 ? 13.951 -7.693 22.613 1.00 57.77 ? ? ? ? ? ? 79 G R "C3'" 1 73
+ATOM 2269 O "O3'" . G B 2 73 ? 14.661 -8.372 23.647 1.00 57.89 ? ? ? ? ? ? 79 G R "O3'" 1 73
+ATOM 2270 C "C2'" . G B 2 73 ? 14.536 -6.321 22.310 1.00 56.72 ? ? ? ? ? ? 79 G R "C2'" 1 73
+ATOM 2271 O "O2'" . G B 2 73 ? 15.951 -6.333 22.264 1.00 57.00 ? ? ? ? ? ? 79 G R "O2'" 1 73
+ATOM 2272 C "C1'" . G B 2 73 ? 13.938 -6.053 20.929 1.00 54.88 ? ? ? ? ? ? 79 G R "C1'" 1 73
+ATOM 2273 N N9 . G B 2 73 ? 12.706 -5.265 20.993 1.00 51.28 ? ? ? ? ? ? 79 G R N9 1 73
+ATOM 2274 C C8 . G B 2 73 ? 11.420 -5.707 20.779 1.00 50.97 ? ? ? ? ? ? 79 G R C8 1 73
+ATOM 2275 N N7 . G B 2 73 ? 10.516 -4.773 20.915 1.00 49.98 ? ? ? ? ? ? 79 G R N7 1 73
+ATOM 2276 C C5 . G B 2 73 ? 11.247 -3.637 21.242 1.00 50.08 ? ? ? ? ? ? 79 G R C5 1 73
+ATOM 2277 C C6 . G B 2 73 ? 10.812 -2.310 21.505 1.00 50.67 ? ? ? ? ? ? 79 G R C6 1 73
+ATOM 2278 O O6 . G B 2 73 ? 9.651 -1.872 21.503 1.00 52.38 ? ? ? ? ? ? 79 G R O6 1 73
+ATOM 2279 N N1 . G B 2 73 ? 11.877 -1.454 21.798 1.00 49.44 ? ? ? ? ? ? 79 G R N1 1 73
+ATOM 2280 C C2 . G B 2 73 ? 13.203 -1.836 21.830 1.00 50.00 ? ? ? ? ? ? 79 G R C2 1 73
+ATOM 2281 N N2 . G B 2 73 ? 14.100 -0.881 22.130 1.00 49.13 ? ? ? ? ? ? 79 G R N2 1 73
+ATOM 2282 N N3 . G B 2 73 ? 13.620 -3.077 21.581 1.00 49.07 ? ? ? ? ? ? 79 G R N3 1 73
+ATOM 2283 C C4 . G B 2 73 ? 12.596 -3.924 21.295 1.00 49.80 ? ? ? ? ? ? 79 G R C4 1 73
+ATOM 2284 P P . G B 2 74 ? 14.122 -8.350 25.160 1.00 57.66 ? ? ? ? ? ? 80 G R P 1 74
+ATOM 2285 O OP1 . G B 2 74 ? 15.098 -9.124 25.964 1.00 57.33 ? ? ? ? ? ? 80 G R OP1 1 74
+ATOM 2286 O OP2 . G B 2 74 ? 12.693 -8.743 25.173 1.00 55.14 ? ? ? ? ? ? 80 G R OP2 1 74
+ATOM 2287 O "O5'" . G B 2 74 ? 14.209 -6.800 25.553 1.00 53.80 ? ? ? ? ? ? 80 G R "O5'" 1 74
+ATOM 2288 C "C5'" . G B 2 74 ? 15.475 -6.243 25.869 1.00 52.46 ? ? ? ? ? ? 80 G R "C5'" 1 74
+ATOM 2289 C "C4'" . G B 2 74 ? 15.433 -4.729 25.957 1.00 51.00 ? ? ? ? ? ? 80 G R "C4'" 1 74
+ATOM 2290 O "O4'" . G B 2 74 ? 14.604 -4.164 24.918 1.00 49.65 ? ? ? ? ? ? 80 G R "O4'" 1 74
+ATOM 2291 C "C3'" . G B 2 74 ? 14.770 -4.162 27.194 1.00 51.14 ? ? ? ? ? ? 80 G R "C3'" 1 74
+ATOM 2292 O "O3'" . G B 2 74 ? 15.575 -4.364 28.347 1.00 52.84 ? ? ? ? ? ? 80 G R "O3'" 1 74
+ATOM 2293 C "C2'" . G B 2 74 ? 14.648 -2.702 26.774 1.00 49.46 ? ? ? ? ? ? 80 G R "C2'" 1 74
+ATOM 2294 O "O2'" . G B 2 74 ? 15.872 -1.998 26.843 1.00 48.81 ? ? ? ? ? ? 80 G R "O2'" 1 74
+ATOM 2295 C "C1'" . G B 2 74 ? 14.205 -2.866 25.319 1.00 47.58 ? ? ? ? ? ? 80 G R "C1'" 1 74
+ATOM 2296 N N9 . G B 2 74 ? 12.761 -2.739 25.118 1.00 45.43 ? ? ? ? ? ? 80 G R N9 1 74
+ATOM 2297 C C8 . G B 2 74 ? 11.886 -3.721 24.714 1.00 43.16 ? ? ? ? ? ? 80 G R C8 1 74
+ATOM 2298 N N7 . G B 2 74 ? 10.650 -3.313 24.622 1.00 43.61 ? ? ? ? ? ? 80 G R N7 1 74
+ATOM 2299 C C5 . G B 2 74 ? 10.705 -1.975 24.988 1.00 42.89 ? ? ? ? ? ? 80 G R C5 1 74
+ATOM 2300 C C6 . G B 2 74 ? 9.674 -1.014 25.075 1.00 42.76 ? ? ? ? ? ? 80 G R C6 1 74
+ATOM 2301 O O6 . G B 2 74 ? 8.469 -1.184 24.835 1.00 45.44 ? ? ? ? ? ? 80 G R O6 1 74
+ATOM 2302 N N1 . G B 2 74 ? 10.150 0.236 25.489 1.00 41.49 ? ? ? ? ? ? 80 G R N1 1 74
+ATOM 2303 C C2 . G B 2 74 ? 11.471 0.513 25.778 1.00 41.84 ? ? ? ? ? ? 80 G R C2 1 74
+ATOM 2304 N N2 . G B 2 74 ? 11.772 1.764 26.155 1.00 39.89 ? ? ? ? ? ? 80 G R N2 1 74
+ATOM 2305 N N3 . G B 2 74 ? 12.447 -0.381 25.694 1.00 43.10 ? ? ? ? ? ? 80 G R N3 1 74
+ATOM 2306 C C4 . G B 2 74 ? 11.996 -1.602 25.296 1.00 44.40 ? ? ? ? ? ? 80 G R C4 1 74
+ATOM 2307 P P . U B 2 75 ? 14.858 -4.790 29.716 1.00 52.40 ? ? ? ? ? ? 81 U R P 1 75
+ATOM 2308 O OP1 . U B 2 75 ? 15.889 -5.311 30.644 1.00 51.65 ? ? ? ? ? ? 81 U R OP1 1 75
+ATOM 2309 O OP2 . U B 2 75 ? 13.689 -5.635 29.391 1.00 50.77 ? ? ? ? ? ? 81 U R OP2 1 75
+ATOM 2310 O "O5'" . U B 2 75 ? 14.320 -3.375 30.238 1.00 51.33 ? ? ? ? ? ? 81 U R "O5'" 1 75
+ATOM 2311 C "C5'" . U B 2 75 ? 15.231 -2.303 30.495 1.00 50.78 ? ? ? ? ? ? 81 U R "C5'" 1 75
+ATOM 2312 C "C4'" . U B 2 75 ? 14.473 -1.002 30.666 1.00 49.83 ? ? ? ? ? ? 81 U R "C4'" 1 75
+ATOM 2313 O "O4'" . U B 2 75 ? 13.684 -0.746 29.482 1.00 50.87 ? ? ? ? ? ? 81 U R "O4'" 1 75
+ATOM 2314 C "C3'" . U B 2 75 ? 13.426 -1.036 31.764 1.00 50.10 ? ? ? ? ? ? 81 U R "C3'" 1 75
+ATOM 2315 O "O3'" . U B 2 75 ? 14.033 -0.837 33.036 1.00 49.50 ? ? ? ? ? ? 81 U R "O3'" 1 75
+ATOM 2316 C "C2'" . U B 2 75 ? 12.480 0.091 31.351 1.00 49.41 ? ? ? ? ? ? 81 U R "C2'" 1 75
+ATOM 2317 O "O2'" . U B 2 75 ? 12.910 1.380 31.745 1.00 50.56 ? ? ? ? ? ? 81 U R "O2'" 1 75
+ATOM 2318 C "C1'" . U B 2 75 ? 12.508 -0.031 29.829 1.00 48.83 ? ? ? ? ? ? 81 U R "C1'" 1 75
+ATOM 2319 N N1 . U B 2 75 ? 11.300 -0.724 29.270 1.00 47.38 ? ? ? ? ? ? 81 U R N1 1 75
+ATOM 2320 C C2 . U B 2 75 ? 10.152 0.012 29.036 1.00 46.82 ? ? ? ? ? ? 81 U R C2 1 75
+ATOM 2321 O O2 . U B 2 75 ? 10.065 1.211 29.258 1.00 47.68 ? ? ? ? ? ? 81 U R O2 1 75
+ATOM 2322 N N3 . U B 2 75 ? 9.097 -0.711 28.527 1.00 44.94 ? ? ? ? ? ? 81 U R N3 1 75
+ATOM 2323 C C4 . U B 2 75 ? 9.079 -2.065 28.232 1.00 46.49 ? ? ? ? ? ? 81 U R C4 1 75
+ATOM 2324 O O4 . U B 2 75 ? 8.064 -2.577 27.774 1.00 48.37 ? ? ? ? ? ? 81 U R O4 1 75
+ATOM 2325 C C5 . U B 2 75 ? 10.309 -2.767 28.497 1.00 46.21 ? ? ? ? ? ? 81 U R C5 1 75
+ATOM 2326 C C6 . U B 2 75 ? 11.346 -2.082 28.998 1.00 47.52 ? ? ? ? ? ? 81 U R C6 1 75
+ATOM 2327 P P . A B 2 76 ? 13.798 -1.911 34.202 1.00 48.15 ? ? ? ? ? ? 82 A R P 1 76
+ATOM 2328 O OP1 . A B 2 76 ? 14.290 -1.283 35.451 1.00 46.89 ? ? ? ? ? ? 82 A R OP1 1 76
+ATOM 2329 O OP2 . A B 2 76 ? 14.356 -3.215 33.771 1.00 46.66 ? ? ? ? ? ? 82 A R OP2 1 76
+ATOM 2330 O "O5'" . A B 2 76 ? 12.207 -2.069 34.249 1.00 44.82 ? ? ? ? ? ? 82 A R "O5'" 1 76
+ATOM 2331 C "C5'" . A B 2 76 ? 11.417 -1.053 34.843 1.00 45.70 ? ? ? ? ? ? 82 A R "C5'" 1 76
+ATOM 2332 C "C4'" . A B 2 76 ? 10.370 -1.627 35.781 1.00 45.95 ? ? ? ? ? ? 82 A R "C4'" 1 76
+ATOM 2333 O "O4'" . A B 2 76 ? 9.539 -2.570 35.053 1.00 45.43 ? ? ? ? ? ? 82 A R "O4'" 1 76
+ATOM 2334 C "C3'" . A B 2 76 ? 10.920 -2.369 36.999 1.00 45.36 ? ? ? ? ? ? 82 A R "C3'" 1 76
+ATOM 2335 O "O3'" . A B 2 76 ? 10.210 -1.979 38.189 1.00 45.87 ? ? ? ? ? ? 82 A R "O3'" 1 76
+ATOM 2336 C "C2'" . A B 2 76 ? 10.697 -3.831 36.622 1.00 45.35 ? ? ? ? ? ? 82 A R "C2'" 1 76
+ATOM 2337 O "O2'" . A B 2 76 ? 10.535 -4.688 37.734 1.00 47.91 ? ? ? ? ? ? 82 A R "O2'" 1 76
+ATOM 2338 C "C1'" . A B 2 76 ? 9.389 -3.719 35.851 1.00 44.92 ? ? ? ? ? ? 82 A R "C1'" 1 76
+ATOM 2339 N N9 . A B 2 76 ? 9.070 -4.873 35.015 1.00 44.59 ? ? ? ? ? ? 82 A R N9 1 76
+ATOM 2340 C C8 . A B 2 76 ? 9.914 -5.869 34.606 1.00 45.57 ? ? ? ? ? ? 82 A R C8 1 76
+ATOM 2341 N N7 . A B 2 76 ? 9.336 -6.785 33.866 1.00 45.95 ? ? ? ? ? ? 82 A R N7 1 76
+ATOM 2342 C C5 . A B 2 76 ? 8.023 -6.360 33.781 1.00 44.58 ? ? ? ? ? ? 82 A R C5 1 76
+ATOM 2343 C C6 . A B 2 76 ? 6.889 -6.894 33.136 1.00 45.34 ? ? ? ? ? ? 82 A R C6 1 76
+ATOM 2344 N N6 . A B 2 76 ? 6.917 -8.024 32.422 1.00 47.42 ? ? ? ? ? ? 82 A R N6 1 76
+ATOM 2345 N N1 . A B 2 76 ? 5.720 -6.226 33.250 1.00 45.56 ? ? ? ? ? ? 82 A R N1 1 76
+ATOM 2346 C C2 . A B 2 76 ? 5.693 -5.094 33.966 1.00 45.89 ? ? ? ? ? ? 82 A R C2 1 76
+ATOM 2347 N N3 . A B 2 76 ? 6.694 -4.495 34.617 1.00 45.59 ? ? ? ? ? ? 82 A R N3 1 76
+ATOM 2348 C C4 . A B 2 76 ? 7.841 -5.185 34.486 1.00 44.73 ? ? ? ? ? ? 82 A R C4 1 76
+ATOM 2349 P P . G B 2 77 ? 11.017 -1.506 39.497 1.00 47.83 ? ? ? ? ? ? 83 G R P 1 77
+ATOM 2350 O OP1 . G B 2 77 ? 12.163 -2.423 39.702 1.00 45.31 ? ? ? ? ? ? 83 G R OP1 1 77
+ATOM 2351 O OP2 . G B 2 77 ? 10.038 -1.282 40.585 1.00 49.31 ? ? ? ? ? ? 83 G R OP2 1 77
+ATOM 2352 O "O5'" . G B 2 77 ? 11.600 -0.072 39.095 1.00 47.50 ? ? ? ? ? ? 83 G R "O5'" 1 77
+ATOM 2353 C "C5'" . G B 2 77 ? 10.743 1.025 38.770 1.00 45.06 ? ? ? ? ? ? 83 G R "C5'" 1 77
+ATOM 2354 C "C4'" . G B 2 77 ? 11.569 2.199 38.272 1.00 43.12 ? ? ? ? ? ? 83 G R "C4'" 1 77
+ATOM 2355 O "O4'" . G B 2 77 ? 12.687 2.441 39.163 1.00 41.40 ? ? ? ? ? ? 83 G R "O4'" 1 77
+ATOM 2356 C "C3'" . G B 2 77 ? 12.210 2.012 36.903 1.00 43.72 ? ? ? ? ? ? 83 G R "C3'" 1 77
+ATOM 2357 O "O3'" . G B 2 77 ? 12.215 3.265 36.248 1.00 47.09 ? ? ? ? ? ? 83 G R "O3'" 1 77
+ATOM 2358 C "C2'" . G B 2 77 ? 13.628 1.572 37.237 1.00 39.54 ? ? ? ? ? ? 83 G R "C2'" 1 77
+ATOM 2359 O "O2'" . G B 2 77 ? 14.543 1.853 36.205 1.00 40.86 ? ? ? ? ? ? 83 G R "O2'" 1 77
+ATOM 2360 C "C1'" . G B 2 77 ? 13.876 2.504 38.408 1.00 38.06 ? ? ? ? ? ? 83 G R "C1'" 1 77
+ATOM 2361 N N9 . G B 2 77 ? 14.986 2.146 39.276 1.00 34.85 ? ? ? ? ? ? 83 G R N9 1 77
+ATOM 2362 C C8 . G B 2 77 ? 15.352 0.889 39.689 1.00 34.47 ? ? ? ? ? ? 83 G R C8 1 77
+ATOM 2363 N N7 . G B 2 77 ? 16.395 0.886 40.469 1.00 33.72 ? ? ? ? ? ? 83 G R N7 1 77
+ATOM 2364 C C5 . G B 2 77 ? 16.739 2.227 40.581 1.00 32.97 ? ? ? ? ? ? 83 G R C5 1 77
+ATOM 2365 C C6 . G B 2 77 ? 17.790 2.841 41.305 1.00 32.85 ? ? ? ? ? ? 83 G R C6 1 77
+ATOM 2366 O O6 . G B 2 77 ? 18.644 2.303 42.017 1.00 36.28 ? ? ? ? ? ? 83 G R O6 1 77
+ATOM 2367 N N1 . G B 2 77 ? 17.800 4.226 41.161 1.00 32.89 ? ? ? ? ? ? 83 G R N1 1 77
+ATOM 2368 C C2 . G B 2 77 ? 16.893 4.933 40.407 1.00 34.15 ? ? ? ? ? ? 83 G R C2 1 77
+ATOM 2369 N N2 . G B 2 77 ? 17.070 6.262 40.398 1.00 34.45 ? ? ? ? ? ? 83 G R N2 1 77
+ATOM 2370 N N3 . G B 2 77 ? 15.895 4.374 39.719 1.00 32.54 ? ? ? ? ? ? 83 G R N3 1 77
+ATOM 2371 C C4 . G B 2 77 ? 15.879 3.019 39.853 1.00 33.39 ? ? ? ? ? ? 83 G R C4 1 77
+ATOM 2372 P P . C B 2 78 ? 11.886 3.373 34.693 1.00 49.46 ? ? ? ? ? ? 84 C R P 1 78
+ATOM 2373 O OP1 . C B 2 78 ? 11.613 2.030 34.141 1.00 48.44 ? ? ? ? ? ? 84 C R OP1 1 78
+ATOM 2374 O OP2 . C B 2 78 ? 12.962 4.192 34.093 1.00 51.80 ? ? ? ? ? ? 84 C R OP2 1 78
+ATOM 2375 O "O5'" . C B 2 78 ? 10.514 4.194 34.693 1.00 51.45 ? ? ? ? ? ? 84 C R "O5'" 1 78
+ATOM 2376 C "C5'" . C B 2 78 ? 10.439 5.554 35.117 1.00 54.65 ? ? ? ? ? ? 84 C R "C5'" 1 78
+ATOM 2377 C "C4'" . C B 2 78 ? 9.043 6.096 34.857 1.00 57.66 ? ? ? ? ? ? 84 C R "C4'" 1 78
+ATOM 2378 O "O4'" . C B 2 78 ? 8.734 5.975 33.441 1.00 58.13 ? ? ? ? ? ? 84 C R "O4'" 1 78
+ATOM 2379 C "C3'" . C B 2 78 ? 7.903 5.325 35.513 1.00 60.05 ? ? ? ? ? ? 84 C R "C3'" 1 78
+ATOM 2380 O "O3'" . C B 2 78 ? 7.710 5.639 36.892 1.00 61.35 ? ? ? ? ? ? 84 C R "O3'" 1 78
+ATOM 2381 C "C2'" . C B 2 78 ? 6.724 5.727 34.625 1.00 60.61 ? ? ? ? ? ? 84 C R "C2'" 1 78
+ATOM 2382 O "O2'" . C B 2 78 ? 6.274 7.057 34.824 1.00 62.79 ? ? ? ? ? ? 84 C R "O2'" 1 78
+ATOM 2383 C "C1'" . C B 2 78 ? 7.382 5.575 33.257 1.00 58.08 ? ? ? ? ? ? 84 C R "C1'" 1 78
+ATOM 2384 N N1 . C B 2 78 ? 7.283 4.163 32.714 1.00 57.22 ? ? ? ? ? ? 84 C R N1 1 78
+ATOM 2385 C C2 . C B 2 78 ? 6.070 3.701 32.163 1.00 57.45 ? ? ? ? ? ? 84 C R C2 1 78
+ATOM 2386 O O2 . C B 2 78 ? 5.082 4.446 32.114 1.00 59.29 ? ? ? ? ? ? 84 C R O2 1 78
+ATOM 2387 N N3 . C B 2 78 ? 6.002 2.429 31.686 1.00 55.60 ? ? ? ? ? ? 84 C R N3 1 78
+ATOM 2388 C C4 . C B 2 78 ? 7.070 1.629 31.743 1.00 55.19 ? ? ? ? ? ? 84 C R C4 1 78
+ATOM 2389 N N4 . C B 2 78 ? 6.947 0.390 31.264 1.00 54.87 ? ? ? ? ? ? 84 C R N4 1 78
+ATOM 2390 C C5 . C B 2 78 ? 8.312 2.066 32.297 1.00 55.31 ? ? ? ? ? ? 84 C R C5 1 78
+ATOM 2391 C C6 . C B 2 78 ? 8.367 3.321 32.761 1.00 56.34 ? ? ? ? ? ? 84 C R C6 1 78
+ATOM 2392 P P . G B 2 79 ? 6.866 4.631 37.815 1.00 63.25 ? ? ? ? ? ? 85 G R P 1 79
+ATOM 2393 O OP1 . G B 2 79 ? 7.429 4.689 39.182 1.00 63.12 ? ? ? ? ? ? 85 G R OP1 1 79
+ATOM 2394 O OP2 . G B 2 79 ? 6.750 3.317 37.143 1.00 62.60 ? ? ? ? ? ? 85 G R OP2 1 79
+ATOM 2395 O "O5'" . G B 2 79 ? 5.422 5.312 37.804 1.00 60.33 ? ? ? ? ? ? 85 G R "O5'" 1 79
+ATOM 2396 C "C5'" . G B 2 79 ? 4.291 4.526 38.093 1.00 59.21 ? ? ? ? ? ? 85 G R "C5'" 1 79
+ATOM 2397 C "C4'" . G B 2 79 ? 3.159 4.854 37.141 1.00 59.01 ? ? ? ? ? ? 85 G R "C4'" 1 79
+ATOM 2398 O "O4'" . G B 2 79 ? 3.589 4.833 35.754 1.00 58.55 ? ? ? ? ? ? 85 G R "O4'" 1 79
+ATOM 2399 C "C3'" . G B 2 79 ? 2.047 3.828 37.153 1.00 59.27 ? ? ? ? ? ? 85 G R "C3'" 1 79
+ATOM 2400 O "O3'" . G B 2 79 ? 1.275 3.953 38.327 1.00 60.57 ? ? ? ? ? ? 85 G R "O3'" 1 79
+ATOM 2401 C "C2'" . G B 2 79 ? 1.325 4.175 35.858 1.00 57.90 ? ? ? ? ? ? 85 G R "C2'" 1 79
+ATOM 2402 O "O2'" . G B 2 79 ? 0.601 5.387 35.895 1.00 58.82 ? ? ? ? ? ? 85 G R "O2'" 1 79
+ATOM 2403 C "C1'" . G B 2 79 ? 2.548 4.294 34.949 1.00 56.89 ? ? ? ? ? ? 85 G R "C1'" 1 79
+ATOM 2404 N N9 . G B 2 79 ? 2.969 2.989 34.430 1.00 54.26 ? ? ? ? ? ? 85 G R N9 1 79
+ATOM 2405 C C8 . G B 2 79 ? 4.195 2.392 34.598 1.00 52.40 ? ? ? ? ? ? 85 G R C8 1 79
+ATOM 2406 N N7 . G B 2 79 ? 4.286 1.222 34.034 1.00 52.13 ? ? ? ? ? ? 85 G R N7 1 79
+ATOM 2407 C C5 . G B 2 79 ? 3.041 1.022 33.456 1.00 51.80 ? ? ? ? ? ? 85 G R C5 1 79
+ATOM 2408 C C6 . G B 2 79 ? 2.545 -0.075 32.708 1.00 51.73 ? ? ? ? ? ? 85 G R C6 1 79
+ATOM 2409 O O6 . G B 2 79 ? 3.131 -1.120 32.395 1.00 51.53 ? ? ? ? ? ? 85 G R O6 1 79
+ATOM 2410 N N1 . G B 2 79 ? 1.227 0.118 32.302 1.00 51.72 ? ? ? ? ? ? 85 G R N1 1 79
+ATOM 2411 C C2 . G B 2 79 ? 0.478 1.234 32.585 1.00 51.74 ? ? ? ? ? ? 85 G R C2 1 79
+ATOM 2412 N N2 . G B 2 79 ? -0.777 1.244 32.113 1.00 52.75 ? ? ? ? ? ? 85 G R N2 1 79
+ATOM 2413 N N3 . G B 2 79 ? 0.930 2.266 33.285 1.00 51.77 ? ? ? ? ? ? 85 G R N3 1 79
+ATOM 2414 C C4 . G B 2 79 ? 2.216 2.099 33.689 1.00 52.38 ? ? ? ? ? ? 85 G R C4 1 79
+ATOM 2415 P P . G B 2 80 ? 1.228 2.708 39.335 1.00 62.35 ? ? ? ? ? ? 86 G R P 1 80
+ATOM 2416 O OP1 . G B 2 80 ? 1.013 3.258 40.692 1.00 62.27 ? ? ? ? ? ? 86 G R OP1 1 80
+ATOM 2417 O OP2 . G B 2 80 ? 2.383 1.811 39.084 1.00 59.97 ? ? ? ? ? ? 86 G R OP2 1 80
+ATOM 2418 O "O5'" . G B 2 80 ? -0.087 1.934 38.852 1.00 61.06 ? ? ? ? ? ? 86 G R "O5'" 1 80
+ATOM 2419 C "C5'" . G B 2 80 ? -1.254 2.660 38.457 1.00 60.52 ? ? ? ? ? ? 86 G R "C5'" 1 80
+ATOM 2420 C "C4'" . G B 2 80 ? -2.023 1.921 37.377 1.00 58.96 ? ? ? ? ? ? 86 G R "C4'" 1 80
+ATOM 2421 O "O4'" . G B 2 80 ? -1.228 1.792 36.170 1.00 60.02 ? ? ? ? ? ? 86 G R "O4'" 1 80
+ATOM 2422 C "C3'" . G B 2 80 ? -2.355 0.482 37.713 1.00 58.00 ? ? ? ? ? ? 86 G R "C3'" 1 80
+ATOM 2423 O "O3'" . G B 2 80 ? -3.443 0.418 38.619 1.00 57.37 ? ? ? ? ? ? 86 G R "O3'" 1 80
+ATOM 2424 C "C2'" . G B 2 80 ? -2.676 -0.070 36.330 1.00 58.05 ? ? ? ? ? ? 86 G R "C2'" 1 80
+ATOM 2425 O "O2'" . G B 2 80 ? -3.948 0.292 35.837 1.00 58.90 ? ? ? ? ? ? 86 G R "O2'" 1 80
+ATOM 2426 C "C1'" . G B 2 80 ? -1.568 0.583 35.507 1.00 58.67 ? ? ? ? ? ? 86 G R "C1'" 1 80
+ATOM 2427 N N9 . G B 2 80 ? -0.399 -0.296 35.406 1.00 58.68 ? ? ? ? ? ? 86 G R N9 1 80
+ATOM 2428 C C8 . G B 2 80 ? 0.857 -0.098 35.933 1.00 57.81 ? ? ? ? ? ? 86 G R C8 1 80
+ATOM 2429 N N7 . G B 2 80 ? 1.687 -1.073 35.683 1.00 57.19 ? ? ? ? ? ? 86 G R N7 1 80
+ATOM 2430 C C5 . G B 2 80 ? 0.936 -1.981 34.947 1.00 57.25 ? ? ? ? ? ? 86 G R C5 1 80
+ATOM 2431 C C6 . G B 2 80 ? 1.295 -3.236 34.393 1.00 57.26 ? ? ? ? ? ? 86 G R C6 1 80
+ATOM 2432 O O6 . G B 2 80 ? 2.390 -3.808 34.454 1.00 58.09 ? ? ? ? ? ? 86 G R O6 1 80
+ATOM 2433 N N1 . G B 2 80 ? 0.232 -3.843 33.722 1.00 57.48 ? ? ? ? ? ? 86 G R N1 1 80
+ATOM 2434 C C2 . G B 2 80 ? -1.026 -3.296 33.595 1.00 58.19 ? ? ? ? ? ? 86 G R C2 1 80
+ATOM 2435 N N2 . G B 2 80 ? -1.938 -4.007 32.914 1.00 58.42 ? ? ? ? ? ? 86 G R N2 1 80
+ATOM 2436 N N3 . G B 2 80 ? -1.373 -2.125 34.112 1.00 57.80 ? ? ? ? ? ? 86 G R N3 1 80
+ATOM 2437 C C4 . G B 2 80 ? -0.349 -1.521 34.770 1.00 57.74 ? ? ? ? ? ? 86 G R C4 1 80
+ATOM 2438 P P . G B 2 81 ? -3.358 -0.547 39.893 1.00 55.75 ? ? ? ? ? ? 87 G R P 1 81
+ATOM 2439 O OP1 . G B 2 81 ? -4.558 -0.317 40.729 1.00 56.05 ? ? ? ? ? ? 87 G R OP1 1 81
+ATOM 2440 O OP2 . G B 2 81 ? -2.015 -0.385 40.504 1.00 54.68 ? ? ? ? ? ? 87 G R OP2 1 81
+ATOM 2441 O "O5'" . G B 2 81 ? -3.461 -2.002 39.228 1.00 53.17 ? ? ? ? ? ? 87 G R "O5'" 1 81
+ATOM 2442 C "C5'" . G B 2 81 ? -4.602 -2.390 38.472 1.00 51.62 ? ? ? ? ? ? 87 G R "C5'" 1 81
+ATOM 2443 C "C4'" . G B 2 81 ? -4.289 -3.619 37.640 1.00 52.46 ? ? ? ? ? ? 87 G R "C4'" 1 81
+ATOM 2444 O "O4'" . G B 2 81 ? -3.197 -3.333 36.730 1.00 52.03 ? ? ? ? ? ? 87 G R "O4'" 1 81
+ATOM 2445 C "C3'" . G B 2 81 ? -3.765 -4.810 38.420 1.00 52.68 ? ? ? ? ? ? 87 G R "C3'" 1 81
+ATOM 2446 O "O3'" . G B 2 81 ? -4.805 -5.524 39.083 1.00 54.90 ? ? ? ? ? ? 87 G R "O3'" 1 81
+ATOM 2447 C "C2'" . G B 2 81 ? -3.090 -5.615 37.312 1.00 51.73 ? ? ? ? ? ? 87 G R "C2'" 1 81
+ATOM 2448 O "O2'" . G B 2 81 ? -3.989 -6.319 36.476 1.00 52.38 ? ? ? ? ? ? 87 G R "O2'" 1 81
+ATOM 2449 C "C1'" . G B 2 81 ? -2.405 -4.494 36.542 1.00 50.01 ? ? ? ? ? ? 87 G R "C1'" 1 81
+ATOM 2450 N N9 . G B 2 81 ? -1.035 -4.247 37.004 1.00 49.04 ? ? ? ? ? ? 87 G R N9 1 81
+ATOM 2451 C C8 . G B 2 81 ? -0.571 -3.162 37.715 1.00 48.04 ? ? ? ? ? ? 87 G R C8 1 81
+ATOM 2452 N N7 . G B 2 81 ? 0.703 -3.218 37.993 1.00 46.91 ? ? ? ? ? ? 87 G R N7 1 81
+ATOM 2453 C C5 . G B 2 81 ? 1.118 -4.423 37.435 1.00 46.63 ? ? ? ? ? ? 87 G R C5 1 81
+ATOM 2454 C C6 . G B 2 81 ? 2.399 -5.032 37.410 1.00 45.57 ? ? ? ? ? ? 87 G R C6 1 81
+ATOM 2455 O O6 . G B 2 81 ? 3.458 -4.617 37.890 1.00 45.95 ? ? ? ? ? ? 87 G R O6 1 81
+ATOM 2456 N N1 . G B 2 81 ? 2.393 -6.253 36.745 1.00 46.37 ? ? ? ? ? ? 87 G R N1 1 81
+ATOM 2457 C C2 . G B 2 81 ? 1.282 -6.820 36.166 1.00 47.68 ? ? ? ? ? ? 87 G R C2 1 81
+ATOM 2458 N N2 . G B 2 81 ? 1.468 -8.004 35.565 1.00 47.34 ? ? ? ? ? ? 87 G R N2 1 81
+ATOM 2459 N N3 . G B 2 81 ? 0.075 -6.262 36.176 1.00 47.12 ? ? ? ? ? ? 87 G R N3 1 81
+ATOM 2460 C C4 . G B 2 81 ? 0.062 -5.068 36.824 1.00 47.59 ? ? ? ? ? ? 87 G R C4 1 81
+ATOM 2461 P P . G B 2 82 ? -4.452 -6.318 40.437 1.00 57.33 ? ? ? ? ? ? 88 G R P 1 82
+ATOM 2462 O OP1 . G B 2 82 ? -5.721 -6.800 41.027 1.00 56.38 ? ? ? ? ? ? 88 G R OP1 1 82
+ATOM 2463 O OP2 . G B 2 82 ? -3.524 -5.481 41.237 1.00 55.25 ? ? ? ? ? ? 88 G R OP2 1 82
+ATOM 2464 O "O5'" . G B 2 82 ? -3.626 -7.587 39.914 1.00 56.94 ? ? ? ? ? ? 88 G R "O5'" 1 82
+ATOM 2465 C "C5'" . G B 2 82 ? -4.248 -8.549 39.058 1.00 56.89 ? ? ? ? ? ? 88 G R "C5'" 1 82
+ATOM 2466 C "C4'" . G B 2 82 ? -3.237 -9.570 38.575 1.00 55.72 ? ? ? ? ? ? 88 G R "C4'" 1 82
+ATOM 2467 O "O4'" . G B 2 82 ? -2.168 -8.913 37.850 1.00 55.49 ? ? ? ? ? ? 88 G R "O4'" 1 82
+ATOM 2468 C "C3'" . G B 2 82 ? -2.501 -10.306 39.680 1.00 55.58 ? ? ? ? ? ? 88 G R "C3'" 1 82
+ATOM 2469 O "O3'" . G B 2 82 ? -3.314 -11.336 40.231 1.00 55.95 ? ? ? ? ? ? 88 G R "O3'" 1 82
+ATOM 2470 C "C2'" . G B 2 82 ? -1.291 -10.825 38.913 1.00 54.34 ? ? ? ? ? ? 88 G R "C2'" 1 82
+ATOM 2471 O "O2'" . G B 2 82 ? -1.605 -11.912 38.070 1.00 54.19 ? ? ? ? ? ? 88 G R "O2'" 1 82
+ATOM 2472 C "C1'" . G B 2 82 ? -0.949 -9.601 38.069 1.00 53.58 ? ? ? ? ? ? 88 G R "C1'" 1 82
+ATOM 2473 N N9 . G B 2 82 ? -0.002 -8.686 38.711 1.00 52.96 ? ? ? ? ? ? 88 G R N9 1 82
+ATOM 2474 C C8 . G B 2 82 ? -0.277 -7.436 39.218 1.00 53.54 ? ? ? ? ? ? 88 G R C8 1 82
+ATOM 2475 N N7 . G B 2 82 ? 0.758 -6.834 39.739 1.00 52.35 ? ? ? ? ? ? 88 G R N7 1 82
+ATOM 2476 C C5 . G B 2 82 ? 1.789 -7.746 39.569 1.00 51.27 ? ? ? ? ? ? 88 G R C5 1 82
+ATOM 2477 C C6 . G B 2 82 ? 3.152 -7.648 39.933 1.00 50.82 ? ? ? ? ? ? 88 G R C6 1 82
+ATOM 2478 O O6 . G B 2 82 ? 3.722 -6.708 40.501 1.00 51.78 ? ? ? ? ? ? 88 G R O6 1 82
+ATOM 2479 N N1 . G B 2 82 ? 3.875 -8.788 39.587 1.00 50.54 ? ? ? ? ? ? 88 G R N1 1 82
+ATOM 2480 C C2 . G B 2 82 ? 3.341 -9.889 38.958 1.00 50.86 ? ? ? ? ? ? 88 G R C2 1 82
+ATOM 2481 N N2 . G B 2 82 ? 4.192 -10.891 38.700 1.00 49.84 ? ? ? ? ? ? 88 G R N2 1 82
+ATOM 2482 N N3 . G B 2 82 ? 2.062 -9.993 38.606 1.00 50.71 ? ? ? ? ? ? 88 G R N3 1 82
+ATOM 2483 C C4 . G B 2 82 ? 1.343 -8.890 38.940 1.00 51.31 ? ? ? ? ? ? 88 G R C4 1 82
+ATOM 2484 P P . U B 2 83 ? -3.334 -11.564 41.818 1.00 56.48 ? ? ? ? ? ? 89 U R P 1 83
+ATOM 2485 O OP1 . U B 2 83 ? -4.350 -12.600 42.112 1.00 56.34 ? ? ? ? ? ? 89 U R OP1 1 83
+ATOM 2486 O OP2 . U B 2 83 ? -3.425 -10.244 42.482 1.00 54.55 ? ? ? ? ? ? 89 U R OP2 1 83
+ATOM 2487 O "O5'" . U B 2 83 ? -1.879 -12.165 42.103 1.00 54.15 ? ? ? ? ? ? 89 U R "O5'" 1 83
+ATOM 2488 C "C5'" . U B 2 83 ? -1.553 -13.490 41.679 1.00 53.12 ? ? ? ? ? ? 89 U R "C5'" 1 83
+ATOM 2489 C "C4'" . U B 2 83 ? -0.059 -13.733 41.777 1.00 51.71 ? ? ? ? ? ? 89 U R "C4'" 1 83
+ATOM 2490 O "O4'" . U B 2 83 ? 0.647 -12.686 41.068 1.00 51.86 ? ? ? ? ? ? 89 U R "O4'" 1 83
+ATOM 2491 C "C3'" . U B 2 83 ? 0.517 -13.633 43.181 1.00 51.13 ? ? ? ? ? ? 89 U R "C3'" 1 83
+ATOM 2492 O "O3'" . U B 2 83 ? 0.299 -14.812 43.934 1.00 48.90 ? ? ? ? ? ? 89 U R "O3'" 1 83
+ATOM 2493 C "C2'" . U B 2 83 ? 1.989 -13.390 42.882 1.00 50.59 ? ? ? ? ? ? 89 U R "C2'" 1 83
+ATOM 2494 O "O2'" . U B 2 83 ? 2.651 -14.558 42.455 1.00 52.53 ? ? ? ? ? ? 89 U R "O2'" 1 83
+ATOM 2495 C "C1'" . U B 2 83 ? 1.876 -12.408 41.724 1.00 51.16 ? ? ? ? ? ? 89 U R "C1'" 1 83
+ATOM 2496 N N1 . U B 2 83 ? 1.939 -10.973 42.165 1.00 52.58 ? ? ? ? ? ? 89 U R N1 1 83
+ATOM 2497 C C2 . U B 2 83 ? 3.180 -10.398 42.367 1.00 53.85 ? ? ? ? ? ? 89 U R C2 1 83
+ATOM 2498 O O2 . U B 2 83 ? 4.232 -10.983 42.204 1.00 56.49 ? ? ? ? ? ? 89 U R O2 1 83
+ATOM 2499 N N3 . U B 2 83 ? 3.157 -9.088 42.774 1.00 55.13 ? ? ? ? ? ? 89 U R N3 1 83
+ATOM 2500 C C4 . U B 2 83 ? 2.040 -8.301 42.996 1.00 56.18 ? ? ? ? ? ? 89 U R C4 1 83
+ATOM 2501 O O4 . U B 2 83 ? 2.195 -7.136 43.355 1.00 58.79 ? ? ? ? ? ? 89 U R O4 1 83
+ATOM 2502 C C5 . U B 2 83 ? 0.775 -8.959 42.768 1.00 54.63 ? ? ? ? ? ? 89 U R C5 1 83
+ATOM 2503 C C6 . U B 2 83 ? 0.776 -10.241 42.373 1.00 54.47 ? ? ? ? ? ? 89 U R C6 1 83
+ATOM 2504 P P . U B 2 84 ? 0.075 -14.665 45.511 1.00 48.67 ? ? ? ? ? ? 90 U R P 1 84
+ATOM 2505 O OP1 . U B 2 84 ? -0.506 -15.933 46.007 1.00 47.76 ? ? ? ? ? ? 90 U R OP1 1 84
+ATOM 2506 O OP2 . U B 2 84 ? -0.603 -13.374 45.774 1.00 46.97 ? ? ? ? ? ? 90 U R OP2 1 84
+ATOM 2507 O "O5'" . U B 2 84 ? 1.566 -14.536 46.062 1.00 46.20 ? ? ? ? ? ? 90 U R "O5'" 1 84
+ATOM 2508 C "C5'" . U B 2 84 ? 2.420 -15.654 45.969 1.00 44.74 ? ? ? ? ? ? 90 U R "C5'" 1 84
+ATOM 2509 C "C4'" . U B 2 84 ? 3.838 -15.242 46.274 1.00 43.30 ? ? ? ? ? ? 90 U R "C4'" 1 84
+ATOM 2510 O "O4'" . U B 2 84 ? 4.267 -14.197 45.366 1.00 42.68 ? ? ? ? ? ? 90 U R "O4'" 1 84
+ATOM 2511 C "C3'" . U B 2 84 ? 4.019 -14.594 47.631 1.00 42.37 ? ? ? ? ? ? 90 U R "C3'" 1 84
+ATOM 2512 O "O3'" . U B 2 84 ? 4.017 -15.566 48.651 1.00 44.11 ? ? ? ? ? ? 90 U R "O3'" 1 84
+ATOM 2513 C "C2'" . U B 2 84 ? 5.393 -13.977 47.427 1.00 41.27 ? ? ? ? ? ? 90 U R "C2'" 1 84
+ATOM 2514 O "O2'" . U B 2 84 ? 6.438 -14.925 47.499 1.00 38.75 ? ? ? ? ? ? 90 U R "O2'" 1 84
+ATOM 2515 C "C1'" . U B 2 84 ? 5.238 -13.396 46.022 1.00 41.69 ? ? ? ? ? ? 90 U R "C1'" 1 84
+ATOM 2516 N N1 . U B 2 84 ? 4.800 -11.952 46.073 1.00 41.46 ? ? ? ? ? ? 90 U R N1 1 84
+ATOM 2517 C C2 . U B 2 84 ? 5.723 -10.971 46.409 1.00 40.57 ? ? ? ? ? ? 90 U R C2 1 84
+ATOM 2518 O O2 . U B 2 84 ? 6.893 -11.198 46.655 1.00 39.08 ? ? ? ? ? ? 90 U R O2 1 84
+ATOM 2519 N N3 . U B 2 84 ? 5.225 -9.689 46.447 1.00 40.46 ? ? ? ? ? ? 90 U R N3 1 84
+ATOM 2520 C C4 . U B 2 84 ? 3.922 -9.295 46.186 1.00 42.05 ? ? ? ? ? ? 90 U R C4 1 84
+ATOM 2521 O O4 . U B 2 84 ? 3.621 -8.106 46.254 1.00 45.54 ? ? ? ? ? ? 90 U R O4 1 84
+ATOM 2522 C C5 . U B 2 84 ? 3.015 -10.365 45.851 1.00 40.72 ? ? ? ? ? ? 90 U R C5 1 84
+ATOM 2523 C C6 . U B 2 84 ? 3.478 -11.621 45.811 1.00 40.94 ? ? ? ? ? ? 90 U R C6 1 84
+ATOM 2524 P P . A B 2 85 ? 3.462 -15.202 50.108 1.00 44.99 ? ? ? ? ? ? 91 A R P 1 85
+ATOM 2525 O OP1 . A B 2 85 ? 3.420 -16.465 50.879 1.00 45.40 ? ? ? ? ? ? 91 A R OP1 1 85
+ATOM 2526 O OP2 . A B 2 85 ? 2.227 -14.392 49.957 1.00 42.04 ? ? ? ? ? ? 91 A R OP2 1 85
+ATOM 2527 O "O5'" . A B 2 85 ? 4.617 -14.274 50.722 1.00 44.06 ? ? ? ? ? ? 91 A R "O5'" 1 85
+ATOM 2528 C "C5'" . A B 2 85 ? 5.928 -14.786 50.971 1.00 43.66 ? ? ? ? ? ? 91 A R "C5'" 1 85
+ATOM 2529 C "C4'" . A B 2 85 ? 6.948 -13.660 51.058 1.00 44.12 ? ? ? ? ? ? 91 A R "C4'" 1 85
+ATOM 2530 O "O4'" . A B 2 85 ? 6.797 -12.722 49.964 1.00 44.00 ? ? ? ? ? ? 91 A R "O4'" 1 85
+ATOM 2531 C "C3'" . A B 2 85 ? 6.797 -12.761 52.266 1.00 45.38 ? ? ? ? ? ? 91 A R "C3'" 1 85
+ATOM 2532 O "O3'" . A B 2 85 ? 7.362 -13.380 53.398 1.00 46.03 ? ? ? ? ? ? 91 A R "O3'" 1 85
+ATOM 2533 C "C2'" . A B 2 85 ? 7.574 -11.521 51.838 1.00 44.50 ? ? ? ? ? ? 91 A R "C2'" 1 85
+ATOM 2534 O "O2'" . A B 2 85 ? 8.978 -11.680 51.941 1.00 44.63 ? ? ? ? ? ? 91 A R "O2'" 1 85
+ATOM 2535 C "C1'" . A B 2 85 ? 7.169 -11.417 50.372 1.00 41.87 ? ? ? ? ? ? 91 A R "C1'" 1 85
+ATOM 2536 N N9 . A B 2 85 ? 6.071 -10.481 50.111 1.00 39.40 ? ? ? ? ? ? 91 A R N9 1 85
+ATOM 2537 C C8 . A B 2 85 ? 4.790 -10.788 49.731 1.00 38.55 ? ? ? ? ? ? 91 A R C8 1 85
+ATOM 2538 N N7 . A B 2 85 ? 4.010 -9.742 49.557 1.00 36.24 ? ? ? ? ? ? 91 A R N7 1 85
+ATOM 2539 C C5 . A B 2 85 ? 4.835 -8.670 49.840 1.00 35.05 ? ? ? ? ? ? 91 A R C5 1 85
+ATOM 2540 C C6 . A B 2 85 ? 4.612 -7.278 49.845 1.00 34.55 ? ? ? ? ? ? 91 A R C6 1 85
+ATOM 2541 N N6 . A B 2 85 ? 3.435 -6.728 49.538 1.00 33.41 ? ? ? ? ? ? 91 A R N6 1 85
+ATOM 2542 N N1 . A B 2 85 ? 5.644 -6.470 50.178 1.00 35.06 ? ? ? ? ? ? 91 A R N1 1 85
+ATOM 2543 C C2 . A B 2 85 ? 6.827 -7.024 50.485 1.00 35.95 ? ? ? ? ? ? 91 A R C2 1 85
+ATOM 2544 N N3 . A B 2 85 ? 7.157 -8.319 50.516 1.00 36.05 ? ? ? ? ? ? 91 A R N3 1 85
+ATOM 2545 C C4 . A B 2 85 ? 6.109 -9.101 50.181 1.00 37.46 ? ? ? ? ? ? 91 A R C4 1 85
+ATOM 2546 P P . C B 2 86 ? 6.789 -13.028 54.847 1.00 48.12 ? ? ? ? ? ? 92 C R P 1 86
+ATOM 2547 O OP1 . C B 2 86 ? 6.771 -14.310 55.590 1.00 48.81 ? ? ? ? ? ? 92 C R OP1 1 86
+ATOM 2548 O OP2 . C B 2 86 ? 5.542 -12.228 54.736 1.00 44.57 ? ? ? ? ? ? 92 C R OP2 1 86
+ATOM 2549 O "O5'" . C B 2 86 ? 7.933 -12.066 55.427 1.00 48.26 ? ? ? ? ? ? 92 C R "O5'" 1 86
+ATOM 2550 C "C5'" . C B 2 86 ? 9.231 -12.573 55.725 1.00 49.47 ? ? ? ? ? ? 92 C R "C5'" 1 86
+ATOM 2551 C "C4'" . C B 2 86 ? 10.101 -11.516 56.382 1.00 52.54 ? ? ? ? ? ? 92 C R "C4'" 1 86
+ATOM 2552 O "O4'" . C B 2 86 ? 10.443 -10.494 55.409 1.00 52.45 ? ? ? ? ? ? 92 C R "O4'" 1 86
+ATOM 2553 C "C3'" . C B 2 86 ? 9.467 -10.732 57.525 1.00 54.93 ? ? ? ? ? ? 92 C R "C3'" 1 86
+ATOM 2554 O "O3'" . C B 2 86 ? 9.573 -11.442 58.753 1.00 59.24 ? ? ? ? ? ? 92 C R "O3'" 1 86
+ATOM 2555 C "C2'" . C B 2 86 ? 10.325 -9.471 57.529 1.00 53.80 ? ? ? ? ? ? 92 C R "C2'" 1 86
+ATOM 2556 O "O2'" . C B 2 86 ? 11.572 -9.651 58.178 1.00 56.21 ? ? ? ? ? ? 92 C R "O2'" 1 86
+ATOM 2557 C "C1'" . C B 2 86 ? 10.521 -9.225 56.037 1.00 51.06 ? ? ? ? ? ? 92 C R "C1'" 1 86
+ATOM 2558 N N1 . C B 2 86 ? 9.491 -8.287 55.465 1.00 48.29 ? ? ? ? ? ? 92 C R N1 1 86
+ATOM 2559 C C2 . C B 2 86 ? 9.610 -6.899 55.667 1.00 47.94 ? ? ? ? ? ? 92 C R C2 1 86
+ATOM 2560 O O2 . C B 2 86 ? 10.568 -6.447 56.314 1.00 49.20 ? ? ? ? ? ? 92 C R O2 1 86
+ATOM 2561 N N3 . C B 2 86 ? 8.660 -6.075 55.142 1.00 45.47 ? ? ? ? ? ? 92 C R N3 1 86
+ATOM 2562 C C4 . C B 2 86 ? 7.636 -6.584 54.448 1.00 45.47 ? ? ? ? ? ? 92 C R C4 1 86
+ATOM 2563 N N4 . C B 2 86 ? 6.725 -5.741 53.948 1.00 46.21 ? ? ? ? ? ? 92 C R N4 1 86
+ATOM 2564 C C5 . C B 2 86 ? 7.497 -7.987 54.232 1.00 45.83 ? ? ? ? ? ? 92 C R C5 1 86
+ATOM 2565 C C6 . C B 2 86 ? 8.434 -8.787 54.751 1.00 47.06 ? ? ? ? ? ? 92 C R C6 1 86
+ATOM 2566 P P . C B 2 87 ? 8.530 -11.192 59.941 1.00 62.53 ? ? ? ? ? ? 93 C R P 1 87
+ATOM 2567 O OP1 . C B 2 87 ? 8.886 -12.134 61.027 1.00 61.81 ? ? ? ? ? ? 93 C R OP1 1 87
+ATOM 2568 O OP2 . C B 2 87 ? 7.161 -11.180 59.374 1.00 62.77 ? ? ? ? ? ? 93 C R OP2 1 87
+ATOM 2569 O "O5'" . C B 2 87 ? 8.842 -9.697 60.413 1.00 62.73 ? ? ? ? ? ? 93 C R "O5'" 1 87
+ATOM 2570 C "C5'" . C B 2 87 ? 10.038 -9.370 61.116 1.00 63.71 ? ? ? ? ? ? 93 C R "C5'" 1 87
+ATOM 2571 C "C4'" . C B 2 87 ? 10.062 -7.877 61.377 1.00 64.24 ? ? ? ? ? ? 93 C R "C4'" 1 87
+ATOM 2572 O "O4'" . C B 2 87 ? 9.922 -7.159 60.127 1.00 62.97 ? ? ? ? ? ? 93 C R "O4'" 1 87
+ATOM 2573 C "C3'" . C B 2 87 ? 8.895 -7.386 62.212 1.00 65.58 ? ? ? ? ? ? 93 C R "C3'" 1 87
+ATOM 2574 O "O3'" . C B 2 87 ? 9.208 -7.548 63.587 1.00 69.98 ? ? ? ? ? ? 93 C R "O3'" 1 87
+ATOM 2575 C "C2'" . C B 2 87 ? 8.757 -5.924 61.792 1.00 63.66 ? ? ? ? ? ? 93 C R "C2'" 1 87
+ATOM 2576 O "O2'" . C B 2 87 ? 9.588 -5.036 62.514 1.00 65.57 ? ? ? ? ? ? 93 C R "O2'" 1 87
+ATOM 2577 C "C1'" . C B 2 87 ? 9.186 -5.964 60.329 1.00 60.61 ? ? ? ? ? ? 93 C R "C1'" 1 87
+ATOM 2578 N N1 . C B 2 87 ? 8.031 -5.894 59.374 1.00 57.06 ? ? ? ? ? ? 93 C R N1 1 87
+ATOM 2579 C C2 . C B 2 87 ? 7.417 -4.656 59.104 1.00 57.01 ? ? ? ? ? ? 93 C R C2 1 87
+ATOM 2580 O O2 . C B 2 87 ? 7.826 -3.622 59.652 1.00 58.45 ? ? ? ? ? ? 93 C R O2 1 87
+ATOM 2581 N N3 . C B 2 87 ? 6.374 -4.615 58.237 1.00 54.97 ? ? ? ? ? ? 93 C R N3 1 87
+ATOM 2582 C C4 . C B 2 87 ? 5.945 -5.733 57.653 1.00 53.89 ? ? ? ? ? ? 93 C R C4 1 87
+ATOM 2583 N N4 . C B 2 87 ? 4.919 -5.630 56.806 1.00 53.67 ? ? ? ? ? ? 93 C R N4 1 87
+ATOM 2584 C C5 . C B 2 87 ? 6.548 -7.001 57.910 1.00 54.10 ? ? ? ? ? ? 93 C R C5 1 87
+ATOM 2585 C C6 . C B 2 87 ? 7.576 -7.033 58.767 1.00 55.05 ? ? ? ? ? ? 93 C R C6 1 87
+ATOM 2586 P P . G B 2 88 ? 8.200 -8.323 64.560 1.00 72.12 ? ? ? ? ? ? 94 G R P 1 88
+ATOM 2587 O OP1 . G B 2 88 ? 8.924 -8.527 65.835 1.00 72.35 ? ? ? ? ? ? 94 G R OP1 1 88
+ATOM 2588 O OP2 . G B 2 88 ? 7.638 -9.492 63.844 1.00 71.76 ? ? ? ? ? ? 94 G R OP2 1 88
+ATOM 2589 O "O5'" . G B 2 88 ? 7.017 -7.265 64.766 1.00 72.76 ? ? ? ? ? ? 94 G R "O5'" 1 88
+ATOM 2590 C "C5'" . G B 2 88 ? 7.316 -5.954 65.232 1.00 75.85 ? ? ? ? ? ? 94 G R "C5'" 1 88
+ATOM 2591 C "C4'" . G B 2 88 ? 6.274 -4.962 64.751 1.00 78.99 ? ? ? ? ? ? 94 G R "C4'" 1 88
+ATOM 2592 O "O4'" . G B 2 88 ? 6.011 -5.149 63.333 1.00 78.53 ? ? ? ? ? ? 94 G R "O4'" 1 88
+ATOM 2593 C "C3'" . G B 2 88 ? 4.927 -5.073 65.462 1.00 81.20 ? ? ? ? ? ? 94 G R "C3'" 1 88
+ATOM 2594 O "O3'" . G B 2 88 ? 4.539 -3.799 65.972 1.00 87.68 ? ? ? ? ? ? 94 G R "O3'" 1 88
+ATOM 2595 C "C2'" . G B 2 88 ? 3.990 -5.521 64.346 1.00 79.31 ? ? ? ? ? ? 94 G R "C2'" 1 88
+ATOM 2596 O "O2'" . G B 2 88 ? 2.671 -5.047 64.513 1.00 79.21 ? ? ? ? ? ? 94 G R "O2'" 1 88
+ATOM 2597 C "C1'" . G B 2 88 ? 4.645 -4.868 63.134 1.00 77.81 ? ? ? ? ? ? 94 G R "C1'" 1 88
+ATOM 2598 N N9 . G B 2 88 ? 4.148 -5.408 61.869 1.00 75.37 ? ? ? ? ? ? 94 G R N9 1 88
+ATOM 2599 C C8 . G B 2 88 ? 4.129 -6.733 61.501 1.00 74.93 ? ? ? ? ? ? 94 G R C8 1 88
+ATOM 2600 N N7 . G B 2 88 ? 3.609 -6.945 60.327 1.00 73.75 ? ? ? ? ? ? 94 G R N7 1 88
+ATOM 2601 C C5 . G B 2 88 ? 3.254 -5.680 59.882 1.00 72.45 ? ? ? ? ? ? 94 G R C5 1 88
+ATOM 2602 C C6 . G B 2 88 ? 2.640 -5.288 58.666 1.00 70.81 ? ? ? ? ? ? 94 G R C6 1 88
+ATOM 2603 O O6 . G B 2 88 ? 2.292 -6.010 57.724 1.00 69.88 ? ? ? ? ? ? 94 G R O6 1 88
+ATOM 2604 N N1 . G B 2 88 ? 2.446 -3.911 58.586 1.00 70.40 ? ? ? ? ? ? 94 G R N1 1 88
+ATOM 2605 C C2 . G B 2 88 ? 2.800 -3.019 59.572 1.00 71.08 ? ? ? ? ? ? 94 G R C2 1 88
+ATOM 2606 N N2 . G B 2 88 ? 2.528 -1.731 59.314 1.00 68.72 ? ? ? ? ? ? 94 G R N2 1 88
+ATOM 2607 N N3 . G B 2 88 ? 3.374 -3.374 60.725 1.00 72.04 ? ? ? ? ? ? 94 G R N3 1 88
+ATOM 2608 C C4 . G B 2 88 ? 3.574 -4.718 60.818 1.00 73.22 ? ? ? ? ? ? 94 G R C4 1 88
+ATOM 2609 P P . A B 2 89 ? 4.584 -3.446 67.537 1.00 92.04 ? ? ? ? ? ? 95 A R P 1 89
+ATOM 2610 O OP1 . A B 2 89 ? 5.975 -3.080 67.889 1.00 91.19 ? ? ? ? ? ? 95 A R OP1 1 89
+ATOM 2611 O OP2 . A B 2 89 ? 3.890 -4.527 68.276 1.00 92.46 ? ? ? ? ? ? 95 A R OP2 1 89
+ATOM 2612 O "O5'" . A B 2 89 ? 3.680 -2.127 67.620 1.00 93.23 ? ? ? ? ? ? 95 A R "O5'" 1 89
+ATOM 2613 C "C5'" . A B 2 89 ? 3.859 -1.104 66.652 1.00 97.33 ? ? ? ? ? ? 95 A R "C5'" 1 89
+ATOM 2614 C "C4'" . A B 2 89 ? 4.415 0.161 67.278 1.00 100.21 ? ? ? ? ? ? 95 A R "C4'" 1 89
+ATOM 2615 O "O4'" . A B 2 89 ? 5.166 0.911 66.286 1.00 101.29 ? ? ? ? ? ? 95 A R "O4'" 1 89
+ATOM 2616 C "C3'" . A B 2 89 ? 3.365 1.124 67.816 1.00 102.08 ? ? ? ? ? ? 95 A R "C3'" 1 89
+ATOM 2617 O "O3'" . A B 2 89 ? 3.881 1.747 68.988 1.00 105.23 ? ? ? ? ? ? 95 A R "O3'" 1 89
+ATOM 2618 C "C2'" . A B 2 89 ? 3.173 2.098 66.652 1.00 102.18 ? ? ? ? ? ? 95 A R "C2'" 1 89
+ATOM 2619 O "O2'" . A B 2 89 ? 2.683 3.363 67.050 1.00 101.40 ? ? ? ? ? ? 95 A R "O2'" 1 89
+ATOM 2620 C "C1'" . A B 2 89 ? 4.599 2.198 66.117 1.00 102.63 ? ? ? ? ? ? 95 A R "C1'" 1 89
+ATOM 2621 N N9 . A B 2 89 ? 4.703 2.597 64.710 1.00 103.68 ? ? ? ? ? ? 95 A R N9 1 89
+ATOM 2622 C C8 . A B 2 89 ? 5.176 3.793 64.247 1.00 104.22 ? ? ? ? ? ? 95 A R C8 1 89
+ATOM 2623 N N7 . A B 2 89 ? 5.169 3.904 62.940 1.00 104.41 ? ? ? ? ? ? 95 A R N7 1 89
+ATOM 2624 C C5 . A B 2 89 ? 4.651 2.697 62.509 1.00 104.59 ? ? ? ? ? ? 95 A R C5 1 89
+ATOM 2625 C C6 . A B 2 89 ? 4.384 2.185 61.220 1.00 104.89 ? ? ? ? ? ? 95 A R C6 1 89
+ATOM 2626 N N6 . A B 2 89 ? 4.622 2.867 60.095 1.00 105.17 ? ? ? ? ? ? 95 A R N6 1 89
+ATOM 2627 N N1 . A B 2 89 ? 3.870 0.938 61.130 1.00 105.05 ? ? ? ? ? ? 95 A R N1 1 89
+ATOM 2628 C C2 . A B 2 89 ? 3.635 0.253 62.259 1.00 104.88 ? ? ? ? ? ? 95 A R C2 1 89
+ATOM 2629 N N3 . A B 2 89 ? 3.844 0.631 63.523 1.00 104.66 ? ? ? ? ? ? 95 A R N3 1 89
+ATOM 2630 C C4 . A B 2 89 ? 4.359 1.874 63.585 1.00 104.33 ? ? ? ? ? ? 95 A R C4 1 89
+ATOM 2631 P P . U B 2 90 ? 3.059 1.780 70.362 1.00 107.65 ? ? ? ? ? ? 96 U R P 1 90
+ATOM 2632 O OP1 . U B 2 90 ? 2.059 2.865 70.231 1.00 107.76 ? ? ? ? ? ? 96 U R OP1 1 90
+ATOM 2633 O OP2 . U B 2 90 ? 4.049 1.829 71.465 1.00 107.27 ? ? ? ? ? ? 96 U R OP2 1 90
+ATOM 2634 O "O5'" . U B 2 90 ? 2.286 0.372 70.414 1.00 108.85 ? ? ? ? ? ? 96 U R "O5'" 1 90
+ATOM 2635 C "C5'" . U B 2 90 ? 2.763 -0.727 71.197 1.00 110.91 ? ? ? ? ? ? 96 U R "C5'" 1 90
+ATOM 2636 C "C4'" . U B 2 90 ? 1.848 -1.029 72.374 1.00 112.56 ? ? ? ? ? ? 96 U R "C4'" 1 90
+ATOM 2637 O "O4'" . U B 2 90 ? 1.519 0.189 73.104 1.00 114.42 ? ? ? ? ? ? 96 U R "O4'" 1 90
+ATOM 2638 C "C3'" . U B 2 90 ? 0.461 -1.556 72.036 1.00 112.56 ? ? ? ? ? ? 96 U R "C3'" 1 90
+ATOM 2639 O "O3'" . U B 2 90 ? 0.450 -2.900 71.570 1.00 110.11 ? ? ? ? ? ? 96 U R "O3'" 1 90
+ATOM 2640 C "C2'" . U B 2 90 ? -0.227 -1.363 73.386 1.00 114.12 ? ? ? ? ? ? 96 U R "C2'" 1 90
+ATOM 2641 O "O2'" . U B 2 90 ? 0.231 -2.231 74.407 1.00 114.58 ? ? ? ? ? ? 96 U R "O2'" 1 90
+ATOM 2642 C "C1'" . U B 2 90 ? 0.209 0.076 73.652 1.00 115.24 ? ? ? ? ? ? 96 U R "C1'" 1 90
+ATOM 2643 N N1 . U B 2 90 ? -0.758 1.066 73.034 1.00 117.03 ? ? ? ? ? ? 96 U R N1 1 90
+ATOM 2644 C C2 . U B 2 90 ? -1.907 1.419 73.730 1.00 117.89 ? ? ? ? ? ? 96 U R C2 1 90
+ATOM 2645 O O2 . U B 2 90 ? -2.191 0.994 74.839 1.00 117.99 ? ? ? ? ? ? 96 U R O2 1 90
+ATOM 2646 N N3 . U B 2 90 ? -2.726 2.313 73.074 1.00 118.50 ? ? ? ? ? ? 96 U R N3 1 90
+ATOM 2647 C C4 . U B 2 90 ? -2.529 2.874 71.821 1.00 118.71 ? ? ? ? ? ? 96 U R C4 1 90
+ATOM 2648 O O4 . U B 2 90 ? -3.353 3.660 71.365 1.00 119.12 ? ? ? ? ? ? 96 U R O4 1 90
+ATOM 2649 C C5 . U B 2 90 ? -1.321 2.459 71.153 1.00 118.47 ? ? ? ? ? ? 96 U R C5 1 90
+ATOM 2650 C C6 . U B 2 90 ? -0.509 1.591 71.771 1.00 117.95 ? ? ? ? ? ? 96 U R C6 1 90
+ATOM 2651 P P . G B 2 91 ? -0.719 -3.356 70.570 1.00 108.46 ? ? ? ? ? ? 97 G R P 1 91
+ATOM 2652 O OP1 . G B 2 91 ? -1.958 -3.506 71.369 1.00 108.16 ? ? ? ? ? ? 97 G R OP1 1 91
+ATOM 2653 O OP2 . G B 2 91 ? -0.210 -4.515 69.800 1.00 108.55 ? ? ? ? ? ? 97 G R OP2 1 91
+ATOM 2654 O "O5'" . G B 2 91 ? -0.898 -2.100 69.579 1.00 105.18 ? ? ? ? ? ? 97 G R "O5'" 1 91
+ATOM 2655 C "C5'" . G B 2 91 ? -0.395 -2.109 68.239 1.00 99.41 ? ? ? ? ? ? 97 G R "C5'" 1 91
+ATOM 2656 C "C4'" . G B 2 91 ? -0.451 -0.724 67.616 1.00 95.40 ? ? ? ? ? ? 97 G R "C4'" 1 91
+ATOM 2657 O "O4'" . G B 2 91 ? 0.728 -0.514 66.795 1.00 94.32 ? ? ? ? ? ? 97 G R "O4'" 1 91
+ATOM 2658 C "C3'" . G B 2 91 ? -1.604 -0.489 66.649 1.00 93.30 ? ? ? ? ? ? 97 G R "C3'" 1 91
+ATOM 2659 O "O3'" . G B 2 91 ? -2.770 -0.024 67.304 1.00 90.11 ? ? ? ? ? ? 97 G R "O3'" 1 91
+ATOM 2660 C "C2'" . G B 2 91 ? -1.025 0.546 65.690 1.00 93.38 ? ? ? ? ? ? 97 G R "C2'" 1 91
+ATOM 2661 O "O2'" . G B 2 91 ? -0.936 1.847 66.240 1.00 93.04 ? ? ? ? ? ? 97 G R "O2'" 1 91
+ATOM 2662 C "C1'" . G B 2 91 ? 0.361 -0.058 65.500 1.00 93.71 ? ? ? ? ? ? 97 G R "C1'" 1 91
+ATOM 2663 N N9 . G B 2 91 ? 0.412 -1.178 64.544 1.00 93.22 ? ? ? ? ? ? 97 G R N9 1 91
+ATOM 2664 C C8 . G B 2 91 ? 0.908 -2.437 64.796 1.00 93.14 ? ? ? ? ? ? 97 G R C8 1 91
+ATOM 2665 N N7 . G B 2 91 ? 0.835 -3.251 63.781 1.00 92.68 ? ? ? ? ? ? 97 G R N7 1 91
+ATOM 2666 C C5 . G B 2 91 ? 0.253 -2.491 62.777 1.00 92.07 ? ? ? ? ? ? 97 G R C5 1 91
+ATOM 2667 C C6 . G B 2 91 ? -0.075 -2.847 61.442 1.00 91.04 ? ? ? ? ? ? 97 G R C6 1 91
+ATOM 2668 O O6 . G B 2 91 ? 0.092 -3.936 60.879 1.00 90.22 ? ? ? ? ? ? 97 G R O6 1 91
+ATOM 2669 N N1 . G B 2 91 ? -0.654 -1.789 60.741 1.00 90.64 ? ? ? ? ? ? 97 G R N1 1 91
+ATOM 2670 C C2 . G B 2 91 ? -0.886 -0.539 61.268 1.00 91.15 ? ? ? ? ? ? 97 G R C2 1 91
+ATOM 2671 N N2 . G B 2 91 ? -1.455 0.354 60.444 1.00 91.28 ? ? ? ? ? ? 97 G R N2 1 91
+ATOM 2672 N N3 . G B 2 91 ? -0.583 -0.193 62.518 1.00 91.92 ? ? ? ? ? ? 97 G R N3 1 91
+ATOM 2673 C C4 . G B 2 91 ? -0.016 -1.211 63.224 1.00 92.35 ? ? ? ? ? ? 97 G R C4 1 91
+ATOM 2674 P P . G B 2 92 ? -4.177 -0.680 66.913 1.00 88.15 ? ? ? ? ? ? 98 G R P 1 92
+ATOM 2675 O OP1 . G B 2 92 ? -5.196 -0.117 67.829 1.00 89.11 ? ? ? ? ? ? 98 G R OP1 1 92
+ATOM 2676 O OP2 . G B 2 92 ? -3.996 -2.152 66.851 1.00 86.93 ? ? ? ? ? ? 98 G R OP2 1 92
+ATOM 2677 O "O5'" . G B 2 92 ? -4.441 -0.139 65.423 1.00 85.99 ? ? ? ? ? ? 98 G R "O5'" 1 92
+ATOM 2678 C "C5'" . G B 2 92 ? -4.702 1.244 65.157 1.00 81.47 ? ? ? ? ? ? 98 G R "C5'" 1 92
+ATOM 2679 C "C4'" . G B 2 92 ? -5.089 1.476 63.702 1.00 78.96 ? ? ? ? ? ? 98 G R "C4'" 1 92
+ATOM 2680 O "O4'" . G B 2 92 ? -4.249 0.680 62.827 1.00 77.34 ? ? ? ? ? ? 98 G R "O4'" 1 92
+ATOM 2681 C "C3'" . G B 2 92 ? -6.541 1.153 63.356 1.00 77.72 ? ? ? ? ? ? 98 G R "C3'" 1 92
+ATOM 2682 O "O3'" . G B 2 92 ? -7.170 2.313 62.821 1.00 77.97 ? ? ? ? ? ? 98 G R "O3'" 1 92
+ATOM 2683 C "C2'" . G B 2 92 ? -6.489 0.018 62.330 1.00 76.50 ? ? ? ? ? ? 98 G R "C2'" 1 92
+ATOM 2684 O "O2'" . G B 2 92 ? -7.292 0.281 61.193 1.00 75.80 ? ? ? ? ? ? 98 G R "O2'" 1 92
+ATOM 2685 C "C1'" . G B 2 92 ? -5.022 -0.068 61.904 1.00 75.46 ? ? ? ? ? ? 98 G R "C1'" 1 92
+ATOM 2686 N N9 . G B 2 92 ? -4.487 -1.439 61.826 1.00 72.64 ? ? ? ? ? ? 98 G R N9 1 92
+ATOM 2687 C C8 . G B 2 92 ? -3.547 -2.008 62.659 1.00 70.33 ? ? ? ? ? ? 98 G R C8 1 92
+ATOM 2688 N N7 . G B 2 92 ? -3.247 -3.242 62.364 1.00 68.22 ? ? ? ? ? ? 98 G R N7 1 92
+ATOM 2689 C C5 . G B 2 92 ? -4.037 -3.523 61.258 1.00 68.81 ? ? ? ? ? ? 98 G R C5 1 92
+ATOM 2690 C C6 . G B 2 92 ? -4.141 -4.716 60.497 1.00 68.33 ? ? ? ? ? ? 98 G R C6 1 92
+ATOM 2691 O O6 . G B 2 92 ? -3.532 -5.783 60.665 1.00 67.91 ? ? ? ? ? ? 98 G R O6 1 92
+ATOM 2692 N N1 . G B 2 92 ? -5.060 -4.595 59.450 1.00 68.01 ? ? ? ? ? ? 98 G R N1 1 92
+ATOM 2693 C C2 . G B 2 92 ? -5.792 -3.458 59.179 1.00 68.56 ? ? ? ? ? ? 98 G R C2 1 92
+ATOM 2694 N N2 . G B 2 92 ? -6.626 -3.531 58.132 1.00 68.46 ? ? ? ? ? ? 98 G R N2 1 92
+ATOM 2695 N N3 . G B 2 92 ? -5.704 -2.330 59.884 1.00 69.01 ? ? ? ? ? ? 98 G R N3 1 92
+ATOM 2696 C C4 . G B 2 92 ? -4.809 -2.427 60.910 1.00 70.46 ? ? ? ? ? ? 98 G R C4 1 92
+ATOM 2697 O OP3 . G C 3 1 ? 16.680 4.894 56.478 1.00 67.77 ? ? ? ? ? ? 1 G A OP3 1 1
+ATOM 2698 P P . G C 3 1 ? 16.591 4.857 55.001 1.00 67.32 ? ? ? ? ? ? 1 G A P 1 1
+ATOM 2699 O OP1 . G C 3 1 ? 17.559 5.658 54.215 1.00 66.30 ? ? ? ? ? ? 1 G A OP1 1 1
+ATOM 2700 O OP2 . G C 3 1 ? 16.756 3.435 54.599 1.00 65.81 ? ? ? ? ? ? 1 G A OP2 1 1
+ATOM 2701 O "O5'" . G C 3 1 ? 15.116 5.343 54.600 1.00 62.36 ? ? ? ? ? ? 1 G A "O5'" 1 1
+ATOM 2702 C "C5'" . G C 3 1 ? 14.036 4.409 54.495 1.00 57.38 ? ? ? ? ? ? 1 G A "C5'" 1 1
+ATOM 2703 C "C4'" . G C 3 1 ? 13.513 4.307 53.072 1.00 53.29 ? ? ? ? ? ? 1 G A "C4'" 1 1
+ATOM 2704 O "O4'" . G C 3 1 ? 14.344 3.389 52.324 1.00 49.91 ? ? ? ? ? ? 1 G A "O4'" 1 1
+ATOM 2705 C "C3'" . G C 3 1 ? 12.097 3.762 52.926 1.00 51.90 ? ? ? ? ? ? 1 G A "C3'" 1 1
+ATOM 2706 O "O3'" . G C 3 1 ? 11.148 4.823 53.089 1.00 53.15 ? ? ? ? ? ? 1 G A "O3'" 1 1
+ATOM 2707 C "C2'" . G C 3 1 ? 12.128 3.210 51.500 1.00 50.86 ? ? ? ? ? ? 1 G A "C2'" 1 1
+ATOM 2708 O "O2'" . G C 3 1 ? 11.883 4.186 50.503 1.00 48.54 ? ? ? ? ? ? 1 G A "O2'" 1 1
+ATOM 2709 C "C1'" . G C 3 1 ? 13.561 2.695 51.372 1.00 49.44 ? ? ? ? ? ? 1 G A "C1'" 1 1
+ATOM 2710 N N9 . G C 3 1 ? 13.715 1.254 51.582 1.00 47.96 ? ? ? ? ? ? 1 G A N9 1 1
+ATOM 2711 C C8 . G C 3 1 ? 14.475 0.634 52.548 1.00 47.85 ? ? ? ? ? ? 1 G A C8 1 1
+ATOM 2712 N N7 . G C 3 1 ? 14.436 -0.669 52.503 1.00 46.32 ? ? ? ? ? ? 1 G A N7 1 1
+ATOM 2713 C C5 . G C 3 1 ? 13.596 -0.940 51.434 1.00 47.44 ? ? ? ? ? ? 1 G A C5 1 1
+ATOM 2714 C C6 . G C 3 1 ? 13.172 -2.184 50.900 1.00 47.47 ? ? ? ? ? ? 1 G A C6 1 1
+ATOM 2715 O O6 . G C 3 1 ? 13.471 -3.324 51.289 1.00 47.88 ? ? ? ? ? ? 1 G A O6 1 1
+ATOM 2716 N N1 . G C 3 1 ? 12.316 -2.023 49.807 1.00 46.02 ? ? ? ? ? ? 1 G A N1 1 1
+ATOM 2717 C C2 . G C 3 1 ? 11.924 -0.805 49.299 1.00 46.75 ? ? ? ? ? ? 1 G A C2 1 1
+ATOM 2718 N N2 . G C 3 1 ? 11.095 -0.837 48.246 1.00 48.57 ? ? ? ? ? ? 1 G A N2 1 1
+ATOM 2719 N N3 . G C 3 1 ? 12.313 0.367 49.789 1.00 46.88 ? ? ? ? ? ? 1 G A N3 1 1
+ATOM 2720 C C4 . G C 3 1 ? 13.145 0.231 50.853 1.00 47.68 ? ? ? ? ? ? 1 G A C4 1 1
+ATOM 2721 P P . G C 3 2 ? 9.589 4.583 53.396 1.00 55.92 ? ? ? ? ? ? 2 G A P 1 2
+ATOM 2722 O OP1 . G C 3 2 ? 9.032 3.714 52.336 1.00 54.98 ? ? ? ? ? ? 2 G A OP1 1 2
+ATOM 2723 O OP2 . G C 3 2 ? 8.950 5.903 53.629 1.00 54.37 ? ? ? ? ? ? 2 G A OP2 1 2
+ATOM 2724 O "O5'" . G C 3 2 ? 9.627 3.783 54.787 1.00 56.00 ? ? ? ? ? ? 2 G A "O5'" 1 2
+ATOM 2725 C "C5'" . G C 3 2 ? 9.986 4.464 55.993 1.00 54.43 ? ? ? ? ? ? 2 G A "C5'" 1 2
+ATOM 2726 C "C4'" . G C 3 2 ? 10.428 3.527 57.108 1.00 53.48 ? ? ? ? ? ? 2 G A "C4'" 1 2
+ATOM 2727 O "O4'" . G C 3 2 ? 9.273 2.816 57.623 1.00 52.76 ? ? ? ? ? ? 2 G A "O4'" 1 2
+ATOM 2728 C "C3'" . G C 3 2 ? 11.449 2.454 56.739 1.00 53.00 ? ? ? ? ? ? 2 G A "C3'" 1 2
+ATOM 2729 O "O3'" . G C 3 2 ? 12.776 2.918 56.975 1.00 51.51 ? ? ? ? ? ? 2 G A "O3'" 1 2
+ATOM 2730 C "C2'" . G C 3 2 ? 11.077 1.300 57.671 1.00 52.24 ? ? ? ? ? ? 2 G A "C2'" 1 2
+ATOM 2731 O "O2'" . G C 3 2 ? 11.644 1.426 58.960 1.00 51.75 ? ? ? ? ? ? 2 G A "O2'" 1 2
+ATOM 2732 C "C1'" . G C 3 2 ? 9.562 1.439 57.773 1.00 51.55 ? ? ? ? ? ? 2 G A "C1'" 1 2
+ATOM 2733 N N9 . G C 3 2 ? 8.790 0.705 56.769 1.00 51.63 ? ? ? ? ? ? 2 G A N9 1 2
+ATOM 2734 C C8 . G C 3 2 ? 7.883 1.261 55.897 1.00 52.21 ? ? ? ? ? ? 2 G A C8 1 2
+ATOM 2735 N N7 . G C 3 2 ? 7.318 0.397 55.104 1.00 52.19 ? ? ? ? ? ? 2 G A N7 1 2
+ATOM 2736 C C5 . G C 3 2 ? 7.884 -0.817 55.466 1.00 51.22 ? ? ? ? ? ? 2 G A C5 1 2
+ATOM 2737 C C6 . G C 3 2 ? 7.647 -2.110 54.945 1.00 50.57 ? ? ? ? ? ? 2 G A C6 1 2
+ATOM 2738 O O6 . G C 3 2 ? 6.872 -2.425 54.031 1.00 51.81 ? ? ? ? ? ? 2 G A O6 1 2
+ATOM 2739 N N1 . G C 3 2 ? 8.417 -3.084 55.582 1.00 48.53 ? ? ? ? ? ? 2 G A N1 1 2
+ATOM 2740 C C2 . G C 3 2 ? 9.303 -2.830 56.603 1.00 48.48 ? ? ? ? ? ? 2 G A C2 1 2
+ATOM 2741 N N2 . G C 3 2 ? 9.957 -3.891 57.096 1.00 46.83 ? ? ? ? ? ? 2 G A N2 1 2
+ATOM 2742 N N3 . G C 3 2 ? 9.531 -1.617 57.104 1.00 49.72 ? ? ? ? ? ? 2 G A N3 1 2
+ATOM 2743 C C4 . G C 3 2 ? 8.791 -0.653 56.494 1.00 51.27 ? ? ? ? ? ? 2 G A C4 1 2
+HETATM 2744 MG MG . MG D 4 . ? 4.000 -2.776 51.209 1.00 66.65 ? ? ? ? ? ? 1 MG R MG 1 1
+HETATM 2745 O O . HOH E 5 . ? 4.376 31.687 10.017 1.00 29.48 ? ? ? ? ? ? 99 HOH P O 1 99
+HETATM 2746 O O . HOH E 5 . ? 8.620 24.826 6.657 1.00 42.09 ? ? ? ? ? ? 100 HOH P O 1 100
+HETATM 2747 O O . HOH E 5 . ? 4.700 30.085 8.176 1.00 44.90 ? ? ? ? ? ? 101 HOH P O 1 101
+HETATM 2748 O O . HOH F 5 . ? 3.779 13.244 -1.019 1.00 39.86 ? ? ? ? ? ? 3 HOH R O 1 3
+HETATM 2749 O O . HOH F 5 . ? 26.468 -4.600 41.966 1.00 27.27 ? ? ? ? ? ? 4 HOH R O 1 4
+HETATM 2750 O O . HOH F 5 . ? 12.478 -8.451 31.611 1.00 33.82 ? ? ? ? ? ? 5 HOH R O 1 5
+HETATM 2751 O O . HOH F 5 . ? 29.314 -2.272 18.976 1.00 48.37 ? ? ? ? ? ? 670 HOH R O 1 670
+HETATM 2752 O O . HOH F 5 . ? 9.514 -9.005 51.220 1.00 55.48 ? ? ? ? ? ? 671 HOH R O 1 671
+HETATM 2753 O O . HOH F 5 . ? 11.169 6.329 -1.078 1.00 59.28 ? ? ? ? ? ? 672 HOH R O 1 672
+HETATM 2754 O O . HOH F 5 . ? 2.744 -4.232 50.183 1.00 67.60 ? ? ? ? ? ? 673 HOH R O 1 673
+HETATM 2755 O O . HOH F 5 . ? 5.774 -3.685 50.326 1.00 67.45 ? ? ? ? ? ? 674 HOH R O 1 674
+HETATM 2756 O O . HOH F 5 . ? 2.234 -1.949 52.189 1.00 67.27 ? ? ? ? ? ? 675 HOH R O 1 675
+HETATM 2757 O O . HOH F 5 . ? 4.177 -4.197 52.851 1.00 67.86 ? ? ? ? ? ? 676 HOH R O 1 676
+HETATM 2758 O O . HOH G 5 . ? 5.266 -1.415 52.341 1.00 67.29 ? ? ? ? ? ? 3 HOH A O 1 3
+#
+loop_
+_pdbx_poly_seq_scheme.asym_id             
+_pdbx_poly_seq_scheme.entity_id           
+_pdbx_poly_seq_scheme.seq_id              
+_pdbx_poly_seq_scheme.mon_id              
+_pdbx_poly_seq_scheme.ndb_seq_num         
+_pdbx_poly_seq_scheme.pdb_seq_num         
+_pdbx_poly_seq_scheme.auth_seq_num        
+_pdbx_poly_seq_scheme.pdb_mon_id          
+_pdbx_poly_seq_scheme.auth_mon_id         
+_pdbx_poly_seq_scheme.pdb_strand_id       
+_pdbx_poly_seq_scheme.pdb_ins_code        
+_pdbx_poly_seq_scheme.hetero              
+A 1 1 MET 1 1 ? ? ? P . n
+A 1 2 ALA 2 2 ? ? ? P . n
+A 1 3 VAL 3 3 ? ? ? P . n
+A 1 4 PRO 4 4 ? ? ? P . n
+A 1 5 GLU 5 5 ? ? ? P . n
+A 1 6 THR 6 6 ? ? ? P . n
+A 1 7 ARG 7 7 7 ARG ARG P . n
+A 1 8 PRO 8 8 8 PRO PRO P . n
+A 1 9 ASN 9 9 9 ASN ASN P . n
+A 1 10 HIS 10 10 10 HIS HIS P . n
+A 1 11 THR 11 11 11 THR THR P . n
+A 1 12 ILE 12 12 12 ILE ILE P . n
+A 1 13 TYR 13 13 13 TYR TYR P . n
+A 1 14 ILE 14 14 14 ILE ILE P . n
+A 1 15 ASN 15 15 15 ASN ASN P . n
+A 1 16 ASN 16 16 16 ASN ASN P . n
+A 1 17 LEU 17 17 17 LEU LEU P . n
+A 1 18 ASN 18 18 18 ASN ASN P . n
+A 1 19 GLU 19 19 19 GLU GLU P . n
+A 1 20 LYS 20 20 20 LYS LYS P . n
+A 1 21 ILE 21 21 21 ILE ILE P . n
+A 1 22 LYS 22 22 22 LYS LYS P . n
+A 1 23 LYS 23 23 23 LYS LYS P . n
+A 1 24 ASP 24 24 24 ASP ASP P . n
+A 1 25 GLU 25 25 25 GLU GLU P . n
+A 1 26 LEU 26 26 26 LEU LEU P . n
+A 1 27 LYS 27 27 27 LYS LYS P . n
+A 1 28 LYS 28 28 28 LYS LYS P . n
+A 1 29 SER 29 29 29 SER SER P . n
+A 1 30 LEU 30 30 30 LEU LEU P . n
+A 1 31 HIS 31 31 31 HIS HIS P . n
+A 1 32 ALA 32 32 32 ALA ALA P . n
+A 1 33 ILE 33 33 33 ILE ILE P . n
+A 1 34 PHE 34 34 34 PHE PHE P . n
+A 1 35 SER 35 35 35 SER SER P . n
+A 1 36 ARG 36 36 36 ARG ARG P . n
+A 1 37 PHE 37 37 37 PHE PHE P . n
+A 1 38 GLY 38 38 38 GLY GLY P . n
+A 1 39 GLN 39 39 39 GLN GLN P . n
+A 1 40 ILE 40 40 40 ILE ILE P . n
+A 1 41 LEU 41 41 41 LEU LEU P . n
+A 1 42 ASP 42 42 42 ASP ASP P . n
+A 1 43 ILE 43 43 43 ILE ILE P . n
+A 1 44 LEU 44 44 44 LEU LEU P . n
+A 1 45 VAL 45 45 45 VAL VAL P . n
+A 1 46 SER 46 46 46 SER SER P . n
+A 1 47 ARG 47 47 47 ARG ARG P . n
+A 1 48 SER 48 48 48 SER SER P . n
+A 1 49 LEU 49 49 49 LEU LEU P . n
+A 1 50 LYS 50 50 50 LYS LYS P . n
+A 1 51 MET 51 51 51 MET MET P . n
+A 1 52 ARG 52 52 52 ARG ARG P . n
+A 1 53 GLY 53 53 53 GLY GLY P . n
+A 1 54 GLN 54 54 54 GLN GLN P . n
+A 1 55 ALA 55 55 55 ALA ALA P . n
+A 1 56 PHE 56 56 56 PHE PHE P . n
+A 1 57 VAL 57 57 57 VAL VAL P . n
+A 1 58 ILE 58 58 58 ILE ILE P . n
+A 1 59 PHE 59 59 59 PHE PHE P . n
+A 1 60 LYS 60 60 60 LYS LYS P . n
+A 1 61 GLU 61 61 61 GLU GLU P . n
+A 1 62 VAL 62 62 62 VAL VAL P . n
+A 1 63 SER 63 63 63 SER SER P . n
+A 1 64 SER 64 64 64 SER SER P . n
+A 1 65 ALA 65 65 65 ALA ALA P . n
+A 1 66 THR 66 66 66 THR THR P . n
+A 1 67 ASN 67 67 67 ASN ASN P . n
+A 1 68 ALA 68 68 68 ALA ALA P . n
+A 1 69 LEU 69 69 69 LEU LEU P . n
+A 1 70 ARG 70 70 70 ARG ARG P . n
+A 1 71 SER 71 71 71 SER SER P . n
+A 1 72 MET 72 72 72 MET MET P . n
+A 1 73 GLN 73 73 73 GLN GLN P . n
+A 1 74 GLY 74 74 74 GLY GLY P . n
+A 1 75 PHE 75 75 75 PHE PHE P . n
+A 1 76 PRO 76 76 76 PRO PRO P . n
+A 1 77 PHE 77 77 77 PHE PHE P . n
+A 1 78 TYR 78 78 78 TYR TYR P . n
+A 1 79 ASP 79 79 79 ASP ASP P . n
+A 1 80 LYS 80 80 80 LYS LYS P . n
+A 1 81 PRO 81 81 81 PRO PRO P . n
+A 1 82 MET 82 82 82 MET MET P . n
+A 1 83 ARG 83 83 83 ARG ARG P . n
+A 1 84 ILE 84 84 84 ILE ILE P . n
+A 1 85 GLN 85 85 85 GLN GLN P . n
+A 1 86 TYR 86 86 86 TYR TYR P . n
+A 1 87 ALA 87 87 87 ALA ALA P . n
+A 1 88 LYS 88 88 88 LYS LYS P . n
+A 1 89 THR 89 89 89 THR THR P . n
+A 1 90 ASP 90 90 90 ASP ASP P . n
+A 1 91 SER 91 91 91 SER SER P . n
+A 1 92 ASP 92 92 92 ASP ASP P . n
+A 1 93 ILE 93 93 93 ILE ILE P . n
+A 1 94 ILE 94 94 ? ? ? P . n
+A 1 95 ALA 95 95 ? ? ? P . n
+A 1 96 LYS 96 96 ? ? ? P . n
+A 1 97 MET 97 97 ? ? ? P . n
+A 1 98 LYS 98 98 ? ? ? P . n
+B 2 1 GTP 1 8 8 GTP GTP R . n
+B 2 2 G 2 9 9 G G R . n
+B 2 3 U 3 10 10 U U R . n
+B 2 4 C 4 11 11 C C R . n
+B 2 5 A 5 12 12 A A R . n
+B 2 6 C 6 13 13 C C R . n
+B 2 7 G 7 14 14 G G R . n
+B 2 8 C 8 15 15 C C R . n
+B 2 9 A 9 16 16 A A R . n
+B 2 10 C 10 17 17 C C R . n
+B 2 11 A 11 18 18 A A R . n
+B 2 12 G 12 19 19 G G R . n
+B 2 13 G 13 20 20 G G R . n
+B 2 14 G 14 21 21 G G R . n
+B 2 15 C 15 22 22 C C R . n
+B 2 16 A 16 23 23 A A R . n
+B 2 17 A 17 24 24 A A R . n
+B 2 18 A 18 25 25 A A R . n
+B 2 19 C 19 26 26 C C R . n
+B 2 20 C 20 27 27 C C R . n
+B 2 21 A 21 28 28 A A R . n
+B 2 22 U 22 29 29 U U R . n
+B 2 23 U 23 30 30 U U R . n
+B 2 24 C 24 31 31 C C R . n
+B 2 25 G 25 32 32 G G R . n
+B 2 26 A 26 33 33 A A R . n
+B 2 27 A 27 34 34 A A R . n
+B 2 28 A 28 35 35 A A R . n
+B 2 29 G 29 36 36 G G R . n
+B 2 30 A 30 37 37 A A R . n
+B 2 31 G 31 38 38 G G R . n
+B 2 32 U 32 39 39 U U R . n
+B 2 33 G 33 40 40 G G R . n
+B 2 34 G 34 41 41 G G R . n
+B 2 35 G 35 42 42 G G R . n
+B 2 36 A 36 43 43 A A R . n
+B 2 37 C 37 44 44 C C R . n
+B 2 38 G 38 45 45 G G R . n
+B 2 39 C 39 46 46 C C R . n
+B 2 40 A 40 47 47 A A R . n
+B 2 41 A 41 48 48 A A R . n
+B 2 42 A 42 49 49 A A R . n
+B 2 43 G 43 50 50 G G R . n
+B 2 44 C 44 51 51 C C R . n
+B 2 45 C 45 52 52 C C R . n
+B 2 46 U 46 53 53 U U R . n
+B 2 47 C 47 54 54 C C R . n
+B 2 48 C 48 55 55 C C R . n
+B 2 49 G 49 56 56 G G R . n
+B 2 50 G 50 57 57 G G R . n
+B 2 51 C 51 58 58 C C R . n
+B 2 52 C 52 59 59 C C R . n
+B 2 53 U 53 60 60 U U R . n
+B 2 54 A 54 61 61 A A R . n
+B 2 55 A 55 62 62 A A R . n
+B 2 56 A 56 63 63 A A R . n
+B 2 57 C 57 64 64 C C R . n
+B 2 58 C 58 65 65 C C R . n
+B 2 59 A 59 660 660 A A R . n
+B 2 60 U 60 661 661 U U R . n
+B 2 61 U 61 662 662 U U R . n
+B 2 62 G 62 663 663 G G R . n
+B 2 63 C 63 664 664 C C R . n
+B 2 64 A 64 665 665 A A R . n
+B 2 65 C 65 666 666 C C R . n
+B 2 66 U 66 667 667 U U R . n
+B 2 67 C 67 668 668 C C R . n
+B 2 68 C 68 669 669 C C R . n
+B 2 69 G 69 75 75 G G R . n
+B 2 70 G 70 76 76 G G R . n
+B 2 71 U 71 77 77 U U R . n
+B 2 72 A 72 78 78 A A R . n
+B 2 73 G 73 79 79 G G R . n
+B 2 74 G 74 80 80 G G R . n
+B 2 75 U 75 81 81 U U R . n
+B 2 76 A 76 82 82 A A R . n
+B 2 77 G 77 83 83 G G R . n
+B 2 78 C 78 84 84 C C R . n
+B 2 79 G 79 85 85 G G R . n
+B 2 80 G 80 86 86 G G R . n
+B 2 81 G 81 87 87 G G R . n
+B 2 82 G 82 88 88 G G R . n
+B 2 83 U 83 89 89 U U R . n
+B 2 84 U 84 90 90 U U R . n
+B 2 85 A 85 91 91 A A R . n
+B 2 86 C 86 92 92 C C R . n
+B 2 87 C 87 93 93 C C R . n
+B 2 88 G 88 94 94 G G R . n
+B 2 89 A 89 95 95 A A R . n
+B 2 90 U 90 96 96 U U R . n
+B 2 91 G 91 97 97 G G R . n
+B 2 92 G 92 98 98 G G R . n
+C 3 1 G 1 1 1 G G A . n
+C 3 2 G 2 2 2 G G A . n
+#
+_pdbx_struct_assembly.id                       1
+_pdbx_struct_assembly.details                  author_and_software_defined_assembly
+_pdbx_struct_assembly.method_details           PISA
+_pdbx_struct_assembly.oligomeric_details       trimeric
+_pdbx_struct_assembly.oligomeric_count         3
+#
+_pdbx_struct_assembly_gen.assembly_id           1
+_pdbx_struct_assembly_gen.oper_expression       1
+_pdbx_struct_assembly_gen.asym_id_list          A,E,B,D,F,C,G
+#
+loop_
+_pdbx_struct_assembly_prop.biol_id       
+_pdbx_struct_assembly_prop.type          
+_pdbx_struct_assembly_prop.value         
+_pdbx_struct_assembly_prop.details       
+1 "ABSA (A^2)" 3630 ?
+1 "SSA (A^2)" 18700 ?
+1 MORE -22 ?
+#
+_pdbx_struct_oper_list.id                       1
+_pdbx_struct_oper_list.type                     "identity operation"
+_pdbx_struct_oper_list.name                     1_555
+_pdbx_struct_oper_list.symmetry_operation       x,y,z
+_pdbx_struct_oper_list.matrix[1][1]             1.0000000000
+_pdbx_struct_oper_list.matrix[1][2]             0.0000000000
+_pdbx_struct_oper_list.matrix[1][3]             0.0000000000
+_pdbx_struct_oper_list.vector[1]                0.0000000000
+_pdbx_struct_oper_list.matrix[2][1]             0.0000000000
+_pdbx_struct_oper_list.matrix[2][2]             1.0000000000
+_pdbx_struct_oper_list.matrix[2][3]             0.0000000000
+_pdbx_struct_oper_list.vector[2]                0.0000000000
+_pdbx_struct_oper_list.matrix[3][1]             0.0000000000
+_pdbx_struct_oper_list.matrix[3][2]             0.0000000000
+_pdbx_struct_oper_list.matrix[3][3]             1.0000000000
+_pdbx_struct_oper_list.vector[3]                0.0000000000
+#
+loop_
+_ndb_struct_conf_na.entry_id       
+_ndb_struct_conf_na.feature        
+3UCU "double helix"
+3UCU "a-form double helix"
+3UCU tetraloop
+3UCU "bulge loop"
+3UCU "mismatched base pair"
+3UCU "triple helix"
+3UCU "quadruple helix"
+#
+loop_
+_ndb_struct_na_base_pair.model_number          
+_ndb_struct_na_base_pair.i_label_asym_id       
+_ndb_struct_na_base_pair.i_label_comp_id       
+_ndb_struct_na_base_pair.i_label_seq_id        
+_ndb_struct_na_base_pair.i_symmetry            
+_ndb_struct_na_base_pair.j_label_asym_id       
+_ndb_struct_na_base_pair.j_label_comp_id       
+_ndb_struct_na_base_pair.j_label_seq_id        
+_ndb_struct_na_base_pair.j_symmetry            
+_ndb_struct_na_base_pair.shear                 
+_ndb_struct_na_base_pair.stretch               
+_ndb_struct_na_base_pair.stagger               
+_ndb_struct_na_base_pair.buckle                
+_ndb_struct_na_base_pair.opening               
+_ndb_struct_na_base_pair.pair_number           
+_ndb_struct_na_base_pair.pair_name             
+_ndb_struct_na_base_pair.i_auth_asym_id        
+_ndb_struct_na_base_pair.i_auth_seq_id         
+_ndb_struct_na_base_pair.i_PDB_ins_code        
+_ndb_struct_na_base_pair.j_auth_asym_id        
+_ndb_struct_na_base_pair.j_auth_seq_id         
+_ndb_struct_na_base_pair.j_PDB_ins_code        
+_ndb_struct_na_base_pair.hbond_type_28         
+_ndb_struct_na_base_pair.hbond_type_12         
+1 B C 4 1_555 B G 92 1_555 0.187 0.071 0.337 9.615 -4.537 1 R_C11:G98_R R 11 ? R 98 ? 19 1
+1 B A 5 1_555 B G 91 1_555 0.554 1.617 -0.349 -16.822 -13.950 2 R_A12:G97_R R 12 ? R 97 ? 8 1
+1 B C 6 1_555 B G 88 1_555 -0.469 0.137 0.622 -20.707 -0.472 3 R_C13:G94_R R 13 ? R 94 ? 19 1
+1 B G 7 1_555 B C 87 1_555 0.184 0.135 0.584 4.716 -2.629 4 R_G14:C93_R R 14 ? R 93 ? 19 1
+1 C G 2 1_555 B C 86 1_555 0.338 0.113 -0.078 -4.607 5.538 5 A_G2:C92_R A 2 ? R 92 ? 19 1
+1 B G 12 1_555 B A 40 1_555 0.069 2.921 -0.085 -9.047 -51.751 6 R_G19:A47_R R 19 ? R 47 ? ? ?
+1 B G 13 1_555 C G 1 1_555 5.879 -0.700 -0.221 4.712 -110.433 7 R_G20:G1_A R 20 ? A 1 ? 7 4
+1 B G 14 1_555 B C 39 1_555 -0.212 0.039 -0.260 0.652 3.393 8 R_G21:C46_R R 21 ? R 46 ? 19 1
+1 B C 15 1_555 B G 38 1_555 0.173 -0.070 -0.159 9.064 3.213 9 R_C22:G45_R R 22 ? R 45 ? 19 1
+1 B G 77 1_555 B C 37 1_555 -0.330 -0.198 0.543 2.720 -5.761 10 R_G83:C44_R R 83 ? R 44 ? 19 1
+1 B A 18 1_555 B G 35 1_555 -6.754 -3.553 0.197 0.918 -0.465 11 R_A25:G42_R R 25 ? R 42 ? 11 9
+1 B C 19 1_555 B G 34 1_555 0.349 0.134 -0.325 10.614 1.783 12 R_C26:G41_R R 26 ? R 41 ? 19 1
+1 B C 20 1_555 B G 33 1_555 -0.075 -0.115 -0.112 8.320 1.321 13 R_C27:G40_R R 27 ? R 40 ? 19 1
+1 B A 21 1_555 B U 32 1_555 0.038 -0.172 0.059 1.620 5.470 14 R_A28:U39_R R 28 ? R 39 ? 20 1
+1 B U 22 1_555 B G 31 1_555 2.342 -0.524 -0.039 4.583 6.387 15 R_U29:G38_R R 29 ? R 38 ? 28 1
+1 B U 23 1_555 B A 30 1_555 0.476 -0.302 -0.019 -2.641 0.821 16 R_U30:A37_R R 30 ? R 37 ? 20 1
+1 B C 24 1_555 B G 29 1_555 0.436 -0.355 -0.148 3.903 -0.692 17 R_C31:G36_R R 31 ? R 36 ? 19 1
+1 B A 41 1_555 B U 84 1_555 -4.304 -2.416 -0.153 10.581 -89.980 18 R_A48:U90_R R 48 ? R 90 ? 24 4
+1 B G 43 1_555 B U 83 1_555 -2.395 -0.696 -0.297 -3.035 -4.662 19 R_G50:U89_R R 50 ? R 89 ? 28 1
+1 B C 44 1_555 B G 82 1_555 0.469 -0.285 -0.089 5.423 1.247 20 R_C51:G88_R R 51 ? R 88 ? 19 1
+1 B C 45 1_555 B G 81 1_555 0.087 -0.116 0.215 -1.792 1.383 21 R_C52:G87_R R 52 ? R 87 ? 19 1
+1 B C 47 1_555 B G 80 1_555 0.004 -0.104 -0.573 18.342 2.114 22 R_C54:G86_R R 54 ? R 86 ? 19 1
+1 B C 48 1_555 B G 79 1_555 0.240 -0.185 -0.103 3.870 -2.273 23 R_C55:G85_R R 55 ? R 85 ? 19 1
+1 B G 49 1_555 B C 78 1_555 -0.983 -0.389 0.218 8.779 0.707 24 R_G56:C84_R R 56 ? R 84 ? 19 1
+1 B G 50 1_555 B U 75 1_555 -1.511 -0.373 0.226 4.965 -5.608 25 R_G57:U81_R R 57 ? R 81 ? 28 1
+1 B C 51 1_555 B G 74 1_555 0.524 -0.235 0.049 12.425 3.189 26 R_C58:G80_R R 58 ? R 80 ? 19 1
+1 B C 52 1_555 B G 73 1_555 -0.007 -0.140 -0.228 3.193 -0.027 27 R_C59:G79_R R 59 ? R 79 ? 19 1
+1 B U 53 1_555 B A 72 1_555 0.250 -0.214 0.217 -5.026 -3.180 28 R_U60:A78_R R 60 ? R 78 ? 20 1
+1 B A 54 1_555 B U 71 1_555 1.394 -0.134 0.318 12.201 -3.591 29 R_A61:U77_R R 61 ? R 77 ? 20 1
+1 B C 57 1_555 B G 70 1_555 -0.041 -0.090 -0.669 18.961 6.074 30 R_C64:G76_R R 64 ? R 76 ? 19 1
+1 B C 58 1_555 B G 69 1_555 1.086 -0.174 0.344 -10.081 9.716 31 R_C65:G75_R R 65 ? R 75 ? 19 1
+#
+loop_
+_ndb_struct_na_base_pair_step.model_number            
+_ndb_struct_na_base_pair_step.i_label_asym_id_1       
+_ndb_struct_na_base_pair_step.i_label_comp_id_1       
+_ndb_struct_na_base_pair_step.i_label_seq_id_1        
+_ndb_struct_na_base_pair_step.i_symmetry_1            
+_ndb_struct_na_base_pair_step.j_label_asym_id_1       
+_ndb_struct_na_base_pair_step.j_label_comp_id_1       
+_ndb_struct_na_base_pair_step.j_label_seq_id_1        
+_ndb_struct_na_base_pair_step.j_symmetry_1            
+_ndb_struct_na_base_pair_step.i_label_asym_id_2       
+_ndb_struct_na_base_pair_step.i_label_comp_id_2       
+_ndb_struct_na_base_pair_step.i_label_seq_id_2        
+_ndb_struct_na_base_pair_step.i_symmetry_2            
+_ndb_struct_na_base_pair_step.j_label_asym_id_2       
+_ndb_struct_na_base_pair_step.j_label_comp_id_2       
+_ndb_struct_na_base_pair_step.j_label_seq_id_2        
+_ndb_struct_na_base_pair_step.j_symmetry_2            
+_ndb_struct_na_base_pair_step.shift                   
+_ndb_struct_na_base_pair_step.slide                   
+_ndb_struct_na_base_pair_step.rise                    
+_ndb_struct_na_base_pair_step.tilt                    
+_ndb_struct_na_base_pair_step.roll                    
+_ndb_struct_na_base_pair_step.twist                   
+_ndb_struct_na_base_pair_step.x_displacement          
+_ndb_struct_na_base_pair_step.y_displacement          
+_ndb_struct_na_base_pair_step.helical_rise            
+_ndb_struct_na_base_pair_step.inclination             
+_ndb_struct_na_base_pair_step.tip                     
+_ndb_struct_na_base_pair_step.helical_twist           
+_ndb_struct_na_base_pair_step.step_number             
+_ndb_struct_na_base_pair_step.step_name               
+_ndb_struct_na_base_pair_step.i_auth_asym_id_1        
+_ndb_struct_na_base_pair_step.i_auth_seq_id_1         
+_ndb_struct_na_base_pair_step.i_PDB_ins_code_1        
+_ndb_struct_na_base_pair_step.j_auth_asym_id_1        
+_ndb_struct_na_base_pair_step.j_auth_seq_id_1         
+_ndb_struct_na_base_pair_step.j_PDB_ins_code_1        
+_ndb_struct_na_base_pair_step.i_auth_asym_id_2        
+_ndb_struct_na_base_pair_step.i_auth_seq_id_2         
+_ndb_struct_na_base_pair_step.i_PDB_ins_code_2        
+_ndb_struct_na_base_pair_step.j_auth_asym_id_2        
+_ndb_struct_na_base_pair_step.j_auth_seq_id_2         
+_ndb_struct_na_base_pair_step.j_PDB_ins_code_2        
+1 B C 4 1_555 B G 92 1_555 B A 5 1_555 B G 91 1_555 0.329 -2.498 3.630 9.758 10.984 33.904 -5.459 0.820 2.710 17.833 -15.843 36.865 1 RR_C11A12:G97G98_RR R 11 ? R 98 ? R 12 ? R 97 ?
+1 B A 5 1_555 B G 91 1_555 B C 6 1_555 B G 88 1_555 2.181 -0.463 3.134 -0.142 6.202 41.158 -1.274 -3.085 3.029 8.762 0.201 41.602 2 RR_A12C13:G94G97_RR R 12 ? R 97 ? R 13 ? R 94 ?
+1 B C 6 1_555 B G 88 1_555 B G 7 1_555 B C 87 1_555 -1.045 -0.668 2.711 -5.009 16.791 28.698 -3.381 1.148 2.155 30.546 9.113 33.529 3 RR_C13G14:C93G94_RR R 13 ? R 94 ? R 14 ? R 93 ?
+1 B G 7 1_555 B C 87 1_555 C G 2 1_555 B C 86 1_555 -0.505 -1.440 3.425 1.406 5.304 40.341 -2.667 0.884 3.199 7.647 -2.027 40.697 4 RA_G14G2:C92C93_RR R 14 ? R 93 ? A 2 ? R 92 ?
+1 C G 2 1_555 B C 86 1_555 B G 12 1_555 B A 40 1_555 -2.554 3.400 3.088 -3.965 -4.060 117.011 2.032 1.459 3.067 -2.380 2.324 117.097 5 AR_G2G19:A47C92_RR A 2 ? R 92 ? R 19 ? R 47 ?
+1 B G 12 1_555 B A 40 1_555 B G 13 1_555 C G 1 1_555 -0.492 -2.731 3.149 -3.804 -0.002 46.167 -3.472 0.313 3.178 -0.003 4.842 46.315 6 RR_G19G20:G1A47_AR R 19 ? R 47 ? R 20 ? A 1 ?
+1 B G 13 1_555 C G 1 1_555 B G 14 1_555 B C 39 1_555 1.693 -1.439 3.386 0.537 0.911 -25.650 2.973 3.968 3.399 -2.052 1.208 -25.671 7 RR_G20G21:C46G1_RA R 20 ? A 1 ? R 21 ? R 46 ?
+1 B G 14 1_555 B C 39 1_555 B C 15 1_555 B G 38 1_555 0.330 -1.786 3.197 -1.954 0.154 31.912 -3.269 -0.944 3.163 0.281 3.550 31.971 8 RR_G21C22:G45C46_RR R 21 ? R 46 ? R 22 ? R 45 ?
+1 B C 15 1_555 B G 38 1_555 B G 77 1_555 B C 37 1_555 -5.423 -0.104 3.649 -12.294 -7.086 57.603 0.358 4.688 4.601 -7.234 12.551 59.179 9 RR_C22G83:C44G45_RR R 22 ? R 45 ? R 83 ? R 44 ?
+1 B A 18 1_555 B G 35 1_555 B C 19 1_555 B G 34 1_555 -0.219 -0.737 3.219 -2.754 6.282 61.924 -0.993 0.089 3.145 6.085 2.667 62.265 10 RR_A25C26:G41G42_RR R 25 ? R 42 ? R 26 ? R 41 ?
+1 B C 19 1_555 B G 34 1_555 B C 20 1_555 B G 33 1_555 -0.032 -1.880 3.288 -2.423 7.796 27.616 -5.406 -0.441 2.662 15.896 4.940 28.775 11 RR_C26C27:G40G41_RR R 26 ? R 41 ? R 27 ? R 40 ?
+1 B C 20 1_555 B G 33 1_555 B A 21 1_555 B U 32 1_555 0.231 -1.453 3.239 2.570 15.815 34.600 -4.050 -0.059 2.386 24.998 -4.062 38.027 12 RR_C27A28:U39G40_RR R 27 ? R 40 ? R 28 ? R 39 ?
+1 B A 21 1_555 B U 32 1_555 B U 22 1_555 B G 31 1_555 0.346 -0.978 3.140 2.582 10.221 39.782 -2.423 -0.232 2.831 14.709 -3.716 41.101 13 RR_A28U29:G38U39_RR R 28 ? R 39 ? R 29 ? R 38 ?
+1 B U 22 1_555 B G 31 1_555 B U 23 1_555 B A 30 1_555 -0.154 -1.916 3.126 3.332 10.226 26.693 -5.809 0.945 2.220 21.092 -6.873 28.742 14 RR_U29U30:A37G38_RR R 29 ? R 38 ? R 30 ? R 37 ?
+1 B U 23 1_555 B A 30 1_555 B C 24 1_555 B G 29 1_555 0.069 -1.598 3.105 1.614 6.134 29.658 -4.171 0.160 2.727 11.813 -3.108 30.313 15 RR_U30C31:G36A37_RR R 30 ? R 37 ? R 31 ? R 36 ?
+1 B A 41 1_555 B U 84 1_555 B G 43 1_555 B U 83 1_555 3.254 -2.249 3.664 -7.112 11.087 64.527 -2.535 -3.295 2.952 10.272 6.590 65.715 16 RR_A48G50:U89U90_RR R 48 ? R 90 ? R 50 ? R 89 ?
+1 B G 43 1_555 B U 83 1_555 B C 44 1_555 B G 82 1_555 0.267 -1.337 3.055 -3.574 4.044 42.574 -2.194 -0.690 2.892 5.543 4.899 42.899 17 RR_G50C51:G88U89_RR R 50 ? R 89 ? R 51 ? R 88 ?
+1 B C 44 1_555 B G 82 1_555 B C 45 1_555 B G 81 1_555 -0.010 -1.850 3.412 1.493 7.127 32.866 -4.342 0.257 2.954 12.406 -2.599 33.641 18 RR_C51C52:G87G88_RR R 51 ? R 88 ? R 52 ? R 87 ?
+1 B C 45 1_555 B G 81 1_555 B C 47 1_555 B G 80 1_555 -2.806 -1.058 2.913 11.418 5.518 51.856 -1.457 3.703 2.179 6.204 -12.838 53.280 19 RR_C52C54:G86G87_RR R 52 ? R 87 ? R 54 ? R 86 ?
+1 B C 47 1_555 B G 80 1_555 B C 48 1_555 B G 79 1_555 -0.843 -2.031 3.701 -4.921 10.685 34.219 -4.875 0.622 3.040 17.529 8.073 36.128 20 RR_C54C55:G85G86_RR R 54 ? R 86 ? R 55 ? R 85 ?
+1 B C 48 1_555 B G 79 1_555 B G 49 1_555 B C 78 1_555 0.175 -2.414 2.994 -3.793 6.575 19.300 -8.968 -1.788 2.000 18.701 10.789 20.726 21 RR_C55G56:C84G85_RR R 55 ? R 85 ? R 56 ? R 84 ?
+1 B G 49 1_555 B C 78 1_555 B G 50 1_555 B U 75 1_555 1.981 -1.778 3.113 0.112 6.738 49.194 -2.573 -2.352 2.866 8.050 -0.134 49.625 22 RR_G56G57:U81C84_RR R 56 ? R 84 ? R 57 ? R 81 ?
+1 B G 50 1_555 B U 75 1_555 B C 51 1_555 B G 74 1_555 0.406 -1.299 3.135 -2.152 3.525 40.540 -2.231 -0.806 2.992 5.071 3.095 40.741 23 RR_G57C58:G80U81_RR R 57 ? R 81 ? R 58 ? R 80 ?
+1 B C 51 1_555 B G 74 1_555 B C 52 1_555 B G 73 1_555 -0.649 -2.133 3.384 -0.838 7.242 27.415 -5.952 1.140 2.760 14.947 1.730 28.349 24 RR_C58C59:G79G80_RR R 58 ? R 80 ? R 59 ? R 79 ?
+1 B C 52 1_555 B G 73 1_555 B U 53 1_555 B A 72 1_555 -0.312 -2.050 3.572 -1.941 9.883 31.032 -5.378 0.217 2.817 17.891 3.513 32.587 25 RR_C59U60:A78G79_RR R 59 ? R 79 ? R 60 ? R 78 ?
+1 B U 53 1_555 B A 72 1_555 B A 54 1_555 B U 71 1_555 -0.076 -1.637 2.879 2.700 14.724 27.674 -5.130 0.526 1.786 28.311 -5.191 31.394 26 RR_U60A61:U77A78_RR R 60 ? R 78 ? R 61 ? R 77 ?
+1 B A 54 1_555 B U 71 1_555 B C 57 1_555 B G 70 1_555 -4.249 0.516 3.328 10.983 2.181 69.865 0.375 4.032 2.733 1.892 -9.528 70.643 27 RR_A61C64:G76U77_RR R 61 ? R 77 ? R 64 ? R 76 ?
+1 B C 57 1_555 B G 70 1_555 B C 58 1_555 B G 69 1_555 -0.004 -1.520 3.987 -6.292 13.783 37.819 -3.943 -0.796 3.225 20.297 9.267 40.638 28 RR_C64C65:G75G76_RR R 64 ? R 76 ? R 65 ? R 75 ?
+#
+loop_
+_software.name                 
+_software.classification       
+_software.version              
+_software.citation_id          
+_software.pdbx_ordinal         
+CBASS "data collection" . ? 1
+Phaser "model building" . ? 2
+REFMAC refinement 5.5.0109 ? 3
+#
+loop_
+_pdbx_unobs_or_zero_occ_residues.id                   
+_pdbx_unobs_or_zero_occ_residues.polymer_flag         
+_pdbx_unobs_or_zero_occ_residues.occupancy_flag       
+_pdbx_unobs_or_zero_occ_residues.PDB_model_num        
+_pdbx_unobs_or_zero_occ_residues.auth_asym_id         
+_pdbx_unobs_or_zero_occ_residues.auth_comp_id         
+_pdbx_unobs_or_zero_occ_residues.auth_seq_id          
+_pdbx_unobs_or_zero_occ_residues.PDB_ins_code         
+1 Y 1 1 P MET 1 ?
+2 Y 1 1 P ALA 2 ?
+3 Y 1 1 P VAL 3 ?
+4 Y 1 1 P PRO 4 ?
+5 Y 1 1 P GLU 5 ?
+6 Y 1 1 P THR 6 ?
+7 Y 1 1 P ILE 94 ?
+8 Y 1 1 P ALA 95 ?
+9 Y 1 1 P LYS 96 ?
+10 Y 1 1 P MET 97 ?
+11 Y 1 1 P LYS 98 ?
+#
+loop_
+_pdbx_nonpoly_scheme.asym_id             
+_pdbx_nonpoly_scheme.entity_id           
+_pdbx_nonpoly_scheme.mon_id              
+_pdbx_nonpoly_scheme.ndb_seq_num         
+_pdbx_nonpoly_scheme.pdb_seq_num         
+_pdbx_nonpoly_scheme.auth_seq_num        
+_pdbx_nonpoly_scheme.pdb_mon_id          
+_pdbx_nonpoly_scheme.auth_mon_id         
+_pdbx_nonpoly_scheme.pdb_strand_id       
+_pdbx_nonpoly_scheme.pdb_ins_code        
+D 4 MG 1 1 1 MG MO6 R .
+E 5 HOH 1 99 1 HOH HOH P .
+E 5 HOH 2 100 2 HOH HOH P .
+E 5 HOH 3 101 7 HOH HOH P .
+F 5 HOH 1 3 3 HOH HOH R .
+F 5 HOH 2 4 4 HOH HOH R .
+F 5 HOH 3 5 5 HOH HOH R .
+F 5 HOH 4 670 8 HOH HOH R .
+F 5 HOH 5 671 9 HOH HOH R .
+F 5 HOH 6 672 10 HOH HOH R .
+F 5 HOH 7 673 1 HOH MO6 R .
+F 5 HOH 8 674 1 HOH MO6 R .
+F 5 HOH 9 675 1 HOH MO6 R .
+F 5 HOH 10 676 1 HOH MO6 R .
+G 5 HOH 1 3 1 HOH MO6 A .
+#
+_pdbx_struct_mod_residue.id                   1
+_pdbx_struct_mod_residue.label_asym_id        B
+_pdbx_struct_mod_residue.label_seq_id         1
+_pdbx_struct_mod_residue.label_comp_id        GTP
+_pdbx_struct_mod_residue.auth_asym_id         R
+_pdbx_struct_mod_residue.auth_seq_id          8
+_pdbx_struct_mod_residue.auth_comp_id         GTP
+_pdbx_struct_mod_residue.PDB_ins_code         ?
+_pdbx_struct_mod_residue.parent_comp_id       G
+_pdbx_struct_mod_residue.details              "GUANOSINE-5'-TRIPHOSPHATE"
+#
+_pdbx_validate_rmsd_bond.id                   1
+_pdbx_validate_rmsd_bond.PDB_model_num        1
+_pdbx_validate_rmsd_bond.auth_atom_id_1       P
+_pdbx_validate_rmsd_bond.auth_asym_id_1       A
+_pdbx_validate_rmsd_bond.auth_comp_id_1       G
+_pdbx_validate_rmsd_bond.auth_seq_id_1        1
+_pdbx_validate_rmsd_bond.PDB_ins_code_1       ?
+_pdbx_validate_rmsd_bond.label_alt_id_1       ?
+_pdbx_validate_rmsd_bond.auth_atom_id_2       OP3
+_pdbx_validate_rmsd_bond.auth_asym_id_2       A
+_pdbx_validate_rmsd_bond.auth_comp_id_2       G
+_pdbx_validate_rmsd_bond.auth_seq_id_2        1
+_pdbx_validate_rmsd_bond.PDB_ins_code_2       ?
+_pdbx_validate_rmsd_bond.label_alt_id_2       ?
+_pdbx_validate_rmsd_bond.bond_deviation       -0.127
+#
+loop_
+_pdbx_validate_rmsd_angle.id                    
+_pdbx_validate_rmsd_angle.PDB_model_num         
+_pdbx_validate_rmsd_angle.auth_atom_id_1        
+_pdbx_validate_rmsd_angle.auth_asym_id_1        
+_pdbx_validate_rmsd_angle.auth_comp_id_1        
+_pdbx_validate_rmsd_angle.auth_seq_id_1         
+_pdbx_validate_rmsd_angle.PDB_ins_code_1        
+_pdbx_validate_rmsd_angle.label_alt_id_1        
+_pdbx_validate_rmsd_angle.auth_atom_id_2        
+_pdbx_validate_rmsd_angle.auth_asym_id_2        
+_pdbx_validate_rmsd_angle.auth_comp_id_2        
+_pdbx_validate_rmsd_angle.auth_seq_id_2         
+_pdbx_validate_rmsd_angle.PDB_ins_code_2        
+_pdbx_validate_rmsd_angle.label_alt_id_2        
+_pdbx_validate_rmsd_angle.auth_atom_id_3        
+_pdbx_validate_rmsd_angle.auth_asym_id_3        
+_pdbx_validate_rmsd_angle.auth_comp_id_3        
+_pdbx_validate_rmsd_angle.auth_seq_id_3         
+_pdbx_validate_rmsd_angle.PDB_ins_code_3        
+_pdbx_validate_rmsd_angle.label_alt_id_3        
+_pdbx_validate_rmsd_angle.angle_deviation       
+1 1 "O4'" R A 48 ? ? "C1'" R A 48 ? ? N9 R A 48 ? ? 5.2
+2 1 OP1 A G 1 ? ? P A G 1 ? ? OP2 A G 1 ? ? -12.1
+#
+_pdbx_validate_torsion.id                  1
+_pdbx_validate_torsion.PDB_model_num       1
+_pdbx_validate_torsion.auth_comp_id        ASP
+_pdbx_validate_torsion.auth_asym_id        P
+_pdbx_validate_torsion.auth_seq_id         92
+_pdbx_validate_torsion.PDB_ins_code        ?
+_pdbx_validate_torsion.phi                 74.40
+_pdbx_validate_torsion.psi                 -158.21
+#
+loop_
+_pdbx_entity_nonpoly.entity_id       
+_pdbx_entity_nonpoly.name            
+_pdbx_entity_nonpoly.comp_id         
+4 "MAGNESIUM ION" MG
+5 water HOH
+#
+loop_
+_chem_comp_bond.comp_id                  
+_chem_comp_bond.pdbx_stereo_config       
+_chem_comp_bond.pdbx_ordinal             
+_chem_comp_bond.pdbx_aromatic_flag       
+_chem_comp_bond.atom_id_1                
+_chem_comp_bond.atom_id_2                
+_chem_comp_bond.value_order              
+ARG N 1 N N CA SING
+ARG N 2 N N H SING
+ARG N 3 N N H2 SING
+ARG N 4 N CA C SING
+ARG N 5 N CA CB SING
+ARG N 6 N CA HA SING
+ARG N 7 N C O DOUB
+ARG N 8 N C OXT SING
+ARG N 9 N CB CG SING
+ARG N 10 N CB HB2 SING
+ARG N 11 N CB HB3 SING
+ARG N 12 N CG CD SING
+ARG N 13 N CG HG2 SING
+ARG N 14 N CG HG3 SING
+ARG N 15 N CD NE SING
+ARG N 16 N CD HD2 SING
+ARG N 17 N CD HD3 SING
+ARG N 18 N NE CZ SING
+ARG N 19 N NE HE SING
+ARG N 20 N CZ NH1 SING
+ARG N 21 N CZ NH2 DOUB
+ARG N 22 N NH1 HH11 SING
+ARG N 23 N NH1 HH12 SING
+ARG N 24 N NH2 HH21 SING
+ARG N 25 N NH2 HH22 SING
+ARG N 26 N OXT HXT SING
+PRO N 1 N N CA SING
+PRO N 2 N N CD SING
+PRO N 3 N N H SING
+PRO N 4 N CA C SING
+PRO N 5 N CA CB SING
+PRO N 6 N CA HA SING
+PRO N 7 N C O DOUB
+PRO N 8 N C OXT SING
+PRO N 9 N CB CG SING
+PRO N 10 N CB HB2 SING
+PRO N 11 N CB HB3 SING
+PRO N 12 N CG CD SING
+PRO N 13 N CG HG2 SING
+PRO N 14 N CG HG3 SING
+PRO N 15 N CD HD2 SING
+PRO N 16 N CD HD3 SING
+PRO N 17 N OXT HXT SING
+ASN N 1 N N CA SING
+ASN N 2 N N H SING
+ASN N 3 N N H2 SING
+ASN N 4 N CA C SING
+ASN N 5 N CA CB SING
+ASN N 6 N CA HA SING
+ASN N 7 N C O DOUB
+ASN N 8 N C OXT SING
+ASN N 9 N CB CG SING
+ASN N 10 N CB HB2 SING
+ASN N 11 N CB HB3 SING
+ASN N 12 N CG OD1 DOUB
+ASN N 13 N CG ND2 SING
+ASN N 14 N ND2 HD21 SING
+ASN N 15 N ND2 HD22 SING
+ASN N 16 N OXT HXT SING
+HIS N 1 N N CA SING
+HIS N 2 N N H SING
+HIS N 3 N N H2 SING
+HIS N 4 N CA C SING
+HIS N 5 N CA CB SING
+HIS N 6 N CA HA SING
+HIS N 7 N C O DOUB
+HIS N 8 N C OXT SING
+HIS N 9 N CB CG SING
+HIS N 10 N CB HB2 SING
+HIS N 11 N CB HB3 SING
+HIS N 12 Y CG ND1 SING
+HIS N 13 Y CG CD2 DOUB
+HIS N 14 Y ND1 CE1 DOUB
+HIS N 15 N ND1 HD1 SING
+HIS N 16 Y CD2 NE2 SING
+HIS N 17 N CD2 HD2 SING
+HIS N 18 Y CE1 NE2 SING
+HIS N 19 N CE1 HE1 SING
+HIS N 20 N NE2 HE2 SING
+HIS N 21 N OXT HXT SING
+THR N 1 N N CA SING
+THR N 2 N N H SING
+THR N 3 N N H2 SING
+THR N 4 N CA C SING
+THR N 5 N CA CB SING
+THR N 6 N CA HA SING
+THR N 7 N C O DOUB
+THR N 8 N C OXT SING
+THR N 9 N CB OG1 SING
+THR N 10 N CB CG2 SING
+THR N 11 N CB HB SING
+THR N 12 N OG1 HG1 SING
+THR N 13 N CG2 HG21 SING
+THR N 14 N CG2 HG22 SING
+THR N 15 N CG2 HG23 SING
+THR N 16 N OXT HXT SING
+ILE N 1 N N CA SING
+ILE N 2 N N H SING
+ILE N 3 N N H2 SING
+ILE N 4 N CA C SING
+ILE N 5 N CA CB SING
+ILE N 6 N CA HA SING
+ILE N 7 N C O DOUB
+ILE N 8 N C OXT SING
+ILE N 9 N CB CG1 SING
+ILE N 10 N CB CG2 SING
+ILE N 11 N CB HB SING
+ILE N 12 N CG1 CD1 SING
+ILE N 13 N CG1 HG12 SING
+ILE N 14 N CG1 HG13 SING
+ILE N 15 N CG2 HG21 SING
+ILE N 16 N CG2 HG22 SING
+ILE N 17 N CG2 HG23 SING
+ILE N 18 N CD1 HD11 SING
+ILE N 19 N CD1 HD12 SING
+ILE N 20 N CD1 HD13 SING
+ILE N 21 N OXT HXT SING
+TYR N 1 N N CA SING
+TYR N 2 N N H SING
+TYR N 3 N N H2 SING
+TYR N 4 N CA C SING
+TYR N 5 N CA CB SING
+TYR N 6 N CA HA SING
+TYR N 7 N C O DOUB
+TYR N 8 N C OXT SING
+TYR N 9 N CB CG SING
+TYR N 10 N CB HB2 SING
+TYR N 11 N CB HB3 SING
+TYR N 12 Y CG CD1 DOUB
+TYR N 13 Y CG CD2 SING
+TYR N 14 Y CD1 CE1 SING
+TYR N 15 N CD1 HD1 SING
+TYR N 16 Y CD2 CE2 DOUB
+TYR N 17 N CD2 HD2 SING
+TYR N 18 Y CE1 CZ DOUB
+TYR N 19 N CE1 HE1 SING
+TYR N 20 Y CE2 CZ SING
+TYR N 21 N CE2 HE2 SING
+TYR N 22 N CZ OH SING
+TYR N 23 N OH HH SING
+TYR N 24 N OXT HXT SING
+LEU N 1 N N CA SING
+LEU N 2 N N H SING
+LEU N 3 N N H2 SING
+LEU N 4 N CA C SING
+LEU N 5 N CA CB SING
+LEU N 6 N CA HA SING
+LEU N 7 N C O DOUB
+LEU N 8 N C OXT SING
+LEU N 9 N CB CG SING
+LEU N 10 N CB HB2 SING
+LEU N 11 N CB HB3 SING
+LEU N 12 N CG CD1 SING
+LEU N 13 N CG CD2 SING
+LEU N 14 N CG HG SING
+LEU N 15 N CD1 HD11 SING
+LEU N 16 N CD1 HD12 SING
+LEU N 17 N CD1 HD13 SING
+LEU N 18 N CD2 HD21 SING
+LEU N 19 N CD2 HD22 SING
+LEU N 20 N CD2 HD23 SING
+LEU N 21 N OXT HXT SING
+GLU N 1 N N CA SING
+GLU N 2 N N H SING
+GLU N 3 N N H2 SING
+GLU N 4 N CA C SING
+GLU N 5 N CA CB SING
+GLU N 6 N CA HA SING
+GLU N 7 N C O DOUB
+GLU N 8 N C OXT SING
+GLU N 9 N CB CG SING
+GLU N 10 N CB HB2 SING
+GLU N 11 N CB HB3 SING
+GLU N 12 N CG CD SING
+GLU N 13 N CG HG2 SING
+GLU N 14 N CG HG3 SING
+GLU N 15 N CD OE1 DOUB
+GLU N 16 N CD OE2 SING
+GLU N 17 N OE2 HE2 SING
+GLU N 18 N OXT HXT SING
+LYS N 1 N N CA SING
+LYS N 2 N N H SING
+LYS N 3 N N H2 SING
+LYS N 4 N CA C SING
+LYS N 5 N CA CB SING
+LYS N 6 N CA HA SING
+LYS N 7 N C O DOUB
+LYS N 8 N C OXT SING
+LYS N 9 N CB CG SING
+LYS N 10 N CB HB2 SING
+LYS N 11 N CB HB3 SING
+LYS N 12 N CG CD SING
+LYS N 13 N CG HG2 SING
+LYS N 14 N CG HG3 SING
+LYS N 15 N CD CE SING
+LYS N 16 N CD HD2 SING
+LYS N 17 N CD HD3 SING
+LYS N 18 N CE NZ SING
+LYS N 19 N CE HE2 SING
+LYS N 20 N CE HE3 SING
+LYS N 21 N NZ HZ1 SING
+LYS N 22 N NZ HZ2 SING
+LYS N 23 N NZ HZ3 SING
+LYS N 24 N OXT HXT SING
+ASP N 1 N N CA SING
+ASP N 2 N N H SING
+ASP N 3 N N H2 SING
+ASP N 4 N CA C SING
+ASP N 5 N CA CB SING
+ASP N 6 N CA HA SING
+ASP N 7 N C O DOUB
+ASP N 8 N C OXT SING
+ASP N 9 N CB CG SING
+ASP N 10 N CB HB2 SING
+ASP N 11 N CB HB3 SING
+ASP N 12 N CG OD1 DOUB
+ASP N 13 N CG OD2 SING
+ASP N 14 N OD2 HD2 SING
+ASP N 15 N OXT HXT SING
+SER N 1 N N CA SING
+SER N 2 N N H SING
+SER N 3 N N H2 SING
+SER N 4 N CA C SING
+SER N 5 N CA CB SING
+SER N 6 N CA HA SING
+SER N 7 N C O DOUB
+SER N 8 N C OXT SING
+SER N 9 N CB OG SING
+SER N 10 N CB HB2 SING
+SER N 11 N CB HB3 SING
+SER N 12 N OG HG SING
+SER N 13 N OXT HXT SING
+ALA N 1 N N CA SING
+ALA N 2 N N H SING
+ALA N 3 N N H2 SING
+ALA N 4 N CA C SING
+ALA N 5 N CA CB SING
+ALA N 6 N CA HA SING
+ALA N 7 N C O DOUB
+ALA N 8 N C OXT SING
+ALA N 9 N CB HB1 SING
+ALA N 10 N CB HB2 SING
+ALA N 11 N CB HB3 SING
+ALA N 12 N OXT HXT SING
+PHE N 1 N N CA SING
+PHE N 2 N N H SING
+PHE N 3 N N H2 SING
+PHE N 4 N CA C SING
+PHE N 5 N CA CB SING
+PHE N 6 N CA HA SING
+PHE N 7 N C O DOUB
+PHE N 8 N C OXT SING
+PHE N 9 N CB CG SING
+PHE N 10 N CB HB2 SING
+PHE N 11 N CB HB3 SING
+PHE N 12 Y CG CD1 DOUB
+PHE N 13 Y CG CD2 SING
+PHE N 14 Y CD1 CE1 SING
+PHE N 15 N CD1 HD1 SING
+PHE N 16 Y CD2 CE2 DOUB
+PHE N 17 N CD2 HD2 SING
+PHE N 18 Y CE1 CZ DOUB
+PHE N 19 N CE1 HE1 SING
+PHE N 20 Y CE2 CZ SING
+PHE N 21 N CE2 HE2 SING
+PHE N 22 N CZ HZ SING
+PHE N 23 N OXT HXT SING
+GLY N 1 N N CA SING
+GLY N 2 N N H SING
+GLY N 3 N N H2 SING
+GLY N 4 N CA C SING
+GLY N 5 N CA HA2 SING
+GLY N 6 N CA HA3 SING
+GLY N 7 N C O DOUB
+GLY N 8 N C OXT SING
+GLY N 9 N OXT HXT SING
+GLN N 1 N N CA SING
+GLN N 2 N N H SING
+GLN N 3 N N H2 SING
+GLN N 4 N CA C SING
+GLN N 5 N CA CB SING
+GLN N 6 N CA HA SING
+GLN N 7 N C O DOUB
+GLN N 8 N C OXT SING
+GLN N 9 N CB CG SING
+GLN N 10 N CB HB2 SING
+GLN N 11 N CB HB3 SING
+GLN N 12 N CG CD SING
+GLN N 13 N CG HG2 SING
+GLN N 14 N CG HG3 SING
+GLN N 15 N CD OE1 DOUB
+GLN N 16 N CD NE2 SING
+GLN N 17 N NE2 HE21 SING
+GLN N 18 N NE2 HE22 SING
+GLN N 19 N OXT HXT SING
+VAL N 1 N N CA SING
+VAL N 2 N N H SING
+VAL N 3 N N H2 SING
+VAL N 4 N CA C SING
+VAL N 5 N CA CB SING
+VAL N 6 N CA HA SING
+VAL N 7 N C O DOUB
+VAL N 8 N C OXT SING
+VAL N 9 N CB CG1 SING
+VAL N 10 N CB CG2 SING
+VAL N 11 N CB HB SING
+VAL N 12 N CG1 HG11 SING
+VAL N 13 N CG1 HG12 SING
+VAL N 14 N CG1 HG13 SING
+VAL N 15 N CG2 HG21 SING
+VAL N 16 N CG2 HG22 SING
+VAL N 17 N CG2 HG23 SING
+VAL N 18 N OXT HXT SING
+MET N 1 N N CA SING
+MET N 2 N N H SING
+MET N 3 N N H2 SING
+MET N 4 N CA C SING
+MET N 5 N CA CB SING
+MET N 6 N CA HA SING
+MET N 7 N C O DOUB
+MET N 8 N C OXT SING
+MET N 9 N CB CG SING
+MET N 10 N CB HB2 SING
+MET N 11 N CB HB3 SING
+MET N 12 N CG SD SING
+MET N 13 N CG HG2 SING
+MET N 14 N CG HG3 SING
+MET N 15 N SD CE SING
+MET N 16 N CE HE1 SING
+MET N 17 N CE HE2 SING
+MET N 18 N CE HE3 SING
+MET N 19 N OXT HXT SING
+GTP N 1 N PG O1G DOUB
+GTP N 2 N PG O2G SING
+GTP N 3 N PG O3G SING
+GTP N 4 N PG O3B SING
+GTP N 5 N O2G HOG2 SING
+GTP N 6 N O3G HOG3 SING
+GTP N 7 N O3B PB SING
+GTP N 8 N PB O1B DOUB
+GTP N 9 N PB O2B SING
+GTP N 10 N PB O3A SING
+GTP N 11 N O2B HOB2 SING
+GTP N 12 N O3A PA SING
+GTP N 13 N PA O1A DOUB
+GTP N 14 N PA O2A SING
+GTP N 15 N PA "O5'" SING
+GTP N 16 N O2A HOA2 SING
+GTP N 17 N "O5'" "C5'" SING
+GTP N 18 N "C5'" "C4'" SING
+GTP N 19 N "C5'" "H5'" SING
+GTP N 20 N "C5'" "H5''" SING
+GTP N 21 N "C4'" "O4'" SING
+GTP N 22 N "C4'" "C3'" SING
+GTP N 23 N "C4'" "H4'" SING
+GTP N 24 N "O4'" "C1'" SING
+GTP N 25 N "C3'" "O3'" SING
+GTP N 26 N "C3'" "C2'" SING
+GTP N 27 N "C3'" "H3'" SING
+GTP N 28 N "O3'" "HO3'" SING
+GTP N 29 N "C2'" "O2'" SING
+GTP N 30 N "C2'" "C1'" SING
+GTP N 31 N "C2'" "H2'" SING
+GTP N 32 N "O2'" "HO2'" SING
+GTP N 33 N "C1'" N9 SING
+GTP N 34 N "C1'" "H1'" SING
+GTP N 35 Y N9 C8 SING
+GTP N 36 Y N9 C4 SING
+GTP N 37 Y C8 N7 DOUB
+GTP N 38 N C8 H8 SING
+GTP N 39 Y N7 C5 SING
+GTP N 40 N C5 C6 SING
+GTP N 41 Y C5 C4 DOUB
+GTP N 42 N C6 O6 DOUB
+GTP N 43 N C6 N1 SING
+GTP N 44 N N1 C2 SING
+GTP N 45 N N1 HN1 SING
+GTP N 46 N C2 N2 SING
+GTP N 47 N C2 N3 DOUB
+GTP N 48 N N2 HN21 SING
+GTP N 49 N N2 HN22 SING
+GTP N 50 N N3 C4 SING
+G N 1 N OP3 P SING
+G N 2 N OP3 HOP3 SING
+G N 3 N P OP1 DOUB
+G N 4 N P OP2 SING
+G N 5 N P "O5'" SING
+G N 6 N OP2 HOP2 SING
+G N 7 N "O5'" "C5'" SING
+G N 8 N "C5'" "C4'" SING
+G N 9 N "C5'" "H5'" SING
+G N 10 N "C5'" "H5''" SING
+G N 11 N "C4'" "O4'" SING
+G N 12 N "C4'" "C3'" SING
+G N 13 N "C4'" "H4'" SING
+G N 14 N "O4'" "C1'" SING
+G N 15 N "C3'" "O3'" SING
+G N 16 N "C3'" "C2'" SING
+G N 17 N "C3'" "H3'" SING
+G N 18 N "O3'" "HO3'" SING
+G N 19 N "C2'" "O2'" SING
+G N 20 N "C2'" "C1'" SING
+G N 21 N "C2'" "H2'" SING
+G N 22 N "O2'" "HO2'" SING
+G N 23 N "C1'" N9 SING
+G N 24 N "C1'" "H1'" SING
+G N 25 Y N9 C8 SING
+G N 26 Y N9 C4 SING
+G N 27 Y C8 N7 DOUB
+G N 28 N C8 H8 SING
+G N 29 Y N7 C5 SING
+G N 30 N C5 C6 SING
+G N 31 Y C5 C4 DOUB
+G N 32 N C6 O6 DOUB
+G N 33 N C6 N1 SING
+G N 34 N N1 C2 SING
+G N 35 N N1 H1 SING
+G N 36 N C2 N2 SING
+G N 37 N C2 N3 DOUB
+G N 38 N N2 H21 SING
+G N 39 N N2 H22 SING
+G N 40 N N3 C4 SING
+U N 1 N OP3 P SING
+U N 2 N OP3 HOP3 SING
+U N 3 N P OP1 DOUB
+U N 4 N P OP2 SING
+U N 5 N P "O5'" SING
+U N 6 N OP2 HOP2 SING
+U N 7 N "O5'" "C5'" SING
+U N 8 N "C5'" "C4'" SING
+U N 9 N "C5'" "H5'" SING
+U N 10 N "C5'" "H5''" SING
+U N 11 N "C4'" "O4'" SING
+U N 12 N "C4'" "C3'" SING
+U N 13 N "C4'" "H4'" SING
+U N 14 N "O4'" "C1'" SING
+U N 15 N "C3'" "O3'" SING
+U N 16 N "C3'" "C2'" SING
+U N 17 N "C3'" "H3'" SING
+U N 18 N "O3'" "HO3'" SING
+U N 19 N "C2'" "O2'" SING
+U N 20 N "C2'" "C1'" SING
+U N 21 N "C2'" "H2'" SING
+U N 22 N "O2'" "HO2'" SING
+U N 23 N "C1'" N1 SING
+U N 24 N "C1'" "H1'" SING
+U N 25 N N1 C2 SING
+U N 26 N N1 C6 SING
+U N 27 N C2 O2 DOUB
+U N 28 N C2 N3 SING
+U N 29 N N3 C4 SING
+U N 30 N N3 H3 SING
+U N 31 N C4 O4 DOUB
+U N 32 N C4 C5 SING
+U N 33 N C5 C6 DOUB
+U N 34 N C5 H5 SING
+U N 35 N C6 H6 SING
+C N 1 N OP3 P SING
+C N 2 N OP3 HOP3 SING
+C N 3 N P OP1 DOUB
+C N 4 N P OP2 SING
+C N 5 N P "O5'" SING
+C N 6 N OP2 HOP2 SING
+C N 7 N "O5'" "C5'" SING
+C N 8 N "C5'" "C4'" SING
+C N 9 N "C5'" "H5'" SING
+C N 10 N "C5'" "H5''" SING
+C N 11 N "C4'" "O4'" SING
+C N 12 N "C4'" "C3'" SING
+C N 13 N "C4'" "H4'" SING
+C N 14 N "O4'" "C1'" SING
+C N 15 N "C3'" "O3'" SING
+C N 16 N "C3'" "C2'" SING
+C N 17 N "C3'" "H3'" SING
+C N 18 N "O3'" "HO3'" SING
+C N 19 N "C2'" "O2'" SING
+C N 20 N "C2'" "C1'" SING
+C N 21 N "C2'" "H2'" SING
+C N 22 N "O2'" "HO2'" SING
+C N 23 N "C1'" N1 SING
+C N 24 N "C1'" "H1'" SING
+C N 25 N N1 C2 SING
+C N 26 N N1 C6 SING
+C N 27 N C2 O2 DOUB
+C N 28 N C2 N3 SING
+C N 29 N N3 C4 DOUB
+C N 30 N C4 N4 SING
+C N 31 N C4 C5 SING
+C N 32 N N4 H41 SING
+C N 33 N N4 H42 SING
+C N 34 N C5 C6 DOUB
+C N 35 N C5 H5 SING
+C N 36 N C6 H6 SING
+A N 1 N OP3 P SING
+A N 2 N OP3 HOP3 SING
+A N 3 N P OP1 DOUB
+A N 4 N P OP2 SING
+A N 5 N P "O5'" SING
+A N 6 N OP2 HOP2 SING
+A N 7 N "O5'" "C5'" SING
+A N 8 N "C5'" "C4'" SING
+A N 9 N "C5'" "H5'" SING
+A N 10 N "C5'" "H5''" SING
+A N 11 N "C4'" "O4'" SING
+A N 12 N "C4'" "C3'" SING
+A N 13 N "C4'" "H4'" SING
+A N 14 N "O4'" "C1'" SING
+A N 15 N "C3'" "O3'" SING
+A N 16 N "C3'" "C2'" SING
+A N 17 N "C3'" "H3'" SING
+A N 18 N "O3'" "HO3'" SING
+A N 19 N "C2'" "O2'" SING
+A N 20 N "C2'" "C1'" SING
+A N 21 N "C2'" "H2'" SING
+A N 22 N "O2'" "HO2'" SING
+A N 23 N "C1'" N9 SING
+A N 24 N "C1'" "H1'" SING
+A N 25 Y N9 C8 SING
+A N 26 Y N9 C4 SING
+A N 27 Y C8 N7 DOUB
+A N 28 N C8 H8 SING
+A N 29 Y N7 C5 SING
+A N 30 Y C5 C6 SING
+A N 31 Y C5 C4 DOUB
+A N 32 N C6 N6 SING
+A N 33 Y C6 N1 DOUB
+A N 34 N N6 H61 SING
+A N 35 N N6 H62 SING
+A N 36 Y N1 C2 SING
+A N 37 Y C2 N3 DOUB
+A N 38 N C2 H2 SING
+A N 39 Y N3 C4 SING
+HOH N 1 N O H1 SING
+HOH N 2 N O H2 SING
+#
index b8c12c6..d8ae999 100644 (file)
@@ -31,6 +31,7 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 import jalview.structure.StructureImportSettings;
 import jalview.structure.StructureImportSettings.StructureParser;
 
@@ -44,6 +45,13 @@ import org.testng.annotations.Test;
 public class AnnotatedPDBFileInputTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   AlignmentI al;
 
   String pdbId;
@@ -63,7 +71,7 @@ public class AnnotatedPDBFileInputTest
             Boolean.TRUE.toString());
     FileLoader loader = new FileLoader(false);
     AlignFrame af = loader.LoadFileWaitTillLoaded("examples/1gaq.txt",
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
     al = af.getViewport().getAlignment();
     pdbId = al.getSequenceAt(0).getDatasetSequence().getAllPDBEntries()
             .get(0).getId();
@@ -204,14 +212,14 @@ public class AnnotatedPDBFileInputTest
     String tfile = File.createTempFile("JalviewTest", ".jvp")
             .getAbsolutePath();
     AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
-            inFile, FormatAdapter.FILE);
+            inFile, DataSourceType.FILE);
     assertTrue("Didn't read input file " + inFile, af != null);
     assertTrue("Failed to store as a project.",
-            af.saveAlignment(tfile, "Jalview"));
+            af.saveAlignment(tfile, FileFormat.Jalview));
     af.closeMenuItem_actionPerformed(true);
     af = null;
     af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(tfile,
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
     assertTrue("Failed to import new project", af != null);
     for (SequenceI asq : af.getViewport().getAlignment().getSequences())
     {
index c9b5f4a..5b90e19 100644 (file)
@@ -25,17 +25,26 @@ import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
+import jalview.gui.JvOptionPane;
 import jalview.io.AnnotationFile.ViewDef;
 
 import java.io.File;
 import java.util.Hashtable;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class AnnotationFileIOTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   static String TestFiles[][] = {
       { "Test example annotation import/export", "examples/uniref50.fa",
           "examples/testdata/example_annot_file.jva" },
@@ -69,8 +78,8 @@ public class AnnotationFileIOTest
     {
       FormatAdapter rf = new FormatAdapter();
 
-      AlignmentI al = rf.readFile(ff, AppletFormatAdapter.FILE,
-              new IdentifyFile().identify(ff, AppletFormatAdapter.FILE));
+      AlignmentI al = rf.readFile(ff, DataSourceType.FILE,
+              new IdentifyFile().identify(ff, DataSourceType.FILE));
 
       // make sure dataset is initialised ? not sure about this
       for (int i = 0; i < al.getSequencesArray().length; ++i)
@@ -114,7 +123,7 @@ public class AnnotationFileIOTest
                       + testname
                       + "\nAlignment was not annotated - annotation file not imported.",
               new AnnotationFile().readAnnotationFile(al, cs, af,
-                      FormatAdapter.FILE));
+                      DataSourceType.FILE));
 
       AnnotationFile aff = new AnnotationFile();
       ViewDef v = aff.new ViewDef(null, al.getHiddenSequences(), cs,
@@ -142,7 +151,7 @@ public class AnnotationFileIOTest
                       + testname
                       + "\nregenerated annotation file did not annotate alignment.",
               new AnnotationFile().readAnnotationFile(al_new, anfileout,
-                      FormatAdapter.PASTE));
+                      DataSourceType.PASTE));
 
       // test for consistency in io
       StockholmFileTest.testAlignmentEquivalence(al, al_new, false);
index ddf9a15..24e6cf7 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.io;
 
+import jalview.gui.JvOptionPane;
 import jalview.json.binding.biojs.BioJSReleasePojo;
 import jalview.json.binding.biojs.BioJSRepositoryPojo;
 
@@ -33,11 +34,19 @@ import java.util.TreeMap;
 
 import org.testng.Assert;
 import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class BioJsHTMLOutputTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void getJalviewAlignmentAsJsonString()
   {
@@ -54,7 +63,8 @@ public class BioJsHTMLOutputTest
       {
         e.printStackTrace();
       }
-      bjsTemplate = BioJsHTMLOutput.getBioJsTemplateAsString();
+      bjsTemplate = HTMLOutput.readFileAsString(BioJsHTMLOutput
+              .getCurrentBJSTemplateFile());
       // System.out.println(bjsTemplate);
     } catch (IOException e)
     {
@@ -70,7 +80,7 @@ public class BioJsHTMLOutputTest
   {
     try
     {
-      BioJsHTMLOutput.refreshBioJSVersionsInfo(null);
+      BioJsHTMLOutput.refreshVersionInfo(null);
     } catch (URISyntaxException e)
     {
       AssertJUnit.fail("Expception occured while testing!");
@@ -85,7 +95,7 @@ public class BioJsHTMLOutputTest
     try
     {
       BioJsHTMLOutput
-              .refreshBioJSVersionsInfo(BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
+              .refreshVersionInfo(BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
       versions = BioJsHTMLOutput.getBioJsMSAVersions();
     } catch (URISyntaxException e)
     {
index c55ddd9..ec5855f 100644 (file)
@@ -30,6 +30,7 @@ import jalview.gui.AlignFrame;
 import jalview.gui.CrossRefAction;
 import jalview.gui.Desktop;
 import jalview.gui.Jalview2XML;
+import jalview.gui.JvOptionPane;
 
 import java.io.File;
 import java.io.IOException;
@@ -38,12 +39,21 @@ import java.util.HashMap;
 import java.util.List;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 @Test(singleThreaded = true)
 public class CrossRef2xmlTests extends Jalview2xmlBase
 {
 
+  @Override
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * test store and recovery of all reachable cross refs from all reachable
    * crossrefs for one or more fetched db refs. Currently, this test has a known
@@ -130,7 +140,7 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
           Desktop.instance.closeAll_actionPerformed(null);
           // recover stored project
           af = new FileLoader(false).LoadFileWaitTillLoaded(savedProjects
-                  .get(first).toString(), FormatAdapter.FILE);
+                  .get(first).toString(), DataSourceType.FILE);
           System.out.println("Recovered view for '" + first + "' from '"
                   + savedProjects.get(first).toString() + "'");
           dna = af.getViewport().getAlignment().isNucleotide();
@@ -203,7 +213,7 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
               // recover stored project
               AlignFrame af2 = new FileLoader(false)
                       .LoadFileWaitTillLoaded(savedProjects.get(nextxref)
-                              .toString(), FormatAdapter.FILE);
+                              .toString(), DataSourceType.FILE);
               System.out.println("Recovered view for '" + nextxref
                       + "' from '" + savedProjects.get(nextxref).toString()
                       + "'");
@@ -314,7 +324,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
                     AlignFrame af2 = new FileLoader(false)
                             .LoadFileWaitTillLoaded(
                                     savedProjects.get(nextnextxref)
-                                            .toString(), FormatAdapter.FILE);
+                                            .toString(),
+                                    DataSourceType.FILE);
                     System.out.println("Recovered view for '"
                             + nextnextxref + "' from '"
                             + savedProjects.get(nextnextxref).toString()
index 602ce9f..d6f1e8b 100644 (file)
@@ -34,17 +34,26 @@ import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 
 import java.awt.Color;
 import java.io.File;
 import java.io.IOException;
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class FeaturesFileTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private static String simpleGffFile = "examples/testdata/simpleGff3.gff";
 
   @Test(groups = { "Functional" })
@@ -56,7 +65,7 @@ public class FeaturesFileTest
     Map<String, FeatureColourI> colours = af.getFeatureRenderer()
             .getFeatureColours();
     FeaturesFile featuresFile = new FeaturesFile(
-            "examples/exampleFeatures.txt", FormatAdapter.FILE);
+            "examples/exampleFeatures.txt", DataSourceType.FILE);
     assertTrue("Test " + "Features file test"
             + "\nFailed to parse features file.",
             featuresFile.parse(al.getDataset(), colours, true));
@@ -158,7 +167,7 @@ public class FeaturesFileTest
             + "FER_CAPAA\tuniprot\tMETAL\t44\t45\t4.0\t.\t.\tNote Iron-sulfur; Note 2Fe-2S\n"
             + "FER1_SOLLC\tuniprot\tPfam\t55\t130\t2.0\t.\t.";
     FeaturesFile featuresFile = new FeaturesFile(gffData,
-            FormatAdapter.PASTE);
+            DataSourceType.PASTE);
     assertTrue("Failed to parse features file",
             featuresFile.parse(al.getDataset(), colours, true));
 
@@ -197,8 +206,8 @@ public class FeaturesFileTest
     String ff = f.getPath();
     FormatAdapter rf = new FormatAdapter();
 
-    AlignmentI al = rf.readFile(ff, FormatAdapter.FILE,
-            new IdentifyFile().identify(ff, FormatAdapter.FILE));
+    AlignmentI al = rf.readFile(ff, DataSourceType.FILE,
+            new IdentifyFile().identify(ff, DataSourceType.FILE));
 
     al.setDataset(null); // creates dataset sequences
     assertNotNull("Couldn't read supplied alignment data.", al);
@@ -224,7 +233,7 @@ public class FeaturesFileTest
             + "Note=Iron-sulfur (2Fe-2S);Note=another note;evidence=ECO:0000255|PROSITE-ProRule:PRU00465\n"
             + "FER1_SOLLC\tuniprot\tPfam\t55\t130\t3.0\t.\t.\tID=$23";
     FeaturesFile featuresFile = new FeaturesFile(gffData,
-            FormatAdapter.PASTE);
+            DataSourceType.PASTE);
     assertTrue("Failed to parse features file",
             featuresFile.parse(al.getDataset(), colours, true));
 
@@ -277,7 +286,7 @@ public class FeaturesFileTest
     String featureData = "Iron-sulfur (2Fe-2S)\tFER_CAPAA\t-1\t39\t39\tMETAL\n"
             + "Iron-phosphorus (2Fe-P)\tID_NOT_SPECIFIED\t2\t86\t87\tMETALLIC\n";
     FeaturesFile featuresFile = new FeaturesFile(featureData,
-            FormatAdapter.PASTE);
+            DataSourceType.PASTE);
     assertTrue("Failed to parse features file",
             featuresFile.parse(al.getDataset(), colours, true));
 
@@ -343,7 +352,7 @@ public class FeaturesFileTest
   public void readGff3File() throws IOException
   {
     FeaturesFile gffreader = new FeaturesFile(true, simpleGffFile,
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
     Alignment dataset = new Alignment(gffreader.getSeqsAsArray());
     gffreader.addProperties(dataset);
     checkDatasetfromSimpleGff3(dataset);
@@ -353,8 +362,9 @@ public class FeaturesFileTest
   public void simpleGff3FileClass() throws IOException
   {
     AlignmentI dataset = new Alignment(new SequenceI[] {});
-    FeaturesFile ffile = new FeaturesFile(simpleGffFile, FormatAdapter.FILE);
-
+    FeaturesFile ffile = new FeaturesFile(simpleGffFile,
+            DataSourceType.FILE);
+  
     boolean parseResult = ffile.parse(dataset, null, false, false);
     assertTrue("return result should be true", parseResult);
     checkDatasetfromSimpleGff3(dataset);
@@ -364,7 +374,7 @@ public class FeaturesFileTest
   public void simpleGff3FileLoader() throws IOException
   {
     AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
-            simpleGffFile, FormatAdapter.FILE);
+            simpleGffFile, DataSourceType.FILE);
     assertTrue(
             "Didn't read the alignment into an alignframe from Gff3 File",
             af != null);
@@ -375,8 +385,9 @@ public class FeaturesFileTest
   public void simpleGff3RelaxedIdMatching() throws IOException
   {
     AlignmentI dataset = new Alignment(new SequenceI[] {});
-    FeaturesFile ffile = new FeaturesFile(simpleGffFile, FormatAdapter.FILE);
-
+    FeaturesFile ffile = new FeaturesFile(simpleGffFile,
+            DataSourceType.FILE);
+  
     boolean parseResult = ffile.parse(dataset, null, false, true);
     assertTrue("return result (relaxedID matching) should be true",
             parseResult);
@@ -400,7 +411,7 @@ public class FeaturesFileTest
             + "<html>Pfam domain<a href=\"http://pfam.xfam.org/family/PF00111\">Pfam_3_4</a></html>\tFER_CAPAA\t-1\t20\t20\tPfam\n"
             + "ENDGROUP\tuniprot\n";
     FeaturesFile featuresFile = new FeaturesFile(features,
-            FormatAdapter.PASTE);
+            DataSourceType.PASTE);
     featuresFile.parse(al.getDataset(), colours, false);
 
     /*
index 2eb3703..f6480a6 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.io;
 
+import jalview.gui.JvOptionPane;
+
 import java.io.File;
 import java.io.IOException;
 
@@ -35,6 +37,13 @@ import org.testng.annotations.Test;
 public class FileIOTester
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * @throws java.lang.Exception
    */
@@ -65,13 +74,14 @@ public class FileIOTester
   final static File STARS_FA_FILE2 = new File(
           "test/jalview/io/test_fasta_stars2.fa");
 
-  private void assertValidFormat(String fmt, String src, FileParse fp)
+  private void assertValidFormat(FileFormatI fmt, String src, FileParse fp)
+          throws FileFormatException
   {
     AssertJUnit.assertTrue("Couldn't resolve " + src + " as a valid file",
             fp.isValid());
-    String type = new IdentifyFile().identify(fp);
-    AssertJUnit.assertTrue("Data from '" + src + "' Expected to be '" + fmt
-            + "' identified as '" + type + "'", type.equalsIgnoreCase(fmt));
+    FileFormatI type = new IdentifyFile().identify(fp);
+    AssertJUnit.assertSame("Data from '" + src + "' Expected to be '" + fmt
+            + "' identified as '" + type + "'", type, fmt);
   }
 
   @Test(groups = { "Functional" })
@@ -79,8 +89,8 @@ public class FileIOTester
   {
     String uri;
     FileParse fp = new FileParse(uri = STARS_FA_FILE1.getAbsoluteFile()
-            .toString(), AppletFormatAdapter.FILE);
-    assertValidFormat("FASTA", uri, fp);
+            .toString(), DataSourceType.FILE);
+    assertValidFormat(FileFormat.Fasta, uri, fp);
   }
 
   @Test(groups = { "Functional" })
@@ -88,8 +98,8 @@ public class FileIOTester
   {
     String uri;
     FileParse fp = new FileParse(uri = STARS_FA_FILE2.getAbsoluteFile()
-            .toString(), AppletFormatAdapter.FILE);
-    assertValidFormat("FASTA", uri, fp);
+            .toString(), DataSourceType.FILE);
+    assertValidFormat(FileFormat.Fasta, uri, fp);
   }
 
   @Test(groups = { "Functional" })
@@ -97,8 +107,8 @@ public class FileIOTester
   {
     String uri;
     FileParse fp = new FileParse(uri = ALIGN_FILE.getAbsoluteFile().toURI()
-            .toString(), AppletFormatAdapter.URL);
-    assertValidFormat("FASTA", uri, fp);
+            .toString(), DataSourceType.URL);
+    assertValidFormat(FileFormat.Fasta, uri, fp);
   }
 
   @Test(groups = { "Functional" })
@@ -106,8 +116,8 @@ public class FileIOTester
   {
     String filepath;
     FileParse fp = new FileParse(filepath = ALIGN_FILE.getAbsoluteFile()
-            .toString(), AppletFormatAdapter.FILE);
-    assertValidFormat("FASTA", filepath, fp);
+            .toString(), DataSourceType.FILE);
+    assertValidFormat(FileFormat.Fasta, filepath, fp);
   }
 
   @Test(groups = { "Functional" })
@@ -115,8 +125,8 @@ public class FileIOTester
   {
     String uri;
     FileParse fp = new FileParse(uri = NOTGZALIGN_FILE.getAbsoluteFile()
-            .toURI().toString(), AppletFormatAdapter.URL);
-    assertValidFormat("FASTA", uri, fp);
+            .toURI().toString(), DataSourceType.URL);
+    assertValidFormat(FileFormat.Fasta, uri, fp);
   }
 
   @Test(groups = { "Functional" })
@@ -124,7 +134,7 @@ public class FileIOTester
   {
     String filepath;
     FileParse fp = new FileParse(filepath = NOTGZALIGN_FILE
-            .getAbsoluteFile().toString(), AppletFormatAdapter.FILE);
-    assertValidFormat("FASTA", filepath, fp);
+            .getAbsoluteFile().toString(), DataSourceType.FILE);
+    assertValidFormat(FileFormat.Fasta, filepath, fp);
   }
 }
index d4242a7..7aa5769 100644 (file)
@@ -26,30 +26,38 @@ import static org.testng.AssertJUnit.fail;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 public class FormatAdapterTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test saving and re-reading in a specified format
    * 
    * @throws IOException
    */
   @Test(groups = { "Functional" }, dataProvider = "formats")
-  public void testRoundTrip(String format) throws IOException
+  public void testRoundTrip(FileFormatI format) throws IOException
   {
     try
     {
       AlignmentI al = new FormatAdapter().readFile("examples/uniref50.fa",
-              FormatAdapter.FILE, "FASTA");
+              DataSourceType.FILE, FileFormat.Fasta);
 
       /*
        * 'gap' is the gap character used in the alignment data file here,
@@ -63,7 +71,7 @@ public class FormatAdapterTest
               false);
 
       AlignmentI reloaded = new FormatAdapter().readFile(formatted,
-              FormatAdapter.PASTE, format);
+              DataSourceType.PASTE, format);
       List<SequenceI> reread = reloaded.getSequences();
       assertEquals("Wrong number of reloaded sequences", seqs.length,
               reread.size());
@@ -101,9 +109,9 @@ public class FormatAdapterTest
    * @return
    */
   String adjustForGapTreatment(String sequenceString, char gap,
-          String format)
+          FileFormatI format)
   {
-    if ("MSF".equals(format))
+    if (FileFormat.MSF.equals(format))
     {
       /*
        * MSF forces gap character to '.', so change it back
@@ -116,27 +124,26 @@ public class FormatAdapterTest
 
   /**
    * Data provider that serves alignment formats that are both readable and
-   * writable
+   * (text) writable
    * 
    * @return
    */
   @DataProvider(name = "formats")
   static Object[][] getFormats()
   {
-    List<String> both = new ArrayList<String>();
-    String[] readable = FormatAdapter.READABLE_FORMATS;
-    List<String> writeable = Arrays.asList(FormatAdapter.WRITEABLE_FORMATS);
-    for (String r : readable)
+    List<FileFormatI> both = new ArrayList<FileFormatI>();
+    for (FileFormat format : FileFormat.values())
     {
-      if (writeable.contains(r))
+      if (format.isReadable() && format.isWritable()
+              && format.isTextFormat())
       {
-        both.add(r);
+        both.add(format);
       }
     }
 
     Object[][] formats = new Object[both.size()][];
     int i = 0;
-    for (String format : both)
+    for (FileFormatI format : both)
     {
       formats[i] = new Object[] { format };
       i++;
@@ -152,6 +159,6 @@ public class FormatAdapterTest
   @Test(groups = { "Functional" }, enabled = false)
   public void testOneFormatRoundTrip() throws IOException
   {
-    testRoundTrip("JSON");
+    testRoundTrip(FileFormat.Json);
   }
 }
index 6c13e26..d7eae8b 100644 (file)
  */
 package jalview.io;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class HtmlFileTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" }, enabled = false)
   public void test()
   {
index c00cf06..3d800d8 100644 (file)
  */
 package jalview.io;
 
-import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 public class IdentifyFileTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" }, dataProvider = "identifyFiles")
-  public void testIdentify(String data, String expectedFileType)
+  public void testIdentify(String data, FileFormatI expectedFileType)
+          throws FileFormatException
   {
-    String protocol = AppletFormatAdapter.FILE;
+    DataSourceType protocol = DataSourceType.FILE;
     IdentifyFile ider = new IdentifyFile();
-    String actualFiletype = ider.identify(data, protocol);
-    Assert.assertEquals(actualFiletype, expectedFileType,
+    FileFormatI actualFiletype = ider.identify(data, protocol);
+    Assert.assertSame(actualFiletype, expectedFileType,
             "File identification Failed!");
   }
 
   /**
    * Additional tests for Jalview features file
+   * 
+   * @throws FileFormatException
    */
   @Test(groups = "Functional")
-  public void testIdentify_featureFile()
+  public void testIdentify_featureFile() throws FileFormatException
   {
     IdentifyFile ider = new IdentifyFile();
 
@@ -54,49 +67,49 @@ public class IdentifyFileTest
      */
     String data = "Iron-sulfur (2Fe-2S)\tFER_CAPAA\t-1\t39\t39\tMETAL\n"
             + "Iron-phosphorus (2Fe-P)\tID_NOT_SPECIFIED\t2\t86\t87\tMETALLIC\n";
-    assertEquals(IdentifyFile.FeaturesFile,
-            ider.identify(data, AppletFormatAdapter.PASTE));
+    assertSame(FileFormat.Features,
+            ider.identify(data, DataSourceType.PASTE));
 
     /*
      * Jalview feature colour followed by GFF format feature data
      */
     data = "METAL\tcc9900\n" + "GFF\n"
             + "FER_CAPAA\tuniprot\tMETAL\t44\t45\t4.0\t.\t.\n";
-    assertEquals(IdentifyFile.FeaturesFile,
-            ider.identify(data, AppletFormatAdapter.PASTE));
+    assertSame(FileFormat.Features,
+            ider.identify(data, DataSourceType.PASTE));
 
     /*
      * Feature with '<' in the name (JAL-2098)
      */
     data = "kD < 3\tred\n" + "Low kD\tFER_CAPAA\t-1\t39\t39\tkD < 3\n";
-    assertEquals(IdentifyFile.FeaturesFile,
-            ider.identify(data, AppletFormatAdapter.PASTE));
+    assertSame(FileFormat.Features,
+            ider.identify(data, DataSourceType.PASTE));
   }
 
   @DataProvider(name = "identifyFiles")
   public Object[][] IdentifyFileDP()
   {
     return new Object[][] {
-        { "examples/example.json", "JSON" },
-        { "examples/plantfdx.fa", "FASTA" },
-        { "examples/dna_interleaved.phy", "PHYLIP" },
-        { "examples/2GIS.pdb", "PDB" },
-        { "examples/rf00031_folded.stk", "STH" },
-        { "examples/testdata/test.rnaml", "RNAML" },
-        { "examples/testdata/test.aln", "CLUSTAL" },
-        { "examples/testdata/test.pfam", "PFAM" },
-        { "examples/testdata/test.msf", "MSF" },
-        { "examples/testdata/test.pir", "PIR" },
-        { "examples/testdata/test.html", "HTML" },
-        { "examples/testdata/test.pileup", "PileUp" },
-        { "examples/testdata/test.blc", "BLC" },
-        { "examples/exampleFeatures.txt", IdentifyFile.FeaturesFile },
-        { "examples/testdata/simpleGff3.gff", IdentifyFile.FeaturesFile },
-        { "examples/testdata/test.jvp", "Jalview" },
-        { "examples/testdata/test.cif", "mmCIF" },
+        { "examples/example.json", FileFormat.Json },
+        { "examples/plantfdx.fa", FileFormat.Fasta },
+        { "examples/dna_interleaved.phy", FileFormat.Phylip },
+        { "examples/2GIS.pdb", FileFormat.PDB },
+        { "examples/rf00031_folded.stk", FileFormat.Stockholm },
+        { "examples/testdata/test.rnaml", FileFormat.Rnaml },
+        { "examples/testdata/test.aln", FileFormat.Clustal },
+        { "examples/testdata/test.pfam", FileFormat.Pfam },
+        { "examples/testdata/test.msf", FileFormat.MSF },
+        { "examples/testdata/test.pir", FileFormat.PIR },
+        { "examples/testdata/test.html", FileFormat.Html },
+        { "examples/testdata/test.pileup", FileFormat.Pileup },
+        { "examples/testdata/test.blc", FileFormat.BLC },
+        { "examples/exampleFeatures.txt", FileFormat.Features },
+        { "examples/testdata/simpleGff3.gff", FileFormat.Features },
+        { "examples/testdata/test.jvp", FileFormat.Jalview },
+        { "examples/testdata/test.cif", FileFormat.MMCif },
         {
             "examples/testdata/cullpdb_pc25_res3.0_R0.3_d150729_chains9361.fasta.15316",
-            "FASTA" },
+            FileFormat.Fasta },
 
     // { "examples/testdata/test.amsa", "AMSA" },
     // { "examples/test.jnet", "JnetFile" },
index f75f433..a705a78 100644 (file)
@@ -33,6 +33,7 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 import jalview.json.binding.biojson.v1.ColourSchemeMapper;
 import jalview.schemes.ColourSchemeI;
 
@@ -44,6 +45,7 @@ import java.util.List;
 import org.testng.Assert;
 import org.testng.AssertJUnit;
 import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
@@ -51,6 +53,13 @@ import org.testng.annotations.Test;
 public class JSONFileTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private int TEST_SEQ_HEIGHT = 0;
 
   private int TEST_GRP_HEIGHT = 0;
@@ -227,7 +236,7 @@ public class JSONFileTest
     try
     {
       alignment = (Alignment) formatAdapter.readFile(TEST_JSON_FILE,
-              AppletFormatAdapter.FILE, JSONFile.FILE_DESC);
+              DataSourceType.FILE, FileFormat.Json);
       jf = (JSONFile) formatAdapter.getAlignFile();
 
       AlignFrame af = new AlignFrame(alignment, jf.getHiddenSequences(),
@@ -241,12 +250,12 @@ public class JSONFileTest
       af.getViewport().setFeaturesDisplayed(jf.getDisplayedFeatures());
 
       formatAdapter = new AppletFormatAdapter(af.alignPanel, exportSettings);
-      String jsonOutput = formatAdapter.formatSequences(JSONFile.FILE_DESC,
+      String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
               af.alignPanel.getAlignment(), false);
 
       formatAdapter = new AppletFormatAdapter();
       testAlignment = formatAdapter.readFile(jsonOutput,
-              AppletFormatAdapter.PASTE, JSONFile.FILE_DESC);
+              DataSourceType.PASTE, FileFormat.Json);
       testJsonFile = (JSONFile) formatAdapter.getAlignFile();
       // System.out.println(jsonOutput);
     } catch (IOException e)
@@ -305,7 +314,8 @@ public class JSONFileTest
     Assert.assertNotNull(cs.getHiddenColumns());
     List<int[]> hiddenCols = cs.getHiddenColumns();
     Assert.assertEquals(hiddenCols.size(), TEST_CS_HEIGHT);
-    Assert.assertEquals(hiddenCols, expectedColSel.getHiddenColumns(),
+    Assert.assertEquals(hiddenCols.get(0), expectedColSel
+            .getHiddenColumns().get(0),
             "Mismatched hidden columns!");
   }
 
@@ -314,7 +324,8 @@ public class JSONFileTest
   {
     Assert.assertNotNull(testJsonFile.getHiddenSequences(),
             "Hidden sequence Expected but found Null");
-    Assert.assertEquals(jf.getHiddenSequences().length, 1, "Hidden sequece");
+    Assert.assertEquals(jf.getHiddenSequences().length, 1,
+            "Hidden sequence");
   }
 
   @Test(groups = { "Functional" })
index 7f38dec..15e18e3 100644 (file)
@@ -25,6 +25,7 @@ import jalview.bin.Jalview;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.SequenceI;
 import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
 
 import java.util.Date;
 
@@ -35,6 +36,13 @@ import org.testng.annotations.BeforeTest;
 public class Jalview2xmlBase
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * @throws java.lang.Exception
    */
index 3d53234..de12086 100644 (file)
@@ -41,6 +41,7 @@ import jalview.gui.AlignFrame;
 import jalview.gui.AlignmentPanel;
 import jalview.gui.Desktop;
 import jalview.gui.Jalview2XML;
+import jalview.gui.JvOptionPane;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
@@ -56,21 +57,29 @@ import java.util.Map;
 
 import org.testng.Assert;
 import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 @Test(singleThreaded = true)
 public class Jalview2xmlTests extends Jalview2xmlBase
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testRNAStructureRecovery() throws Exception
   {
     String inFile = "examples/RF00031_folded.stk";
     String tfile = File.createTempFile("JalviewTest", ".jvp")
             .getAbsolutePath();
-    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
-            FormatAdapter.FILE);
-    assertNotNull("Didn't read input file " + inFile, af);
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            inFile, DataSourceType.FILE);
+    assertTrue("Didn't read input file " + inFile, af != null);
     int olddsann = countDsAnn(af.getViewport());
     assertTrue("Didn't find any dataset annotations", olddsann > 0);
     af.rnahelicesColour_actionPerformed(null);
@@ -78,11 +87,11 @@ public class Jalview2xmlTests extends Jalview2xmlBase
             "Couldn't apply RNA helices colourscheme",
             af.getViewport().getGlobalColourScheme() instanceof jalview.schemes.RNAHelicesColour);
     assertTrue("Failed to store as a project.",
-            af.saveAlignment(tfile, "Jalview"));
+            af.saveAlignment(tfile, FileFormat.Jalview));
     af.closeMenuItem_actionPerformed(true);
     af = null;
-    af = new FileLoader().LoadFileWaitTillLoaded(tfile, FormatAdapter.FILE);
-    assertNotNull("Failed to import new project", af);
+    af = new FileLoader().LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
+    assertTrue("Failed to import new project", af != null);
     int newdsann = countDsAnn(af.getViewport());
     assertTrue(
             "Differing numbers of dataset sequence annotation\nOriginally "
@@ -102,22 +111,23 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     String inFile = "examples/uniref50.fa", inAnnot = "examples/uniref50.score_ascii";
     String tfile = File.createTempFile("JalviewTest", ".jvp")
             .getAbsolutePath();
-    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
-            FormatAdapter.FILE);
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            inFile, DataSourceType.FILE);
     assertNotNull("Didn't read input file " + inFile, af);
-    af.loadJalviewDataFile(inAnnot, FormatAdapter.FILE, null, null);
+    af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
     assertSame("Didn't set T-coffee colourscheme", af.getViewport()
             .getGlobalColourScheme().getClass(), TCoffeeColourScheme.class);
     assertNotNull("Recognise T-Coffee score from string",
-            jalview.schemes.ColourSchemeProperty.getColour(af.getViewport()
+            ColourSchemeProperty.getColour(af.getViewport()
                     .getAlignment(), ColourSchemeProperty.getColourName(af
                     .getViewport().getGlobalColourScheme())));
 
     assertTrue("Failed to store as a project.",
-            af.saveAlignment(tfile, "Jalview"));
+            af.saveAlignment(tfile, FileFormat.Jalview));
     af.closeMenuItem_actionPerformed(true);
     af = null;
-    af = new FileLoader().LoadFileWaitTillLoaded(tfile, FormatAdapter.FILE);
+    af = new FileLoader().LoadFileWaitTillLoaded(tfile,
+            DataSourceType.FILE);
     assertNotNull("Failed to import new project", af);
     assertSame("Didn't set T-coffee colourscheme for imported project.", af
             .getViewport().getGlobalColourScheme().getClass(),
@@ -132,10 +142,9 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     String inFile = "examples/uniref50.fa", inAnnot = "examples/testdata/uniref50_iupred.jva";
     String tfile = File.createTempFile("JalviewTest", ".jvp")
             .getAbsolutePath();
-    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
-            FormatAdapter.FILE);
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile, DataSourceType.FILE);
     assertNotNull("Didn't read input file " + inFile, af);
-    af.loadJalviewDataFile(inAnnot, FormatAdapter.FILE, null, null);
+    af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
     AlignmentAnnotation[] aa = af.getViewport().getAlignment()
             .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
     assertTrue(
@@ -157,11 +166,11 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
     af.alignPanel.alignmentChanged();
     assertTrue("Failed to store as a project.",
-            af.saveAlignment(tfile, "Jalview"));
+            af.saveAlignment(tfile, FileFormat.Jalview));
     af.closeMenuItem_actionPerformed(true);
     af = null;
-    af = new FileLoader().LoadFileWaitTillLoaded(tfile, FormatAdapter.FILE);
-    assertNotNull("Failed to import new project", af);
+    af = new FileLoader().LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
+    assertTrue("Failed to import new project", af != null);
 
     // check for group and alignment colourschemes
 
@@ -217,7 +226,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop
             .getAlignFrames().length;
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
-            "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
+            "examples/exampleFile_2_7.jar", DataSourceType.FILE);
     assertNotNull("Didn't read in the example file correctly.", af);
     assertTrue("Didn't gather the views in the example file.",
             Desktop.getAlignFrames().length == 1 + origCount);
@@ -230,7 +239,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     StructureImportSettings.setProcessSecondaryStructure(true);
     StructureImportSettings.setVisibleChainAnnotation(true);
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
-            "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
+            "examples/exampleFile_2_7.jar", DataSourceType.FILE);
     assertNotNull("Didn't read in the example file correctly.", af);
     AlignmentViewPanel sps = null;
     for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
@@ -291,7 +300,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   public void testCopyViewSettings() throws Exception
   {
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
-            "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
+            "examples/exampleFile_2_7.jar", DataSourceType.FILE);
     assertNotNull("Didn't read in the example file correctly.", af);
     AlignmentViewPanel sps = null, groups = null;
     for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
@@ -331,7 +340,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     Desktop.instance.closeAll_actionPerformed(null);
 
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
-            "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
+            "examples/exampleFile_2_7.jar", DataSourceType.FILE);
     Assert.assertEquals(Desktop.getAlignFrames().length, 1);
     String afid = af.getViewport().getSequenceSetId();
 
@@ -362,8 +371,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     {
       Assert.assertEquals(Desktop.getAlignFrames().length, 0);
     }
-    af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
-            FormatAdapter.FILE);
+    af = new FileLoader().LoadFileWaitTillLoaded(
+            tfile.getAbsolutePath(), DataSourceType.FILE);
     Assert.assertNotNull(af);
     Assert.assertEquals(
             Desktop.getAlignFrames().length,
@@ -384,7 +393,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   {
     Desktop.instance.closeAll_actionPerformed(null);
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
-            "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
+            "examples/exampleFile_2_7.jar", DataSourceType.FILE);
     assertNotNull("Didn't read in the example file correctly.", af);
     String afid = af.getViewport().getSequenceSetId();
 
@@ -427,8 +436,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
       Assert.assertEquals(Desktop.getAlignFrames().length, 0);
     }
 
-    af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
-            FormatAdapter.FILE);
+    af = new FileLoader().LoadFileWaitTillLoaded(
+            tfile.getAbsolutePath(), DataSourceType.FILE);
     afid = af.getViewport().getSequenceSetId();
 
     for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
@@ -517,7 +526,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   {
     Desktop.instance.closeAll_actionPerformed(null);
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
-            "examples/uniref50.fa", FormatAdapter.FILE);
+            "examples/uniref50.fa", DataSourceType.FILE);
     assertNotNull("Didn't read in the example file correctly.", af);
     String afid = af.getViewport().getSequenceSetId();
     // make a second view of the alignment
@@ -595,9 +604,9 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     {
       Assert.assertEquals(Desktop.getAlignFrames().length, 0);
     }
-
-    af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
-            FormatAdapter.FILE);
+  
+    af = new FileLoader().LoadFileWaitTillLoaded(
+            tfile.getAbsolutePath(), DataSourceType.FILE);
     afid = af.getViewport().getSequenceSetId();
 
     for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
@@ -638,7 +647,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     Desktop.instance.closeAll_actionPerformed(null);
     String exampleFile = "examples/3W5V.pdb";
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
     assertNotNull("Didn't read in the example file correctly.", af);
     String afid = af.getViewport().getSequenceSetId();
 
@@ -687,7 +696,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     }
 
     AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
-            tfile.getAbsolutePath(), FormatAdapter.FILE);
+            tfile.getAbsolutePath(), DataSourceType.FILE);
     String rfid = restoredFrame.getViewport().getSequenceSetId();
     AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
     AlignmentViewPanel rap = rAlignPanels[0];
index 164c259..06d177d 100644 (file)
@@ -24,6 +24,7 @@ import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.datamodel.SequenceGroup;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -39,6 +40,13 @@ import org.testng.annotations.Test;
 public class JalviewExportPropertiesTests
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * @throws java.lang.Exception
    */
@@ -66,7 +74,7 @@ public class JalviewExportPropertiesTests
     assertTrue("Couldn't set gap character to '.'",
             ".".equals("" + jalview.bin.Cache.getProperty("GAP_SYMBOL")));
     AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
-            "examples/uniref50.fa", FormatAdapter.FILE);
+            "examples/uniref50.fa", DataSourceType.FILE);
     assertTrue("Didn't read in the example file correctly.", af != null);
     assertTrue("Didn't set the gap character correctly", af.getViewport()
             .getAlignment().getSequenceAt(0).getCharAt(5) == '.');
@@ -78,7 +86,7 @@ public class JalviewExportPropertiesTests
     sg.setEndRes(7);
     af.getViewport().setSelectionGroup(sg);
     String fseqs = new FormatAdapter(af.alignPanel).formatSequences(
-            "FASTA", af.alignPanel, true);
+            FileFormat.Fasta, af.alignPanel, true);
     assertTrue("Couldn't find '.' in the exported region\n" + fseqs,
             fseqs.indexOf(".") > -1);
   }
diff --git a/test/jalview/io/JalviewFileViewTest.java b/test/jalview/io/JalviewFileViewTest.java
new file mode 100644 (file)
index 0000000..d867e5e
--- /dev/null
@@ -0,0 +1,107 @@
+package jalview.io;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+
+import java.io.File;
+
+import javax.swing.ImageIcon;
+
+import org.testng.annotations.Test;
+
+public class JalviewFileViewTest
+{
+  @Test
+  public void testGetImageIcon()
+  {
+    JalviewFileView jfv = new JalviewFileView();
+    ImageIcon icon1 = jfv.getImageIcon("/images/file.png");
+    ImageIcon icon2 = jfv.getImageIcon("/images/file.png");
+    ImageIcon icon3 = jfv.getImageIcon("/images/dna.png");
+    ImageIcon icon4 = jfv.getImageIcon("/images/dna.png");
+
+    /*
+     * verify a single image object is served per file path
+     */
+    assertNotNull(icon1);
+    assertSame(icon1, icon2);
+    assertNotNull(icon3);
+    assertSame(icon3, icon4);
+    assertNotSame(icon1, icon3);
+
+    assertNull(jfv.getImageIcon("/images/nosuchfile.png"));
+    assertNull(jfv.getImageIcon("images/file.png"));
+  }
+
+  @Test
+  public void testGetExtension()
+  {
+    assertEquals(JalviewFileView.getExtension(new File("text.txt")), "txt");
+    assertEquals(JalviewFileView.getExtension(new File(
+            "/a/longer/file/path/text.png.TXT")), "txt");
+    assertNull(JalviewFileView.getExtension(new File(
+            "/a/longer/file/path/text.")));
+    assertNull(JalviewFileView.getExtension(new File(
+            "/a/longer/file/path/text")));
+  }
+
+  @Test
+  public void testGetTypeDescription()
+  {
+    JalviewFileView jfw = new JalviewFileView();
+    assertEquals(jfw.getTypeDescription(new File("uniref50.fa")),
+            "Fasta file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.fasta")),
+            "Fasta file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.MFA")),
+            "Fasta file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.fastQ")),
+            "Fasta file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.pfam")),
+            "PFAM file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.stk")),
+            "Stockholm file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.sto")),
+            "Stockholm file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.pir")),
+            "PIR file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.blc")),
+            "BLC file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.amsa")),
+            "AMSA file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.html")),
+            "HTML file");
+    assertNull(jfw.getTypeDescription(new File("uniref50.htm")));
+    assertEquals(jfw.getTypeDescription(new File("uniref50.xml")),
+            "RNAML file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.rnaml")),
+            "RNAML file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.json")),
+            "JSON file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.pileup")),
+            "PileUp file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.msf")),
+            "MSF file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.aln")),
+            "Clustal file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.phy")),
+            "PHYLIP file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.gff2")),
+            "GFF or Jalview features file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.gff3")),
+            "GFF or Jalview features file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.pdb")),
+            "PDB file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.ent")),
+            "PDB file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.cif")),
+            "mmCIF file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.jvp")),
+            "Jalview file");
+    assertEquals(jfw.getTypeDescription(new File("uniref50.jar")),
+            "Jalview file (old)");
+  }
+}
index 4de36f2..d198f0f 100644 (file)
@@ -26,6 +26,7 @@ import jalview.analysis.NJTree;
 import jalview.analysis.SequenceIdMatcher;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.SequenceNode;
+import jalview.gui.JvOptionPane;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -46,6 +47,13 @@ import org.testng.annotations.Test;
 public class NewickFileTests
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Factory
   public static Object[] factoryData()
   {
@@ -93,7 +101,7 @@ public class NewickFileTests
     {
       stage = "Parsing testTree " + treename;
       System.out.println(treename + "\n" + testTree);
-      NewickFile nf = new NewickFile(testTree, FormatAdapter.PASTE);
+      NewickFile nf = new NewickFile(testTree, DataSourceType.PASTE);
       nf.parse();
       AssertJUnit.assertTrue(
               stage + "Invalid Tree '" + nf.getWarningMessage() + "'",
@@ -106,7 +114,7 @@ public class NewickFileTests
       AssertJUnit.assertTrue(stage + "Empty string generated",
               gentree != null && gentree.trim().length() > 0);
       stage = "Parsing regenerated testTree " + treename;
-      NewickFile nf_regen = new NewickFile(gentree, FormatAdapter.PASTE);
+      NewickFile nf_regen = new NewickFile(gentree, DataSourceType.PASTE);
       nf_regen.parse();
       AssertJUnit.assertTrue(
               stage + "Newick file is invalid ('"
index 0eaf94b..52a13f6 100644 (file)
 package jalview.io;
 
 import jalview.datamodel.AlignmentI;
+import jalview.gui.JvOptionPane;
 
 import java.io.IOException;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class PfamFormatInputTest
 {
-  @Test
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
   public void testPfamFormatNoLimits() throws IOException
   {
-    AlignmentI al = new jalview.io.AppletFormatAdapter().readFile("ASEQ"
-            + '\t' + "...--FFAFAFF--", AppletFormatAdapter.PASTE, "PFAM");
+    AlignmentI al = new AppletFormatAdapter().readFile("ASEQ"
+            + '\t' + "...--FFAFAFF--", DataSourceType.PASTE,
+            FileFormat.Pfam);
     Assert.assertEquals(1, al.getHeight(), "Wrong number of sequences");
     Assert.assertTrue(al.hasValidSequence(),
             "Didn't extract limits from PFAM ID");
   }
 
-  @Test
+  @Test(groups = "Functional")
   public void testPfamFormatValidLimits() throws IOException
   {
-    AlignmentI al = new jalview.io.AppletFormatAdapter().readFile(
-            "ASEQ/15-25" + '\t' + "...--FFAFAFF--",
-            AppletFormatAdapter.PASTE, "PFAM");
+    AlignmentI al = new AppletFormatAdapter().readFile("ASEQ/15-25" + '\t'
+            + "...--FFAFAFF--", DataSourceType.PASTE, FileFormat.Pfam);
     Assert.assertEquals(1, al.getHeight(), "Wrong number of sequences");
     Assert.assertTrue(al.hasValidSequence(),
             "Didn't extract limits from PFAM ID");
index fa57c3d..f99c67a 100644 (file)
@@ -25,11 +25,13 @@ import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 /**
@@ -45,6 +47,13 @@ import org.testng.annotations.Test;
 public class PhylipFileTests
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   // interleaved file from
   // http://www.molecularevolution.org/molevolfiles/fileformats/dna.phy.dat
   // sequential file is the interleave file converted into sequential format
@@ -126,8 +135,8 @@ public class PhylipFileTests
   private void testDataExtraction(String file) throws IOException
   {
     AppletFormatAdapter rf = new AppletFormatAdapter();
-    AlignmentI al = rf.readFile(file, AppletFormatAdapter.FILE,
-            PhylipFile.FILE_DESC);
+    AlignmentI al = rf.readFile(file, DataSourceType.FILE,
+            FileFormat.Phylip);
     assertNotNull("Couldn't read supplied alignment data.", al);
 
     Map<String, String> data = PhylipFileTests.getTestData();
@@ -171,14 +180,14 @@ public class PhylipFileTests
   public void testIO(String file) throws IOException
   {
     AppletFormatAdapter rf = new AppletFormatAdapter();
-    AlignmentI al = rf.readFile(file, AppletFormatAdapter.FILE,
-            PhylipFile.FILE_DESC);
+    AlignmentI al = rf.readFile(file, DataSourceType.FILE,
+            FileFormat.Phylip);
     assertNotNull("Couldn't read supplied alignment data.", al);
 
-    String outputfile = rf.formatSequences(PhylipFile.FILE_DESC, al, true);
+    String outputfile = rf.formatSequences(FileFormat.Phylip, al, true);
 
     AlignmentI al_input = new AppletFormatAdapter().readFile(outputfile,
-            AppletFormatAdapter.PASTE, PhylipFile.FILE_DESC);
+            DataSourceType.PASTE, FileFormat.Phylip);
     assertNotNull("Couldn't parse reimported alignment data.", al_input);
 
     StockholmFileTest.testAlignmentEquivalence(al, al_input, false);
index c084792..d16fb5f 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.io;
 
+import jalview.gui.JvOptionPane;
+
 import java.io.File;
 
 import org.testng.annotations.AfterClass;
@@ -30,6 +32,13 @@ public class RNAMLfileTest
 {
 
   @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @BeforeClass(alwaysRun = true)
   public static void setUpBeforeClass() throws Exception
   {
   }
@@ -43,7 +52,8 @@ public class RNAMLfileTest
   public void testRnamlToStockholmIO()
   {
     StockholmFileTest.testFileIOwithFormat(new File(
-            "examples/testdata/rna-alignment.xml"), "STH", -1, -1);
+            "examples/testdata/rna-alignment.xml"), FileFormat.Stockholm,
+            -1, -1);
 
   }
 
index a96a2a8..2895874 100644 (file)
@@ -23,19 +23,29 @@ package jalview.io;
 import static org.testng.AssertJUnit.assertEquals;
 
 import jalview.datamodel.SequenceFeature;
+import jalview.gui.JvOptionPane;
 
 import java.util.Hashtable;
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class SequenceAnnotationReportTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testAppendFeature_disulfideBond()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     sb.append("123456");
     SequenceFeature sf = new SequenceFeature("disulfide bond", "desc", 1,
             3, 1.2f, "group");
@@ -60,7 +70,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_status()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
             Float.NaN, "group");
     sf.setStatus("Confirmed");
@@ -73,7 +83,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_withScore()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3, 1.3f,
             "group");
 
@@ -106,7 +116,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_noScore()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
             Float.NaN, "group");
 
@@ -118,7 +128,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_clinicalSignificance()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
             Float.NaN, "group");
     sf.setValue("clinical_significance", "Benign");
@@ -131,7 +141,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_withScoreStatusClinicalSignificance()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3, 1.3f,
             "group");
     sf.setStatus("Confirmed");
@@ -148,7 +158,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_DescEqualsType()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "METAL", 1, 3,
             Float.NaN, "group");
 
@@ -167,7 +177,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_stripHtml()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL",
             "<html><body>hello<em>world</em></body></html>", 1, 3,
             Float.NaN, "group");
index 035f484..4028913 100644 (file)
@@ -30,32 +30,41 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.io.File;
 import java.util.BitSet;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class StockholmFileTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   static String PfamFile = "examples/PF00111_seed.stk",
           RfamFile = "examples/RF00031_folded.stk";
 
   @Test(groups = { "Functional" })
   public void pfamFileIO() throws Exception
   {
-    testFileIOwithFormat(new File(PfamFile), "STH", -1, 0);
+    testFileIOwithFormat(new File(PfamFile), FileFormat.Stockholm, -1, 0);
   }
 
   @Test(groups = { "Functional" })
   public void pfamFileDataExtraction() throws Exception
   {
     AppletFormatAdapter af = new AppletFormatAdapter();
-    AlignmentI al = af.readFile(PfamFile, af.FILE,
-            new IdentifyFile().identify(PfamFile, af.FILE));
+    AlignmentI al = af.readFile(PfamFile, DataSourceType.FILE,
+            new IdentifyFile().identify(PfamFile, DataSourceType.FILE));
     int numpdb = 0;
     for (SequenceI sq : al.getSequences())
     {
@@ -72,7 +81,7 @@ public class StockholmFileTest
   @Test(groups = { "Functional" })
   public void rfamFileIO() throws Exception
   {
-    testFileIOwithFormat(new File(RfamFile), "STH", 2, 1);
+    testFileIOwithFormat(new File(RfamFile), FileFormat.Stockholm, 2, 1);
   }
 
   /**
@@ -86,7 +95,7 @@ public class StockholmFileTest
    *          f
    */
 
-  public static void testFileIOwithFormat(File f, String ioformat,
+  public static void testFileIOwithFormat(File f, FileFormatI ioformat,
           int naliannot, int nminseqann)
   {
     System.out.println("Reading file: " + f);
@@ -95,8 +104,8 @@ public class StockholmFileTest
     {
       AppletFormatAdapter rf = new AppletFormatAdapter();
 
-      AlignmentI al = rf.readFile(ff, AppletFormatAdapter.FILE,
-              new IdentifyFile().identify(ff, AppletFormatAdapter.FILE));
+      AlignmentI al = rf.readFile(ff, DataSourceType.FILE,
+              new IdentifyFile().identify(ff, DataSourceType.FILE));
 
       assertNotNull("Couldn't read supplied alignment data.", al);
 
@@ -110,11 +119,11 @@ public class StockholmFileTest
               + outputfile + "\n<<EOF\n");
       // test for consistency in io
       AlignmentI al_input = new AppletFormatAdapter().readFile(outputfile,
-              AppletFormatAdapter.PASTE, ioformat);
+              DataSourceType.PASTE, ioformat);
       assertNotNull("Couldn't parse reimported alignment data.", al_input);
 
-      String identifyoutput = new IdentifyFile().identify(outputfile,
-              AppletFormatAdapter.PASTE);
+      FileFormatI identifyoutput = new IdentifyFile().identify(outputfile,
+              DataSourceType.PASTE);
       assertNotNull("Identify routine failed for outputformat " + ioformat,
               identifyoutput);
       assertTrue(
index 181aabd..38c9a89 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.io;
 
+import jalview.gui.JvOptionPane;
 import jalview.io.TCoffeeScoreFile.Block;
 import jalview.io.TCoffeeScoreFile.Header;
 
@@ -29,11 +30,19 @@ import java.io.IOException;
 import java.util.List;
 
 import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class TCoffeeScoreFileTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   final static File SCORE_FILE = new File(
           "test/jalview/io/tcoffee.score_ascii");
 
@@ -45,7 +54,7 @@ public class TCoffeeScoreFileTest
   {
 
     TCoffeeScoreFile scoreFile = new TCoffeeScoreFile(SCORE_FILE.getPath(),
-            AppletFormatAdapter.FILE);
+            DataSourceType.FILE);
     AssertJUnit.assertTrue(scoreFile.getWarningMessage(),
             scoreFile.isValid());
 
@@ -73,7 +82,7 @@ public class TCoffeeScoreFileTest
     try
     {
       TCoffeeScoreFile result = new TCoffeeScoreFile(ALIGN_FILE.getPath(),
-              FormatAdapter.FILE);
+              DataSourceType.FILE);
       AssertJUnit.assertFalse(result.isValid());
     } catch (IOException x)
     {
@@ -86,7 +95,7 @@ public class TCoffeeScoreFileTest
   public void testHeightAndWidth() throws IOException
   {
     TCoffeeScoreFile result = new TCoffeeScoreFile(SCORE_FILE.getPath(),
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
     AssertJUnit.assertTrue(result.isValid());
     AssertJUnit.assertEquals(8, result.getHeight());
     AssertJUnit.assertEquals(83, result.getWidth());
@@ -107,7 +116,7 @@ public class TCoffeeScoreFileTest
             + "1QCF   99999999999999999999999999974-------2---------24\n"
             + "cons   999999999999999999999999999851000110321100001134\n"
             + "\n" + "\n";
-    FileParse source = new FileParse(BLOCK, FormatAdapter.PASTE);
+    FileParse source = new FileParse(BLOCK, DataSourceType.PASTE);
     Block block = TCoffeeScoreFile.readBlock(source, 0);
 
     AssertJUnit.assertNotNull(block);
@@ -145,7 +154,7 @@ public class TCoffeeScoreFileTest
   {
 
     TCoffeeScoreFile parser = new TCoffeeScoreFile(SCORE_FILE.getPath(),
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
 
     AssertJUnit
             .assertEquals(
@@ -190,7 +199,7 @@ public class TCoffeeScoreFileTest
   {
 
     TCoffeeScoreFile parser = new TCoffeeScoreFile(SCORE_FILE.getPath(),
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
     AssertJUnit.assertTrue(parser.getWarningMessage(), parser.isValid());
     List<String> scores = parser.getScoresList();
     AssertJUnit
@@ -237,7 +246,7 @@ public class TCoffeeScoreFileTest
   {
 
     TCoffeeScoreFile parser = new TCoffeeScoreFile(SCORE_FILE.getPath(),
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
     AssertJUnit.assertTrue(parser.getWarningMessage(), parser.isValid());
     byte[][] scores = parser.getScoresArray();
 
@@ -267,7 +276,7 @@ public class TCoffeeScoreFileTest
   public void testHeightAndWidthWithResidueNumbers() throws Exception
   {
     String file = "test/jalview/io/tcoffee.score_ascii_with_residue_numbers";
-    TCoffeeScoreFile result = new TCoffeeScoreFile(file, FormatAdapter.FILE);
+    TCoffeeScoreFile result = new TCoffeeScoreFile(file, DataSourceType.FILE);
     AssertJUnit.assertTrue(result.isValid());
     AssertJUnit.assertEquals(5, result.getHeight());
     AssertJUnit.assertEquals(84, result.getWidth());
index dbacceb..825af24 100644 (file)
@@ -35,8 +35,9 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.io.FileLoader;
-import jalview.io.FormatAdapter;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -44,10 +45,19 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ExonerateHelperTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testGetMappingType()
   {
@@ -258,19 +268,20 @@ public class ExonerateHelperTest
   {
     FileLoader loader = new FileLoader(false);
     AlignFrame af = loader.LoadFileWaitTillLoaded(
-            "examples/testdata/exonerateseqs.fa", FormatAdapter.FILE);
-
+            "examples/testdata/exonerateseqs.fa",
+            DataSourceType.FILE);
+  
     af.loadJalviewDataFile("examples/testdata/exonerateoutput.gff",
-            FormatAdapter.FILE, null, null);
-
+            DataSourceType.FILE, null, null);
+  
     /*
      * verify one mapping to a dummy sequence, one to a real one
      */
-    List<AlignedCodonFrame> mappings = af.getViewport().getAlignment()
-            .getDataset().getCodonFrames();
+    List<AlignedCodonFrame> mappings = af
+            .getViewport().getAlignment().getDataset().getCodonFrames();
     assertEquals(2, mappings.size());
     Iterator<AlignedCodonFrame> iter = mappings.iterator();
-
+  
     // first mapping is to dummy sequence
     AlignedCodonFrame mapping = iter.next();
     Mapping[] mapList = mapping.getProtMappings();
@@ -281,7 +292,7 @@ public class ExonerateHelperTest
     // 143 in protein should map to codon [11270, 11269, 11268] in dna
     int[] mappedRegion = mapList[0].getMap().locateInFrom(143, 143);
     assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion);
-
+  
     // second mapping is to a sequence in the alignment
     mapping = iter.next();
     mapList = mapping.getProtMappings();
@@ -290,23 +301,23 @@ public class ExonerateHelperTest
             .findName("DDB_G0280897");
     assertSame(proteinSeq.getDatasetSequence(), mapList[0].getTo());
     assertEquals(1, mapping.getdnaToProt().length);
-
+  
     // 143 in protein should map to codon [11270, 11269, 11268] in dna
     mappedRegion = mapList[0].getMap().locateInFrom(143, 143);
     assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion);
-
+  
     // 182 in protein should map to codon [11153, 11152, 11151] in dna
     mappedRegion = mapList[0].getMap().locateInFrom(182, 182);
     assertArrayEquals(new int[] { 11153, 11151 }, mappedRegion);
-
+  
     // and the reverse mapping:
     mappedRegion = mapList[0].getMap().locateInTo(11151, 11153);
     assertArrayEquals(new int[] { 182, 182 }, mappedRegion);
-
+  
     // 11150 in dna should _not_ map to protein
     mappedRegion = mapList[0].getMap().locateInTo(11150, 11150);
     assertNull(mappedRegion);
-
+  
     // similarly 183 in protein should _not_ map to dna
     mappedRegion = mapList[0].getMap().locateInFrom(183, 183);
     assertNull(mappedRegion);
index 4355e40..bf038ac 100644 (file)
@@ -33,16 +33,25 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class Gff3HelperTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test processing one PASA GFF line giving a match from forward strand to
    * forward strand
index a1032ef..7fb716f 100644 (file)
@@ -24,15 +24,25 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class GffHelperBaseTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test the method that parses lines like <br>
    * ID=2345;Name=Something,Another thing;Notes=Hello;Notes=World
index cfe1d12..84725ff 100644 (file)
@@ -24,11 +24,21 @@ import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class GffHelperFactoryTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testGetHelper()
   {
index 221f612..393f2ce 100644 (file)
@@ -33,11 +33,13 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.io.FileLoader;
-import jalview.io.FormatAdapter;
 
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 /**
@@ -47,6 +49,14 @@ import org.testng.annotations.Test;
  */
 public class GffTests
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test the case where we load a protein ('query') sequence, then exonerateGff
    * describing its mapping to cDNA, and then a DNA sequence including the
@@ -57,7 +67,7 @@ public class GffTests
   {
     String proteinSeq = ">prot1/10-16\nYCWRSGA";
     AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
-            proteinSeq, FormatAdapter.PASTE);
+            proteinSeq, DataSourceType.PASTE);
 
     /*
      * exonerate GFF output mapping residues 11-15 (CWRSG) 
@@ -65,7 +75,7 @@ public class GffTests
      */
     String exonerateGff = "##gff-version 2\n"
             + "prot1\tprotein2genome\tsimilarity\t11\t15\t99\t-\t.\talignment_id 0 ; Target dna1 ; Align 11 24 5";
-    af.loadJalviewDataFile(exonerateGff, FormatAdapter.PASTE, null, null);
+    af.loadJalviewDataFile(exonerateGff, DataSourceType.PASTE, null, null);
 
     /*
      * check we have a mapping from prot1 to SequenceDummy 'dna1'
index 75546fb..bcccf35 100644 (file)
@@ -31,17 +31,26 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class InterProScanHelperTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test processing one InterProScan GFF line
    * 
index 45b56c2..908d07b 100644 (file)
@@ -22,13 +22,23 @@ package jalview.schemes;
 
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class DnaCodonTests
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testAmbiguityCodeGeneration()
   {
index fd49971..47613a1 100644 (file)
@@ -26,14 +26,24 @@ import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.AssertJUnit.fail;
 
 import jalview.datamodel.SequenceFeature;
+import jalview.gui.JvOptionPane;
 import jalview.util.Format;
 
 import java.awt.Color;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class FeatureColourTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testCopyConstructor()
   {
diff --git a/test/jalview/schemes/ResidueColourSchemeTest.java b/test/jalview/schemes/ResidueColourSchemeTest.java
new file mode 100644 (file)
index 0000000..d3a4fff
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.schemes;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.datamodel.Profile;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.Profiles;
+import jalview.gui.JvOptionPane;
+
+import java.awt.Color;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ResidueColourSchemeTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
+  public void testAboveThreshold()
+  {
+    /*
+     * make up profiles for this alignment:
+     * AR-Q
+     * AR--
+     * SR-T
+     * SR-T
+     */
+    ProfileI[] profiles = new ProfileI[4];
+    profiles[0] = new Profile(4, 0, 2, "AS");
+    profiles[1] = new Profile(4, 0, 4, "R");
+    profiles[2] = new Profile(4, 4, 0, "");
+    profiles[3] = new Profile(4, 1, 2, "T");
+    ResidueColourScheme rcs = new ResidueColourScheme();
+    rcs.setConsensus(new Profiles(profiles));
+    
+    /*
+     * no threshold
+     */
+    rcs.setThreshold(0, true);
+    assertTrue(rcs.aboveThreshold('a', 0));
+    assertTrue(rcs.aboveThreshold('S', 0));
+    assertFalse(rcs.aboveThreshold('W', 0));
+    assertTrue(rcs.aboveThreshold('R', 1));
+    assertFalse(rcs.aboveThreshold('W', 2));
+    assertTrue(rcs.aboveThreshold('t', 3));
+    assertFalse(rcs.aboveThreshold('Q', 3));
+
+    /*
+     * with threshold, include gaps
+     */
+    rcs.setThreshold(60, false);
+    assertFalse(rcs.aboveThreshold('a', 0));
+    assertFalse(rcs.aboveThreshold('S', 0));
+    assertTrue(rcs.aboveThreshold('R', 1));
+    assertFalse(rcs.aboveThreshold('W', 2));
+    assertFalse(rcs.aboveThreshold('t', 3)); // 50% < 60%
+
+    /*
+     * with threshold, ignore gaps
+     */
+    rcs.setThreshold(60, true);
+    assertFalse(rcs.aboveThreshold('a', 0));
+    assertFalse(rcs.aboveThreshold('S', 0));
+    assertTrue(rcs.aboveThreshold('R', 1));
+    assertFalse(rcs.aboveThreshold('W', 2));
+    assertTrue(rcs.aboveThreshold('t', 3)); // 67% > 60%
+  }
+
+  /**
+   * Test colour bleaching based on conservation score and conservation slider.
+   * Scores of 10 or 11 should leave colours unchanged. Gap is always white.
+   */
+  @Test(groups = "Functional")
+  public void testApplyConservation()
+  {
+    ResidueColourScheme rcs = new ResidueColourScheme();
+
+    // no conservation present - no fading
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 12));
+    
+    // cheat by setting conservation sequence directly
+    // rather than calculating it - good enough for this test
+    String consensus = "0123456789+*-";
+    rcs.conservation = consensus.toCharArray();
+
+    // column out of range:
+    assertEquals(Color.RED,
+            rcs.applyConservation(Color.RED, consensus.length()));
+
+    /*
+     * with 100% threshold, 'fade factor' is 
+     * (11-score)/10 * 100/20 = (11-score)/2
+     * which is >= 1 for all scores i.e. all fade to white except +, *
+     */
+    rcs.setConservationInc(100);
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 0));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 1));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 2));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 3));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 4));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 5));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 6));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 7));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 8));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 9));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12));
+
+    /*
+     * with 0% threshold, there should be no fading
+     */
+    rcs.setConservationInc(0);
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 0));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 1));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 2));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 3));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 4));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 5));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 6));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 7));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 8));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 9));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12)); // gap
+
+    /*
+     * with 40% threshold, 'fade factor' is 
+     * (11-score)/10 * 40/20 = (11-score)/5
+     * which is {>1, >1, >1, >1, >1, >1, 1, 0.8, 0.6, 0.4} for score 0-9
+     * e.g. score 7 colour fades 80% of the way to white (255, 255, 255)
+     */
+    rcs.setConservationInc(40);
+    Color colour = new Color(155, 105, 55);
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 0));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 1));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 2));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 3));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 4));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 5));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 6));
+    assertEquals(new Color(235, 225, 215), rcs.applyConservation(colour, 7));
+    assertEquals(new Color(215, 195, 175), rcs.applyConservation(colour, 8));
+    assertEquals(new Color(195, 165, 135), rcs.applyConservation(colour, 9));
+    assertEquals(colour, rcs.applyConservation(colour, 10));
+    assertEquals(colour, rcs.applyConservation(colour, 11));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 12));
+  }
+}
index b68ca68..7fbad50 100644 (file)
@@ -23,14 +23,25 @@ package jalview.schemes;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ResiduePropertiesTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test 'standard' codon translations (no ambiguity codes)
    */
@@ -1556,4 +1567,62 @@ public class ResiduePropertiesTest
     assertEquals('Q', ResidueProperties.getSingleCharacterCode("Gln"));
     assertEquals('Q', ResidueProperties.getSingleCharacterCode("gln"));
   }
+
+  @Test(groups = { "Functional" })
+  public void testPhysicoChemicalProperties()
+  {
+    checkProperty("aromatic", "FYWH-*");
+    checkProperty("aliphatic", "IVL-*");
+    checkProperty("tiny", "GAS-*");
+    checkProperty("small", "VCTGACSDNP-*");
+    checkProperty("charged", "HKRDE-*");
+    checkProperty("negative", "DE-*");
+    checkProperty("polar", "YWHRKTSNDEQ-*X");
+    checkProperty("positive", "HKR-*");
+    checkProperty("proline", "P-*");
+    checkProperty("hydrophobic", "MILVFYWHKTGAC-*X");
+  }
+
+  /**
+   * Verify that the residues in the list have the named property, and other
+   * residues do not
+   * 
+   * @param property
+   * @param residues
+   */
+  void checkProperty(String property, String residues)
+  {
+    Map<String, Integer> props = ResidueProperties.propHash.get(property);
+
+    /*
+     * assert residues have the property (value 1 in lookup)
+     */
+    for (char res : residues.toCharArray())
+    {
+      assertEquals(res + " should be " + property, 1,
+              props.get(String.valueOf(res)).intValue());
+    }
+
+    /*
+     * assert other residues do not (value 0 in lookup)
+     */
+    for (String res : ResidueProperties.aa)
+    {
+      if (!residues.contains(res))
+      {
+        Integer propValue = props.get(String.valueOf(res));
+
+        if (propValue != null)
+        {
+          /*
+           * conservation calculation assigns unexpected symbols
+           * the same value as '-'; here we just check those which
+           * explicitly do not have the property
+           */
+          assertEquals(res + " should not be " + property, 0,
+                  propValue.intValue());
+        }
+      }
+    }
+  }
 }
index 293690b..a743163 100644 (file)
 package jalview.schemes;
 
 import jalview.api.analysis.ScoreModelI;
+import jalview.gui.JvOptionPane;
 
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ScoreMatrixPrinter
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void printAllMatrices()
   {
index 34af086..645d5b8 100644 (file)
@@ -24,13 +24,23 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertSame;
 
+import jalview.gui.JvOptionPane;
+
 import java.awt.Color;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class UserColourSchemeTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testGetColourFromString()
   {
index 9ec3a92..85aea40 100644 (file)
@@ -28,17 +28,27 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FileLoader;
-import jalview.io.FormatAdapter;
 import jalview.io.StructureFile;
 
 import org.testng.Assert;
 import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class Mapping
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /*
    * more test data
    * 
@@ -68,7 +78,7 @@ public class Mapping
       StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
       StructureFile pmap = ssm.setMapping(true, new SequenceI[] { uprot },
               new String[] { "A" }, "test/jalview/ext/jmol/1QCF.pdb",
-              jalview.io.FormatAdapter.FILE);
+              DataSourceType.FILE);
       assertTrue(pmap != null);
       SequenceI protseq = pmap.getSeqsAsArray()[0];
       AlignmentAnnotation pstra = protseq
@@ -138,8 +148,8 @@ public class Mapping
     // Associate the 1GAQ pdb file with the subsequence 'imported' from another
     // source
     StructureFile pde = ssm.setMapping(true, new SequenceI[] { sq },
-            new String[] { "A" }, inFile = "examples/1gaq.txt",
-            jalview.io.FormatAdapter.FILE);
+            new String[]
+    { "A" }, inFile = "examples/1gaq.txt", DataSourceType.FILE);
     assertTrue("PDB File couldn't be found", pde != null);
     StructureMapping[] mp = ssm.getMapping(inFile);
     assertTrue("No mappings made.", mp != null && mp.length > 0);
@@ -231,12 +241,12 @@ public class Mapping
     AlignFrame seqf = new FileLoader(false)
             .LoadFileWaitTillLoaded(
                     ">FER1_MAIZE/1-150 Ferredoxin-1, chloroplast precursor\nMATVLGSPRAPAFFFSSSSLRAAPAPTAVALPAAKVGIMGRSASSRRRLRAQATYNVKLITPEGEVELQVPD\nDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDVVIETHKE\nEELTGA",
-                    FormatAdapter.PASTE, "FASTA");
+                    DataSourceType.PASTE, FileFormat.Fasta);
     SequenceI newseq = seqf.getViewport().getAlignment().getSequenceAt(0);
     StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
     StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq },
             new String[] { null }, "examples/3W5V.pdb",
-            jalview.io.FormatAdapter.FILE);
+            DataSourceType.FILE);
     if (pmap == null)
     {
       AssertJUnit.fail("Couldn't make a mapping for 3W5V to FER1_MAIZE");
@@ -253,7 +263,7 @@ public class Mapping
     StructureImportSettings.setShowSeqFeatures(true);
     AlignFrame ref = new FileLoader(false)
             .LoadFileWaitTillLoaded("test/jalview/ext/jmol/1QCF.pdb",
-                    jalview.io.FormatAdapter.FILE);
+                    DataSourceType.FILE);
     SequenceI refseq = ref.getViewport().getAlignment().getSequenceAt(0);
     SequenceI newseq = new Sequence(refseq.getName() + "Copy",
             refseq.getSequenceAsString());
@@ -265,7 +275,7 @@ public class Mapping
     ssm.setAddTempFacAnnot(true);
     StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq },
             new String[] { null }, "test/jalview/ext/jmol/1QCF.pdb",
-            jalview.io.FormatAdapter.FILE);
+            DataSourceType.FILE);
     assertTrue(pmap != null);
     assertEquals("Original and copied sequence of different lengths.",
             refseq.getLength(), newseq.getLength());
index 2074fb4..a7e52ff 100644 (file)
@@ -27,18 +27,28 @@ import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
-import jalview.io.FormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.io.StructureFile;
 import jalview.util.MapList;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class StructureSelectionManagerTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private StructureSelectionManager ssm;
 
   @BeforeMethod(alwaysRun = true)
@@ -124,7 +134,7 @@ public class StructureSelectionManagerTest
     sm.setProcessSecondaryStructure(true);
     sm.setAddTempFacAnnot(true);
     StructureFile pmap = sm.setMapping(true, new SequenceI[] { seq },
-            new String[] { null }, "examples/1gaq.txt", FormatAdapter.FILE);
+            new String[] { null }, "examples/1gaq.txt", DataSourceType.FILE);
     assertTrue(pmap != null);
 
     assertEquals(3, pmap.getSeqs().size());
index 0d00169..b74a089 100644 (file)
@@ -30,7 +30,8 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.structure.AtomSpec;
 import jalview.structure.StructureSelectionManager;
 import jalview.structures.models.AAStructureBindingModel.SuperposeData;
@@ -38,6 +39,7 @@ import jalview.structures.models.AAStructureBindingModel.SuperposeData;
 import java.util.Arrays;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -49,6 +51,14 @@ import org.testng.annotations.Test;
  */
 public class AAStructureBindingModelTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /*
    * Scenario: Jalview has 4 sequences, corresponding to 1YCS (chains A and B), 3A6S|B, 1OOT|A
    */
@@ -104,7 +114,6 @@ public class AAStructureBindingModelTest
     pdbFiles[0] = new PDBEntry("1YCS", "A", Type.PDB, "INLINE1YCS");
     pdbFiles[1] = new PDBEntry("3A6S", "B", Type.PDB, "INLINE3A6S");
     pdbFiles[2] = new PDBEntry("1OOT", "A", Type.PDB, "INLINE1OOT");
-    String[][] chains = new String[3][];
     SequenceI[][] seqs = new SequenceI[3][];
     seqs[0] = new SequenceI[] { seq1a, seq1b };
     seqs[1] = new SequenceI[] { seq2 };
@@ -112,13 +121,13 @@ public class AAStructureBindingModelTest
     StructureSelectionManager ssm = new StructureSelectionManager();
 
     ssm.setMapping(new SequenceI[] { seq1a, seq1b }, null, PDB_1,
-            AppletFormatAdapter.PASTE);
+            DataSourceType.PASTE);
     ssm.setMapping(new SequenceI[] { seq2 }, null, PDB_2,
-            AppletFormatAdapter.PASTE);
+            DataSourceType.PASTE);
     ssm.setMapping(new SequenceI[] { seq3 }, null, PDB_3,
-            AppletFormatAdapter.PASTE);
+            DataSourceType.PASTE);
 
-    testee = new AAStructureBindingModel(ssm, pdbFiles, seqs, chains, null)
+    testee = new AAStructureBindingModel(ssm, pdbFiles, seqs, null)
     {
       @Override
       public String[] getPdbFile()
@@ -140,6 +149,12 @@ public class AAStructureBindingModelTest
       public void highlightAtoms(List<AtomSpec> atoms)
       {
       }
+
+      @Override
+      public List<String> getChainNames()
+      {
+        return null;
+      }
     };
   }
 
index 30cc07d..743b9a3 100644 (file)
@@ -22,12 +22,23 @@ package jalview.util;
 
 import static org.testng.AssertJUnit.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Arrays;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ArrayUtilsTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testReverseIntArray()
   {
index 0429cce..093428c 100644 (file)
@@ -25,10 +25,21 @@ import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotEquals;
 import static org.testng.Assert.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class CaseInsensitiveStringTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = "Functional")
   public void testEquals()
   {
index 69675f7..9a5d093 100644 (file)
@@ -22,14 +22,25 @@ package jalview.util;
 
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertSame;
+
+import jalview.gui.JvOptionPane;
 
 import java.awt.Color;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ColorUtilsTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   Color paleColour = new Color(97, 203, 111); // pale green
 
   Color midColour = new Color(135, 57, 41); // mid red
@@ -132,4 +143,27 @@ public class ColorUtilsTest
             .getGraduatedColour(40f, 10f, minColour, 10f, maxColour);
     assertEquals(minColour, col);
   }
+
+  @Test(groups = { "Functional" })
+  public void testBleachColour()
+  {
+    Color colour = new Color(155, 105, 55);
+    assertSame(colour, ColorUtils.bleachColour(colour, 0));
+    assertEquals(Color.WHITE, ColorUtils.bleachColour(colour, 1));
+    assertEquals(Color.WHITE, ColorUtils.bleachColour(colour, 2));
+    assertEquals(new Color(175, 135, 95),
+            ColorUtils.bleachColour(colour, 0.2f));
+    assertEquals(new Color(225, 210, 195),
+            ColorUtils.bleachColour(colour, 0.7f));
+
+    /*
+     * and some 'negative fade'
+     */
+    assertEquals(Color.BLACK, ColorUtils.bleachColour(colour, -1));
+    assertEquals(Color.BLACK, ColorUtils.bleachColour(colour, -2));
+    assertEquals(new Color(124, 84, 44),
+            ColorUtils.bleachColour(colour, -0.2f));
+    assertEquals(new Color(46, 31, 16), // with rounding down
+            ColorUtils.bleachColour(colour, -0.7f));
+  }
 }
index 9aab66c..f955879 100644 (file)
@@ -26,12 +26,21 @@ import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ComparisonTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testIsGap()
   {
@@ -188,4 +197,16 @@ public class ComparisonTest
     assertTrue(Comparison.isNucleotideSequence("a A-g.GcCtTuU", true));
     assertFalse(Comparison.isNucleotideSequence("a A-g.GcCtTuU", false));
   }
+
+  @Test(groups = { "Functional" })
+  public void testIsSameResidue()
+  {
+    assertTrue(Comparison.isSameResidue('a', 'a', false));
+    assertTrue(Comparison.isSameResidue('a', 'a', true));
+    assertTrue(Comparison.isSameResidue('A', 'a', false));
+    assertTrue(Comparison.isSameResidue('a', 'A', false));
+
+    assertFalse(Comparison.isSameResidue('a', 'A', true));
+    assertFalse(Comparison.isSameResidue('A', 'a', true));
+  }
 }
index d1c24d1..0ef3c25 100644 (file)
@@ -32,14 +32,23 @@ import jalview.datamodel.Mapping;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class DBRefUtilsTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test the method that selects DBRefEntry items whose source is in a supplied
    * list
@@ -74,9 +83,16 @@ public class DBRefUtilsTest
     assertSame(ref2, selected[0]);
     assertSame(ref3, selected[1]);
 
-    sources = new String[] { "Uniprot", "EMBLCDS" };
+    sources = new String[] { "EMBLCDS" };
     selected = DBRefUtils.selectRefs(dbrefs, sources);
     assertNull(selected);
+
+    sources = new String[] { "embl", "uniprot" };
+    selected = DBRefUtils.selectRefs(dbrefs, sources);
+    assertEquals(3, selected.length);
+    assertSame(ref1, selected[0]);
+    assertSame(ref2, selected[1]);
+    assertSame(ref3, selected[2]);
   }
 
   /**
@@ -99,6 +115,11 @@ public class DBRefUtilsTest
     assertEquals("UNIPROTKB/SWISS-CHEESE",
             DBRefUtils.getCanonicalName("UNIPROTKB/SWISS-CHEESE"));
     assertEquals("ENSEMBL", DBRefUtils.getCanonicalName("Ensembl"));
+
+    // these are not 'known' to Jalview
+    assertEquals("PFAM", DBRefUtils.getCanonicalName("PFAM"));
+    assertEquals("pfam", DBRefUtils.getCanonicalName("pfam"));
+
   }
 
   @Test(groups = { "Functional" })
index b9083f5..9815aa0 100644 (file)
@@ -24,13 +24,24 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.fail;
 
+import jalview.gui.JvOptionPane;
+
 import java.text.ParseException;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class DnaUtilsTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Tests for parsing an ENA/GenBank location specifier
    * 
diff --git a/test/jalview/util/FormatTest.java b/test/jalview/util/FormatTest.java
new file mode 100644 (file)
index 0000000..1404f0b
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class FormatTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
+  public void testAppendPercentage()
+  {
+    StringBuilder sb = new StringBuilder();
+    Format.appendPercentage(sb, 123.436f, 0);
+    assertEquals(sb.toString(), "123");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.536f, 0);
+    assertEquals(sb.toString(), "124");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 799.536f, 0);
+    assertEquals(sb.toString(), "800");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.436f, 1);
+    assertEquals(sb.toString(), "123.4");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.436f, 2);
+    assertEquals(sb.toString(), "123.44");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.436f, 3);
+    assertEquals(sb.toString(), "123.436");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.436f, 4);
+    assertEquals(sb.toString(), "123.4360");
+  }
+
+  @Test(groups = "Functional")
+  public void testForm_float()
+  {
+    Format f = new Format("%3.2f");
+    assertEquals(f.form(123f), "123.00");
+    assertEquals(f.form(123.1f), "123.10");
+    assertEquals(f.form(123.12f), "123.12");
+    assertEquals(f.form(123.124f), "123.12");
+    assertEquals(f.form(123.125f), "123.13");
+    assertEquals(f.form(123.126f), "123.13");
+
+    f = new Format("%3.0f");
+    assertEquals(f.form(123f), "123.");
+    assertEquals(f.form(12f), "12.");
+    assertEquals(f.form(123.4f), "123.");
+    assertEquals(f.form(123.5f), "124.");
+    assertEquals(f.form(123.6f), "124.");
+    assertEquals(f.form(129.6f), "130.");
+  }
+
+  @Test(groups = "Functional")
+  public void testRepeat()
+  {
+    assertEquals(Format.repeat('a', 3), "aaa");
+    assertEquals(Format.repeat('b', 0), "");
+    assertEquals(Format.repeat('c', -1), "");
+  }
+}
index 9a0bdd7..a2f38e2 100644 (file)
@@ -27,15 +27,25 @@ import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class MapListTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testSomething()
   {
index 655aa2a..b84e770 100644 (file)
@@ -33,13 +33,16 @@ 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.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignViewport;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
 
 import java.awt.Color;
@@ -48,10 +51,19 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class MappingUtilsTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private AlignViewportI dnaView;
 
   private AlignViewportI proteinView;
@@ -81,9 +93,9 @@ public class MappingUtilsTest
     /*
      * Check protein residue 12 maps to codon 5-7, 13 to codon 8-10
      */
-    SearchResults sr = MappingUtils.buildSearchResults(aseq1, 12, acfList);
+    SearchResultsI sr = MappingUtils.buildSearchResults(aseq1, 12, acfList);
     assertEquals(1, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertEquals(seq1.getDatasetSequence(), m.getSequence());
     assertEquals(5, m.getStart());
     assertEquals(7, m.getEnd());
@@ -134,9 +146,9 @@ public class MappingUtilsTest
     /*
      * Check protein residue 8 maps to [6, 8, 9]
      */
-    SearchResults sr = MappingUtils.buildSearchResults(aseq1, 8, acfList);
+    SearchResultsI sr = MappingUtils.buildSearchResults(aseq1, 8, acfList);
     assertEquals(2, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertEquals(seq1.getDatasetSequence(), m.getSequence());
     assertEquals(6, m.getStart());
     assertEquals(6, m.getEnd());
@@ -197,10 +209,10 @@ public class MappingUtilsTest
      * viewport).
      */
     AlignmentI cdna = loadAlignment(">Seq1\nACG\n>Seq2\nTGA\n>Seq3\nTAC\n",
-            "FASTA");
+            FileFormat.Fasta);
     cdna.setDataset(null);
     AlignmentI protein = loadAlignment(">Seq1\nK\n>Seq2\nL\n>Seq3\nQ\n",
-            "FASTA");
+            FileFormat.Fasta);
     protein.setDataset(null);
     AlignedCodonFrame acf = new AlignedCodonFrame();
     MapList map = new MapList(new int[] { 1, 3 }, new int[] { 1, 1 }, 3, 1);
@@ -268,11 +280,11 @@ public class MappingUtilsTest
    * @return
    * @throws IOException
    */
-  protected AlignmentI loadAlignment(final String data, String format)
+  protected AlignmentI loadAlignment(final String data, FileFormatI format)
           throws IOException
   {
     AlignmentI a = new FormatAdapter().readFile(data,
-            AppletFormatAdapter.PASTE, format);
+            DataSourceType.PASTE, format);
     a.setDataset(null);
     return a;
   }
@@ -351,11 +363,11 @@ public class MappingUtilsTest
      */
     AlignmentI cdna = loadAlignment(">Seq1/10-18\nAC-GctGtC-T\n"
             + ">Seq2/20-27\nTc-GA-G-T-Tc\n" + ">Seq3/30-38\nTtTT-AaCGg-\n",
-            "FASTA");
+            FileFormat.Fasta);
     cdna.setDataset(null);
     AlignmentI protein = loadAlignment(
             ">Seq1/40-41\n-K-P\n>Seq2/50-51\nL--Q\n>Seq3/60-61\nG--S\n",
-            "FASTA");
+            FileFormat.Fasta);
     protein.setDataset(null);
 
     // map first dna to first protein seq
@@ -466,10 +478,11 @@ public class MappingUtilsTest
      * viewport).
      */
     AlignmentI cdna = loadAlignment(
-            ">Seq1\nACGGCA\n>Seq2\nTGACAG\n>Seq3\nTACGTA\n", "FASTA");
+            ">Seq1\nACGGCA\n>Seq2\nTGACAG\n>Seq3\nTACGTA\n",
+            FileFormat.Fasta);
     cdna.setDataset(null);
     AlignmentI protein = loadAlignment(">Seq1\nKA\n>Seq2\nLQ\n>Seq3\nQV\n",
-            "FASTA");
+            FileFormat.Fasta);
     protein.setDataset(null);
     AlignedCodonFrame acf = new AlignedCodonFrame();
     MapList map = new MapList(new int[] { 1, 6 }, new int[] { 1, 2 }, 3, 1);
@@ -549,10 +562,10 @@ public class MappingUtilsTest
      */
     AlignmentI cdna = loadAlignment(
             ">Seq1\nA-CG-GC--AT-CA\n>Seq2\n-TG-AC-AG-T-AT\n>Seq3\n-T--ACG-TAAT-G\n",
-            "FASTA");
+            FileFormat.Fasta);
     cdna.setDataset(null);
     AlignmentI protein = loadAlignment(
-            ">Seq1\n-KA-S\n>Seq2\n--L-QY\n>Seq3\nQ-V-M\n", "FASTA");
+            ">Seq1\n-KA-S\n>Seq2\n--L-QY\n>Seq3\nQ-V-M\n", FileFormat.Fasta);
     protein.setDataset(null);
     AlignedCodonFrame acf = new AlignedCodonFrame();
     MapList map = new MapList(new int[] { 1, 9 }, new int[] { 1, 3 }, 3, 1);
index 2d5b4b3..bfaa7af 100644 (file)
@@ -22,10 +22,21 @@ package jalview.util;
 
 import static org.testng.AssertJUnit.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ParseHtmlBodyAndLinksTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testParseHtml_noLinks()
   {
diff --git a/test/jalview/util/PlatformTest.java b/test/jalview/util/PlatformTest.java
new file mode 100644 (file)
index 0000000..307f450
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import jalview.gui.JvOptionPane;
+
+import java.awt.Button;
+import java.awt.Event;
+import java.awt.event.MouseEvent;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class PlatformTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  Button b = new Button();
+
+  /**
+   * isControlDown for Mac should answer true for Meta-down, but not for right
+   * mouse (popup trigger)
+   */
+  @Test(groups = "Functional")
+  public void testIsControlDown_mac()
+  {
+    int clickCount = 1;
+    boolean isPopupTrigger = false;
+    int buttonNo = MouseEvent.BUTTON1;
+    boolean mac = true;
+
+    int mods = 0;
+    // not concerned with MouseEvent id, when, x, y, xAbs, yAbs values
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    mods = Event.CTRL_MASK;
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    mods = Event.META_MASK;
+    assertTrue(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    isPopupTrigger = true;
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    isPopupTrigger = false;
+    buttonNo = MouseEvent.BUTTON2;
+    mods = 0;
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+  }
+
+  /**
+   * If not a Mac, we only care whether CTRL_MASK modifier is set on the mouse
+   * event
+   */
+  @Test(groups = "Functional")
+  public void testIsControlDown_notMac()
+  {
+    int clickCount = 1;
+    boolean isPopupTrigger = false;
+    int buttonNo = MouseEvent.BUTTON1;
+    boolean mac = false;
+
+    int mods = 0;
+    // not concerned with MouseEvent id, when, x, y, xAbs, yAbs values
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    mods = Event.CTRL_MASK;
+    assertTrue(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    mods = Event.CTRL_MASK | Event.SHIFT_MASK | Event.ALT_MASK;
+    clickCount = 2;
+    buttonNo = 2;
+    isPopupTrigger = true;
+    assertTrue(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+  }
+}
index f976955..f09dee9 100644 (file)
@@ -23,13 +23,24 @@ package jalview.util;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Arrays;
 import java.util.Random;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class QuickSortTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private static final String c1 = "Blue";
 
   private static final String c2 = "Yellow";
index 62ddfb0..e8b9b50 100644 (file)
@@ -23,14 +23,24 @@ package jalview.util;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Arrays;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ShiftListTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testParseMap()
   {
diff --git a/test/jalview/util/SparseCountTest.java b/test/jalview/util/SparseCountTest.java
new file mode 100644 (file)
index 0000000..c4d67b6
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+public class SparseCountTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
+  public void testAdd()
+  {
+    SparseCount p = new SparseCount(8);
+    p.add('a', 1);
+    p.add('b', 2);
+    p.add('a', 3);
+    p.add('b', -4);
+    assertEquals(p.size(), 2);
+    assertEquals(p.get('a'), 4);
+    assertEquals(p.get('b'), -2);
+  }
+
+  @Test(groups = "Functional")
+  public void testPut()
+  {
+    SparseCount p = new SparseCount(8);
+    p.put('a', 3);
+    p.add('b', 2);
+    p.put('b', 4);
+    assertEquals(p.size(), 2);
+    assertEquals(p.get('a'), 3);
+    assertEquals(p.get('b'), 4);
+  }
+
+  /**
+   * Test handling overflow of short by switching to counting ints
+   */
+  @Test(groups = "Functional")
+  public void testOverflow()
+  {
+    SparseCount p = new SparseCount(8);
+    p.put('a', Short.MAX_VALUE - 1);
+    p.add('a', 1);
+    assertFalse(p.isUsingInt());
+    p.add('a', 1);
+    assertTrue(p.isUsingInt());
+  }
+
+  /**
+   * Test handling underflow of short by switching to counting ints
+   */
+  @Test(groups = "Functional")
+  public void testUnderflow()
+  {
+    SparseCount p = new SparseCount(8);
+    p.put('a', Short.MIN_VALUE + 1);
+    p.add('a', -1);
+    assertFalse(p.isUsingInt());
+    p.add('a', -1);
+    assertTrue(p.isUsingInt());
+  }
+
+  @Test(groups = "Functional")
+  public void testKeyAt_ValueAt()
+  {
+    SparseCount p = new SparseCount(8);
+    p.put('W', 12);
+    p.put('K', 9);
+    p.put('R', 6);
+    assertEquals(p.size(), 3);
+    assertEquals(p.keyAt(0), 'K');
+    assertEquals(p.valueAt(0), 9);
+    assertEquals(p.keyAt(1), 'R');
+    assertEquals(p.valueAt(1), 6);
+    assertEquals(p.keyAt(2), 'W');
+    assertEquals(p.valueAt(2), 12);
+  }
+
+}
index 4dc44d4..b6f8a25 100644 (file)
@@ -24,15 +24,25 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class StringUtilsTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testInsertCharAt()
   {
diff --git a/test/jalview/util/UrlLinkTest.java b/test/jalview/util/UrlLinkTest.java
new file mode 100644 (file)
index 0000000..d07206f
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.Sequence;
+import jalview.gui.JvOptionPane;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class UrlLinkTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  final static String DB = "Test";
+
+  final static String URL_PREFIX = "http://www.jalview.org/";
+
+  final static String URL_SUFFIX = "/blah";
+
+  final static String SEP = "|";
+
+  final static String DELIM = "$";
+
+  final static String REGEX_NESTED = "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=";
+  
+  final static String REGEX_RUBBISH = "=/[0-9]++/=";
+
+  /**
+   * Test URL link creation when the input string has no regex
+   */
+  @Test(groups = { "Functional" })
+  public void testUrlLinkCreationNoRegex()
+  {
+    // SEQUENCE_ID
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + DELIM + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertFalse(ul.usesDBAccession());
+    assertNull(ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // DB_ACCESSION
+    ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
+            + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertTrue(ul.usesDBAccession());
+    assertNull(ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // Not dynamic
+    ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX.substring(1));
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX + URL_SUFFIX.substring(1), ul.getUrl_prefix());
+    assertFalse(ul.isDynamic());
+    assertFalse(ul.usesDBAccession());
+    assertNull(ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+  }
+
+  /**
+   * Test URL link creation when the input string has regex
+   */
+  @Test(groups = { "Functional" })
+  public void testUrlLinkCreationWithRegex()
+  {
+    // SEQUENCE_ID
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + REGEX_NESTED + DELIM + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertFalse(ul.usesDBAccession());
+    assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
+            ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // DB_ACCESSION
+    ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
+            + REGEX_NESTED + DELIM + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertTrue(ul.usesDBAccession());
+    assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
+            ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // invalid regex
+    ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
+            + REGEX_RUBBISH + DELIM + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertTrue(ul.usesDBAccession());
+    assertEquals(REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2),
+            ul.getRegexReplace());
+    assertFalse(ul.isValid());
+    assertEquals(
+            "Invalid Regular Expression : '"
+                    + REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2)
+                    + "'\n",
+            ul.getInvalidMessage());
+  }
+
+  /**
+   * Test construction of link by substituting sequence id or name
+   */
+  @Test(groups = { "Functional" })
+  public void testMakeUrlNoRegex()
+  {
+    // Single non-regex
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + DELIM + URL_SUFFIX);
+    String idstring = "FER_CAPAA";
+    String[] urls = ul.makeUrls(idstring, true);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+  }
+
+  /**
+   * Test construction of link by substituting sequence id or name using regular
+   * expression
+   */
+  @Test(groups = { "Functional" })
+  public void testMakeUrlWithRegex()
+  {
+    // Unused regex
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
+            + REGEX_NESTED + DELIM + URL_SUFFIX);
+    String idstring = "FER_CAPAA";
+    String[] urls = ul.makeUrls(idstring, true);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // nested regex
+    idstring = "Label:gi|9234|pdb|102L|A";
+    urls = ul.makeUrls(idstring, true);
+
+    assertEquals(2, urls.length);
+    assertEquals("9234", urls[0]);
+    assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals("9234", urls[0]);
+    assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // unmatched regex
+    idstring = "this does not match";
+    urls = ul.makeUrls(idstring, true);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // empty idstring
+    idstring = "";
+    urls = ul.makeUrls(idstring, true);
+
+    assertNull(urls);
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals("", urls[0]);
+    assertEquals(URL_PREFIX + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+  }
+
+  /**
+   * Test creating links with null sequence
+   */
+  @Test(groups = { "Functional" })
+  public void testCreateLinksFromNullSequence()
+  {
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + DELIM + URL_SUFFIX);
+
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(null, linkset);
+
+    String key = DB + SEP + URL_PREFIX;
+    assertEquals(1, linkset.size());
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), DB);
+    assertEquals(linkset.get(key).get(1), DB);
+    assertEquals(linkset.get(key).get(2), null);
+    assertEquals(linkset.get(key).get(3), URL_PREFIX);
+  }
+
+  /**
+   * Test creating links with non-dynamic urlLink
+   */
+  @Test(groups = { "Functional" })
+  public void testCreateLinksForNonDynamic()
+  {
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX);
+
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(null, linkset);
+
+    String key = DB + SEP + URL_PREFIX + URL_SUFFIX;
+    assertEquals(1, linkset.size());
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), DB);
+    assertEquals(linkset.get(key).get(1), DB);
+    assertEquals(linkset.get(key).get(2), null);
+    assertEquals(linkset.get(key).get(3), URL_PREFIX + URL_SUFFIX);
+  }
+
+  /**
+   * Test creating links
+   */
+  @Test(groups = { "Functional" })
+  public void testCreateLinksFromSequence()
+  {
+
+    // create list of links and list of DBRefs
+    List<String> links = new ArrayList<String>();
+    List<DBRefEntry> refs = new ArrayList<DBRefEntry>();
+
+    // links as might be added into Preferences | Connections dialog
+    links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
+            + SEQUENCE_ID + "$");
+    links.add("UNIPROT | http://www.uniprot.org/uniprot/$" + DB_ACCESSION
+            + "$");
+    links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$"
+            + DB_ACCESSION + "$");
+
+    // make seq0 dbrefs
+    refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR001041"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR006058"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR012675"));
+
+    Sequence seq0 = new Sequence("FER1", "AKPNGVL");
+
+    // add all the dbrefs to the sequence
+    seq0.addDBRef(refs.get(0));
+    seq0.addDBRef(refs.get(1));
+    seq0.addDBRef(refs.get(2));
+    seq0.addDBRef(refs.get(3));
+    seq0.createDatasetSequence();
+
+    // Test where link takes a sequence id as replacement
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + DELIM + URL_SUFFIX);
+
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(seq0, linkset);
+
+    String key = seq0.getName() + SEP + URL_PREFIX + seq0.getName()
+            + URL_SUFFIX;
+    assertEquals(1, linkset.size());
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), DB);
+    assertEquals(linkset.get(key).get(1), DB);
+    assertEquals(linkset.get(key).get(2), seq0.getName());
+    assertEquals(linkset.get(key).get(3), URL_PREFIX + seq0.getName()
+            + URL_SUFFIX);
+
+    // Test where link takes a db annotation id and only has one dbref
+    ul = new UrlLink(links.get(1));
+    linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(seq0, linkset);
+
+    key = "P83527|http://www.uniprot.org/uniprot/P83527";
+    assertEquals(1, linkset.size());
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), DBRefSource.UNIPROT);
+    assertEquals(linkset.get(key).get(1), DBRefSource.UNIPROT + SEP
+            + "P83527");
+    assertEquals(linkset.get(key).get(2), "P83527");
+    assertEquals(linkset.get(key).get(3),
+            "http://www.uniprot.org/uniprot/P83527");
+
+    // Test where link takes a db annotation id and has multiple dbrefs
+    ul = new UrlLink(links.get(2));
+    linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(seq0, linkset);
+    assertEquals(3, linkset.size());
+
+    // check each link made it in correctly
+    key = "IPR001041|http://www.ebi.ac.uk/interpro/entry/IPR001041";
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), "INTERPRO");
+    assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR001041");
+    assertEquals(linkset.get(key).get(2), "IPR001041");
+    assertEquals(linkset.get(key).get(3),
+            "http://www.ebi.ac.uk/interpro/entry/IPR001041");
+
+    key = "IPR006058|http://www.ebi.ac.uk/interpro/entry/IPR006058";
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), "INTERPRO");
+    assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR006058");
+    assertEquals(linkset.get(key).get(2), "IPR006058");
+    assertEquals(linkset.get(key).get(3),
+            "http://www.ebi.ac.uk/interpro/entry/IPR006058");
+
+    key = "IPR012675|http://www.ebi.ac.uk/interpro/entry/IPR012675";
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), "INTERPRO");
+    assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR012675");
+    assertEquals(linkset.get(key).get(2), "IPR012675");
+    assertEquals(linkset.get(key).get(3),
+            "http://www.ebi.ac.uk/interpro/entry/IPR012675");
+
+    // Test where there are no matching dbrefs for the link
+    ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
+            + URL_SUFFIX);
+    linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(seq0, linkset);
+    assertTrue(linkset.isEmpty());
+  }
+
+}
index 200cfbb..26c3574 100644 (file)
@@ -24,16 +24,26 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.gui.JvOptionPane;
+
 import java.awt.Color;
 import java.lang.reflect.Field;
 import java.util.Random;
 
 import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ViewStyleTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   Random r = new Random();
 
   /**
index acb9f33..9cc4fc2 100644 (file)
@@ -34,15 +34,25 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 
 import java.util.Collections;
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class AlignCalcManagerTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private AlignFrame alignFrame;
 
   /**
index 4b9437a..95863e7 100644 (file)
@@ -25,18 +25,27 @@ import static org.testng.AssertJUnit.assertTrue;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.structure.StructureImportSettings;
 import jalview.structure.StructureImportSettings.StructureParser;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class PDBSequenceFetcherTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   SequenceFetcher sf;
 
   @BeforeMethod(alwaysRun = true)
index bc9f9a2..32afd5f 100644 (file)
@@ -25,6 +25,7 @@ import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.ws.seqfetcher.ASequenceFetcher;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
@@ -32,9 +33,18 @@ import java.util.Enumeration;
 import java.util.List;
 import java.util.Vector;
 
+import org.testng.annotations.BeforeClass;
+
 public class SequenceFetcherTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * simple run method to test dbsources.
    * 
index 2df8be6..2f548d0 100644 (file)
@@ -29,15 +29,25 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.UniprotEntry;
+import jalview.gui.JvOptionPane;
 
 import java.io.Reader;
 import java.io.StringReader;
 import java.util.Vector;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class UniprotTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   // adapted from http://www.uniprot.org/uniprot/A9CKP4.xml
   private static final String UNIPROT_XML = "<?xml version='1.0' encoding='UTF-8'?>"
           + "<uniprot>"
index c894fd1..2f28484 100644 (file)
 package jalview.ws.dbsources;
 
 import jalview.datamodel.AlignmentI;
+import jalview.gui.JvOptionPane;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class XfamFetcherTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "External" })
   public void testRfamSeed() throws Exception
   {
index e323a0d..40737ca 100644 (file)
@@ -23,10 +23,21 @@ package jalview.ws.ebi;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class EBIFetchClientTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Test method that constructs URL to fetch from
    */
index d672ab6..80b48c3 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.ws.gui;
 
 import jalview.bin.Cache;
+import jalview.gui.JvOptionPane;
 import jalview.gui.WsJobParameters;
 import jalview.util.MessageManager;
 import jalview.ws.jabaws.JalviewJabawsTestUtils;
@@ -46,6 +47,14 @@ import compbio.metadata.PresetManager;
 
 public class Jws2ParamView
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * which services to test
    */
index 9f62481..3573f50 100644 (file)
@@ -26,7 +26,10 @@ import static org.testng.AssertJUnit.assertTrue;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.gui.JvOptionPane;
 import jalview.io.AnnotationFile;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 import jalview.io.StockholmFileTest;
 import jalview.ws.jws2.AADisorderClient;
@@ -44,6 +47,14 @@ import org.testng.annotations.Test;
 @Test(groups = { "External" })
 public class DisorderAnnotExportImport
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   public static String testseqs = "examples/uniref50.fa";
 
   public static Jws2Discoverer disc;
@@ -71,7 +82,7 @@ public class DisorderAnnotExportImport
     assertTrue("Couldn't discover any IUPred services to use to test.",
             iupreds.size() > 0);
     jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
-    af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.FormatAdapter.FILE);
+    af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.DataSourceType.FILE);
     assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
   }
 
@@ -119,16 +130,16 @@ public class DisorderAnnotExportImport
     {
       orig_alig.deleteAnnotation(aa);
     }
-    testAnnotationFileIO("Testing IUPred Annotation IO", orig_alig);
+    checkAnnotationFileIO("Testing IUPred Annotation IO", orig_alig);
 
   }
 
-  public static void testAnnotationFileIO(String testname, AlignmentI al)
+  static void checkAnnotationFileIO(String testname, AlignmentI al)
   {
     try
     {
-      String aligfileout = new FormatAdapter().formatSequences("PFAM",
-              al.getSequencesArray());
+      String aligfileout = FileFormat.Pfam.getAlignmentFile().print(
+              al.getSequencesArray(), true);
       String anfileout = new AnnotationFile()
               .printAnnotationsForAlignment(al);
       assertTrue(
@@ -146,13 +157,13 @@ public class DisorderAnnotExportImport
               + "\n<<EOF\n");
 
       AlignmentI al_new = new FormatAdapter().readFile(aligfileout,
-              FormatAdapter.PASTE, "PFAM");
+              DataSourceType.PASTE, FileFormat.Pfam);
       assertTrue(
               "Test "
                       + testname
                       + "\nregenerated annotation file did not annotate alignment.",
               new AnnotationFile().readAnnotationFile(al_new, anfileout,
-                      FormatAdapter.PASTE));
+                      DataSourceType.PASTE));
 
       // test for consistency in io
       StockholmFileTest.testAlignmentEquivalence(al, al_new, true);
index 4414782..12f5e1b 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.ws.jabaws;
 
+import jalview.gui.JvOptionPane;
 import jalview.ws.jws2.Jws2Discoverer;
 
 import java.util.Vector;
@@ -33,6 +34,13 @@ public class JalviewJabawsTestUtils
 {
 
   @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @BeforeClass(alwaysRun = true)
   public static void setUpBeforeClass() throws Exception
   {
   }
index 7f94b6b..b8fe0a3 100644 (file)
@@ -26,7 +26,10 @@ import static org.testng.AssertJUnit.assertTrue;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
 import jalview.gui.Jalview2XML;
+import jalview.gui.JvOptionPane;
 import jalview.io.AnnotationFile;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 import jalview.io.StockholmFileTest;
 import jalview.ws.jws2.JPred301Client;
@@ -53,6 +56,14 @@ import compbio.metadata.WrongParameterException;
 
 public class JpredJabaStructExportImport
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   public static String testseqs = "examples/uniref50.fa";
 
   public static Jws2Discoverer disc;
@@ -81,7 +92,7 @@ public class JpredJabaStructExportImport
     System.out.println("State of jpredws: " + jpredws);
     Assert.assertNotNull(jpredws, "jpredws is null!");
     jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
-    af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.FormatAdapter.FILE);
+    af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.DataSourceType.FILE);
     assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
   }
 
@@ -177,8 +188,8 @@ public class JpredJabaStructExportImport
     try
     {
       // what format would be appropriate for RNAalifold annotations?
-      String aligfileout = new FormatAdapter().formatSequences("PFAM",
-              al.getSequencesArray());
+      String aligfileout = FileFormat.Pfam.getAlignmentFile().print(
+              al.getSequencesArray(), true);
 
       String anfileout = new AnnotationFile()
               .printAnnotationsForAlignment(al);
@@ -198,13 +209,13 @@ public class JpredJabaStructExportImport
 
       // again what format would be appropriate?
       AlignmentI al_new = new FormatAdapter().readFile(aligfileout,
-              FormatAdapter.PASTE, "PFAM");
+              DataSourceType.PASTE, FileFormat.Fasta);
       assertTrue(
               "Test "
                       + testname
                       + "\nregenerated annotation file did not annotate alignment.",
               new AnnotationFile().readAnnotationFile(al_new, anfileout,
-                      FormatAdapter.PASTE));
+                      DataSourceType.PASTE));
 
       // test for consistency in io
       StockholmFileTest.testAlignmentEquivalence(al, al_new, false);
index 53ab8d9..998524a 100644 (file)
@@ -22,10 +22,13 @@ package jalview.ws.jabaws;
 
 import static org.testng.AssertJUnit.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.ArrayList;
 import java.util.List;
 
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import compbio.data.msa.MsaWS;
@@ -38,6 +41,13 @@ import compbio.ws.client.Services;
 public class MinJabawsClientTests
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * simple test for the benefit of JAL-1338
    * 
index 7bb6bdd..06c803f 100644 (file)
@@ -27,8 +27,10 @@ import jalview.bin.Cache;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.gui.Jalview2XML;
+import jalview.gui.JvOptionPane;
 import jalview.io.AnnotationFile;
-import jalview.io.FileLoader;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
 import jalview.io.StockholmFileTest;
 import jalview.ws.jws2.Jws2Discoverer;
@@ -55,6 +57,14 @@ import compbio.metadata.WrongParameterException;
 
 public class RNAStructExportImport
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   private static final String JAR_FILE_NAME = "testRnalifold_param.jar";
 
   public static String testseqs = "examples/RF00031_folded.stk";
@@ -90,9 +100,9 @@ public class RNAStructExportImport
       Assert.fail("no web service");
     }
 
-    FileLoader fl = new FileLoader(false);
+    jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
 
-    af = fl.LoadFileWaitTillLoaded(testseqs, FormatAdapter.FILE);
+    af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.DataSourceType.FILE);
 
     assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
 
@@ -191,8 +201,8 @@ public class RNAStructExportImport
     try
     {
       // what format would be appropriate for RNAalifold annotations?
-      String aligfileout = new FormatAdapter().formatSequences("PFAM",
-              al.getSequencesArray());
+      String aligfileout = FileFormat.Pfam.getAlignmentFile().print(
+              al.getSequencesArray(), true);
 
       String anfileout = new AnnotationFile()
               .printAnnotationsForAlignment(al);
@@ -212,13 +222,13 @@ public class RNAStructExportImport
 
       // again what format would be appropriate?
       AlignmentI al_new = new FormatAdapter().readFile(aligfileout,
-              FormatAdapter.PASTE, "PFAM");
+              DataSourceType.PASTE, FileFormat.Pfam);
       assertTrue(
               "Test "
                       + testname
                       + "\nregenerated annotation file did not annotate alignment.",
               new AnnotationFile().readAnnotationFile(al_new, anfileout,
-                      FormatAdapter.PASTE));
+                      DataSourceType.PASTE));
 
       // test for consistency in io
       StockholmFileTest.testAlignmentEquivalence(al, al_new, false);
index 1e02213..0662e5b 100644 (file)
@@ -25,6 +25,7 @@ import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.bin.Cache;
+import jalview.gui.JvOptionPane;
 import jalview.ws.jabaws.JalviewJabawsTestUtils;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 
@@ -43,6 +44,14 @@ import compbio.metadata.WrongParameterException;
 
 public class ParameterUtilsTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /*
    * To limit tests to specify services, add them to this list; leave list empty
    * to test all
index 12556b3..7a9419a 100644 (file)
@@ -23,13 +23,23 @@ package jalview.ws.rest;
 import static org.testng.AssertJUnit.assertEquals;
 
 import jalview.bin.Cache;
+import jalview.gui.JvOptionPane;
 
 import java.util.Vector;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class RestClientTest
 {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * Refactored 'as is' from main method
    */
index 30383f7..709f2c5 100644 (file)
@@ -24,9 +24,11 @@ import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
 
 import java.util.Map;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 /**
@@ -36,6 +38,13 @@ import org.testng.annotations.Test;
 public class ShmmrRSBSService
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testShmmrService()
   {
@@ -53,10 +62,10 @@ public class ShmmrRSBSService
     assertNotNull(_rc);
     AlignFrame alf = new jalview.io.FileLoader(false)
             .LoadFileWaitTillLoaded("examples/testdata/smad.fa",
-                    jalview.io.FormatAdapter.FILE);
+                    jalview.io.DataSourceType.FILE);
     assertNotNull("Couldn't find test data.", alf);
     alf.loadJalviewDataFile("examples/testdata/smad_groups.jva",
-            jalview.io.FormatAdapter.FILE, null, null);
+            jalview.io.DataSourceType.FILE, null, null);
     assertTrue(
             "Couldn't load the test data's annotation file (should be 5 groups but found "
                     + alf.getViewport().getAlignment().getGroups().size()
index 3a011df..98ca303 100644 (file)
  */
 package jalview.ws.seqfetcher;
 
+import jalview.gui.JvOptionPane;
+
 import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class DasSequenceFetcher
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   @Test(groups = { "Functional" })
   public void testDasRegistryContact()
   {
index 0a565bd..e35f83e 100644 (file)
@@ -31,6 +31,7 @@ import jalview.datamodel.DBRefSource;
 import jalview.datamodel.FeatureProperties;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
 import jalview.util.DBRefUtils;
 import jalview.ws.SequenceFetcher;
 import jalview.ws.dbsources.Pdb;
@@ -51,6 +52,13 @@ import org.testng.annotations.Test;
 public class DbRefFetcherTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   /**
    * @throws java.lang.Exception
    */
index 8d26c45..45c5412 100644 (file)
@@ -26,7 +26,8 @@ import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
 import jalview.structure.StructureMapping;
 import jalview.xml.binding.sifts.Entry.Entity;
 
@@ -38,6 +39,7 @@ import java.util.HashMap;
 import org.testng.Assert;
 import org.testng.FileAssert;
 import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
@@ -47,6 +49,13 @@ import MCview.PDBfile;
 public class SiftsClientTest
 {
 
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
   public static final String DEFAULT_SIFTS_DOWNLOAD_DIR = System
           .getProperty("user.home")
           + File.separatorChar
@@ -185,7 +194,7 @@ public class SiftsClientTest
     try
     {
       pdbFile = new PDBfile(false, false, false, "test/jalview/io/"
-              + testPDBId + ".pdb", AppletFormatAdapter.FILE);
+              + testPDBId + ".pdb", DataSourceType.FILE);
       siftsClient = new SiftsClient(pdbFile);
     } catch (Exception e)
     {
@@ -387,8 +396,8 @@ public class SiftsClientTest
               testSeq, testPDBId, "A");
       String expectedMappingOutput = "\nSequence ⟷ Structure mapping details\n"
               + "Method: SIFTS\n\n"
-              + "P00221 :  1 - 97 Maps to \n"
-              + "1A70|A :  51 - 147\n\n"
+              + "P00221 :  51 - 147 Maps to \n"
+              + "1A70|A :  1 - 97\n\n"
               + "P00221 AAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLD\n"
               + "       |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n"
               + "1A70|A AAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLD\n\n"
@@ -449,14 +458,14 @@ public class SiftsClientTest
   }
 
   @Test(groups = { "Functional" })
-  public void getEntityByMostOptimalMatchedIdTest()
+  public void getEntityByMostOptimalMatchedIdTest1()
   {
     SiftsClient siftsClientX = null;
     PDBfile pdbFile;
     try
     {
       pdbFile = new PDBfile(false, false, false, "test/jalview/io/2nq2"
-              + ".pdb", AppletFormatAdapter.FILE);
+              + ".pdb", DataSourceType.FILE);
       siftsClientX = new SiftsClient(pdbFile);
     } catch (Exception e)
     {
@@ -472,4 +481,34 @@ public class SiftsClientTest
     Assert.assertEquals(entityD.getEntityId(), "D");
 
   }
+
+  @Test(groups = { "Functional" })
+  public void getEntityByMostOptimalMatchedIdTest2()
+  {
+    // This test is for a SIFTS file in which entity A should map to chain P for
+    // the given PDB Id. All the other chains shouldn't be mapped as there are
+    // no SIFTS entity records for them.
+    SiftsClient siftsClientX = null;
+    PDBfile pdbFile;
+    try
+    {
+      pdbFile = new PDBfile(false, false, false,
+              "test/jalview/io/3ucu.cif", DataSourceType.FILE);
+      siftsClientX = new SiftsClient(pdbFile);
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+    Entity entityA = siftsClientX.getEntityByMostOptimalMatchedId("P");
+    Entity entityP = siftsClientX.getEntityByMostOptimalMatchedId("A");
+    Entity entityR = siftsClientX.getEntityByMostOptimalMatchedId("R");
+    Assert.assertEquals(entityA.getEntityId(), "A");
+    Assert.assertNotEquals(entityR, "A");
+    Assert.assertNotEquals(entityP, "A");
+    Assert.assertNotEquals(entityR, "R");
+    Assert.assertNotEquals(entityP, "P");
+    Assert.assertNull(entityR);
+    Assert.assertNull(entityP);
+
+  }
 }
index fc799bb..3cfc2bb 100755 (executable)
@@ -1245,7 +1245,7 @@ and any path to a file to save to the file]]></string>
                                                                <string><![CDATA[664]]></string>
                                                        </property>
                                                        <property name="sourceName">
-                                                               <string><![CDATA[Jmol-14.2.14_2015.06.11.jar]]></string>
+                                                               <string><![CDATA[Jmol-14.6.4_2016.10.26.jar]]></string>
                                                        </property>
                                                        <property name="overrideUnixPermissions">
                                                                <boolean>false</boolean>
@@ -1263,7 +1263,7 @@ and any path to a file to save to the file]]></string>
                                                                <boolean>true</boolean>
                                                        </property>
                                                        <property name="destinationName">
-                                                               <string><![CDATA[Jmol-14.2.14_2015.06.11.jar]]></string>
+                                                               <string><![CDATA[Jmol-14.6.4_2016.10.26.jar]]></string>
                                                        </property>
                                                        <property name="fileSize">
                                                                <long>5417196</long>
@@ -3846,7 +3846,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[OracleJRE8u5_Macosx.vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE180u92_macosx.vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -3883,7 +3883,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[SunJRE170_03Win32.vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE8u92_windows(x86).vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -3954,10 +3954,10 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="buildWithVM">
-                                                                                               <boolean>true</boolean>
+                                                                                               <boolean>false</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[JRE16_16002HPUX11PA-RISC.vm]]></string>
+                                                                                               <string><![CDATA[JRE16_16010HPUXPA-RISC.vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -3994,7 +3994,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[ORACLEJRE7u60_linux32.vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE180u92_Linux32.vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -4102,7 +4102,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[ORACLEJRE7u60_linux32.vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE180u92_Linux32.vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -4173,7 +4173,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[OracleJRE8u5_windows(x64).vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE180u92_windows(x64).vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -5270,7 +5270,7 @@ Press "Done" to quit the installer.]]></string>
                                        </method>
                                        <method name="put">
                                                <string><![CDATA[com.zerog.ia.installer.options.valid.vm.list]]></string>
-                                               <string><![CDATA[1.7+]]></string>
+                                               <string><![CDATA[1.8+]]></string>
                                        </method>
                                        <method name="put">
                                                <string><![CDATA[com.zerog.ia.project.build.last.date]]></string>
@@ -5366,7 +5366,7 @@ Press "Done" to quit the installer.]]></string>
                                        </method>
                                        <method name="put">
                                                <string><![CDATA[com.zerog.ia.installer.options.platform.macosx.vm.version]]></string>
-                                               <string><![CDATA[1.7+]]></string>
+                                               <string><![CDATA[1.8+]]></string>
                                        </method>
                                        <method name="put">
                                                <string><![CDATA[com.zerog.ia.build.platform.java.novm]]></string>