Merge branch 'develop' into features/JAL-250_hideredundantseqs
authorJim Procter <jprocter@issues.jalview.org>
Tue, 6 Dec 2016 15:30:00 +0000 (15:30 +0000)
committerJim Procter <jprocter@issues.jalview.org>
Tue, 6 Dec 2016 15:30:00 +0000 (15:30 +0000)
619 files changed:
.classpath
AUTHORS
CITATION [new file with mode: 0644]
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/biojson-doc/index.html
examples/biojson-doc/tests/test.html
examples/embedded.html
examples/embeddedWJmol.html
examples/exampleFeatures.txt
examples/exampleFile.jar
examples/exampleFile_2_3.jar
examples/exampleFile_2_7.jar
examples/example_biojs.html
examples/ferredoxin.nw
examples/formComplete.html
examples/groovy/selectColumnsByFeatureAndGroup.groovy
examples/index.html
examples/javascript/facebox-1.3.js [new file with mode: 0644]
examples/javascriptLaunch.html
examples/linkedapplets_ng.html
examples/plantfdx.fa
examples/plantfdx.features
examples/testdata/jal-2005.fa [new file with mode: 0644]
examples/testdata/jal-2005.jvf [new file with mode: 0644]
examples/testdata/localstruct.pdb [new file with mode: 0644]
examples/testdata/test.html
examples/uniref50.fa
examples/uniref50_mz.fa
help/help.jhm
help/helpTOC.xml
help/html/calculations/consensus.html
help/html/calculations/conservation.html
help/html/calculations/pca.html
help/html/calculations/redundancy.html
help/html/calculations/referenceseq.html
help/html/calculations/scorematrices.html
help/html/calculations/sorting.html
help/html/calculations/structureconsensus.html
help/html/calculations/tree.html
help/html/calculations/treeviewer.html
help/html/colourSchemes/abovePID.html
help/html/colourSchemes/annotationColouring.html
help/html/colourSchemes/conservation.html
help/html/colourSchemes/index.html
help/html/colourSchemes/rnahelicesColouring.html
help/html/editing/index.html
help/html/features/annotation.html
help/html/features/annotationsFormat.html
help/html/features/bioJsonFormat.html
help/html/features/chimera.html
help/html/features/clarguments.html
help/html/features/columnFilterByAnnotation.html
help/html/features/commandline.html
help/html/features/creatinFeatures.html
help/html/features/dasfeatures.html
help/html/features/dassettings.html
help/html/features/editingFeatures.html
help/html/features/ensemblsequencefetcher.html
help/html/features/featuresFormat.html
help/html/features/featuresettings.html
help/html/features/groovy.html
help/html/features/hiddenRegions.html
help/html/features/jmol.html
help/html/features/mmcif.html
help/html/features/multipleViews.html
help/html/features/pdbseqfetcher.png
help/html/features/pdbsequencefetcher.html
help/html/features/pdbviewer.html
help/html/features/preferences.html
help/html/features/search.html
help/html/features/seqfeatures.html
help/html/features/seqfetch.html
help/html/features/seqmappings.html
help/html/features/siftsmapping.html
help/html/features/splitView.html
help/html/features/structurechooser.html
help/html/features/uniprotqueryfields.html
help/html/features/uniprotsequencefetcher.html
help/html/features/varna.html
help/html/features/viewingpdbs.html
help/html/features/xsspannotation.html
help/html/groovy/featureCounter.html
help/html/index.html
help/html/io/export.html
help/html/io/exportseqreport.html
help/html/io/fileformats.html
help/html/io/index.html
help/html/io/modellerpir.html
help/html/io/tcoffeescores.html
help/html/keys.html
help/html/memory.html
help/html/menus/alignmentMenu.html
help/html/menus/alwannotation.html
help/html/menus/alwannotationpanel.html
help/html/menus/alwcalculate.html
help/html/menus/alwedit.html
help/html/menus/alwfile.html
help/html/menus/alwformat.html
help/html/menus/alwselect.html
help/html/menus/desktopMenu.html
help/html/menus/index.html
help/html/menus/popupMenu.html
help/html/menus/wsmenu.html
help/html/misc/aaproperties.html
help/html/na/index.html
help/html/privacy.html
help/html/releases.html
help/html/vamsas/index.html
help/html/webServices/AACon.html
help/html/webServices/JABAWS.html
help/html/webServices/RNAalifold.html
help/html/webServices/dbreffetcher.html
help/html/webServices/index.html
help/html/webServices/jnet.html
help/html/webServices/msaclient.html
help/html/webServices/newsreader.html
help/html/webServices/proteinDisorder.html
help/html/webServices/shmr.html
help/html/webServices/urllinks.html
help/html/webServices/webServicesParams.html
help/html/webServices/webServicesPrefs.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/embl_mapping.xml
resources/fts/pdb_data_columns.txt
resources/lang/Messages.properties
resources/lang/Messages_es.properties
resources/uniprot_mapping.xml
src/MCview/AppletPDBCanvas.java
src/MCview/AppletPDBViewer.java
src/MCview/Atom.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/AlignmentSorter.java
src/jalview/analysis/AlignmentUtils.java
src/jalview/analysis/Conservation.java
src/jalview/analysis/CrossRef.java
src/jalview/analysis/Dna.java
src/jalview/analysis/Finder.java
src/jalview/analysis/NJTree.java
src/jalview/analysis/Rna.java
src/jalview/analysis/SeqsetUtils.java
src/jalview/analysis/StructureFrequency.java
src/jalview/api/AlignViewControllerI.java
src/jalview/api/AlignViewportI.java
src/jalview/api/DBRefEntryI.java
src/jalview/api/FeatureColourI.java
src/jalview/api/FeatureRenderer.java
src/jalview/api/FeaturesSourceI.java
src/jalview/api/SiftsClientI.java
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AlignViewport.java
src/jalview/appletgui/AlignmentPanel.java
src/jalview/appletgui/AnnotationColourChooser.java
src/jalview/appletgui/AnnotationColumnChooser.java
src/jalview/appletgui/AnnotationRowFilter.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/FeatureSettings.java
src/jalview/appletgui/Finder.java
src/jalview/appletgui/IdPanel.java
src/jalview/appletgui/ScalePanel.java
src/jalview/appletgui/SeqCanvas.java
src/jalview/appletgui/SeqPanel.java
src/jalview/appletgui/SliderPanel.java
src/jalview/appletgui/TreeCanvas.java
src/jalview/bin/ArgsParser.java
src/jalview/bin/Cache.java
src/jalview/bin/Jalview.java
src/jalview/bin/JalviewLite.java
src/jalview/bin/JalviewLiteURLRetrieve.java
src/jalview/commands/TrimRegionCommand.java
src/jalview/controller/AlignViewController.java
src/jalview/datamodel/AlignedCodonFrame.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentAnnotation.java
src/jalview/datamodel/AlignmentI.java
src/jalview/datamodel/ColumnSelection.java
src/jalview/datamodel/HiddenSequences.java
src/jalview/datamodel/MappingType.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/Sequence.java
src/jalview/datamodel/SequenceFeature.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/datamodel/SequenceI.java
src/jalview/datamodel/xdb/embl/EmblEntry.java
src/jalview/datamodel/xdb/embl/EmblFile.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/EnsemblCdna.java
src/jalview/ext/ensembl/EnsemblCds.java
src/jalview/ext/ensembl/EnsemblFeatures.java
src/jalview/ext/ensembl/EnsemblGene.java
src/jalview/ext/ensembl/EnsemblGenome.java
src/jalview/ext/ensembl/EnsemblGenomes.java
src/jalview/ext/ensembl/EnsemblInfo.java
src/jalview/ext/ensembl/EnsemblLookup.java
src/jalview/ext/ensembl/EnsemblProtein.java
src/jalview/ext/ensembl/EnsemblRestClient.java
src/jalview/ext/ensembl/EnsemblSeqProxy.java
src/jalview/ext/ensembl/EnsemblSequenceFetcher.java
src/jalview/ext/ensembl/EnsemblSymbol.java
src/jalview/ext/ensembl/EnsemblXref.java
src/jalview/ext/ensembl/Species.java
src/jalview/ext/htsjdk/HtsContigDb.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/ext/jmol/JmolParser.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/ext/so/SequenceOntology.java
src/jalview/fts/api/FTSRestClientI.java
src/jalview/fts/core/DecimalFormatTableCellRenderer.java
src/jalview/fts/core/FTSDataColumnPreferences.java
src/jalview/fts/core/FTSRestClient.java
src/jalview/fts/core/FTSRestRequest.java
src/jalview/fts/core/FTSRestResponse.java
src/jalview/fts/core/GFTSPanel.java
src/jalview/fts/service/pdb/PDBFTSPanel.java
src/jalview/fts/service/pdb/PDBFTSRestClient.java
src/jalview/fts/service/uniprot/UniProtFTSRestClient.java
src/jalview/fts/service/uniprot/UniprotFTSPanel.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/AnnotationColourChooser.java
src/jalview/gui/AnnotationColumnChooser.java
src/jalview/gui/AnnotationExporter.java
src/jalview/gui/AnnotationLabels.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/AnnotationRowFilter.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/Help.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/OptsAndParamsPage.java
src/jalview/gui/OverviewPanel.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/SliderPanel.java
src/jalview/gui/SplitFrame.java
src/jalview/gui/StructureChooser.java
src/jalview/gui/StructureViewer.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/PDBFeatureSettings.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/gff/ExonerateHelper.java
src/jalview/io/gff/Gff2Helper.java
src/jalview/io/gff/Gff3Helper.java
src/jalview/io/gff/GffConstants.java
src/jalview/io/gff/GffHelperBase.java
src/jalview/io/gff/GffHelperFactory.java
src/jalview/io/gff/GffHelperI.java
src/jalview/io/gff/InterProScanHelper.java
src/jalview/io/gff/SequenceOntologyFactory.java
src/jalview/io/gff/SequenceOntologyI.java
src/jalview/io/gff/SequenceOntologyLite.java
src/jalview/io/packed/JalviewDataset.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/jbgui/GStructureChooser.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/renderer/ScaleRenderer.java
src/jalview/renderer/seqfeatures/FeatureRenderer.java
src/jalview/schemes/Blosum62ColourScheme.java
src/jalview/schemes/ColourSchemeI.java
src/jalview/schemes/FeatureColour.java
src/jalview/schemes/FeatureSettingsAdapter.java
src/jalview/schemes/FollowerColourScheme.java
src/jalview/schemes/PIDColourScheme.java
src/jalview/schemes/ResidueColourScheme.java
src/jalview/schemes/ResidueProperties.java
src/jalview/schemes/TCoffeeColourScheme.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/ArrayUtils.java
src/jalview/util/CaseInsensitiveString.java
src/jalview/util/ColorUtils.java
src/jalview/util/Comparison.java
src/jalview/util/DBRefUtils.java
src/jalview/util/DnaUtils.java
src/jalview/util/Format.java
src/jalview/util/HttpUtils.java
src/jalview/util/ImageMaker.java
src/jalview/util/MapList.java
src/jalview/util/MappingUtils.java
src/jalview/util/Platform.java
src/jalview/util/QuickSort.java
src/jalview/util/SparseCount.java [new file with mode: 0644]
src/jalview/util/StringUtils.java
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/AlignCalcWorker.java
src/jalview/workers/AlignmentAnnotationFactory.java
src/jalview/workers/AnnotationProviderI.java
src/jalview/workers/ColumnCounterWorker.java
src/jalview/workers/ComplementConsensusThread.java
src/jalview/workers/ConsensusThread.java
src/jalview/workers/ConservationThread.java
src/jalview/workers/FeatureCounterI.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/DasSequenceFeatureFetcher.java
src/jalview/ws/SequenceFetcherFactory.java
src/jalview/ws/dbsources/EmblXmlSource.java
src/jalview/ws/dbsources/Pdb.java
src/jalview/ws/dbsources/Pfam.java
src/jalview/ws/dbsources/PfamFull.java
src/jalview/ws/dbsources/PfamSeed.java
src/jalview/ws/dbsources/RfamFull.java
src/jalview/ws/dbsources/RfamSeed.java
src/jalview/ws/dbsources/Uniprot.java
src/jalview/ws/dbsources/Xfam.java
src/jalview/ws/dbsources/das/datamodel/DasSourceRegistry.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/MsaWSThread.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/ASequenceFetcher.java
src/jalview/ws/seqfetcher/DbSourceProxyImpl.java
src/jalview/ws/sifts/MappingOutputPojo.java
src/jalview/ws/sifts/SiftsClient.java
src/jalview/ws/sifts/SiftsException.java
src/jalview/ws/sifts/SiftsSettings.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/datamodel/xdb/embl/EmblTestHelper.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/EnsemblRestClientTest.java
test/jalview/ext/ensembl/EnsemblSeqProxyAdapter.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/MouseEventDemo.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 [new file with mode: 0644]
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/BufferedLineReader.java [new file with mode: 0644]
utils/HelpLinksChecker.java
utils/InstallAnywhere/Jalview.iap_xml
utils/JettyExamplesDir.java
utils/MessageBundleChecker.java
utils/getJavaVersion.java
utils/help2Website.java

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 30db2a1..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 4th June 2014.
+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/CITATION b/CITATION
new file mode 100644 (file)
index 0000000..9b06f7c
--- /dev/null
+++ b/CITATION
@@ -0,0 +1,5 @@
+If you use Jalview in your work, please cite the Jalview 2 paper in Bioinformatics:
+
+Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M., Barton, G.J (2009),
+"Jalview version 2: A Multiple Sequence Alignment and Analysis Workbench,"
+Bioinformatics 25 (9) 1189-1191 doi: 10.1093/bioinformatics/btp033 
diff --git a/RELEASE b/RELEASE
index 6cd9254..9bc5817 100644 (file)
--- a/RELEASE
+++ b/RELEASE
@@ -1,2 +1,2 @@
-jalview.release=Release_2_9_0b1_Branch
-jalview.version=2.9.0b2
+jalview.release=releases/Release_2_10_1_Branch
+jalview.version=2.10.1
index caaa7f9..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
@@ -46,7 +49,11 @@ jfreesvg-2.1.jar : GPL v3 licensed library from the JFree suite: http://www.jfre
 
 quaqua: v.8.0 (latest stable) by Randel S Hofer. LGPL and BSD Modified license: downloaded from http://www.randelshofer.ch/quaqua/ 
 
-lib/htsjdk-1.120-SNAPSHOT.jar: built from maven master at https://github.com/samtools/htsjdk MIT License to Broad Institute
+lib/htsjdk-1.120-SNAPSHOT.jar: (currently not required for 2.10) built from maven master at https://github.com/samtools/htsjdk MIT License to Broad Institute
+
+lib/biojava-core-4.1.0.jar LGPLv2.1 - latest license at https://github.com/biojava/biojava/blob/master/LICENSE
+
+lib/biojava-ontology-4.1.0.jar LGPLv2.1 - latest license at https://github.com/biojava/biojava/blob/master/LICENSE
 
 
 Additional dependencies
@@ -54,7 +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
-
-Tools not bundled with Jalview source
-jbake (http://jbake.org MIT license) was used to build the JalviewLite examples pages found in the examples directory.
+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 184596c..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 name="compileApplet" depends="init,clean">
   <mkdir dir="${outputDir}" />
-  <javac source="${javac.source}" target="${javac.target}" srcdir="${sourceDir}" destdir="${outputDir}" debug="${javac.debug}" classpathref="jalviewlite.deps" includes="jalview/appletgui/**" excludes="ext/**,gui/**,jbgui/**,MCview/**,org/**,vamsas/**,jalview/ext/rbvi/**,jalview/ext/paradise/**,jalview/ext/ensembl/**,jalview/ext/so" />
+  <javac source="${javac.source}" target="${javac.target}" srcdir="${sourceDir}" destdir="${outputDir}" debug="${javac.debug}" classpathref="jalviewlite.deps" includes="jalview/appletgui/**" excludes="ext/**,gui/**,jbgui/**,MCview/**,org/**,vamsas/**,jalview/ext/rbvi/**,jalview/ext/paradise/**,jalview/ext/ensembl/**,jalview/ext/so/**" />
 </target>
 
 <target name="packageApplet" depends="compileApplet, buildPropertiesFile">
 </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 7fcca00..7b4daee 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 1f65565..d997f14 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 ba607f4..e0e5741 100755 (executable)
@@ -1,4 +1,24 @@
 <!DOCTYPE html>
+<!--
+ * 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.
+ -->
 <html>
 <head>
     <title>BioJSON Format Documentation</title>
@@ -358,4 +378,4 @@ This page describes the data available in BioJSON format, the main content secti
 </html>
 
 
\ No newline at end of file
index 2cbbd50..c6bebd6 100755 (executable)
@@ -1,3 +1,23 @@
+<!--
+ * 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.
+ -->
 <!DOCTYPE html>
 <html>
 <head>
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 1ecff58..6fdcc07 100644 (file)
@@ -1,5 +1,25 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML+RDFa 1.1//EN">
-<html lang="en" dir="ltr" version="HTML+RDFa 1.1"
+<!--
+ * 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.
+ -->
+ <html lang="en" dir="ltr" version="HTML+RDFa 1.1"
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:dc="http://purl.org/dc/terms/"
        xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#"
@@ -191,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;
@@ -222,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',
@@ -275,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 c0098a9..2de9817 100755 (executable)
@@ -79,12 +79,12 @@ Iron-sulfur (2Fe-2S)        FER_BRANA       -1      47      47      METAL
 Iron-sulfur (2Fe-2S)   FER_BRANA       -1      77      77      METAL
 <html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_8</a></html>     FER_BRANA       -1      8       83      Pfam
 Ferredoxin_fold Status: True Positive  FER_BRANA       -1      2       96      Cath
-Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      91      91      METAL
-Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      96      96      METAL
-Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      99      99      METAL
-Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      129     129     METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_13</a></html>   FER2_ARATH      -1      60      135     Pfam
-Ferredoxin_fold Status: True Positive  FER2_ARATH      -1      50      145     Cath
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      91      91      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      96      96      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      99      99      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      129     129     METAL
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_13</a></html>   FER1_ARATH      -1      60      135     Pfam
+Ferredoxin_fold Status: True Positive  FER1_ARATH      -1      50      145     Cath
 <html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_11</a></html>   Q93Z60_ARATH    -1      60      118     Pfam
 Ferredoxin_fold Status: True Positive  Q93Z60_ARATH    -1      52      118     Cath
 Iron-sulfur (2Fe-2S)   FER1_MAIZE      -1      91      91      METAL
@@ -127,13 +127,13 @@ STARTGROUP        netphos
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00221&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 112_11</a></html>     FER1_SPIOL      -1      112     112     PHOSPHORYLATION (S)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00221&amp;service=NetPhos-2.0">PHOSPHORYLATION (T) 139_13</a></html>     FER1_SPIOL      -1      139     139     PHOSPHORYLATION (T)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00221&amp;service=NetPhos-2.0">PHOSPHORYLATION (Y) 73_7</a></html>       FER1_SPIOL      -1      73      73      PHOSPHORYLATION (Y)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 19_1</a></html>   FER1_ARATH      -1      19      19      PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 24_2</a></html>   FER1_ARATH      -1      24      24      PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 90_9</a></html>   FER1_ARATH      -1      90      90      PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 107_10</a></html> FER1_ARATH      -1      107     107     PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 114_11</a></html> FER1_ARATH      -1      114     114     PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (T) 141_14</a></html> FER1_ARATH      -1      141     141     PHOSPHORYLATION (T)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (Y) 75_7</a></html>   FER1_ARATH      -1      75      75      PHOSPHORYLATION (Y)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 19_1</a></html>   FER2_ARATH      -1      19      19      PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 24_2</a></html>   FER2_ARATH      -1      24      24      PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 90_9</a></html>   FER2_ARATH      -1      90      90      PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 107_10</a></html> FER2_ARATH      -1      107     107     PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 114_11</a></html> FER2_ARATH      -1      114     114     PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (T) 141_14</a></html> FER2_ARATH      -1      141     141     PHOSPHORYLATION (T)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (Y) 75_7</a></html>   FER2_ARATH      -1      75      75      PHOSPHORYLATION (Y)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00227&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 38_3</a></html>       FER_BRANA       -1      38      38      PHOSPHORYLATION (S)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00227&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 62_6</a></html>       FER_BRANA       -1      62      62      PHOSPHORYLATION (S)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00227&amp;service=NetPhos-2.0">PHOSPHORYLATION (T) 89_8</a></html>       FER_BRANA       -1      89      89      PHOSPHORYLATION (T)
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 b6f7bec..6738672 100644 (file)
@@ -1,4 +1,24 @@
 <html>
+<!--
+ * 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.
+ -->
 <header><title>BioJS viewer</title></header>
 
 <body>
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
index 46df4eb..37edb8e 100644 (file)
@@ -1,5 +1,25 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML+RDFa 1.1//EN">
-<html lang="en" dir="ltr" version="HTML+RDFa 1.1"
+<!--
+ * 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.
+ -->
+ <html lang="en" dir="ltr" version="HTML+RDFa 1.1"
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:dc="http://purl.org/dc/terms/"
        xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#"
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 1412a5a..80d7133 100644 (file)
@@ -34,7 +34,7 @@ IETHKEEELTA-
 ----------------------------------------------------------ATYKVKFITPEGEQ
 EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDVT
 IETHREEDMV--
->FER1_ARATH/1-148
+>FER2_ARATH/1-148
 ----MASTALSSAIVGTSFIRRSPAPISLRSLPSANT-QSLFGLKS-GTARGGRVTAMATYKVKFITPEGEL
 EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDVT
 IETHKEEDIV--
@@ -42,7 +42,7 @@ IETHKEEDIV--
 ----------------------------------------------------------ATYKVKFITPEGEQ
 EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDVT
 IETHKEEELV--
->FER2_ARATH/1-148
+>FER1_ARATH/1-148
 ----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQ
 EVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDVV
 IETHKEEAIM--
index 872dadc..6a2e058 100644 (file)
@@ -78,23 +78,23 @@ Iron-sulfur (2Fe-2S)        FER3_RAPSA      -1      77      77      METAL
 R -> K         FER3_RAPSA      -1      91      91      VARIANT
 M -> V         FER3_RAPSA      -1      95      95      VARIANT
 <html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html>       FER3_RAPSA      -1      8       83      Pfam
-Chloroplast    FER1_ARATH      -1      1       52      TRANSIT
-Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      91      91      METAL
-Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      96      96      METAL
-Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      99      99      METAL
-Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      129     129     METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html>     FER1_ARATH      -1      60      135     Pfam
-Iron-sulfur (2Fe-2S)   FER_BRANA       -1      39      39      METAL
-Iron-sulfur (2Fe-2S)   FER_BRANA       -1      44      44      METAL
-Iron-sulfur (2Fe-2S)   FER_BRANA       -1      47      47      METAL
-Iron-sulfur (2Fe-2S)   FER_BRANA       -1      77      77      METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html>       FER_BRANA       -1      8       83      Pfam
 Chloroplast    FER2_ARATH      -1      1       52      TRANSIT
 Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      91      91      METAL
 Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      96      96      METAL
 Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      99      99      METAL
 Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      129     129     METAL
 <html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html>     FER2_ARATH      -1      60      135     Pfam
+Iron-sulfur (2Fe-2S)   FER_BRANA       -1      39      39      METAL
+Iron-sulfur (2Fe-2S)   FER_BRANA       -1      44      44      METAL
+Iron-sulfur (2Fe-2S)   FER_BRANA       -1      47      47      METAL
+Iron-sulfur (2Fe-2S)   FER_BRANA       -1      77      77      METAL
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html>       FER_BRANA       -1      8       83      Pfam
+Chloroplast    FER1_ARATH      -1      1       52      TRANSIT
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      91      91      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      96      96      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      99      99      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      129     129     METAL
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html>     FER1_ARATH      -1      60      135     Pfam
 <html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_118</a></html>     Q93Z60_ARATH    -1      60      118     Pfam
 Chloroplast    FER1_MAIZE      -1      1       52      TRANSIT
 STRAND FER1_MAIZE      -1      57      59      STRAND
diff --git a/examples/testdata/jal-2005.fa b/examples/testdata/jal-2005.fa
new file mode 100644 (file)
index 0000000..cc58469
--- /dev/null
@@ -0,0 +1,16 @@
+>a
+QQQ
+>b
+QQQ
+>c
+QQQ
+>d
+QQQ
+>e
+QQQ
+>f
+QQQ
+>g
+QQQ
+>h
+QQQ
diff --git a/examples/testdata/jal-2005.jvf b/examples/testdata/jal-2005.jvf
new file mode 100644 (file)
index 0000000..8f37849
--- /dev/null
@@ -0,0 +1,11 @@
+feature_1      8c25cd
+
+STARTGROUP     Jalview
+feature_1      a       -1      1       1       feature_1       0.4
+feature_1      a       -1      2       2       feature_1       0.6
+feature_1      b       -1      1       1       feature_1       0.8
+feature_1      b       -1      2       2       feature_1       1.0
+feature_1      c       -1      1       1       feature_1       1.5
+feature_1      d       -1      1       1       feature_1       2.0
+feature_1      e       -1      1       1       feature_1       3.0
+ENDGROUP       Jalview
diff --git a/examples/testdata/localstruct.pdb b/examples/testdata/localstruct.pdb
new file mode 100644 (file)
index 0000000..bdf13db
--- /dev/null
@@ -0,0 +1,51 @@
+ATOM   7013  N   ALA A 650     -32.039 -14.559  -3.977  1.00 97.16           N  
+ATOM   7014  CA  ALA A 650     -33.253 -15.372  -3.971  1.00101.29           C  
+ATOM   7015  C   ALA A 650     -32.928 -16.865  -4.014  1.00102.48           C  
+ATOM   7016  O   ALA A 650     -33.833 -17.704  -4.075  1.00102.31           O  
+ATOM   7017  CB  ALA A 650     -34.168 -14.987  -5.138  1.00 94.98           C  
+ATOM   7018  N   MET A 651     -31.636 -17.186  -3.978  1.00 98.86           N  
+ATOM   7019  CA  MET A 651     -31.164 -18.568  -4.040  1.00 95.81           C  
+ATOM   7020  C   MET A 651     -29.680 -18.618  -3.678  1.00 95.69           C  
+ATOM   7021  O   MET A 651     -28.847 -18.030  -4.367  1.00 93.27           O  
+ATOM   7022  CB  MET A 651     -31.414 -19.157  -5.435  1.00 94.70           C  
+ATOM   7023  CG  MET A 651     -31.097 -18.189  -6.581  1.00 93.74           C  
+ATOM   7024  SD  MET A 651     -31.780 -18.651  -8.198  1.00 87.88           S  
+ATOM   7025  CE  MET A 651     -30.854 -20.142  -8.594  1.00 81.80           C  
+ATOM   7026  N   LYS A 652     -29.355 -19.313  -2.589  1.00 95.36           N  
+ATOM   7027  CA  LYS A 652     -27.982 -19.355  -2.075  1.00 88.97           C  
+ATOM   7028  C   LYS A 652     -27.021 -20.133  -2.984  1.00 89.03           C  
+ATOM   7029  O   LYS A 652     -27.393 -21.143  -3.592  1.00 90.36           O  
+ATOM   7030  CB  LYS A 652     -27.953 -19.930  -0.656  1.00 85.99           C  
+ATOM   7031  N   ARG A 653     -25.784 -19.655  -3.070  1.00 83.57           N  
+ATOM   7032  CA  ARG A 653     -24.765 -20.305  -3.888  1.00 82.09           C  
+ATOM   7033  C   ARG A 653     -23.704 -20.963  -3.017  1.00 79.82           C  
+ATOM   7034  O   ARG A 653     -23.327 -20.431  -1.977  1.00 79.58           O  
+ATOM   7035  CB  ARG A 653     -24.115 -19.291  -4.831  1.00 84.10           C  
+ATOM   7036  CG  ARG A 653     -23.554 -18.068  -4.129  1.00 82.91           C  
+ATOM   7037  CD  ARG A 653     -23.098 -17.010  -5.124  1.00 84.28           C  
+ATOM   7038  NE  ARG A 653     -23.064 -15.675  -4.527  1.00 83.48           N  
+ATOM   7039  CZ  ARG A 653     -21.959 -15.047  -4.134  1.00 82.34           C  
+ATOM   7040  NH1 ARG A 653     -20.770 -15.621  -4.277  1.00 80.52           N  
+ATOM   7041  NH2 ARG A 653     -22.045 -13.836  -3.602  1.00 84.76           N  
+ATOM   7042  N   ARG A 654     -23.219 -22.122  -3.446  1.00 83.16           N  
+ATOM   7043  CA  ARG A 654     -22.263 -22.882  -2.647  1.00 84.47           C  
+ATOM   7044  C   ARG A 654     -20.845 -22.831  -3.207  1.00 82.72           C  
+ATOM   7045  O   ARG A 654     -20.611 -22.306  -4.294  1.00 84.47           O  
+ATOM   7046  CB  ARG A 654     -22.720 -24.337  -2.500  1.00 86.90           C  
+ATOM   7047  CG  ARG A 654     -22.700 -25.156  -3.785  1.00 90.62           C  
+ATOM   7048  CD  ARG A 654     -21.792 -26.372  -3.625  1.00 94.56           C  
+ATOM   7049  NE  ARG A 654     -22.296 -27.559  -4.313  1.00100.64           N  
+ATOM   7050  CZ  ARG A 654     -21.755 -28.770  -4.203  1.00101.77           C  
+ATOM   7051  NH1 ARG A 654     -20.690 -28.949  -3.433  1.00 99.43           N  
+ATOM   7052  NH2 ARG A 654     -22.277 -29.803  -4.858  1.00103.21           N  
+ATOM   7053  N   ARG A 655     -19.901 -23.377  -2.452  1.00 80.06           N  
+ATOM   7054  CA  ARG A 655     -18.522 -23.461  -2.899  1.00 81.57           C  
+ATOM   7055  C   ARG A 655     -18.393 -24.576  -3.925  1.00 85.28           C  
+ATOM   7056  O   ARG A 655     -19.120 -25.567  -3.865  1.00 87.19           O  
+ATOM   7057  CB  ARG A 655     -17.617 -23.772  -1.718  1.00 83.19           C  
+ATOM   7058  CG  ARG A 655     -17.720 -25.217  -1.265  1.00 86.49           C  
+ATOM   7059  CD  ARG A 655     -17.099 -25.402   0.093  1.00 85.01           C  
+ATOM   7060  NE  ARG A 655     -15.880 -24.617   0.223  1.00 85.24           N  
+ATOM   7061  CZ  ARG A 655     -15.123 -24.608   1.310  1.00 87.53           C  
+ATOM   7062  NH1 ARG A 655     -15.465 -25.351   2.354  1.00 87.44           N  
+ATOM   7063  NH2 ARG A 655     -14.028 -23.864   1.350  1.00 89.64           N  
index 1e41232..12be42e 100644 (file)
@@ -1,4 +1,24 @@
 <html>
+<!--
+ * 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.
+ -->
 <input type="hidden" name="seqData" id="seqData" value='{"seqs":[{"name":"FER_CAPAA/1-97","start":1,"svid":"1.0","end":97,"id":"4362914","seq":"-----------------------------------------------------------ASYKVKLITPDGPIEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG-","order":1},{"name":"FER_CAPAN/1-144","start":1,"svid":"1.0","end":144,"id":"87519910","seq":"MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMASYKVKLITPDGPIEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG-","order":2},{"name":"FER1_SOLLC/1-144","start":1,"svid":"1.0","end":144,"id":"706449716","seq":"MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPEGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDGNFLDEDQEAAGFVLTCVAYPKGDVTIETHKEEELTA-","order":3},{"name":"Q93XJ9_SOLTU/1-144","start":1,"svid":"1.0","end":144,"id":"1704607829","seq":"MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPDGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDGKFLDDDQEAAGFVLTCVAYPKCDVTIETHKEEELTA-","order":4},{"name":"FER1_PEA/1-149","start":1,"svid":"1.0","end":149,"id":"1901660614","seq":"MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMASYKVKLVTPDGTQEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDGSFLDDEQIEAGFVLTCVAYPTSDVVIETHKEEDLTA-","order":5},{"name":"Q7XA98_TRIPR/1-152","start":1,"svid":"1.0","end":152,"id":"1329985289","seq":"MATT---PALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGFGLKSVSTKRGDLAVAMATYKVKLITPEGPQEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDGSFLDDEQIEGGWVLTCVAFPTSDVTIETHKEEELTA-","order":6},{"name":"FER1_MESCR/1-148","start":1,"svid":"1.0","end":148,"id":"966876644","seq":"MAAT--TAALSGATMSTAFAPK--TPPMTAALPTNVGR--ALFGLKS-SASR-GRVTAMAAYKVTLVTPEGKQELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDGSFLDDDQIKEGWVLTCVAYPTGDVTIETHKEEELTA-","order":7},{"name":"FER1_SPIOL/1-147","start":1,"svid":"1.0","end":147,"id":"235809389","seq":"MAAT--TTTMMG--MATTFVPKPQAPPMMAALPSNTGR--SLFGLKT-GSR--GGRMTMAAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDVTIETHKEEELTA-","order":8},{"name":"FER3_RAPSA/1-96","start":1,"svid":"1.0","end":96,"id":"924845395","seq":"-----------------------------------------------------------ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDVTIETHREEDMV--","order":9},{"name":"FER1_ARATH/1-148","start":1,"svid":"1.0","end":148,"id":"1472020737","seq":"MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGELEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDVTIETHKEEDIV--","order":10},{"name":"FER_BRANA/1-96","start":1,"svid":"1.0","end":96,"id":"1690335343","seq":"-----------------------------------------------------------ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDVTIETHKEEELV--","order":11},{"name":"FER2_ARATH/1-148","start":1,"svid":"1.0","end":148,"id":"467823576","seq":"MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDVVIETHKEEAIM--","order":12},{"name":"Q93Z60_ARATH/1-118","start":1,"svid":"1.0","end":118,"id":"752877418","seq":"MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD--------------------------------","order":13},{"name":"FER1_MAIZE/1-150","start":1,"svid":"1.0","end":150,"id":"299304633","seq":"MATVLGSPRAPAFFFSSSSLRAAPAPTAV--ALPAAKV--GIMGRSA-SSRR--RLRAQATYNVKLITPEGEVELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDVVIETHKEEELTGA","order":14},{"name":"O80429_MAIZE/1-140","start":1,"svid":"1.0","end":140,"id":"1991448556","seq":"MAAT---------ALSMSILR---APPPCFSSPLRLRV--AVAKPLA-APMRRQLLRAQATYNVKLITPEGEVELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQSFLNDNQVADGWVLTCAAYPTSDVVIETHKEDDLL--","order":15},{"name":"1A70|/1-97","start":1,"svid":"1.0","end":97,"id":"2114395721","seq":"-----------------------------------------------------------AAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDVTIETHKKEELTA","order":16}],"appSettings":{"globalColorScheme":"foo","webStartUrl":"www.jalview.org/services/launchApp","application":"Jalview","hiddenSeqs":"2114395721","showSeqFeatures":"false","version":"2.9"},"seqGroups":[{"displayText":true,"startRes":59,"groupName":"ferredoxin","endRes":124,"colourText":false,"seqsHash":["1472020737","299304633","966876644","1901660614","706449716","235809389","467823576","924845395","1690335343","4362914","87519910","752877418","1329985289","1991448556","1704607829"],"svid":"1.0","showNonconserved":false,"colourScheme":"Zappo","displayBoxes":true}],"alignAnnotation":[{"svid":"1.0","annotations":[{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"1","value":1,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"2","value":2,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"3","value":3,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"4","value":4,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"5","value":5,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"6","value":6,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"7","value":7,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"9","value":9,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"}],"description":"New description","label":"Secondary Structure"},{"svid":"1.0","annotations":[{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"}],"description":"New description","label":"Iron Sulphur Contacts"}],"svid":"1.0","seqFeatures":[{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:   1  1a70 ","xStart":59,"xEnd":60,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:   2  1a70 ","xStart":60,"xEnd":61,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:   3  1a70 ","xStart":61,"xEnd":62,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:   4  1a70 ","xStart":62,"xEnd":63,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:   5  1a70 ","xStart":63,"xEnd":64,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:   6  1a70 ","xStart":64,"xEnd":65,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:   7  1a70 ","xStart":65,"xEnd":66,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:   8  1a70 ","xStart":66,"xEnd":67,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:   9  1a70 ","xStart":67,"xEnd":68,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:  10  1a70 ","xStart":68,"xEnd":69,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:  11  1a70 ","xStart":69,"xEnd":70,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:  12  1a70 ","xStart":70,"xEnd":71,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:  13  1a70 ","xStart":71,"xEnd":72,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:  14  1a70 ","xStart":72,"xEnd":73,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:  15  1a70 ","xStart":73,"xEnd":74,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:  16  1a70 ","xStart":74,"xEnd":75,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:  17  1a70 ","xStart":75,"xEnd":76,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:  18  1a70 ","xStart":76,"xEnd":77,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:  19  1a70 ","xStart":77,"xEnd":78,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  20  1a70 ","xStart":78,"xEnd":79,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  21  1a70 ","xStart":79,"xEnd":80,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:  22  1a70 ","xStart":80,"xEnd":81,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:  23  1a70 ","xStart":81,"xEnd":82,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:  24  1a70 ","xStart":82,"xEnd":83,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:  25  1a70 ","xStart":83,"xEnd":84,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  26  1a70 ","xStart":84,"xEnd":85,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:  27  1a70 ","xStart":85,"xEnd":86,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:  28  1a70 ","xStart":86,"xEnd":87,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:  29  1a70 ","xStart":87,"xEnd":88,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:  30  1a70 ","xStart":88,"xEnd":89,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:  31  1a70 ","xStart":89,"xEnd":90,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:  32  1a70 ","xStart":90,"xEnd":91,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:  33  1a70 ","xStart":91,"xEnd":92,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  34  1a70 ","xStart":92,"xEnd":93,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:  35  1a70 ","xStart":93,"xEnd":94,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:  36  1a70 ","xStart":94,"xEnd":95,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:  37  1a70 ","xStart":95,"xEnd":96,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:  38  1a70 ","xStart":96,"xEnd":97,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:  39  1a70 ","xStart":97,"xEnd":98,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ARG:  40  1a70 ","xStart":98,"xEnd":99,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:  41  1a70 ","xStart":99,"xEnd":100,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:  42  1a70 ","xStart":100,"xEnd":101,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:  43  1a70 ","xStart":101,"xEnd":102,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:  44  1a70 ","xStart":102,"xEnd":103,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:  45  1a70 ","xStart":103,"xEnd":104,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:  46  1a70 ","xStart":104,"xEnd":105,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:  47  1a70 ","xStart":105,"xEnd":106,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:  48  1a70 ","xStart":106,"xEnd":107,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:  49  1a70 ","xStart":107,"xEnd":108,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:  50  1a70 ","xStart":108,"xEnd":109,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:  51  1a70 ","xStart":109,"xEnd":110,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:  52  1a70 ","xStart":110,"xEnd":111,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:  53  1a70 ","xStart":111,"xEnd":112,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:  54  1a70 ","xStart":112,"xEnd":113,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:  55  1a70 ","xStart":113,"xEnd":114,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:  56  1a70 ","xStart":114,"xEnd":115,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:  57  1a70 ","xStart":115,"xEnd":116,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:  58  1a70 ","xStart":116,"xEnd":117,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  59  1a70 ","xStart":117,"xEnd":118,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  60  1a70 ","xStart":118,"xEnd":119,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:  61  1a70 ","xStart":119,"xEnd":120,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:  62  1a70 ","xStart":120,"xEnd":121,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:  63  1a70 ","xStart":121,"xEnd":122,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:  64  1a70 ","xStart":122,"xEnd":123,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  65  1a70 ","xStart":123,"xEnd":124,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  66  1a70 ","xStart":124,"xEnd":125,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  67  1a70 ","xStart":125,"xEnd":126,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:  68  1a70 ","xStart":126,"xEnd":127,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:  69  1a70 ","xStart":127,"xEnd":128,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  70  1a70 ","xStart":128,"xEnd":129,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:  71  1a70 ","xStart":129,"xEnd":130,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:  72  1a70 ","xStart":130,"xEnd":131,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TRP:  73  1a70 ","xStart":131,"xEnd":132,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:  74  1a70 ","xStart":132,"xEnd":133,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:  75  1a70 ","xStart":133,"xEnd":134,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:  76  1a70 ","xStart":134,"xEnd":135,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:  77  1a70 ","xStart":135,"xEnd":136,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:  78  1a70 ","xStart":136,"xEnd":137,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:  79  1a70 ","xStart":137,"xEnd":138,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:  80  1a70 ","xStart":138,"xEnd":139,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:  81  1a70 ","xStart":139,"xEnd":140,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:  82  1a70 ","xStart":140,"xEnd":141,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:  83  1a70 ","xStart":141,"xEnd":142,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:  84  1a70 ","xStart":142,"xEnd":143,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:  85  1a70 ","xStart":143,"xEnd":144,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:  86  1a70 ","xStart":144,"xEnd":145,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:  87  1a70 ","xStart":145,"xEnd":146,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:  88  1a70 ","xStart":146,"xEnd":147,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:  89  1a70 ","xStart":147,"xEnd":148,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"HIS:  90  1a70 ","xStart":148,"xEnd":149,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:  91  1a70 ","xStart":149,"xEnd":150,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:  93  1a70 ","xStart":151,"xEnd":152,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:  94  1a70 ","xStart":152,"xEnd":153,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:  95  1a70 ","xStart":153,"xEnd":154,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:  96  1a70 ","xStart":154,"xEnd":155,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:  97  1a70 ","xStart":155,"xEnd":156,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:1 1a70 ","xStart":59,"xEnd":60,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:2 1a70 ","xStart":60,"xEnd":61,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:3 1a70 ","xStart":61,"xEnd":62,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:4 1a70 ","xStart":62,"xEnd":63,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:5 1a70 ","xStart":63,"xEnd":64,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:6 1a70 ","xStart":64,"xEnd":65,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:7 1a70 ","xStart":65,"xEnd":66,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:8 1a70 ","xStart":66,"xEnd":67,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:9 1a70 ","xStart":67,"xEnd":68,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:10 1a70 ","xStart":68,"xEnd":69,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:11 1a70 ","xStart":69,"xEnd":70,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:12 1a70 ","xStart":70,"xEnd":71,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:13 1a70 ","xStart":71,"xEnd":72,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:14 1a70 ","xStart":72,"xEnd":73,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:15 1a70 ","xStart":73,"xEnd":74,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:16 1a70 ","xStart":74,"xEnd":75,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:17 1a70 ","xStart":75,"xEnd":76,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:18 1a70 ","xStart":76,"xEnd":77,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:19 1a70 ","xStart":77,"xEnd":78,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:20 1a70 ","xStart":78,"xEnd":79,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:21 1a70 ","xStart":79,"xEnd":80,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:22 1a70 ","xStart":80,"xEnd":81,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:23 1a70 ","xStart":81,"xEnd":82,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:24 1a70 ","xStart":82,"xEnd":83,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:25 1a70 ","xStart":83,"xEnd":84,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:26 1a70 ","xStart":84,"xEnd":85,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:27 1a70 ","xStart":85,"xEnd":86,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:28 1a70 ","xStart":86,"xEnd":87,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:29 1a70 ","xStart":87,"xEnd":88,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:30 1a70 ","xStart":88,"xEnd":89,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:31 1a70 ","xStart":89,"xEnd":90,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:32 1a70 ","xStart":90,"xEnd":91,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:33 1a70 ","xStart":91,"xEnd":92,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:34 1a70 ","xStart":92,"xEnd":93,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:35 1a70 ","xStart":93,"xEnd":94,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:36 1a70 ","xStart":94,"xEnd":95,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:37 1a70 ","xStart":95,"xEnd":96,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:38 1a70 ","xStart":96,"xEnd":97,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:39 1a70 ","xStart":97,"xEnd":98,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ARG:40 1a70 ","xStart":98,"xEnd":99,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:41 1a70 ","xStart":99,"xEnd":100,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:42 1a70 ","xStart":100,"xEnd":101,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:43 1a70 ","xStart":101,"xEnd":102,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:44 1a70 ","xStart":102,"xEnd":103,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:45 1a70 ","xStart":103,"xEnd":104,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:46 1a70 ","xStart":104,"xEnd":105,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:47 1a70 ","xStart":105,"xEnd":106,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:48 1a70 ","xStart":106,"xEnd":107,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:49 1a70 ","xStart":107,"xEnd":108,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:50 1a70 ","xStart":108,"xEnd":109,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:51 1a70 ","xStart":109,"xEnd":110,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:52 1a70 ","xStart":110,"xEnd":111,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:53 1a70 ","xStart":111,"xEnd":112,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:54 1a70 ","xStart":112,"xEnd":113,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:55 1a70 ","xStart":113,"xEnd":114,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:56 1a70 ","xStart":114,"xEnd":115,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:57 1a70 ","xStart":115,"xEnd":116,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:58 1a70 ","xStart":116,"xEnd":117,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:59 1a70 ","xStart":117,"xEnd":118,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:60 1a70 ","xStart":118,"xEnd":119,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:61 1a70 ","xStart":119,"xEnd":120,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:62 1a70 ","xStart":120,"xEnd":121,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:63 1a70 ","xStart":121,"xEnd":122,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:64 1a70 ","xStart":122,"xEnd":123,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:65 1a70 ","xStart":123,"xEnd":124,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:66 1a70 ","xStart":124,"xEnd":125,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:67 1a70 ","xStart":125,"xEnd":126,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:68 1a70 ","xStart":126,"xEnd":127,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:69 1a70 ","xStart":127,"xEnd":128,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:70 1a70 ","xStart":128,"xEnd":129,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:71 1a70 ","xStart":129,"xEnd":130,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:72 1a70 ","xStart":130,"xEnd":131,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TRP:73 1a70 ","xStart":131,"xEnd":132,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:74 1a70 ","xStart":132,"xEnd":133,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:75 1a70 ","xStart":133,"xEnd":134,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:76 1a70 ","xStart":134,"xEnd":135,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:77 1a70 ","xStart":135,"xEnd":136,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:78 1a70 ","xStart":136,"xEnd":137,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:79 1a70 ","xStart":137,"xEnd":138,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:80 1a70 ","xStart":138,"xEnd":139,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:81 1a70 ","xStart":139,"xEnd":140,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:82 1a70 ","xStart":140,"xEnd":141,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:83 1a70 ","xStart":141,"xEnd":142,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:84 1a70 ","xStart":142,"xEnd":143,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:85 1a70 ","xStart":143,"xEnd":144,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:86 1a70 ","xStart":144,"xEnd":145,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:87 1a70 ","xStart":145,"xEnd":146,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:88 1a70 ","xStart":146,"xEnd":147,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:89 1a70 ","xStart":147,"xEnd":148,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"HIS:90 1a70 ","xStart":148,"xEnd":149,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:91 1a70 ","xStart":149,"xEnd":150,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:93 1a70 ","xStart":151,"xEnd":152,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:94 1a70 ","xStart":152,"xEnd":153,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:95 1a70 ","xStart":153,"xEnd":154,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:96 1a70 ","xStart":154,"xEnd":155,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:97 1a70 ","xStart":155,"xEnd":156,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA:   1  1a70 ","xStart":59,"xEnd":60,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA:   2  1a70 ","xStart":60,"xEnd":61,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TYR:   3  1a70 ","xStart":61,"xEnd":62,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS:   4  1a70 ","xStart":62,"xEnd":63,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL:   5  1a70 ","xStart":63,"xEnd":64,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR:   6  1a70 ","xStart":64,"xEnd":65,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU:   7  1a70 ","xStart":65,"xEnd":66,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL:   8  1a70 ","xStart":66,"xEnd":67,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR:   9  1a70 ","xStart":67,"xEnd":68,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PRO:  10  1a70 ","xStart":68,"xEnd":69,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR:  11  1a70 ","xStart":69,"xEnd":70,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY:  12  1a70 ","xStart":70,"xEnd":71,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASN:  13  1a70 ","xStart":71,"xEnd":72,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL:  14  1a70 ","xStart":72,"xEnd":73,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU:  15  1a70 ","xStart":73,"xEnd":74,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PHE:  16  1a70 ","xStart":74,"xEnd":75,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLN:  17  1a70 ","xStart":75,"xEnd":76,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS:  18  1a70 ","xStart":76,"xEnd":77,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PRO:  19  1a70 ","xStart":77,"xEnd":78,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  20  1a70 ","xStart":78,"xEnd":79,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  21  1a70 ","xStart":79,"xEnd":80,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL:  22  1a70 ","xStart":80,"xEnd":81,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TYR:  23  1a70 ","xStart":81,"xEnd":82,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ILE:  24  1a70 ","xStart":82,"xEnd":83,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU:  25  1a70 ","xStart":83,"xEnd":84,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  26  1a70 ","xStart":84,"xEnd":85,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA:  27  1a70 ","xStart":85,"xEnd":86,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA:  28  1a70 ","xStart":86,"xEnd":87,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU:  29  1a70 ","xStart":87,"xEnd":88,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU:  30  1a70 ","xStart":88,"xEnd":89,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU:  31  1a70 ","xStart":89,"xEnd":90,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY:  32  1a70 ","xStart":90,"xEnd":91,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ILE:  33  1a70 ","xStart":91,"xEnd":92,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  34  1a70 ","xStart":92,"xEnd":93,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU:  35  1a70 ","xStart":93,"xEnd":94,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PRO:  36  1a70 ","xStart":94,"xEnd":95,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TYR:  37  1a70 ","xStart":95,"xEnd":96,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER:  38  1a70 ","xStart":96,"xEnd":97,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS:  39  1a70 ","xStart":97,"xEnd":98,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ARG:  40  1a70 ","xStart":98,"xEnd":99,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA:  41  1a70 ","xStart":99,"xEnd":100,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY:  42  1a70 ","xStart":100,"xEnd":101,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER:  43  1a70 ","xStart":101,"xEnd":102,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS:  44  1a70 ","xStart":102,"xEnd":103,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER:  45  1a70 ","xStart":103,"xEnd":104,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER:  46  1a70 ","xStart":104,"xEnd":105,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS:  47  1a70 ","xStart":105,"xEnd":106,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA:  48  1a70 ","xStart":106,"xEnd":107,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY:  49  1a70 ","xStart":107,"xEnd":108,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS:  50  1a70 ","xStart":108,"xEnd":109,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU:  51  1a70 ","xStart":109,"xEnd":110,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS:  52  1a70 ","xStart":110,"xEnd":111,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR:  53  1a70 ","xStart":111,"xEnd":112,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY:  54  1a70 ","xStart":112,"xEnd":113,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER:  55  1a70 ","xStart":113,"xEnd":114,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU:  56  1a70 ","xStart":114,"xEnd":115,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASN:  57  1a70 ","xStart":115,"xEnd":116,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLN:  58  1a70 ","xStart":116,"xEnd":117,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  59  1a70 ","xStart":117,"xEnd":118,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  60  1a70 ","xStart":118,"xEnd":119,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLN:  61  1a70 ","xStart":119,"xEnd":120,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER:  62  1a70 ","xStart":120,"xEnd":121,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PHE:  63  1a70 ","xStart":121,"xEnd":122,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU:  64  1a70 ","xStart":122,"xEnd":123,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  65  1a70 ","xStart":123,"xEnd":124,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  66  1a70 ","xStart":124,"xEnd":125,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  67  1a70 ","xStart":125,"xEnd":126,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLN:  68  1a70 ","xStart":126,"xEnd":127,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ILE:  69  1a70 ","xStart":127,"xEnd":128,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  70  1a70 ","xStart":128,"xEnd":129,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU:  71  1a70 ","xStart":129,"xEnd":130,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY:  72  1a70 ","xStart":130,"xEnd":131,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TRP:  73  1a70 ","xStart":131,"xEnd":132,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL:  74  1a70 ","xStart":132,"xEnd":133,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU:  75  1a70 ","xStart":133,"xEnd":134,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR:  76  1a70 ","xStart":134,"xEnd":135,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS:  77  1a70 ","xStart":135,"xEnd":136,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA:  78  1a70 ","xStart":136,"xEnd":137,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA:  79  1a70 ","xStart":137,"xEnd":138,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TYR:  80  1a70 ","xStart":138,"xEnd":139,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PRO:  81  1a70 ","xStart":139,"xEnd":140,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL:  82  1a70 ","xStart":140,"xEnd":141,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER:  83  1a70 ","xStart":141,"xEnd":142,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP:  84  1a70 ","xStart":142,"xEnd":143,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL:  85  1a70 ","xStart":143,"xEnd":144,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR:  86  1a70 ","xStart":144,"xEnd":145,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ILE:  87  1a70 ","xStart":145,"xEnd":146,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU:  88  1a70 ","xStart":146,"xEnd":147,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR:  89  1a70 ","xStart":147,"xEnd":148,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"HIS:  90  1a70 ","xStart":148,"xEnd":149,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS:  91  1a70 ","xStart":149,"xEnd":150,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS:  92  1a70 ","xStart":150,"xEnd":151,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU:  93  1a70 ","xStart":151,"xEnd":152,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU:  94  1a70 ","xStart":152,"xEnd":153,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU:  95  1a70 ","xStart":153,"xEnd":154,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR:  96  1a70 ","xStart":154,"xEnd":155,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA:  97  1a70 ","xStart":155,"xEnd":156,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:1 1a70 ","xStart":59,"xEnd":60,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:2 1a70 ","xStart":60,"xEnd":61,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:3 1a70 ","xStart":61,"xEnd":62,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:4 1a70 ","xStart":62,"xEnd":63,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:5 1a70 ","xStart":63,"xEnd":64,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:6 1a70 ","xStart":64,"xEnd":65,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:7 1a70 ","xStart":65,"xEnd":66,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:8 1a70 ","xStart":66,"xEnd":67,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:9 1a70 ","xStart":67,"xEnd":68,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:10 1a70 ","xStart":68,"xEnd":69,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:11 1a70 ","xStart":69,"xEnd":70,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:12 1a70 ","xStart":70,"xEnd":71,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:13 1a70 ","xStart":71,"xEnd":72,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:14 1a70 ","xStart":72,"xEnd":73,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:15 1a70 ","xStart":73,"xEnd":74,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:16 1a70 ","xStart":74,"xEnd":75,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:17 1a70 ","xStart":75,"xEnd":76,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:18 1a70 ","xStart":76,"xEnd":77,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:19 1a70 ","xStart":77,"xEnd":78,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:20 1a70 ","xStart":78,"xEnd":79,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:21 1a70 ","xStart":79,"xEnd":80,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:22 1a70 ","xStart":80,"xEnd":81,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:23 1a70 ","xStart":81,"xEnd":82,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:24 1a70 ","xStart":82,"xEnd":83,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:25 1a70 ","xStart":83,"xEnd":84,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:26 1a70 ","xStart":84,"xEnd":85,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:27 1a70 ","xStart":85,"xEnd":86,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:28 1a70 ","xStart":86,"xEnd":87,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:29 1a70 ","xStart":87,"xEnd":88,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:30 1a70 ","xStart":88,"xEnd":89,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:31 1a70 ","xStart":89,"xEnd":90,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:32 1a70 ","xStart":90,"xEnd":91,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:33 1a70 ","xStart":91,"xEnd":92,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:34 1a70 ","xStart":92,"xEnd":93,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:35 1a70 ","xStart":93,"xEnd":94,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:36 1a70 ","xStart":94,"xEnd":95,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:37 1a70 ","xStart":95,"xEnd":96,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:38 1a70 ","xStart":96,"xEnd":97,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:39 1a70 ","xStart":97,"xEnd":98,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ARG:40 1a70 ","xStart":98,"xEnd":99,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:41 1a70 ","xStart":99,"xEnd":100,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:42 1a70 ","xStart":100,"xEnd":101,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:43 1a70 ","xStart":101,"xEnd":102,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:44 1a70 ","xStart":102,"xEnd":103,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:45 1a70 ","xStart":103,"xEnd":104,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:46 1a70 ","xStart":104,"xEnd":105,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:47 1a70 ","xStart":105,"xEnd":106,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:48 1a70 ","xStart":106,"xEnd":107,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:49 1a70 ","xStart":107,"xEnd":108,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:50 1a70 ","xStart":108,"xEnd":109,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:51 1a70 ","xStart":109,"xEnd":110,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:52 1a70 ","xStart":110,"xEnd":111,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:53 1a70 ","xStart":111,"xEnd":112,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:54 1a70 ","xStart":112,"xEnd":113,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:55 1a70 ","xStart":113,"xEnd":114,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:56 1a70 ","xStart":114,"xEnd":115,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:57 1a70 ","xStart":115,"xEnd":116,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:58 1a70 ","xStart":116,"xEnd":117,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:59 1a70 ","xStart":117,"xEnd":118,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:60 1a70 ","xStart":118,"xEnd":119,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:61 1a70 ","xStart":119,"xEnd":120,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:62 1a70 ","xStart":120,"xEnd":121,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:63 1a70 ","xStart":121,"xEnd":122,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:64 1a70 ","xStart":122,"xEnd":123,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:65 1a70 ","xStart":123,"xEnd":124,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:66 1a70 ","xStart":124,"xEnd":125,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:67 1a70 ","xStart":125,"xEnd":126,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:68 1a70 ","xStart":126,"xEnd":127,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:69 1a70 ","xStart":127,"xEnd":128,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:70 1a70 ","xStart":128,"xEnd":129,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:71 1a70 ","xStart":129,"xEnd":130,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:72 1a70 ","xStart":130,"xEnd":131,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TRP:73 1a70 ","xStart":131,"xEnd":132,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:74 1a70 ","xStart":132,"xEnd":133,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:75 1a70 ","xStart":133,"xEnd":134,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:76 1a70 ","xStart":134,"xEnd":135,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:77 1a70 ","xStart":135,"xEnd":136,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:78 1a70 ","xStart":136,"xEnd":137,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:79 1a70 ","xStart":137,"xEnd":138,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:80 1a70 ","xStart":138,"xEnd":139,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:81 1a70 ","xStart":139,"xEnd":140,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:82 1a70 ","xStart":140,"xEnd":141,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:83 1a70 ","xStart":141,"xEnd":142,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:84 1a70 ","xStart":142,"xEnd":143,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:85 1a70 ","xStart":143,"xEnd":144,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:86 1a70 ","xStart":144,"xEnd":145,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:87 1a70 ","xStart":145,"xEnd":146,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:88 1a70 ","xStart":146,"xEnd":147,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:89 1a70 ","xStart":147,"xEnd":148,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"HIS:90 1a70 ","xStart":148,"xEnd":149,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:91 1a70 ","xStart":149,"xEnd":150,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:92 1a70 ","xStart":150,"xEnd":151,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:93 1a70 ","xStart":151,"xEnd":152,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:94 1a70 ","xStart":152,"xEnd":153,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:95 1a70 ","xStart":153,"xEnd":154,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:96 1a70 ","xStart":154,"xEnd":155,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:97 1a70 ","xStart":155,"xEnd":156,"type":"RESNUM"}]}'>
 <style type="text/css"> div.parent{ width:100%;<!-- overflow: auto; -->}
 div.titlex{ width:11%; float: left; }
index 72c062d..6e6c670 100755 (executable)
@@ -34,7 +34,7 @@ TIETHKEEELTA-
 -----------------------------------------------------------ATYKVKFITPEGE
 QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDV
 TIETHREEDMV--
->FER1_ARATH Ferredoxin-1, chloroplast precursor
+>FER2_ARATH Ferredoxin-2, chloroplast precursor
 MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE
 LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV
 TIETHKEEDIV--
@@ -42,7 +42,7 @@ TIETHKEEDIV--
 -----------------------------------------------------------ATYKVKFITPEGE
 QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV
 TIETHKEEELV--
->FER2_ARATH Ferredoxin-2, chloroplast precursor
+>FER1_ARATH Ferredoxin-1, chloroplast precursor
 MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
 QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV
 VIETHKEEAIM--
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 7e14204..e034fc2 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 bf1710c..3a6b0b3 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 2ade2e0..c1b276d 100644 (file)
   <strong>Normalise Consensus Logo</strong> to scale all columns of the
   logo to the same height.
 
-    <p>
-    <strong>Group Consensus</strong><br>
-    If sequence groups have been defined, then selecting option 'Group Consensus' in the <a href="../menus/alwannotation.html">Annotations menu</a> will 
-    result in Consensus being calculated for each group, as well as the alignment as a whole.
+  <p>
+    <strong>Group Consensus</strong><br> If sequence groups have
+    been defined, then selecting option 'Group Consensus' in the <a
+      href="../menus/alwannotation.html">Annotations menu</a> will
+    result in Consensus being calculated for each group, as well as the
+    alignment as a whole.
   </p>
   <p>
     <strong>cDNA Consensus</strong>
index 9cb8ce1..4535525 100755 (executable)
@@ -40,8 +40,8 @@
     <b>9</b> No. 6 (745-756)).
   </ul>
   <em><a
-    href="http://www.compbio.dundee.ac.uk/papers/amas/amas3d.html"
-  >View an HTML version of the paper</a></em>
+    href="http://www.compbio.dundee.ac.uk/papers/amas/amas3d.html">View
+      an HTML version of the paper</a></em>
   </p>
   <p>
     Conservation is measured as a numerical index reflecting the
     <strong>Colouring an alignment by conservation</strong><br>
     Conservation scores can be used to colour an alignment. This is
     explained further in the help page for <a
-      href="../colourSchemes/conservation.html"
-    >conservation colouring</a>.
+      href="../colourSchemes/conservation.html">conservation
+      colouring</a>.
   </p>
   <p>
-    <strong>Group conservation</strong><br>
-    If sequence groups have been defined, then selecting option 'Group Conservation' in the <a href="../menus/alwannotation.html">Annotations menu</a> will 
-    result in Conservation being calculated for each group, as well as the alignment as a whole.
+    <strong>Group conservation</strong><br> If sequence groups have
+    been defined, then selecting option 'Group Conservation' in the <a
+      href="../menus/alwannotation.html">Annotations menu</a> will
+    result in Conservation being calculated for each group, as well as
+    the alignment as a whole.
   </p>
 </body>
 </html>
index 071a2b5..c38d9ac 100755 (executable)
     pair of sequences - computed with one of the available score
     matrices, such as <a href="scorematrices.html#blosum62">BLOSUM62</a>,
     <a href="scorematrices.html#pam250">PAM250</a>, or the <a
-      href="scorematrices.html#simplenucleotide"
-    >simple single nucleotide substitution matrix</a>. The options
-    available for calculation are given in the <strong><em>Change
+      href="scorematrices.html#simplenucleotide">simple single
+      nucleotide substitution matrix</a>. The options available for
+    calculation are given in the <strong><em>Change
         Parameters</em></strong> menu.
   </p>
   <p>
-    <em>PCA Calculation modes</em><br /> The default Jalview calculation
-    mode (indicated when <em><strong>Jalview PCA
-        Calculation</strong></em> is ticked in the <strong><em>Change
+    <em>PCA Calculation modes</em><br /> The default Jalview
+    calculation mode (indicated when <em><strong>Jalview
+        PCA Calculation</strong></em> is ticked in the <strong><em>Change
         Parameters</em></strong> menu) is to perform a PCA on a matrix where elements
     in the upper diagonal give the sum of scores for mutating in one
     direction, and the lower diagonal is the sum of scores for mutating
     gives an asymmetric matrix, and a different PCA to a matrix produced
     with the method described in the paper by G. Casari, C. Sander and
     A. Valencia. Structural Biology volume 2, no. 2, February 1995 (<a
-      href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=pubmed&dopt=Abstract&list_uids=7749921"
-    >pubmed</a>) and implemented at the SeqSpace server at the EBI. This
-    method preconditions the matrix by multiplying it with its
-    transpose, and can be employed in the PCA viewer by unchecking the <strong><em>Jalview
+      href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=pubmed&dopt=Abstract&list_uids=7749921">pubmed</a>)
+    and implemented at the SeqSpace server at the EBI. This method
+    preconditions the matrix by multiplying it with its transpose, and
+    can be employed in the PCA viewer by unchecking the <strong><em>Jalview
         PCA Calculation</em></strong> option in the <strong><em>Change
         Parameters</em></strong> menu.
   </p>
index 94cbc65..5b1badb 100755 (executable)
     menu or pressing <strong>'CONTROL+D'</strong> brings up a dialog box
     asking you to select a threshold. If the percentage identity between
     the aligned positions of any two sequences in the visible alignment
-    exceeds this value, the shorter sequence is discarded.<br>
-    <em>Note:</em> The redundancy calculation is done when the dialog
-    box is opened. For large numbers of sequences this can take a long
-    time as all pairs have to be compared.
+    exceeds this value, the shorter sequence is discarded.<br> <em>Note:</em>
+    The redundancy calculation is done when the dialog box is opened.
+    For large numbers of sequences this can take a long time as all
+    pairs have to be compared.
   </p>
 </body>
 </html>
index 912be55..a79541b 100644 (file)
     organisms that are similar to a newly sequenced gene, or when
     searching for structurally similar sequences for use in homology
     modelling.</p>
-<p>
+  <p>
     <strong>What happens when a reference sequence is defined ?</strong>
   </p>
-  <p>
-    The reference sequence for an alignment is indicated by its ID being
-    shown in bold. In addition:</p>
+  <p>The reference sequence for an alignment is indicated by its ID
+    being shown in bold. In addition:</p>
   <ul>
     <li><strong>Reference sequence numbering</strong>. Instead of
       column numbers, the alignment ruler shows the reference sequence
@@ -61,8 +60,8 @@
       sequence when importing analysis results, such as those returned
       from <a href="../webServices/jnet.html">JPred4</a> . A reference
       sequence can also be assigned via the <a
-      href="../features/annotationsFormat.html#refsandviews">SET_REF</a> command in
-      an alignment annotation file.</li>
+      href="../features/annotationsFormat.html#refsandviews">SET_REF</a>
+      command in an alignment annotation file.</li>
   </ul>
   <p>
     <em>Reference sequence based alignment visualisation was
index f6bffb0..5fbbc19 100644 (file)
@@ -33,7 +33,8 @@
       matrix, and (since 2.8.1) is available for Tree and PCA
       calculations.</li>
     <li><a href="#simplenucleotide">Simple Nucleotide
-        Substitution</a> is a (fairly) arbitrary DNA/RNA substitution matrix.</li>
+        Substitution</a> is a (fairly) arbitrary DNA/RNA substitution
+      matrix.</li>
     <!--  <li><a href="#conservation">Conservation Matrices</a> A range of matrices for distinguishing amino-acids by physicochemical property conservation.
 </li> -->
   </ul>
     <strong><a name="pam250">PAM250</a></strong><br /> <em><strong>P</strong>ercentage
       <strong>A</strong>ccepted <strong>M</strong>utation matrix. PAM250
       estimates substitutions after 250% of sites have changed (each
-      site can be mutated multple times).<br /> Jalview 2.8.1 introduced
-      support for PAM250 based <a href="../calculations/pca.html">PCA</a>
-      and <a href="../calculations/tree.html">tree</a> calculations.</em>
+      site can be mutated multple times).<br /> Jalview 2.8.1
+      introduced support for PAM250 based <a
+      href="../calculations/pca.html">PCA</a> and <a
+      href="../calculations/tree.html">tree</a> calculations.</em>
   <table border="1">
     <tr>
       <td></td>
   </table>
   <strong><em>This nucleotide matrix was introduced in
       Jalview 2.8. If you'd like to improve it - please take a look at <a
-      href="http://issues.jalview.org/browse/JAL-1027"
-    >Issue JAL-1027 - introduce a nucleotide substitution matrix that
+      href="http://issues.jalview.org/browse/JAL-1027">Issue
+        JAL-1027 - introduce a nucleotide substitution matrix that
         supports RNA/DNA and ambiguity codes</a>
   </em></strong>
   </p>
index 8c017a9..aeb461a 100755 (executable)
       </p>
       <p>
         This menu appears if the alignment contains any <a
-          href="../features/annotationsFormat.html"
-        >sequence associated alignment annotation</a> with associated
-        score values. Each entry is the label for a distinct group of
-        sequence associated annotation scores which can be used for
-        sorting.
+          href="../features/annotationsFormat.html">sequence
+          associated alignment annotation</a> with associated score values.
+        Each entry is the label for a distinct group of sequence
+        associated annotation scores which can be used for sorting.
       </p>
   </ul>
   <p>
+    <strong>Sorting according to sequence features</strong><br />
+    Additional sort operations for alignments containing sequence
+    features are provided in the <strong><a
+      href="../features/featuresettings.html#sortbyfeature">Feature
+        Settings</a></strong> dialog, opened via <strong>View&#8594;Feature
+      Settings...</strong>
+  <p>
     <strong>Reversing the Order</strong>
   </p>
   <p>Selecting any item from the Sort menu will sort sequences in an
     ascending order according to the property defining the sort. If the
     same sort is re-applied, the sequences will be sorted in the inverse
-    order. In the case of trees and alignment orderings, Jalview will
-    remember your last choice for sorting the alignment and only apply
-    the inverse ordering if you select the same tree or alignment
-    ordering item again.</p>
+    order. In both cases, for sequences which are equivalent under the
+    sort operation, their order will be preserved (since version 2.10).
+    In the case of trees and alignment orderings, Jalview will remember
+    your last choice for sorting the alignment and only apply the
+    inverse ordering if you select the same tree or alignment ordering
+    item again.</p>
 
 </body>
 </html>
index c194a53..fd47dc0 100755 (executable)
     <strong>Alignment RNA Structure Consensus Annotation</strong>
   </p>
 
-  <p>The RNA structure consensus displayed below the alignment gives the
-    percentage of valid base pairs per column for the first secondary
-    structure annotation shown on the annotation panel. These values are
-    shown as a histogram labeled &quot;StrucConsensus&quot;, where a
-    symbol below each bar indicates whether the majority of base pairs
-    are:<ul>
+  <p>The RNA structure consensus displayed below the alignment gives
+    the percentage of valid base pairs per column for the first
+    secondary structure annotation shown on the annotation panel. These
+    values are shown as a histogram labeled &quot;StrucConsensus&quot;,
+    where a symbol below each bar indicates whether the majority of base
+    pairs are:
+  <ul>
     <li>'(' - Watson-Crick (C:G, A:U/T)</li>
     <li>'[' - Non-canonical (a.ka. wobble) (G:U/T)</li>
     <li>'{' - Invalid (a.k.a. tertiary) (the rest)</li>
   <p>Mousing over the column gives the fraction of pairs classified
     as Watson-Crick, Canonical or Invalid.</p>
 
-  <p>By default
-    this calculation includes gaps in columns. You can choose to ignore
-    gaps in the calculation by right clicking on the label
-    &quot;StrucConsensus&quot; to the left of the structure consensus bar
-    chart.<br>
-  
+  <p>
+    By default this calculation includes gaps in columns. You can choose
+    to ignore gaps in the calculation by right clicking on the label
+    &quot;StrucConsensus&quot; to the left of the structure consensus
+    bar chart.<br>
   <p>
     <strong>RNA Structure logo</strong><br /> Right-clicking on the
     label allows you to enable the structure logo. It is very similar to
index 7a8271e..59736ca 100755 (executable)
     Trees are calculated on either the complete alignment, or just the
     currently selected group of sequences, using the functions in the <strong>Calculate&#8594;Calculate
       tree</strong> submenu. Once calculated, trees are displayed in a new <a
-      href="../calculations/treeviewer.html"
-    >tree viewing window</a>. There are four different calculations, using
-    one of two distance measures and constructing the tree from one of
-    two algorithms :
+      href="../calculations/treeviewer.html">tree viewing
+      window</a>. There are four different calculations, using one of two
+    distance measures and constructing the tree from one of two
+    algorithms :
   </p>
   <p>
     <strong>Distance Measures</strong>
@@ -56,8 +56,8 @@
       scores for the residue pairs at each aligned position.
       <ul>
         <li>For details about each model, see the <a
-          href="scorematrices.html"
-        >list of built-in score matrices</a>.
+          href="scorematrices.html">list of built-in score
+            matrices</a>.
         </li>
       </ul></li>
     <li><strong>Sequence Feature Similarity</strong><br>Trees
   </ul>
   <p>
     A newly calculated tree will be displayed in a new <a
-      href="../calculations/treeviewer.html"
-    >tree viewing window</a>. In addition, a new entry with the same tree
-    viewer window name will be added in the Sort menu so that the
-    alignment can be reordered to reflect the ordering of the leafs of
-    the tree. If the tree was calculated on a selected region of the
-    alignment, then the title of the tree view will reflect this.
+      href="../calculations/treeviewer.html">tree viewing
+      window</a>. In addition, a new entry with the same tree viewer window
+    name will be added in the Sort menu so that the alignment can be
+    reordered to reflect the ordering of the leafs of the tree. If the
+    tree was calculated on a selected region of the alignment, then the
+    title of the tree view will reflect this.
   </p>
 
   <p>
     phylogenetic trees, which can cope with large numbers of sequences,
     use better distance methods and can perform bootstrapping. Jalview
     can read <a
-      href="http://evolution.genetics.washington.edu/phylip/newick_doc.html"
-    >Newick</a> format tree files using the 'Load Associated Tree' entry
-    of the alignment's File menu. Sequences in the alignment will be
+      href="http://evolution.genetics.washington.edu/phylip/newick_doc.html">Newick</a>
+    format tree files using the 'Load Associated Tree' entry of the
+    alignment's File menu. Sequences in the alignment will be
     automatically associated to nodes in the tree, by matching Sequence
     IDs to the tree's leaf names.
   </p>
index c91fe1b..3d6245e 100755 (executable)
   </p>
   <p>
     The tree viewing window is opened when a tree has been <a
-      href="tree.html"
-    >calculated from an alignment</a>, or imported via a file or web
-    service. It includes <a href="#menus">menus</a> for controlling
-    layout and file and figure creation, and enables various selection
-    and colouring operations on the associated sequences in the
-    alignment.
+      href="tree.html">calculated from an alignment</a>, or
+    imported via a file or web service. It includes <a href="#menus">menus</a>
+    for controlling layout and file and figure creation, and enables
+    various selection and colouring operations on the associated
+    sequences in the alignment.
   </p>
   <p>
     <strong><em>Selecting Sequence Leaf Nodes</em></strong><br>
     tree is rendered and labeled:
   <ul>
     <li><strong>Fit to Window</strong>
-    <p>The tree layout will be scaled to fit in the display window.
-        You may need to reduce the font size to minimise the leaf label
-        overlap when this option is selected.</p></li>
+      <p>The tree layout will be scaled to fit in the display
+        window. You may need to reduce the font size to minimise the
+        leaf label overlap when this option is selected.</p></li>
     <li><strong>Font Size ...</strong><em>n</em>
-    <p>
+      <p>
         Brings up a dialog box to set the font size for the leaf names.
         <em>n</em> is the current font size.
       </p></li>
     <li><strong>Show Distances</strong>
-    <p>Labels each branch or leaf with its associated branch length.</p></li>
+      <p>Labels each branch or leaf with its associated branch
+        length.</p></li>
     <li><strong>Show Bootstrap values</strong>
-    <p>Labels each branch or leaf with its associated bootstrap
+      <p>Labels each branch or leaf with its associated bootstrap
         value.</p></li>
     <li><strong>Mark unlinked leaves</strong>
-    <p>Toggles the display of a '*' at the beginning of a leaf label
-        to indicate that there is no sequence corresponding to that leaf
-        in the associated alignment.</p></li>
+      <p>Toggles the display of a '*' at the beginning of a leaf
+        label to indicate that there is no sequence corresponding to
+        that leaf in the associated alignment.</p></li>
     <li><strong>Sort Alignment By Tree</strong>
       <p>
         Sorts any associated alignment views using the current tree. (<em>Only
     <li><strong>Associate Leaves with ...</strong>
       <p>
         Only visible when there are <a
-          href="../features/multipleViews.html"
-        >multiple views</a> of the same alignment to show and edit which
-        alignment views are associated with the leaves of the displayed
-        tree.
+          href="../features/multipleViews.html">multiple
+          views</a> of the same alignment to show and edit which alignment
+        views are associated with the leaves of the displayed tree.
       </p>
   </ul>
   </p>
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 30b6396..2272503 100755 (executable)
   </div>
   <ul>
     <li>Select which annotation to base the colouring scheme on
-      using the top left selection box.<br />If the <strong>Per-sequence
-        only</strong> tick box is not greyed out, then ticking it will limit the
-      available annotation rows to just those that are sequence
-      associated (e.g. T-COFFEE scores and <a
-      href="../webServices/proteinDisorder.html"
-    >protein disorder predictions</a>), which will colour each sequence
-      according to its own per-residue scores.<br /> <em>Per-sequence
-        associated annotation colouring was introduced in Jalview 2.8</em>
+      using the top left selection box. Sequence associated alignment
+      annotation are shown with the seuqence's name appended.<br />If
+      the <strong>Per-sequence only</strong> tick box is not greyed out,
+      then ticking it will limit the list of available annotation rows
+      to just the labels for those that are sequence associated.
+      Annotation rows on each sequence with the same label (e.g.
+      T-COFFEE scores and <a href="../webServices/proteinDisorder.html">protein
+        disorder predictions</a>) will then be used to colour its
+      corresponding positions in the alignment.<br /> <em>Per-sequence
+        associated annotation colouring is currently only available in
+        the Desktop.</em>
     </li>
     <li>If the &quot;Use Original Colours&quot; box is selected,
       the colouring scheme will use the colouring scheme present on the
@@ -74,9 +77,9 @@
         <li>Press the &quot;Defaults&quot; button to reset the
           minimum and maximum colours to their default settings (these
           are configured in the applet's parameters or the <a
-          href="../features/preferences.html"
-        >application's user preferences</a>.).<br /> <em>Default min
-            and max colours were introduced in Jalview 2.7</em>
+          href="../features/preferences.html">application's
+            user preferences</a>.).<br /> <em>Default min and max
+            colours were introduced in Jalview 2.7</em>
       </ul>
     </li>
 
index 19d276e..88ef6ba 100755 (executable)
@@ -33,9 +33,9 @@
     alignment analysis (Livingstone C.D. and Barton G.J. (1993), Protein
     Sequence Alignments: A Strategy for the Hierarchical Analysis of
     Residue Conservation.CABIOS Vol. 9 No. 6 (745-756)). See the <a
-      href="../calculations/conservation.html"
-    >conservation calculation</a> help page for a more thorough
-    explanation of the calculation.
+      href="../calculations/conservation.html">conservation
+      calculation</a> help page for a more thorough explanation of the
+    calculation.
   </p>
   <p>For an already coloured alignment, the conservation index at
     each alignment position is used to modify the shading intensity of
   <p>
     Conservation can be calculated over all sequences in an alignment,
     or just within specific groups (such as those defined by <a
-      href="../calculations/tree.html"
-    >phylogenetic tree partitioning</a>). The option 'apply to all groups'
-    controls whether the contrast slider value will be applied to the
-    indices for the currently selected group, or all groups defined over
-    the alignment.
+      href="../calculations/tree.html">phylogenetic tree
+      partitioning</a>). The option 'apply to all groups' controls whether
+    the contrast slider value will be applied to the indices for the
+    currently selected group, or all groups defined over the alignment.
   </p>
 </body>
 </html>
index 3f01bdf..7664101 100755 (executable)
@@ -49,8 +49,7 @@ td {
     the background colour.</p>
   <p>
     The <strong>&quot;Colour&#8594;<a
-      href="../colourSchemes/textcolour.html"
-    >Colour Text...</a>&quot;
+      href="../colourSchemes/textcolour.html">Colour Text...</a>&quot;
     </strong> entry opens a dialog box to set a different text colour for light
     and dark background, and the intensity threshold for transition
     between them.
index a7d0898..9b9d41a 100644 (file)
     on its helices. The helices are determined from the secondary
     structure line in the Stockholm file (#GC SS_cons) written in WUSS
     notation that specifies base pairing. See <a
-      href="http://en.wikipedia.org/wiki/Stockholm_format"
-    > Wikipedia</a> or <a
-      href="http://jalview-rnasupport.blogspot.com/2010/06/parsing-wuss-notation-of-rna-secondary.html"
-    > Jalview RNA Support Blog</a> for more information about Stockholm
+      href="http://en.wikipedia.org/wiki/Stockholm_format">
+      Wikipedia</a> or <a
+      href="http://jalview-rnasupport.blogspot.com/2010/06/parsing-wuss-notation-of-rna-secondary.html">
+      Jalview RNA Support Blog</a> for more information about Stockholm
     files and WUSS notation.
   </p>
   Select &quot;Colour&quot;
index 5d83d00..fd8c5a3 100755 (executable)
     clicking the left mouse button and pressing a combination of either
     shift and control (or the alt, option or apple key on Macs) and
     dragging the mouse. Pressing <em>F2</em> toggles the alternative <a
-      href="../features/cursorMode.html"
-    >'Cursor mode'</a> keyboard editing facility, where the space bar and
-    delete keys add and remove gaps at the current editing position. The
-    key strokes for both these modes are summarised in the <a
-      href="../keys.html"
-    >keystrokes table</a>.
+      href="../features/cursorMode.html">'Cursor mode'</a> keyboard
+    editing facility, where the space bar and delete keys add and remove
+    gaps at the current editing position. The key strokes for both these
+    modes are summarised in the <a href="../keys.html">keystrokes
+      table</a>.
   </p>
   <p>
     <strong>Tip:</strong> For large alignments, deselect &quot;Calculate
@@ -50,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 d13afe4..b63d20b 100755 (executable)
     <strong>Types of annotation</strong>
   <ul>
     <li><a name="seqannots"><strong>Sequence
-          associated annotation.</strong></a><br/>Data displayed on sequence annotation
-      rows are associated with the positions of a sequence. Often this
-      is 'Reference annotation' such as secondary structure information
-      derived from 3D structure data, or from the results of sequence
-      based prediction of <a href="../webServices/jnet.html">secondary
+          associated annotation.</strong></a><br />Data displayed on sequence
+      annotation rows are associated with the positions of a sequence.
+      Often this is 'Reference annotation' such as secondary structure
+      information derived from 3D structure data, or from the results of
+      sequence based prediction of <a href="../webServices/jnet.html">secondary
         structure</a> and <a href="../webServices/proteinDisorder.html">disorder</a>.
       If reference annotation is available for a the currently selected
       sequences, it can be shown by selecting the <strong>Add
         Reference Annotation</strong> option in the sequence or selection popup
       menu.</li>
-    <li><strong>Group associated annotation.</strong><br/>Data can be associated with
-      groups defined on the alignment.     If sequence groups are defined, <a
-      href="../calculations/conservation.html">Conservation</a> and <a
-      href="../calculations/consensus.html">Consensus</a> annotation can
-    be enabled for each group from the <a
+    <li><strong>Group associated annotation.</strong><br />Data can
+      be associated with groups defined on the alignment. If sequence
+      groups are defined, <a href="../calculations/conservation.html">Conservation</a>
+      and <a href="../calculations/consensus.html">Consensus</a>
+      annotation can be enabled for each group from the <a
       href="../menus/alwannotation.html">Annotations menu</a>, or can be
-    imported from a Jalview <a href="annotationsFormat.html">Annotations
-      file</a>.</li>
-    <li><strong>Alignment associated annotation.</strong><br />Annotation rows
-      associated with columns on the alignment are simply 'alignment
-      annotation'. Controls allow you to <a href="#iaannot">interactively create
-        alignment annotation</a> to add labels and symbols to alignment columns.
-      Jalview's consensus, conservation and quality calculations also
-      create histogram and sequence logo annotations on the alignment.
-    </li>
+      imported from a Jalview <a href="annotationsFormat.html">Annotations
+        file</a>.</li>
+    <li><strong>Alignment associated annotation.</strong><br />Annotation
+      rows associated with columns on the alignment are simply
+      'alignment annotation'. Controls allow you to <a href="#iaannot">interactively
+        create alignment annotation</a> to add labels and symbols to
+      alignment columns. Jalview's consensus, conservation and quality
+      calculations also create histogram and sequence logo annotations
+      on the alignment.</li>
   </ul>
   <p>
     <strong>Importing and exporting annotation</strong><br />
     groups of annotation rows can be shown or hidden using the pop-up
     menu obtained by right-clicking the label. You can also reorder them
     by dragging the label to a new position with the left mouse button.
-    The
-    <strong>Annotations</strong> menu provides settings controlling the
-    ordering and display of sequence, group and alignment associated
-    annotation. The
-    <strong>Colour by annotation</strong> option in the colour menu
-    allows annotation to be used to
-    <a href="../colourSchemes/annotationColouring.html">shade the
-      alignment</a>. Annotations can also be used to
-    <a href="../features/columnFilterByAnnotation.html">select or
-      hide columns</a> via the dialog opened from the
-    <strong>Selection</strong> menu.
+    The <strong>Annotations</strong> menu provides settings controlling
+    the ordering and display of sequence, group and alignment associated
+    annotation. The <strong>Colour by annotation</strong> option in the
+    colour menu allows annotation to be used to <a
+      href="../colourSchemes/annotationColouring.html">shade the
+      alignment</a>. Annotations can also be used to <a
+      href="../features/columnFilterByAnnotation.html">select or
+      hide columns</a> via the dialog opened from the <strong>Selection</strong>
+    menu.
   </p>
   <p>
     <strong>Sequence Highlighting and Selection from Annotation</strong>
         using the view's standard font size.</em></li>
   </ul>
   <p>
-    <strong>Editing labels and secondary structure annotation rows</strong>
+    <strong>Editing labels and secondary structure annotation
+      rows</strong>
   </p>
   <p>
     Use the <strong>left mouse button</strong> to select a position
     along the row that are to be annotated - these regions will be
-    coloured red. Press <strong>Control</strong> or <strong>shift</strong> in
-    combination with the left-click to either select an additional position,
-    or a range of positions on the alignment.
+    coloured red. Press <strong>Control</strong> or <strong>shift</strong>
+    in combination with the left-click to either select an additional
+    position, or a range of positions on the alignment.
   </p>
   <p>
     Once positions have been selected, use the <strong>right
-      mouse button</strong> and select one of the following from the <strong>annotation menu</strong>:
+      mouse button</strong> and select one of the following from the <strong>annotation
+      menu</strong>:
   </p>
   <ul>
-    <li>Helix<br>
-    <em>Marks selected positions with a helix glyph (a red oval),
-        and optional text label (see below). A dialog box will open for
-        you to enter the text. Consecutive ovals will be rendered as an
-        unbroken red line.</em>
+    <li>Helix<br> <em>Marks selected positions with a
+        helix glyph (a red oval), and optional text label (see below). A
+        dialog box will open for you to enter the text. Consecutive
+        ovals will be rendered as an unbroken red line.</em>
     </li>
-    <li>Sheet<br>
-    <em>Marks selected positions with a sheet glyph (a green arrow
-        oriented from left to right), and optional text label (see
-        below). A dialog box will open for you to enter the text.
-        Consecutive arrows will be joined together to form a single
-        green arrow.</em>
+    <li>Sheet<br> <em>Marks selected positions with a
+        sheet glyph (a green arrow oriented from left to right), and
+        optional text label (see below). A dialog box will open for you
+        to enter the text. Consecutive arrows will be joined together to
+        form a single green arrow.</em>
     </li>
     <li><a name="rna">RNA Helix</a> (only shown when working with
       nucleotide sequences)<br> <em>Marks selected positions
         region pairs with bases to the left of the highlighted columns.
         Other kinds of base-pair annotation are also supported (e.g. 'A'
         and 'a', or '&lt;' and '&gt;'), and Jalview will suggest an
-        appropriate symbol based on the closest unmatched
-        parenthesis to the left.<br />If any brackets do not match up, then an
-        orange square will highlight the first position where a bracket
-        was found not to match.
+        appropriate symbol based on the closest unmatched parenthesis to
+        the left.<br />If any brackets do not match up, then an orange
+        square will highlight the first position where a bracket was
+        found not to match.
     </em></li>
-    <li>Label<br>
-    <em>Set the text label at the selected positions. A dialog box
-        will open for you to enter the text. If more than one
-        consecutive position is marked with the same label, only the
-        first position's label will be rendered.</em>
+    <li>Label<br> <em>Set the text label at the selected
+        positions. A dialog box will open for you to enter the text. If
+        more than one consecutive position is marked with the same
+        label, only the first position's label will be rendered.</em>
     </li>
-    <li>Colour<br>
-    <em>Changes the colour of the annotation text label.</em>
+    <li>Colour<br> <em>Changes the colour of the
+        annotation text label.</em>
     </li>
-    <li>Remove Annotation<br>
-    <em>Blanks any annotation at the selected positions on the row.
-        Note: <strong>This cannot be undone</strong>
+    <li>Remove Annotation<br> <em>Blanks any annotation
+        at the selected positions on the row. Note: <strong>This
+          cannot be undone</strong>
     </em>
     </li>
   </ul>
     <em>Current Limitations</em>
   </p>
   <p>
-    The Jalview user interface does not support interactive
-    creation and editing of quantitative annotation (histograms and line
-    graphs), or to create annotation associated with a specific
-    sequence or group. It is also incapable of annotation grouping or changing
-    the style of existing annotation (e.g. to change between line or bar
-    charts, or to make multiple line graphs). These annotation
-    capabilities are only possible by the import of an <a
-      href="annotationsFormat.html">Annotation file</a>.<br>
+    The Jalview user interface does not support interactive creation and
+    editing of quantitative annotation (histograms and line graphs), or
+    to create annotation associated with a specific sequence or group.
+    It is also incapable of annotation grouping or changing the style of
+    existing annotation (e.g. to change between line or bar charts, or
+    to make multiple line graphs). These annotation capabilities are
+    only possible by the import of an <a href="annotationsFormat.html">Annotation
+      file</a>.<br>
   </p>
 </body>
 </html>
index 744370b..fcdb908 100755 (executable)
@@ -31,9 +31,8 @@
     Alignment annotations can be imported onto an alignment since
     version 2.08 of Jalview, via an annotations file. It is a simple
     ASCII text file consisting of tab delimited records similar to the <a
-      href="featuresFormat.html"
-    >Sequence Features File</a>, and introduced primarily for use with the
-    Jalview applet.
+      href="featuresFormat.html">Sequence Features File</a>, and
+    introduced primarily for use with the Jalview applet.
   </p>
 
   <p>
@@ -55,8 +54,8 @@
     alignment window.
   </p>
   <p>
-    <strong>THE ANNOTATION FILE FORMAT</strong> <br />An annotation file
-    consists of lines containing an instruction followed by tab
+    <strong>THE ANNOTATION FILE FORMAT</strong> <br />An annotation
+    file consists of lines containing an instruction followed by tab
     delimited fields. Any lines starting with &quot;#&quot; are
     considered comments, and ignored. The sections below describe the
     structure of an annotation file.
   </ul>
   <p>
     At the end of this document, you can also find notes on <a
-      href="#compatibility"
-    >compatibility</a> of annotation files across different versions of
-    Jalview. An <a href="#exampleann">example annotation file</a> is
-    also provided along with instructions on how to import it to
-    Jalview.
+      href="#compatibility">compatibility</a> of annotation files
+    across different versions of Jalview. An <a href="#exampleann">example
+      annotation file</a> is also provided along with instructions on how to
+    import it to Jalview.
   </p>
   <hr />
   <p>
     followed by a <em>description</em> for the row, which is shown in a
     tooltip when the user mouses over the annotation row's label. Since
     Jalview 2.7, the description field may also contain HTML tags (in
-    the same way as a <a href="featuresFormat.html">sequence feature's</a>
-    label), providing the text is enclosed in an &lt;html/&gt; tag.
+    the same way as a <a href="featuresFormat.html">sequence
+      feature's</a> label), providing the text is enclosed in an
+    &lt;html/&gt; tag.
   <ul>
     <em>Please note: URL links embedded in HTML descriptions are
       not yet supported.</em>
     <em>GRAPH_TYPE</em>. The allowed values of <em>GRAPH_TYPE</em> and
     corresponding interpretation of each <em>Value</em> are shown below:
 
+
   
   <ul>
     <li><strong>BAR_GRAPH</strong><br> Plots a histogram with
@@ -190,9 +190,9 @@ GRAPHLINE&#9;<em>graph_name</em>&#9;<em>value</em>&#9;<em>label</em>&#9;<em>colo
   </ul>
   </p>
   <p>
-    <strong><a name="groupdefs">SEQUENCE_GROUP</a></strong><br /> Groups
-    of sequences and column ranges can be defined using a tab delimited
-    statement like:
+    <strong><a name="groupdefs">SEQUENCE_GROUP</a></strong><br />
+    Groups of sequences and column ranges can be defined using a tab
+    delimited statement like:
   </p>
   <pre>SEQUENCE_GROUP&#9;Group_Name&#9;Group_Start&#9;Group_End&#9;<em>Sequences</em>
   </pre>
@@ -296,8 +296,8 @@ GRAPHLINE&#9;<em>graph_name</em>&#9;<em>value</em>&#9;<em>label</em>&#9;<em>colo
       <tr>
         <td width="50%">hide</td>
         <td>Boolean (default false) indicating whether the rows in
-          this group should be marked as hidden.<br />
-        <em>Note:</em> if the group is sequence associated (specified by
+          this group should be marked as hidden.<br /> <em>Note:</em>
+          if the group is sequence associated (specified by
           SEQUENCE_REF), then all members will be hidden and marked as
           represented by the reference sequence.
         </td>
index cb7ccc0..59b4936 100644 (file)
@@ -40,8 +40,7 @@
   </p>
   <p>
     The BioJSON specification is published at <a
-      href="http://jalview.github.io/biojson/"
-    >http://jalview.github.io/biojson/</a>.
+      href="http://jalview.github.io/biojson/">http://jalview.github.io/biojson/</a>.
   </p>
   <p>
     <em>Import of BioJSON data from HTML pages</em>
index 0569513..5ae00af 100644 (file)
   </p>
   <p>
     Since Jalview 2.8.2, <a href="http://www.cgl.ucsf.edu/chimera/">Chimera</a>
-    (http://www.cgl.ucsf.edu/chimera/) has been integrated into Jalview
-    for interactively viewing structures opened by entries in the <strong>&quot;Structure&quot;</strong>
-    submenu in the <a href="../menus/popupMenu.html">sequence id
-      pop-up menu</a> (if you can't see this, then you need to <a
-      href="viewingpdbs.html"
-    >associate a PDB structure</a> with the sequence). Chimera is
-    available from the Jalview desktop, provided Chimera has been
-    separately installed.
+    (http://www.cgl.ucsf.edu/chimera/) can be used for viewing
+    structures opened via the <a href="structurechooser.html"><strong>&quot;View
+        Structure Data..&quot;</strong> dialog</a>.
   </p>
   <p>
     You can set a default choice of Jmol or Chimera structure viewer in
     <a href="preferences.html#structure"> Preferences</a>. You can also
     optionally specify the path to the Chimera program here (if it
-    differs from the standard paths searched by Jalview).
+    differs from the standard paths searched by Jalview).<br /> <strong>Please
+      make sure your version of Chimera is up to date. Jalview requires
+      at least Chimera version 1.11.1</strong>
+  </p>
   <p>
     If you save your Jalview session as a project file, the state of any
     open Chimera windows will also be saved, and can be reopened by
     loading the project file on any machine with Chimera installed. <em>Since
       Jalview 2.9.</em>
-    <!-- <p>The following menu entries are provided for viewing structure data<br>
-  <ul>
-    <li>The <strong>&quot;Structure&#8594;View
-        Structure&#8594;</strong> submenu allows a single PDB structure to be chosen
-      for display from the available structures for a sequence.
-    </li>
-    <li>The <strong>&quot;Structure&#8594;View all <em>N</em>
-        structures
-    </strong> option will open a new window containing all structures associated
-      with the current selection.
-    </li>
-    <li>The <strong>&quot;Structure&#8594;View all <em>N</em>
-        representative structures
-    </strong> option will open a new window containing exactly one structure per
-      currently selected sequence.<br /></li>
-  </ul>
-  <br> 
-</p> -->
   <p>
     <a name="align"><strong>Superposing structures based on
         their aligned sequences</strong></a><br> If several structures are
     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 help</a> at
+      href="http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/mouse.html">Chimera
+      help</a> at
     http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/mouse.html
     for full details).
   <table border="1">
             colourschemes.<br>
         </strong><em>The remaining entries apply the colourschemes available
             from the standard and user defined <a
-            href="../colourSchemes/index.html"
-          >amino acid colours</a>.
+            href="../colourSchemes/index.html">amino acid
+              colours</a>.
         </em></li>
       </ul></li>
     <li><strong>Chimera<br>
   </p>
   Jalview and Chimera communicate using Chimera's
   <a
-    href="http://www.cgl.ucsf.edu/chimera/current/docs/ContributedSoftware/restserver/restserver.html"
-  >REST service</a>
+    href="http://www.cgl.ucsf.edu/chimera/current/docs/ContributedSoftware/restserver/restserver.html">REST
+    service</a>
   (http://www.cgl.ucsf.edu/chimera/current/docs/ContributedSoftware/restserver/restserver.html).
   <br> Technically this requires both Chimera and Jalview to open
   ports on the local network, and this may be blocked by Windows
index 1d6f62d..e065494 100644 (file)
@@ -67,8 +67,8 @@
         <div align="center">-annotations FILE/URL</div>
       </td>
       <td>Add precalculated annotations to the alignment. See <a
-        href="annotationsFormat.html" target="NEW"
-      >Annotation File</a> description.
+        href="annotationsFormat.html" target="NEW">Annotation
+          File</a> description.
       </td>
     </tr>
     <tr>
       <td>
         <div align="center">-nonews</div>
       <td>
-        <div align="left">Disable check for <a href="../webServices/newsreader.html">Jalview news</a> on startup (not recommended other than for classroom / demo usage)</div>
+        <div align="left">
+          Disable check for <a href="../webServices/newsreader.html">Jalview
+            news</a> on startup (not recommended other than for classroom /
+          demo usage)
+        </div>
       </td>
     </tr>
     <tr>
       <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 2b7d0ec..b260cee 100644 (file)
@@ -31,8 +31,8 @@
     The 'Select/Hide by Annotation' window allows columns to be selected
     or hidden according to annotation rows on the alignment. The dialog
     box is opened <em>via</em> &quot;<strong>Select&#8594;Select/Hide
-      Columns by Annotation...</strong>&quot;, and different filters are
-    presented dependent upon the data shown in the selected annotation
+      Columns by Annotation...</strong>&quot;, and different filters are then
+    presented for filtering data according to the selected annotation
     row.
   </p>
   <table>
       <td><img src="AnnotationColumnSelectionWithoutSM.gif"></td>
     </tr>
   </table>
-
-  <p>If an annotation with numeric values is selected, the threshold
+  <p>The drop down menu lists the annotation available on the
+    alignment. Sequence associated annotation rows will be shown with
+    the sequence ID appended to the annotation label. It is only
+    possible to select one row at a time.</p>
+  <p>
+    If an annotation with numeric values is selected, the threshold
     filter option is activated. For other types of annotation, use the
     text box and secondary structure check boxes (right). The radio
     buttons at the bottom of the dialog specify the action applied to
-    columns matching the query.</p>
+    columns matching the query.<br /> <em>Note: annotation
+      containing only numeric labels (e.g. T-COFFEE column confidence
+      scores) will not be treated as quantitative data. You will need to
+      enter search expressions to select columns in this case.</em>
+  </p>
   <ul>
     <li><strong>Search Filter</strong>
       <ul>
index 0e1f109..9cffc51 100644 (file)
@@ -56,8 +56,8 @@
   <pre>java -Djava.ext.dirs=$INSTALL_DIR$/lib -cp $INSTALL_DIR$/jalview.jar jalview.bin.Jalview -open [FILE] </pre>
   <p>
     Use '-help' to get more information on the <a
-      href="clarguments.html"
-    >command line arguments</a> that Jalview accepts.
+      href="clarguments.html">command line arguments</a> that
+    Jalview accepts.
   </p>
   <p>&nbsp;</p>
   <p>&nbsp;</p>
index a6a17a5..68a594a 100644 (file)
   <strong>Creating Sequence Features</strong>
   <p>
     Jalview can create sequence features from the matches of a <a
-      href="search.html"
-    >regular expression search</a>, or from the currently selected area
-    via the <strong>&quot;selection&#8594;Create sequence
-      feature&quot;</strong> entry in the <a href="../menus/popupMenu.html">selection
-      area popup menu</a>. In both cases, the <strong>Create
-      Features</strong> dialog box will then be opened:
+      href="search.html">regular expression search</a>, or from the
+    currently selected area via the <strong>&quot;selection&#8594;Create
+      sequence feature&quot;</strong> entry in the <a
+      href="../menus/popupMenu.html">selection area popup menu</a>. In
+    both cases, the <strong>Create Features</strong> dialog box will
+    then be opened:
   </p>
   <p>
     <img src="crnewfeature.gif">
index 32408ee..1965e70 100644 (file)
   <p>
     <strong>DAS Sequence Feature Retrieval</strong>
   </p>
-  <p>
-    Jalview includes a client for retrieving sequences and their
-    features via the Distributed Annotation System.
-  </p>
+  <p>Jalview includes a client for retrieving sequences and their
+    features via the Distributed Annotation System.</p>
   <ol>
     <li>Open the Feature Settings panel by selecting &quot;View
       -&gt; Feature Settings...&quot;</li>
     Accession ids for the given sequence names. It is important to
     realise that many DAS sources only use UniProt accession ids, rather
     than Swissprot/UniProt sequence names.<br> The <a
-      href="../webServices/dbreffetcher.html"
-    >database reference fetcher</a> documentation describes how Jalview
-    discovers what database references are appropriate for the sequences
-    in the alignment.
+      href="../webServices/dbreffetcher.html">database
+      reference fetcher</a> documentation describes how Jalview discovers
+    what database references are appropriate for the sequences in the
+    alignment.
   <ul>
     <li><em>Note</em><br> Please remember to save your
       alignment if either the start/end numbering, or the sequence IDs
   <p>
     <em>DAS support was introduced in Jalview Version 2.1.</em>
   </p>
-  <br/>
+  <br />
   <p>
-    <em>The DAS registry at http://www.dasregistry.org was decommissioned early in 2015. An unmaintained mirror is currently hosted at http://www.ebi.ac.uk/das-srv/registry/.</em>
+    <em>The DAS registry at http://www.dasregistry.org was
+      decommissioned early in 2015. An unmaintained mirror is currently
+      hosted at http://www.ebi.ac.uk/das-srv/registry/.</em>
   </p>
   <p>&nbsp;
 </body>
index a86d37f..9600070 100644 (file)
   </p>
   <p>
     Jalview can retrieve sequences and features from many <a
-      href="http://biodas.org/"
-    >DAS</a> sources. The DAS sources that it uses are discovered and
-    selected <em>via</em> the DAS settings panel, opened either from the
-    <a href="featuresettings.html">View&#8594;Feature Settings</a>
-    dialog box from the alignment window's menu bar, or the <a
-      href="featuresettings.html"
-    >Tools&#8594;Preferences</a> dialog box opened from the Desktop menu
-    bar.
+      href="http://biodas.org/">DAS</a> sources. The DAS sources
+    that it uses are discovered and selected <em>via</em> the DAS
+    settings panel, opened either from the <a
+      href="featuresettings.html">View&#8594;Feature Settings</a> dialog
+    box from the alignment window's menu bar, or the <a
+      href="featuresettings.html">Tools&#8594;Preferences</a>
+    dialog box opened from the Desktop menu bar.
   </p>
   <p>
     <img src="das.gif">
index 748eeba..14e98e5 100644 (file)
     <!-- and <strong>Feature Group</strong>  -->
     pull down menu. In addition to the Name, group, colour and
     description attributes described for the <a
-      href="creatinFeatures.html"
-    >new feature dialog box</a>, a feature's start and end position can be
-    changed either by entering a new position directly or by using the
-    adjacent up and down buttons.
+      href="creatinFeatures.html">new feature dialog box</a>, a
+    feature's start and end position can be changed either by entering a
+    new position directly or by using the adjacent up and down buttons.
   </p>
   <p>
     Select <strong>Amend</strong> to update the feature, <strong>Delete</strong>
index 2a62caa..e547c58 100644 (file)
 <body>
 
   <strong>Fetching ENSEMBL Data in Jalview</strong>
-  <br /> Jalview Version 2.10 (September 2016) introduced support to
+  <br /> Jalview Version 2.10 (October 2016) introduced support to
   retrieve annotated transcripts, peptides and genomic contigs from
   <a href="http://www.ensembl.org">ENSEMBL</a>.
   <br />
-  <img src="selectfetchdb.gif" align="left" width="480" height="204"
-    alt="Database selection dialog for fetching sequences (introduced in Jalview 2.8)">
+  <img src="selectfetchdb.gif" align="right" width="480" height="204"
+    alt="Database selection dialog with Ensembl sequence source tooltip">
 
   <p>Two types of ENSEMBL source are provided. ENSEMBL queries the
-    main ENSEMBL site, which only serves data for higher eukaryotes, and
-    EnsemblGenomes, which provides access to Ensembl Pathogens, and
-    other warehouses.</p>
-    <p><strong>General Use</strong><br/> If you have a set of Ensembl
-    peptide or transcript IDs, then you can retrieve them
-    <em>via</em> the sequence fetcher dialog opened after selecting the
-    most appropriate source (either 'ENSEMBL', or Ensembl Genomes).
-    However, Jalview's Ensembl client has a couple of additional
-    capabilities: </p><p><strong>Retrieving aligned transcripts for a genomic ID</strong>
-  </p>
-  <p>If a single genomic identifier is entered in the
-    Ensembl fetcher, Jalview will return all transcripts and products
-    for the locus, and display them in a split view - complete with
-    sequence variant annotation.</p>
-  <p><strong>Retrieving orthologs for a gene ID</strong></p>
-  <p>If a gene ID is entered (e.g. fox1), Jalview will resolve
-    Ensembl genomic identifiers for a predefined set of taxa (Mouse,
-    Rat, Human, Yeast in Jalview 2.10).
-    </p>
+    main ENSEMBL warehouse containing data for higher eukaryotes, and
+    EnsemblGenomes, which queries Ensembl Pathogens, and other
+    warehouses.</p>
+  <p>
+    <strong>General Use</strong><br /> If you have a set of Ensembl
+    gene or transcript IDs, then you can retrieve them <em>via</em> the
+    sequence fetcher dialog opened after selecting the most appropriate
+    source (either 'ENSEMBL', or Ensembl Genomes). However, Jalview's
+    Ensembl client has a couple of additional capabilities:
+  </p>
+  <p>
+    <strong>Retrieving aligned transcripts for a genomic ID</strong>
+  </p>
+  <p>If a single genomic identifier is entered in the Ensembl
+    fetcher, Jalview will return all transcripts and products for the
+    locus, and display them in a split view - complete with sequence
+    variant annotation.</p>
+  <p>
+    <strong>Retrieving orthologs for a gene ID</strong>
+  </p>
+  <p>
+    If a gene ID is entered (e.g. fox1), Jalview will resolve Ensembl
+    genomic identifiers for a predefined set of taxa (Mouse, Rat, Human,
+    Yeast in Jalview 2.10).<br />
+  </p>
+  <p>
+    <strong><a name="ensemblannotation">Ensembl Sequence
+        Features</a></strong><br /> Jalview 2.10 includes support for the
+    visualisation and transfer genomic and transcriptomic sequence
+    features onto protein product sequences. Retrieval of a genomic
+    locus results in a set of transcripts that are annotated with
+    nucleotide variant information and exonic regions. By default,
+    intronic regions will be hidden.
+  </p>
+  <p>
+    <strong><a name="variantvis">Variant information on
+        Protein Products</a></strong><br />Jalview can translate genomic variant
+    annotation into protein sequence variant codes for variants
+    intersecting coding regions of a gene. To see this in action, use
+    the <strong>Calculate&#8594;Show cross-references</strong> menu to
+    view protein product sequences for the currently displayed (or
+    selected) sequences. The same menu allows you to recover Ensembl
+    exon, transcript and variant information when viewing UniProt
+    sequences.
+  </p>
+  <p>
+    <strong>Viewing more information about variant annotation</strong><br />
+    Variants are highlighted as red sequence features on the protein
+    sequence, with each one reporting all protein sequence variants
+    observed at that position as a result of the genomic variants.
+    Right-clicking a variant allows you to open the Ensembl Variants web
+    page for each variant, via the <strong>Link</strong> submenu.
+  </p>
+  <p>
+    <strong>Work in Progress !</strong><br />In the next few releases,
+    we hope to improve and extend Jalview's support for working with
+    Ensembl. If you have any problems, questions or suggestions then
+    please get in contact with us via the Jalview discussion list.
+  </p>
 </body>
 </html>
\ No newline at end of file
index 9f33b7b..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 'GFF' after any Jalview feature colour definitions (<em>this
-      mixed format capability was added in Jalview 2.6</em>). Alternately,
+    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,
     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.
 </pre>
 
   This format allows two alternate ways of referring to a sequence,
-  either by its text ID, or its index (base 0) in an associated alignment.
-  Normally, sequence features are associated with sequences rather than
-  alignments, and the sequenceIndex field is given as &quot;-1&quot;. In
-  order to specify a sequence by its index in a particular alignment,
-  the sequenceId should be given as &quot;ID_NOT_SPECIFIED&quot;,
-  otherwise the sequenceId field will be used in preference to the
-  sequenceIndex field.
+  either by its text ID, or its index (base 0) in an associated
+  alignment. Normally, sequence features are associated with sequences
+  rather than alignments, and the sequenceIndex field is given as
+  &quot;-1&quot;. In order to specify a sequence by its index in a
+  particular alignment, the sequenceId should be given as
+  &quot;ID_NOT_SPECIFIED&quot;, otherwise the sequenceId field will be
+  used in preference to the sequenceIndex field.
   </p>
 
 
     description line will be translated into URL links. A link symbol
     will be displayed adjacent to any feature which includes links, and
     these are made available from the <a
-      href="../menus/popupMenu.html#sqid.popup"
-    >links submenu</a> of the popup menu which is obtained by
-    right-clicking when a link symbol is displayed in the tooltip.<br>
-    <em>Non-positional features</em><br> Specify the <em>start</em>
-    and <em>end</em> for a feature to be <strong>0</strong> in order to
-    attach it to the whole sequence. Non-positional features are shown
-    in a tooltip when the mouse hovers over the sequence ID panel, and
-    any embedded links can be accessed from the popup menu.<br /> <em>Scores</em><br>
+      href="../menus/popupMenu.html#sqid.popup">links submenu</a>
+    of the popup menu which is obtained by right-clicking when a link
+    symbol is displayed in the tooltip.<br> <em>Non-positional
+      features</em><br> Specify the <em>start</em> and <em>end</em> for
+    a feature to be <strong>0</strong> in order to attach it to the
+    whole sequence. Non-positional features are shown in a tooltip when
+    the mouse hovers over the sequence ID panel, and any embedded links
+    can be accessed from the popup menu.<br /> <em>Scores</em><br>
     Scores can be associated with sequence features, and used to sort
     sequences or shade the alignment (this was added in Jalview 2.5).
     The score field is optional, and malformed scores will be ignored.
index b7738cd..3d7c944 100755 (executable)
   </p>
   <p>
     <strong><em>Feature settings pop-up menu</em></strong><br> <strong>Right-click</strong>
-    on a feature to open a pop-up menu that allows you to<ul><li>Hide, show and
-    select columns containing that feature</li><li>Sort the alignment or
-    current selection using that feature type (see below)</li><li>Toggle the
-    type of colouring used for the feature</li></ul><p>Features may be highlighted
-    with either a single colour or a <a href="featureschemes.html">feature
-      colourscheme</a> based on either the scores associated with that
-    feature or from the feature's description (e.g. to distinguish
-    different names associated with a DOMAIN feature).
+    on a feature to open a pop-up menu that allows you to
+  <ul>
+    <li>Hide, show and select columns containing that feature</li>
+    <li>Sort the alignment or current selection using that feature
+      type (see below)</li>
+    <li>Toggle the type of colouring used for the feature</li>
+  </ul>
+  <p>
+    Features may be highlighted with either a single colour or a <a
+      href="featureschemes.html">feature colourscheme</a> based on
+    either the scores associated with that feature or from the feature's
+    description (e.g. to distinguish different names associated with a
+    DOMAIN feature).
   </p>
   <p>
-    <strong>Ordering alignment by features</strong><br> The 'Seq
-    Sort by Score' and 'Seq Sort by Density' buttons will sort the
-    alignment based on the average score or total number of currently
-    active features and groups on each sequence. To order the alignment
-    using a specific feature type, use the <em>sort by ..</em> entries
-    in the pop-up menu for that type.<br> <em>Feature sorting
-      and graduated feature colouring were introduced in Jalview 2.5</em>
+    <strong><a name="sortbyfeature">Ordering alignment by
+        features</a></strong><br> The 'Seq Sort by Score' and 'Seq Sort by
+    Density' buttons will sort the alignment based on the average score
+    or total number of currently active features and groups on each
+    sequence. To order the alignment using a specific feature type, use
+    the <em>sort by ..</em> entries in the pop-up menu for that type.<br>
+    <em>Feature sorting and graduated feature colouring were
+      introduced in Jalview 2.5</em>
   </p>
 
   <p>
     ordering based on the average length of each feature type.
   </p>
   <p>
-    The <strong><em>transparency slider setting</em></strong> controls the visibility
-    of features rendered below other features. Reducing the transparency
-    will mean that features at the top of the list can obscure features
-    lower down, and increasing it allows the user to 'see through' the
-    upper layers of a set of features.
+    The <strong><em>transparency slider setting</em></strong> controls
+    the visibility of features rendered below other features. Reducing
+    the transparency will mean that features at the top of the list can
+    obscure features lower down, and increasing it allows the user to
+    'see through' the upper layers of a set of features.
   </p>
   <p>
     <strong><em>You can save all features, with their
index 079cf9e..254f92e 100644 (file)
@@ -64,6 +64,7 @@
     public methods of the jalview class hierarchy can be called from
     Groovy scripts. In addition, the following objects are also defined:
 
+
   
   <ul>
     <li><strong>Jalview</strong> - this is bound to <code>jalview.bin.Jalview</code>.<br />Useful
@@ -90,9 +91,9 @@ def alignment = alf[0].viewport.alignment;
 def seq = alignment.getSequenceAt(0);
 </pre>
     </li>
-    <li>If you wanted to do the same thing from the command line, you can refer to
-      alignment that was just loaded with currentAlFrame:<br>
-      <pre>
+    <li>If you wanted to do the same thing from the command line,
+      you can refer to alignment that was just loaded with
+      currentAlFrame:<br> <pre>
 print currentAlFrame.getTitle();</pre>
   </ul>
   <p>
index ac9b8b1..d69f877 100644 (file)
@@ -86,9 +86,9 @@
     <li><strong><a href="../calculations/tree.html">Tree</a></strong>,
       <strong><a href="../calculations/pairwise.html">pairwise
           alignment</a></strong> and <strong><a
-        href="../calculations/pca.html"
-      >PCA</a></strong> calculations will only be performed using the <em>visible</em>
-      parts of the alignment.</li>
+        href="../calculations/pca.html">PCA</a></strong> calculations will
+      only be performed using the <em>visible</em> parts of the
+      alignment.</li>
     <li><a href="../webServices/msaclient.html">Multiple
         Sequence Alignments</a> are performed locally on on each visible
       chunk of the input, and concatenated with the hidden regions to
index 3141aae..0cd6168 100644 (file)
     structures opened by entries in the <strong>&quot;Structure&quot;</strong>
     submenu in the <a href="../menus/popupMenu.html">sequence id
       pop-up menu</a> (if you can't see this, then you need to <a
-      href="viewingpdbs.html"
-    >associate a PDB structure</a> with the sequence). Jmol is available
-    from the Jalview desktop and should also run in the JalviewLite
-    applet, providing the browser supports Java 1.5. If Jmol is not
-    available, then the original <a href="pdbviewer.html">internal
-      pdb viewer</a> will be used as a fallback.
+      href="viewingpdbs.html">associate a PDB structure</a> with
+    the sequence). Jmol is available from the Jalview desktop and should
+    also run in the JalviewLite applet, providing the browser supports
+    Java 1.5. If Jmol is not available, then the original <a
+      href="pdbviewer.html">internal pdb viewer</a> will be used as a
+    fallback.
   </p>
   <!-- <p>The following menu entries are provided for viewing structure data<br>
   <ul>
       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
             colourschemes.<br>
         </strong><em>The remaining entries apply the colourschemes available
             from the standard and user defined <a
-            href="../colourSchemes/index.html"
-          >amino acid colours</a>.
+            href="../colourSchemes/index.html">amino acid
+              colours</a>.
         </em></li>
       </ul></li>
     <li><strong>Jmol<br>
     Jmol scripting console.</p>
   <p>
     The state of each Jmol display is stored within <a
-      href="jalarchive.html"
-    >Jalview archives</a> as a Jmol state recovery script file. This means
-    that any Jmol visualization effects that you add beyond those
-    provided by Jalview will be able to be stored and recovered along
-    with the displayed alignments in Jalview.
+      href="jalarchive.html">Jalview archives</a> as a Jmol state
+    recovery script file. This means that any Jmol visualization effects
+    that you add beyond those provided by Jalview will be able to be
+    stored and recovered along with the displayed alignments in Jalview.
   </p>
   <p>
     <strong>More Information</strong>
     Jmol is a sophisticated program in its own right, with its own
     command console and scripting language. Only the essentials have
     been described here - the interested reader is referred to <a
-      href="http://jmol.sourceforge.net/docs/"
-    >Jmol's own comprehensive online documentation</a>.
+      href="http://jmol.sourceforge.net/docs/">Jmol's own
+      comprehensive online documentation</a>.
   </p>
   </p>
 </body>
index e67f5cd..b507fe1 100644 (file)
@@ -1,4 +1,24 @@
 <!DOCTYPE html>
+<!--
+ * 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.
+ -->
 <html>
 <head>
 <meta charset="UTF-8">
@@ -10,8 +30,9 @@
   File'. This format was developed by the PDB consortium and the
   International Union of Crystallography (IUCr), based on
   Crystallographic Information File (CIF), a format used for describing
-  the structures of small molecules.<br/>mmCIF became the recommended format
-  for the exchange of biomacromolecular structures in 2014.
+  the structures of small molecules.
+  <br />mmCIF became the recommended format for the exchange of
+  biomacromolecular structures in 2014.
   <p>
     <strong>mmCIF and Jalview</strong> <br />Since Jalview 2.10, mmCIF
     is used for structures downloaded from the PDB. This means:
@@ -31,4 +52,4 @@
   <em>Support for importing 3D structure data from flat file and
     EMBL-PDBe as mmCIF was added in Jalview 2.10</em>
 </body>
-</html>
\ No newline at end of file
+</html>
index 1700de5..cc7183c 100644 (file)
@@ -74,8 +74,7 @@
   <p>
     A tree calculated on a particular view, or loaded onto it, is by
     default associated with just that view. However, the <a
-      href="../calculations/treeviewer.html"
-    >Tree Viewer's</a> <strong>&quot;View&#8594;Associate
+      href="../calculations/treeviewer.html">Tree Viewer's</a> <strong>&quot;View&#8594;Associate
       leaves&quot;</strong> submenu allows a tree's view association to be
     changed to to any or all other views.
   </p>
index b243168..97a779a 100644 (file)
Binary files a/help/html/features/pdbseqfetcher.png and b/help/html/features/pdbseqfetcher.png differ
index 0465762..2962ba6 100644 (file)
@@ -40,8 +40,7 @@
     <strong>&quot;File &#8594;Fetch Sequences&quot;</strong>).
   </p>
   <img src="pdbseqfetcher.png" align="left"
-    alt="PDB sequence fetcher (introduced in Jalview 2.9)"
-  />
+    alt="PDB sequence fetcher (introduced in Jalview 2.9)" />
 
   <p>
     <strong>Searching the PDB Database</strong>
@@ -56,9 +55,9 @@
   </p>
   <p>
   <ul>
-    <li><strong>Searching a specific PDB field</strong><br />If you
-      want to find structures based on a specific PDB metadata field,
-      you can select it from the drop-down menu.</li>
+    <li><strong>Searching a specific PDB field</strong><br />If
+      you want to find structures based on a specific PDB metadata
+      field, you can select it from the drop-down menu.</li>
     <li><strong>Retrieving a unique chain for a PDB entry</strong><br>To
       retrieve a specific chain for a PDB entry, append the PDB ID with
       a colon followed by the chain code in the search box.<br /> e.g
index eca218a..05bf2f1 100755 (executable)
       pop-up menu</a>. The internal PDB viewer is not able to show
     superpositions, so no other options are provided. Structures can
     only be viewed for sequences which have an <a
-      href="viewingpdbs.html"
-    >associated PDB structure</a>, and the PDB Viewer will only be
-    associated with the particular alignment view from which it was
-    opened.
+      href="viewingpdbs.html">associated PDB structure</a>, and the
+    PDB Viewer will only be associated with the particular alignment
+    view from which it was opened.
   </p>
   <p>
     <strong>Controls</strong>
               Jalview colourschemes.<br>
           </em></strong> The remaining entries apply the colourschemes available from
           the standard and user defined <a
-          href="../colourSchemes/index.html"
-        >amino acid colours</a>.</em></li>
+          href="../colourSchemes/index.html">amino acid
+            colours</a>.</em></li>
       </ul></li>
     <li><strong>View<br>
     </strong><em> These options can be turned off to improve performance
index 4af43de..6a8c86c 100755 (executable)
@@ -63,8 +63,8 @@
     </li>
     <li>The <a href="../webServices/webServicesPrefs.html"><strong>&quot;Web
           Service&quot;</strong> Preferences</a> tab allows you to configure the <a
-      href="http://www.compbio.dundee.ac.uk/jabaws"
-    >JABAWS</a> servers that Jalview uses, and change the layout of the
+      href="http://www.compbio.dundee.ac.uk/jabaws">JABAWS</a>
+      servers that Jalview uses, and change the layout of the
       alignment's Web Services menu.
     </li>
   </ul>
@@ -78,9 +78,8 @@
   </p>
   <p>
     <em>Open Overview Window</em> - When this is selected, the <a
-      href="overview.html"
-    >alignment overview</a> panel is opened by default for a new alignment
-    window.
+      href="overview.html">alignment overview</a> panel is opened
+    by default for a new alignment window.
   </p>
   <p>
     <em>Show Annotations</em> - If this is selected the new window will
     <em>Open file</em> - If this is selected then the default alignment
     file will be opened when Jalview is started. You can change the
     default file by clicking on file name and either typing in the file
-    path or selecting it from the file chooser window.<br />
-    <em>Note: The default example alignment is updated periodically
-      to demonstrate new features in Jalview.</em>
+    path or selecting it from the file chooser window.<br /> <em>Note:
+      The default example alignment is updated periodically to
+      demonstrate new features in Jalview.</em>
   </p>
   <p>
     <a name="colours"><strong>&quot;Colours&quot;
   <p>
     <em>Annotation Shading Default</em> - set the default minimum and
     maximum colours used when <a
-      href="../colourSchemes/annotationColouring.html"
-    >Colour by Annotation...</a> is selected from the alignment window's
-    colours menu.
+      href="../colourSchemes/annotationColouring.html">Colour
+      by Annotation...</a> is selected from the alignment window's colours
+    menu.
   </p>
   <p>
     <a name="structure"><strong>&quot;Structure&quot;
     <em>URL Link From Sequence ID</em><br> These definitions are
     used to generate URLs from a sequence's ID or database cross
     references. Read more about <a
-      href="../webServices/urllinks.html#urllinks"
-    >configuring URL links here</a>.
+      href="../webServices/urllinks.html#urllinks">configuring
+      URL links here</a>.
   </p>
   <p>
     <em>Default Browser (Unix)</em><br> Its difficult in Java to
   </p>
   <p>
     When this option is enabled, Jalview embeds <a
-      href="bioJsonFormat.html"
-    >BioJSON</a> data within HTML files exported from Jalview at
-    generation time. This enables the exported HTML files to be
-    extracted and imported back into the Jalview desktop application at
-    a later time.
+      href="bioJsonFormat.html">BioJSON</a> data within HTML files
+    exported from Jalview at generation time. This enables the exported
+    HTML files to be extracted and imported back into the Jalview
+    desktop application at a later time.
   <p>
     <em>Use Modeller Output</em>
   </p>
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 cf79858..3c9d2b8 100755 (executable)
   <p>
     By default, Jalview will assign a color to each feature based on its
     type. These colours can be changed from the <a
-      href="featuresettings.html"
-    >feature settings</a> and <a href="editingFeatures.html">amend
-      features</a> dialog boxes. Since Jalview 2.5, it is also possible to
-    define <a href="featureschemes.html">feature colourschemes</a> to
-    shade features based on their associated scores or text labels.
+      href="featuresettings.html">feature settings</a> and <a
+      href="editingFeatures.html">amend features</a> dialog boxes. Since
+    Jalview 2.5, it is also possible to define <a
+      href="featureschemes.html">feature colourschemes</a> to shade
+    features based on their associated scores or text labels.
   </p>
   <p>
     <strong>Sequence Feature Groups</strong>
@@ -56,8 +56,7 @@
     organised into groups, which may indicate that the features were all
     retrieved from the same database (such as UniProt features), or
     generated by the same analysis process (as might be specified in a <a
-      href="featuresFormat.html"
-    >sequence features file</a>).
+      href="featuresFormat.html">sequence features file</a>).
   </p>
   <p>
     <strong>Sequence Feature Inheritance</strong>
   <p>
     Once sequence features have been loaded, their display can be fully
     controlled using the alignment window's <a
-      href="featuresettings.html"
-    >Sequence Feature Settings</a> dialog box. Feature colour schemes and
-    display parameters are unique to a particular alignment, so it is
-    possible to colour the same sequence features differently in
-    different alignment views.<br> Since Jalview 2.1, it is
-    possible to add <a href="dassettings.html">DAS features</a> to an
-    alignment via the DAS tabbed pane of the feature settings window.
+      href="featuresettings.html">Sequence Feature Settings</a>
+    dialog box. Feature colour schemes and display parameters are unique
+    to a particular alignment, so it is possible to colour the same
+    sequence features differently in different alignment views.<br>
+    Since Jalview 2.1, it is possible to add <a href="dassettings.html">DAS
+      features</a> to an alignment via the DAS tabbed pane of the feature
+    settings window.
   </p>
   <p>
     <strong>View&#8594;Sequence ID Tooltip&#8594;Show
     Precalculated Sequence Features may be added to an alignment from
     the command line, drag and drop, or from the &quot;File&#8594;Load
     Features / Annotations&quot; menu item. See the <a
-      href="featuresFormat.html"
-    >Features File Format</a> for more details.
+      href="featuresFormat.html">Features File Format</a> for more
+    details.
   </p>
 </body>
 </html>
index 04d3c1d..44aa1c2 100755 (executable)
     Institute, or, since Jalview 2.4, DAS servers capable of the <em>sequence</em>
     command (configured in <a href="dassettings.html">DAS settings</a>).
   </p>
-  <p>The Sequence Fetcher can be opened via the
-    &quot;File&quot; menu on the main desktop in order to retrieve
-    sequences as a new alignment, or opened via the &quot;File&quot;
-    menu of an existing alignment to import additional sequences. There
-    may be a short delay when the sequence fetcher is first opened,
-    whilst Jalview compiles the list of available sequence datasources
-    from the currently defined DAS server registry.</p>
+  <p>The Sequence Fetcher can be opened via the &quot;File&quot;
+    menu on the main desktop in order to retrieve sequences as a new
+    alignment, or opened via the &quot;File&quot; menu of an existing
+    alignment to import additional sequences. There may be a short delay
+    when the sequence fetcher is first opened, whilst Jalview compiles
+    the list of available sequence datasources from the currently
+    defined DAS server registry.</p>
   <p>
-    Every time a new fetcher is opened, you will need to <strong>select the database you want to retrieve
-      sequences</strong> from the database chooser.
+    Every time a new fetcher is opened, you will need to <strong>select
+      the database you want to retrieve sequences</strong> from the database
+    chooser.
   </p>
   <img src="selectfetchdb.gif" align="left" width="480" height="204"
-    alt="Database selection dialog for fetching sequences (introduced in Jalview 2.8)"
-  >
-  <p>The databases are shown as a tree, and ordered alphabetically;
+    alt="Database selection dialog for fetching sequences (introduced in Jalview 2.8)">
+  <p>
+    The databases are shown as a tree, and ordered alphabetically;
     tooltips are shown if you mouse over some sources, explaining what
     the database will retrieve. You can select one by using the up/down
     arrow keys and hitting return, or by double clicking with the mouse.
-    <br/><em>If you have DAS sources enabled, then you may have several sources
-    for the same type of sequence identifier, and these will be grouped
-    together in a sub-branch branch labeled with the identifier.</em></p>
+    <br />
+    <em>If you have DAS sources enabled, then you may have several
+      sources for the same type of sequence identifier, and these will
+      be grouped together in a sub-branch branch labeled with the
+      identifier.</em>
+  </p>
   <p>Once you have selected a sequence database, its fetcher dialog
     will open. Jalview provides two types of dialog:</p>
-    <ol><li><strong>The Free-text Search Interface</strong>
-  
-  <br/>Free-text search clients are provided for PDB (Since 2.9), and
-    UniProt (Since 2.10). They provide access to each database's own
-    query system, enabling you to retrieve data by accession, free text
-    description, or any other type of supported field. For full details,
-    see each client's help page:
-  <ul>
-    <li><a href="pdbsequencefetcher.html">PDB Sequence Fetcher</a></li>
-    <li><a href="uniprotsequencefetcher.html">UniProt Sequence
-        Fetcher</a></li>
-  </ul>
-  </li>
-  <li><strong>Accession based sequence retrieval</strong>
-  <br/>
+  <ol>
+    <li><strong>The Free-text Search Interface</strong> <br />Free-text
+      search clients are provided for PDB (Since 2.9), and UniProt
+      (Since 2.10). They provide access to each database's own query
+      system, enabling you to retrieve data by accession, free text
+      description, or any other type of supported field. For full
+      details, see each client's help page:
+      <ul>
+        <li><a href="pdbsequencefetcher.html">PDB Sequence
+            Fetcher</a></li>
+        <li><a href="uniprotsequencefetcher.html">UniProt
+            Sequence Fetcher</a></li>
+      </ul></li>
+    <li><strong>Accession based sequence retrieval</strong> <br />
 
-  <img src="seqfetcher.gif" align="center"
-    alt="The Jalview Sequence Fetcher Dialog Box"><br/>
-  To retrieve sequences, simply <strong>enter one or more accession ids</strong> (as a semi-colon
-  separated list), or press the &quot;Example&quot; button to paste the
-  example accession for the currently selected database into the
-  retrieval box. Finally, press &quot;OK&quot; to initiate the
-  retrieval.
-  </li>
+      <img src="seqfetcher.gif" align="center"
+      alt="The Jalview Sequence Fetcher Dialog Box"><br /> To
+      retrieve sequences, simply <strong>enter one or more
+        accession ids</strong> (as a semi-colon separated list), or press the
+      &quot;Example&quot; button to paste the example accession for the
+      currently selected database into the retrieval box. Finally, press
+      &quot;OK&quot; to initiate the retrieval.</li>
   </ol>
   <p>
     <strong>Only retrieving part of a sequence</strong>
index b88aefc..ce41702 100644 (file)
@@ -25,7 +25,8 @@
 <body>
   <p>
     <strong>Mapping Between Different Sequences</strong>
-  </p><!--  TODO: review and check if this page is really needed -->
+  </p>
+  <!--  TODO: review and check if this page is really needed -->
   <p>A new feature in Jalview 2.3 is the ability to map between
     sequences in different domains, based on alignment, or by the use of
     explicit mappings provided by databases.</p>
index 9492d70..c12d45b 100644 (file)
@@ -1,4 +1,24 @@
 <!DOCTYPE html>
+<!--
+ * 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.
+ -->
 <html>
 <head>
 <meta charset="UTF-8">
@@ -24,7 +44,8 @@
     will generate a mapping using the built-in Needleman and Wunsch
     global alignment algorithm. This is how sequence-structure mappings
     were created before version 2.10.</p>
-  <p><strong>Controlling and troubleshooting SIFTS mappings</strong> <br />
+  <p>
+    <strong>Controlling and troubleshooting SIFTS mappings</strong> <br />
     Configuration options controlling whether SIFTS mappings are used
     can be found in the <strong>Tools &rarr; Preferences &rarr;
       Structure tab</strong>, under 'Sequence &harr; Structure method'.<br /> <em>Note:</em>
     <strong>Multi-Chain Mappings</strong> <br />SIFTS gives Jalview the
     ability to display multi-chain mappings between UniProt sequences
     and PDB structure data. This is important when working with
-    multimeric proteins, when the biological assembly can contain several
-    structures for the same protein sequence. Multi-chain mapping allows
-    all residues in a structure to be located in the alignment, and
-    also, when shading the structure by sequence colours, enables
-    conservation patterns between oligomer interfaces to be explored.
+    multimeric proteins, when the biological assembly can contain
+    several structures for the same protein sequence. Multi-chain
+    mapping allows all residues in a structure to be located in the
+    alignment, and also, when shading the structure by sequence colours,
+    enables conservation patterns between oligomer interfaces to be
+    explored.
   </p>
   <p>To see this in action, Retrieve the UniProt sequence
     FER1_MAIZE, and then view one of its structures: 3B2F. Mousing over
     <Strong>Viewing Mapping Output</Strong> <br /> The mapping provided
     by the SIFTS record is accessible via <strong>File &rarr;
       View mapping</strong> menu of the structure viewers. The screenshot below
-    shows the mapping created between UniProt sequence FER1_MAIZE and proteins in PDB 3B2F, which reports thattwo chains
-    were mapped. The mapping method is also reported (highlighted with red border).
+    shows the mapping created between UniProt sequence FER1_MAIZE and
+    proteins in PDB 3B2F, which reports mappings for two chains. The
+    mapping method is also reported (highlighted with red border).
   <p>
 
     &emsp;<img src="sifts_mapping_output.png" align="left"
-      alt="SIFTS mapping output" />
-      <br/>
+      alt="SIFTS mapping output" /> <br />
   <p>
     <em>SIFTS Mapping integration was added in Jalview 2.10</em>
   </p>
 
 </body>
-</html>
\ No newline at end of file
+</html>
index 1c36abd..03b993c 100644 (file)
   <ul>
     <li>Mouseover or scrolling of either alignment is followed by
       the other (unless you turn off <strong><a
-        href="../menus/alwview.html"
-      >"View&#8594;Automatic Scrolling"</a></strong>)
+        href="../menus/alwview.html">"View&#8594;Automatic
+          Scrolling"</a></strong>)
     </li>
     <li>On selecting rows, columns or regions in one alignment, the
       corresponding selection is made in the other</li>
     <li>Sequence ordering in one alignment (using the cursor, or <strong><a
-        href="../calculations/sorting.html"
-      >"Calculate&#8594;Sort")</a></strong> is also applied to the other
+        href="../calculations/sorting.html">"Calculate&#8594;Sort")</a></strong>
+      is also applied to the other
     </li>
     <li>Editing (gap insertion / deletion) in the protein alignment
       is reflected in the cDNA (but not vice versa)</li>
     <li>Any trees imported or created with <strong><a
-        href="../calculations/tree.html"
-      >"Calculate Tree"</a></strong> on one of the views allow both cDNA and
-      Protein views to be grouped, coloured or sorted.
+        href="../calculations/tree.html">"Calculate Tree"</a></strong> on
+      one of the views allow both cDNA and Protein views to be grouped,
+      coloured or sorted.
     </li>
     <li>To allow for the different widths in cDNA and Protein
       alignments, the <strong><a href="../menus/alwformat.html">"Format&#8594;Font"</a></strong>
   </ul>
   <p>
     An alignment annotation row on the protein alignment shows the <strong><a
-      href="../calculations/consensus.html"
-    >cDNA consensus</a></strong> for each peptide column.<br /> This consensus may
-    reveal variation in nucleotides coding for conserved protein
-    residues.
+      href="../calculations/consensus.html">cDNA consensus</a></strong> for
+    each peptide column.<br /> This consensus may reveal variation in
+    nucleotides coding for conserved protein residues.
   </p>
 
   <a name="opensplit" />
index c9600bb..fc71826 100644 (file)
@@ -31,7 +31,7 @@
   <p>
     The Structure Chooser interface allows you to interactively select
     which PDB structures to view for the currently selected set of
-    sequences. It's opened by selecting the <strong>"3D
+    sequences. It is opened by selecting the <strong>"3D
       Structure Data.."</strong> option from the Sequence ID panel's <a
       href="../menus/popupMenu.html">pop-up menu</a>. The dialog
     provides:
     <li>Association of structure data from a local file (in mmCIF
       or PDB format)</li>
   </ul>
-
+  <p>
+    <strong>Selecting and Viewing Structures</strong>
+  </p>
+  <p>
+    Once one or more structures have been selected, pressing the <strong>View</strong>
+    button will import them into <a
+      href="viewingpdbs.html#afterviewbutton">a new or existing
+      structure view</a>.
+  </p>
   <p>
     <strong>Automated discovery of structure data</strong>
   </p>
-  <p>After selecting "3D Structure Data ..", Jalview queries the PDB
-    via the PDBe SOLR Rest API provided by EMBL-EBI to discover PDB ids
+  <p>
+    After selecting "3D Structure Data ..", Jalview queries the PDB via
+    the PDBe SOLR Rest API provided by EMBL-EBI to discover PDB IDs
     associated with the sequence. It does this based on the sequence's
-    ID string, and any other associated database IDs.</p>
+    ID string, and any other associated database IDs. <br />
+    <br />
   <p>
-    <strong>Exploration of meta-data for available structures</strong>
+    <strong><a name="cachedstructview">Viewing existing
+        structures for your sequences</a></strong>
+  </p>
+  <p>
+    If you have already loaded 3D structure data for the selected
+    sequences, the structure chooser will first open with the <strong>Cached
+      Structures View</strong>. This view shows associations between each
+    sequence, and chains for 3D structure files already in memory. If
+    you want to download additional structures, select one of the other
+    options from the drop down menu.
   </p>
-  <p>Information on each structure available is displayed in columns
-    in the dialog box. By default, only the title, resolution and PDB
-    identifier are shown, but many more are provided by the PDBe. To
-    configure which ones are displayed, select the 'Configure Displayed
-    Columns' tab and tick the columns which you want to see.</p>
   <p>
     <strong>Selection of the best structure for each sequence</strong>
   </p>
   <p>Jalview can automatically select the best structures according
-    to meta-data provided by the PDB. By default, the 'Best Quality'
-    structure for each sequence will be selected, but clicking on the
-    drop down menu allows other criteria to be chosen, including
-    Resolution (only defined for X-Ray structures), Highest Protein
-    Chain etc. When 'Invert' is selected, structures are selected in
-    reverse order for the current criteria (e.g. worst quality rather
-    than best).</p>
+    to meta-data provided by the PDB. For alignments with no existing
+    structure data, the 'Best Quality' structure for each sequence will
+    by default be selected, but clicking on the drop down menu allows
+    other criteria to be chosen, including Resolution (only defined for
+    X-Ray structures), Highest Protein Chain etc. When 'Invert' is
+    selected, structures are selected in reverse order for the current
+    criteria (e.g. worst quality rather than best).</p>
   <p>
 
     <img src="schooser_main.png" style="width: 464px; height: 369px;">
        <p><img src="schooser_cached.png"> -->
     <br>The screenshot above shows the Structure Chooser interface
     along with the meta-data of auto-discovered structures for the
-    sample alignment. Note however that if no structures were
-    auto-discovered, a different interface for manual association will
-    be invoked as seen in the screenshot below.
-  
+    sample alignment. If no structures were
+    auto-discovered, options for manually associating PDB records will be shown (see below).
+  <p>
+    <strong>Exploration of meta-data for available structures</strong>
+  </p>
+  <p>Information on each structure available is displayed in columns
+    in the dialog box. By default, only the title, resolution and PDB
+    identifier are shown, but many more are provided by the PDBe. To
+    configure which ones are displayed, select the 'Configure Displayed
+    Columns' tab and tick the columns which you want to see.</p>
   <p>
     <img src="schooser_enter-id.png"
       style="width: 464px; height: 369px;">
-  
-  <p>
+      <br/>
     <strong>Manual selection/association of PDB files with
       Sequences</strong>
   </p>
   <p>To manually associate PDB files with a sequence, select 'From
     File', or 'Enter PDB Id' from the drop-down menu:
-  
   <ul>
     <li><strong>From File</strong> - allows you to load a PDB file
       from the local machine or network and associate it with the
       for your sequence. The PDB Rest API, provided by EMBL-EBI, is used
       to validate and fetch structure data.<br></li>
   </ul>
-  <p>
-    <strong>Viewing existing structures for your sequences</strong>
-  </p>
-  <p>
-    If you have previously associated structure data on the alignment,
-    selecting <strong>Cached PDB Entries</strong> from the drop down
-    menu allows you to select these structures for display.
-  </p>
 
   <p>
     <em>The Structure Chooser interface was introduced in Jalview
index eaee308..182b206 100644 (file)
       syntax</a>).
   </p>
 
-  <table  border="1" width="95%">
-  <tr>
-    <th>Field</th>
-    <th>Example</th>
-    <th>Description</th>
-  </tr>
-  <tr>
-    <td>accession</td>
-    <td>
-      <code>accession:P62988</code>
-    </td>
-    <td>
-        Lists all entries with the primary or secondary
-        accession number P62988.
-    </td>
-  </tr>
-  <tr>
-    <td>active</td>
-    <td>
-      <code>active:no </code>
-    </td>
-    <td>
-        Lists all obsolete entries.
-    </td>
-  </tr>
-  <tr>
-    <td>annotation</td>
-    <td>
-      <code>
-        annotation:(type:non-positional)
-        <br />
-        annotation:(type:positional)
-        <br />
-        annotation:(type:mod_res "Pyrrolidone carboxylic acid" evidence:experimental)
-      </code>
-    </td>
-    <td>
-      Lists all entries with:
-      <ul>
-        <li>any general annotation (comments [CC])</li>
-        <li>any sequence annotation (features [FT])</li>
-        <li>at least one amino acid modified with a Pyrrolidone carboxylic acid group</li>
-      </ul>
-    </td>
-  </tr>
-  <tr>
-    <td>author</td>
-    <td>
-      <code>
-        author:ashburner
-      </code>
-    </td>
-    <td>
-        Lists all entries with at least one reference co-authored by Michael Ashburner.
-    </td>
-  </tr>
-  <tr>
-    <td>cdantigen</td>
-    <td>
-      <code>
-        cdantigen:CD233
-      </code>
-    </td>
-    <td>
-        Lists all entries whose cluster of differentiation number is CD233.
-    </td>
-  </tr>
-  <tr>
-    <td>citation</td>
-    <td>
-      <code>
-        citation:("intracellular structural proteins")
-        <br />
-        citation:(author:ashburner journal:nature)
-        citation:9169874
-      </code>
-    </td>
-    <td>
-      Lists all entries with a literature citation:
-      <ul>
-        <li>containing the phrase "intracellular structural proteins" in either title or abstract</li>
-        <li>co-authored by Michael Ashburner and published in Nature</li>
-        <li>with the PubMed identifier 9169874</li>
-      </ul>
-    </td>
-  </tr>
-  <tr>
-    <td>cluster</td>
-    <td>
-      <code>
-        cluster:UniRef90_A5YMT3
-      </code>
-    </td>
-    <td>
-        Lists all entries in the UniRef 90% identity cluster whose
-        representative sequence is UniProtKB entry A5YMT3.
-    </td>
-  </tr>
-  <tr>
-       <td>count</td>
-       <td>
-               <code>
-                       annotation:(type:transmem count:5)<br />
-                       annotation:(type:transmem count:[5 TO *])<br />
-                       annotation:(type:cofactor count:[3 TO *])
-               </code>
-       </td>
-       <td>Lists all entries with:
-               <ul>
-                       <li>exactly 5 transmembrane regions</li>
-                       <li>5 or more transmembrane regions</li>
-                       <li>3 or more Cofactor comments</li>
-               </ul>
-       </td>
-  </tr>
-  <tr>
-    <td>created</td>
-    <td>
-      <code>
-        created:[20121001 TO *]<br />
-        reviewed:yes AND created:[current TO *]
-      </code>
-    </td>
-    <td>
-        Lists all entries created since October 1st 2012.<br />
+  <table border="1" width="95%">
+    <tr>
+      <th>Field</th>
+      <th>Example</th>
+      <th>Description</th>
+    </tr>
+    <tr>
+      <td>accession</td>
+      <td><code>accession:P62988</code></td>
+      <td>Lists all entries with the primary or secondary accession
+        number P62988.</td>
+    </tr>
+    <tr>
+      <td>active</td>
+      <td><code>active:no </code></td>
+      <td>Lists all obsolete entries.</td>
+    </tr>
+    <tr>
+      <td>annotation</td>
+      <td><code>
+          annotation:(type:non-positional) <br />
+          annotation:(type:positional) <br /> annotation:(type:mod_res
+          "Pyrrolidone carboxylic acid" evidence:experimental)
+        </code></td>
+      <td>Lists all entries with:
+        <ul>
+          <li>any general annotation (comments [CC])</li>
+          <li>any sequence annotation (features [FT])</li>
+          <li>at least one amino acid modified with a Pyrrolidone
+            carboxylic acid group</li>
+        </ul>
+      </td>
+    </tr>
+    <tr>
+      <td>author</td>
+      <td><code> author:ashburner </code></td>
+      <td>Lists all entries with at least one reference co-authored
+        by Michael Ashburner.</td>
+    </tr>
+    <tr>
+      <td>cdantigen</td>
+      <td><code> cdantigen:CD233 </code></td>
+      <td>Lists all entries whose cluster of differentiation number
+        is CD233.</td>
+    </tr>
+    <tr>
+      <td>citation</td>
+      <td><code>
+          citation:("intracellular structural proteins") <br />
+          citation:(author:ashburner journal:nature) citation:9169874
+        </code></td>
+      <td>Lists all entries with a literature citation:
+        <ul>
+          <li>containing the phrase "intracellular structural
+            proteins" in either title or abstract</li>
+          <li>co-authored by Michael Ashburner and published in
+            Nature</li>
+          <li>with the PubMed identifier 9169874</li>
+        </ul>
+      </td>
+    </tr>
+    <tr>
+      <td>cluster</td>
+      <td><code> cluster:UniRef90_A5YMT3 </code></td>
+      <td>Lists all entries in the UniRef 90% identity cluster
+        whose representative sequence is UniProtKB entry A5YMT3.</td>
+    </tr>
+    <tr>
+      <td>count</td>
+      <td><code>
+          annotation:(type:transmem count:5)<br />
+          annotation:(type:transmem count:[5 TO *])<br />
+          annotation:(type:cofactor count:[3 TO *])
+        </code></td>
+      <td>Lists all entries with:
+        <ul>
+          <li>exactly 5 transmembrane regions</li>
+          <li>5 or more transmembrane regions</li>
+          <li>3 or more Cofactor comments</li>
+        </ul>
+      </td>
+    </tr>
+    <tr>
+      <td>created</td>
+      <td><code>
+          created:[20121001 TO *]<br /> reviewed:yes AND
+          created:[current TO *]
+        </code></td>
+      <td>Lists all entries created since October 1st 2012.<br />
         Lists all new UniProtKB/Swiss-Prot entries in the last release.
-    </td>
-  </tr>
-  <tr>
-    <td>database</td>
-    <td>
-      <code>
-        database:(type:pfam)
-        <br />
-        database:(type:pdb 1aut)
-      </code>
-    </td>
-    <td>
-      Lists all entries with:
-      <ul>
-        <li>a cross-reference to the Pfam database</li>
-        <li>a cross-reference to the PDB database entry 1aut</li>
-      </ul>
-     
-    </td>
-  </tr>
-  <tr>
-    <td>domain</td>
-    <td>
-      <code>
-        domain:VWFA
-      </code>
-    </td>
-    <td>
-        Lists all entries with a Von Willebrand factor type A domain described
-        in the 'Family and Domains' section.
-    </td>
-  </tr>
-  <tr>
-    <td>ec</td>
-    <td>
-      <code>
-        ec:3.2.1.23
-      </code>
-    </td>
-    <td>
-        Lists all beta-galactosidases.
-    </td>
-  </tr>
-  <tr>
-       <td>evidence</td>
-       <td>
-               <code>
-                       annotation:(type:signal evidence:ECO_0000269)<br />
-                       (type:mod_res phosphoserine evidence:ECO_0000269)<br />
-                       annotation:(type:function AND evidence:ECO_0000255)
-               </code>
-       </td>
-       <td>Lists all entries with:
-               <ul>
-                       <li>a signal sequence whose positions have been experimentally proven</li>
-                       <li>experimentally proven phosphoserine sites</li>
-                       <li>a function manually asserted according to rules</li>
-               </ul>
-       </td>
-  </tr>
-  <tr>
-    <td>family</td>
-    <td>
-      <code>
-        family:serpin
-      </code>
-    </td>
-    <td>
-        Lists all entries belonging to the Serpin family of proteins.
-    </td>
-  </tr>
-  <tr>
-    <td>fragment</td>
-    <td>
-      <code>
-        fragment:yes
-      </code>
-    </td>
-    <td>
-        Lists all entries with an incomplete sequence.
-    </td>
-  </tr>
+      </td>
+    </tr>
+    <tr>
+      <td>database</td>
+      <td><code>
+          database:(type:pfam) <br /> database:(type:pdb 1aut)
+        </code></td>
+      <td>Lists all entries with:
+        <ul>
+          <li>a cross-reference to the Pfam database</li>
+          <li>a cross-reference to the PDB database entry 1aut</li>
+        </ul>
 
-  <tr>
-    <td>gene</td>
-    <td>
-      <code>
-        gene:HSPC233
-      </code>
-    </td>
-    <td>
-        Lists all entries for proteins encoded by gene HSPC233.
-    </td>
-  </tr>
-  <tr>
-    <td>go</td>
-    <td>
-      <code>
-        go:cytoskeleton
-        <br />
-        go:0015629
-      </code>
-    </td>
-    <td>
-      Lists all entries associated with:
-      <ul>
-        <li>a GO term containing the word "cytoskeleton"</li>
-        <li>the GO term Actin cytoskeleton and any subclasses</li>
-      </ul>
-    </td>
-  </tr>
-  <tr>
-    <td>host</td>
-    <td>
-      <code>
-        host:mouse
-        <br />
-        host:10090
-        <br />
-        host:40674
-      </code>
-    </td>
-    <td>
-      Lists all entries for viruses infecting:
-      <ul>
-        <li>organisms with a name containing the word "mouse"</li>
-        <li>Mus musculus (Mouse)</li>
-        <li>all mammals (all taxa classified under the taxonomy node for Mammalia)</li>
-      </ul>
-    </td>
-  </tr>
-  <tr>
-    <td>id</td>
-    <td>
-      <code>id:P00750</code>
-    </td>
-    <td>
-        Returns the entry with the primary
-        accession number P00750.
-    </td>
-  </tr>
-  <tr>
-    <td>inn</td>
-    <td>
-      <code>
-        inn:Anakinra
-      </code>
-    </td>
-    <td>
-        Lists all entries whose "International Nonproprietary Name" is Anakinra.
-    </td>
-  </tr>
-  <tr>
-    <td>interactor</td>
-    <td>
-      <code>
-        interactor:P00520
-      </code>
-    </td>
-    <td>
-        Lists all entries describing interactions with the protein described by
-        entry P00520.
-    </td>
-  </tr>
-  <tr>
-    <td>keyword</td>
-    <td>
-      <code>
-        keyword:toxin
-      </code>
-    </td>
-    <td>
-        Lists all entries associated with the keyword Toxin.
-    </td>
-  </tr>
-  <tr>
-    <td>length</td>
-    <td>
-      <code>
-        length:[500 TO 700]
-      </code>
-    </td>
-    <td>
-        Lists all entries describing sequences of length between 500 and 700 residues.
-    </td>
-  </tr>
-  <tr>
-    <td>lineage</td>
-    <td />
-    <td>
-      This field is a synonym for the field <code>taxonomy</code>.
-    </td>
-  </tr>
-  <tr>
-    <td>mass</td>
-    <td>
-      <code>
-        mass:[500000 TO *]
-      </code>
-    </td>
-    <td>
-        Lists all entries describing sequences with a mass of at least 500,000 Da.
-    </td>
-  </tr>
-  <tr>
-    <td>method</td>
-    <td>
-      <code>
-        method:maldi
-        <br />
-        method:xray
-      </code>
-    </td>
-    <td>
-        Lists all entries for proteins identified by: matrix-assisted laser
-        desorption/ionization (MALDI), crystallography (X-Ray). The
-        <code>method</code> field searches names of physico-chemical
-        identification methods in the 'Biophysicochemical properties' subsection of the 'Function' section, the 'Publications' and
-        'Cross-references' sections.
-    </td>
-  </tr>
-  <tr>
-    <td>mnemonic</td>
-    <td>
-      <code>
-        mnemonic:ATP6_HUMAN
-      </code>
-    </td>
-    <td>
-        Lists all entries with entry name (ID) ATP6_HUMAN. Searches also
-        obsolete entry names.
-    </td>
-  </tr>
-  <tr>
-    <td>modified</td>
-    <td>
-      <code>
-        modified:[20120101 TO 20120301]<br />
-        reviewed:yes AND modified:[current TO *]
-      </code>
-    </td>
-    <td>
-        Lists all entries that were last modified between January and March 2012.<br />
-        Lists all UniProtKB/Swiss-Prot entries modified in the last release.
-    </td>
-  </tr>
-  <tr>
-    <td>name</td>
-    <td>
-      <code>
-        name:"prion protein"
-      </code>
-    </td>
-    <td>
-        Lists all entries for prion proteins.
-    </td>
-  </tr>
-  <tr>
-    <td>organelle</td>
-    <td>
-      <code>
-        organelle:Mitochondrion
-      </code>
-    </td>
-    <td>
-        Lists all entries for proteins encoded by a gene of the mitochondrial
-        chromosome.
-    </td>
-  </tr>
-  <tr>
-    <td>organism</td>
-    <td>
-      <code>
-        organism:"Ovis aries"
-        <br />
-        organism:9940
-        <br />
-        organism:sheep
-        <br />
-      </code>
-    </td>
-    <td>
-        Lists all entries for proteins expressed in sheep (first 2 examples) and
-        organisms whose name contains the term "sheep".
-    </td>
-  </tr>
-  <tr>
-    <td>plasmid</td>
-    <td>
-      <code>
-        plasmid:ColE1
-      </code>
-    </td>
-    <td>
-        Lists all entries for proteins encoded by a gene of plasmid ColE1.
-    </td>
-  </tr>
-  <tr>
-    <td>proteome</td>
-    <td>
-      <code>
-        proteome:UP000005640
-      </code>
-    </td>
-    <td>
-        Lists all entries from the human proteome.
-    </td>
-  </tr>
-  <tr>
-    <td>proteomecomponent</td>
-    <td>
-      <code>
-        proteomecomponent:"chromosome 1" and organism:9606
-      </code>
-    </td>
-    <td>
-        Lists all entries from the human chromosome 1.
-    </td>
-  </tr>
-  <tr>
-    <td>replaces</td>
-    <td>
-      <code>
-        replaces:P02023
-      </code>
-    </td>
-    <td>
-        Lists all entries that were created from a merge with entry P02023.
-    </td>
-  </tr>
-  <tr>
-    <td>reviewed</td>
-    <td>
-      <code>
-        reviewed:yes
-      </code>
-    </td>
-    <td>
-        Lists all UniProtKB/Swiss-Prot entries.
-    </td>
-  </tr>
-  <tr>
-    <td>scope</td>
-    <td>
-      <code>
-        scope:mutagenesis
-      </code>
-    </td>
-    <td>
-        Lists all entries containing a reference that was used to gather
-        information about mutagenesis.
-    </td>
-  </tr>
-  <tr>
-    <td>sequence</td>
-    <td>
-      <code>
-        sequence:P05067-9
-      </code>
-    </td>
-    <td>
-        Lists all entries containing a link to isoform 9 of the sequence
-        described in entry P05067. Allows searching by specific sequence
-        identifier.
-    </td>
-  </tr>
-  <tr>
-    <td>sequence_modified</td>
-    <td>
-      <code>
-        sequence_modified:[20120101 TO 20120301]<br />
-        reviewed:yes AND sequence_modified:[current TO *]
-      </code>
-    </td>
-    <td>
-        Lists all entries whose sequences were last modified between January and March 2012.<br />
-        Lists all UniProtKB/Swiss-Prot entries whose sequences were modified in the last release.
-    </td>
-  </tr>
-  <tr>
-    <td>source</td>
-    <td>
-      <code>
-        source:intact
-      </code>
-    </td>
-    <td>
-        Lists all entries containing a GO term whose annotation source is the
-        IntAct database.
-    </td>
-  </tr>
-  <tr>
-    <td>strain</td>
-    <td>
-      <code>
-        strain:wistar
-      </code>
-    </td>
-    <td>
-        Lists all entries containing a reference relevant to strain wistar.
-    </td>
-  </tr>
-  <tr>
-    <td>taxonomy</td>
-    <td>
-      <code>
-        taxonomy:40674
-      </code>
-    </td>
-    <td>
-        Lists all entries for proteins expressed in Mammals. This field is used to retrieve
-        entries for all organisms classified below a given taxonomic node taxonomy classification).
-    </td>
-  </tr>
-  <tr>
-    <td>tissue</td>
-    <td>
-      <code>
-        tissue:liver
-      </code>
-    </td>
-    <td>
-        Lists all entries containing a reference describing the protein sequence
-        obtained from a clone isolated from liver.
-    </td>
-  </tr>
-  <tr>
-    <td>web</td>
-    <td>
-      <code>
-        web:wikipedia
-      </code>
-    </td>
-    <td>
-        Lists all entries for proteins that are described in Wikipedia.
-    </td>
-  </tr>
-</table>
+      </td>
+    </tr>
+    <tr>
+      <td>domain</td>
+      <td><code> domain:VWFA </code></td>
+      <td>Lists all entries with a Von Willebrand factor type A
+        domain described in the 'Family and Domains' section.</td>
+    </tr>
+    <tr>
+      <td>ec</td>
+      <td><code> ec:3.2.1.23 </code></td>
+      <td>Lists all beta-galactosidases.</td>
+    </tr>
+    <tr>
+      <td>evidence</td>
+      <td><code>
+          annotation:(type:signal evidence:ECO_0000269)<br />
+          (type:mod_res phosphoserine evidence:ECO_0000269)<br />
+          annotation:(type:function AND evidence:ECO_0000255)
+        </code></td>
+      <td>Lists all entries with:
+        <ul>
+          <li>a signal sequence whose positions have been
+            experimentally proven</li>
+          <li>experimentally proven phosphoserine sites</li>
+          <li>a function manually asserted according to rules</li>
+        </ul>
+      </td>
+    </tr>
+    <tr>
+      <td>family</td>
+      <td><code> family:serpin </code></td>
+      <td>Lists all entries belonging to the Serpin family of
+        proteins.</td>
+    </tr>
+    <tr>
+      <td>fragment</td>
+      <td><code> fragment:yes </code></td>
+      <td>Lists all entries with an incomplete sequence.</td>
+    </tr>
+
+    <tr>
+      <td>gene</td>
+      <td><code> gene:HSPC233 </code></td>
+      <td>Lists all entries for proteins encoded by gene HSPC233.</td>
+    </tr>
+    <tr>
+      <td>go</td>
+      <td><code>
+          go:cytoskeleton <br /> go:0015629
+        </code></td>
+      <td>Lists all entries associated with:
+        <ul>
+          <li>a GO term containing the word "cytoskeleton"</li>
+          <li>the GO term Actin cytoskeleton and any subclasses</li>
+        </ul>
+      </td>
+    </tr>
+    <tr>
+      <td>host</td>
+      <td><code>
+          host:mouse <br /> host:10090 <br /> host:40674
+        </code></td>
+      <td>Lists all entries for viruses infecting:
+        <ul>
+          <li>organisms with a name containing the word "mouse"</li>
+          <li>Mus musculus (Mouse)</li>
+          <li>all mammals (all taxa classified under the taxonomy
+            node for Mammalia)</li>
+        </ul>
+      </td>
+    </tr>
+    <tr>
+      <td>id</td>
+      <td><code>id:P00750</code></td>
+      <td>Returns the entry with the primary accession number
+        P00750.</td>
+    </tr>
+    <tr>
+      <td>inn</td>
+      <td><code> inn:Anakinra </code></td>
+      <td>Lists all entries whose "International Nonproprietary
+        Name" is Anakinra.</td>
+    </tr>
+    <tr>
+      <td>interactor</td>
+      <td><code> interactor:P00520 </code></td>
+      <td>Lists all entries describing interactions with the
+        protein described by entry P00520.</td>
+    </tr>
+    <tr>
+      <td>keyword</td>
+      <td><code> keyword:toxin </code></td>
+      <td>Lists all entries associated with the keyword Toxin.</td>
+    </tr>
+    <tr>
+      <td>length</td>
+      <td><code> length:[500 TO 700] </code></td>
+      <td>Lists all entries describing sequences of length between
+        500 and 700 residues.</td>
+    </tr>
+    <tr>
+      <td>lineage</td>
+      <td />
+      <td>This field is a synonym for the field <code>taxonomy</code>.
+      </td>
+    </tr>
+    <tr>
+      <td>mass</td>
+      <td><code> mass:[500000 TO *] </code></td>
+      <td>Lists all entries describing sequences with a mass of at
+        least 500,000 Da.</td>
+    </tr>
+    <tr>
+      <td>method</td>
+      <td><code>
+          method:maldi <br /> method:xray
+        </code></td>
+      <td>Lists all entries for proteins identified by:
+        matrix-assisted laser desorption/ionization (MALDI),
+        crystallography (X-Ray). The <code>method</code> field searches
+        names of physico-chemical identification methods in the
+        'Biophysicochemical properties' subsection of the 'Function'
+        section, the 'Publications' and 'Cross-references' sections.
+      </td>
+    </tr>
+    <tr>
+      <td>mnemonic</td>
+      <td><code> mnemonic:ATP6_HUMAN </code></td>
+      <td>Lists all entries with entry name (ID) ATP6_HUMAN.
+        Searches also obsolete entry names.</td>
+    </tr>
+    <tr>
+      <td>modified</td>
+      <td><code>
+          modified:[20120101 TO 20120301]<br /> reviewed:yes AND
+          modified:[current TO *]
+        </code></td>
+      <td>Lists all entries that were last modified between January
+        and March 2012.<br /> Lists all UniProtKB/Swiss-Prot entries
+        modified in the last release.
+      </td>
+    </tr>
+    <tr>
+      <td>name</td>
+      <td><code> name:"prion protein" </code></td>
+      <td>Lists all entries for prion proteins.</td>
+    </tr>
+    <tr>
+      <td>organelle</td>
+      <td><code> organelle:Mitochondrion </code></td>
+      <td>Lists all entries for proteins encoded by a gene of the
+        mitochondrial chromosome.</td>
+    </tr>
+    <tr>
+      <td>organism</td>
+      <td><code>
+          organism:"Ovis aries" <br /> organism:9940 <br />
+          organism:sheep <br />
+        </code></td>
+      <td>Lists all entries for proteins expressed in sheep (first
+        2 examples) and organisms whose name contains the term "sheep".
+      </td>
+    </tr>
+
+    <tr>
+      <td>plasmid</td>
+      <td><code> plasmid:ColE1 </code></td>
+      <td>Lists all entries for proteins encoded by a gene of
+        plasmid ColE1.</td>
+    </tr>
+    <tr>
+      <td>proteome</td>
+      <td><code> proteome:UP000005640 </code></td>
+      <td>Lists all entries from the human proteome.</td>
+    </tr>
+    <tr>
+      <td>proteomecomponent</td>
+      <td><code> proteomecomponent:"chromosome 1" and
+          organism:9606 </code></td>
+      <td>Lists all entries from the human chromosome 1.</td>
+    </tr>
+    <tr>
+      <td>replaces</td>
+      <td><code> replaces:P02023 </code></td>
+      <td>Lists all entries that were created from a merge with
+        entry P02023.</td>
+    </tr>
+    <tr>
+      <td>reviewed</td>
+      <td><code> reviewed:yes </code></td>
+      <td>Lists all UniProtKB/Swiss-Prot entries.</td>
+    </tr>
+    <tr>
+      <td>scope</td>
+      <td><code> scope:mutagenesis </code></td>
+      <td>Lists all entries containing a reference that was used to
+        gather information about mutagenesis.</td>
+    </tr>
+    <tr>
+      <td>sequence</td>
+      <td><code> sequence:P05067-9 </code></td>
+      <td>Lists all entries containing a link to isoform 9 of the
+        sequence described in entry P05067. Allows searching by specific
+        sequence identifier.</td>
+    </tr>
+    <tr>
+      <td>sequence_modified</td>
+      <td><code>
+          sequence_modified:[20120101 TO 20120301]<br /> reviewed:yes
+          AND sequence_modified:[current TO *]
+        </code></td>
+      <td>Lists all entries whose sequences were last modified
+        between January and March 2012.<br /> Lists all
+        UniProtKB/Swiss-Prot entries whose sequences were modified in
+        the last release.
+      </td>
+    </tr>
+    <tr>
+      <td>source</td>
+      <td><code> source:intact </code></td>
+      <td>Lists all entries containing a GO term whose annotation
+        source is the IntAct database.</td>
+    </tr>
+    <tr>
+      <td>strain</td>
+      <td><code> strain:wistar </code></td>
+      <td>Lists all entries containing a reference relevant to
+        strain wistar.</td>
+    </tr>
+    <tr>
+      <td>taxonomy</td>
+      <td><code> taxonomy:40674 </code></td>
+      <td>Lists all entries for proteins expressed in Mammals. This
+        field is used to retrieve entries for all organisms classified
+        below a given taxonomic node taxonomy classification).</td>
+    </tr>
+    <tr>
+      <td>tissue</td>
+      <td><code> tissue:liver </code></td>
+      <td>Lists all entries containing a reference describing the
+        protein sequence obtained from a clone isolated from liver.</td>
+    </tr>
+    <tr>
+      <td>web</td>
+      <td><code> web:wikipedia </code></td>
+      <td>Lists all entries for proteins that are described in
+        Wikipedia.</td>
+    </tr>
+  </table>
 
 </body>
 </html>
\ No newline at end of file
index ed7cbb7..edd8995 100644 (file)
@@ -25,7 +25,7 @@
 <body>
 
   <strong>The UniProt Free Text Search Interface</strong>
-  <br /> Since version 2.10 (September 2016), the Jalview Desktop
+  <br /> Since version 2.10 (October 2016), the Jalview Desktop
   provides a search interface for interactive discovery and retrieval of
   sequence data from UniProt. This dialog enables UniProt sequence
   metadata to be searched with free text and structured queries, which
@@ -48,7 +48,7 @@
   </p>
   <p>
     To search UniProt, simply begin typing in the text box. After a
-    short delay (uabout 1.5 seconds), results will be shown in the table
+    short delay (about 1.5 seconds), results will be shown in the table
     below. You can sort results by clicking on the displayed columns,
     and select entries with the mouse or keyboard. Once you have
     selected one or more entries, hit the <strong>OK</strong> button to
       mnt_mouse).<br />Hitting Return or OK will automatically fetch
       those IDs, like the default Sequence Fetcher interface.</li>
 
-    <li><strong><a name="text-search">Complex queries with the UniProt query
-        Syntax</a></strong> The text box also allows complex queries to be entered.
-      The table below provides a brief overview of the supported syntax
-      (see <a href="uniprotqueryfields.html">query fields for
-        UniProtKB</a>):
+    <li><strong><a name="text-search">Complex queries
+          with the UniProt query Syntax</a></strong> The text box also allows complex
+      queries to be entered. The table below provides a brief overview
+      of the supported syntax (see <a href="uniprotqueryfields.html">query
+        fields for UniProtKB</a>):
       <table border="1" width="95%">
         <tr>
           <td><code>human antigen</code></td>
   </p>
   <p>To change the displayed meta-data in the search result, click
     the 'Customise Displayed Options' tab, and select the fields you'd
-    like to displayed or remove.</p>
+    like to be displayed or removed.</p>
   <p>
     <em>The UniProt Free Test Search Interface was introduced in
       Jalview 2.10.0</em>
index ce446f3..77f56dc 100644 (file)
@@ -27,9 +27,9 @@
     <strong>The VARNA RNA Viewer</strong>
   </p>
   <p>
-    <a href="http://varna.lri.fr">VARNA</a> was integrated
-    into Jalview 2.8 to allow interactive viewing of RNA secondary
-    structure annotation. It is opened by selecting the <strong>&quot;Structure&#8594;View
+    <a href="http://varna.lri.fr">VARNA</a> was integrated into Jalview
+    2.8 to allow interactive viewing of RNA secondary structure
+    annotation. It is opened by selecting the <strong>&quot;Structure&#8594;View
       Structure:&quot;</strong> option in the <a href="../menus/popupMenu.html">sequence
       id pop-up menu</a> (if you can't see this, then no RNA structure is
     associated with your sequence or alignment). In the pop-up menu all
@@ -86,8 +86,8 @@
   <p>
     VARNA is a very powerful RNA viewer on its own. Only the essentials
     have been described here - the interested reader is referred to <a
-      href="http://varna.lri.fr/index.php?page=manual&css=varna"
-    >VARNA's own comprehensive online documentation</a>.
+      href="http://varna.lri.fr/index.php?page=manual&css=varna">VARNA's
+      own comprehensive online documentation</a>.
   </p>
 </body>
 </html>
index 9cead2d..f60da1a 100755 (executable)
       </ul>
     </li>
     <li><strong>Selecting Structures</strong><br />You can select
-      the structures that you want to open and view by selecting them with
-      the mouse and keyboard.<br />By default, if structures were
+      the structures that you want to open and view by selecting them
+      with the mouse and keyboard.<br />By default, if structures were
       discovered, then some will already be selected according to the
       criteria shown in the drop-down menu. The default criteria is
       'highest resolution', simply choose another to pick structures in
       a different way.<br />
       <ul>
-        <li><strong>Viewing Cached Structures</strong><br />If you
-          have previously downloaded structures for your sequences, they
-          can be viewed by selecting the <strong>Cached PDB
-            Entries</strong> option from the drop down menu at the top of the
-          dialog box.</li>
+        <li><strong>Viewing Cached Structures</strong><br />If
+          previously downloaded structures are available for your
+          sequences, the structure chooser will automatically offer them
+          via the <strong>Cached PDB Entries</strong> view. If you wish
+          to download new structures, select one of the PDBe selection
+          criteria from the drop-down menu.</li>
       </ul></li>
     <li><strong>To view selected structures, click the <strong>"View"</strong>
-      button.</strong><br />
+        button.
+    </strong><br />
       <ul>
         <li>Additional structure data will be downloaded with the
           EMBL-EBI's dbfetch service</li>
         <li><a href="siftsmapping.html">SIFTS</a> records will also
           be downloaded for mapping UniProt protein sequence data to PDB
           coordinates.</li>
+        <li>A new structure viewer will open, or you will be
+          prompted to add structures to existing viewers (see <a
+          href="#afterviewbutton">below</a> for details).
+        </li>
       </ul></li>
   </ol>
-
+  <p>
+  <strong>Structure Viewers in the Jalview Desktop</strong><br/>
   The
   <a href="jmol.html">Jmol viewer</a> has been included since Jalview
   2.3. Jalview 2.8.2 included support for
     the <a href="xsspannotation.html">Annotation from Structure</a> page
     for more information.
   </p>
-
   <p>
-    If a <strong>single</strong> PDB structure is selected, one of the
-    following will happen:
+    <strong><a name="afterviewbutton">After pressing the
+        'View' button in the Structure Chooser</a></strong><br /> The behaviour of
+    the 'View' button depends on the number of structures selected, and
+    whether structure views already exist for the selected structures or
+    aligned sequences.
+  </p>
+  <p>
+    If multiple structures are selected, then Jalview will always create
+    a new structure view. The selected structures will be imported into
+    this view, and superposed with the matched positions from the
+    aligned sequences.<br /> If a <strong>single</strong> PDB structure
+    is selected, one of the following will happen:
   </p>
 
   <ul>
 
     <li>If another structure is already shown for the current
       alignment, then you will be asked if you want to add and <a
-      href="jmol.html#align">align this structure</a> to the structure
-      in the existing view. (<em>new feature in Jalview 2.6</em>).
-    </li>
+      href="jmol.html#align"></a> to
+    the structure in the existing view. (<em>new feature in Jalview
+      2.6</em>).
+  </li>
 
     <li>If the structure is already shown, then you will be
       prompted to associate the sequence with an existing view of the
     retrieved with this service are derived directly from the PDB 3D
     structure data, which can be viewed in the same way above. Secondary
     structure and temperature factor annotation can also be added. <br />
- <br>Jalview
-    will also read PDB files directly - either in PDB format, or <a
-      href="mmcif.html">mmCIF</a>. Simply load in the file as you would
-    an alignment file. The sequences of any protein or nucleotide chains
-    will be extracted from the file and viewed in the alignment window.
+
+    <br>Jalview will also read PDB files directly - either in PDB
+    format, or <a href="mmcif.html">mmCIF</a>. Simply load in the file
+    as you would an alignment file. The sequences of any protein or
+    nucleotide chains will be extracted from the file and viewed in the
+    alignment window.
   </p>
 
   <p>
       Features"</strong> menu item and the <a href="featuresettings.html">Feature
       Settings dialog box</a>.
   </p>
-  <br/>
+  <br />
   <hr>
   <p>
     <strong>Switching between mmCIF and PDB format for
index 1c6ab7b..870b005 100644 (file)
     tab in the <strong>Tools&rarr;Preferences</strong> dialog allow the
     processing of structure data to be disabled, or selectively enabled.
     For more information, take a look at the <a
-      href="preferences.html#structure"
-    >documentation for the structure panel</a>.
+      href="preferences.html#structure">documentation for the
+      structure panel</a>.
   </p>
   <p>
     <em>The display of secondary structure data was introduced in
       Jalview 2.8.2, and is made possible by Jalview's use of <a
-      href="jmol.html"
-    >Jmol's DSSP implementation</a>, based on the original <a
-      href="http://www.ncbi.nlm.nih.gov/pubmed/6667333"
-    >Kabsch and Sander algorithm</a> ported by <a
-      href="http://swift.cmbi.ru.nl/gv/dssp/"
-    >Robbie P. Joosten and colleagues</a>, and a client for <a
-      href="https://github.com/fjossinet/PyRNA"
-    >Fabrice Jossinet's pyRNA services</a> that was developed by Anne
-      Menard, Jim Procter and Yann Ponty as part of the Jalview Summer
-      of Code 2012.
+      href="jmol.html">Jmol's DSSP implementation</a>, based on the
+      original <a href="http://www.ncbi.nlm.nih.gov/pubmed/6667333">Kabsch
+        and Sander algorithm</a> ported by <a
+      href="http://swift.cmbi.ru.nl/gv/dssp/">Robbie P. Joosten
+        and colleagues</a>, and a client for <a
+      href="https://github.com/fjossinet/PyRNA">Fabrice
+        Jossinet's pyRNA services</a> that was developed by Anne Menard, Jim
+      Procter and Yann Ponty as part of the Jalview Summer of Code 2012.
     </em>
   </p>
 </body>
index fe848a9..2ebaf45 100644 (file)
 <body>
   <p>
     <strong>Extending Jalview with Groovy - A customisable
-      feature counter</strong><br /> 
-    <br />The groovy script below shows how to add a new calculation
-    track to a Jalview alignment window.</p><p>As currently written, it will
-    add two tracks to a protein alignment view which count Pfam features
-    in each column, and ones where a charge residue also occur.</p><p>To try
-    it for yourself:</p><ol><li>Copy and paste it into the groovy script
-    console</li><li>Load the example Feredoxin project (the one that opens
-    by default when you first launched Jalview)</li><li>Select <strong>Calculations&#8594;Execute
-      Groovy Script</strong> from the alignment window's menu bar to run the script on
-    the current view.</li></ol>
+      feature counter</strong><br /> <br />The groovy script below shows how to
+    add a new calculation track to a Jalview alignment window.
+  </p>
+  <p>As currently written, it will add two tracks to a protein
+    alignment view which count Pfam features in each column, and ones
+    where a charge residue also occur.</p>
+  <p>To try it for yourself:</p>
+  <ol>
+    <li>Copy and paste it into the groovy script console</li>
+    <li>Load the example Feredoxin project (the one that opens by
+      default when you first launched Jalview)</li>
+    <li>Select <strong>Calculations&#8594;Execute Groovy
+        Script</strong> from the alignment window's menu bar to run the script on
+      the current view.
+    </li>
+  </ol>
   <em><a
-      href="http://www.jalview.org/examples/groovy/featureCounter.groovy">http://www.jalview.org/examples/groovy/featureCounter.groovy</a> - rendered with <a href="http://hilite.me">hilite.me</a></em>
+    href="http://www.jalview.org/examples/groovy/featureCounter.groovy">http://www.jalview.org/examples/groovy/featureCounter.groovy</a>
+    - rendered with <a href="http://hilite.me">hilite.me</a></em>
   <!-- HTML generated using hilite.me -->
   <div
     style="background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
index 5bb9020..62b46a9 100755 (executable)
@@ -45,8 +45,7 @@
   <p>
     For more information, you might also want to take a look at the
     documentation section of the Jalview website (<a
-      href="http://www-test.jalview.org/about/documentation"
-    >http://www.jalview.org/about/documentation</a>).
+      href="http://www-test.jalview.org/about/documentation">http://www.jalview.org/about/documentation</a>).
   </p>
   <p>
     If you are using the Jalview Desktop application and are looking for
@@ -55,8 +54,7 @@
     google the online version of these pages. If you don't find what you
     are looking for, or want to report a bug or make a feature request,
     then get in contact over at <a
-      href="http://www.jalview.org/community"
-    >http://www.jalview.org/community</a>
+      href="http://www.jalview.org/community">http://www.jalview.org/community</a>
   </p>
 
   <p>
@@ -70,8 +68,8 @@
     <strong>25</strong> (9) 1189-1191 doi: 10.1093/bioinformatics/btp033
   </p>
   <p>
-    <strong>The Jalview Authors</strong><br /> The following people have
-    contributed to Jalview's development:
+    <strong>The Jalview Authors</strong><br /> The following people
+    have contributed to Jalview's development:
   <ul>
     <li>Jalview 1
       <ul>
index 46e7fe4..8a554aa 100755 (executable)
@@ -25,8 +25,7 @@
 <body>
   <p>
     <strong>Exporting alignments as graphics and lineart<a
-      name="export"
-    ></a></strong>
+      name="export"></a></strong>
   </p>
   <p>
     The alignment view can be printed using <strong>File&#8594;Print</strong>,
index 46e2189..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>.
   </p>
   <img src="seqreport.gif"
-    alt="Sequence Annotation is displayed as HTML in a report window"
-  />
+    alt="Sequence Annotation is displayed as HTML in a report window" />
   <p>
     <strong>Copying and pasting annotation to other programs</strong><br>
     The <strong>File&rarr;Save</strong> option in the sequence
index d887f18..af4e2c4 100755 (executable)
@@ -95,9 +95,9 @@ td {
     <tr>
       <td width="17%">JSON</td>
       <td width="60%">Data starts with '{' <br>Data ends with
-        '}' <br>
-      <br>See <a href="../features/bioJsonFormat.html">BioJSON</a>
-        for more infomation about the Jalview JSON format <br></td>
+        '}' <br> <br>See <a
+        href="../features/bioJsonFormat.html">BioJSON</a> for more
+        infomation about the Jalview JSON format <br></td>
       <td width="23%">.json</td>
     </tr>
 
index d2196c1..b0d6b04 100755 (executable)
   </p>
   <p>
     Jalview can also read Jalview specific files for <a
-      href="../features/featuresFormat.html"
-    >sequence features</a> and <a
-      href="../features/annotationsFormat.html"
-    >alignment annotation</a>.
+      href="../features/featuresFormat.html">sequence features</a>
+    and <a href="../features/annotationsFormat.html">alignment
+      annotation</a>.
   </p>
   <p>
     <strong>Output</strong>
index 1fc5f39..d6157fb 100755 (executable)
   </p>
   <p>
     The homology modelling program, <a
-      href="http://salilab.org/modeller/"
-    >Modeller</a> uses a special form of the PIR format where information
-    about sequence numbering and chain codes are written into the
-    'description' line between the PIR protein tag and the protein
-    alignment entry:
+      href="http://salilab.org/modeller/">Modeller</a> uses a
+    special form of the PIR format where information about sequence
+    numbering and chain codes are written into the 'description' line
+    between the PIR protein tag and the protein alignment entry:
   </p>
   <pre>&gt;P1;Q93Z60_ARATH
 sequence:Q93Z60_ARATH:1:.:118:.:.
@@ -52,12 +51,12 @@ KDPLPDAEDWDGVKGKLQHLE*
     no information is lost if this parsing process fails.</p>
   <p>
     The 'Modeller Output' flag in the 'Output' tab of the Jalview <a
-      href="../features/preferences.html"
-    >Preferences dialog box</a> controls whether Jalview will also output
-    MODELLER style PIR files. In this case, any existing 'non-modeller
-    PIR' header information in the description string of an alignment is
-    appended to an automatically generated modeller description line for
-    that sequence.
+      href="../features/preferences.html">Preferences dialog
+      box</a> controls whether Jalview will also output MODELLER style PIR
+    files. In this case, any existing 'non-modeller PIR' header
+    information in the description string of an alignment is appended to
+    an automatically generated modeller description line for that
+    sequence.
   </p>
   <p>The general format used for generating the Modeller/PIR
     sequence description line is shown below :
index c8e5aec..08d1889 100644 (file)
@@ -30,8 +30,8 @@
     T-COFFEE score files like the <a href="#tcoffeeeg">one below</a> can
     be displayed on the alignment using the <strong><em>Colours&rarr;T-COFFEE
         Scores</em></strong> or <strong><em>Colour &rarr; <a
-        href="../colourSchemes/annotationColouring.html"
-      >Colour by Annotation</a></em></strong> options.
+        href="../colourSchemes/annotationColouring.html">Colour
+          by Annotation</a></em></strong> options.
   </p>
   <img src="../colourSchemes/colbytcoffee.png" />
   <p>
index f129551..1a5fc18 100755 (executable)
     Jalview has two distinct modes of keyboard operation - in 'Normal'
     mode, single keystrokes (including those shown next to menu items)
     provide short cuts to common commands. In <a
-      href="features/cursorMode.html"
-    >'Cursor'</a> mode (enabled by <em>F2</em>), some of these are
-    disabled and more complex 'Compound Keystrokes' can be entered to
-    perform precise navigation, selection and editing operations.
+      href="features/cursorMode.html">'Cursor'</a> mode (enabled by
+    <em>F2</em>), some of these are disabled and more complex 'Compound
+    Keystrokes' can be entered to perform precise navigation, selection
+    and editing operations.
   </p>
   <table border="1">
     <tr>
@@ -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>
@@ -279,7 +292,7 @@ columns are selected, you should use the <a href="features/hiddenRegions.html">H
       <td>Cursor</td>
       <td>Move cursor to a particular column (<strong><em>p1</em></strong>)
         and row (<strong><em>p2</em></strong>) in the alignment.<br>
-      <em>e.g. '5,6&lt;Return&gt;' moves the cursor to the 5th
+        <em>e.g. '5,6&lt;Return&gt;' moves the cursor to the 5th
           column in the 6th sequence.</em></td>
     </tr>
     <tr>
@@ -317,25 +330,22 @@ columns are selected, you should use the <a href="features/hiddenRegions.html">H
       <td><strong><em>[p]</em><br>Space</strong></td>
       <td>Cursor</td>
       <td>Inserts one (or optionally <strong><em>p</em></strong>)
-        gaps at the current position.<br>
-      <em>Hold down Control or Shift to insert gaps over a sequence
-          group</em></td>
+        gaps at the current position.<br> <em>Hold down
+          Control or Shift to insert gaps over a sequence group</em></td>
     </tr>
     <tr>
       <td><strong><em>[p]</em><br>Delete<br></strong></td>
       <td>Cursor</td>
       <td>Removes one (or optionally <strong><em>p</em></strong>)
-        gaps at the cursor position.<br>
-      <em>Hold down Control or Shift to insert gaps over a sequence
-          group</em></td>
+        gaps at the cursor position.<br> <em>Hold down Control
+          or Shift to insert gaps over a sequence group</em></td>
     </tr>
     <tr>
       <td><strong><em>[p]</em><br>Backspace<br></strong></td>
       <td>Cursor</td>
       <td>Removes one (or optionally <strong><em>p</em></strong>)
-        gaps at the cursor position.<br>
-      <em>Hold down Control or Shift to insert gaps over a sequence
-          group</em></td>
+        gaps at the cursor position.<br> <em>Hold down Control
+          or Shift to insert gaps over a sequence group</em></td>
     </tr>
   </table>
   <p>&nbsp;</p>
index 9c856a9..2142f98 100755 (executable)
         file. You can obtain a JNLP file with modified memory settings
         from our service with the following link (replace 2G with
         desired memory in G or M):<br /> <a
-          href="http://www.jalview.org/services/launchApp?jvm-max-heap=2G"
-        >http://www.jalview.org/services/launchApp?jvm-max-heap=2G</a>
+          href="http://www.jalview.org/services/launchApp?jvm-max-heap=2G">http://www.jalview.org/services/launchApp?jvm-max-heap=2G</a>
       </p>
       <p>
         Alternatively, if you want to create your own JNLP file then
         please download the latest JNLP file from <a
-          href="http://www.jalview.org/webstart/jalview.jnlp"
-        >http://www.jalview.org/webstart/jalview.jnlp</a> and modify the
-        max-heap-size parameter for the j2se tag in the
+          href="http://www.jalview.org/webstart/jalview.jnlp">http://www.jalview.org/webstart/jalview.jnlp</a>
+        and modify the max-heap-size parameter for the j2se tag in the
         &lt;resources&gt; element. e.g.
       <pre>
 &lt;j2se version="1.7+" initial-heap-size="500M" max-heap-size="1000M"/&gt;
@@ -109,6 +107,7 @@ lax.nl.java.option.java.heap.size.initial=500m
             The lines you need to change are in the <em>Info.plist</em>
             file inside the <em>Jalview.app/Contents</em> directory
             (which is where the installAnywhere installation was made) :
+
           
           <pre>
 &lt;key&ht;VMOptions&lt;/key&ht;
index 5739797..167cb25 100755 (executable)
         </em></li>
         <li><strong>Load Features / Annotations<br>
         </strong><em>Load files describing precalculated <a
-            href="../features/featuresFormat.html"
-          >sequence features</a> or <a
-            href="../features/annotationsFormat.html"
-          >alignment annotations</a>.
+            href="../features/featuresFormat.html">sequence
+              features</a> or <a href="../features/annotationsFormat.html">alignment
+              annotations</a>.
         </em></li>
         <li><strong>Close (Control W)</strong><br> <em>Close
             the alignment window. Make sure you have saved your
         </strong><em>All columns which only contain gap characters
             (&quot;-&quot;, &quot;.&quot;) will be deleted.<br> You
             may set the default gap character in <a
-            href="../features/preferences.html"
-          >preferences</a>.
+            href="../features/preferences.html">preferences</a>.
         </em></li>
         <li><strong>Remove All Gaps (Control Shift E)</strong><br>
           <em>Gap characters (&quot;-&quot;, &quot;.&quot;) will be
             deleted from the selected area of the alignment. If no
             selection is made, ALL the gaps in the alignment will be
             removed.<br> You may set the default gap character in <a
-            href="../features/preferences.html"
-          >preferences</a>.
+            href="../features/preferences.html">preferences</a>.
         </em></li>
         <li><strong>Remove Redundancy (Control D)<br>
         </strong><em>Selecting this option brings up a window asking you to
             with alignment analysis programs which require 'properly
             aligned sequences' to be all the same length.<br> You
             may set the default for <strong>Pad Gaps</strong> in the <a
-            href="../features/preferences.html"
-          >preferences</a>.
+            href="../features/preferences.html">preferences</a>.
         </em></li>
       </ul></li>
     <li><strong>Select</strong>
             <strong>WARNING</strong>: This cannot be undone.
         </em></li>
         <li><strong><a
-            href="../features/columnFilterByAnnotation.html"
-          >Select/Hide 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>
+            href="../features/columnFilterByAnnotation.html">Select/Hide
+              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>
         <li><strong>Show Sequence Features</strong><br> <em>Show
             or hide sequence features on this alignment.</em></li>
         <li><strong><a
-            href="../features/featuresettings.html"
-          >Sequence Feature Settings...</a> </strong><em><br> <em>Opens
-              the Sequence Feature Settings dialog box to control the
-              colour and display of sequence features on the alignment,
-              and configure and retrieve features from DAS annotation
+            href="../features/featuresettings.html">Sequence
+              Feature Settings...</a> </strong><em><br> <em>Opens the
+              Sequence Feature Settings dialog box to control the colour
+              and display of sequence features on the alignment, and
+              configure and retrieve features from DAS annotation
               servers.</em></li>
         <li><strong>Sequence ID Tooltip</strong><em>
             (application only) <br>This submenu's options allow the
             rendering. </em></li>
         <li><strong>Wrap<br>
         </strong><em>When ticked, the alignment display is &quot;<a
-            href="../features/wrap.html"
-          >wrapped</a>&quot; to the width of the alignment window. This is
-            useful if your alignment has only a few sequences to view
-            its full width at once.
+            href="../features/wrap.html">wrapped</a>&quot; to
+            the width of the alignment window. This is useful if your
+            alignment has only a few sequences to view its full width at
+            once.
         </em><br> Additional options for display of sequence numbering
           and scales are also visible in wrapped layout mode:<br>
           <ul>
-            <li><strong>Scale Above</strong><br>
-            <em> Show the alignment column position scale.</em></li>
-            <li><strong>Scale Left</strong><br>
-            <em> Show the sequence position for the first aligned
-                residue in each row in the left column of the alignment.</em></li>
-            <li><strong>Scale Right</strong><br>
-            <em> Show the sequence position for the last aligned
-                residue in each row in the right-most column of the
-                alignment.</em></li>
+            <li><strong>Scale Above</strong><br> <em>
+                Show the alignment column position scale.</em></li>
+            <li><strong>Scale Left</strong><br> <em> Show
+                the sequence position for the first aligned residue in
+                each row in the left column of the alignment.</em></li>
+            <li><strong>Scale Right</strong><br> <em>
+                Show the sequence position for the last aligned residue
+                in each row in the right-most column of the alignment.</em></li>
             <li><strong>Show Sequence Limits<br>
             </strong><em>If this box is selected the sequence name will have
                 the start and end position of the sequence appended to
           colour will be applied to all currently defined groups.<br>
       </em></li>
       <li><strong><a
-          href="../colourSchemes/textcolour.html"
-        >Colour Text...</a> </strong><em><br> Opens the Colour Text
-          dialog box to set a different text colour for light and dark
-          background, and the intensity threshold for transition between
-          them. </em></li>
+          href="../colourSchemes/textcolour.html">Colour
+            Text...</a> </strong><em><br> Opens the Colour Text dialog box
+          to set a different text colour for light and dark background,
+          and the intensity threshold for transition between them. </em></li>
       <li>Colour Scheme options: <strong>None, ClustalX,
           Blosum62 Score, Percentage Identity, Zappo, Taylor,
           Hydrophobicity, Helix Propensity, Strand Propensity, Turn
       <li><strong>By Annotation</strong><br> <em>Colours
           the alignment on a per-column value from a specified
           annotation. See <a
-          href="../colourSchemes/annotationColouring.html"
-        >Annotation Colouring</a>.
+          href="../colourSchemes/annotationColouring.html">Annotation
+            Colouring</a>.
       </em><br></li>
       <li><strong>By RNA Helices</strong><br> <em>Colours
           the helices of an RNA alignment loaded from a Stockholm file.
           provided in this menu.</strong></li>
       <li><strong>Pairwise Alignments</strong><br> <em>Applies
           Smith and Waterman algorithm to selected sequences. See <a
-          href="../calculations/pairwise.html"
-        >pairwise alignments</a>.
+          href="../calculations/pairwise.html">pairwise
+            alignments</a>.
       </em><br></li>
       <li><strong>Principal Component Analysis</strong><br> <em>Shows
           a spatial clustering of the sequences based on similarity
           scores calculated with the alignment. See <a
-          href="../calculations/pca.html"
-        >Principal Component Analysis</a>.
+          href="../calculations/pca.html">Principal
+            Component Analysis</a>.
       </em> <br></li>
       <li><strong>Extract Scores ... (optional)</strong><br> <em>This
           option is only visible if Jalview detects one or more
       or elsewhere. You need a continuous network connection in order to
       use these services through Jalview.</p>
     <ul>
-      <li><strong>Alignment</strong><br />
-      <em> Align the currently selected sequences or all sequences
-          in the alignment, or re-align unaligned sequences to the
-          aligned sequences. Entries in this menu provide access to the
-          various alignment programs supported by <a
-          href="../webServices/JABAWS.html"
-        >JABAWS</a>. See the <a href="../webServices/msaclient.html">Multiple
-            Sequence Alignment webservice client</a> entry for more
-          information.
+      <li><strong>Alignment</strong><br /> <em> Align the
+          currently selected sequences or all sequences in the
+          alignment, or re-align unaligned sequences to the aligned
+          sequences. Entries in this menu provide access to the various
+          alignment programs supported by <a
+          href="../webServices/JABAWS.html">JABAWS</a>. See the
+          <a href="../webServices/msaclient.html">Multiple Sequence
+            Alignment webservice client</a> entry for more information.
       </em></li>
       <li><strong>Secondary Structure Prediction</strong>
         <ul>
           <li><strong>Multi-Harmony</strong><br> <em>Performs
               functional residue analysis on a protein family alignment
               with sub-families defined on it. See the <a
-              href="../webServices/shmr.html"
-            >Multi-Harmony service</a> entry for more information.
+              href="../webServices/shmr.html">Multi-Harmony
+                service</a> entry for more information.
           </em></li>
         </ul></li>
     </ul></li>
index 6f91d2f..8ac116b 100755 (executable)
@@ -25,8 +25,8 @@
 
 <body>
   <p>
-    <strong>Alignment Window Annotations Menu</strong> <em>Since Jalview
-    2.8.2</em>
+    <strong>Alignment Window Annotations Menu</strong> <em>Since
+      Jalview 2.8.2</em>
   </p>
   <ul>
     <li><strong>Show Alignment Related</strong><em><br>
@@ -44,8 +44,7 @@
         example, Consensus).</em></li>
     <li><em>You can also selectively show or hide annotations
         from the <a href="./popupMenu.html">Popup</a> or <a
-        href="../features/annotation.html"
-      >Annotation</a> menus.
+        href="../features/annotation.html">Annotation</a> menus.
     </em></li>
     <li><strong>Sort by Sequence</strong><em><br>Sort
         sequence-specific annotations by sequence order in the alignment
index 7d07595..cd09693 100755 (executable)
   <ul>
     <li><strong>Annotation Label Popup Menu</strong><br> <em>This
         menu is opened by clicking anywhere on the annotation row labels
-        area (below the sequence ID area).</em>
-        <br/><em><strong>Mac Users:</strong> pressing CTRL whilst clicking
-      the mouse/track pad is the same as a right-click. See your
-      system's settings to configure your track-pad's corners to
-      generate right-clicks.</em>
+        area (below the sequence ID area).</em> <br />
+    <em><strong>Mac Users:</strong> pressing CTRL whilst clicking
+        the mouse/track pad is the same as a right-click. See your
+        system's settings to configure your track-pad's corners to
+        generate right-clicks.</em>
       <ul>
         <li><strong>Add New Row</strong><br> <em>Adds a
             new, named annotation row (a dialog box will pop up for you
index 34e8d75..8032348 100755 (executable)
       </ul></li>
     <li><strong>Pairwise Alignments</strong><br> <em>Applies
         Smith and Waterman algorithm to selected sequences. See <a
-        href="../calculations/pairwise.html"
-      >pairwise alignments</a>.
+        href="../calculations/pairwise.html">pairwise
+          alignments</a>.
     </em><br></li>
     <li><strong>Principal Component Analysis</strong><br> <em>Shows
         a spatial clustering of the sequences based on similarity scores
         calculated over the alignment.. See <a
-        href="../calculations/pca.html"
-      >Principal Component Analysis</a>.
+        href="../calculations/pca.html">Principal Component
+          Analysis</a>.
     </em> <br></li>
     <li><strong>Extract Scores ... (optional)</strong><br> <em>This
         option is only visible if Jalview detects one or more
         parsed into sequence associated annotation which can then be
         used to sort the alignment via the Sort by&#8594;Score menu.
     </em> <br></li>
-    <li><strong>Translate as cDNA</strong> (not applet)<br>
-    <em>This option is visible for nucleotide alignments. Selecting
-        this option shows the DNA's calculated protein product in a new
-        <a href="../features/splitView.html">split frame</a> window.
-        Note that the translation is not frame- or intron-aware; it
-        simply translates all codons in each sequence, using the
-        standard <a href="../misc/geneticCode.html">genetic code</a>
-        (any incomplete final codon is discarded). You can perform this
-        action on the whole alignment, or selected rows, columns, or
-        regions.
+    <li><strong>Translate as cDNA</strong> (not applet)<br> <em>This
+        option is visible for nucleotide alignments. Selecting this
+        option shows the DNA's calculated protein product in a new <a
+        href="../features/splitView.html">split frame</a> window. Note
+        that the translation is not frame- or intron-aware; it simply
+        translates all codons in each sequence, using the standard <a
+        href="../misc/geneticCode.html">genetic code</a> (any incomplete
+        final codon is discarded). You can perform this action on the
+        whole alignment, or selected rows, columns, or regions.
     </em> <br></li>
     <li><strong>Reverse, Reverse Complement</strong> (not applet)<br>
-    <em>These options are visible for nucleotide alignments. Selecting them adds the reverse (or reverse complement)
-    of the sequences (or selected region) as new sequences in the alignment. To try this out, add this sequence and
-    perform 'Reverse Complement' followed by 'Translate as cDNA':
-    <br><small>
-    Seq GTCATTTGCGCGTGTTGATTATTCGGACCGCTCCACTTCCCTTTACTCGTGCGTTCAATTGATTTAATCCTC
-    TGGGGGGGCTCTGGTTTACATAGCTTAAATCTATTCCATTCAAGGAAGCTCATG</small>
+      <em>These options are visible for nucleotide alignments.
+        Selecting them adds the reverse (or reverse complement) of the
+        sequences (or selected region) as new sequences in the
+        alignment. To try this out, add this sequence and perform
+        'Reverse Complement' followed by 'Translate as cDNA': <br>
+      <small> Seq
+          GTCATTTGCGCGTGTTGATTATTCGGACCGCTCCACTTCCCTTTACTCGTGCGTTCAATTGATTTAATCCTC
+          TGGGGGGGCTCTGGTTTACATAGCTTAAATCTATTCCATTCAAGGAAGCTCATG</small>
     </em> <br></li>
     <li><strong>Get Cross-References</strong> (not applet)<br>
-    <em>This option is visible where sequences have
+      <em>This option is visible where sequences have
         cross-references to other standard databases; for example, an
         EMBL entry may have cross-references to one or more UNIPROT
         entries. Select the database to view all cross-referenced
index 846a1bd..eb8e839 100755 (executable)
     </strong><em>All columns which only contain gap characters
         (&quot;-&quot;, &quot;.&quot;) will be deleted.<br> You may
         set the default gap character in <a
-        href="../features/preferences.html"
-      >preferences</a>.
+        href="../features/preferences.html">preferences</a>.
     </em></li>
     <li><strong>Remove All Gaps (Control Shift E)</strong><br>
       <em>Gap characters (&quot;-&quot;, &quot;.&quot;) will be
         deleted from the selected area of the alignment. If no selection
         is made, ALL the gaps in the alignment will be removed.<br>
         You may set the default gap character in <a
-        href="../features/preferences.html"
-      >preferences</a>.
+        href="../features/preferences.html">preferences</a>.
     </em></li>
     <li><strong>Remove Redundancy (Control D)<br>
     </strong><em>Selecting this option brings up a window asking you to
index bf1ba90..b8445af 100755 (executable)
@@ -32,8 +32,7 @@
         dialog window in which you can select known ids from UniProt,
         EMBL, EMBLCDS, PDB, PFAM, or RFAM databases using Web Services
         provided by the European Bioinformatics Institute. See <a
-        href="../features/seqfetch.html"
-      >Sequence Fetcher</a>
+        href="../features/seqfetch.html">Sequence Fetcher</a>
     </em>.</li>
     <li><strong>Add Sequences</strong><em><br> Add
         sequences to the visible alignment from file, URL, or cut &amp;
@@ -86,9 +85,9 @@
     <li><strong>Export Image</strong> <em><br> Creates an
         alignment graphic with the current view's annotation, alignment
         background colours and group colours. If the alignment is <a
-        href="../features/wrap.html"
-      >wrapped</a>, the output will also be wrapped and will have the same
-        visible residue width as the open alignment. </em>
+        href="../features/wrap.html">wrapped</a>, the output will
+        also be wrapped and will have the same visible residue width as
+        the open alignment. </em>
       <ul>
         <li><strong>HTML<br>
         </strong><em>Create a <a href="../io/export.html">web page</a> from
     </em></li>
     <li><strong>Load Features / Annotations<br>
     </strong><em>Load files describing precalculated <a
-        href="../features/featuresFormat.html"
-      >sequence features</a> or <a
-        href="../features/annotationsFormat.html"
-      >alignment annotations</a>.
+        href="../features/featuresFormat.html">sequence
+          features</a> or <a href="../features/annotationsFormat.html">alignment
+          annotations</a>.
     </em></li>
     <li><strong>Close (Control W)</strong><br> <em>Close
         the alignment window. Make sure you have saved your alignment
index a7cee0b..092e623 100644 (file)
       for faster alignment rendering. </em></em></li>
   <li><strong>Wrap<br>
   </strong><em>When ticked, the alignment display is &quot;<a
-      href="../features/wrap.html"
-    >wrapped</a>&quot; to the width of the alignment window. This is
-      useful if your alignment has only a few sequences to view its full
-      width at once.<br> Additional options for display of sequence
-      numbering and scales are also visible in wrapped layout mode:
+      href="../features/wrap.html">wrapped</a>&quot; to the width
+      of the alignment window. This is useful if your alignment has only
+      a few sequences to view its full width at once.<br>
+      Additional options for display of sequence numbering and scales
+      are also visible in wrapped layout mode:
   </em>
     <ul>
       <li><strong>Scale Left</strong><br> <em>Show the
index a80f239..07828a3 100644 (file)
         <strong>WARNING</strong>: This cannot be undone.
     </em></li>
     <li><strong><a
-        href="../features/columnFilterByAnnotation.html"
-      >Select/Hide 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>
+        href="../features/columnFilterByAnnotation.html">Select/Hide
+          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 1ccbbcf..20e784b 100755 (executable)
@@ -48,8 +48,8 @@
         <li><strong>Save Project</strong><br> <em>Saves
             all currently open alignment windows with their current view
             settings and any associated trees, as a <a
-            href="../features/jalarchive.html"
-          >Jalview Archive</a> (which has a .jar extension).
+            href="../features/jalarchive.html">Jalview
+              Archive</a> (which has a .jar extension).
         </em></li>
         <li><strong>Load Project</strong><br> <em>Loads
             Jalview archives <strong>only</strong>.
         window to the top of the pile when it is selected.
         <ul>
           <li><strong>Close All</strong><br> Close all
-            alignment and analysis windows.<br>
-          <strong>Note: This will erase all alignments from
-              memory, and cannot be undone!</strong></li>
+            alignment and analysis windows.<br> <strong>Note:
+              This will erase all alignments from memory, and cannot be
+              undone!</strong></li>
           <li><strong>Raise Associated Windows</strong><br>
             Bring all windows associated with the current alignment to
             the top of the pile.</li>
index fcfcdae..d799378 100755 (executable)
   <p>
     The <a href="popupMenu.html">Popup Menus</a> are opened by clicking
     with the right mouse button in the alignment display area or on a
-    sequence label in the alignment window.<br />
-    <em><strong>Mac Users:</strong> pressing CTRL whilst clicking
-      the mouse/track pad is the same as a right-click. See your
-      system's settings to configure your track-pad's corners to
-      generate right-clicks.</em>
+    sequence label in the alignment window.<br /> <em><strong>Mac
+        Users:</strong> pressing CTRL whilst clicking the mouse/track pad is the
+      same as a right-click. See your system's settings to configure
+      your track-pad's corners to generate right-clicks.</em>
   </p>
   <p>
     The <a href="alwannotationpanel.html">Annotations Menu</a> is opened
index 79e7ada..d42f854 100755 (executable)
 
 <body>
   <p>
-    <strong>Popup Menu</strong><br> <em>This menu is visible when
-      right clicking either within a selected region on the alignment or
-      on a selected sequence name. It may not be accessible when in
-      'Cursor Mode' (toggled with the F2 key).</em><br /> <em><strong>Mac Users:</strong> pressing CTRL whilst clicking
-        the mouse/track pad is the same as a right-click. See your
-        system's settings to configure your track-pad's corners to
-        generate right-clicks.</em>
+    <strong>Popup Menu</strong><br> <em>This menu is visible
+      when right clicking either within a selected region on the
+      alignment or on a selected sequence name. It may not be accessible
+      when in 'Cursor Mode' (toggled with the F2 key).</em><br /> <em><strong>Mac
+        Users:</strong> pressing CTRL whilst clicking the mouse/track pad is the
+      same as a right-click. See your system's settings to configure
+      your track-pad's corners to generate right-clicks.</em>
   </p>
   <ul>
     <li><strong>Selection</strong>
@@ -39,9 +39,9 @@
         <li><a name="sqreport"><strong>Sequence
               Details...<br>
           </strong></a><em>(Since Jalview 2.8)<br>Open an <a
-            href="../io/exportseqreport.html"
-          >HTML report containing the annotation and database cross
-              references</a>&nbsp;normally shown in the sequence's tooltip.
+            href="../io/exportseqreport.html">HTML report
+              containing the annotation and database cross references</a>&nbsp;normally
+            shown in the sequence's tooltip.
         </em></li>
         <li><strong>Show Annotations...<br>
         </strong><em>Choose to show (unhide) either All or a selected type
         </strong><em>The selection area will be output to a a text window in
             the selected alignment format. </em></li>
         <li><strong><a
-            href="../features/creatinFeatures.html"
-          >Create Sequence Feature...</a></strong><br> <em>Opens the
-            dialog box for creating sequence features over the currently
-            selected region on each selected sequence.</em></li>
+            href="../features/creatinFeatures.html">Create
+              Sequence Feature...</a></strong><br> <em>Opens the dialog box
+            for creating sequence features over the currently selected
+            region on each selected sequence.</em></li>
         <li><strong>Create Group<br>
         </strong><em>This will define a new group from the current
             selection.</em><strong> </strong></li>
         <li><a name="sqreport"><strong>Sequence
               Details ...<br>
           </strong></a><em>(Since Jalview 2.8)<br>Open an <a
-            href="../io/exportseqreport.html"
-          >HTML report containing the annotation and database cross
-              references</a> normally shown in the sequence's tooltip.
+            href="../io/exportseqreport.html">HTML report
+              containing the annotation and database cross references</a>
+            normally shown in the sequence's tooltip.
         </em></li>
         <li><strong>Edit Name/Description<br>
         </strong><em>You may edit the name and description of each sequence.
             and sequence description to be entered. Press OK to accept
             your edit. To save sequence descriptions, you must save in
             Fasta, PIR or Jalview File format.</em></li>
-        <li><strong>Add <a href="../features/annotation.html#seqannots">Reference Annotations</a></strong><br>
-              <em>When enabled, copies any available alignment
-              annotation for this sequence to the current view.</em></li>
+        <li><strong>Add <a
+            href="../features/annotation.html#seqannots">Reference
+              Annotations</a></strong><br> <em>When enabled, copies any
+            available alignment annotation for this sequence to the
+            current view.</em></li>
         <li><strong>Set as Reference</strong> or <strong>Unmark
-            as Reference</strong><br /> Sets or unsets the reference sequence for
-          the the alignment.</li>
+            as Reference</strong><br /> Sets or unsets the reference sequence
+          for the the alignment.</li>
 
         <li><strong>Represent Group With (Sequence Id)</strong><br>
           <em>All sequences in the current selection group will be
               Connections tab.<br> Since Jalview 2.4, links will
               also be made for database cross references (where the
               database name exactly matches the link name set up in <a
-              href="../features/preferences.html"
-            >Preferences</a>). <br>Since Jalview 2.5, links are also
-              shown for non-positional sequence features attached to the
-              sequence, and any regular-expression based URL links that
-              matched the description line.
+              href="../features/preferences.html">Preferences</a>).
+              <br>Since Jalview 2.5, links are also shown for
+              non-positional sequence features attached to the sequence,
+              and any regular-expression based URL links that matched
+              the description line.
           </em><strong><br> </strong></li>
       </ul></li>
     <li><strong>3D Structure Data...</strong> </strong><em>This menu is
         visible when you right-click on a sequence name. When this
         option is clicked, Jalview will open the <a
-        href="../features/structurechooser.html">'Structure
-          Chooser' </a>, which allows you to discover and view 3D structures
-        for the current selection. For more info, see <a
+        href="../features/structurechooser.html">'Structure Chooser'
+      </a>, which allows you to discover and view 3D structures for the
+        current selection. For more info, see <a
         href="../features/viewingpdbs.html">viewing PDB structures</a>.
     </em></li>
-    <li><strong>VARNA 2D Structure</strong><br />
-    <em> If the sequence or alignment has RNA structure, then <strong>VARNA
+    <li><strong>VARNA 2D Structure</strong><br /> <em> If the
+        sequence or alignment has RNA structure, then <strong>VARNA
           2D Structure</strong> entries will also be present enabling you to open
         a linked view of the RNA structure in <a
-        href="../features/varna.html"
-      >VARNA</a>.
+        href="../features/varna.html">VARNA</a>.
     </em></li>
     <li><a name="hideinserts"><strong>Hide Insertions</strong></a><br />
       <em>Hides columns containing gaps in the current sequence or
index ee44c91..33282e9 100755 (executable)
     elsewhere. You need a continuous network connection in order to use
     these services through Jalview.</p>
   <ul>
-    <li><strong>Alignment</strong><br />
-    <em> Align the currently selected sequences or all sequences in
-        the alignment, or re-align unaligned sequences to the aligned
-        sequences. Entries in this menu provide access to the various
-        alignment programs supported by <a
-        href="../webServices/JABAWS.html"
-      >JABAWS</a>. See the <a href="../webServices/msaclient.html">Multiple
+    <li><strong>Alignment</strong><br /> <em> Align the
+        currently selected sequences or all sequences in the alignment,
+        or re-align unaligned sequences to the aligned sequences.
+        Entries in this menu provide access to the various alignment
+        programs supported by <a href="../webServices/JABAWS.html">JABAWS</a>.
+        See the <a href="../webServices/msaclient.html">Multiple
           Sequence Alignment webservice client</a> entry for more
         information.
     </em></li>
@@ -96,8 +95,8 @@
         <li><strong>Multi-Harmony</strong><br> <em>Performs
             functional residue analysis on a protein family alignment
             with sub-families defined on it. See the <a
-            href="../webServices/shmr.html"
-          >Multi-Harmony service</a> entry for more information.
+            href="../webServices/shmr.html">Multi-Harmony
+              service</a> entry for more information.
         </em></li>
       </ul></li>
   </ul>
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 22ea27e..2d5aa08 100644 (file)
@@ -57,17 +57,16 @@ td {
   way:
   <ul>
     <li><em>RFAM</em> - Sequences can be <a
-      href="../features/seqfetch.html"
-    >fetched</a> from the RFAM database by accession number or ID.</li>
+      href="../features/seqfetch.html">fetched</a> from the RFAM
+      database by accession number or ID.</li>
     <li><em>Stockholm files</em> - WUSS (or VIENNA) dot-bracket
       notation found in the secondary structure annotation line will be
       imported as sequence or alignment associated secondary structure
       annotation.</li>
     <li><em>Clustal files</em> - certain RNA alignment programs,
-      such as <a
-      href="http://rna.informatik.uni-freiburg.de/LocARNA"
-    >LocaRNA</a> output consensus RNA secondary structure lines in the
-      line normally reserved for the Clustal consensus line in a clustal
+      such as <a href="http://rna.informatik.uni-freiburg.de/LocARNA">LocaRNA</a>
+      output consensus RNA secondary structure lines in the line
+      normally reserved for the Clustal consensus line in a clustal
       file.</li>
     <li><em>RNAML</em> Jalview can import RNAML files containing
       sequences and extended secondary structure annotation derived from
@@ -79,7 +78,7 @@ td {
     the alignment will have a secondary structure line shown below it,
     and a number of additional options become available:
   <ul>
-    <li><a href="../colourschemes/rnahelicesColouring.html">RNA
+    <li><a href="../colourSchemes/rnahelicesColouring.html">RNA
         Helix colouring</a> - highlights columns of alignment involved in
       particular RNA helices, Uses the first displayed secondary
       structure annotation.</li>
@@ -103,9 +102,9 @@ td {
       per-sequence secondary structure is available).</li>
   </ul>
   <p>
-    <strong>Pseudo-knots</strong><br /> Jalview 2.8.2 introduced limited
-    support for working with structures including pseudoknots. Where
-    possible, extended WUSS symbols (e.g. different types of
+    <strong>Pseudo-knots</strong><br /> Jalview 2.8.2 introduced
+    limited support for working with structures including pseudoknots.
+    Where possible, extended WUSS symbols (e.g. different types of
     parentheses, or upper and lower case letters) are preserved when
     parsing RNA structure annotation and will be shaded differently when
     displayed in the structure.<br /> Extended WUSS annotation is also
index 5c6939a..37ae169 100644 (file)
@@ -38,8 +38,7 @@
     <li><em>HTTP logs on the Jalview website</em><br> We
       record IP addresses of machines which access the web site, either
       via the browser when downloading the application, or when the
-      Jalview Desktop user interface is launched.<br>
-    <br>
+      Jalview Desktop user interface is launched.<br> <br>
       <ul>
         <li><i>The JNLP file at
             www.jalview.org/webstart/jalview.jnlp is retrieved to
@@ -53,8 +52,7 @@
             interactions with the public Jalview web services are
             logged, but we delete all job data (input data and results)
             after about two weeks.</i></li>
-      </ul>
-      <br></li>
+      </ul> <br></li>
     <li><em>Google Analytics</em><br> Since Jalview 2.4.0b2,
       the Jalview Desktop records usage data with Google Analytics via
       the <a href="http://code.google.com/p/jgoogleanalytics/">JGoogleAnalytics</a>
     run Jalview in 'headless mode' via the command line, then the
     program shouldn't try to contact any of the web servers mentioned
     above (if it does, then it's a bug!). You can also specify some <a
-      href="features/commandline.html"
-    >command line options</a> to disable the questionnaire and usage
-    statistics check. Finally, the <a
-      href="features/preferences.html#connections"
-    >Connections Tab</a> of the Jalview preferences contains options for
-    controlling the submission of usage statistics.
+      href="features/commandline.html">command line options</a> to
+    disable the questionnaire and usage statistics check. Finally, the <a
+      href="features/preferences.html#connections">Connections
+      Tab</a> of the Jalview preferences contains options for controlling
+    the submission of usage statistics.
   <p>
     <strong>Other Web Clients in Jalview</strong><br> The Jalview
     desktop is intended to make it easier to interact with web-based
index dcf04c5..6f44b3d 100755 (executable)
     <tr>
       <td width="60" nowrap>
         <div align="center">
-          <strong><a name="Jalview.2.10.0">2.10.0</a><br /> <em>27/9/2016</em></strong>
+          <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>
+        </ul></td>
+      <td>
+        <div align="left">
+          <em>General</em>
+          <ul>
+            <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>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>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>Build and deployment</em>
+          <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>
+    <tr>
+      <td width="60" nowrap>
+        <div align="center">
+          <strong><a name="Jalview.2.10.0">2.10.0</a><br /> <em>06/10/2016</em></strong>
         </div>
       </td>
       <td><em>General</em>
         <ul>
-            <li><!-- JAL-2164,JAL-1919,-->Jmol now primary parser for importing structure data to Jalview. Enables mmCIF and better PDB parsing.</li>
-            <li><!-- JAL-192 --->Alignment ruler shows positions relative to reference sequence</li>
-            <li><!-- JAL-2202 -->Position/residue shown in status bar when mousing over sequence associated annotation</li>
-            <li><!-- JAL-2171 -->Default RNA SS symbol to 'matching bracket' for manual entry</li>
-            <li><!-- JAL-2214 -->RNA Structure consensus indicates wc-only '()', canonical '[]' and invalid '{}' base pair populations for each column</li>
-            <li><!-- JAL-2092 -->Feature settings popup menu options for showing or hiding columns containing a feature</li>
-            <li><!-- JAL-1557 -->Edit selected group by double clicking on group and sequence associated annotation labels</li>
+          <li>
+          <!-- JAL-2124 -->Updated Spanish translations.
+          </li> 
+          <li>
+            <!-- JAL-2164,JAL-1919,JAL-2148 -->Jmol now primary parser
+            for importing structure data to Jalview. Enables mmCIF and
+            better PDB parsing.
+          </li>
+          <li>
+            <!-- JAL-192 --->Alignment ruler shows positions relative to
+            reference sequence
+          </li>
+          <li>
+            <!-- JAL-2202 -->Position/residue shown in status bar when
+            mousing over sequence associated annotation
+          </li>
+          <li>
+            <!-- JAL-2171 -->Default RNA SS symbol to 'matching bracket'
+            for manual entry
+          </li>
+          <li>
+            <!-- JAL-2214 -->RNA Structure consensus indicates wc-only
+            '()', canonical '[]' and invalid '{}' base pair populations
+            for each column
+          </li>
+          <li>
+            <!-- JAL-2092 -->Feature settings popup menu options for
+            showing or hiding columns containing a feature
+          </li>
+          <li>
+            <!-- JAL-1557 -->Edit selected group by double clicking on
+            group and sequence associated annotation labels
+          </li>
+          <li>
+            <!-- JAL-2236 -->Sequence name added to annotation label in
+            select/hide columns by annotation and colour by annotation
+            dialogs
+          </li>
+
         </ul> <em>Application</em>
         <ul>
-            <li><!-- JAL---></li>
-            <li><!-- JAL---></li>
-            <li><!-- JAL---></li>
-            <li><!-- JAL---></li>
-            <li><!--  JAL-1957, JAL-1479 JAL-1491 -->UniProt - PDB protein structure mappings with the EMBL-EBI PDBe SIFTS database</li>          
-            <li><!-- JAL-2079 -->Updated download sites used for Rfam and Pfam sources to xfam.org</li>
-            <li><!-- JAL-2084 -->Disabled Rfam(Full) in the sequence fetcher</li>
-            <li><!-- JAL-2123 -->Show residue labels in Chimera when mousing over sequences in Jalview</li>
-            <li><!-- JAL-2027-->Support for reverse-complement coding regions in ENA and EMBL</li>
-            <li><!-- JAL-1855, JAL-2113, JAL-2114-->Upgrade to EMBL XML 1.2 for ENA record retrieval</li>
-            <li><!-- JAL-2027 -->Support for ENA CDS records with reverse complement operator</li>
-            <li><!--  JAL-1812 -->New 'execute Groovy script' option in an alignment window's Calculate menu</li>
-            <li><!--  JAL-1812 -->Allow groovy scripts that call Jalview.getAlignFrames() to run in headless mode</li>
-            <li><!--  JAL-2068 -->Support for creating new alignment calculation workers from groovy scripts</li>
-            <li><!-- JAL-1369 --->Store/restore reference sequence in Jalview projects</li>
-            <li><!-- JAL-1803 -->Chain codes for a sequence's PDB associations are now saved/restored from project</li>
-            <li><!-- JAL-2183 -->Double click on an entry in Jalview's database chooser opens a sequence fetcher</li>
-            <li><!-- JAL-1563 -->Free-text search client for UniProt using the UniProt REST API</li>
-            <li><!-- JAL-2168 -->-nonews command line parameter to prevent the news reader opening</li>
-                    
-             
-        </ul> <em>Applet</em>
+          <li>
+            <!-- JAL-2050-->Automatically hide introns when opening a
+            gene/transcript view
+          </li>
+          <li>
+            <!-- JAL-1563 -->Uniprot Sequence fetcher Free Text Search
+            dialog
+          </li>
+          <li>
+            <!--  JAL-1957, JAL-1479 JAL-1491 -->UniProt - PDB protein
+            structure mappings with the EMBL-EBI PDBe SIFTS database
+          </li>
+          <li>
+            <!-- JAL-2079 -->Updated download sites used for Rfam and
+            Pfam sources to xfam.org
+          </li>
+          <li>
+            <!-- JAL-2084 -->Disabled Rfam(Full) in the sequence fetcher
+          </li>
+          <li>
+            <!-- JAL-2123 -->Show residue labels in Chimera when mousing
+            over sequences in Jalview
+          </li>
+          <li>
+            <!-- JAL-2027-->Support for reverse-complement coding
+            regions in ENA and EMBL
+          </li>
+          <li>
+            <!-- JAL-1855, JAL-2113, JAL-2114-->Upgrade to EMBL XML 1.2
+            for record retrieval via ENA rest API
+          </li>
+          <li>
+            <!-- JAL-2027 -->Support for ENA CDS records with reverse
+            complement operator
+          </li>
+          <li>
+            <!--  JAL-1812 -->Update to groovy-2.4.6-indy - for faster
+            groovy script execution
+          </li>
+          <li>
+            <!--  JAL-1812 -->New 'execute Groovy script' option in an
+            alignment window's Calculate menu
+          </li>
+          <li>
+            <!--  JAL-1812 -->Allow groovy scripts that call
+            Jalview.getAlignFrames() to run in headless mode
+          </li>
+          <li>
+            <!--  JAL-2068 -->Support for creating new alignment
+            calculation workers from groovy scripts
+          </li>
+          <li>
+            <!-- JAL-1369 --->Store/restore reference sequence in
+            Jalview projects
+          </li>
+          <li>
+            <!-- JAL-1803 -->Chain codes for a sequence's PDB
+            associations are now saved/restored from project
+          </li>
+          <li>
+            <!-- JAL-1993 -->Database selection dialog always shown
+            before sequence fetcher is opened
+          </li>
+          <li>
+            <!-- JAL-2183 -->Double click on an entry in Jalview's
+            database chooser opens a sequence fetcher
+          </li>
+          <li>
+            <!-- JAL-1563 -->Free-text search client for UniProt using
+            the UniProt REST API
+          </li>
+          <li>
+            <!-- JAL-2168 -->-nonews command line parameter to prevent
+            the news reader opening
+          </li>
+          <li>
+            <!-- JAL-2028 -->Displayed columns for PDBe and Uniprot
+            querying stored in preferences
+          </li>
+          <li>
+            <!-- JAL-2091 -->Pagination for displaying PDBe and Uniprot
+            search results
+          </li>
+          <li>
+            <!-- JAL-1977-->Tooltips shown on database chooser
+          </li>
+          <li>
+            <!--  JAL-391 -->Reverse complement function in calculate
+            menu for nucleotide sequences
+          </li>
+          <li>
+            <!-- JAL-2005, JAL-599 -->Alignment sort by feature scores
+            and feature counts preserves alignment ordering (and
+            debugged for complex feature sets).
+          </li>
+          <li>
+            <!-- JAL-2152-->Chimera 1.11.1 minimum requirement for
+            viewing structures with Jalview 2.10
+          </li>
+          <li>
+            <!-- JAL-1705, JAL-1975, JAL-2050,JAL-2041,JAL-2105 -->Retrieve
+            genome, transcript CCDS and gene ids via the Ensembl and
+            Ensembl Genomes REST API
+          </li>
+          <li>
+            <!-- JAL-2049 -->Protein sequence variant annotation
+            computed for 'sequence_variant' annotation on CDS regions
+            (Ensembl)
+          </li>
+          <li>
+            <!-- JAL-2232 -->ENA CDS 'show cross references' for Uniprot
+            sequences
+          </li>
+          <li>
+            <!-- JAL-2213,JAL-1856 -->Improved warning messages when DB
+            Ref Fetcher fails to match, or otherwise updates sequence
+            data from external database records.
+          </li>
+          <li>
+            <!-- JAL-2154 -->Revised Jalview Project format for
+            efficient recovery of sequence coding and alignment
+            annotation relationships.
+          </li>
+        </ul> <!-- <em>Applet</em>
         <ul>
-            <li><!-- JAL---></li>
-        </ul></td>
+          <li>
+            -- JAL---
+          </li>
+        </ul> --></td>
       <td>
         <div align="left">
           <em>General</em>
           <ul>
-            <li><!-- JAL-2077 -->reinstate CTRL-click for opening pop-up menu on OSX</li>
-            <li><!-- JAL-2018-->Export features in Jalview format (again) includes graduated colourschemes</li>
-            <li><!-- JAL-1722, JAL-2001-->More responsive when working with big alignments and lots of hidden columns</li>
-            <li><!-- JAL-2053-->Hidden column markers not always rendered at right of alignment window</li>
-            <li><!-- JAL-2067, JAL-  -->Tidied up links in help file table of contents</li>
-            <li><!-- JAL-2072  -->Feature based tree calculation not shown for DNA alignments</li>
-            <li><!-- JAL-2075  -->Hidden columns ignored during feature based tree calculation</li>
-            <li><!-- JAL-2065  -->Alignment view stops updating when show unconserved enabled for group on alignment</li>
-            <li><!--  JAL-2086  -->Cannot insert gaps into sequence when set as reference</li>
-            <li><!-- JAL-2146 -->Alignment column in status incorrectly shown as &quot;Sequence position&quot; when mousing over annotation</li>
-            <li><!--  JAL-2099 -->Incorrect column numbers in ruler when hidden columns present</li>
-            <li><!--  JAL-1577 -->Colour by RNA Helices not enabled when user created annotation added to alignment</li>
-            <li><!-- JAL-1841 -->RNA Structure consensus only computed for '()' base pair annotation</li>
-            <li><!-- JAL-2215, JAL-1841 -->Enabling 'Ignore Gaps' results in zero scores for all base pairs in RNA Structure Consensus</li>
-            <li><!-- JAL-2174-->Extend selection with columns containing feature not working</li>
-            <li><!-- JAL-2275 -->Pfam format writer puts extra space at beginning of sequence</li>            
-            <li><!-- JAL-1827 -->Incomplete sequence extracted from pdb entry 3a6s </li>
-            
+            <li>
+              <!-- JAL-2077 -->reinstate CTRL-click for opening pop-up
+              menu on OSX
+            </li>
+            <li>
+              <!-- JAL-2018-->Export features in Jalview format (again)
+              includes graduated colourschemes
+            </li>
+            <li>
+              <!-- JAL-2172,JAL-1722, JAL-2001-->More responsive when
+              working with big alignments and lots of hidden columns
+            </li>
+            <li>
+              <!-- JAL-2053-->Hidden column markers not always rendered
+              at right of alignment window
+            </li>
+            <li>
+              <!-- JAL-2067 -->Tidied up links in help file table of
+              contents
+            </li>
+            <li>
+              <!-- JAL-2072  -->Feature based tree calculation not shown
+              for DNA alignments
+            </li>
+            <li>
+              <!-- JAL-2075  -->Hidden columns ignored during feature
+              based tree calculation
+            </li>
+            <li>
+              <!-- JAL-2065  -->Alignment view stops updating when show
+              unconserved enabled for group on alignment
+            </li>
+            <li>
+              <!--  JAL-2086  -->Cannot insert gaps into sequence when
+              set as reference
+            </li>
+            <li>
+              <!-- JAL-2146 -->Alignment column in status incorrectly
+              shown as &quot;Sequence position&quot; when mousing over
+              annotation
+            </li>
+            <li>
+              <!--  JAL-2099 -->Incorrect column numbers in ruler when
+              hidden columns present
+            </li>
+            <li>
+              <!--  JAL-1577 -->Colour by RNA Helices not enabled when
+              user created annotation added to alignment
+            </li>
+            <li>
+              <!-- JAL-1841 -->RNA Structure consensus only computed for
+              '()' base pair annotation
+            </li>
+            <li>
+              <!-- JAL-2215, JAL-1841 -->Enabling 'Ignore Gaps' results
+              in zero scores for all base pairs in RNA Structure
+              Consensus
+            </li>
+            <li>
+              <!-- JAL-2174-->Extend selection with columns containing
+              feature not working
+            </li>
+            <li>
+              <!-- JAL-2275 -->Pfam format writer puts extra space at
+              beginning of sequence
+            </li>
+            <li>
+              <!-- JAL-1827 -->Incomplete sequence extracted from pdb
+              entry 3a6s
+            </li>
+            <li>
+              <!-- JAL-2238 -->Cannot create groups on an alignment from
+              from a tree when t-coffee scores are shown
+            </li>
+            <li>
+              <!-- JAL-1836,1967 -->Cannot import and view PDB
+              structures with chains containing negative resnums (4q4h)
+            </li>
+            <li>
+              <!--  JAL-1998 -->ArithmeticExceptions raised when parsing
+              some structures
+            </li>
+            <li>
+              <!--  JAL-1991, JAl-1952 -->'Empty' alignment blocks added
+              to Clustal, PIR and PileUp output
+            </li>
+            <li>
+              <!--  JAL-2008 -->Reordering sequence features that are
+              not visible causes alignment window to repaint
+            </li>
+            <li>
+              <!--  JAL-2006 -->Threshold sliders don't work in
+              graduated colour and colour by annotation row for e-value
+              scores associated with features and annotation rows
+            </li>
+            <li>
+              <!-- JAL-1797 -->amino acid physicochemical conservation
+              calculation should be case independent
+            </li>
+            <li>
+              <!-- JAL-2173 -->Remove annotation also updates hidden
+              columns
+            </li>
+            <li>
+              <!-- JAL-2234 -->FER1_ARATH and FER2_ARATH mislabelled in
+              example file (uniref50.fa, feredoxin.fa, unaligned.fa,
+              exampleFile_2_7.jar, exampleFile.jar, exampleFile_2_3.jar)
+            </li>
+            <li>
+              <!-- JAL-2065 -->Null pointer exceptions and redraw
+              problems when reference sequence defined and 'show
+              non-conserved' enabled
+            </li>
+            <li>
+              <!-- 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>
-            <li><!-- JAL-1944 not yet fixed Error thrown when exporting a view with hidden sequences as flat-file alignment--></li>
-            <li><!-- JAL-1911-->Corrupt preferences for SVG, EPS & HTML output when running on non-gb/us i18n platforms</li>
-            <li><!-- JAL-1552-->URLs and links can imported by drag'n'drop on OSX webstart</li>
-            <li><!-- JAL-2030-->InstallAnywhere distribution fails when launching Chimera</li>
-            <li><!-- JAL-2080-->Jalview very slow to launch via webstart (also hotfix for 2.9.0b2)</li>
-            <li><!--  JAL-2085  -->Cannot save project when view has a reference sequence defined</li>
-            <li><!--  JAL-1011  -->Columns are suddenly selected in other alignments and views when revealing hidden columns</li>
-            <li><!--  JAL-1989  -->Hide columns not mirrored in complement view in a cDNA/Protein splitframe</li>
-            <li><!--  JAL-1369 -->Cannot save/restore representative sequence from project when only one sequence is represented</li>
-            <li><!-- JAL-2002 -->Disabled 'Best Uniprot Coverage' option in Structure Chooser</li>
-            <li><!-- JAL-2215 -->Modifying 'Ignore Gaps' on consensus or structure consensus didn't refresh annotation panel</li>
-            <li><!-- JAL-1962 -->View mapping in structure view shows mappings between sequence and all chains in a PDB file</li>                        
-            <!--  may exclude, this is an external service stability issue  JAL-1941 /> RNA 3D structure not added via DSSR service</li> -->
+            <li>
+              <!-- JAL-1552-->URLs and links can't be imported by
+              drag'n'drop on OSX when launched via webstart (note - not
+              yet fixed for El Capitan)
+            </li>
+            <li>
+              <!-- JAL-1911-->Corrupt preferences for SVG, EPS & HTML
+              output when running on non-gb/us i18n platforms
+            </li>
+            <li>
+              <!-- JAL-1944 -->Error thrown when exporting a view with
+              hidden sequences as flat-file alignment
+            </li>
+            <li>
+              <!-- JAL-2030-->InstallAnywhere distribution fails when
+              launching Chimera
+            </li>
+            <li>
+              <!-- JAL-2080-->Jalview very slow to launch via webstart
+              (also hotfix for 2.9.0b2)
+            </li>
+            <li>
+              <!--  JAL-2085  -->Cannot save project when view has a
+              reference sequence defined
+            </li>
+            <li>
+              <!--  JAL-1011  -->Columns are suddenly selected in other
+              alignments and views when revealing hidden columns
+            </li>
+            <li>
+              <!--  JAL-1989  -->Hide columns not mirrored in complement
+              view in a cDNA/Protein splitframe
+            </li>
+            <li>
+              <!--  JAL-1369 -->Cannot save/restore representative
+              sequence from project when only one sequence is
+              represented
+            </li>
+            <li>
+              <!-- JAL-2002 -->Disabled 'Best Uniprot Coverage' option
+              in Structure Chooser
+            </li>
+            <li>
+              <!-- JAL-2215 -->Modifying 'Ignore Gaps' on consensus or
+              structure consensus didn't refresh annotation panel
+            </li>
+            <li>
+              <!-- JAL-1962 -->View mapping in structure view shows
+              mappings between sequence and all chains in a PDB file
+            </li>
+            <li>
+              <!-- JAL-2102, JAL-2101, JAL-2102, -->PDB and Uniprot FTS
+              dialogs format columns correctly, don't display array
+              data, sort columns according to type
+            </li>
+            <li>
+              <!-- JAL-1975 -->Export complete shown after destination
+              file chooser is cancelled during an image export
+            </li>
+            <li>
+              <!-- JAL-2025 -->Error when querying PDB Service with
+              sequence name containing special characters
+            </li>
+            <li>
+              <!-- JAL-2024 -->Manual PDB structure querying should be
+              case insensitive
+            </li>
+            <li>
+              <!-- JAL-2104 -->Large tooltips with broken HTML
+              formatting don't wrap
+            </li>
+            <li>
+              <!-- JAL-1128 -->Figures exported from wrapped view are
+              truncated so L looks like I in consensus annotation
+            </li>
+            <li>
+              <!-- JAL-2003 -->Export features should only export the
+              currently displayed features for the current selection or
+              view
+            </li>
+            <li>
+              <!-- JAL-2036 -->Enable 'Get Cross-References' in menu
+              after fetching cross-references, and restoring from project
+            </li>
+            <li>
+              <!-- JAL-2032 -->Mouseover of a copy of a sequence is not
+              followed in the structure viewer
+            </li>
+            <li>
+              <!-- JAL-2163 -->Titles for individual alignments in
+              splitframe not restored from project
+            </li>
+            <li>
+              <!-- JAL-2145 -->missing autocalculated annotation at
+              trailing end of protein alignment in transcript/product
+              splitview when pad-gaps not enabled by default
+            </li>
+            <li>
+              <!-- JAL-1797 -->amino acid physicochemical conservation
+              is case dependent
+            </li>
+            <li>
+              <!-- JAL-1448 -->RSS reader doesn't stay hidden after last
+              article has been read (reopened issue due to
+              internationalisation problems)
+            </li>
+            <li>
+              <!-- JAL-1960 -->Only offer PDB structures in structure
+              viewer based on sequence name, PDB and UniProt
+              cross-references
+            </li>
+
+            <li>
+              <!-- JAL-1976 -->No progress bar shown during export of
+              alignment as HTML
+            </li>
+            <li>
+              <!-- JAL-2213 -->Structures not always superimposed after
+              multiple structures are shown for one or more sequences.
+            </li>
+            <li>
+              <!-- JAL-1370 -->Reference sequence characters should not
+              be replaced with '.' when 'Show unconserved' format option
+              is enabled.
+            </li>
+            <li>
+              <!-- JAL-1823 -->Cannot specify chain code when entering
+              specific PDB id for sequence
+            </li>
+            <li>
+              <!-- JAL-1944 -->File->Export->.. as doesn't work when
+              'Export hidden sequences' is enabled, but 'export hidden
+              columns' is disabled.
+            </li>
+            <li>
+              <!--JAL-2026-->Best Quality option in structure chooser
+              selects lowest rather than highest resolution structures
+              for each sequence
+            </li>
+            <li>
+              <!-- 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>
           <em>Applet</em>
           <ul>
-            <li><!-- JAL-2151 -->Incorrect columns are selected when hidden columns present before start of sequence</li>
+            <li>
+              <!-- JAL-2151 -->Incorrect columns are selected when
+              hidden columns present before start of sequence
+            </li>
+            <li>
+              <!-- JAL-1986 -->Missing dependencies on applet pages
+              (JSON jars)
+            </li>
+            <li>
+              <!-- JAL-1947 -->Overview pixel size changes when
+              sequences are hidden in applet
+            </li>
+            <li>
+              <!-- JAL-1996 -->Updated instructions for applet
+              deployment on examples pages.
+            </li>
           </ul>
         </div>
       </td>
           <li>Updated Spanish translations of localized text for
             2.9</li>
         </ul> <em>Application</em>
-      <ul>
+        <ul>
           <!-- <li>cDNA/Protein splitframe window geometry preserved in Jalview projects</li>-->
           <li>Signed OSX InstallAnywhere installer<br></li>
           <li>Support for per-sequence based annotations in BioJSON</li>
         </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">
           <li>URL links generated from description line for
             regular-expression based URL links (applet and application)
 
+
+
+
+
           
           <li>Non-positional feature URL links are shown in link
             menu</li>
             between different screens.</li>
           <li>New preference items for sequence ID tooltip and
             consensus annotation</li>
-          <li>Client to submit sequences and IDs to Envision2 Workflows</li>
+          <li>Client to submit sequences and IDs to Envision2
+            Workflows</li>
           <li><em>Vamsas Capabilities</em>
             <ul>
               <li>Improved VAMSAS synchronization (Jalview archive
           <li>PCA and PDB Viewers zoom via mouse roller
           <li>User-defined sub-tree colours and sub-tree selection
 
+
+
+
+
           
           <li>'New Window' button on the 'Output to Text box'
         </ul>
             of alignment)
           <li>Slowed DAS Feature Fetching for increased robustness.
 
+
+
+
+
           
           <li>Made angle brackets in ASCII feature descriptions
             display correctly
           <li>Tree leaf to sequence mapping improved
           <li>Smooth fonts switch moved to FontChooser dialog box.
 
+
+
+
+
           
         </ul>
       </td>
index 73090d0..72a336a 100644 (file)
     and <strong>A</strong>nalysis of <strong>Molecular</strong> <strong>S</strong>equences,
     <strong>Alignements</strong> and <strong>S</strong>tructures).
     Currently, the only other VAMSAS enabled application is <a
-      href="http://www.topali.org"
-    >TOPALi</a> - a user friendly program for phylogenetics and
-    evolutionary analysis.
+      href="http://www.topali.org">TOPALi</a> - a user friendly
+    program for phylogenetics and evolutionary analysis.
   <p>
     VAMSAS enabled applications access a shared bioinformatics dataset
     containing sequences, alignments, annotation and trees, which can be
     represented by an XML document analogous to a <a
-      href="../features/jalarchive.html"
-    >Jalview Project Archive</a>.
+      href="../features/jalarchive.html">Jalview Project
+      Archive</a>.
   </p>
   <br>
   <strong>Connecting to a VAMSAS session</strong>
index 6d4a461..5cec67d 100644 (file)
     The majority of these scores were described by Valdar in 2002
     (Scoring residue conservation. <em>Proteins: Structure,
       Function, and Genetics</em> 43(2): 227-241. <a
-      href="http://www.ncbi.nlm.nih.gov/pubmed/12112692"
-    >PubMed</a> or available on the <a
-      href="http://valdarlab.unc.edu/publications.html"
-    >Valdar Group publications page</a>), but the SMERFs score was
-    developed later and described by Manning et al. in 2008 (<a
-      href="http://www.biomedcentral.com/1471-2105/9/51"
-    >BMC Bioinformatics 2008, 9:51 doi:10.1186/1471-2105-9-51</a>).
+      href="http://www.ncbi.nlm.nih.gov/pubmed/12112692">PubMed</a>
+    or available on the <a
+      href="http://valdarlab.unc.edu/publications.html">Valdar
+      Group publications page</a>), but the SMERFs score was developed later
+    and described by Manning et al. in 2008 (<a
+      href="http://www.biomedcentral.com/1471-2105/9/51">BMC
+      Bioinformatics 2008, 9:51 doi:10.1186/1471-2105-9-51</a>).
   </p>
   <p>
     <strong>Enabling and disabling AACon calculations</strong><br />
     <strong>Configuring which AACon calculations are performed</strong><br />
     The <strong>Web Services&rarr;Conservation&rarr;Change
       AACon Settings ...</strong> menu entry will open a <a
-      href="webServicesParams.html"
-    >web services parameter dialog</a> for the currently configured AACon
-    server. Standard presets are provided for quick and more expensive
-    conservation calculations, and parameters are also provided to
-    change the way that SMERFS calculations are performed.<br /> <em>AACon
-      settings for an alignment are saved in <a
-      href="../features/jalarchive.html"
-    >Jalview projects</a> along with the latest calculation results.
+      href="webServicesParams.html">web services parameter
+      dialog</a> for the currently configured AACon server. Standard presets
+    are provided for quick and more expensive conservation calculations,
+    and parameters are also provided to change the way that SMERFS
+    calculations are performed.<br /> <em>AACon settings for an
+      alignment are saved in <a href="../features/jalarchive.html">Jalview
+        projects</a> along with the latest calculation results.
     </em>
   </p>
   <p>
index 6750b55..f74e4c4 100644 (file)
@@ -42,8 +42,7 @@
     the <a href="webServicesPrefs.html">Web Services Preferences
       Panel</a>, and detailed information about a particular service is
     available from the help text and web pages accessible from its <a
-      href="webServicesParams.html"
-    >job parameters dialog box</a>.
+      href="webServicesParams.html">job parameters dialog box</a>.
   </p>
   <p>
     <strong>Obtaining JABAWS</strong><br> One of the aims of JABAWS
     stand-alone execution of analysis programs, or as a job submission
     engine - enabling larger numbers of jobs to be handled. If you would
     like to download and install JABAWS for your own use, please go to <a
-      href="http://www.compbio.dundee.ac.uk/jabaws"
-    >http://www.compbio.dundee.ac.uk/jabaws</a> for more information.
+      href="http://www.compbio.dundee.ac.uk/jabaws">http://www.compbio.dundee.ac.uk/jabaws</a>
+    for more information.
   </p>
   <p>
     <strong>Configuring your own JABAWS services for use by
       Jalview</strong><br> Once you have downloaded and installed JABAWS,
     and verified it is working, all that is needed is to add the URL for
     your JABAWS server(s) to the list in the <a
-      href="webServicesPrefs.html"
-    >Web Services Preferences Panel</a>. After adding your service and
-    saving your preferences or hitting the 'refresh web services'
-    button, you should be able to submit jobs to the server via the
-    alignment window's web services menu. Your JABAWS servers list is
-    stored in your Jalview preferences, so you will only have to
-    configure Jalview once for each new server.
+      href="webServicesPrefs.html">Web Services Preferences
+      Panel</a>. After adding your service and saving your preferences or
+    hitting the 'refresh web services' button, you should be able to
+    submit jobs to the server via the alignment window's web services
+    menu. Your JABAWS servers list is stored in your Jalview
+    preferences, so you will only have to configure Jalview once for
+    each new server.
   </p>
   <p>
     <em>Support for accessing JABAWS servers was introduced in
index 432e0a6..36e43aa 100644 (file)
@@ -36,8 +36,7 @@
     Gruber, and Peter F. Stadler, <em>RNAalifold: Improved
       consensus structure prediction for RNA alignments</em> (BMC
     Bioinformatics, 9:474, 2008). Download the paper at <a
-      href="http://www.biomedcentral.com/1471-2105/9/474"
-    >http://www.biomedcentral.com/1471-2105/9/474</a>.
+      href="http://www.biomedcentral.com/1471-2105/9/474">http://www.biomedcentral.com/1471-2105/9/474</a>.
   </p>
   <p>
     <strong>Running RNAalifold from Jalview</strong><br />
@@ -54,8 +53,7 @@
     <Strong>RNAalifold prediction parameters</Strong> <br /> JABAWS and
     Jalview only provide access to a selection of the RNAalifold
     arguments. For a full description, see the documentation at <a
-      href="http://www.tbi.univie.ac.at/RNA/RNAalifold.html"
-    >http://www.tbi.univie.ac.at/RNA/RNAalifold.html</a>.
+      href="http://www.tbi.univie.ac.at/RNA/RNAalifold.html">http://www.tbi.univie.ac.at/RNA/RNAalifold.html</a>.
   </p>
   <p>
     <strong>Supported Arguments which give alternate structures</strong>
@@ -75,8 +73,7 @@
     Calculate an MEA structure where the expected Accuracy is computed
     from the base pair probabilities. A more detailed description can be
     found in the <strong>RNAfold</strong> program documentation at <a
-      href="http://www.tbi.univie.ac.at/RNA/RNAfold.html"
-    >http://www.tbi.univie.ac.at/RNA/RNAfold.html</a>.
+      href="http://www.tbi.univie.ac.at/RNA/RNAfold.html">http://www.tbi.univie.ac.at/RNA/RNAfold.html</a>.
   </p>
   <p>
     <strong>Example RNAalifold Structure Annotation rows</strong>
index 632e993..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 href="../features/dasfeatures.html">DAS
-    features</a>, and for retrieving sequence cross-references such as the
-  protein products of a DNA sequence.
+  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.
 </p>
 <p>
   <strong>Initiating reference retrieval</strong><br> The
@@ -68,9 +70,9 @@
   and was originally restricted to the identification of valid UniProt
   accessions.<br> Essentially, Jalview will try to retrieve records
   from a subset of the databases accessible by the <a
-    href="../features/seqfetch.html"
-  >sequence fetcher</a> using each sequence's ID string (or each string in
-  the ID separated by the '&#8739;' symbol).
+    href="../features/seqfetch.html">sequence fetcher</a> using each
+  sequence's ID string (or each string in the ID separated by the
+  '&#8739;' symbol).
 </p>
 <p>If a record (or set of records) is retrieved by any query derived
   from the ID string of a sequence, then the sequence is aligned to the
index 1463554..d0b497c 100755 (executable)
       <ul>
         <li>Programs for <a href="msaclient.html">multiple
             sequence alignment</a>, made available <em>via</em> <a
-          href="JABAWS.html"
-        >Java Bioinformatic Analysis Web Service (JABAWS)</a> servers.
+          href="JABAWS.html">Java Bioinformatic Analysis
+            Web Service (JABAWS)</a> servers.
         </li>
         <li>Jalview SOAP Web Services for <a href="jnet.html">secondary
             structure prediction</a> based at the University of Dundee.
         </li>
         <li>Services for alignment analysis, such as <a
-          href="shmr.html"
-        >Multi-Harmony</a>.
+          href="shmr.html">Multi-Harmony</a>.
       </ul>
       <p>
         <strong>Web Service Dialog Box</strong>
         citation information, and monitors the progress of the
         calculation. The cancel button will permanently cancel the job,
         but this is only possible for some services.</p> The <a
-      href="webServicesPrefs.html"
-    >Web Services Preference panel</a> controls the display and appearance
-      of the submission and analysis services in the <strong>Web
-        Services</strong> menu.
+      href="webServicesPrefs.html">Web Services Preference
+        panel</a> controls the display and appearance of the submission and
+      analysis services in the <strong>Web Services</strong> menu.
     </li>
     <li>If Jalview encounters problems accessing any services, it
       may display a <a href="webServicesPrefs.html#wswarnings">warning
   <p>
     <strong>More about Jalview's Web Services</strong> <br>
     Jalview's distributed computations utilise <a
-      href="http://en.wikipedia.org/wiki/SOAP"
-    >SOAP</a> and <a
-      href="http://en.wikipedia.org/wiki/Representational_State_Transfer"
-    >REST</a> web services exposing sequence alignment, analysis, and
-    secondary structure prediction programs. Originally, Jalview 2's
-    services were maintained by the Barton group at the University of
-    Dundee, and ran programs on the Life Sciences High-performance
-    Computing Cluster. With the advent of <a
-      href="http://www.compbio.dundee.ac.uk/jabaws"
-    >JABAWS</a>, however, it is possible for anyone to host Jalview web
-    services.
+      href="http://en.wikipedia.org/wiki/SOAP">SOAP</a> and <a
+      href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a>
+    web services exposing sequence alignment, analysis, and secondary
+    structure prediction programs. Originally, Jalview 2's services were
+    maintained by the Barton group at the University of Dundee, and ran
+    programs on the Life Sciences High-performance Computing Cluster.
+    With the advent of <a href="http://www.compbio.dundee.ac.uk/jabaws">JABAWS</a>,
+    however, it is possible for anyone to host Jalview web services.
   </p>
 </body>
 </html>
index 0dfbd10..396a3a7 100755 (executable)
@@ -38,8 +38,7 @@
       JPred4: a protein secondary structure prediction server<br /> <em>Nucleic
         Acids Research</em>, <strong>Web Server issue</strong> (first
       published 15th April 2015)<br /> <a
-      href="http://dx.doi.org/10.1093/nar/gkv332"
-    >http://dx.doi.org/10.1093/nar/gkv332</a>
+      href="http://dx.doi.org/10.1093/nar/gkv332">http://dx.doi.org/10.1093/nar/gkv332</a>
     </li>
     <li>Cole C., Barber J.D. and Barton G.J. (2008) The Jpred 3
       secondary structure prediction server <em>Nucleic Acids
   </p>
   <em>JNet annotation created in Jalview 2.8.2 and later versions
     can be displayed on other alignments via the <a
-    href="../features/annotation.html#seqannots"
-  >Add reference annotation</a> Sequence ID popup menu option.
+    href="../features/annotation.html#seqannots">Add reference
+      annotation</a> Sequence ID popup menu option.
   </em>
   <em>As of Jalview 2.6, the Jnet service accessed accessed via the
     'Secondary structure prediction' submenu should be considered a
index 6266036..2fbbdbc 100644 (file)
@@ -63,8 +63,8 @@
     <li><a href="http://www.drive5.com/muscle">Muscle</a> (version
       3.8.31)</li>
     <li><a
-      href="http://www.tcoffee.org/Projects_home_page/t_coffee_home_page.html"
-    >Tcoffee</a> (version 8.99)</li>
+      href="http://www.tcoffee.org/Projects_home_page/t_coffee_home_page.html">Tcoffee</a>
+      (version 8.99)</li>
     <li><a href="http://probcons.stanford.edu/">Probcons</a>
       (version 1.12)</li>
   </ul>
     <strong>Multiple Alignments of Sequences with hidden
       columns</strong><br> Multiple alignment services are 'column
     separable' analysis operations. If the input contains <a
-      href="../features/hiddenRegions.html"
-    >hidden columns</a> then each visible segment of the input sequence
-    set will be submitted for alignment separately, and the results
-    concatenated (with the hidden regions preserved) once all alignment
-    functions have completed. Each sub-job's state is reported in its
-    own tab:
+      href="../features/hiddenRegions.html">hidden columns</a> then
+    each visible segment of the input sequence set will be submitted for
+    alignment separately, and the results concatenated (with the hidden
+    regions preserved) once all alignment functions have completed. Each
+    sub-job's state is reported in its own tab:
   <p>
   <center>
     <strong>Multiple Multiple Sequence Alignment sub jobs
index 1f2b7c9..c3c1d3f 100644 (file)
   <p>
     <strong>The Jalview Desktop RSS News Reader</strong><br /> The
     Jalview Desktop includes a built in news reader for the <a
-      href="http://www.jalview.org/feeds/desktop/rss"
-    >Jalview Desktop News Channel</a>.
+      href="http://www.jalview.org/feeds/desktop/rss">Jalview
+      Desktop News Channel</a>.
   </p>
 
   <p>We will use the desktop news channel to keep you informed of
     important updates relevant to users of the Jalview desktop, such as
     web service outages and user community events.</p>
-  <p>The news reader will be launched automatically when you start
-    the Desktop if new items are available. Should you want to browse
-    older items, however, you can open it manually from the 'Jalview
-    news reader' option in the Desktop's <a href="../menus/desktopMenu.html">'Tools' menu</a>.</p><br/>
-  <div style="text-align: center;"><img src="jalviewrssreader.gif" width="513"
-    height="337" alt="Snapshot of the Jalview Desktop's RSS reader"/></div>
+  <p>
+    The news reader will be launched automatically when you start the
+    Desktop if new items are available. Should you want to browse older
+    items, however, you can open it manually from the 'Jalview news
+    reader' option in the Desktop's <a href="../menus/desktopMenu.html">'Tools'
+      menu</a>.
+  </p>
+  <br />
+  <div style="text-align: center;">
+    <img src="jalviewrssreader.gif" width="513" height="337"
+      alt="Snapshot of the Jalview Desktop's RSS reader" />
+  </div>
 
-  <br/><p>
+  <br />
+  <p>
     The <em>Jalview news reader</em> was introduced in <a
-      href="http://www.jalview.org/releaseHistory.html#Jalview2.7"
-    >Jalview version 2.7</a>. Its implementation is based on <a
-      href="http://jswingreader.sourceforge.net/"
-    >JSwingReader</a>.
+      href="http://www.jalview.org/releaseHistory.html#Jalview2.7">Jalview
+      version 2.7</a>. Its implementation is based on <a
+      href="http://jswingreader.sourceforge.net/">JSwingReader</a>.
   </p>
   <br />
   <em>If you need to prevent the news-reader opening, then add the
index 2c98139..1c35bf3 100644 (file)
     The <strong>Web Services&rarr;Disorder</strong> menu in the
     alignment window allows access to protein disorder prediction
     services provided by the configured <a
-      href="http://www.compbio.dundee.ac.uk/jabaws"
-    >JABAWS servers</a>. Each service operates on sequences in the
-    alignment or currently selected region (<em>since Jalview
-      2.8.0b1</em>) to identify regions likely to be unstructured or
-    flexible, or alternately, fold to form globular domains.
+      href="http://www.compbio.dundee.ac.uk/jabaws">JABAWS
+      servers</a>. Each service operates on sequences in the alignment or
+    currently selected region (<em>since Jalview 2.8.0b1</em>) to
+    identify regions likely to be unstructured or flexible, or
+    alternately, fold to form globular domains.
   </p>
   <p>
     Predictor results include both <a
-      href="../features/seqfeatures.html"
-    >sequence features</a> and sequence associated <a
-      href="../features/annotation.html"
-    >alignment annotation</a> rows. Features display is controlled from
-    the <a href="../features/featuresettings.html">Feature Settings</a>
+      href="../features/seqfeatures.html">sequence features</a> and
+    sequence associated <a href="../features/annotation.html">alignment
+      annotation</a> rows. Features display is controlled from the <a
+      href="../features/featuresettings.html">Feature Settings</a>
     dialog box. Clicking on the ID for a disorder prediction annotation
     row will highlight or select (if double clicked) the associated
     sequence for that row. You can also use the <em>Sequence
       Associated</em> option in the <a
-      href="../colourSchemes/annotationColouring.html"
-    >Colour By Annotation</a> dialog box to colour sequences according to
-    the results of predictors shown as annotation rows.
+      href="../colourSchemes/annotationColouring.html">Colour
+      By Annotation</a> dialog box to colour sequences according to the
+    results of predictors shown as annotation rows.
   </p>
   <p>JABAWS 2.0 provides four disorder predictors which are
     described below:</p>
       <td>Sequence Feature &amp;<br />Annotation Row
       </td>
       <td>Predicts loops/coils according to DSSP definition<a
-        href="#dsspstates"
-      >[1]</a>.<br />Features mark range(s) of residues predicted as
-        loops/coils, and annotation row gives raw value for each
-        residue. Value over 0.516 indicates loop/coil.
+        href="#dsspstates">[1]</a>.<br />Features mark range(s)
+        of residues predicted as loops/coils, and annotation row gives
+        raw value for each residue. Value over 0.516 indicates
+        loop/coil.
       </td>
     </tr>
     <tr>
 
   <p>
     <strong><a name="ronn"></a><a
-      href="http://www.strubi.ox.ac.uk/RONN"
-    >RONN</a></strong> <em>a.k.a.</em> Regional Order Neural Network<br />This
-    predictor employs an approach known as the 'bio-basis' method to
-    predict regions of disorder in sequences based on their local
-    similarity with a gold-standard set of disordered protein sequences.
-    It yields a set of disorder prediction scores, which are shown as
-    sequence annotation below the alignment.
+      href="http://www.strubi.ox.ac.uk/RONN">RONN</a></strong> <em>a.k.a.</em>
+    Regional Order Neural Network<br />This predictor employs an
+    approach known as the 'bio-basis' method to predict regions of
+    disorder in sequences based on their local similarity with a
+    gold-standard set of disordered protein sequences. It yields a set
+    of disorder prediction scores, which are shown as sequence
+    annotation below the alignment.
   </p>
   <table border="1">
     <tr>
   </p>
   <p>
     <strong><a name="iupred"></a><a
-      href="http://iupred.enzim.hu/Help.php"
-    >IUPred</a></strong><br /> IUPred employs an empirical model to estimate
-    likely regions of disorder. There are three different prediction
-    types offered, each using different parameters optimized for
-    slightly different applications. It provides raw scores based on two
-    models for predicting regions of 'long disorder' and 'short
-    disorder'. A third predictor identifies regions likely to form
-    structured domains.
+      href="http://iupred.enzim.hu/Help.php">IUPred</a></strong><br />
+    IUPred employs an empirical model to estimate likely regions of
+    disorder. There are three different prediction types offered, each
+    using different parameters optimized for slightly different
+    applications. It provides raw scores based on two models for
+    predicting regions of 'long disorder' and 'short disorder'. A third
+    predictor identifies regions likely to form structured domains.
   </p>
   <table border="1">
     <tr>
   </table>
   <p>
     <strong><a name="globplot"></a><a
-      href="http://globplot.embl.de/"
-    >GLOBPLOT</a></strong><br /> Defines regions of globularity or natively
-    unstructured regions based on a running sum of the propensity of
-    residues to be structured or unstructured. The propensity is
-    calculated based on the probability of each amino acid being
-    observed within well defined regions of secondary structure or
-    within regions of random coil. The initial signal is smoothed with a
-    Savitzky-Golay filter, and its first order derivative computed.
-    Residues for which the first order derivative is positive are
-    designated as natively unstructured, whereas those with negative
-    values are structured.<br />
+      href="http://globplot.embl.de/">GLOBPLOT</a></strong><br /> Defines
+    regions of globularity or natively unstructured regions based on a
+    running sum of the propensity of residues to be structured or
+    unstructured. The propensity is calculated based on the probability
+    of each amino acid being observed within well defined regions of
+    secondary structure or within regions of random coil. The initial
+    signal is smoothed with a Savitzky-Golay filter, and its first order
+    derivative computed. Residues for which the first order derivative
+    is positive are designated as natively unstructured, whereas those
+    with negative values are structured.<br />
   <table border="1">
     <tr>
       <td><strong>Name</strong></td>
index 29e2c1e..803def7 100755 (executable)
     a protein sequence multiple alignment that has been sub-divided into
     groups containing at least two non-identical protein sequences. An
     easy way to create groups is to use the built-in <a
-      href="../calculations/tree.html"
-    >neighbour-joining or UPGMA tree</a> routines to calculate a tree for
-    the alignment, and then click on the tree to subdivide the
-    alignment.
+      href="../calculations/tree.html">neighbour-joining or
+      UPGMA tree</a> routines to calculate a tree for the alignment, and
+    then click on the tree to subdivide the alignment.
   </p>
   <p>
     The SHMR service operates on the currently selected visible
     region(s) of the alignment. Once submitted, a job progress window
     will display status information about your job, including a URL
     which allows you to visit the status page on the <a
-      href="http://zeus.few.vu.nl/programs/shmrwww/"
-    >IBIVU SHMR server</a>.
+      href="http://zeus.few.vu.nl/programs/shmrwww/">IBIVU SHMR
+      server</a>.
   </p>
   <p>When the job is complete, Jalview will automatically open a new
     window containing the alignment and groups that were submitted for
     analysis, with additional histograms added portraying the SHMR
     scores for each column of the sub-grouped alignment.</p>
   <p>
-    If you use this service in your work, please cite :<br />
+    If you use this service in your work, please cite :<br /> 
     <a name="shmrref" /> Brandt, B.W.*, Feenstra, K.A*. and Heringa, J.
     (2010) Multi-Harmony: detecting functional specificity from sequence
     alignment. <a
-      href="http://nar.oxfordjournals.org/cgi/content/abstract/gkq415"
-    >Nucleic Acids Res. 38: W35-W40.</a> (<em>* joint first authors</em>)
-  
+      href="http://nar.oxfordjournals.org/cgi/content/abstract/gkq415">Nucleic
+      Acids Res. 38: W35-W40.</a> (<em>* joint first authors</em>)
   <p>
     <strong><em>Note:</em></strong> The Multi-Harmony service is
     implemented with a prototype of Jalview's RESTful web service client
index 7a23d58..088a539 100644 (file)
@@ -28,9 +28,8 @@
     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
-      href="#urllinks"
-    >sequence URL links</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>
     Other links for a sequence either derived from any other configured
   <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 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>
+    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
     new link, and <strong>edit</strong> to modify an existing link, or <strong>delete</strong>
     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 585cdfb..84eccc3 100644 (file)
 
   <p>
     Some Jalview services, including those provided by <a
-      href="JABAWS.html"
-    >JABAWS</a>, support a range of parameters and options, enabling you
-    to employ the most appropriate settings for the input data. In
-    addition to any preset combinations provided by services themselves,
-    the Web services parameters dialog box also allows you to create and
-    store your own parameter sets, so they can be accessed quickly from
-    the presets menu.
+      href="JABAWS.html">JABAWS</a>, support a range of parameters
+    and options, enabling you to employ the most appropriate settings
+    for the input data. In addition to any preset combinations provided
+    by services themselves, the Web services parameters dialog box also
+    allows you to create and store your own parameter sets, so they can
+    be accessed quickly from the presets menu.
   </p>
   <p>
     <Strong>Accessing the parameter dialog box</Strong><br> The
@@ -61,8 +60,8 @@
   <p>
   <center>
     <img src="wsparams.gif" align="center" width="480" height="499"
-      alt="Analysis Parameters Dialog Box for JABAWS Services"
-    > <br> Parameter settings dialog box for JABAWS MAFFT Service
+      alt="Analysis Parameters Dialog Box for JABAWS Services">
+    <br> Parameter settings dialog box for JABAWS MAFFT Service
   </center>
   </p>
   <p>The menu and text box at the top of the dialog box displays the
@@ -73,6 +72,7 @@
     this), allowing you to provide notes to accompany the parameter set.
     The modification of these or any of the option or parameter settings
     will enable one or more of the following buttons, that allow you to:
+
   
   <ul>
     <li><em>Revert</em> the changes you have made. This will undo
index 1950058..0ebeea5 100644 (file)
@@ -38,8 +38,8 @@
   <p>
   <center>
     <img src="wsprefs.gif" align="center"
-      alt="Web Services Preferences Panel" width="571" height="461"
-    ><br> Web Services Preference Panel
+      alt="Web Services Preferences Panel" width="571" height="461"><br>
+    Web Services Preference Panel
   </center>
   </p>
   <p>
@@ -85,8 +85,8 @@
   <center>
     <img src="invalidurldialog.gif" align="center"
       alt="Web Services Invalid URL Warning dialog box" width="389"
-      height="258"
-    ><br> Web Services Invalid URL Warning dialog box
+      height="258"><br> Web Services Invalid URL Warning
+    dialog box
   </center>
   <br>
   <strong><em>Note:</em></strong> this warning will be shown if you are
index e1b00c4..d1d141d 100755 (executable)
 </head>
 <body>
   <p>
-    <strong>What's new ?</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>
-  <p>
-    <strong>Highlights in Jalview 2.10</strong>
   <ul>
-    <li><strong>Ensembl sequence fetcher.</strong> 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 also allows:
-      <ul>
-        <li><strong>Sequence variant data.</strong> Jalview
-          propagates variant annotation imported via Ensembl onto
-          protein products, complete with associated metadata such as
-          clinical significance.</li>
-        <li><strong>Aligned locus view.</strong> Transcripts
-          retrieved for a gene identifier via the Ensembl or
-          EnsemblGenomes sequence databases are automatically aligned to
-          their reference genome.</li>
-      </ul></li>
-    <li><strong>Working with structures.</strong>
-      <ul>
-        <li><strong>More accurate structure mappings.</strong>
-          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>. 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>
-      </ul></li>
-    <li><strong>UniProt Free Text Search</strong>. The new search
-      dialog for UniProt allows you to browse and retrieve sequences
-      from UniProt with free-text search and more structured queries</li>
-    <li><strong>Reference sequence based alignment
-        visualisation.</strong>. 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></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 d41c2ca..3488ac6 100644 (file)
@@ -1,4 +1,4 @@
-YEAR=2014
-AUTHORS=J Procter, AM Waterhouse, M Carstairs, TC Ofoegbu, J Engelhardt, LM Lui, A Menard, D Barton, N Sherstnev, D Roldan-Martinez, M Clamp, S Searle, G Barton
-AUTHORFNAMES=Jim Procter, Andrew Waterhouse, Mungo Carstairs, Tochukwu 'Charles' Ofoegbu, Jan Engelhardt, Lauren Lui, Anne Menard, Daniel Barton, Natasha Sherstnev, David Roldan-Martinez, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+YEAR=2016
+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 01b921a..3b80821 100644 (file)
@@ -28,6 +28,9 @@
        -->
        <class name="jalview.datamodel.xdb.embl.EmblFile">
                <map-to xml="ROOT"/>
+               <field name="text" type="string">
+                       <bind-xml node="text"/>
+               </field>
                <field name="entries" type="jalview.datamodel.xdb.embl.EmblEntry" collection="vector">
                        <bind-xml name="entry"/>
                </field>
index 5ac50bb..278b86e 100644 (file)
@@ -44,7 +44,7 @@ _data_column.preferred_col_width
 _data_column.is_shown_by_default
 _data_column.is_searchable
 PDB Id;pdb_id;String;g2;40;60;45;true;true
-Title;title;String;g6;300;1500;400;true;false
+Title;title;String;g6;50;1500;400;true;false
 Molecule;molecule_name;String;g3;50;400;95;false;true
 Molecule Type;molecule_type;String;g3;50;400;95;false;true
 Sequence;molecule_sequence;String;g6;50;400;95;false;false
@@ -111,7 +111,7 @@ R Free;r_free;Double|T|3;g1;50;150;85;false;false
 Number of Polymer Entities;number_of_polymer_entities;int;g6;50;400;95;false;false
 Number of Bound Entities;number_of_bound_entities;int;g6;50;400;95;false;false
 Crystallisation Reservoir;crystallisation_reservoir;String;g6;50;400;95;false;false
-Data Scalling Software;data_scaling_software;String;g4;50;400;95;false;false
+Data Scaling Software;data_scaling_software;String;g4;50;400;95;false;false
 Detector;detector;String;g6;50;400;95;false;false
 Detector Type;detector_type;String;g6;50;400;95;false;false
 Modified Residue Flag;modified_residue_flag;String;g6;50;400;95;false;false
index f5b4f7a..6360dc7 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
@@ -729,8 +731,8 @@ label.move_url_down = Move URL Down
 label.add_sbrs_definition = Add a SBRS Definition
 label.edit_sbrs_definition = Edit SBRS Definition
 label.delete_sbrs_definition = Delete SBRS Definition
-label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases. Some of the ids have been\n altered, most likely the start/end residue will have been updated.\n Save your alignment to maintain the updated id.\n\n
-label.sequence_names_updated = Sequence names updated
+label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases.\n(Use Calculate | Show flanking regions to show enclosing sequence.)\nTo preserve data changes, save your alignment.\n\n
+label.sequences_updated = Sequences updated
 label.dbref_search_completed = DBRef search completed
 label.show_all_chains = Show all chains
 label.fetch_all_param = Fetch all {0}
@@ -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
@@ -1128,7 +1132,7 @@ status.das_feature_fetching_complete = DAS Feature Fetching Complete
 status.fetching_db_refs = Fetching db refs
 status.loading_cached_pdb_entries = Loading Cached PDB Entries
 status.searching_for_pdb_structures = Searching for PDB Structures
-status.opening_file = opening file
+status.opening_file_for = opening file for
 status.colouring_chimera = Colouring Chimera
 label.font_doesnt_have_letters_defined = Font doesn't have letters defined\nso cannot be used\nwith alignment data
 label.font_too_small = Font size is too small
@@ -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 87538be..e5b5e27 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
@@ -674,8 +676,8 @@ label.move_url_down = Mover la URL hacia abajo
 label.add_sbrs_definition = Añadir una definición SBRS 
 label.edit_sbrs_definition = Editar una definición SBRS 
 label.delete_sbrs_definition = Borrar una definición SBRS 
-label.your_sequences_have_been_verified = Sus secuencias has sido verificadas en una base de datos de secuencias conocidas. Algunos de sus ID se han alterado y\n, probablemente, el residuo de inicio/fin se haya actualizado.\nGuarde su alineamiento para mantener el ID actualizado.\n\n 
-label.sequence_names_updated = Nombres de secuencia actualizados
+label.your_sequences_have_been_verified = Sus secuencias has sido verificadas en una base de datos de secuencias conocidas.\n(Usar Calcular | Mostrar flancos para ver ampliación.)\nPara mantener los datos actualizados, guarde su alineamiento.\n\n 
+label.sequences_updated = Secuencias actualizadas
 label.dbref_search_completed = Búsqueda de DBRef terminada
 label.show_all_chains = Mostrar todas las cadenas
 label.fetch_all_param = Recuperar todas {0}
@@ -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?
@@ -1127,7 +1131,7 @@ action.yes=S
 label.export_settings=Exportar Ajustes
 label.linked_view_title=Vista vinculada de cDNA y proteína
 label.couldnt_read_data=No se pudo leer los datos
-status.opening_file=abriendo fichero
+status.opening_file_for=abriendo fichero para
 label.except_selected_sequences=Todo excepto secuencias seleccionadas
 label.structure_chooser_no_of_structures=Selector de Estructuras - {0} Encontró ({1})
 label.search_filter=filtro de búsqueda
@@ -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 a8634af..4a981ad 100755 (executable)
@@ -80,7 +80,7 @@
         <class name="jalview.datamodel.PDBEntry">
                <field name="type"><bind-xml node="attribute"/></field>
                <field name="id"><bind-xml node="attribute"/></field>
-               <field name="property" collection="hashtable">
+               <field name="props" collection="hashtable">
                        <bind-xml name="property">
                           <class name="org.exolab.castor.mapping.MapItem">
                              <field name="key">
index df98833..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());
       }
@@ -189,8 +190,10 @@ public class AppletPDBCanvas extends Panel implements MouseListener,
     for (int i = 0; i < pdb.getChains().size(); i++)
     {
 
-      mappingDetails.append("\n\nPDB Sequence is :\nSequence = "
-              + pdb.getChains().elementAt(i).sequence.getSequenceAsString());
+      mappingDetails
+              .append("\n\nPDB Sequence is :\nSequence = "
+                      + pdb.getChains().elementAt(i).sequence
+                              .getSequenceAsString());
       mappingDetails.append("\nNo of residues = "
               + pdb.getChains().elementAt(i).residues.size() + "\n\n");
 
@@ -199,8 +202,8 @@ public class AppletPDBCanvas extends Panel implements MouseListener,
       // Align the sequence to the pdb
       // TODO: DNa/Pep switch
       AlignSeq as = new AlignSeq(sequence,
-              pdb.getChains().elementAt(i).sequence,
-              pdb.getChains().elementAt(i).isNa ? AlignSeq.DNA : AlignSeq.PEP);
+              pdb.getChains().elementAt(i).sequence, pdb.getChains()
+                      .elementAt(i).isNa ? AlignSeq.DNA : AlignSeq.PEP);
       as.calcScoreMatrix();
       as.traceAlignment();
       PrintStream ps = new PrintStream(System.out)
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 fe6a0ac..904e307 100755 (executable)
@@ -126,6 +126,7 @@ public class Atom
     }
     return false;
   }
+
   public Atom(float x, float y, float z)
   {
     this.x = x;
index 1c7a1f7..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());
       }
@@ -188,8 +189,10 @@ public class PDBCanvas extends JPanel implements MouseListener,
     for (int i = 0; i < pdb.getChains().size(); i++)
     {
 
-      mappingDetails.append("\n\nPDB Sequence is :\nSequence = "
-              + pdb.getChains().elementAt(i).sequence.getSequenceAsString());
+      mappingDetails
+              .append("\n\nPDB Sequence is :\nSequence = "
+                      + pdb.getChains().elementAt(i).sequence
+                              .getSequenceAsString());
       mappingDetails.append("\nNo of residues = "
               + pdb.getChains().elementAt(i).residues.size() + "\n\n");
 
index cf794b6..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())
         {
@@ -199,7 +202,8 @@ public class PDBChain
     }
     for (int i = 0; i < features.length; i++)
     {
-      if (features[i].getFeatureGroup().equals(pdbid))
+      if (features[i].getFeatureGroup() != null
+              && features[i].getFeatureGroup().equals(pdbid))
       {
         SequenceFeature tx = new SequenceFeature(features[i]);
         tx.setBegin(1 + residues.elementAt(tx.getBegin() - offset).atoms
@@ -357,53 +361,53 @@ public class PDBChain
       else
       {
 
-      // Make a new Residue object with the new atoms vector
-      residues.addElement(new Residue(resAtoms, resNumber - 1, count));
+        // Make a new Residue object with the new atoms vector
+        residues.addElement(new Residue(resAtoms, resNumber - 1, count));
 
-      Residue tmpres = residues.lastElement();
-      Atom tmpat = tmpres.atoms.get(0);
-      // Make A new SequenceFeature for the current residue numbering
+        Residue tmpres = residues.lastElement();
+        Atom tmpat = tmpres.atoms.get(0);
+        // Make A new SequenceFeature for the current residue numbering
         SequenceFeature sf = new SequenceFeature("RESNUM", tmpat.resName
-              + ":" + tmpat.resNumIns + " " + pdbid + id, "", offset
-              + count, offset + count, pdbid);
-      resFeatures.addElement(sf);
-      resAnnotation.addElement(new Annotation(tmpat.tfactor));
-      // Keep totting up the sequence
+                + ":" + tmpat.resNumIns + " " + pdbid + id, "", offset
+                + count, offset + count, pdbid);
+        resFeatures.addElement(sf);
+        resAnnotation.addElement(new Annotation(tmpat.tfactor));
+        // Keep totting up the sequence
 
-      if ((symbol = ResidueProperties.getAA3Hash().get(tmpat.resName)) == null)
-      {
-        String nucname = tmpat.resName.trim();
-        // use the aaIndex rather than call 'toLower' - which would take a bit
-        // more time.
-        deoxyn = nucname.length() == 2
-                && ResidueProperties.aaIndex[nucname.charAt(0)] == ResidueProperties.aaIndex['D'];
-        if (tmpat.name.equalsIgnoreCase("CA")
-                || ResidueProperties.nucleotideIndex[nucname
-                        .charAt((deoxyn ? 1 : 0))] == -1)
+        if ((symbol = ResidueProperties.getAA3Hash().get(tmpat.resName)) == null)
         {
+          String nucname = tmpat.resName.trim();
+          // use the aaIndex rather than call 'toLower' - which would take a bit
+          // more time.
+          deoxyn = nucname.length() == 2
+                  && ResidueProperties.aaIndex[nucname.charAt(0)] == ResidueProperties.aaIndex['D'];
+          if (tmpat.name.equalsIgnoreCase("CA")
+                  || ResidueProperties.nucleotideIndex[nucname
+                          .charAt((deoxyn ? 1 : 0))] == -1)
+          {
             char r = ResidueProperties
                     .getSingleCharacterCode(ResidueProperties
                             .getCanonicalAminoAcid(tmpat.resName));
             seq.append(r == '0' ? 'X' : r);
             // System.err.println("PDBReader:Null aa3Hash for " +
             // tmpat.resName);
+          }
+          else
+          {
+            // nucleotide flag
+            nucleotide = true;
+            seq.append(nucname.charAt((deoxyn ? 1 : 0)));
+          }
         }
         else
         {
-          // nucleotide flag
-          nucleotide = true;
-          seq.append(nucname.charAt((deoxyn ? 1 : 0)));
-        }
-      }
-      else
-      {
-        if (nucleotide)
-        {
-          System.err
-                  .println("Warning: mixed nucleotide and amino acid chain.. its gonna do bad things to you!");
+          if (nucleotide)
+          {
+            System.err
+                    .println("Warning: mixed nucleotide and amino acid chain.. its gonna do bad things to you!");
+          }
+          seq.append(ResidueProperties.aa[((Integer) symbol).intValue()]);
         }
-        seq.append(ResidueProperties.aa[((Integer) symbol).intValue()]);
-      }
         count++;
       }
     }
@@ -425,11 +429,11 @@ public class PDBChain
 
     if (StructureImportSettings.isShowSeqFeatures())
     {
-    for (i = 0, iSize = resFeatures.size(); i < iSize; i++)
-    {
-      sequence.addSequenceFeature(resFeatures.elementAt(i));
-      resFeatures.setElementAt(null, i);
-    }
+      for (i = 0, iSize = resFeatures.size(); i < iSize; i++)
+      {
+        sequence.addSequenceFeature(resFeatures.elementAt(i));
+        resFeatures.setElementAt(null, i);
+      }
     }
     if (visibleChainAnnotation)
     {
index 66ce147..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);
 
@@ -128,18 +129,17 @@ public class PDBViewer extends JInternalFrame implements Runnable
       worker.start();
     }
 
-    if (pdbentry.getProperty() != null)
+    String method = (String) pdbentry.getProperty("method");
+    if (method != null)
     {
-      if (pdbentry.getProperty().get("method") != null)
-      {
-        title.append(" Method: ");
-        title.append(pdbentry.getProperty().get("method"));
-      }
-      if (pdbentry.getProperty().get("chains") != null)
-      {
-        title.append(" Chain:");
-        title.append(pdbentry.getProperty().get("chains"));
-      }
+      title.append(" Method: ");
+      title.append(method);
+    }
+    String ch = (String) pdbentry.getProperty("chains");
+    if (ch != null)
+    {
+      title.append(" Chain:");
+      title.append(ch);
     }
     Desktop.addInternalFrame(this, title.toString(), 400, 400);
   }
@@ -151,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)
@@ -437,14 +437,13 @@ public class PDBViewer extends JInternalFrame implements Runnable
           {
             radioItem.removeActionListener(radioItem.getActionListeners()[0]);
 
-            int option = JOptionPane.showInternalConfirmDialog(
-                    jalview.gui.Desktop.desktop,
-                    MessageManager
+            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 2746807..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,17 +47,17 @@ 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();
   }
 
   public PDBfile(boolean addAlignmentAnnotations, boolean predictSecStr,
-          boolean externalSecStr,
-          FileParse source) throws IOException
+          boolean externalSecStr, FileParse source) throws IOException
   {
     super(false, source);
     addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
@@ -64,7 +65,7 @@ public class PDBfile extends StructureFile
   }
 
   @Override
-  public String print()
+  public String print(SequenceI[] seqs, boolean jvSuffix)
   {
     return null;
   }
@@ -145,7 +146,7 @@ public class PDBfile extends StructureFile
           Atom tmpatom = new Atom(line);
           try
           {
-          tmpchain = findChain(tmpatom.chain);
+            tmpchain = findChain(tmpatom.chain);
             if (tmpatom.resNumIns.trim().equals(lastID))
             {
               // phosphorylated protein - seen both CA and P..
@@ -203,8 +204,6 @@ public class PDBfile extends StructureFile
     markCalcIds();
   }
 
-
-
   /**
    * Process a parsed chain to construct and return a Sequence, and add it to
    * the list of sequences parsed.
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 c0c7c46..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;
@@ -27,6 +59,10 @@ import ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads;
  */
 public class ChimeraManager
 {
+  private static final int REST_REPLY_TIMEOUT_MS = 15000;
+
+  private static final int CONNECTION_TIMEOUT_MS = 100;
+
   private static final boolean debug = false;
 
   private int chimeraRestPort;
@@ -344,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)
       {
@@ -782,8 +820,8 @@ public class ChimeraManager
     BufferedReader response = null;
     try
     {
-      response = HttpClientUtils
-              .doHttpUrlPost(restUrl, commands, 100, 5000);
+      response = HttpClientUtils.doHttpUrlPost(restUrl, commands, CONNECTION_TIMEOUT_MS,
+              REST_REPLY_TIMEOUT_MS);
       String line = "";
       while ((line = response.readLine()) != null)
       {
@@ -850,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 76b8fe9..f31aa1e 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))))
           {
@@ -663,8 +666,7 @@ public class AlignSeq
     }
 
     pid = pid / (aseq1.length - count) * 100;
-    output = output.append(new Format("Percentage ID = %2.2f\n")
-            .form(pid));
+    output = output.append(new Format("Percentage ID = %2.2f\n").form(pid));
     try
     {
       os.print(output.toString());
index 5ee4bcb..59cdccf 100755 (executable)
@@ -719,10 +719,12 @@ public class AlignmentSorter
   public static void sortByFeature(String featureLabel, String groupLabel,
           int start, int stop, AlignmentI alignment, String method)
   {
-    sortByFeature(featureLabel == null ? null
+    sortByFeature(
+            featureLabel == null ? null
                     : Arrays.asList(new String[] { featureLabel }),
-            groupLabel == null ? null
-            : Arrays.asList(new String[]{ groupLabel }), start, stop, alignment, method);
+            groupLabel == null ? null : Arrays
+                    .asList(new String[] { groupLabel }), start, stop,
+            alignment, method);
   }
 
   private static boolean containsIgnoreCase(final String lab,
@@ -747,8 +749,8 @@ public class AlignmentSorter
   }
 
   public static void sortByFeature(List<String> featureLabels,
-          List<String> groupLabels, int start, int stop, AlignmentI alignment,
-          String method)
+          List<String> groupLabels, int start, int stop,
+          AlignmentI alignment, String method)
   {
     if (method != FEATURE_SCORE && method != FEATURE_LABEL
             && method != FEATURE_DENSITY)
index ea330d8..34fe221 100644 (file)
@@ -73,7 +73,9 @@ public class AlignmentUtils
 {
 
   private static final int CODON_LENGTH = 3;
+
   private static final String SEQUENCE_VARIANT = "sequence_variant:";
+
   private static final String ID = "ID";
 
   /**
@@ -446,8 +448,8 @@ public class AlignmentUtils
      */
     if (cdnaLength != mappedLength && cdnaLength > 2)
     {
-      String lastCodon = String.valueOf(cdnaSeqChars, cdnaLength - CODON_LENGTH, CODON_LENGTH)
-              .toUpperCase();
+      String lastCodon = String.valueOf(cdnaSeqChars,
+              cdnaLength - CODON_LENGTH, CODON_LENGTH).toUpperCase();
       for (String stop : ResidueProperties.STOP)
       {
         if (lastCodon.equals(stop))
@@ -509,8 +511,7 @@ public class AlignmentUtils
 
     int aaPos = 0;
     int dnaPos = cdnaStart;
-    for (; dnaPos < cdnaSeqChars.length - 2
-            && aaPos < aaSeqChars.length; dnaPos += CODON_LENGTH, aaPos++)
+    for (; dnaPos < cdnaSeqChars.length - 2 && aaPos < aaSeqChars.length; dnaPos += CODON_LENGTH, aaPos++)
     {
       String codon = String.valueOf(cdnaSeqChars, dnaPos, CODON_LENGTH);
       final String translated = ResidueProperties.codonTranslate(codon);
@@ -936,7 +937,7 @@ public class AlignmentUtils
               .println("alignCdsSequenceAsProtein needs aligned sequence!");
       return false;
     }
-    
+
     List<AlignedCodonFrame> dnaMappings = MappingUtils
             .findMappingsForSequence(cdsSeq, mappings);
     for (AlignedCodonFrame mapping : dnaMappings)
@@ -958,7 +959,8 @@ public class AlignmentUtils
                   .getFromRanges());
           int mappedToLength = MappingUtils
                   .getLength(mapList.getToRanges());
-          boolean addStopCodon = (cdsLength == mappedFromLength * CODON_LENGTH + CODON_LENGTH)
+          boolean addStopCodon = (cdsLength == mappedFromLength
+                  * CODON_LENGTH + CODON_LENGTH)
                   || (peptide.getDatasetSequence().getLength() == mappedFromLength - 1);
           if (cdsLength != mappedToLength && !addStopCodon)
           {
@@ -1097,7 +1099,7 @@ public class AlignmentUtils
     // TODO resolve JAL-2022 so this fudge can be removed
     int mappedSequenceCount = protein.getHeight() - unmappedProtein.size();
     addUnmappedPeptideStarts(alignedCodons, mappedSequenceCount);
-    
+
     return alignedCodons;
   }
 
@@ -1710,8 +1712,9 @@ public class AlignmentUtils
            */
           List<int[]> cdsRange = Collections.singletonList(new int[] { 1,
               cdsSeq.getLength() });
-          MapList cdsToProteinMap = new MapList(cdsRange, mapList.getToRanges(),
-                  mapList.getFromRatio(), mapList.getToRatio());
+          MapList cdsToProteinMap = new MapList(cdsRange,
+                  mapList.getToRanges(), mapList.getFromRatio(),
+                  mapList.getToRatio());
           AlignedCodonFrame cdsToProteinMapping = new AlignedCodonFrame();
           cdsToProteinMapping.addMap(cdsSeqDss, proteinProduct,
                   cdsToProteinMap);
@@ -1731,8 +1734,7 @@ public class AlignmentUtils
            */
           AlignedCodonFrame dnaToCdsMapping = new AlignedCodonFrame();
           MapList dnaToCdsMap = new MapList(mapList.getFromRanges(),
-                  cdsRange, 1,
-                  1);
+                  cdsRange, 1, 1);
           dnaToCdsMapping.addMap(dnaSeq.getDatasetSequence(), cdsSeqDss,
                   dnaToCdsMap);
           if (!mappings.contains(dnaToCdsMapping))
@@ -1747,16 +1749,16 @@ public class AlignmentUtils
            * same source and accession, so need a different accession for
            * the CDS from the dna sequence
            */
-          
+
           // specific use case:
           // Genomic contig ENSCHR:1, contains coding regions for ENSG01,
           // ENSG02, ENSG03, with transcripts and products similarly named.
           // cannot add distinct dbrefs mapping location on ENSCHR:1 to ENSG01
-          
+
           // JBPNote: ?? can't actually create an example that demonstrates we
           // need to
           // synthesize an xref.
-          
+
           for (DBRefEntry primRef : dnaDss.getPrimaryDBRefs())
           {
             // creates a complementary cross-reference to the source sequence's
@@ -1786,7 +1788,7 @@ public class AlignmentUtils
           /*
            * transfer any features on dna that overlap the CDS
            */
-          transferFeatures(dnaSeq, cdsSeq, cdsToProteinMap, null,
+          transferFeatures(dnaSeq, cdsSeq, dnaToCdsMap, null,
                   SequenceOntologyI.CDS);
         }
       }
@@ -1833,7 +1835,8 @@ public class AlignmentUtils
     int mappedFromLength = MappingUtils.getLength(aMapping.getMap()
             .getFromRanges());
     int dnaLength = seqDss.getLength();
-    if (mappedFromLength == dnaLength || mappedFromLength == dnaLength - CODON_LENGTH)
+    if (mappedFromLength == dnaLength
+            || mappedFromLength == dnaLength - CODON_LENGTH)
     {
       return seqDss;
     }
@@ -1849,7 +1852,8 @@ public class AlignmentUtils
       for (SequenceToSequenceMapping map : acf.getMappings())
       {
         Mapping mapping = map.getMapping();
-        if (mapping != aMapping && mapping.getMap().getFromRatio() == CODON_LENGTH
+        if (mapping != aMapping
+                && mapping.getMap().getFromRatio() == CODON_LENGTH
                 && proteinProduct == mapping.getTo()
                 && seqDss != map.getFromSeq())
         {
@@ -1917,7 +1921,7 @@ public class AlignmentUtils
         }
       }
     }
-    
+
     /*
      * assign 'from id' held in the mapping if set (e.g. EMBL protein_id),
      * else generate a sequence name
@@ -2483,7 +2487,9 @@ public class AlignmentUtils
         StringBuilder link = new StringBuilder(32);
         try
         {
-          link.append(desc).append(" ").append(id)
+          link.append(desc)
+                  .append(" ")
+                  .append(id)
                   .append("|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=")
                   .append(URLEncoder.encode(id, "UTF-8"));
           sf.addLink(link.toString());
@@ -2492,8 +2498,7 @@ public class AlignmentUtils
           // as if
         }
       }
-      String clinSig = (String) var.variant
-              .getValue(CLINICAL_SIGNIFICANCE);
+      String clinSig = (String) var.variant.getValue(CLINICAL_SIGNIFICANCE);
       if (clinSig != null)
       {
         sf.setValue(CLINICAL_SIGNIFICANCE, clinSig);
@@ -2742,7 +2747,7 @@ public class AlignmentUtils
           }
           newCol++;
         }
-        
+
         /*
          * trim trailing gaps
          */
index 711710b..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++)
+    {
+      ResidueCount values = countResidues(column);
+
+      /*
+       * percentage count at or below which we ignore residues
+       */
+      int thresh = (threshold * height) / 100;
+
+      /*
+       * 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++)
+      {
+        char c = symbols[j];
+        if (counts[j] > thresh)
+        {
+          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())
     {
-      values = new int[255];
+      String propertyName = property.getKey();
+      Integer residuePropertyValue = property.getValue().get(res);
 
-      for (j = 0; j < jSize; j++)
+      if (!resultMap.containsKey(propertyName))
       {
-        if (sequences[j].getLength() > i)
+        /*
+         * first time we've seen this residue - note whether it has this property
+         */
+        if (residuePropertyValue != null)
         {
-          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]++;
+          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)
     {
-      if (j >= sequences[i].getLength())
+      return new int[] { 0, 0 };
+    }
+
+    char lastRes = '0';
+    for (int i = 0; i < iSize; i++)
+    {
+      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
@@ -558,8 +643,10 @@ public class Conservation
       {
         tot = 0;
         xx = new double[24];
-        seqNum = (j < lengths[k]) ? seqNums.elementAt(k)[j + 1]
-                : 23; // Sequence, or gap at the end
+        seqNum = (j < lengths[k]) ? seqNums.elementAt(k)[j + 1] : 23; // Sequence,
+                                                                      // or gap
+                                                                      // at the
+                                                                      // end
 
         // This is a loop over r
         for (i = 0; i < 23; i++)
@@ -718,35 +805,53 @@ 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)
     {
       cons.findQuality();
     }
-    
+
     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 1295b46..4ba7e41 100644 (file)
@@ -24,6 +24,7 @@ import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
@@ -106,6 +107,16 @@ public class CrossRef
         findXrefSourcesForSequence(seq, dna, sources);
       }
     }
+    sources.remove(DBRefSource.EMBL); // hack to prevent EMBL xrefs resulting in
+                                      // redundant datasets
+    if (dna)
+    {
+      sources.remove(DBRefSource.ENSEMBL); // hack to prevent Ensembl and
+                                           // EnsemblGenomes xref option shown
+                                           // from cdna panel
+      sources.remove(DBRefSource.ENSEMBLGENOMES);
+    }
+    // redundant datasets
     return sources;
   }
 
@@ -209,8 +220,7 @@ public class CrossRef
 
     rseqs = new ArrayList<SequenceI>();
     AlignedCodonFrame cf = new AlignedCodonFrame();
-    matcher = new SequenceIdMatcher(
-            dataset.getSequences());
+    matcher = new SequenceIdMatcher(dataset.getSequences());
 
     for (SequenceI seq : fromSeqs)
     {
@@ -296,20 +306,28 @@ public class CrossRef
               if (!rseqs.contains(matchInDataset))
               {
                 rseqs.add(matchInDataset);
-                // need to try harder to only add unique mappings
-                if (xref.getMap().getMap().isTripletMap()
-                        && dataset.getMapping(seq, matchInDataset) == null
-                        && cf.getMappingBetween(seq, matchInDataset) == null)
+              }
+              // even if rseqs contained matchInDataset - check mappings between
+              // these seqs are added
+              // need to try harder to only add unique mappings
+              if (xref.getMap().getMap().isTripletMap()
+                      && dataset.getMapping(seq, matchInDataset) == null
+                      && cf.getMappingBetween(seq, matchInDataset) == null)
+              {
+                // materialise a mapping for highlighting between these
+                // sequences
+                if (fromDna)
                 {
-                  // materialise a mapping for highlighting between these sequences
-                  if (fromDna)
-                  {
-                    cf.addMap(dss, matchInDataset, xref.getMap().getMap(), xref.getMap().getMappedFromId());
-                  } else {
-                    cf.addMap(matchInDataset, dss, xref.getMap().getMap().getInverse(), xref.getMap().getMappedFromId());
-                  }
+                  cf.addMap(dss, matchInDataset, xref.getMap().getMap(),
+                          xref.getMap().getMappedFromId());
+                }
+                else
+                {
+                  cf.addMap(matchInDataset, dss, xref.getMap().getMap()
+                          .getInverse(), xref.getMap().getMappedFromId());
                 }
               }
+
               refIterator.remove();
               continue;
             }
@@ -393,28 +411,7 @@ public class CrossRef
     // first filter in case we are retrieving crossrefs that have already been
     // retrieved. this happens for cases where a database record doesn't yield
     // protein products for CDS
-    DBRefEntry[] dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
-    for (SequenceI sq : dataset.getSequences())
-    {
-      boolean dupeFound = false;
-      // !fromDna means we are looking only for nucleotide sequences, not
-      // protein
-      if (sq.isProtein() == fromDna)
-      {
-        for (DBRefEntry dbr : sq.getPrimaryDBRefs())
-        {
-          for (DBRefEntry found : DBRefUtils.searchRefs(dbrSourceSet, dbr))
-          {
-            sourceRefs.remove(found);
-            dupeFound = true;
-          }
-        }
-      }
-      if (dupeFound)
-      {
-        dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
-      }
-    }
+    removeAlreadyRetrievedSeqs(sourceRefs, fromDna);
     if (sourceRefs.size() == 0)
     {
       // no more work to do! We already had all requested sequence records in
@@ -434,132 +431,241 @@ public class CrossRef
 
     if (retrieved != null)
     {
-      updateDbrefMappings(seq, xrfs, retrieved, cf, fromDna);
+      boolean addedXref = false;
+      List<SequenceI> newDsSeqs = new ArrayList<SequenceI>(), doNotAdd = new ArrayList<SequenceI>();
+
       for (SequenceI retrievedSequence : retrieved)
       {
         // dataset gets contaminated ccwith non-ds sequences. why ??!
         // try: Ensembl -> Nuc->Ensembl, Nuc->Uniprot-->Protein->EMBL->
         SequenceI retrievedDss = retrievedSequence.getDatasetSequence() == null ? retrievedSequence
                 : retrievedSequence.getDatasetSequence();
-        DBRefEntry[] dbr = retrievedSequence.getDBRefs();
-        if (dbr != null)
+        addedXref |= importCrossRefSeq(cf, newDsSeqs, doNotAdd, dss,
+                retrievedDss);
+      }
+      if (!addedXref)
+      {
+        // try again, after looking for matching IDs
+        // shouldn't need to do this unless the dbref mechanism has broken.
+        updateDbrefMappings(seq, xrfs, retrieved, cf, fromDna);
+        for (SequenceI retrievedSequence : retrieved)
+        {
+          // dataset gets contaminated ccwith non-ds sequences. why ??!
+          // try: Ensembl -> Nuc->Ensembl, Nuc->Uniprot-->Protein->EMBL->
+          SequenceI retrievedDss = retrievedSequence.getDatasetSequence() == null ? retrievedSequence
+                  : retrievedSequence.getDatasetSequence();
+          addedXref |= importCrossRefSeq(cf, newDsSeqs, doNotAdd, dss,
+                  retrievedDss);
+        }
+      }
+      for (SequenceI newToSeq : newDsSeqs)
+      {
+        if (!doNotAdd.contains(newToSeq)
+                && dataset.findIndex(newToSeq) == -1)
         {
-          for (DBRefEntry dbref : dbr)
+          dataset.addSequence(newToSeq);
+          matcher.add(newToSeq);
+        }
+      }
+    }
+  }
+
+  /**
+   * Search dataset for sequences with a primary reference contained in
+   * sourceRefs.
+   * 
+   * @param sourceRefs
+   *          - list of references to filter.
+   * @param fromDna
+   *          - type of sequence to search for matching primary reference.
+   */
+  private void removeAlreadyRetrievedSeqs(List<DBRefEntry> sourceRefs,
+          boolean fromDna)
+  {
+    DBRefEntry[] dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
+    for (SequenceI sq : dataset.getSequences())
+    {
+      boolean dupeFound = false;
+      // !fromDna means we are looking only for nucleotide sequences, not
+      // protein
+      if (sq.isProtein() == fromDna)
+      {
+        for (DBRefEntry dbr : sq.getPrimaryDBRefs())
+        {
+          for (DBRefEntry found : DBRefUtils.searchRefs(dbrSourceSet, dbr))
           {
-            // find any entry where we should put in the sequence being
-            // cross-referenced into the map
-            Mapping map = dbref.getMap();
-            if (map != null)
+            sourceRefs.remove(found);
+            dupeFound = true;
+          }
+        }
+      }
+      if (dupeFound)
+      {
+        // rebuild the search array from the filtered sourceRefs list
+        dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
+      }
+    }
+  }
+
+  /**
+   * process sequence retrieved via a dbref on source sequence to resolve and
+   * transfer data
+   * 
+   * @param cf
+   * @param sourceSequence
+   * @param retrievedSequence
+   * @return true if retrieveSequence was imported
+   */
+  private boolean importCrossRefSeq(AlignedCodonFrame cf,
+          List<SequenceI> newDsSeqs, List<SequenceI> doNotAdd,
+          SequenceI sourceSequence, SequenceI retrievedSequence)
+  {
+    /**
+     * set when retrievedSequence has been verified as a crossreference for
+     * sourceSequence
+     */
+    boolean imported = false;
+    DBRefEntry[] dbr = retrievedSequence.getDBRefs();
+    if (dbr != null)
+    {
+      for (DBRefEntry dbref : dbr)
+      {
+        SequenceI matched = findInDataset(dbref);
+        if (matched == sourceSequence)
+        {
+          // verified retrieved and source sequence cross-reference each other
+          imported = true;
+        }
+        // find any entry where we should put in the sequence being
+        // cross-referenced into the map
+        Mapping map = dbref.getMap();
+        if (map != null)
+        {
+          if (map.getTo() != null && map.getMap() != null)
+          {
+            if (map.getTo() == sourceSequence)
+            {
+              // already called to import once, and most likely this sequence
+              // already imported !
+              continue;
+            }
+            if (matched == null)
+            {
+              /*
+               * sequence is new to dataset, so save a reference so it can be added. 
+               */
+              newDsSeqs.add(map.getTo());
+              continue;
+            }
+
+            /*
+             * there was a matching sequence in dataset, so now, check to see if we can update the map.getTo() sequence to the existing one.
+             */
+
+            try
             {
-              if (map.getTo() != null && map.getMap() != null)
+              // compare ms with dss and replace with dss in mapping
+              // if map is congruent
+              SequenceI ms = map.getTo();
+              // TODO findInDataset requires exact sequence match but
+              // 'congruent' test is only for the mapped part
+              // maybe not a problem in practice since only ENA provide a
+              // mapping and it is to the full protein translation of CDS
+              // matcher.findIdMatch(map.getTo());
+              // TODO addendum: if matched is shorter than getTo, this will fail
+              // - when it should really succeed.
+              int sf = map.getMap().getToLowest();
+              int st = map.getMap().getToHighest();
+              SequenceI mappedrg = ms.getSubSequence(sf, st);
+              if (mappedrg.getLength() > 0
+                      && ms.getSequenceAsString().equals(
+                              matched.getSequenceAsString()))
               {
-                // TODO findInDataset requires exact sequence match but
-                // 'congruent' test is only for the mapped part
-                // maybe not a problem in practice since only ENA provide a
-                // mapping and it is to the full protein translation of CDS
-                SequenceI matched = findInDataset(dbref);
-                // matcher.findIdMatch(map.getTo());
-                if (matched != null)
+                /*
+                 * sequences were a match, 
+                 */
+                String msg = "Mapping updated from " + ms.getName()
+                        + " to retrieved crossreference "
+                        + matched.getName();
+                System.out.println(msg);
+
+                DBRefEntry[] toRefs = map.getTo().getDBRefs();
+                if (toRefs != null)
                 {
                   /*
-                   * already got an xref to this sequence; update this
-                   * map to point to the same sequence, and add
-                   * any new dbrefs to it
+                   * transfer database refs
                    */
-                  DBRefEntry[] toRefs = map.getTo().getDBRefs();
-                  if (toRefs != null)
+                  for (DBRefEntry ref : toRefs)
                   {
-                    for (DBRefEntry ref : toRefs)
+                    if (dbref.getSrcAccString().equals(
+                            ref.getSrcAccString()))
                     {
-                      matched.addDBRef(ref); // add or update mapping
+                      continue; // avoid overwriting the ref on source sequence
                     }
-                  }
-                  map.setTo(matched);
-                }
-                else
-                {
-                  if (dataset.findIndex(map.getTo()) == -1)
-                  {
-                    dataset.addSequence(map.getTo());
-                    matcher.add(map.getTo());
+                    matched.addDBRef(ref); // add or update mapping
                   }
                 }
-                try
-                {
-                  // compare ms with dss and replace with dss in mapping
-                  // if map is congruent
-                  SequenceI ms = map.getTo();
-                  int sf = map.getMap().getToLowest();
-                  int st = map.getMap().getToHighest();
-                  SequenceI mappedrg = ms.getSubSequence(sf, st);
-                  // SequenceI loc = dss.getSubSequence(sf, st);
-                  if (mappedrg.getLength() > 0
-                          && ms.getSequenceAsString().equals(
-                                  dss.getSequenceAsString()))
-                  // && mappedrg.getSequenceAsString().equals(
-                  // loc.getSequenceAsString()))
-                  {
-                    String msg = "Mapping updated from " + ms.getName()
-                            + " to retrieved crossreference "
-                            + dss.getName();
-                    System.out.println(msg);
-                    map.setTo(dss);
+                doNotAdd.add(map.getTo());
+                map.setTo(matched);
 
-                    /*
-                     * give the reverse reference the inverse mapping 
-                     * (if it doesn't have one already)
-                     */
-                    setReverseMapping(dss, dbref, cf);
+                /*
+                 * give the reverse reference the inverse mapping 
+                 * (if it doesn't have one already)
+                 */
+                setReverseMapping(matched, dbref, cf);
 
+                /*
+                 * copy sequence features as well, avoiding
+                 * duplication (e.g. same variation from two 
+                 * transcripts)
+                 */
+                SequenceFeature[] sfs = ms.getSequenceFeatures();
+                if (sfs != null)
+                {
+                  for (SequenceFeature feat : sfs)
+                  {
                     /*
-                     * copy sequence features as well, avoiding
-                     * duplication (e.g. same variation from two 
-                     * transcripts)
+                     * make a flyweight feature object which ignores Parent
+                     * attribute in equality test; this avoids creating many
+                     * otherwise duplicate exon features on genomic sequence
                      */
-                    SequenceFeature[] sfs = ms.getSequenceFeatures();
-                    if (sfs != null)
+                    SequenceFeature newFeature = new SequenceFeature(feat)
                     {
-                      for (SequenceFeature feat : sfs)
+                      @Override
+                      public boolean equals(Object o)
                       {
-                        /*
-                         * make a flyweight feature object which ignores Parent
-                         * attribute in equality test; this avoids creating many
-                         * otherwise duplicate exon features on genomic sequence
-                         */
-                        SequenceFeature newFeature = new SequenceFeature(
-                                feat)
-                        {
-                          @Override
-                          public boolean equals(Object o)
-                          {
-                            return super.equals(o, true);
-                          }
-                        };
-                        dss.addSequenceFeature(newFeature);
+                        return super.equals(o, true);
                       }
-                    }
+                    };
+                    matched.addSequenceFeature(newFeature);
                   }
-                  cf.addMap(retrievedDss, map.getTo(), map.getMap());
-                } catch (Exception e)
-                {
-                  System.err
-                          .println("Exception when consolidating Mapped sequence set...");
-                  e.printStackTrace(System.err);
                 }
+
               }
+              cf.addMap(retrievedSequence, map.getTo(), map.getMap());
+            } catch (Exception e)
+            {
+              System.err
+                      .println("Exception when consolidating Mapped sequence set...");
+              e.printStackTrace(System.err);
             }
           }
         }
-        retrievedSequence.updatePDBIds();
-        rseqs.add(retrievedDss);
-        if (dataset.findIndex(retrievedDss) == -1)
-        {
-          dataset.addSequence(retrievedDss);
-          matcher.add(retrievedDss);
-        }
       }
     }
+    if (imported)
+    {
+      retrievedSequence.updatePDBIds();
+      rseqs.add(retrievedSequence);
+      if (dataset.findIndex(retrievedSequence) == -1)
+      {
+        dataset.addSequence(retrievedSequence);
+        matcher.add(retrievedSequence);
+      }
+    }
+    return imported;
   }
+
   /**
    * Sets the inverse sequence mapping in the corresponding dbref of the mapped
    * to sequence (if any). This is used after fetching a cross-referenced
@@ -602,9 +708,12 @@ public class CrossRef
   }
 
   /**
-   * Returns the first identical sequence in the dataset if any, else null
+   * Returns null or the first sequence in the dataset which is identical to
+   * xref.mapTo, and has a) a primary dbref matching xref, or if none found, the
+   * first one with an ID source|xrefacc
    * 
    * @param xref
+   *          with map and mapped-to sequence
    * @return
    */
   SequenceI findInDataset(DBRefEntry xref)
@@ -618,22 +727,42 @@ public class CrossRef
     String name2 = xref.getSource() + "|" + name;
     SequenceI dss = mapsTo.getDatasetSequence() == null ? mapsTo : mapsTo
             .getDatasetSequence();
+    // first check ds if ds is directly referenced
+    if (dataset.findIndex(dss) > -1)
+    {
+      return dss;
+    }
+    DBRefEntry template = new DBRefEntry(xref.getSource(), null,
+            xref.getAccessionId());
+    /**
+     * remember the first ID match - in case we don't find a match to template
+     */
+    SequenceI firstIdMatch = null;
     for (SequenceI seq : dataset.getSequences())
     {
+      // first check primary refs.
+      List<DBRefEntry> match = DBRefUtils.searchRefs(seq.getPrimaryDBRefs()
+              .toArray(new DBRefEntry[0]), template);
+      if (match != null && match.size() == 1 && sameSequence(seq, dss))
+      {
+        return seq;
+      }
       /*
        * clumsy alternative to using SequenceIdMatcher which currently
        * returns sequences with a dbref to the matched accession id 
        * which we don't want
        */
-      if (name.equals(seq.getName()) || seq.getName().startsWith(name2))
+      if (firstIdMatch == null
+              && (name.equals(seq.getName()) || seq.getName().startsWith(
+                      name2)))
       {
         if (sameSequence(seq, dss))
         {
-          return seq;
+          firstIdMatch = seq;
         }
       }
     }
-    return null;
+    return firstIdMatch;
   }
 
   /**
@@ -736,8 +865,8 @@ public class CrossRef
     MapList mapping = null;
     SequenceI dsmapFrom = mapFrom.getDatasetSequence() == null ? mapFrom
             : mapFrom.getDatasetSequence();
-    SequenceI dsmapTo = mapTo.getDatasetSequence() == null ? mapTo
-            : mapTo.getDatasetSequence();
+    SequenceI dsmapTo = mapTo.getDatasetSequence() == null ? mapTo : mapTo
+            .getDatasetSequence();
     /*
      * look for a reverse mapping, if found make its inverse. 
      * Note - we do this on dataset sequences only.
index 800cef2..799a8ed 100644 (file)
@@ -878,7 +878,8 @@ public class Dna
   public static char getComplement(char c)
   {
     char result = c;
-    switch (c) {
+    switch (c)
+    {
     case '-':
     case '.':
     case ' ':
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 96b45c1..e0e50fb 100644 (file)
@@ -878,8 +878,7 @@ public class NJTree
 
     if ((nd.left() == null) && (nd.right() == null))
     {
-      System.out
-              .println("Leaf = " + ((SequenceI) nd.element()).getName());
+      System.out.println("Leaf = " + ((SequenceI) nd.element()).getName());
       System.out.println("Dist " + nd.dist);
       System.out.println("Boot " + nd.getBootstrap());
     }
@@ -1108,8 +1107,7 @@ public class NJTree
     }
     else
     {
-      System.out.println(" name = "
-              + ((SequenceI) nd.element()).getName());
+      System.out.println(" name = " + ((SequenceI) nd.element()).getName());
     }
 
     System.out.println(" dist = " + nd.dist + " " + nd.count + " "
@@ -1303,8 +1301,8 @@ public class NJTree
   public void applyToNodes(NodeTransformI nodeTransformI)
   {
     for (Enumeration<SequenceNode> nodes = node.elements(); nodes
-            .hasMoreElements(); nodeTransformI
-            .transform(nodes.nextElement()))
+            .hasMoreElements(); nodeTransformI.transform(nodes
+            .nextElement()))
     {
       ;
     }
index 41324d9..89c5c30 100644 (file)
@@ -376,7 +376,7 @@ public class Rna
     {
       second -= 32;
     }
-  
+
     switch (first)
     {
     case 'A':
index b0ecfde..21ad1cc 100755 (executable)
@@ -63,14 +63,14 @@ public class SeqsetUtils
     {
       sqinfo.put("SeqFeatures", sfeat);
       sqinfo.put("PdbId",
-            (seq.getAllPDBEntries() != null) ? seq.getAllPDBEntries()
-                    : new Vector<PDBEntry>());
+              (seq.getAllPDBEntries() != null) ? seq.getAllPDBEntries()
+                      : new Vector<PDBEntry>());
     }
     else
     {
       sqinfo.put("datasetSequence",
-            (seq.getDatasetSequence() != null) ? seq.getDatasetSequence()
-                    : new Sequence("THISISAPLACEHOLDER", ""));
+              (seq.getDatasetSequence() != null) ? seq.getDatasetSequence()
+                      : new Sequence("THISISAPLACEHOLDER", ""));
     }
     return sqinfo;
   }
@@ -135,7 +135,7 @@ public class SeqsetUtils
             && !(seqds.getName().equals("THISISAPLACEHOLDER") && seqds
                     .getLength() == 0))
     {
-      if (sfeatures!=null)
+      if (sfeatures != null)
       {
         System.err
                 .println("Implementation error: setting dataset sequence for a sequence which has sequence features.\n\tDataset sequence features will not be visible.");
index ad3f8d9..7b0858d 100644 (file)
@@ -218,7 +218,7 @@ public class StructureFrequency
         if (canonicalOrWobblePairCount >= otherPairCount)
         {
           maxResidue = (canonicalOrWobblePairCount - canonical) < canonical ? "("
-                : "[";
+                  : "[";
         }
         else
         {
index 70ae61e..04c1fd9 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.api;
 
 import jalview.datamodel.SequenceGroup;
+import jalview.io.DataSourceType;
 
 import java.util.List;
 
@@ -90,13 +91,13 @@ 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);
 
   /**
@@ -107,4 +108,16 @@ public interface AlignViewControllerI
    */
   void showRandomColoursForGroups(List<SequenceGroup> gps);
 
+  /**
+   * 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 0840520..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
@@ -260,7 +262,7 @@ public interface AlignViewportI extends ViewStyleI
    * @return String[]
    */
   String[] getViewAsString(boolean selectedRegionOnly);
-  
+
   /**
    * This method returns the visible alignment as text, as seen on the GUI, ie
    * if columns are hidden they will not be returned in the result. Use this for
@@ -275,7 +277,8 @@ public interface AlignViewportI extends ViewStyleI
    * 
    * @return String[]
    */
-  String[] getViewAsString(boolean selectedRegionOnly, boolean isExportHiddenSeqs);
+  String[] getViewAsString(boolean selectedRegionOnly,
+          boolean isExportHiddenSeqs);
 
   void setSelectionGroup(SequenceGroup sg);
 
@@ -412,7 +415,6 @@ public interface AlignViewportI extends ViewStyleI
    */
   void setFollowHighlight(boolean b);
 
-
   public void applyFeaturesStyle(FeatureSettingsModelI featureSettings);
 
   /**
@@ -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 52ee381..51c35c5 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.api;
 
 import jalview.datamodel.Mapping;
index 1fcbfd0..01eb7fa 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.api;
 
 import jalview.datamodel.SequenceFeature;
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 8f8d8c1..dd8e721 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.api;
 
 /**
index dad434a..c795f3f 100644 (file)
@@ -47,7 +47,6 @@ public interface SiftsClientI
    */
   public String getDbCoordSys();
 
-
   /**
    * Get DB Source for the SIFTs Entry
    * 
@@ -117,7 +116,7 @@ public interface SiftsClientI
    */
   public StructureMapping getSiftsStructureMapping(SequenceI seq,
           String pdbFile, String chain) throws SiftsException;
-  
+
   /**
    * Get residue by residue mapping for a given Sequence and SIFTs entity
    * 
@@ -129,6 +128,5 @@ public interface SiftsClientI
    * @throws Exception
    */
   public HashMap<Integer, int[]> getGreedyMapping(String entityId,
-          SequenceI seq,
-          java.io.PrintStream os) throws SiftsException;
+          SequenceI seq, java.io.PrintStream os) throws SiftsException;
 }
\ No newline at end of file
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 e36944f..f830fe6 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;
@@ -102,7 +104,6 @@ import java.net.URLEncoder;
 import java.util.Arrays;
 import java.util.Deque;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
@@ -346,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);
   }
@@ -356,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;
@@ -373,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)
     {
@@ -926,11 +927,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     if (alignPanel.getAlignment().getAlignmentAnnotation() != null)
     {
       for (AlignmentAnnotation aa : alignPanel.getAlignment()
-            .getAlignmentAnnotation())
-    {
-      boolean visible = (aa.sequenceRef == null ? showForAlignment
-              : showForSequences);
-      aa.visible = visible;
+              .getAlignmentAnnotation())
+      {
+        boolean visible = (aa.sequenceRef == null ? showForAlignment
+                : showForSequences);
+        aa.visible = visible;
       }
     }
     alignPanel.validateAnnotationDimensions(true);
@@ -1357,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()));
   }
 
@@ -1415,9 +1416,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     FeaturesFile formatter = new FeaturesFile();
     if (format.equalsIgnoreCase("Jalview"))
     {
-      features = formatter.printJalviewFormat(viewport
-              .getAlignment().getSequencesArray(),
-              getDisplayedFeatureCols());
+      features = formatter.printJalviewFormat(viewport.getAlignment()
+              .getSequencesArray(), getDisplayedFeatureCols());
     }
     else
     {
@@ -3236,11 +3236,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()
       {
@@ -4018,19 +4016,15 @@ 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;
       }
       if (needtoadd)
       {
-        // make a note of the access mode and add
-        if (pdbentry.getProperty() == null)
-        {
-          pdbentry.setProperty(new Hashtable());
-        }
-        pdbentry.getProperty().put("protocol", protocol);
+        pdbentry.setProperty("protocol", protocol);
         toaddpdb.addPDBId(pdbentry);
         alignPanel.getStructureSelectionManager()
                 .registerPDBEntry(pdbentry);
@@ -4067,7 +4061,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);
@@ -4078,10 +4072,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().get("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: "
@@ -4104,12 +4104,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;
@@ -4128,7 +4127,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 5a9cd55..79d2f1f 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.appletgui;
 
+import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.SequenceGroup;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.ColourSchemeI;
@@ -96,7 +97,8 @@ public class AnnotationColourChooser extends Panel implements
     slider.addAdjustmentListener(this);
     slider.addMouseListener(this);
 
-    if (av.getAlignment().getAlignmentAnnotation() == null)
+    AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
+    if (anns == null)
     {
       return;
     }
@@ -117,11 +119,15 @@ public class AnnotationColourChooser extends Panel implements
       // seqAssociated.setState(acg.isSeqAssociated());
     }
 
-    Vector list = new Vector();
+    Vector<String> list = new Vector<String>();
     int index = 1;
-    for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
+    for (int i = 0; i < anns.length; i++)
     {
-      String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+      String label = anns[i].label;
+      if (anns[i].sequenceRef != null)
+      {
+        label = label + "_" + anns[i].sequenceRef.getName();
+      }
       if (!list.contains(label))
       {
         list.addElement(label);
@@ -309,6 +315,7 @@ public class AnnotationColourChooser extends Panel implements
 
   Checkbox thresholdIsMin = new Checkbox();
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     if (evt.getSource() == thresholdValue)
@@ -351,6 +358,7 @@ public class AnnotationColourChooser extends Panel implements
     }
   }
 
+  @Override
   public void itemStateChanged(ItemEvent evt)
   {
     if (evt.getSource() == currentColours)
@@ -368,6 +376,7 @@ public class AnnotationColourChooser extends Panel implements
     changeColour();
   }
 
+  @Override
   public void adjustmentValueChanged(AdjustmentEvent evt)
   {
     if (!adjusting)
@@ -552,23 +561,28 @@ public class AnnotationColourChooser extends Panel implements
 
   }
 
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
   }
 
+  @Override
   public void mousePressed(MouseEvent evt)
   {
   }
 
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
     ap.paintAlignment(true);
   }
 
+  @Override
   public void mouseEntered(MouseEvent evt)
   {
   }
 
+  @Override
   public void mouseExited(MouseEvent evt)
   {
   }
index e3def25..a8dff62 100644 (file)
@@ -135,17 +135,22 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     slider.addAdjustmentListener(this);
     slider.addMouseListener(this);
 
-    if (av.getAlignment().getAlignmentAnnotation() == null)
+    AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
+    if (anns == null)
     {
       return;
     }
     setOldColumnSelection(av.getColumnSelection());
     adjusting = true;
-    Vector list = new Vector();
+    Vector<String> list = new Vector<String>();
     int index = 1;
-    for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
+    for (int i = 0; i < anns.length; i++)
     {
-      String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+      String label = anns[i].label;
+      if (anns[i].sequenceRef != null)
+      {
+        label = label + "_" + anns[i].sequenceRef.getName();
+      }
       if (!list.contains(label))
       {
         list.addElement(label);
@@ -273,6 +278,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     this.validate();
   }
 
+  @Override
   @SuppressWarnings("unchecked")
   public void reset()
   {
@@ -302,6 +308,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
 
   }
 
+  @Override
   public void adjustmentValueChanged(AdjustmentEvent evt)
   {
     if (!adjusting)
@@ -343,6 +350,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     });
   }
 
+  @Override
   public void valueChanged(boolean updateAllAnnotation)
   {
     if (slider.isEnabled())
@@ -866,6 +874,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     }
   }
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     if (evt.getSource() == thresholdValue)
index fc49de5..8d67d71 100644 (file)
@@ -85,45 +85,6 @@ public abstract class AnnotationRowFilter extends Panel
 
   }
 
-  public Vector getAnnotationItems(boolean isSeqAssociated)
-  {
-    Vector list = new Vector();
-    int index = 1;
-    int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length];
-    for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
-    {
-      if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null)
-      {
-        if (isSeqAssociated)
-        {
-          continue;
-        }
-      }
-      else
-      {
-        enableSeqAss = true;
-      }
-      String label = av.getAlignment().getAlignmentAnnotation()[i].label;
-      if (!list.contains(label))
-      {
-        anmap[list.size()] = i;
-        list.add(label);
-
-      }
-      else
-      {
-        if (!isSeqAssociated)
-        {
-          anmap[list.size()] = i;
-          list.add(label + "_" + (index++));
-        }
-      }
-    }
-    this.annmap = new int[list.size()];
-    System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length);
-    return list;
-  }
-
   protected int getSelectedThresholdItem(int indexValue)
   {
     int selectedThresholdItem = -1;
index 8374721..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;
@@ -60,7 +61,6 @@ import java.awt.event.KeyListener;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.util.ArrayList;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Vector;
 
@@ -176,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()));
@@ -196,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,22 +290,19 @@ public class AppletJmol extends EmbmenuFrame implements
         closeViewer();
       }
     });
-    if (pdbentry.getProperty() == null)
-    {
-      pdbentry.setProperty(new Hashtable());
-      pdbentry.getProperty().put("protocol", protocol);
-    }
+    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());
       }
@@ -373,7 +370,7 @@ public class AppletJmol extends EmbmenuFrame implements
     jmb.loadInline(string);
   }
 
-  void setChainMenuItems(Vector<String> chains)
+  void setChainMenuItems(List<String> chains)
   {
     chainMenu.removeAll();
 
@@ -592,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 9733c86..2c454a4 100755 (executable)
@@ -185,8 +185,7 @@ public class FeatureSettings extends Panel implements ItemListener,
   }
 
   protected void popupSort(final MyCheckbox check,
-          final Map<String, float[][]> minmax,
-          int x, int y)
+          final Map<String, float[][]> minmax, int x, int y)
   {
     final String type = check.type;
     final FeatureColourI typeCol = fr.getFeatureStyle(type);
@@ -804,11 +803,10 @@ public class FeatureSettings extends Panel implements ItemListener,
    * @param type
    * @param columnsContaining
    */
-  void hideFeatureColumns(final String type,
-          boolean columnsContaining)
+  void hideFeatureColumns(final String type, boolean columnsContaining)
   {
-    if (ap.alignFrame.avc.markColumnsContainingFeatures(
-            columnsContaining, false, false, type))
+    if (ap.alignFrame.avc.markColumnsContainingFeatures(columnsContaining,
+            false, false, type))
     {
       if (ap.alignFrame.avc.markColumnsContainingFeatures(
               !columnsContaining, false, false, type))
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 36c2199..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());
@@ -352,8 +359,7 @@ public class IdPanel extends Panel implements MouseListener,
 
     if ((av.getSelectionGroup() == null)
             || ((!jalview.util.Platform.isControlDown(e) && !e
-                    .isShiftDown()) && av
-                    .getSelectionGroup() != null))
+                    .isShiftDown()) && av.getSelectionGroup() != null))
     {
       av.setSelectionGroup(new SequenceGroup());
       av.getSelectionGroup().setStartRes(0);
index d2c1693..5a156fa 100755 (executable)
@@ -152,8 +152,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     PopupMenu pop = new PopupMenu();
     if (reveal != null)
     {
-      MenuItem item = new MenuItem(
-              MessageManager.getString("label.reveal"));
+      MenuItem item = new MenuItem(MessageManager.getString("label.reveal"));
       item.addActionListener(new ActionListener()
       {
         @Override
@@ -205,8 +204,8 @@ public class ScalePanel extends Panel implements MouseMotionListener,
         {
           av.hideColumns(res, res);
           if (av.getSelectionGroup() != null
-                  && av.getSelectionGroup().getSize() == av
-                          .getAlignment().getHeight())
+                  && av.getSelectionGroup().getSize() == av.getAlignment()
+                          .getHeight())
           {
             av.setSelectionGroup(null);
           }
@@ -495,8 +494,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
           gg.fillPolygon(new int[] {
               -1 + res * avCharWidth - avcharHeight / 4,
               -1 + res * avCharWidth + avcharHeight / 4,
-              -1 + res * avCharWidth },
-                  new int[] { y, y, y + 2 * yOf }, 3);
+              -1 + res * avCharWidth }, new int[] { y, y, y + 2 * yOf }, 3);
         }
       }
     }
index 22849f1..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;
@@ -113,8 +111,7 @@ public class SeqCanvas extends Panel
         }
         g.drawLine((mpos * avcharWidth) + (avcharWidth / 2), (ypos + 2)
                 - (avcharHeight / 2), (mpos * avcharWidth)
-                + (avcharWidth / 2),
-                ypos - 2);
+                + (avcharWidth / 2), ypos - 2);
       }
     }
   }
@@ -633,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)
         {
@@ -844,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 a437960..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())
     {
@@ -1552,7 +1553,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     }
     PaintRefresher.Refresh(ap, av.getSequenceSetId());
     ap.paintAlignment(needOverviewUpdate);
-    needOverviewUpdate =false;
+    needOverviewUpdate = false;
     changeEndRes = false;
     changeStartRes = false;
     stretchGroup = null;
index 2c53c08..35c2a22 100644 (file)
@@ -131,8 +131,9 @@ public class SliderPanel extends Panel implements ActionListener,
       pid = (SliderPanel) PIDSlider.getComponent(0);
       pid.cs = cs;
     }
-    PIDSlider.setTitle(MessageManager
-            .formatMessage("label.percentage_identity_threshold",
+    PIDSlider
+            .setTitle(MessageManager.formatMessage(
+                    "label.percentage_identity_threshold",
                     new String[] { source }));
 
     if (ap.av.getAlignment().getGroups() != null)
index 47c2d28..8292a5a 100755 (executable)
@@ -528,8 +528,7 @@ public class TreeCanvas extends Panel implements MouseListener,
 
         for (int i = 0; i < leaves.size(); i++)
         {
-          SequenceI seq = (SequenceI) leaves.elementAt(i)
-                  .element();
+          SequenceI seq = (SequenceI) leaves.elementAt(i).element();
           treeSelectionChanged(seq);
         }
       }
@@ -628,14 +627,13 @@ public class TreeCanvas extends Panel implements MouseListener,
               (int) (Math.random() * 255), (int) (Math.random() * 255));
       setColor(tree.getGroups().elementAt(i), col.brighter());
 
-      Vector<SequenceNode> l = tree.findLeaves(tree
-              .getGroups().elementAt(i));
+      Vector<SequenceNode> l = tree.findLeaves(tree.getGroups()
+              .elementAt(i));
 
       Vector<SequenceI> sequences = new Vector<SequenceI>();
       for (int j = 0; j < l.size(); j++)
       {
-        SequenceI s1 = (SequenceI) l.elementAt(j)
-                .element();
+        SequenceI s1 = (SequenceI) l.elementAt(j).element();
         if (!sequences.contains(s1))
         {
           sequences.addElement(s1);
@@ -678,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 9c8d0df..c927f1f 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.bin;
 
 import java.net.URLDecoder;
@@ -94,4 +114,4 @@ public class ArgsParser
     return vargs.size();
   }
 
-}
\ No newline at end of file
+}
index 00c8b86..8412dab 100755 (executable)
@@ -228,7 +228,7 @@ public class Cache
   private final static String DEFAULT_CACHE_THRESHOLD_IN_DAYS = "2";
 
   private final static String DEFAULT_FAIL_SAFE_PID_THRESHOLD = "30";
-  
+
   /**
    * Allowed values are PDB or mmCIF
    */
@@ -895,7 +895,7 @@ public class Cache
   {
     setProperty(property, jalview.util.Format.getHexString(colour));
   }
-  
+
   /**
    * Stores a formatted date in a jalview property, using a fixed locale.
    * 
index 3294c26..39c0a5b 100755 (executable)
@@ -23,16 +23,21 @@ package jalview.bin;
 import groovy.lang.Binding;
 import groovy.util.GroovyScriptEngine;
 
+import jalview.ext.so.SequenceOntology;
 import jalview.gui.AlignFrame;
 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;
+import jalview.io.gff.SequenceOntologyFactory;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
 import jalview.schemes.UserColourScheme;
@@ -49,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;
@@ -288,6 +294,15 @@ public class Jalview
       }
     }
 
+    /*
+     * configure 'full' SO model if preferences say to, 
+     * else use the default (SO Lite)
+     */
+    if (Cache.getDefault("USE_FULL_SO", false))
+    {
+      SequenceOntologyFactory.setInstance(new SequenceOntology());
+    }
+
     if (!headless)
     {
       desktop = new Desktop();
@@ -344,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
@@ -377,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));
           }
@@ -472,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);
@@ -617,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();
@@ -635,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: "
@@ -698,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,
@@ -778,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 b30ad41..9fd8a90 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 dc6c424..655657e 100644 (file)
@@ -68,7 +68,6 @@ public class TrimRegionCommand extends EditCommand
       setEdit(new Edit(Action.CUT, seqs, column + 1, width, al));
     }
 
-
     performEdit(0, null);
   }
 
index 7378529..e71ccfb 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;
 
@@ -251,10 +252,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)
@@ -272,29 +269,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
               }
             }
           }
@@ -357,7 +379,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;
@@ -389,4 +411,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 326cc4e..4fbfd62 100644 (file)
@@ -93,8 +93,8 @@ public class AlignedCodonFrame
       return (this.fromSeq == that.fromSeq || (this.fromSeq != null
               && that.fromSeq != null
               && this.fromSeq.getDatasetSequence() != null && this.fromSeq
-              .getDatasetSequence() == that.fromSeq
-              .getDatasetSequence())) && this.mapping.equals(that.mapping);
+              .getDatasetSequence() == that.fromSeq.getDatasetSequence()))
+              && this.mapping.equals(that.mapping);
     }
 
     public SequenceI getFromSeq()
@@ -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();
@@ -719,8 +719,8 @@ public class AlignedCodonFrame
   }
 
   /**
-   * Returns the first mapping found that is between 'fromSeq' and 'toSeq', or null
-   * if none found
+   * Returns the first mapping found that is between 'fromSeq' and 'toSeq', or
+   * null if none found
    * 
    * @param fromSeq
    *          aligned or dataset sequence
index 35ee8c4..d651c1d 100755 (executable)
@@ -24,6 +24,7 @@ import jalview.analysis.AlignmentUtils;
 import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
 import jalview.io.FastaFile;
 import jalview.util.Comparison;
+import jalview.util.LinkedIdentityHashSet;
 import jalview.util.MessageManager;
 
 import java.util.ArrayList;
@@ -660,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;
 
@@ -1054,6 +1055,7 @@ public class Alignment implements AlignmentI
   private void resolveAndAddDatasetSeq(SequenceI currentSeq,
           Set<SequenceI> seqs, boolean createDatasetSequence)
   {
+    SequenceI alignedSeq = currentSeq;
     if (currentSeq.getDatasetSequence() != null)
     {
       currentSeq = currentSeq.getDatasetSequence();
@@ -1088,12 +1090,19 @@ public class Alignment implements AlignmentI
         {
           if (dbr.getMap() != null && dbr.getMap().getTo() != null)
           {
+            if (dbr.getMap().getTo() == alignedSeq)
+            {
+              /*
+               * update mapping to be to the newly created dataset sequence
+               */
+              dbr.getMap().setTo(currentSeq);
+            }
             if (dbr.getMap().getTo().getDatasetSequence() != null)
             {
-              throw new Error("Implementation error: Map.getTo() for dbref"
-                      + dbr + " is not a dataset sequence.");
-              // TODO: if this happens, could also rewrite the reference to
-              // point to new dataset sequence
+              throw new Error(
+                      "Implementation error: Map.getTo() for dbref " + dbr
+                              + " from " + curDs.getName()
+                              + " is not a dataset sequence.");
             }
             // we recurse to add all forward references to dataset sequences via
             // DBRefs/etc
@@ -1115,7 +1124,7 @@ public class Alignment implements AlignmentI
       return;
     }
     // try to avoid using SequenceI.equals at this stage, it will be expensive
-    Set<SequenceI> seqs = new jalview.util.LinkedIdentityHashSet<SequenceI>();
+    Set<SequenceI> seqs = new LinkedIdentityHashSet<SequenceI>();
 
     for (int i = 0; i < getHeight(); i++)
     {
@@ -1828,7 +1837,7 @@ public class Alignment implements AlignmentI
   @Override
   public String toString()
   {
-    return new FastaFile().print(getSequencesArray());
+    return new FastaFile().print(getSequencesArray(), true);
   }
 
   /**
index 2a89fa1..05688cb 100755 (executable)
@@ -1307,8 +1307,7 @@ public class AlignmentAnnotation
    *       already
    */
   public void remap(SequenceI newref, HashMap<Integer, int[]> mapping,
-          int from, int to,
-          int idxoffset)
+          int from, int to, int idxoffset)
   {
     if (mapping != null)
     {
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 8bc8f54..d651c0b 100644 (file)
@@ -1148,9 +1148,9 @@ public class ColumnSelection
    */
   public int[] locateVisibleBoundsOfSequence(SequenceI seq)
   {
-    int fpos=seq.getStart(),lpos= seq.getEnd();
+    int fpos = seq.getStart(), lpos = seq.getEnd();
     int start = 0;
-    
+
     if (hiddenColumns == null || hiddenColumns.size() == 0)
     {
       int ifpos = seq.findIndex(fpos) - 1, ilpos = seq.findIndex(lpos) - 1;
index 8ca3c5a..9e2cf72 100755 (executable)
@@ -296,6 +296,7 @@ public class HiddenSequences
    * makes a copy of the alignment with hidden sequences included. Using the
    * copy for anything other than simple output is not recommended. Note - this
    * method DOES NOT USE THE AlignmentI COPY CONSTRUCTOR!
+   * 
    * @return
    */
   public AlignmentI getFullAlignment()
index c0c69aa..551e5d8 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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;
 
 /**
index 1403595..8debacf 100755 (executable)
@@ -22,10 +22,20 @@ package jalview.datamodel;
 
 import jalview.util.CaseInsensitiveString;
 
+import java.util.Collections;
+import java.util.Enumeration;
 import java.util.Hashtable;
 
 public class PDBEntry
 {
+
+  /**
+   * constant for storing chain code in properties table
+   */
+  private static final String CHAIN_ID = "chain_code";
+
+  private Hashtable<String, Object> properties;
+
   private static final int PDB_ID_LENGTH = 4;
 
   private String file;
@@ -36,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
      * 
@@ -68,13 +109,6 @@ public class PDBEntry
   }
 
   /**
-   * constant for storing chain code in properties table
-   */
-  private static final String CHAIN_ID = "chain_code";
-
-  Hashtable properties;
-
-  /**
    * Answers true if obj is a PDBEntry with the same id and chain code (both
    * ignoring case), file, type and properties
    */
@@ -117,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)
@@ -137,13 +161,13 @@ public class PDBEntry
   /**
    * @param pdbId
    * @param chain
-   * @param type
+   * @param entryType
    * @param filePath
    */
-  void init(String pdbId, String chain, PDBEntry.Type type, String filePath)
+  void init(String pdbId, String chain, PDBEntry.Type entryType, String filePath)
   {
     this.id = pdbId;
-    this.type = type == null ? null : type.toString();
+    this.type = entryType == null ? null : entryType.toString();
     this.file = filePath;
     setChainCode(chain);
   }
@@ -160,7 +184,7 @@ public class PDBEntry
     id = entry.id;
     if (entry.properties != null)
     {
-      properties = (Hashtable) entry.properties.clone();
+      properties = (Hashtable<String, Object>) entry.properties.clone();
     }
   }
 
@@ -193,9 +217,9 @@ public class PDBEntry
     init(pdbId, chainCode, null, null);
   }
 
-  public void setFile(String file)
+  public void setFile(String f)
   {
-    this.file = file;
+    this.file = f;
   }
 
   public String getFile()
@@ -228,14 +252,33 @@ public class PDBEntry
     return id;
   }
 
-  public void setProperty(Hashtable property)
+  public void setProperty(String key, Object value)
   {
-    this.properties = property;
+    if (this.properties == null)
+    {
+      this.properties = new Hashtable<String, Object>();
+    }
+    properties.put(key, value);
   }
 
-  public Hashtable getProperty()
+  public Object getProperty(String key)
   {
-    return properties;
+    return properties == null ? null : properties.get(key);
+  }
+
+  /**
+   * Returns an enumeration of the keys of this object's properties (or an empty
+   * enumeration if it has no properties)
+   * 
+   * @return
+   */
+  public Enumeration<String> getProperties()
+  {
+    if (properties == null)
+    {
+      return Collections.emptyEnumeration();
+    }
+    return properties.keys();
   }
 
   /**
@@ -248,24 +291,37 @@ public class PDBEntry
             : properties.get(CHAIN_ID).toString();
   }
 
+  /**
+   * Sets a non-case-sensitive property for the given chain code. Two PDBEntry
+   * objects which differ only in the case of their chain code are considered
+   * equal. This avoids duplication of objects in lists of PDB ids.
+   * 
+   * @param chainCode
+   */
   public void setChainCode(String chainCode)
   {
-    if (properties == null)
+    if (chainCode == null)
     {
-      if (chainCode == null)
-      {
-        // nothing to do.
-        return;
-      }
-      properties = new Hashtable();
+      deleteProperty(CHAIN_ID);
     }
-    if (chainCode == null)
+    else
+    {
+      setProperty(CHAIN_ID, new CaseInsensitiveString(chainCode));
+    }
+  }
+
+  /**
+   * Deletes the property with the given key, and returns the deleted value (or
+   * null)
+   */
+  Object deleteProperty(String key)
+  {
+    Object result = null;
+    if (properties != null)
     {
-      properties.remove(CHAIN_ID);
-      return;
+      result = properties.remove(key);
     }
-    // update property for non-null chainCode
-    properties.put(CHAIN_ID, new CaseInsensitiveString(chainCode));
+    return result;
   }
 
   @Override
@@ -275,6 +331,35 @@ public class PDBEntry
   }
 
   /**
+   * Getter provided for Castor binding only. Application code should call
+   * getProperty() or getProperties() instead.
+   * 
+   * @deprecated
+   * @see #getProperty(String)
+   * @see #getProperties()
+   * @see jalview.ws.dbsources.Uniprot#getUniprotEntries
+   * @return
+   */
+  @Deprecated
+  public Hashtable<String, Object> getProps()
+  {
+    return properties;
+  }
+
+  /**
+   * Setter provided for Castor binding only. Application code should call
+   * setProperty() instead.
+   * 
+   * @deprecated
+   * @return
+   */
+  @Deprecated
+  public void setProps(Hashtable<String, Object> props)
+  {
+    properties = props;
+  }
+
+  /**
    * Answers true if this object is either equivalent to, or can be 'improved'
    * by, the given entry.
    * <p>
@@ -285,7 +370,7 @@ public class PDBEntry
    * @param newEntry
    * @return true if modifications were made
    */
-  protected boolean updateFrom(PDBEntry newEntry)
+  public boolean updateFrom(PDBEntry newEntry)
   {
     if (this.equals(newEntry))
     {
@@ -299,7 +384,7 @@ public class PDBEntry
     }
 
     /*
-     * id (less any chain code) has to match (ignoring case)
+     * id has to match (ignoring case)
      */
     if (!getId().equalsIgnoreCase(newId))
     {
@@ -356,26 +441,20 @@ public class PDBEntry
     }
 
     /*
-     * copy any new properties; notice this may include chain_code,
-     * but we excluded differing chain codes earlier
+     * copy any new or modified properties
      */
-    if (newEntry.getProperty() != null)
+    Enumeration<String> newProps = newEntry.getProperties();
+    while (newProps.hasMoreElements())
     {
-      if (properties == null)
+      /*
+       * copy properties unless value matches; this defends against changing
+       * the case of chain_code which is wrapped in a CaseInsensitiveString
+       */
+      String key = newProps.nextElement();
+      Object value = newEntry.getProperty(key);
+      if (!value.equals(getProperty(key)))
       {
-        properties = new Hashtable();
-      }
-      for (Object p : newEntry.getProperty().keySet())
-      {
-        /*
-         * copy properties unless value matches; this defends against changing
-         * the case of chain_code which is wrapped in a CaseInsensitiveString
-         */
-        Object value = newEntry.getProperty().get(p);
-        if (!value.equals(properties.get(p)))
-        {
-          properties.put(p, newEntry.getProperty().get(p));
-        }
+        setProperty(key, value);
       }
     }
     return true;
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 44522a8..c8b94ce 100755 (executable)
@@ -22,6 +22,7 @@ package jalview.datamodel;
 
 import jalview.analysis.AlignSeq;
 import jalview.api.DBRefEntryI;
+import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.MapList;
 import jalview.util.StringUtils;
@@ -232,8 +233,7 @@ public class Sequence extends ASequence implements SequenceI
     {
       char[] oseq = seq.getSequence();
       initSeqAndName(seq.getName(), Arrays.copyOf(oseq, oseq.length),
-              seq.getStart(),
-            seq.getEnd());
+              seq.getStart(), seq.getEnd());
     }
     description = seq.getDescription();
     if (seq != datasetSequence)
@@ -292,7 +292,6 @@ public class Sequence extends ASequence implements SequenceI
     }
   }
 
-
   @Override
   public void setSequenceFeatures(SequenceFeature[] features)
   {
@@ -317,7 +316,7 @@ public class Sequence extends ASequence implements SequenceI
   @Override
   public synchronized void addSequenceFeature(SequenceFeature sf)
   {
-    if (sequenceFeatures==null && datasetSequence != null)
+    if (sequenceFeatures == null && datasetSequence != null)
     {
       datasetSequence.addSequenceFeature(sf);
       return;
@@ -347,8 +346,9 @@ public class Sequence extends ASequence implements SequenceI
   {
     if (sequenceFeatures == null)
     {
-      if (datasetSequence!=null) {
-         datasetSequence.deleteFeature(sf);
+      if (datasetSequence != null)
+      {
+        datasetSequence.deleteFeature(sf);
       }
       return;
     }
@@ -944,7 +944,17 @@ public class Sequence extends ASequence implements SequenceI
   @Override
   public void setDBRefs(DBRefEntry[] dbref)
   {
+    if (dbrefs == null && datasetSequence != null
+            && this != datasetSequence)
+    {
+      datasetSequence.setDBRefs(dbref);
+      return;
+    }
     dbrefs = dbref;
+    if (dbrefs != null)
+    {
+      DBRefUtils.ensurePrimaries(this);
+    }
   }
 
   @Override
@@ -961,7 +971,12 @@ public class Sequence extends ASequence implements SequenceI
   @Override
   public void addDBRef(DBRefEntry entry)
   {
-    // TODO add to dataset sequence instead if there is one?
+    if (datasetSequence != null)
+    {
+      datasetSequence.addDBRef(entry);
+      return;
+    }
+
     if (dbrefs == null)
     {
       dbrefs = new DBRefEntry[0];
@@ -989,12 +1004,23 @@ public class Sequence extends ASequence implements SequenceI
     temp[temp.length - 1] = entry;
 
     dbrefs = temp;
+
+    DBRefUtils.ensurePrimaries(this);
   }
 
   @Override
   public void setDatasetSequence(SequenceI seq)
   {
-    // TODO check for circular reference before setting?
+    if (seq == this)
+    {
+      throw new IllegalArgumentException(
+              "Implementation Error: self reference passed to SequenceI.setDatasetSequence");
+    }
+    if (seq != null && seq.getDatasetSequence() != null)
+    {
+      throw new IllegalArgumentException(
+              "Implementation error: cascading dataset sequences are not allowed.");
+    }
     datasetSequence = seq;
   }
 
@@ -1067,7 +1093,7 @@ public class Sequence extends ASequence implements SequenceI
   @Override
   public SequenceI deriveSequence()
   {
-    Sequence seq=null;
+    Sequence seq = null;
     if (datasetSequence == null)
     {
       if (isValidDatasetSequence())
@@ -1081,7 +1107,7 @@ public class Sequence extends ASequence implements SequenceI
       else
       {
         // Create a new, valid dataset sequence
-       createDatasetSequence();
+        createDatasetSequence();
       }
     }
     return new Sequence(this);
@@ -1091,6 +1117,10 @@ public class Sequence extends ASequence implements SequenceI
 
   private long _seqhash = 0;
 
+  /**
+   * Answers false if the sequence is more than 85% nucleotide (ACGTU), else
+   * true
+   */
   @Override
   public boolean isProtein()
   {
@@ -1101,7 +1131,7 @@ public class Sequence extends ASequence implements SequenceI
     if (_seqhash != sequence.hashCode())
     {
       _seqhash = sequence.hashCode();
-      _isNa=jalview.util.Comparison.isNucleotide(new SequenceI[] { this });
+      _isNa = Comparison.isNucleotide(this);
     }
     return !_isNa;
   };
@@ -1125,9 +1155,9 @@ public class Sequence extends ASequence implements SequenceI
       dsseq.setDescription(description);
       // move features and database references onto dataset sequence
       dsseq.sequenceFeatures = sequenceFeatures;
-      sequenceFeatures=null;
+      sequenceFeatures = null;
       dsseq.dbrefs = dbrefs;
-      dbrefs=null;
+      dbrefs = null;
       // TODO: search and replace any references to this sequence with
       // references to the dataset sequence in Mappings on dbref
       dsseq.pdbIds = pdbIds;
@@ -1385,15 +1415,14 @@ public class Sequence extends ASequence implements SequenceI
     return null;
   }
 
-
   @Override
   public List<DBRefEntry> getPrimaryDBRefs()
   {
-    if (datasetSequence!=null)
+    if (datasetSequence != null)
     {
       return datasetSequence.getPrimaryDBRefs();
     }
-    if (dbrefs==null || dbrefs.length==0)
+    if (dbrefs == null || dbrefs.length == 0)
     {
       return Collections.emptyList();
     }
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)
     {
index b7a291e..aec68ab 100755 (executable)
@@ -217,8 +217,11 @@ public interface SequenceI extends ASequenceI
   public int[] findPositionMap();
 
   /**
+   * Answers true if the sequence is composed of amino acid characters. Note
+   * that implementations may use heuristic methods which are not guaranteed to
+   * give the biologically 'right' answer.
    * 
-   * @return true if sequence is composed of amino acid characters
+   * @return
    */
   public boolean isProtein();
 
@@ -314,6 +317,14 @@ public interface SequenceI extends ASequenceI
 
   public void setVamsasId(String id);
 
+  /**
+   * set the array of Database references for the sequence.
+   * 
+   * @param dbs
+   * @deprecated - use is discouraged since side-effects may occur if DBRefEntry
+   *             set are not normalised.
+   */
+  @Deprecated
   public void setDBRefs(DBRefEntry[] dbs);
 
   public DBRefEntry[] getDBRefs();
@@ -448,7 +459,6 @@ public interface SequenceI extends ASequenceI
    */
   public PDBEntry getPDBEntry(String pdbId);
 
-
   /**
    * Get all primary database/accessions for this sequence's data. These
    * DBRefEntry are expected to resolve to a valid record in the associated
index 3ba36ca..4d09bdc 100644 (file)
@@ -48,8 +48,7 @@ import java.util.regex.Pattern;
  * Data model for one entry returned from an EMBL query, as marshalled by a
  * Castor binding file
  * 
- * For example:
- * http://www.ebi.ac.uk/ena/data/view/J03321&display=xml
+ * For example: http://www.ebi.ac.uk/ena/data/view/J03321&display=xml
  * 
  * @see embl_mapping.xml
  */
@@ -200,7 +199,6 @@ public class EmblEntry
     retrievedref.setMap(new Mapping(null, new int[] { 1, dna.getLength() },
             new int[] { 1, dna.getLength() }, 1, 1));
 
-
     /*
      * transform EMBL Database refs to canonical form
      */
@@ -298,7 +296,8 @@ public class EmblEntry
         if (qname.equals("translation"))
         {
           // remove all spaces (precompiled String.replaceAll(" ", ""))
-          translation = SPACE_PATTERN.matcher(q.getValues()[0]).replaceAll("");
+          translation = SPACE_PATTERN.matcher(q.getValues()[0]).replaceAll(
+                  "");
         }
         else if (qname.equals("protein_id"))
         {
@@ -469,13 +468,14 @@ public class EmblEntry
          */
         String source = DBRefUtils.getCanonicalName(ref.getSource());
         ref.setSource(source);
-        DBRefEntry proteinDbRef = new DBRefEntry(ref.getSource(), ref.getVersion(), ref
-                .getAccessionId());
+        DBRefEntry proteinDbRef = new DBRefEntry(ref.getSource(),
+                ref.getVersion(), ref.getAccessionId());
         if (source.equals(DBRefSource.UNIPROT))
         {
           String proteinSeqName = DBRefSource.UNIPROT + "|"
                   + ref.getAccessionId();
-          if (dnaToProteinMapping != null && dnaToProteinMapping.getTo() != null)
+          if (dnaToProteinMapping != null
+                  && dnaToProteinMapping.getTo() != null)
           {
             if (mappingUsed)
             {
index 69870b6..1dd854a 100644 (file)
@@ -46,6 +46,8 @@ public class EmblFile
 
   Vector<EmblError> errors;
 
+  String text;
+
   /**
    * @return the entries
    */
@@ -152,6 +154,10 @@ public class EmblFile
    */
   static void canonicaliseDbRefs(EmblFile record)
   {
+    if (record.getEntries() == null)
+    {
+      return;
+    }
     for (EmblEntry entry : record.getEntries())
     {
       if (entry.getDbRefs() != null)
@@ -183,4 +189,14 @@ public class EmblFile
       }
     }
   }
+
+  public String getText()
+  {
+    return text;
+  }
+
+  public void setText(String text)
+  {
+    this.text = text;
+  }
 }
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 e141db4..dc000c6 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.SequenceFeature;
@@ -23,7 +43,7 @@ public class EnsemblCdna extends EnsemblSeqProxy
    */
   private static final Regex ACCESSION_REGEX = new Regex(
           "(ENS([A-Z]{3}|)[TG][0-9]{11}$)" + "|" + "(CCDS[0-9.]{3,}$)");
-  
+
   /*
    * fetch exon features on genomic sequence (to identify the cdna regions)
    * and cds and variation features (to retain)
index 2086eba..8b2550d 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.SequenceFeature;
index 0547433..b28a37f 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.Alignment;
@@ -79,8 +99,7 @@ class EnsemblFeatures extends EnsemblRestClient
   protected URL getUrl(List<String> ids) throws MalformedURLException
   {
     StringBuffer urlstring = new StringBuffer(128);
-    urlstring.append(getDomain()).append("/overlap/id/")
-            .append(ids.get(0));
+    urlstring.append(getDomain()).append("/overlap/id/").append(ids.get(0));
 
     // @see https://github.com/Ensembl/ensembl-rest/wiki/Output-formats
     urlstring.append("?content-type=text/x-gff3");
index 0c20e12..24e3e95 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.api.FeatureColourI;
@@ -262,8 +282,7 @@ public class EnsemblGene extends EnsemblSeqProxy
         }
       }
       gene.setSequenceFeatures(filtered
-              .toArray(new SequenceFeature[filtered
-              .size()]));
+              .toArray(new SequenceFeature[filtered.size()]));
     }
   }
 
@@ -529,6 +548,7 @@ public class EnsemblGene extends EnsemblSeqProxy
     return new FeatureSettingsAdapter()
     {
       SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+
       @Override
       public boolean isFeatureDisplayed(String type)
       {
index 20987e1..458a233 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.SequenceFeature;
index 9ba2e1c..ef46a5b 100644 (file)
@@ -1,6 +1,25 @@
+/*
+ * 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.ensembl;
 
-
 /**
  * A class to behave much like EnsemblGene but referencing the ensemblgenomes
  * domain and data
index 88b5ac4..3108194 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 /**
index c5945ae..eb8f90e 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.AlignmentI;
@@ -105,7 +125,7 @@ public class EnsemblLookup extends EnsemblRestClient
   public String getParent(String identifier)
   {
     List<String> ids = Arrays.asList(new String[] { identifier });
-  
+
     BufferedReader br = null;
     try
     {
index 0facbb5..1554a0b 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.AlignmentI;
index 72efdc1..8ee6aaf 100644 (file)
@@ -1,5 +1,26 @@
+/*
+ * 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.ensembl;
 
+import jalview.io.DataSourceType;
 import jalview.io.FileParse;
 import jalview.util.StringUtils;
 
@@ -30,14 +51,19 @@ import com.stevesoft.pat.Regex;
  */
 abstract class EnsemblRestClient extends EnsemblSequenceFetcher
 {
+  private static final int DEFAULT_READ_TIMEOUT = 5 * 60 * 1000; // 5 minutes
+
+  private static final int CONNECT_TIMEOUT_MS = 10 * 1000; // 10 seconds
+
   /*
    * update these constants when Jalview has been checked / updated for
    * changes to Ensembl REST API
    * @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_ENSEMBL_REST_VERSION = "4.6";
+  private static final String LATEST_ENSEMBL_REST_VERSION = "4.7";
 
   private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log";
 
@@ -51,10 +77,10 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
   private final static long VERSION_RETEST_INTERVAL = 1000L * 3600; // 1 hr
 
   private static final Regex TRANSCRIPT_REGEX = new Regex(
-            "(ENS)([A-Z]{3}|)T[0-9]{11}$");
+          "(ENS)([A-Z]{3}|)T[0-9]{11}$");
 
   private static final Regex GENE_REGEX = new Regex(
-            "(ENS)([A-Z]{3}|)G[0-9]{11}$");
+          "(ENS)([A-Z]{3}|)G[0-9]{11}$");
 
   static
   {
@@ -165,7 +191,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
    */
   private boolean checkEnsembl()
   {
-    HttpURLConnection conn = null;
+    BufferedReader br = null;
     try
     {
       // note this format works for both ensembl and ensemblgenomes
@@ -175,8 +201,9 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
 
       /*
        * expect {"ping":1} if ok
+       * if ping takes more than 2 seconds to respond, treat as if unavailable
        */
-      BufferedReader br = getHttpResponse(ping, null);
+      br = getHttpResponse(ping, null, 2 * 1000);
       JSONParser jp = new JSONParser();
       JSONObject val = (JSONObject) jp.parse(br);
       String pingString = val.get("ping").toString();
@@ -187,9 +214,15 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
               + t.getMessage());
     } finally
     {
-      if (conn != null)
+      if (br != null)
       {
-        conn.disconnect();
+        try
+        {
+          br.close();
+        } catch (IOException e)
+        {
+          // ignore
+        }
       }
     }
     return false;
@@ -206,28 +239,50 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
           throws IOException
   {
     URL url = getUrl(ids);
-  
+
     BufferedReader reader = getHttpResponse(url, ids);
-    FileParse fp = new FileParse(reader, url.toString(), "HTTP_POST");
+    if (reader == null)
+    {
+      // request failed
+      return null;
+    }
+    FileParse fp = new FileParse(reader, url.toString(), DataSourceType.URL);
     return fp;
   }
 
   /**
+   * Gets a reader to the HTTP response, using the default read timeout of 5
+   * minutes
+   * 
+   * @param url
+   * @param ids
+   * @return
+   * @throws IOException
+   */
+  protected BufferedReader getHttpResponse(URL url, List<String> ids)
+          throws IOException
+  {
+    return getHttpResponse(url, ids, DEFAULT_READ_TIMEOUT);
+  }
+
+  /**
    * Writes the HTTP request and gets the response as a reader.
    * 
    * @param url
    * @param ids
    *          written as Json POST body if more than one
+   * @param readTimeout
+   *          in milliseconds
    * @return
    * @throws IOException
    *           if response code was not 200, or other I/O error
    */
-  protected BufferedReader getHttpResponse(URL url, List<String> ids)
-          throws IOException
+  protected BufferedReader getHttpResponse(URL url, List<String> ids,
+          int readTimeout) throws IOException
   {
     // long now = System.currentTimeMillis();
     HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-  
+
     /*
      * POST method allows multiple queries in one request; it is supported for
      * sequence queries, but not for overlap
@@ -243,29 +298,33 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
     connection.setDoInput(true);
     connection.setDoOutput(multipleIds);
 
+    connection.setConnectTimeout(CONNECT_TIMEOUT_MS);
+    connection.setReadTimeout(readTimeout);
+
     if (multipleIds)
     {
       writePostBody(connection, ids);
     }
-  
-    InputStream response = connection.getInputStream();
+
     int responseCode = connection.getResponseCode();
-  
+
     if (responseCode != 200)
     {
       /*
        * note: a GET request for an invalid id returns an error code e.g. 415
        * but POST request returns 200 and an empty Fasta response 
        */
-      throw new IOException(
-              "Response code was not 200. Detected response was "
-                      + responseCode);
+      System.err.println("Response code " + responseCode + " for " + url);
+      return null;
     }
+    // get content
+    InputStream response = connection.getInputStream();
+
     // System.out.println(getClass().getName() + " took "
     // + (System.currentTimeMillis() - now) + "ms to fetch");
 
     checkRateLimits(connection);
-  
+
     BufferedReader reader = null;
     reader = new BufferedReader(new InputStreamReader(response, "UTF-8"));
     return reader;
@@ -318,7 +377,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
       // remaining, limit, reset));
     }
   }
-  
+
   /**
    * Rechecks if Ensembl is responding, unless the last check was successful and
    * the retest interval has not yet elapsed. Returns true if Ensembl is up,
index 5fccedd..7aa7178 100644 (file)
@@ -1,10 +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.ext.ensembl;
 
 import jalview.analysis.AlignmentUtils;
 import jalview.analysis.Dna;
+import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
@@ -158,6 +180,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
                 + " chunks. Unexpected problem (" + r.getLocalizedMessage()
                 + ")";
         System.err.println(msg);
+        r.printStackTrace();
         break;
       }
     }
@@ -271,7 +294,8 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
       proteinSeq.createDatasetSequence();
       querySeq.createDatasetSequence();
 
-      MapList mapList = AlignmentUtils.mapCdsToProtein(querySeq, proteinSeq);
+      MapList mapList = AlignmentUtils
+              .mapCdsToProtein(querySeq, proteinSeq);
       if (mapList != null)
       {
         // clunky: ensure Uniprot xref if we have one is on mapped sequence
@@ -281,12 +305,52 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
         DBRefEntry dbr = new DBRefEntry(getDbSource(),
                 getEnsemblDataVersion(), proteinSeq.getName(), map);
         querySeq.getDatasetSequence().addDBRef(dbr);
-        
+        DBRefEntry[] uprots = DBRefUtils.selectRefs(ds.getDBRefs(),
+                new String[] { DBRefSource.UNIPROT });
+        DBRefEntry[] upxrefs = DBRefUtils.selectRefs(querySeq.getDBRefs(),
+                new String[] { DBRefSource.UNIPROT });
+        if (uprots != null)
+        {
+          for (DBRefEntry up : uprots)
+          {
+            // locate local uniprot ref and map
+            List<DBRefEntry> upx = DBRefUtils.searchRefs(upxrefs,
+                    up.getAccessionId());
+            DBRefEntry upxref;
+            if (upx.size() != 0)
+            {
+              upxref = upx.get(0);
+
+              if (upx.size() > 1)
+              {
+                Cache.log
+                        .warn("Implementation issue - multiple uniprot acc on product sequence.");
+              }
+            }
+            else
+            {
+              upxref = new DBRefEntry(DBRefSource.UNIPROT,
+                      getEnsemblDataVersion(), up.getAccessionId());
+            }
+
+            Mapping newMap = new Mapping(ds, mapList);
+            upxref.setVersion(getEnsemblDataVersion());
+            upxref.setMap(newMap);
+            if (upx.size() == 0)
+            {
+              // add the new uniprot ref
+              querySeq.getDatasetSequence().addDBRef(upxref);
+            }
+
+          }
+        }
+
         /*
          * copy exon features to protein, compute peptide variants from dna 
          * variants and add as features on the protein sequence ta-da
          */
-        AlignmentUtils.computeProteinFeatures(querySeq, proteinSeq, mapList);
+        AlignmentUtils
+                .computeProteinFeatures(querySeq, proteinSeq, mapList);
       }
     } catch (Exception e)
     {
@@ -343,6 +407,11 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
       throw new JalviewException("ENSEMBL Rest API not available.");
     }
     FileParse fp = getSequenceReader(ids);
+    if (fp == null)
+    {
+      return alignment;
+    }
+
     FastaFile fr = new FastaFile(fp);
     if (fr.hasWarningMessage())
     {
@@ -367,9 +436,8 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
 
     if (fr.getSeqs().size() > 0)
     {
-      AlignmentI seqal = new Alignment(
-              fr.getSeqsAsArray());
-      for (SequenceI sq:seqal.getSequences())
+      AlignmentI seqal = new Alignment(fr.getSeqsAsArray());
+      for (SequenceI sq : seqal.getSequences())
       {
         if (sq.getDescription() == null)
         {
@@ -501,7 +569,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
     int mappedLength = 0;
     int direction = 1; // forward
     boolean directionSet = false;
-  
+
     for (SequenceFeature sf : sfs)
     {
       /*
@@ -518,20 +586,20 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
           // abort - mix of forward and backward
           System.err.println("Error: forward and backward strand for "
                   + accId);
-            return null;
-          }
-          direction = strand;
-          directionSet = true;
-  
-          /*
-           * add to CDS ranges, semi-sorted forwards/backwards
-           */
-          if (strand < 0)
-          {
-            regions.add(0, new int[] { sf.getEnd(), sf.getBegin() });
-          }
-          else
-          {
+          return null;
+        }
+        direction = strand;
+        directionSet = true;
+
+        /*
+         * add to CDS ranges, semi-sorted forwards/backwards
+         */
+        if (strand < 0)
+        {
+          regions.add(0, new int[] { sf.getEnd(), sf.getBegin() });
+        }
+        else
+        {
           regions.add(new int[] { sf.getBegin(), sf.getEnd() });
         }
         mappedLength += Math.abs(sf.getEnd() - sf.getBegin() + 1);
@@ -546,7 +614,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
         }
       }
     }
-  
+
     if (regions.isEmpty())
     {
       System.out.println("Failed to identify target sequence for " + accId
@@ -559,10 +627,10 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
      * (havana / ensembl_havana)
      */
     Collections.sort(regions, new RangeSorter(direction == 1));
-  
+
     List<int[]> to = Arrays.asList(new int[] { start,
         start + mappedLength - 1 });
-  
+
     return new MapList(regions, to, 1, 1);
   }
 
@@ -606,7 +674,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
     int start = sf.getBegin();
     int end = sf.getEnd();
     int[] mappedRange = mapping.locateInTo(start, end);
-  
+
     if (mappedRange != null)
     {
       SequenceFeature copy = new SequenceFeature(sf);
@@ -716,8 +784,8 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
 
     // long start = System.currentTimeMillis();
     SequenceFeature[] sfs = sourceSequence.getSequenceFeatures();
-    MapList mapping = getGenomicRangesFromFeatures(sourceSequence, accessionId,
-            targetSequence.getStart());
+    MapList mapping = getGenomicRangesFromFeatures(sourceSequence,
+            accessionId, targetSequence.getStart());
     if (mapping == null)
     {
       return false;
@@ -848,11 +916,13 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
           String type, String parentId)
   {
     List<SequenceFeature> result = new ArrayList<SequenceFeature>();
-    
+
     SequenceFeature[] sfs = sequence.getSequenceFeatures();
-    if (sfs != null) {
+    if (sfs != null)
+    {
       SequenceOntologyI so = SequenceOntologyFactory.getInstance();
-      for (SequenceFeature sf :sfs) {
+      for (SequenceFeature sf : sfs)
+      {
         if (so.isA(sf.getType(), type))
         {
           String parent = (String) sf.getValue(PARENT);
index dd1739b..bd6335a 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.DBRefSource;
index b8c8c54..0d79864 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import java.io.BufferedReader;
@@ -71,8 +91,7 @@ public class EnsemblSymbol extends EnsemblXref
   protected URL getUrl(String id, Species species)
   {
     String url = getDomain() + "/xrefs/symbol/" + species.toString() + "/"
-            + id
-            + "?content-type=application/json";
+            + id + "?content-type=application/json";
     try
     {
       return new URL(url);
@@ -94,7 +113,7 @@ public class EnsemblSymbol extends EnsemblXref
     List<String> result = new ArrayList<String>();
     List<String> ids = new ArrayList<String>();
     ids.add(identifier);
-  
+
     String[] queries = identifier.split(getAccessionSeparator());
     BufferedReader br = null;
     try
index 313572f..c0b00b1 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.AlignmentI;
@@ -41,7 +61,7 @@ class EnsemblXref extends EnsemblRestClient
     super(d);
     dbName = dbSource;
     xrefVersion = dbSource + ":" + version;
-    
+
   }
 
   @Override
index d8a00a5..350d0d5 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 /**
index f3b5098..4357abd 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.htsjdk;
 
 import htsjdk.samtools.SAMSequenceDictionary;
@@ -59,18 +79,21 @@ public class HtsContigDb
 
   }
 
-
   SAMSequenceDictionary rrefDict = null;
-  private ReferenceSequenceFile initSequenceDictionaryFor(File dbLocation2) throws Exception
+
+  private ReferenceSequenceFile initSequenceDictionaryFor(File dbLocation2)
+          throws Exception
   {
     rrefDict = getDictionary(dbLocation2, true);
     if (rrefDict != null)
     {
-      ReferenceSequenceFile rrefFile = ReferenceSequenceFileFactory.getReferenceSequenceFile(dbLocation2, true);
+      ReferenceSequenceFile rrefFile = ReferenceSequenceFileFactory
+              .getReferenceSequenceFile(dbLocation2, true);
       return rrefFile;
     }
     return null;
   }
+
   /**
    * code below hacked out from picard ----
    * 
@@ -79,7 +102,6 @@ public class HtsContigDb
    * broadinstitute/picard/commit/270580d3e28123496576f0b91b3433179bb5d876
    */
 
-
   /*
    * The MIT License
    * 
index 2ccf118..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;
@@ -43,13 +43,12 @@ import java.awt.event.ComponentListener;
 import java.io.File;
 import java.net.URL;
 import java.security.AccessControlException;
+import java.util.ArrayList;
 import java.util.Hashtable;
 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;
@@ -73,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;
 
@@ -93,20 +92,15 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
 
   boolean loadedInline;
 
-  /**
-   * current set of model filenames loaded in the Jmol instance
-   */
-  String[] modelFileNames = null;
-
   StringBuffer resetLastRes = new StringBuffer();
 
   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(),
@@ -171,7 +165,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   {
     // remove listeners for all structures in viewer
     getSsm().removeStructureViewerListener(this, this.getPdbFile());
-     viewer.dispose();
+    viewer.dispose();
     lastCommand = null;
     viewer = null;
     releaseUIResources();
@@ -258,8 +252,12 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       } catch (InterruptedException i)
       {
       }
-      ;
     }
+
+    /*
+     * get the distinct structure files modelled
+     * (a file with multiple chains may map to multiple sequences)
+     */
     String[] files = getPdbFile();
     if (!waitForFileLoad(files))
     {
@@ -307,6 +305,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
        * 'matched' array will hold 'true' for visible alignment columns where
        * all sequences have a residue with a mapping to the PDB structure
        */
+      // TODO could use a BitSet for matched
       boolean matched[] = new boolean[alignment.getWidth()];
       for (int m = 0; m < matched.length; m++)
       {
@@ -352,6 +351,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
        * generate select statements to select regions to superimpose structures
        */
       {
+        // TODO extract method to construct selection statements
         for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
         {
           String chainCd = ":" + structures[pdbfnum].chain;
@@ -419,6 +419,8 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
         }
       }
       StringBuilder command = new StringBuilder(256);
+      // command.append("set spinFps 10;\n");
+
       for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
       {
         if (pdbfnum == refStructure || selcom[pdbfnum] == null
@@ -449,12 +451,13 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       }
       if (selectioncom.length() > 0)
       {
-        System.out.println("Select regions:\n" + selectioncom.toString());
+        // TODO is performing selectioncom redundant here? is done later on
+        // System.out.println("Select regions:\n" + selectioncom.toString());
         evalStateCommand("select *; cartoons off; backbone; select ("
                 + selectioncom.toString() + "); cartoons; ");
         // selcom.append("; ribbons; ");
         String cmdString = command.toString();
-        System.out.println("Superimpose command(s):\n" + cmdString);
+        // System.out.println("Superimpose command(s):\n" + cmdString);
 
         evalStateCommand(cmdString);
       }
@@ -465,7 +468,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       {
         selectioncom.setLength(selectioncom.length() - 1);
       }
-      System.out.println("Select regions:\n" + selectioncom.toString());
+      // System.out.println("Select regions:\n" + selectioncom.toString());
       evalStateCommand("select *; cartoons off; backbone; select ("
               + selectioncom.toString() + "); cartoons; ");
       // evalStateCommand("select *; backbone; select "+selcom.toString()+"; cartoons; center "+selcom.toString());
@@ -647,15 +650,15 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     }
     if (modelFileNames == null)
     {
-      String mset[] = new String[viewer.ms.mc];
-      _modelFileNameMap = new int[mset.length];
+      List<String> mset = new ArrayList<String>();
+      _modelFileNameMap = new int[viewer.ms.mc];
       String m = viewer.ms.getModelFileName(0);
       if (m != null)
       {
-        mset[0] = m;
+        String filePath = m;
         try
         {
-          mset[0] = new File(m).getAbsolutePath();
+          filePath = new File(m).getAbsolutePath();
         } catch (AccessControlException x)
         {
           // usually not allowed to do this in applet
@@ -663,39 +666,43 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
                   .println("jmolBinding: Using local file string from Jmol: "
                           + m);
         }
-        if (mset[0].indexOf("/file:") != -1)
+        if (filePath.indexOf("/file:") != -1)
         {
           // applet path with docroot - discard as format won't match pdbfile
-          mset[0] = m;
+          filePath = m;
         }
+        mset.add(filePath);
         _modelFileNameMap[0] = 0; // filename index for first model is always 0.
       }
       int j = 1;
-      for (int i = 1; i < mset.length; i++)
+      for (int i = 1; i < viewer.ms.mc; i++)
       {
         m = viewer.ms.getModelFileName(i);
-        mset[j] = m;
+        String filePath = m;
         if (m != null)
         {
           try
           {
-            mset[j] = new File(m).getAbsolutePath();
+            filePath = new File(m).getAbsolutePath();
           } catch (AccessControlException x)
           {
             // usually not allowed to do this in applet, so keep raw handle
             // System.err.println("jmolBinding: Using local file string from Jmol: "+m);
           }
         }
-        _modelFileNameMap[j] = i; // record the model index for the filename
-        // skip any additional models in the same file (NMR structures)
-        if ((mset[j] == null ? mset[j] != mset[j - 1]
-                : (mset[j - 1] == null || !mset[j].equals(mset[j - 1]))))
+
+        /*
+         * add this model unless it is read from a structure file we have
+         * already seen (example: 2MJW is an NMR structure with 10 models)
+         */
+        if (!mset.contains(filePath))
         {
+          mset.add(filePath);
+          _modelFileNameMap[j] = i; // record the model index for the filename
           j++;
         }
       }
-      modelFileNames = new String[j];
-      System.arraycopy(mset, 0, modelFileNames, 0, j);
+      modelFileNames = mset.toArray(new String[mset.size()]);
     }
     return modelFileNames;
   }
@@ -1074,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();
@@ -1134,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;
@@ -1158,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)
             {
@@ -1185,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;
         }
@@ -1233,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);
@@ -1395,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 cef552f..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,10 +60,10 @@ public class JmolParser extends StructureFile implements JmolStatusListener
 {
   Viewer viewer = null;
 
-  public JmolParser(String inFile, String type)
+  public JmolParser(String inFile, DataSourceType sourceType)
           throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public JmolParser(FileParse fp) throws IOException
@@ -124,6 +123,10 @@ public class JmolParser extends StructureFile implements JmolStatusListener
     {
       try
       {
+        /*
+         * params -o (output to sysout) -n (nodisplay) -x (exit when finished)
+         * see http://wiki.jmol.org/index.php/Jmol_Application
+         */
         viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
                 null, "-x -o -n", this);
         // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
@@ -147,7 +150,17 @@ public class JmolParser extends StructureFile implements JmolStatusListener
       List<SequenceI> prot = new ArrayList<SequenceI>();
       PDBChain tmpchain;
       String pdbId = (String) ms.getInfo(0, "title");
-      setId(pdbId);
+
+      if (pdbId == null)
+      {
+        setId(safeName(getDataName()));
+        setPDBIdAvailable(false);
+      }
+      else
+      {
+        setId(pdbId);
+        setPDBIdAvailable(true);
+      }
       List<Atom> significantAtoms = convertSignificantAtoms(ms);
       for (Atom tmpatom : significantAtoms)
       {
@@ -162,7 +175,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
           tmpchain.atoms.addElement(tmpatom);
         } catch (Exception e)
         {
-          tmpchain = new PDBChain(pdbId, tmpatom.chain);
+          tmpchain = new PDBChain(getId(), tmpatom.chain);
           getChains().add(tmpchain);
           tmpchain.atoms.addElement(tmpatom);
         }
@@ -173,10 +186,6 @@ public class JmolParser extends StructureFile implements JmolStatusListener
       makeResidueList();
       makeCaBondList();
 
-      if (getId() == null)
-      {
-        setId(safeName(getDataName()));
-      }
       for (PDBChain chain : getChains())
       {
         SequenceI chainseq = postProcessChain(chain);
@@ -351,9 +360,9 @@ public class JmolParser extends StructureFile implements JmolStatusListener
       {
         try
         {
-        asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
-                secstrcode[p], Float.NaN);
-        ssFound = true;
+          asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
+                  secstrcode[p], Float.NaN);
+          ssFound = true;
         } catch (Exception e)
         {
           // e.printStackTrace();
@@ -463,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;
   }
@@ -617,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 944ef52..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
    */
@@ -101,11 +108,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   private String lastCommand;
 
-  /*
-   * current set of model filenames loaded
-   */
-  String[] modelFileNames = null;
-
   String lastHighlightCommand;
 
   /*
@@ -115,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.
    * 
@@ -192,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, chains, protocol);
-    viewer = new ChimeraManager(
-            new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true));
+    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()
+  {
+    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();
   }
 
   /**
@@ -249,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;
     }
 
@@ -262,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);
   }
@@ -286,6 +321,10 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     lastCommand = null;
     viewer = null;
 
+    if (chimeraMonitor != null)
+    {
+      chimeraMonitor.interrupt();
+    }
     releaseUIResources();
   }
 
@@ -566,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;
   }
 
   /**
@@ -763,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()]);
@@ -1067,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()
@@ -1130,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 af80b7a..a4c195f 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.so;
 
 import jalview.io.gff.SequenceOntologyI;
@@ -77,11 +97,11 @@ public class SequenceOntology implements SequenceOntologyI
    */
   protected void loadOntologyZipFile(String ontologyFile)
   {
+    long now = System.currentTimeMillis();
     ZipInputStream zipStream = null;
     try
     {
       String zipFile = ontologyFile + ".zip";
-      System.out.println("Loading Sequence Ontology from " + zipFile);
       InputStream inStream = this.getClass().getResourceAsStream(
               "/" + zipFile);
       zipStream = new ZipInputStream(new BufferedInputStream(inStream));
@@ -93,6 +113,9 @@ public class SequenceOntology implements SequenceOntologyI
           loadOboFile(zipStream);
         }
       }
+      long elapsed = System.currentTimeMillis() - now;
+      System.out.println("Loaded Sequence Ontology from " + zipFile + " ("
+              + elapsed + "ms)");
     } catch (Exception e)
     {
       e.printStackTrace();
@@ -172,9 +195,9 @@ public class SequenceOntology implements SequenceOntologyI
             }
             else
             {
-            System.err.println("Warning: " + term.getName()
-                    + " has replaced " + replaced.getName()
-                    + " for lookup of '" + description + "'");
+              System.err.println("Warning: " + term.getName()
+                      + " has replaced " + replaced.getName()
+                      + " for lookup of '" + description + "'");
             }
           }
           termsByDescription.put(description, term);
@@ -197,8 +220,8 @@ public class SequenceOntology implements SequenceOntologyI
     {
       try
       {
-      if (Boolean.TRUE.equals(ann.getProperty("is_obsolete")))
-      {
+        if (Boolean.TRUE.equals(ann.getProperty("is_obsolete")))
+        {
           return true;
         }
       } catch (NoSuchElementException e)
index 3701c76..33b0ed6 100644 (file)
@@ -74,7 +74,6 @@ public interface FTSRestClientI
   public FTSDataColumnI getDataColumnByNameOrCode(String nameOrCode)
           throws Exception;
 
-
   /**
    * Convert collection of FTSDataColumnI objects to a comma delimited string of
    * the 'code' values
@@ -87,7 +86,6 @@ public interface FTSRestClientI
   public String getDataColumnsFieldsAsCommaDelimitedString(
           Collection<FTSDataColumnI> wantedFields);
 
-
   /**
    * Fetch index of the primary key column for the dynamic table
    * 
@@ -102,7 +100,7 @@ public interface FTSRestClientI
   public int getPrimaryKeyColumIndex(
           Collection<FTSDataColumnI> wantedFields, boolean hasRefSeq)
           throws Exception;
-          
+
   /**
    * Fetch the primary key data column object
    * 
@@ -139,4 +137,3 @@ public interface FTSRestClientI
    */
   public int getDefaultResponsePageSize();
 }
-
index 3642721..a9e303c 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.fts.core;
 
 import java.awt.Component;
@@ -57,4 +77,4 @@ public class DecimalFormatTableCellRenderer extends
     return super.getTableCellRendererComponent(table, value, isSelected,
             hasFocus, row, column);
   }
-}
\ No newline at end of file
+}
index eb7455e..1a8f398 100644 (file)
@@ -40,7 +40,6 @@ import javax.swing.table.AbstractTableModel;
 import javax.swing.table.TableModel;
 import javax.swing.table.TableRowSorter;
 
-
 @SuppressWarnings("serial")
 public class FTSDataColumnPreferences extends JScrollPane
 {
@@ -71,7 +70,7 @@ public class FTSDataColumnPreferences extends JScrollPane
     if (source.equals(PreferenceSource.STRUCTURE_CHOOSER)
             || source.equals(PreferenceSource.PREFERENCES))
     {
-    structSummaryColumns = ((PDBFTSRestClient) ftsRestClient)
+      structSummaryColumns = ((PDBFTSRestClient) ftsRestClient)
               .getAllDefaultDisplayedStructureDataColumns();
     }
     allFTSDataColumns.addAll(ftsRestClient.getAllFTSDataColumns());
@@ -111,19 +110,18 @@ public class FTSDataColumnPreferences extends JScrollPane
       {
       case SEARCH_SUMMARY:
         data[x++] = new Object[] {
-            ftsRestClient.getAllDefaultDisplayedFTSDataColumns()
-                    .contains(field),
-            field.getName(), field.getGroup() };
+            ftsRestClient.getAllDefaultDisplayedFTSDataColumns().contains(
+                    field), field.getName(), field.getGroup() };
         break;
       case STRUCTURE_CHOOSER:
         data[x++] = new Object[] { structSummaryColumns.contains(field),
             field.getName(), field.getGroup() };
         break;
       case PREFERENCES:
-        data[x++] = new Object[] { field.getName(),
-            ftsRestClient.getAllDefaultDisplayedFTSDataColumns()
-                    .contains(field),
-            structSummaryColumns.contains(field) };
+        data[x++] = new Object[] {
+            field.getName(),
+            ftsRestClient.getAllDefaultDisplayedFTSDataColumns().contains(
+                    field), structSummaryColumns.contains(field) };
         break;
       default:
         break;
@@ -131,7 +129,8 @@ public class FTSDataColumnPreferences extends JScrollPane
       map.put(field.getName(), field);
     }
 
-    FTSDataColumnPrefsTableModel model = new FTSDataColumnPrefsTableModel(columnNames, data);
+    FTSDataColumnPrefsTableModel model = new FTSDataColumnPrefsTableModel(
+            columnNames, data);
     tbl_FTSDataColumnPrefs.setModel(model);
 
     switch (source)
@@ -147,8 +146,7 @@ public class FTSDataColumnPreferences extends JScrollPane
       tbl_FTSDataColumnPrefs.getColumnModel().getColumn(1).setMinWidth(150);
       tbl_FTSDataColumnPrefs.getColumnModel().getColumn(2)
               .setPreferredWidth(150);
-      tbl_FTSDataColumnPrefs.getColumnModel().getColumn(2)
-.setMinWidth(150);
+      tbl_FTSDataColumnPrefs.getColumnModel().getColumn(2).setMinWidth(150);
 
       TableRowSorter<TableModel> sorter = new TableRowSorter<>(
               tbl_FTSDataColumnPrefs.getModel());
@@ -158,8 +156,7 @@ public class FTSDataColumnPreferences extends JScrollPane
       sortKeys.add(new RowSorter.SortKey(columnIndexToSort,
               SortOrder.ASCENDING));
       sorter.setSortKeys(sortKeys);
-      sorter.setComparator(
-              columnIndexToSort,
+      sorter.setComparator(columnIndexToSort,
               new Comparator<FTSDataColumnGroupI>()
               {
                 @Override
@@ -189,7 +186,8 @@ public class FTSDataColumnPreferences extends JScrollPane
   class FTSDataColumnPrefsTableModel extends AbstractTableModel
   {
 
-    public FTSDataColumnPrefsTableModel(String[] columnNames, Object[][] data)
+    public FTSDataColumnPrefsTableModel(String[] columnNames,
+            Object[][] data)
     {
       this.data = data;
       this.columnNames = columnNames;
@@ -301,9 +299,8 @@ public class FTSDataColumnPreferences extends JScrollPane
 
       if (currentSource == PreferenceSource.SEARCH_SUMMARY)
       {
-        updatePrefs(ftsRestClient
-                .getAllDefaultDisplayedFTSDataColumns(), ftsDataColumn,
-                selected);
+        updatePrefs(ftsRestClient.getAllDefaultDisplayedFTSDataColumns(),
+                ftsDataColumn, selected);
       }
       else if (currentSource == PreferenceSource.STRUCTURE_CHOOSER)
       {
@@ -313,9 +310,8 @@ public class FTSDataColumnPreferences extends JScrollPane
       {
         if (col == 1)
         {
-          updatePrefs(ftsRestClient
-                  .getAllDefaultDisplayedFTSDataColumns(), ftsDataColumn,
-                  selected);
+          updatePrefs(ftsRestClient.getAllDefaultDisplayedFTSDataColumns(),
+                  ftsDataColumn, selected);
         }
         else if (col == 2)
         {
@@ -324,8 +320,7 @@ public class FTSDataColumnPreferences extends JScrollPane
       }
     }
 
-    private void updatePrefs(
-            Collection<FTSDataColumnI> prefConfig,
+    private void updatePrefs(Collection<FTSDataColumnI> prefConfig,
             FTSDataColumnI dataColumn, boolean selected)
     {
       if (prefConfig.contains(dataColumn) && !selected)
index 00a081b..4899e38 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.fts.core;
 
 import jalview.fts.api.FTSDataColumnI;
@@ -45,9 +65,9 @@ public abstract class FTSRestClient implements FTSRestClientI
   public void parseDataColumnsConfigFile()
   {
     String fileName = getColumnDataConfigFileName();
-    
-    InputStream in = getClass().getResourceAsStream(fileName); 
-    
+
+    InputStream in = getClass().getResourceAsStream(fileName);
+
     try (BufferedReader br = new BufferedReader(new InputStreamReader(in)))
     {
       String line;
@@ -259,7 +279,6 @@ public abstract class FTSRestClient implements FTSRestClientI
                         this.getGroup());
               }
 
-
               @Override
               public boolean equals(Object otherObject)
               {
@@ -269,7 +288,6 @@ public abstract class FTSRestClient implements FTSRestClientI
                         && this.getGroup().equals(that.getGroup());
               }
 
-
             };
             dataColumns.add(dataCol);
 
@@ -345,7 +363,6 @@ public abstract class FTSRestClient implements FTSRestClientI
     return result;
   }
 
-
   @Override
   public Collection<FTSDataColumnI> getAllFTSDataColumns()
   {
@@ -432,10 +449,9 @@ public abstract class FTSRestClient implements FTSRestClientI
     switch (code)
     {
     case 400:
-      message = MessageManager
-              .getString("exception.bad_request");
+      message = MessageManager.getString("exception.bad_request");
       break;
-      
+
     case 410:
       message = MessageManager.formatMessage(
               "exception.fts_rest_service_no_longer_available", service);
@@ -451,7 +467,8 @@ public abstract class FTSRestClient implements FTSRestClientI
     case 502:
     case 504:
     case 505:
-      message = MessageManager.getString("exception.fts_server_error");
+      message = MessageManager.formatMessage("exception.fts_server_error",
+              service);
       break;
     case 503:
       message = MessageManager.getString("exception.service_not_available");
index 164b102..2e1c632 100644 (file)
@@ -107,8 +107,7 @@ public class FTSRestRequest
     return wantedFields;
   }
 
-  public void setWantedFields(
-          Collection<FTSDataColumnI> wantedFields)
+  public void setWantedFields(Collection<FTSDataColumnI> wantedFields)
   {
     this.wantedFields = wantedFields;
   }
index 92ea5f8..5d8fb96 100644 (file)
@@ -90,8 +90,8 @@ public class FTSRestResponse
   public static DefaultTableModel getTableModel(FTSRestRequest request,
           Collection<FTSData> summariesList)
   {
-    final FTSDataColumnI[] cols = request.getWantedFields()
-            .toArray(new FTSDataColumnI[0]);
+    final FTSDataColumnI[] cols = request.getWantedFields().toArray(
+            new FTSDataColumnI[0]);
     final int colOffset = request.getAssociatedSequence() == null ? 0 : 1;
     DefaultTableModel tableModel = new DefaultTableModel()
     {
@@ -118,8 +118,7 @@ public class FTSRestResponse
       tableModel.addColumn("Ref Sequence"); // Create sequence column header if
       // exists in the request
     }
-    for (FTSDataColumnI field : request
-            .getWantedFields())
+    for (FTSDataColumnI field : request.getWantedFields())
     {
       tableModel.addColumn(field.getName()); // Create sequence column header if
                                              // exists in the request
@@ -172,5 +171,4 @@ public class FTSRestResponse
     }
   }
 
-
 }
index 30b6417..a69d9f8 100644 (file)
@@ -148,6 +148,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
 
   protected static final DecimalFormat totalNumberformatter = new DecimalFormat(
           "###,###");
+
   private JTable tbl_summary = new JTable()
   {
     private boolean inLayout;
@@ -225,6 +226,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
       return toolTipText;
     }
   };
+
   protected JScrollPane scrl_searchResult = new JScrollPane(tbl_summary);
 
   public GFTSPanel()
@@ -504,8 +506,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     });
 
     final DeferredTextInputListener listener = new DeferredTextInputListener(
-            1500,
-            new ActionListener()
+            1500, new ActionListener()
             {
               @Override
               public void actionPerformed(ActionEvent e)
@@ -530,7 +531,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
       @Override
       public void focusLost(FocusEvent e)
       {
-//        listener.stop();
+        // listener.stop();
       }
     });
 
@@ -563,8 +564,8 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
           txt_search.setEnabled(false);
           cmb_searchTarget.setEnabled(false);
           previousWantedFields = getFTSRestClient()
-                  .getAllDefaultDisplayedFTSDataColumns()
-                  .toArray(new Object[0]);
+                  .getAllDefaultDisplayedFTSDataColumns().toArray(
+                          new Object[0]);
         }
         if (sourceTabbedPane.getTitleAt(index).equals(searchTabTitle))
         {
@@ -645,6 +646,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     getTempUserPrefs().put("FTSPanel.y", mainFrame.getY());
     mainFrame.dispose();
   }
+
   public class DeferredTextInputListener implements DocumentListener
   {
     private final Timer swingTimer;
@@ -694,9 +696,8 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     }
 
     return Arrays.equals(getFTSRestClient()
-            .getAllDefaultDisplayedFTSDataColumns()
-            .toArray(new Object[0]), previousWantedFields) ? false
-            : true;
+            .getAllDefaultDisplayedFTSDataColumns().toArray(new Object[0]),
+            previousWantedFields) ? false : true;
 
   }
 
@@ -812,7 +813,6 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     }
   }
 
-
   public void transferToSequenceFetcher(String ids)
   {
     // mainFrame.dispose();
@@ -925,8 +925,8 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     int[] selectedRows = resultTable.getSelectedRows();
     for (int summaryRow : selectedRows)
     {
-      String idStr = resultTable.getValueAt(summaryRow,
-              primaryKeyColIndex).toString();
+      String idStr = resultTable.getValueAt(summaryRow, primaryKeyColIndex)
+              .toString();
       paginatorCart.add(idStr);
     }
     // System.out.println("Paginator shopping cart size : "
@@ -962,6 +962,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     }
     validateSelection();
   }
+
   public void refreshPaginatorState()
   {
     // System.out.println("resultSet count : " + resultSetCount);
@@ -982,6 +983,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
       setPrevPageButtonEnabled(true);
     }
   }
+
   public void referesh()
   {
     mainFrame.setTitle(getFTSFrameTitle());
index 3fe8603..1dfabce 100644 (file)
@@ -52,7 +52,6 @@ public class PDBFTSPanel extends GFTSPanel
             .getProgressIndicator();
   }
 
-
   @Override
   public void searchAction(boolean isFreshSearch)
   {
@@ -104,7 +103,7 @@ public class PDBFTSPanel extends GFTSPanel
           {
             getResultTable().setModel(
                     FTSRestResponse.getTableModel(request,
-                    resultList.getSearchSummary()));
+                            resultList.getSearchSummary()));
             FTSRestResponse.configureTableColumn(getResultTable(),
                     wantedFields, tempUserPrefs);
             getResultTable().setVisible(true);
@@ -117,10 +116,12 @@ public class PDBFTSPanel extends GFTSPanel
           String result = (resultSetCount > 0) ? MessageManager
                   .getString("label.results") : MessageManager
                   .getString("label.result");
-         
+
           if (isPaginationEnabled() && resultSetCount > 0)
           {
-            updateSearchFrameTitle(defaultFTSFrameTitle + " - " + result
+            updateSearchFrameTitle(defaultFTSFrameTitle
+                    + " - "
+                    + result
                     + " "
                     + totalNumberformatter.format((Number) (offSet + 1))
                     + " to "
@@ -128,8 +129,8 @@ public class PDBFTSPanel extends GFTSPanel
                             .format((Number) (offSet + resultSetCount))
                     + " of "
                     + totalNumberformatter
-                            .format((Number) totalResultSetCount)
-                    + " " + " (" + (endTime - startTime) + " milli secs)");
+                            .format((Number) totalResultSetCount) + " "
+                    + " (" + (endTime - startTime) + " milli secs)");
           }
           else
           {
@@ -137,7 +138,7 @@ public class PDBFTSPanel extends GFTSPanel
                     + resultSetCount + " " + result + " ("
                     + (endTime - startTime) + " milli secs)");
           }
-          
+
           setSearchInProgress(false);
           refreshPaginatorState();
           updateSummaryTableSelections();
@@ -193,8 +194,7 @@ public class PDBFTSPanel extends GFTSPanel
     try
     {
       primaryKeyColIndex = getFTSRestClient().getPrimaryKeyColumIndex(
-              wantedFields,
-              false);
+              wantedFields, false);
     } catch (Exception e)
     {
       e.printStackTrace();
@@ -204,8 +204,7 @@ public class PDBFTSPanel extends GFTSPanel
     for (int summaryRow : selectedRows)
     {
       String idStr = getResultTable().getValueAt(summaryRow,
-              primaryKeyColIndex)
-              .toString();
+              primaryKeyColIndex).toString();
       selectedIdsSet.add(getPDBIdwithSpecifiedChain(idStr, searchTerm));
     }
 
@@ -227,7 +226,6 @@ public class PDBFTSPanel extends GFTSPanel
     delayAndEnableActionButtons();
   }
 
-
   public static String getPDBIdwithSpecifiedChain(String pdbId,
           String searchTerm)
   {
index 219d6d6..06bf55b 100644 (file)
@@ -140,8 +140,7 @@ public class PDBFTSRestClient extends FTSRestClient
                 .queryParam("wt", "json").queryParam("fl", wantedFields)
                 .queryParam("rows", String.valueOf(responseSize))
                 .queryParam("start", String.valueOf(offSet))
-                .queryParam("q", query)
-                .queryParam("sort", sortParam);
+                .queryParam("q", query).queryParam("sort", sortParam);
       }
       // Execute the REST request
       ClientResponse clientResponse = webResource.accept(
@@ -162,8 +161,8 @@ public class PDBFTSRestClient extends FTSRestClient
         }
         else
         {
-          errorMessage = getMessageByHTTPStatusCode(clientResponse
-.getStatus(), "PDB");
+          errorMessage = getMessageByHTTPStatusCode(
+                  clientResponse.getStatus(), "PDB");
           throw new Exception(errorMessage);
         }
       }
@@ -198,7 +197,6 @@ public class PDBFTSRestClient extends FTSRestClient
     }
   }
 
-
   /**
    * Process error response from PDB server if/when one occurs.
    * 
@@ -328,15 +326,13 @@ public class PDBFTSRestClient extends FTSRestClient
         {
           summaryRowData[colCounter++] = (field.getDataType()
                   .getDataTypeClass() == Integer.class) ? Integer
-                  .valueOf(fieldData)
- : (field.getDataType()
+                  .valueOf(fieldData) : (field.getDataType()
                   .getDataTypeClass() == Double.class) ? Double
-                          .valueOf(fieldData)
- : sanitiseData(fieldData);
+                  .valueOf(fieldData) : sanitiseData(fieldData);
         } catch (Exception e)
         {
           e.printStackTrace();
-            System.out.println("offending value:" + fieldData);
+          System.out.println("offending value:" + fieldData);
         }
       }
     }
@@ -405,7 +401,6 @@ public class PDBFTSRestClient extends FTSRestClient
     return "/fts/pdb_data_columns.txt";
   }
 
-
   public static FTSRestClientI getInstance()
   {
     if (instance == null)
index 5ee518b..27bfca8 100644 (file)
@@ -241,13 +241,12 @@ public class UniProtFTSRestClient extends FTSRestClient
             summaryRowData[colCounter++] = (field.getDataType()
                     .getDataTypeClass() == Integer.class) ? Integer
                     .valueOf(fieldData.replace(",", ""))
- : (field.getDataType()
-                    .getDataTypeClass() == Double.class) ? Double
+                    : (field.getDataType().getDataTypeClass() == Double.class) ? Double
                             .valueOf(fieldData) : fieldData;
           } catch (Exception e)
           {
             e.printStackTrace();
-              System.out.println("offending value:" + fieldData);
+            System.out.println("offending value:" + fieldData);
           }
         }
       } catch (Exception e)
@@ -306,7 +305,6 @@ public class UniProtFTSRestClient extends FTSRestClient
     };
   }
 
-
   public static FTSRestClientI getInstance()
   {
     if (instance == null)
index 0d02cc0..f04e4fa 100644 (file)
@@ -62,7 +62,7 @@ public class UniprotFTSPanel extends GFTSPanel
       offSet = 0;
     }
     new Thread()
-  {
+    {
       @Override
       public void run()
       {
@@ -120,7 +120,9 @@ public class UniprotFTSPanel extends GFTSPanel
                   .getString("label.result");
           if (isPaginationEnabled() && resultSetCount > 0)
           {
-            updateSearchFrameTitle(defaultFTSFrameTitle + " - " + result
+            updateSearchFrameTitle(defaultFTSFrameTitle
+                    + " - "
+                    + result
                     + " "
                     + totalNumberformatter.format((Number) (offSet + 1))
                     + " to "
@@ -128,8 +130,8 @@ public class UniprotFTSPanel extends GFTSPanel
                             .format((Number) (offSet + resultSetCount))
                     + " of "
                     + totalNumberformatter
-                            .format((Number) totalResultSetCount)
-                    + " " + " (" + (endTime - startTime) + " milli secs)");
+                            .format((Number) totalResultSetCount) + " "
+                    + " (" + (endTime - startTime) + " milli secs)");
           }
           else
           {
@@ -173,7 +175,6 @@ public class UniprotFTSPanel extends GFTSPanel
     return foundSearchTerms;
   }
 
-
   @Override
   public boolean isPaginationEnabled()
   {
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 49bd138..8ca9085 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;
@@ -108,6 +112,7 @@ import java.awt.datatransfer.Clipboard;
 import java.awt.datatransfer.DataFlavor;
 import java.awt.datatransfer.StringSelection;
 import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
 import java.awt.dnd.DropTargetDragEvent;
 import java.awt.dnd.DropTargetDropEvent;
 import java.awt.dnd.DropTargetEvent;
@@ -141,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;
@@ -174,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
@@ -483,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);
@@ -668,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())
           {
@@ -1002,7 +1016,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++)
@@ -1024,7 +1038,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
@@ -1032,7 +1047,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);
 
@@ -1076,9 +1092,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);
@@ -1098,11 +1112,11 @@ 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);
+    JalviewFileChooser chooser = JalviewFileChooser.forWrite(
+            Cache.getProperty("LAST_DIRECTORY"),
+            // AppletFormatAdapter.WRITABLE_EXTENSIONS,
+            // AppletFormatAdapter.WRITABLE_FNAMES,
+            currentFileFormat.toString(), false);
 
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
@@ -1116,14 +1130,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)
@@ -1134,24 +1148,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;
 
@@ -1170,16 +1179,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);
@@ -1224,11 +1233,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;
@@ -1243,8 +1252,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;
   }
@@ -1259,8 +1268,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;
@@ -1269,8 +1279,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(),
@@ -1287,7 +1298,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;
@@ -1303,7 +1314,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if (settings == null)
     {
       settings = new AlignExportSettings(hasHiddenSeqs,
-              viewport.hasHiddenColumns(), exportFormat);
+              viewport.hasHiddenColumns(), format);
     }
     // settings.isExportAnnotations();
 
@@ -1339,14 +1350,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)
@@ -1860,7 +1872,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);
@@ -1947,7 +1960,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         return;
       }
 
-      String str, format;
+      String str;
+      FileFormatI format;
       try
       {
         str = (String) contents.getTransferData(DataFlavor.stringFlavor);
@@ -1956,7 +1970,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)
       {
@@ -1986,7 +2000,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();
       }
 
@@ -2355,13 +2370,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;
         }
@@ -2906,8 +2921,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);
     }
   }
 
@@ -3639,14 +3653,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           {
             radioItem.removeActionListener(radioItem.getActionListeners()[0]);
 
-            int option = JOptionPane.showInternalConfirmDialog(
-                    jalview.gui.Desktop.desktop,
-                    MessageManager
+            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 +3807,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 +3836,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 +3941,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 +3959,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 +3980,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 +4252,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 +4328,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 +4731,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 +4741,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 +4768,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 +4780,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));
 
   }
 
@@ -4815,8 +4828,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void drop(DropTargetDropEvent evt)
   {
+    // JAL-1552 - acceptDrop required before getTransferable call for
+    // 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
     {
@@ -4842,13 +4859,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();
@@ -4872,7 +4889,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             }
             if (mtch != null)
             {
-              String type = null;
+              FileFormatI type = null;
               try
               {
                 type = new IdentifyFile().identify(file, protocol);
@@ -4880,13 +4897,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.
@@ -4897,20 +4911,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)
@@ -4922,7 +4936,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)
                 {
@@ -4940,7 +4954,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>"
@@ -4955,7 +4969,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;
           }
@@ -4981,21 +4995,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)
       {
@@ -5003,7 +5017,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))
@@ -5020,7 +5034,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
@@ -5028,7 +5042,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
@@ -5049,12 +5063,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);
@@ -5065,16 +5079,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);
           }
         }
       }
@@ -5099,8 +5114,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);
@@ -5149,8 +5164,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)
       {
@@ -5889,12 +5904,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
@@ -5927,6 +5942,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 f755b25..53d118b 100644 (file)
  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
-/*
- * Jalview - A Sequence Alignment Editor and Viewer
- * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
- *
- * This program 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 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
- */
 package jalview.gui;
 
 import jalview.analysis.AlignmentUtils;
@@ -55,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;
@@ -676,7 +659,8 @@ public class AlignViewport extends AlignmentViewport implements
       List<SequenceI> choosenSeqs = new ArrayList<SequenceI>();
       for (SequenceI sq : alignment.getSequences())
       {
-        Vector<PDBEntry> pdbRefEntries = sq.getDatasetSequence().getAllPDBEntries();
+        Vector<PDBEntry> pdbRefEntries = sq.getDatasetSequence()
+                .getAllPDBEntries();
         if (pdbRefEntries == null)
         {
           continue;
@@ -708,7 +692,8 @@ public class AlignViewport extends AlignmentViewport implements
           }
         }
       }
-      seqvectors.add(choosenSeqs.toArray(new SequenceI[choosenSeqs.size()]));
+      seqvectors
+              .add(choosenSeqs.toArray(new SequenceI[choosenSeqs.size()]));
     }
     return seqvectors.toArray(new SequenceI[seqvectors.size()][]);
   }
@@ -891,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)
@@ -933,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);
     // }
@@ -1058,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 424d52f..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;
   }
@@ -1281,7 +1316,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
       if (file != null)
       {
         alignFrame.setProgressBar(MessageManager.formatMessage(
-              "status.saving_file", new Object[] { type.getLabel() }),
+                "status.saving_file", new Object[] { type.getLabel() }),
                 pSessionId);
       }
     }
@@ -1310,23 +1345,25 @@ public class AlignmentPanel extends GAlignmentPanel implements
 
         im = new jalview.util.ImageMaker(this, type, imageAction,
                 aDimension.getWidth(), aDimension.getHeight()
-                        + boarderBottomOffset, file,
-                imageTitle, alignFrame, pSessionId, headless);
+                        + 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 93c9a6b..39cde03 100644 (file)
@@ -210,7 +210,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        ok_actionPerformed(e);
+        ok_actionPerformed();
       }
     });
     cancel.setOpaque(false);
@@ -220,7 +220,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        cancel_actionPerformed(e);
+        cancel_actionPerformed();
       }
     });
     defColours.setOpaque(false);
@@ -233,7 +233,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent arg0)
       {
-        resetColours_actionPerformed(arg0);
+        resetColours_actionPerformed();
       }
     });
 
@@ -242,7 +242,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        annotations_actionPerformed(e);
+        annotations_actionPerformed();
       }
     });
     getThreshold().addActionListener(new ActionListener()
@@ -250,7 +250,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        threshold_actionPerformed(e);
+        threshold_actionPerformed();
       }
     });
     thresholdValue.addActionListener(new ActionListener()
@@ -258,7 +258,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        thresholdValue_actionPerformed(e);
+        thresholdValue_actionPerformed();
       }
     });
     slider.setPaintLabels(false);
@@ -278,7 +278,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        currentColours_actionPerformed(e);
+        currentColours_actionPerformed();
       }
     });
     thresholdIsMin.setBackground(Color.white);
@@ -290,7 +290,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent actionEvent)
       {
-        thresholdIsMin_actionPerformed(actionEvent);
+        thresholdIsMin_actionPerformed();
       }
     });
     seqAssociated.setBackground(Color.white);
@@ -303,7 +303,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent arg0)
       {
-        seqAssociated_actionPerformed(arg0, annotations, seqAssociated);
+        seqAssociated_actionPerformed(annotations);
       }
     });
 
@@ -332,7 +332,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     this.validate();
   }
 
-  protected void resetColours_actionPerformed(ActionEvent arg0)
+  protected void resetColours_actionPerformed()
   {
     setDefaultMinMax();
     updateView();
@@ -372,6 +372,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     updateView();
   }
 
+  @Override
   public void reset()
   {
     av.setGlobalColourScheme(oldcs);
@@ -385,6 +386,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     }
   }
 
+  @Override
   public void valueChanged(boolean updateAllAnnotation)
   {
     if (slider.isEnabled())
@@ -411,7 +413,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     this.threshold = threshold;
   }
 
-  public void currentColours_actionPerformed(ActionEvent e)
+  public void currentColours_actionPerformed()
   {
     if (currentColours.isSelected())
     {
index c0d7084..1290d70 100644 (file)
@@ -178,7 +178,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        ok_actionPerformed(e);
+        ok_actionPerformed();
       }
     });
 
@@ -189,7 +189,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        cancel_actionPerformed(e);
+        cancel_actionPerformed();
       }
     });
 
@@ -201,7 +201,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        threshold_actionPerformed(e);
+        threshold_actionPerformed();
       }
     });
 
@@ -212,7 +212,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        thresholdValue_actionPerformed(e);
+        thresholdValue_actionPerformed();
       }
     });
 
@@ -288,14 +288,15 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     String defaultTtip = MessageManager
             .getString("info.change_threshold_mode_to_enable");
 
-    String threshold = getThreshold().getSelectedItem().toString();
-    if (threshold.equalsIgnoreCase("No Threshold"))
+    String thresh = getThreshold().getSelectedItem().toString();
+    if (thresh.equalsIgnoreCase("No Threshold"))
     {
       thresholdValue.setToolTipText(defaultTtip);
       slider.setToolTipText(defaultTtip);
     }
   }
 
+  @Override
   public void reset()
   {
     if (this.getOldColumnSelection() != null)
@@ -324,6 +325,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
 
   }
 
+  @Override
   public void valueChanged(boolean updateAllAnnotation)
   {
     if (slider.isEnabled())
index 469e495..0d47e36 100644 (file)
@@ -174,7 +174,8 @@ public class AnnotationExporter extends JPanel
       else
       {
         text = new FeaturesFile().printJalviewFormat(ap.av.getAlignment()
-                .getDataset().getSequencesArray(), displayedFeatureColours, true, ap.av.isShowNPFeats()); // ap.av.featuresDisplayed);
+                .getDataset().getSequencesArray(), displayedFeatureColours,
+                true, ap.av.isShowNPFeats()); // ap.av.featuresDisplayed);
         text = formatter.printJalviewFormat(sequences, featureColours,
                 true, includeNonPositional);
       }
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 0b2f6cc..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)
@@ -458,8 +458,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       String tlabel = null;
       if (anots[index] != null)
       { // LML added stem code
-        if (type.equals(HELIX) || type.equals(SHEET)
-                || type.equals(STEM) || type.equals(LABEL))
+        if (type.equals(HELIX) || type.equals(SHEET) || type.equals(STEM)
+                || type.equals(LABEL))
         {
           tlabel = anots[index].description;
           if (tlabel == null || tlabel.length() < 1)
@@ -814,8 +814,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       {
         text.append(", ")
                 .append(MessageManager.getString("label.sequence"))
-                .append(" ")
-                .append(seqIndex + 1);
+                .append(" ").append(seqIndex + 1);
         char residue = seqref.getCharAt(column);
         if (!Comparison.isGap(residue))
         {
index f0bea60..c8bd69c 100644 (file)
@@ -26,7 +26,6 @@ import jalview.datamodel.SequenceGroup;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.util.MessageManager;
 
-import java.awt.event.ActionEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.util.Vector;
@@ -52,7 +51,7 @@ public abstract class AnnotationRowFilter extends JPanel
 
   protected boolean enableSeqAss = false;
 
-  private jalview.datamodel.AlignmentAnnotation currentAnnotation;
+  private AlignmentAnnotation currentAnnotation;
 
   protected boolean adjusting = false;
 
@@ -161,11 +160,20 @@ public abstract class AnnotationRowFilter extends JPanel
         enableSeqAss = true;
       }
       String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+      // add associated sequence ID if available
+      if (!isSeqAssociated
+              && av.getAlignment().getAlignmentAnnotation()[i].sequenceRef != null)
+      {
+        label = label
+                + "_"
+                + av.getAlignment().getAlignmentAnnotation()[i].sequenceRef
+                        .getName();
+      }
+      // make label unique
       if (!list.contains(label))
       {
         anmap[list.size()] = i;
         list.add(label);
-
       }
       else
       {
@@ -200,7 +208,7 @@ public abstract class AnnotationRowFilter extends JPanel
     seqAssociated.setEnabled(enableSeqAss);
   }
 
-  public void ok_actionPerformed(ActionEvent e)
+  public void ok_actionPerformed()
   {
     try
     {
@@ -210,7 +218,7 @@ public abstract class AnnotationRowFilter extends JPanel
     }
   }
 
-  public void cancel_actionPerformed(ActionEvent e)
+  public void cancel_actionPerformed()
   {
     reset();
     ap.paintAlignment(true);
@@ -222,22 +230,22 @@ public abstract class AnnotationRowFilter extends JPanel
     }
   }
 
-  public void thresholdCheck_actionPerformed(ActionEvent e)
+  public void thresholdCheck_actionPerformed()
   {
     updateView();
   }
 
-  public void annotations_actionPerformed(ActionEvent e)
+  public void annotations_actionPerformed()
   {
     updateView();
   }
 
-  public void threshold_actionPerformed(ActionEvent e)
+  public void threshold_actionPerformed()
   {
     updateView();
   }
 
-  public void thresholdValue_actionPerformed(ActionEvent e)
+  public void thresholdValue_actionPerformed()
   {
     try
     {
@@ -249,7 +257,7 @@ public abstract class AnnotationRowFilter extends JPanel
     }
   }
 
-  public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
+  public void thresholdIsMin_actionPerformed()
   {
     updateView();
   }
@@ -264,8 +272,7 @@ public abstract class AnnotationRowFilter extends JPanel
             .getString("label.threshold_feature_below_threshold"));
   }
 
-  protected void seqAssociated_actionPerformed(ActionEvent arg0,
-          JComboBox<String> annotations, JCheckBox seqAssociated)
+  protected void seqAssociated_actionPerformed(JComboBox<String> annotations)
   {
     adjusting = true;
     String cursel = (String) annotations.getSelectedItem();
@@ -322,26 +329,25 @@ public abstract class AnnotationRowFilter extends JPanel
     }
   }
 
-  protected boolean colorAlignmContaining(
-          AlignmentAnnotation currentAnnotation, int selectedThresholdItem)
+  protected boolean colorAlignmContaining(AlignmentAnnotation currentAnn,
+          int selectedThresholdOption)
   {
 
     AnnotationColourGradient acg = null;
     if (currentColours.isSelected())
     {
-      acg = new AnnotationColourGradient(currentAnnotation,
-              av.getGlobalColourScheme(), selectedThresholdItem);
+      acg = new AnnotationColourGradient(currentAnn,
+              av.getGlobalColourScheme(), selectedThresholdOption);
     }
     else
     {
-      acg = new AnnotationColourGradient(currentAnnotation,
+      acg = new AnnotationColourGradient(currentAnn,
               minColour.getBackground(), maxColour.getBackground(),
-              selectedThresholdItem);
+              selectedThresholdOption);
     }
     acg.setSeqAssociated(seqAssociated.isSelected());
 
-    if (currentAnnotation.graphMin == 0f
-            && currentAnnotation.graphMax == 0f)
+    if (currentAnn.graphMin == 0f && currentAnn.graphMax == 0f)
     {
       acg.setPredefinedColours(true);
     }
@@ -362,17 +368,17 @@ public abstract class AnnotationRowFilter extends JPanel
 
         if (currentColours.isSelected())
         {
-          sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
-                  selectedThresholdItem);
+          sg.cs = new AnnotationColourGradient(currentAnn, sg.cs,
+                  selectedThresholdOption);
           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
                   .isSelected());
 
         }
         else
         {
-          sg.cs = new AnnotationColourGradient(currentAnnotation,
+          sg.cs = new AnnotationColourGradient(currentAnn,
                   minColour.getBackground(), maxColour.getBackground(),
-                  selectedThresholdItem);
+                  selectedThresholdOption);
           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
                   .isSelected());
         }
index a1846bc..e2e54aa 100644 (file)
@@ -41,6 +41,7 @@ import jalview.schemes.ZappoColourScheme;
 import jalview.structures.models.AAStructureBindingModel;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
+import jalview.ws.dbsources.Pdb;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -49,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;
@@ -66,10 +66,10 @@ 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;
+import javax.swing.SwingUtilities;
 import javax.swing.event.InternalFrameAdapter;
 import javax.swing.event.InternalFrameEvent;
 import javax.swing.event.MenuEvent;
@@ -77,6 +77,13 @@ import javax.swing.event.MenuListener;
 
 public class AppJmol extends StructureViewerBase
 {
+  // ms to wait for Jmol to load files
+  private static final int JMOL_LOAD_TIMEOUT = 20000;
+
+  private static final String SPACE = " ";
+
+  private static final String BACKSLASH = "\"";
+
   AppJmolBinding jmb;
 
   JPanel scriptWindow;
@@ -122,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);
@@ -292,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)
@@ -303,12 +310,10 @@ public class AppJmol extends StructureViewerBase
     jmb.setColourBySequence(true);
     setSize(400, 400); // probably should be a configurable/dynamic default here
     initMenus();
-    worker = null;
-    {
-      addingStructures = false;
-      worker = new Thread(this);
-      worker.start();
-    }
+    addingStructures = false;
+    worker = new Thread(this);
+    worker.start();
+
     this.addInternalFrameListener(new InternalFrameAdapter()
     {
       @Override
@@ -375,8 +380,8 @@ public class AppJmol extends StructureViewerBase
       scriptWindow.setVisible(false);
     }
 
-    jmb.allocateViewer(renderPanel, true, "", null, null, "", scriptWindow,
-            null);
+    jmb.allocateViewer(renderPanel, true, "", null, null, "",
+            scriptWindow, null);
     // jmb.newJmolPopup("Jmol");
     if (command == null)
     {
@@ -387,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++)
@@ -475,15 +435,168 @@ public class AppJmol extends StructureViewerBase
   public void run()
   {
     _started = true;
+    try
+    {
+      List<String> files = fetchPdbFiles();
+      if (files.size() > 0)
+      {
+        showFilesInViewer(files);
+      }
+    } finally
+    {
+      _started = false;
+      worker = null;
+    }
+  }
+
+  /**
+   * Either adds the given files to a structure viewer or opens a new viewer to
+   * show them
+   * 
+   * @param files
+   *          list of absolute paths to structure files
+   */
+  void showFilesInViewer(List<String> files)
+  {
+    long lastnotify = jmb.getLoadNotifiesHandled();
+    StringBuilder fileList = new StringBuilder();
+    for (String s : files)
+    {
+      fileList.append(SPACE).append(BACKSLASH)
+              .append(Platform.escapeString(s)).append(BACKSLASH);
+    }
+    String filesString = fileList.toString();
+
+    if (!addingStructures)
+    {
+      try
+      {
+        initJmol("load FILES " + filesString);
+      } catch (OutOfMemoryError oomerror)
+      {
+        new OOMWarning("When trying to open the Jmol viewer!", oomerror);
+        Cache.log.debug("File locations are " + filesString);
+      } catch (Exception ex)
+      {
+        Cache.log.error("Couldn't open Jmol viewer!", ex);
+      }
+    }
+    else
+    {
+      StringBuilder cmd = new StringBuilder();
+      cmd.append("loadingJalviewdata=true\nload APPEND ");
+      cmd.append(filesString);
+      cmd.append("\nloadingJalviewdata=null");
+      final String command = cmd.toString();
+      lastnotify = jmb.getLoadNotifiesHandled();
+
+      try
+      {
+        jmb.evalStateCommand(command);
+      } catch (OutOfMemoryError oomerror)
+      {
+        new OOMWarning("When trying to add structures to the Jmol viewer!",
+                oomerror);
+        Cache.log.debug("File locations are " + filesString);
+      } catch (Exception ex)
+      {
+        Cache.log.error("Couldn't add files to Jmol viewer!", ex);
+      }
+    }
+
+    // need to wait around until script has finished
+    int waitMax = JMOL_LOAD_TIMEOUT;
+    int waitFor = 35;
+    int waitTotal = 0;
+    while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled()
+            : !(jmb.isFinishedInit() && jmb.getPdbFile() != null && jmb
+                    .getPdbFile().length == files.size()))
+    {
+      try
+      {
+        Cache.log.debug("Waiting around for jmb notify.");
+        Thread.sleep(waitFor);
+        waitTotal += waitFor;
+      } catch (Exception e)
+      {
+      }
+      if (waitTotal > waitMax)
+      {
+        System.err
+                .println("Timed out waiting for Jmol to load files after "
+                        + waitTotal + "ms");
+//        System.err.println("finished: " + jmb.isFinishedInit()
+//                + "; loaded: " + Arrays.toString(jmb.getPdbFile())
+//                + "; files: " + files.toString());
+        jmb.getPdbFile();
+        break;
+      }
+    }
+
+    // refresh the sequence colours for the new structure(s)
+    for (AlignmentPanel ap : _colourwith)
+    {
+      jmb.updateColours(ap);
+    }
+    // do superposition if asked to
+    if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures)
+    {
+      alignAddedStructures();
+    }
+    addingStructures = false;
+  }
+
+  /**
+   * Queues a thread to align structures with Jalview alignments
+   */
+  void alignAddedStructures()
+  {
+    javax.swing.SwingUtilities.invokeLater(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        if (jmb.viewer.isScriptExecuting())
+        {
+          SwingUtilities.invokeLater(this);
+          try
+          {
+            Thread.sleep(5);
+          } catch (InterruptedException q)
+          {
+          }
+          return;
+        }
+        else
+        {
+          alignStructs_withAllAlignPanels();
+        }
+      }
+    });
+    alignAddedStructures = false;
+  }
+
+  /**
+   * Retrieves and saves as file any modelled PDB entries for which we do not
+   * already have a file saved. Returns a list of absolute paths to structure
+   * files which were either retrieved, or already stored but not modelled in
+   * the structure viewer (i.e. files to add to the viewer display).
+   * 
+   * @return
+   */
+  List<String> fetchPdbFiles()
+  {
+    // todo - record which pdbids were successfully imported.
+    StringBuilder errormsgs = new StringBuilder();
+
+    List<String> files = new ArrayList<String>();
     String pdbid = "";
-    // todo - record which pdbids were successfuly imported.
-    StringBuffer errormsgs = new StringBuffer(), files = new StringBuffer();
     try
     {
-      String[] curfiles = jmb.getPdbFile(); // files currently in viewer
+      String[] filesInViewer = jmb.getPdbFile();
       // TODO: replace with reference fetching/transfer code (validate PDBentry
       // as a DBRef?)
-      jalview.ws.dbsources.Pdb pdbclient = new jalview.ws.dbsources.Pdb();
+      Pdb pdbclient = new Pdb();
       for (int pi = 0; pi < jmb.getPdbCount(); pi++)
       {
         String file = jmb.getPdbEntry(pi).getFile();
@@ -507,12 +620,15 @@ public class AppJmol extends StructureViewerBase
           } catch (Exception ex)
           {
             ex.printStackTrace();
-            errormsgs.append("'" + pdbid + "'");
-          }
-          if (progressBar != null)
+            errormsgs.append("'").append(pdbid).append("'");
+          } finally
           {
-            progressBar.setProgressBar(
-                    MessageManager.getString("label.state_completed"), hdl);
+            if (progressBar != null)
+            {
+              progressBar.setProgressBar(
+                      MessageManager.getString("label.state_completed"),
+                      hdl);
+            }
           }
           if (pdbseq != null)
           {
@@ -521,22 +637,21 @@ public class AppJmol extends StructureViewerBase
             file = new File(pdbseq.getSequenceAt(0).getAllPDBEntries()
                     .elementAt(0).getFile()).getAbsolutePath();
             jmb.getPdbEntry(pi).setFile(file);
-
-            files.append(" \"" + Platform.escapeString(file) + "\"");
+            files.add(file);
           }
           else
           {
-            errormsgs.append("'" + pdbid + "' ");
+            errormsgs.append("'").append(pdbid).append("' ");
           }
         }
         else
         {
-          if (curfiles != null && curfiles.length > 0)
+          if (filesInViewer != null && filesInViewer.length > 0)
           {
             addingStructures = true; // already files loaded.
-            for (int c = 0; c < curfiles.length; c++)
+            for (int c = 0; c < filesInViewer.length; c++)
             {
-              if (curfiles[c].equals(file))
+              if (filesInViewer[c].equals(file))
               {
                 file = null;
                 break;
@@ -545,7 +660,7 @@ public class AppJmol extends StructureViewerBase
           }
           if (file != null)
           {
-            files.append(" \"" + Platform.escapeString(file) + "\"");
+            files.add(file);
           }
         }
       }
@@ -555,114 +670,18 @@ public class AppJmol extends StructureViewerBase
     } catch (Exception ex)
     {
       ex.printStackTrace();
-      errormsgs.append("When retrieving pdbfiles : current was: '" + pdbid
-              + "'");
+      errormsgs.append("When retrieving pdbfiles : current was: '")
+              .append(pdbid).append("'");
     }
     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);
-
-    }
-    long lastnotify = jmb.getLoadNotifiesHandled();
-    if (files.length() > 0)
-    {
-      if (!addingStructures)
-      {
-
-        try
-        {
-          initJmol("load FILES " + files.toString());
-        } catch (OutOfMemoryError oomerror)
-        {
-          new OOMWarning("When trying to open the Jmol viewer!", oomerror);
-          Cache.log.debug("File locations are " + files);
-        } catch (Exception ex)
-        {
-          Cache.log.error("Couldn't open Jmol viewer!", ex);
-        }
-      }
-      else
-      {
-        StringBuffer cmd = new StringBuffer();
-        cmd.append("loadingJalviewdata=true\nload APPEND ");
-        cmd.append(files.toString());
-        cmd.append("\nloadingJalviewdata=null");
-        final String command = cmd.toString();
-        cmd = null;
-        lastnotify = jmb.getLoadNotifiesHandled();
-
-        try
-        {
-          jmb.evalStateCommand(command);
-        } catch (OutOfMemoryError oomerror)
-        {
-          new OOMWarning(
-                  "When trying to add structures to the Jmol viewer!",
-                  oomerror);
-          Cache.log.debug("File locations are " + files);
-        } catch (Exception ex)
-        {
-          Cache.log.error("Couldn't add files to Jmol viewer!", ex);
-        }
-      }
-
-      // need to wait around until script has finished
-      while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled()
-              : (!jmb.isFinishedInit() && jmb.getPdbFile() != null && jmb
-                      .getPdbFile().length != jmb.getPdbCount()))
-      {
-        try
-        {
-          Cache.log.debug("Waiting around for jmb notify.");
-          Thread.sleep(35);
-        } catch (Exception e)
-        {
-        }
-      }
-
-      // refresh the sequence colours for the new structure(s)
-      for (AlignmentPanel ap : _colourwith)
-      {
-        jmb.updateColours(ap);
-      }
-      // do superposition if asked to
-      if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures)
-      {
-        javax.swing.SwingUtilities.invokeLater(new Runnable()
-        {
-          @Override
-          public void run()
-          {
-            if (jmb.viewer.isScriptExecuting())
-            {
-              javax.swing.SwingUtilities.invokeLater(this);
-              try
-              {
-                Thread.sleep(5);
-              } catch (InterruptedException q)
-              {
-              }
-              ;
-              return;
-            }
-            else
-            {
-              alignStructs_withAllAlignPanels();
-            }
-          }
-        });
-        alignAddedStructures = false;
-      }
-      addingStructures = false;
-
+              JvOptionPane.ERROR_MESSAGE);
     }
-    _started = false;
-    worker = null;
+    return files;
   }
 
   @Override
@@ -1009,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 592f56c..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)
@@ -660,16 +570,17 @@ public class ChimeraViewFrame extends StructureViewerBase
           {
             int pos = filePDBpos.get(num).intValue();
             long startTime = startProgressBar("Chimera "
-                    + MessageManager.getString("status.opening_file"));
+                    + MessageManager.getString("status.opening_file_for")
+                    + " " + pe.getId());
             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)
             {
@@ -678,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(
@@ -695,6 +607,7 @@ public class ChimeraViewFrame extends StructureViewerBase
           }
         }
       }
+      jmb.refreshGUI();
       jmb.setFinishedInit(true);
       jmb.setLoadingFromArchive(false);
 
@@ -730,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 00b359a..77bc7d4 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;
@@ -382,6 +392,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
     showNews.setVisible(false);
 
+    checkURLLinks();
+
     this.addWindowListener(new WindowAdapter()
     {
       @Override
@@ -452,11 +464,11 @@ 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"),
+        // jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
+        // jalview.io.AppletFormatAdapter.READABLE_FNAMES,
+                fileFormat, true);
         Cache.log.debug("Filechooser init thread finished.");
       }
     }).start();
@@ -676,10 +688,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)
@@ -941,9 +953,12 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   public void drop(DropTargetDropEvent evt)
   {
     boolean success = true;
+    // JAL-1552 - acceptDrop required before getTransferable call for
+    // 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
     {
@@ -961,13 +976,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
@@ -996,11 +1011,12 @@ 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"),
+            // AppletFormatAdapter.READABLE_EXTENSIONS,
+            // AppletFormatAdapter.READABLE_FNAMES,
+            fileFormat, true);
 
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
@@ -1012,28 +1028,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);
       }
     }
   }
@@ -1074,11 +1096,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;
     }
@@ -1089,36 +1111,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);
       }
     }
   }
@@ -1202,9 +1234,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
@@ -1504,8 +1536,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" },
+            Cache.getProperty("LAST_DIRECTORY"), "jvp", "Jalview Project",
             "Jalview Project");
 
     chooser.setFileView(new JalviewFileView());
@@ -1544,11 +1575,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());
         }
@@ -1576,7 +1607,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());
@@ -1589,7 +1620,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()
       {
@@ -1610,12 +1641,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());
         }
@@ -1900,7 +1931,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(
@@ -1908,7 +1939,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);
         }
       }
     }
@@ -2160,9 +2191,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", "Vamsas Document");
 
       chooser.setFileView(new JalviewFileView());
       chooser.setDialogTitle(MessageManager
@@ -2176,7 +2206,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
@@ -2200,9 +2230,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);
         }
       }
     }
@@ -2218,7 +2248,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)
@@ -2253,6 +2283,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
@@ -2454,11 +2562,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);
     }
   }
 
@@ -2514,8 +2622,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   {
     getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
             KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
-                    .getDefaultToolkit().getMenuShortcutKeyMask()),
-            "Quit");
+                    .getDefaultToolkit().getMenuShortcutKeyMask()), "Quit");
     getRootPane().getActionMap().put("Quit", new AbstractAction()
     {
       @Override
@@ -2800,7 +2907,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
                  * 
                  * jd.waitForInput();
                  */
-                JOptionPane
+                JvOptionPane
                         .showConfirmDialog(
                                 Desktop.desktop,
                                 new JLabel(
@@ -2812,8 +2919,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;
 
               }
@@ -2870,11 +2977,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();
         }
@@ -3171,7 +3278,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
   {
 
@@ -3181,12 +3289,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     {
       // Works on Windows and MacOSX
       Cache.log.debug("Drop handled as javaFileListFlavor");
-      evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
       for (Object file : (List) t
               .getTransferData(DataFlavor.javaFileListFlavor))
       {
-        files.add(((File)file).toString());
-        protocols.add(FormatAdapter.FILE);
+        files.add(((File) file).toString());
+        protocols.add(DataSourceType.FILE);
       }
     }
     else
@@ -3198,7 +3305,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       {
         Cache.log.debug("Drop handled as uriListFlavor");
         // This is used by Unix drag system
-        evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
         data = (String) t.getTransferData(uriListFlavor);
       }
       if (data == null)
@@ -3217,7 +3323,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 +3338,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());
         }
       }
@@ -3253,7 +3359,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements
           {
             Cache.log.debug("Supported transfer dataflavor: "
                     + fl.toString());
-            evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
             Object df = t.getTransferData(fl);
             if (df != null)
             {
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 874ce16..d65016e 100644 (file)
@@ -749,10 +749,8 @@ 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" },
-            "Sequence Feature Colours");
+            Cache.getProperty("LAST_DIRECTORY"), "fc",
+            "Sequence Feature Colours", "Sequence Feature Colours");
     chooser.setFileView(new jalview.io.JalviewFileView());
     chooser.setDialogTitle(MessageManager
             .getString("label.load_feature_colours"));
@@ -844,10 +842,8 @@ public class FeatureSettings extends JPanel implements
   void save()
   {
     JalviewFileChooser chooser = new JalviewFileChooser(
-            Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "fc" },
-            new String[] { "Sequence Feature Colours" },
-            "Sequence Feature Colours");
+            Cache.getProperty("LAST_DIRECTORY"), "fc",
+            "Sequence Feature Colours", "Sequence Feature Colours");
     chooser.setFileView(new jalview.io.JalviewFileView());
     chooser.setDialogTitle(MessageManager
             .getString("label.save_feature_colours"));
@@ -1403,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 8f16e77..f2d8113 100644 (file)
@@ -37,8 +37,8 @@ public class Help
 {
   public enum HelpId
   {
-    Home("home"), SequenceFeatureSettings("seqfeatures.settings"), StructureViewer(
-            "viewingpdbs");
+    Home("home"), SequenceFeatureSettings("seqfeatures.settings"),
+    StructureViewer("viewingpdbs");
 
     private String id;
 
index 05166ad..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();
     }
   }
@@ -334,8 +341,8 @@ public class IdPanel extends JPanel implements MouseListener,
     }
 
     if ((av.getSelectionGroup() == null)
-            || (!jalview.util.Platform.isControlDown(e)
-                    && !e.isShiftDown() && av.getSelectionGroup() != null))
+            || (!jalview.util.Platform.isControlDown(e) && !e.isShiftDown() && av
+                    .getSelectionGroup() != null))
     {
       av.setSelectionGroup(new SequenceGroup());
       av.getSelectionGroup().setStartRes(0);
@@ -368,8 +375,7 @@ public class IdPanel extends JPanel implements MouseListener,
     Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq2);
     // build a new links menu based on the current links + any non-positional
     // features
-    Vector<String> nlinks = new Vector<String>(
-            Preferences.sequenceURLLinks);
+    Vector<String> nlinks = new Vector<String>(Preferences.sequenceURLLinks);
     SequenceFeature sfs[] = sq == null ? null : sq.getSequenceFeatures();
     if (sfs != null)
     {
index 47a8faf..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;
@@ -314,6 +316,7 @@ public class Jalview2XML
       }
       return sq;
     }
+
     /**
      * @return true if the forward reference was fully resolved
      */
@@ -388,35 +391,44 @@ public class Jalview2XML
 
   public void resolveFrefedSequences()
   {
-    Iterator<SeqFref> nextFref=frefedSequence.iterator();
-    int toresolve=frefedSequence.size();
-    int unresolved=0,failedtoresolve=0;
-    while (nextFref.hasNext()) {
+    Iterator<SeqFref> nextFref = frefedSequence.iterator();
+    int toresolve = frefedSequence.size();
+    int unresolved = 0, failedtoresolve = 0;
+    while (nextFref.hasNext())
+    {
       SeqFref ref = nextFref.next();
       if (ref.isResolvable())
       {
-        try {
+        try
+        {
           if (ref.resolve())
           {
             nextFref.remove();
-          } else {
+          }
+          else
+          {
             failedtoresolve++;
           }
-        } catch (Exception x) {
-          System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref());
+        } catch (Exception x)
+        {
+          System.err
+                  .println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
+                          + ref.getSref());
           x.printStackTrace();
           failedtoresolve++;
-        } 
-      } else {
+        }
+      }
+      else
+      {
         unresolved++;
       }
     }
-    if (unresolved>0)
+    if (unresolved > 0)
     {
       System.err.println("Jalview Project Import: There were " + unresolved
               + " forward references left unresolved on the stack.");
     }
-    if (failedtoresolve>0)
+    if (failedtoresolve > 0)
     {
       System.err.println("SERIOUS! " + failedtoresolve
               + " resolvable forward references failed to resolve.");
@@ -795,7 +807,7 @@ public class Jalview2XML
     JSeq jseq;
     Set<String> calcIdSet = new HashSet<String>();
     // record the set of vamsas sequence XML POJO we create.
-    HashMap<String,Sequence> vamsasSetIds = new HashMap<String,Sequence>(); 
+    HashMap<String, Sequence> vamsasSetIds = new HashMap<String, Sequence>();
     // SAVE SEQUENCES
     for (final SequenceI jds : rjal.getSequences())
     {
@@ -848,8 +860,7 @@ public class Jalview2XML
           if (av.isHiddenRepSequence(jds))
           {
             jalview.datamodel.SequenceI[] reps = av
-                    .getRepresentedSequences(jds)
-                    .getSequencesInOrder(rjal);
+                    .getRepresentedSequences(jds).getSequencesInOrder(rjal);
 
             for (int h = 0; h < reps.length; h++)
             {
@@ -983,17 +994,16 @@ public class Jalview2XML
             }
           }
 
-          if (entry.getProperty() != null && !entry.getProperty().isEmpty())
+          Enumeration<String> props = entry.getProperties();
+          if (props.hasMoreElements())
           {
             PdbentryItem item = new PdbentryItem();
-            Hashtable properties = entry.getProperty();
-            Enumeration en2 = properties.keys();
-            while (en2.hasMoreElements())
+            while (props.hasMoreElements())
             {
               Property prop = new Property();
-              String key = en2.nextElement().toString();
+              String key = props.nextElement();
               prop.setName(key);
-              prop.setValue(properties.get(key).toString());
+              prop.setValue(entry.getProperty(key).toString());
               item.addProperty(prop);
             }
             pdb.addPdbentryItem(item);
@@ -1341,8 +1351,7 @@ public class Jalview2XML
           for (String featureType : renderOrder)
           {
             FeatureColourI fcol = ap.getSeqPanel().seqCanvas
-                    .getFeatureRenderer()
-                    .getFeatureStyle(featureType);
+                    .getFeatureRenderer().getFeatureStyle(featureType);
             Setting setting = new Setting();
             setting.setType(featureType);
             if (!fcol.isSimpleColour())
@@ -1355,8 +1364,8 @@ public class Jalview2XML
               setting.setAutoScale(fcol.isAutoScaled());
               setting.setThreshold(fcol.getThreshold());
               // -1 = No threshold, 0 = Below, 1 = Above
-              setting.setThreshstate(fcol.isAboveThreshold() ? 1
-                      : (fcol.isBelowThreshold() ? 0 : -1));
+              setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol
+                      .isBelowThreshold() ? 0 : -1));
             }
             else
             {
@@ -1378,8 +1387,7 @@ public class Jalview2XML
 
         // is groups actually supposed to be a map here ?
         Iterator<String> en = ap.getSeqPanel().seqCanvas
-                .getFeatureRenderer()
-                .getFeatureGroups().iterator();
+                .getFeatureRenderer().getFeatureGroups().iterator();
         Vector<String> groupsAdded = new Vector<String>();
         while (en.hasNext())
         {
@@ -2537,6 +2545,8 @@ public class Jalview2XML
           SplitFrame sf = createSplitFrame(dnaFrame, af);
           addedToSplitFrames.add(dnaFrame);
           addedToSplitFrames.add(af);
+          dnaFrame.setMenusForViewport();
+          af.setMenusForViewport();
           if (af.viewport.isGatherViewsHere())
           {
             gatherTo.add(sf);
@@ -2558,6 +2568,7 @@ public class Jalview2XML
         Viewport view = candidate.getKey();
         Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
                 view.getHeight());
+        af.setMenusForViewport();
         System.err.println("Failed to restore view " + view.getTitle()
                 + " to split frame");
       }
@@ -2627,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);
           }
         });
       }
@@ -2813,7 +2824,6 @@ public class Jalview2XML
 
     List<SequenceI> hiddenSeqs = null;
 
-
     List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
 
     boolean multipleView = false;
@@ -2830,13 +2840,16 @@ public class Jalview2XML
         if (!incompleteSeqs.containsKey(seqId))
         {
           // may not need this check, but keep it for at least 2.9,1 release
-          if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
-          { 
+          if (tmpSeq.getStart() != jseqs[i].getStart()
+                  || tmpSeq.getEnd() != jseqs[i].getEnd())
+          {
             System.err
                     .println("Warning JAL-2154 regression: updating start/end for sequence "
                             + tmpSeq.toString() + " to " + jseqs[i]);
           }
-        } else {
+        }
+        else
+        {
           incompleteSeqs.remove(seqId);
         }
         if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
@@ -3006,7 +3019,8 @@ public class Jalview2XML
                 entry.setType(PDBEntry.Type.FILE);
               }
             }
-            if (ids[p].getFile() != null)
+            // jprovider is null when executing 'New View'
+            if (ids[p].getFile() != null && jprovider != null)
             {
               if (!pdbloaded.containsKey(ids[p].getFile()))
               {
@@ -3020,12 +3034,11 @@ public class Jalview2XML
             }
             if (ids[p].getPdbentryItem() != null)
             {
-              entry.setProperty(new Hashtable());
               for (PdbentryItem item : ids[p].getPdbentryItem())
               {
                 for (Property pr : item.getProperty())
                 {
-                  entry.getProperty().put(pr.getName(), pr.getValue());
+                  entry.setProperty(pr.getName(), pr.getValue());
                 }
               }
             }
@@ -3390,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);
@@ -4009,11 +4022,10 @@ public class Jalview2XML
         // filename
         // translation differently.
         StructureData filedat = oldFiles.get(new File(oldfilenam));
-          if (filedat == null)
-          {
-            String reformatedOldFilename = oldfilenam.replaceAll("/",
-                    "\\\\");
-            filedat = oldFiles.get(new File(reformatedOldFilename));
+        if (filedat == null)
+        {
+          String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
+          filedat = oldFiles.get(new File(reformatedOldFilename));
         }
         newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
         pdbfilenames.add(filedat.getFilePath());
@@ -4220,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
@@ -4336,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 040a1e5..e584eb7 100644 (file)
@@ -579,8 +579,8 @@ public class OptsAndParamsPage
       if (!adjusting)
       {
         valueField.setText(""
-                + ((integ) ? ("" + slider.getValue())
-                        : ("" + slider.getValue() / 1000f)));
+                + ((integ) ? ("" + slider.getValue()) : ("" + slider
+                        .getValue() / 1000f)));
         checkIfModified();
       }
 
index d09c756..1c48690 100755 (executable)
@@ -480,6 +480,7 @@ public class OverviewPanel extends JPanel implements Runnable
   }
 
   private BufferedImage lastMiniMe = null;
+
   /**
    * DOCUMENT ME!
    * 
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 939c087..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
@@ -928,8 +863,7 @@ public class PopupMenu extends JPopupMenu
         urlLink = new GroupUrlLink(link);
       } catch (Exception foo)
       {
-        Cache.log.error("Exception for GroupURLLink '" + link
-                + "'", foo);
+        Cache.log.error("Exception for GroupURLLink '" + link + "'", foo);
         continue;
       }
       ;
@@ -1005,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
    * 
@@ -1735,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>"
@@ -1750,7 +1693,6 @@ public class PopupMenu extends JPopupMenu
                       seq,
                       true,
                       true,
-                      false,
                       (ap.getSeqPanel().seqCanvas.fr != null) ? ap
                               .getSeqPanel().seqCanvas.fr.getMinMax()
                               : null);
@@ -2038,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);
 
@@ -2147,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(' ', '_'));
@@ -2253,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();
     }
@@ -2332,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 afc93e0..e46a555 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;
@@ -110,10 +116,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 +127,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 +144,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);
       }
     }
 
@@ -536,8 +539,8 @@ public class Preferences extends GPreferences
     /*
      * Save Output settings
      */
-      Cache.applicationProperties.setProperty("EPS_RENDERING",
-              ((OptionsParam) epsRendering.getSelectedItem()).getCode());
+    Cache.applicationProperties.setProperty("EPS_RENDERING",
+            ((OptionsParam) epsRendering.getSelectedItem()).getCode());
 
     /*
      * Save Connections settings
@@ -565,6 +568,7 @@ public class Preferences extends GPreferences
     else
     {
       Cache.applicationProperties.remove("SEQUENCE_LINKS");
+      sequenceURLLinks.clear();
     }
 
     Cache.applicationProperties.setProperty("USE_PROXY",
@@ -683,12 +687,14 @@ 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, true);
+    // new String[] {
+    // "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
+    // "jar" }, new String[] { "Fasta", "Clustal", "PFAM", "MSF",
+    // "PIR", "BLC", "Jalview" },
+    // fileFormat);
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(MessageManager
             .getString("label.select_startup_file"));
@@ -697,8 +703,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 +761,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 +788,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 +802,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 +828,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 +923,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 +949,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 +988,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
         {
@@ -1046,7 +1056,8 @@ public class Preferences extends GPreferences
     }
 
     @Override
-    public int hashCode(){
+    public int hashCode()
+    {
       return name.hashCode() + code.hashCode();
     }
   }
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 136d222..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;
     }
 
@@ -1752,7 +1754,7 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
     PaintRefresher.Refresh(this, av.getSequenceSetId());
     ap.paintAlignment(needOverviewUpdate);
-    needOverviewUpdate =false;
+    needOverviewUpdate = false;
     changeEndRes = false;
     changeStartRes = false;
     stretchGroup = null;
@@ -2012,8 +2014,8 @@ public class SeqPanel extends JPanel implements MouseListener,
     {
       if (av.getAlignment() == null)
       {
-        Cache.log.warn("alignviewport av SeqSetId="
-                + av.getSequenceSetId() + " ViewId=" + av.getViewId()
+        Cache.log.warn("alignviewport av SeqSetId=" + av.getSequenceSetId()
+                + " ViewId=" + av.getViewId()
                 + " 's alignment is NULL! returning immediately.");
         return;
       }
index 5d4ea68..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;
@@ -167,9 +168,8 @@ public class SequenceFetcher extends JPanel implements Runnable
     if (sfetch == null
             || dasRegistry != Cache.getDasSourceRegistry()
             || lastDasSourceRegistry != (Cache.getDasSourceRegistry()
-                    .getDasRegistryURL() + Cache
-                    .getDasSourceRegistry().getLocalSourceString())
-                    .hashCode())
+                    .getDasRegistryURL() + Cache.getDasSourceRegistry()
+                    .getLocalSourceString()).hashCode())
     {
       _initingFetcher = true;
       initingThread = Thread.currentThread();
@@ -213,7 +213,7 @@ public class SequenceFetcher extends JPanel implements Runnable
   public SequenceFetcher(IProgressIndicator guiIndic,
           final String selectedDb, final String queryString)
   {
-    this._isConstructing=true;
+    this._isConstructing = true;
     this.progressIndicator = guiIndic;
     final SequenceFetcher us = this;
     // launch initialiser thread
@@ -226,7 +226,7 @@ public class SequenceFetcher extends JPanel implements Runnable
         if (getSequenceFetcherSingleton(progressIndicator) != null)
         {
           us.initGui(progressIndicator, selectedDb, queryString);
-          us._isConstructing=false;
+          us._isConstructing = false;
         }
         else
         {
@@ -235,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);
             }
           });
 
@@ -252,17 +252,23 @@ public class SequenceFetcher extends JPanel implements Runnable
     });
     sf.start();
   }
+
   /**
-   * blocking call which creates a new sequence fetcher panel, configures it and presses the OK button with the given database and query.
+   * blocking call which creates a new sequence fetcher panel, configures it and
+   * presses the OK button with the given database and query.
+   * 
    * @param database
    * @param query
    */
   public static List<AlignFrame> fetchAndShow(String database, String query)
   {
-    final SequenceFetcher sf = new SequenceFetcher(Desktop.instance, database, query);
+    final SequenceFetcher sf = new SequenceFetcher(Desktop.instance,
+            database, query);
     while (sf._isConstructing)
     {
-      try { Thread.sleep(50);
+      try
+      {
+        Thread.sleep(50);
       } catch (Exception q)
       {
         return Collections.emptyList();
@@ -282,7 +288,7 @@ public class SequenceFetcher extends JPanel implements Runnable
   {
 
   };
-  
+
   /**
    * initialise the database and query for this fetcher panel
    * 
@@ -523,6 +529,7 @@ public class SequenceFetcher extends JPanel implements Runnable
     new UniprotFTSPanel(this);
     frame.dispose();
   }
+
   private void otherSourceAction()
   {
     try
@@ -912,8 +919,8 @@ public class SequenceFetcher extends JPanel implements Runnable
     } catch (Exception e)
     {
       Cache.log.info(
-              "Error retrieving " + accession
-              + " from " + proxy.getDbName(), e);
+              "Error retrieving " + accession + " from "
+                      + proxy.getDbName(), e);
     }
     return success;
   }
@@ -972,7 +979,7 @@ public class SequenceFetcher extends JPanel implements Runnable
   }
 
   AlignmentI parseResult(AlignmentI al, String title,
-          String currentFileFormat,
+          FileFormatI currentFileFormat,
           FeatureSettingsModelI preferredFeatureColours)
   {
 
@@ -1032,8 +1039,7 @@ public class SequenceFetcher extends JPanel implements Runnable
 
         try
         {
-          af.setMaximum(Cache.getDefault("SHOW_FULLSCREEN",
-                  false));
+          af.setMaximum(Cache.getDefault("SHOW_FULLSCREEN", false));
         } catch (Exception ex)
         {
         }
@@ -1054,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 c3fec4f..a381e8b 100755 (executable)
@@ -219,8 +219,9 @@ public class SliderPanel extends GSliderPanel
       pid.cs = cs;
     }
 
-    PIDSlider.setTitle(MessageManager
-            .formatMessage("label.percentage_identity_threshold",
+    PIDSlider
+            .setTitle(MessageManager.formatMessage(
+                    "label.percentage_identity_threshold",
                     new String[] { source }));
 
     if (ap.av.getAlignment().getGroups() != null)
index 1bc85d2..6c849c3 100644 (file)
@@ -70,7 +70,9 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
   private static final int WINDOWS_INSETS_HEIGHT = 50; // tbc
 
   private static final int MAC_INSETS_HEIGHT = 50;
+
   private static final int DESKTOP_DECORATORS_HEIGHT = 65;
+
   private static final long serialVersionUID = 1L;
 
   public SplitFrame(GAlignFrame top, GAlignFrame bottom)
@@ -723,6 +725,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
     return Arrays.asList(new AlignFrame[] { (AlignFrame) getTopFrame(),
         (AlignFrame) getBottomFrame() });
   }
+
   /**
    * Replace Cmd-F Find action with our version. This is necessary because the
    * 'default' Finder searches in the first AlignFrame it finds. We need it to
index 33c7ff3..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,7 +66,7 @@ import javax.swing.table.AbstractTableModel;
 public class StructureChooser extends GStructureChooser implements
         IProgressIndicator
 {
-  private boolean structuresDiscovered = false;
+  private static int MAX_QLENGTH = 7820;
 
   private SequenceI selectedSequence;
 
@@ -83,6 +84,8 @@ public class StructureChooser extends GStructureChooser implements
 
   private boolean isValidPBDEntry;
 
+  private boolean cachedPDBExists;
+
   public StructureChooser(SequenceI[] selectedSeqs, SequenceI selectedSeq,
           AlignmentPanel ap)
   {
@@ -103,6 +106,8 @@ public class StructureChooser extends GStructureChooser implements
       progressBar = new ProgressBar(this.statusPanel, this.statusBar);
     }
 
+    // ensure a filter option is in force for search
+    populateFilterComboBox(true, cachedPDBExists);
     Thread discoverPDBStructuresThread = new Thread(new Runnable()
     {
       @Override
@@ -117,7 +122,8 @@ public class StructureChooser extends GStructureChooser implements
                 .getString("status.searching_for_pdb_structures"),
                 startTime);
         fetchStructuresMetaData();
-        populateFilterComboBox();
+        // revise filter options if no results were found
+        populateFilterComboBox(isStructuresDiscovered(), cachedPDBExists);
         updateProgressIndicator(null, startTime);
         mainFrame.setVisible(true);
         updateCurrentView();
@@ -161,6 +167,10 @@ public class StructureChooser extends GStructureChooser implements
       pdbRequest.setAllowEmptySeq(false);
       pdbRequest.setResponseSize(500);
       pdbRequest.setFieldToSearchBy("(");
+      FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
+              .getSelectedItem());
+      pdbRequest.setFieldToSortBy(selectedFilterOpt.getValue(),
+              !chk_invertFilter.isSelected());
       pdbRequest.setWantedFields(wantedFields);
       pdbRequest.setSearchTerm(buildQuery(seq) + ")");
       pdbRequest.setAssociatedSequence(seq);
@@ -190,8 +200,7 @@ public class StructureChooser extends GStructureChooser implements
     {
       getResultTable().setModel(
               FTSRestResponse.getTableModel(lastPdbRequest,
-              discoveredStructuresSet));
-      structuresDiscovered = true;
+                      discoveredStructuresSet));
       noOfStructuresFound = discoveredStructuresSet.size();
       mainFrame.setTitle(MessageManager.formatMessage(
               "label.structure_chooser_no_of_structures",
@@ -208,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);
       }
     }
   }
@@ -233,7 +242,7 @@ public class StructureChooser extends GStructureChooser implements
         }
       }
     }
-
+    cachedPDBExists = !entries.isEmpty();
     PDBEntryTableModel tableModelx = new PDBEntryTableModel(entries);
     tbl_local_pdb.setModel(tableModelx);
   }
@@ -253,17 +262,16 @@ 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())
       {
         if (isValidSeqName(entry.getId()))
         {
           queryBuilder.append("pdb_id:")
-                  .append(entry.getId().toLowerCase())
-                  .append(" OR ");
+                  .append(entry.getId().toLowerCase()).append(" OR ");
           isPDBRefsFound = true;
-          // seqRefs.add(entry.getId());
         }
       }
     }
@@ -272,13 +280,13 @@ 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))
           {
             queryBuilder.append("uniprot_accession:")
-                    .append(getDBRefId(dbRef))
-                    .append(" OR ");
+                    .append(getDBRefId(dbRef)).append(" OR ");
             queryBuilder.append("uniprot_id:").append(getDBRefId(dbRef))
                     .append(" OR ");
             isUniProtRefsFound = true;
@@ -287,8 +295,7 @@ public class StructureChooser extends GStructureChooser implements
           {
 
             queryBuilder.append("pdb_id:")
-                    .append(getDBRefId(dbRef).toLowerCase())
-                    .append(" OR ");
+                    .append(getDBRefId(dbRef).toLowerCase()).append(" OR ");
             isPDBRefsFound = true;
           }
           else
@@ -343,7 +350,6 @@ public class StructureChooser extends GStructureChooser implements
             .replaceAll("[^\\dA-Za-z|_]", "").replaceAll("\\s+", "+");
   }
 
-
   /**
    * Ensures sequence ref names are not less than 3 characters and does not
    * contain a database name
@@ -454,8 +460,8 @@ public class StructureChooser extends GStructureChooser implements
           reorderedStructuresSet.addAll(filteredResponse);
           reorderedStructuresSet.addAll(discoveredStructuresSet);
           getResultTable().setModel(
-                  FTSRestResponse.getTableModel(
-                  lastPdbRequest, reorderedStructuresSet));
+                  FTSRestResponse.getTableModel(lastPdbRequest,
+                          reorderedStructuresSet));
 
           FTSRestResponse.configureTableColumn(getResultTable(),
                   wantedFields, tempUserPrefs);
@@ -479,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);
           }
         }
 
@@ -524,10 +530,16 @@ public class StructureChooser extends GStructureChooser implements
    * Populates the filter combo-box options dynamically depending on discovered
    * structures
    */
-  @Override
-  protected void populateFilterComboBox()
+  protected void populateFilterComboBox(boolean haveData,
+          boolean cachedPDBExists)
   {
-    if (isStructuresDiscovered())
+    /*
+     * temporarily suspend the change listener behaviour
+     */
+    cmb_filterOption.removeItemListener(this);
+
+    cmb_filterOption.removeAllItems();
+    if (haveData)
     {
       cmb_filterOption.addItem(new FilterOption("Best Quality",
               "overall_quality", VIEWS_FILTER));
@@ -544,14 +556,21 @@ public class StructureChooser extends GStructureChooser implements
             VIEWS_ENTER_ID));
     cmb_filterOption.addItem(new FilterOption("From File", "-",
             VIEWS_FROM_FILE));
-    cmb_filterOption.addItem(new FilterOption("Cached PDB Entries", "-",
-            VIEWS_LOCAL_PDB));
+    FilterOption cachedOption = new FilterOption("Cached PDB Entries", "-",
+            VIEWS_LOCAL_PDB);
+    cmb_filterOption.addItem(cachedOption);
+
+    if (/*!haveData &&*/cachedPDBExists)
+    {
+      cmb_filterOption.setSelectedItem(cachedOption);
+    }
+
+    cmb_filterOption.addItemListener(this);
   }
 
   /**
    * Updates the displayed view based on the selected filter option
    */
-  @Override
   protected void updateCurrentView()
   {
     FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
@@ -717,6 +736,7 @@ public class StructureChooser extends GStructureChooser implements
   {
     final long progressSessionId = System.currentTimeMillis();
     final StructureSelectionManager ssm = ap.getStructureSelectionManager();
+    final int preferredHeight = pnl_filter.getHeight();
     ssm.setProgressIndicator(this);
     ssm.setProgressSessionId(progressSessionId);
     new Thread(new Runnable()
@@ -724,84 +744,82 @@ public class StructureChooser extends GStructureChooser implements
       @Override
       public void run()
       {
-    FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
-            .getSelectedItem());
-    String currentView = selectedFilterOpt.getView();
-    if (currentView == VIEWS_FILTER)
-    {
+        FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
+                .getSelectedItem());
+        String currentView = selectedFilterOpt.getView();
+        if (currentView == VIEWS_FILTER)
+        {
           int pdbIdColIndex = getResultTable().getColumn("PDB Id")
                   .getModelIndex();
           int refSeqColIndex = getResultTable().getColumn("Ref Sequence")
-              .getModelIndex();
+                  .getModelIndex();
           int[] selectedRows = getResultTable().getSelectedRows();
-      PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
-      int count = 0;
-      ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
-      for (int row : selectedRows)
-      {
+          PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
+          int count = 0;
+          List<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+          for (int row : selectedRows)
+          {
             String pdbIdStr = getResultTable().getValueAt(row,
-                    pdbIdColIndex)
-                .toString();
+                    pdbIdColIndex).toString();
             SequenceI selectedSeq = (SequenceI) getResultTable()
-                    .getValueAt(row,
-                refSeqColIndex);
-        selectedSeqsToView.add(selectedSeq);
+                    .getValueAt(row, refSeqColIndex);
+            selectedSeqsToView.add(selectedSeq);
             PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
             if (pdbEntry == null)
             {
               pdbEntry = getFindEntry(pdbIdStr,
                       selectedSeq.getAllPDBEntries());
             }
-        if (pdbEntry == null)
-        {
-          pdbEntry = new PDBEntry();
-          pdbEntry.setId(pdbIdStr);
-          pdbEntry.setType(PDBEntry.Type.PDB);
-          selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
-        }
-        pdbEntriesToView[count++] = pdbEntry;
-      }
-      SequenceI[] selectedSeqs = selectedSeqsToView
-              .toArray(new SequenceI[selectedSeqsToView.size()]);
+            if (pdbEntry == null)
+            {
+              pdbEntry = new PDBEntry();
+              pdbEntry.setId(pdbIdStr);
+              pdbEntry.setType(PDBEntry.Type.PDB);
+              selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
+            }
+            pdbEntriesToView[count++] = pdbEntry;
+          }
+          SequenceI[] selectedSeqs = selectedSeqsToView
+                  .toArray(new SequenceI[selectedSeqsToView.size()]);
           launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
-    }
-    else if (currentView == VIEWS_LOCAL_PDB)
-    {
-      int[] selectedRows = tbl_local_pdb.getSelectedRows();
-      PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
-      int count = 0;
+        }
+        else if (currentView == VIEWS_LOCAL_PDB)
+        {
+          int[] selectedRows = tbl_local_pdb.getSelectedRows();
+          PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
+          int count = 0;
           int pdbIdColIndex = tbl_local_pdb.getColumn("PDB Id")
                   .getModelIndex();
-      int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
-              .getModelIndex();
-      ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
-      for (int row : selectedRows)
-      {
-        PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
-                pdbIdColIndex);
-        pdbEntriesToView[count++] = pdbEntry;
-        SequenceI selectedSeq = (SequenceI) tbl_local_pdb.getValueAt(row,
-                refSeqColIndex);
-        selectedSeqsToView.add(selectedSeq);
-      }
-      SequenceI[] selectedSeqs = selectedSeqsToView
-              .toArray(new SequenceI[selectedSeqsToView.size()]);
+          int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
+                  .getModelIndex();
+          List<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+          for (int row : selectedRows)
+          {
+            PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
+                    pdbIdColIndex);
+            pdbEntriesToView[count++] = pdbEntry;
+            SequenceI selectedSeq = (SequenceI) tbl_local_pdb.getValueAt(
+                    row, refSeqColIndex);
+            selectedSeqsToView.add(selectedSeq);
+          }
+          SequenceI[] selectedSeqs = selectedSeqsToView
+                  .toArray(new SequenceI[selectedSeqsToView.size()]);
           launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
-    }
-    else if (currentView == VIEWS_ENTER_ID)
-    {
-      SequenceI userSelectedSeq = ((AssociateSeqOptions) idInputAssSeqPanel
-              .getCmb_assSeq().getSelectedItem()).getSequence();
-      if (userSelectedSeq != null)
-      {
-        selectedSequence = userSelectedSeq;
-      }
+        }
+        else if (currentView == VIEWS_ENTER_ID)
+        {
+          SequenceI userSelectedSeq = ((AssociateSeqOptions) idInputAssSeqPanel
+                  .getCmb_assSeq().getSelectedItem()).getSequence();
+          if (userSelectedSeq != null)
+          {
+            selectedSequence = userSelectedSeq;
+          }
 
-      String pdbIdStr = txt_search.getText();
-      PDBEntry pdbEntry = selectedSequence.getPDBEntry(pdbIdStr);
-      if (pdbEntry == null)
-      {
-        pdbEntry = new PDBEntry();
+          String pdbIdStr = txt_search.getText();
+          PDBEntry pdbEntry = selectedSequence.getPDBEntry(pdbIdStr);
+          if (pdbEntry == null)
+          {
+            pdbEntry = new PDBEntry();
             if (pdbIdStr.split(":").length > 1)
             {
               pdbEntry.setId(pdbIdStr.split(":")[0]);
@@ -811,11 +829,11 @@ public class StructureChooser extends GStructureChooser implements
             {
               pdbEntry.setId(pdbIdStr);
             }
-        pdbEntry.setType(PDBEntry.Type.PDB);
-        selectedSequence.getDatasetSequence().addPDBId(pdbEntry);
-      }
+            pdbEntry.setType(PDBEntry.Type.PDB);
+            selectedSequence.getDatasetSequence().addPDBId(pdbEntry);
+          }
 
-      PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
+          PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
           launchStructureViewer(ssm, pdbEntriesToView, ap,
                   new SequenceI[] { selectedSequence });
     }
@@ -829,13 +847,13 @@ public class StructureChooser extends GStructureChooser implements
       }
       PDBEntry fileEntry = new AssociatePdbFileWithSeq()
               .associatePdbWithSeq(selectedPdbFileName,
-                      jalview.io.AppletFormatAdapter.FILE,
+                          DataSourceType.FILE,
                       selectedSequence, true, Desktop.instance);
 
           launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
                   new SequenceI[] { selectedSequence });
-    }
-        closeAction();
+        }
+        closeAction(preferredHeight);
       }
     }).start();
   }
@@ -865,7 +883,7 @@ public class StructureChooser extends GStructureChooser implements
 
     if (SiftsSettings.isMapWithSifts())
     {
-      ArrayList<SequenceI> seqsWithoutSourceDBRef = new ArrayList<SequenceI>();
+      List<SequenceI> seqsWithoutSourceDBRef = new ArrayList<SequenceI>();
       int p = 0;
       // TODO: skip PDBEntry:Sequence pairs where PDBEntry doesn't look like a
       // real PDB ID. For moment, we can also safely do this if there is already
@@ -889,9 +907,9 @@ public class StructureChooser extends GStructureChooser implements
         }
         if (seq.getPrimaryDBRefs().size() == 0)
         {
-            seqsWithoutSourceDBRef.add(seq);
-            continue;
-          }
+          seqsWithoutSourceDBRef.add(seq);
+          continue;
+        }
       }
       if (!seqsWithoutSourceDBRef.isEmpty())
       {
@@ -906,7 +924,8 @@ public class StructureChooser extends GStructureChooser implements
         {
           seqWithoutSrcDBRef[x++] = fSeq;
         }
-        new DBRefFetcher(seqWithoutSrcDBRef).fetchDBRefs(true);
+        DBRefFetcher dbRefFetcher = new DBRefFetcher(seqWithoutSrcDBRef);
+        dbRefFetcher.fetchDBRefs(true);
       }
     }
     if (pdbEntriesToView.length > 1)
@@ -963,12 +982,8 @@ public class StructureChooser extends GStructureChooser implements
 
   public boolean isStructuresDiscovered()
   {
-    return structuresDiscovered;
-  }
-
-  public void setStructuresDiscovered(boolean structuresDiscovered)
-  {
-    this.structuresDiscovered = structuresDiscovered;
+    return discoveredStructuresSet != null
+            && !discoveredStructuresSet.isEmpty();
   }
 
   public Collection<FTSData> getDiscoveredStructuresSet()
@@ -997,8 +1012,7 @@ public class StructureChooser extends GStructureChooser implements
           pdbRequest.setResponseSize(1);
           pdbRequest.setFieldToSearchBy("(pdb_id:");
           pdbRequest.setWantedFields(wantedFields);
-          pdbRequest
-.setSearchTerm(searchTerm + ")");
+          pdbRequest.setSearchTerm(searchTerm + ")");
           pdbRequest.setAssociatedSequence(selectedSequence);
           pdbRestCleint = PDBFTSRestClient.getInstance();
           wantedFields.add(pdbRestCleint.getPrimaryKeyColumn());
index 21b2984..189d490 100644 (file)
@@ -136,14 +136,16 @@ public class StructureViewer
   protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
           PDBEntry[] pdbs, SequenceI[][] seqsForPdbs, AlignmentPanel ap)
   {
+    PDBEntry[] pdbsForFile = getUniquePdbFiles(pdbs);
     JalviewStructureDisplayI sview = null;
     if (viewerType.equals(ViewerType.JMOL))
     {
-      sview = new AppJmol(ap, pdbs, ap.av.collateForPDB(pdbs));
+      sview = new AppJmol(ap, pdbsForFile, ap.av.collateForPDB(pdbsForFile));
     }
     else if (viewerType.equals(ViewerType.CHIMERA))
     {
-      sview = new ChimeraViewFrame(pdbs, ap.av.collateForPDB(pdbs), ap);
+      sview = new ChimeraViewFrame(pdbsForFile,
+              ap.av.collateForPDB(pdbsForFile), ap);
     }
     else
     {
@@ -153,6 +155,36 @@ public class StructureViewer
     return sview;
   }
 
+  /**
+   * Convert the array of PDBEntry into an array with no filename repeated
+   * 
+   * @param pdbs
+   * @return
+   */
+  static PDBEntry[] getUniquePdbFiles(PDBEntry[] pdbs)
+  {
+    if (pdbs == null)
+    {
+      return null;
+    }
+    List<PDBEntry> uniques = new ArrayList<PDBEntry>();
+    List<String> filesSeen = new ArrayList<String>();
+    for (PDBEntry entry : pdbs)
+    {
+      String file = entry.getFile();
+      if (file == null)
+      {
+        uniques.add(entry);
+      }
+      else if (!filesSeen.contains(file))
+      {
+        uniques.add(entry);
+        filesSeen.add(file);
+      }
+    }
+    return uniques.toArray(new PDBEntry[uniques.size()]);
+  }
+
   protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
           PDBEntry pdb, SequenceI[] seqsForPdb, AlignmentPanel ap)
   {
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 ef65b92..84fd82f 100755 (executable)
@@ -811,8 +811,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
 
       for (int i = 0; i < leaves.size(); i++)
       {
-        SequenceI seq = (SequenceI) leaves.elementAt(i)
-                .element();
+        SequenceI seq = (SequenceI) leaves.elementAt(i).element();
         treeSelectionChanged(seq);
       }
       av.sendSelection();
@@ -968,15 +967,14 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
               (int) (Math.random() * 255), (int) (Math.random() * 255));
       setColor(tree.getGroups().elementAt(i), col.brighter());
 
-      Vector<SequenceNode> l = tree.findLeaves(tree
-              .getGroups().elementAt(i));
+      Vector<SequenceNode> l = tree.findLeaves(tree.getGroups()
+              .elementAt(i));
 
       Vector<SequenceI> sequences = new Vector<SequenceI>();
 
       for (int j = 0; j < l.size(); j++)
       {
-        SequenceI s1 = (SequenceI) l.elementAt(j)
-                .element();
+        SequenceI s1 = (SequenceI) l.elementAt(j).element();
 
         if (!sequences.contains(s1))
         {
@@ -1019,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..af84dbc 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,24 @@ 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,
+              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 +796,10 @@ 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,
+              ImageMaker.PNG_DESCRIPTION);
 
       chooser.setFileView(new jalview.io.JalviewFileView());
       chooser.setDialogTitle(MessageManager
index c9c1531..c380049 100755 (executable)
@@ -21,6 +21,7 @@
 package jalview.gui;
 
 import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.bin.Cache;
 import jalview.datamodel.SequenceGroup;
 import jalview.io.JalviewFileChooser;
 import jalview.jbgui.GUserDefinedColours;
@@ -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,9 +598,8 @@ 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" },
-            "Jalview User Colours");
+            Cache.getProperty("LAST_DIRECTORY"), "jc",
+            "Jalview User Colours", "Jalview User Colours");
     chooser.setFileView(new jalview.io.JalviewFileView());
     chooser.setDialogTitle(MessageManager
             .getString("label.load_colour_scheme"));
@@ -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,9 +833,8 @@ 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" },
-            "Jalview User Colours");
+            Cache.getProperty("LAST_DIRECTORY"), "jc",
+            "Jalview User Colours", "Jalview User Colours");
 
     chooser.setFileView(new jalview.io.JalviewFileView());
     chooser.setDialogTitle(MessageManager
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..80798c6 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;
@@ -185,11 +186,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" },
-              "Web Service Parameter File");
-      chooser.setFileView(new jalview.io.JalviewFileView());
+              Cache.getProperty("LAST_DIRECTORY"), "wsparams",
+              "Web Service Parameter File", "Web Service Parameter File");
+      chooser.setFileView(new JalviewFileView());
       chooser.setDialogTitle(MessageManager
               .getString("label.choose_filename_for_param_file"));
       chooser.setToolTipText(MessageManager.getString("action.save"));
@@ -294,9 +293,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 4c2265c..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!
    * 
@@ -174,35 +180,21 @@ public class FastaFile extends AlignFile
     addProperties(al);
     for (int i = 0; i < annotations.size(); i++)
     {
-      AlignmentAnnotation aa = annotations
-              .elementAt(i);
+      AlignmentAnnotation aa = annotations.elementAt(i);
       aa.setPadGaps(true, al.getGapCharacter());
       al.addAnnotation(aa);
     }
   }
 
-  /**
-   * 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());
@@ -234,15 +226,4 @@ public class FastaFile extends AlignFile
 
     return out.toString();
   }
-
-  /**
-   * DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
-   */
-  @Override
-  public String print()
-  {
-    return print(getSeqsAsArray());
-  }
 }
index aa38540..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);
@@ -138,8 +140,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * @return true if features were added
    */
   public boolean parse(AlignmentI align,
-          Map<String, FeatureColourI> colours,
-          boolean removeHTML)
+          Map<String, FeatureColourI> colours, boolean removeHTML)
   {
     return parse(align, colours, removeHTML, false);
   }
@@ -176,8 +177,8 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * @return true if features were added
    */
   public boolean parse(AlignmentI align,
-          Map<String, FeatureColourI> colours,
-          boolean removeHTML, boolean relaxedIdmatching)
+          Map<String, FeatureColourI> colours, boolean removeHTML,
+          boolean relaxedIdmatching)
   {
     Map<String, String> gffProps = new HashMap<String, String>();
     /*
@@ -587,7 +588,8 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
         {
           for (SequenceFeature sequenceFeature : features)
           {
-            isnonpos = sequenceFeature.begin == 0 && sequenceFeature.end == 0;
+            isnonpos = sequenceFeature.begin == 0
+                    && sequenceFeature.end == 0;
             if ((!nonpos && isnonpos)
                     || (!isnonpos && visOnly && !visible
                             .containsKey(sequenceFeature.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..381a40b 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.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 +231,122 @@ 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(
+            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
+            new String[] { "html" }, new String[] { "HTML files" },
+            "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 4e1b261..1ec3a4e 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();
-
+    new Thread(this).start();
   }
 
-  private void setProgressMessage(String message)
-  {
-    if (pIndicator != null && !headless)
-    {
-      pIndicator.setProgressBar(message, pSessionId);
-    }
-    else
-    {
-      System.out.println(message);
-    }
-  }
 
   static JalviewFileChooser getHTMLChooser()
   {
@@ -259,139 +81,22 @@ public class HtmlSvgOutput
             "Hypertext Markup Language");
   }
 
-  public int printUnwrapped(int pwidth, int pheight, int pi, Graphics... pg)
+  public int printUnwrapped(int pwidth, int pheight, int pi,
+          Graphics idGraphics, Graphics alignmentGraphics)
           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 ap.printUnwrapped(pwidth, pheight, pi, idGraphics,
+            alignmentGraphics);
+  }
 
-    return Printable.PAGE_EXISTS;
+  public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg)
+          throws PrinterException
+  {
+    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");
@@ -431,8 +136,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");
@@ -453,9 +159,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");
@@ -480,269 +193,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 889359f..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 String identify(FileParse source)
+  public FileFormatI identify(FileParse source) throws FileFormatException
   {
-    return identify(source, true); // preserves original behaviour prior to
-    // version 2.3
+    return identify(source, true);
+    // preserves original behaviour prior to version 2.3
+  }
+
+  public FileFormatI identify(AlignmentFileI file, boolean closeSource)
+          throws IOException
+  {
+    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)
@@ -251,24 +259,24 @@ public class IdentifyFile
         }
         int lessThan = data.indexOf("<");
         if ((lessThan > -1)) // possible Markup Language data i.e HTML,
-                                      // RNAML, XML
+                             // RNAML, XML
         {
           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;
   }
 
@@ -361,8 +370,9 @@ public class IdentifyFile
   }
 
   /**
-   * Returns true if the data has at least 6 tab-delimited fields _and_ 
-   * fields 4 and 5 are integer (start/end) 
+   * Returns true if the data has at least 6 tab-delimited fields _and_ fields 4
+   * and 5 are integer (start/end)
+   * 
    * @param data
    * @return
    */
@@ -373,14 +383,17 @@ public class IdentifyFile
       return false;
     }
     String[] columns = data.split("\t");
-    if (columns.length < 6) {
+    if (columns.length < 6)
+    {
       return false;
     }
     for (int col = 3; col < 5; col++)
     {
-      try {
+      try
+      {
         Integer.parseInt(columns[col]);
-      } catch (NumberFormatException e) {
+      } catch (NumberFormatException e)
+      {
         return false;
       }
     }
@@ -389,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..7ebe081 100755 (executable)
@@ -21,6 +21,7 @@
 //////////////////////////////////////////////////////////////////
 package jalview.io;
 
+import jalview.gui.JvOptionPane;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 
@@ -31,16 +32,20 @@ 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.Collections;
+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.filechooser.FileView;
+import javax.swing.plaf.basic.BasicFileChooserUI;
 
 /**
  * Enhanced file chooser dialog box.
@@ -53,12 +58,97 @@ 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
+   * @param selectAll
+   * @return
+   */
+  public static JalviewFileChooser forRead(String directory,
+          String selected, boolean selectAll)
+  {
+    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);
+  }
+
+  /**
+   * Factory method to return a file chooser that offers writable alignment file
+   * formats
+   * 
+   * @param directory
+   * @param selected
+   * @param selectAll
+   * @return
+   */
+  public static JalviewFileChooser forWrite(String directory,
+          String selected, boolean selectAll)
+  {
+    // 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);
+  }
+
   public JalviewFileChooser(String dir)
   {
     super(safePath(dir));
     setAccessory(new RecentlyOpened());
   }
 
+  public JalviewFileChooser(String dir, String extension, String desc,
+          String selected)
+  {
+    super(safePath(dir));
+    init(Collections.singletonList(new String[] { extension, desc }),
+            selected);
+  }
+
+  public JalviewFileChooser(String dir, String[] extensions, String[] descs,
+          String selected)
+  {
+    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);
+    }
+    else
+    {
+      System.err.println("JalviewFileChooser arguments mismatch: "
+              + extensions + ", " + descs);
+    }
+  }
+
   private static File safePath(String dir)
   {
     if (dir == null)
@@ -74,35 +164,26 @@ 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
+   */
+  void init(List<String[]> formats, String selected)
   {
 
     JalviewFileFilter chosen = null;
 
     // SelectAllFilter needs to be set first before adding further
     // file filters to fix bug on Mac OSX
-    setAcceptAllFileFilterUsed(selectAll);
+    setAcceptAllFileFilterUsed(true);
 
-    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 +204,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 +219,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 +234,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"))
-    {
-      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"))
+    int parenPos = format.indexOf("(");
+    if (parenPos > 0)
     {
-      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 +294,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 ab510d5..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);
@@ -239,8 +240,7 @@ public class MSFfile extends AlignFile
        * modify to MSF format: uses '.' for internal gaps, 
        * and '~' for leading or trailing gaps
        */
-      String seqString = sqs[i].getSequenceAsString()
-              .replace('-', '.');
+      String seqString = sqs[i].getSequenceAsString().replace('-', '.');
 
       StringBuilder sb = new StringBuilder(seqString);
 
@@ -308,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: "
@@ -360,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 + " "));
 
@@ -408,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 ecce1a3..746c4a7 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.api.FeatureColourI;
@@ -8,10 +28,10 @@ import java.awt.Color;
 
 public class PDBFeatureSettings extends FeatureSettingsAdapter
 {
+  // TODO find one central place to define feature names
+  private static final String FEATURE_INSERTION = "INSERTION";
 
-  public static final String FEATURE_INSERTION = "INSERTION";
-
-  public static final String FEATURE_RES_NUM = "RESNUM";
+  private static final String FEATURE_RES_NUM = "RESNUM";
 
   @Override
   public boolean isFeatureDisplayed(String type)
@@ -63,4 +83,3 @@ public class PDBFeatureSettings extends FeatureSettingsAdapter
     return 0;
   }
 }
-
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 667da9f..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
@@ -124,8 +125,7 @@ public class PfamFile extends AlignFile
     {
       if (seqhash.get(headers.get(i)) != null)
       {
-        if (maxLength < seqhash.get(headers.get(i)).toString()
-                .length())
+        if (maxLength < seqhash.get(headers.get(i)).toString().length())
         {
           maxLength = seqhash.get(headers.get(i)).toString().length();
         }
@@ -143,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("");
 
@@ -154,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)
       {
@@ -178,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);
@@ -189,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 2d76d6b..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)
           {
@@ -141,14 +204,15 @@ public class SequenceAnnotationReport
           }
           else
           {
-            if (tmpString.indexOf("<") > -1
-                    || tmpString.indexOf(">") > -1)
+            if (tmpString.indexOf("<") > -1 || tmpString.indexOf(">") > -1)
             {
               // The description does not specify html is to
               // 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
             {
@@ -156,19 +220,14 @@ 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
                   .getType());
           if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
           {
-            sb.append(" Score=").append(
-                    String.valueOf(feature.getScore()));
+            sb.append(" Score=").append(String.valueOf(feature.getScore()));
           }
         }
         String status = (String) feature.getValue("status");
@@ -184,7 +243,6 @@ public class SequenceAnnotationReport
         }
       }
     }
-    appendLinks(sb, feature);
   }
 
   /**
@@ -208,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)
@@ -236,149 +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;
@@ -389,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)
     {
@@ -406,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 bec7d82..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);
   }
@@ -829,8 +830,7 @@ public class StockholmFile extends AlignFile
         {
           if (DETECT_BRACKETS.search(pos))
           {
-            ann.secondaryStructure = Rna.getRNASecStrucState(
-                    pos).charAt(0);
+            ann.secondaryStructure = Rna.getRNASecStrucState(pos).charAt(0);
           }
           else
           {
@@ -881,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;
@@ -890,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;
@@ -987,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 = "";
@@ -1001,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++;
@@ -1054,6 +1060,10 @@ public class StockholmFile extends AlignFile
         out.append(newline);
       }
     }
+
+    out.append("//");
+    out.append(newline);
+
     return out.toString();
   }
 
@@ -1106,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 0bc6a73..7fe17c8 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.analysis.AlignSeq;
@@ -15,7 +35,6 @@ import jalview.structure.StructureImportSettings;
 import java.awt.Color;
 import java.io.IOException;
 import java.lang.reflect.Constructor;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Vector;
 
@@ -23,7 +42,6 @@ import MCview.PDBChain;
 
 public abstract class StructureFile extends AlignFile
 {
-
   private String id;
 
   private PDBEntry.Type dbRefType;
@@ -48,9 +66,12 @@ public abstract class StructureFile extends AlignFile
 
   private Vector<PDBChain> chains;
 
-  public StructureFile(String inFile, String type) throws IOException
+  private boolean pdbIdAvailable;
+
+  public StructureFile(String inFile, DataSourceType sourceType)
+          throws IOException
   {
-    super(inFile, type);
+    super(inFile, sourceType);
   }
 
   public StructureFile(FileParse fp) throws IOException
@@ -77,10 +98,10 @@ public abstract class StructureFile extends AlignFile
 
   }
 
-  public StructureFile(boolean parseImmediately, String dataObject, String type)
-          throws IOException
+  public StructureFile(boolean parseImmediately, String dataObject,
+          DataSourceType sourceType) throws IOException
   {
-    super(parseImmediately, dataObject, type);
+    super(parseImmediately, dataObject, sourceType);
   }
 
   public StructureFile(boolean a, FileParse fp) throws IOException
@@ -92,7 +113,6 @@ public abstract class StructureFile extends AlignFile
   {
   }
 
-  @SuppressWarnings("rawtypes")
   protected SequenceI postProcessChain(PDBChain chain)
   {
     SequenceI pdbSequence = chain.sequence;
@@ -100,10 +120,9 @@ public abstract class StructureFile extends AlignFile
     PDBEntry entry = new PDBEntry();
     entry.setId(getId());
     entry.setType(getStructureFileType());
-    entry.setProperty(new Hashtable());
     if (chain.id != null)
     {
-      entry.setChainCode(String.valueOf(chain.id));
+      entry.setChainCode(chain.id);
     }
     if (inFile != null)
     {
@@ -176,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)
@@ -285,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);
@@ -450,4 +467,19 @@ public abstract class StructureFile extends AlignFile
   {
     return new PDBFeatureSettings();
   }
+
+  /**
+   * Answers true if the structure file has a PDBId
+   * 
+   * @return
+   */
+  public boolean isPPDBIdAvailable()
+  {
+    return pdbIdAvailable;
+  }
+
+  public void setPDBIdAvailable(boolean pdbIdAvailable)
+  {
+    this.pdbIdAvailable = pdbIdAvailable;
+  }
 }
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 f7805fd..eb74eea 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import jalview.datamodel.AlignedCodonFrame;
@@ -64,8 +84,8 @@ public class ExonerateHelper extends Gff2Helper
 
     try
     {
-      processGffSimilarity(set, seq, gffColumns,
-              align, newseqs, relaxedIdMatching);
+      processGffSimilarity(set, seq, gffColumns, align, newseqs,
+              relaxedIdMatching);
     } catch (IOException ivfe)
     {
       System.err.println(ivfe);
@@ -98,8 +118,7 @@ public class ExonerateHelper extends Gff2Helper
    *          if true allow fuzzy search for a matching target sequence
    * @throws IOException
    */
-  protected void processGffSimilarity(
-          Map<String, List<String>> set,
+  protected void processGffSimilarity(Map<String, List<String>> set,
           SequenceI seq, String[] gff, AlignmentI align,
           List<SequenceI> newseqs, boolean relaxedIdMatching)
           throws IOException
@@ -228,15 +247,17 @@ public class ExonerateHelper extends Gff2Helper
     int alignFromStart;
     int alignToStart;
     int alignCount;
-    try {
+    try
+    {
       alignFromStart = Integer.parseInt(tokens[0]);
       alignToStart = Integer.parseInt(tokens[1]);
       alignCount = Integer.parseInt(tokens[2]);
-    } catch (NumberFormatException nfe) {
+    } catch (NumberFormatException nfe)
+    {
       System.err.println(nfe.toString());
       return null;
     }
-    
+
     int fromStart;
     int fromEnd;
     int toStart;
@@ -290,10 +311,8 @@ public class ExonerateHelper extends Gff2Helper
     {
       result = MappingType.PeptideToNucleotide;
     }
-    else if (model.contains(CODING2CODING)
-            || model.contains(CODING2GENOME)
-            || model.contains(CDNA2GENOME)
-            || model.contains(GENOME2GENOME))
+    else if (model.contains(CODING2CODING) || model.contains(CODING2GENOME)
+            || model.contains(CDNA2GENOME) || model.contains(GENOME2GENOME))
     {
       result = MappingType.NucleotideToNucleotide;
     }
@@ -323,10 +342,8 @@ public class ExonerateHelper extends Gff2Helper
     {
       String mdl = model.toLowerCase();
       if (mdl.contains(PROTEIN2DNA) || mdl.contains(PROTEIN2GENOME)
-              || mdl.contains(CODING2CODING)
-              || mdl.contains(CODING2GENOME)
-              || mdl.contains(CDNA2GENOME)
-              || mdl.contains(GENOME2GENOME))
+              || mdl.contains(CODING2CODING) || mdl.contains(CODING2GENOME)
+              || mdl.contains(CDNA2GENOME) || mdl.contains(GENOME2GENOME))
       {
         return true;
       }
index 31303b1..19045d5 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import jalview.datamodel.AlignmentI;
index 031900d..82e5313 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import jalview.datamodel.AlignedCodonFrame;
@@ -77,8 +97,8 @@ public class Gff3Helper extends GffHelperBase
       }
       else if (so.isA(soTerm, SequenceOntologyI.NUCLEOTIDE_MATCH))
       {
-        sf = processNucleotideMatch(attributes, seq, gff, align,
-                newseqs, relaxedIdMatching);
+        sf = processNucleotideMatch(attributes, seq, gff, align, newseqs,
+                relaxedIdMatching);
       }
       else
       {
@@ -92,7 +112,7 @@ public class Gff3Helper extends GffHelperBase
        */
       sf = buildSequenceFeature(gff, null);
     }
-  
+
     return sf;
   }
 
@@ -119,8 +139,7 @@ public class Gff3Helper extends GffHelperBase
   protected SequenceFeature processNucleotideMatch(
           Map<String, List<String>> attributes, SequenceI seq,
           String[] gffColumns, AlignmentI align, List<SequenceI> newseqs,
-          boolean relaxedIdMatching)
-          throws IOException
+          boolean relaxedIdMatching) throws IOException
   {
     String strand = gffColumns[STRAND_COL];
 
@@ -166,8 +185,8 @@ public class Gff3Helper extends GffHelperBase
        * (new or existing) virtual sequence in the newseqs list 
        */
       String targetId = findTargetId(tokens[0], attributes);
-      SequenceI mappedSequence1 = findSequence(targetId, align,
-      newseqs, relaxedIdMatching);
+      SequenceI mappedSequence1 = findSequence(targetId, align, newseqs,
+              relaxedIdMatching);
       SequenceI mappedSequence = mappedSequence1;
       if (mappedSequence == null)
       {
@@ -195,8 +214,7 @@ public class Gff3Helper extends GffHelperBase
         int fromStart = Integer.parseInt(gffColumns[START_COL]);
         int fromEnd = Integer.parseInt(gffColumns[END_COL]);
         MapList mapping = constructMappingFromAlign(fromStart, fromEnd,
-                toStart, toEnd,
-                MappingType.NucleotideToNucleotide);
+                toStart, toEnd, MappingType.NucleotideToNucleotide);
 
         if (mapping != null)
         {
@@ -280,8 +298,8 @@ public class Gff3Helper extends GffHelperBase
       for (String target : targets)
       {
 
-        SequenceI mappedSequence1 = findSequence(findTargetId(target, set), align,
-        newseqs, relaxedIdMatching);
+        SequenceI mappedSequence1 = findSequence(findTargetId(target, set),
+                align, newseqs, relaxedIdMatching);
         SequenceI mappedSequence = mappedSequence1;
         if (mappedSequence == null)
         {
@@ -379,8 +397,8 @@ public class Gff3Helper extends GffHelperBase
       /*
        * Ensembl returns dna variants as 'alleles'
        */
-      desc = StringUtils.listToDelimitedString(
-              attributes.get("alleles"), ",");
+      desc = StringUtils.listToDelimitedString(attributes.get("alleles"),
+              ",");
     }
 
     /*
index 545c6e3..571f0ea 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 /**
index feeec1d..48c33e5 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import jalview.analysis.SequenceIdMatcher;
@@ -392,7 +412,8 @@ public abstract class GffHelperBase implements GffHelperI
    * @param toSeq
    * @return
    */
-  protected AlignedCodonFrame getMapping(AlignmentI align, SequenceI fromSeq, SequenceI toSeq)
+  protected AlignedCodonFrame getMapping(AlignmentI align,
+          SequenceI fromSeq, SequenceI toSeq)
   {
     AlignedCodonFrame acf = align.getMapping(fromSeq, toSeq);
     if (acf == null)
index 8bd5115..c03082a 100644 (file)
@@ -1,6 +1,25 @@
+/*
+ * 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.gff;
 
-
 /**
  * A factory to serve instances of GFF helper classes
  */
index 3d9dc6f..7fbcf5c 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import jalview.datamodel.AlignmentI;
@@ -35,9 +55,8 @@ public interface GffHelperI
    * @throws IOException
    */
   SequenceFeature processGff(SequenceI seq, String[] gffColumns,
-          AlignmentI align,
-          List<SequenceI> newseqs, boolean relaxedIdMatching)
-          throws IOException;
+          AlignmentI align, List<SequenceI> newseqs,
+          boolean relaxedIdMatching) throws IOException;
 
   // java 8 will allow static methods in interfaces:
   // static boolean recognises(String [] columns);
index 68d5d4f..e1334e1 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import jalview.datamodel.AlignmentI;
index 3eaa5d1..90cae7a 100644 (file)
@@ -1,5 +1,33 @@
+/*
+ * 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.gff;
 
+/**
+ * A factory class that returns a model of the Sequence Ontology. By default a
+ * hard-coded subset is used (for the applet, or testing), or setInstance() can
+ * be used to set full Ontology data.
+ * 
+ * @author gmcarstairs
+ *
+ */
 public class SequenceOntologyFactory
 {
   private static SequenceOntologyI instance;
@@ -8,7 +36,6 @@ public class SequenceOntologyFactory
   {
     if (instance == null)
     {
-      // instance = new SequenceOntology();
       instance = new SequenceOntologyLite();
     }
     return instance;
index c7a5baa..c0570e0 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import java.util.List;
index b3f8161..f989f7b 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import java.util.ArrayList;
@@ -51,6 +71,7 @@ public class SequenceOntologyLite implements SequenceOntologyI
     { "miRNA", "transcript" },
     { "lincRNA", "transcript" },
     { "rRNA", "transcript" },
+    { "mRNA", "transcript" },
     // there are many more sub-types of ncRNA...
     
     /*
@@ -111,7 +132,8 @@ public class SequenceOntologyLite implements SequenceOntologyI
   private void loadStaticData()
   {
     parents = new HashMap<String, List<String>>();
-    for (String [] pair : TERMS) {
+    for (String[] pair : TERMS)
+    {
       List<String> p = parents.get(pair[0]);
       if (p == null)
       {
@@ -180,9 +202,11 @@ public class SequenceOntologyLite implements SequenceOntologyI
     {
       if (!termsNotFound.contains(term))
       {
-        System.out.println("SO term " + term
-                + " not known - may be invalid, or model if needed in "
-                + getClass().getName());
+        // suppress logging here as it reports Uniprot sequence features
+        // (which do not use SO terms) when auto-configuring feature colours
+        // System.out.println("SO term " + term
+        // + " not known - add to model if needed in "
+        // + getClass().getName());
         termsNotFound.add(term);
       }
     }
index 63263d2..c1ca1b7 100644 (file)
@@ -211,8 +211,7 @@ public class JalviewDataset
    * @param parentAlignment
    */
   public JalviewDataset(AlignmentI aldataset,
-          Map<String, FeatureColourI> fc,
-          Hashtable seqDets)
+          Map<String, FeatureColourI> fc, Hashtable seqDets)
   {
     // TODO not used - remove?
     this(aldataset, fc, seqDets, null);
@@ -234,8 +233,8 @@ public class JalviewDataset
    *          with.
    */
   public JalviewDataset(AlignmentI aldataset,
-          Map<String, FeatureColourI> fc,
-          Hashtable seqDets, AlignmentI parentAlignment)
+          Map<String, FeatureColourI> fc, Hashtable seqDets,
+          AlignmentI parentAlignment)
   {
     this();
     parentDataset = aldataset;
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 70333f4..4de3d3a 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,14 +314,13 @@ public class GAlignFrame extends JInternalFrame
           {
             radioItem.removeActionListener(radioItem.getActionListeners()[0]);
 
-            int option = JOptionPane.showInternalConfirmDialog(
-                    jalview.gui.Desktop.desktop,
-                    MessageManager
+            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());
@@ -1742,7 +1741,8 @@ public class GAlignFrame extends JInternalFrame
     showProducts.setText(MessageManager.getString("label.get_cross_refs"));
 
     runGroovy.setText(MessageManager.getString("label.run_groovy"));
-    runGroovy.setToolTipText(MessageManager.getString("label.run_groovy_tip"));
+    runGroovy.setToolTipText(MessageManager
+            .getString("label.run_groovy_tip"));
     runGroovy.addActionListener(new ActionListener()
     {
       @Override
@@ -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(
@@ -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
@@ -2406,6 +2427,7 @@ public class GAlignFrame extends JInternalFrame
   {
 
   }
+
   /**
    * Adds the given action listener and key accelerator to the given menu item.
    * Also saves in a lookup table to support lookup of action by key stroke.
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 1348e59..3a064d2 100644 (file)
@@ -166,7 +166,7 @@ public abstract class GStructureChooser extends JPanel implements
 
   protected JScrollPane scrl_localPDB = new JScrollPane(tbl_local_pdb);
 
-  private JTabbedPane pnl_filter = new JTabbedPane();
+  protected JTabbedPane pnl_filter = new JTabbedPane();
 
   protected FTSDataColumnPreferences pdbDocFieldPrefs = new FTSDataColumnPreferences(
           PreferenceSource.STRUCTURE_CHOOSER,
@@ -414,7 +414,7 @@ public abstract class GStructureChooser extends JPanel implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        closeAction();
+        closeAction(pnl_filter.getHeight());
       }
     });
     btn_cancel.addKeyListener(new KeyAdapter()
@@ -424,7 +424,7 @@ public abstract class GStructureChooser extends JPanel implements
       {
         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
         {
-          closeAction();
+          closeAction(pnl_filter.getHeight());
         }
       }
     });
@@ -577,7 +577,7 @@ public abstract class GStructureChooser extends JPanel implements
               @Override
               public void internalFrameClosing(InternalFrameEvent e)
               {
-                closeAction();
+                closeAction(pnl_filter.getHeight());
               }
             });
     mainFrame.setVisible(true);
@@ -592,7 +592,7 @@ public abstract class GStructureChooser extends JPanel implements
     Desktop.addInternalFrame(mainFrame, frameTitle, width, height);
   }
 
-  protected void closeAction()
+  protected void closeAction(int preferredHeight)
   {
     // System.out.println(">>>>>>>>>> closing internal frame!!!");
     // System.out.println("width : " + mainFrame.getWidth());
@@ -600,21 +600,21 @@ public abstract class GStructureChooser extends JPanel implements
     // System.out.println("x : " + mainFrame.getX());
     // System.out.println("y : " + mainFrame.getY());
     tempUserPrefs.put("structureChooser.width", pnl_filter.getWidth());
-    tempUserPrefs.put("structureChooser.height", pnl_filter.getHeight());
+    tempUserPrefs.put("structureChooser.height", preferredHeight);
     tempUserPrefs.put("structureChooser.x", mainFrame.getX());
     tempUserPrefs.put("structureChooser.y", mainFrame.getY());
     mainFrame.dispose();
   }
+
   public boolean wantedFieldsUpdated()
   {
     if (previousWantedFields == null)
     {
       return true;
     }
-    
+
     FTSDataColumnI[] currentWantedFields = pdbDocFieldPrefs
-            .getStructureSummaryFields()
-            .toArray(new FTSDataColumnI[0]);
+            .getStructureSummaryFields().toArray(new FTSDataColumnI[0]);
     return Arrays.equals(currentWantedFields, previousWantedFields) ? false
             : true;
 
@@ -794,6 +794,7 @@ public abstract class GStructureChooser extends JPanel implements
   {
     return tbl_summary;
   }
+
   public JComboBox<FilterOption> getCmbFilterOption()
   {
     return cmb_filterOption;
@@ -801,10 +802,6 @@ public abstract class GStructureChooser extends JPanel implements
 
   protected abstract void stateChanged(ItemEvent e);
 
-  protected abstract void updateCurrentView();
-
-  protected abstract void populateFilterComboBox();
-
   protected abstract void ok_ActionPerformed();
 
   protected abstract void pdbFromFile_actionPerformed();
index e58ba02..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;
 
@@ -151,9 +152,9 @@ public class AnnotationRenderer
     annotationPanel = null;
   }
 
-  void drawStemAnnot(Graphics g, Annotation[] row_annotations,
-          int lastSSX, int x, int y, int iconOffset, int startRes,
-          int column, boolean validRes, boolean validEnd)
+  void drawStemAnnot(Graphics g, Annotation[] row_annotations, int lastSSX,
+          int x, int y, int iconOffset, int startRes, int column,
+          boolean validRes, boolean validEnd)
   {
     g.setColor(STEM_COLOUR);
     int sCol = (lastSSX / charWidth) + startRes;
@@ -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);
         }
       }
@@ -1085,8 +1087,8 @@ public class AnnotationRenderer
 
   private Color sdNOTCANONICAL_COLOUR;
 
-  void drawGlyphLine(Graphics g, Annotation[] row, int lastSSX,
-          int x, int y, int iconOffset, int startRes, int column,
+  void drawGlyphLine(Graphics g, Annotation[] row, int lastSSX, int x,
+          int y, int iconOffset, int startRes, int column,
           boolean validRes, boolean validEnd)
   {
     g.setColor(GLYPHLINE_COLOR);
@@ -1117,8 +1119,8 @@ public class AnnotationRenderer
 
   }
 
-  void drawHelixAnnot(Graphics g, Annotation[] row, int lastSSX,
-          int x, int y, int iconOffset, int startRes, int column,
+  void drawHelixAnnot(Graphics g, Annotation[] row, int lastSSX, int x,
+          int y, int iconOffset, int startRes, int column,
           boolean validRes, boolean validEnd)
   {
     g.setColor(HELIX_COLOUR);
index 6940f22..82536d4 100644 (file)
@@ -62,8 +62,8 @@ public class ScaleRenderer
    *         marker position in alignment column coords, a String to be rendered
    *         at the position (or null)
    */
-  public List<ScaleMark> calculateMarks(AlignViewportI av,
-          int startx, int endx)
+  public List<ScaleMark> calculateMarks(AlignViewportI av, int startx,
+          int endx)
   {
     int scalestartx = (startx / 10) * 10;
 
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 bdc70c9..23087a8 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.schemes;
 
 import jalview.api.FeatureColourI;
@@ -336,9 +356,10 @@ public class FeatureColour implements FeatureColourI
     setAutoScaled(fc.isAutoScaled());
     setColourByLabel(fc.isColourByLabel());
   }
-  
+
   /**
    * Copy constructor with new min/max ranges
+   * 
    * @param fc
    * @param min
    * @param max
@@ -406,6 +427,7 @@ public class FeatureColour implements FeatureColourI
       setGraduatedColour(false);
     }
   }
+
   @Override
   public boolean isBelowThreshold()
   {
@@ -543,7 +565,8 @@ public class FeatureColour implements FeatureColourI
     {
       scl = 1f;
     }
-    return new Color(minRed + scl * deltaRed, minGreen + scl * deltaGreen, minBlue + scl * deltaBlue);
+    return new Color(minRed + scl * deltaRed, minGreen + scl * deltaGreen,
+            minBlue + scl * deltaBlue);
   }
 
   /**
index 699d954..b15e4cf 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.schemes;
 
 import jalview.api.FeatureColourI;
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 c235c7a..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));
+    // Alternative would be charged and
+    // negative (in basic form)?
+    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 62f3a2e..2be51c2 100644 (file)
@@ -86,6 +86,10 @@ public class TCoffeeColourScheme extends ResidueColourScheme
     seqMap = new IdentityHashMap<SequenceI, Color[]>();
     AnnotatedCollectionI alcontext = alignment instanceof AlignmentI ? alignment
             : alignment.getContext();
+    if (alcontext == null)
+    {
+      return;
+    }
     int w = 0;
     for (AlignmentAnnotation al : alcontext
             .findAnnotation(TCoffeeScoreFile.TCOFFEE_SCORE))
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 82b5f69..9662fee 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.structure;
 
 import jalview.datamodel.PDBEntry;
@@ -37,7 +57,6 @@ public class StructureImportSettings
     JMOL_PARSER, JALVIEW_PARSER
   }
 
-
   /**
    * Determines the default file format for structure files to be downloaded
    * from the PDB sequence fetcher. Possible options include: PDB|mmCIF
@@ -49,6 +68,7 @@ public class StructureImportSettings
    * are : JMolParser|JalveiwParser
    */
   private static StructureParser defaultPDBFileParser = StructureParser.JMOL_PARSER;
+
   public static void addSettings(boolean addAlignmentAnnotations,
           boolean processSecStr, boolean externalSecStr)
   {
@@ -101,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 7b103be..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,12 +323,11 @@ 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);
   }
 
-
   /**
    * create sequence structure mappings between each sequence and the given
    * pdbFile (retrieved via the given protocol).
@@ -342,14 +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
@@ -385,13 +384,16 @@ 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 = isMapUsingSIFTs && pdb.isPPDBIdAvailable();
+
     } catch (Exception ex)
     {
       ex.printStackTrace();
@@ -489,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);
@@ -532,14 +534,13 @@ public class StructureSelectionManager
         }
         else
         {
-          ArrayList<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
+          List<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
           for (PDBChain chain : pdb.getChains())
           {
             try
             {
               StructureMapping siftsMapping = getStructureMapping(seq,
-                      pdbFile,
-                      chain.id, pdb, chain, sqmpping, maxAlignseq);
+                      pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
               foundSiftsMappings.add(siftsMapping);
             } catch (SiftsException e)
             {
@@ -614,24 +615,23 @@ public class StructureSelectionManager
           PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
           AlignSeq maxAlignseq) throws SiftsException
   {
-      StructureMapping curChainMapping = siftsClient
-              .getSiftsStructureMapping(seq, pdbFile, targetChainId);
-      try
-      {
+    StructureMapping curChainMapping = siftsClient
+            .getSiftsStructureMapping(seq, pdbFile, targetChainId);
+    try
+    {
       PDBChain chain = pdb.findChain(targetChainId);
       if (chain != null)
       {
         chain.transferResidueAnnotation(curChainMapping, sqmpping);
       }
-      } catch (Exception e)
-      {
-        e.printStackTrace();
-      }
-      return curChainMapping;
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+    return curChainMapping;
   }
 
-  private StructureMapping getNWMappings(SequenceI seq,
-          String pdbFile,
+  private StructureMapping getNWMappings(SequenceI seq, String pdbFile,
           String maxChainId, PDBChain maxChain, StructureFile pdb,
           AlignSeq maxAlignseq)
   {
@@ -806,7 +806,7 @@ public class StructureSelectionManager
       return;
     }
 
-    SearchResults results = new SearchResults();
+    SearchResultsI results = new SearchResults();
     for (AtomSpec atom : atoms)
     {
       SequenceI lastseq = null;
@@ -856,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 dc42315..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;
@@ -51,6 +53,10 @@ public abstract class AAStructureBindingModel extends
 
   private StructureSelectionManager ssm;
 
+  /*
+   * distinct PDB entries (pdb files) associated
+   * with sequences
+   */
   private PDBEntry[] pdbEntry;
 
   /*
@@ -66,7 +72,7 @@ public abstract class AAStructureBindingModel extends
   /*
    * datasource protocol for access to PDBEntrylatest
    */
-  String protocol = null;
+  DataSourceType protocol = null;
 
   protected boolean colourBySequence = true;
 
@@ -75,6 +81,11 @@ public abstract class AAStructureBindingModel extends
   private boolean finishedInit = false;
 
   /**
+   * current set of model filenames loaded in the Jmol instance
+   */
+  protected String[] modelFileNames = null;
+
+  /**
    * Data bean class to simplify parameterisation in superposeStructures
    */
   protected class SuperposeData
@@ -126,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()
@@ -198,7 +204,7 @@ public abstract class AAStructureBindingModel extends
     return chains;
   }
 
-  public String getProtocol()
+  public DataSourceType getProtocol()
   {
     return protocol;
   }
@@ -239,24 +245,21 @@ public abstract class AAStructureBindingModel extends
     // TODO: give a more informative title when multiple structures are
     // displayed.
     StringBuilder title = new StringBuilder(64);
-    final PDBEntry pdbEntry = getPdbEntry(0);
+    final PDBEntry pdbe = getPdbEntry(0);
     title.append(viewerName + " view for " + getSequence()[0][0].getName()
-            + ":" + pdbEntry.getId());
+            + ":" + pdbe.getId());
 
     if (verbose)
     {
-      if (pdbEntry.getProperty() != null)
+      String method = (String) pdbe.getProperty("method");
+      if (method != null)
       {
-        if (pdbEntry.getProperty().get("method") != null)
-        {
-          title.append(" Method: ");
-          title.append(pdbEntry.getProperty().get("method"));
-        }
-        if (pdbEntry.getProperty().get("chains") != null)
-        {
-          title.append(" Chain:");
-          title.append(pdbEntry.getProperty().get("chains"));
-        }
+        title.append(" Method: ").append(method);
+      }
+      String chain = (String) pdbe.getProperty("chains");
+      if (chain != null)
+      {
+        title.append(" Chain:").append(chain);
       }
     }
     return title.toString();
@@ -521,6 +524,10 @@ public abstract class AAStructureBindingModel extends
   {
     int refStructure = -1;
     String[] files = getPdbFile();
+    if (files == null)
+    {
+      return -1;
+    }
     for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
     {
       StructureMapping[] mappings = getSsm().getMapping(files[pdbfnum]);
@@ -565,7 +572,11 @@ public abstract class AAStructureBindingModel extends
             }
             structures[pdbfnum].pdbId = mapping.getPdbId();
             structures[pdbfnum].isRna = theSequence.getRNA() != null;
-            // move on to next pdb file
+
+            /*
+             * move on to next pdb file (ignore sequences for other chains
+             * for the same structure)
+             */
             s = seqCountForPdbFile;
             break;
           }
@@ -660,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 92085c3..c05dac5 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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;
 
 public class ArrayUtils
index aa42228..b66e80d 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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;
 
 /**
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 405f6e6..04cb75e 100755 (executable)
@@ -26,9 +26,9 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -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);
       }
@@ -301,7 +301,8 @@ public class DBRefUtils
     @Override
     public boolean matches(DBRefEntry refa, DBRefEntry refb)
     {
-      if (refa.getSource() != null && refb.getSource() != null
+      if (refa.getSource() != null
+              && refb.getSource() != null
               && DBRefUtils.getCanonicalName(refb.getSource()).equals(
                       DBRefUtils.getCanonicalName(refa.getSource())))
       {
@@ -333,7 +334,8 @@ public class DBRefUtils
     @Override
     public boolean matches(DBRefEntry refa, DBRefEntry refb)
     {
-      if (refa.getSource() != null && refb.getSource() != null
+      if (refa.getSource() != null
+              && refb.getSource() != null
               && DBRefUtils.getCanonicalName(refb.getSource()).equals(
                       DBRefUtils.getCanonicalName(refa.getSource())))
       {
@@ -370,7 +372,8 @@ public class DBRefUtils
     @Override
     public boolean matches(DBRefEntry refa, DBRefEntry refb)
     {
-      if (refa.getSource() != null && refb.getSource() != null
+      if (refa.getSource() != null
+              && refb.getSource() != null
               && DBRefUtils.getCanonicalName(refb.getSource()).equals(
                       DBRefUtils.getCanonicalName(refa.getSource())))
       {
@@ -410,7 +413,8 @@ public class DBRefUtils
     @Override
     public boolean matches(DBRefEntry refa, DBRefEntry refb)
     {
-      if (refa.getSource() != null && refb.getSource() != null
+      if (refa.getSource() != null
+              && refb.getSource() != null
               && DBRefUtils.getCanonicalName(refb.getSource()).equals(
                       DBRefUtils.getCanonicalName(refa.getSource())))
       {
@@ -503,9 +507,7 @@ public class DBRefUtils
           PDBEntry pdbr = new PDBEntry();
           pdbr.setId(pdbid);
           pdbr.setType(PDBEntry.Type.PDB);
-          pdbr.setProperty(new Hashtable());
           pdbr.setChainCode(chaincode);
-          // pdbr.getProperty().put("CHAIN", chaincode);
           seq.addPDBId(pdbr);
         }
         else
@@ -608,4 +610,127 @@ public class DBRefUtils
     return matches;
   }
 
+  /**
+   * promote direct database references to primary for nucleotide or protein
+   * sequences if they have an appropriate primary ref
+   * <table>
+   * <tr>
+   * <th>Seq Type</th>
+   * <th>Primary DB</th>
+   * <th>Direct which will be promoted</th>
+   * </tr>
+   * <tr align=center>
+   * <td>peptides</td>
+   * <td>Ensembl</td>
+   * <td>Uniprot</td>
+   * </tr>
+   * <tr align=center>
+   * <td>peptides</td>
+   * <td>Ensembl</td>
+   * <td>Uniprot</td>
+   * </tr>
+   * <tr align=center>
+   * <td>dna</td>
+   * <td>Ensembl</td>
+   * <td>ENA</td>
+   * </tr>
+   * </table>
+   * 
+   * @param sequence
+   */
+  public static void ensurePrimaries(SequenceI sequence)
+  {
+    List<DBRefEntry> pr = sequence.getPrimaryDBRefs();
+    if (pr.size() == 0)
+    {
+      // nothing to do
+      return;
+    }
+    List<DBRefEntry> selfs = new ArrayList<DBRefEntry>();
+    {
+      DBRefEntry[] selfArray = selectDbRefs(!sequence.isProtein(),
+              sequence.getDBRefs());
+      if (selfArray == null || selfArray.length == 0)
+      {
+        // nothing to do
+        return;
+      }
+      selfs.addAll(Arrays.asList(selfArray));
+    }
+
+    // filter non-primary refs
+    for (DBRefEntry p : pr)
+    {
+      while (selfs.contains(p))
+      {
+        selfs.remove(p);
+      }
+    }
+    List<DBRefEntry> toPromote = new ArrayList<DBRefEntry>();
+
+    for (DBRefEntry p : pr)
+    {
+      List<String> promType = new ArrayList<String>();
+      if (sequence.isProtein())
+      {
+        switch (getCanonicalName(p.getSource()))
+        {
+        case DBRefSource.UNIPROT:
+          // case DBRefSource.UNIPROTKB:
+          // case DBRefSource.UP_NAME:
+          // search for and promote ensembl
+          promType.add(DBRefSource.ENSEMBL);
+          break;
+        case DBRefSource.ENSEMBL:
+          // search for and promote Uniprot
+          promType.add(DBRefSource.UNIPROT);
+          break;
+        }
+      }
+      else
+      {
+        // TODO: promote transcript refs
+      }
+
+      // collate candidates and promote them
+      DBRefEntry[] candidates = selectRefs(
+              selfs.toArray(new DBRefEntry[0]),
+              promType.toArray(new String[0]));
+      if (candidates != null)
+      {
+        for (DBRefEntry cand : candidates)
+        {
+          if (cand.hasMap())
+          {
+            if (cand.getMap().getTo() != null
+                    && cand.getMap().getTo() != sequence)
+            {
+              // can't promote refs with mappings to other sequences
+              continue;
+            }
+            if (cand.getMap().getMap().getFromLowest() != sequence
+                    .getStart()
+                    && cand.getMap().getMap().getFromHighest() != sequence
+                            .getEnd())
+            {
+              // can't promote refs with mappings from a region of this sequence
+              // - eg CDS
+              continue;
+            }
+          }
+          // and promote
+          cand.setVersion(p.getVersion() + " (promoted)");
+          selfs.remove(cand);
+          toPromote.add(cand);
+          if (!cand.isPrimaryCandidate())
+          {
+            System.out.println("Warning: Couldn't promote dbref "
+                    + cand.toString() + " for sequence "
+                    + sequence.toString());
+          }
+        }
+      }
+    }
+  }
+
 }
index 9582e2e..284ec10 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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 java.text.ParseException;
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 991a20a..a5a9460 100644 (file)
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*
  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
  * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
@@ -17,7 +17,7 @@
  * 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 java.io.IOException;
index fcea21d..71e2c7e 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;
@@ -62,9 +79,9 @@ public class ImageMaker
 
   public enum TYPE
   {
-    EPS("EPS", MessageManager.getString("label.eps_file"), getEPSChooser()), PNG(
-            "PNG", MessageManager.getString("label.png_image"),
-            getPNGChooser()), SVG("SVG", "SVG", getSVGChooser());
+    EPS("EPS", MessageManager.getString("label.eps_file"), getEPSChooser()),
+    PNG("PNG", MessageManager.getString("label.png_image"), getPNGChooser()),
+    SVG("SVG", "SVG", getSVGChooser());
 
     private JalviewFileChooser chooser;
 
@@ -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, 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, 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, SVG_DESCRIPTION);
   }
 }
index dc5bee8..58abdc3 100644 (file)
@@ -342,7 +342,8 @@ public class MapList
    */
   public static List<int[]> coalesceRanges(final List<int[]> ranges)
   {
-    if (ranges == null || ranges.size() < 2) {
+    if (ranges == null || ranges.size() < 2)
+    {
       return ranges;
     }
 
@@ -353,7 +354,7 @@ public class MapList
     lastRange = new int[] { lastRange[0], lastRange[1] };
     merged.add(lastRange);
     boolean first = true;
-    
+
     for (final int[] range : ranges)
     {
       if (first)
@@ -387,7 +388,8 @@ public class MapList
        * if next range is in the same direction as last and contiguous,
        * just update the end position of the last range
        */
-      boolean sameDirection = range[1] == range[0] || direction == lastDirection;
+      boolean sameDirection = range[1] == range[0]
+              || direction == lastDirection;
       boolean extending = range[0] == lastRange[1] + lastDirection;
       boolean overlapping = (lastDirection == 1 && range[0] >= lastRange[0] && range[0] <= lastRange[1])
               || (lastDirection == -1 && range[0] <= lastRange[0] && range[0] >= lastRange[1]);
@@ -404,7 +406,7 @@ public class MapList
         lastDirection = (range[1] == range[0]) ? lastDirection : direction;
       }
     }
-    
+
     return changed ? merged : ranges;
   }
 
index da83338..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())
@@ -374,16 +375,17 @@ public final class MappingUtils
               /*
                * Found a sequence mapping. Locate the start/end mapped residues.
                */
-              List<AlignedCodonFrame> mapping = Arrays.asList(new AlignedCodonFrame[] { acf });
-              SearchResults sr = buildSearchResults(selected,
+              List<AlignedCodonFrame> mapping = Arrays
+                      .asList(new AlignedCodonFrame[] { acf });
+              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());
@@ -555,9 +557,9 @@ public final class MappingUtils
    * @param fromGapChar
    */
   protected static void mapHiddenColumns(int[] hidden,
-          List<AlignedCodonFrame> mappings,
-          ColumnSelection mappedColumns, List<SequenceI> fromSequences,
-          List<SequenceI> toSequences, char fromGapChar)
+          List<AlignedCodonFrame> mappings, ColumnSelection mappedColumns,
+          List<SequenceI> fromSequences, List<SequenceI> toSequences,
+          char fromGapChar)
   {
     for (int col = hidden[0]; col <= hidden[1]; col++)
     {
@@ -589,9 +591,9 @@ public final class MappingUtils
    * @param fromGapChar
    */
   protected static void mapColumn(int col,
-          List<AlignedCodonFrame> mappings,
-          ColumnSelection mappedColumns, List<SequenceI> fromSequences,
-          List<SequenceI> toSequences, char fromGapChar)
+          List<AlignedCodonFrame> mappings, ColumnSelection mappedColumns,
+          List<SequenceI> fromSequences, List<SequenceI> toSequences,
+          char fromGapChar)
   {
     int[] mappedTo = findMappedColumns(col, mappings, fromSequences,
             toSequences, fromGapChar);
@@ -646,9 +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();
@@ -893,7 +894,7 @@ public final class MappingUtils
     {
       return ranges;
     }
-  
+
     int[] copy = Arrays.copyOf(ranges, ranges.length);
     int sxpos = -1;
     int cdspos = 0;
@@ -921,7 +922,7 @@ public final class MappingUtils
         break;
       }
     }
-  
+
     if (sxpos > 0)
     {
       /*
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?
index c1ef153..62fd56e 100755 (executable)
@@ -670,7 +670,7 @@ public class QuickSort
     final int length = arr.length;
     Integer[] indices = makeIndexArray(length);
     Arrays.sort(indices, new IntComparator(arr, ascending));
-  
+
     /*
      * Copy the array values as per the sorted indices
      */
@@ -681,7 +681,7 @@ public class QuickSort
       sortedInts[i] = arr[indices[i]];
       sortedObjects[i] = s[indices[i]];
     }
-  
+
     /*
      * And copy the sorted values back into the arrays
      */
@@ -707,7 +707,7 @@ public class QuickSort
     final int length = arr.length;
     Integer[] indices = makeIndexArray(length);
     Arrays.sort(indices, new ExternalComparator(arr, ascending));
-  
+
     /*
      * Copy the array values as per the sorted indices
      */
@@ -718,7 +718,7 @@ public class QuickSort
       sortedStrings[i] = arr[indices[i]];
       sortedObjects[i] = s[indices[i]];
     }
-  
+
     /*
      * And copy the sorted values back into the arrays
      */
@@ -743,7 +743,7 @@ public class QuickSort
     final int length = arr.length;
     Integer[] indices = makeIndexArray(length);
     Arrays.sort(indices, new DoubleComparator(arr, ascending));
-  
+
     /*
      * Copy the array values as per the sorted indices
      */
@@ -754,7 +754,7 @@ public class QuickSort
       sortedDoubles[i] = arr[indices[i]];
       sortedObjects[i] = s[indices[i]];
     }
-  
+
     /*
      * And copy the sorted values back into the arrays
      */
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;
+  }
+}
index ccc2012..b5ab40d 100644 (file)
@@ -248,7 +248,7 @@ public class StringUtils
     }
     return "" + separator;
   }
-  
+
   /**
    * Converts a list to a string with a delimiter before each term except the
    * first. Returns an empty string given a null or zero-length argument. This
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 80319be..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;
@@ -612,7 +613,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
     boolean recalc = false;
     if (cs != null)
     {
-      cs.setConservationApplied(recalc = getConservationSelected());
+      recalc = getConservationSelected();
       if (getAbovePIDThreshold() || cs instanceof PIDColourScheme
               || cs instanceof Blosum62ColourScheme)
       {
@@ -629,6 +630,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
         cs.setConsensus(hconsensus);
         cs.setConservation(hconservation);
       }
+      cs.setConservationApplied(getConservationSelected());
       cs.alignmentChanged(alignment, hiddenRepSequences);
     }
     if (getColourAppliesToAllGroups())
@@ -699,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
@@ -733,7 +735,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public void setSequenceConsensusHash(Hashtable[] hconsensus)
+  public void setSequenceConsensusHash(ProfilesI hconsensus)
   {
     this.hconsensus = hconsensus;
   }
@@ -745,7 +747,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public Hashtable[] getSequenceConsensusHash()
+  public ProfilesI getSequenceConsensusHash()
   {
     return hconsensus;
   }
@@ -938,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);
   }
@@ -1573,7 +1577,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   public boolean isHiddenRepSequence(SequenceI seq)
   {
     return (hiddenRepSequences != null && hiddenRepSequences
-                    .containsKey(seq));
+            .containsKey(seq));
   }
 
   /**
@@ -1863,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));
       }
@@ -2714,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())
@@ -2796,8 +2800,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   public void expandColSelection(SequenceGroup sg, boolean wholewidth)
   {
     int sgs, sge;
-    if (sg != null
-            && (sgs = sg.getStartRes()) >= 0
+    if (sg != null && (sgs = sg.getStartRes()) >= 0
             && sg.getStartRes() <= (sge = sg.getEndRes())
             && !this.hasSelectedColumns())
     {
@@ -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 d813fe2..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,15 +568,22 @@ 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
   public void setColour(String featureType, FeatureColourI col)
   {
-     featureColours.put(featureType, col);
+    featureColours.put(featureType, col);
   }
 
   public void setTransparency(float value)
index 771c492..0ad8726 100644 (file)
@@ -95,6 +95,7 @@ public abstract class AlignCalcWorker implements AlignCalcWorkerI
       ourAnnots.clear();
     }
   }
+
   // TODO: allow GUI to query workers associated with annotation to add items to
   // annotation label panel popup menu
 
@@ -118,8 +119,10 @@ public abstract class AlignCalcWorker implements AlignCalcWorkerI
     float max = Float.MIN_VALUE;
     float min = Float.MAX_VALUE;
     boolean set = false;
-    for (Annotation a : anns) {
-      if (a != null) {
+    for (Annotation a : anns)
+    {
+      if (a != null)
+      {
         set = true;
         float val = a.value;
         max = Math.max(max, val);
index 2b7d9e1..beee1eb 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.workers;
 
 import jalview.api.AlignViewportI;
@@ -69,7 +89,7 @@ public class AlignmentAnnotationFactory
   {
     // TODO need an interface for AlignFrame by which to access
     // its AlignViewportI and AlignmentViewPanel
-    AlignFrame currentAlignFrame = Jalview.getCurrentAlignFrame() ;
+    AlignFrame currentAlignFrame = Jalview.getCurrentAlignFrame();
     if (currentAlignFrame != null)
     {
       newCalculator(currentAlignFrame.getViewport(), currentAlignFrame
@@ -91,8 +111,7 @@ public class AlignmentAnnotationFactory
    *          provider of AlignmentAnnotation for the alignment
    */
   public static void newCalculator(AlignViewportI viewport,
-          AlignmentViewPanel panel,
-          AnnotationProviderI calculator)
+          AlignmentViewPanel panel, AnnotationProviderI calculator)
   {
     new AnnotationWorker(viewport, panel, calculator);
   }
index bd24461..d11429e 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.workers;
 
 import jalview.api.FeatureRenderer;
index 2f73cb5..dd56aaf 100644 (file)
@@ -168,8 +168,7 @@ class ColumnCounterWorker extends AlignCalcWorker
      */
     AlignmentAnnotation ann = alignViewport.getAlignment()
             .findOrCreateAnnotation(counter.getName(),
-                    counter.getDescription(), false, null,
-                    null);
+                    counter.getDescription(), false, null, null);
     ann.description = counter.getDescription();
     ann.showAllColLabels = true;
     ann.scaleColLabel = true;
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 aa4a283..3a080ec 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.workers;
 
 import jalview.datamodel.SequenceFeature;
index ca403c5..fd511dc 100644 (file)
@@ -29,15 +29,19 @@ import jalview.datamodel.Mapping;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.CutAndPasteTransfer;
+import jalview.gui.DasSourceBrowser;
 import jalview.gui.Desktop;
 import jalview.gui.FeatureSettings;
 import jalview.gui.IProgressIndicator;
 import jalview.gui.OOMWarning;
+import jalview.util.DBRefUtils;
 import jalview.util.MessageManager;
 import jalview.ws.dbsources.das.api.jalviewSourceI;
+import jalview.ws.dbsources.das.datamodel.DasSequenceSource;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
@@ -45,6 +49,7 @@ import java.util.StringTokenizer;
 import java.util.Vector;
 
 import uk.ac.ebi.picr.model.UPEntry;
+import uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperServiceLocator;
 
 /**
  * Implements a runnable for validating a sequence against external databases
@@ -55,21 +60,19 @@ import uk.ac.ebi.picr.model.UPEntry;
  */
 public class DBRefFetcher implements Runnable
 {
+  private static final String NEWLINE = System.lineSeparator();
+
   public interface FetchFinishedListenerI
   {
     void finished();
   }
 
-  private List<FetchFinishedListenerI> listeners;
-
   SequenceI[] dataset;
 
   IProgressIndicator progressWindow;
 
   CutAndPasteTransfer output = new CutAndPasteTransfer();
 
-  StringBuffer sbuffer = new StringBuffer();
-
   boolean running = false;
 
   /**
@@ -77,17 +80,19 @@ public class DBRefFetcher implements Runnable
    */
   uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperInterface picrClient = null;
 
-  // /This will be a collection of Vectors of sequenceI refs.
+  // This will be a collection of Vectors of sequenceI refs.
   // The key will be the seq name or accession id of the seq
-  Hashtable seqRefs;
+  Hashtable<String, Vector<SequenceI>> seqRefs;
 
   DbSourceProxy[] dbSources;
 
   SequenceFetcher sfetcher;
 
+  private List<FetchFinishedListenerI> listeners;
+
   private SequenceI[] alseqs;
 
-  /**
+  /*
    * when true - retrieved sequences will be trimmed to cover longest derived
    * alignment sequence
    */
@@ -110,7 +115,8 @@ public class DBRefFetcher implements Runnable
    */
   public DBRefFetcher(SequenceI[] seqs,
           IProgressIndicator progressIndicatorFrame,
-          DbSourceProxy[] sources, FeatureSettings featureSettings, boolean isNucleotide)
+          DbSourceProxy[] sources, FeatureSettings featureSettings,
+          boolean isNucleotide)
   {
     listeners = new ArrayList<FetchFinishedListenerI>();
     this.progressWindow = progressIndicatorFrame;
@@ -137,59 +143,74 @@ public class DBRefFetcher implements Runnable
     trimDsSeqs = Cache.getDefault("TRIM_FETCHED_DATASET_SEQS", true);
     if (sources == null)
     {
-      // af.featureSettings_actionPerformed(null);
-      String[] defdb = null, otherdb = sfetcher
-              .getDbInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);
-      List<DbSourceProxy> selsources = new ArrayList<DbSourceProxy>();
-      Vector<jalviewSourceI> dasselsrc = (featureSettings != null) ? featureSettings
-              .getSelectedSources() : new jalview.gui.DasSourceBrowser()
-              .getSelectedSources();
-      Enumeration<jalviewSourceI> en = dasselsrc.elements();
-      while (en.hasMoreElements())
+      setDatabaseSources(featureSettings, isNucleotide);
+    }
+    else
+    {
+      // we assume the caller knows what they're doing and ensured that all the
+      // db source names are valid
+      dbSources = sources;
+    }
+  }
+
+  /**
+   * Helper method to configure the list of database sources to query
+   * 
+   * @param featureSettings
+   * @param forNucleotide
+   */
+  void setDatabaseSources(FeatureSettings featureSettings,
+          boolean forNucleotide)
+  {
+    // af.featureSettings_actionPerformed(null);
+    String[] defdb = null;
+    List<DbSourceProxy> selsources = new ArrayList<DbSourceProxy>();
+    Vector<jalviewSourceI> dasselsrc = (featureSettings != null) ? featureSettings
+            .getSelectedSources() : new DasSourceBrowser()
+            .getSelectedSources();
+
+    for (jalviewSourceI src : dasselsrc)
+    {
+      List<DbSourceProxy> sp = src.getSequenceSourceProxies();
+      if (sp != null)
       {
-        jalviewSourceI src = en.nextElement();
-        List<DbSourceProxy> sp = src.getSequenceSourceProxies();
-        if (sp != null)
+        selsources.addAll(sp);
+        if (sp.size() > 1)
         {
-          selsources.addAll(sp);
-          if (sp.size() > 1)
-          {
-            Cache.log.debug("Added many Db Sources for :" + src.getTitle());
-          }
+          Cache.log.debug("Added many Db Sources for :" + src.getTitle());
         }
       }
-      // select appropriate databases based on alignFrame context.
-      if (isNucleotide)
-      {
-        defdb = DBRefSource.DNACODINGDBS;
-      }
-      else
-      {
-        defdb = DBRefSource.PROTEINDBS;
-      }
-      List<DbSourceProxy> srces = new ArrayList<DbSourceProxy>();
-      for (String ddb : defdb)
+    }
+    // select appropriate databases based on alignFrame context.
+    if (forNucleotide)
+    {
+      defdb = DBRefSource.DNACODINGDBS;
+    }
+    else
+    {
+      defdb = DBRefSource.PROTEINDBS;
+    }
+    List<DbSourceProxy> srces = new ArrayList<DbSourceProxy>();
+    for (String ddb : defdb)
+    {
+      List<DbSourceProxy> srcesfordb = sfetcher.getSourceProxy(ddb);
+      if (srcesfordb != null)
       {
-        List<DbSourceProxy> srcesfordb = sfetcher.getSourceProxy(ddb);
-        if (srcesfordb != null)
+        for (DbSourceProxy src : srcesfordb)
         {
-          srces.addAll(srcesfordb);
+          if (!srces.contains(src))
+          {
+            srces.addAll(srcesfordb);
+          }
         }
       }
-      // append the PDB data source, since it is 'special', catering for both
-      // nucleotide and protein
-      srces.addAll(sfetcher.getSourceProxy(DBRefSource.PDB));
-
-      // append the selected sequence sources to the default dbs
-      srces.addAll(selsources);
-      dbSources = srces.toArray(new DbSourceProxy[0]);
-    }
-    else
-    {
-      // we assume the caller knows what they're doing and ensured that all the
-      // db source names are valid
-      dbSources = sources;
     }
+    // append the PDB data source, since it is 'special', catering for both
+    // nucleotide and protein
+    // srces.addAll(sfetcher.getSourceProxy(DBRefSource.PDB));
+
+    srces.addAll(selsources);
+    dbSources = srces.toArray(new DbSourceProxy[srces.size()]);
   }
 
   /**
@@ -224,7 +245,7 @@ public class DBRefFetcher implements Runnable
     }
     // append additional sources
     DbSourceProxy[] otherdb = sfetcher
-            .getDbSourceProxyInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);
+            .getDbSourceProxyInstances(DasSequenceSource.class);
     if (otherdb != null && otherdb.length > 0)
     {
       DbSourceProxy[] newsrc = new DbSourceProxy[dbSources.length
@@ -243,6 +264,9 @@ public class DBRefFetcher implements Runnable
    */
   public void fetchDBRefs(boolean waitTillFinished)
   {
+    // TODO can we not simply write
+    // if (waitTillFinished) { run(); } else { new Thread(this).start(); }
+
     Thread thread = new Thread(this);
     thread.start();
     running = true;
@@ -274,10 +298,10 @@ public class DBRefFetcher implements Runnable
   {
     key = key.toUpperCase();
 
-    Vector seqs;
+    Vector<SequenceI> seqs;
     if (seqRefs.containsKey(key))
     {
-      seqs = (Vector) seqRefs.get(key);
+      seqs = seqRefs.get(key);
 
       if (seqs != null && !seqs.contains(seq))
       {
@@ -285,14 +309,14 @@ public class DBRefFetcher implements Runnable
       }
       else if (seqs == null)
       {
-        seqs = new Vector();
+        seqs = new Vector<SequenceI>();
         seqs.addElement(seq);
       }
 
     }
     else
     {
-      seqs = new Vector();
+      seqs = new Vector<SequenceI>();
       seqs.addElement(seq);
     }
 
@@ -317,13 +341,13 @@ public class DBRefFetcher implements Runnable
     {
       progressWindow.setProgressBar(
               MessageManager.getString("status.fetching_db_refs"),
-            startTime);
+              startTime);
     }
     try
     {
       if (Cache.getDefault("DBREFFETCH_USEPICR", false))
       {
-        picrClient = new uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperServiceLocator()
+        picrClient = new AccessionMapperServiceLocator()
                 .getAccessionMapperPort();
       }
     } catch (Exception e)
@@ -331,149 +355,145 @@ public class DBRefFetcher implements Runnable
       System.err.println("Couldn't locate PICR service instance.\n");
       e.printStackTrace();
     }
+
+    Vector<SequenceI> sdataset = new Vector<SequenceI>(
+            Arrays.asList(dataset));
+    List<String> warningMessages = new ArrayList<String>();
+
     int db = 0;
-    Vector sdataset = new Vector();
-    for (int s = 0; s < dataset.length; s++)
-    {
-      sdataset.addElement(dataset[s]);
-    }
     while (sdataset.size() > 0 && db < dbSources.length)
     {
-      int maxqlen = 1; // default number of queries made to at one time
-      System.err.println("Verifying against " + dbSources[db].getDbName());
-      boolean dn = false;
+      int maxqlen = 1; // default number of queries made at one time
+      System.out.println("Verifying against " + dbSources[db].getDbName());
 
       // iterate through db for each remaining un-verified sequence
       SequenceI[] currSeqs = new SequenceI[sdataset.size()];
       sdataset.copyInto(currSeqs);// seqs that are to be validated against
       // dbSources[db]
-      Vector queries = new Vector(); // generated queries curSeq
-      seqRefs = new Hashtable();
+      Vector<String> queries = new Vector<String>(); // generated queries curSeq
+      seqRefs = new Hashtable<String, Vector<SequenceI>>();
 
       int seqIndex = 0;
 
-      jalview.ws.seqfetcher.DbSourceProxy dbsource = dbSources[db];
+      DbSourceProxy dbsource = dbSources[db];
+      // for moment, we dumbly iterate over all retrieval sources for a
+      // particular database
+      // TODO: introduce multithread multisource queries and logic to remove a
+      // query from other sources if any source for a database returns a
+      // record
+      maxqlen = dbsource.getMaximumQueryCount();
+
+      while (queries.size() > 0 || seqIndex < currSeqs.length)
       {
-        // for moment, we dumbly iterate over all retrieval sources for a
-        // particular database
-        // TODO: introduce multithread multisource queries and logic to remove a
-        // query from other sources if any source for a database returns a
-        // record
-        maxqlen = dbsource.getMaximumQueryCount();
-
-        while (queries.size() > 0 || seqIndex < currSeqs.length)
+        if (queries.size() > 0)
         {
-          if (queries.size() > 0)
-          {
-            // Still queries to make for current seqIndex
-            StringBuffer queryString = new StringBuffer("");
-            int numq = 0, nqSize = (maxqlen > queries.size()) ? queries
-                    .size() : maxqlen;
+          // Still queries to make for current seqIndex
+          StringBuffer queryString = new StringBuffer("");
+          int numq = 0;
+          int nqSize = (maxqlen > queries.size()) ? queries.size()
+                  : maxqlen;
 
-            while (queries.size() > 0 && numq < nqSize)
-            {
-              String query = (String) queries.elementAt(0);
-              if (dbsource.isValidReference(query))
-              {
-                queryString.append((numq == 0) ? "" : dbsource
-                        .getAccessionSeparator());
-                queryString.append(query);
-                numq++;
-              }
-              // remove the extracted query string
-              queries.removeElementAt(0);
-            }
-            // make the queries and process the response
-            AlignmentI retrieved = null;
-            try
-            {
-              if (jalview.bin.Cache.log.isDebugEnabled())
-              {
-                jalview.bin.Cache.log.debug("Querying "
-                        + dbsource.getDbName() + " with : '"
-                        + queryString.toString() + "'");
-              }
-              retrieved = dbsource.getSequenceRecords(queryString
-                      .toString());
-            } catch (Exception ex)
-            {
-              ex.printStackTrace();
-            } catch (OutOfMemoryError err)
+          while (queries.size() > 0 && numq < nqSize)
+          {
+            String query = queries.elementAt(0);
+            if (dbsource.isValidReference(query))
             {
-              new OOMWarning("retrieving database references ("
-                      + queryString.toString() + ")", err);
+              queryString.append((numq == 0) ? "" : dbsource
+                      .getAccessionSeparator());
+              queryString.append(query);
+              numq++;
             }
-            if (retrieved != null)
+            // remove the extracted query string
+            queries.removeElementAt(0);
+          }
+          // make the queries and process the response
+          AlignmentI retrieved = null;
+          try
+          {
+            if (Cache.log.isDebugEnabled())
             {
-              transferReferences(sdataset, dbsource.getDbSource(),
-                      retrieved, trimDsSeqs);
+              Cache.log.debug("Querying " + dbsource.getDbName()
+                      + " with : '" + queryString.toString() + "'");
             }
+            retrieved = dbsource.getSequenceRecords(queryString.toString());
+          } catch (Exception ex)
+          {
+            ex.printStackTrace();
+          } catch (OutOfMemoryError err)
+          {
+            new OOMWarning("retrieving database references ("
+                    + queryString.toString() + ")", err);
+          }
+          if (retrieved != null)
+          {
+            transferReferences(sdataset, dbsource.getDbSource(), retrieved,
+                    trimDsSeqs, warningMessages);
           }
-          else
+        }
+        else
+        {
+          // make some more strings for use as queries
+          for (int i = 0; (seqIndex < dataset.length) && (i < 50); seqIndex++, i++)
           {
-            // make some more strings for use as queries
-            for (int i = 0; (seqIndex < dataset.length) && (i < 50); seqIndex++, i++)
+            SequenceI sequence = dataset[seqIndex];
+            DBRefEntry[] uprefs = DBRefUtils.selectRefs(
+                    sequence.getDBRefs(),
+                    new String[] { dbsource.getDbSource() }); // jalview.datamodel.DBRefSource.UNIPROT
+            // });
+            // check for existing dbrefs to use
+            if (uprefs != null && uprefs.length > 0)
             {
-              SequenceI sequence = dataset[seqIndex];
-              DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(
-                      sequence.getDBRefs(),
-                      new String[] { dbsource.getDbSource() }); // jalview.datamodel.DBRefSource.UNIPROT
-              // });
-              // check for existing dbrefs to use
-              if (uprefs != null && uprefs.length > 0)
+              for (int j = 0; j < uprefs.length; j++)
               {
-                for (int j = 0; j < uprefs.length; j++)
-                {
-                  addSeqId(sequence, uprefs[j].getAccessionId());
-                  queries.addElement(uprefs[j].getAccessionId()
-                          .toUpperCase());
-                }
+                addSeqId(sequence, uprefs[j].getAccessionId());
+                queries.addElement(uprefs[j].getAccessionId().toUpperCase());
               }
-              else
+            }
+            else
+            {
+              // generate queries from sequence ID string
+              StringTokenizer st = new StringTokenizer(sequence.getName(),
+                      "|");
+              while (st.hasMoreTokens())
               {
-                // generate queries from sequence ID string
-                StringTokenizer st = new StringTokenizer(
-                        sequence.getName(), "|");
-                while (st.hasMoreTokens())
+                String token = st.nextToken();
+                UPEntry[] presp = null;
+                if (picrClient != null)
                 {
-                  String token = st.nextToken();
-                  UPEntry[] presp = null;
-                  if (picrClient != null)
+                  // resolve the string against PICR to recover valid IDs
+                  try
                   {
-                    // resolve the string against PICR to recover valid IDs
-                    try
-                    {
-                      presp = picrClient.getUPIForAccession(token, null,
-                              picrClient.getMappedDatabaseNames(), null,
-                              true);
-                    } catch (Exception e)
-                    {
-                      System.err.println("Exception with Picr for '"
-                              + token + "'\n");
-                      e.printStackTrace();
-                    }
-                  }
-                  if (presp != null && presp.length > 0)
+                    presp = picrClient
+                            .getUPIForAccession(token, null,
+                                    picrClient.getMappedDatabaseNames(),
+                                    null, true);
+                  } catch (Exception e)
                   {
-                    for (int id = 0; id < presp.length; id++)
-                    {
-                      // construct sequences from response if sequences are
-                      // present, and do a transferReferences
-                      // otherwise transfer non sequence x-references directly.
-                    }
-                    System.out
-                            .println("Validated ID against PICR... (for what its worth):"
-                                    + token);
-                    addSeqId(sequence, token);
-                    queries.addElement(token.toUpperCase());
+                    System.err.println("Exception with Picr for '" + token
+                            + "'\n");
+                    e.printStackTrace();
                   }
-                  else
+                }
+                if (presp != null && presp.length > 0)
+                {
+                  for (int id = 0; id < presp.length; id++)
                   {
-                    // if ()
-                    // System.out.println("Not querying source with token="+token+"\n");
-                    addSeqId(sequence, token);
-                    queries.addElement(token.toUpperCase());
+                    // construct sequences from response if sequences are
+                    // present, and do a transferReferences
+                    // otherwise transfer non sequence x-references directly.
                   }
+                  System.out
+                          .println("Validated ID against PICR... (for what its worth):"
+                                  + token);
+                  addSeqId(sequence, token);
+                  queries.addElement(token.toUpperCase());
+                }
+                else
+                {
+                  // if ()
+                  // System.out.println("Not querying source with token="+token+"\n");
+                  addSeqId(sequence, token);
+                  queries.addElement(token.toUpperCase());
                 }
               }
             }
@@ -482,15 +502,20 @@ public class DBRefFetcher implements Runnable
       }
       // advance to next database
       db++;
-    } // all databases have been queries.
-    if (sbuffer.length() > 0)
+    } // all databases have been queried
+    if (!warningMessages.isEmpty())
     {
-      output.setText(MessageManager
-              .getString("label.your_sequences_have_been_verified")
-              + sbuffer.toString());
+      StringBuilder sb = new StringBuilder(warningMessages.size() * 30);
+      sb.append(MessageManager
+              .getString("label.your_sequences_have_been_verified"));
+      for (String msg : warningMessages)
+      {
+        sb.append(msg).append(NEWLINE);
+      }
+      output.setText(sb.toString());
+
       Desktop.addInternalFrame(output,
-              MessageManager.getString("label.sequence_names_updated"),
-              600, 300);
+              MessageManager.getString("label.sequences_updated"), 600, 300);
       // The above is the dataset, we must now find out the index
       // of the viewed sequence
 
@@ -511,57 +536,61 @@ public class DBRefFetcher implements Runnable
 
   /**
    * Verify local sequences in seqRefs against the retrieved sequence database
-   * records.
+   * records. Returns true if any sequence was modified as a result (start/end
+   * changed and/or sequence enlarged), else false.
    * 
+   * @param sdataset
+   *          dataset sequences we are retrieving for
+   * @param dbSource
+   *          database source we are retrieving from
+   * @param retrievedAl
+   *          retrieved sequences as alignment
    * @param trimDatasetSeqs
-   * 
+   *          if true, sequences will not be enlarged to match longer retrieved
+   *          sequences, only their start/end adjusted
+   * @param warningMessages
+   *          a list of messages to add to
    */
-  void transferReferences(Vector sdataset, String dbSource,
-          AlignmentI retrievedAl, boolean trimDatasetSeqs) // File
-  // file)
+  boolean transferReferences(Vector<SequenceI> sdataset, String dbSource,
+          AlignmentI retrievedAl, boolean trimDatasetSeqs,
+          List<String> warningMessages)
   {
-    System.out.println("trimming ? " + trimDatasetSeqs);
+    // System.out.println("trimming ? " + trimDatasetSeqs);
     if (retrievedAl == null || retrievedAl.getHeight() == 0)
     {
-      return;
+      return false;
     }
+
+    boolean modified = false;
     SequenceI[] retrieved = recoverDbSequences(retrievedAl
             .getSequencesArray());
     SequenceI sequence = null;
-    boolean transferred = false;
-    StringBuffer messages = new StringBuffer();
 
-    // Vector entries = new Uniprot().getUniprotEntries(file);
-
-    int i, iSize = retrieved.length; // entries == null ? 0 : entries.size();
-    // UniprotEntry entry;
-    for (i = 0; i < iSize; i++)
+    for (SequenceI retrievedSeq : retrieved)
     {
-      SequenceI entry = retrieved[i]; // (UniprotEntry) entries.elementAt(i);
-
       // Work out which sequences this sequence matches,
       // taking into account all accessionIds and names in the file
-      Vector sequenceMatches = new Vector();
+      Vector<SequenceI> sequenceMatches = new Vector<SequenceI>();
       // look for corresponding accession ids
-      DBRefEntry[] entryRefs = jalview.util.DBRefUtils.selectRefs(
-              entry.getDBRefs(), new String[] { dbSource });
+      DBRefEntry[] entryRefs = DBRefUtils.selectRefs(
+              retrievedSeq.getDBRefs(), new String[] { dbSource });
       if (entryRefs == null)
       {
         System.err
                 .println("Dud dbSource string ? no entryrefs selected for "
-                        + dbSource + " on " + entry.getName());
+                        + dbSource + " on " + retrievedSeq.getName());
         continue;
       }
       for (int j = 0; j < entryRefs.length; j++)
       {
-        String accessionId = entryRefs[j].getAccessionId(); // .getAccession().elementAt(j).toString();
+        String accessionId = entryRefs[j].getAccessionId();
         // match up on accessionId
         if (seqRefs.containsKey(accessionId.toUpperCase()))
         {
-          Vector seqs = (Vector) seqRefs.get(accessionId);
+          Vector<SequenceI> seqs = seqRefs.get(accessionId);
           for (int jj = 0; jj < seqs.size(); jj++)
           {
-            sequence = (SequenceI) seqs.elementAt(jj);
+            sequence = seqs.elementAt(jj);
             if (!sequenceMatches.contains(sequence))
             {
               sequenceMatches.addElement(sequence);
@@ -569,17 +598,17 @@ public class DBRefFetcher implements Runnable
           }
         }
       }
-      if (sequenceMatches.size() == 0)
+      if (sequenceMatches.isEmpty())
       {
         // failed to match directly on accessionId==query so just compare all
         // sequences to entry
-        Enumeration e = seqRefs.keys();
+        Enumeration<String> e = seqRefs.keys();
         while (e.hasMoreElements())
         {
-          Vector sqs = (Vector) seqRefs.get(e.nextElement());
+          Vector<SequenceI> sqs = seqRefs.get(e.nextElement());
           if (sqs != null && sqs.size() > 0)
           {
-            Enumeration sqe = sqs.elements();
+            Enumeration<SequenceI> sqe = sqs.elements();
             while (sqe.hasMoreElements())
             {
               sequenceMatches.addElement(sqe.nextElement());
@@ -603,10 +632,11 @@ public class DBRefFetcher implements Runnable
        */
       // sequenceMatches now contains the set of all sequences associated with
       // the returned db record
-      String entrySeq = entry.getSequenceAsString().toUpperCase();
+      final String retrievedSeqString = retrievedSeq.getSequenceAsString();
+      String entrySeq = retrievedSeqString.toUpperCase();
       for (int m = 0; m < sequenceMatches.size(); m++)
       {
-        sequence = (SequenceI) sequenceMatches.elementAt(m);
+        sequence = sequenceMatches.elementAt(m);
         // only update start and end positions and shift features if there are
         // no existing references
         // TODO: test for legacy where uniprot or EMBL refs exist but no
@@ -616,13 +646,13 @@ public class DBRefFetcher implements Runnable
         // TODO:
         // verify sequence against the entry sequence
 
+        Mapping mp;
+        final int sequenceStart = sequence.getStart();
+
+        boolean remoteEnclosesLocal = false;
         String nonGapped = AlignSeq.extractGaps("-. ",
                 sequence.getSequenceAsString()).toUpperCase();
-
         int absStart = entrySeq.indexOf(nonGapped);
-        Mapping mp;
-
-        final int sequenceStart = sequence.getStart();
         if (absStart == -1)
         {
           // couldn't find local sequence in sequence from database, so check if
@@ -632,17 +662,20 @@ public class DBRefFetcher implements Runnable
           {
             // verification failed. couldn't find any relationship between
             // entrySeq and local sequence
-            messages.append(sequence.getName()
-                    + " SEQUENCE NOT %100 MATCH \n");
+            // messages suppressed as many-to-many matches are confusing
+            // String msg = sequence.getName()
+            // + " Sequence not 100% match with "
+            // + retrievedSeq.getName();
+            // addWarningMessage(warningMessages, msg);
             continue;
           }
           /*
-           * found match for the whole of the database sequence within the local
-           * sequence's reference frame. 
+           * retrieved sequence is a proper subsequence of local sequence
            */
-          transferred = true;
-          sbuffer.append(sequence.getName() + " HAS " + absStart
-                  + " PREFIXED RESIDUES COMPARED TO " + dbSource + "\n");
+          String msg = sequence.getName() + " has " + absStart
+                  + " prefixed residues compared to "
+                  + retrievedSeq.getName();
+          addWarningMessage(warningMessages, msg);
 
           /*
            * So create a mapping to the external entry from the matching region of 
@@ -650,50 +683,40 @@ public class DBRefFetcher implements Runnable
            */
           mp = new Mapping(null, new int[] { sequenceStart + absStart,
               sequenceStart + absStart + entrySeq.length() - 1 }, new int[]
-          { entry.getStart(), entry.getStart() + entrySeq.length() - 1 },
-                  1, 1);
+          { retrievedSeq.getStart(),
+              retrievedSeq.getStart() + entrySeq.length() - 1 }, 1, 1);
           updateRefFrame = false;
         }
         else
         {
           /*
-           * found a match for the local sequence within sequence from 
-           * the external database 
+           * local sequence is a subsequence of (or matches) retrieved sequence
            */
-          transferred = true;
-
-          // update start and end of local sequence to place it in entry's
-          // reference frame.
-          // apply identity map map from whole of local sequence to matching
-          // region of database
-          // sequence
-          mp = null; // Mapping.getIdentityMap();
-          // new Mapping(null,
-          // new int[] { absStart+sequence.getStart(),
-          // absStart+sequence.getStart()+entrySeq.length()-1},
-          // new int[] { entry.getStart(), entry.getEnd() }, 1, 1);
-          // relocate local features for updated start
+          remoteEnclosesLocal = true;
+          mp = null;
 
           if (updateRefFrame)
           {
-            if (sequence.getSequenceFeatures() != null)
+            SequenceFeature[] sfs = sequence.getSequenceFeatures();
+            if (sfs != null)
             {
               /*
                * relocate existing sequence features by offset
                */
-              SequenceFeature[] sf = sequence.getSequenceFeatures();
               int start = sequenceStart;
               int end = sequence.getEnd();
-              int startShift = 1 - absStart - start; // how much the features
-                                                     // are
-              // to be shifted by
-              for (int sfi = 0; sfi < sf.length; sfi++)
+              int startShift = 1 - absStart - start;
+
+              if (startShift != 0)
               {
-                if (sf[sfi].getBegin() >= start && sf[sfi].getEnd() <= end)
+                for (SequenceFeature sf : sfs)
                 {
-                  // shift feature along by absstart
-                  sf[sfi].setBegin(sf[sfi].getBegin() + startShift);
-                  sf[sfi].setEnd(sf[sfi].getEnd() + startShift);
+                  if (sf.getBegin() >= start && sf.getEnd() <= end)
+                  {
+                    sf.setBegin(sf.getBegin() + startShift);
+                    sf.setEnd(sf.getEnd() + startShift);
+                    modified = true;
+                  }
                 }
               }
             }
@@ -701,16 +724,37 @@ public class DBRefFetcher implements Runnable
         }
 
         System.out.println("Adding dbrefs to " + sequence.getName()
-                + " from " + dbSource + " sequence : " + entry.getName());
-        sequence.transferAnnotation(entry, mp);
+                + " from " + dbSource + " sequence : "
+                + retrievedSeq.getName());
+        sequence.transferAnnotation(retrievedSeq, mp);
 
-        absStart += entry.getStart();
+        absStart += retrievedSeq.getStart();
         int absEnd = absStart + nonGapped.length() - 1;
         if (!trimDatasetSeqs)
         {
-          // insert full length sequence from record
-          sequence.setSequence(entry.getSequenceAsString());
-          sequence.setStart(entry.getStart());
+          /*
+           * update start position and/or expand to longer retrieved sequence
+           */
+          if (!retrievedSeqString.equals(sequence.getSequenceAsString())
+                  && remoteEnclosesLocal)
+          {
+            sequence.setSequence(retrievedSeqString);
+            modified = true;
+            addWarningMessage(warningMessages,
+                    "Sequence for " + sequence.getName()
+                            + " expanded from " + retrievedSeq.getName());
+          }
+          if (sequence.getStart() != retrievedSeq.getStart())
+          {
+            sequence.setStart(retrievedSeq.getStart());
+            modified = true;
+            if (absStart != sequenceStart)
+            {
+              addWarningMessage(warningMessages, "Start/end position for "
+                      + sequence.getName() + " updated from "
+                      + retrievedSeq.getName());
+            }
+          }
         }
         if (updateRefFrame)
         {
@@ -718,8 +762,16 @@ public class DBRefFetcher implements Runnable
           if (trimDatasetSeqs)
           {
             // just fix start/end
-            sequence.setStart(absStart);
-            sequence.setEnd(absEnd);
+            if (sequence.getStart() != absStart
+                    || sequence.getEnd() != absEnd)
+            {
+              sequence.setStart(absStart);
+              sequence.setEnd(absEnd);
+              modified = true;
+              addWarningMessage(warningMessages, "Start/end for "
+                      + sequence.getName() + " updated from "
+                      + retrievedSeq.getName());
+            }
           }
           // search for alignment sequences to update coordinate frame for
           for (int alsq = 0; alsq < alseqs.length; alsq++)
@@ -736,6 +788,7 @@ public class DBRefFetcher implements Runnable
               {
                 alseqs[alsq].setEnd(ngAlsq.length()
                         + alseqs[alsq].getStart() - 1);
+                modified = true;
               }
             }
           }
@@ -752,10 +805,20 @@ public class DBRefFetcher implements Runnable
         // ids, so we can query all enabled DAS servers for them ?
       }
     }
-    if (!transferred)
+    return modified;
+  }
+
+  /**
+   * Adds the message to the list unless it already contains it
+   * 
+   * @param messageList
+   * @param msg
+   */
+  void addWarningMessage(List<String> messageList, String msg)
+  {
+    if (!messageList.contains(msg))
     {
-      // report the ID/sequence mismatches
-      sbuffer.append(messages);
+      messageList.add(msg);
     }
   }
 
@@ -767,12 +830,12 @@ public class DBRefFetcher implements Runnable
    */
   private SequenceI[] recoverDbSequences(SequenceI[] sequencesArray)
   {
-    Vector nseq = new Vector();
+    Vector<SequenceI> nseq = new Vector<SequenceI>();
     for (int i = 0; sequencesArray != null && i < sequencesArray.length; i++)
     {
       nseq.addElement(sequencesArray[i]);
-      DBRefEntry dbr[] = sequencesArray[i].getDBRefs();
-      jalview.datamodel.Mapping map = null;
+      DBRefEntry[] dbr = sequencesArray[i].getDBRefs();
+      Mapping map = null;
       for (int r = 0; (dbr != null) && r < dbr.length; r++)
       {
         if ((map = dbr[r].getMap()) != null)
index 5f9b2d9..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();
@@ -253,8 +252,7 @@ public class DasSequenceFeatureFetcher
     public void run()
     {
       running = true;
-      boolean isNucleotide = af.getViewport().getAlignment()
-              .isNucleotide();
+      boolean isNucleotide = af.getViewport().getAlignment().isNucleotide();
       new DBRefFetcher(sequences, af, null, af.featureSettings,
               isNucleotide).fetchDBRefs(true);
 
@@ -287,8 +285,7 @@ public class DasSequenceFeatureFetcher
       {
         jalviewSourceI[] sources = sourceRegistry.getSources().toArray(
                 new jalviewSourceI[0]);
-        String active = Cache.getDefault("DAS_ACTIVE_SOURCE",
-                "uniprot");
+        String active = Cache.getDefault("DAS_ACTIVE_SOURCE", "uniprot");
         StringTokenizer st = new StringTokenizer(active, "\t");
         selectedSources = new Vector();
         String token;
@@ -644,8 +641,8 @@ public class DasSequenceFeatureFetcher
     {
       return null;
     }
-    DBRefEntry[] uprefs = DBRefUtils.selectRefs(
-            seq.getDBRefs(), new String[] {
+    DBRefEntry[] uprefs = DBRefUtils.selectRefs(seq.getDBRefs(),
+            new String[] {
             // jalview.datamodel.DBRefSource.PDB,
             DBRefSource.UNIPROT,
             // jalview.datamodel.DBRefSource.EMBL - not tested on any EMBL coord
@@ -666,8 +663,8 @@ public class DasSequenceFeatureFetcher
 
         for (COORDINATES csys : dasSource.getVersion().getCOORDINATES())
         {
-          if (DBRefUtils.isDasCoordinateSystem(
-                  csys.getAuthority(), uprefs[j]))
+          if (DBRefUtils.isDasCoordinateSystem(csys.getAuthority(),
+                  uprefs[j]))
           {
             debug("Launched fetcher for coordinate system "
                     + csys.getAuthority());
index 2b8f364..9cc4960 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ws;
 
 import jalview.ws.seqfetcher.ASequenceFetcher;
index 2049766..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();
@@ -102,8 +102,13 @@ public abstract class EmblXmlSource extends EbiFileRetrievedProxy
       }
     }
 
+    /*
+     * invalid accession gets a reply with no <entry> elements, text content of
+     * EmbFile reads something like (e.g.) this ungrammatical phrase
+     * Entry: <acc> display type is either not supported or entry is not found.
+     */
     List<SequenceI> peptides = new ArrayList<SequenceI>();
-    if (efile != null)
+    if (efile != null && efile.getEntries() != null)
     {
       for (EmblEntry entry : efile.getEntries())
       {
index 04c23a2..982c399 100644 (file)
@@ -29,15 +29,18 @@ 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;
-import java.util.Vector;
 
 import com.stevesoft.pat.Regex;
 
@@ -47,15 +50,17 @@ import com.stevesoft.pat.Regex;
  */
 public class Pdb extends EbiFileRetrievedProxy
 {
+  private static final String SEPARATOR = "|";
+
+  private static final String COLON = ":";
+
+  private static final int PDB_ID_LENGTH = 4;
+
   public Pdb()
   {
     super();
   }
 
-  public static final String FEATURE_INSERTION = "INSERTION";
-
-  public static final String FEATURE_RES_NUM = "RESNUM";
-
   /*
    * (non-Javadoc)
    * 
@@ -64,7 +69,6 @@ public class Pdb extends EbiFileRetrievedProxy
   @Override
   public String getAccessionSeparator()
   {
-    // TODO Auto-generated method stub
     return null;
   }
 
@@ -110,36 +114,47 @@ public class Pdb extends EbiFileRetrievedProxy
   public AlignmentI getSequenceRecords(String queries) throws Exception
   {
     AlignmentI pdbAlignment = null;
-    Vector result = new Vector();
     String chain = null;
     String id = null;
-    if (queries.indexOf(":") > -1)
+    if (queries.indexOf(COLON) > -1)
     {
-      chain = queries.substring(queries.indexOf(":") + 1);
-      id = queries.substring(0, queries.indexOf(":"));
+      chain = queries.substring(queries.indexOf(COLON) + 1);
+      id = queries.substring(0, queries.indexOf(COLON));
     }
     else
     {
       id = queries;
     }
-    if (queries.length() > 4 && chain == null)
+
+    /*
+     * extract chain code if it is appended to the id and we
+     * don't already have one
+     */
+    if (queries.length() > PDB_ID_LENGTH && chain == null)
     {
-      chain = queries.substring(4, 5);
-      id = queries.substring(0, 4);
+      chain = queries.substring(PDB_ID_LENGTH, PDB_ID_LENGTH + 1);
+      id = queries.substring(0, PDB_ID_LENGTH);
     }
+
     if (!isValidReference(id))
     {
       System.err.println("Ignoring invalid pdb query: '" + id + "'");
       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)
     {
@@ -147,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>();
@@ -165,8 +181,6 @@ public class Pdb extends EbiFileRetrievedProxy
               chid = pid.getChainCode();
 
             }
-            ;
-
           }
           if (chain == null
                   || (chid != null && (chid.equals(chain)
@@ -175,8 +189,8 @@ public class Pdb extends EbiFileRetrievedProxy
           {
             // FIXME seems to result in 'PDB|1QIP|1qip|A' - 1QIP is redundant.
             // TODO: suggest simplify naming to 1qip|A as default name defined
-            pdbcs.setName(jalview.datamodel.DBRefSource.PDB + "|" + id
-                    + "|" + pdbcs.getName());
+            pdbcs.setName(jalview.datamodel.DBRefSource.PDB + SEPARATOR
+                    + id + SEPARATOR + pdbcs.getName());
             // Might need to add more metadata to the PDBEntry object
             // like below
             /*
@@ -267,7 +281,6 @@ public class Pdb extends EbiFileRetrievedProxy
     return 0;
   }
 
-
   /**
    * Returns a descriptor for suitable feature display settings with
    * <ul>
index 4f081ee..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,14 +121,13 @@ 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,
-              // getDbSource(),
-                      getDbVersion(), queries.trim().toUpperCase()));
+      rcds.getSequenceAt(s).addDBRef(new DBRefEntry(DBRefSource.PFAM,
+      // getDbSource(),
+              getDbVersion(), queries.trim().toUpperCase()));
       if (!getDbSource().equals(DBRefSource.PFAM))
       { // add the specific ref too
         rcds.getSequenceAt(s).addDBRef(
index 62b9686..3c5373d 100644 (file)
@@ -20,7 +20,6 @@
  */
 package jalview.ws.dbsources;
 
-
 /**
  * flyweight class specifying retrieval of Full family alignments from PFAM
  * 
index 053953c..ba9d1e0 100644 (file)
@@ -20,7 +20,6 @@
  */
 package jalview.ws.dbsources;
 
-
 /**
  * flyweight class specifying retrieval of Seed alignments from PFAM
  * 
index 3053363..e6fc8ff 100644 (file)
@@ -20,7 +20,6 @@
  */
 package jalview.ws.dbsources;
 
-
 /**
  * Flyweight class specifying retrieval of Full family alignments from RFAM
  * 
index 77fb841..580ebe2 100644 (file)
@@ -20,7 +20,6 @@
  */
 package jalview.ws.dbsources;
 
-
 /**
  * Flyweight class specifying retrieval of Seed family alignments from RFAM
  * 
@@ -52,6 +51,7 @@ public class RfamSeed extends Rfam
   {
     return "/alignment";
   }
+
   /*
    * (non-Javadoc)
    * 
index 81b4caf..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)
@@ -193,7 +193,8 @@ public class Uniprot extends DbSourceProxyImpl
    *          UniprotEntry
    * @return SequenceI instance created from the UniprotEntry instance
    */
-  public SequenceI uniprotEntryToSequenceI(UniprotEntry entry){
+  public SequenceI uniprotEntryToSequenceI(UniprotEntry entry)
+  {
     String id = getUniprotEntryId(entry);
     SequenceI sequence = new Sequence(id, entry.getUniprotSequence()
             .getContent());
@@ -222,6 +223,38 @@ public class Uniprot extends DbSourceProxyImpl
       {
         onlyPdbEntries.addElement(pdb);
       }
+      if ("EMBL".equals(pdb.getType()))
+      {
+        // look for a CDS reference and add it, too.
+        String cdsId = (String) pdb.getProperty("protein sequence ID");
+        if (cdsId != null && cdsId.trim().length() > 0)
+        {
+          // remove version
+          String[] vrs = cdsId.split("\\.");
+          dbr = new DBRefEntry(DBRefSource.EMBLCDS, vrs.length > 1 ? vrs[1]
+                  : DBRefSource.UNIPROT + ":" + dbVersion, vrs[0]);
+          dbRefs.add(dbr);
+        }
+      }
+      if ("Ensembl".equals(pdb.getType()))
+      {
+        /*UniprotXML
+         * <dbReference type="Ensembl" id="ENST00000321556">
+        * <molecule id="Q9BXM7-1"/>
+        * <property type="protein sequence ID" value="ENSP00000364204"/>
+        * <property type="gene ID" value="ENSG00000158828"/>
+        * </dbReference> 
+         */
+        String cdsId = (String) pdb.getProperty("protein sequence ID");
+        if (cdsId != null && cdsId.trim().length() > 0)
+        {
+          dbr = new DBRefEntry(DBRefSource.ENSEMBL, DBRefSource.UNIPROT
+                  + ":" + dbVersion, cdsId.trim());
+          dbRefs.add(dbr);
+
+        }
+      }
+
     }
 
     sequence.setPDBId(onlyPdbEntries);
@@ -233,7 +266,10 @@ public class Uniprot extends DbSourceProxyImpl
         sequence.addSequenceFeature(sf);
       }
     }
-    sequence.setDBRefs(dbRefs.toArray(new DBRefEntry[0]));
+    for (DBRefEntry dbr : dbRefs)
+    {
+      sequence.addDBRef(dbr);
+    }
     return sequence;
   }
 
index 508047d..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,8 +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 3f6afbc..b184ff2 100644 (file)
@@ -259,8 +259,8 @@ public class DasSourceRegistry implements DasSourceRegistryI,
   }
 
   /*
- * 
- */
+  * 
+  */
 
   @Override
   public jalviewSourceI createLocalSource(String url, String name,
index 1dff32f..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)
@@ -139,7 +139,8 @@ public class EBIFetchClient
     }
 
     // note: outFile is currently always specified, so return value is null
-    String[] rslt = fetchBatch(querystring.toString(), database, format, outFile);
+    String[] rslt = fetchBatch(querystring.toString(), database, format,
+            outFile);
 
     return (rslt != null && rslt.length > 0 ? rslt : null);
   }
@@ -241,8 +242,7 @@ public class EBIFetchClient
         return null;
       }
       System.err.println("Unexpected exception when retrieving from "
-              + database
-              + "\nQuery was : '" + ids + "'");
+              + database + "\nQuery was : '" + ids + "'");
       ex.printStackTrace(System.err);
       return null;
     } finally
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 4643119..7258f51 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
@@ -383,11 +382,13 @@ public class Discoverer implements Runnable
   /**
    * creates a new thread to call discoverServices()
    */
+  @Override
   public void run()
   {
     final Discoverer discoverer = this;
     Thread discoverThread = new Thread()
     {
+      @Override
       public void run()
       {
         discoverer.doDiscovery();
index f13672b..2c05386 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",
@@ -345,6 +345,7 @@ public class JPredClient extends WS1Client
     return server;
   }
 
+  @Override
   public void attachWSMenuEntry(JMenu wsmenu, final ServiceHandle sh,
           final AlignFrame af)
   {
@@ -352,6 +353,7 @@ public class JPredClient extends WS1Client
     method.setToolTipText(sh.getEndpointURL());
     method.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         AlignmentView msa = af.gatherSeqOrMsaForSecStrPrediction();
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 3fd7c5a..e4247f7 100644 (file)
@@ -670,8 +670,8 @@ class MsaWSThread extends JWS1Thread implements WSClientI
 
             while (j < l)
             {
-              if (((AlignmentOrder) alorders.get(i))
-                      .equals((alorders.get(j))))
+              if (((AlignmentOrder) alorders.get(i)).equals((alorders
+                      .get(j))))
               {
                 alorders.remove(j);
                 l--;
index 2d83bf9..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;
     }
@@ -172,8 +172,7 @@ public class SeqSearchWSClient extends WS1Client
 
     try
     {
-      this.server = loc.getSeqSearchService(new java.net.URL(
-              WsURL));
+      this.server = loc.getSeqSearchService(new java.net.URL(WsURL));
       ((SeqSearchServiceSoapBindingStub) this.server).setTimeout(60000); // One
       // minute
       // timeout
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 758d941..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);
     }
   }
@@ -338,13 +338,14 @@ public class MsaWSClient extends Jws2Client
               }
 
             });
-            String tooltip = JvSwingUtils.wrapTooltip(
-                    true,
+            String tooltip = JvSwingUtils
+                    .wrapTooltip(
+                            true,
                             "<strong>"
-                            + (preset.isModifiable() ? MessageManager
-                                    .getString("label.user_preset")
-                                    : MessageManager
-                                            .getString("label.service_preset"))
+                                    + (preset.isModifiable() ? MessageManager
+                                            .getString("label.user_preset")
+                                            : MessageManager
+                                                    .getString("label.service_preset"))
                                     + "</strong><br/>"
                                     + preset.getDescription());
             methodR.setToolTipText(tooltip);
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 33a917e..31168b4 100644 (file)
@@ -112,8 +112,7 @@ public class ASequenceFetcher
         return true;
       }
     }
-    Cache.log.warn("isFetchable doesn't know about '" + source
-            + "'");
+    Cache.log.warn("isFetchable doesn't know about '" + source + "'");
     return false;
   }
 
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 aa65f49..4675fb7 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ws.sifts;
 
 public class MappingOutputPojo
@@ -114,5 +134,4 @@ public class MappingOutputPojo
     this.type = type;
   }
 
-
 }
index f20954e..27db604 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;
@@ -149,7 +150,6 @@ public class SiftsClient implements SiftsClientI
     siftsEntry = parseSIFTs(siftsFile);
   }
 
-
   /**
    * Parse the given SIFTs File and return a JAXB POJO of parsed data
    * 
@@ -276,21 +276,21 @@ public class SiftsClient implements SiftsClientI
     {
       siftsDownloadDir.mkdirs();
     }
-      // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
-      URL url = new URL(siftsFileFTPURL);
-      URLConnection conn = url.openConnection();
-      InputStream inputStream = conn.getInputStream();
-      FileOutputStream outputStream = new FileOutputStream(
-              downloadedSiftsFile);
-      byte[] buffer = new byte[BUFFER_SIZE];
-      int bytesRead = -1;
-      while ((bytesRead = inputStream.read(buffer)) != -1)
-      {
-        outputStream.write(buffer, 0, bytesRead);
-      }
-      outputStream.close();
-      inputStream.close();
-      // System.out.println(">>> File downloaded : " + downloadedSiftsFile);
+    // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
+    URL url = new URL(siftsFileFTPURL);
+    URLConnection conn = url.openConnection();
+    InputStream inputStream = conn.getInputStream();
+    FileOutputStream outputStream = new FileOutputStream(
+            downloadedSiftsFile);
+    byte[] buffer = new byte[BUFFER_SIZE];
+    int bytesRead = -1;
+    while ((bytesRead = inputStream.read(buffer)) != -1)
+    {
+      outputStream.write(buffer, 0, bytesRead);
+    }
+    outputStream.close();
+    inputStream.close();
+    // System.out.println(">>> File downloaded : " + downloadedSiftsFile);
     return new File(downloadedSiftsFile);
   }
 
@@ -391,8 +391,8 @@ public class SiftsClient implements SiftsClientI
           String pdbFile, String chain) throws SiftsException
   {
     structId = (chain == null) ? pdbId : pdbId + "|" + chain;
-    System.out.println("Getting mapping for: " + pdbId + "|" + chain
-            + " : seq- " + seq.getName());
+    System.out.println("Getting SIFTS mapping for " + structId + ": seq "
+            + seq.getName());
 
     final StringBuilder mappingDetails = new StringBuilder(128);
     PrintStream ps = new PrintStream(System.out)
@@ -471,12 +471,13 @@ public class SiftsClient implements SiftsClientI
     int pdbStart = UNASSIGNED;
     int pdbEnd = UNASSIGNED;
 
-    Integer[] keys = mapping.keySet().toArray(new Integer[0]);
-    Arrays.sort(keys);
-    if (keys.length < 1)
+    if (mapping.isEmpty())
     {
-      throw new SiftsException(">>> Empty SIFTS mapping generated!!");
+      throw new SiftsException("SIFTS mapping failed");
     }
+
+    Integer[] keys = mapping.keySet().toArray(new Integer[0]);
+    Arrays.sort(keys);
     seqStart = keys[0];
     seqEnd = keys[keys.length - 1];
 
@@ -510,13 +511,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());
 
@@ -611,6 +612,7 @@ public class SiftsClient implements SiftsClientI
       }
     }
   }
+
   /**
    * 
    * @param chainId
@@ -762,8 +764,6 @@ public class SiftsClient implements SiftsClientI
     }
   }
 
-
-
   @Override
   public Entity getEntityById(String id) throws SiftsException
   {
@@ -827,6 +827,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))
@@ -1001,8 +1005,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 2923541..191aa2d 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ws.sifts;
 
 public class SiftsException extends Exception
index e1e3de8..5e2c526 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ws.sifts;
 
 import java.util.Objects;
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 8e2e2fe..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 ddd38e7..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;
   }
@@ -439,7 +453,8 @@ public class AlignmentUtilsTests
     SequenceI alignFrom = new Sequence("Seq2", alignModel);
     alignFrom.createDatasetSequence();
     AlignedCodonFrame acf = new AlignedCodonFrame();
-    acf.addMap(alignMe.getDatasetSequence(), alignFrom.getDatasetSequence(), map);
+    acf.addMap(alignMe.getDatasetSequence(),
+            alignFrom.getDatasetSequence(), map);
 
     AlignmentUtils.alignSequenceAs(alignMe, alignFrom, acf, "---", '-',
             preserveMappedGaps, preserveUnmappedGaps);
@@ -977,7 +992,7 @@ public class AlignmentUtilsTests
     /*
      * scenario:
      *     dna1 --> [4, 6] [10,12]        --> pep1 
-     *     dna2 --> [1, 3] [7, 9] [13,15] --> pep1 
+     *     dna2 --> [1, 3] [7, 9] [13,15] --> pep2
      */
     SequenceI dna1 = new Sequence("dna1", "aaaGGGcccTTTaaa");
     SequenceI dna2 = new Sequence("dna2", "GGGcccTTTaaaCCC");
@@ -993,6 +1008,13 @@ public class AlignmentUtilsTests
     dna.setDataset(null);
 
     /*
+     * put a variant feature on dna2 base 8
+     * - should transfer to cds2 base 5
+     */
+    dna2.addSequenceFeature(new SequenceFeature("variant", "hgmd", 8, 8,
+            0f, null));
+
+    /*
      * need a sourceDbRef if we are to construct dbrefs to the CDS
      * sequence from the dna contig sequences
      */
@@ -1007,15 +1029,14 @@ public class AlignmentUtilsTests
      * CDS sequences are 'discovered' from dna-to-protein mappings on the alignment
      * dataset (e.g. added from dbrefs by CrossRef.findXrefSequences)
      */
-    MapList mapfordna1 = new MapList(new int[] { 4, 6, 10, 12 },
-            new int[] { 1, 2 }, 3, 1);
+    MapList mapfordna1 = new MapList(new int[] { 4, 6, 10, 12 }, new int[] {
+        1, 2 }, 3, 1);
     AlignedCodonFrame acf = new AlignedCodonFrame();
     acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(),
             mapfordna1);
     dna.addCodonFrame(acf);
     MapList mapfordna2 = new MapList(new int[] { 1, 3, 7, 9, 13, 15 },
-            new int[] { 1, 3 },
-            3, 1);
+            new int[] { 1, 3 }, 3, 1);
     acf = new AlignedCodonFrame();
     acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(),
             mapfordna2);
@@ -1112,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());
@@ -1154,6 +1175,16 @@ public class AlignmentUtilsTests
     assertSame(cds2Dss, m.getSequence());
     assertEquals(7, m.getStart());
     assertEquals(9, m.getEnd());
+
+    /*
+     * check cds2 acquired a variant feature in position 5
+     */
+    SequenceFeature[] sfs = cds2Dss.getSequenceFeatures();
+    assertNotNull(sfs);
+    assertEquals(1, sfs.length);
+    assertEquals("variant", sfs[0].type);
+    assertEquals(5, sfs[0].begin);
+    assertEquals(5, sfs[0].end);
   }
 
   /**
@@ -1293,8 +1324,7 @@ public class AlignmentUtilsTests
             .findMappingsForSequence(cds.get(0), dnaMappings);
     Mapping mapping = dnaToCds1Mappings.get(0).getMappings().get(0)
             .getMapping();
-    assertSame(cds.get(0).getDatasetSequence(), mapping
-            .getTo());
+    assertSame(cds.get(0).getDatasetSequence(), mapping.getTo());
     assertEquals("G(1) in CDS should map to G(4) in DNA", 4, mapping
             .getMap().getToPosition(1));
 
@@ -1362,8 +1392,7 @@ public class AlignmentUtilsTests
    * @throws IOException
    */
   @Test(groups = { "Functional" })
-  public void testMapCdnaToProtein_forSubsequence()
-          throws IOException
+  public void testMapCdnaToProtein_forSubsequence() throws IOException
   {
     SequenceI prot = new Sequence("UNIPROT|V12345", "E-I--Q", 10, 12);
     prot.createDatasetSequence();
@@ -1384,7 +1413,7 @@ public class AlignmentUtilsTests
   @Test(groups = { "Functional" })
   public void testAlignSequenceAs_mappedProteinProtein()
   {
-  
+
     SequenceI alignMe = new Sequence("Match", "MGAASEV");
     alignMe.createDatasetSequence();
     SequenceI alignFrom = new Sequence("Query", "LQTGYMGAASEVMFSPTRR");
@@ -1395,7 +1424,7 @@ public class AlignmentUtilsTests
     MapList map = new MapList(new int[] { 6, 12 }, new int[] { 1, 7 }, 1, 1);
     acf.addMap(alignFrom.getDatasetSequence(),
             alignMe.getDatasetSequence(), map);
-    
+
     AlignmentUtils.alignSequenceAs(alignMe, alignFrom, acf, "-", '-', true,
             true);
     assertEquals("-----MGAASEV-------", alignMe.getSequenceAsString());
@@ -1410,7 +1439,7 @@ public class AlignmentUtilsTests
   {
     // map first 3 codons to KPF; G is a trailing unmapped residue
     MapList map = new MapList(new int[] { 1, 9 }, new int[] { 1, 3 }, 3, 1);
-  
+
     checkAlignSequenceAs("AAACCCTTT", "K-PFG", true, true, map,
             "AAA---CCCTTT---");
   }
@@ -1509,7 +1538,7 @@ public class AlignmentUtilsTests
 
     MapList map = new MapList(new int[] { 4, 6, 10, 12 },
             new int[] { 1, 6 }, 1, 1);
-  
+
     // [5, 11] maps to [2, 5]
     dna.addSequenceFeature(new SequenceFeature("type4", "desc4", 5, 11, 4f,
             null));
@@ -1519,12 +1548,12 @@ public class AlignmentUtilsTests
     // [12, 12] maps to [6, 6]
     dna.addSequenceFeature(new SequenceFeature("type8", "desc8", 12, 12,
             8f, null));
-  
+
     // desc4 and desc8 are the 'omit these' varargs
     AlignmentUtils.transferFeatures(dna, cds, map, null, "type4", "type8");
     SequenceFeature[] sfs = cds.getSequenceFeatures();
     assertEquals(1, sfs.length);
-  
+
     SequenceFeature sf = sfs[0];
     assertEquals("type5", sf.getType());
     assertEquals(1, sf.getBegin());
@@ -1539,10 +1568,10 @@ public class AlignmentUtilsTests
   {
     SequenceI dna = new Sequence("dna/20-34", "acgTAGcaaGCCcgt");
     SequenceI cds = new Sequence("cds/10-15", "TAGGCC");
-  
+
     MapList map = new MapList(new int[] { 4, 6, 10, 12 },
             new int[] { 1, 6 }, 1, 1);
-  
+
     // [5, 11] maps to [2, 5]
     dna.addSequenceFeature(new SequenceFeature("type4", "desc4", 5, 11, 4f,
             null));
@@ -1552,12 +1581,12 @@ public class AlignmentUtilsTests
     // [12, 12] maps to [6, 6]
     dna.addSequenceFeature(new SequenceFeature("type8", "desc8", 12, 12,
             8f, null));
-  
+
     // "type5" is the 'select this type' argument
     AlignmentUtils.transferFeatures(dna, cds, map, "type5");
     SequenceFeature[] sfs = cds.getSequenceFeatures();
     assertEquals(1, sfs.length);
-  
+
     SequenceFeature sf = sfs[0];
     assertEquals("type5", sf.getType());
     assertEquals(1, sf.getBegin());
@@ -1586,26 +1615,25 @@ public class AlignmentUtilsTests
 
     AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2, dna3 });
     dna.setDataset(null);
-  
+
     MapList map = new MapList(new int[] { 4, 12, 16, 18 },
             new int[] { 1, 4 }, 3, 1);
     AlignedCodonFrame acf = new AlignedCodonFrame();
     acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(), map);
     dna.addCodonFrame(acf);
     map = new MapList(new int[] { 4, 8, 12, 12, 16, 18 },
-            new int[] { 1, 3 },
-            3, 1);
+            new int[] { 1, 3 }, 3, 1);
     acf = new AlignedCodonFrame();
     acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(), map);
     dna.addCodonFrame(acf);
-  
+
     AlignmentI cds = AlignmentUtils.makeCdsAlignment(new SequenceI[] {
         dna1, dna2, dna3 }, dna.getDataset(), null);
     List<SequenceI> cdsSeqs = cds.getSequences();
     assertEquals(2, cdsSeqs.size());
     assertEquals("GGGCCCTTTGGG", cdsSeqs.get(0).getSequenceAsString());
     assertEquals("GGGCCTGGG", cdsSeqs.get(1).getSequenceAsString());
-  
+
     /*
      * verify shared, extended alignment dataset
      */
@@ -1621,7 +1649,7 @@ public class AlignmentUtilsTests
      */
     List<AlignedCodonFrame> mappings = cds.getCodonFrames();
     assertEquals(6, mappings.size());
-  
+
     /*
      * 2 mappings involve pep1
      */
@@ -1636,12 +1664,11 @@ 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);
-    assertEquals(cds.getSequenceAt(0).getDatasetSequence(),
-            m.getSequence());
+    SearchResultMatchI m = sr.getResults().get(0);
+    assertEquals(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence());
     assertEquals(1, m.getStart());
     assertEquals(3, m.getEnd());
     sr = MappingUtils.buildSearchResults(pep1, 2, pep1CdsMappings);
@@ -1656,7 +1683,7 @@ public class AlignmentUtilsTests
     m = sr.getResults().get(0);
     assertEquals(10, m.getStart());
     assertEquals(12, m.getEnd());
-  
+
     /*
      * Get mapping of pep2 to cds2 and verify it
      * maps GPG in pep2 to 1-3,4-6,7-9 in second CDS sequence
@@ -1670,8 +1697,7 @@ public class AlignmentUtilsTests
     sr = MappingUtils.buildSearchResults(pep2, 1, pep2CdsMappings);
     assertEquals(1, sr.getResults().size());
     m = sr.getResults().get(0);
-    assertEquals(cds.getSequenceAt(1).getDatasetSequence(),
-            m.getSequence());
+    assertEquals(cds.getSequenceAt(1).getDatasetSequence(), m.getSequence());
     assertEquals(1, m.getStart());
     assertEquals(3, m.getEnd());
     sr = MappingUtils.buildSearchResults(pep2, 2, pep2CdsMappings);
@@ -1698,7 +1724,7 @@ public class AlignmentUtilsTests
     SequenceI dna3 = new Sequence("Seq3", "ccaaa-ttt-GGG-");
     AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2, dna3 });
     dna.setDataset(null);
-  
+
     // prot1 has 'X' for incomplete start codon (not mapped)
     SequenceI prot1 = new Sequence("Seq1", "XKFG"); // X for incomplete start
     SequenceI prot2 = new Sequence("Seq2", "NG");
@@ -1706,7 +1732,7 @@ public class AlignmentUtilsTests
     AlignmentI protein = new Alignment(new SequenceI[] { prot1, prot2,
         prot3 });
     protein.setDataset(null);
-  
+
     // map dna1 [3, 11] to prot1 [2, 4] KFG
     MapList map = new MapList(new int[] { 3, 11 }, new int[] { 2, 4 }, 3, 1);
     AlignedCodonFrame acf = new AlignedCodonFrame();
@@ -1745,7 +1771,7 @@ public class AlignmentUtilsTests
     SequenceI dnaSeq = new Sequence("dna", "aaagGGCCCaaaTTTttt");
     dnaSeq.createDatasetSequence();
     SequenceI ds = dnaSeq.getDatasetSequence();
-  
+
     // CDS for dna 5-6 (incomplete codon), 7-9
     SequenceFeature sf = new SequenceFeature("CDS", "", 5, 9, 0f, null);
     sf.setPhase("2"); // skip 2 bases to start of next codon
@@ -1753,9 +1779,9 @@ public class AlignmentUtilsTests
     // CDS for dna 13-15
     sf = new SequenceFeature("CDS_predicted", "", 13, 15, 0f, null);
     ds.addSequenceFeature(sf);
-  
+
     List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
-  
+
     /*
      * check the mapping starts with the first complete codon
      */
@@ -1777,7 +1803,7 @@ public class AlignmentUtilsTests
     SequenceI dnaSeq = new Sequence("dna", "aaaGGGcccAAATTTttt");
     dnaSeq.createDatasetSequence();
     SequenceI ds = dnaSeq.getDatasetSequence();
-  
+
     // CDS for dna 10-12
     SequenceFeature sf = new SequenceFeature("CDS_predicted", "", 10, 12,
             0f, null);
@@ -1790,7 +1816,7 @@ public class AlignmentUtilsTests
     // exon feature should be ignored here
     sf = new SequenceFeature("exon", "", 7, 9, 0f, null);
     ds.addSequenceFeature(sf);
-  
+
     List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
     /*
      * verify ranges { [4-6], [12-10] }
@@ -2135,7 +2161,7 @@ public class AlignmentUtilsTests
     SequenceI dnaSeq = new Sequence("dna", "aaaGGGcccAAATTTttt");
     dnaSeq.createDatasetSequence();
     SequenceI ds = dnaSeq.getDatasetSequence();
-  
+
     // CDS for dna 4-6
     SequenceFeature sf = new SequenceFeature("CDS", "", 4, 6, 0f, null);
     sf.setStrand("-");
@@ -2147,7 +2173,7 @@ public class AlignmentUtilsTests
     sf = new SequenceFeature("CDS_predicted", "", 10, 12, 0f, null);
     sf.setStrand("-");
     ds.addSequenceFeature(sf);
-  
+
     List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
     /*
      * verify ranges { [12-10], [6-4] }
@@ -2173,7 +2199,7 @@ public class AlignmentUtilsTests
     SequenceI dnaSeq = new Sequence("dna", "aaagGGCCCaaaTTTttt");
     dnaSeq.createDatasetSequence();
     SequenceI ds = dnaSeq.getDatasetSequence();
-  
+
     // CDS for dna 5-9
     SequenceFeature sf = new SequenceFeature("CDS", "", 5, 9, 0f, null);
     sf.setStrand("-");
@@ -2183,9 +2209,9 @@ public class AlignmentUtilsTests
     sf.setStrand("-");
     sf.setPhase("2"); // skip 2 bases to start of next codon
     ds.addSequenceFeature(sf);
-  
+
     List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
-  
+
     /*
      * check the mapping starts with the first complete codon
      * expect ranges [13, 13], [9, 5]
@@ -2238,8 +2264,7 @@ public class AlignmentUtilsTests
     from.createDatasetSequence();
     seq1.createDatasetSequence();
     Mapping mapping = new Mapping(seq1, new MapList(
-            new int[] { 3, 6, 9, 10 },
-            new int[] { 1, 6 }, 1, 1));
+            new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1));
     Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
     AlignmentUtils.addMappedPositions(seq1, from, mapping, map);
 
@@ -2271,11 +2296,10 @@ public class AlignmentUtilsTests
     from.createDatasetSequence();
     seq1.createDatasetSequence();
     Mapping mapping = new Mapping(seq1, new MapList(
-            new int[] { 3, 6, 9, 10 },
-            new int[] { 1, 6 }, 1, 1));
+            new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1));
     Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
     AlignmentUtils.addMappedPositions(seq1, from, mapping, map);
-  
+
     /*
      * verify map has seq1 residues in columns 3,4,6,7,11,12
      */
@@ -2313,7 +2337,7 @@ public class AlignmentUtilsTests
     dna.setDataset(null);
     AlignmentI emblPeptides = new Alignment(new SequenceI[] { pep3, pep4 });
     emblPeptides.setDataset(null);
-  
+
     AlignedCodonFrame acf = new AlignedCodonFrame();
     MapList map = new MapList(new int[] { 4, 6, 10, 12 },
             new int[] { 1, 2 }, 3, 1);
@@ -2327,17 +2351,17 @@ public class AlignmentUtilsTests
     acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(), map);
     acf.addMap(dna2.getDatasetSequence(), pep4.getDatasetSequence(), map);
     dna.addCodonFrame(acf);
-  
+
     /*
      * execute method under test to find CDS for EMBL peptides only
      */
     AlignmentI cds = AlignmentUtils.makeCdsAlignment(new SequenceI[] {
         dna1, dna2 }, dna.getDataset(), emblPeptides.getSequencesArray());
-  
+
     assertEquals(2, cds.getSequences().size());
     assertEquals("GGGTTT", cds.getSequenceAt(0).getSequenceAsString());
     assertEquals("GGGTTTCCC", cds.getSequenceAt(1).getSequenceAsString());
-  
+
     /*
      * verify shared, extended alignment dataset
      */
@@ -2346,7 +2370,7 @@ public class AlignmentUtilsTests
             .contains(cds.getSequenceAt(0).getDatasetSequence()));
     assertTrue(dna.getDataset().getSequences()
             .contains(cds.getSequenceAt(1).getDatasetSequence()));
-  
+
     /*
      * Verify mappings from CDS to peptide, cDNA to CDS, and cDNA to peptide
      * the mappings are on the shared alignment dataset
@@ -2356,7 +2380,7 @@ public class AlignmentUtilsTests
      * 6 mappings, 2*(DNA->CDS), 2*(DNA->Pep), 2*(CDS->Pep) 
      */
     assertEquals(6, cdsMappings.size());
-  
+
     /*
      * verify that mapping sets for dna and cds alignments are different
      * [not current behaviour - all mappings are on the alignment dataset]  
@@ -2365,7 +2389,7 @@ public class AlignmentUtilsTests
     // Assert.assertNotSame(dna.getCodonFrames(), cds.getCodonFrames());
     // assertEquals(4, dna.getCodonFrames().size());
     // assertEquals(4, cds.getCodonFrames().size());
-  
+
     /*
      * Two mappings involve pep3 (dna to pep3, cds to pep3)
      * Mapping from pep3 to GGGTTT in first new exon sequence
@@ -2376,11 +2400,11 @@ public class AlignmentUtilsTests
     List<AlignedCodonFrame> mappings = MappingUtils
             .findMappingsForSequence(cds.getSequenceAt(0), pep3Mappings);
     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());
@@ -2390,7 +2414,7 @@ public class AlignmentUtilsTests
     assertSame(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence());
     assertEquals(4, m.getStart());
     assertEquals(6, m.getEnd());
-  
+
     /*
      * Two mappings involve pep4 (dna to pep4, cds to pep4)
      * Verify mapping from pep4 to GGGTTTCCC in second new exon sequence
@@ -2444,7 +2468,7 @@ public class AlignmentUtilsTests
     dna4.setSequence(seq2);
     AlignmentI al2 = new Alignment(new SequenceI[] { dna3, dna4 });
     ((Alignment) al2).createDatasetAlignment();
-    
+
     assertTrue(AlignmentUtils.alignAsSameSequences(al1, al2));
     assertEquals(seq1, al1.getSequenceAt(0).getSequenceAsString());
     assertEquals(seq2, al1.getSequenceAt(1).getSequenceAsString());
@@ -2501,5 +2525,5 @@ public class AlignmentUtilsTests
     assertEquals(s_as2, uas2.getSequenceAsString());
     assertEquals(s_as3, uas3.getSequenceAsString());
   }
-    
+
 }
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 24ddb34..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()
   {
@@ -121,8 +131,9 @@ public class CrossRefTest
     seq.addDBRef(new DBRefEntry("ENSEMBLGENOMES", "0", "E2350"));
     sources = new CrossRef(new SequenceI[] { seq }, al)
             .findXrefSourcesForSequences(false);
-    assertEquals(4, sources.size());
-    assertEquals("[EMBL, EMBLCDS, GENEDB, ENSEMBL]", sources.toString());
+    // method is patched to remove EMBL from the sources to match
+    assertEquals(3, sources.size());
+    assertEquals("[EMBLCDS, GENEDB, ENSEMBL]", sources.toString());
 
     /*
      * add a sequence to the alignment which has a dbref to UNIPROT|A1234
@@ -140,8 +151,9 @@ public class CrossRefTest
     al.addSequence(seq2);
     sources = new CrossRef(new SequenceI[] { seq, seq2 }, al)
             .findXrefSourcesForSequences(false);
-    assertEquals(3, sources.size());
-    assertEquals("[EMBLCDS, EMBL, GENEDB]", sources.toString());
+    // method removed EMBL from sources to match
+    assertEquals(2, sources.size());
+    assertEquals("[EMBLCDS, GENEDB]", sources.toString());
   }
 
   /**
@@ -249,8 +261,7 @@ public class CrossRefTest
      */
     SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
     Mapping map = new Mapping(new Sequence("pep2", "MLAVSRG"), new MapList(
-            new int[] { 1, 21 }, new int[] {
-        1, 7 }, 3, 1));
+            new int[] { 1, 21 }, new int[] { 1, 7 }, 3, 1));
     DBRefEntry dbref = new DBRefEntry("UNIPROT", "0", "Q9ZTS2", map);
     dna1.addDBRef(dbref);
     dna1.addDBRef(new DBRefEntry("EMBL", "0", "AF039662"));
@@ -280,7 +291,7 @@ public class CrossRefTest
     dbref = new DBRefEntry("UNIPROT", "0", "Q9ZTS2");
     found = testee.searchDataset(!dna1.isProtein(), dna1, dbref, result,
             acf, false); // search dataset with a protein xref from a dna
-                          // sequence to locate the protein product
+                         // sequence to locate the protein product
     assertTrue(found);
     assertEquals(1, result.size());
     assertSame(pep1, result.get(0));
@@ -294,7 +305,7 @@ public class CrossRefTest
     dbref = new DBRefEntry("UNIPROT", "0", "Q9ZTS2");
     found = testee.searchDataset(!pep1.isProtein(), pep1, dbref, result,
             acf, false); // search dataset with a protein's direct dbref to
-                          // locate dna sequences with matching xref
+                         // locate dna sequences with matching xref
     assertTrue(found);
     assertEquals(1, result.size());
     assertSame(dna1, result.get(0));
@@ -402,11 +413,14 @@ public class CrossRefTest
   public void testFindXrefSequences_withFetch()
   {
     SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
-    dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
-    dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P30419"));
-    dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P00314"));
+    dna1.addDBRef(new DBRefEntry("UNIPROT", "ENA:0", "Q9ZTS2"));
+    dna1.addDBRef(new DBRefEntry("UNIPROT", "ENA:0", "P30419"));
+    dna1.addDBRef(new DBRefEntry("UNIPROT", "ENA:0", "P00314"));
     final SequenceI pep1 = new Sequence("Q9ZTS2", "MYQLIRSSW");
+    pep1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
+
     final SequenceI pep2 = new Sequence("P00314", "MRKLLAASG");
+    pep2.addDBRef(new DBRefEntry("UNIPROT", "0", "P00314"));
 
     /*
      * argument false suppresses adding DAS sources
@@ -471,7 +485,7 @@ public class CrossRefTest
      * 'spliced transcript' with CDS ranges
      */
     SequenceI braf002 = new Sequence("ENST00000497784", "gCAGGCtaTCTGTTCaa");
-    braf002.addDBRef(new DBRefEntry("UNIPROT", "0", "H7C5K3"));
+    braf002.addDBRef(new DBRefEntry("UNIPROT", "ENSEMBL|0", "H7C5K3"));
     braf002.addSequenceFeature(new SequenceFeature("CDS", "", 2, 6, 0f,
             null));
     braf002.addSequenceFeature(new SequenceFeature("CDS", "", 9, 15, 0f,
@@ -483,8 +497,9 @@ public class CrossRefTest
      * which happens to be true for Uniprot,PDB,EMBL but not Pfam,Rfam,Ensembl 
      */
     final SequenceI pep1 = new Sequence("UNIPROT|P15056", "MAAL");
+    pep1.addDBRef(new DBRefEntry("UNIPROT", "0", "P15056"));
     final SequenceI pep2 = new Sequence("UNIPROT|H7C5K3", "QALF");
-
+    pep2.addDBRef(new DBRefEntry("UNIPROT", "0", "H7C5K3"));
     /*
      * argument false suppresses adding DAS sources
      * todo: define an interface type SequenceFetcherI and mock that
@@ -620,7 +635,7 @@ public class CrossRefTest
      */
     final SequenceI x07547 = new Sequence("EMBL|X07547", "cccAAACCCTTTGGG");
     DBRefEntry dbref7 = new DBRefEntry("UNIPROT", "0", "P0CE20");
-    dbref7.setMap(new Mapping(new Sequence("UNIPROT|P0CE19", "KPFG"),
+    dbref7.setMap(new Mapping(new Sequence("UNIPROT|P0CE20", "PFGK"),
             new MapList(map2)));
     x07547.addDBRef(dbref7);
     DBRefEntry dbref8 = new DBRefEntry("UNIPROT", "0", "B0BCM4");
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 0142ab5..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
@@ -525,7 +536,7 @@ public class DnaTest
     String seqDsRev = new StringBuilder(seqDs).reverse().toString();
 
     SequenceI dna = new Sequence("Seq1", seq);
-    Alignment al = new Alignment(new SequenceI[] {dna});
+    Alignment al = new Alignment(new SequenceI[] { dna });
     al.createDatasetAlignment();
     assertEquals(seqDs, al.getSequenceAt(0).getDatasetSequence()
             .getSequenceAsString());
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 df39b81..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");
@@ -44,11 +53,11 @@ public class GroupingTest
 
   Sequence s5 = new Sequence("s5", "AAAADDEDTTEE");
 
-  SequenceGroup sg_12 = new SequenceGroup(Arrays.asList(new SequenceI[] { s1,
-      s2 }), "Group1", null, false, false, false, 0, 5);
+  SequenceGroup sg_12 = new SequenceGroup(Arrays.asList(new SequenceI[] {
+      s1, s2 }), "Group1", null, false, false, false, 0, 5);
 
-  SequenceGroup sg_345 = new SequenceGroup(Arrays.asList(new SequenceI[] { s3,
-      s4, s5 }), "Group2", null, false, false, false, 0, 5);
+  SequenceGroup sg_345 = new SequenceGroup(Arrays.asList(new SequenceI[] {
+      s3, s4, s5 }), "Group2", null, false, false, false, 0, 5);
 
   AlignmentI alignment = new Alignment(
           new SequenceI[] { s1, s2, s3, s4, s5 });
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 f96d2c9..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
   {
@@ -105,7 +115,7 @@ public class RnaTest
     {
       String s = String.valueOf((char) i);
       String ss = Rna.getRNASecStrucState(s);
-  
+
       /*
        * valid SS chars are a-z, A-Z, and various brackets;
        * anything else is returned as a space
@@ -120,7 +130,7 @@ public class RnaTest
         assertEquals(" ", ss);
       }
     }
-  
+
     /*
      * a string is processed character by character
      */
@@ -278,7 +288,7 @@ public class RnaTest
   public void testIsRnaSecondaryStructureSymbol()
   {
     assertFalse(Rna.isRnaSecondaryStructureSymbol(null));
-  
+
     /*
      * only A-Z,  a-z, ()[]{}<> are valid symbols
      */
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 a17270d..bbed9d3 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.AssertJUnit.assertFalse;
@@ -5,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 029483f..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);
@@ -82,8 +94,8 @@ public class FeatureScoreModelTest
   {
     AlignFrame alf = getTestAlignmentFrame();
     FeatureScoreModel fsm = new FeatureScoreModel();
-    Assert.assertTrue(fsm.configureFromAlignmentView(alf
-            .getCurrentView().getAlignPanel()));
+    Assert.assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
+            .getAlignPanel()));
     alf.selectAllSequenceMenuItem_actionPerformed(null);
     float[][] dm = fsm.findDistances(alf.getViewport().getAlignmentView(
             true));
@@ -124,15 +136,58 @@ public class FeatureScoreModelTest
     alf.selectAllSequenceMenuItem_actionPerformed(null);
     float[][] dm = fsm.findDistances(alf.getViewport().getAlignmentView(
             true));
-    Assert.assertTrue(dm[0][2] == 0f,
+    Assert.assertTrue(
+            dm[0][2] == 0f,
             "After hiding last two columns FER1_MESCR (0) should still be identical with RAPSA (2)");
-    Assert.assertTrue(dm[0][1] == 0f,
+    Assert.assertTrue(
+            dm[0][1] == 0f,
             "After hiding last two columns FER1_MESCR (0) should now also be identical with SPIOL (1)");
-    for (int s=0;s<3;s++)
+    for (int s = 0; s < 3; s++)
     {
       Assert.assertTrue(dm[s][3] > 0f, "After hiding last two columns "
               + alf.getViewport().getAlignment().getSequenceAt(s).getName()
               + "(" + 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 06e79de..0485db7 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.bin;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -5,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 a37370f..e762dd5 100644 (file)
@@ -1,7 +1,29 @@
+/*
+ * 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.bin;
 
 import static org.testng.AssertJUnit.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
@@ -12,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 9afae37..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;
@@ -239,7 +248,7 @@ public class EditCommandTest
   public void testReplace()
   {
     // seem to need a dataset sequence on the edited sequence here
-    seqs[1].setDatasetSequence(seqs[1]);
+    seqs[1].createDatasetSequence();
     new EditCommand("", Action.REPLACE, "ZXY", new SequenceI[] { seqs[1] },
             4, 8, al);
     assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
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 3eefada..2e89b0e 100644 (file)
@@ -1,26 +1,64 @@
+/*
+ * 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.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
@@ -33,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);
@@ -50,37 +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);
+    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);
@@ -88,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);
@@ -97,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 f2dd968..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.
    */
@@ -462,7 +471,7 @@ public class AlignedCodonFrameTest
     seq1.createDatasetSequence();
     final Sequence aseq1 = new Sequence("Seq1", "-V-L");
     aseq1.createDatasetSequence();
-  
+
     AlignedCodonFrame acf = new AlignedCodonFrame();
     MapList map = new MapList(new int[] { 2, 4, 6, 6, 8, 9 }, new int[] {
         1, 2 }, 3, 1);
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 7ad9436..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;
   }
@@ -134,19 +146,23 @@ public class AlignmentTest
    *          - the alignmentI object to verify (either alignment or dataset)
    * @param raiseAssert
    *          - when set, testng assertions are raised.
-   *          @param message
-   *          - null or a string message to prepend to the assert failed messages.
+   * @param message
+   *          - null or a string message to prepend to the assert failed
+   *          messages.
    * @return true if alignment references were in order, otherwise false.
    */
   public static boolean verifyAlignmentDatasetRefs(AlignmentI alignment,
           boolean raiseAssert, String message)
   {
-    if (message==null) { message = ""; }
+    if (message == null)
+    {
+      message = "";
+    }
     if (alignment == null)
     {
       if (raiseAssert)
       {
-        Assert.fail(message+"Alignment for verification was null.");
+        Assert.fail(message + "Alignment for verification was null.");
       }
       return false;
     }
@@ -161,7 +177,8 @@ public class AlignmentTest
         {
           if (raiseAssert)
           {
-            Assert.fail(message+" Alignment contained a sequence who's dataset sequence has a second dataset reference.");
+            Assert.fail(message
+                    + " Alignment contained a sequence who's dataset sequence has a second dataset reference.");
           }
           return false;
         }
@@ -169,12 +186,14 @@ public class AlignmentTest
         {
           if (raiseAssert)
           {
-            Assert.fail(message+" Alignment contained a sequence who's dataset sequence was not in the dataset.");
+            Assert.fail(message
+                    + " Alignment contained a sequence who's dataset sequence was not in the dataset.");
           }
           return false;
         }
       }
-      return verifyAlignmentDatasetRefs(alignment.getDataset(), raiseAssert, message);
+      return verifyAlignmentDatasetRefs(alignment.getDataset(),
+              raiseAssert, message);
     }
     else
     {
@@ -187,7 +206,8 @@ public class AlignmentTest
         {
           if (raiseAssert)
           {
-            Assert.fail(message+" Dataset contained a sequence with non-null dataset reference (ie not a dataset sequence!)");
+            Assert.fail(message
+                    + " Dataset contained a sequence with non-null dataset reference (ie not a dataset sequence!)");
           }
           return false;
         }
@@ -216,7 +236,8 @@ public class AlignmentTest
                 {
                   if (raiseAssert)
                   {
-                    Assert.fail(message+" DBRefEntry for sequence in alignment had map to sequence which was not a dataset sequence");
+                    Assert.fail(message
+                            + " DBRefEntry for sequence in alignment had map to sequence which was not a dataset sequence");
                   }
                   return false;
 
@@ -225,7 +246,8 @@ public class AlignmentTest
                 {
                   if (raiseAssert)
                   {
-                    Assert.fail(message+" DBRefEntry for sequence in alignment had map to sequence not in dataset");
+                    Assert.fail(message
+                            + " DBRefEntry for sequence in alignment had map to sequence not in dataset");
                   }
                   return false;
                 }
@@ -245,7 +267,8 @@ public class AlignmentTest
             {
               if (raiseAssert)
               {
-                Assert.fail(message+" CodonFrame-SSM-FromSeq is not a dataset sequence");
+                Assert.fail(message
+                        + " CodonFrame-SSM-FromSeq is not a dataset sequence");
               }
               return false;
             }
@@ -254,7 +277,8 @@ public class AlignmentTest
 
               if (raiseAssert)
               {
-                Assert.fail(message+" CodonFrame-SSM-FromSeq is not contained in dataset");
+                Assert.fail(message
+                        + " CodonFrame-SSM-FromSeq is not contained in dataset");
               }
               return false;
             }
@@ -262,7 +286,8 @@ public class AlignmentTest
             {
               if (raiseAssert)
               {
-                Assert.fail(message+" CodonFrame-SSM-Mapping-ToSeq is not a dataset sequence");
+                Assert.fail(message
+                        + " CodonFrame-SSM-Mapping-ToSeq is not a dataset sequence");
               }
               return false;
             }
@@ -271,7 +296,8 @@ public class AlignmentTest
 
               if (raiseAssert)
               {
-                Assert.fail(message+" CodonFrame-SSM-Mapping-ToSeq is not contained in dataset");
+                Assert.fail(message
+                        + " CodonFrame-SSM-Mapping-ToSeq is not contained in dataset");
               }
               return false;
             }
@@ -335,6 +361,7 @@ public class AlignmentTest
                       + msg);
     }
   }
+
   @Test(groups = { "Functional" })
   public void testVerifyAlignmentDatasetRefs()
   {
@@ -342,16 +369,13 @@ public class AlignmentTest
             "TTTTTT");
 
     // construct simple valid alignment dataset
-    Alignment al = new Alignment(new SequenceI[] {
-        sq1, sq2 });
+    Alignment al = new Alignment(new SequenceI[] { sq1, sq2 });
     // expect this to pass
     assertVerifyAlignment(al, true, "Simple valid alignment didn't verify");
 
     // check test for sequence->datasetSequence validity
     sq1.setDatasetSequence(sq2);
-    assertVerifyAlignment(
-            al,
-            false,
+    assertVerifyAlignment(al, false,
             "didn't detect dataset sequence with a dataset sequence reference.");
 
     sq1.setDatasetSequence(null);
@@ -445,7 +469,7 @@ public class AlignmentTest
    */
   public static void assertDatasetIsNormalised(AlignmentI al, String message)
   {
-    if (al.getDataset()!=null)
+    if (al.getDataset() != null)
     {
       assertDatasetIsNormalised(al.getDataset(), message);
       return;
@@ -454,17 +478,17 @@ public class AlignmentTest
      * look for pairs of sequences with same ID, start, end, and sequence
      */
     List<SequenceI> seqSet = al.getSequences();
-    for (int p=0;p<seqSet.size(); p++)
+    for (int p = 0; p < seqSet.size(); p++)
     {
       SequenceI pSeq = seqSet.get(p);
-      for (int q=p+1; q<seqSet.size(); q++)
+      for (int q = p + 1; q < seqSet.size(); q++)
       {
         SequenceI qSeq = seqSet.get(q);
-        if (pSeq.getStart()!=qSeq.getStart())
+        if (pSeq.getStart() != qSeq.getStart())
         {
           continue;
         }
-        if (pSeq.getEnd()!=qSeq.getEnd())
+        if (pSeq.getEnd() != qSeq.getEnd())
         {
           continue;
         }
@@ -482,7 +506,7 @@ public class AlignmentTest
       }
     }
   }
-  
+
   @Test(groups = { "Functional", "Asserts" })
   public void testAssertDatasetIsNormalised()
   {
@@ -557,6 +581,7 @@ public class AlignmentTest
       Assert.fail("Expected identical sequence to raise exception.");
     }
   }
+
   /*
    * Read in Stockholm format test data including secondary structure
    * annotations.
@@ -564,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())
     {
@@ -630,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
@@ -656,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
@@ -680,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);
 
     /*
@@ -737,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);
 
     /*
@@ -795,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
@@ -837,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();
@@ -874,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
@@ -1013,6 +1038,7 @@ public class AlignmentTest
     assertAlignmentDatasetRefs(align,
             "addSequence broke dataset reference integrity");
   }
+
   @Test(groups = "Functional")
   public void getVisibleStartAndEndIndexTest()
   {
@@ -1042,4 +1068,67 @@ public class AlignmentTest
     assertEquals(23, startEnd[1]);
   }
 
+  /**
+   * Tests that dbrefs with mappings to sequence get updated if the sequence
+   * acquires a dataset sequence
+   */
+  @Test(groups = "Functional")
+  public void testCreateDataset_updateDbrefMappings()
+  {
+    SequenceI pep = new Sequence("pep", "ASD");
+    SequenceI dna = new Sequence("dna", "aaaGCCTCGGATggg");
+    SequenceI cds = new Sequence("cds", "GCCTCGGAT");
+
+    // add dbref from dna to peptide
+    DBRefEntry dbr = new DBRefEntry("UNIPROT", "", "pep");
+    dbr.setMap(new Mapping(pep, new MapList(new int[] { 4, 15 }, new int[] {
+        1, 4 }, 3, 1)));
+    dna.addDBRef(dbr);
+
+    // add dbref from dna to peptide
+    DBRefEntry dbr2 = new DBRefEntry("UNIPROT", "", "pep");
+    dbr2.setMap(new Mapping(pep, new MapList(new int[] { 1, 12 }, new int[]
+    { 1, 4 }, 3, 1)));
+    cds.addDBRef(dbr2);
+
+    // add dbref from peptide to dna
+    DBRefEntry dbr3 = new DBRefEntry("EMBL", "", "dna");
+    dbr3.setMap(new Mapping(dna, new MapList(new int[] { 1, 4 }, new int[] {
+        4, 15 }, 1, 3)));
+    pep.addDBRef(dbr3);
+
+    // add dbref from peptide to cds
+    DBRefEntry dbr4 = new DBRefEntry("EMBLCDS", "", "cds");
+    dbr4.setMap(new Mapping(cds, new MapList(new int[] { 1, 4 }, new int[] {
+        1, 12 }, 1, 3)));
+    pep.addDBRef(dbr4);
+
+    AlignmentI protein = new Alignment(new SequenceI[] { pep });
+
+    /*
+     * create the alignment dataset
+     */
+    ((Alignment) protein).createDatasetAlignment();
+
+    AlignmentI ds = protein.getDataset();
+
+    // should be 3 sequences in dataset
+    assertEquals(3, ds.getHeight());
+    assertTrue(ds.getSequences().contains(pep.getDatasetSequence()));
+    assertTrue(ds.getSequences().contains(dna));
+    assertTrue(ds.getSequences().contains(cds));
+
+    /*
+     * verify peptide.cdsdbref.peptidedbref is now mapped to peptide dataset
+     */
+    DBRefEntry[] dbRefs = pep.getDBRefs();
+    assertEquals(2, dbRefs.length);
+    assertSame(dna, dbRefs[0].map.to);
+    assertSame(cds, dbRefs[1].map.to);
+    assertEquals(1, dna.getDBRefs().length);
+    assertSame(pep.getDatasetSequence(), dna.getDBRefs()[0].map.to);
+    assertEquals(1, cds.getDBRefs().length);
+    assertSame(pep.getDatasetSequence(), cds.getDBRefs()[0].map.to);
+  }
+
 }
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 a943e7c..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()
   {
@@ -162,11 +172,12 @@ public class ColumnSelectionTest
 
   }
 
-  @Test(groups={"Functional"})
+  @Test(groups = { "Functional" })
   public void testLocateVisibleBoundsPathologicals()
   {
     // test some pathological cases we missed
-    AlignmentI al = new Alignment(new SequenceI[] { new Sequence("refseqGaptest","KTDVTI----------NFI-----G----L")});
+    AlignmentI al = new Alignment(new SequenceI[] { new Sequence(
+            "refseqGaptest", "KTDVTI----------NFI-----G----L") });
     ColumnSelection cs = new ColumnSelection();
     cs.hideInsertionsFor(al.getSequenceAt(0));
     assertEquals(
@@ -175,8 +186,8 @@ public class ColumnSelectionTest
                     + al.getSequenceAt(0).getCharAt(
                             cs.adjustForHiddenColumns(9)));
 
-
   }
+
   @Test(groups = { "Functional" })
   public void testHideColumns()
   {
@@ -499,7 +510,7 @@ public class ColumnSelectionTest
     cs.addElement(1);
     cs.hideColumns(3);
     cs.hideColumns(7);
-    cs.hideColumns(5,9);
+    cs.hideColumns(5, 9);
 
     // same selections added in a different order
     ColumnSelection cs2 = new ColumnSelection();
@@ -515,7 +526,7 @@ public class ColumnSelectionTest
     cs2.hideColumns(6, 9);
     cs2.hideColumns(5, 8);
     cs2.hideColumns(3);
-    
+
     assertTrue(cs.equals(cs2));
     assertTrue(cs.equals(cs));
     assertTrue(cs2.equals(cs));
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 7b1ab57..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)
    */
@@ -81,7 +90,7 @@ public class DBRefEntryTest
     assertTrue(ref1.updateFrom(ref2));
     assertEquals("UNIPROT", ref1.getSource()); // unchanged
     assertEquals("V71633", ref1.getAccessionId()); // unchanged
-  
+
     /*
      * ref1 has no mapping, acquires mapping from ref2
      */
index 8b50a8b..cae3536 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.AssertJUnit.assertEquals;
@@ -10,19 +30,29 @@ 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;
-  
+
   /**
    * Set up an alignment of 10 sequences
    */
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 64dc793..f6a1116 100644 (file)
@@ -1,15 +1,43 @@
+/*
+ * 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.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 979fee4..cf4294e 100644 (file)
@@ -31,17 +31,24 @@ import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
 import jalview.datamodel.PDBEntry.Type;
-
-import java.util.Hashtable;
+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
   {
@@ -101,17 +108,17 @@ public class PDBEntryTest
     assertNotEquals(case9, case10);
 
     // add properties
-    case7.getProperty().put("hello", "world");
+    case7.setProperty("hello", "world");
     assertNotEquals(case7, case9);
-    case9.getProperty().put("hello", "world");
+    case9.setProperty("hello", "world");
     assertEquals(case7, case9);
-    case9.getProperty().put("hello", "WORLD");
+    case9.setProperty("hello", "WORLD");
     assertNotEquals(case7, case9);
 
     /*
      * change string wrapper property to string...
      */
-    case1.getProperty().put("chain_code", "a");
+    case1.setProperty("chain_code", "a");
     assertFalse(pdbEntry.equals(case1));
     assertFalse(case1.equals(pdbEntry));
   }
@@ -245,28 +252,23 @@ public class PDBEntryTest
      */
     pdb1 = new PDBEntry("3A6S", null, null, null);
     pdb2 = new PDBEntry("3A6S", null, null, null);
-    // ughh properties not null if chain code has been set...
-    // JAL-2196 addresses this
-    pdb1.properties = new Hashtable();
-    pdb2.properties = new Hashtable();
-    pdb1.properties.put("destination", "mars");
-    pdb1.properties.put("hello", "world");
-    pdb2.properties.put("hello", "moon");
-    pdb2.properties.put("goodbye", "world");
+    pdb1.setProperty("destination", "mars");
+    pdb1.setProperty("hello", "world");
+    pdb2.setProperty("hello", "moon");
+    pdb2.setProperty("goodbye", "world");
     assertTrue(pdb1.updateFrom(pdb2));
-    assertEquals(pdb1.properties.get("destination"), "mars");
-    assertEquals(pdb1.properties.get("hello"), "moon");
-    assertEquals(pdb1.properties.get("goodbye"), "world");
+    assertEquals(pdb1.getProperty("destination"), "mars");
+    assertEquals(pdb1.getProperty("hello"), "moon");
+    assertEquals(pdb1.getProperty("goodbye"), "world");
 
     /*
      * add properties only
      */
     pdb1 = new PDBEntry("3A6S", null, null, null);
     pdb2 = new PDBEntry("3A6S", null, null, null);
-    pdb2.properties = new Hashtable();
-    pdb2.properties.put("hello", "moon");
+    pdb2.setProperty("hello", "moon");
     assertTrue(pdb1.updateFrom(pdb2));
-    assertEquals(pdb1.properties.get("hello"), "moon");
+    assertEquals(pdb1.getProperty("hello"), "moon");
   }
 
   @Test(groups = { "Functional" })
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 ffcaa26..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
@@ -169,7 +165,7 @@ public class SearchResultsTest
     sr2.addResult(seq1, 6, 8);
     assertEquals(sr1.hashCode(), sr2.hashCode());
   }
-  
+
   /**
    * Verify that SearchResults$Match constructor normalises start/end to the
    * 'forwards' direction
@@ -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 8d3c878..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()
   {
@@ -55,6 +65,7 @@ public class SeqCigarTest
       }
     }
   }
+
   /*
    * refactored 'as is' from main method
    * 
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 82b260e..2da8918 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.AssertJUnit.assertEquals;
@@ -6,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()
   {
@@ -92,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());
@@ -150,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 8c5073b..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)
@@ -70,11 +80,11 @@ public class SequenceTest
   public void testIsProtein()
   {
     // test Protein
-    assertTrue(new Sequence("prot","ASDFASDFASDF").isProtein());
+    assertTrue(new Sequence("prot", "ASDFASDFASDF").isProtein());
     // test DNA
-    assertFalse(new Sequence("prot","ACGTACGTACGT").isProtein());
+    assertFalse(new Sequence("prot", "ACGTACGTACGT").isProtein());
     // test RNA
-    SequenceI sq = new Sequence("prot","ACGUACGUACGU");
+    SequenceI sq = new Sequence("prot", "ACGUACGUACGU");
     assertFalse(sq.isProtein());
     // change sequence, should trigger an update of cached result
     sq.setSequence("ASDFASDFADSF");
@@ -336,7 +346,6 @@ public class SequenceTest
     assertEquals(1, sfs.length);
     assertSame(sf, sfs[0]);
 
-
     /*
      * SequenceFeature on sequence and dataset sequence; returns that on
      * sequence
@@ -366,7 +375,16 @@ public class SequenceTest
      * is there a usecase for this ? setDatasetSequence should throw an error if
      * this actually occurs.
      */
-    sq.getDatasetSequence().setDatasetSequence(sq); // loop!
+    try
+    {
+      sq.getDatasetSequence().setDatasetSequence(sq); // loop!
+      Assert.fail("Expected Error to be raised when calling setDatasetSequence with self reference");
+    } catch (IllegalArgumentException e)
+    {
+      // TODO Jalview error/exception class for raising implementation errors
+      assertTrue(e.getMessage().toLowerCase()
+              .contains("implementation error"));
+    }
     assertNull(sq.getSequenceFeatures());
   }
 
@@ -416,7 +434,7 @@ public class SequenceTest
   @Test(groups = { "Functional" })
   public void testCreateDatasetSequence()
   {
-    SequenceI sq = new Sequence("my","ASDASD");
+    SequenceI sq = new Sequence("my", "ASDASD");
     assertNull(sq.getDatasetSequence());
     SequenceI rds = sq.createDatasetSequence();
     assertNotNull(rds);
@@ -450,29 +468,29 @@ public class SequenceTest
     sq.addPDBId(new PDBEntry("1PDB", "B", Type.PDB, "filePath/test1"));
     sq.addPDBId(new PDBEntry("2PDB", "A", Type.MMCIF, "filePath/test2"));
     sq.addPDBId(new PDBEntry("2PDB", "B", Type.MMCIF, "filePath/test2"));
-    
+
+    // these are the same as ones already added
     DBRefEntry pdb1pdb = new DBRefEntry("PDB", "version1", "1PDB");
-    DBRefEntry pdb2pdb = new DBRefEntry("PDB", "version1", "2PDB");
+    DBRefEntry pdb2pdb = new DBRefEntry("PDB", "version2", "2PDB");
 
-    
     List<DBRefEntry> primRefs = Arrays.asList(new DBRefEntry[] { pdb1pdb,
         pdb2pdb });
 
-    sq.getDatasetSequence().addDBRef(pdb1pdb);
-    sq.getDatasetSequence().addDBRef(pdb2pdb);
+    sq.getDatasetSequence().addDBRef(pdb1pdb); // should do nothing
+    sq.getDatasetSequence().addDBRef(pdb2pdb); // should do nothing
     sq.getDatasetSequence().addDBRef(
-            new DBRefEntry("PDB", "version3", "3PDB"));
+            new DBRefEntry("PDB", "version3", "3PDB")); // should do nothing
     sq.getDatasetSequence().addDBRef(
-            new DBRefEntry("PDB", "version4", "4PDB"));
-    
-    PDBEntry pdbe1a=new PDBEntry("1PDB", "A", Type.PDB, "filePath/test1");
+            new DBRefEntry("PDB", "version4", "4PDB")); // should do nothing
+
+    PDBEntry pdbe1a = new PDBEntry("1PDB", "A", Type.PDB, "filePath/test1");
     PDBEntry pdbe1b = new PDBEntry("1PDB", "B", Type.PDB, "filePath/test1");
-    PDBEntry pdbe2a=new PDBEntry("2PDB", "A", Type.MMCIF, "filePath/test2");
-    PDBEntry pdbe2b = new PDBEntry("2PDB", "B", Type.MMCIF, "filePath/test2");
-    sq.getDatasetSequence().addPDBId(
-            pdbe1a);
-    sq.getDatasetSequence().addPDBId(
-            pdbe1b);
+    PDBEntry pdbe2a = new PDBEntry("2PDB", "A", Type.MMCIF,
+            "filePath/test2");
+    PDBEntry pdbe2b = new PDBEntry("2PDB", "B", Type.MMCIF,
+            "filePath/test2");
+    sq.getDatasetSequence().addPDBId(pdbe1a);
+    sq.getDatasetSequence().addPDBId(pdbe1b);
     sq.getDatasetSequence().addPDBId(pdbe2a);
     sq.getDatasetSequence().addPDBId(pdbe2b);
 
@@ -500,11 +518,14 @@ public class SequenceTest
             new AlignmentAnnotation("Test annot", "Test annot description",
                     annots));
     Assert.assertEquals(sq.getDescription(), "Test sequence description..");
-    Assert.assertEquals(sq.getDBRefs().length, 5);
+    Assert.assertEquals(sq.getDBRefs().length, 5); // DBRefs are on dataset
+                                                   // sequence
     Assert.assertEquals(sq.getAllPDBEntries().size(), 4);
     Assert.assertNotNull(sq.getAnnotation());
     Assert.assertEquals(sq.getAnnotation()[0].annotations.length, 2);
-    Assert.assertEquals(sq.getDatasetSequence().getDBRefs().length, 4);
+    Assert.assertEquals(sq.getDatasetSequence().getDBRefs().length, 5); // same
+                                                                        // as
+                                                                        // sq.getDBRefs()
     Assert.assertEquals(sq.getDatasetSequence().getAllPDBEntries().size(),
             4);
     Assert.assertNotNull(sq.getDatasetSequence().getAnnotation());
@@ -513,11 +534,11 @@ public class SequenceTest
 
     Assert.assertEquals(derived.getDescription(),
             "Test sequence description..");
-    Assert.assertEquals(derived.getDBRefs().length, 4); // come from dataset
+    Assert.assertEquals(derived.getDBRefs().length, 5); // come from dataset
     Assert.assertEquals(derived.getAllPDBEntries().size(), 4);
     Assert.assertNotNull(derived.getAnnotation());
     Assert.assertEquals(derived.getAnnotation()[0].annotations.length, 2);
-    Assert.assertEquals(derived.getDatasetSequence().getDBRefs().length, 4);
+    Assert.assertEquals(derived.getDatasetSequence().getDBRefs().length, 5);
     Assert.assertEquals(derived.getDatasetSequence().getAllPDBEntries()
             .size(), 4);
     Assert.assertNotNull(derived.getDatasetSequence().getAnnotation());
@@ -531,7 +552,7 @@ public class SequenceTest
     assertNotNull(sq.getSequenceFeatures());
     assertArrayEquals(sq.getSequenceFeatures(),
             derived.getSequenceFeatures());
-    
+
     /*
      *  verify we have primary db refs *just* for PDB IDs with associated
      *  PDBEntry objects
@@ -586,7 +607,7 @@ public class SequenceTest
             12.4f, "group"));
     seq1.addPDBId(new PDBEntry("1A70", "B", Type.PDB, "File"));
     seq1.addDBRef(new DBRefEntry("EMBL", "1.2", "AZ12345"));
-    
+
     SequenceI copy = new Sequence(seq1);
 
     assertNull(copy.getDatasetSequence());
@@ -662,9 +683,13 @@ public class SequenceTest
     // copy has a copy of the sequence feature:
     SequenceFeature[] sfs = copy.getSequenceFeatures();
     assertEquals(1, sfs.length);
-    if (seq1.getDatasetSequence()!=null && copy.getDatasetSequence()==seq1.getDatasetSequence()) {
+    if (seq1.getDatasetSequence() != null
+            && copy.getDatasetSequence() == seq1.getDatasetSequence())
+    {
       assertTrue(sfs[0] == seq1.getSequenceFeatures()[0]);
-    } else {
+    }
+    else
+    {
       assertFalse(sfs[0] == seq1.getSequenceFeatures()[0]);
     }
     assertTrue(sfs[0].equals(seq1.getSequenceFeatures()[0]));
@@ -854,11 +879,11 @@ public class SequenceTest
   public void testGetPrimaryDBRefs_nucleotide()
   {
     SequenceI sq = new Sequence("aseq", "TGATCACTCGACTAGCATCAGCATA", 10, 34);
-  
+
     // primary - Ensembl
     DBRefEntry dbr1 = new DBRefEntry("ENSEMBL", "0", "ENSG1234");
     sq.addDBRef(dbr1);
-  
+
     // not primary - Ensembl 'transcript' mapping of sub-sequence
     DBRefEntry dbr2 = new DBRefEntry("ENSEMBL", "0", "ENST1234");
     dbr2.setMap(new Mapping(null, new MapList(new int[] { 15, 25 },
@@ -878,7 +903,7 @@ public class SequenceTest
     // not primary - to protein
     DBRefEntry dbr5 = new DBRefEntry("UNIPROT", "0", "Q87654");
     sq.addDBRef(dbr5);
-  
+
     List<DBRefEntry> primaryDBRefs = sq.getPrimaryDBRefs();
     assertEquals(2, primaryDBRefs.size());
     assertTrue(primaryDBRefs.contains(dbr1));
@@ -900,7 +925,7 @@ public class SequenceTest
     seq.addDBRef(new DBRefEntry("PDB", "0", "3a6sB"));
     // 7 is not a valid chain code:
     seq.addDBRef(new DBRefEntry("PDB", "0", "2GIS7"));
-    
+
     seq.updatePDBIds();
     List<PDBEntry> pdbIds = seq.getAllPDBEntries();
     assertEquals(4, pdbIds.size());
@@ -967,4 +992,22 @@ public class SequenceTest
     assertEquals(4, seq.getAllPDBEntries().size());
     assertSame(pdbe5, seq.getAllPDBEntries().get(3));
   }
+
+  @Test(
+    groups = { "Functional" },
+    expectedExceptions = { IllegalArgumentException.class })
+  public void testSetDatasetSequence_toSelf()
+  {
+    seq.setDatasetSequence(seq);
+  }
+
+  @Test(
+    groups = { "Functional" },
+    expectedExceptions = { IllegalArgumentException.class })
+  public void testSetDatasetSequence_cascading()
+  {
+    SequenceI seq2 = new Sequence("Seq2", "xyz");
+    seq2.createDatasetSequence();
+    seq.setDatasetSequence(seq2);
+  }
 }
index abe5099..4672574 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.xdb.embl;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -8,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()
   {
@@ -216,8 +246,7 @@ public class EmblEntryTest
 
     // truncate last exon by 6bp
     int[] truncated = EmblEntry.adjustForProteinLength(4, exons);
-    assertEquals("[11, 15, 21, 25, 31, 32]",
-            Arrays.toString(truncated));
+    assertEquals("[11, 15, 21, 25, 31, 32]", Arrays.toString(truncated));
 
     // remove last exon and truncate preceding by 1bp
     truncated = EmblEntry.adjustForProteinLength(3, exons);
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()
   {
index 6349164..0c7624f 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.xdb.embl;
 
 import java.io.StringReader;
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 fb7e143..fb0204b 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -8,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;
@@ -21,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()
   {
@@ -32,6 +61,7 @@ public class EnsemblCdnaTest
   {
     SequenceOntologyFactory.setInstance(null);
   }
+
   /**
    * Test that the cdna part of genomic sequence is correctly identified by
    * 'exon' features (or subtypes) - reverse strand case.
@@ -99,30 +129,30 @@ public class EnsemblCdnaTest
     genomic.setStart(10000);
     genomic.setEnd(50000);
     String transcriptId = "ABC123";
-  
+
     // exon at (start+10000) length 501
     SequenceFeature sf = new SequenceFeature("exon", "", 20000, 20500, 0f,
             null);
     sf.setValue("Parent", "transcript:" + transcriptId);
     sf.setStrand("+");
     genomic.addSequenceFeature(sf);
-  
+
     // exon (sub-type) at (start + exon_variant) length 101
     sf = new SequenceFeature("coding_exon", "", 10500, 10600, 0f, null);
     sf.setValue("Parent", "transcript:" + transcriptId);
     sf.setStrand("+");
     genomic.addSequenceFeature(sf);
-  
+
     // exon belonging to a different transcript doesn't count
     sf = new SequenceFeature("exon", "", 11500, 12600, 0f, null);
     sf.setValue("Parent", "transcript:anotherOne");
     genomic.addSequenceFeature(sf);
-  
+
     // transcript feature doesn't count
     sf = new SequenceFeature("transcript", "", 10000, 50000, 0f, null);
     sf.setStrand("-"); // weird but ignored
     genomic.addSequenceFeature(sf);
-  
+
     MapList ranges = testee.getGenomicRangesFromFeatures(genomic,
             transcriptId, 23);
     List<int[]> fromRanges = ranges.getFromRanges();
@@ -151,18 +181,18 @@ public class EnsemblCdnaTest
     genomic.setStart(10000);
     genomic.setEnd(50000);
     String transcriptId = "ABC123";
-  
+
     SequenceFeature sf = new SequenceFeature("exon", "", 20000, 20500, 0f,
             null);
     sf.setValue("Parent", "transcript:" + transcriptId);
     sf.setStrand("-");
     genomic.addSequenceFeature(sf);
-  
+
     sf = new SequenceFeature("coding_exon", "", 10500, 10600, 0f, null);
     sf.setValue("Parent", "transcript:" + transcriptId);
     sf.setStrand("+");
     genomic.addSequenceFeature(sf);
-  
+
     MapList ranges = testee.getGenomicRangesFromFeatures(genomic,
             transcriptId, 23);
     assertNull(ranges);
index 5344575..b7f9f8d 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -7,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;
@@ -20,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()
   {
@@ -44,25 +73,25 @@ public class EnsemblCdsTest
     genomic.setStart(10000);
     genomic.setEnd(50000);
     String transcriptId = "ABC123";
-  
+
     // CDS at (start+10000) length 501
     SequenceFeature sf = new SequenceFeature("CDS", "", 20000, 20500, 0f,
             null);
     sf.setValue("Parent", "transcript:" + transcriptId);
     sf.setStrand("+");
     genomic.addSequenceFeature(sf);
-  
+
     // CDS (sub-type) at (start + 10500) length 101
     sf = new SequenceFeature("CDS_predicted", "", 10500, 10600, 0f, null);
     sf.setValue("Parent", "transcript:" + transcriptId);
     sf.setStrand("+");
     genomic.addSequenceFeature(sf);
-  
+
     // CDS belonging to a different transcript doesn't count
     sf = new SequenceFeature("CDS", "", 11500, 12600, 0f, null);
     sf.setValue("Parent", "transcript:anotherOne");
     genomic.addSequenceFeature(sf);
-  
+
     // exon feature doesn't count
     sf = new SequenceFeature("exon", "", 10000, 50000, 0f, null);
     genomic.addSequenceFeature(sf);
@@ -70,7 +99,7 @@ public class EnsemblCdsTest
     // mRNA_region feature doesn't count (parent of CDS)
     sf = new SequenceFeature("mRNA_region", "", 10000, 50000, 0f, null);
     genomic.addSequenceFeature(sf);
-  
+
     MapList ranges = testee.getGenomicRangesFromFeatures(genomic,
             transcriptId, 23);
     List<int[]> fromRanges = ranges.getFromRanges();
@@ -96,22 +125,22 @@ public class EnsemblCdsTest
   {
     String accId = "ABC123";
     EnsemblCds testee = new EnsemblCds();
-  
-    SequenceFeature sf = new SequenceFeature("CDS", "", 20000,
-            20500, 0f, null);
+
+    SequenceFeature sf = new SequenceFeature("CDS", "", 20000, 20500, 0f,
+            null);
     assertFalse(testee.retainFeature(sf, accId));
-  
+
     sf.setType("CDS_predicted");
     assertFalse(testee.retainFeature(sf, accId));
-  
+
     // other feature with no parent is retained
     sf.setType("sequence_variant");
     assertTrue(testee.retainFeature(sf, accId));
-  
+
     // other feature with desired parent is retained
     sf.setValue("Parent", "transcript:" + accId);
     assertTrue(testee.retainFeature(sf, accId));
-  
+
     // feature with wrong parent is not retained
     sf.setValue("Parent", "transcript:XYZ");
     assertFalse(testee.retainFeature(sf, accId));
@@ -126,27 +155,27 @@ public class EnsemblCdsTest
   {
     String accId = "ABC123";
     EnsemblCds testee = new EnsemblCds();
-  
+
     // cds with no parent not valid
     SequenceFeature sf = new SequenceFeature("CDS", "", 1, 2, 0f, null);
     assertFalse(testee.identifiesSequence(sf, accId));
-  
+
     // cds with wrong parent not valid
     sf.setValue("Parent", "transcript:XYZ");
     assertFalse(testee.identifiesSequence(sf, accId));
-  
+
     // cds with right parent is valid
     sf.setValue("Parent", "transcript:" + accId);
     assertTrue(testee.identifiesSequence(sf, accId));
-  
+
     // cds sub-type with right parent is valid
     sf.setType("CDS_predicted");
     assertTrue(testee.identifiesSequence(sf, accId));
-  
+
     // transcript not valid:
     sf.setType("transcript");
     assertFalse(testee.identifiesSequence(sf, accId));
-  
+
     // exon not valid:
     sf.setType("exon");
     assertFalse(testee.identifiesSequence(sf, accId));
index 4e815d1..6cfd85b 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -9,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;
@@ -22,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()
   {
@@ -135,8 +164,8 @@ public class EnsemblGeneTest
     genomic.addSequenceFeature(sf1);
 
     // transcript sub-type feature
-    SequenceFeature sf2 = new SequenceFeature("snRNA", "", 20000,
-            20500, 0f, null);
+    SequenceFeature sf2 = new SequenceFeature("snRNA", "", 20000, 20500,
+            0f, null);
     sf2.setValue("Parent", "gene:" + geneId);
     sf2.setValue("transcript_id", "transcript2");
     genomic.addSequenceFeature(sf2);
@@ -177,8 +206,8 @@ public class EnsemblGeneTest
   {
     String geneId = "ABC123";
     EnsemblGene testee = new EnsemblGene();
-    SequenceFeature sf = new SequenceFeature("gene", "", 20000,
-            20500, 0f, null);
+    SequenceFeature sf = new SequenceFeature("gene", "", 20000, 20500, 0f,
+            null);
     sf.setValue("ID", "gene:" + geneId);
     assertFalse(testee.retainFeature(sf, geneId));
 
@@ -210,27 +239,27 @@ public class EnsemblGeneTest
   {
     String accId = "ABC123";
     EnsemblGene testee = new EnsemblGene();
-  
+
     // gene with no ID not valid
     SequenceFeature sf = new SequenceFeature("gene", "", 1, 2, 0f, null);
     assertFalse(testee.identifiesSequence(sf, accId));
-  
+
     // gene with wrong ID not valid
     sf.setValue("ID", "gene:XYZ");
     assertFalse(testee.identifiesSequence(sf, accId));
-  
+
     // gene with right ID is valid
     sf.setValue("ID", "gene:" + accId);
     assertTrue(testee.identifiesSequence(sf, accId));
-  
+
     // gene sub-type with right ID is valid
     sf.setType("snRNA_gene");
     assertTrue(testee.identifiesSequence(sf, accId));
-  
+
     // transcript not valid:
     sf.setType("transcript");
     assertFalse(testee.identifiesSequence(sf, accId));
-  
+
     // exon not valid:
     sf.setType("exon");
     assertFalse(testee.identifiesSequence(sf, accId));
index c711279..654797c 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -7,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;
@@ -19,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()
   {
@@ -43,15 +72,14 @@ public class EnsemblGenomeTest
     genomic.setStart(10000);
     genomic.setEnd(50000);
     String transcriptId = "ABC123";
-  
+
     // transcript at (start+10000) length 501
     SequenceFeature sf = new SequenceFeature("transcript", "", 20000,
-            20500, 0f,
-            null);
+            20500, 0f, null);
     sf.setValue("ID", "transcript:" + transcriptId);
     sf.setStrand("+");
     genomic.addSequenceFeature(sf);
-  
+
     // transcript (sub-type) at (start + 10500) length 101
     sf = new SequenceFeature("ncRNA", "", 10500, 10600, 0f, null);
     sf.setValue("ID", "transcript:" + transcriptId);
@@ -65,12 +93,12 @@ public class EnsemblGenomeTest
     sf.setValue("ID", "transcript:" + transcriptId);
     sf.setStrand("+");
     genomic.addSequenceFeature(sf);
-  
+
     // transcript with a different ID doesn't count
     sf = new SequenceFeature("transcript", "", 11500, 12600, 0f, null);
     sf.setValue("ID", "transcript:anotherOne");
     genomic.addSequenceFeature(sf);
-  
+
     // parent of transcript feature doesn't count
     sf = new SequenceFeature("gene_member_region", "", 10000, 50000, 0f,
             null);
@@ -107,13 +135,13 @@ public class EnsemblGenomeTest
     SequenceFeature sf = new SequenceFeature("transcript", "", 20000,
             20500, 0f, null);
     assertFalse(testee.retainFeature(sf, accId));
-  
+
     sf.setType("mature_transcript");
     assertFalse(testee.retainFeature(sf, accId));
-  
+
     sf.setType("NMD_transcript_variant");
     assertFalse(testee.retainFeature(sf, accId));
-  
+
     // other feature with no parent is kept
     sf.setType("anything");
     assertTrue(testee.retainFeature(sf, accId));
@@ -136,20 +164,20 @@ public class EnsemblGenomeTest
   {
     String accId = "ABC123";
     EnsemblGenome testee = new EnsemblGenome();
-  
+
     // transcript with no ID not valid
     SequenceFeature sf = new SequenceFeature("transcript", "", 1, 2, 0f,
             null);
     assertFalse(testee.identifiesSequence(sf, accId));
-  
+
     // transcript with wrong ID not valid
     sf.setValue("ID", "transcript");
     assertFalse(testee.identifiesSequence(sf, accId));
-  
+
     // transcript with right ID is valid
     sf.setValue("ID", "transcript:" + accId);
     assertTrue(testee.identifiesSequence(sf, accId));
-  
+
     // transcript sub-type with right ID is valid
     sf.setType("ncRNA");
     assertTrue(testee.identifiesSequence(sf, accId));
@@ -157,11 +185,11 @@ public class EnsemblGenomeTest
     // Ensembl treats NMD_transcript_variant as if a transcript
     sf.setType("NMD_transcript_variant");
     assertTrue(testee.identifiesSequence(sf, accId));
-  
+
     // gene not valid:
     sf.setType("gene");
     assertFalse(testee.identifiesSequence(sf, accId));
-  
+
     // exon not valid:
     sf.setType("exon");
     assertFalse(testee.identifiesSequence(sf, accId));
index e6f6683..f6a4c8c 100644 (file)
@@ -1,13 +1,43 @@
+/*
+ * 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.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 56e1339..31001da 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.AlignmentI;
@@ -16,43 +36,43 @@ public class EnsemblRestClientTest
   {
     EnsemblRestClient sf = new EnsemblRestClient()
     {
-  
+
       @Override
       public String getDbName()
       {
         return null;
       }
-  
+
       @Override
       public AlignmentI getSequenceRecords(String queries) throws Exception
       {
         return null;
       }
-  
+
       @Override
       protected URL getUrl(List<String> ids) throws MalformedURLException
       {
         return null;
       }
-  
+
       @Override
       protected boolean useGetRequest()
       {
         return false;
       }
-  
+
       @Override
       protected String getRequestMimeType(boolean b)
       {
         return null;
       }
-  
+
       @Override
       protected String getResponseMimeType()
       {
         return null;
       }
-  
+
     };
     boolean isAvailable = sf.isEnsemblAvailable();
     if (isAvailable)
index 510e072..9fad30e 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import jalview.datamodel.SequenceFeature;
index 2d3948f..e977233 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ensembl;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -8,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;
@@ -23,9 +44,16 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 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(),
@@ -125,14 +153,13 @@ public class EnsemblSeqProxyTest
   }
 
   @Test(dataProvider = "ens_seqs", suiteName = "live")
-  public void testGetOneSeqs(EnsemblRestClient proxy, String sq, String fastasq)
-          throws Exception
+  public void testGetOneSeqs(EnsemblRestClient proxy, String sq,
+          String fastasq) throws Exception
   {
     FileParse fp = proxy.getSequenceReader(Arrays
-            .asList(new String[]
-    { sq }));
+            .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);
@@ -152,7 +179,7 @@ public class EnsemblSeqProxyTest
               "Sequences differ for " + tr.getName() + "\n" + "Exp:"
                       + tr.getSequenceAsString() + "\n" + "Got:"
                       + rseq[0].getSequenceAsString());
-  
+
     }
   }
 
@@ -253,4 +280,4 @@ public class EnsemblSeqProxyTest
     EnsemblSeqProxy.sortFeatures(sfs, false);
     assertArrayEquals(new SequenceFeature[] { sf1, sf3, sf2, sf4 }, sfs);
   }
-}
\ No newline at end of file
+}
index df1c1ad..9cc6627 100644 (file)
@@ -1,9 +1,30 @@
+/*
+ * 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.ensembl;
 
 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;
@@ -11,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 5e0f99a..350b599 100644 (file)
@@ -1,13 +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.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;
 
 /**
@@ -16,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 46fa241..439e188 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.jmol;
 
 import jalview.datamodel.Alignment;
@@ -5,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 f728d63..131ef41 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.ext.jmol;
 
 import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.bin.Cache;
@@ -28,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;
@@ -36,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;
 
@@ -47,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
@@ -104,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());
     }
   }
@@ -116,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(
@@ -183,10 +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,12 +215,12 @@ 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();
-  
+
     assertEquals("Failed to find 1 sequence\n", 1, seqs.size());
     assertEquals("Failed to find 1 sequence\n", 1, mcseqs.size());
     assertEquals("ALC", seqs.get(0).getSequenceAsString());
@@ -249,4 +257,30 @@ public class JmolParserTest
     assertEquals('H', structCode[4]);
     assertEquals('E', structCode[5]);
   }
+
+  @Test(groups = "Functional")
+  public void testLocalPDBId() throws Exception
+  {
+    JmolParser structureData;
+    /*
+     * reads a local structure
+     */
+    structureData = new JmolParser("examples/testdata/localstruct.pdb",
+            DataSourceType.FILE);
+    assertNotNull(structureData);
+    /*
+     * local structure files should yield a false ID based on the filename
+     */
+    assertNotNull(structureData.getId());
+    assertEquals(structureData.getId(), "localstruct.pdb");
+    assertNotNull(structureData.getSeqs());
+    /*
+     * the ID is also the group for features derived from structure data 
+     */
+    assertNotNull(structureData.getSeqs().get(0).getSequenceFeatures()[0].featureGroup);
+    assertEquals(
+            structureData.getSeqs().get(0).getSequenceFeatures()[0].featureGroup,
+            "localstruct.pdb");
+
+  }
 }
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 c984b3a..d285b04 100644 (file)
@@ -1,7 +1,28 @@
+/*
+ * 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.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;
@@ -9,6 +30,8 @@ import java.util.HashSet;
 import java.util.Set;
 import java.util.Vector;
 
+import org.testng.annotations.BeforeClass;
+
 import MCview.PDBfile;
 
 /**
@@ -23,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)
@@ -51,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);
@@ -65,15 +94,15 @@ public class JmolVsJalviewPDBParserEndToEndTest
       {
         try
         {
-        String testSeq = mcseqs.remove(0).getSequenceAsString();
+          String testSeq = mcseqs.remove(0).getSequenceAsString();
           if (!sq.getSequenceAsString().equals(testSeq))
-        {
-          ++totalFail;
+          {
+            ++totalFail;
             System.err.println("Test Failed for " + pdbStr + ". Diff:");
-          System.err.println(sq.getSequenceAsString());
-          System.err.println(testSeq);
-          failedFiles.add(pdbStr);
-        }
+            System.err.println(sq.getSequenceAsString());
+            System.err.println(testSeq);
+            failedFiles.add(pdbStr);
+          }
           ++totalSeqScanned;
         } catch (Exception e)
         {
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 ea92e3c..b76a295 100644 (file)
@@ -1,8 +1,29 @@
+/*
+ * 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.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;
@@ -10,10 +31,19 @@ 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)
-  public void setUp() {
+  public void setUp()
+  {
     long now = System.currentTimeMillis();
     try
     {
index eae5575..44fe8d0 100644 (file)
@@ -1,18 +1,48 @@
+/*
+ * 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.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)
@@ -61,11 +91,12 @@ public class FTSRestClientTest
   @Test(groups = { "Functional" })
   public void getAllDefaulDisplayedDataColumns()
   {
-    Assert.assertNotNull(ftsRestClient.getAllDefaultDisplayedFTSDataColumns());
+    Assert.assertNotNull(ftsRestClient
+            .getAllDefaultDisplayedFTSDataColumns());
     Assert.assertTrue(!ftsRestClient.getAllDefaultDisplayedFTSDataColumns()
             .isEmpty());
-    Assert.assertEquals(ftsRestClient.getAllDefaultDisplayedFTSDataColumns()
-            .size(), 7);
+    Assert.assertEquals(ftsRestClient
+            .getAllDefaultDisplayedFTSDataColumns().size(), 7);
   }
 
   @Test(groups = { "Functional" })
@@ -79,7 +110,6 @@ public class FTSRestClientTest
             "id,entry name,protein names,genes,organism,reviewed,length");
   }
 
-
   @Test(groups = { "Functional" })
   public void getAllFTSDataColumns()
   {
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 ed248bb..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
   {
@@ -72,13 +81,11 @@ public class PDBFTSRestClientTest
     {
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("molecule_type"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("pdb_id"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("genus"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("gene_name"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("title"));
@@ -117,13 +124,11 @@ public class PDBFTSRestClientTest
     {
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("molecule_type"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("pdb_id"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("genus"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("gene_name"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("title"));
@@ -147,13 +152,11 @@ public class PDBFTSRestClientTest
     {
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("molecule_type"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("pdb_id"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("genus"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("gene_name"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("title"));
@@ -190,9 +193,7 @@ public class PDBFTSRestClientTest
     assertEquals(expectedErrorMsg, parsedErrorResponse);
   }
 
-  @Test(
-    groups = { "External" },
-    expectedExceptions = Exception.class)
+  @Test(groups = { "External" }, expectedExceptions = Exception.class)
   public void testForExpectedRuntimeException() throws Exception
   {
     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
@@ -206,7 +207,7 @@ public class PDBFTSRestClientTest
     PDBFTSRestClient.getInstance().executeRequest(request);
   }
 
-    // JBP: Is this actually external ?  Looks like it is mocked
+  // JBP: Is this actually external ? Looks like it is mocked
   @Test(groups = { "External" })
   public void parsePDBJsonResponseTest()
   {
@@ -215,13 +216,11 @@ public class PDBFTSRestClientTest
     {
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("molecule_type"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("pdb_id"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("genus"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("gene_name"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("title"));
@@ -259,13 +258,11 @@ public class PDBFTSRestClientTest
               .getDataColumnByNameOrCode("molecule_type"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("genus"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("gene_name"));
       wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("title"));
-      wantedFields
-.add(PDBFTSRestClient.getInstance()
+      wantedFields.add(PDBFTSRestClient.getInstance()
               .getDataColumnByNameOrCode("pdb_id"));
     } catch (Exception e)
     {
@@ -273,11 +270,9 @@ public class PDBFTSRestClientTest
     }
     try
     {
-      assertEquals(5,
- PDBFTSRestClient.getInstance()
+      assertEquals(5, PDBFTSRestClient.getInstance()
               .getPrimaryKeyColumIndex(wantedFields, true));
-      assertEquals(4,
- PDBFTSRestClient.getInstance()
+      assertEquals(4, PDBFTSRestClient.getInstance()
               .getPrimaryKeyColumIndex(wantedFields, false));
     } catch (Exception e)
     {
index 80e3d5a..60db9dd 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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 static org.testng.AssertJUnit.assertEquals;
@@ -12,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");
@@ -60,8 +88,7 @@ public class AlignFrameTest
      * [1-3], [6-8] base zero
      */
     assertTrue(af.hideFeatureColumns("Turn", true));
-    hidden = af.getViewport().getColumnSelection()
-            .getHiddenColumns();
+    hidden = af.getViewport().getColumnSelection().getHiddenColumns();
     assertEquals(2, hidden.size());
     assertEquals(1, hidden.get(0)[0]);
     assertEquals(3, hidden.get(0)[1]);
index bbad963..5695b15 100644 (file)
@@ -35,10 +35,14 @@ 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;
 import jalview.util.MapList;
 
@@ -52,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;
@@ -136,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();
@@ -185,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);
@@ -248,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);
@@ -300,7 +311,7 @@ public class AlignViewportTest
     assertTrue(ssmMappings.contains(acf2));
     assertFalse(ssmMappings.contains(acf3));
   }
-  
+
   /**
    * Test for JAL-1306 - conservation thread should run even when only Quality
    * (and not Conservation) is enabled in Preferences
@@ -317,8 +328,9 @@ public class AlignViewportTest
     Cache.applicationProperties.setProperty("SHOW_IDENTITY",
             Boolean.FALSE.toString());
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
-            "examples/uniref50.fa", FormatAdapter.FILE);
-    AlignmentAnnotation[] anns = af.viewport.getAlignment().getAlignmentAnnotation();
+            "examples/uniref50.fa", DataSourceType.FILE);
+    AlignmentAnnotation[] anns = af.viewport.getAlignment()
+            .getAlignmentAnnotation();
     assertNotNull("No annotations found", anns);
     assertEquals("More than one annotation found", 1, anns.length);
     assertTrue("Annotation is not Quality",
@@ -328,4 +340,44 @@ public class AlignViewportTest
     assertNotNull("Quality in column 1 is null", annotations[0]);
     assertTrue("No quality value in column 1", annotations[0].value > 10f);
   }
+
+  @Test(groups = { "Functional" })
+  public void testSetGlobalColourScheme()
+  {
+    /*
+     * test for JAL-2283 don't inadvertently turn on colour by conservation
+     */
+    Cache.applicationProperties.setProperty("DEFAULT_COLOUR_PROT", "NONE");
+    Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+            Boolean.TRUE.toString());
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "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 3667b52..6d154de 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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;
 
 /*
@@ -233,4 +253,4 @@ public class MouseEventDemo extends JPanel implements MouseListener
   {
     logEvent("Mouse clicked", e);
   }
-}
\ No newline at end of file
+}
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 bad536b..b7eef0f 100644 (file)
@@ -28,15 +28,25 @@ import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+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)
@@ -44,7 +54,7 @@ public class StructureChooserTest
   {
     seq = new Sequence("PDB|4kqy|4KQY|A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1,
             26);
-    seq.setDatasetSequence(seq);
+    seq.createDatasetSequence();
     for (int x = 1; x < 5; x++)
     {
       DBRefEntry dbRef = new DBRefEntry();
@@ -105,27 +115,25 @@ public class StructureChooserTest
   }
 
   @Test(groups = { "Functional" })
-  public void populateFilterComboBoxTest()
+  public void populateFilterComboBoxTest() throws InterruptedException
   {
     SequenceI[] selectedSeqs = new SequenceI[] { seq };
     StructureChooser sc = new StructureChooser(selectedSeqs, seq, null);
-    sc.populateFilterComboBox();
+    sc.populateFilterComboBox(false, false);
     int optionsSize = sc.getCmbFilterOption().getItemCount();
     assertEquals(3, optionsSize); // if structures are not discovered then don't
                                   // populate filter options
 
-    sc.setStructuresDiscovered(true);
-    sc.populateFilterComboBox();
-    try
-    {
-      Thread.sleep(2000);
-    } catch (InterruptedException e)
-    {
-      e.printStackTrace();
-    }
+    sc.populateFilterComboBox(true, false);
     optionsSize = sc.getCmbFilterOption().getItemCount();
     assertTrue(optionsSize > 3); // if structures are found, filter options
                                  // should be populated
+
+    sc.populateFilterComboBox(true, true);
+    assertTrue(sc.getCmbFilterOption().getSelectedItem() != null);
+    FilterOption filterOpt = (FilterOption) sc.getCmbFilterOption()
+            .getSelectedItem();
+    assertEquals("Cached PDB Entries", filterOpt.getName());
   }
 
   @Test(groups = { "Functional" })
diff --git a/test/jalview/gui/StructureViewerTest.java b/test/jalview/gui/StructureViewerTest.java
new file mode 100644 (file)
index 0000000..c1c1d5c
--- /dev/null
@@ -0,0 +1,42 @@
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+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()
+  {
+    assertNull(StructureViewer.getUniquePdbFiles(null));
+
+    PDBEntry pdbe1 = new PDBEntry("1A70", "A", Type.PDB, "path1");
+    PDBEntry pdbe2 = new PDBEntry("3A6S", "A", Type.PDB, "path2");
+    PDBEntry pdbe3 = new PDBEntry("1A70", "B", Type.PDB, "path1");
+    PDBEntry pdbe4 = new PDBEntry("1GAQ", "A", Type.PDB, null);
+    PDBEntry pdbe5 = new PDBEntry("3A6S", "B", Type.PDB, "path2");
+    PDBEntry pdbe6 = new PDBEntry("1GAQ", "B", Type.PDB, null);
+
+    /*
+     * pdbe2 and pdbe5 get removed as having a duplicate file path
+     */
+    PDBEntry[] uniques = StructureViewer.getUniquePdbFiles(new PDBEntry[] {
+        pdbe1, pdbe2, pdbe3, pdbe4, pdbe5, pdbe6 });
+    assertEquals(uniques,
+ new PDBEntry[] { pdbe1, pdbe2, pdbe4, pdbe6 });
+  }
+}
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 fd989ad..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();
@@ -85,8 +93,8 @@ public class AnnotatedPDBFileInputTest
     {
       for (int q = p + 1; q < avec.length; q++)
       {
-        assertTrue("Found a duplicate annotation row "
-                + avec[p].label, avec[p] != avec[q]);
+        assertTrue("Found a duplicate annotation row " + avec[p].label,
+                avec[p] != avec[q]);
       }
     }
   }
@@ -104,7 +112,7 @@ public class AnnotatedPDBFileInputTest
         if (StructureImportSettings.getDefaultPDBFileParser().equals(
                 StructureParser.JALVIEW_PARSER))
         {
-        assertTrue(MCview.PDBfile.isCalcIdForFile(aa, pdbId));
+          assertTrue(MCview.PDBfile.isCalcIdForFile(aa, pdbId));
         }
       }
     }
@@ -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 625244d..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,14 +78,13 @@ 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)
       {
-        al.getSequenceAt(i).setDatasetSequence(
-                al.getSequenceAt(i).createDatasetSequence());
+        al.getSequenceAt(i).createDatasetSequence();
       }
       assertNotNull("Couldn't read supplied alignment data.", al);
       return al;
@@ -115,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,
@@ -143,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 2063c88..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();
@@ -168,7 +178,7 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
             // perform crossref action, or retrieve stored project
             List<AlignmentViewPanel> cra_views = new ArrayList<AlignmentViewPanel>();
             CrossRefAction cra = null;
-            
+
             if (pass2 == 0)
             { // retrieve and show cross-refs in this thread
               cra = new CrossRefAction(af, seqs, dna, db);
@@ -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()
                       + "'");
@@ -248,7 +258,7 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
                       : new CrossRef(xrseqs, dataset)
                               .findXrefSourcesForSequences(avp
                                       .getAlignViewport().isNucleotide());
-              
+
               stringify(dbtoviewBit, savedProjects, nextxref, avp);
               xrptypes.put(nextxref, _xrptypes);
 
@@ -266,8 +276,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
                 {
                   List<AlignmentViewPanel> cra_views2 = new ArrayList<AlignmentViewPanel>();
                   int q = 0;
-                  String nextnextxref = nextxref
-                          + " -> " + xrefdb + "{" + q + "}";
+                  String nextnextxref = nextxref + " -> " + xrefdb + "{"
+                          + q + "}";
 
                   if (pass3 == 0)
                   {
@@ -284,8 +294,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
                     {
                       failedXrefMenuItems
                               .add("No crossrefs retrieved for '"
-                              + nextxref + "' to " + xrefdb + " via '"
-                              + nextaf.getTitle() + "'");
+                                      + nextxref + "' to " + xrefdb
+                                      + " via '" + nextaf.getTitle() + "'");
                       continue;
                     }
                     cra_views2 = cra.getXrefViews();
@@ -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()
@@ -345,8 +356,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
 
                   for (AlignmentViewPanel nextavp : cra_views2)
                   {
-                    nextnextxref = nextxref
-                            + " -> " + xrefdb + "{" + q++ + "}";
+                    nextnextxref = nextxref + " -> " + xrefdb + "{" + q++
+                            + "}";
 
                     // verify references for this panel
                     AlignmentTest.assertAlignmentDatasetRefs(
@@ -471,8 +482,7 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
   {
     List<SequenceI> nonType = new ArrayList<SequenceI>();
     for (SequenceI sq : alignmentViewPanel.getAlignViewport()
-            .getAlignment()
-            .getSequences())
+            .getAlignment().getSequences())
     {
       if (sq.isProtein() != expectProtein)
       {
@@ -483,8 +493,7 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
     {
       Assert.fail(message + " [ "
               + (expectProtein ? "nucleotides were " : "proteins were ")
-              + nonType.toString()
-              + " ]");
+              + nonType.toString() + " ]");
     }
   }
 
index 2f5d0c5..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));
@@ -153,11 +162,12 @@ public class FeaturesFileTest
     Map<String, FeatureColourI> colours = af.getFeatureRenderer()
             .getFeatureColours();
     // GFF2 uses space as name/value separator in column 9
-    String gffData = "METAL\tcc9900\n" + "GFF\n"
+    String gffData = "METAL\tcc9900\n"
+            + "GFF\n"
             + "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));
 
@@ -196,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);
@@ -223,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));
 
@@ -276,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));
 
@@ -304,7 +314,7 @@ public class FeaturesFileTest
   {
     assertEquals("no sequences extracted from GFF3 file", 2,
             dataset.getHeight());
-  
+
     SequenceI seq1 = dataset.findName("seq1");
     SequenceI seq2 = dataset.findName("seq2");
     assertNotNull(seq1);
@@ -335,14 +345,14 @@ public class FeaturesFileTest
             "Expected at least one CDNA/Protein mapping for seq1",
             dataset.getCodonFrame(seq1) != null
                     && dataset.getCodonFrame(seq1).size() > 0);
-  
+
   }
 
   @Test(groups = { "Functional" })
   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,7 +363,7 @@ public class FeaturesFileTest
   {
     AlignmentI dataset = new Alignment(new SequenceI[] {});
     FeaturesFile ffile = new FeaturesFile(simpleGffFile,
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
   
     boolean parseResult = ffile.parse(dataset, null, false, false);
     assertTrue("return result should be true", parseResult);
@@ -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);
@@ -376,7 +386,7 @@ public class FeaturesFileTest
   {
     AlignmentI dataset = new Alignment(new SequenceI[] {});
     FeaturesFile ffile = new FeaturesFile(simpleGffFile,
-            FormatAdapter.FILE);
+            DataSourceType.FILE);
   
     boolean parseResult = ffile.parse(dataset, null, false, true);
     assertTrue("return result (relaxedID matching) should be true",
@@ -401,15 +411,14 @@ 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);
 
     /*
      * first with no features displayed
      */
     FeatureRenderer fr = af.alignPanel.getFeatureRenderer();
-    Map<String, FeatureColourI> visible = fr
-            .getDisplayedFeatureCols();
+    Map<String, FeatureColourI> visible = fr.getDisplayedFeatureCols();
     String exported = featuresFile.printJalviewFormat(
             al.getSequencesArray(), visible);
     String expected = "No Features Visible";
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 81e336e..7aa5769 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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 static org.testng.AssertJUnit.assertEquals;
@@ -6,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,
@@ -43,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());
@@ -58,9 +86,8 @@ public class FormatAdapterTest
          */
         sequenceString = adjustForGapTreatment(sequenceString, gap, format);
         assertEquals(
-                String.format("Sequence %d: %s", i,
-                        seqs[i].getName()), seqs[i].getSequenceAsString(),
-                sequenceString);
+                String.format("Sequence %d: %s", i, seqs[i].getName()),
+                seqs[i].getSequenceAsString(), sequenceString);
         i++;
       }
     } catch (IOException e)
@@ -82,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
@@ -97,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++;
@@ -133,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 93fb12b..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;
@@ -114,7 +123,7 @@ public class JSONFileTest
 
     for (Sequence seq : seqs)
     {
-      seq.setDatasetSequence(seq);
+      seq.createDatasetSequence();
       expectedSeqs.put(seq.getName(), seq);
     }
 
@@ -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 379fd68..15e18e3 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.bin.Cache;
@@ -5,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;
 
@@ -15,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 5dd4ecb..52a13f6 100644 (file)
@@ -1,30 +1,60 @@
+/*
+ * 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.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 f551571..2895874 100644 (file)
@@ -1,21 +1,51 @@
+/*
+ * 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 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");
@@ -40,11 +70,11 @@ 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");
-  
+
     sar.appendFeature(sb, 1, null, sf);
     assertEquals("METAL 1 3; Fe2-S; (Confirmed)", sb.toString());
   }
@@ -53,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");
 
@@ -86,10 +116,10 @@ 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");
-  
+
     sar.appendFeature(sb, 1, null, sf);
     assertEquals("METAL 1 3; Fe2-S", sb.toString());
   }
@@ -98,11 +128,11 @@ 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");
-  
+
     sar.appendFeature(sb, 1, null, sf);
     assertEquals("METAL 1 3; Fe2-S; Benign", sb.toString());
   }
@@ -111,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");
@@ -128,10 +158,10 @@ 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");
-  
+
     // description is not included if it duplicates type:
     sar.appendFeature(sb, 1, null, sf);
     assertEquals("METAL 1 3", sb.toString());
@@ -147,15 +177,14 @@ 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");
-  
+
     sar.appendFeature(sb, 1, null, sf);
     // !! strips off </body> but not <body> ??
-    assertEquals("METAL 1 3; <body>hello<em>world</em>",
-            sb.toString());
+    assertEquals("METAL 1 3; <body>hello<em>world</em>", sb.toString());
 
     sb.setLength(0);
     sf.setDescription("<br>&kHD>6");
index 0e2b630..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,26 +104,26 @@ 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);
 
       // make sure dataset is initialised ? not sure about this
       for (int i = 0; i < al.getSequencesArray().length; ++i)
       {
-        al.getSequenceAt(i).setDatasetSequence(al.getSequenceAt(i));
+        al.getSequenceAt(i).createDatasetSequence();
       }
       String outputfile = rf.formatSequences(ioformat, al, true);
       System.out.println("Output file in '" + ioformat + "':\n"
               + 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(
@@ -281,8 +290,7 @@ public class StockholmFileTest
 
             assertEquals("different number of features",
                     seq_original[i].getSequenceFeatures().length,
-                    seq_new[in]
-                    .getSequenceFeatures().length);
+                    seq_new[in].getSequenceFeatures().length);
 
             for (int feat = 0; feat < seq_original[i].getSequenceFeatures().length; feat++)
             {
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 54d6eb2..825af24 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -15,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;
@@ -24,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()
   {
@@ -239,10 +269,10 @@ public class ExonerateHelperTest
     FileLoader loader = new FileLoader(false);
     AlignFrame af = loader.LoadFileWaitTillLoaded(
             "examples/testdata/exonerateseqs.fa",
-            FormatAdapter.FILE);
+            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
index 420b032..bf038ac 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -13,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
@@ -161,7 +190,7 @@ public class Gff3HelperTest
             "GAATTCGTTCATGTAGGTTGATTTTTATT");
     seq.createDatasetSequence();
     AlignmentI align = new Alignment(new SequenceI[] {});
-  
+
     // mapping from gi|68711 12923-13060 to gi|N37351 1-138
     String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 +"
             .split("\\t");
@@ -179,7 +208,7 @@ public class Gff3HelperTest
     // (this is important for 'align cdna to genome' to work correctly)
     assertEquals(1, align.getCodonFrames().size());
     AlignedCodonFrame mapping = align.getCodonFrames().get(0);
-  
+
     /*
      * 'dnaseqs' (map from) is here [gi|68711]
      * 'aaseqs' (map to) is here [gi|N37351]
@@ -192,8 +221,7 @@ public class Gff3HelperTest
     assertEquals(1, mapping.getdnaToProt().length);
     assertEquals(2, mapping.getdnaToProt()[0].getFromRanges().size());
     // the two spliced dna ranges are combined in one MapList
-    assertArrayEquals(new int[] { 12923, 13060 },
-            mapping.getdnaToProt()[0]
+    assertArrayEquals(new int[] { 12923, 13060 }, mapping.getdnaToProt()[0]
             .getFromRanges().get(0));
     assertArrayEquals(new int[] { 13411, 13550 }, mapping.getdnaToProt()[0]
             .getFromRanges().get(1));
index fe8f88e..7fb716f 100644 (file)
@@ -1,18 +1,48 @@
+/*
+ * 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.gff;
 
 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 657b5bd..84725ff 100644 (file)
@@ -1,14 +1,44 @@
+/*
+ * 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.gff;
 
 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 2ee4eac..393f2ce 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -13,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;
 
 /**
@@ -27,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
@@ -37,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) 
@@ -45,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 2ef4c99..bcccf35 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.gff;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -11,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
    * 
@@ -38,7 +67,7 @@ public class InterProScanHelperTest
     seq.createDatasetSequence();
     AlignmentI align = new Alignment(new SequenceI[] {});
     Map<String, List<String>> set = Gff3Helper.parseNameValuePairs(gff[8]);
-  
+
     /*
      * this should create a mapping from Prot1/5-30 to virtual sequence
      * match$17_5_30 (added to newseqs) positions 1-26
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 e13f542..47613a1 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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;
@@ -6,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()
   {
@@ -123,7 +153,8 @@ public class FeatureColourTest
   @Test(groups = { "Functional" })
   public void testGetColor_Graduated()
   {
-    // graduated colour from score 0 to 100, gray(128, 128, 128) to red(255, 0, 0)
+    // graduated colour from score 0 to 100, gray(128, 128, 128) to red(255, 0,
+    // 0)
     FeatureColour fc = new FeatureColour(Color.GRAY, Color.RED, 0f, 100f);
     // feature score is 75 which is 3/4 of the way from GRAY to RED
     SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
@@ -166,7 +197,7 @@ public class FeatureColourTest
     String redHex = Format.getHexString(Color.RED);
     String hexColour = redHex;
     assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
-    
+
     /*
      * colour by label (no threshold)
      */
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 e524cb4..645d5b8 100644 (file)
@@ -1,15 +1,46 @@
+/*
+ * 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.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 5ab43b5..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
@@ -139,7 +149,7 @@ public class Mapping
     // source
     StructureFile pde = ssm.setMapping(true, new SequenceI[] { sq },
             new String[]
-    { "A" }, inFile = "examples/1gaq.txt", jalview.io.FormatAdapter.FILE);
+    { "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 bb81992..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,26 +51,44 @@ 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
+   */
   private static final String PDB_1 = "HEADER    COMPLEX (ANTI-ONCOGENE/ANKYRIN REPEATS) 30-SEP-96   1YCS              \n"
           + "ATOM      2  CA  VAL A  97      24.134   4.926  45.821  1.00 47.43           C  \n"
           + "ATOM      9  CA  PRO A  98      25.135   8.584  46.217  1.00 41.60           C  \n"
           + "ATOM     16  CA  SER A  99      28.243   9.596  44.271  1.00 39.63           C  \n"
           + "ATOM     22  CA  GLN A 100      31.488  10.133  46.156  1.00 35.60           C  \n"
-          + "ATOM     31  CA  LYS A 101      33.323  11.587  43.115  1.00 41.69           C  \n";
+          // artificial jump in residue numbering to prove it is correctly
+          // mapped:
+          + "ATOM     31  CA  LYS A 102      33.323  11.587  43.115  1.00 41.69           C  \n"
+          + "ATOM   1857  CA  GLU B 374       9.193 -16.005  95.870  1.00 54.22           C  \n"
+          + "ATOM   1866  CA  ILE B 375       7.101 -14.921  92.847  1.00 46.82           C  \n"
+          + "ATOM   1874  CA  VAL B 376      10.251 -13.625  91.155  1.00 47.80           C  \n"
+          + "ATOM   1881  CA  LYS B 377      11.767 -17.068  91.763  1.00 50.21           C  \n"
+          + "ATOM   1890  CA  PHE B 378       8.665 -18.948  90.632  1.00 44.85           C  \n";
 
   private static final String PDB_2 = "HEADER    HYDROLASE                               09-SEP-09   3A6S              \n"
-          + "ATOM      2  CA  MET A   1      15.366 -11.648  24.854  1.00 32.05           C  \n"
-          + "ATOM     10  CA  LYS A   2      16.846  -9.215  22.340  1.00 25.68           C  \n"
-          + "ATOM     19  CA  LYS A   3      15.412  -6.335  20.343  1.00 19.42           C  \n"
-          + "ATOM     28  CA  LEU A   4      15.629  -5.719  16.616  1.00 15.49           C  \n"
-          + "ATOM     36  CA  GLN A   5      14.412  -2.295  15.567  1.00 12.19           C  \n";
+          + "ATOM      2  CA  MET B   1      15.366 -11.648  24.854  1.00 32.05           C  \n"
+          + "ATOM     10  CA  LYS B   2      16.846  -9.215  22.340  1.00 25.68           C  \n"
+          + "ATOM     19  CA  LYS B   3      15.412  -6.335  20.343  1.00 19.42           C  \n"
+          + "ATOM     28  CA  LEU B   4      15.629  -5.719  16.616  1.00 15.49           C  \n"
+          + "ATOM     36  CA  GLN B   5      14.412  -2.295  15.567  1.00 12.19           C  \n";
 
   private static final String PDB_3 = "HEADER    STRUCTURAL GENOMICS                     04-MAR-03   1OOT              \n"
-          + "ATOM      2  CA  SER A   1      29.427   3.330  -6.578  1.00 32.50           C  \n"
-          + "ATOM      8  CA  PRO A   2      29.975   3.340  -2.797  1.00 17.62           C  \n"
-          + "ATOM     16  CA ALYS A   3      26.958   3.024  -0.410  0.50  8.78           C  \n"
-          + "ATOM     33  CA  ALA A   4      26.790   4.320   3.172  1.00 11.98           C  \n"
-          + "ATOM     39  CA AVAL A   5      24.424   3.853   6.106  0.50 13.83           C  \n";
+          + "ATOM      2  CA  SER A   7      29.427   3.330  -6.578  1.00 32.50           C  \n"
+          + "ATOM      8  CA  PRO A   8      29.975   3.340  -2.797  1.00 17.62           C  \n"
+          + "ATOM     16  CA ALYS A   9      26.958   3.024  -0.410  0.50  8.78           C  \n"
+          + "ATOM     33  CA  ALA A  10      26.790   4.320   3.172  1.00 11.98           C  \n"
+          + "ATOM     39  CA AVAL A  12      24.424   3.853   6.106  0.50 13.83           C  \n";
 
   AAStructureBindingModel testee;
 
@@ -80,39 +100,38 @@ public class AAStructureBindingModelTest
   @BeforeMethod(alwaysRun = true)
   public void setUp()
   {
-    SequenceI seq1 = new Sequence("1YCS", "-VPSQK");
+    SequenceI seq1a = new Sequence("1YCS|A", "-VPSQK");
+    SequenceI seq1b = new Sequence("1YCS|B", "EIVKF-");
     SequenceI seq2 = new Sequence("3A6S", "MK-KLQ");
     SequenceI seq3 = new Sequence("1OOT", "SPK-AV");
-    al = new Alignment(new SequenceI[] { seq1, seq2, seq3 });
+    al = new Alignment(new SequenceI[] { seq1a, seq1b, seq2, seq3 });
     al.setDataset(null);
 
+    /*
+     * give pdb files the name generated by Jalview for PASTE source
+     */
     PDBEntry[] pdbFiles = new PDBEntry[3];
-    pdbFiles[0] = new PDBEntry("1YCS", "A", Type.PDB, "1YCS.pdb");
-    pdbFiles[1] = new PDBEntry("3A6S", "B", Type.PDB, "3A6S.pdb");
-    pdbFiles[2] = new PDBEntry("1OOT", "A", Type.PDB, "1OOT.pdb");
-    String[][] chains = new String[3][];
+    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");
     SequenceI[][] seqs = new SequenceI[3][];
-    seqs[0] = new SequenceI[] { seq1 };
+    seqs[0] = new SequenceI[] { seq1a, seq1b };
     seqs[1] = new SequenceI[] { seq2 };
     seqs[2] = new SequenceI[] { seq3 };
     StructureSelectionManager ssm = new StructureSelectionManager();
 
-    ssm.setMapping(new SequenceI[] { seq1 }, null, PDB_1,
-            AppletFormatAdapter.PASTE);
+    ssm.setMapping(new SequenceI[] { seq1a, seq1b }, null, PDB_1,
+            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()
       {
-        /*
-         * fudge 'filenames' to match those generated when PDBFile parses PASTE
-         * data
-         */
         return new String[] { "INLINE1YCS", "INLINE3A6S", "INLINE1OOT" };
       }
 
@@ -130,6 +149,12 @@ public class AAStructureBindingModelTest
       public void highlightAtoms(List<AtomSpec> atoms)
       {
       }
+
+      @Override
+      public List<String> getChainNames()
+      {
+        return null;
+      }
     };
   }
 
@@ -140,7 +165,10 @@ public class AAStructureBindingModelTest
   @Test(groups = { "Functional" })
   public void testFindSuperposableResidues()
   {
-    SuperposeData[] structs = new SuperposeData[al.getHeight()];
+    /*
+     * create a data bean to hold data per structure file
+     */
+    SuperposeData[] structs = new SuperposeData[testee.getPdbFile().length];
     for (int i = 0; i < structs.length; i++)
     {
       structs[i] = testee.new SuperposeData(al.getWidth());
@@ -162,10 +190,23 @@ public class AAStructureBindingModelTest
      */
     assertFalse(matched[0]); // gap in first sequence
     assertTrue(matched[1]);
-    assertFalse(matched[2]); // gap in second sequence
-    assertFalse(matched[3]); // gap in third sequence
+    assertFalse(matched[2]); // gap in third sequence
+    assertFalse(matched[3]); // gap in fourth sequence
     assertTrue(matched[4]);
-    assertTrue(matched[5]);
+    assertTrue(matched[5]); // gap in second sequence
+
+    assertEquals("1YCS", structs[0].pdbId);
+    assertEquals("3A6S", structs[1].pdbId);
+    assertEquals("1OOT", structs[2].pdbId);
+    assertEquals("A", structs[0].chain); // ? struct has chains A _and_ B
+    assertEquals("B", structs[1].chain);
+    assertEquals("A", structs[2].chain);
+    // the 0's for unsuperposable positions propagate down the columns:
+    assertEquals("[0, 97, 98, 99, 100, 102]",
+            Arrays.toString(structs[0].pdbResNo));
+    assertEquals("[0, 2, 0, 3, 4, 5]", Arrays.toString(structs[1].pdbResNo));
+    assertEquals("[0, 8, 0, 0, 10, 12]",
+            Arrays.toString(structs[2].pdbResNo));
   }
 
   @Test(groups = { "Functional" })
index 5a2674a..743b9a3 100644 (file)
@@ -1,15 +1,47 @@
+/*
+ * 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.AssertJUnit.assertEquals;
 
+import jalview.gui.JvOptionPane;
+
 import java.util.Arrays;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class ArrayUtilsTest
 {
-  @Test(groups="Functional")
-  public void testReverseIntArray() {
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups = "Functional")
+  public void testReverseIntArray()
+  {
 
     // null value: should be no exception
     ArrayUtils.reverseIntArray((int[]) null);
index 9a846e6..093428c 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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;
@@ -5,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 a82b9c0..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
@@ -122,8 +133,7 @@ public class ColorUtilsTest
      * value > max
      */
     col = ColorUtils
-            .getGraduatedColour(40f, 10f, minColour, 30f,
-            maxColour);
+            .getGraduatedColour(40f, 10f, minColour, 30f, maxColour);
     assertEquals(maxColour, col);
 
     /*
@@ -133,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 5e0683e..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" })
@@ -197,8 +218,7 @@ public class DBRefUtilsTest
         1 }, 1, 1)));
 
     List<DBRefEntry> matches = DBRefUtils.searchRefs(new DBRefEntry[] {
-        ref1,
-        ref2, ref3, ref4, ref5 }, target);
+        ref1, ref2, ref3, ref4, ref5 }, target);
     assertEquals(3, matches.size());
     assertSame(ref1, matches.get(0));
     assertSame(ref2, matches.get(1));
@@ -231,8 +251,7 @@ public class DBRefUtilsTest
     ref3.setMap(map3);
 
     List<DBRefEntry> matches = DBRefUtils.searchRefs(new DBRefEntry[] {
-        ref1,
-        ref2, ref3 }, target);
+        ref1, ref2, ref3 }, target);
     assertEquals(2, matches.size());
     assertSame(ref1, matches.get(0));
     assertSame(ref2, matches.get(1));
@@ -245,7 +264,7 @@ public class DBRefUtilsTest
   @Test(groups = { "Functional" })
   public void testSearchRefs_accessionid()
   {
-  
+
     DBRefEntry ref1 = new DBRefEntry("Uniprot", "1", "A1234"); // matches
     DBRefEntry ref2 = new DBRefEntry("embl", "1", "A1234"); // matches
     // constructor does not upper-case accession id
@@ -255,9 +274,8 @@ public class DBRefUtilsTest
     DBRefEntry ref5 = new DBRefEntry("EMBL", "1", "A1234");
     ref5.setMap(new Mapping(new MapList(new int[] { 1, 1 }, new int[] { 1,
         1 }, 1, 1)));
-  
-    DBRefEntry[] dbrefs = new DBRefEntry[] { ref1,
-        ref2, ref3, ref4, ref5 };
+
+    DBRefEntry[] dbrefs = new DBRefEntry[] { ref1, ref2, ref3, ref4, ref5 };
     List<DBRefEntry> matches = DBRefUtils.searchRefs(dbrefs, "A1234");
     assertEquals(3, matches.size());
     assertSame(ref1, matches.get(0));
@@ -273,7 +291,7 @@ public class DBRefUtilsTest
   public void testSearchRefs_wildcardAccessionid()
   {
     DBRefEntry target = new DBRefEntry("EMBL", "2", null);
-  
+
     DBRefEntry ref1 = new DBRefEntry("EMBL", "1", "A1234"); // matches
     // constructor changes embl to EMBL
     DBRefEntry ref2 = new DBRefEntry("embl", "1", "A1235"); // matches
@@ -284,10 +302,9 @@ public class DBRefUtilsTest
     DBRefEntry ref5 = new DBRefEntry("EMBL", "1", "A1237");
     ref5.setMap(new Mapping(new MapList(new int[] { 1, 1 }, new int[] { 1,
         1 }, 1, 1)));
-  
+
     List<DBRefEntry> matches = DBRefUtils.searchRefs(new DBRefEntry[] {
-        ref1,
-        ref2, ref3, ref4, ref5 }, target);
+        ref1, ref2, ref3, ref4, ref5 }, target);
     assertEquals(4, matches.size());
     assertSame(ref1, matches.get(0));
     assertSame(ref2, matches.get(1));
index fbc95ad..9815aa0 100644 (file)
@@ -1,16 +1,47 @@
+/*
+ * 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.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 ba298c5..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()
   {
@@ -535,8 +545,7 @@ public class MapListTest
     MapList ml = new MapList(new int[] { 1, 5, 10, 15, 25, 20 }, new int[] {
         51, 1 }, 1, 3);
     String s = ml.toString();
-    assertEquals("[ [1, 5] [10, 15] [25, 20] ] 1:3 to [ [51, 1] ]",
-            s);
+    assertEquals("[ [1, 5] [10, 15] [25, 20] ] 1:3 to [ [51, 1] ]", s);
   }
 
   @Test(groups = { "Functional" })
@@ -671,8 +680,8 @@ public class MapListTest
   public void testIsFromForwardStrand()
   {
     // [3-9] declares forward strand
-    MapList ml = new MapList(new int[] { 2, 2, 3, 9, 12, 11 },
-            new int[] { 20, 11 }, 1, 1);
+    MapList ml = new MapList(new int[] { 2, 2, 3, 9, 12, 11 }, new int[] {
+        20, 11 }, 1, 1);
     assertTrue(ml.isFromForwardStrand());
 
     // [11-5] declares reverse strand ([13-14] is ignored)
index d131ed2..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);
@@ -867,7 +880,7 @@ public class MappingUtilsTest
   public void testMapColumnSelection_hiddenColumns() throws IOException
   {
     setupMappedAlignments();
-  
+
     ColumnSelection proteinSelection = new ColumnSelection();
 
     /*
@@ -875,8 +888,8 @@ public class MappingUtilsTest
      * in dna respectively, overall 0-4
      */
     proteinSelection.hideColumns(0);
-    ColumnSelection dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
-            proteinView, dnaView);
+    ColumnSelection dnaSelection = MappingUtils.mapColumnSelection(
+            proteinSelection, proteinView, dnaView);
     assertEquals("[]", dnaSelection.getSelected().toString());
     List<int[]> hidden = dnaSelection.getHiddenColumns();
     assertEquals(1, hidden.size());
@@ -891,7 +904,8 @@ public class MappingUtilsTest
     // deselect these or hideColumns will be expanded to include 0
     proteinSelection.clear();
     proteinSelection.hideColumns(1);
-    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
+            proteinView, dnaView);
     hidden = dnaSelection.getHiddenColumns();
     assertEquals(1, hidden.size());
     assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
@@ -902,7 +916,8 @@ public class MappingUtilsTest
     proteinSelection.revealAllHiddenColumns();
     proteinSelection.clear();
     proteinSelection.hideColumns(2);
-    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
+            proteinView, dnaView);
     assertTrue(dnaSelection.getHiddenColumns().isEmpty());
 
     /*
@@ -913,7 +928,8 @@ public class MappingUtilsTest
     proteinSelection.clear();
     proteinSelection.hideColumns(3); // 5-10 hidden in dna
     proteinSelection.addElement(1); // 0-3 selected in dna
-    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
+            proteinView, dnaView);
     assertEquals("[0, 1, 2, 3]", dnaSelection.getSelected().toString());
     hidden = dnaSelection.getHiddenColumns();
     assertEquals(1, hidden.size());
@@ -926,7 +942,8 @@ public class MappingUtilsTest
     proteinSelection.clear();
     proteinSelection.hideColumns(1);
     proteinSelection.hideColumns(3);
-    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
+            proteinView, dnaView);
     hidden = dnaSelection.getHiddenColumns();
     assertEquals(2, hidden.size());
     assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
@@ -1060,42 +1077,42 @@ public class MappingUtilsTest
     int[] adjusted = MappingUtils.removeStartPositions(0, ranges);
     assertEquals("[10, 1]", Arrays.toString(adjusted));
     assertEquals("[10, 1]", Arrays.toString(ranges));
-  
+
     ranges = adjusted;
     adjusted = MappingUtils.removeStartPositions(1, ranges);
     assertEquals("[9, 1]", Arrays.toString(adjusted));
     assertEquals("[10, 1]", Arrays.toString(ranges));
-  
+
     ranges = adjusted;
     adjusted = MappingUtils.removeStartPositions(1, ranges);
     assertEquals("[8, 1]", Arrays.toString(adjusted));
     assertEquals("[9, 1]", Arrays.toString(ranges));
-  
+
     ranges = new int[] { 12, 11, 9, 6 };
     adjusted = MappingUtils.removeStartPositions(1, ranges);
     assertEquals("[11, 11, 9, 6]", Arrays.toString(adjusted));
     assertEquals("[12, 11, 9, 6]", Arrays.toString(ranges));
-  
+
     ranges = new int[] { 12, 12, 8, 4 };
     adjusted = MappingUtils.removeStartPositions(1, ranges);
     assertEquals("[8, 4]", Arrays.toString(adjusted));
     assertEquals("[12, 12, 8, 4]", Arrays.toString(ranges));
-  
+
     ranges = new int[] { 12, 12, 8, 4 };
     adjusted = MappingUtils.removeStartPositions(2, ranges);
     assertEquals("[7, 4]", Arrays.toString(adjusted));
     assertEquals("[12, 12, 8, 4]", Arrays.toString(ranges));
-  
+
     ranges = new int[] { 12, 12, 10, 10, 8, 4 };
     adjusted = MappingUtils.removeStartPositions(1, ranges);
     assertEquals("[10, 10, 8, 4]", Arrays.toString(adjusted));
     assertEquals("[12, 12, 10, 10, 8, 4]", Arrays.toString(ranges));
-  
+
     ranges = new int[] { 12, 12, 10, 10, 8, 4 };
     adjusted = MappingUtils.removeStartPositions(2, ranges);
     assertEquals("[8, 4]", Arrays.toString(adjusted));
     assertEquals("[12, 12, 10, 10, 8, 4]", Arrays.toString(ranges));
-  
+
     ranges = new int[] { 12, 11, 8, 4 };
     adjusted = MappingUtils.removeStartPositions(3, ranges);
     assertEquals("[7, 4]", Arrays.toString(adjusted));
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 54e46a0..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";
@@ -110,8 +121,7 @@ public class QuickSortTest
         "ALISON" };
     QuickSort.sort(values, things);
     assertTrue(Arrays.equals(new String[] { "lucy", "henry", "henry",
-        "JOHN",
-        "ALISON" }, values));
+        "JOHN", "ALISON" }, values));
     assertTrue(Arrays.equals(new Object[] { c3, c2, c4, c1, c5 }, things));
   }
 
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 735c75d..9cc4fc2 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.workers;
 
 import static org.testng.AssertJUnit.assertEquals;
@@ -14,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;
 
   /**
@@ -35,11 +65,9 @@ public class AlignCalcManagerTest
   {
     AlignCalcManagerI acm = alignFrame.getViewport().getCalcManager();
     final AlignmentAnnotation ann1 = new AlignmentAnnotation("Ann1",
-            "desc",
-            new Annotation[] {});
+            "desc", new Annotation[] {});
     final AlignmentAnnotation ann2 = new AlignmentAnnotation("Ann2",
-            "desc",
-            new Annotation[] {});
+            "desc", new Annotation[] {});
 
     /*
      * make two workers for ann1, one deletable, one not
@@ -68,7 +96,8 @@ public class AlignCalcManagerTest
       }
     }
 
-    List<AlignCalcWorkerI> workers = acm.getRegisteredWorkersOfClass(worker1.getClass());
+    List<AlignCalcWorkerI> workers = acm
+            .getRegisteredWorkersOfClass(worker1.getClass());
     assertEquals(2, workers.size());
     assertTrue(workers.contains(worker1));
     assertTrue(workers.contains(worker2));
@@ -119,8 +148,7 @@ public class AlignCalcManagerTest
       }
     };
     return new AnnotationWorker(alignFrame.getViewport(),
-            alignFrame.alignPanel,
-            annotationProvider)
+            alignFrame.alignPanel, annotationProvider)
     {
       @Override
       public boolean isDeletable()
index 1401f6a..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)
@@ -63,8 +72,7 @@ public class PDBSequenceFetcherTest
   @Test(groups = { "Network" }, enabled = true)
   public void testRnaSeqRetrieve() throws Exception
   {
-    Cache.applicationProperties.setProperty("PDB_DOWNLOAD_FORMAT",
-            "PDB");
+    Cache.applicationProperties.setProperty("PDB_DOWNLOAD_FORMAT", "PDB");
     List<DbSourceProxy> sps = sf.getSourceProxy("PDB");
     AlignmentI response = sps.get(0).getSequenceRecords("2GIS");
     assertTrue(response != null);
index 94bf979..32afd5f 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.ws;
 
 import jalview.analysis.CrossRef;
@@ -5,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;
 
@@ -12,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.
    * 
@@ -52,8 +82,7 @@ public class SequenceFetcherTest
           try
           {
             testRetrieval(argv[0], sp,
-                    argv.length > 1 ? argv[1] : sp
-                    .getTestQuery());
+                    argv.length > 1 ? argv[1] : sp.getTestQuery());
           } catch (Exception e)
           {
             e.printStackTrace();
index 72e599d..2f548d0 100644 (file)
 package jalview.ws.dbsources;
 
 import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertNull;
 
 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>"
@@ -46,6 +59,7 @@ public class UniprotTest
           + "<protein><recommendedName><fullName>Mitogen-activated protein kinase 13</fullName><fullName>Henry</fullName></recommendedName></protein>"
           + "<dbReference type=\"PDB\" id=\"2FSQ\"><property type=\"method\" value=\"X-ray\"/><property type=\"resolution\" value=\"1.40\"/></dbReference>"
           + "<dbReference type=\"PDBsum\" id=\"2FSR\"/>"
+          + "<dbReference type=\"EMBL\" id=\"AE007869\"><property type=\"protein sequence ID\" value=\"AAK85932.1\"/><property type=\"molecule type\" value=\"Genomic_DNA\"/></dbReference>"
           + "<feature type=\"signal peptide\" evidence=\"7\"><location><begin position=\"1\"/><end position=\"18\"/></location></feature>"
           + "<feature type=\"propeptide\" description=\"Activation peptide\" id=\"PRO_0000027399\" evidence=\"9 16 17 18\"><location><begin position=\"19\"/><end position=\"20\"/></location></feature>"
           + "<feature type=\"chain\" description=\"Granzyme B\" id=\"PRO_0000027400\"><location><begin position=\"21\"/><end position=\"247\"/></location></feature>"
@@ -109,19 +123,37 @@ public class UniprotTest
      * Check cross-references
      */
     Vector<PDBEntry> xrefs = entry.getDbReference();
-    assertEquals(2, xrefs.size());
+    assertEquals(3, xrefs.size());
 
     PDBEntry xref = xrefs.get(0);
     assertEquals("2FSQ", xref.getId());
     assertEquals("PDB", xref.getType());
-    assertEquals(2, xref.getProperty().size());
-    assertEquals("X-ray", xref.getProperty().get("method"));
-    assertEquals("1.40", xref.getProperty().get("resolution"));
+    assertEquals("X-ray", xref.getProperty("method"));
+    assertEquals("1.40", xref.getProperty("resolution"));
 
     xref = xrefs.get(1);
     assertEquals("2FSR", xref.getId());
     assertEquals("PDBsum", xref.getType());
-    assertNull(xref.getProperty());
+    assertFalse(xref.getProperties().hasMoreElements());
+
+    xref = xrefs.get(2);
+    assertEquals("AE007869", xref.getId());
+    assertEquals("EMBL", xref.getType());
+    assertEquals("AAK85932.1",
+ xref.getProperty("protein sequence ID"));
+    assertEquals("Genomic_DNA",
+ xref.getProperty("molecule type"));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetUniprotSequence()
+  {
+    UniprotEntry entry = new Uniprot().getUniprotEntries(
+            new StringReader(UNIPROT_XML)).get(0);
+    SequenceI seq = new Uniprot().uniprotEntryToSequenceI(entry);
+    assertNotNull(seq);
+    assertEquals(6, seq.getDBRefs().length); // 2*Uniprot, PDB, PDBsum, 2*EMBL
+
   }
 
   /**
@@ -149,7 +181,7 @@ public class UniprotTest
   {
     UniprotEntry entry = new Uniprot().getUniprotEntries(
             new StringReader(UNIPROT_XML)).get(0);
-  
+
     /*
      * recommended names concatenated with space separator
      */
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 4eaa5b1..40737ca 100644 (file)
@@ -1,12 +1,43 @@
+/*
+ * 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.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 2a111ee..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);
@@ -236,8 +246,8 @@ public class RNAStructExportImport
   public void testRnaalifoldSettingsRecovery()
   {
     List<Argument> opts = new ArrayList<Argument>();
-    for (Argument rg : (List<Argument>) rnaalifoldws
-            .getRunnerConfig().getArguments())
+    for (Argument rg : (List<Argument>) rnaalifoldws.getRunnerConfig()
+            .getArguments())
     {
       if (rg.getDescription().contains("emperature"))
       {
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 59bf445..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
    */
@@ -173,8 +181,7 @@ public class DbRefFetcherTest
                     sfs[0].getType()));
     assertEquals(embl.getDbSource(), sfs[0].getFeatureGroup());
     DBRefEntry[] dr = DBRefUtils.selectRefs(seq.getDBRefs(),
-            new String[] { DBRefSource.UNIPROT, DBRefSource.UNIPROTKB,
-                DBRefSource.EMBLCDSProduct, DBRefSource.ENSEMBL });
+            new String[] { DBRefSource.UNIPROT });
     assertNotNull(dr);
     assertEquals("Expected a single Uniprot cross reference", 1, dr.length);
     assertEquals("Expected cross reference map to be one amino acid", dr[0]
index 6f9a864..45c5412 100644 (file)
 package jalview.ws.sifts;
 
 import jalview.api.DBRefEntryI;
+import jalview.bin.Cache;
 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;
 
@@ -37,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;
 
@@ -46,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
@@ -67,7 +77,7 @@ public class SiftsClientTest
 
   @BeforeTest(alwaysRun = true)
   public void populateExpectedMapping() throws SiftsException
-   {
+  {
     expectedMapping.put(51, new int[] { 1, 2 });
     expectedMapping.put(52, new int[] { 2, 7 });
     expectedMapping.put(53, new int[] { 3, 12 });
@@ -165,11 +175,13 @@ public class SiftsClientTest
     expectedMapping.put(145, new int[] { 95, 714 });
     expectedMapping.put(146, new int[] { 96, 722 });
     expectedMapping.put(147, new int[] { 97, 729 });
-   }
-   
+  }
+
   @BeforeTest(alwaysRun = true)
   public void setUpSiftsClient() throws SiftsException
   {
+    // read test props before manipulating config
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
     // SIFTs entries are updated weekly - so use saved SIFTs file to enforce
     // test reproducibility
     new SiftsSettings();
@@ -182,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)
     {
@@ -233,7 +245,6 @@ public class SiftsClientTest
     }
   }
 
-
   @Test(groups = { "Functional" })
   public void getAllMappingAccessionTest()
   {
@@ -257,8 +268,7 @@ public class SiftsClientTest
     try
     {
       HashMap<Integer, int[]> actualMapping = siftsClient.getGreedyMapping(
-              "A", testSeq,
-              null);
+              "A", testSeq, null);
       Assert.assertEquals(testSeq.getStart(), 1);
       Assert.assertEquals(testSeq.getEnd(), 147);
       Assert.assertEquals(actualMapping, expectedMapping);
@@ -303,7 +313,7 @@ public class SiftsClientTest
   private void populateAtomPositionsNullTest1()
           throws IllegalArgumentException, SiftsException
   {
-      siftsClient.populateAtomPositions(null, null);
+    siftsClient.populateAtomPositions(null, null);
   }
 
   @Test(
@@ -337,7 +347,7 @@ public class SiftsClientTest
     expectedExceptions = SiftsException.class)
   public void getValidSourceDBRefExceptionTest() throws SiftsException
   {
-      SequenceI invalidTestSeq = new Sequence("testSeq", "ABCDEFGH");
+    SequenceI invalidTestSeq = new Sequence("testSeq", "ABCDEFGH");
     try
     {
       siftsClient.getValidSourceDBRef(invalidTestSeq);
@@ -386,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"
@@ -448,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)
     {
@@ -471,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);
+
+  }
 }
diff --git a/utils/BufferedLineReader.java b/utils/BufferedLineReader.java
new file mode 100644 (file)
index 0000000..b813fb2
--- /dev/null
@@ -0,0 +1,182 @@
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ * A file reader that concatenates lines
+ * 
+ * @author gmcarstairs
+ *
+ */
+public class BufferedLineReader
+{
+  interface LineCleaner
+  {
+    String cleanLine(String l);
+  }
+
+  /*
+   * a reader for the file being read
+   */
+  private BufferedReader br;
+  
+  /*
+   * optional handler to post-process each line as it is read
+   */
+  private LineCleaner cleaner;
+
+  /*
+   * current buffer of <bufferSize> post-processed input lines
+   */
+  private String[] buffer;
+
+  private boolean atEof;
+
+  /**
+   * Constructor
+   * 
+   * @param reader
+   * @param bufferSize
+   *          the number of lines to concatenate at a time while reading
+   * @param tidier
+   *          an optional callback handler to post-process each line after
+   *          reading
+   * @throws FileNotFoundException
+   */
+  public BufferedLineReader(BufferedReader reader, int bufferSize,
+          LineCleaner tidier)
+          throws IOException
+  {
+    br = reader;
+    buffer = new String[bufferSize];
+    cleaner = tidier;
+
+    /*
+     * load up the buffer with N-1 lines, ready for the first read
+     */
+    for (int i = 1; i < bufferSize; i++)
+    {
+      readLine();
+    }
+
+  }
+
+  /**
+   * Reads the next line from file, invokes the post-processor if one was
+   * provided, and returns the 'cleaned' line, or null at end of file.
+   * 
+   * @return
+   */
+  private String readLine() // throws IOException
+  {
+    if (atEof)
+    {
+      return null;
+    }
+
+    String line = null;
+    try
+    {
+      line = br.readLine();
+    } catch (IOException e)
+    {
+      e.printStackTrace();
+    }
+    if (line == null)
+    {
+      atEof = true;
+      return null;
+    }
+    if (cleaner != null)
+    {
+      line = cleaner.cleanLine(line);
+    }
+
+    /*
+     * shuffle down the lines buffer and add the new line
+     * in the last position
+     */
+    for (int i = 1; i < buffer.length; i++)
+    {
+      buffer[i - 1] = buffer[i];
+    }
+    buffer[buffer.length - 1] = line;
+    return line;
+  }
+
+  /**
+   * Returns a number of concatenated lines from the file, or null at end of
+   * file.
+   * 
+   * @return
+   */
+  public String read()
+  {
+    if (readLine() == null)
+    {
+      return null;
+    }
+    StringBuilder result = new StringBuilder(100 * buffer.length);
+    for (String line : buffer)
+    {
+      if (line != null)
+      {
+        result.append(line);
+      }
+    }
+    return result.toString();
+  }
+
+  /**
+   * A main 'test' method!
+   * 
+   * @throws IOException
+   */
+  public static void main(String[] args) throws IOException
+  {
+    String data = "Now is the winter\n" + "Of our discontent\n"
+            + "Made glorious summer\n" + "By this sun of York\n";
+    BufferedReader br = new BufferedReader(new StringReader(data));
+    BufferedLineReader reader = new BufferedLineReader(br, 3,
+            new LineCleaner()
+            {
+              @Override
+              public String cleanLine(String l)
+              {
+                return l.toUpperCase();
+              }
+            });
+    String line = reader.read();
+    String expect = "NOW IS THE WINTEROF OUR DISCONTENTMADE GLORIOUS SUMMER";
+    if (!line.equals(expect))
+    {
+      System.err.println("Fail: expected '" + expect + "', found '" + line
+              + ";");
+    }
+    else
+    {
+      System.out.println("Line one ok!");
+    }
+    line = reader.read();
+    expect = "OF OUR DISCONTENTMADE GLORIOUS SUMMERBY THIS SUN OF YORK";
+    if (!line.equals(expect))
+    {
+      System.err.println("Fail: expected '" + expect + "', found '" + line
+              + "'");
+    }
+    else
+    {
+      System.out.println("Line two ok!!");
+    }
+    line = reader.read();
+    if (line != null)
+    {
+      System.err.println("Fail: expected null at eof, got '" + line + "'");
+    }
+    else
+    {
+      System.out.println("EOF ok!!!");
+    }
+  }
+}
index 8085446..1279b31 100644 (file)
@@ -1,5 +1,23 @@
-
-
+/*
+ * 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.
+ */
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -16,7 +34,7 @@ import java.util.Map;
  * @author gmcarstairs
  *
  */
-public class HelpLinksChecker
+public class HelpLinksChecker implements BufferedLineReader.LineCleaner
 {
   private static final String HELP_HS = "help.hs";
 
@@ -159,9 +177,8 @@ public class HelpLinksChecker
         unusedTargets.remove(image);
         if (!tocTargets.containsKey(image))
         {
-          log(String.format(
-                  "Invalid image '%s' at line %d of %s", image, lineNo,
-                  HELP_HS));
+          log(String.format("Invalid image '%s' at line %d of %s", image,
+                  lineNo, HELP_HS));
           invalidImageCount++;
         }
       }
@@ -184,23 +201,18 @@ public class HelpLinksChecker
     log(unusedTargets.size() + " unused targets");
     for (String target : unusedTargets.keySet())
     {
-      log(String.format("    %s: %s", target,
-              unusedTargets.get(target)));
+      log(String.format("    %s: %s", target, unusedTargets.get(target)));
     }
     log(invalidMapUrlCount + " invalid map urls");
     log(invalidImageCount + " invalid image attributes");
-    log(String.format(
-            "%d internal href links (%d with anchors)", internalHrefCount,
-            anchorRefCount));
-    log(invalidInternalHrefCount
-            + " invalid internal href links");
-    log(invalidAnchorRefCount
-            + " invalid internal anchor links");
+    log(String.format("%d internal href links (%d with anchors)",
+            internalHrefCount, anchorRefCount));
+    log(invalidInternalHrefCount + " invalid internal href links");
+    log(invalidAnchorRefCount + " invalid internal anchor links");
     log(externalHrefCount + " external href links");
     if (internetAvailable)
     {
-      log(invalidExternalHrefCount
-              + " invalid external href links");
+      log(invalidExternalHrefCount + " invalid external href links");
     }
     else
     {
@@ -284,9 +296,8 @@ public class HelpLinksChecker
             {
               if (!checkAnchorExists(hrefFile, anchor))
               {
-                log(String.format(
-                        "Invalid anchor: %s at line %d of %s", anchor,
-                        lineNo, getPath(htmlFile)));
+                log(String.format("Invalid anchor: %s at line %d of %s",
+                        anchor, lineNo, getPath(htmlFile)));
                 invalidAnchorRefCount++;
               }
             }
@@ -294,9 +305,8 @@ public class HelpLinksChecker
         }
         if (badLink)
         {
-          log(String.format(
-                  "Invalid href %s at line %d of %s", href, lineNo,
-                  getPath(htmlFile)));
+          log(String.format("Invalid href %s at line %d of %s", href,
+                  lineNo, getPath(htmlFile)));
         }
       }
       data = br.readLine();
@@ -348,7 +358,8 @@ public class HelpLinksChecker
     try
     {
       BufferedReader br = new BufferedReader(new FileReader(hrefFile));
-      String data = br.readLine();
+      BufferedLineReader blr = new BufferedLineReader(br, 3, this);
+      String data = blr.read();
       while (data != null)
       {
         if (data.contains(nameAnchor) || data.contains(idAnchor))
@@ -356,7 +367,7 @@ public class HelpLinksChecker
           found = true;
           break;
         }
-        data = br.readLine();
+        data = blr.read();
       }
       br.close();
     } catch (IOException e)
@@ -455,9 +466,8 @@ public class HelpLinksChecker
         }
         if (!new File(helpFolder, url).exists())
         {
-          log(String.format(
-                  "Invalid url path '%s' at line %d of %s", url, lineNo,
-                  HELP_JHM));
+          log(String.format("Invalid url path '%s' at line %d of %s", url,
+                  lineNo, HELP_JHM));
           invalidMapUrlCount++;
         }
       }
@@ -498,9 +508,8 @@ public class HelpLinksChecker
         unusedTargets.remove(target);
         if (!tocTargets.containsKey(target))
         {
-          log(String.format(
-                  "Invalid target '%s' at line %d of %s", target, lineNo,
-                  HELP_TOC_XML));
+          log(String.format("Invalid target '%s' at line %d of %s", target,
+                  lineNo, HELP_TOC_XML));
           invalidTargetCount++;
         }
       }
@@ -536,4 +545,14 @@ public class HelpLinksChecker
     }
     return value;
   }
+
+  /**
+   * Trim whitespace from concatenated lines but preserve one space for valid
+   * parsing
+   */
+  @Override
+  public String cleanLine(String l)
+  {
+    return l.trim() + " ";
+  }
 }
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>
index 76375d6..5518e13 100644 (file)
@@ -36,7 +36,6 @@
 //========================================================================
 //
 
-
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.handler.DefaultHandler;
@@ -70,16 +69,15 @@ public class JettyExamplesDir
     // In this example it is the current directory but it can be configured to
     // anything that the jvm has access to.
     resource_handler.setDirectoriesListed(true);
-    resource_handler.setWelcomeFiles(new String[]
-    { "applets.html" });
+    resource_handler.setWelcomeFiles(new String[] { "applets.html" });
     resource_handler.setResourceBase(".");
 
     // Add the ResourceHandler to the server.
     // GzipHandler gzip = new GzipHandler();
     // server.setHandler(gzip);
     HandlerList handlers = new HandlerList();
-    handlers.setHandlers(new Handler[]
-    { resource_handler, new DefaultHandler() });
+    handlers.setHandlers(new Handler[] { resource_handler,
+        new DefaultHandler() });
     server.setHandler(handlers);
 
     // Start things up! By using the server.join() the server thread will join
@@ -89,5 +87,5 @@ public class JettyExamplesDir
     // for more details.
     server.start();
     server.join();
-}
+  }
 }
index 9d322df..4489a93 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * 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.
+ */
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -20,7 +40,7 @@ import java.util.regex.Pattern;
  * @author gmcarstairs
  *
  */
-public class MessageBundleChecker
+public class MessageBundleChecker implements BufferedLineReader.LineCleaner
 {
   /*
    * regex ^"[^"]*"$
@@ -192,64 +212,37 @@ public class MessageBundleChecker
       return;
     }
 
-    String[] lines = new String[bufferSize];
     BufferedReader br = new BufferedReader(new FileReader(f));
-    for (int i = 0; i < bufferSize; i++)
-    {
-      String readLine = br.readLine();
-      lines[i] = stripCommentsAndTrim(readLine);
-    }
+    BufferedLineReader blr = new BufferedLineReader(br, bufferSize, this);
 
     int lineNo = 0;
-
-    while (lines[bufferSize - 1] != null)
+    String line = blr.read();
+    while (line != null)
     {
       lineNo++;
-      inspectSourceLines(path, lineNo, lines);
-
-      for (int i = 0; i < bufferSize - 1; i++)
-      {
-        lines[i] = lines[i + 1];
-      }
-      lines[bufferSize - 1] = stripCommentsAndTrim(br.readLine());
+      inspectSourceLines(path, lineNo, line);
+      line = blr.read();
     }
     br.close();
 
   }
 
-  /*
-   * removes anything after (and including) '//'
-   */
-  private String stripCommentsAndTrim(String line)
-  {
-    if (line != null)
-    {
-      int pos = line.indexOf("//");
-      if (pos != -1)
-      {
-        line = line.substring(0, pos);
-      }
-      line = line.replace("\t", " ").trim();
-    }
-    return line;
-  }
-
   /**
    * Look for calls to MessageManager methods, possibly split over two or more
-   * lines
+   * lines that have been concatenated while parsing the file
    * 
    * @param path
    * @param lineNo
-   * @param lines
+   * @param line
    */
-  private void inspectSourceLines(String path, int lineNo, String[] lines)
+  private void inspectSourceLines(String path, int lineNo, String line)
   {
-    String lineNos = String.format("%d-%d", lineNo, lineNo + lines.length
+    String lineNos = String
+            .format("%d-%d", lineNo, lineNo + bufferSize
             - 1);
-    String combined = combineLines(lines);
     for (String method : METHODS)
     {
-      int pos = combined.indexOf(method);
+      int pos = line.indexOf(method);
       if (pos == -1)
       {
         continue;
@@ -258,7 +251,7 @@ public class MessageBundleChecker
       /*
        * extract what follows the opening bracket of the method call
        */
-      String methodArgs = combined.substring(pos + method.length()).trim();
+      String methodArgs = line.substring(pos + method.length()).trim();
       if ("".equals(methodArgs))
       {
         /*
@@ -285,7 +278,7 @@ public class MessageBundleChecker
       if (METHOD3 == method)
       {
         System.out.println(String.format("Dynamic key at %s line %s %s",
-                path.substring(sourcePath.length()), lineNos, combined));
+                path.substring(sourcePath.length()), lineNos, line));
         continue;
       }
 
@@ -293,14 +286,14 @@ public class MessageBundleChecker
       if (messageKey == null)
       {
         System.out.println(String.format("Trouble parsing %s line %s %s",
-                path.substring(sourcePath.length()), lineNos, combined));
+                path.substring(sourcePath.length()), lineNos, line));
         continue;
       }
 
       if (!(STRING_PATTERN.matcher(messageKey).matches()))
       {
         System.out.println(String.format("Dynamic key at %s line %s %s",
-                path.substring(sourcePath.length()), lineNos, combined));
+                path.substring(sourcePath.length()), lineNos, line));
         continue;
       }
 
@@ -364,22 +357,6 @@ public class MessageBundleChecker
     return endPos == -1 ? null : key.substring(0, endPos);
   }
 
-  private String combineLines(String[] lines)
-  {
-    String combined = "";
-    if (lines != null)
-    {
-      for (String line : lines)
-      {
-        if (line != null)
-        {
-          combined += line;
-        }
-      }
-    }
-    return combined;
-  }
-
   /**
    * Loads properties from Message.properties
    * 
@@ -401,4 +378,22 @@ public class MessageBundleChecker
 
   }
 
+  /**
+   * Remove any trailing comments, change tabs to space, and trim
+   */
+  @Override
+  public String cleanLine(String l)
+  {
+    if (l != null)
+    {
+      int pos = l.indexOf("//");
+      if (pos != -1)
+      {
+        l = l.substring(0, pos);
+      }
+      l = l.replace("\t", " ").trim();
+    }
+    return l;
+  }
+
 }
index 98747f7..8496f8b 100644 (file)
@@ -28,28 +28,32 @@ import java.util.jar.JarInputStream;
 
 public class getJavaVersion
 {
-/**
- * Takes a set of Jars and/or class files as arguments. Reports the java version for the classes
- */
+  /**
+   * Takes a set of Jars and/or class files as arguments. Reports the java
+   * version for the classes
+   */
 
   public static void main(String[] args) throws IOException
   {
-    Hashtable observed=new Hashtable();
+    Hashtable observed = new Hashtable();
     for (int i = 0; i < args.length; i++)
-      {
-        checkClassVersion(args[i], observed);
-      }
+    {
+      checkClassVersion(args[i], observed);
+    }
     printVersions(observed, System.out);
   }
-  public static void printVersions(Hashtable observed, java.io.PrintStream outs)
+
+  public static void printVersions(Hashtable observed,
+          java.io.PrintStream outs)
   {
-    if (observed.size()>0)
+    if (observed.size() > 0)
     {
-      int space=0;
-      String key=null;
-      for (Enumeration keys = observed.keys(); keys.hasMoreElements(); ) {
+      int space = 0;
+      String key = null;
+      for (Enumeration keys = observed.keys(); keys.hasMoreElements();)
+      {
         key = (String) keys.nextElement();
-        if (space++>0)
+        if (space++ > 0)
         {
           outs.print(" ");
         }
@@ -65,13 +69,13 @@ public class getJavaVersion
     String version = checkClassVersion(filename);
     if (version == null)
     {
-//      System.err.println("Reading "+filename+" as  jar:");
+      // System.err.println("Reading "+filename+" as  jar:");
       try
       {
         JarInputStream jis = new JarInputStream(new FileInputStream(
                 filename));
         JarEntry entry;
-        Hashtable perjar=new Hashtable();
+        Hashtable perjar = new Hashtable();
         while ((entry = jis.getNextJarEntry()) != null)
         {
           if (entry != null)
@@ -93,8 +97,8 @@ public class getJavaVersion
             }
           }
         }
-        System.err.println("Jar : "+filename);
-        printVersions(perjar,System.err);
+        System.err.println("Jar : " + filename);
+        printVersions(perjar, System.err);
       } catch (Exception e)
       {
 
@@ -110,12 +114,11 @@ public class getJavaVersion
   {
     if (version != null)
     {
-//      System.err.println("Version is '"+version+"'");
+      // System.err.println("Version is '"+version+"'");
       int[] vrs = (int[]) observed.get(version);
       if (vrs == null)
       {
-        vrs = new int[]
-        { 0 };
+        vrs = new int[] { 0 };
       }
       vrs[0]++;
       observed.put(version, vrs);
@@ -147,14 +150,13 @@ public class getJavaVersion
       versions.put("52.0", "1.8");
 
     }
-    String version = (String) versions.get(major + "."
-            + minor);
+    String version = (String) versions.get(major + "." + minor);
     if (version == null)
     {
       // get nearest known version
       version = (String) versions.get(major + ".0");
     }
-//    System.err.println("Version "+version);
+    // System.err.println("Version "+version);
     if (version == null)
     {
       versions.put(major + "." + minor, "Class v" + major + ".0");
@@ -171,7 +173,7 @@ public class getJavaVersion
     }
     int minor = in.readUnsignedShort();
     int major = in.readUnsignedShort();
-//    System.err.println("Version "+major+"."+minor);
+    // System.err.println("Version "+major+"."+minor);
     return parseVersions(minor, major);
   }
 
index e9e9ce7..83e4b5f 100755 (executable)
@@ -24,93 +24,87 @@ import java.util.*;
 public class help2Website
 {
 
-       public static void main(String [] args)
-       {
-               String line = "";
-               try{
-                       Hashtable targets = new Hashtable();
+  public static void main(String[] args)
+  {
+    String line = "";
+    try
+    {
+      Hashtable targets = new Hashtable();
 
-                       File toc = new File("helpTOC.xml");
-                       File jhm = new File("help.jhm");
+      File toc = new File("helpTOC.xml");
+      File jhm = new File("help.jhm");
 
-                       BufferedReader in = new BufferedReader(new FileReader(jhm));
+      BufferedReader in = new BufferedReader(new FileReader(jhm));
 
-                       PrintWriter out = new PrintWriter(new FileWriter("helpTOC.html"));
-                       out.println("<html><head><title>Jalview - Help </title></head>\n"
-                       +"<body bgcolor=#F1F1F1>\n"
-                       +"<p><center><strong>Contents</strong></center></p>\n");
+      PrintWriter out = new PrintWriter(new FileWriter("helpTOC.html"));
+      out.println("<html><head><title>Jalview - Help </title></head>\n"
+              + "<body bgcolor=#F1F1F1>\n"
+              + "<p><center><strong>Contents</strong></center></p>\n");
 
+      StringTokenizer st;
+      StringBuffer indent = new StringBuffer();
+      String target, url, text;
+      while ((line = in.readLine()) != null)
+      {
+        if (line.indexOf("target") == -1)
+          continue;
 
-                       StringTokenizer st;
-                       StringBuffer indent = new StringBuffer();
-                       String target, url, text;
-                       while( (line = in.readLine()) != null)
-                       {
-                               if(line.indexOf("target")==-1)
-                                       continue;
+        st = new StringTokenizer(line, "\"");
+        st.nextToken(); // <mapID target="
 
+        target = st.nextToken();
+        st.nextToken(); // " url="
 
-                               st = new StringTokenizer(line, "\"");
-                               st.nextToken(); //<mapID target="
+        url = st.nextToken();
+        targets.put(target, url);
+      }
 
-                               target = st.nextToken();
-                               st.nextToken(); //" url="
+      in = new BufferedReader(new FileReader(toc));
+      while ((line = in.readLine()) != null)
+      {
+        if (line.indexOf("</tocitem>") != -1)
+          indent.setLength(indent.length() - 18);
 
-                               url = st.nextToken();
-                               targets.put(target, url);
-                       }
+        if (line.indexOf("<tocitem") == -1)
+          continue;
 
-                       in = new BufferedReader(new FileReader(toc));
-                       while( (line = in.readLine()) != null)
-                       {
-                               if(line.indexOf("</tocitem>")!=-1)
-                                       indent.setLength(indent.length()-18);
+        st = new StringTokenizer(line, "\"");
+        st.nextToken();
 
-                               if(line.indexOf("<tocitem")==-1)
-                                       continue;
+        text = st.nextToken();
+        st.nextToken();
 
-                               st = new StringTokenizer(line, "\"");
-                               st.nextToken();
+        target = st.nextToken();
 
-                               text = st.nextToken();
-                               st.nextToken();
+        if (targets.get(target) != null)
+        {
+          out.println("<br>" + indent + "<a href=\"" + targets.get(target)
+                  + "\" target=bodyframe>" + text + "</a>");
+        }
+        else
+          out.println("<br>" + indent + text);
 
-                               target = st.nextToken();
+        if (line.indexOf("/>") == -1)
+          indent.append("&nbsp;&nbsp;&nbsp;");
 
-                               if(targets.get(target)!=null)
-                               {
-                                       out.println("<br>"+indent+"<a href=\""
-                                                       + targets.get(target)
-                                                       +"\" target=bodyframe>"
-                                                       +text
-                                                       +"</a>");
-                               }
-                               else
-                                       out.println("<br>"+indent+text);
+      }
+      // Add Googletracker.
 
+      out.close();
 
-                               if(line.indexOf("/>")==-1)
-                                       indent.append("&nbsp;&nbsp;&nbsp;");
+    }
 
-                       }
-                       // Add Googletracker.
+    catch (Exception ex)
+    {
 
+      ex.printStackTrace();
 
-                       out.close();
-
-               }
-
-               catch(Exception ex)
-               {
-
-                       ex.printStackTrace();
-
-                       System.out.println("\n"+line+"\n");
-
-                       System.out.println("Usage: move to Help directory. help2Website will read"
-                       +"\nhelpTOC.xml and help.jhm producing output helpTOC.html");
-               }
-       }
+      System.out.println("\n" + line + "\n");
 
+      System.out
+              .println("Usage: move to Help directory. help2Website will read"
+                      + "\nhelpTOC.xml and help.jhm producing output helpTOC.html");
+    }
+  }
 
 }