From ae19c8ca2b69263aaa59b40da06b521fec3d3afb Mon Sep 17 00:00:00 2001 From: Aleix Lafita Date: Thu, 29 Jun 2017 16:03:42 -0700 Subject: [PATCH 001/769] Organize the MMTF tests --- .../io/mmtf/MmtfStructureReader.java | 2 + .../io/mmtf/MmtfStructureWriter.java | 5 +- .../structure/io/mmtf/TestBondFinding.java | 24 +- .../io/mmtf/TestMmtfPerformance.java | 19 +- .../structure/io/mmtf/TestMmtfRoundTrip.java | 21 +- .../io/mmtf/TestMmtfStructureReader.java | 65 + ...Mmtf.java => TestMmtfStructureWriter.java} | 55 +- .../nbio/structure/io/mmtf/TestMmtfUtils.java | 6 +- .../biojava/nbio/structure/io/mmtf/4CUP.cif | 3305 +++++++++++++++++ 9 files changed, 3449 insertions(+), 53 deletions(-) create mode 100644 biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java rename biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/{TestBasicMmtf.java => TestMmtfStructureWriter.java} (67%) create mode 100644 biojava-structure/src/test/resources/org/biojava/nbio/structure/io/mmtf/4CUP.cif diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java index 961a5a483f..7eb07e806a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java @@ -47,6 +47,8 @@ * Should be ported to biojava code. * * @author Anthony Bradley + * @since 5.0 + * */ public class MmtfStructureReader implements StructureAdapterInterface, Serializable { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java index f8a2d13672..b47b2b1dcb 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java @@ -19,14 +19,15 @@ import org.rcsb.mmtf.dataholders.MmtfStructure; /** - * Class to take Biojava structure data and covert to the DataApi for encoding. + * Class to take Biojava structure data and covert to the DataApi for encoding. * Must implement all the functions in {@link StructureAdapterInterface}. + * * @author Anthony Bradley + * @since 5.0 * */ public class MmtfStructureWriter { - private StructureAdapterInterface mmtfDecoderInterface; /** diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java index 38ac99899b..e5580c4c94 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java @@ -21,37 +21,46 @@ /** * Test bond finding in BioJava + * * @author Anthony Bradley * */ public class TestBondFinding { /** - * Test that the bonds we are finding is consistenty. + * Test that the bonds we are finding are consistent. + * * @throws IOException * @throws StructureException */ @Test public void testInterGroupBonds() throws IOException, StructureException { + // Normal assertEquals(2236, getInterBonds("1QMZ")); + // Disulphide assertEquals(956, getInterBonds("2QWO")); + // Covalent ligand assertEquals(2294, getInterBonds("4QDV")); + // DNA assertEquals(22, getInterBonds("4XSN")); } /** - * Find all of the inter group bonds in a structure + * Find all of the inter group bonds in a structure. + * * @param pdbId the pdb id of the structure to determine * @return the number of inter group bonds (double counted) in a structure * @throws IOException * @throws StructureException */ - public int getInterBonds(String pdbId) throws IOException, StructureException{ + public int getInterBonds(String pdbId) throws IOException, StructureException { + + // Download parameters AtomCache cache = new AtomCache(); cache.setUseMmCif(true); cache.setFetchBehavior(FetchBehavior.FETCH_FILES); @@ -64,10 +73,13 @@ public int getInterBonds(String pdbId) throws IOException, StructureException{ dcc.checkDoFirstInstall(); cache.setFileParsingParams(params); StructureIO.setAtomCache(cache); - int counter =0; - // Now get the structure + + // Get the structure Structure newStruc = StructureIO.getStructure(pdbId); - // Now loop through the atoms + + int counter =0; + + // Loop through the atoms and count the bonds for(Chain c: newStruc.getChains()){ for(Group g: c.getAtomGroups()){ List theseAtoms = g.getAtoms(); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfPerformance.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfPerformance.java index 2f7b9cbe65..823ff20236 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfPerformance.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfPerformance.java @@ -1,31 +1,23 @@ package org.biojava.nbio.structure.io.mmtf; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureIO; -import org.biojava.nbio.structure.TestStructureCrossReferences; import org.biojava.nbio.structure.io.PDBFileParser; -import org.biojava.nbio.structure.io.mmcif.AllChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.ChemCompProvider; import org.junit.Test; -import org.rcsb.mmtf.dataholders.MmtfStructure; -import org.rcsb.mmtf.decoder.ReaderUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.zip.GZIPInputStream; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; /** - * Created by andreas on 1/9/17. + * Test the performance of MMTF format in BioJava. + * + * @author Andreas Prlic + * on 1/9/17. + * */ public class TestMmtfPerformance { @@ -35,6 +27,7 @@ public class TestMmtfPerformance { // Returns the contents of the file in a byte array. public static byte[] getBytesFromFile(File file) throws IOException { + // Get the size of the file long length = file.length(); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java index e3ef070731..d22fae960d 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java @@ -24,6 +24,7 @@ /** * Tests to see if roundtripping of MMTF can be done. + * * @author Anthony Bradley * */ @@ -31,22 +32,29 @@ public class TestMmtfRoundTrip { /** * Test that we can round trip a simple structure. + * * @throws IOException an error reading the file * @throws StructureException an error parsing the structure */ @Test public void testRoundTrip() throws IOException, StructureException { + + // Load a structure in MMCIF format AtomCache cache = new AtomCache(); cache.setUseMmCif(true); ChemCompGroupFactory.setChemCompProvider(new DownloadChemCompProvider()); - StructureIO.setAtomCache(cache); Structure structure = StructureIO.getStructure("4CUP"); + + // Write the structure to a MMTF encoding AdapterToStructureData writerToEncoder = new AdapterToStructureData(); new MmtfStructureWriter(structure, writerToEncoder); + + // Load back the structure from the MMTF encoding MmtfStructureReader mmtfStructureReader = new MmtfStructureReader(); new StructureDataToAdapter(writerToEncoder, mmtfStructureReader); + assertTrue(checkIfAtomsSame(structure,mmtfStructureReader.getStructure())); } @@ -58,18 +66,23 @@ public void testRoundTrip() throws IOException, StructureException { * @return */ private boolean checkIfAtomsSame(Structure structOne, Structure structTwo) { + + // Check the same number of models int numModels = structOne.nrModels(); if(numModels!=structTwo.nrModels()){ System.out.println("Error - diff number models: "+structOne.getPDBCode()); return false; } + for(int i=0;i chainsOne = structOne.getChains(i); List chainsTwo = structTwo.getChains(i); if(chainsOne.size()!=chainsTwo.size()){ System.out.println("Error - diff number chains: "+structOne.getPDBCode()); return false; } + // Now make sure they're sorted in the right order sortChains(chainsOne, chainsTwo); // Check that each one has the same number of poly, non-poly and water chains @@ -182,8 +195,9 @@ else if(atomOne.getBonds().size()!=atomTwo.getBonds().size()){ } return true; } + /** - * Check both structures have the same number of poly,non-poly and water chains + * Check both structures have the same number of poly, non-poly and water chains * @param structOne the first structure * @param structTwo the second structure * @param i the model index @@ -193,8 +207,10 @@ private void checkDiffChains(Structure structOne, Structure structTwo, int i) { assertEquals(structOne.getNonPolyChains(i).size(), structTwo.getNonPolyChains(i).size()); assertEquals(structOne.getWaterChains(i).size(), structTwo.getWaterChains(i).size()); } + /** * Sort the atom based on PDB serial id + * * @param atomsOne the first list * @param atomsTwo the second list */ @@ -227,6 +243,7 @@ public int compare(Atom o1, Atom o2) { /** * Sort the chains based on chain id. + * * @param chainsOne the first list of chains * @param chainsTwo the second list of chains */ diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java new file mode 100644 index 0000000000..0f797bc55a --- /dev/null +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java @@ -0,0 +1,65 @@ +package org.biojava.nbio.structure.io.mmtf; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.nio.file.Paths; +import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureIO; +import org.junit.Test; + +/** + * Test the Biojava MMTF reader. + * + * @author Anthony Bradley + * @author Aleix Lafita + * + */ +public class TestMmtfStructureReader { + + /** + * Test reading an MMTF file into a BioJava structure. + */ + @Test + public void testRead() throws IOException { + + // Get the MMTF file from the resources folder + ClassLoader classLoader = getClass().getClassLoader(); + String resource = "org/biojava/nbio/structure/io/mmtf/4CUP.mmtf"; + + // Load the structure into memory + Structure structure = MmtfActions.readFromFile(( + Paths.get(classLoader.getResource(resource).getPath()))); + + // Check header properties of the structure + assertEquals(structure.getPDBCode(), "4CUP"); + assertEquals(MmtfUtils.dateToIsoString(structure.getPDBHeader().getDepDate()), + "2014-03-21"); + + assertEquals(structure.getChains().size(), 6); + } + + /** + * Compare structures loaded from MMCIF and MMTF files. + */ + @Test + public void compareMmcif() throws IOException, StructureException { + + // Get the MMTF and MMCIF files from the resources folder + ClassLoader classLoader = getClass().getClassLoader(); + String resource = "org/biojava/nbio/structure/io/mmtf/4CUP"; + + // Load the structures into memory + Structure mmtf = StructureIO.getStructure(classLoader.getResource(resource).getPath() + ".mmtf"); + Structure mmcif = StructureIO.getStructure(classLoader.getResource(resource).getPath() + ".mmcif"); + + // Compare the SEQRES + assertEquals(mmcif.getChain("A").getSeqResSequence(), + mmtf.getChain("A").getSeqResSequence()); + + + + } + +} diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBasicMmtf.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureWriter.java similarity index 67% rename from biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBasicMmtf.java rename to biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureWriter.java index 5e91ff195e..0f7178abc4 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBasicMmtf.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureWriter.java @@ -1,10 +1,7 @@ package org.biojava.nbio.structure.io.mmtf; -import static org.junit.Assert.assertEquals; - import java.io.File; import java.io.IOException; -import java.nio.file.Paths; import java.util.ArrayList; import org.biojava.nbio.structure.AminoAcidImpl; @@ -25,63 +22,65 @@ import org.junit.rules.TemporaryFolder; /** - * Test that Biojava can read and write MMTF data. + * Test the Biojava MMTF writer. + * * @author Anthony Bradley + * @author Aleix Lafita * */ -public class TestBasicMmtf { +public class TestMmtfStructureWriter { - /** - * A test folder for testing writing files. - */ - @Rule - public TemporaryFolder testFolder = new TemporaryFolder(); - - - /** - * Test that Biojava can read a file from the file system. - * @throws IOException - */ - @Test - public void testRead() throws IOException { - ClassLoader classLoader = getClass().getClassLoader(); - Structure structure = MmtfActions.readFromFile((Paths.get(classLoader.getResource("org/biojava/nbio/structure/io/mmtf/4CUP.mmtf").getPath()))); - assertEquals(structure.getPDBCode(),"4CUP"); - assertEquals(structure.getChains().size(),6); - } + @Rule + public TemporaryFolder testFolder = new TemporaryFolder(); /** * Test the writing of Structure objects to a file. - * @throws IOException + * + * @throws IOException */ @Test public void testWrite() throws IOException { + + // Create a structure Structure structure = new StructureImpl(); + + // Add some header information PDBHeader pdbHeader = new PDBHeader(); pdbHeader.setExperimentalTechnique("X-RAY DIFFRACTION"); - structure.setEntityInfos(new ArrayList()); structure.setPDBHeader(pdbHeader); + + // Create one chain + structure.setEntityInfos(new ArrayList()); Chain chain = new ChainImpl(); chain.setId("A"); chain.setName("A"); - Group group = new AminoAcidImpl(); + + // Create one group + Group group = new AminoAcidImpl(); group.setPDBName("FKF"); ChemComp chemComp = new ChemComp(); chemComp.setType("TYPfdl"); chemComp.setOne_letter_code("A"); group.setChemComp(chemComp); + + // Create one Atom Atom atom = new AtomImpl(); atom.setName("A"); atom.setElement(Element.Ag); - atom.setCoords(new double[] {1.0,2.0,3.0}); + atom.setCoords(new double[] { 1.0, 2.0, 3.0 }); + + // Link together the objects chain.addGroup(group); group.addAtom(atom); + ResidueNumber residueNumber = new ResidueNumber(); residueNumber.setInsCode('A'); residueNumber.setSeqNum(100); group.setResidueNumber(residueNumber); + structure.addChain(chain); + File tempFile = testFolder.newFile("tmpfile"); - MmtfActions.writeToFile(structure, tempFile.toPath()); + MmtfActions.writeToFile(structure, tempFile.toPath()); } } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfUtils.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfUtils.java index af0db75615..3e5e2021df 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfUtils.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfUtils.java @@ -1,6 +1,5 @@ package org.biojava.nbio.structure.io.mmtf; - import org.junit.Test; import static org.junit.Assert.*; @@ -38,8 +37,10 @@ import org.biojava.nbio.structure.xtal.BravaisLattice; import org.biojava.nbio.structure.xtal.CrystalCell; import org.biojava.nbio.structure.xtal.SpaceGroup; + /** - * Test the MMTF utils class + * Test the MMTF utils class. + * * @author Anthony Bradley * */ @@ -47,6 +48,7 @@ public class TestMmtfUtils { /** * Integration test to see that the microheterogenity is being dealt with correctly. + * * @throws IOException * @throws StructureException */ diff --git a/biojava-structure/src/test/resources/org/biojava/nbio/structure/io/mmtf/4CUP.cif b/biojava-structure/src/test/resources/org/biojava/nbio/structure/io/mmtf/4CUP.cif new file mode 100644 index 0000000000..3f88049aa2 --- /dev/null +++ b/biojava-structure/src/test/resources/org/biojava/nbio/structure/io/mmtf/4CUP.cif @@ -0,0 +1,3305 @@ +data_4CUP +# +_entry.id 4CUP +# +_audit_conform.dict_name mmcif_pdbx.dic +_audit_conform.dict_version 4.040 +_audit_conform.dict_location http://mmcif.pdb.org/dictionaries/ascii/mmcif_pdbx.dic +# +loop_ +_database_2.database_id +_database_2.database_code +PDB 4CUP +PDBE EBI-60082 +# +_database_PDB_rev.num 1 +_database_PDB_rev.date 2014-04-02 +_database_PDB_rev.date_original 2014-03-21 +_database_PDB_rev.status ? +_database_PDB_rev.replaces 4CUP +_database_PDB_rev.mod_type 0 +# +loop_ +_pdbx_database_related.db_name +_pdbx_database_related.db_id +_pdbx_database_related.content_type +_pdbx_database_related.details +PDB 4CUQ unspecified 'CRYSTAL STRUCTURE OF HUMAN BAZ2B IN COMPLEX WITH FRAGMENT-2 N09594' +PDB 4CUR unspecified 'CRYSTAL STRUCTURE OF HUMAN BAZ2B IN COMPLEX WITH FRAGMENT-3 N09555' +PDB 4CUS unspecified 'CRYSTAL STRUCTURE OF HUMAN BAZ2B IN COMPLEX WITH FRAGMENT-4 N09496' +PDB 4CUT unspecified 'CRYSTAL STRUCTURE OF HUMAN BAZ2B IN COMPLEX WITH FRAGMENT-5 N09428' +PDB 4CUU unspecified 'CRYSTAL STRUCTURE OF HUMAN BAZ2B IN COMPLEX WITH FRAGMENT-6 N09645' +# +_pdbx_database_status.status_code REL +_pdbx_database_status.entry_id 4CUP +_pdbx_database_status.deposit_site PDBE +_pdbx_database_status.process_site PDBE +_pdbx_database_status.SG_entry . +# +loop_ +_audit_author.name +_audit_author.pdbx_ordinal +'Bradley, A.R.' 1 +'Liu, Y.' 2 +'Krojer, T.' 3 +'Bountra, C.' 4 +'Arrowsmith, C.H.' 5 +'Edwards, A.' 6 +'Knapp, S.' 7 +'von Delft, F.' 8 +# +_citation.id primary +_citation.title 'Crystal Structure of Human Baz2B in Complex with Fragment-1 N09421' +_citation.journal_abbrev 'To be Published' +_citation.journal_volume ? +_citation.page_first ? +_citation.page_last ? +_citation.year ? +_citation.journal_id_ASTM ? +_citation.country ? +_citation.journal_id_ISSN ? +_citation.journal_id_CSD 0353 +_citation.book_publisher ? +_citation.pdbx_database_id_PubMed ? +_citation.pdbx_database_id_DOI ? +# +loop_ +_citation_author.citation_id +_citation_author.name +_citation_author.ordinal +primary 'R Bradley, A.' 1 +primary 'Liu, Y.' 2 +primary 'Krojer, T.' 3 +primary 'Bountra, C.' 4 +primary 'Arrowsmith, C.H.' 5 +primary 'Edwards, A.' 6 +primary 'Knapp, S.' 7 +primary 'Von Delft, F.' 8 +# +_cell.entry_id 4CUP +_cell.length_a 80.370 +_cell.length_b 96.120 +_cell.length_c 57.670 +_cell.angle_alpha 90.00 +_cell.angle_beta 90.00 +_cell.angle_gamma 90.00 +_cell.Z_PDB 8 +_cell.pdbx_unique_axis ? +# +_symmetry.entry_id 4CUP +_symmetry.space_group_name_H-M 'C 2 2 21' +_symmetry.pdbx_full_space_group_name_H-M ? +_symmetry.cell_setting ? +_symmetry.Int_Tables_number ? +# +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 'BROMODOMAIN ADJACENT TO ZINC FINGER DOMAIN PROTEIN 2B' 13618.761 1 ? ? 'BROMODOMAIN, RESIDUES 1858-1972' ? +2 non-polymer syn 4-FLUOROBENZAMIDOXIME 154.144 1 ? ? ? ? +3 non-polymer syn METHANOL 32.042 3 ? ? ? ? +4 water nat water 18.015 146 ? ? ? ? +# +loop_ +_entity_keywords.entity_id +_entity_keywords.text +1 ? +2 ? +3 ? +4 ? +# +loop_ +_entity_name_com.entity_id +_entity_name_com.name +1 'HWALP4, BAZ2B' +2 ? +3 ? +4 ? +# +_entity_poly.entity_id 1 +_entity_poly.type 'polypeptide(L)' +_entity_poly.nstd_linkage no +_entity_poly.nstd_monomer no +_entity_poly.pdbx_seq_one_letter_code +;SMSVKKPKRDDSKDLALCSMILTEMETHEDAWPFLLPVNLKLVPGYKKVIKKPMDFSTIREKLSSGQYPNLETFALDVRL +VFDNCETFNEDDSDIGRAGHNMRKYFEKKWTDTFKVS +; +_entity_poly.pdbx_seq_one_letter_code_can +;SMSVKKPKRDDSKDLALCSMILTEMETHEDAWPFLLPVNLKLVPGYKKVIKKPMDFSTIREKLSSGQYPNLETFALDVRL +VFDNCETFNEDDSDIGRAGHNMRKYFEKKWTDTFKVS +; +_entity_poly.pdbx_strand_id A +# +loop_ +_entity_poly_seq.entity_id +_entity_poly_seq.num +_entity_poly_seq.mon_id +_entity_poly_seq.hetero +1 1 SER n +1 2 MET n +1 3 SER n +1 4 VAL n +1 5 LYS n +1 6 LYS n +1 7 PRO n +1 8 LYS n +1 9 ARG n +1 10 ASP n +1 11 ASP n +1 12 SER n +1 13 LYS n +1 14 ASP n +1 15 LEU n +1 16 ALA n +1 17 LEU n +1 18 CYS n +1 19 SER n +1 20 MET n +1 21 ILE n +1 22 LEU n +1 23 THR n +1 24 GLU n +1 25 MET n +1 26 GLU n +1 27 THR n +1 28 HIS n +1 29 GLU n +1 30 ASP n +1 31 ALA n +1 32 TRP n +1 33 PRO n +1 34 PHE n +1 35 LEU n +1 36 LEU n +1 37 PRO n +1 38 VAL n +1 39 ASN n +1 40 LEU n +1 41 LYS n +1 42 LEU n +1 43 VAL n +1 44 PRO n +1 45 GLY n +1 46 TYR n +1 47 LYS n +1 48 LYS n +1 49 VAL n +1 50 ILE n +1 51 LYS n +1 52 LYS n +1 53 PRO n +1 54 MET n +1 55 ASP n +1 56 PHE n +1 57 SER n +1 58 THR n +1 59 ILE n +1 60 ARG n +1 61 GLU n +1 62 LYS n +1 63 LEU n +1 64 SER n +1 65 SER n +1 66 GLY n +1 67 GLN n +1 68 TYR n +1 69 PRO n +1 70 ASN n +1 71 LEU n +1 72 GLU n +1 73 THR n +1 74 PHE n +1 75 ALA n +1 76 LEU n +1 77 ASP n +1 78 VAL n +1 79 ARG n +1 80 LEU n +1 81 VAL n +1 82 PHE n +1 83 ASP n +1 84 ASN n +1 85 CYS n +1 86 GLU n +1 87 THR n +1 88 PHE n +1 89 ASN n +1 90 GLU n +1 91 ASP n +1 92 ASP n +1 93 SER n +1 94 ASP n +1 95 ILE n +1 96 GLY n +1 97 ARG n +1 98 ALA n +1 99 GLY n +1 100 HIS n +1 101 ASN n +1 102 MET n +1 103 ARG n +1 104 LYS n +1 105 TYR n +1 106 PHE n +1 107 GLU n +1 108 LYS n +1 109 LYS n +1 110 TRP n +1 111 THR n +1 112 ASP n +1 113 THR n +1 114 PHE n +1 115 LYS n +1 116 VAL n +1 117 SER 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 ? +_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 469008 +_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(DE3)' +_entity_src_gen.pdbx_host_org_variant R3 +_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 PNIC28-BSA4 +_entity_src_gen.plasmid_details ? +_entity_src_gen.pdbx_description ? +# +_struct_ref.id 1 +_struct_ref.db_name UNP +_struct_ref.db_code BAZ2B_HUMAN +_struct_ref.entity_id 1 +_struct_ref.pdbx_seq_one_letter_code ? +_struct_ref.pdbx_align_begin ? +_struct_ref.biol_id . +_struct_ref.pdbx_db_accession Q9UIF8 +# +_struct_ref_seq.align_id 1 +_struct_ref_seq.ref_id 1 +_struct_ref_seq.pdbx_PDB_id_code 4CUP +_struct_ref_seq.pdbx_strand_id A +_struct_ref_seq.seq_align_beg 3 +_struct_ref_seq.pdbx_seq_align_beg_ins_code ? +_struct_ref_seq.seq_align_end 117 +_struct_ref_seq.pdbx_seq_align_end_ins_code ? +_struct_ref_seq.pdbx_db_accession Q9UIF8 +_struct_ref_seq.db_align_beg 1858 +_struct_ref_seq.pdbx_db_align_beg_ins_code ? +_struct_ref_seq.db_align_end 1972 +_struct_ref_seq.pdbx_db_align_end_ins_code ? +_struct_ref_seq.pdbx_auth_seq_align_beg 1858 +_struct_ref_seq.pdbx_auth_seq_align_end 1972 +# +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 4CUP SER A 1 ? UNP Q9UIF8 ? ? 'EXPRESSION TAG' 1856 1 +1 4CUP MET A 2 ? UNP Q9UIF8 ? ? 'EXPRESSION TAG' 1857 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 +SER 'L-peptide linking' y SERINE ? 'C3 H7 N O3' 105.093 +MET 'L-peptide linking' y METHIONINE ? 'C5 H11 N O2 S' 149.207 +VAL 'L-peptide linking' y VALINE ? 'C5 H11 N O2' 117.147 +LYS 'L-peptide linking' y LYSINE ? 'C6 H15 N2 O2 1' 147.197 +PRO 'L-peptide linking' y PROLINE ? 'C5 H9 N O2' 115.132 +ARG 'L-peptide linking' y ARGININE ? 'C6 H15 N4 O2 1' 175.210 +ASP 'L-peptide linking' y 'ASPARTIC ACID' ? 'C4 H7 N O4' 133.104 +LEU 'L-peptide linking' y LEUCINE ? 'C6 H13 N O2' 131.174 +ALA 'L-peptide linking' y ALANINE ? 'C3 H7 N O2' 89.094 +CYS 'L-peptide linking' y CYSTEINE ? 'C3 H7 N O2 S' 121.154 +ILE 'L-peptide linking' y ISOLEUCINE ? 'C6 H13 N O2' 131.174 +THR 'L-peptide linking' y THREONINE ? 'C4 H9 N O3' 119.120 +GLU 'L-peptide linking' y 'GLUTAMIC ACID' ? 'C5 H9 N O4' 147.130 +HIS 'L-peptide linking' y HISTIDINE ? 'C6 H10 N3 O2 1' 156.164 +TRP 'L-peptide linking' y TRYPTOPHAN ? 'C11 H12 N2 O2' 204.228 +PHE 'L-peptide linking' y PHENYLALANINE ? 'C9 H11 N O2' 165.191 +ASN 'L-peptide linking' y ASPARAGINE ? 'C4 H8 N2 O3' 132.119 +GLY 'PEPTIDE LINKING' y GLYCINE ? 'C2 H5 N O2' 75.067 +TYR 'L-peptide linking' y TYROSINE ? 'C9 H11 N O3' 181.191 +GLN 'L-peptide linking' y GLUTAMINE ? 'C5 H10 N2 O3' 146.146 +ZYB NON-POLYMER . 4-FLUOROBENZAMIDOXIME ? 'C7 H7 F N2 O' 154.144 +MOH NON-POLYMER . METHANOL ? 'C H4 O' 32.042 +HOH NON-POLYMER . WATER ? 'H2 O' 18.015 +# +_exptl.entry_id 4CUP +_exptl.method 'X-RAY DIFFRACTION' +_exptl.crystals_number 1 +# +_exptl_crystal.id 1 +_exptl_crystal.density_meas ? +_exptl_crystal.density_Matthews 4.3 +_exptl_crystal.density_percent_sol 70 +_exptl_crystal.description NONE +# +_exptl_crystal_grow.crystal_id 1 +_exptl_crystal_grow.method ? +_exptl_crystal_grow.temp ? +_exptl_crystal_grow.temp_details ? +_exptl_crystal_grow.pH 6.4 +_exptl_crystal_grow.pdbx_pH_range ? +_exptl_crystal_grow.pdbx_details '34% PEG SMEAR LOW, 0.1M MES PH 6.4' +# +_diffrn.id 1 +_diffrn.ambient_temp 100 +_diffrn.ambient_temp_details ? +_diffrn.crystal_id 1 +# +_diffrn_detector.diffrn_id 1 +_diffrn_detector.detector 'PIXEL (PILATUS)' +_diffrn_detector.type DECTRIS +_diffrn_detector.pdbx_collection_date 2012-04-29 +_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 ? +_diffrn_radiation.pdbx_diffrn_protocol 'SINGLE WAVELENGTH' +_diffrn_radiation.pdbx_scattering_type x-ray +# +_diffrn_radiation_wavelength.id 1 +_diffrn_radiation_wavelength.wavelength 0.97 +_diffrn_radiation_wavelength.wt 1.0 +# +_diffrn_source.diffrn_id 1 +_diffrn_source.source SYNCHROTRON +_diffrn_source.type 'DIAMOND BEAMLINE I04' +_diffrn_source.pdbx_synchrotron_site DIAMOND +_diffrn_source.pdbx_synchrotron_beamline I04 +_diffrn_source.pdbx_wavelength 0.97 +_diffrn_source.pdbx_wavelength_list ? +# +_reflns.pdbx_diffrn_id 1 +_reflns.pdbx_ordinal 1 +_reflns.entry_id 4CUP +_reflns.observed_criterion_sigma_I -3.0 +_reflns.observed_criterion_sigma_F ? +_reflns.d_resolution_low 32.97 +_reflns.d_resolution_high 1.88 +_reflns.number_obs 18470 +_reflns.number_all ? +_reflns.percent_possible_obs 99.5 +_reflns.pdbx_Rmerge_I_obs 0.06 +_reflns.pdbx_Rsym_value ? +_reflns.pdbx_netI_over_sigmaI 16.20 +_reflns.B_iso_Wilson_estimate 26.58 +_reflns.pdbx_redundancy 5.4 +# +_reflns_shell.pdbx_diffrn_id 1 +_reflns_shell.pdbx_ordinal 1 +_reflns_shell.d_res_high 1.88 +_reflns_shell.d_res_low 1.93 +_reflns_shell.percent_possible_all 98.6 +_reflns_shell.Rmerge_I_obs 0.74 +_reflns_shell.pdbx_Rsym_value ? +_reflns_shell.meanI_over_sigI_obs 1.90 +_reflns_shell.pdbx_redundancy 4.8 +# +_computing.entry_id 4CUP +_computing.pdbx_data_reduction_ii XDS +_computing.pdbx_data_reduction_ds AIMLESS +_computing.data_collection ? +_computing.structure_solution ? +_computing.structure_refinement 'PHENIX (PHENIX.REFINE)' +_computing.pdbx_structure_refinement_method ? +# +_refine.pdbx_refine_id 'X-RAY DIFFRACTION' +_refine.entry_id 4CUP +_refine.pdbx_diffrn_id 1 +_refine.pdbx_TLS_residual_ADP_flag ? +_refine.ls_number_reflns_obs 18429 +_refine.ls_number_reflns_all ? +_refine.pdbx_ls_sigma_I ? +_refine.pdbx_ls_sigma_F 1.90 +_refine.pdbx_data_cutoff_high_absF ? +_refine.pdbx_data_cutoff_low_absF ? +_refine.pdbx_data_cutoff_high_rms_absF ? +_refine.ls_d_res_low 18.538 +_refine.ls_d_res_high 1.880 +_refine.ls_percent_reflns_obs 99.44 +_refine.ls_R_factor_obs 0.1779 +_refine.ls_R_factor_all ? +_refine.ls_R_factor_R_work 0.1763 +_refine.ls_R_factor_R_free 0.2078 +_refine.ls_R_factor_R_free_error ? +_refine.ls_R_factor_R_free_error_details ? +_refine.ls_percent_reflns_R_free 5.1 +_refine.ls_number_reflns_R_free 940 +_refine.ls_number_parameters ? +_refine.ls_number_restraints ? +_refine.occupancy_min ? +_refine.occupancy_max ? +_refine.correlation_coeff_Fo_to_Fc ? +_refine.correlation_coeff_Fo_to_Fc_free ? +_refine.B_iso_mean ? +_refine.aniso_B[1][1] ? +_refine.aniso_B[2][2] ? +_refine.aniso_B[3][3] ? +_refine.aniso_B[1][2] ? +_refine.aniso_B[1][3] ? +_refine.aniso_B[2][3] ? +_refine.solvent_model_details 'FLAT BULK SOLVENT MODEL' +_refine.solvent_model_param_ksol ? +_refine.solvent_model_param_bsol ? +_refine.pdbx_solvent_vdw_probe_radii 1.11 +_refine.pdbx_solvent_ion_probe_radii ? +_refine.pdbx_solvent_shrinkage_radii 0.90 +_refine.pdbx_ls_cross_valid_method ? +_refine.details ? +_refine.pdbx_starting_model ? +_refine.pdbx_method_to_determine_struct 'MOLECULAR REPLACEMENT' +_refine.pdbx_isotropic_thermal_model ? +_refine.pdbx_stereochemistry_target_values ML +_refine.pdbx_stereochem_target_val_spec_case ? +_refine.pdbx_R_Free_selection_details ? +_refine.pdbx_overall_ESU_R ? +_refine.pdbx_overall_ESU_R_Free ? +_refine.overall_SU_ML 0.20 +_refine.pdbx_overall_phase_error 25.38 +_refine.overall_SU_B ? +_refine.overall_SU_R_Cruickshank_DPI ? +_refine.pdbx_overall_SU_R_free_Cruickshank_DPI ? +_refine.pdbx_overall_SU_R_Blow_DPI ? +_refine.pdbx_overall_SU_R_free_Blow_DPI ? +# +_refine_hist.pdbx_refine_id 'X-RAY DIFFRACTION' +_refine_hist.cycle_id LAST +_refine_hist.pdbx_number_atoms_protein 924 +_refine_hist.pdbx_number_atoms_nucleic_acid 0 +_refine_hist.pdbx_number_atoms_ligand 17 +_refine_hist.number_atoms_solvent 146 +_refine_hist.number_atoms_total 1087 +_refine_hist.d_res_high 1.880 +_refine_hist.d_res_low 18.538 +# +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_refine_id +_refine_ls_restr.pdbx_restraint_function +f_bond_d 0.006 ? ? 973 'X-RAY DIFFRACTION' ? +f_angle_d 0.898 ? ? 1309 'X-RAY DIFFRACTION' ? +f_dihedral_angle_d 12.740 ? ? 365 'X-RAY DIFFRACTION' ? +f_chiral_restr 0.034 ? ? 141 'X-RAY DIFFRACTION' ? +f_plane_restr 0.005 ? ? 168 'X-RAY DIFFRACTION' ? +# +loop_ +_refine_ls_shell.pdbx_refine_id +_refine_ls_shell.pdbx_total_number_of_bins_used +_refine_ls_shell.d_res_high +_refine_ls_shell.d_res_low +_refine_ls_shell.number_reflns_R_work +_refine_ls_shell.R_factor_R_work +_refine_ls_shell.percent_reflns_obs +_refine_ls_shell.R_factor_R_free +_refine_ls_shell.R_factor_R_free_error +_refine_ls_shell.percent_reflns_R_free +_refine_ls_shell.number_reflns_R_free +_refine_ls_shell.number_reflns_all +_refine_ls_shell.R_factor_all +'X-RAY DIFFRACTION' ? 1.8800 1.9790 2458 0.3152 99.00 0.3338 ? ? 133 ? ? +'X-RAY DIFFRACTION' ? 1.9790 2.1029 2430 0.2368 99.00 0.2971 ? ? 139 ? ? +'X-RAY DIFFRACTION' ? 2.1029 2.2650 2453 0.1915 99.00 0.2154 ? ? 138 ? ? +'X-RAY DIFFRACTION' ? 2.2650 2.4924 2496 0.1683 100.00 0.2131 ? ? 137 ? ? +'X-RAY DIFFRACTION' ? 2.4924 2.8519 2493 0.1662 100.00 0.2138 ? ? 138 ? ? +'X-RAY DIFFRACTION' ? 2.8519 3.5889 2505 0.1669 100.00 0.1748 ? ? 143 ? ? +'X-RAY DIFFRACTION' ? 3.5889 18.5386 2654 0.1558 100.00 0.1894 ? ? 112 ? ? +# +_struct.entry_id 4CUP +_struct.title 'Crystal structure of human BAZ2B in complex with fragment-1 N09421' +_struct.pdbx_descriptor 'BROMODOMAIN ADJACENT TO ZINC FINGER DOMAIN PROTEIN 2B' +_struct.pdbx_model_details ? +_struct.pdbx_CASP_flag ? +_struct.pdbx_model_type_details ? +# +_struct_keywords.entry_id 4CUP +_struct_keywords.pdbx_keywords TRANSCRIPTION +_struct_keywords.text TRANSCRIPTION +# +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 3 ? +E N N 3 ? +F N N 4 ? +# +_struct_biol.id 1 +# +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 13 ? HIS A 28 ? LYS A 1868 HIS A 1883 1 ? 16 +HELX_P HELX_P2 2 ALA A 31 ? LEU A 35 ? ALA A 1886 LEU A 1890 5 ? 5 +HELX_P HELX_P3 3 GLY A 45 ? ILE A 50 ? GLY A 1900 ILE A 1905 1 ? 6 +HELX_P HELX_P4 4 ASP A 55 ? SER A 65 ? ASP A 1910 SER A 1920 1 ? 11 +HELX_P HELX_P5 5 ASN A 70 ? ASN A 89 ? ASN A 1925 ASN A 1944 1 ? 20 +HELX_P HELX_P6 6 SER A 93 ? LYS A 115 ? SER A 1948 LYS A 1970 1 ? 23 +# +_struct_conf_type.id HELX_P +_struct_conf_type.criteria ? +_struct_conf_type.reference ? +# +_struct_site.id AC1 +_struct_site.details 'BINDING SITE FOR RESIDUE ZYB A 2971' +_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 6 VAL A 43 ? VAL A 1898 . . 1_555 ? +2 AC1 6 PRO A 44 ? PRO A 1899 . . 4_566 ? +3 AC1 6 ASN A 89 ? ASN A 1944 . . 1_555 ? +4 AC1 6 ILE A 95 ? ILE A 1950 . . 1_555 ? +5 AC1 6 HOH F . ? HOH A 2072 . . 4_566 ? +6 AC1 6 HOH F . ? HOH A 2124 . . 1_555 ? +# +_database_PDB_matrix.entry_id 4CUP +_database_PDB_matrix.origx[1][1] 1.000000 +_database_PDB_matrix.origx[1][2] 0.000000 +_database_PDB_matrix.origx[1][3] 0.000000 +_database_PDB_matrix.origx[2][1] 0.000000 +_database_PDB_matrix.origx[2][2] 1.000000 +_database_PDB_matrix.origx[2][3] 0.000000 +_database_PDB_matrix.origx[3][1] 0.000000 +_database_PDB_matrix.origx[3][2] 0.000000 +_database_PDB_matrix.origx[3][3] 1.000000 +_database_PDB_matrix.origx_vector[1] 0.00000 +_database_PDB_matrix.origx_vector[2] 0.00000 +_database_PDB_matrix.origx_vector[3] 0.00000 +# +_atom_sites.entry_id 4CUP +_atom_sites.Cartn_transform_axes ? +_atom_sites.fract_transf_matrix[1][1] 0.012442 +_atom_sites.fract_transf_matrix[1][2] 0.000000 +_atom_sites.fract_transf_matrix[1][3] 0.000000 +_atom_sites.fract_transf_matrix[2][1] 0.000000 +_atom_sites.fract_transf_matrix[2][2] 0.010404 +_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.017340 +_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 +C +F +H +N +O +S +# +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 1 N N . SER A 1 1 ? 50.346 19.287 17.288 1.00 32.02 ? ? ? ? ? ? 1856 SER A N 1 +ATOM 2 C CA . SER A 1 1 ? 50.745 19.964 16.058 1.00 34.08 ? ? ? ? ? ? 1856 SER A CA 1 +ATOM 3 C C . SER A 1 1 ? 50.691 18.998 14.887 1.00 35.85 ? ? ? ? ? ? 1856 SER A C 1 +ATOM 4 O O . SER A 1 1 ? 50.070 17.937 14.987 1.00 33.26 ? ? ? ? ? ? 1856 SER A O 1 +ATOM 5 C CB . SER A 1 1 ? 52.146 20.564 16.199 1.00 30.82 ? ? ? ? ? ? 1856 SER A CB 1 +ATOM 6 O OG . SER A 1 1 ? 53.116 19.545 16.371 1.00 32.50 ? ? ? ? ? ? 1856 SER A OG 1 +ATOM 7 N N . MET A 1 2 ? 51.330 19.363 13.776 1.00 35.47 ? ? ? ? ? ? 1857 MET A N 1 +ATOM 8 C CA . MET A 1 2 ? 51.310 18.508 12.593 1.00 36.62 ? ? ? ? ? ? 1857 MET A CA 1 +ATOM 9 C C . MET A 1 2 ? 51.837 17.105 12.904 1.00 32.24 ? ? ? ? ? ? 1857 MET A C 1 +ATOM 10 O O . MET A 1 2 ? 52.974 16.947 13.359 1.00 34.35 ? ? ? ? ? ? 1857 MET A O 1 +ATOM 11 C CB . MET A 1 2 ? 52.123 19.127 11.456 1.00 36.12 ? ? ? ? ? ? 1857 MET A CB 1 +ATOM 12 C CG . MET A 1 2 ? 51.875 18.454 10.119 1.00 37.34 ? ? ? ? ? ? 1857 MET A CG 1 +ATOM 13 S SD . MET A 1 2 ? 52.981 18.997 8.800 1.00 39.70 ? ? ? ? ? ? 1857 MET A SD 1 +ATOM 14 C CE . MET A 1 2 ? 52.932 20.770 8.993 1.00 36.58 ? ? ? ? ? ? 1857 MET A CE 1 +ATOM 15 N N . SER A 1 3 ? 50.992 16.104 12.654 1.00 35.27 ? ? ? ? ? ? 1858 SER A N 1 +ATOM 16 C CA . SER A 1 3 ? 51.276 14.687 12.929 1.00 35.35 ? ? ? ? ? ? 1858 SER A CA 1 +ATOM 17 C C . SER A 1 3 ? 51.511 14.388 14.413 1.00 36.48 ? ? ? ? ? ? 1858 SER A C 1 +ATOM 18 O O . SER A 1 3 ? 52.097 13.363 14.762 1.00 33.72 ? ? ? ? ? ? 1858 SER A O 1 +ATOM 19 C CB . SER A 1 3 ? 52.482 14.212 12.114 1.00 35.21 ? ? ? ? ? ? 1858 SER A CB 1 +ATOM 20 O OG . SER A 1 3 ? 52.279 14.436 10.727 1.00 35.86 ? ? ? ? ? ? 1858 SER A OG 1 +ATOM 21 N N . VAL A 1 4 ? 51.048 15.277 15.285 1.00 30.95 ? ? ? ? ? ? 1859 VAL A N 1 +ATOM 22 C CA . VAL A 1 4 ? 51.130 15.041 16.731 1.00 31.15 ? ? ? ? ? ? 1859 VAL A CA 1 +ATOM 23 C C . VAL A 1 4 ? 49.768 15.284 17.370 1.00 35.24 ? ? ? ? ? ? 1859 VAL A C 1 +ATOM 24 O O . VAL A 1 4 ? 49.410 16.424 17.672 1.00 36.46 ? ? ? ? ? ? 1859 VAL A O 1 +ATOM 25 C CB . VAL A 1 4 ? 52.177 15.945 17.413 1.00 31.83 ? ? ? ? ? ? 1859 VAL A CB 1 +ATOM 26 C CG1 . VAL A 1 4 ? 52.253 15.637 18.914 1.00 31.15 ? ? ? ? ? ? 1859 VAL A CG1 1 +ATOM 27 C CG2 . VAL A 1 4 ? 53.546 15.779 16.764 1.00 33.39 ? ? ? ? ? ? 1859 VAL A CG2 1 +ATOM 28 N N . LYS A 1 5 ? 49.005 14.214 17.571 1.00 42.36 ? ? ? ? ? ? 1860 LYS A N 1 +ATOM 29 C CA . LYS A 1 5 ? 47.636 14.345 18.058 1.00 45.72 ? ? ? ? ? ? 1860 LYS A CA 1 +ATOM 30 C C . LYS A 1 5 ? 47.418 13.675 19.410 1.00 44.41 ? ? ? ? ? ? 1860 LYS A C 1 +ATOM 31 O O . LYS A 1 5 ? 47.998 12.625 19.688 1.00 45.19 ? ? ? ? ? ? 1860 LYS A O 1 +ATOM 32 C CB . LYS A 1 5 ? 46.661 13.761 17.032 1.00 46.44 ? ? ? ? ? ? 1860 LYS A CB 1 +ATOM 33 C CG . LYS A 1 5 ? 46.603 14.552 15.731 1.00 61.31 ? ? ? ? ? ? 1860 LYS A CG 1 +ATOM 34 C CD . LYS A 1 5 ? 45.784 15.830 15.892 1.00 65.67 ? ? ? ? ? ? 1860 LYS A CD 1 +ATOM 35 C CE . LYS A 1 5 ? 46.118 16.850 14.820 1.00 68.56 ? ? ? ? ? ? 1860 LYS A CE 1 +ATOM 36 N NZ . LYS A 1 5 ? 47.383 17.565 15.134 1.00 71.00 ? ? ? ? ? ? 1860 LYS A NZ 1 +ATOM 37 N N . LYS A 1 6 ? 46.582 14.292 20.245 1.00 47.64 ? ? ? ? ? ? 1861 LYS A N 1 +ATOM 38 C CA . LYS A 1 6 ? 46.107 13.653 21.467 1.00 58.98 ? ? ? ? ? ? 1861 LYS A CA 1 +ATOM 39 C C . LYS A 1 6 ? 45.212 12.495 21.075 1.00 56.13 ? ? ? ? ? ? 1861 LYS A C 1 +ATOM 40 O O . LYS A 1 6 ? 44.629 12.513 19.990 1.00 58.78 ? ? ? ? ? ? 1861 LYS A O 1 +ATOM 41 C CB . LYS A 1 6 ? 45.323 14.628 22.354 1.00 69.74 ? ? ? ? ? ? 1861 LYS A CB 1 +ATOM 42 C CG . LYS A 1 6 ? 46.129 15.745 22.995 1.00 73.06 ? ? ? ? ? ? 1861 LYS A CG 1 +ATOM 43 C CD . LYS A 1 6 ? 45.315 16.398 24.110 1.00 76.41 ? ? ? ? ? ? 1861 LYS A CD 1 +ATOM 44 C CE . LYS A 1 6 ? 45.913 17.721 24.569 1.00 77.31 ? ? ? ? ? ? 1861 LYS A CE 1 +ATOM 45 N NZ . LYS A 1 6 ? 45.777 18.787 23.539 1.00 76.95 ? ? ? ? ? ? 1861 LYS A NZ 1 +ATOM 46 N N . PRO A 1 7 ? 45.102 11.484 21.949 1.00 56.20 ? ? ? ? ? ? 1862 PRO A N 1 +ATOM 47 C CA . PRO A 1 7 ? 44.136 10.405 21.727 1.00 60.79 ? ? ? ? ? ? 1862 PRO A CA 1 +ATOM 48 C C . PRO A 1 7 ? 42.751 10.956 21.409 1.00 65.14 ? ? ? ? ? ? 1862 PRO A C 1 +ATOM 49 O O . PRO A 1 7 ? 42.303 11.920 22.036 1.00 61.93 ? ? ? ? ? ? 1862 PRO A O 1 +ATOM 50 C CB . PRO A 1 7 ? 44.149 9.652 23.055 1.00 62.28 ? ? ? ? ? ? 1862 PRO A CB 1 +ATOM 51 C CG . PRO A 1 7 ? 45.547 9.829 23.540 1.00 62.61 ? ? ? ? ? ? 1862 PRO A CG 1 +ATOM 52 C CD . PRO A 1 7 ? 45.950 11.224 23.125 1.00 57.35 ? ? ? ? ? ? 1862 PRO A CD 1 +ATOM 53 N N . LYS A 1 8 ? 42.100 10.360 20.416 1.00 68.79 ? ? ? ? ? ? 1863 LYS A N 1 +ATOM 54 C CA . LYS A 1 8 ? 40.836 10.879 19.914 1.00 73.53 ? ? ? ? ? ? 1863 LYS A CA 1 +ATOM 55 C C . LYS A 1 8 ? 39.701 10.620 20.892 1.00 72.50 ? ? ? ? ? ? 1863 LYS A C 1 +ATOM 56 O O . LYS A 1 8 ? 39.396 9.473 21.215 1.00 73.78 ? ? ? ? ? ? 1863 LYS A O 1 +ATOM 57 C CB . LYS A 1 8 ? 40.507 10.266 18.550 1.00 73.63 ? ? ? ? ? ? 1863 LYS A CB 1 +ATOM 58 N N . ARG A 1 9 ? 39.091 11.698 21.369 1.00 70.21 ? ? ? ? ? ? 1864 ARG A N 1 +ATOM 59 C CA . ARG A 1 9 ? 37.895 11.604 22.190 1.00 69.66 ? ? ? ? ? ? 1864 ARG A CA 1 +ATOM 60 C C . ARG A 1 9 ? 36.694 11.259 21.314 1.00 70.65 ? ? ? ? ? ? 1864 ARG A C 1 +ATOM 61 O O . ARG A 1 9 ? 36.517 11.839 20.241 1.00 70.51 ? ? ? ? ? ? 1864 ARG A O 1 +ATOM 62 C CB . ARG A 1 9 ? 37.651 12.914 22.938 1.00 67.41 ? ? ? ? ? ? 1864 ARG A CB 1 +ATOM 63 C CG . ARG A 1 9 ? 36.356 12.937 23.721 1.00 64.44 ? ? ? ? ? ? 1864 ARG A CG 1 +ATOM 64 C CD . ARG A 1 9 ? 35.997 14.337 24.184 1.00 62.86 ? ? ? ? ? ? 1864 ARG A CD 1 +ATOM 65 N NE . ARG A 1 9 ? 34.678 14.349 24.805 1.00 62.84 ? ? ? ? ? ? 1864 ARG A NE 1 +ATOM 66 C CZ . ARG A 1 9 ? 33.550 14.599 24.151 1.00 65.98 ? ? ? ? ? ? 1864 ARG A CZ 1 +ATOM 67 N NH1 . ARG A 1 9 ? 33.579 14.880 22.855 1.00 71.46 ? ? ? ? ? ? 1864 ARG A NH1 1 +ATOM 68 N NH2 . ARG A 1 9 ? 32.392 14.578 24.795 1.00 67.66 ? ? ? ? ? ? 1864 ARG A NH2 1 +ATOM 69 N N . ASP A 1 10 ? 35.876 10.311 21.763 1.00 71.15 ? ? ? ? ? ? 1865 ASP A N 1 +ATOM 70 C CA . ASP A 1 10 ? 34.693 9.915 21.008 1.00 66.70 ? ? ? ? ? ? 1865 ASP A CA 1 +ATOM 71 C C . ASP A 1 10 ? 33.597 10.965 21.142 1.00 60.95 ? ? ? ? ? ? 1865 ASP A C 1 +ATOM 72 O O . ASP A 1 10 ? 32.969 11.089 22.191 1.00 62.37 ? ? ? ? ? ? 1865 ASP A O 1 +ATOM 73 C CB . ASP A 1 10 ? 34.183 8.548 21.472 1.00 71.14 ? ? ? ? ? ? 1865 ASP A CB 1 +ATOM 74 C CG . ASP A 1 10 ? 32.882 8.151 20.796 1.00 72.95 ? ? ? ? ? ? 1865 ASP A CG 1 +ATOM 75 O OD1 . ASP A 1 10 ? 32.567 8.705 19.717 1.00 65.36 ? ? ? ? ? ? 1865 ASP A OD1 1 +ATOM 76 O OD2 . ASP A 1 10 ? 32.173 7.280 21.343 1.00 74.36 ? ? ? ? ? ? 1865 ASP A OD2 1 +ATOM 77 N N . ASP A 1 11 ? 33.361 11.711 20.068 1.00 48.20 ? ? ? ? ? ? 1866 ASP A N 1 +ATOM 78 C CA . ASP A 1 11 ? 32.406 12.813 20.113 1.00 43.93 ? ? ? ? ? ? 1866 ASP A CA 1 +ATOM 79 C C . ASP A 1 11 ? 31.081 12.473 19.431 1.00 40.69 ? ? ? ? ? ? 1866 ASP A C 1 +ATOM 80 O O . ASP A 1 11 ? 30.235 13.348 19.233 1.00 41.33 ? ? ? ? ? ? 1866 ASP A O 1 +ATOM 81 C CB . ASP A 1 11 ? 33.020 14.063 19.472 1.00 47.30 ? ? ? ? ? ? 1866 ASP A CB 1 +ATOM 82 C CG . ASP A 1 11 ? 33.442 13.838 18.029 1.00 58.18 ? ? ? ? ? ? 1866 ASP A CG 1 +ATOM 83 O OD1 . ASP A 1 11 ? 33.545 12.666 17.610 1.00 64.93 ? ? ? ? ? ? 1866 ASP A OD1 1 +ATOM 84 O OD2 . ASP A 1 11 ? 33.681 14.834 17.313 1.00 64.43 ? ? ? ? ? ? 1866 ASP A OD2 1 +ATOM 85 N N . SER A 1 12 ? 30.896 11.200 19.096 1.00 44.14 ? ? ? ? ? ? 1867 SER A N 1 +ATOM 86 C CA . SER A 1 12 ? 29.765 10.775 18.275 1.00 43.67 ? ? ? ? ? ? 1867 SER A CA 1 +ATOM 87 C C . SER A 1 12 ? 28.422 10.980 18.960 1.00 42.67 ? ? ? ? ? ? 1867 SER A C 1 +ATOM 88 O O . SER A 1 12 ? 27.394 11.083 18.291 1.00 43.89 ? ? ? ? ? ? 1867 SER A O 1 +ATOM 89 C CB . SER A 1 12 ? 29.917 9.303 17.883 1.00 49.00 ? ? ? ? ? ? 1867 SER A CB 1 +ATOM 90 O OG . SER A 1 12 ? 29.813 8.468 19.024 1.00 54.91 ? ? ? ? ? ? 1867 SER A OG 1 +ATOM 91 N N . LYS A 1 13 ? 28.430 11.041 20.289 1.00 40.18 ? ? ? ? ? ? 1868 LYS A N 1 +ATOM 92 C CA . LYS A 1 13 ? 27.201 11.234 21.060 1.00 34.76 ? ? ? ? ? ? 1868 LYS A CA 1 +ATOM 93 C C . LYS A 1 13 ? 26.971 12.672 21.532 1.00 34.13 ? ? ? ? ? ? 1868 LYS A C 1 +ATOM 94 O O . LYS A 1 13 ? 25.970 12.949 22.194 1.00 35.15 ? ? ? ? ? ? 1868 LYS A O 1 +ATOM 95 C CB . LYS A 1 13 ? 27.201 10.318 22.285 1.00 36.58 ? ? ? ? ? ? 1868 LYS A CB 1 +ATOM 96 C CG . LYS A 1 13 ? 27.235 8.825 21.961 1.00 41.60 ? ? ? ? ? ? 1868 LYS A CG 1 +ATOM 97 C CD . LYS A 1 13 ? 27.236 8.002 23.238 1.00 58.66 ? ? ? ? ? ? 1868 LYS A CD 1 +ATOM 98 N N . ASP A 1 14 ? 27.893 13.577 21.220 1.00 36.26 ? ? ? ? ? ? 1869 ASP A N 1 +ATOM 99 C CA . ASP A 1 14 ? 27.801 14.944 21.749 1.00 33.90 ? ? ? ? ? ? 1869 ASP A CA 1 +ATOM 100 C C . ASP A 1 14 ? 26.513 15.639 21.331 1.00 36.45 ? ? ? ? ? ? 1869 ASP A C 1 +ATOM 101 O O . ASP A 1 14 ? 25.872 16.309 22.140 1.00 36.50 ? ? ? ? ? ? 1869 ASP A O 1 +ATOM 102 C CB . ASP A 1 14 ? 28.997 15.789 21.307 1.00 31.90 ? ? ? ? ? ? 1869 ASP A CB 1 +ATOM 103 C CG . ASP A 1 14 ? 30.280 15.382 21.990 1.00 43.01 ? ? ? ? ? ? 1869 ASP A CG 1 +ATOM 104 O OD1 . ASP A 1 14 ? 30.229 14.494 22.871 1.00 40.83 ? ? ? ? ? ? 1869 ASP A OD1 1 +ATOM 105 O OD2 . ASP A 1 14 ? 31.334 15.964 21.664 1.00 39.80 ? ? ? ? ? ? 1869 ASP A OD2 1 +ATOM 106 N N . LEU A 1 15 ? 26.130 15.476 20.069 1.00 32.79 ? ? ? ? ? ? 1870 LEU A N 1 +ATOM 107 C CA . LEU A 1 15 ? 24.940 16.138 19.558 1.00 32.80 ? ? ? ? ? ? 1870 LEU A CA 1 +ATOM 108 C C . LEU A 1 15 ? 23.701 15.689 20.336 1.00 35.75 ? ? ? ? ? ? 1870 LEU A C 1 +ATOM 109 O O . LEU A 1 15 ? 22.925 16.521 20.806 1.00 36.32 ? ? ? ? ? ? 1870 LEU A O 1 +ATOM 110 C CB . LEU A 1 15 ? 24.776 15.869 18.056 1.00 33.83 ? ? ? ? ? ? 1870 LEU A CB 1 +ATOM 111 C CG . LEU A 1 15 ? 23.582 16.530 17.365 1.00 31.69 ? ? ? ? ? ? 1870 LEU A CG 1 +ATOM 112 C CD1 . LEU A 1 15 ? 23.636 18.058 17.479 1.00 32.12 ? ? ? ? ? ? 1870 LEU A CD1 1 +ATOM 113 C CD2 . LEU A 1 15 ? 23.507 16.090 15.894 1.00 33.01 ? ? ? ? ? ? 1870 LEU A CD2 1 +ATOM 114 N N . ALA A 1 16 ? 23.540 14.380 20.504 1.00 34.82 ? ? ? ? ? ? 1871 ALA A N 1 +ATOM 115 C CA . ALA A 1 16 ? 22.419 13.834 21.269 1.00 36.97 ? ? ? ? ? ? 1871 ALA A CA 1 +ATOM 116 C C . ALA A 1 16 ? 22.444 14.286 22.729 1.00 37.20 ? ? ? ? ? ? 1871 ALA A C 1 +ATOM 117 O O . ALA A 1 16 ? 21.403 14.588 23.312 1.00 36.24 ? ? ? ? ? ? 1871 ALA A O 1 +ATOM 118 C CB . ALA A 1 16 ? 22.418 12.303 21.195 1.00 38.32 ? ? ? ? ? ? 1871 ALA A CB 1 +ATOM 119 N N . LEU A 1 17 ? 23.634 14.325 23.320 1.00 35.33 ? ? ? ? ? ? 1872 LEU A N 1 +ATOM 120 C CA . LEU A 1 17 ? 23.770 14.709 24.723 1.00 34.07 ? ? ? ? ? ? 1872 LEU A CA 1 +ATOM 121 C C . LEU A 1 17 ? 23.462 16.196 24.942 1.00 34.96 ? ? ? ? ? ? 1872 LEU A C 1 +ATOM 122 O O . LEU A 1 17 ? 22.828 16.574 25.930 1.00 37.32 ? ? ? ? ? ? 1872 LEU A O 1 +ATOM 123 C CB . LEU A 1 17 ? 25.175 14.377 25.229 1.00 35.88 ? ? ? ? ? ? 1872 LEU A CB 1 +ATOM 124 C CG . LEU A 1 17 ? 25.474 12.879 25.339 1.00 39.51 ? ? ? ? ? ? 1872 LEU A CG 1 +ATOM 125 C CD1 . LEU A 1 17 ? 26.935 12.631 25.680 1.00 39.12 ? ? ? ? ? ? 1872 LEU A CD1 1 +ATOM 126 C CD2 . LEU A 1 17 ? 24.560 12.228 26.367 1.00 44.69 ? ? ? ? ? ? 1872 LEU A CD2 1 +ATOM 127 N N . CYS A 1 18 ? 23.908 17.042 24.019 1.00 34.73 ? ? ? ? ? ? 1873 CYS A N 1 +ATOM 128 C CA . CYS A 1 18 ? 23.589 18.466 24.098 1.00 33.93 ? ? ? ? ? ? 1873 CYS A CA 1 +ATOM 129 C C . CYS A 1 18 ? 22.087 18.706 23.956 1.00 35.83 ? ? ? ? ? ? 1873 CYS A C 1 +ATOM 130 O O . CYS A 1 18 ? 21.515 19.559 24.648 1.00 32.57 ? ? ? ? ? ? 1873 CYS A O 1 +ATOM 131 C CB . CYS A 1 18 ? 24.360 19.249 23.033 1.00 32.12 ? ? ? ? ? ? 1873 CYS A CB 1 +ATOM 132 S SG . CYS A 1 18 ? 26.096 19.489 23.460 1.00 34.87 ? ? ? ? ? ? 1873 CYS A SG 1 +ATOM 133 N N . SER A 1 19 ? 21.456 17.945 23.063 1.00 31.48 ? ? ? ? ? ? 1874 SER A N 1 +ATOM 134 C CA . SER A 1 19 ? 20.009 18.011 22.874 1.00 29.68 ? ? ? ? ? ? 1874 SER A CA 1 +ATOM 135 C C . SER A 1 19 ? 19.281 17.609 24.153 1.00 31.01 ? ? ? ? ? ? 1874 SER A C 1 +ATOM 136 O O . SER A 1 19 ? 18.287 18.229 24.550 1.00 32.67 ? ? ? ? ? ? 1874 SER A O 1 +ATOM 137 C CB . SER A 1 19 ? 19.573 17.102 21.720 1.00 29.36 ? ? ? ? ? ? 1874 SER A CB 1 +ATOM 138 O OG . SER A 1 19 ? 18.157 17.090 21.603 1.00 37.19 ? ? ? ? ? ? 1874 SER A OG 1 +ATOM 139 N N . MET A 1 20 ? 19.779 16.554 24.786 1.00 32.48 ? ? ? ? ? ? 1875 MET A N 1 +ATOM 140 C CA . MET A 1 20 ? 19.235 16.095 26.056 1.00 34.40 ? ? ? ? ? ? 1875 MET A CA 1 +ATOM 141 C C . MET A 1 20 ? 19.314 17.198 27.110 1.00 34.75 ? ? ? ? ? ? 1875 MET A C 1 +ATOM 142 O O . MET A 1 20 ? 18.325 17.506 27.775 1.00 34.20 ? ? ? ? ? ? 1875 MET A O 1 +ATOM 143 C CB . MET A 1 20 ? 19.985 14.857 26.541 1.00 36.76 ? ? ? ? ? ? 1875 MET A CB 1 +ATOM 144 C CG . MET A 1 20 ? 19.603 14.413 27.948 1.00 46.65 ? ? ? ? ? ? 1875 MET A CG 1 +ATOM 145 S SD . MET A 1 20 ? 20.818 13.270 28.644 1.00 70.07 ? ? ? ? ? ? 1875 MET A SD 1 +ATOM 146 C CE . MET A 1 20 ? 22.116 14.422 29.100 1.00 61.11 ? ? ? ? ? ? 1875 MET A CE 1 +ATOM 147 N N . ILE A 1 21 ? 20.500 17.774 27.263 1.00 33.13 ? ? ? ? ? ? 1876 ILE A N 1 +ATOM 148 C CA . ILE A 1 21 ? 20.703 18.842 28.243 1.00 34.10 ? ? ? ? ? ? 1876 ILE A CA 1 +ATOM 149 C C . ILE A 1 21 ? 19.798 20.028 27.926 1.00 36.98 ? ? ? ? ? ? 1876 ILE A C 1 +ATOM 150 O O . ILE A 1 21 ? 19.167 20.590 28.820 1.00 31.38 ? ? ? ? ? ? 1876 ILE A O 1 +ATOM 151 C CB . ILE A 1 21 ? 22.178 19.300 28.292 1.00 32.28 ? ? ? ? ? ? 1876 ILE A CB 1 +ATOM 152 C CG1 . ILE A 1 21 ? 23.049 18.201 28.905 1.00 35.04 ? ? ? ? ? ? 1876 ILE A CG1 1 +ATOM 153 C CG2 . ILE A 1 21 ? 22.324 20.616 29.088 1.00 32.40 ? ? ? ? ? ? 1876 ILE A CG2 1 +ATOM 154 C CD1 . ILE A 1 21 ? 24.534 18.477 28.796 1.00 37.95 ? ? ? ? ? ? 1876 ILE A CD1 1 +ATOM 155 N N . LEU A 1 22 ? 19.709 20.387 26.647 1.00 34.79 ? ? ? ? ? ? 1877 LEU A N 1 +ATOM 156 C CA . LEU A 1 22 ? 18.880 21.519 26.252 1.00 31.03 ? ? ? ? ? ? 1877 LEU A CA 1 +ATOM 157 C C . LEU A 1 22 ? 17.412 21.245 26.591 1.00 28.71 ? ? ? ? ? ? 1877 LEU A C 1 +ATOM 158 O O . LEU A 1 22 ? 16.713 22.127 27.087 1.00 29.96 ? ? ? ? ? ? 1877 LEU A O 1 +ATOM 159 C CB . LEU A 1 22 ? 19.060 21.827 24.757 1.00 26.02 ? ? ? ? ? ? 1877 LEU A CB 1 +ATOM 160 C CG . LEU A 1 22 ? 18.305 23.039 24.209 1.00 30.76 ? ? ? ? ? ? 1877 LEU A CG 1 +ATOM 161 C CD1 . LEU A 1 22 ? 18.668 24.315 24.969 1.00 32.05 ? ? ? ? ? ? 1877 LEU A CD1 1 +ATOM 162 C CD2 . LEU A 1 22 ? 18.606 23.191 22.724 1.00 29.86 ? ? ? ? ? ? 1877 LEU A CD2 1 +ATOM 163 N N . THR A 1 23 ? 16.960 20.010 26.365 1.00 29.80 ? ? ? ? ? ? 1878 THR A N 1 +ATOM 164 C CA . THR A 1 23 ? 15.604 19.615 26.744 1.00 30.76 ? ? ? ? ? ? 1878 THR A CA 1 +ATOM 165 C C . THR A 1 23 ? 15.344 19.795 28.249 1.00 36.26 ? ? ? ? ? ? 1878 THR A C 1 +ATOM 166 O O . THR A 1 23 ? 14.270 20.242 28.658 1.00 34.92 ? ? ? ? ? ? 1878 THR A O 1 +ATOM 167 C CB . THR A 1 23 ? 15.326 18.162 26.348 1.00 40.24 ? ? ? ? ? ? 1878 THR A CB 1 +ATOM 168 O OG1 . THR A 1 23 ? 15.391 18.058 24.921 1.00 37.15 ? ? ? ? ? ? 1878 THR A OG1 1 +ATOM 169 C CG2 . THR A 1 23 ? 13.950 17.736 26.815 1.00 39.79 ? ? ? ? ? ? 1878 THR A CG2 1 +ATOM 170 N N . GLU A 1 24 ? 16.334 19.469 29.069 1.00 34.69 ? ? ? ? ? ? 1879 GLU A N 1 +ATOM 171 C CA . GLU A 1 24 ? 16.199 19.640 30.517 1.00 38.00 ? ? ? ? ? ? 1879 GLU A CA 1 +ATOM 172 C C . GLU A 1 24 ? 16.114 21.121 30.904 1.00 31.79 ? ? ? ? ? ? 1879 GLU A C 1 +ATOM 173 O O . GLU A 1 24 ? 15.377 21.491 31.814 1.00 31.13 ? ? ? ? ? ? 1879 GLU A O 1 +ATOM 174 C CB . GLU A 1 24 ? 17.362 18.971 31.239 1.00 34.00 ? ? ? ? ? ? 1879 GLU A CB 1 +ATOM 175 C CG . GLU A 1 24 ? 17.390 17.463 31.079 1.00 42.64 ? ? ? ? ? ? 1879 GLU A CG 1 +ATOM 176 C CD . GLU A 1 24 ? 18.576 16.834 31.775 1.00 57.52 ? ? ? ? ? ? 1879 GLU A CD 1 +ATOM 177 O OE1 . GLU A 1 24 ? 19.720 17.088 31.343 1.00 59.47 ? ? ? ? ? ? 1879 GLU A OE1 1 +ATOM 178 O OE2 . GLU A 1 24 ? 18.365 16.095 32.759 1.00 68.87 ? ? ? ? ? ? 1879 GLU A OE2 1 +ATOM 179 N N A MET A 1 25 ? 16.894 21.946 30.214 0.50 29.83 ? ? ? ? ? ? 1880 MET A N 1 +ATOM 180 N N B MET A 1 25 ? 16.861 21.973 30.215 0.50 30.08 ? ? ? ? ? ? 1880 MET A N 1 +ATOM 181 C CA A MET A 1 25 ? 16.841 23.392 30.395 0.50 32.58 ? ? ? ? ? ? 1880 MET A CA 1 +ATOM 182 C CA B MET A 1 25 ? 16.776 23.400 30.498 0.50 33.02 ? ? ? ? ? ? 1880 MET A CA 1 +ATOM 183 C C A MET A 1 25 ? 15.470 23.918 30.013 0.50 35.67 ? ? ? ? ? ? 1880 MET A C 1 +ATOM 184 C C B MET A 1 25 ? 15.465 23.980 29.993 0.50 35.47 ? ? ? ? ? ? 1880 MET A C 1 +ATOM 185 O O A MET A 1 25 ? 14.851 24.668 30.763 0.50 33.66 ? ? ? ? ? ? 1880 MET A O 1 +ATOM 186 O O B MET A 1 25 ? 14.881 24.839 30.646 0.50 33.82 ? ? ? ? ? ? 1880 MET A O 1 +ATOM 187 C CB A MET A 1 25 ? 17.914 24.079 29.553 0.50 27.06 ? ? ? ? ? ? 1880 MET A CB 1 +ATOM 188 C CB B MET A 1 25 ? 17.952 24.144 29.886 0.50 29.17 ? ? ? ? ? ? 1880 MET A CB 1 +ATOM 189 C CG A MET A 1 25 ? 19.311 23.593 29.839 0.50 35.88 ? ? ? ? ? ? 1880 MET A CG 1 +ATOM 190 C CG B MET A 1 25 ? 19.275 23.710 30.456 0.50 37.28 ? ? ? ? ? ? 1880 MET A CG 1 +ATOM 191 S SD A MET A 1 25 ? 19.882 24.127 31.457 0.50 28.14 ? ? ? ? ? ? 1880 MET A SD 1 +ATOM 192 S SD B MET A 1 25 ? 20.611 24.675 29.769 0.50 50.99 ? ? ? ? ? ? 1880 MET A SD 1 +ATOM 193 C CE A MET A 1 25 ? 20.137 25.867 31.121 0.50 39.07 ? ? ? ? ? ? 1880 MET A CE 1 +ATOM 194 C CE B MET A 1 25 ? 20.256 26.231 30.541 0.50 42.98 ? ? ? ? ? ? 1880 MET A CE 1 +ATOM 195 N N . GLU A 1 26 ? 15.004 23.503 28.839 1.00 31.13 ? ? ? ? ? ? 1881 GLU A N 1 +ATOM 196 C CA . GLU A 1 26 ? 13.712 23.922 28.308 1.00 29.36 ? ? ? ? ? ? 1881 GLU A CA 1 +ATOM 197 C C . GLU A 1 26 ? 12.547 23.576 29.227 1.00 34.55 ? ? ? ? ? ? 1881 GLU A C 1 +ATOM 198 O O . GLU A 1 26 ? 11.561 24.305 29.284 1.00 32.96 ? ? ? ? ? ? 1881 GLU A O 1 +ATOM 199 C CB . GLU A 1 26 ? 13.474 23.286 26.935 1.00 32.30 ? ? ? ? ? ? 1881 GLU A CB 1 +ATOM 200 C CG . GLU A 1 26 ? 14.297 23.903 25.821 1.00 33.09 ? ? ? ? ? ? 1881 GLU A CG 1 +ATOM 201 C CD . GLU A 1 26 ? 14.350 23.025 24.574 1.00 38.42 ? ? ? ? ? ? 1881 GLU A CD 1 +ATOM 202 O OE1 . GLU A 1 26 ? 13.998 21.829 24.664 1.00 39.73 ? ? ? ? ? ? 1881 GLU A OE1 1 +ATOM 203 O OE2 . GLU A 1 26 ? 14.760 23.530 23.510 1.00 45.56 ? ? ? ? ? ? 1881 GLU A OE2 1 +ATOM 204 N N . THR A 1 27 ? 12.651 22.460 29.945 1.00 25.47 ? ? ? ? ? ? 1882 THR A N 1 +ATOM 205 C CA . THR A 1 27 ? 11.531 22.002 30.761 1.00 30.27 ? ? ? ? ? ? 1882 THR A CA 1 +ATOM 206 C C . THR A 1 27 ? 11.632 22.451 32.232 1.00 31.67 ? ? ? ? ? ? 1882 THR A C 1 +ATOM 207 O O . THR A 1 27 ? 10.696 22.263 33.008 1.00 34.96 ? ? ? ? ? ? 1882 THR A O 1 +ATOM 208 C CB . THR A 1 27 ? 11.394 20.460 30.692 1.00 33.67 ? ? ? ? ? ? 1882 THR A CB 1 +ATOM 209 O OG1 . THR A 1 27 ? 12.640 19.855 31.035 1.00 38.66 ? ? ? ? ? ? 1882 THR A OG1 1 +ATOM 210 C CG2 . THR A 1 27 ? 11.036 20.041 29.285 1.00 37.00 ? ? ? ? ? ? 1882 THR A CG2 1 +ATOM 211 N N . HIS A 1 28 ? 12.760 23.047 32.605 1.00 29.70 ? ? ? ? ? ? 1883 HIS A N 1 +ATOM 212 C CA . HIS A 1 28 ? 12.923 23.639 33.936 1.00 32.25 ? ? ? ? ? ? 1883 HIS A CA 1 +ATOM 213 C C . HIS A 1 28 ? 11.846 24.700 34.183 1.00 36.99 ? ? ? ? ? ? 1883 HIS A C 1 +ATOM 214 O O . HIS A 1 28 ? 11.529 25.487 33.293 1.00 30.64 ? ? ? ? ? ? 1883 HIS A O 1 +ATOM 215 C CB . HIS A 1 28 ? 14.320 24.251 34.061 1.00 30.48 ? ? ? ? ? ? 1883 HIS A CB 1 +ATOM 216 C CG . HIS A 1 28 ? 14.718 24.603 35.462 1.00 33.35 ? ? ? ? ? ? 1883 HIS A CG 1 +ATOM 217 N ND1 . HIS A 1 28 ? 14.036 25.526 36.223 1.00 36.28 ? ? ? ? ? ? 1883 HIS A ND1 1 +ATOM 218 C CD2 . HIS A 1 28 ? 15.757 24.182 36.222 1.00 30.70 ? ? ? ? ? ? 1883 HIS A CD2 1 +ATOM 219 C CE1 . HIS A 1 28 ? 14.626 25.647 37.401 1.00 34.92 ? ? ? ? ? ? 1883 HIS A CE1 1 +ATOM 220 N NE2 . HIS A 1 28 ? 15.672 24.843 37.425 1.00 39.78 ? ? ? ? ? ? 1883 HIS A NE2 1 +ATOM 221 N N . GLU A 1 29 ? 11.278 24.738 35.385 1.00 34.00 ? ? ? ? ? ? 1884 GLU A N 1 +ATOM 222 C CA . GLU A 1 29 ? 10.160 25.645 35.622 1.00 35.82 ? ? ? ? ? ? 1884 GLU A CA 1 +ATOM 223 C C . GLU A 1 29 ? 10.586 27.122 35.551 1.00 34.04 ? ? ? ? ? ? 1884 GLU A C 1 +ATOM 224 O O . GLU A 1 29 ? 9.746 28.004 35.369 1.00 36.46 ? ? ? ? ? ? 1884 GLU A O 1 +ATOM 225 C CB . GLU A 1 29 ? 9.483 25.343 36.969 1.00 49.90 ? ? ? ? ? ? 1884 GLU A CB 1 +ATOM 226 C CG . GLU A 1 29 ? 10.188 25.869 38.208 1.00 53.04 ? ? ? ? ? ? 1884 GLU A CG 1 +ATOM 227 C CD . GLU A 1 29 ? 9.307 25.790 39.459 1.00 68.03 ? ? ? ? ? ? 1884 GLU A CD 1 +ATOM 228 O OE1 . GLU A 1 29 ? 8.420 26.658 39.624 1.00 64.96 ? ? ? ? ? ? 1884 GLU A OE1 1 +ATOM 229 O OE2 . GLU A 1 29 ? 9.501 24.864 40.281 1.00 72.50 ? ? ? ? ? ? 1884 GLU A OE2 1 +ATOM 230 N N . ASP A 1 30 ? 11.882 27.391 35.668 1.00 30.65 ? ? ? ? ? ? 1885 ASP A N 1 +ATOM 231 C CA . ASP A 1 30 ? 12.369 28.766 35.569 1.00 33.88 ? ? ? ? ? ? 1885 ASP A CA 1 +ATOM 232 C C . ASP A 1 30 ? 12.913 29.088 34.175 1.00 33.81 ? ? ? ? ? ? 1885 ASP A C 1 +ATOM 233 O O . ASP A 1 30 ? 13.650 30.056 34.003 1.00 27.56 ? ? ? ? ? ? 1885 ASP A O 1 +ATOM 234 C CB . ASP A 1 30 ? 13.463 29.036 36.605 1.00 28.96 ? ? ? ? ? ? 1885 ASP A CB 1 +ATOM 235 C CG . ASP A 1 30 ? 12.966 28.918 38.042 1.00 31.94 ? ? ? ? ? ? 1885 ASP A CG 1 +ATOM 236 O OD1 . ASP A 1 30 ? 11.742 28.962 38.296 1.00 35.25 ? ? ? ? ? ? 1885 ASP A OD1 1 +ATOM 237 O OD2 . ASP A 1 30 ? 13.827 28.805 38.927 1.00 32.07 ? ? ? ? ? ? 1885 ASP A OD2 1 +ATOM 238 N N . ALA A 1 31 ? 12.558 28.279 33.181 1.00 29.61 ? ? ? ? ? ? 1886 ALA A N 1 +ATOM 239 C CA . ALA A 1 31 ? 13.059 28.492 31.823 1.00 28.61 ? ? ? ? ? ? 1886 ALA A CA 1 +ATOM 240 C C . ALA A 1 31 ? 12.324 29.611 31.095 1.00 26.63 ? ? ? ? ? ? 1886 ALA A C 1 +ATOM 241 O O . ALA A 1 31 ? 12.806 30.122 30.092 1.00 31.44 ? ? ? ? ? ? 1886 ALA A O 1 +ATOM 242 C CB . ALA A 1 31 ? 12.955 27.206 31.015 1.00 29.69 ? ? ? ? ? ? 1886 ALA A CB 1 +ATOM 243 N N . TRP A 1 32 ? 11.158 29.990 31.607 1.00 29.05 ? ? ? ? ? ? 1887 TRP A N 1 +ATOM 244 C CA . TRP A 1 32 ? 10.261 30.870 30.869 1.00 32.31 ? ? ? ? ? ? 1887 TRP A CA 1 +ATOM 245 C C . TRP A 1 32 ? 10.870 32.201 30.396 1.00 33.67 ? ? ? ? ? ? 1887 TRP A C 1 +ATOM 246 O O . TRP A 1 32 ? 10.483 32.682 29.337 1.00 34.21 ? ? ? ? ? ? 1887 TRP A O 1 +ATOM 247 C CB . TRP A 1 32 ? 8.996 31.146 31.691 1.00 34.38 ? ? ? ? ? ? 1887 TRP A CB 1 +ATOM 248 C CG . TRP A 1 32 ? 9.226 31.762 33.047 1.00 33.00 ? ? ? ? ? ? 1887 TRP A CG 1 +ATOM 249 C CD1 . TRP A 1 32 ? 9.416 31.096 34.231 1.00 28.53 ? ? ? ? ? ? 1887 TRP A CD1 1 +ATOM 250 C CD2 . TRP A 1 32 ? 9.259 33.161 33.360 1.00 34.53 ? ? ? ? ? ? 1887 TRP A CD2 1 +ATOM 251 N NE1 . TRP A 1 32 ? 9.578 32.000 35.257 1.00 30.56 ? ? ? ? ? ? 1887 TRP A NE1 1 +ATOM 252 C CE2 . TRP A 1 32 ? 9.492 33.273 34.749 1.00 35.49 ? ? ? ? ? ? 1887 TRP A CE2 1 +ATOM 253 C CE3 . TRP A 1 32 ? 9.139 34.330 32.600 1.00 33.60 ? ? ? ? ? ? 1887 TRP A CE3 1 +ATOM 254 C CZ2 . TRP A 1 32 ? 9.594 34.509 35.394 1.00 35.74 ? ? ? ? ? ? 1887 TRP A CZ2 1 +ATOM 255 C CZ3 . TRP A 1 32 ? 9.239 35.559 33.242 1.00 34.23 ? ? ? ? ? ? 1887 TRP A CZ3 1 +ATOM 256 C CH2 . TRP A 1 32 ? 9.463 35.638 34.625 1.00 35.07 ? ? ? ? ? ? 1887 TRP A CH2 1 +ATOM 257 N N . PRO A 1 33 ? 11.829 32.792 31.146 1.00 28.38 ? ? ? ? ? ? 1888 PRO A N 1 +ATOM 258 C CA . PRO A 1 33 ? 12.350 34.041 30.578 1.00 27.50 ? ? ? ? ? ? 1888 PRO A CA 1 +ATOM 259 C C . PRO A 1 33 ? 13.239 33.826 29.347 1.00 26.54 ? ? ? ? ? ? 1888 PRO A C 1 +ATOM 260 O O . PRO A 1 33 ? 13.584 34.806 28.679 1.00 27.61 ? ? ? ? ? ? 1888 PRO A O 1 +ATOM 261 C CB . PRO A 1 33 ? 13.180 34.638 31.733 1.00 28.19 ? ? ? ? ? ? 1888 PRO A CB 1 +ATOM 262 C CG . PRO A 1 33 ? 12.712 33.929 32.972 1.00 28.71 ? ? ? ? ? ? 1888 PRO A CG 1 +ATOM 263 C CD . PRO A 1 33 ? 12.373 32.550 32.496 1.00 25.46 ? ? ? ? ? ? 1888 PRO A CD 1 +ATOM 264 N N . PHE A 1 34 ? 13.588 32.572 29.062 1.00 28.06 ? ? ? ? ? ? 1889 PHE A N 1 +ATOM 265 C CA . PHE A 1 34 ? 14.655 32.264 28.111 1.00 27.14 ? ? ? ? ? ? 1889 PHE A CA 1 +ATOM 266 C C . PHE A 1 34 ? 14.199 31.419 26.939 1.00 26.62 ? ? ? ? ? ? 1889 PHE A C 1 +ATOM 267 O O . PHE A 1 34 ? 15.010 31.052 26.090 1.00 27.89 ? ? ? ? ? ? 1889 PHE A O 1 +ATOM 268 C CB . PHE A 1 34 ? 15.799 31.547 28.835 1.00 30.41 ? ? ? ? ? ? 1889 PHE A CB 1 +ATOM 269 C CG . PHE A 1 34 ? 16.170 32.186 30.136 1.00 29.02 ? ? ? ? ? ? 1889 PHE A CG 1 +ATOM 270 C CD1 . PHE A 1 34 ? 16.737 33.452 30.154 1.00 28.32 ? ? ? ? ? ? 1889 PHE A CD1 1 +ATOM 271 C CD2 . PHE A 1 34 ? 15.933 31.541 31.339 1.00 26.75 ? ? ? ? ? ? 1889 PHE A CD2 1 +ATOM 272 C CE1 . PHE A 1 34 ? 17.069 34.073 31.359 1.00 27.87 ? ? ? ? ? ? 1889 PHE A CE1 1 +ATOM 273 C CE2 . PHE A 1 34 ? 16.267 32.147 32.548 1.00 28.96 ? ? ? ? ? ? 1889 PHE A CE2 1 +ATOM 274 C CZ . PHE A 1 34 ? 16.840 33.419 32.556 1.00 30.62 ? ? ? ? ? ? 1889 PHE A CZ 1 +ATOM 275 N N . LEU A 1 35 ? 12.913 31.083 26.901 1.00 27.89 ? ? ? ? ? ? 1890 LEU A N 1 +ATOM 276 C CA . LEU A 1 35 ? 12.435 30.097 25.937 1.00 31.41 ? ? ? ? ? ? 1890 LEU A CA 1 +ATOM 277 C C . LEU A 1 35 ? 12.409 30.654 24.523 1.00 36.61 ? ? ? ? ? ? 1890 LEU A C 1 +ATOM 278 O O . LEU A 1 35 ? 12.694 29.937 23.567 1.00 29.63 ? ? ? ? ? ? 1890 LEU A O 1 +ATOM 279 C CB . LEU A 1 35 ? 11.042 29.594 26.326 1.00 29.84 ? ? ? ? ? ? 1890 LEU A CB 1 +ATOM 280 C CG . LEU A 1 35 ? 11.004 28.701 27.566 1.00 32.90 ? ? ? ? ? ? 1890 LEU A CG 1 +ATOM 281 C CD1 . LEU A 1 35 ? 9.569 28.385 27.953 1.00 34.21 ? ? ? ? ? ? 1890 LEU A CD1 1 +ATOM 282 C CD2 . LEU A 1 35 ? 11.793 27.421 27.314 1.00 39.56 ? ? ? ? ? ? 1890 LEU A CD2 1 +ATOM 283 N N . LEU A 1 36 ? 12.075 31.934 24.407 1.00 28.94 ? ? ? ? ? ? 1891 LEU A N 1 +ATOM 284 C CA . LEU A 1 36 ? 11.895 32.575 23.112 1.00 30.89 ? ? ? ? ? ? 1891 LEU A CA 1 +ATOM 285 C C . LEU A 1 36 ? 12.724 33.845 23.030 1.00 33.60 ? ? ? ? ? ? 1891 LEU A C 1 +ATOM 286 O O . LEU A 1 36 ? 13.086 34.417 24.064 1.00 29.30 ? ? ? ? ? ? 1891 LEU A O 1 +ATOM 287 C CB . LEU A 1 36 ? 10.419 32.893 22.884 1.00 35.28 ? ? ? ? ? ? 1891 LEU A CB 1 +ATOM 288 C CG . LEU A 1 36 ? 9.467 31.700 22.830 1.00 35.57 ? ? ? ? ? ? 1891 LEU A CG 1 +ATOM 289 C CD1 . LEU A 1 36 ? 8.034 32.196 22.731 1.00 39.91 ? ? ? ? ? ? 1891 LEU A CD1 1 +ATOM 290 C CD2 . LEU A 1 36 ? 9.805 30.796 21.657 1.00 41.14 ? ? ? ? ? ? 1891 LEU A CD2 1 +ATOM 291 N N . PRO A 1 37 ? 13.034 34.296 21.801 1.00 29.55 ? ? ? ? ? ? 1892 PRO A N 1 +ATOM 292 C CA . PRO A 1 37 ? 13.814 35.533 21.691 1.00 27.16 ? ? ? ? ? ? 1892 PRO A CA 1 +ATOM 293 C C . PRO A 1 37 ? 13.045 36.734 22.242 1.00 25.28 ? ? ? ? ? ? 1892 PRO A C 1 +ATOM 294 O O . PRO A 1 37 ? 11.820 36.781 22.132 1.00 30.03 ? ? ? ? ? ? 1892 PRO A O 1 +ATOM 295 C CB . PRO A 1 37 ? 14.056 35.674 20.176 1.00 31.06 ? ? ? ? ? ? 1892 PRO A CB 1 +ATOM 296 C CG . PRO A 1 37 ? 13.058 34.797 19.530 1.00 30.15 ? ? ? ? ? ? 1892 PRO A CG 1 +ATOM 297 C CD . PRO A 1 37 ? 12.741 33.696 20.481 1.00 27.23 ? ? ? ? ? ? 1892 PRO A CD 1 +ATOM 298 N N . VAL A 1 38 ? 13.758 37.666 22.864 1.00 29.36 ? ? ? ? ? ? 1893 VAL A N 1 +ATOM 299 C CA . VAL A 1 38 ? 13.161 38.932 23.290 1.00 31.65 ? ? ? ? ? ? 1893 VAL A CA 1 +ATOM 300 C C . VAL A 1 38 ? 12.647 39.692 22.076 1.00 39.03 ? ? ? ? ? ? 1893 VAL A C 1 +ATOM 301 O O . VAL A 1 38 ? 13.336 39.764 21.056 1.00 37.18 ? ? ? ? ? ? 1893 VAL A O 1 +ATOM 302 C CB . VAL A 1 38 ? 14.175 39.803 24.058 1.00 35.58 ? ? ? ? ? ? 1893 VAL A CB 1 +ATOM 303 C CG1 . VAL A 1 38 ? 13.634 41.215 24.274 1.00 37.63 ? ? ? ? ? ? 1893 VAL A CG1 1 +ATOM 304 C CG2 . VAL A 1 38 ? 14.528 39.150 25.388 1.00 34.79 ? ? ? ? ? ? 1893 VAL A CG2 1 +ATOM 305 N N . ASN A 1 39 ? 11.425 40.216 22.168 1.00 39.34 ? ? ? ? ? ? 1894 ASN A N 1 +ATOM 306 C CA . ASN A 1 39 ? 10.860 41.038 21.102 1.00 47.30 ? ? ? ? ? ? 1894 ASN A CA 1 +ATOM 307 C C . ASN A 1 39 ? 11.486 42.426 21.145 1.00 43.68 ? ? ? ? ? ? 1894 ASN A C 1 +ATOM 308 O O . ASN A 1 39 ? 11.179 43.228 22.023 1.00 43.55 ? ? ? ? ? ? 1894 ASN A O 1 +ATOM 309 C CB . ASN A 1 39 ? 9.335 41.130 21.229 1.00 47.40 ? ? ? ? ? ? 1894 ASN A CB 1 +ATOM 310 C CG . ASN A 1 39 ? 8.686 41.844 20.053 1.00 50.62 ? ? ? ? ? ? 1894 ASN A CG 1 +ATOM 311 O OD1 . ASN A 1 39 ? 9.260 42.764 19.468 1.00 51.95 ? ? ? ? ? ? 1894 ASN A OD1 1 +ATOM 312 N ND2 . ASN A 1 39 ? 7.479 41.424 19.705 1.00 48.95 ? ? ? ? ? ? 1894 ASN A ND2 1 +ATOM 313 N N . LEU A 1 40 ? 12.356 42.701 20.179 1.00 42.52 ? ? ? ? ? ? 1895 LEU A N 1 +ATOM 314 C CA . LEU A 1 40 ? 13.168 43.910 20.186 1.00 40.45 ? ? ? ? ? ? 1895 LEU A CA 1 +ATOM 315 C C . LEU A 1 40 ? 12.364 45.167 19.869 1.00 41.59 ? ? ? ? ? ? 1895 LEU A C 1 +ATOM 316 O O . LEU A 1 40 ? 12.845 46.289 20.060 1.00 40.45 ? ? ? ? ? ? 1895 LEU A O 1 +ATOM 317 C CB . LEU A 1 40 ? 14.322 43.760 19.193 1.00 42.57 ? ? ? ? ? ? 1895 LEU A CB 1 +ATOM 318 C CG . LEU A 1 40 ? 15.246 42.566 19.440 1.00 44.45 ? ? ? ? ? ? 1895 LEU A CG 1 +ATOM 319 C CD1 . LEU A 1 40 ? 16.345 42.506 18.379 1.00 48.93 ? ? ? ? ? ? 1895 LEU A CD1 1 +ATOM 320 C CD2 . LEU A 1 40 ? 15.835 42.620 20.854 1.00 40.29 ? ? ? ? ? ? 1895 LEU A CD2 1 +ATOM 321 N N . LYS A 1 41 ? 11.138 44.982 19.391 1.00 49.11 ? ? ? ? ? ? 1896 LYS A N 1 +ATOM 322 C CA . LYS A 1 41 ? 10.271 46.113 19.099 1.00 57.85 ? ? ? ? ? ? 1896 LYS A CA 1 +ATOM 323 C C . LYS A 1 41 ? 9.396 46.467 20.298 1.00 58.57 ? ? ? ? ? ? 1896 LYS A C 1 +ATOM 324 O O . LYS A 1 41 ? 8.780 47.529 20.324 1.00 58.04 ? ? ? ? ? ? 1896 LYS A O 1 +ATOM 325 C CB . LYS A 1 41 ? 9.395 45.822 17.876 1.00 61.41 ? ? ? ? ? ? 1896 LYS A CB 1 +ATOM 326 C CG . LYS A 1 41 ? 10.183 45.455 16.627 1.00 66.66 ? ? ? ? ? ? 1896 LYS A CG 1 +ATOM 327 C CD . LYS A 1 41 ? 9.506 45.982 15.364 1.00 80.59 ? ? ? ? ? ? 1896 LYS A CD 1 +ATOM 328 C CE . LYS A 1 41 ? 8.207 45.248 15.057 1.00 89.11 ? ? ? ? ? ? 1896 LYS A CE 1 +ATOM 329 N NZ . LYS A 1 41 ? 8.440 43.883 14.504 1.00 90.85 ? ? ? ? ? ? 1896 LYS A NZ 1 +ATOM 330 N N . LEU A 1 42 ? 9.344 45.589 21.296 1.00 51.72 ? ? ? ? ? ? 1897 LEU A N 1 +ATOM 331 C CA . LEU A 1 42 ? 8.461 45.825 22.437 1.00 56.54 ? ? ? ? ? ? 1897 LEU A CA 1 +ATOM 332 C C . LEU A 1 42 ? 9.205 46.067 23.744 1.00 55.52 ? ? ? ? ? ? 1897 LEU A C 1 +ATOM 333 O O . LEU A 1 42 ? 8.626 46.570 24.704 1.00 60.78 ? ? ? ? ? ? 1897 LEU A O 1 +ATOM 334 C CB . LEU A 1 42 ? 7.495 44.656 22.615 1.00 52.50 ? ? ? ? ? ? 1897 LEU A CB 1 +ATOM 335 C CG . LEU A 1 42 ? 6.563 44.373 21.433 1.00 64.69 ? ? ? ? ? ? 1897 LEU A CG 1 +ATOM 336 C CD1 . LEU A 1 42 ? 5.508 43.344 21.818 1.00 69.25 ? ? ? ? ? ? 1897 LEU A CD1 1 +ATOM 337 C CD2 . LEU A 1 42 ? 5.915 45.651 20.923 1.00 68.57 ? ? ? ? ? ? 1897 LEU A CD2 1 +ATOM 338 N N . VAL A 1 43 ? 10.484 45.716 23.784 1.00 45.98 ? ? ? ? ? ? 1898 VAL A N 1 +ATOM 339 C CA . VAL A 1 43 ? 11.266 45.878 25.004 1.00 42.42 ? ? ? ? ? ? 1898 VAL A CA 1 +ATOM 340 C C . VAL A 1 43 ? 12.303 46.989 24.850 1.00 41.98 ? ? ? ? ? ? 1898 VAL A C 1 +ATOM 341 O O . VAL A 1 43 ? 13.318 46.808 24.174 1.00 39.52 ? ? ? ? ? ? 1898 VAL A O 1 +ATOM 342 C CB . VAL A 1 43 ? 11.976 44.571 25.396 1.00 42.66 ? ? ? ? ? ? 1898 VAL A CB 1 +ATOM 343 C CG1 . VAL A 1 43 ? 12.746 44.759 26.696 1.00 42.08 ? ? ? ? ? ? 1898 VAL A CG1 1 +ATOM 344 C CG2 . VAL A 1 43 ? 10.965 43.431 25.515 1.00 40.06 ? ? ? ? ? ? 1898 VAL A CG2 1 +ATOM 345 N N . PRO A 1 44 ? 12.045 48.151 25.476 1.00 40.07 ? ? ? ? ? ? 1899 PRO A N 1 +ATOM 346 C CA . PRO A 1 44 ? 12.974 49.281 25.405 1.00 40.44 ? ? ? ? ? ? 1899 PRO A CA 1 +ATOM 347 C C . PRO A 1 44 ? 14.377 48.914 25.877 1.00 41.94 ? ? ? ? ? ? 1899 PRO A C 1 +ATOM 348 O O . PRO A 1 44 ? 14.525 48.134 26.821 1.00 38.75 ? ? ? ? ? ? 1899 PRO A O 1 +ATOM 349 C CB . PRO A 1 44 ? 12.337 50.325 26.338 1.00 47.77 ? ? ? ? ? ? 1899 PRO A CB 1 +ATOM 350 C CG . PRO A 1 44 ? 10.892 49.974 26.362 1.00 50.19 ? ? ? ? ? ? 1899 PRO A CG 1 +ATOM 351 C CD . PRO A 1 44 ? 10.840 48.473 26.260 1.00 42.99 ? ? ? ? ? ? 1899 PRO A CD 1 +ATOM 352 N N . GLY A 1 45 ? 15.389 49.449 25.202 1.00 33.46 ? ? ? ? ? ? 1900 GLY A N 1 +ATOM 353 C CA . GLY A 1 45 ? 16.771 49.217 25.580 1.00 32.23 ? ? ? ? ? ? 1900 GLY A CA 1 +ATOM 354 C C . GLY A 1 45 ? 17.421 47.944 25.066 1.00 33.36 ? ? ? ? ? ? 1900 GLY A C 1 +ATOM 355 O O . GLY A 1 45 ? 18.625 47.926 24.815 1.00 35.28 ? ? ? ? ? ? 1900 GLY A O 1 +ATOM 356 N N . TYR A 1 46 ? 16.646 46.876 24.903 1.00 32.27 ? ? ? ? ? ? 1901 TYR A N 1 +ATOM 357 C CA . TYR A 1 46 ? 17.257 45.557 24.700 1.00 30.42 ? ? ? ? ? ? 1901 TYR A CA 1 +ATOM 358 C C . TYR A 1 46 ? 18.127 45.468 23.444 1.00 36.14 ? ? ? ? ? ? 1901 TYR A C 1 +ATOM 359 O O . TYR A 1 46 ? 19.244 44.943 23.500 1.00 30.38 ? ? ? ? ? ? 1901 TYR A O 1 +ATOM 360 C CB . TYR A 1 46 ? 16.198 44.459 24.660 1.00 34.29 ? ? ? ? ? ? 1901 TYR A CB 1 +ATOM 361 C CG . TYR A 1 46 ? 16.781 43.117 25.064 1.00 35.59 ? ? ? ? ? ? 1901 TYR A CG 1 +ATOM 362 C CD1 . TYR A 1 46 ? 17.358 42.268 24.123 1.00 30.79 ? ? ? ? ? ? 1901 TYR A CD1 1 +ATOM 363 C CD2 . TYR A 1 46 ? 16.801 42.728 26.401 1.00 30.40 ? ? ? ? ? ? 1901 TYR A CD2 1 +ATOM 364 C CE1 . TYR A 1 46 ? 17.915 41.043 24.505 1.00 31.12 ? ? ? ? ? ? 1901 TYR A CE1 1 +ATOM 365 C CE2 . TYR A 1 46 ? 17.353 41.512 26.791 1.00 34.55 ? ? ? ? ? ? 1901 TYR A CE2 1 +ATOM 366 C CZ . TYR A 1 46 ? 17.909 40.678 25.843 1.00 36.23 ? ? ? ? ? ? 1901 TYR A CZ 1 +ATOM 367 O OH . TYR A 1 46 ? 18.459 39.483 26.247 1.00 32.02 ? ? ? ? ? ? 1901 TYR A OH 1 +ATOM 368 N N . LYS A 1 47 ? 17.634 45.987 22.322 1.00 37.30 ? ? ? ? ? ? 1902 LYS A N 1 +ATOM 369 C CA . LYS A 1 47 ? 18.369 45.871 21.066 1.00 37.06 ? ? ? ? ? ? 1902 LYS A CA 1 +ATOM 370 C C . LYS A 1 47 ? 19.692 46.641 21.093 1.00 32.98 ? ? ? ? ? ? 1902 LYS A C 1 +ATOM 371 O O . LYS A 1 47 ? 20.710 46.152 20.601 1.00 38.46 ? ? ? ? ? ? 1902 LYS A O 1 +ATOM 372 C CB . LYS A 1 47 ? 17.509 46.348 19.890 1.00 37.99 ? ? ? ? ? ? 1902 LYS A CB 1 +ATOM 373 C CG . LYS A 1 47 ? 18.141 46.051 18.527 1.00 40.43 ? ? ? ? ? ? 1902 LYS A CG 1 +ATOM 374 C CD . LYS A 1 47 ? 17.258 46.494 17.371 1.00 42.73 ? ? ? ? ? ? 1902 LYS A CD 1 +ATOM 375 C CE . LYS A 1 47 ? 17.951 46.245 16.036 1.00 50.85 ? ? ? ? ? ? 1902 LYS A CE 1 +ATOM 376 N NZ . LYS A 1 47 ? 17.207 46.890 14.923 1.00 57.37 ? ? ? ? ? ? 1902 LYS A NZ 1 +ATOM 377 N N . LYS A 1 48 ? 19.683 47.838 21.673 1.00 32.27 ? ? ? ? ? ? 1903 LYS A N 1 +ATOM 378 C CA . LYS A 1 48 ? 20.895 48.649 21.746 1.00 32.40 ? ? ? ? ? ? 1903 LYS A CA 1 +ATOM 379 C C . LYS A 1 48 ? 21.882 48.107 22.787 1.00 35.38 ? ? ? ? ? ? 1903 LYS A C 1 +ATOM 380 O O . LYS A 1 48 ? 23.098 48.167 22.607 1.00 36.08 ? ? ? ? ? ? 1903 LYS A O 1 +ATOM 381 C CB . LYS A 1 48 ? 20.543 50.111 22.073 1.00 33.13 ? ? ? ? ? ? 1903 LYS A CB 1 +ATOM 382 C CG . LYS A 1 48 ? 21.739 51.039 22.110 1.00 34.50 ? ? ? ? ? ? 1903 LYS A CG 1 +ATOM 383 C CD . LYS A 1 48 ? 22.399 51.137 20.737 1.00 39.54 ? ? ? ? ? ? 1903 LYS A CD 1 +ATOM 384 C CE . LYS A 1 48 ? 23.422 52.266 20.683 1.00 37.79 ? ? ? ? ? ? 1903 LYS A CE 1 +ATOM 385 N NZ . LYS A 1 48 ? 22.789 53.615 20.601 1.00 37.62 ? ? ? ? ? ? 1903 LYS A NZ 1 +ATOM 386 N N . VAL A 1 49 ? 21.351 47.577 23.880 1.00 30.58 ? ? ? ? ? ? 1904 VAL A N 1 +ATOM 387 C CA . VAL A 1 49 ? 22.188 47.139 24.992 1.00 32.15 ? ? ? ? ? ? 1904 VAL A CA 1 +ATOM 388 C C . VAL A 1 49 ? 22.761 45.735 24.761 1.00 34.56 ? ? ? ? ? ? 1904 VAL A C 1 +ATOM 389 O O . VAL A 1 49 ? 23.956 45.509 24.950 1.00 33.83 ? ? ? ? ? ? 1904 VAL A O 1 +ATOM 390 C CB . VAL A 1 49 ? 21.398 47.184 26.317 1.00 30.41 ? ? ? ? ? ? 1904 VAL A CB 1 +ATOM 391 C CG1 . VAL A 1 49 ? 22.159 46.483 27.445 1.00 31.36 ? ? ? ? ? ? 1904 VAL A CG1 1 +ATOM 392 C CG2 . VAL A 1 49 ? 21.081 48.650 26.706 1.00 30.57 ? ? ? ? ? ? 1904 VAL A CG2 1 +ATOM 393 N N . ILE A 1 50 ? 21.920 44.799 24.336 1.00 30.97 ? ? ? ? ? ? 1905 ILE A N 1 +ATOM 394 C CA . ILE A 1 50 ? 22.343 43.402 24.225 1.00 32.63 ? ? ? ? ? ? 1905 ILE A CA 1 +ATOM 395 C C . ILE A 1 50 ? 22.824 43.113 22.811 1.00 36.52 ? ? ? ? ? ? 1905 ILE A C 1 +ATOM 396 O O . ILE A 1 50 ? 22.019 42.933 21.902 1.00 33.48 ? ? ? ? ? ? 1905 ILE A O 1 +ATOM 397 C CB . ILE A 1 50 ? 21.203 42.441 24.604 1.00 31.55 ? ? ? ? ? ? 1905 ILE A CB 1 +ATOM 398 C CG1 . ILE A 1 50 ? 20.724 42.736 26.029 1.00 35.63 ? ? ? ? ? ? 1905 ILE A CG1 1 +ATOM 399 C CG2 . ILE A 1 50 ? 21.638 40.961 24.450 1.00 25.75 ? ? ? ? ? ? 1905 ILE A CG2 1 +ATOM 400 C CD1 . ILE A 1 50 ? 21.817 42.611 27.087 1.00 30.40 ? ? ? ? ? ? 1905 ILE A CD1 1 +ATOM 401 N N . LYS A 1 51 ? 24.140 43.070 22.635 1.00 32.04 ? ? ? ? ? ? 1906 LYS A N 1 +ATOM 402 C CA . LYS A 1 51 ? 24.726 43.008 21.302 1.00 37.03 ? ? ? ? ? ? 1906 LYS A CA 1 +ATOM 403 C C . LYS A 1 51 ? 24.508 41.665 20.624 1.00 42.60 ? ? ? ? ? ? 1906 LYS A C 1 +ATOM 404 O O . LYS A 1 51 ? 24.452 41.591 19.401 1.00 36.95 ? ? ? ? ? ? 1906 LYS A O 1 +ATOM 405 C CB . LYS A 1 51 ? 26.222 43.317 21.366 1.00 43.52 ? ? ? ? ? ? 1906 LYS A CB 1 +ATOM 406 C CG . LYS A 1 51 ? 26.531 44.687 21.956 1.00 51.77 ? ? ? ? ? ? 1906 LYS A CG 1 +ATOM 407 C CD . LYS A 1 51 ? 25.713 45.780 21.283 1.00 56.04 ? ? ? ? ? ? 1906 LYS A CD 1 +ATOM 408 C CE . LYS A 1 51 ? 26.063 47.155 21.843 1.00 60.15 ? ? ? ? ? ? 1906 LYS A CE 1 +ATOM 409 N NZ . LYS A 1 51 ? 25.459 48.252 21.038 1.00 68.25 ? ? ? ? ? ? 1906 LYS A NZ 1 +ATOM 410 N N . LYS A 1 52 ? 24.400 40.606 21.421 1.00 32.40 ? ? ? ? ? ? 1907 LYS A N 1 +ATOM 411 C CA . LYS A 1 52 ? 24.177 39.271 20.878 1.00 38.26 ? ? ? ? ? ? 1907 LYS A CA 1 +ATOM 412 C C . LYS A 1 52 ? 23.059 38.573 21.636 1.00 32.50 ? ? ? ? ? ? 1907 LYS A C 1 +ATOM 413 O O . LYS A 1 52 ? 23.324 37.822 22.566 1.00 32.01 ? ? ? ? ? ? 1907 LYS A O 1 +ATOM 414 C CB . LYS A 1 52 ? 25.451 38.425 20.954 1.00 40.79 ? ? ? ? ? ? 1907 LYS A CB 1 +ATOM 415 C CG . LYS A 1 52 ? 26.658 38.995 20.226 1.00 52.88 ? ? ? ? ? ? 1907 LYS A CG 1 +ATOM 416 C CD . LYS A 1 52 ? 27.825 38.022 20.317 1.00 64.25 ? ? ? ? ? ? 1907 LYS A CD 1 +ATOM 417 C CE . LYS A 1 52 ? 29.103 38.594 19.730 1.00 70.75 ? ? ? ? ? ? 1907 LYS A CE 1 +ATOM 418 N NZ . LYS A 1 52 ? 30.235 37.639 19.894 1.00 74.50 ? ? ? ? ? ? 1907 LYS A NZ 1 +ATOM 419 N N . PRO A 1 53 ? 21.805 38.835 21.249 1.00 34.48 ? ? ? ? ? ? 1908 PRO A N 1 +ATOM 420 C CA . PRO A 1 53 ? 20.656 38.155 21.850 1.00 35.95 ? ? ? ? ? ? 1908 PRO A CA 1 +ATOM 421 C C . PRO A 1 53 ? 20.735 36.641 21.643 1.00 32.19 ? ? ? ? ? ? 1908 PRO A C 1 +ATOM 422 O O . PRO A 1 53 ? 21.178 36.187 20.593 1.00 29.35 ? ? ? ? ? ? 1908 PRO A O 1 +ATOM 423 C CB . PRO A 1 53 ? 19.462 38.744 21.090 1.00 32.29 ? ? ? ? ? ? 1908 PRO A CB 1 +ATOM 424 C CG . PRO A 1 53 ? 19.952 40.057 20.564 1.00 35.82 ? ? ? ? ? ? 1908 PRO A CG 1 +ATOM 425 C CD . PRO A 1 53 ? 21.391 39.810 20.226 1.00 40.19 ? ? ? ? ? ? 1908 PRO A CD 1 +ATOM 426 N N . MET A 1 54 ? 20.317 35.874 22.638 1.00 31.14 ? ? ? ? ? ? 1909 MET A N 1 +ATOM 427 C CA . MET A 1 54 ? 20.273 34.420 22.502 1.00 31.21 ? ? ? ? ? ? 1909 MET A CA 1 +ATOM 428 C C . MET A 1 54 ? 19.186 33.889 23.421 1.00 36.10 ? ? ? ? ? ? 1909 MET A C 1 +ATOM 429 O O . MET A 1 54 ? 18.899 34.476 24.464 1.00 32.24 ? ? ? ? ? ? 1909 MET A O 1 +ATOM 430 C CB . MET A 1 54 ? 21.632 33.786 22.821 1.00 27.46 ? ? ? ? ? ? 1909 MET A CB 1 +ATOM 431 C CG . MET A 1 54 ? 21.703 32.276 22.560 1.00 30.39 ? ? ? ? ? ? 1909 MET A CG 1 +ATOM 432 S SD . MET A 1 54 ? 21.231 31.849 20.860 1.00 31.61 ? ? ? ? ? ? 1909 MET A SD 1 +ATOM 433 C CE . MET A 1 54 ? 22.413 32.841 19.935 1.00 31.97 ? ? ? ? ? ? 1909 MET A CE 1 +ATOM 434 N N . ASP A 1 55 ? 18.559 32.797 23.006 1.00 28.10 ? ? ? ? ? ? 1910 ASP A N 1 +ATOM 435 C CA . ASP A 1 55 ? 17.488 32.167 23.764 1.00 26.44 ? ? ? ? ? ? 1910 ASP A CA 1 +ATOM 436 C C . ASP A 1 55 ? 17.478 30.676 23.438 1.00 27.11 ? ? ? ? ? ? 1910 ASP A C 1 +ATOM 437 O O . ASP A 1 55 ? 18.103 30.252 22.462 1.00 28.75 ? ? ? ? ? ? 1910 ASP A O 1 +ATOM 438 C CB . ASP A 1 55 ? 16.142 32.797 23.420 1.00 30.13 ? ? ? ? ? ? 1910 ASP A CB 1 +ATOM 439 C CG . ASP A 1 55 ? 15.704 32.466 22.000 1.00 36.62 ? ? ? ? ? ? 1910 ASP A CG 1 +ATOM 440 O OD1 . ASP A 1 55 ? 16.234 33.093 21.063 1.00 31.77 ? ? ? ? ? ? 1910 ASP A OD1 1 +ATOM 441 O OD2 . ASP A 1 55 ? 14.859 31.562 21.821 1.00 31.86 ? ? ? ? ? ? 1910 ASP A OD2 1 +ATOM 442 N N . PHE A 1 56 ? 16.754 29.888 24.235 1.00 24.97 ? ? ? ? ? ? 1911 PHE A N 1 +ATOM 443 C CA . PHE A 1 56 ? 16.744 28.437 24.077 1.00 27.50 ? ? ? ? ? ? 1911 PHE A CA 1 +ATOM 444 C C . PHE A 1 56 ? 16.227 27.982 22.709 1.00 26.99 ? ? ? ? ? ? 1911 PHE A C 1 +ATOM 445 O O . PHE A 1 56 ? 16.751 27.029 22.142 1.00 25.02 ? ? ? ? ? ? 1911 PHE A O 1 +ATOM 446 C CB . PHE A 1 56 ? 15.903 27.769 25.174 1.00 27.27 ? ? ? ? ? ? 1911 PHE A CB 1 +ATOM 447 C CG . PHE A 1 56 ? 16.472 27.918 26.573 1.00 31.18 ? ? ? ? ? ? 1911 PHE A CG 1 +ATOM 448 C CD1 . PHE A 1 56 ? 17.757 28.402 26.783 1.00 26.63 ? ? ? ? ? ? 1911 PHE A CD1 1 +ATOM 449 C CD2 . PHE A 1 56 ? 15.715 27.551 27.681 1.00 27.78 ? ? ? ? ? ? 1911 PHE A CD2 1 +ATOM 450 C CE1 . PHE A 1 56 ? 18.268 28.534 28.077 1.00 27.00 ? ? ? ? ? ? 1911 PHE A CE1 1 +ATOM 451 C CE2 . PHE A 1 56 ? 16.224 27.670 28.970 1.00 28.79 ? ? ? ? ? ? 1911 PHE A CE2 1 +ATOM 452 C CZ . PHE A 1 56 ? 17.500 28.165 29.165 1.00 30.35 ? ? ? ? ? ? 1911 PHE A CZ 1 +ATOM 453 N N . SER A 1 57 ? 15.190 28.633 22.191 1.00 26.47 ? ? ? ? ? ? 1912 SER A N 1 +ATOM 454 C CA . SER A 1 57 ? 14.603 28.194 20.930 1.00 33.83 ? ? ? ? ? ? 1912 SER A CA 1 +ATOM 455 C C . SER A 1 57 ? 15.586 28.418 19.779 1.00 34.95 ? ? ? ? ? ? 1912 SER A C 1 +ATOM 456 O O . SER A 1 57 ? 15.630 27.642 18.820 1.00 28.99 ? ? ? ? ? ? 1912 SER A O 1 +ATOM 457 C CB . SER A 1 57 ? 13.281 28.913 20.652 1.00 33.80 ? ? ? ? ? ? 1912 SER A CB 1 +ATOM 458 O OG . SER A 1 57 ? 13.496 30.242 20.197 1.00 38.46 ? ? ? ? ? ? 1912 SER A OG 1 +ATOM 459 N N . THR A 1 58 ? 16.388 29.471 19.885 1.00 31.25 ? ? ? ? ? ? 1913 THR A N 1 +ATOM 460 C CA . THR A 1 58 ? 17.395 29.745 18.866 1.00 31.67 ? ? ? ? ? ? 1913 THR A CA 1 +ATOM 461 C C . THR A 1 58 ? 18.520 28.719 18.986 1.00 29.55 ? ? ? ? ? ? 1913 THR A C 1 +ATOM 462 O O . THR A 1 58 ? 19.008 28.205 17.984 1.00 34.32 ? ? ? ? ? ? 1913 THR A O 1 +ATOM 463 C CB . THR A 1 58 ? 17.940 31.187 18.983 1.00 30.13 ? ? ? ? ? ? 1913 THR A CB 1 +ATOM 464 O OG1 . THR A 1 58 ? 16.860 32.105 18.780 1.00 29.32 ? ? ? ? ? ? 1913 THR A OG1 1 +ATOM 465 C CG2 . THR A 1 58 ? 19.016 31.461 17.927 1.00 31.08 ? ? ? ? ? ? 1913 THR A CG2 1 +ATOM 466 N N . ILE A 1 59 ? 18.918 28.414 20.218 1.00 25.28 ? ? ? ? ? ? 1914 ILE A N 1 +ATOM 467 C CA . ILE A 1 59 ? 19.932 27.393 20.446 1.00 26.38 ? ? ? ? ? ? 1914 ILE A CA 1 +ATOM 468 C C . ILE A 1 59 ? 19.460 26.062 19.866 1.00 30.29 ? ? ? ? ? ? 1914 ILE A C 1 +ATOM 469 O O . ILE A 1 59 ? 20.231 25.338 19.228 1.00 30.05 ? ? ? ? ? ? 1914 ILE A O 1 +ATOM 470 C CB . ILE A 1 59 ? 20.247 27.240 21.947 1.00 26.58 ? ? ? ? ? ? 1914 ILE A CB 1 +ATOM 471 C CG1 . ILE A 1 59 ? 20.925 28.510 22.466 1.00 26.62 ? ? ? ? ? ? 1914 ILE A CG1 1 +ATOM 472 C CG2 . ILE A 1 59 ? 21.136 26.013 22.205 1.00 21.45 ? ? ? ? ? ? 1914 ILE A CG2 1 +ATOM 473 C CD1 . ILE A 1 59 ? 21.130 28.533 23.994 1.00 24.52 ? ? ? ? ? ? 1914 ILE A CD1 1 +ATOM 474 N N . ARG A 1 60 ? 18.183 25.757 20.077 1.00 29.81 ? ? ? ? ? ? 1915 ARG A N 1 +ATOM 475 C CA . ARG A 1 60 ? 17.607 24.512 19.602 1.00 30.33 ? ? ? ? ? ? 1915 ARG A CA 1 +ATOM 476 C C . ARG A 1 60 ? 17.611 24.470 18.072 1.00 35.06 ? ? ? ? ? ? 1915 ARG A C 1 +ATOM 477 O O . ARG A 1 60 ? 17.918 23.437 17.476 1.00 31.40 ? ? ? ? ? ? 1915 ARG A O 1 +ATOM 478 C CB . ARG A 1 60 ? 16.188 24.338 20.151 1.00 28.64 ? ? ? ? ? ? 1915 ARG A CB 1 +ATOM 479 C CG . ARG A 1 60 ? 15.384 23.225 19.497 1.00 29.90 ? ? ? ? ? ? 1915 ARG A CG 1 +ATOM 480 C CD . ARG A 1 60 ? 15.922 21.873 19.869 1.00 33.14 ? ? ? ? ? ? 1915 ARG A CD 1 +ATOM 481 N NE . ARG A 1 60 ? 15.700 21.544 21.276 1.00 35.58 ? ? ? ? ? ? 1915 ARG A NE 1 +ATOM 482 C CZ . ARG A 1 60 ? 16.197 20.459 21.861 1.00 40.70 ? ? ? ? ? ? 1915 ARG A CZ 1 +ATOM 483 N NH1 . ARG A 1 60 ? 16.937 19.615 21.157 1.00 35.66 ? ? ? ? ? ? 1915 ARG A NH1 1 +ATOM 484 N NH2 . ARG A 1 60 ? 15.958 20.219 23.141 1.00 37.90 ? ? ? ? ? ? 1915 ARG A NH2 1 +ATOM 485 N N . GLU A 1 61 ? 17.295 25.596 17.435 1.00 29.84 ? ? ? ? ? ? 1916 GLU A N 1 +ATOM 486 C CA . GLU A 1 61 ? 17.260 25.633 15.973 1.00 30.91 ? ? ? ? ? ? 1916 GLU A CA 1 +ATOM 487 C C . GLU A 1 61 ? 18.666 25.472 15.398 1.00 29.06 ? ? ? ? ? ? 1916 GLU A C 1 +ATOM 488 O O . GLU A 1 61 ? 18.861 24.764 14.401 1.00 31.85 ? ? ? ? ? ? 1916 GLU A O 1 +ATOM 489 C CB . GLU A 1 61 ? 16.612 26.929 15.467 1.00 28.90 ? ? ? ? ? ? 1916 GLU A CB 1 +ATOM 490 C CG . GLU A 1 61 ? 16.574 27.044 13.930 1.00 37.82 ? ? ? ? ? ? 1916 GLU A CG 1 +ATOM 491 C CD . GLU A 1 61 ? 15.696 25.986 13.251 1.00 49.56 ? ? ? ? ? ? 1916 GLU A CD 1 +ATOM 492 O OE1 . GLU A 1 61 ? 14.669 25.588 13.839 1.00 50.88 ? ? ? ? ? ? 1916 GLU A OE1 1 +ATOM 493 O OE2 . GLU A 1 61 ? 16.030 25.555 12.118 1.00 51.91 ? ? ? ? ? ? 1916 GLU A OE2 1 +ATOM 494 N N . LYS A 1 62 ? 19.642 26.112 16.042 1.00 29.56 ? ? ? ? ? ? 1917 LYS A N 1 +ATOM 495 C CA . LYS A 1 62 ? 21.041 25.972 15.641 1.00 29.59 ? ? ? ? ? ? 1917 LYS A CA 1 +ATOM 496 C C . LYS A 1 62 ? 21.544 24.535 15.813 1.00 30.33 ? ? ? ? ? ? 1917 LYS A C 1 +ATOM 497 O O . LYS A 1 62 ? 22.188 23.971 14.913 1.00 30.89 ? ? ? ? ? ? 1917 LYS A O 1 +ATOM 498 C CB . LYS A 1 62 ? 21.919 26.939 16.441 1.00 25.57 ? ? ? ? ? ? 1917 LYS A CB 1 +ATOM 499 C CG . LYS A 1 62 ? 21.718 28.409 16.027 1.00 30.26 ? ? ? ? ? ? 1917 LYS A CG 1 +ATOM 500 C CD . LYS A 1 62 ? 22.485 29.397 16.918 1.00 35.48 ? ? ? ? ? ? 1917 LYS A CD 1 +ATOM 501 C CE . LYS A 1 62 ? 23.988 29.313 16.704 1.00 33.84 ? ? ? ? ? ? 1917 LYS A CE 1 +ATOM 502 N NZ . LYS A 1 62 ? 24.696 30.465 17.350 1.00 36.79 ? ? ? ? ? ? 1917 LYS A NZ 1 +ATOM 503 N N . LEU A 1 63 ? 21.248 23.952 16.968 1.00 29.86 ? ? ? ? ? ? 1918 LEU A N 1 +ATOM 504 C CA . LEU A 1 63 ? 21.651 22.587 17.267 1.00 34.49 ? ? ? ? ? ? 1918 LEU A CA 1 +ATOM 505 C C . LEU A 1 63 ? 21.065 21.617 16.240 1.00 31.75 ? ? ? ? ? ? 1918 LEU A C 1 +ATOM 506 O O . LEU A 1 63 ? 21.771 20.739 15.735 1.00 38.05 ? ? ? ? ? ? 1918 LEU A O 1 +ATOM 507 C CB . LEU A 1 63 ? 21.216 22.199 18.685 1.00 35.71 ? ? ? ? ? ? 1918 LEU A CB 1 +ATOM 508 C CG . LEU A 1 63 ? 21.814 20.910 19.261 1.00 32.32 ? ? ? ? ? ? 1918 LEU A CG 1 +ATOM 509 C CD1 . LEU A 1 63 ? 23.322 21.051 19.401 1.00 33.35 ? ? ? ? ? ? 1918 LEU A CD1 1 +ATOM 510 C CD2 . LEU A 1 63 ? 21.179 20.541 20.603 1.00 30.86 ? ? ? ? ? ? 1918 LEU A CD2 1 +ATOM 511 N N . SER A 1 64 ? 19.782 21.797 15.925 1.00 31.49 ? ? ? ? ? ? 1919 SER A N 1 +ATOM 512 C CA . SER A 1 64 ? 19.055 20.898 15.026 1.00 35.20 ? ? ? ? ? ? 1919 SER A CA 1 +ATOM 513 C C . SER A 1 64 ? 19.457 21.063 13.567 1.00 34.05 ? ? ? ? ? ? 1919 SER A C 1 +ATOM 514 O O . SER A 1 64 ? 19.078 20.255 12.728 1.00 38.36 ? ? ? ? ? ? 1919 SER A O 1 +ATOM 515 C CB . SER A 1 64 ? 17.540 21.109 15.152 1.00 40.18 ? ? ? ? ? ? 1919 SER A CB 1 +ATOM 516 O OG . SER A 1 64 ? 17.080 20.795 16.459 1.00 47.92 ? ? ? ? ? ? 1919 SER A OG 1 +ATOM 517 N N . SER A 1 65 ? 20.219 22.102 13.260 1.00 33.75 ? ? ? ? ? ? 1920 SER A N 1 +ATOM 518 C CA . SER A 1 65 ? 20.567 22.378 11.861 1.00 36.24 ? ? ? ? ? ? 1920 SER A CA 1 +ATOM 519 C C . SER A 1 65 ? 22.078 22.408 11.653 1.00 34.46 ? ? ? ? ? ? 1920 SER A C 1 +ATOM 520 O O . SER A 1 65 ? 22.570 23.001 10.691 1.00 36.07 ? ? ? ? ? ? 1920 SER A O 1 +ATOM 521 C CB . SER A 1 65 ? 19.938 23.697 11.403 1.00 34.42 ? ? ? ? ? ? 1920 SER A CB 1 +ATOM 522 O OG . SER A 1 65 ? 20.338 24.791 12.220 1.00 34.45 ? ? ? ? ? ? 1920 SER A OG 1 +ATOM 523 N N . GLY A 1 66 ? 22.803 21.767 12.573 1.00 33.82 ? ? ? ? ? ? 1921 GLY A N 1 +ATOM 524 C CA . GLY A 1 66 ? 24.244 21.625 12.461 1.00 34.38 ? ? ? ? ? ? 1921 GLY A CA 1 +ATOM 525 C C . GLY A 1 66 ? 25.022 22.927 12.495 1.00 34.51 ? ? ? ? ? ? 1921 GLY A C 1 +ATOM 526 O O . GLY A 1 66 ? 26.042 23.067 11.830 1.00 36.20 ? ? ? ? ? ? 1921 GLY A O 1 +ATOM 527 N N . GLN A 1 67 ? 24.560 23.889 13.281 1.00 33.26 ? ? ? ? ? ? 1922 GLN A N 1 +ATOM 528 C CA . GLN A 1 67 ? 25.256 25.167 13.328 1.00 35.41 ? ? ? ? ? ? 1922 GLN A CA 1 +ATOM 529 C C . GLN A 1 67 ? 26.207 25.285 14.528 1.00 35.45 ? ? ? ? ? ? 1922 GLN A C 1 +ATOM 530 O O . GLN A 1 67 ? 26.852 26.311 14.701 1.00 34.29 ? ? ? ? ? ? 1922 GLN A O 1 +ATOM 531 C CB . GLN A 1 67 ? 24.244 26.316 13.318 1.00 34.27 ? ? ? ? ? ? 1922 GLN A CB 1 +ATOM 532 C CG . GLN A 1 67 ? 23.422 26.361 12.032 1.00 37.66 ? ? ? ? ? ? 1922 GLN A CG 1 +ATOM 533 C CD . GLN A 1 67 ? 22.535 27.579 11.947 1.00 43.12 ? ? ? ? ? ? 1922 GLN A CD 1 +ATOM 534 O OE1 . GLN A 1 67 ? 22.998 28.706 12.094 1.00 51.92 ? ? ? ? ? ? 1922 GLN A OE1 1 +ATOM 535 N NE2 . GLN A 1 67 ? 21.250 27.359 11.707 1.00 46.61 ? ? ? ? ? ? 1922 GLN A NE2 1 +ATOM 536 N N . TYR A 1 68 ? 26.305 24.235 15.345 1.00 31.80 ? ? ? ? ? ? 1923 TYR A N 1 +ATOM 537 C CA . TYR A 1 68 ? 27.362 24.153 16.358 1.00 31.75 ? ? ? ? ? ? 1923 TYR A CA 1 +ATOM 538 C C . TYR A 1 68 ? 28.434 23.185 15.879 1.00 40.06 ? ? ? ? ? ? 1923 TYR A C 1 +ATOM 539 O O . TYR A 1 68 ? 28.165 21.999 15.682 1.00 36.46 ? ? ? ? ? ? 1923 TYR A O 1 +ATOM 540 C CB . TYR A 1 68 ? 26.816 23.710 17.730 1.00 31.01 ? ? ? ? ? ? 1923 TYR A CB 1 +ATOM 541 C CG . TYR A 1 68 ? 25.900 24.749 18.330 1.00 32.47 ? ? ? ? ? ? 1923 TYR A CG 1 +ATOM 542 C CD1 . TYR A 1 68 ? 26.367 26.024 18.612 1.00 30.54 ? ? ? ? ? ? 1923 TYR A CD1 1 +ATOM 543 C CD2 . TYR A 1 68 ? 24.566 24.466 18.585 1.00 30.01 ? ? ? ? ? ? 1923 TYR A CD2 1 +ATOM 544 C CE1 . TYR A 1 68 ? 25.529 26.993 19.136 1.00 30.27 ? ? ? ? ? ? 1923 TYR A CE1 1 +ATOM 545 C CE2 . TYR A 1 68 ? 23.718 25.429 19.107 1.00 31.24 ? ? ? ? ? ? 1923 TYR A CE2 1 +ATOM 546 C CZ . TYR A 1 68 ? 24.209 26.686 19.383 1.00 30.03 ? ? ? ? ? ? 1923 TYR A CZ 1 +ATOM 547 O OH . TYR A 1 68 ? 23.366 27.644 19.882 1.00 30.30 ? ? ? ? ? ? 1923 TYR A OH 1 +ATOM 548 N N . PRO A 1 69 ? 29.652 23.694 15.669 1.00 33.86 ? ? ? ? ? ? 1924 PRO A N 1 +ATOM 549 C CA . PRO A 1 69 ? 30.730 22.832 15.181 1.00 35.51 ? ? ? ? ? ? 1924 PRO A CA 1 +ATOM 550 C C . PRO A 1 69 ? 31.306 21.926 16.269 1.00 43.48 ? ? ? ? ? ? 1924 PRO A C 1 +ATOM 551 O O . PRO A 1 69 ? 31.987 20.958 15.941 1.00 40.53 ? ? ? ? ? ? 1924 PRO A O 1 +ATOM 552 C CB . PRO A 1 69 ? 31.780 23.828 14.676 1.00 40.57 ? ? ? ? ? ? 1924 PRO A CB 1 +ATOM 553 C CG . PRO A 1 69 ? 31.490 25.101 15.394 1.00 43.85 ? ? ? ? ? ? 1924 PRO A CG 1 +ATOM 554 C CD . PRO A 1 69 ? 30.013 25.123 15.648 1.00 42.71 ? ? ? ? ? ? 1924 PRO A CD 1 +ATOM 555 N N . ASN A 1 70 ? 31.026 22.226 17.535 1.00 35.69 ? ? ? ? ? ? 1925 ASN A N 1 +ATOM 556 C CA . ASN A 1 70 ? 31.537 21.419 18.646 1.00 38.09 ? ? ? ? ? ? 1925 ASN A CA 1 +ATOM 557 C C . ASN A 1 70 ? 30.831 21.743 19.965 1.00 38.90 ? ? ? ? ? ? 1925 ASN A C 1 +ATOM 558 O O . ASN A 1 70 ? 30.026 22.675 20.019 1.00 34.01 ? ? ? ? ? ? 1925 ASN A O 1 +ATOM 559 C CB . ASN A 1 70 ? 33.051 21.620 18.797 1.00 38.20 ? ? ? ? ? ? 1925 ASN A CB 1 +ATOM 560 C CG . ASN A 1 70 ? 33.436 23.076 19.015 1.00 43.89 ? ? ? ? ? ? 1925 ASN A CG 1 +ATOM 561 O OD1 . ASN A 1 70 ? 32.795 23.801 19.779 1.00 43.39 ? ? ? ? ? ? 1925 ASN A OD1 1 +ATOM 562 N ND2 . ASN A 1 70 ? 34.491 23.511 18.340 1.00 44.29 ? ? ? ? ? ? 1925 ASN A ND2 1 +ATOM 563 N N . LEU A 1 71 ? 31.143 20.972 21.013 1.00 34.25 ? ? ? ? ? ? 1926 LEU A N 1 +ATOM 564 C CA . LEU A 1 71 ? 30.608 21.194 22.363 1.00 35.00 ? ? ? ? ? ? 1926 LEU A CA 1 +ATOM 565 C C . LEU A 1 71 ? 30.763 22.617 22.868 1.00 35.07 ? ? ? ? ? ? 1926 LEU A C 1 +ATOM 566 O O . LEU A 1 71 ? 29.817 23.223 23.386 1.00 37.04 ? ? ? ? ? ? 1926 LEU A O 1 +ATOM 567 C CB . LEU A 1 71 ? 31.307 20.275 23.368 1.00 44.18 ? ? ? ? ? ? 1926 LEU A CB 1 +ATOM 568 C CG . LEU A 1 71 ? 30.919 18.812 23.382 1.00 49.79 ? ? ? ? ? ? 1926 LEU A CG 1 +ATOM 569 C CD1 . LEU A 1 71 ? 31.581 18.126 24.560 1.00 55.29 ? ? ? ? ? ? 1926 LEU A CD1 1 +ATOM 570 C CD2 . LEU A 1 71 ? 29.425 18.712 23.477 1.00 55.89 ? ? ? ? ? ? 1926 LEU A CD2 1 +ATOM 571 N N . GLU A 1 72 ? 31.987 23.118 22.749 1.00 39.82 ? ? ? ? ? ? 1927 GLU A N 1 +ATOM 572 C CA . GLU A 1 72 ? 32.363 24.426 23.263 1.00 40.34 ? ? ? ? ? ? 1927 GLU A CA 1 +ATOM 573 C C . GLU A 1 72 ? 31.459 25.539 22.733 1.00 39.22 ? ? ? ? ? ? 1927 GLU A C 1 +ATOM 574 O O . GLU A 1 72 ? 31.051 26.423 23.486 1.00 35.73 ? ? ? ? ? ? 1927 GLU A O 1 +ATOM 575 C CB . GLU A 1 72 ? 33.826 24.715 22.911 1.00 46.91 ? ? ? ? ? ? 1927 GLU A CB 1 +ATOM 576 C CG . GLU A 1 72 ? 34.325 26.079 23.362 1.00 63.97 ? ? ? ? ? ? 1927 GLU A CG 1 +ATOM 577 N N . THR A 1 73 ? 31.130 25.494 21.443 1.00 38.59 ? ? ? ? ? ? 1928 THR A N 1 +ATOM 578 C CA . THR A 1 73 ? 30.324 26.561 20.860 1.00 33.76 ? ? ? ? ? ? 1928 THR A CA 1 +ATOM 579 C C . THR A 1 73 ? 28.870 26.490 21.323 1.00 33.70 ? ? ? ? ? ? 1928 THR A C 1 +ATOM 580 O O . THR A 1 73 ? 28.206 27.518 21.432 1.00 32.64 ? ? ? ? ? ? 1928 THR A O 1 +ATOM 581 C CB . THR A 1 73 ? 30.384 26.548 19.317 1.00 30.44 ? ? ? ? ? ? 1928 THR A CB 1 +ATOM 582 O OG1 . THR A 1 73 ? 29.892 25.298 18.816 1.00 37.12 ? ? ? ? ? ? 1928 THR A OG1 1 +ATOM 583 C CG2 . THR A 1 73 ? 31.808 26.752 18.857 1.00 31.73 ? ? ? ? ? ? 1928 THR A CG2 1 +ATOM 584 N N . PHE A 1 74 ? 28.378 25.285 21.603 1.00 30.48 ? ? ? ? ? ? 1929 PHE A N 1 +ATOM 585 C CA . PHE A 1 74 ? 27.052 25.116 22.203 1.00 29.85 ? ? ? ? ? ? 1929 PHE A CA 1 +ATOM 586 C C . PHE A 1 74 ? 26.994 25.742 23.606 1.00 35.95 ? ? ? ? ? ? 1929 PHE A C 1 +ATOM 587 O O . PHE A 1 74 ? 26.075 26.511 23.937 1.00 30.77 ? ? ? ? ? ? 1929 PHE A O 1 +ATOM 588 C CB . PHE A 1 74 ? 26.688 23.621 22.265 1.00 32.02 ? ? ? ? ? ? 1929 PHE A CB 1 +ATOM 589 C CG . PHE A 1 74 ? 25.453 23.323 23.078 1.00 28.04 ? ? ? ? ? ? 1929 PHE A CG 1 +ATOM 590 C CD1 . PHE A 1 74 ? 24.185 23.520 22.541 1.00 28.81 ? ? ? ? ? ? 1929 PHE A CD1 1 +ATOM 591 C CD2 . PHE A 1 74 ? 25.557 22.827 24.376 1.00 24.98 ? ? ? ? ? ? 1929 PHE A CD2 1 +ATOM 592 C CE1 . PHE A 1 74 ? 23.043 23.240 23.284 1.00 26.80 ? ? ? ? ? ? 1929 PHE A CE1 1 +ATOM 593 C CE2 . PHE A 1 74 ? 24.417 22.552 25.128 1.00 28.74 ? ? ? ? ? ? 1929 PHE A CE2 1 +ATOM 594 C CZ . PHE A 1 74 ? 23.161 22.754 24.580 1.00 30.78 ? ? ? ? ? ? 1929 PHE A CZ 1 +ATOM 595 N N . ALA A 1 75 ? 27.985 25.416 24.432 1.00 31.73 ? ? ? ? ? ? 1930 ALA A N 1 +ATOM 596 C CA . ALA A 1 75 ? 28.056 25.955 25.784 1.00 31.43 ? ? ? ? ? ? 1930 ALA A CA 1 +ATOM 597 C C . ALA A 1 75 ? 28.166 27.482 25.772 1.00 30.25 ? ? ? ? ? ? 1930 ALA A C 1 +ATOM 598 O O . ALA A 1 75 ? 27.612 28.159 26.642 1.00 31.91 ? ? ? ? ? ? 1930 ALA A O 1 +ATOM 599 C CB . ALA A 1 75 ? 29.230 25.350 26.533 1.00 31.56 ? ? ? ? ? ? 1930 ALA A CB 1 +ATOM 600 N N . LEU A 1 76 ? 28.887 28.019 24.796 1.00 34.82 ? ? ? ? ? ? 1931 LEU A N 1 +ATOM 601 C CA . LEU A 1 76 ? 29.039 29.467 24.685 1.00 35.94 ? ? ? ? ? ? 1931 LEU A CA 1 +ATOM 602 C C . LEU A 1 76 ? 27.695 30.170 24.500 1.00 35.82 ? ? ? ? ? ? 1931 LEU A C 1 +ATOM 603 O O . LEU A 1 76 ? 27.444 31.208 25.118 1.00 32.68 ? ? ? ? ? ? 1931 LEU A O 1 +ATOM 604 C CB . LEU A 1 76 ? 29.978 29.824 23.535 1.00 41.45 ? ? ? ? ? ? 1931 LEU A CB 1 +ATOM 605 C CG . LEU A 1 76 ? 31.462 29.590 23.818 1.00 53.37 ? ? ? ? ? ? 1931 LEU A CG 1 +ATOM 606 C CD1 . LEU A 1 76 ? 32.308 29.881 22.586 1.00 57.14 ? ? ? ? ? ? 1931 LEU A CD1 1 +ATOM 607 C CD2 . LEU A 1 76 ? 31.915 30.436 24.997 1.00 60.29 ? ? ? ? ? ? 1931 LEU A CD2 1 +ATOM 608 N N . ASP A 1 77 ? 26.839 29.614 23.647 1.00 31.25 ? ? ? ? ? ? 1932 ASP A N 1 +ATOM 609 C CA . ASP A 1 77 ? 25.517 30.203 23.423 1.00 32.01 ? ? ? ? ? ? 1932 ASP A CA 1 +ATOM 610 C C . ASP A 1 77 ? 24.640 30.072 24.670 1.00 28.29 ? ? ? ? ? ? 1932 ASP A C 1 +ATOM 611 O O . ASP A 1 77 ? 23.914 31.002 25.032 1.00 27.78 ? ? ? ? ? ? 1932 ASP A O 1 +ATOM 612 C CB . ASP A 1 77 ? 24.827 29.556 22.215 1.00 30.42 ? ? ? ? ? ? 1932 ASP A CB 1 +ATOM 613 C CG . ASP A 1 77 ? 25.064 30.328 20.924 1.00 32.46 ? ? ? ? ? ? 1932 ASP A CG 1 +ATOM 614 O OD1 . ASP A 1 77 ? 25.721 31.397 20.973 1.00 38.41 ? ? ? ? ? ? 1932 ASP A OD1 1 +ATOM 615 O OD2 . ASP A 1 77 ? 24.573 29.882 19.862 1.00 32.64 ? ? ? ? ? ? 1932 ASP A OD2 1 +ATOM 616 N N . VAL A 1 78 ? 24.706 28.921 25.333 1.00 26.03 ? ? ? ? ? ? 1933 VAL A N 1 +ATOM 617 C CA . VAL A 1 78 ? 23.919 28.735 26.541 1.00 25.19 ? ? ? ? ? ? 1933 VAL A CA 1 +ATOM 618 C C . VAL A 1 78 ? 24.327 29.778 27.596 1.00 28.73 ? ? ? ? ? ? 1933 VAL A C 1 +ATOM 619 O O . VAL A 1 78 ? 23.479 30.393 28.248 1.00 29.59 ? ? ? ? ? ? 1933 VAL A O 1 +ATOM 620 C CB . VAL A 1 78 ? 24.076 27.309 27.118 1.00 25.85 ? ? ? ? ? ? 1933 VAL A CB 1 +ATOM 621 C CG1 . VAL A 1 78 ? 23.425 27.208 28.497 1.00 28.07 ? ? ? ? ? ? 1933 VAL A CG1 1 +ATOM 622 C CG2 . VAL A 1 78 ? 23.477 26.268 26.154 1.00 25.40 ? ? ? ? ? ? 1933 VAL A CG2 1 +ATOM 623 N N . ARG A 1 79 ? 25.629 29.982 27.754 1.00 28.03 ? ? ? ? ? ? 1934 ARG A N 1 +ATOM 624 C CA . ARG A 1 79 ? 26.113 30.895 28.785 1.00 27.43 ? ? ? ? ? ? 1934 ARG A CA 1 +ATOM 625 C C . ARG A 1 79 ? 25.792 32.332 28.400 1.00 30.65 ? ? ? ? ? ? 1934 ARG A C 1 +ATOM 626 O O . ARG A 1 79 ? 25.539 33.181 29.265 1.00 30.65 ? ? ? ? ? ? 1934 ARG A O 1 +ATOM 627 C CB . ARG A 1 79 ? 27.614 30.708 29.006 1.00 27.29 ? ? ? ? ? ? 1934 ARG A CB 1 +ATOM 628 C CG . ARG A 1 79 ? 27.941 29.384 29.669 1.00 33.20 ? ? ? ? ? ? 1934 ARG A CG 1 +ATOM 629 C CD . ARG A 1 79 ? 29.412 29.028 29.597 1.00 34.94 ? ? ? ? ? ? 1934 ARG A CD 1 +ATOM 630 N NE . ARG A 1 79 ? 29.644 27.736 30.235 1.00 38.04 ? ? ? ? ? ? 1934 ARG A NE 1 +ATOM 631 C CZ . ARG A 1 79 ? 30.617 26.893 29.905 1.00 42.83 ? ? ? ? ? ? 1934 ARG A CZ 1 +ATOM 632 N NH1 . ARG A 1 79 ? 31.468 27.197 28.933 1.00 38.09 ? ? ? ? ? ? 1934 ARG A NH1 1 +ATOM 633 N NH2 . ARG A 1 79 ? 30.735 25.740 30.552 1.00 42.69 ? ? ? ? ? ? 1934 ARG A NH2 1 +ATOM 634 N N . LEU A 1 80 ? 25.786 32.588 27.096 1.00 26.99 ? ? ? ? ? ? 1935 LEU A N 1 +ATOM 635 C CA . LEU A 1 80 ? 25.410 33.889 26.561 1.00 29.07 ? ? ? ? ? ? 1935 LEU A CA 1 +ATOM 636 C C . LEU A 1 80 ? 23.992 34.253 26.989 1.00 32.51 ? ? ? ? ? ? 1935 LEU A C 1 +ATOM 637 O O . LEU A 1 80 ? 23.719 35.411 27.317 1.00 27.66 ? ? ? ? ? ? 1935 LEU A O 1 +ATOM 638 C CB . LEU A 1 80 ? 25.530 33.892 25.028 1.00 28.32 ? ? ? ? ? ? 1935 LEU A CB 1 +ATOM 639 C CG . LEU A 1 80 ? 25.028 35.120 24.273 1.00 27.58 ? ? ? ? ? ? 1935 LEU A CG 1 +ATOM 640 C CD1 . LEU A 1 80 ? 25.833 36.375 24.639 1.00 30.42 ? ? ? ? ? ? 1935 LEU A CD1 1 +ATOM 641 C CD2 . LEU A 1 80 ? 25.068 34.867 22.757 1.00 27.70 ? ? ? ? ? ? 1935 LEU A CD2 1 +ATOM 642 N N . VAL A 1 81 ? 23.095 33.266 27.008 1.00 26.26 ? ? ? ? ? ? 1936 VAL A N 1 +ATOM 643 C CA . VAL A 1 81 ? 21.736 33.512 27.486 1.00 27.50 ? ? ? ? ? ? 1936 VAL A CA 1 +ATOM 644 C C . VAL A 1 81 ? 21.759 34.102 28.905 1.00 32.28 ? ? ? ? ? ? 1936 VAL A C 1 +ATOM 645 O O . VAL A 1 81 ? 21.052 35.067 29.211 1.00 27.70 ? ? ? ? ? ? 1936 VAL A O 1 +ATOM 646 C CB . VAL A 1 81 ? 20.885 32.224 27.497 1.00 28.63 ? ? ? ? ? ? 1936 VAL A CB 1 +ATOM 647 C CG1 . VAL A 1 81 ? 19.557 32.467 28.211 1.00 24.40 ? ? ? ? ? ? 1936 VAL A CG1 1 +ATOM 648 C CG2 . VAL A 1 81 ? 20.660 31.681 26.065 1.00 24.09 ? ? ? ? ? ? 1936 VAL A CG2 1 +ATOM 649 N N . PHE A 1 82 ? 22.587 33.533 29.774 1.00 27.41 ? ? ? ? ? ? 1937 PHE A N 1 +ATOM 650 C CA . PHE A 1 82 ? 22.579 33.975 31.170 1.00 26.33 ? ? ? ? ? ? 1937 PHE A CA 1 +ATOM 651 C C . PHE A 1 82 ? 23.418 35.227 31.406 1.00 29.45 ? ? ? ? ? ? 1937 PHE A C 1 +ATOM 652 O O . PHE A 1 82 ? 23.106 36.028 32.290 1.00 29.67 ? ? ? ? ? ? 1937 PHE A O 1 +ATOM 653 C CB . PHE A 1 82 ? 23.025 32.819 32.060 1.00 25.80 ? ? ? ? ? ? 1937 PHE A CB 1 +ATOM 654 C CG . PHE A 1 82 ? 22.212 31.597 31.840 1.00 30.27 ? ? ? ? ? ? 1937 PHE A CG 1 +ATOM 655 C CD1 . PHE A 1 82 ? 20.830 31.686 31.834 1.00 28.31 ? ? ? ? ? ? 1937 PHE A CD1 1 +ATOM 656 C CD2 . PHE A 1 82 ? 22.806 30.386 31.555 1.00 30.22 ? ? ? ? ? ? 1937 PHE A CD2 1 +ATOM 657 C CE1 . PHE A 1 82 ? 20.059 30.577 31.586 1.00 31.20 ? ? ? ? ? ? 1937 PHE A CE1 1 +ATOM 658 C CE2 . PHE A 1 82 ? 22.031 29.260 31.311 1.00 35.06 ? ? ? ? ? ? 1937 PHE A CE2 1 +ATOM 659 C CZ . PHE A 1 82 ? 20.657 29.367 31.319 1.00 32.47 ? ? ? ? ? ? 1937 PHE A CZ 1 +ATOM 660 N N . ASP A 1 83 ? 24.467 35.402 30.611 1.00 29.08 ? ? ? ? ? ? 1938 ASP A N 1 +ATOM 661 C CA . ASP A 1 83 ? 25.234 36.642 30.618 1.00 32.04 ? ? ? ? ? ? 1938 ASP A CA 1 +ATOM 662 C C . ASP A 1 83 ? 24.380 37.831 30.187 1.00 34.86 ? ? ? ? ? ? 1938 ASP A C 1 +ATOM 663 O O . ASP A 1 83 ? 24.466 38.909 30.780 1.00 29.17 ? ? ? ? ? ? 1938 ASP A O 1 +ATOM 664 C CB . ASP A 1 83 ? 26.452 36.528 29.706 1.00 32.61 ? ? ? ? ? ? 1938 ASP A CB 1 +ATOM 665 C CG . ASP A 1 83 ? 27.500 35.589 30.256 1.00 38.89 ? ? ? ? ? ? 1938 ASP A CG 1 +ATOM 666 O OD1 . ASP A 1 83 ? 27.415 35.232 31.456 1.00 32.48 ? ? ? ? ? ? 1938 ASP A OD1 1 +ATOM 667 O OD2 . ASP A 1 83 ? 28.418 35.218 29.494 1.00 35.36 ? ? ? ? ? ? 1938 ASP A OD2 1 +ATOM 668 N N . ASN A 1 84 ? 23.574 37.640 29.145 1.00 30.48 ? ? ? ? ? ? 1939 ASN A N 1 +ATOM 669 C CA . ASN A 1 84 ? 22.634 38.674 28.723 1.00 33.26 ? ? ? ? ? ? 1939 ASN A CA 1 +ATOM 670 C C . ASN A 1 84 ? 21.654 38.984 29.840 1.00 32.30 ? ? ? ? ? ? 1939 ASN A C 1 +ATOM 671 O O . ASN A 1 84 ? 21.332 40.146 30.095 1.00 30.36 ? ? ? ? ? ? 1939 ASN A O 1 +ATOM 672 C CB . ASN A 1 84 ? 21.857 38.255 27.472 1.00 25.18 ? ? ? ? ? ? 1939 ASN A CB 1 +ATOM 673 C CG . ASN A 1 84 ? 22.709 38.251 26.215 1.00 29.97 ? ? ? ? ? ? 1939 ASN A CG 1 +ATOM 674 O OD1 . ASN A 1 84 ? 23.794 38.836 26.176 1.00 28.27 ? ? ? ? ? ? 1939 ASN A OD1 1 +ATOM 675 N ND2 . ASN A 1 84 ? 22.198 37.612 25.159 1.00 26.96 ? ? ? ? ? ? 1939 ASN A ND2 1 +ATOM 676 N N . CYS A 1 85 ? 21.179 37.932 30.501 1.00 31.32 ? ? ? ? ? ? 1940 CYS A N 1 +ATOM 677 C CA . CYS A 1 85 ? 20.194 38.085 31.560 1.00 29.13 ? ? ? ? ? ? 1940 CYS A CA 1 +ATOM 678 C C . CYS A 1 85 ? 20.763 38.940 32.694 1.00 31.24 ? ? ? ? ? ? 1940 CYS A C 1 +ATOM 679 O O . CYS A 1 85 ? 20.077 39.811 33.227 1.00 31.83 ? ? ? ? ? ? 1940 CYS A O 1 +ATOM 680 C CB . CYS A 1 85 ? 19.749 36.707 32.085 1.00 28.82 ? ? ? ? ? ? 1940 CYS A CB 1 +ATOM 681 S SG . CYS A 1 85 ? 18.470 36.758 33.375 1.00 29.95 ? ? ? ? ? ? 1940 CYS A SG 1 +ATOM 682 N N . GLU A 1 86 ? 22.023 38.697 33.051 1.00 28.43 ? ? ? ? ? ? 1941 GLU A N 1 +ATOM 683 C CA . GLU A 1 86 ? 22.669 39.493 34.090 1.00 31.75 ? ? ? ? ? ? 1941 GLU A CA 1 +ATOM 684 C C . GLU A 1 86 ? 22.862 40.940 33.655 1.00 34.58 ? ? ? ? ? ? 1941 GLU A C 1 +ATOM 685 O O . GLU A 1 86 ? 22.776 41.856 34.470 1.00 31.05 ? ? ? ? ? ? 1941 GLU A O 1 +ATOM 686 C CB . GLU A 1 86 ? 24.024 38.904 34.476 1.00 36.13 ? ? ? ? ? ? 1941 GLU A CB 1 +ATOM 687 C CG . GLU A 1 86 ? 23.948 37.594 35.232 1.00 35.39 ? ? ? ? ? ? 1941 GLU A CG 1 +ATOM 688 C CD . GLU A 1 86 ? 25.213 37.326 36.023 1.00 38.45 ? ? ? ? ? ? 1941 GLU A CD 1 +ATOM 689 O OE1 . GLU A 1 86 ? 25.676 38.250 36.725 1.00 39.90 ? ? ? ? ? ? 1941 GLU A OE1 1 +ATOM 690 O OE2 . GLU A 1 86 ? 25.743 36.198 35.947 1.00 43.60 ? ? ? ? ? ? 1941 GLU A OE2 1 +ATOM 691 N N . THR A 1 87 ? 23.148 41.144 32.376 1.00 31.32 ? ? ? ? ? ? 1942 THR A N 1 +ATOM 692 C CA . THR A 1 87 ? 23.340 42.498 31.854 1.00 28.96 ? ? ? ? ? ? 1942 THR A CA 1 +ATOM 693 C C . THR A 1 87 ? 22.060 43.335 31.958 1.00 32.76 ? ? ? ? ? ? 1942 THR A C 1 +ATOM 694 O O . THR A 1 87 ? 22.109 44.534 32.235 1.00 30.32 ? ? ? ? ? ? 1942 THR A O 1 +ATOM 695 C CB . THR A 1 87 ? 23.816 42.460 30.385 1.00 28.57 ? ? ? ? ? ? 1942 THR A CB 1 +ATOM 696 O OG1 . THR A 1 87 ? 25.111 41.849 30.326 1.00 32.82 ? ? ? ? ? ? 1942 THR A OG1 1 +ATOM 697 C CG2 . THR A 1 87 ? 23.904 43.872 29.800 1.00 30.17 ? ? ? ? ? ? 1942 THR A CG2 1 +ATOM 698 N N . PHE A 1 88 ? 20.914 42.692 31.755 1.00 29.35 ? ? ? ? ? ? 1943 PHE A N 1 +ATOM 699 C CA . PHE A 1 88 ? 19.650 43.410 31.635 1.00 34.04 ? ? ? ? ? ? 1943 PHE A CA 1 +ATOM 700 C C . PHE A 1 88 ? 18.744 43.304 32.858 1.00 34.49 ? ? ? ? ? ? 1943 PHE A C 1 +ATOM 701 O O . PHE A 1 88 ? 17.689 43.949 32.896 1.00 35.90 ? ? ? ? ? ? 1943 PHE A O 1 +ATOM 702 C CB . PHE A 1 88 ? 18.888 42.912 30.401 1.00 29.33 ? ? ? ? ? ? 1943 PHE A CB 1 +ATOM 703 C CG . PHE A 1 88 ? 17.982 43.944 29.782 1.00 32.47 ? ? ? ? ? ? 1943 PHE A CG 1 +ATOM 704 C CD1 . PHE A 1 88 ? 18.507 44.976 29.017 1.00 31.42 ? ? ? ? ? ? 1943 PHE A CD1 1 +ATOM 705 C CD2 . PHE A 1 88 ? 16.609 43.874 29.952 1.00 29.77 ? ? ? ? ? ? 1943 PHE A CD2 1 +ATOM 706 C CE1 . PHE A 1 88 ? 17.679 45.928 28.434 1.00 36.08 ? ? ? ? ? ? 1943 PHE A CE1 1 +ATOM 707 C CE2 . PHE A 1 88 ? 15.778 44.822 29.377 1.00 31.01 ? ? ? ? ? ? 1943 PHE A CE2 1 +ATOM 708 C CZ . PHE A 1 88 ? 16.314 45.852 28.617 1.00 37.00 ? ? ? ? ? ? 1943 PHE A CZ 1 +ATOM 709 N N . ASN A 1 89 ? 19.137 42.505 33.854 1.00 28.83 ? ? ? ? ? ? 1944 ASN A N 1 +ATOM 710 C CA . ASN A 1 89 ? 18.284 42.300 35.022 1.00 30.73 ? ? ? ? ? ? 1944 ASN A CA 1 +ATOM 711 C C . ASN A 1 89 ? 19.016 42.414 36.354 1.00 32.65 ? ? ? ? ? ? 1944 ASN A C 1 +ATOM 712 O O . ASN A 1 89 ? 20.125 41.898 36.507 1.00 31.45 ? ? ? ? ? ? 1944 ASN A O 1 +ATOM 713 C CB . ASN A 1 89 ? 17.611 40.927 34.943 1.00 34.61 ? ? ? ? ? ? 1944 ASN A CB 1 +ATOM 714 C CG . ASN A 1 89 ? 16.723 40.785 33.727 1.00 32.63 ? ? ? ? ? ? 1944 ASN A CG 1 +ATOM 715 O OD1 . ASN A 1 89 ? 15.546 41.142 33.760 1.00 35.63 ? ? ? ? ? ? 1944 ASN A OD1 1 +ATOM 716 N ND2 . ASN A 1 89 ? 17.280 40.252 32.646 1.00 27.99 ? ? ? ? ? ? 1944 ASN A ND2 1 +ATOM 717 N N . GLU A 1 90 ? 18.386 43.090 37.313 1.00 32.24 ? ? ? ? ? ? 1945 GLU A N 1 +ATOM 718 C CA . GLU A 1 90 ? 18.886 43.108 38.677 1.00 33.29 ? ? ? ? ? ? 1945 GLU A CA 1 +ATOM 719 C C . GLU A 1 90 ? 18.905 41.679 39.231 1.00 32.47 ? ? ? ? ? ? 1945 GLU A C 1 +ATOM 720 O O . GLU A 1 90 ? 17.983 40.909 38.976 1.00 31.39 ? ? ? ? ? ? 1945 GLU A O 1 +ATOM 721 C CB A GLU A 1 90 ? 18.011 43.988 39.579 0.38 35.34 ? ? ? ? ? ? 1945 GLU A CB 1 +ATOM 722 C CB B GLU A 1 90 ? 18.042 44.036 39.556 0.62 35.37 ? ? ? ? ? ? 1945 GLU A CB 1 +ATOM 723 C CG A GLU A 1 90 ? 17.770 45.411 39.096 0.38 42.01 ? ? ? ? ? ? 1945 GLU A CG 1 +ATOM 724 C CG B GLU A 1 90 ? 18.309 45.531 39.315 0.62 37.27 ? ? ? ? ? ? 1945 GLU A CG 1 +ATOM 725 C CD A GLU A 1 90 ? 16.688 46.118 39.901 0.38 54.23 ? ? ? ? ? ? 1945 GLU A CD 1 +ATOM 726 C CD B GLU A 1 90 ? 19.695 45.965 39.774 0.62 40.34 ? ? ? ? ? ? 1945 GLU A CD 1 +ATOM 727 O OE1 A GLU A 1 90 ? 16.878 46.321 41.121 0.38 56.59 ? ? ? ? ? ? 1945 GLU A OE1 1 +ATOM 728 O OE1 B GLU A 1 90 ? 20.288 45.277 40.633 0.62 46.18 ? ? ? ? ? ? 1945 GLU A OE1 1 +ATOM 729 O OE2 A GLU A 1 90 ? 15.643 46.466 39.312 0.38 62.75 ? ? ? ? ? ? 1945 GLU A OE2 1 +ATOM 730 O OE2 B GLU A 1 90 ? 20.196 46.993 39.282 0.62 44.10 ? ? ? ? ? ? 1945 GLU A OE2 1 +ATOM 731 N N . ASP A 1 91 ? 19.954 41.340 39.975 1.00 35.86 ? ? ? ? ? ? 1946 ASP A N 1 +ATOM 732 C CA . ASP A 1 91 ? 20.018 40.057 40.675 1.00 36.39 ? ? ? ? ? ? 1946 ASP A CA 1 +ATOM 733 C C . ASP A 1 91 ? 18.778 39.863 41.539 1.00 42.48 ? ? ? ? ? ? 1946 ASP A C 1 +ATOM 734 O O . ASP A 1 91 ? 18.210 38.773 41.594 1.00 40.19 ? ? ? ? ? ? 1946 ASP A O 1 +ATOM 735 C CB . ASP A 1 91 ? 21.269 39.965 41.550 1.00 36.05 ? ? ? ? ? ? 1946 ASP A CB 1 +ATOM 736 C CG . ASP A 1 91 ? 22.543 39.886 40.746 1.00 42.27 ? ? ? ? ? ? 1946 ASP A CG 1 +ATOM 737 O OD1 . ASP A 1 91 ? 22.476 39.556 39.545 1.00 37.88 ? ? ? ? ? ? 1946 ASP A OD1 1 +ATOM 738 O OD2 . ASP A 1 91 ? 23.617 40.146 41.324 1.00 46.40 ? ? ? ? ? ? 1946 ASP A OD2 1 +ATOM 739 N N . ASP A 1 92 ? 18.365 40.934 42.211 1.00 38.15 ? ? ? ? ? ? 1947 ASP A N 1 +ATOM 740 C CA . ASP A 1 92 ? 17.180 40.900 43.061 1.00 43.91 ? ? ? ? ? ? 1947 ASP A CA 1 +ATOM 741 C C . ASP A 1 92 ? 15.919 41.183 42.245 1.00 39.14 ? ? ? ? ? ? 1947 ASP A C 1 +ATOM 742 O O . ASP A 1 92 ? 15.275 42.227 42.401 1.00 40.30 ? ? ? ? ? ? 1947 ASP A O 1 +ATOM 743 C CB . ASP A 1 92 ? 17.310 41.904 44.215 1.00 43.31 ? ? ? ? ? ? 1947 ASP A CB 1 +ATOM 744 C CG . ASP A 1 92 ? 16.215 41.745 45.255 1.00 52.31 ? ? ? ? ? ? 1947 ASP A CG 1 +ATOM 745 O OD1 . ASP A 1 92 ? 15.443 40.763 45.171 1.00 47.68 ? ? ? ? ? ? 1947 ASP A OD1 1 +ATOM 746 O OD2 . ASP A 1 92 ? 16.137 42.597 46.168 1.00 56.72 ? ? ? ? ? ? 1947 ASP A OD2 1 +ATOM 747 N N . SER A 1 93 ? 15.588 40.239 41.371 1.00 38.75 ? ? ? ? ? ? 1948 SER A N 1 +ATOM 748 C CA . SER A 1 93 ? 14.357 40.264 40.593 1.00 39.48 ? ? ? ? ? ? 1948 SER A CA 1 +ATOM 749 C C . SER A 1 93 ? 14.030 38.826 40.217 1.00 33.30 ? ? ? ? ? ? 1948 SER A C 1 +ATOM 750 O O . SER A 1 93 ? 14.900 37.955 40.303 1.00 35.25 ? ? ? ? ? ? 1948 SER A O 1 +ATOM 751 C CB . SER A 1 93 ? 14.493 41.151 39.343 1.00 38.54 ? ? ? ? ? ? 1948 SER A CB 1 +ATOM 752 O OG . SER A 1 93 ? 15.382 40.592 38.385 1.00 32.01 ? ? ? ? ? ? 1948 SER A OG 1 +ATOM 753 N N . ASP A 1 94 ? 12.791 38.561 39.811 1.00 35.44 ? ? ? ? ? ? 1949 ASP A N 1 +ATOM 754 C CA . ASP A 1 94 ? 12.407 37.194 39.422 1.00 33.10 ? ? ? ? ? ? 1949 ASP A CA 1 +ATOM 755 C C . ASP A 1 94 ? 13.248 36.653 38.260 1.00 33.47 ? ? ? ? ? ? 1949 ASP A C 1 +ATOM 756 O O . ASP A 1 94 ? 13.710 35.506 38.288 1.00 32.07 ? ? ? ? ? ? 1949 ASP A O 1 +ATOM 757 C CB . ASP A 1 94 ? 10.920 37.138 39.050 1.00 37.99 ? ? ? ? ? ? 1949 ASP A CB 1 +ATOM 758 C CG . ASP A 1 94 ? 10.005 37.337 40.253 1.00 48.36 ? ? ? ? ? ? 1949 ASP A CG 1 +ATOM 759 O OD1 . ASP A 1 94 ? 9.739 36.355 40.978 1.00 41.29 ? ? ? ? ? ? 1949 ASP A OD1 1 +ATOM 760 O OD2 . ASP A 1 94 ? 9.538 38.475 40.467 1.00 56.01 ? ? ? ? ? ? 1949 ASP A OD2 1 +ATOM 761 N N . ILE A 1 95 ? 13.445 37.481 37.241 1.00 30.24 ? ? ? ? ? ? 1950 ILE A N 1 +ATOM 762 C CA . ILE A 1 95 ? 14.180 37.055 36.048 1.00 30.04 ? ? ? ? ? ? 1950 ILE A CA 1 +ATOM 763 C C . ILE A 1 95 ? 15.668 36.953 36.371 1.00 32.86 ? ? ? ? ? ? 1950 ILE A C 1 +ATOM 764 O O . ILE A 1 95 ? 16.347 36.033 35.916 1.00 30.59 ? ? ? ? ? ? 1950 ILE A O 1 +ATOM 765 C CB . ILE A 1 95 ? 13.927 38.029 34.871 1.00 33.92 ? ? ? ? ? ? 1950 ILE A CB 1 +ATOM 766 C CG1 . ILE A 1 95 ? 12.476 37.904 34.411 1.00 33.14 ? ? ? ? ? ? 1950 ILE A CG1 1 +ATOM 767 C CG2 . ILE A 1 95 ? 14.886 37.780 33.705 1.00 35.56 ? ? ? ? ? ? 1950 ILE A CG2 1 +ATOM 768 C CD1 . ILE A 1 95 ? 12.095 38.915 33.365 1.00 36.92 ? ? ? ? ? ? 1950 ILE A CD1 1 +ATOM 769 N N . GLY A 1 96 ? 16.165 37.891 37.176 1.00 32.60 ? ? ? ? ? ? 1951 GLY A N 1 +ATOM 770 C CA . GLY A 1 96 ? 17.537 37.839 37.656 1.00 30.59 ? ? ? ? ? ? 1951 GLY A CA 1 +ATOM 771 C C . GLY A 1 96 ? 17.839 36.536 38.387 1.00 36.77 ? ? ? ? ? ? 1951 GLY A C 1 +ATOM 772 O O . GLY A 1 96 ? 18.833 35.861 38.109 1.00 33.48 ? ? ? ? ? ? 1951 GLY A O 1 +ATOM 773 N N . ARG A 1 97 ? 16.970 36.171 39.320 1.00 32.93 ? ? ? ? ? ? 1952 ARG A N 1 +ATOM 774 C CA . ARG A 1 97 ? 17.131 34.922 40.052 1.00 34.35 ? ? ? ? ? ? 1952 ARG A CA 1 +ATOM 775 C C . ARG A 1 97 ? 17.006 33.712 39.120 1.00 31.54 ? ? ? ? ? ? 1952 ARG A C 1 +ATOM 776 O O . ARG A 1 97 ? 17.763 32.749 39.248 1.00 33.69 ? ? ? ? ? ? 1952 ARG A O 1 +ATOM 777 C CB . ARG A 1 97 ? 16.112 34.837 41.185 1.00 33.09 ? ? ? ? ? ? 1952 ARG A CB 1 +ATOM 778 C CG . ARG A 1 97 ? 16.488 35.691 42.396 1.00 41.69 ? ? ? ? ? ? 1952 ARG A CG 1 +ATOM 779 C CD . ARG A 1 97 ? 15.514 35.495 43.543 1.00 42.50 ? ? ? ? ? ? 1952 ARG A CD 1 +ATOM 780 N NE . ARG A 1 97 ? 14.232 36.143 43.284 1.00 40.68 ? ? ? ? ? ? 1952 ARG A NE 1 +ATOM 781 C CZ . ARG A 1 97 ? 13.961 37.411 43.575 1.00 44.47 ? ? ? ? ? ? 1952 ARG A CZ 1 +ATOM 782 N NH1 . ARG A 1 97 ? 14.885 38.184 44.134 1.00 45.51 ? ? ? ? ? ? 1952 ARG A NH1 1 +ATOM 783 N NH2 . ARG A 1 97 ? 12.762 37.903 43.307 1.00 51.23 ? ? ? ? ? ? 1952 ARG A NH2 1 +ATOM 784 N N . ALA A 1 98 ? 16.050 33.766 38.198 1.00 29.50 ? ? ? ? ? ? 1953 ALA A N 1 +ATOM 785 C CA . ALA A 1 98 ? 15.882 32.690 37.213 1.00 32.25 ? ? ? ? ? ? 1953 ALA A CA 1 +ATOM 786 C C . ALA A 1 98 ? 17.183 32.411 36.472 1.00 29.92 ? ? ? ? ? ? 1953 ALA A C 1 +ATOM 787 O O . ALA A 1 98 ? 17.586 31.248 36.300 1.00 29.24 ? ? ? ? ? ? 1953 ALA A O 1 +ATOM 788 C CB . ALA A 1 98 ? 14.781 33.040 36.220 1.00 29.72 ? ? ? ? ? ? 1953 ALA A CB 1 +ATOM 789 N N . GLY A 1 99 ? 17.839 33.482 36.029 1.00 30.97 ? ? ? ? ? ? 1954 GLY A N 1 +ATOM 790 C CA . GLY A 1 99 ? 19.076 33.351 35.278 1.00 28.98 ? ? ? ? ? ? 1954 GLY A CA 1 +ATOM 791 C C . GLY A 1 99 ? 20.159 32.670 36.087 1.00 30.72 ? ? ? ? ? ? 1954 GLY A C 1 +ATOM 792 O O . GLY A 1 99 ? 20.821 31.744 35.612 1.00 29.33 ? ? ? ? ? ? 1954 GLY A O 1 +ATOM 793 N N . HIS A 1 100 ? 20.339 33.125 37.321 1.00 31.19 ? ? ? ? ? ? 1955 HIS A N 1 +ATOM 794 C CA . HIS A 1 100 ? 21.316 32.505 38.198 1.00 31.81 ? ? ? ? ? ? 1955 HIS A CA 1 +ATOM 795 C C . HIS A 1 100 ? 20.991 31.031 38.433 1.00 33.17 ? ? ? ? ? ? 1955 HIS A C 1 +ATOM 796 O O . HIS A 1 100 ? 21.888 30.188 38.375 1.00 35.31 ? ? ? ? ? ? 1955 HIS A O 1 +ATOM 797 C CB . HIS A 1 100 ? 21.399 33.264 39.529 1.00 35.90 ? ? ? ? ? ? 1955 HIS A CB 1 +ATOM 798 C CG . HIS A 1 100 ? 22.066 34.600 39.410 1.00 40.36 ? ? ? ? ? ? 1955 HIS A CG 1 +ATOM 799 N ND1 . HIS A 1 100 ? 23.424 34.739 39.225 1.00 40.84 ? ? ? ? ? ? 1955 HIS A ND1 1 +ATOM 800 C CD2 . HIS A 1 100 ? 21.559 35.856 39.439 1.00 38.62 ? ? ? ? ? ? 1955 HIS A CD2 1 +ATOM 801 C CE1 . HIS A 1 100 ? 23.726 36.025 39.146 1.00 39.21 ? ? ? ? ? ? 1955 HIS A CE1 1 +ATOM 802 N NE2 . HIS A 1 100 ? 22.613 36.722 39.273 1.00 36.18 ? ? ? ? ? ? 1955 HIS A NE2 1 +ATOM 803 N N . ASN A 1 101 ? 19.722 30.719 38.694 1.00 32.99 ? ? ? ? ? ? 1956 ASN A N 1 +ATOM 804 C CA . ASN A 1 101 ? 19.299 29.326 38.903 1.00 34.70 ? ? ? ? ? ? 1956 ASN A CA 1 +ATOM 805 C C . ASN A 1 101 ? 19.578 28.459 37.676 1.00 34.43 ? ? ? ? ? ? 1956 ASN A C 1 +ATOM 806 O O . ASN A 1 101 ? 20.085 27.343 37.789 1.00 36.59 ? ? ? ? ? ? 1956 ASN A O 1 +ATOM 807 C CB . ASN A 1 101 ? 17.807 29.250 39.229 1.00 34.70 ? ? ? ? ? ? 1956 ASN A CB 1 +ATOM 808 C CG . ASN A 1 101 ? 17.483 29.711 40.637 1.00 40.79 ? ? ? ? ? ? 1956 ASN A CG 1 +ATOM 809 O OD1 . ASN A 1 101 ? 18.375 30.019 41.430 1.00 43.96 ? ? ? ? ? ? 1956 ASN A OD1 1 +ATOM 810 N ND2 . ASN A 1 101 ? 16.191 29.769 40.951 1.00 38.39 ? ? ? ? ? ? 1956 ASN A ND2 1 +ATOM 811 N N . MET A 1 102 ? 19.234 28.985 36.500 1.00 28.43 ? ? ? ? ? ? 1957 MET A N 1 +ATOM 812 C CA . MET A 1 102 ? 19.356 28.207 35.265 1.00 28.51 ? ? ? ? ? ? 1957 MET A CA 1 +ATOM 813 C C . MET A 1 102 ? 20.816 28.021 34.891 1.00 32.93 ? ? ? ? ? ? 1957 MET A C 1 +ATOM 814 O O . MET A 1 102 ? 21.192 26.987 34.350 1.00 30.25 ? ? ? ? ? ? 1957 MET A O 1 +ATOM 815 C CB . MET A 1 102 ? 18.604 28.871 34.114 1.00 27.47 ? ? ? ? ? ? 1957 MET A CB 1 +ATOM 816 C CG . MET A 1 102 ? 17.097 28.897 34.268 1.00 39.52 ? ? ? ? ? ? 1957 MET A CG 1 +ATOM 817 S SD . MET A 1 102 ? 16.345 27.268 34.380 1.00 49.64 ? ? ? ? ? ? 1957 MET A SD 1 +ATOM 818 C CE . MET A 1 102 ? 16.875 26.538 32.833 1.00 45.28 ? ? ? ? ? ? 1957 MET A CE 1 +ATOM 819 N N . ARG A 1 103 ? 21.646 29.016 35.189 1.00 29.70 ? ? ? ? ? ? 1958 ARG A N 1 +ATOM 820 C CA . ARG A 1 103 ? 23.072 28.885 34.919 1.00 32.76 ? ? ? ? ? ? 1958 ARG A CA 1 +ATOM 821 C C . ARG A 1 103 ? 23.687 27.764 35.757 1.00 32.90 ? ? ? ? ? ? 1958 ARG A C 1 +ATOM 822 O O . ARG A 1 103 ? 24.428 26.919 35.246 1.00 33.36 ? ? ? ? ? ? 1958 ARG A O 1 +ATOM 823 C CB . ARG A 1 103 ? 23.808 30.197 35.193 1.00 31.20 ? ? ? ? ? ? 1958 ARG A CB 1 +ATOM 824 C CG . ARG A 1 103 ? 25.253 30.163 34.725 1.00 32.68 ? ? ? ? ? ? 1958 ARG A CG 1 +ATOM 825 C CD . ARG A 1 103 ? 26.096 31.232 35.384 1.00 31.57 ? ? ? ? ? ? 1958 ARG A CD 1 +ATOM 826 N NE . ARG A 1 103 ? 25.736 32.575 34.924 1.00 31.75 ? ? ? ? ? ? 1958 ARG A NE 1 +ATOM 827 C CZ . ARG A 1 103 ? 26.204 33.146 33.817 1.00 35.48 ? ? ? ? ? ? 1958 ARG A CZ 1 +ATOM 828 N NH1 . ARG A 1 103 ? 27.050 32.489 33.024 1.00 32.53 ? ? ? ? ? ? 1958 ARG A NH1 1 +ATOM 829 N NH2 . ARG A 1 103 ? 25.819 34.378 33.499 1.00 30.07 ? ? ? ? ? ? 1958 ARG A NH2 1 +ATOM 830 N N . LYS A 1 104 ? 23.374 27.766 37.048 1.00 32.49 ? ? ? ? ? ? 1959 LYS A N 1 +ATOM 831 C CA . LYS A 1 104 ? 23.852 26.728 37.954 1.00 32.19 ? ? ? ? ? ? 1959 LYS A CA 1 +ATOM 832 C C . LYS A 1 104 ? 23.352 25.369 37.481 1.00 35.33 ? ? ? ? ? ? 1959 LYS A C 1 +ATOM 833 O O . LYS A 1 104 ? 24.099 24.389 37.459 1.00 36.31 ? ? ? ? ? ? 1959 LYS A O 1 +ATOM 834 C CB . LYS A 1 104 ? 23.385 27.010 39.384 1.00 33.87 ? ? ? ? ? ? 1959 LYS A CB 1 +ATOM 835 C CG . LYS A 1 104 ? 23.866 25.994 40.405 1.00 43.97 ? ? ? ? ? ? 1959 LYS A CG 1 +ATOM 836 C CD . LYS A 1 104 ? 25.302 26.262 40.817 1.00 51.40 ? ? ? ? ? ? 1959 LYS A CD 1 +ATOM 837 N N . TYR A 1 105 ? 22.082 25.329 37.093 1.00 32.80 ? ? ? ? ? ? 1960 TYR A N 1 +ATOM 838 C CA . TYR A 1 105 ? 21.460 24.112 36.601 1.00 36.37 ? ? ? ? ? ? 1960 TYR A CA 1 +ATOM 839 C C . TYR A 1 105 ? 22.227 23.581 35.389 1.00 37.71 ? ? ? ? ? ? 1960 TYR A C 1 +ATOM 840 O O . TYR A 1 105 ? 22.574 22.398 35.340 1.00 33.30 ? ? ? ? ? ? 1960 TYR A O 1 +ATOM 841 C CB . TYR A 1 105 ? 19.992 24.369 36.251 1.00 30.23 ? ? ? ? ? ? 1960 TYR A CB 1 +ATOM 842 C CG . TYR A 1 105 ? 19.191 23.115 35.960 1.00 40.26 ? ? ? ? ? ? 1960 TYR A CG 1 +ATOM 843 C CD1 . TYR A 1 105 ? 18.833 22.234 36.984 1.00 41.13 ? ? ? ? ? ? 1960 TYR A CD1 1 +ATOM 844 C CD2 . TYR A 1 105 ? 18.783 22.816 34.664 1.00 33.74 ? ? ? ? ? ? 1960 TYR A CD2 1 +ATOM 845 C CE1 . TYR A 1 105 ? 18.095 21.083 36.716 1.00 41.13 ? ? ? ? ? ? 1960 TYR A CE1 1 +ATOM 846 C CE2 . TYR A 1 105 ? 18.042 21.678 34.393 1.00 33.48 ? ? ? ? ? ? 1960 TYR A CE2 1 +ATOM 847 C CZ . TYR A 1 105 ? 17.705 20.817 35.416 1.00 36.28 ? ? ? ? ? ? 1960 TYR A CZ 1 +ATOM 848 O OH . TYR A 1 105 ? 16.972 19.687 35.128 1.00 45.03 ? ? ? ? ? ? 1960 TYR A OH 1 +ATOM 849 N N . PHE A 1 106 ? 22.513 24.465 34.437 1.00 31.27 ? ? ? ? ? ? 1961 PHE A N 1 +ATOM 850 C CA . PHE A 1 106 ? 23.262 24.083 33.235 1.00 31.21 ? ? ? ? ? ? 1961 PHE A CA 1 +ATOM 851 C C . PHE A 1 106 ? 24.652 23.563 33.541 1.00 32.40 ? ? ? ? ? ? 1961 PHE A C 1 +ATOM 852 O O . PHE A 1 106 ? 25.042 22.504 33.063 1.00 32.91 ? ? ? ? ? ? 1961 PHE A O 1 +ATOM 853 C CB . PHE A 1 106 ? 23.419 25.254 32.274 1.00 28.14 ? ? ? ? ? ? 1961 PHE A CB 1 +ATOM 854 C CG . PHE A 1 106 ? 24.362 24.954 31.127 1.00 30.53 ? ? ? ? ? ? 1961 PHE A CG 1 +ATOM 855 C CD1 . PHE A 1 106 ? 23.998 24.060 30.134 1.00 30.88 ? ? ? ? ? ? 1961 PHE A CD1 1 +ATOM 856 C CD2 . PHE A 1 106 ? 25.617 25.546 31.060 1.00 32.26 ? ? ? ? ? ? 1961 PHE A CD2 1 +ATOM 857 C CE1 . PHE A 1 106 ? 24.857 23.772 29.081 1.00 29.70 ? ? ? ? ? ? 1961 PHE A CE1 1 +ATOM 858 C CE2 . PHE A 1 106 ? 26.484 25.258 30.005 1.00 32.55 ? ? ? ? ? ? 1961 PHE A CE2 1 +ATOM 859 C CZ . PHE A 1 106 ? 26.105 24.372 29.023 1.00 28.34 ? ? ? ? ? ? 1961 PHE A CZ 1 +ATOM 860 N N . GLU A 1 107 ? 25.406 24.328 34.324 1.00 33.72 ? ? ? ? ? ? 1962 GLU A N 1 +ATOM 861 C CA . GLU A 1 107 ? 26.809 24.010 34.550 1.00 37.64 ? ? ? ? ? ? 1962 GLU A CA 1 +ATOM 862 C C . GLU A 1 107 ? 26.988 22.655 35.226 1.00 39.50 ? ? ? ? ? ? 1962 GLU A C 1 +ATOM 863 O O . GLU A 1 107 ? 27.959 21.952 34.954 1.00 36.63 ? ? ? ? ? ? 1962 GLU A O 1 +ATOM 864 C CB . GLU A 1 107 ? 27.486 25.111 35.371 1.00 39.16 ? ? ? ? ? ? 1962 GLU A CB 1 +ATOM 865 C CG . GLU A 1 107 ? 27.549 26.475 34.649 1.00 39.91 ? ? ? ? ? ? 1962 GLU A CG 1 +ATOM 866 C CD . GLU A 1 107 ? 28.307 26.437 33.316 1.00 47.97 ? ? ? ? ? ? 1962 GLU A CD 1 +ATOM 867 O OE1 . GLU A 1 107 ? 29.002 25.435 33.020 1.00 42.54 ? ? ? ? ? ? 1962 GLU A OE1 1 +ATOM 868 O OE2 . GLU A 1 107 ? 28.208 27.428 32.558 1.00 37.48 ? ? ? ? ? ? 1962 GLU A OE2 1 +ATOM 869 N N . LYS A 1 108 ? 26.050 22.276 36.088 1.00 37.04 ? ? ? ? ? ? 1963 LYS A N 1 +ATOM 870 C CA . LYS A 1 108 ? 26.137 20.954 36.716 1.00 41.72 ? ? ? ? ? ? 1963 LYS A CA 1 +ATOM 871 C C . LYS A 1 108 ? 25.835 19.846 35.711 1.00 40.43 ? ? ? ? ? ? 1963 LYS A C 1 +ATOM 872 O O . LYS A 1 108 ? 26.542 18.836 35.675 1.00 42.16 ? ? ? ? ? ? 1963 LYS A O 1 +ATOM 873 C CB . LYS A 1 108 ? 25.191 20.833 37.909 1.00 40.30 ? ? ? ? ? ? 1963 LYS A CB 1 +ATOM 874 C CG . LYS A 1 108 ? 25.520 19.621 38.793 1.00 50.69 ? ? ? ? ? ? 1963 LYS A CG 1 +ATOM 875 C CD . LYS A 1 108 ? 24.282 19.018 39.423 1.00 58.23 ? ? ? ? ? ? 1963 LYS A CD 1 +ATOM 876 C CE . LYS A 1 108 ? 24.642 18.038 40.538 1.00 62.27 ? ? ? ? ? ? 1963 LYS A CE 1 +ATOM 877 N NZ . LYS A 1 108 ? 25.690 17.053 40.151 1.00 55.24 ? ? ? ? ? ? 1963 LYS A NZ 1 +ATOM 878 N N . LYS A 1 109 ? 24.778 20.027 34.918 1.00 36.41 ? ? ? ? ? ? 1964 LYS A N 1 +ATOM 879 C CA . LYS A 1 109 ? 24.452 19.070 33.856 1.00 38.89 ? ? ? ? ? ? 1964 LYS A CA 1 +ATOM 880 C C . LYS A 1 109 ? 25.639 18.936 32.918 1.00 36.92 ? ? ? ? ? ? 1964 LYS A C 1 +ATOM 881 O O . LYS A 1 109 ? 25.984 17.839 32.483 1.00 39.37 ? ? ? ? ? ? 1964 LYS A O 1 +ATOM 882 C CB . LYS A 1 109 ? 23.215 19.508 33.061 1.00 38.49 ? ? ? ? ? ? 1964 LYS A CB 1 +ATOM 883 C CG . LYS A 1 109 ? 21.915 19.561 33.850 1.00 47.19 ? ? ? ? ? ? 1964 LYS A CG 1 +ATOM 884 C CD . LYS A 1 109 ? 21.390 18.172 34.161 1.00 56.84 ? ? ? ? ? ? 1964 LYS A CD 1 +ATOM 885 C CE . LYS A 1 109 ? 20.048 18.232 34.877 1.00 57.29 ? ? ? ? ? ? 1964 LYS A CE 1 +ATOM 886 N N . TRP A 1 110 ? 26.267 20.068 32.617 1.00 35.24 ? ? ? ? ? ? 1965 TRP A N 1 +ATOM 887 C CA . TRP A 1 110 ? 27.410 20.094 31.715 1.00 36.43 ? ? ? ? ? ? 1965 TRP A CA 1 +ATOM 888 C C . TRP A 1 110 ? 28.555 19.268 32.286 1.00 41.14 ? ? ? ? ? ? 1965 TRP A C 1 +ATOM 889 O O . TRP A 1 110 ? 29.107 18.407 31.610 1.00 39.79 ? ? ? ? ? ? 1965 TRP A O 1 +ATOM 890 C CB . TRP A 1 110 ? 27.853 21.538 31.459 1.00 34.92 ? ? ? ? ? ? 1965 TRP A CB 1 +ATOM 891 C CG . TRP A 1 110 ? 28.814 21.688 30.316 1.00 34.06 ? ? ? ? ? ? 1965 TRP A CG 1 +ATOM 892 C CD1 . TRP A 1 110 ? 30.143 21.986 30.396 1.00 39.20 ? ? ? ? ? ? 1965 TRP A CD1 1 +ATOM 893 C CD2 . TRP A 1 110 ? 28.524 21.526 28.921 1.00 29.86 ? ? ? ? ? ? 1965 TRP A CD2 1 +ATOM 894 N NE1 . TRP A 1 110 ? 30.694 22.033 29.140 1.00 39.13 ? ? ? ? ? ? 1965 TRP A NE1 1 +ATOM 895 C CE2 . TRP A 1 110 ? 29.722 21.749 28.217 1.00 29.67 ? ? ? ? ? ? 1965 TRP A CE2 1 +ATOM 896 C CE3 . TRP A 1 110 ? 27.366 21.222 28.200 1.00 24.15 ? ? ? ? ? ? 1965 TRP A CE3 1 +ATOM 897 C CZ2 . TRP A 1 110 ? 29.797 21.679 26.824 1.00 27.82 ? ? ? ? ? ? 1965 TRP A CZ2 1 +ATOM 898 C CZ3 . TRP A 1 110 ? 27.443 21.156 26.814 1.00 28.78 ? ? ? ? ? ? 1965 TRP A CZ3 1 +ATOM 899 C CH2 . TRP A 1 110 ? 28.649 21.385 26.146 1.00 26.52 ? ? ? ? ? ? 1965 TRP A CH2 1 +ATOM 900 N N . THR A 1 111 ? 28.891 19.519 33.546 1.00 36.20 ? ? ? ? ? ? 1966 THR A N 1 +ATOM 901 C CA . THR A 1 111 ? 29.960 18.784 34.204 1.00 48.09 ? ? ? ? ? ? 1966 THR A CA 1 +ATOM 902 C C . THR A 1 111 ? 29.626 17.299 34.329 1.00 47.68 ? ? ? ? ? ? 1966 THR A C 1 +ATOM 903 O O . THR A 1 111 ? 30.461 16.443 34.032 1.00 52.24 ? ? ? ? ? ? 1966 THR A O 1 +ATOM 904 C CB . THR A 1 111 ? 30.254 19.363 35.599 1.00 51.62 ? ? ? ? ? ? 1966 THR A CB 1 +ATOM 905 O OG1 . THR A 1 111 ? 30.772 20.692 35.456 1.00 59.18 ? ? ? ? ? ? 1966 THR A OG1 1 +ATOM 906 C CG2 . THR A 1 111 ? 31.273 18.511 36.327 1.00 60.31 ? ? ? ? ? ? 1966 THR A CG2 1 +ATOM 907 N N . ASP A 1 112 ? 28.404 16.993 34.760 1.00 48.06 ? ? ? ? ? ? 1967 ASP A N 1 +ATOM 908 C CA . ASP A 1 112 ? 27.997 15.601 34.957 1.00 49.92 ? ? ? ? ? ? 1967 ASP A CA 1 +ATOM 909 C C . ASP A 1 112 ? 27.962 14.815 33.654 1.00 48.00 ? ? ? ? ? ? 1967 ASP A C 1 +ATOM 910 O O . ASP A 1 112 ? 28.092 13.594 33.655 1.00 50.67 ? ? ? ? ? ? 1967 ASP A O 1 +ATOM 911 C CB . ASP A 1 112 ? 26.623 15.528 35.618 1.00 50.79 ? ? ? ? ? ? 1967 ASP A CB 1 +ATOM 912 C CG . ASP A 1 112 ? 26.642 16.003 37.056 1.00 58.55 ? ? ? ? ? ? 1967 ASP A CG 1 +ATOM 913 O OD1 . ASP A 1 112 ? 27.745 16.187 37.615 1.00 55.68 ? ? ? ? ? ? 1967 ASP A OD1 1 +ATOM 914 O OD2 . ASP A 1 112 ? 25.548 16.185 37.626 1.00 54.57 ? ? ? ? ? ? 1967 ASP A OD2 1 +ATOM 915 N N . THR A 1 113 ? 27.772 15.514 32.541 1.00 44.16 ? ? ? ? ? ? 1968 THR A N 1 +ATOM 916 C CA . THR A 1 113 ? 27.627 14.831 31.264 1.00 42.40 ? ? ? ? ? ? 1968 THR A CA 1 +ATOM 917 C C . THR A 1 113 ? 28.976 14.606 30.593 1.00 43.79 ? ? ? ? ? ? 1968 THR A C 1 +ATOM 918 O O . THR A 1 113 ? 29.202 13.558 30.000 1.00 53.58 ? ? ? ? ? ? 1968 THR A O 1 +ATOM 919 C CB . THR A 1 113 ? 26.695 15.613 30.321 1.00 43.22 ? ? ? ? ? ? 1968 THR A CB 1 +ATOM 920 O OG1 . THR A 1 113 ? 25.412 15.759 30.945 1.00 39.24 ? ? ? ? ? ? 1968 THR A OG1 1 +ATOM 921 C CG2 . THR A 1 113 ? 26.532 14.884 28.984 1.00 39.18 ? ? ? ? ? ? 1968 THR A CG2 1 +ATOM 922 N N . PHE A 1 114 ? 29.887 15.566 30.708 1.00 54.37 ? ? ? ? ? ? 1969 PHE A N 1 +ATOM 923 C CA . PHE A 1 114 ? 31.148 15.467 29.980 1.00 58.67 ? ? ? ? ? ? 1969 PHE A CA 1 +ATOM 924 C C . PHE A 1 114 ? 32.385 15.400 30.880 1.00 71.55 ? ? ? ? ? ? 1969 PHE A C 1 +ATOM 925 O O . PHE A 1 114 ? 33.348 14.706 30.558 1.00 82.08 ? ? ? ? ? ? 1969 PHE A O 1 +ATOM 926 C CB . PHE A 1 114 ? 31.266 16.638 29.001 1.00 54.23 ? ? ? ? ? ? 1969 PHE A CB 1 +ATOM 927 C CG . PHE A 1 114 ? 30.148 16.694 27.995 1.00 45.53 ? ? ? ? ? ? 1969 PHE A CG 1 +ATOM 928 C CD1 . PHE A 1 114 ? 30.067 15.757 26.973 1.00 49.90 ? ? ? ? ? ? 1969 PHE A CD1 1 +ATOM 929 C CD2 . PHE A 1 114 ? 29.175 17.676 28.077 1.00 41.75 ? ? ? ? ? ? 1969 PHE A CD2 1 +ATOM 930 C CE1 . PHE A 1 114 ? 29.033 15.804 26.049 1.00 45.03 ? ? ? ? ? ? 1969 PHE A CE1 1 +ATOM 931 C CE2 . PHE A 1 114 ? 28.143 17.733 27.160 1.00 39.17 ? ? ? ? ? ? 1969 PHE A CE2 1 +ATOM 932 C CZ . PHE A 1 114 ? 28.068 16.800 26.145 1.00 40.53 ? ? ? ? ? ? 1969 PHE A CZ 1 +ATOM 933 N N . LYS A 1 115 ? 32.363 16.107 32.004 1.00 77.87 ? ? ? ? ? ? 1970 LYS A N 1 +ATOM 934 C CA . LYS A 1 115 ? 33.495 16.083 32.929 1.00 84.68 ? ? ? ? ? ? 1970 LYS A CA 1 +ATOM 935 C C . LYS A 1 115 ? 33.430 14.872 33.857 1.00 86.35 ? ? ? ? ? ? 1970 LYS A C 1 +ATOM 936 O O . LYS A 1 115 ? 33.662 13.738 33.432 1.00 87.69 ? ? ? ? ? ? 1970 LYS A O 1 +ATOM 937 C CB . LYS A 1 115 ? 33.549 17.374 33.750 1.00 80.81 ? ? ? ? ? ? 1970 LYS A CB 1 +HETATM 938 F F . ZYB B 2 . ? 13.101 41.429 28.043 1.00 57.66 ? ? ? ? ? ? 2971 ZYB A F 1 +HETATM 939 C C2 . ZYB B 2 . ? 12.706 41.725 29.252 1.00 56.97 ? ? ? ? ? ? 2971 ZYB A C2 1 +HETATM 940 C C1 . ZYB B 2 . ? 13.585 41.632 30.293 1.00 55.75 ? ? ? ? ? ? 2971 ZYB A C1 1 +HETATM 941 C C3 . ZYB B 2 . ? 11.420 42.125 29.483 1.00 52.80 ? ? ? ? ? ? 2971 ZYB A C3 1 +HETATM 942 C C4 . ZYB B 2 . ? 11.019 42.445 30.749 1.00 44.44 ? ? ? ? ? ? 2971 ZYB A C4 1 +HETATM 943 C C5 . ZYB B 2 . ? 11.884 42.352 31.805 1.00 44.59 ? ? ? ? ? ? 2971 ZYB A C5 1 +HETATM 944 C C . ZYB B 2 . ? 13.173 41.955 31.565 1.00 45.42 ? ? ? ? ? ? 2971 ZYB A C 1 +HETATM 945 C C6 . ZYB B 2 . ? 11.464 42.703 33.214 1.00 53.45 ? ? ? ? ? ? 2971 ZYB A C6 1 +HETATM 946 N N . ZYB B 2 . ? 12.323 43.272 34.165 1.00 56.95 ? ? ? ? ? ? 2971 ZYB A N 1 +HETATM 947 N N1 . ZYB B 2 . ? 10.288 42.524 33.655 1.00 62.80 ? ? ? ? ? ? 2971 ZYB A N1 1 +HETATM 948 O O . ZYB B 2 . ? 9.346 41.983 32.897 1.00 74.37 ? ? ? ? ? ? 2971 ZYB A O 1 +HETATM 949 H H1 . ZYB B 2 . ? 14.499 41.347 30.130 1.00 66.90 ? ? ? ? ? ? 2971 ZYB A H1 1 +HETATM 950 H H3 . ZYB B 2 . ? 10.792 42.194 28.744 1.00 63.37 ? ? ? ? ? ? 2971 ZYB A H3 1 +HETATM 951 H H . ZYB B 2 . ? 13.802 41.889 32.302 1.00 54.51 ? ? ? ? ? ? 2971 ZYB A H 1 +HETATM 952 H H4 . ZYB B 2 . ? 10.105 42.732 30.881 1.00 53.33 ? ? ? ? ? ? 2971 ZYB A H4 1 +HETATM 953 H HN1 . ZYB B 2 . ? 12.007 43.463 34.999 1.00 68.34 ? ? ? ? ? ? 2971 ZYB A HN1 1 +HETATM 954 H HN2 . ZYB B 2 . ? 13.192 43.451 33.952 1.00 68.34 ? ? ? ? ? ? 2971 ZYB A HN2 1 +HETATM 955 H HB . ZYB B 2 . ? 9.117 42.563 32.266 1.00 89.25 ? ? ? ? ? ? 2971 ZYB A HB 1 +HETATM 956 C C . MOH C 3 . ? 14.843 38.427 29.938 1.00 20.02 ? ? ? ? ? ? 2972 MOH A C 1 +HETATM 957 O O . MOH C 3 . ? 15.883 39.362 30.110 1.00 23.93 ? ? ? ? ? ? 2972 MOH A O 1 +HETATM 958 C C . MOH D 3 . ? 19.997 17.491 15.480 1.00 47.26 ? ? ? ? ? ? 2973 MOH A C 1 +HETATM 959 O O . MOH D 3 . ? 19.916 17.750 16.873 1.00 51.18 ? ? ? ? ? ? 2973 MOH A O 1 +HETATM 960 C C . MOH E 3 . ? 20.262 13.641 17.581 1.00 65.59 ? ? ? ? ? ? 2974 MOH A C 1 +HETATM 961 O O . MOH E 3 . ? 19.727 14.187 18.770 1.00 65.24 ? ? ? ? ? ? 2974 MOH A O 1 +HETATM 962 O O . HOH F 4 . ? 10.022 21.482 25.696 1.00 72.06 ? ? ? ? ? ? 2001 HOH A O 1 +HETATM 963 O O . HOH F 4 . ? 9.855 23.456 23.774 1.00 66.16 ? ? ? ? ? ? 2002 HOH A O 1 +HETATM 964 O O . HOH F 4 . ? 49.309 8.719 21.892 1.00 45.11 ? ? ? ? ? ? 2003 HOH A O 1 +HETATM 965 O O . HOH F 4 . ? 13.719 20.834 37.413 1.00 62.79 ? ? ? ? ? ? 2004 HOH A O 1 +HETATM 966 O O . HOH F 4 . ? 4.983 33.736 30.894 1.00 67.99 ? ? ? ? ? ? 2005 HOH A O 1 +HETATM 967 O O . HOH F 4 . ? 6.459 35.205 30.033 1.00 61.90 ? ? ? ? ? ? 2006 HOH A O 1 +HETATM 968 O O . HOH F 4 . ? 7.918 32.035 26.603 1.00 61.36 ? ? ? ? ? ? 2007 HOH A O 1 +HETATM 969 O O . HOH F 4 . ? 10.497 38.082 29.860 1.00 67.61 ? ? ? ? ? ? 2008 HOH A O 1 +HETATM 970 O O . HOH F 4 . ? 9.999 27.064 20.875 1.00 70.16 ? ? ? ? ? ? 2009 HOH A O 1 +HETATM 971 O O . HOH F 4 . ? 16.743 38.611 18.320 1.00 33.23 ? ? ? ? ? ? 2010 HOH A O 1 +HETATM 972 O O . HOH F 4 . ? 14.593 38.990 16.988 1.00 75.27 ? ? ? ? ? ? 2011 HOH A O 1 +HETATM 973 O O . HOH F 4 . ? 12.283 49.752 21.320 1.00 55.93 ? ? ? ? ? ? 2012 HOH A O 1 +HETATM 974 O O . HOH F 4 . ? 20.363 42.495 17.546 1.00 39.08 ? ? ? ? ? ? 2013 HOH A O 1 +HETATM 975 O O . HOH F 4 . ? 13.381 45.493 15.888 1.00 49.69 ? ? ? ? ? ? 2014 HOH A O 1 +HETATM 976 O O . HOH F 4 . ? 27.826 39.234 23.817 1.00 37.96 ? ? ? ? ? ? 2015 HOH A O 1 +HETATM 977 O O . HOH F 4 . ? 21.090 38.507 16.588 1.00 45.63 ? ? ? ? ? ? 2016 HOH A O 1 +HETATM 978 O O . HOH F 4 . ? 29.397 34.268 22.742 1.00 55.62 ? ? ? ? ? ? 2017 HOH A O 1 +HETATM 979 O O . HOH F 4 . ? 31.710 37.827 23.339 1.00 72.95 ? ? ? ? ? ? 2018 HOH A O 1 +HETATM 980 O O . HOH F 4 . ? 17.743 36.110 18.353 1.00 30.04 ? ? ? ? ? ? 2019 HOH A O 1 +HETATM 981 O O . HOH F 4 . ? 12.010 25.049 19.917 1.00 41.58 ? ? ? ? ? ? 2020 HOH A O 1 +HETATM 982 O O . HOH F 4 . ? 15.066 30.157 15.335 1.00 56.83 ? ? ? ? ? ? 2021 HOH A O 1 +HETATM 983 O O . HOH F 4 . ? 28.488 34.280 19.639 1.00 77.03 ? ? ? ? ? ? 2022 HOH A O 1 +HETATM 984 O O . HOH F 4 . ? 13.795 19.144 14.680 1.00 66.35 ? ? ? ? ? ? 2023 HOH A O 1 +HETATM 985 O O . HOH F 4 . ? 20.388 31.994 14.337 1.00 52.47 ? ? ? ? ? ? 2024 HOH A O 1 +HETATM 986 O O . HOH F 4 . ? 17.099 30.537 14.683 1.00 46.13 ? ? ? ? ? ? 2025 HOH A O 1 +HETATM 987 O O . HOH F 4 . ? 19.150 30.128 14.146 1.00 55.85 ? ? ? ? ? ? 2026 HOH A O 1 +HETATM 988 O O . HOH F 4 . ? 30.873 32.142 27.922 1.00 43.66 ? ? ? ? ? ? 2027 HOH A O 1 +HETATM 989 O O . HOH F 4 . ? 28.359 38.272 26.378 1.00 36.65 ? ? ? ? ? ? 2028 HOH A O 1 +HETATM 990 O O . HOH F 4 . ? 26.162 44.602 34.444 1.00 76.95 ? ? ? ? ? ? 2029 HOH A O 1 +HETATM 991 O O . HOH F 4 . ? 20.950 34.480 42.959 1.00 54.47 ? ? ? ? ? ? 2030 HOH A O 1 +HETATM 992 O O . HOH F 4 . ? 23.798 36.496 43.163 1.00 55.30 ? ? ? ? ? ? 2031 HOH A O 1 +HETATM 993 O O . HOH F 4 . ? 28.782 29.253 36.276 1.00 58.23 ? ? ? ? ? ? 2032 HOH A O 1 +HETATM 994 O O . HOH F 4 . ? 32.622 23.373 33.061 1.00 57.54 ? ? ? ? ? ? 2033 HOH A O 1 +HETATM 995 O O . HOH F 4 . ? 7.889 28.220 23.936 1.00 66.20 ? ? ? ? ? ? 2034 HOH A O 1 +HETATM 996 O O . HOH F 4 . ? 18.062 36.986 14.008 1.00 64.39 ? ? ? ? ? ? 2035 HOH A O 1 +HETATM 997 O O . HOH F 4 . ? 6.759 29.564 25.379 1.00 61.49 ? ? ? ? ? ? 2036 HOH A O 1 +HETATM 998 O O . HOH F 4 . ? 18.877 40.002 17.035 1.00 41.58 ? ? ? ? ? ? 2037 HOH A O 1 +HETATM 999 O O . HOH F 4 . ? 17.947 40.034 14.360 1.00 71.33 ? ? ? ? ? ? 2038 HOH A O 1 +HETATM 1000 O O . HOH F 4 . ? 49.700 17.754 20.028 1.00 33.75 ? ? ? ? ? ? 2039 HOH A O 1 +HETATM 1001 O O . HOH F 4 . ? 54.699 18.951 14.314 1.00 36.13 ? ? ? ? ? ? 2040 HOH A O 1 +HETATM 1002 O O . HOH F 4 . ? 48.417 16.913 11.414 1.00 44.68 ? ? ? ? ? ? 2041 HOH A O 1 +HETATM 1003 O O . HOH F 4 . ? 47.833 9.932 20.324 1.00 44.46 ? ? ? ? ? ? 2042 HOH A O 1 +HETATM 1004 O O . HOH F 4 . ? 47.016 20.600 15.420 1.00 56.49 ? ? ? ? ? ? 2043 HOH A O 1 +HETATM 1005 O O . HOH F 4 . ? 36.084 8.857 24.173 1.00 64.01 ? ? ? ? ? ? 2044 HOH A O 1 +HETATM 1006 O O . HOH F 4 . ? 30.306 11.616 22.382 1.00 41.64 ? ? ? ? ? ? 2045 HOH A O 1 +HETATM 1007 O O . HOH F 4 . ? 24.872 12.423 18.724 1.00 31.83 ? ? ? ? ? ? 2046 HOH A O 1 +HETATM 1008 O O . HOH F 4 . ? 32.113 18.160 20.044 1.00 43.06 ? ? ? ? ? ? 2047 HOH A O 1 +HETATM 1009 O O . HOH F 4 . ? 18.823 13.311 22.917 1.00 51.53 ? ? ? ? ? ? 2048 HOH A O 1 +HETATM 1010 O O . HOH F 4 . ? 16.161 15.671 23.834 1.00 53.90 ? ? ? ? ? ? 2049 HOH A O 1 +HETATM 1011 O O . HOH F 4 . ? 16.474 15.356 28.505 1.00 49.39 ? ? ? ? ? ? 2050 HOH A O 1 +HETATM 1012 O O . HOH F 4 . ? 19.716 11.870 25.898 1.00 55.67 ? ? ? ? ? ? 2051 HOH A O 1 +HETATM 1013 O O . HOH F 4 . ? 14.190 20.080 33.755 1.00 40.86 ? ? ? ? ? ? 2052 HOH A O 1 +HETATM 1014 O O . HOH F 4 . ? 16.006 16.626 33.801 1.00 63.70 ? ? ? ? ? ? 2053 HOH A O 1 +HETATM 1015 O O . HOH F 4 . ? 9.820 25.253 31.112 1.00 38.19 ? ? ? ? ? ? 2054 HOH A O 1 +HETATM 1016 O O . HOH F 4 . ? 9.286 23.840 26.837 1.00 71.54 ? ? ? ? ? ? 2055 HOH A O 1 +HETATM 1017 O O . HOH F 4 . ? 11.813 22.481 37.237 1.00 40.67 ? ? ? ? ? ? 2056 HOH A O 1 +HETATM 1018 O O . HOH F 4 . ? 8.637 27.688 31.635 1.00 50.11 ? ? ? ? ? ? 2057 HOH A O 1 +HETATM 1019 O O . HOH F 4 . ? 7.209 33.128 28.724 1.00 71.36 ? ? ? ? ? ? 2058 HOH A O 1 +HETATM 1020 O O . HOH F 4 . ? 10.592 33.431 26.632 1.00 31.26 ? ? ? ? ? ? 2059 HOH A O 1 +HETATM 1021 O O . HOH F 4 . ? 11.235 37.314 27.829 1.00 50.09 ? ? ? ? ? ? 2060 HOH A O 1 +HETATM 1022 O O . HOH F 4 . ? 14.805 35.285 26.097 1.00 28.85 ? ? ? ? ? ? 2061 HOH A O 1 +HETATM 1023 O O . HOH F 4 . ? 12.020 27.287 23.727 1.00 39.16 ? ? ? ? ? ? 2062 HOH A O 1 +HETATM 1024 O O . HOH F 4 . ? 10.652 36.085 25.723 1.00 45.42 ? ? ? ? ? ? 2063 HOH A O 1 +HETATM 1025 O O . HOH F 4 . ? 9.631 36.738 20.608 1.00 68.57 ? ? ? ? ? ? 2064 HOH A O 1 +HETATM 1026 O O . HOH F 4 . ? 15.877 39.137 20.800 1.00 31.10 ? ? ? ? ? ? 2065 HOH A O 1 +HETATM 1027 O O . HOH F 4 . ? 16.548 37.288 22.780 1.00 27.50 ? ? ? ? ? ? 2066 HOH A O 1 +HETATM 1028 O O . HOH F 4 . ? 9.739 39.897 24.415 1.00 38.01 ? ? ? ? ? ? 2067 HOH A O 1 +HETATM 1029 O O . HOH F 4 . ? 12.396 41.088 17.671 1.00 54.61 ? ? ? ? ? ? 2068 HOH A O 1 +HETATM 1030 O O . HOH F 4 . ? 14.917 46.883 22.021 1.00 34.11 ? ? ? ? ? ? 2069 HOH A O 1 +HETATM 1031 O O . HOH F 4 . ? 10.354 49.867 22.445 1.00 54.04 ? ? ? ? ? ? 2070 HOH A O 1 +HETATM 1032 O O . HOH F 4 . ? 17.013 49.205 22.232 1.00 35.94 ? ? ? ? ? ? 2071 HOH A O 1 +HETATM 1033 O O . HOH F 4 . ? 15.002 51.840 23.760 1.00 38.50 ? ? ? ? ? ? 2072 HOH A O 1 +HETATM 1034 O O . HOH F 4 . ? 18.929 37.372 24.878 1.00 26.24 ? ? ? ? ? ? 2073 HOH A O 1 +HETATM 1035 O O . HOH F 4 . ? 18.365 38.934 28.770 1.00 27.93 ? ? ? ? ? ? 2074 HOH A O 1 +HETATM 1036 O O . HOH F 4 . ? 20.711 43.703 19.713 1.00 38.04 ? ? ? ? ? ? 2075 HOH A O 1 +HETATM 1037 O O . HOH F 4 . ? 15.285 43.920 14.949 1.00 62.80 ? ? ? ? ? ? 2076 HOH A O 1 +HETATM 1038 O O . HOH F 4 . ? 24.523 55.530 19.752 1.00 41.19 ? ? ? ? ? ? 2077 HOH A O 1 +HETATM 1039 O O . HOH F 4 . ? 25.819 42.790 24.965 1.00 41.83 ? ? ? ? ? ? 2078 HOH A O 1 +HETATM 1040 O O . HOH F 4 . ? 25.262 40.180 24.148 1.00 32.73 ? ? ? ? ? ? 2079 HOH A O 1 +HETATM 1041 O O . HOH F 4 . ? 23.236 40.295 16.935 1.00 65.81 ? ? ? ? ? ? 2080 HOH A O 1 +HETATM 1042 O O . HOH F 4 . ? 23.693 44.108 18.054 1.00 51.91 ? ? ? ? ? ? 2081 HOH A O 1 +HETATM 1043 O O . HOH F 4 . ? 24.530 49.151 18.245 1.00 68.10 ? ? ? ? ? ? 2082 HOH A O 1 +HETATM 1044 O O . HOH F 4 . ? 29.757 36.549 22.673 1.00 59.13 ? ? ? ? ? ? 2083 HOH A O 1 +HETATM 1045 O O . HOH F 4 . ? 17.620 35.461 21.013 1.00 26.30 ? ? ? ? ? ? 2084 HOH A O 1 +HETATM 1046 O O . HOH F 4 . ? 20.282 36.066 18.152 1.00 47.27 ? ? ? ? ? ? 2085 HOH A O 1 +HETATM 1047 O O . HOH F 4 . ? 17.191 35.183 26.434 1.00 31.45 ? ? ? ? ? ? 2086 HOH A O 1 +HETATM 1048 O O . HOH F 4 . ? 13.631 26.057 18.018 1.00 31.32 ? ? ? ? ? ? 2087 HOH A O 1 +HETATM 1049 O O . HOH F 4 . ? 13.876 31.159 17.942 1.00 48.99 ? ? ? ? ? ? 2088 HOH A O 1 +HETATM 1050 O O . HOH F 4 . ? 16.769 34.148 16.880 1.00 37.84 ? ? ? ? ? ? 2089 HOH A O 1 +HETATM 1051 O O . HOH F 4 . ? 18.148 19.502 18.580 1.00 41.24 ? ? ? ? ? ? 2090 HOH A O 1 +HETATM 1052 O O . HOH F 4 . ? 13.480 17.462 21.017 1.00 63.97 ? ? ? ? ? ? 2091 HOH A O 1 +HETATM 1053 O O . HOH F 4 . ? 14.246 24.172 16.064 1.00 40.37 ? ? ? ? ? ? 2092 HOH A O 1 +HETATM 1054 O O . HOH F 4 . ? 13.807 24.254 10.402 1.00 53.41 ? ? ? ? ? ? 2093 HOH A O 1 +HETATM 1055 O O . HOH F 4 . ? 18.290 26.528 10.971 1.00 37.65 ? ? ? ? ? ? 2094 HOH A O 1 +HETATM 1056 O O . HOH F 4 . ? 23.456 32.819 16.199 1.00 41.64 ? ? ? ? ? ? 2095 HOH A O 1 +HETATM 1057 O O . HOH F 4 . ? 27.413 30.028 17.492 1.00 49.77 ? ? ? ? ? ? 2096 HOH A O 1 +HETATM 1058 O O . HOH F 4 . ? 26.076 32.886 18.780 1.00 39.46 ? ? ? ? ? ? 2097 HOH A O 1 +HETATM 1059 O O . HOH F 4 . ? 24.839 21.430 15.660 1.00 26.90 ? ? ? ? ? ? 2098 HOH A O 1 +HETATM 1060 O O . HOH F 4 . ? 17.451 17.851 12.901 1.00 47.85 ? ? ? ? ? ? 2099 HOH A O 1 +HETATM 1061 O O . HOH F 4 . ? 14.075 21.548 16.258 1.00 52.21 ? ? ? ? ? ? 2100 HOH A O 1 +HETATM 1062 O O . HOH F 4 . ? 28.093 28.077 16.234 1.00 53.38 ? ? ? ? ? ? 2101 HOH A O 1 +HETATM 1063 O O . HOH F 4 . ? 22.331 30.655 10.032 1.00 57.12 ? ? ? ? ? ? 2102 HOH A O 1 +HETATM 1064 O O . HOH F 4 . ? 22.795 31.536 13.460 1.00 58.79 ? ? ? ? ? ? 2103 HOH A O 1 +HETATM 1065 O O . HOH F 4 . ? 25.878 30.199 13.548 1.00 62.49 ? ? ? ? ? ? 2104 HOH A O 1 +HETATM 1066 O O . HOH F 4 . ? 18.842 29.119 12.218 1.00 43.86 ? ? ? ? ? ? 2105 HOH A O 1 +HETATM 1067 O O . HOH F 4 . ? 36.270 22.341 16.173 1.00 63.22 ? ? ? ? ? ? 2106 HOH A O 1 +HETATM 1068 O O . HOH F 4 . ? 35.040 21.758 21.898 1.00 58.36 ? ? ? ? ? ? 2107 HOH A O 1 +HETATM 1069 O O . HOH F 4 . ? 28.536 29.888 20.202 1.00 41.22 ? ? ? ? ? ? 2108 HOH A O 1 +HETATM 1070 O O . HOH F 4 . ? 29.358 32.925 25.925 1.00 31.19 ? ? ? ? ? ? 2109 HOH A O 1 +HETATM 1071 O O . HOH F 4 . ? 32.517 29.815 28.520 1.00 49.95 ? ? ? ? ? ? 2110 HOH A O 1 +HETATM 1072 O O . HOH F 4 . ? 18.672 36.149 28.506 1.00 26.69 ? ? ? ? ? ? 2111 HOH A O 1 +HETATM 1073 O O . HOH F 4 . ? 21.697 35.070 34.500 1.00 23.79 ? ? ? ? ? ? 2112 HOH A O 1 +HETATM 1074 O O . HOH F 4 . ? 27.482 39.559 32.373 1.00 56.82 ? ? ? ? ? ? 2113 HOH A O 1 +HETATM 1075 O O . HOH F 4 . ? 29.646 35.212 33.130 1.00 50.55 ? ? ? ? ? ? 2114 HOH A O 1 +HETATM 1076 O O . HOH F 4 . ? 28.416 35.532 26.914 1.00 38.68 ? ? ? ? ? ? 2115 HOH A O 1 +HETATM 1077 O O . HOH F 4 . ? 30.252 33.192 30.122 1.00 38.14 ? ? ? ? ? ? 2116 HOH A O 1 +HETATM 1078 O O . HOH F 4 . ? 26.307 39.198 27.582 1.00 37.97 ? ? ? ? ? ? 2117 HOH A O 1 +HETATM 1079 O O . HOH F 4 . ? 20.619 36.858 36.208 1.00 26.65 ? ? ? ? ? ? 2118 HOH A O 1 +HETATM 1080 O O . HOH F 4 . ? 23.667 34.037 36.165 1.00 31.26 ? ? ? ? ? ? 2119 HOH A O 1 +HETATM 1081 O O . HOH F 4 . ? 27.237 34.635 37.381 1.00 53.65 ? ? ? ? ? ? 2120 HOH A O 1 +HETATM 1082 O O . HOH F 4 . ? 26.758 41.946 35.152 1.00 68.46 ? ? ? ? ? ? 2121 HOH A O 1 +HETATM 1083 O O . HOH F 4 . ? 24.279 45.804 32.838 1.00 31.87 ? ? ? ? ? ? 2122 HOH A O 1 +HETATM 1084 O O . HOH F 4 . ? 21.112 39.380 37.230 1.00 27.53 ? ? ? ? ? ? 2123 HOH A O 1 +HETATM 1085 O O . HOH F 4 . ? 14.000 41.650 36.058 1.00 40.53 ? ? ? ? ? ? 2124 HOH A O 1 +HETATM 1086 O O . HOH F 4 . ? 16.010 44.370 36.642 1.00 31.64 ? ? ? ? ? ? 2125 HOH A O 1 +HETATM 1087 O O . HOH F 4 . ? 22.159 43.235 40.031 1.00 35.31 ? ? ? ? ? ? 2126 HOH A O 1 +HETATM 1088 O O . HOH F 4 . ? 19.831 43.489 42.462 1.00 29.68 ? ? ? ? ? ? 2127 HOH A O 1 +HETATM 1089 O O . HOH F 4 . ? 22.549 48.439 39.132 1.00 55.22 ? ? ? ? ? ? 2128 HOH A O 1 +HETATM 1090 O O . HOH F 4 . ? 13.893 48.371 41.323 1.00 71.57 ? ? ? ? ? ? 2129 HOH A O 1 +HETATM 1091 O O . HOH F 4 . ? 18.115 38.151 45.161 1.00 56.51 ? ? ? ? ? ? 2130 HOH A O 1 +HETATM 1092 O O . HOH F 4 . ? 19.704 36.599 42.356 1.00 48.79 ? ? ? ? ? ? 2131 HOH A O 1 +HETATM 1093 O O . HOH F 4 . ? 12.235 40.880 43.778 1.00 50.38 ? ? ? ? ? ? 2132 HOH A O 1 +HETATM 1094 O O . HOH F 4 . ? 14.322 39.623 47.341 1.00 56.25 ? ? ? ? ? ? 2133 HOH A O 1 +HETATM 1095 O O . HOH F 4 . ? 11.799 40.005 36.902 1.00 32.82 ? ? ? ? ? ? 2134 HOH A O 1 +HETATM 1096 O O . HOH F 4 . ? 10.801 40.634 39.586 1.00 45.53 ? ? ? ? ? ? 2135 HOH A O 1 +HETATM 1097 O O . HOH F 4 . ? 18.804 32.671 41.946 1.00 50.79 ? ? ? ? ? ? 2136 HOH A O 1 +HETATM 1098 O O . HOH F 4 . ? 23.623 34.350 42.820 1.00 62.35 ? ? ? ? ? ? 2137 HOH A O 1 +HETATM 1099 O O . HOH F 4 . ? 25.654 32.960 38.818 1.00 38.93 ? ? ? ? ? ? 2138 HOH A O 1 +HETATM 1100 O O . HOH F 4 . ? 24.552 30.490 39.019 1.00 37.91 ? ? ? ? ? ? 2139 HOH A O 1 +HETATM 1101 O O . HOH F 4 . ? 28.619 30.000 33.367 1.00 34.88 ? ? ? ? ? ? 2140 HOH A O 1 +HETATM 1102 O O . HOH F 4 . ? 30.386 31.617 32.147 1.00 45.65 ? ? ? ? ? ? 2141 HOH A O 1 +HETATM 1103 O O . HOH F 4 . ? 26.947 28.741 37.897 1.00 44.53 ? ? ? ? ? ? 2142 HOH A O 1 +HETATM 1104 O O . HOH F 4 . ? 21.982 20.442 37.227 1.00 34.13 ? ? ? ? ? ? 2143 HOH A O 1 +HETATM 1105 O O . HOH F 4 . ? 30.213 23.289 34.002 1.00 38.74 ? ? ? ? ? ? 2144 HOH A O 1 +HETATM 1106 O O . HOH F 4 . ? 32.249 27.856 33.935 1.00 59.39 ? ? ? ? ? ? 2145 HOH A O 1 +HETATM 1107 O O . HOH F 4 . ? 6.377 28.531 21.462 1.00 71.01 ? ? ? ? ? ? 2146 HOH A O 1 +# +loop_ +_atom_site_anisotrop.id +_atom_site_anisotrop.type_symbol +_atom_site_anisotrop.pdbx_label_atom_id +_atom_site_anisotrop.pdbx_label_alt_id +_atom_site_anisotrop.pdbx_label_comp_id +_atom_site_anisotrop.pdbx_label_asym_id +_atom_site_anisotrop.pdbx_label_seq_id +_atom_site_anisotrop.U[1][1] +_atom_site_anisotrop.U[2][2] +_atom_site_anisotrop.U[3][3] +_atom_site_anisotrop.U[1][2] +_atom_site_anisotrop.U[1][3] +_atom_site_anisotrop.U[2][3] +_atom_site_anisotrop.U[1][1]_esd +_atom_site_anisotrop.U[2][2]_esd +_atom_site_anisotrop.U[3][3]_esd +_atom_site_anisotrop.U[1][2]_esd +_atom_site_anisotrop.U[1][3]_esd +_atom_site_anisotrop.U[2][3]_esd +_atom_site_anisotrop.pdbx_auth_seq_id +_atom_site_anisotrop.pdbx_auth_comp_id +_atom_site_anisotrop.pdbx_auth_asym_id +_atom_site_anisotrop.pdbx_auth_atom_id +1 N N . SER A 1 0.4738 0.4524 0.2904 -0.0309 -0.0231 0.0036 ? ? ? ? ? ? 1856 SER A N +2 C CA . SER A 1 0.5262 0.4447 0.3239 -0.0195 -0.0197 0.0010 ? ? ? ? ? ? 1856 SER A CA +3 C C . SER A 1 0.5639 0.4532 0.3452 -0.0370 -0.0113 0.0088 ? ? ? ? ? ? 1856 SER A C +4 O O . SER A 1 0.5214 0.4379 0.3045 -0.0533 -0.0125 0.0141 ? ? ? ? ? ? 1856 SER A O +5 C CB . SER A 1 0.4971 0.3714 0.3023 -0.0165 -0.0119 0.0024 ? ? ? ? ? ? 1856 SER A CB +6 O OG . SER A 1 0.5159 0.3779 0.3411 -0.0339 0.0002 0.0133 ? ? ? ? ? ? 1856 SER A OG +7 N N . MET A 2 0.5837 0.4186 0.3455 -0.0378 -0.0030 0.0086 ? ? ? ? ? ? 1857 MET A N +8 C CA . MET A 2 0.6137 0.4220 0.3555 -0.0563 0.0075 0.0102 ? ? ? ? ? ? 1857 MET A CA +9 C C . MET A 2 0.5509 0.3572 0.3169 -0.0727 0.0190 0.0130 ? ? ? ? ? ? 1857 MET A C +10 O O . MET A 2 0.5733 0.3648 0.3670 -0.0718 0.0282 0.0138 ? ? ? ? ? ? 1857 MET A O +11 C CB . MET A 2 0.6333 0.3897 0.3494 -0.0611 0.0183 0.0080 ? ? ? ? ? ? 1857 MET A CB +12 C CG . MET A 2 0.6662 0.4019 0.3504 -0.0816 0.0276 0.0051 ? ? ? ? ? ? 1857 MET A CG +13 S SD . MET A 2 0.7242 0.4097 0.3748 -0.0992 0.0465 0.0007 ? ? ? ? ? ? 1857 MET A SD +14 C CE . MET A 2 0.6967 0.3644 0.3288 -0.0833 0.0238 0.0119 ? ? ? ? ? ? 1857 MET A CE +15 N N . SER A 3 0.5878 0.4076 0.3446 -0.0878 0.0151 0.0151 ? ? ? ? ? ? 1858 SER A N +16 C CA . SER A 3 0.5857 0.3954 0.3621 -0.1048 0.0183 0.0192 ? ? ? ? ? ? 1858 SER A CA +17 C C . SER A 3 0.5798 0.4172 0.3892 -0.1053 0.0073 0.0323 ? ? ? ? ? ? 1858 SER A C +18 O O . SER A 3 0.5438 0.3604 0.3770 -0.1155 0.0058 0.0394 ? ? ? ? ? ? 1858 SER A O +19 C CB . SER A 3 0.5979 0.3558 0.3839 -0.1078 0.0384 0.0078 ? ? ? ? ? ? 1858 SER A CB +20 O OG . SER A 3 0.6262 0.3621 0.3742 -0.1152 0.0497 -0.0044 ? ? ? ? ? ? 1858 SER A OG +21 N N . VAL A 4 0.4939 0.3776 0.3045 -0.0949 -0.0024 0.0344 ? ? ? ? ? ? 1859 VAL A N +22 C CA . VAL A 4 0.4767 0.3977 0.3092 -0.1020 -0.0135 0.0465 ? ? ? ? ? ? 1859 VAL A CA +23 C C . VAL A 4 0.5088 0.5015 0.3286 -0.1077 -0.0251 0.0451 ? ? ? ? ? ? 1859 VAL A C +24 O O . VAL A 4 0.5134 0.5399 0.3319 -0.0881 -0.0267 0.0318 ? ? ? ? ? ? 1859 VAL A O +25 C CB . VAL A 4 0.4800 0.3967 0.3327 -0.0859 -0.0107 0.0446 ? ? ? ? ? ? 1859 VAL A CB +26 C CG1 . VAL A 4 0.4519 0.4100 0.3216 -0.0993 -0.0239 0.0587 ? ? ? ? ? ? 1859 VAL A CG1 +27 C CG2 . VAL A 4 0.5126 0.3724 0.3835 -0.0805 0.0028 0.0427 ? ? ? ? ? ? 1859 VAL A CG2 +28 N N . LYS A 5 0.4184 0.6083 0.5828 -0.0988 -0.1528 0.2685 ? ? ? ? ? ? 1860 LYS A N +29 C CA . LYS A 5 0.4552 0.6496 0.6325 -0.0654 -0.1521 0.2879 ? ? ? ? ? ? 1860 LYS A CA +30 C C . LYS A 5 0.4328 0.6577 0.5968 -0.0092 -0.1309 0.2755 ? ? ? ? ? ? 1860 LYS A C +31 O O . LYS A 5 0.4454 0.6901 0.5816 0.0006 -0.1073 0.2704 ? ? ? ? ? ? 1860 LYS A O +32 C CB . LYS A 5 0.4611 0.6595 0.6439 -0.0955 -0.1461 0.3268 ? ? ? ? ? ? 1860 LYS A CB +33 C CG . LYS A 5 0.6581 0.8246 0.8468 -0.1371 -0.1692 0.3453 ? ? ? ? ? ? 1860 LYS A CG +34 C CD . LYS A 5 0.7149 0.8580 0.9223 -0.1116 -0.1903 0.3526 ? ? ? ? ? ? 1860 LYS A CD +35 C CE . LYS A 5 0.7720 0.8624 0.9706 -0.1413 -0.2066 0.3626 ? ? ? ? ? ? 1860 LYS A CE +36 N NZ . LYS A 5 0.8178 0.8686 1.0113 -0.1511 -0.2051 0.3295 ? ? ? ? ? ? 1860 LYS A NZ +37 N N . LYS A 6 0.4692 0.6928 0.6480 0.0313 -0.1362 0.2725 ? ? ? ? ? ? 1861 LYS A N +38 C CA . LYS A 6 0.6114 0.8554 0.7743 0.0867 -0.1112 0.2684 ? ? ? ? ? ? 1861 LYS A CA +39 C C . LYS A 6 0.5733 0.8254 0.7342 0.0749 -0.0786 0.2996 ? ? ? ? ? ? 1861 LYS A C +40 O O . LYS A 6 0.5994 0.8503 0.7837 0.0317 -0.0861 0.3218 ? ? ? ? ? ? 1861 LYS A O +41 C CB . LYS A 6 0.7434 0.9802 0.9261 0.1278 -0.1232 0.2597 ? ? ? ? ? ? 1861 LYS A CB +42 C CG . LYS A 6 0.7862 1.0176 0.9719 0.1455 -0.1467 0.2195 ? ? ? ? ? ? 1861 LYS A CG +43 C CD . LYS A 6 0.8266 1.0544 1.0221 0.1964 -0.1476 0.2103 ? ? ? ? ? ? 1861 LYS A CD +44 C CE . LYS A 6 0.8375 1.0530 1.0469 0.2029 -0.1703 0.1696 ? ? ? ? ? ? 1861 LYS A CE +45 N NZ . LYS A 6 0.8385 1.0090 1.0763 0.1584 -0.1875 0.1810 ? ? ? ? ? ? 1861 LYS A NZ +46 N N . PRO A 7 0.5816 0.8418 0.7121 0.1142 -0.0387 0.2989 ? ? ? ? ? ? 1862 PRO A N +47 C CA . PRO A 7 0.6381 0.9005 0.7711 0.1039 0.0042 0.3218 ? ? ? ? ? ? 1862 PRO A CA +48 C C . PRO A 7 0.6730 0.9453 0.8566 0.0916 -0.0078 0.3341 ? ? ? ? ? ? 1862 PRO A C +49 O O . PRO A 7 0.6273 0.8969 0.8289 0.1239 -0.0295 0.3269 ? ? ? ? ? ? 1862 PRO A O +50 C CB . PRO A 7 0.6742 0.9288 0.7631 0.1672 0.0488 0.3153 ? ? ? ? ? ? 1862 PRO A CB +51 C CG . PRO A 7 0.6893 0.9500 0.7394 0.1956 0.0316 0.2926 ? ? ? ? ? ? 1862 PRO A CG +52 C CD . PRO A 7 0.6081 0.8758 0.6951 0.1702 -0.0265 0.2749 ? ? ? ? ? ? 1862 PRO A CD +53 N N . LYS A 8 0.7059 0.9950 0.9129 0.0455 0.0055 0.3496 ? ? ? ? ? ? 1863 LYS A N +54 C CA . LYS A 8 0.7398 1.0556 0.9985 0.0313 -0.0125 0.3585 ? ? ? ? ? ? 1863 LYS A CA +55 C C . LYS A 8 0.7165 1.0435 0.9948 0.0696 0.0212 0.3536 ? ? ? ? ? ? 1863 LYS A C +56 O O . LYS A 8 0.7360 1.0631 1.0042 0.0701 0.0769 0.3512 ? ? ? ? ? ? 1863 LYS A O +57 C CB . LYS A 8 0.7246 1.0699 1.0032 -0.0290 -0.0092 0.3690 ? ? ? ? ? ? 1863 LYS A CB +58 N N . ARG A 9 0.6778 1.0076 0.9823 0.1019 -0.0072 0.3517 ? ? ? ? ? ? 1864 ARG A N +59 C CA . ARG A 9 0.6566 1.0008 0.9892 0.1352 0.0201 0.3470 ? ? ? ? ? ? 1864 ARG A CA +60 C C . ARG A 9 0.6321 1.0311 1.0213 0.0983 0.0267 0.3499 ? ? ? ? ? ? 1864 ARG A C +61 O O . ARG A 9 0.6122 1.0401 1.0269 0.0699 -0.0162 0.3588 ? ? ? ? ? ? 1864 ARG A O +62 C CB . ARG A 9 0.6292 0.9594 0.9727 0.1807 -0.0134 0.3432 ? ? ? ? ? ? 1864 ARG A CB +63 C CG . ARG A 9 0.5745 0.9213 0.9527 0.2143 0.0111 0.3389 ? ? ? ? ? ? 1864 ARG A CG +64 C CD . ARG A 9 0.5640 0.8839 0.9405 0.2369 -0.0241 0.3215 ? ? ? ? ? ? 1864 ARG A CD +65 N NE . ARG A 9 0.5445 0.8849 0.9583 0.2629 -0.0026 0.3175 ? ? ? ? ? ? 1864 ARG A NE +66 C CZ . ARG A 9 0.5468 0.9388 1.0212 0.2529 -0.0155 0.3255 ? ? ? ? ? ? 1864 ARG A CZ +67 N NH1 . ARG A 9 0.5996 1.0224 1.0932 0.2187 -0.0514 0.3384 ? ? ? ? ? ? 1864 ARG A NH1 +68 N NH2 . ARG A 9 0.5486 0.9622 1.0598 0.2776 0.0076 0.3169 ? ? ? ? ? ? 1864 ARG A NH2 +69 N N . ASP A 10 0.7256 0.8417 1.1362 0.2683 0.2421 0.2356 ? ? ? ? ? ? 1865 ASP A N +70 C CA . ASP A 10 0.7403 0.7329 1.0610 0.2483 0.2581 0.1826 ? ? ? ? ? ? 1865 ASP A CA +71 C C . ASP A 10 0.7015 0.6912 0.9233 0.1950 0.2095 0.1579 ? ? ? ? ? ? 1865 ASP A C +72 O O . ASP A 10 0.7150 0.7259 0.9290 0.1788 0.1645 0.1822 ? ? ? ? ? ? 1865 ASP A O +73 C CB . ASP A 10 0.8165 0.7280 1.1585 0.2739 0.2703 0.1987 ? ? ? ? ? ? 1865 ASP A CB +74 C CG . ASP A 10 0.9099 0.7057 1.1560 0.2439 0.2842 0.1412 ? ? ? ? ? ? 1865 ASP A CG +75 O OD1 . ASP A 10 0.8455 0.6158 1.0222 0.2174 0.2979 0.0871 ? ? ? ? ? ? 1865 ASP A OD1 +76 O OD2 . ASP A 10 0.9524 0.6845 1.1886 0.2439 0.2813 0.1501 ? ? ? ? ? ? 1865 ASP A OD2 +77 N N . ASP A 11 0.5749 0.5367 0.7198 0.1683 0.2192 0.1089 ? ? ? ? ? ? 1866 ASP A N +78 C CA . ASP A 11 0.5516 0.5121 0.6054 0.1256 0.1724 0.0859 ? ? ? ? ? ? 1866 ASP A CA +79 C C . ASP A 11 0.5709 0.4370 0.5379 0.1077 0.1738 0.0332 ? ? ? ? ? ? 1866 ASP A C +80 O O . ASP A 11 0.6087 0.4659 0.4959 0.0785 0.1386 0.0055 ? ? ? ? ? ? 1866 ASP A O +81 C CB . ASP A 11 0.5950 0.5917 0.6105 0.1051 0.1720 0.0736 ? ? ? ? ? ? 1866 ASP A CB +82 C CG . ASP A 11 0.7604 0.7038 0.7461 0.1085 0.2261 0.0337 ? ? ? ? ? ? 1866 ASP A CG +83 O OD1 . ASP A 11 0.8501 0.7459 0.8712 0.1342 0.2704 0.0215 ? ? ? ? ? ? 1866 ASP A OD1 +84 O OD2 . ASP A 11 0.8603 0.8046 0.7830 0.0829 0.2267 0.0138 ? ? ? ? ? ? 1866 ASP A OD2 +85 N N . SER A 12 0.6320 0.4296 0.6157 0.1257 0.2142 0.0188 ? ? ? ? ? ? 1867 SER A N +86 C CA . SER A 12 0.6814 0.3936 0.5843 0.1053 0.2269 -0.0379 ? ? ? ? ? ? 1867 SER A CA +87 C C . SER A 12 0.6849 0.3969 0.5396 0.0775 0.1768 -0.0499 ? ? ? ? ? ? 1867 SER A C +88 O O . SER A 12 0.7401 0.4117 0.5161 0.0534 0.1698 -0.1005 ? ? ? ? ? ? 1867 SER A O +89 C CB . SER A 12 0.7634 0.3993 0.6992 0.1274 0.2868 -0.0499 ? ? ? ? ? ? 1867 SER A CB +90 O OG . SER A 12 0.8212 0.4518 0.8132 0.1438 0.2792 -0.0100 ? ? ? ? ? ? 1867 SER A OG +91 N N . LYS A 13 0.6196 0.3847 0.5225 0.0791 0.1420 -0.0056 ? ? ? ? ? ? 1868 LYS A N +92 C CA . LYS A 13 0.5594 0.3358 0.4255 0.0498 0.0964 -0.0178 ? ? ? ? ? ? 1868 LYS A CA +93 C C . LYS A 13 0.5357 0.3838 0.3774 0.0305 0.0412 -0.0137 ? ? ? ? ? ? 1868 LYS A C +94 O O . LYS A 13 0.5501 0.4187 0.3667 0.0066 0.0025 -0.0278 ? ? ? ? ? ? 1868 LYS A O +95 C CB . LYS A 13 0.5625 0.3427 0.4848 0.0549 0.0937 0.0244 ? ? ? ? ? ? 1868 LYS A CB +96 C CG . LYS A 13 0.6511 0.3411 0.5886 0.0718 0.1468 0.0197 ? ? ? ? ? ? 1868 LYS A CG +97 C CD . LYS A 13 0.8535 0.5396 0.8356 0.0757 0.1386 0.0691 ? ? ? ? ? ? 1868 LYS A CD +98 N N . ASP A 14 0.5792 0.3303 0.4684 0.0423 -0.0386 -0.0023 ? ? ? ? ? ? 1869 ASP A N +99 C CA . ASP A 14 0.5678 0.3073 0.4127 0.0349 -0.0492 0.0045 ? ? ? ? ? ? 1869 ASP A CA +100 C C . ASP A 14 0.6101 0.3378 0.4371 0.0335 -0.0449 -0.0058 ? ? ? ? ? ? 1869 ASP A C +101 O O . ASP A 14 0.6273 0.3336 0.4261 0.0321 -0.0465 -0.0005 ? ? ? ? ? ? 1869 ASP A O +102 C CB . ASP A 14 0.5388 0.2972 0.3760 0.0245 -0.0586 0.0021 ? ? ? ? ? ? 1869 ASP A CB +103 C CG . ASP A 14 0.6681 0.4483 0.5179 0.0278 -0.0681 0.0065 ? ? ? ? ? ? 1869 ASP A CG +104 O OD1 . ASP A 14 0.6410 0.4160 0.4944 0.0440 -0.0684 0.0185 ? ? ? ? ? ? 1869 ASP A OD1 +105 O OD2 . ASP A 14 0.6181 0.4211 0.4730 0.0164 -0.0729 -0.0030 ? ? ? ? ? ? 1869 ASP A OD2 +106 N N . LEU A 15 0.5514 0.2997 0.3946 0.0377 -0.0407 -0.0232 ? ? ? ? ? ? 1870 LEU A N +107 C CA . LEU A 15 0.5578 0.3070 0.3816 0.0456 -0.0398 -0.0364 ? ? ? ? ? ? 1870 LEU A CA +108 C C . LEU A 15 0.5951 0.3328 0.4304 0.0472 -0.0318 -0.0464 ? ? ? ? ? ? 1870 LEU A C +109 O O . LEU A 15 0.6180 0.3389 0.4232 0.0491 -0.0348 -0.0454 ? ? ? ? ? ? 1870 LEU A O +110 C CB . LEU A 15 0.5520 0.3412 0.3925 0.0574 -0.0381 -0.0580 ? ? ? ? ? ? 1870 LEU A CB +111 C CG . LEU A 15 0.5274 0.3326 0.3440 0.0770 -0.0402 -0.0750 ? ? ? ? ? ? 1870 LEU A CG +112 C CD1 . LEU A 15 0.5653 0.3347 0.3204 0.0821 -0.0437 -0.0515 ? ? ? ? ? ? 1870 LEU A CD1 +113 C CD2 . LEU A 15 0.5195 0.3802 0.3546 0.0945 -0.0401 -0.1006 ? ? ? ? ? ? 1870 LEU A CD2 +114 N N . ALA A 16 0.5666 0.3090 0.4473 0.0454 -0.0173 -0.0565 ? ? ? ? ? ? 1871 ALA A N +115 C CA . ALA A 16 0.5937 0.3192 0.4919 0.0431 0.0005 -0.0671 ? ? ? ? ? ? 1871 ALA A CA +116 C C . ALA A 16 0.6230 0.3085 0.4819 0.0398 -0.0006 -0.0384 ? ? ? ? ? ? 1871 ALA A C +117 O O . ALA A 16 0.6187 0.2914 0.4668 0.0380 0.0061 -0.0458 ? ? ? ? ? ? 1871 ALA A O +118 C CB . ALA A 16 0.5909 0.3165 0.5484 0.0402 0.0262 -0.0798 ? ? ? ? ? ? 1871 ALA A CB +119 N N . LEU A 17 0.6095 0.2840 0.4489 0.0408 -0.0096 -0.0104 ? ? ? ? ? ? 1872 LEU A N +120 C CA . LEU A 17 0.6141 0.2645 0.4157 0.0425 -0.0130 0.0129 ? ? ? ? ? ? 1872 LEU A CA +121 C C . LEU A 17 0.6387 0.2879 0.4016 0.0364 -0.0290 0.0099 ? ? ? ? ? ? 1872 LEU A C +122 O O . LEU A 17 0.6820 0.3146 0.4212 0.0357 -0.0266 0.0142 ? ? ? ? ? ? 1872 LEU A O +123 C CB . LEU A 17 0.6376 0.2941 0.4317 0.0510 -0.0222 0.0350 ? ? ? ? ? ? 1872 LEU A CB +124 C CG . LEU A 17 0.6777 0.3222 0.5014 0.0641 -0.0023 0.0464 ? ? ? ? ? ? 1872 LEU A CG +125 C CD1 . LEU A 17 0.6695 0.3318 0.4852 0.0791 -0.0171 0.0641 ? ? ? ? ? ? 1872 LEU A CD1 +126 C CD2 . LEU A 17 0.7596 0.3640 0.5745 0.0715 0.0256 0.0601 ? ? ? ? ? ? 1872 LEU A CD2 +127 N N . CYS A 18 0.6335 0.2966 0.3896 0.0327 -0.0413 0.0031 ? ? ? ? ? ? 1873 CYS A N +128 C CA . CYS A 18 0.6385 0.2901 0.3607 0.0287 -0.0491 0.0007 ? ? ? ? ? ? 1873 CYS A CA +129 C C . CYS A 18 0.6661 0.3114 0.3836 0.0353 -0.0438 -0.0149 ? ? ? ? ? ? 1873 CYS A C +130 O O . CYS A 18 0.6390 0.2677 0.3309 0.0337 -0.0463 -0.0152 ? ? ? ? ? ? 1873 CYS A O +131 C CB . CYS A 18 0.6163 0.2733 0.3310 0.0261 -0.0529 0.0002 ? ? ? ? ? ? 1873 CYS A CB +132 S SG . CYS A 18 0.6459 0.3141 0.3649 0.0123 -0.0590 0.0080 ? ? ? ? ? ? 1873 CYS A SG +133 N N . SER A 19 0.4692 0.2749 0.4520 0.0232 -0.0131 -0.0129 ? ? ? ? ? ? 1874 SER A N +134 C CA . SER A 19 0.4433 0.2640 0.4204 0.0160 0.0026 -0.0235 ? ? ? ? ? ? 1874 SER A CA +135 C C . SER A 19 0.4728 0.2763 0.4291 0.0073 0.0096 -0.0021 ? ? ? ? ? ? 1874 SER A C +136 O O . SER A 19 0.4994 0.3140 0.4279 0.0031 0.0179 -0.0038 ? ? ? ? ? ? 1874 SER A O +137 C CB . SER A 19 0.4195 0.2523 0.4438 0.0114 0.0132 -0.0454 ? ? ? ? ? ? 1874 SER A CB +138 O OG . SER A 19 0.5132 0.3642 0.5358 0.0042 0.0279 -0.0576 ? ? ? ? ? ? 1874 SER A OG +139 N N . MET A 20 0.4965 0.2714 0.4660 0.0050 0.0070 0.0177 ? ? ? ? ? ? 1875 MET A N +140 C CA . MET A 20 0.5371 0.2878 0.4822 -0.0030 0.0140 0.0415 ? ? ? ? ? ? 1875 MET A CA +141 C C . MET A 20 0.5594 0.3103 0.4507 -0.0003 0.0056 0.0568 ? ? ? ? ? ? 1875 MET A C +142 O O . MET A 20 0.5613 0.3137 0.4244 -0.0089 0.0169 0.0608 ? ? ? ? ? ? 1875 MET A O +143 C CB . MET A 20 0.5730 0.2878 0.5358 -0.0011 0.0095 0.0633 ? ? ? ? ? ? 1875 MET A CB +144 C CG . MET A 20 0.7207 0.4031 0.6487 -0.0073 0.0151 0.0928 ? ? ? ? ? ? 1875 MET A CG +145 S SD . MET A 20 1.0298 0.6680 0.9644 0.0036 0.0012 0.1240 ? ? ? ? ? ? 1875 MET A SD +146 C CE . MET A 20 0.9212 0.5748 0.8259 0.0201 -0.0290 0.1319 ? ? ? ? ? ? 1875 MET A CE +147 N N . ILE A 21 0.5427 0.2937 0.4223 0.0106 -0.0132 0.0630 ? ? ? ? ? ? 1876 ILE A N +148 C CA . ILE A 21 0.5705 0.3237 0.4014 0.0129 -0.0217 0.0749 ? ? ? ? ? ? 1876 ILE A CA +149 C C . ILE A 21 0.6057 0.3842 0.4153 0.0099 -0.0116 0.0570 ? ? ? ? ? ? 1876 ILE A C +150 O O . ILE A 21 0.5472 0.3256 0.3194 0.0044 -0.0063 0.0655 ? ? ? ? ? ? 1876 ILE A O +151 C CB . ILE A 21 0.5472 0.3026 0.3767 0.0245 -0.0426 0.0774 ? ? ? ? ? ? 1876 ILE A CB +152 C CG1 . ILE A 21 0.5864 0.3165 0.4286 0.0304 -0.0556 0.0995 ? ? ? ? ? ? 1876 ILE A CG1 +153 C CG2 . ILE A 21 0.5611 0.3267 0.3433 0.0253 -0.0485 0.0811 ? ? ? ? ? ? 1876 ILE A CG2 +154 C CD1 . ILE A 21 0.6169 0.3542 0.4709 0.0427 -0.0766 0.0967 ? ? ? ? ? ? 1876 ILE A CD1 +155 N N . LEU A 22 0.5634 0.3626 0.3959 0.0142 -0.0085 0.0322 ? ? ? ? ? ? 1877 LEU A N +156 C CA . LEU A 22 0.5152 0.3367 0.3271 0.0153 -0.0002 0.0153 ? ? ? ? ? ? 1877 LEU A CA +157 C C . LEU A 22 0.4851 0.3129 0.2929 0.0055 0.0161 0.0133 ? ? ? ? ? ? 1877 LEU A C +158 O O . LEU A 22 0.5084 0.3455 0.2844 0.0040 0.0218 0.0122 ? ? ? ? ? ? 1877 LEU A O +159 C CB . LEU A 22 0.4378 0.2772 0.2735 0.0233 0.0001 -0.0096 ? ? ? ? ? ? 1877 LEU A CB +160 C CG . LEU A 22 0.4987 0.3588 0.3113 0.0293 0.0069 -0.0269 ? ? ? ? ? ? 1877 LEU A CG +161 C CD1 . LEU A 22 0.5316 0.3867 0.2995 0.0326 0.0031 -0.0185 ? ? ? ? ? ? 1877 LEU A CD1 +162 C CD2 . LEU A 22 0.4763 0.3487 0.3097 0.0379 0.0063 -0.0487 ? ? ? ? ? ? 1877 LEU A CD2 +163 N N . THR A 23 0.4987 0.2395 0.3943 -0.0643 0.0641 -0.0004 ? ? ? ? ? ? 1878 THR A N +164 C CA . THR A 23 0.5130 0.2464 0.4093 -0.0903 0.0735 -0.0121 ? ? ? ? ? ? 1878 THR A CA +165 C C . THR A 23 0.5878 0.3106 0.4792 -0.0858 0.0744 0.0106 ? ? ? ? ? ? 1878 THR A C +166 O O . THR A 23 0.5609 0.3074 0.4583 -0.1021 0.0705 0.0066 ? ? ? ? ? ? 1878 THR A O +167 C CB . THR A 23 0.6509 0.3353 0.5429 -0.1052 0.0979 -0.0297 ? ? ? ? ? ? 1878 THR A CB +168 O OG1 . THR A 23 0.6050 0.3057 0.5009 -0.1095 0.0946 -0.0550 ? ? ? ? ? ? 1878 THR A OG1 +169 C CG2 . THR A 23 0.6457 0.3212 0.5451 -0.1335 0.1108 -0.0417 ? ? ? ? ? ? 1878 THR A CG2 +170 N N . GLU A 24 0.5832 0.2725 0.4624 -0.0610 0.0787 0.0336 ? ? ? ? ? ? 1879 GLU A N +171 C CA . GLU A 24 0.6323 0.3103 0.5013 -0.0498 0.0787 0.0562 ? ? ? ? ? ? 1879 GLU A CA +172 C C . GLU A 24 0.5307 0.2659 0.4114 -0.0414 0.0512 0.0642 ? ? ? ? ? ? 1879 GLU A C +173 O O . GLU A 24 0.5199 0.2654 0.3975 -0.0452 0.0485 0.0721 ? ? ? ? ? ? 1879 GLU A O +174 C CB . GLU A 24 0.6036 0.2341 0.4541 -0.0195 0.0867 0.0765 ? ? ? ? ? ? 1879 GLU A CB +175 C CG . GLU A 24 0.7399 0.3054 0.5748 -0.0257 0.1156 0.0721 ? ? ? ? ? ? 1879 GLU A CG +176 C CD . GLU A 24 0.9405 0.4824 0.7625 0.0080 0.1157 0.0874 ? ? ? ? ? ? 1879 GLU A CD +177 O OE1 . GLU A 24 0.9598 0.5124 0.7875 0.0285 0.1035 0.0880 ? ? ? ? ? ? 1879 GLU A OE1 +178 O OE2 . GLU A 24 1.0959 0.6160 0.9048 0.0138 0.1270 0.0965 ? ? ? ? ? ? 1879 GLU A OE2 +179 N N A MET A 25 0.4896 0.2596 0.3842 -0.0295 0.0326 0.0624 ? ? ? ? ? ? 1880 MET A N +180 N N B MET A 25 0.4922 0.2635 0.3871 -0.0300 0.0322 0.0622 ? ? ? ? ? ? 1880 MET A N +181 C CA A MET A 25 0.5014 0.3253 0.4112 -0.0233 0.0067 0.0674 ? ? ? ? ? ? 1880 MET A CA +182 C CA B MET A 25 0.5072 0.3309 0.4163 -0.0235 0.0066 0.0682 ? ? ? ? ? ? 1880 MET A CA +183 C C A MET A 25 0.5271 0.3859 0.4424 -0.0500 0.0013 0.0514 ? ? ? ? ? ? 1880 MET A C +184 C C B MET A 25 0.5234 0.3847 0.4395 -0.0499 0.0002 0.0512 ? ? ? ? ? ? 1880 MET A C +185 O O A MET A 25 0.4920 0.3769 0.4102 -0.0510 -0.0112 0.0572 ? ? ? ? ? ? 1880 MET A O +186 O O B MET A 25 0.4908 0.3827 0.4114 -0.0507 -0.0144 0.0563 ? ? ? ? ? ? 1880 MET A O +187 C CB A MET A 25 0.4174 0.2671 0.3436 -0.0091 -0.0063 0.0669 ? ? ? ? ? ? 1880 MET A CB +188 C CB B MET A 25 0.4446 0.2934 0.3704 -0.0051 -0.0083 0.0712 ? ? ? ? ? ? 1880 MET A CB +189 C CG A MET A 25 0.5384 0.3600 0.4647 0.0177 -0.0023 0.0787 ? ? ? ? ? ? 1880 MET A CG +190 C CG B MET A 25 0.5571 0.3777 0.4816 0.0238 -0.0061 0.0856 ? ? ? ? ? ? 1880 MET A CG +191 S SD A MET A 25 0.4384 0.2633 0.3676 0.0476 -0.0187 0.1000 ? ? ? ? ? ? 1880 MET A SD +192 S SD B MET A 25 0.7091 0.5653 0.6630 0.0426 -0.0219 0.0873 ? ? ? ? ? ? 1880 MET A SD +193 C CE A MET A 25 0.5438 0.4337 0.5069 0.0512 -0.0466 0.0994 ? ? ? ? ? ? 1880 MET A CE +194 C CE B MET A 25 0.5847 0.4907 0.5578 0.0472 -0.0494 0.0952 ? ? ? ? ? ? 1880 MET A CE +195 N N . GLU A 26 0.4688 0.3289 0.3853 -0.0694 0.0098 0.0293 ? ? ? ? ? ? 1881 GLU A N +196 C CA . GLU A 26 0.4328 0.3275 0.3552 -0.0933 0.0039 0.0084 ? ? ? ? ? ? 1881 GLU A CA +197 C C . GLU A 26 0.5013 0.3887 0.4226 -0.1109 0.0135 0.0064 ? ? ? ? ? ? 1881 GLU A C +198 O O . GLU A 26 0.4657 0.3921 0.3945 -0.1232 0.0015 -0.0031 ? ? ? ? ? ? 1881 GLU A O +199 C CB . GLU A 26 0.4718 0.3617 0.3937 -0.1077 0.0134 -0.0180 ? ? ? ? ? ? 1881 GLU A CB +200 C CG . GLU A 26 0.4743 0.3864 0.3965 -0.0935 0.0023 -0.0201 ? ? ? ? ? ? 1881 GLU A CG +201 C CD . GLU A 26 0.5494 0.4448 0.4654 -0.1002 0.0150 -0.0430 ? ? ? ? ? ? 1881 GLU A CD +202 O OE1 . GLU A 26 0.5788 0.4376 0.4930 -0.1134 0.0333 -0.0546 ? ? ? ? ? ? 1881 GLU A OE1 +203 O OE2 . GLU A 26 0.6336 0.5510 0.5463 -0.0910 0.0076 -0.0490 ? ? ? ? ? ? 1881 GLU A OE2 +204 N N . THR A 27 0.2402 0.3235 0.4042 -0.0194 -0.0022 -0.0112 ? ? ? ? ? ? 1882 THR A N +205 C CA . THR A 27 0.3182 0.3588 0.4732 -0.0398 0.0500 -0.0119 ? ? ? ? ? ? 1882 THR A CA +206 C C . THR A 27 0.3855 0.3624 0.4554 -0.0377 0.0727 0.0009 ? ? ? ? ? ? 1882 THR A C +207 O O . THR A 27 0.4394 0.3924 0.4964 -0.0600 0.1185 -0.0031 ? ? ? ? ? ? 1882 THR A O +208 C CB . THR A 27 0.3803 0.3746 0.5246 -0.0550 0.0624 -0.0094 ? ? ? ? ? ? 1882 THR A CB +209 O OG1 . THR A 27 0.4878 0.4203 0.5607 -0.0382 0.0311 0.0041 ? ? ? ? ? ? 1882 THR A OG1 +210 C CG2 . THR A 27 0.3676 0.4327 0.6056 -0.0613 0.0499 -0.0273 ? ? ? ? ? ? 1882 THR A CG2 +211 N N . HIS A 28 0.3870 0.3427 0.3988 -0.0141 0.0416 0.0139 ? ? ? ? ? ? 1883 HIS A N +212 C CA . HIS A 28 0.4622 0.3668 0.3965 -0.0103 0.0588 0.0246 ? ? ? ? ? ? 1883 HIS A CA +213 C C . HIS A 28 0.4888 0.4423 0.4743 -0.0171 0.0865 0.0043 ? ? ? ? ? ? 1883 HIS A C +214 O O . HIS A 28 0.3572 0.3818 0.4250 -0.0094 0.0654 -0.0107 ? ? ? ? ? ? 1883 HIS A O +215 C CB . HIS A 28 0.4623 0.3528 0.3430 0.0190 0.0143 0.0388 ? ? ? ? ? ? 1883 HIS A CB +216 C CG . HIS A 28 0.5530 0.3756 0.3384 0.0239 0.0274 0.0542 ? ? ? ? ? ? 1883 HIS A CG +217 N ND1 . HIS A 28 0.5869 0.4207 0.3710 0.0187 0.0566 0.0450 ? ? ? ? ? ? 1883 HIS A ND1 +218 C CD2 . HIS A 28 0.5765 0.3224 0.2674 0.0340 0.0117 0.0754 ? ? ? ? ? ? 1883 HIS A CD2 +219 C CE1 . HIS A 28 0.6232 0.3919 0.3118 0.0226 0.0623 0.0614 ? ? ? ? ? ? 1883 HIS A CE1 +220 N NE2 . HIS A 28 0.7239 0.4349 0.3526 0.0314 0.0344 0.0824 ? ? ? ? ? ? 1883 HIS A NE2 +221 N N . GLU A 29 0.4781 0.3963 0.4174 -0.0336 0.1303 0.0009 ? ? ? ? ? ? 1884 GLU A N +222 C CA . GLU A 29 0.4619 0.4358 0.4632 -0.0404 0.1589 -0.0302 ? ? ? ? ? ? 1884 GLU A CA +223 C C . GLU A 29 0.4199 0.4289 0.4447 -0.0098 0.1221 -0.0376 ? ? ? ? ? ? 1884 GLU A C +224 O O . GLU A 29 0.4045 0.4713 0.5094 -0.0067 0.1245 -0.0677 ? ? ? ? ? ? 1884 GLU A O +225 C CB . GLU A 29 0.6711 0.6107 0.6143 -0.0708 0.2167 -0.0383 ? ? ? ? ? ? 1884 GLU A CB +226 C CG . GLU A 29 0.7593 0.6500 0.6061 -0.0636 0.2190 -0.0261 ? ? ? ? ? ? 1884 GLU A CG +227 C CD . GLU A 29 0.9640 0.8494 0.7713 -0.1009 0.2798 -0.0453 ? ? ? ? ? ? 1884 GLU A CD +228 O OE1 . GLU A 29 0.8792 0.8338 0.7551 -0.1012 0.3025 -0.0873 ? ? ? ? ? ? 1884 GLU A OE1 +229 O OE2 . GLU A 29 1.0775 0.8914 0.7858 -0.1326 0.3019 -0.0207 ? ? ? ? ? ? 1884 GLU A OE2 +230 N N . ASP A 30 0.4104 0.3844 0.3698 0.0125 0.0836 -0.0120 ? ? ? ? ? ? 1885 ASP A N +231 C CA . ASP A 30 0.4370 0.4388 0.4115 0.0387 0.0429 -0.0143 ? ? ? ? ? ? 1885 ASP A CA +232 C C . ASP A 30 0.4027 0.4518 0.4300 0.0494 -0.0144 -0.0062 ? ? ? ? ? ? 1885 ASP A C +233 O O . ASP A 30 0.3230 0.3838 0.3405 0.0670 -0.0590 0.0028 ? ? ? ? ? ? 1885 ASP A O +234 C CB . ASP A 30 0.4306 0.3711 0.2986 0.0543 0.0346 0.0074 ? ? ? ? ? ? 1885 ASP A CB +235 C CG . ASP A 30 0.5016 0.4015 0.3106 0.0388 0.0876 -0.0010 ? ? ? ? ? ? 1885 ASP A CG +236 O OD1 . ASP A 30 0.5150 0.4494 0.3749 0.0192 0.1290 -0.0315 ? ? ? ? ? ? 1885 ASP A OD1 +237 O OD2 . ASP A 30 0.5570 0.3944 0.2672 0.0440 0.0866 0.0212 ? ? ? ? ? ? 1885 ASP A OD2 +238 N N . ALA A 31 0.5429 0.3202 0.2619 0.0479 0.0596 0.0166 ? ? ? ? ? ? 1886 ALA A N +239 C CA . ALA A 31 0.5369 0.2954 0.2548 0.0415 0.0479 0.0104 ? ? ? ? ? ? 1886 ALA A CA +240 C C . ALA A 31 0.5010 0.2677 0.2430 0.0312 0.0353 0.0001 ? ? ? ? ? ? 1886 ALA A C +241 O O . ALA A 31 0.5622 0.3256 0.3069 0.0279 0.0240 -0.0042 ? ? ? ? ? ? 1886 ALA A O +242 C CB . ALA A 31 0.5662 0.2889 0.2730 0.0342 0.0536 0.0170 ? ? ? ? ? ? 1886 ALA A CB +243 N N . TRP A 32 0.5200 0.3015 0.2822 0.0284 0.0393 0.0001 ? ? ? ? ? ? 1887 TRP A N +244 C CA . TRP A 32 0.5482 0.3397 0.3399 0.0195 0.0311 -0.0021 ? ? ? ? ? ? 1887 TRP A CA +245 C C . TRP A 32 0.5598 0.3574 0.3622 0.0233 0.0199 -0.0117 ? ? ? ? ? ? 1887 TRP A C +246 O O . TRP A 32 0.5578 0.3604 0.3818 0.0146 0.0105 -0.0084 ? ? ? ? ? ? 1887 TRP A O +247 C CB . TRP A 32 0.5603 0.3720 0.3738 0.0225 0.0417 0.0033 ? ? ? ? ? ? 1887 TRP A CB +248 C CG . TRP A 32 0.5422 0.3659 0.3460 0.0399 0.0524 -0.0059 ? ? ? ? ? ? 1887 TRP A CG +249 C CD1 . TRP A 32 0.4903 0.3211 0.2727 0.0488 0.0644 -0.0026 ? ? ? ? ? ? 1887 TRP A CD1 +250 C CD2 . TRP A 32 0.5567 0.3858 0.3695 0.0493 0.0526 -0.0205 ? ? ? ? ? ? 1887 TRP A CD2 +251 N NE1 . TRP A 32 0.5152 0.3586 0.2874 0.0620 0.0707 -0.0167 ? ? ? ? ? ? 1887 TRP A NE1 +252 C CE2 . TRP A 32 0.5742 0.4112 0.3632 0.0621 0.0640 -0.0300 ? ? ? ? ? ? 1887 TRP A CE2 +253 C CE3 . TRP A 32 0.5374 0.3638 0.3755 0.0480 0.0448 -0.0259 ? ? ? ? ? ? 1887 TRP A CE3 +254 C CZ2 . TRP A 32 0.5794 0.4147 0.3637 0.0717 0.0679 -0.0500 ? ? ? ? ? ? 1887 TRP A CZ2 +255 C CZ3 . TRP A 32 0.5462 0.3684 0.3861 0.0592 0.0501 -0.0425 ? ? ? ? ? ? 1887 TRP A CZ3 +256 C CH2 . TRP A 32 0.5663 0.3894 0.3766 0.0701 0.0614 -0.0571 ? ? ? ? ? ? 1887 TRP A CH2 +257 N N . PRO A 33 0.4964 0.2964 0.2854 0.0340 0.0197 -0.0215 ? ? ? ? ? ? 1888 PRO A N +258 C CA . PRO A 33 0.4793 0.2814 0.2840 0.0334 0.0076 -0.0282 ? ? ? ? ? ? 1888 PRO A CA +259 C C . PRO A 33 0.4698 0.2681 0.2705 0.0281 -0.0046 -0.0213 ? ? ? ? ? ? 1888 PRO A C +260 O O . PRO A 33 0.4749 0.2791 0.2950 0.0260 -0.0154 -0.0212 ? ? ? ? ? ? 1888 PRO A O +261 C CB . PRO A 33 0.4932 0.2978 0.2801 0.0408 0.0082 -0.0412 ? ? ? ? ? ? 1888 PRO A CB +262 C CG . PRO A 33 0.5042 0.3148 0.2718 0.0477 0.0233 -0.0419 ? ? ? ? ? ? 1888 PRO A CG +263 C CD . PRO A 33 0.4659 0.2716 0.2299 0.0441 0.0282 -0.0257 ? ? ? ? ? ? 1888 PRO A CD +264 N N . PHE A 34 0.5008 0.2881 0.2774 0.0275 -0.0008 -0.0145 ? ? ? ? ? ? 1889 PHE A N +265 C CA . PHE A 34 0.4953 0.2777 0.2581 0.0288 -0.0071 -0.0086 ? ? ? ? ? ? 1889 PHE A CA +266 C C . PHE A 34 0.4966 0.2639 0.2509 0.0196 -0.0070 -0.0054 ? ? ? ? ? ? 1889 PHE A C +267 O O . PHE A 34 0.5209 0.2808 0.2579 0.0227 -0.0087 -0.0018 ? ? ? ? ? ? 1889 PHE A O +268 C CB . PHE A 34 0.5467 0.3266 0.2821 0.0406 0.0004 -0.0031 ? ? ? ? ? ? 1889 PHE A CB +269 C CG . PHE A 34 0.5233 0.3207 0.2584 0.0453 -0.0002 -0.0077 ? ? ? ? ? ? 1889 PHE A CG +270 C CD1 . PHE A 34 0.5053 0.3167 0.2541 0.0424 -0.0134 -0.0131 ? ? ? ? ? ? 1889 PHE A CD1 +271 C CD2 . PHE A 34 0.4986 0.2987 0.2189 0.0506 0.0120 -0.0067 ? ? ? ? ? ? 1889 PHE A CD2 +272 C CE1 . PHE A 34 0.4978 0.3212 0.2398 0.0423 -0.0155 -0.0222 ? ? ? ? ? ? 1889 PHE A CE1 +273 C CE2 . PHE A 34 0.5225 0.3422 0.2357 0.0531 0.0107 -0.0133 ? ? ? ? ? ? 1889 PHE A CE2 +274 C CZ . PHE A 34 0.5377 0.3668 0.2589 0.0477 -0.0037 -0.0234 ? ? ? ? ? ? 1889 PHE A CZ +275 N N . LEU A 35 0.5106 0.2744 0.2746 0.0076 -0.0047 -0.0061 ? ? ? ? ? ? 1890 LEU A N +276 C CA . LEU A 35 0.5668 0.3116 0.3150 -0.0067 -0.0053 -0.0059 ? ? ? ? ? ? 1890 LEU A CA +277 C C . LEU A 35 0.6253 0.3845 0.3814 -0.0165 -0.0192 -0.0045 ? ? ? ? ? ? 1890 LEU A C +278 O O . LEU A 35 0.5520 0.2934 0.2803 -0.0226 -0.0203 -0.0080 ? ? ? ? ? ? 1890 LEU A O +279 C CB . LEU A 35 0.5433 0.2871 0.3036 -0.0213 -0.0015 -0.0030 ? ? ? ? ? ? 1890 LEU A CB +280 C CG . LEU A 35 0.5914 0.3192 0.3395 -0.0139 0.0140 -0.0005 ? ? ? ? ? ? 1890 LEU A CG +281 C CD1 . LEU A 35 0.5980 0.3350 0.3669 -0.0283 0.0165 0.0073 ? ? ? ? ? ? 1890 LEU A CD1 +282 C CD2 . LEU A 35 0.7012 0.3891 0.4128 -0.0109 0.0232 -0.0021 ? ? ? ? ? ? 1890 LEU A CD2 +283 N N . LEU A 36 0.5053 0.2959 0.2984 -0.0166 -0.0283 0.0009 ? ? ? ? ? ? 1891 LEU A N +284 C CA . LEU A 36 0.5160 0.3313 0.3262 -0.0259 -0.0416 0.0085 ? ? ? ? ? ? 1891 LEU A CA +285 C C . LEU A 36 0.5357 0.3707 0.3704 -0.0133 -0.0477 0.0144 ? ? ? ? ? ? 1891 LEU A C +286 O O . LEU A 36 0.4790 0.3102 0.3240 -0.0021 -0.0433 0.0104 ? ? ? ? ? ? 1891 LEU A O +287 C CB . LEU A 36 0.5523 0.3927 0.3955 -0.0419 -0.0467 0.0180 ? ? ? ? ? ? 1891 LEU A CB +288 C CG . LEU A 36 0.5662 0.3936 0.3917 -0.0618 -0.0452 0.0161 ? ? ? ? ? ? 1891 LEU A CG +289 C CD1 . LEU A 36 0.5943 0.4596 0.4625 -0.0756 -0.0505 0.0328 ? ? ? ? ? ? 1891 LEU A CD1 +290 C CD2 . LEU A 36 0.6564 0.4658 0.4411 -0.0766 -0.0517 0.0082 ? ? ? ? ? ? 1891 LEU A CD2 +291 N N . PRO A 37 0.4743 0.3312 0.3174 -0.0168 -0.0584 0.0242 ? ? ? ? ? ? 1892 PRO A N +292 C CA . PRO A 37 0.4277 0.3040 0.3004 -0.0069 -0.0650 0.0338 ? ? ? ? ? ? 1892 PRO A CA +293 C C . PRO A 37 0.3838 0.2721 0.3049 -0.0062 -0.0651 0.0384 ? ? ? ? ? ? 1892 PRO A C +294 O O . PRO A 37 0.4330 0.3337 0.3745 -0.0141 -0.0637 0.0441 ? ? ? ? ? ? 1892 PRO A O +295 C CB . PRO A 37 0.4672 0.3713 0.3415 -0.0121 -0.0753 0.0476 ? ? ? ? ? ? 1892 PRO A CB +296 C CG . PRO A 37 0.4622 0.3670 0.3164 -0.0290 -0.0766 0.0441 ? ? ? ? ? ? 1892 PRO A CG +297 C CD . PRO A 37 0.4485 0.3141 0.2719 -0.0309 -0.0652 0.0271 ? ? ? ? ? ? 1892 PRO A CD +298 N N . VAL A 38 0.4942 0.2174 0.4040 -0.0429 -0.0705 -0.0274 ? ? ? ? ? ? 1893 VAL A N +299 C CA . VAL A 38 0.5101 0.2401 0.4522 -0.0415 -0.0589 -0.0233 ? ? ? ? ? ? 1893 VAL A CA +300 C C . VAL A 38 0.6208 0.3203 0.5418 -0.0191 -0.0972 -0.0229 ? ? ? ? ? ? 1893 VAL A C +301 O O . VAL A 38 0.6349 0.3025 0.4751 -0.0082 -0.1142 -0.0213 ? ? ? ? ? ? 1893 VAL A O +302 C CB . VAL A 38 0.5722 0.3104 0.4694 -0.0539 -0.0107 -0.0162 ? ? ? ? ? ? 1893 VAL A CB +303 C CG1 . VAL A 38 0.5924 0.3232 0.5140 -0.0520 0.0058 -0.0148 ? ? ? ? ? ? 1893 VAL A CG1 +304 C CG2 . VAL A 38 0.5375 0.3218 0.4626 -0.0733 0.0259 -0.0133 ? ? ? ? ? ? 1893 VAL A CG2 +305 N N . ASN A 39 0.5962 0.3081 0.5906 -0.0103 -0.1108 -0.0228 ? ? ? ? ? ? 1894 ASN A N +306 C CA . ASN A 39 0.7082 0.4000 0.6889 0.0171 -0.1454 -0.0153 ? ? ? ? ? ? 1894 ASN A CA +307 C C . ASN A 39 0.6909 0.3501 0.6187 0.0239 -0.1094 0.0009 ? ? ? ? ? ? 1894 ASN A C +308 O O . ASN A 39 0.6708 0.3376 0.6462 0.0168 -0.0721 0.0048 ? ? ? ? ? ? 1894 ASN A O +309 C CB . ASN A 39 0.6637 0.3873 0.7499 0.0268 -0.1699 -0.0190 ? ? ? ? ? ? 1894 ASN A CB +310 C CG . ASN A 39 0.7107 0.4265 0.7861 0.0614 -0.2133 -0.0075 ? ? ? ? ? ? 1894 ASN A CG +311 O OD1 . ASN A 39 0.7650 0.4428 0.7660 0.0796 -0.2058 0.0114 ? ? ? ? ? ? 1894 ASN A OD1 +312 N ND2 . ASN A 39 0.6513 0.4064 0.8020 0.0715 -0.2574 -0.0182 ? ? ? ? ? ? 1894 ASN A ND2 +313 N N . LEU A 40 0.7217 0.3417 0.5522 0.0360 -0.1167 0.0078 ? ? ? ? ? ? 1895 LEU A N +314 C CA . LEU A 40 0.7282 0.3101 0.4985 0.0379 -0.0740 0.0191 ? ? ? ? ? ? 1895 LEU A CA +315 C C . LEU A 40 0.7414 0.3010 0.5376 0.0647 -0.0710 0.0382 ? ? ? ? ? ? 1895 LEU A C +316 O O . LEU A 40 0.7475 0.2734 0.5160 0.0642 -0.0234 0.0464 ? ? ? ? ? ? 1895 LEU A O +317 C CB . LEU A 40 0.8050 0.3479 0.4644 0.0432 -0.0811 0.0203 ? ? ? ? ? ? 1895 LEU A CB +318 C CG . LEU A 40 0.8330 0.3932 0.4627 0.0206 -0.0785 0.0049 ? ? ? ? ? ? 1895 LEU A CG +319 C CD1 . LEU A 40 0.9397 0.4571 0.4622 0.0274 -0.0839 0.0056 ? ? ? ? ? ? 1895 LEU A CD1 +320 C CD2 . LEU A 40 0.7600 0.3540 0.4168 -0.0086 -0.0259 -0.0022 ? ? ? ? ? ? 1895 LEU A CD2 +321 N N . LYS A 41 0.8106 0.3912 0.6642 0.0883 -0.1186 0.0446 ? ? ? ? ? ? 1896 LYS A N +322 C CA . LYS A 41 0.9136 0.4811 0.8033 0.1201 -0.1185 0.0679 ? ? ? ? ? ? 1896 LYS A CA +323 C C . LYS A 41 0.8753 0.4727 0.8774 0.1078 -0.0881 0.0635 ? ? ? ? ? ? 1896 LYS A C +324 O O . LYS A 41 0.8602 0.4429 0.9022 0.1295 -0.0693 0.0825 ? ? ? ? ? ? 1896 LYS A O +325 C CB . LYS A 41 0.9521 0.5374 0.8438 0.1567 -0.1889 0.0790 ? ? ? ? ? ? 1896 LYS A CB +326 C CG . LYS A 41 1.0659 0.6232 0.8438 0.1684 -0.2207 0.0816 ? ? ? ? ? ? 1896 LYS A CG +327 C CD . LYS A 41 1.2516 0.8070 1.0034 0.2164 -0.2675 0.1087 ? ? ? ? ? ? 1896 LYS A CD +328 C CE . LYS A 41 1.3088 0.9363 1.1407 0.2276 -0.3328 0.0968 ? ? ? ? ? ? 1896 LYS A CE +329 N NZ . LYS A 41 1.3332 0.9864 1.1324 0.2074 -0.3768 0.0645 ? ? ? ? ? ? 1896 LYS A NZ +330 N N . LEU A 42 0.7870 0.4509 0.7273 0.0312 -0.1080 -0.0253 ? ? ? ? ? ? 1897 LEU A N +331 C CA . LEU A 42 0.8228 0.4968 0.8288 0.0409 -0.0926 -0.0355 ? ? ? ? ? ? 1897 LEU A CA +332 C C . LEU A 42 0.8150 0.4832 0.8113 0.0431 -0.0578 -0.0448 ? ? ? ? ? ? 1897 LEU A C +333 O O . LEU A 42 0.8639 0.5385 0.9069 0.0475 -0.0412 -0.0552 ? ? ? ? ? ? 1897 LEU A O +334 C CB . LEU A 42 0.7542 0.4467 0.7937 0.0369 -0.0892 -0.0497 ? ? ? ? ? ? 1897 LEU A CB +335 C CG . LEU A 42 0.8972 0.6045 0.9562 0.0315 -0.1249 -0.0450 ? ? ? ? ? ? 1897 LEU A CG +336 C CD1 . LEU A 42 0.9322 0.6597 1.0393 0.0270 -0.1166 -0.0629 ? ? ? ? ? ? 1897 LEU A CD1 +337 C CD2 . LEU A 42 0.9307 0.6422 1.0324 0.0407 -0.1561 -0.0264 ? ? ? ? ? ? 1897 LEU A CD2 +338 N N . VAL A 43 0.7164 0.3760 0.6545 0.0378 -0.0464 -0.0427 ? ? ? ? ? ? 1898 VAL A N +339 C CA . VAL A 43 0.6759 0.3364 0.5996 0.0366 -0.0184 -0.0490 ? ? ? ? ? ? 1898 VAL A CA +340 C C . VAL A 43 0.6844 0.3320 0.5787 0.0359 -0.0189 -0.0422 ? ? ? ? ? ? 1898 VAL A C +341 O O . VAL A 43 0.6706 0.3116 0.5195 0.0317 -0.0242 -0.0346 ? ? ? ? ? ? 1898 VAL A O +342 C CB . VAL A 43 0.6877 0.3532 0.5800 0.0319 -0.0038 -0.0500 ? ? ? ? ? ? 1898 VAL A CB +343 C CG1 . VAL A 43 0.6832 0.3562 0.5596 0.0283 0.0191 -0.0516 ? ? ? ? ? ? 1898 VAL A CG1 +344 C CG2 . VAL A 43 0.6423 0.3156 0.5644 0.0302 -0.0012 -0.0562 ? ? ? ? ? ? 1898 VAL A CG2 +345 N N . PRO A 44 0.6511 0.2951 0.5762 0.0382 -0.0101 -0.0481 ? ? ? ? ? ? 1899 PRO A N +346 C CA . PRO A 44 0.6676 0.2970 0.5720 0.0353 -0.0076 -0.0441 ? ? ? ? ? ? 1899 PRO A CA +347 C C . PRO A 44 0.7014 0.3382 0.5539 0.0266 0.0075 -0.0463 ? ? ? ? ? ? 1899 PRO A C +348 O O . PRO A 44 0.6574 0.3121 0.5029 0.0230 0.0232 -0.0539 ? ? ? ? ? ? 1899 PRO A O +349 C CB . PRO A 44 0.7434 0.3713 0.7005 0.0371 0.0094 -0.0600 ? ? ? ? ? ? 1899 PRO A CB +350 C CG . PRO A 44 0.7513 0.3891 0.7666 0.0450 0.0042 -0.0651 ? ? ? ? ? ? 1899 PRO A CG +351 C CD . PRO A 44 0.6642 0.3172 0.6518 0.0420 0.0012 -0.0625 ? ? ? ? ? ? 1899 PRO A CD +352 N N . GLY A 45 0.6092 0.2342 0.4281 0.0223 0.0015 -0.0373 ? ? ? ? ? ? 1900 GLY A N +353 C CA . GLY A 45 0.6028 0.2388 0.3828 0.0144 0.0140 -0.0395 ? ? ? ? ? ? 1900 GLY A CA +354 C C . GLY A 45 0.6235 0.2690 0.3750 0.0147 0.0107 -0.0339 ? ? ? ? ? ? 1900 GLY A C +355 O O . GLY A 45 0.6555 0.3054 0.3797 0.0093 0.0149 -0.0321 ? ? ? ? ? ? 1900 GLY A O +356 N N . TYR A 46 0.6042 0.2531 0.3687 0.0201 0.0058 -0.0337 ? ? ? ? ? ? 1901 TYR A N +357 C CA . TYR A 46 0.5828 0.2402 0.3329 0.0208 0.0096 -0.0327 ? ? ? ? ? ? 1901 TYR A CA +358 C C . TYR A 46 0.6679 0.3178 0.3875 0.0156 0.0049 -0.0316 ? ? ? ? ? ? 1901 TYR A C +359 O O . TYR A 46 0.5951 0.2549 0.3044 0.0146 0.0153 -0.0333 ? ? ? ? ? ? 1901 TYR A O +360 C CB . TYR A 46 0.6239 0.2817 0.3972 0.0249 0.0068 -0.0352 ? ? ? ? ? ? 1901 TYR A CB +361 C CG . TYR A 46 0.6372 0.3033 0.4118 0.0271 0.0180 -0.0335 ? ? ? ? ? ? 1901 TYR A CG +362 C CD1 . TYR A 46 0.5813 0.2418 0.3469 0.0266 0.0184 -0.0373 ? ? ? ? ? ? 1901 TYR A CD1 +363 C CD2 . TYR A 46 0.5632 0.2425 0.3495 0.0280 0.0293 -0.0275 ? ? ? ? ? ? 1901 TYR A CD2 +364 C CE1 . TYR A 46 0.5788 0.2437 0.3597 0.0312 0.0298 -0.0347 ? ? ? ? ? ? 1901 TYR A CE1 +365 C CE2 . TYR A 46 0.6115 0.2962 0.4050 0.0312 0.0364 -0.0186 ? ? ? ? ? ? 1901 TYR A CE2 +366 C CZ . TYR A 46 0.6346 0.3105 0.4313 0.0350 0.0366 -0.0218 ? ? ? ? ? ? 1901 TYR A CZ +367 O OH . TYR A 46 0.5736 0.2519 0.3909 0.0407 0.0444 -0.0117 ? ? ? ? ? ? 1901 TYR A OH +368 N N . LYS A 47 0.6918 0.3268 0.3987 0.0107 -0.0107 -0.0280 ? ? ? ? ? ? 1902 LYS A N +369 C CA . LYS A 47 0.7033 0.3323 0.3724 -0.0004 -0.0130 -0.0287 ? ? ? ? ? ? 1902 LYS A CA +370 C C . LYS A 47 0.6587 0.2887 0.3056 -0.0071 -0.0017 -0.0271 ? ? ? ? ? ? 1902 LYS A C +371 O O . LYS A 47 0.7321 0.3688 0.3603 -0.0139 0.0101 -0.0346 ? ? ? ? ? ? 1902 LYS A O +372 C CB . LYS A 47 0.7250 0.3406 0.3780 -0.0085 -0.0366 -0.0195 ? ? ? ? ? ? 1902 LYS A CB +373 C CG . LYS A 47 0.7732 0.3857 0.3771 -0.0266 -0.0375 -0.0231 ? ? ? ? ? ? 1902 LYS A CG +374 C CD . LYS A 47 0.8132 0.4170 0.3935 -0.0389 -0.0662 -0.0090 ? ? ? ? ? ? 1902 LYS A CD +375 C CE . LYS A 47 0.9365 0.5396 0.4558 -0.0639 -0.0637 -0.0146 ? ? ? ? ? ? 1902 LYS A CE +376 N NZ . LYS A 47 1.0326 0.6289 0.5181 -0.0802 -0.0963 0.0076 ? ? ? ? ? ? 1902 LYS A NZ +377 N N . LYS A 48 0.6491 0.2731 0.3038 -0.0066 -0.0025 -0.0205 ? ? ? ? ? ? 1903 LYS A N +378 C CA . LYS A 48 0.6562 0.2814 0.2935 -0.0157 0.0087 -0.0206 ? ? ? ? ? ? 1903 LYS A CA +379 C C . LYS A 48 0.6806 0.3332 0.3304 -0.0124 0.0250 -0.0299 ? ? ? ? ? ? 1903 LYS A C +380 O O . LYS A 48 0.6895 0.3536 0.3276 -0.0198 0.0355 -0.0338 ? ? ? ? ? ? 1903 LYS A O +381 C CB . LYS A 48 0.6675 0.2751 0.3163 -0.0176 0.0047 -0.0136 ? ? ? ? ? ? 1903 LYS A CB +382 C CG . LYS A 48 0.6908 0.2965 0.3235 -0.0304 0.0169 -0.0149 ? ? ? ? ? ? 1903 LYS A CG +383 C CD . LYS A 48 0.7722 0.3665 0.3637 -0.0450 0.0154 -0.0066 ? ? ? ? ? ? 1903 LYS A CD +384 C CE . LYS A 48 0.7570 0.3431 0.3358 -0.0604 0.0273 -0.0053 ? ? ? ? ? ? 1903 LYS A CE +385 N NZ . LYS A 48 0.7623 0.3145 0.3525 -0.0627 0.0181 0.0098 ? ? ? ? ? ? 1903 LYS A NZ +386 N N . VAL A 49 0.6071 0.2725 0.2823 -0.0027 0.0263 -0.0316 ? ? ? ? ? ? 1904 VAL A N +387 C CA . VAL A 49 0.6139 0.3080 0.2997 -0.0013 0.0358 -0.0334 ? ? ? ? ? ? 1904 VAL A CA +388 C C . VAL A 49 0.6367 0.3441 0.3324 0.0058 0.0394 -0.0319 ? ? ? ? ? ? 1904 VAL A C +389 O O . VAL A 49 0.6181 0.3471 0.3202 0.0048 0.0458 -0.0319 ? ? ? ? ? ? 1904 VAL A O +390 C CB . VAL A 49 0.5833 0.2866 0.2856 0.0009 0.0371 -0.0337 ? ? ? ? ? ? 1904 VAL A CB +391 C CG1 . VAL A 49 0.5827 0.3186 0.2901 0.0005 0.0414 -0.0284 ? ? ? ? ? ? 1904 VAL A CG1 +392 C CG2 . VAL A 49 0.5884 0.2817 0.2912 -0.0077 0.0405 -0.0419 ? ? ? ? ? ? 1904 VAL A CG2 +393 N N . ILE A 50 0.4941 0.2495 0.4330 -0.0620 0.0377 -0.0105 ? ? ? ? ? ? 1905 ILE A N +394 C CA . ILE A 50 0.5233 0.2878 0.4288 -0.0397 0.0202 -0.0219 ? ? ? ? ? ? 1905 ILE A CA +395 C C . ILE A 50 0.6079 0.3288 0.4510 -0.0237 0.0572 -0.0068 ? ? ? ? ? ? 1905 ILE A C +396 O O . ILE A 50 0.6180 0.2819 0.3724 -0.0104 0.0506 0.0152 ? ? ? ? ? ? 1905 ILE A O +397 C CB . ILE A 50 0.5374 0.2784 0.3829 -0.0299 -0.0330 -0.0197 ? ? ? ? ? ? 1905 ILE A CB +398 C CG1 . ILE A 50 0.5576 0.3358 0.4604 -0.0433 -0.0664 -0.0325 ? ? ? ? ? ? 1905 ILE A CG1 +399 C CG2 . ILE A 50 0.4791 0.2158 0.2834 -0.0058 -0.0413 -0.0304 ? ? ? ? ? ? 1905 ILE A CG2 +400 C CD1 . ILE A 50 0.4390 0.2914 0.4247 -0.0372 -0.0651 -0.0614 ? ? ? ? ? ? 1905 ILE A CD1 +401 N N . LYS A 51 0.5238 0.2778 0.4156 -0.0226 0.0954 -0.0232 ? ? ? ? ? ? 1906 LYS A N +402 C CA . LYS A 51 0.6171 0.3291 0.4608 -0.0105 0.1416 -0.0086 ? ? ? ? ? ? 1906 LYS A CA +403 C C . LYS A 51 0.7278 0.4092 0.4817 0.0168 0.1177 -0.0013 ? ? ? ? ? ? 1906 LYS A C +404 O O . LYS A 51 0.6980 0.3273 0.3786 0.0325 0.1413 0.0192 ? ? ? ? ? ? 1906 LYS A O +405 C CB . LYS A 51 0.6524 0.4157 0.5855 -0.0205 0.1915 -0.0364 ? ? ? ? ? ? 1906 LYS A CB +406 C CG . LYS A 51 0.7122 0.5083 0.7466 -0.0522 0.2272 -0.0529 ? ? ? ? ? ? 1906 LYS A CG +407 C CD . LYS A 51 0.8099 0.5256 0.7937 -0.0600 0.2585 -0.0147 ? ? ? ? ? ? 1906 LYS A CD +408 C CE . LYS A 51 0.8195 0.5591 0.9067 -0.0943 0.3051 -0.0324 ? ? ? ? ? ? 1906 LYS A CE +409 N NZ . LYS A 51 0.9728 0.6195 1.0008 -0.0948 0.3537 0.0080 ? ? ? ? ? ? 1906 LYS A NZ +410 N N . LYS A 52 0.5879 0.2982 0.3450 0.0253 0.0754 -0.0191 ? ? ? ? ? ? 1907 LYS A N +411 C CA . LYS A 52 0.6989 0.3774 0.3772 0.0480 0.0573 -0.0172 ? ? ? ? ? ? 1907 LYS A CA +412 C C . LYS A 52 0.6391 0.3058 0.2900 0.0484 0.0091 -0.0231 ? ? ? ? ? ? 1907 LYS A C +413 O O . LYS A 52 0.6176 0.3087 0.2900 0.0571 -0.0078 -0.0395 ? ? ? ? ? ? 1907 LYS A O +414 C CB . LYS A 52 0.7118 0.4252 0.4130 0.0647 0.0722 -0.0359 ? ? ? ? ? ? 1907 LYS A CB +415 C CG . LYS A 52 0.8474 0.5770 0.5846 0.0623 0.1248 -0.0384 ? ? ? ? ? ? 1907 LYS A CG +416 C CD . LYS A 52 0.9725 0.7418 0.7268 0.0833 0.1319 -0.0612 ? ? ? ? ? ? 1907 LYS A CD +417 C CE . LYS A 52 1.0273 0.8250 0.8360 0.0769 0.1867 -0.0737 ? ? ? ? ? ? 1907 LYS A CE +418 N NZ . LYS A 52 1.0514 0.8989 0.8805 0.1009 0.1886 -0.1013 ? ? ? ? ? ? 1907 LYS A NZ +419 N N . PRO A 53 0.6932 0.3217 0.2950 0.0424 -0.0097 -0.0120 ? ? ? ? ? ? 1908 PRO A N +420 C CA . PRO A 53 0.7254 0.3382 0.3023 0.0385 -0.0490 -0.0236 ? ? ? ? ? ? 1908 PRO A CA +421 C C . PRO A 53 0.6770 0.2942 0.2517 0.0520 -0.0476 -0.0281 ? ? ? ? ? ? 1908 PRO A C +422 O O . PRO A 53 0.6607 0.2598 0.1947 0.0657 -0.0305 -0.0268 ? ? ? ? ? ? 1908 PRO A O +423 C CB . PRO A 53 0.6863 0.2893 0.2512 0.0342 -0.0567 -0.0117 ? ? ? ? ? ? 1908 PRO A CB +424 C CG . PRO A 53 0.7441 0.3295 0.2874 0.0351 -0.0296 0.0079 ? ? ? ? ? ? 1908 PRO A CG +425 C CD . PRO A 53 0.7881 0.3860 0.3528 0.0432 0.0085 0.0092 ? ? ? ? ? ? 1908 PRO A CD +426 N N . MET A 54 0.6788 0.1783 0.3262 -0.0349 0.0269 0.0263 ? ? ? ? ? ? 1909 MET A N +427 C CA . MET A 54 0.6402 0.2193 0.3265 -0.0283 0.0067 0.0252 ? ? ? ? ? ? 1909 MET A CA +428 C C . MET A 54 0.6941 0.2935 0.3841 -0.0051 -0.0057 0.0194 ? ? ? ? ? ? 1909 MET A C +429 O O . MET A 54 0.6652 0.2273 0.3323 -0.0035 -0.0021 0.0097 ? ? ? ? ? ? 1909 MET A O +430 C CB . MET A 54 0.5640 0.1894 0.2901 -0.0623 -0.0022 0.0126 ? ? ? ? ? ? 1909 MET A CB +431 C CG . MET A 54 0.5663 0.2609 0.3274 -0.0513 -0.0153 0.0136 ? ? ? ? ? ? 1909 MET A CG +432 S SD . MET A 54 0.5831 0.2862 0.3319 -0.0286 -0.0069 0.0294 ? ? ? ? ? ? 1909 MET A SD +433 C CE . MET A 54 0.6009 0.2745 0.3392 -0.0503 0.0200 0.0413 ? ? ? ? ? ? 1909 MET A CE +434 N N . ASP A 55 0.5662 0.2199 0.2815 0.0114 -0.0168 0.0244 ? ? ? ? ? ? 1910 ASP A N +435 C CA . ASP A 55 0.5309 0.2124 0.2611 0.0291 -0.0233 0.0222 ? ? ? ? ? ? 1910 ASP A CA +436 C C . ASP A 55 0.5085 0.2463 0.2753 0.0239 -0.0353 0.0193 ? ? ? ? ? ? 1910 ASP A C +437 O O . ASP A 55 0.5231 0.2743 0.2951 0.0155 -0.0381 0.0194 ? ? ? ? ? ? 1910 ASP A O +438 C CB . ASP A 55 0.5837 0.2584 0.3028 0.0628 -0.0171 0.0355 ? ? ? ? ? ? 1910 ASP A CB +439 C CG . ASP A 55 0.6507 0.3621 0.3787 0.0756 -0.0271 0.0464 ? ? ? ? ? ? 1910 ASP A CG +440 O OD1 . ASP A 55 0.6092 0.2904 0.3076 0.0765 -0.0212 0.0558 ? ? ? ? ? ? 1910 ASP A OD1 +441 O OD2 . ASP A 55 0.5599 0.3291 0.3216 0.0817 -0.0404 0.0444 ? ? ? ? ? ? 1910 ASP A OD2 +442 N N . PHE A 56 0.4664 0.2287 0.2538 0.0294 -0.0371 0.0170 ? ? ? ? ? ? 1911 PHE A N +443 C CA . PHE A 56 0.4768 0.2738 0.2943 0.0209 -0.0427 0.0130 ? ? ? ? ? ? 1911 PHE A CA +444 C C . PHE A 56 0.4579 0.2806 0.2870 0.0218 -0.0513 0.0112 ? ? ? ? ? ? 1911 PHE A C +445 O O . PHE A 56 0.4288 0.2582 0.2639 0.0108 -0.0542 0.0034 ? ? ? ? ? ? 1911 PHE A O +446 C CB . PHE A 56 0.4637 0.2736 0.2991 0.0253 -0.0355 0.0149 ? ? ? ? ? ? 1911 PHE A CB +447 C CG . PHE A 56 0.5287 0.3153 0.3407 0.0264 -0.0295 0.0151 ? ? ? ? ? ? 1911 PHE A CG +448 C CD1 . PHE A 56 0.4840 0.2535 0.2741 0.0168 -0.0373 0.0093 ? ? ? ? ? ? 1911 PHE A CD1 +449 C CD2 . PHE A 56 0.4854 0.2729 0.2974 0.0359 -0.0163 0.0209 ? ? ? ? ? ? 1911 PHE A CD2 +450 C CE1 . PHE A 56 0.5018 0.2587 0.2656 0.0169 -0.0395 0.0057 ? ? ? ? ? ? 1911 PHE A CE1 +451 C CE2 . PHE A 56 0.5176 0.2826 0.2935 0.0407 -0.0129 0.0207 ? ? ? ? ? ? 1911 PHE A CE2 +452 C CZ . PHE A 56 0.5508 0.3021 0.3003 0.0313 -0.0284 0.0113 ? ? ? ? ? ? 1911 PHE A CZ +453 N N . SER A 57 0.4467 0.2843 0.2749 0.0380 -0.0561 0.0175 ? ? ? ? ? ? 1912 SER A N +454 C CA . SER A 57 0.5260 0.3987 0.3608 0.0393 -0.0719 0.0131 ? ? ? ? ? ? 1912 SER A CA +455 C C . SER A 57 0.5609 0.4103 0.3569 0.0381 -0.0730 0.0130 ? ? ? ? ? ? 1912 SER A C +456 O O . SER A 57 0.4827 0.3472 0.2718 0.0311 -0.0831 0.0014 ? ? ? ? ? ? 1912 SER A O +457 C CB . SER A 57 0.5103 0.4187 0.3554 0.0643 -0.0804 0.0240 ? ? ? ? ? ? 1912 SER A CB +458 O OG . SER A 57 0.5952 0.4688 0.3972 0.0892 -0.0748 0.0406 ? ? ? ? ? ? 1912 SER A OG +459 N N . THR A 58 0.5369 0.3454 0.3051 0.0425 -0.0594 0.0243 ? ? ? ? ? ? 1913 THR A N +460 C CA . THR A 58 0.5605 0.3464 0.2963 0.0393 -0.0513 0.0285 ? ? ? ? ? ? 1913 THR A CA +461 C C . THR A 58 0.5263 0.3176 0.2791 0.0193 -0.0453 0.0164 ? ? ? ? ? ? 1913 THR A C +462 O O . THR A 58 0.5915 0.3852 0.3275 0.0189 -0.0419 0.0122 ? ? ? ? ? ? 1913 THR A O +463 C CB . THR A 58 0.5669 0.3029 0.2749 0.0423 -0.0330 0.0443 ? ? ? ? ? ? 1913 THR A CB +464 O OG1 . THR A 58 0.5684 0.2917 0.2538 0.0712 -0.0345 0.0593 ? ? ? ? ? ? 1913 THR A OG1 +465 C CG2 . THR A 58 0.5953 0.3099 0.2755 0.0353 -0.0167 0.0525 ? ? ? ? ? ? 1913 THR A CG2 +466 N N . ILE A 59 0.4623 0.2553 0.2430 0.0084 -0.0430 0.0122 ? ? ? ? ? ? 1914 ILE A N +467 C CA . ILE A 59 0.4660 0.2702 0.2661 -0.0010 -0.0380 0.0054 ? ? ? ? ? ? 1914 ILE A CA +468 C C . ILE A 59 0.5118 0.3249 0.3142 0.0011 -0.0420 -0.0067 ? ? ? ? ? ? 1914 ILE A C +469 O O . ILE A 59 0.5119 0.3217 0.3080 0.0018 -0.0328 -0.0122 ? ? ? ? ? ? 1914 ILE A O +470 C CB . ILE A 59 0.4598 0.2687 0.2813 -0.0060 -0.0399 0.0055 ? ? ? ? ? ? 1914 ILE A CB +471 C CG1 . ILE A 59 0.4667 0.2629 0.2816 -0.0165 -0.0378 0.0090 ? ? ? ? ? ? 1914 ILE A CG1 +472 C CG2 . ILE A 59 0.3829 0.2078 0.2243 -0.0046 -0.0359 0.0035 ? ? ? ? ? ? 1914 ILE A CG2 +473 C CD1 . ILE A 59 0.4373 0.2369 0.2574 -0.0205 -0.0456 0.0052 ? ? ? ? ? ? 1914 ILE A CD1 +474 N N . ARG A 60 0.4991 0.3222 0.3113 0.0007 -0.0533 -0.0122 ? ? ? ? ? ? 1915 ARG A N +475 C CA . ARG A 60 0.5024 0.3297 0.3203 -0.0075 -0.0583 -0.0290 ? ? ? ? ? ? 1915 ARG A CA +476 C C . ARG A 60 0.5748 0.4014 0.3559 -0.0050 -0.0656 -0.0400 ? ? ? ? ? ? 1915 ARG A C +477 O O . ARG A 60 0.5393 0.3486 0.3053 -0.0110 -0.0611 -0.0573 ? ? ? ? ? ? 1915 ARG A O +478 C CB . ARG A 60 0.4626 0.3145 0.3111 -0.0143 -0.0680 -0.0316 ? ? ? ? ? ? 1915 ARG A CB +479 C CG . ARG A 60 0.4714 0.3342 0.3307 -0.0331 -0.0779 -0.0537 ? ? ? ? ? ? 1915 ARG A CG +480 C CD . ARG A 60 0.5246 0.3473 0.3874 -0.0457 -0.0601 -0.0633 ? ? ? ? ? ? 1915 ARG A CD +481 N NE . ARG A 60 0.5476 0.3633 0.4408 -0.0478 -0.0445 -0.0494 ? ? ? ? ? ? 1915 ARG A NE +482 C CZ . ARG A 60 0.6266 0.4007 0.5192 -0.0500 -0.0241 -0.0476 ? ? ? ? ? ? 1915 ARG A CZ +483 N NH1 . ARG A 60 0.5839 0.3193 0.4518 -0.0495 -0.0158 -0.0607 ? ? ? ? ? ? 1915 ARG A NH1 +484 N NH2 . ARG A 60 0.5880 0.3542 0.4977 -0.0475 -0.0086 -0.0306 ? ? ? ? ? ? 1915 ARG A NH2 +485 N N . GLU A 61 0.5132 0.3504 0.2703 0.0075 -0.0742 -0.0293 ? ? ? ? ? ? 1916 GLU A N +486 C CA . GLU A 61 0.5432 0.3798 0.2513 0.0156 -0.0820 -0.0362 ? ? ? ? ? ? 1916 GLU A CA +487 C C . GLU A 61 0.5402 0.3460 0.2179 0.0191 -0.0573 -0.0345 ? ? ? ? ? ? 1916 GLU A C +488 O O . GLU A 61 0.5927 0.3860 0.2315 0.0207 -0.0556 -0.0512 ? ? ? ? ? ? 1916 GLU A O +489 C CB . GLU A 61 0.5218 0.3720 0.2045 0.0369 -0.0933 -0.0171 ? ? ? ? ? ? 1916 GLU A CB +490 C CG . GLU A 61 0.6569 0.5061 0.2740 0.0520 -0.1024 -0.0193 ? ? ? ? ? ? 1916 GLU A CG +491 C CD . GLU A 61 0.7974 0.6794 0.4062 0.0410 -0.1329 -0.0506 ? ? ? ? ? ? 1916 GLU A CD +492 O OE1 . GLU A 61 0.7831 0.7062 0.4440 0.0271 -0.1533 -0.0618 ? ? ? ? ? ? 1916 GLU A OE1 +493 O OE2 . GLU A 61 0.8505 0.7186 0.4033 0.0434 -0.1338 -0.0651 ? ? ? ? ? ? 1916 GLU A OE2 +494 N N . LYS A 62 0.5433 0.3400 0.2401 0.0192 -0.0375 -0.0163 ? ? ? ? ? ? 1917 LYS A N +495 C CA . LYS A 62 0.5498 0.3354 0.2389 0.0211 -0.0107 -0.0115 ? ? ? ? ? ? 1917 LYS A CA +496 C C . LYS A 62 0.5556 0.3371 0.2598 0.0205 -0.0018 -0.0280 ? ? ? ? ? ? 1917 LYS A C +497 O O . LYS A 62 0.5774 0.3446 0.2515 0.0301 0.0165 -0.0353 ? ? ? ? ? ? 1917 LYS A O +498 C CB . LYS A 62 0.4864 0.2769 0.2081 0.0129 0.0030 0.0075 ? ? ? ? ? ? 1917 LYS A CB +499 C CG . LYS A 62 0.5621 0.3325 0.2550 0.0149 0.0082 0.0261 ? ? ? ? ? ? 1917 LYS A CG +500 C CD . LYS A 62 0.6198 0.3843 0.3440 -0.0033 0.0199 0.0374 ? ? ? ? ? ? 1917 LYS A CD +501 C CE . LYS A 62 0.5837 0.3673 0.3347 -0.0164 0.0452 0.0426 ? ? ? ? ? ? 1917 LYS A CE +502 N NZ . LYS A 62 0.6141 0.3918 0.3921 -0.0432 0.0554 0.0509 ? ? ? ? ? ? 1917 LYS A NZ +503 N N . LEU A 63 0.5349 0.3214 0.2784 0.0134 -0.0100 -0.0318 ? ? ? ? ? ? 1918 LEU A N +504 C CA . LEU A 63 0.5952 0.3654 0.3499 0.0174 0.0017 -0.0423 ? ? ? ? ? ? 1918 LEU A CA +505 C C . LEU A 63 0.5855 0.3229 0.2981 0.0147 0.0003 -0.0692 ? ? ? ? ? ? 1918 LEU A C +506 O O . LEU A 63 0.6824 0.3902 0.3730 0.0263 0.0218 -0.0793 ? ? ? ? ? ? 1918 LEU A O +507 C CB . LEU A 63 0.5970 0.3703 0.3895 0.0116 -0.0059 -0.0375 ? ? ? ? ? ? 1918 LEU A CB +508 C CG . LEU A 63 0.5575 0.3084 0.3620 0.0234 0.0114 -0.0370 ? ? ? ? ? ? 1918 LEU A CG +509 C CD1 . LEU A 63 0.5559 0.3328 0.3783 0.0433 0.0270 -0.0205 ? ? ? ? ? ? 1918 LEU A CD1 +510 C CD2 . LEU A 63 0.5330 0.2787 0.3608 0.0185 0.0062 -0.0292 ? ? ? ? ? ? 1918 LEU A CD2 +511 N N . SER A 64 0.6048 0.2953 0.2965 -0.0049 -0.0686 -0.0288 ? ? ? ? ? ? 1919 SER A N +512 C CA . SER A 64 0.6727 0.3168 0.3479 -0.0024 -0.0860 -0.0300 ? ? ? ? ? ? 1919 SER A CA +513 C C . SER A 64 0.6920 0.2863 0.3155 0.0038 -0.0916 -0.0344 ? ? ? ? ? ? 1919 SER A C +514 O O . SER A 64 0.7697 0.3206 0.3674 0.0072 -0.1051 -0.0379 ? ? ? ? ? ? 1919 SER A O +515 C CB . SER A 64 0.7247 0.3685 0.4334 -0.0112 -0.1066 -0.0350 ? ? ? ? ? ? 1919 SER A CB +516 O OG . SER A 64 0.7923 0.4832 0.5450 -0.0180 -0.0986 -0.0304 ? ? ? ? ? ? 1919 SER A OG +517 N N . SER A 65 0.6918 0.2921 0.2983 0.0041 -0.0819 -0.0341 ? ? ? ? ? ? 1920 SER A N +518 C CA . SER A 65 0.7556 0.3128 0.3086 0.0068 -0.0858 -0.0354 ? ? ? ? ? ? 1920 SER A CA +519 C C . SER A 65 0.7375 0.3060 0.2659 0.0143 -0.0581 -0.0301 ? ? ? ? ? ? 1920 SER A C +520 O O . SER A 65 0.7771 0.3266 0.2667 0.0135 -0.0540 -0.0277 ? ? ? ? ? ? 1920 SER A O +521 C CB . SER A 65 0.7356 0.2817 0.2904 -0.0028 -0.1050 -0.0357 ? ? ? ? ? ? 1920 SER A CB +522 O OG . SER A 65 0.7107 0.2974 0.3008 -0.0073 -0.0956 -0.0335 ? ? ? ? ? ? 1920 SER A OG +523 N N . GLY A 66 0.7095 0.3116 0.2639 0.0204 -0.0396 -0.0259 ? ? ? ? ? ? 1921 GLY A N +524 C CA . GLY A 66 0.7151 0.3324 0.2590 0.0291 -0.0134 -0.0203 ? ? ? ? ? ? 1921 GLY A CA +525 C C . GLY A 66 0.7065 0.3495 0.2552 0.0227 -0.0028 -0.0128 ? ? ? ? ? ? 1921 GLY A C +526 O O . GLY A 66 0.7360 0.3778 0.2617 0.0273 0.0159 -0.0080 ? ? ? ? ? ? 1921 GLY A O +527 N N . GLN A 67 0.6714 0.3391 0.2531 0.0118 -0.0138 -0.0124 ? ? ? ? ? ? 1922 GLN A N +528 C CA . GLN A 67 0.6889 0.3767 0.2801 0.0043 -0.0083 -0.0059 ? ? ? ? ? ? 1922 GLN A CA +529 C C . GLN A 67 0.6599 0.3978 0.2894 0.0036 0.0056 -0.0003 ? ? ? ? ? ? 1922 GLN A C +530 O O . GLN A 67 0.6337 0.3912 0.2781 -0.0034 0.0085 0.0049 ? ? ? ? ? ? 1922 GLN A O +531 C CB . GLN A 67 0.6730 0.3512 0.2779 -0.0067 -0.0316 -0.0115 ? ? ? ? ? ? 1922 GLN A CB +532 C CG . GLN A 67 0.7456 0.3732 0.3120 -0.0084 -0.0498 -0.0126 ? ? ? ? ? ? 1922 GLN A CG +533 C CD . GLN A 67 0.8112 0.4286 0.3987 -0.0186 -0.0750 -0.0150 ? ? ? ? ? ? 1922 GLN A CD +534 O OE1 . GLN A 67 0.9121 0.5429 0.5178 -0.0256 -0.0755 -0.0099 ? ? ? ? ? ? 1922 GLN A OE1 +535 N NE2 . GLN A 67 0.8624 0.4550 0.4537 -0.0196 -0.0981 -0.0226 ? ? ? ? ? ? 1922 GLN A NE2 +536 N N . TYR A 68 0.6017 0.3588 0.2477 0.0094 0.0111 0.0006 ? ? ? ? ? ? 1923 TYR A N +537 C CA . TYR A 68 0.5763 0.3777 0.2522 0.0094 0.0228 0.0097 ? ? ? ? ? ? 1923 TYR A CA +538 C C . TYR A 68 0.6847 0.4835 0.3540 0.0227 0.0415 0.0188 ? ? ? ? ? ? 1923 TYR A C +539 O O . TYR A 68 0.6485 0.4277 0.3092 0.0326 0.0420 0.0169 ? ? ? ? ? ? 1923 TYR A O +540 C CB . TYR A 68 0.5486 0.3791 0.2506 0.0044 0.0148 0.0084 ? ? ? ? ? ? 1923 TYR A CB +541 C CG . TYR A 68 0.5586 0.4012 0.2739 -0.0073 0.0018 -0.0043 ? ? ? ? ? ? 1923 TYR A CG +542 C CD1 . TYR A 68 0.5235 0.3843 0.2524 -0.0149 0.0002 -0.0082 ? ? ? ? ? ? 1923 TYR A CD1 +543 C CD2 . TYR A 68 0.5285 0.3640 0.2479 -0.0101 -0.0090 -0.0135 ? ? ? ? ? ? 1923 TYR A CD2 +544 C CE1 . TYR A 68 0.5120 0.3811 0.2571 -0.0232 -0.0117 -0.0244 ? ? ? ? ? ? 1923 TYR A CE1 +545 C CE2 . TYR A 68 0.5335 0.3823 0.2713 -0.0183 -0.0181 -0.0284 ? ? ? ? ? ? 1923 TYR A CE2 +546 C CZ . TYR A 68 0.5088 0.3732 0.2589 -0.0238 -0.0192 -0.0355 ? ? ? ? ? ? 1923 TYR A CZ +547 O OH . TYR A 68 0.5013 0.3762 0.2737 -0.0296 -0.0284 -0.0544 ? ? ? ? ? ? 1923 TYR A OH +548 N N . PRO A 69 0.5966 0.4150 0.2749 0.0234 0.0567 0.0281 ? ? ? ? ? ? 1924 PRO A N +549 C CA . PRO A 69 0.6162 0.4369 0.2961 0.0381 0.0781 0.0349 ? ? ? ? ? ? 1924 PRO A CA +550 C C . PRO A 69 0.6932 0.5453 0.4134 0.0438 0.0789 0.0442 ? ? ? ? ? ? 1924 PRO A C +551 O O . PRO A 69 0.6541 0.5031 0.3828 0.0591 0.0928 0.0472 ? ? ? ? ? ? 1924 PRO A O +552 C CB . PRO A 69 0.6727 0.5111 0.3575 0.0336 0.0934 0.0445 ? ? ? ? ? ? 1924 PRO A CB +553 C CG . PRO A 69 0.7023 0.5588 0.4051 0.0160 0.0761 0.0457 ? ? ? ? ? ? 1924 PRO A CG +554 C CD . PRO A 69 0.7009 0.5339 0.3881 0.0111 0.0546 0.0317 ? ? ? ? ? ? 1924 PRO A CD +555 N N . ASN A 70 0.4315 0.4773 0.4474 -0.0358 0.0433 -0.0702 ? ? ? ? ? ? 1925 ASN A N +556 C CA . ASN A 70 0.4714 0.4996 0.4763 0.0139 0.0064 -0.0819 ? ? ? ? ? ? 1925 ASN A CA +557 C C . ASN A 70 0.5267 0.4946 0.4568 0.0472 -0.0018 -0.0448 ? ? ? ? ? ? 1925 ASN A C +558 O O . ASN A 70 0.4838 0.4307 0.3776 0.0312 0.0198 -0.0159 ? ? ? ? ? ? 1925 ASN A O +559 C CB . ASN A 70 0.4381 0.5189 0.4946 0.0198 -0.0205 -0.1458 ? ? ? ? ? ? 1925 ASN A CB +560 C CG . ASN A 70 0.5050 0.6016 0.5610 -0.0002 -0.0158 -0.1643 ? ? ? ? ? ? 1925 ASN A CG +561 O OD1 . ASN A 70 0.5318 0.5851 0.5317 0.0105 -0.0139 -0.1350 ? ? ? ? ? ? 1925 ASN A OD1 +562 N ND2 . ASN A 70 0.4676 0.6274 0.5879 -0.0300 -0.0136 -0.2145 ? ? ? ? ? ? 1925 ASN A ND2 +563 N N . LEU A 71 0.4852 0.4256 0.3905 0.0947 -0.0338 -0.0468 ? ? ? ? ? ? 1926 LEU A N +564 C CA . LEU A 71 0.5380 0.4234 0.3683 0.1321 -0.0447 -0.0156 ? ? ? ? ? ? 1926 LEU A CA +565 C C . LEU A 71 0.5436 0.4346 0.3544 0.1281 -0.0453 -0.0276 ? ? ? ? ? ? 1926 LEU A C +566 O O . LEU A 71 0.5993 0.4542 0.3537 0.1323 -0.0308 0.0098 ? ? ? ? ? ? 1926 LEU A O +567 C CB . LEU A 71 0.6675 0.5310 0.4802 0.1844 -0.0862 -0.0315 ? ? ? ? ? ? 1926 LEU A CB +568 C CG . LEU A 71 0.7550 0.5819 0.5549 0.2042 -0.0922 -0.0045 ? ? ? ? ? ? 1926 LEU A CG +569 C CD1 . LEU A 71 0.8475 0.6409 0.6123 0.2603 -0.1361 -0.0174 ? ? ? ? ? ? 1926 LEU A CD1 +570 C CD2 . LEU A 71 0.8658 0.6447 0.6129 0.1951 -0.0593 0.0605 ? ? ? ? ? ? 1926 LEU A CD2 +571 N N . GLU A 72 0.5715 0.5093 0.4320 0.1217 -0.0641 -0.0830 ? ? ? ? ? ? 1927 GLU A N +572 C CA . GLU A 72 0.5779 0.5240 0.4307 0.1197 -0.0720 -0.1047 ? ? ? ? ? ? 1927 GLU A CA +573 C C . GLU A 72 0.5730 0.5093 0.4077 0.0802 -0.0371 -0.0756 ? ? ? ? ? ? 1927 GLU A C +574 O O . GLU A 72 0.5537 0.4621 0.3419 0.0926 -0.0399 -0.0625 ? ? ? ? ? ? 1927 GLU A O +575 C CB . GLU A 72 0.6153 0.6239 0.5431 0.1064 -0.0911 -0.1718 ? ? ? ? ? ? 1927 GLU A CB +576 C CG . GLU A 72 0.8258 0.8469 0.7580 0.0993 -0.1005 -0.2004 ? ? ? ? ? ? 1927 GLU A CG +577 N N . THR A 73 0.5470 0.5041 0.4151 0.0354 -0.0062 -0.0664 ? ? ? ? ? ? 1928 THR A N +578 C CA . THR A 73 0.4955 0.4412 0.3461 -0.0018 0.0240 -0.0418 ? ? ? ? ? ? 1928 THR A CA +579 C C . THR A 73 0.5349 0.4277 0.3179 0.0150 0.0389 0.0147 ? ? ? ? ? ? 1928 THR A C +580 O O . THR A 73 0.5398 0.4114 0.2889 0.0049 0.0508 0.0327 ? ? ? ? ? ? 1928 THR A O +581 C CB . THR A 73 0.4250 0.4065 0.3250 -0.0531 0.0524 -0.0485 ? ? ? ? ? ? 1928 THR A CB +582 O OG1 . THR A 73 0.5080 0.4871 0.4154 -0.0486 0.0618 -0.0272 ? ? ? ? ? ? 1928 THR A OG1 +583 C CG2 . THR A 73 0.3993 0.4391 0.3670 -0.0741 0.0425 -0.1057 ? ? ? ? ? ? 1928 THR A CG2 +584 N N . PHE A 74 0.5646 0.3316 0.2618 -0.0301 0.0485 -0.0061 ? ? ? ? ? ? 1929 PHE A N +585 C CA . PHE A 74 0.5491 0.3251 0.2601 -0.0229 0.0348 -0.0180 ? ? ? ? ? ? 1929 PHE A CA +586 C C . PHE A 74 0.6157 0.4065 0.3437 -0.0182 0.0268 -0.0127 ? ? ? ? ? ? 1929 PHE A C +587 O O . PHE A 74 0.5543 0.3386 0.2761 -0.0130 0.0104 -0.0174 ? ? ? ? ? ? 1929 PHE A O +588 C CB . PHE A 74 0.5645 0.3486 0.3036 -0.0227 0.0548 -0.0283 ? ? ? ? ? ? 1929 PHE A CB +589 C CG . PHE A 74 0.4998 0.2935 0.2719 -0.0189 0.0558 -0.0403 ? ? ? ? ? ? 1929 PHE A CG +590 C CD1 . PHE A 74 0.5029 0.3076 0.2841 -0.0216 0.0370 -0.0672 ? ? ? ? ? ? 1929 PHE A CD1 +591 C CD2 . PHE A 74 0.4529 0.2497 0.2464 -0.0064 0.0787 -0.0252 ? ? ? ? ? ? 1929 PHE A CD2 +592 C CE1 . PHE A 74 0.4579 0.2769 0.2836 -0.0213 0.0436 -0.0812 ? ? ? ? ? ? 1929 PHE A CE1 +593 C CE2 . PHE A 74 0.4903 0.2868 0.3147 -0.0010 0.0906 -0.0325 ? ? ? ? ? ? 1929 PHE A CE2 +594 C CZ . PHE A 74 0.5045 0.3123 0.3525 -0.0132 0.0747 -0.0618 ? ? ? ? ? ? 1929 PHE A CZ +595 N N . ALA A 75 0.5479 0.3644 0.2934 -0.0140 0.0373 -0.0050 ? ? ? ? ? ? 1930 ALA A N +596 C CA . ALA A 75 0.5326 0.3743 0.2874 -0.0025 0.0267 -0.0066 ? ? ? ? ? ? 1930 ALA A CA +597 C C . ALA A 75 0.5248 0.3534 0.2712 -0.0180 0.0099 -0.0174 ? ? ? ? ? ? 1930 ALA A C +598 O O . ALA A 75 0.5468 0.3755 0.2903 -0.0108 -0.0030 -0.0243 ? ? ? ? ? ? 1930 ALA A O +599 C CB . ALA A 75 0.5136 0.4026 0.2828 0.0147 0.0364 -0.0018 ? ? ? ? ? ? 1930 ALA A CB +600 N N . LEU A 76 0.5911 0.3997 0.3323 -0.0377 0.0184 -0.0181 ? ? ? ? ? ? 1931 LEU A N +601 C CA . LEU A 76 0.6182 0.3946 0.3528 -0.0541 0.0200 -0.0270 ? ? ? ? ? ? 1931 LEU A CA +602 C C . LEU A 76 0.6446 0.3746 0.3419 -0.0414 0.0111 -0.0210 ? ? ? ? ? ? 1931 LEU A C +603 O O . LEU A 76 0.6124 0.3233 0.3062 -0.0438 0.0082 -0.0297 ? ? ? ? ? ? 1931 LEU A O +604 C CB . LEU A 76 0.6987 0.4455 0.4305 -0.0728 0.0463 -0.0220 ? ? ? ? ? ? 1931 LEU A CB +605 C CG . LEU A 76 0.8144 0.6146 0.5990 -0.0911 0.0578 -0.0364 ? ? ? ? ? ? 1931 LEU A CG +606 C CD1 . LEU A 76 0.8747 0.6378 0.6587 -0.1087 0.0935 -0.0274 ? ? ? ? ? ? 1931 LEU A CD1 +607 C CD2 . LEU A 76 0.8739 0.7145 0.7025 -0.1062 0.0478 -0.0702 ? ? ? ? ? ? 1931 LEU A CD2 +608 N N . ASP A 77 0.5992 0.3174 0.2707 -0.0258 0.0065 -0.0110 ? ? ? ? ? ? 1932 ASP A N +609 C CA . ASP A 77 0.6270 0.3221 0.2671 -0.0051 -0.0063 -0.0086 ? ? ? ? ? ? 1932 ASP A CA +610 C C . ASP A 77 0.5628 0.2847 0.2273 0.0035 -0.0213 -0.0160 ? ? ? ? ? ? 1932 ASP A C +611 O O . ASP A 77 0.5691 0.2700 0.2162 0.0157 -0.0277 -0.0151 ? ? ? ? ? ? 1932 ASP A O +612 C CB . ASP A 77 0.6125 0.3143 0.2290 0.0122 -0.0140 -0.0097 ? ? ? ? ? ? 1932 ASP A CB +613 C CG . ASP A 77 0.6747 0.3288 0.2298 0.0290 -0.0012 0.0045 ? ? ? ? ? ? 1932 ASP A CG +614 O OD1 . ASP A 77 0.7730 0.3761 0.3102 0.0225 0.0230 0.0180 ? ? ? ? ? ? 1932 ASP A OD1 +615 O OD2 . ASP A 77 0.6836 0.3495 0.2072 0.0517 -0.0112 -0.0005 ? ? ? ? ? ? 1932 ASP A OD2 +616 N N . VAL A 78 0.4379 0.3036 0.2476 0.0313 -0.0191 0.0152 ? ? ? ? ? ? 1933 VAL A N +617 C CA . VAL A 78 0.4338 0.2859 0.2373 0.0247 -0.0186 0.0129 ? ? ? ? ? ? 1933 VAL A CA +618 C C . VAL A 78 0.4840 0.3284 0.2793 0.0198 -0.0215 0.0172 ? ? ? ? ? ? 1933 VAL A C +619 O O . VAL A 78 0.5009 0.3348 0.2884 0.0149 -0.0170 0.0160 ? ? ? ? ? ? 1933 VAL A O +620 C CB . VAL A 78 0.4509 0.2860 0.2452 0.0258 -0.0167 0.0125 ? ? ? ? ? ? 1933 VAL A CB +621 C CG1 . VAL A 78 0.4988 0.2992 0.2683 0.0210 -0.0062 0.0136 ? ? ? ? ? ? 1933 VAL A CG1 +622 C CG2 . VAL A 78 0.4373 0.2800 0.2479 0.0279 -0.0118 0.0030 ? ? ? ? ? ? 1933 VAL A CG2 +623 N N . ARG A 79 0.4693 0.3215 0.2741 0.0217 -0.0294 0.0172 ? ? ? ? ? ? 1934 ARG A N +624 C CA . ARG A 79 0.4629 0.3113 0.2681 0.0196 -0.0377 0.0133 ? ? ? ? ? ? 1934 ARG A CA +625 C C . ARG A 79 0.4983 0.3517 0.3146 0.0114 -0.0269 0.0147 ? ? ? ? ? ? 1934 ARG A C +626 O O . ARG A 79 0.5035 0.3481 0.3130 0.0075 -0.0297 0.0123 ? ? ? ? ? ? 1934 ARG A O +627 C CB . ARG A 79 0.4473 0.3108 0.2786 0.0259 -0.0529 0.0017 ? ? ? ? ? ? 1934 ARG A CB +628 C CG . ARG A 79 0.5368 0.3831 0.3417 0.0417 -0.0697 -0.0004 ? ? ? ? ? ? 1934 ARG A CG +629 C CD . ARG A 79 0.5386 0.4082 0.3808 0.0528 -0.0886 -0.0175 ? ? ? ? ? ? 1934 ARG A CD +630 N NE . ARG A 79 0.6002 0.4425 0.4026 0.0746 -0.1070 -0.0180 ? ? ? ? ? ? 1934 ARG A NE +631 C CZ . ARG A 79 0.6484 0.5052 0.4737 0.0878 -0.1203 -0.0287 ? ? ? ? ? ? 1934 ARG A CZ +632 N NH1 . ARG A 79 0.5504 0.4519 0.4452 0.0782 -0.1132 -0.0412 ? ? ? ? ? ? 1934 ARG A NH1 +633 N NH2 . ARG A 79 0.6762 0.4951 0.4505 0.1119 -0.1365 -0.0270 ? ? ? ? ? ? 1934 ARG A NH2 +634 N N . LEU A 80 0.4479 0.3065 0.2710 0.0121 -0.0136 0.0189 ? ? ? ? ? ? 1935 LEU A N +635 C CA . LEU A 80 0.4804 0.3277 0.2965 0.0107 0.0002 0.0230 ? ? ? ? ? ? 1935 LEU A CA +636 C C . LEU A 80 0.5333 0.3719 0.3301 0.0129 -0.0049 0.0233 ? ? ? ? ? ? 1935 LEU A C +637 O O . LEU A 80 0.4765 0.3051 0.2692 0.0096 -0.0004 0.0240 ? ? ? ? ? ? 1935 LEU A O +638 C CB . LEU A 80 0.4799 0.3155 0.2807 0.0208 0.0158 0.0290 ? ? ? ? ? ? 1935 LEU A CB +639 C CG . LEU A 80 0.4921 0.2961 0.2597 0.0299 0.0312 0.0360 ? ? ? ? ? ? 1935 LEU A CG +640 C CD1 . LEU A 80 0.5264 0.3171 0.3122 0.0159 0.0528 0.0363 ? ? ? ? ? ? 1935 LEU A CD1 +641 C CD2 . LEU A 80 0.5157 0.2933 0.2436 0.0496 0.0433 0.0418 ? ? ? ? ? ? 1935 LEU A CD2 +642 N N . VAL A 81 0.4541 0.2968 0.2469 0.0170 -0.0113 0.0191 ? ? ? ? ? ? 1936 VAL A N +643 C CA . VAL A 81 0.4711 0.3103 0.2635 0.0165 -0.0117 0.0117 ? ? ? ? ? ? 1936 VAL A CA +644 C C . VAL A 81 0.5379 0.3649 0.3239 0.0062 -0.0090 0.0131 ? ? ? ? ? ? 1936 VAL A C +645 O O . VAL A 81 0.4820 0.3036 0.2667 0.0050 -0.0061 0.0103 ? ? ? ? ? ? 1936 VAL A O +646 C CB . VAL A 81 0.4790 0.3237 0.2852 0.0166 -0.0106 0.0003 ? ? ? ? ? ? 1936 VAL A CB +647 C CG1 . VAL A 81 0.4216 0.2627 0.2428 0.0110 -0.0022 -0.0131 ? ? ? ? ? ? 1936 VAL A CG1 +648 C CG2 . VAL A 81 0.4144 0.2728 0.2280 0.0310 -0.0190 -0.0082 ? ? ? ? ? ? 1936 VAL A CG2 +649 N N . PHE A 82 0.4821 0.3009 0.2584 0.0033 -0.0131 0.0155 ? ? ? ? ? ? 1937 PHE A N +650 C CA . PHE A 82 0.4827 0.2802 0.2376 0.0007 -0.0145 0.0142 ? ? ? ? ? ? 1937 PHE A CA +651 C C . PHE A 82 0.5163 0.3206 0.2818 -0.0016 -0.0229 0.0113 ? ? ? ? ? ? 1937 PHE A C +652 O O . PHE A 82 0.5282 0.3185 0.2808 -0.0039 -0.0231 0.0080 ? ? ? ? ? ? 1937 PHE A O +653 C CB . PHE A 82 0.4952 0.2670 0.2182 0.0080 -0.0189 0.0151 ? ? ? ? ? ? 1937 PHE A CB +654 C CG . PHE A 82 0.5580 0.3163 0.2756 0.0067 -0.0019 0.0162 ? ? ? ? ? ? 1937 PHE A CG +655 C CD1 . PHE A 82 0.5301 0.2841 0.2612 -0.0021 0.0192 0.0098 ? ? ? ? ? ? 1937 PHE A CD1 +656 C CD2 . PHE A 82 0.5609 0.3150 0.2723 0.0136 -0.0058 0.0186 ? ? ? ? ? ? 1937 PHE A CD2 +657 C CE1 . PHE A 82 0.5648 0.3109 0.3099 -0.0064 0.0386 0.0026 ? ? ? ? ? ? 1937 PHE A CE1 +658 C CE2 . PHE A 82 0.6261 0.3662 0.3400 0.0100 0.0140 0.0164 ? ? ? ? ? ? 1937 PHE A CE2 +659 C CZ . PHE A 82 0.5869 0.3244 0.3222 -0.0014 0.0373 0.0067 ? ? ? ? ? ? 1937 PHE A CZ +660 N N . ASP A 83 0.4960 0.3194 0.2894 -0.0024 -0.0253 0.0098 ? ? ? ? ? ? 1938 ASP A N +661 C CA . ASP A 83 0.5226 0.3523 0.3427 -0.0091 -0.0228 0.0024 ? ? ? ? ? ? 1938 ASP A CA +662 C C . ASP A 83 0.5649 0.3822 0.3775 -0.0129 -0.0067 0.0090 ? ? ? ? ? ? 1938 ASP A C +663 O O . ASP A 83 0.4929 0.3032 0.3121 -0.0188 -0.0051 0.0030 ? ? ? ? ? ? 1938 ASP A O +664 C CB . ASP A 83 0.5111 0.3582 0.3697 -0.0119 -0.0154 -0.0028 ? ? ? ? ? ? 1938 ASP A CB +665 C CG . ASP A 83 0.5785 0.4424 0.4568 -0.0053 -0.0371 -0.0172 ? ? ? ? ? ? 1938 ASP A CG +666 O OD1 . ASP A 83 0.5093 0.3629 0.3618 0.0047 -0.0602 -0.0236 ? ? ? ? ? ? 1938 ASP A OD1 +667 O OD2 . ASP A 83 0.5160 0.3973 0.4301 -0.0065 -0.0304 -0.0234 ? ? ? ? ? ? 1938 ASP A OD2 +668 N N . ASN A 84 0.5161 0.3285 0.3133 -0.0057 0.0018 0.0183 ? ? ? ? ? ? 1939 ASN A N +669 C CA . ASN A 84 0.5625 0.3581 0.3431 0.0000 0.0100 0.0220 ? ? ? ? ? ? 1939 ASN A CA +670 C C . ASN A 84 0.5528 0.3461 0.3285 -0.0030 0.0039 0.0162 ? ? ? ? ? ? 1939 ASN A C +671 O O . ASN A 84 0.5340 0.3143 0.3054 -0.0040 0.0089 0.0154 ? ? ? ? ? ? 1939 ASN A O +672 C CB . ASN A 84 0.4680 0.2594 0.2293 0.0178 0.0087 0.0249 ? ? ? ? ? ? 1939 ASN A CB +673 C CG . ASN A 84 0.5388 0.3144 0.2857 0.0256 0.0224 0.0333 ? ? ? ? ? ? 1939 ASN A CG +674 O OD1 . ASN A 84 0.5172 0.2816 0.2753 0.0149 0.0415 0.0365 ? ? ? ? ? ? 1939 ASN A OD1 +675 N ND2 . ASN A 84 0.5097 0.2812 0.2335 0.0452 0.0154 0.0330 ? ? ? ? ? ? 1939 ASN A ND2 +676 N N . CYS A 85 0.5390 0.3383 0.3127 -0.0044 -0.0016 0.0121 ? ? ? ? ? ? 1940 CYS A N +677 C CA . CYS A 85 0.5175 0.3059 0.2835 -0.0079 0.0027 0.0058 ? ? ? ? ? ? 1940 CYS A CA +678 C C . CYS A 85 0.5534 0.3270 0.3065 -0.0135 -0.0001 0.0044 ? ? ? ? ? ? 1940 CYS A C +679 O O . CYS A 85 0.5661 0.3289 0.3143 -0.0154 0.0055 0.0006 ? ? ? ? ? ? 1940 CYS A O +680 C CB . CYS A 85 0.5181 0.2995 0.2774 -0.0097 0.0093 0.0025 ? ? ? ? ? ? 1940 CYS A CB +681 S SG . CYS A 85 0.5454 0.2995 0.2930 -0.0160 0.0312 -0.0066 ? ? ? ? ? ? 1940 CYS A SG +682 N N . GLU A 86 0.5174 0.2928 0.2700 -0.0138 -0.0118 0.0027 ? ? ? ? ? ? 1941 GLU A N +683 C CA . GLU A 86 0.5642 0.3302 0.3120 -0.0150 -0.0224 -0.0074 ? ? ? ? ? ? 1941 GLU A CA +684 C C . GLU A 86 0.5890 0.3603 0.3647 -0.0230 -0.0145 -0.0106 ? ? ? ? ? ? 1941 GLU A C +685 O O . GLU A 86 0.5495 0.3093 0.3208 -0.0255 -0.0168 -0.0190 ? ? ? ? ? ? 1941 GLU A O +686 C CB . GLU A 86 0.6149 0.3886 0.3693 -0.0082 -0.0440 -0.0184 ? ? ? ? ? ? 1941 GLU A CB +687 C CG . GLU A 86 0.6297 0.3788 0.3361 0.0060 -0.0536 -0.0160 ? ? ? ? ? ? 1941 GLU A CG +688 C CD . GLU A 86 0.6721 0.4182 0.3706 0.0230 -0.0860 -0.0345 ? ? ? ? ? ? 1941 GLU A CD +689 O OE1 . GLU A 86 0.6873 0.4342 0.3944 0.0264 -0.1028 -0.0532 ? ? ? ? ? ? 1941 GLU A OE1 +690 O OE2 . GLU A 86 0.7424 0.4857 0.4286 0.0357 -0.0977 -0.0343 ? ? ? ? ? ? 1941 GLU A OE2 +691 N N . THR A 87 0.5378 0.3175 0.3348 -0.0252 -0.0020 -0.0038 ? ? ? ? ? ? 1942 THR A N +692 C CA . THR A 87 0.5072 0.2743 0.3188 -0.0310 0.0155 -0.0037 ? ? ? ? ? ? 1942 THR A CA +693 C C . THR A 87 0.5701 0.3178 0.3566 -0.0258 0.0214 0.0017 ? ? ? ? ? ? 1942 THR A C +694 O O . THR A 87 0.5430 0.2747 0.3343 -0.0308 0.0302 -0.0025 ? ? ? ? ? ? 1942 THR A O +695 C CB . THR A 87 0.5028 0.2629 0.3198 -0.0289 0.0356 0.0061 ? ? ? ? ? ? 1942 THR A CB +696 O OG1 . THR A 87 0.5373 0.3181 0.3918 -0.0363 0.0342 -0.0041 ? ? ? ? ? ? 1942 THR A OG1 +697 C CG2 . THR A 87 0.5361 0.2612 0.3491 -0.0314 0.0639 0.0102 ? ? ? ? ? ? 1942 THR A CG2 +698 N N . PHE A 88 0.5319 0.2831 0.3002 -0.0156 0.0168 0.0065 ? ? ? ? ? ? 1943 PHE A N +699 C CA . PHE A 88 0.5991 0.3386 0.3556 -0.0061 0.0199 0.0056 ? ? ? ? ? ? 1943 PHE A CA +700 C C . PHE A 88 0.6044 0.3460 0.3602 -0.0102 0.0179 -0.0040 ? ? ? ? ? ? 1943 PHE A C +701 O O . PHE A 88 0.6236 0.3597 0.3806 -0.0035 0.0210 -0.0100 ? ? ? ? ? ? 1943 PHE A O +702 C CB . PHE A 88 0.5408 0.2840 0.2897 0.0127 0.0155 0.0074 ? ? ? ? ? ? 1943 PHE A CB +703 C CG . PHE A 88 0.5934 0.3157 0.3247 0.0330 0.0145 0.0053 ? ? ? ? ? ? 1943 PHE A CG +704 C CD1 . PHE A 88 0.6036 0.2865 0.3035 0.0426 0.0272 0.0172 ? ? ? ? ? ? 1943 PHE A CD1 +705 C CD2 . PHE A 88 0.5494 0.2859 0.2958 0.0447 0.0035 -0.0113 ? ? ? ? ? ? 1943 PHE A CD2 +706 C CE1 . PHE A 88 0.6842 0.3348 0.3517 0.0689 0.0245 0.0164 ? ? ? ? ? ? 1943 PHE A CE1 +707 C CE2 . PHE A 88 0.5767 0.2944 0.3069 0.0702 -0.0045 -0.0179 ? ? ? ? ? ? 1943 PHE A CE2 +708 C CZ . PHE A 88 0.6842 0.3551 0.3667 0.0851 0.0036 -0.0021 ? ? ? ? ? ? 1943 PHE A CZ +709 N N . ASN A 89 0.5350 0.2771 0.2832 -0.0179 0.0148 -0.0067 ? ? ? ? ? ? 1944 ASN A N +710 C CA . ASN A 89 0.5694 0.2966 0.3016 -0.0202 0.0230 -0.0138 ? ? ? ? ? ? 1944 ASN A CA +711 C C . ASN A 89 0.6123 0.3161 0.3121 -0.0220 0.0167 -0.0173 ? ? ? ? ? ? 1944 ASN A C +712 O O . ASN A 89 0.5993 0.3047 0.2910 -0.0194 0.0015 -0.0175 ? ? ? ? ? ? 1944 ASN A O +713 C CB . ASN A 89 0.6164 0.3469 0.3517 -0.0198 0.0329 -0.0158 ? ? ? ? ? ? 1944 ASN A CB +714 C CG . ASN A 89 0.5703 0.3266 0.3427 -0.0130 0.0326 -0.0227 ? ? ? ? ? ? 1944 ASN A CG +715 O OD1 . ASN A 89 0.5987 0.3603 0.3947 -0.0103 0.0404 -0.0371 ? ? ? ? ? ? 1944 ASN A OD1 +716 N ND2 . ASN A 89 0.5041 0.2763 0.2830 -0.0071 0.0213 -0.0166 ? ? ? ? ? ? 1944 ASN A ND2 +717 N N . GLU A 90 0.6617 0.2709 0.2922 -0.0009 -0.0431 -0.0189 ? ? ? ? ? ? 1945 GLU A N +718 C CA . GLU A 90 0.6969 0.2833 0.2846 -0.0021 -0.0453 -0.0373 ? ? ? ? ? ? 1945 GLU A CA +719 C C . GLU A 90 0.6842 0.2900 0.2597 0.0095 -0.0515 -0.0338 ? ? ? ? ? ? 1945 GLU A C +720 O O . GLU A 90 0.6618 0.2758 0.2550 0.0213 -0.0391 -0.0205 ? ? ? ? ? ? 1945 GLU A O +721 C CB A GLU A 90 0.7491 0.2830 0.3105 0.0061 -0.0212 -0.0437 ? ? ? ? ? ? 1945 GLU A CB +722 C CB B GLU A 90 0.7496 0.2831 0.3113 0.0053 -0.0215 -0.0440 ? ? ? ? ? ? 1945 GLU A CB +723 C CG A GLU A 90 0.8407 0.3404 0.4150 0.0013 -0.0078 -0.0433 ? ? ? ? ? ? 1945 GLU A CG +724 C CG B GLU A 90 0.7861 0.2833 0.3468 -0.0078 -0.0140 -0.0528 ? ? ? ? ? ? 1945 GLU A CG +725 C CD A GLU A 90 1.0169 0.4661 0.5775 0.0165 0.0229 -0.0479 ? ? ? ? ? ? 1945 GLU A CD +726 C CD B GLU A 90 0.8351 0.3297 0.3681 -0.0336 -0.0307 -0.0781 ? ? ? ? ? ? 1945 GLU A CD +727 O OE1 A GLU A 90 1.0741 0.4898 0.5862 0.0113 0.0317 -0.0701 ? ? ? ? ? ? 1945 GLU A OE1 +728 O OE1 B GLU A 90 0.9127 0.4252 0.4165 -0.0358 -0.0473 -0.0906 ? ? ? ? ? ? 1945 GLU A OE1 +729 O OE2 A GLU A 90 1.1134 0.5589 0.7121 0.0342 0.0383 -0.0298 ? ? ? ? ? ? 1945 GLU A OE2 +730 O OE2 B GLU A 90 0.8864 0.3619 0.4274 -0.0522 -0.0275 -0.0848 ? ? ? ? ? ? 1945 GLU A OE2 +731 N N . ASP A 91 0.7341 0.3474 0.2809 0.0059 -0.0707 -0.0454 ? ? ? ? ? ? 1946 ASP A N +732 C CA . ASP A 91 0.7468 0.3653 0.2707 0.0211 -0.0762 -0.0384 ? ? ? ? ? ? 1946 ASP A CA +733 C C . ASP A 91 0.8490 0.4263 0.3389 0.0340 -0.0490 -0.0321 ? ? ? ? ? ? 1946 ASP A C +734 O O . ASP A 91 0.8195 0.3961 0.3115 0.0457 -0.0373 -0.0186 ? ? ? ? ? ? 1946 ASP A O +735 C CB . ASP A 91 0.7500 0.3796 0.2401 0.0189 -0.1045 -0.0505 ? ? ? ? ? ? 1946 ASP A CB +736 C CG . ASP A 91 0.7965 0.4780 0.3315 0.0084 -0.1292 -0.0571 ? ? ? ? ? ? 1946 ASP A CG +737 O OD1 . ASP A 91 0.7169 0.4222 0.3003 0.0060 -0.1226 -0.0493 ? ? ? ? ? ? 1946 ASP A OD1 +738 O OD2 . ASP A 91 0.8463 0.5483 0.3685 0.0011 -0.1548 -0.0722 ? ? ? ? ? ? 1946 ASP A OD2 +739 N N . ASP A 92 0.8167 0.3564 0.2763 0.0298 -0.0345 -0.0444 ? ? ? ? ? ? 1947 ASP A N +740 C CA . ASP A 92 0.9132 0.4127 0.3425 0.0403 -0.0021 -0.0427 ? ? ? ? ? ? 1947 ASP A CA +741 C C . ASP A 92 0.8321 0.3366 0.3186 0.0465 0.0237 -0.0331 ? ? ? ? ? ? 1947 ASP A C +742 O O . ASP A 92 0.8541 0.3316 0.3453 0.0484 0.0445 -0.0403 ? ? ? ? ? ? 1947 ASP A O +743 C CB . ASP A 92 0.9411 0.3954 0.3089 0.0328 0.0058 -0.0644 ? ? ? ? ? ? 1947 ASP A CB +744 C CG . ASP A 92 1.0843 0.4946 0.4086 0.0425 0.0428 -0.0653 ? ? ? ? ? ? 1947 ASP A CG +745 O OD1 . ASP A 92 1.0182 0.4348 0.3585 0.0540 0.0603 -0.0481 ? ? ? ? ? ? 1947 ASP A OD1 +746 O OD2 . ASP A 92 1.1634 0.5412 0.4503 0.0350 0.0566 -0.0822 ? ? ? ? ? ? 1947 ASP A OD2 +747 N N . SER A 93 0.7999 0.3407 0.3316 0.0502 0.0215 -0.0178 ? ? ? ? ? ? 1948 SER A N +748 C CA . SER A 93 0.7836 0.3439 0.3725 0.0559 0.0399 -0.0079 ? ? ? ? ? ? 1948 SER A CA +749 C C . SER A 93 0.6889 0.2767 0.2998 0.0558 0.0427 0.0019 ? ? ? ? ? ? 1948 SER A C +750 O O . SER A 93 0.7197 0.3107 0.3088 0.0533 0.0277 0.0033 ? ? ? ? ? ? 1948 SER A O +751 C CB . SER A 93 0.7489 0.3332 0.3822 0.0514 0.0248 -0.0029 ? ? ? ? ? ? 1948 SER A CB +752 O OG . SER A 93 0.6493 0.2695 0.2976 0.0404 -0.0007 0.0011 ? ? ? ? ? ? 1948 SER A OG +753 N N . ASP A 94 0.6936 0.3018 0.3511 0.0586 0.0627 0.0073 ? ? ? ? ? ? 1949 ASP A N +754 C CA . ASP A 94 0.6483 0.2801 0.3294 0.0526 0.0697 0.0119 ? ? ? ? ? ? 1949 ASP A CA +755 C C . ASP A 94 0.6349 0.3011 0.3356 0.0423 0.0423 0.0138 ? ? ? ? ? ? 1949 ASP A C +756 O O . ASP A 94 0.6226 0.2847 0.3112 0.0388 0.0422 0.0141 ? ? ? ? ? ? 1949 ASP A O +757 C CB . ASP A 94 0.6801 0.3424 0.4208 0.0527 0.0921 0.0131 ? ? ? ? ? ? 1949 ASP A CB +758 C CG . ASP A 94 0.8270 0.4565 0.5538 0.0611 0.1303 0.0087 ? ? ? ? ? ? 1949 ASP A CG +759 O OD1 . ASP A 94 0.7538 0.3596 0.4553 0.0565 0.1554 0.0079 ? ? ? ? ? ? 1949 ASP A OD1 +760 O OD2 . ASP A 94 0.9217 0.5447 0.6619 0.0722 0.1393 0.0060 ? ? ? ? ? ? 1949 ASP A OD2 +761 N N . ILE A 95 0.5754 0.2699 0.3035 0.0382 0.0226 0.0157 ? ? ? ? ? ? 1950 ILE A N +762 C CA . ILE A 95 0.5564 0.2841 0.3011 0.0256 0.0014 0.0155 ? ? ? ? ? ? 1950 ILE A CA +763 C C . ILE A 95 0.6088 0.3209 0.3189 0.0247 -0.0143 0.0103 ? ? ? ? ? ? 1950 ILE A C +764 O O . ILE A 95 0.5735 0.3000 0.2888 0.0191 -0.0207 0.0072 ? ? ? ? ? ? 1950 ILE A O +765 C CB . ILE A 95 0.5855 0.3434 0.3599 0.0211 -0.0133 0.0226 ? ? ? ? ? ? 1950 ILE A CB +766 C CG1 . ILE A 95 0.5492 0.3409 0.3691 0.0230 -0.0048 0.0281 ? ? ? ? ? ? 1950 ILE A CG1 +767 C CG2 . ILE A 95 0.5971 0.3807 0.3732 0.0053 -0.0325 0.0207 ? ? ? ? ? ? 1950 ILE A CG2 +768 C CD1 . ILE A 95 0.5795 0.3987 0.4246 0.0255 -0.0219 0.0414 ? ? ? ? ? ? 1950 ILE A CD1 +769 N N . GLY A 96 0.6252 0.3097 0.3037 0.0299 -0.0193 0.0071 ? ? ? ? ? ? 1951 GLY A N +770 C CA . GLY A 96 0.6116 0.2894 0.2611 0.0290 -0.0371 -0.0001 ? ? ? ? ? ? 1951 GLY A CA +771 C C . GLY A 96 0.7012 0.3677 0.3282 0.0394 -0.0348 0.0026 ? ? ? ? ? ? 1951 GLY A C +772 O O . GLY A 96 0.6510 0.3354 0.2856 0.0403 -0.0491 0.0011 ? ? ? ? ? ? 1951 GLY A O +773 N N . ARG A 97 0.6723 0.3063 0.2726 0.0486 -0.0137 0.0077 ? ? ? ? ? ? 1952 ARG A N +774 C CA . ARG A 97 0.7080 0.3186 0.2785 0.0598 -0.0067 0.0157 ? ? ? ? ? ? 1952 ARG A CA +775 C C . ARG A 97 0.6532 0.2819 0.2632 0.0559 0.0016 0.0190 ? ? ? ? ? ? 1952 ARG A C +776 O O . ARG A 97 0.6859 0.3071 0.2872 0.0654 -0.0040 0.0240 ? ? ? ? ? ? 1952 ARG A O +777 C CB . ARG A 97 0.7201 0.2869 0.2501 0.0660 0.0221 0.0206 ? ? ? ? ? ? 1952 ARG A CB +778 C CG . ARG A 97 0.8602 0.3962 0.3279 0.0712 0.0148 0.0155 ? ? ? ? ? ? 1952 ARG A CG +779 C CD . ARG A 97 0.9027 0.3907 0.3213 0.0760 0.0489 0.0196 ? ? ? ? ? ? 1952 ARG A CD +780 N NE . ARG A 97 0.8657 0.3574 0.3226 0.0700 0.0787 0.0127 ? ? ? ? ? ? 1952 ARG A NE +781 C CZ . ARG A 97 0.9191 0.4007 0.3699 0.0686 0.0845 0.0005 ? ? ? ? ? ? 1952 ARG A CZ +782 N NH1 . ARG A 97 0.9534 0.4189 0.3569 0.0669 0.0633 -0.0099 ? ? ? ? ? ? 1952 ARG A NH1 +783 N NH2 . ARG A 97 0.9872 0.4760 0.4833 0.0689 0.1122 -0.0028 ? ? ? ? ? ? 1952 ARG A NH2 +784 N N . ALA A 98 0.6050 0.2574 0.2584 0.0426 0.0147 0.0153 ? ? ? ? ? ? 1953 ALA A N +785 C CA . ALA A 98 0.6213 0.2933 0.3109 0.0320 0.0231 0.0120 ? ? ? ? ? ? 1953 ALA A CA +786 C C . ALA A 98 0.5805 0.2741 0.2824 0.0309 0.0029 0.0067 ? ? ? ? ? ? 1953 ALA A C +787 O O . ALA A 98 0.5731 0.2573 0.2806 0.0340 0.0110 0.0057 ? ? ? ? ? ? 1953 ALA A O +788 C CB . ALA A 98 0.5618 0.2712 0.2961 0.0154 0.0291 0.0066 ? ? ? ? ? ? 1953 ALA A CB +789 N N . GLY A 99 0.5830 0.3023 0.2914 0.0262 -0.0190 0.0024 ? ? ? ? ? ? 1954 GLY A N +790 C CA . GLY A 99 0.5429 0.2889 0.2692 0.0219 -0.0342 -0.0053 ? ? ? ? ? ? 1954 GLY A CA +791 C C . GLY A 99 0.5743 0.3068 0.2859 0.0415 -0.0428 -0.0026 ? ? ? ? ? ? 1954 GLY A C +792 O O . GLY A 99 0.5464 0.2882 0.2800 0.0454 -0.0400 -0.0067 ? ? ? ? ? ? 1954 GLY A O +793 N N . HIS A 100 0.6004 0.3108 0.2738 0.0550 -0.0536 0.0042 ? ? ? ? ? ? 1955 HIS A N +794 C CA . HIS A 100 0.6181 0.3190 0.2715 0.0772 -0.0682 0.0110 ? ? ? ? ? ? 1955 HIS A CA +795 C C . HIS A 100 0.6493 0.3154 0.2956 0.0930 -0.0475 0.0236 ? ? ? ? ? ? 1955 HIS A C +796 O O . HIS A 100 0.6697 0.3404 0.3316 0.1100 -0.0540 0.0273 ? ? ? ? ? ? 1955 HIS A O +797 C CB . HIS A 100 0.6945 0.3748 0.2946 0.0853 -0.0832 0.0149 ? ? ? ? ? ? 1955 HIS A CB +798 C CG . HIS A 100 0.7385 0.4490 0.3460 0.0705 -0.1052 -0.0004 ? ? ? ? ? ? 1955 HIS A CG +799 N ND1 . HIS A 100 0.7218 0.4744 0.3556 0.0704 -0.1313 -0.0099 ? ? ? ? ? ? 1955 HIS A ND1 +800 C CD2 . HIS A 100 0.7230 0.4251 0.3191 0.0544 -0.1013 -0.0088 ? ? ? ? ? ? 1955 HIS A CD2 +801 C CE1 . HIS A 100 0.6958 0.4631 0.3311 0.0505 -0.1417 -0.0249 ? ? ? ? ? ? 1955 HIS A CE1 +802 N NE2 . HIS A 100 0.6775 0.4098 0.2875 0.0418 -0.1234 -0.0235 ? ? ? ? ? ? 1955 HIS A NE2 +803 N N . ASN A 101 0.6652 0.2957 0.2925 0.0876 -0.0200 0.0298 ? ? ? ? ? ? 1956 ASN A N +804 C CA . ASN A 101 0.7039 0.2917 0.3228 0.0966 0.0072 0.0406 ? ? ? ? ? ? 1956 ASN A CA +805 C C . ASN A 101 0.6778 0.2829 0.3474 0.0883 0.0186 0.0290 ? ? ? ? ? ? 1956 ASN A C +806 O O . ASN A 101 0.7138 0.2916 0.3849 0.1057 0.0279 0.0365 ? ? ? ? ? ? 1956 ASN A O +807 C CB . ASN A 101 0.7194 0.2767 0.3225 0.0834 0.0394 0.0430 ? ? ? ? ? ? 1956 ASN A CB +808 C CG . ASN A 101 0.8299 0.3496 0.3703 0.0948 0.0414 0.0560 ? ? ? ? ? ? 1956 ASN A CG +809 O OD1 . ASN A 101 0.8855 0.3989 0.3860 0.1126 0.0157 0.0641 ? ? ? ? ? ? 1956 ASN A OD1 +810 N ND2 . ASN A 101 0.8093 0.3078 0.3418 0.0827 0.0727 0.0555 ? ? ? ? ? ? 1956 ASN A ND2 +811 N N . MET A 102 0.5470 0.2688 0.2644 0.0023 0.0138 0.0050 ? ? ? ? ? ? 1957 MET A N +812 C CA . MET A 102 0.5273 0.2765 0.2795 0.0003 0.0000 0.0099 ? ? ? ? ? ? 1957 MET A CA +813 C C . MET A 102 0.5890 0.3390 0.3233 0.0050 -0.0262 0.0155 ? ? ? ? ? ? 1957 MET A C +814 O O . MET A 102 0.5523 0.3040 0.2933 0.0031 -0.0288 0.0191 ? ? ? ? ? ? 1957 MET A O +815 C CB . MET A 102 0.4798 0.2734 0.2908 0.0000 -0.0063 0.0075 ? ? ? ? ? ? 1957 MET A CB +816 C CG . MET A 102 0.6127 0.4222 0.4668 -0.0037 0.0165 0.0017 ? ? ? ? ? ? 1957 MET A CG +817 S SD . MET A 102 0.7378 0.5435 0.6050 -0.0199 0.0399 -0.0088 ? ? ? ? ? ? 1957 MET A SD +818 C CE . MET A 102 0.6630 0.5093 0.5480 -0.0285 0.0121 -0.0150 ? ? ? ? ? ? 1957 MET A CE +819 N N . ARG A 103 0.5532 0.3017 0.2736 0.0092 -0.0411 0.0124 ? ? ? ? ? ? 1958 ARG A N +820 C CA . ARG A 103 0.5915 0.3459 0.3073 0.0129 -0.0644 0.0150 ? ? ? ? ? ? 1958 ARG A CA +821 C C . ARG A 103 0.6116 0.3478 0.2906 0.0199 -0.0693 0.0265 ? ? ? ? ? ? 1958 ARG A C +822 O O . ARG A 103 0.6111 0.3510 0.3056 0.0247 -0.0768 0.0352 ? ? ? ? ? ? 1958 ARG A O +823 C CB . ARG A 103 0.5698 0.3285 0.2873 0.0118 -0.0755 0.0030 ? ? ? ? ? ? 1958 ARG A CB +824 C CG . ARG A 103 0.5778 0.3516 0.3121 0.0134 -0.0970 0.0022 ? ? ? ? ? ? 1958 ARG A CG +825 C CD . ARG A 103 0.5623 0.3408 0.2962 0.0079 -0.1080 -0.0171 ? ? ? ? ? ? 1958 ARG A CD +826 N NE . ARG A 103 0.5556 0.3292 0.3215 0.0018 -0.0900 -0.0273 ? ? ? ? ? ? 1958 ARG A NE +827 C CZ . ARG A 103 0.5862 0.3670 0.3949 0.0016 -0.0853 -0.0233 ? ? ? ? ? ? 1958 ARG A CZ +828 N NH1 . ARG A 103 0.5390 0.3340 0.3631 0.0039 -0.0963 -0.0151 ? ? ? ? ? ? 1958 ARG A NH1 +829 N NH2 . ARG A 103 0.5120 0.2812 0.3494 0.0003 -0.0635 -0.0254 ? ? ? ? ? ? 1958 ARG A NH2 +830 N N . LYS A 104 0.6302 0.3448 0.2594 0.0220 -0.0618 0.0287 ? ? ? ? ? ? 1959 LYS A N +831 C CA . LYS A 104 0.6481 0.3436 0.2313 0.0341 -0.0652 0.0496 ? ? ? ? ? ? 1959 LYS A CA +832 C C . LYS A 104 0.6873 0.3628 0.2922 0.0364 -0.0403 0.0657 ? ? ? ? ? ? 1959 LYS A C +833 O O . LYS A 104 0.7014 0.3684 0.3097 0.0491 -0.0444 0.0856 ? ? ? ? ? ? 1959 LYS A O +834 C CB . LYS A 104 0.7007 0.3735 0.2126 0.0337 -0.0543 0.0494 ? ? ? ? ? ? 1959 LYS A CB +835 C CG . LYS A 104 0.8488 0.5102 0.3116 0.0497 -0.0575 0.0780 ? ? ? ? ? ? 1959 LYS A CG +836 C CD . LYS A 104 0.9248 0.6347 0.3935 0.0573 -0.0990 0.0775 ? ? ? ? ? ? 1959 LYS A CD +837 N N . TYR A 105 0.6488 0.3193 0.2783 0.0236 -0.0122 0.0545 ? ? ? ? ? ? 1960 TYR A N +838 C CA . TYR A 105 0.6885 0.3442 0.3491 0.0176 0.0165 0.0576 ? ? ? ? ? ? 1960 TYR A CA +839 C C . TYR A 105 0.6848 0.3589 0.3893 0.0160 0.0049 0.0531 ? ? ? ? ? ? 1960 TYR A C +840 O O . TYR A 105 0.6336 0.2832 0.3486 0.0206 0.0217 0.0647 ? ? ? ? ? ? 1960 TYR A O +841 C CB . TYR A 105 0.5946 0.2630 0.2911 0.0007 0.0400 0.0378 ? ? ? ? ? ? 1960 TYR A CB +842 C CG . TYR A 105 0.7147 0.3684 0.4467 -0.0118 0.0761 0.0324 ? ? ? ? ? ? 1960 TYR A CG +843 C CD1 . TYR A 105 0.7521 0.3543 0.4563 -0.0085 0.1148 0.0494 ? ? ? ? ? ? 1960 TYR A CD1 +844 C CD2 . TYR A 105 0.5998 0.2911 0.3913 -0.0290 0.0745 0.0084 ? ? ? ? ? ? 1960 TYR A CD2 +845 C CE1 . TYR A 105 0.7438 0.3271 0.4918 -0.0235 0.1565 0.0405 ? ? ? ? ? ? 1960 TYR A CE1 +846 C CE2 . TYR A 105 0.5860 0.2680 0.4182 -0.0469 0.1098 -0.0069 ? ? ? ? ? ? 1960 TYR A CE2 +847 C CZ . TYR A 105 0.6454 0.2710 0.4622 -0.0449 0.1533 0.0080 ? ? ? ? ? ? 1960 TYR A CZ +848 O OH . TYR A 105 0.7435 0.3555 0.6120 -0.0661 0.1962 -0.0113 ? ? ? ? ? ? 1960 TYR A OH +849 N N . PHE A 106 0.5825 0.2940 0.3116 0.0102 -0.0181 0.0378 ? ? ? ? ? ? 1961 PHE A N +850 C CA . PHE A 106 0.5650 0.2935 0.3274 0.0062 -0.0252 0.0303 ? ? ? ? ? ? 1961 PHE A CA +851 C C . PHE A 106 0.5854 0.2997 0.3458 0.0224 -0.0348 0.0469 ? ? ? ? ? ? 1961 PHE A C +852 O O . PHE A 106 0.5875 0.2884 0.3746 0.0225 -0.0181 0.0481 ? ? ? ? ? ? 1961 PHE A O +853 C CB . PHE A 106 0.5090 0.2744 0.2855 0.0010 -0.0455 0.0188 ? ? ? ? ? ? 1961 PHE A CB +854 C CG . PHE A 106 0.5280 0.3059 0.3262 -0.0026 -0.0492 0.0122 ? ? ? ? ? ? 1961 PHE A CG +855 C CD1 . PHE A 106 0.5238 0.3091 0.3405 -0.0181 -0.0322 -0.0043 ? ? ? ? ? ? 1961 PHE A CD1 +856 C CD2 . PHE A 106 0.5468 0.3292 0.3498 0.0061 -0.0654 0.0173 ? ? ? ? ? ? 1961 PHE A CD2 +857 C CE1 . PHE A 106 0.5019 0.2942 0.3322 -0.0241 -0.0284 -0.0146 ? ? ? ? ? ? 1961 PHE A CE1 +858 C CE2 . PHE A 106 0.5402 0.3303 0.3663 0.0018 -0.0606 0.0100 ? ? ? ? ? ? 1961 PHE A CE2 +859 C CZ . PHE A 106 0.4832 0.2755 0.3182 -0.0128 -0.0408 -0.0052 ? ? ? ? ? ? 1961 PHE A CZ +860 N N . GLU A 107 0.6308 0.3621 0.2885 0.0459 0.0259 0.0233 ? ? ? ? ? ? 1962 GLU A N +861 C CA . GLU A 107 0.6750 0.4314 0.3239 0.0624 -0.0334 0.0085 ? ? ? ? ? ? 1962 GLU A CA +862 C C . GLU A 107 0.7379 0.4337 0.3291 0.0886 -0.0551 0.0185 ? ? ? ? ? ? 1962 GLU A C +863 O O . GLU A 107 0.6771 0.4122 0.3023 0.1097 -0.0960 0.0118 ? ? ? ? ? ? 1962 GLU A O +864 C CB . GLU A 107 0.7188 0.4540 0.3153 0.0495 -0.0596 -0.0018 ? ? ? ? ? ? 1962 GLU A CB +865 C CG . GLU A 107 0.6809 0.4838 0.3519 0.0234 -0.0513 -0.0105 ? ? ? ? ? ? 1962 GLU A CG +866 C CD . GLU A 107 0.6981 0.6326 0.4920 0.0238 -0.0736 -0.0132 ? ? ? ? ? ? 1962 GLU A CD +867 O OE1 . GLU A 107 0.6091 0.5814 0.4258 0.0483 -0.1007 -0.0151 ? ? ? ? ? ? 1962 GLU A OE1 +868 O OE2 . GLU A 107 0.5176 0.5195 0.3870 0.0009 -0.0619 -0.0120 ? ? ? ? ? ? 1962 GLU A OE2 +869 N N . LYS A 108 0.7637 0.3681 0.2755 0.0890 -0.0262 0.0387 ? ? ? ? ? ? 1963 LYS A N +870 C CA . LYS A 108 0.8576 0.4050 0.3225 0.1110 -0.0475 0.0562 ? ? ? ? ? ? 1963 LYS A CA +871 C C . LYS A 108 0.8072 0.3802 0.3489 0.1231 -0.0448 0.0589 ? ? ? ? ? ? 1963 LYS A C +872 O O . LYS A 108 0.8247 0.3966 0.3806 0.1477 -0.0827 0.0566 ? ? ? ? ? ? 1963 LYS A O +873 C CB . LYS A 108 0.8793 0.3647 0.2872 0.1003 -0.0129 0.0707 ? ? ? ? ? ? 1963 LYS A CB +874 C CG . LYS A 108 1.0339 0.4843 0.4077 0.1140 -0.0424 0.0856 ? ? ? ? ? ? 1963 LYS A CG +875 C CD . LYS A 108 1.1386 0.5653 0.5087 0.1061 -0.0046 0.1074 ? ? ? ? ? ? 1963 LYS A CD +876 C CE . LYS A 108 1.2177 0.6085 0.5398 0.1146 -0.0333 0.1280 ? ? ? ? ? ? 1963 LYS A CE +877 N NZ . LYS A 108 1.1147 0.5149 0.4693 0.1335 -0.0849 0.1300 ? ? ? ? ? ? 1963 LYS A NZ +878 N N . LYS A 109 0.7345 0.3249 0.3241 0.1054 -0.0020 0.0649 ? ? ? ? ? ? 1964 LYS A N +879 C CA . LYS A 109 0.7366 0.3481 0.3932 0.1098 -0.0029 0.0626 ? ? ? ? ? ? 1964 LYS A CA +880 C C . LYS A 109 0.6631 0.3560 0.3838 0.1276 -0.0372 0.0276 ? ? ? ? ? ? 1964 LYS A C +881 O O . LYS A 109 0.6881 0.3753 0.4324 0.1508 -0.0595 0.0165 ? ? ? ? ? ? 1964 LYS A O +882 C CB . LYS A 109 0.7077 0.3419 0.4127 0.0798 0.0426 0.0765 ? ? ? ? ? ? 1964 LYS A CB +883 C CG . LYS A 109 0.8109 0.4535 0.5288 0.0552 0.0724 0.0930 ? ? ? ? ? ? 1964 LYS A CG +884 C CD . LYS A 109 0.9384 0.5568 0.6646 0.0563 0.0582 0.1092 ? ? ? ? ? ? 1964 LYS A CD +885 C CE . LYS A 109 0.9305 0.5681 0.6782 0.0378 0.0791 0.1298 ? ? ? ? ? ? 1964 LYS A CE +886 N N . TRP A 110 0.6067 0.3747 0.3576 0.1180 -0.0401 0.0118 ? ? ? ? ? ? 1965 TRP A N +887 C CA . TRP A 110 0.5672 0.4306 0.3863 0.1342 -0.0668 -0.0144 ? ? ? ? ? ? 1965 TRP A CA +888 C C . TRP A 110 0.6376 0.4849 0.4406 0.1710 -0.1118 -0.0185 ? ? ? ? ? ? 1965 TRP A C +889 O O . TRP A 110 0.5958 0.4730 0.4432 0.2002 -0.1264 -0.0350 ? ? ? ? ? ? 1965 TRP A O +890 C CB . TRP A 110 0.5090 0.4529 0.3647 0.1124 -0.0655 -0.0193 ? ? ? ? ? ? 1965 TRP A CB +891 C CG . TRP A 110 0.4299 0.4932 0.3713 0.1227 -0.0812 -0.0377 ? ? ? ? ? ? 1965 TRP A CG +892 C CD1 . TRP A 110 0.4626 0.5917 0.4352 0.1381 -0.1179 -0.0416 ? ? ? ? ? ? 1965 TRP A CD1 +893 C CD2 . TRP A 110 0.3311 0.4671 0.3365 0.1183 -0.0603 -0.0504 ? ? ? ? ? ? 1965 TRP A CD2 +894 N NE1 . TRP A 110 0.3967 0.6381 0.4519 0.1457 -0.1142 -0.0540 ? ? ? ? ? ? 1965 TRP A NE1 +895 C CE2 . TRP A 110 0.2699 0.5174 0.3399 0.1351 -0.0800 -0.0630 ? ? ? ? ? ? 1965 TRP A CE2 +896 C CE3 . TRP A 110 0.2616 0.3817 0.2745 0.0992 -0.0287 -0.0488 ? ? ? ? ? ? 1965 TRP A CE3 +897 C CZ2 . TRP A 110 0.2137 0.5192 0.3242 0.1221 -0.0570 -0.0726 ? ? ? ? ? ? 1965 TRP A CZ2 +898 C CZ3 . TRP A 110 0.2713 0.4802 0.3421 0.0956 -0.0201 -0.0650 ? ? ? ? ? ? 1965 TRP A CZ3 +899 C CH2 . TRP A 110 0.1983 0.4980 0.3112 0.1087 -0.0338 -0.0781 ? ? ? ? ? ? 1965 TRP A CH2 +900 N N . THR A 111 0.6141 0.4106 0.3506 0.1700 -0.1335 -0.0024 ? ? ? ? ? ? 1966 THR A N +901 C CA . THR A 111 0.7745 0.5557 0.4969 0.2002 -0.1809 0.0040 ? ? ? ? ? ? 1966 THR A CA +902 C C . THR A 111 0.7963 0.5077 0.5076 0.2262 -0.1854 0.0125 ? ? ? ? ? ? 1966 THR A C +903 O O . THR A 111 0.8314 0.5646 0.5891 0.2604 -0.2120 0.0047 ? ? ? ? ? ? 1966 THR A O +904 C CB . THR A 111 0.8654 0.5951 0.5009 0.1857 -0.2059 0.0229 ? ? ? ? ? ? 1966 THR A CB +905 O OG1 . THR A 111 0.9338 0.7260 0.5887 0.1634 -0.2144 0.0128 ? ? ? ? ? ? 1966 THR A OG1 +906 C CG2 . THR A 111 0.9783 0.6988 0.6144 0.2047 -0.2481 0.0362 ? ? ? ? ? ? 1966 THR A CG2 +907 N N . ASP A 112 0.8599 0.5261 0.4400 0.2514 0.0300 -0.0040 ? ? ? ? ? ? 1967 ASP A N +908 C CA . ASP A 112 0.9086 0.5111 0.4771 0.2866 0.0345 0.0318 ? ? ? ? ? ? 1967 ASP A CA +909 C C . ASP A 112 0.8628 0.4610 0.5001 0.2906 0.0369 0.0277 ? ? ? ? ? ? 1967 ASP A C +910 O O . ASP A 112 0.9063 0.4738 0.5450 0.3262 0.0298 0.0473 ? ? ? ? ? ? 1967 ASP A O +911 C CB . ASP A 112 0.9629 0.4778 0.4889 0.2765 0.0715 0.0643 ? ? ? ? ? ? 1967 ASP A CB +912 C CG . ASP A 112 1.0945 0.5950 0.5351 0.2767 0.0733 0.0728 ? ? ? ? ? ? 1967 ASP A CG +913 O OD1 . ASP A 112 1.0520 0.6041 0.4594 0.2898 0.0390 0.0611 ? ? ? ? ? ? 1967 ASP A OD1 +914 O OD2 . ASP A 112 1.0768 0.5131 0.4834 0.2611 0.1101 0.0912 ? ? ? ? ? ? 1967 ASP A OD2 +915 N N . THR A 113 0.7881 0.4116 0.4783 0.2510 0.0470 0.0026 ? ? ? ? ? ? 1968 THR A N +916 C CA . THR A 113 0.7523 0.3614 0.4972 0.2435 0.0533 -0.0016 ? ? ? ? ? ? 1968 THR A CA +917 C C . THR A 113 0.7321 0.4150 0.5166 0.2569 0.0290 -0.0364 ? ? ? ? ? ? 1968 THR A C +918 O O . THR A 113 0.8527 0.5188 0.6642 0.2772 0.0298 -0.0353 ? ? ? ? ? ? 1968 THR A O +919 C CB . THR A 113 0.7564 0.3480 0.5379 0.1882 0.0740 -0.0069 ? ? ? ? ? ? 1968 THR A CB +920 O OG1 . THR A 113 0.7213 0.2767 0.4928 0.1671 0.0942 0.0252 ? ? ? ? ? ? 1968 THR A OG1 +921 C CG2 . THR A 113 0.6879 0.2779 0.5231 0.1644 0.0753 -0.0096 ? ? ? ? ? ? 1968 THR A CG2 +922 N N . PHE A 114 0.8377 0.6014 0.6268 0.2459 0.0096 -0.0682 ? ? ? ? ? ? 1969 PHE A N +923 C CA . PHE A 114 0.8504 0.6915 0.6875 0.2521 -0.0093 -0.1052 ? ? ? ? ? ? 1969 PHE A CA +924 C C . PHE A 114 0.9949 0.9019 0.8218 0.2921 -0.0423 -0.1117 ? ? ? ? ? ? 1969 PHE A C +925 O O . PHE A 114 1.0997 1.0486 0.9703 0.3222 -0.0567 -0.1259 ? ? ? ? ? ? 1969 PHE A O +926 C CB . PHE A 114 0.7676 0.6575 0.6352 0.1956 -0.0062 -0.1422 ? ? ? ? ? ? 1969 PHE A CB +927 C CG . PHE A 114 0.6713 0.5018 0.5569 0.1514 0.0187 -0.1346 ? ? ? ? ? ? 1969 PHE A CG +928 C CD1 . PHE A 114 0.7263 0.5269 0.6430 0.1485 0.0302 -0.1373 ? ? ? ? ? ? 1969 PHE A CD1 +929 C CD2 . PHE A 114 0.6371 0.4390 0.5103 0.1115 0.0299 -0.1237 ? ? ? ? ? ? 1969 PHE A CD2 +930 C CE1 . PHE A 114 0.6797 0.4232 0.6082 0.1024 0.0483 -0.1265 ? ? ? ? ? ? 1969 PHE A CE1 +931 C CE2 . PHE A 114 0.6139 0.3633 0.5112 0.0694 0.0469 -0.1117 ? ? ? ? ? ? 1969 PHE A CE2 +932 C CZ . PHE A 114 0.6327 0.3528 0.5544 0.0627 0.0540 -0.1117 ? ? ? ? ? ? 1969 PHE A CZ +933 N N . LYS A 115 1.0908 1.0054 0.8625 0.2910 -0.0540 -0.1009 ? ? ? ? ? ? 1970 LYS A N +934 C CA . LYS A 115 1.1633 1.1367 0.9175 0.3230 -0.0907 -0.1015 ? ? ? ? ? ? 1970 LYS A CA +935 C C . LYS A 115 1.2127 1.1336 0.9346 0.3736 -0.1031 -0.0597 ? ? ? ? ? ? 1970 LYS A C +936 O O . LYS A 115 1.2202 1.1268 0.9847 0.4077 -0.1050 -0.0523 ? ? ? ? ? ? 1970 LYS A O +937 C CB . LYS A 115 1.1242 1.1240 0.8221 0.2942 -0.0995 -0.1088 ? ? ? ? ? ? 1970 LYS A CB +# +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 SER 1 1856 1856 SER SER A . n +A 1 2 MET 2 1857 1857 MET MET A . n +A 1 3 SER 3 1858 1858 SER SER A . n +A 1 4 VAL 4 1859 1859 VAL VAL A . n +A 1 5 LYS 5 1860 1860 LYS LYS A . n +A 1 6 LYS 6 1861 1861 LYS LYS A . n +A 1 7 PRO 7 1862 1862 PRO PRO A . n +A 1 8 LYS 8 1863 1863 LYS LYS A . n +A 1 9 ARG 9 1864 1864 ARG ARG A . n +A 1 10 ASP 10 1865 1865 ASP ASP A . n +A 1 11 ASP 11 1866 1866 ASP ASP A . n +A 1 12 SER 12 1867 1867 SER SER A . n +A 1 13 LYS 13 1868 1868 LYS LYS A . n +A 1 14 ASP 14 1869 1869 ASP ASP A . n +A 1 15 LEU 15 1870 1870 LEU LEU A . n +A 1 16 ALA 16 1871 1871 ALA ALA A . n +A 1 17 LEU 17 1872 1872 LEU LEU A . n +A 1 18 CYS 18 1873 1873 CYS CYS A . n +A 1 19 SER 19 1874 1874 SER SER A . n +A 1 20 MET 20 1875 1875 MET MET A . n +A 1 21 ILE 21 1876 1876 ILE ILE A . n +A 1 22 LEU 22 1877 1877 LEU LEU A . n +A 1 23 THR 23 1878 1878 THR THR A . n +A 1 24 GLU 24 1879 1879 GLU GLU A . n +A 1 25 MET 25 1880 1880 MET MET A . n +A 1 26 GLU 26 1881 1881 GLU GLU A . n +A 1 27 THR 27 1882 1882 THR THR A . n +A 1 28 HIS 28 1883 1883 HIS HIS A . n +A 1 29 GLU 29 1884 1884 GLU GLU A . n +A 1 30 ASP 30 1885 1885 ASP ASP A . n +A 1 31 ALA 31 1886 1886 ALA ALA A . n +A 1 32 TRP 32 1887 1887 TRP TRP A . n +A 1 33 PRO 33 1888 1888 PRO PRO A . n +A 1 34 PHE 34 1889 1889 PHE PHE A . n +A 1 35 LEU 35 1890 1890 LEU LEU A . n +A 1 36 LEU 36 1891 1891 LEU LEU A . n +A 1 37 PRO 37 1892 1892 PRO PRO A . n +A 1 38 VAL 38 1893 1893 VAL VAL A . n +A 1 39 ASN 39 1894 1894 ASN ASN A . n +A 1 40 LEU 40 1895 1895 LEU LEU A . n +A 1 41 LYS 41 1896 1896 LYS LYS A . n +A 1 42 LEU 42 1897 1897 LEU LEU A . n +A 1 43 VAL 43 1898 1898 VAL VAL A . n +A 1 44 PRO 44 1899 1899 PRO PRO A . n +A 1 45 GLY 45 1900 1900 GLY GLY A . n +A 1 46 TYR 46 1901 1901 TYR TYR A . n +A 1 47 LYS 47 1902 1902 LYS LYS A . n +A 1 48 LYS 48 1903 1903 LYS LYS A . n +A 1 49 VAL 49 1904 1904 VAL VAL A . n +A 1 50 ILE 50 1905 1905 ILE ILE A . n +A 1 51 LYS 51 1906 1906 LYS LYS A . n +A 1 52 LYS 52 1907 1907 LYS LYS A . n +A 1 53 PRO 53 1908 1908 PRO PRO A . n +A 1 54 MET 54 1909 1909 MET MET A . n +A 1 55 ASP 55 1910 1910 ASP ASP A . n +A 1 56 PHE 56 1911 1911 PHE PHE A . n +A 1 57 SER 57 1912 1912 SER SER A . n +A 1 58 THR 58 1913 1913 THR THR A . n +A 1 59 ILE 59 1914 1914 ILE ILE A . n +A 1 60 ARG 60 1915 1915 ARG ARG A . n +A 1 61 GLU 61 1916 1916 GLU GLU A . n +A 1 62 LYS 62 1917 1917 LYS LYS A . n +A 1 63 LEU 63 1918 1918 LEU LEU A . n +A 1 64 SER 64 1919 1919 SER SER A . n +A 1 65 SER 65 1920 1920 SER SER A . n +A 1 66 GLY 66 1921 1921 GLY GLY A . n +A 1 67 GLN 67 1922 1922 GLN GLN A . n +A 1 68 TYR 68 1923 1923 TYR TYR A . n +A 1 69 PRO 69 1924 1924 PRO PRO A . n +A 1 70 ASN 70 1925 1925 ASN ASN A . n +A 1 71 LEU 71 1926 1926 LEU LEU A . n +A 1 72 GLU 72 1927 1927 GLU GLU A . n +A 1 73 THR 73 1928 1928 THR THR A . n +A 1 74 PHE 74 1929 1929 PHE PHE A . n +A 1 75 ALA 75 1930 1930 ALA ALA A . n +A 1 76 LEU 76 1931 1931 LEU LEU A . n +A 1 77 ASP 77 1932 1932 ASP ASP A . n +A 1 78 VAL 78 1933 1933 VAL VAL A . n +A 1 79 ARG 79 1934 1934 ARG ARG A . n +A 1 80 LEU 80 1935 1935 LEU LEU A . n +A 1 81 VAL 81 1936 1936 VAL VAL A . n +A 1 82 PHE 82 1937 1937 PHE PHE A . n +A 1 83 ASP 83 1938 1938 ASP ASP A . n +A 1 84 ASN 84 1939 1939 ASN ASN A . n +A 1 85 CYS 85 1940 1940 CYS CYS A . n +A 1 86 GLU 86 1941 1941 GLU GLU A . n +A 1 87 THR 87 1942 1942 THR THR A . n +A 1 88 PHE 88 1943 1943 PHE PHE A . n +A 1 89 ASN 89 1944 1944 ASN ASN A . n +A 1 90 GLU 90 1945 1945 GLU GLU A . n +A 1 91 ASP 91 1946 1946 ASP ASP A . n +A 1 92 ASP 92 1947 1947 ASP ASP A . n +A 1 93 SER 93 1948 1948 SER SER A . n +A 1 94 ASP 94 1949 1949 ASP ASP A . n +A 1 95 ILE 95 1950 1950 ILE ILE A . n +A 1 96 GLY 96 1951 1951 GLY GLY A . n +A 1 97 ARG 97 1952 1952 ARG ARG A . n +A 1 98 ALA 98 1953 1953 ALA ALA A . n +A 1 99 GLY 99 1954 1954 GLY GLY A . n +A 1 100 HIS 100 1955 1955 HIS HIS A . n +A 1 101 ASN 101 1956 1956 ASN ASN A . n +A 1 102 MET 102 1957 1957 MET MET A . n +A 1 103 ARG 103 1958 1958 ARG ARG A . n +A 1 104 LYS 104 1959 1959 LYS LYS A . n +A 1 105 TYR 105 1960 1960 TYR TYR A . n +A 1 106 PHE 106 1961 1961 PHE PHE A . n +A 1 107 GLU 107 1962 1962 GLU GLU A . n +A 1 108 LYS 108 1963 1963 LYS LYS A . n +A 1 109 LYS 109 1964 1964 LYS LYS A . n +A 1 110 TRP 110 1965 1965 TRP TRP A . n +A 1 111 THR 111 1966 1966 THR THR A . n +A 1 112 ASP 112 1967 1967 ASP ASP A . n +A 1 113 THR 113 1968 1968 THR THR A . n +A 1 114 PHE 114 1969 1969 PHE PHE A . n +A 1 115 LYS 115 1970 1970 LYS LYS A . n +A 1 116 VAL 116 1971 ? ? ? A . n +A 1 117 SER 117 1972 ? ? ? A . n +# +loop_ +_pdbx_refine_tls.pdbx_refine_id +_pdbx_refine_tls.id +_pdbx_refine_tls.details +_pdbx_refine_tls.method +_pdbx_refine_tls.origin_x +_pdbx_refine_tls.origin_y +_pdbx_refine_tls.origin_z +_pdbx_refine_tls.T[1][1] +_pdbx_refine_tls.T[2][2] +_pdbx_refine_tls.T[3][3] +_pdbx_refine_tls.T[1][2] +_pdbx_refine_tls.T[1][3] +_pdbx_refine_tls.T[2][3] +_pdbx_refine_tls.L[1][1] +_pdbx_refine_tls.L[2][2] +_pdbx_refine_tls.L[3][3] +_pdbx_refine_tls.L[1][2] +_pdbx_refine_tls.L[1][3] +_pdbx_refine_tls.L[2][3] +_pdbx_refine_tls.S[1][1] +_pdbx_refine_tls.S[1][2] +_pdbx_refine_tls.S[1][3] +_pdbx_refine_tls.S[2][1] +_pdbx_refine_tls.S[2][2] +_pdbx_refine_tls.S[2][3] +_pdbx_refine_tls.S[3][1] +_pdbx_refine_tls.S[3][2] +_pdbx_refine_tls.S[3][3] +'X-RAY DIFFRACTION' 1 ? refined 51.7028 17.1821 14.0205 0.5031 0.3420 0.2895 -0.0671 0.0101 0.0176 5.7992 3.5258 6.0477 3.2401 +2.5199 1.0981 -0.1168 -0.2207 -0.2330 -0.5495 0.0610 -0.3682 0.0226 -0.7649 0.0478 +'X-RAY DIFFRACTION' 2 ? refined 42.4520 13.1926 21.0656 0.4230 0.6859 0.6532 0.0898 -0.0825 0.3308 4.0626 3.8144 6.1364 -2.3137 +-4.9969 3.1409 -1.3114 -0.2286 0.6970 0.3171 0.9615 0.6816 -0.3104 -0.3295 0.3944 +'X-RAY DIFFRACTION' 3 ? refined 30.9297 10.9717 20.1215 0.6035 0.4343 0.6338 0.1338 0.1929 0.0564 4.8720 3.6220 8.1344 3.1681 +-1.7368 2.2974 -0.5739 -0.1423 -2.0455 -1.0255 -0.4365 -1.5901 1.2374 1.0387 1.0343 +'X-RAY DIFFRACTION' 4 ? refined 24.9736 15.8473 22.3096 0.5504 0.2498 0.3584 0.0361 -0.0383 -0.0065 7.0249 3.3900 5.0728 -2.8125 +-3.8763 4.1012 -0.1369 0.1165 -0.6617 0.3502 -0.1947 0.0007 -0.1270 0.1826 0.2831 +'X-RAY DIFFRACTION' 5 ? refined 19.8248 18.4657 26.3083 0.5076 0.2863 0.3932 0.0095 -0.0044 0.0375 2.1489 2.1690 2.2850 -0.0077 +-1.3098 1.8074 -0.0188 -0.3145 -1.0586 0.7185 -0.1463 -0.1241 0.3930 -0.1897 0.1294 +'X-RAY DIFFRACTION' 6 ? refined 16.5283 22.0022 29.2251 0.4324 0.2186 0.3336 -0.0452 0.0328 0.0454 2.4656 2.5873 2.0098 -2.1360 +-0.4599 1.4935 -0.4931 0.1661 -0.8137 0.1552 -0.0212 -0.0001 1.0938 -0.2369 0.5633 +'X-RAY DIFFRACTION' 7 ? refined 12.0584 25.3550 35.2106 0.4467 0.3712 0.3756 -0.0106 0.0959 0.0082 4.7862 2.5992 3.6907 3.4538 +4.1960 2.9932 -0.1064 -0.4934 -0.2901 1.7150 -0.4447 1.3036 0.9397 -0.7725 0.5716 +'X-RAY DIFFRACTION' 8 ? refined 12.2558 32.3038 28.3473 0.4360 0.2224 0.2301 0.0152 -0.0008 -0.0103 5.3004 2.4000 4.3745 0.1590 +-1.0980 -3.1474 -0.2325 -0.1494 0.1781 0.1259 0.1722 0.4258 0.3504 -0.1263 0.1180 +'X-RAY DIFFRACTION' 9 ? refined 11.5957 42.8738 20.2128 0.6552 0.2868 0.5332 0.0442 -0.1285 0.0101 6.0673 3.4729 3.8865 0.1395 +-4.5955 1.0862 0.7227 0.6985 0.2798 -1.2197 -0.3470 1.8211 -0.5498 -0.5622 -0.3211 +'X-RAY DIFFRACTION' 10 ? refined 16.3571 46.5450 23.5539 0.6036 0.2413 0.3569 0.0195 -0.0108 -0.0286 6.9735 5.2432 2.7354 3.1230 +-1.1141 0.6592 -0.1130 0.1813 0.2376 -0.4285 0.0510 0.6625 -0.2049 0.0641 0.0605 +'X-RAY DIFFRACTION' 11 ? refined 23.6802 41.1211 21.8391 0.5657 0.2720 0.3311 0.0137 0.0586 -0.0140 4.1251 4.0476 5.3170 -4.0621 +-4.6203 4.6329 0.5135 0.3499 0.8601 -1.4383 0.0666 -1.1686 0.0655 0.8293 -0.6056 +'X-RAY DIFFRACTION' 12 ? refined 18.4353 27.5606 20.0883 0.3986 0.2077 0.1894 0.0090 -0.0497 0.0046 6.0865 7.5463 9.7191 -1.8657 +-3.0431 -0.7044 0.1115 0.5094 -0.0441 -0.4900 -0.0858 0.0693 -0.3356 -0.2682 -0.0162 +'X-RAY DIFFRACTION' 13 ? refined 24.4900 23.9184 14.6960 0.6220 0.3324 0.2481 0.0078 -0.0132 -0.0121 5.1692 4.8504 2.0828 0.9603 +1.6702 -0.5802 -0.0147 -0.0525 -0.0270 -0.8332 -0.1793 0.0751 0.1942 0.3749 0.1700 +'X-RAY DIFFRACTION' 14 ? refined 31.2758 23.4917 21.2425 0.4733 0.4321 0.3634 0.0615 -0.0186 -0.0631 2.8833 3.2327 3.2546 -1.1102 +1.3483 2.1959 -0.4924 -0.2820 -0.2985 1.0556 1.4267 -1.0819 0.1691 0.9400 -0.9175 +'X-RAY DIFFRACTION' 15 ? refined 26.8945 27.5460 23.7543 0.4822 0.2508 0.1870 -0.0216 0.0094 -0.0124 8.0179 7.1898 8.3202 -5.8089 +-6.6000 3.1255 -0.1503 0.0185 0.1006 -0.5472 -0.0187 -0.1842 -0.5116 0.1461 0.1819 +'X-RAY DIFFRACTION' 16 ? refined 22.7495 36.5039 30.4054 0.4434 0.2548 0.2240 -0.0050 -0.0107 0.0143 2.6955 9.8561 3.7702 -3.5102 +-2.0328 4.8267 0.1136 -0.0208 0.1876 0.2430 -0.0417 -0.2487 -0.0826 0.1457 -0.0535 +'X-RAY DIFFRACTION' 17 ? refined 17.2344 37.4881 39.5019 0.6457 0.2743 0.2348 0.0444 -0.0230 -0.0001 5.3185 6.4588 5.7668 1.0649 +-2.5329 1.0621 -0.1798 -0.3139 0.0723 1.0978 0.2017 0.2587 -0.1173 0.2469 -0.1121 +'X-RAY DIFFRACTION' 18 ? refined 22.2045 26.2103 34.8182 0.5133 0.2435 0.2278 0.0105 -0.0345 0.0298 9.3593 8.2893 4.5231 0.5053 +-4.8951 1.0187 -0.2980 -0.3294 -0.3719 0.9189 0.0026 0.2408 0.3713 0.0019 0.3063 +'X-RAY DIFFRACTION' 19 ? refined 27.2243 20.7729 33.5863 0.5648 0.3303 0.2710 0.1217 -0.0692 0.0099 7.3775 6.7995 4.6886 0.9350 +1.6224 -4.7865 0.1544 -0.1645 -0.6502 1.8910 0.2371 -0.4276 0.7722 1.0419 -0.1655 +'X-RAY DIFFRACTION' 20 ? refined 29.3472 15.6284 31.7260 0.7479 0.4722 0.4878 0.2564 0.0149 -0.0419 2.6405 5.7804 2.6468 3.8115 +0.0362 -0.6806 -0.3472 -0.9397 -0.9159 1.2543 0.7286 -0.3107 0.8458 1.6357 -0.4624 +# +loop_ +_pdbx_refine_tls_group.pdbx_refine_id +_pdbx_refine_tls_group.id +_pdbx_refine_tls_group.refine_tls_id +_pdbx_refine_tls_group.beg_auth_asym_id +_pdbx_refine_tls_group.beg_auth_seq_id +_pdbx_refine_tls_group.beg_label_asym_id +_pdbx_refine_tls_group.beg_label_seq_id +_pdbx_refine_tls_group.end_auth_asym_id +_pdbx_refine_tls_group.end_auth_seq_id +_pdbx_refine_tls_group.end_label_asym_id +_pdbx_refine_tls_group.end_label_seq_id +_pdbx_refine_tls_group.selection +_pdbx_refine_tls_group.selection_details +'X-RAY DIFFRACTION' 1 1 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1856:1859)' +'X-RAY DIFFRACTION' 2 2 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1860:1864)' +'X-RAY DIFFRACTION' 3 3 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1865:1868)' +'X-RAY DIFFRACTION' 4 4 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1869:1873)' +'X-RAY DIFFRACTION' 5 5 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1874:1877)' +'X-RAY DIFFRACTION' 6 6 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1878:1881)' +'X-RAY DIFFRACTION' 7 7 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1882:1885)' +'X-RAY DIFFRACTION' 8 8 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1886:1892)' +'X-RAY DIFFRACTION' 9 9 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1893:1896)' +'X-RAY DIFFRACTION' 10 10 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1897:1904)' +'X-RAY DIFFRACTION' 11 11 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1905:1908)' +'X-RAY DIFFRACTION' 12 12 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1909:1918)' +'X-RAY DIFFRACTION' 13 13 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1919:1924)' +'X-RAY DIFFRACTION' 14 14 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1925:1928)' +'X-RAY DIFFRACTION' 15 15 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1929:1932)' +'X-RAY DIFFRACTION' 16 16 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1933:1944)' +'X-RAY DIFFRACTION' 17 17 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1945:1956)' +'X-RAY DIFFRACTION' 18 18 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1957:1961)' +'X-RAY DIFFRACTION' 19 19 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1962:1966)' +'X-RAY DIFFRACTION' 20 20 ? ? ? ? ? ? ? ? ? '(CHAIN A AND RESID 1967:1970)' +# +_software.name PHENIX +_software.classification refinement +_software.version '(PHENIX.REFINE)' +_software.citation_id ? +_software.pdbx_ordinal 1 +# +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 A VAL 1971 ? +2 Y 1 1 A SER 1972 ? +# +loop_ +_pdbx_unobs_or_zero_occ_atoms.id +_pdbx_unobs_or_zero_occ_atoms.polymer_flag +_pdbx_unobs_or_zero_occ_atoms.occupancy_flag +_pdbx_unobs_or_zero_occ_atoms.PDB_model_num +_pdbx_unobs_or_zero_occ_atoms.auth_asym_id +_pdbx_unobs_or_zero_occ_atoms.auth_comp_id +_pdbx_unobs_or_zero_occ_atoms.auth_seq_id +_pdbx_unobs_or_zero_occ_atoms.PDB_ins_code +_pdbx_unobs_or_zero_occ_atoms.auth_atom_id +_pdbx_unobs_or_zero_occ_atoms.label_alt_id +1 Y 1 1 A LYS 1863 ? CG ? +2 Y 1 1 A LYS 1863 ? CD ? +3 Y 1 1 A LYS 1863 ? CE ? +4 Y 1 1 A LYS 1863 ? NZ ? +5 Y 1 1 A LYS 1868 ? CE ? +6 Y 1 1 A LYS 1868 ? NZ ? +7 Y 1 1 A GLU 1927 ? CD ? +8 Y 1 1 A GLU 1927 ? OE1 ? +9 Y 1 1 A GLU 1927 ? OE2 ? +10 Y 1 1 A LYS 1959 ? CE ? +11 Y 1 1 A LYS 1959 ? NZ ? +12 Y 1 1 A LYS 1964 ? NZ ? +13 Y 1 1 A LYS 1970 ? CG ? +14 Y 1 1 A LYS 1970 ? CD ? +15 Y 1 1 A LYS 1970 ? CE ? +16 Y 1 1 A LYS 1970 ? NZ ? +# +_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 dimeric +_pdbx_struct_assembly.oligomeric_count 2 +# +_pdbx_struct_assembly_gen.assembly_id 1 +_pdbx_struct_assembly_gen.oper_expression 1,2 +_pdbx_struct_assembly_gen.asym_id_list A,B,C,D,E,F +# +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)' 2050 ? +1 'SSA (A^2)' 14260 ? +1 MORE -16.8 ? +# +loop_ +_pdbx_struct_oper_list.id +_pdbx_struct_oper_list.type +_pdbx_struct_oper_list.name +_pdbx_struct_oper_list.symmetry_operation +_pdbx_struct_oper_list.matrix[1][1] +_pdbx_struct_oper_list.matrix[1][2] +_pdbx_struct_oper_list.matrix[1][3] +_pdbx_struct_oper_list.vector[1] +_pdbx_struct_oper_list.matrix[2][1] +_pdbx_struct_oper_list.matrix[2][2] +_pdbx_struct_oper_list.matrix[2][3] +_pdbx_struct_oper_list.vector[2] +_pdbx_struct_oper_list.matrix[3][1] +_pdbx_struct_oper_list.matrix[3][2] +_pdbx_struct_oper_list.matrix[3][3] +_pdbx_struct_oper_list.vector[3] +1 'identity operation' 1_555 x,y,z 1.0000000000 0.0000000000 0.0000000000 0.0000000000 0.0000000000 1.0000000000 +0.0000000000 0.0000000000 0.0000000000 0.0000000000 1.0000000000 0.0000000000 +2 'crystal symmetry operation' 3_655 -x+1,y,-z+1/2 -1.0000000000 0.0000000000 0.0000000000 80.3700000000 0.0000000000 1.0000000000 +0.0000000000 0.0000000000 0.0000000000 0.0000000000 -1.0000000000 28.8350000000 +# +_pdbx_version.entry_id 4CUP +_pdbx_version.revision_date 2014-04-02 +_pdbx_version.major_version 4 +_pdbx_version.minor_version 0000 +_pdbx_version.revision_type 'Initial release' +_pdbx_version.details 'Entry released' +# +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 +B 2 ZYB 1 2971 2971 ZYB ZYB A . +C 3 MOH 1 2972 2972 MOH MOH A . +D 3 MOH 1 2973 2973 MOH MOH A . +E 3 MOH 1 2974 2974 MOH MOH A . +F 4 HOH 1 2001 2001 HOH HOH A . +F 4 HOH 2 2002 2002 HOH HOH A . +F 4 HOH 3 2003 2003 HOH HOH A . +F 4 HOH 4 2004 2004 HOH HOH A . +F 4 HOH 5 2005 2005 HOH HOH A . +F 4 HOH 6 2006 2006 HOH HOH A . +F 4 HOH 7 2007 2007 HOH HOH A . +F 4 HOH 8 2008 2008 HOH HOH A . +F 4 HOH 9 2009 2009 HOH HOH A . +F 4 HOH 10 2010 2010 HOH HOH A . +F 4 HOH 11 2011 2011 HOH HOH A . +F 4 HOH 12 2012 2012 HOH HOH A . +F 4 HOH 13 2013 2013 HOH HOH A . +F 4 HOH 14 2014 2014 HOH HOH A . +F 4 HOH 15 2015 2015 HOH HOH A . +F 4 HOH 16 2016 2016 HOH HOH A . +F 4 HOH 17 2017 2017 HOH HOH A . +F 4 HOH 18 2018 2018 HOH HOH A . +F 4 HOH 19 2019 2019 HOH HOH A . +F 4 HOH 20 2020 2020 HOH HOH A . +F 4 HOH 21 2021 2021 HOH HOH A . +F 4 HOH 22 2022 2022 HOH HOH A . +F 4 HOH 23 2023 2023 HOH HOH A . +F 4 HOH 24 2024 2024 HOH HOH A . +F 4 HOH 25 2025 2025 HOH HOH A . +F 4 HOH 26 2026 2026 HOH HOH A . +F 4 HOH 27 2027 2027 HOH HOH A . +F 4 HOH 28 2028 2028 HOH HOH A . +F 4 HOH 29 2029 2029 HOH HOH A . +F 4 HOH 30 2030 2030 HOH HOH A . +F 4 HOH 31 2031 2031 HOH HOH A . +F 4 HOH 32 2032 2032 HOH HOH A . +F 4 HOH 33 2033 2033 HOH HOH A . +F 4 HOH 34 2034 2034 HOH HOH A . +F 4 HOH 35 2035 2035 HOH HOH A . +F 4 HOH 36 2036 2036 HOH HOH A . +F 4 HOH 37 2037 2037 HOH HOH A . +F 4 HOH 38 2038 2038 HOH HOH A . +F 4 HOH 39 2039 2039 HOH HOH A . +F 4 HOH 40 2040 2040 HOH HOH A . +F 4 HOH 41 2041 2041 HOH HOH A . +F 4 HOH 42 2042 2042 HOH HOH A . +F 4 HOH 43 2043 2043 HOH HOH A . +F 4 HOH 44 2044 2044 HOH HOH A . +F 4 HOH 45 2045 2045 HOH HOH A . +F 4 HOH 46 2046 2046 HOH HOH A . +F 4 HOH 47 2047 2047 HOH HOH A . +F 4 HOH 48 2048 2048 HOH HOH A . +F 4 HOH 49 2049 2049 HOH HOH A . +F 4 HOH 50 2050 2050 HOH HOH A . +F 4 HOH 51 2051 2051 HOH HOH A . +F 4 HOH 52 2052 2052 HOH HOH A . +F 4 HOH 53 2053 2053 HOH HOH A . +F 4 HOH 54 2054 2054 HOH HOH A . +F 4 HOH 55 2055 2055 HOH HOH A . +F 4 HOH 56 2056 2056 HOH HOH A . +F 4 HOH 57 2057 2057 HOH HOH A . +F 4 HOH 58 2058 2058 HOH HOH A . +F 4 HOH 59 2059 2059 HOH HOH A . +F 4 HOH 60 2060 2060 HOH HOH A . +F 4 HOH 61 2061 2061 HOH HOH A . +F 4 HOH 62 2062 2062 HOH HOH A . +F 4 HOH 63 2063 2063 HOH HOH A . +F 4 HOH 64 2064 2064 HOH HOH A . +F 4 HOH 65 2065 2065 HOH HOH A . +F 4 HOH 66 2066 2066 HOH HOH A . +F 4 HOH 67 2067 2067 HOH HOH A . +F 4 HOH 68 2068 2068 HOH HOH A . +F 4 HOH 69 2069 2069 HOH HOH A . +F 4 HOH 70 2070 2070 HOH HOH A . +F 4 HOH 71 2071 2071 HOH HOH A . +F 4 HOH 72 2072 2072 HOH HOH A . +F 4 HOH 73 2073 2073 HOH HOH A . +F 4 HOH 74 2074 2074 HOH HOH A . +F 4 HOH 75 2075 2075 HOH HOH A . +F 4 HOH 76 2076 2076 HOH HOH A . +F 4 HOH 77 2077 2077 HOH HOH A . +F 4 HOH 78 2078 2078 HOH HOH A . +F 4 HOH 79 2079 2079 HOH HOH A . +F 4 HOH 80 2080 2080 HOH HOH A . +F 4 HOH 81 2081 2081 HOH HOH A . +F 4 HOH 82 2082 2082 HOH HOH A . +F 4 HOH 83 2083 2083 HOH HOH A . +F 4 HOH 84 2084 2084 HOH HOH A . +F 4 HOH 85 2085 2085 HOH HOH A . +F 4 HOH 86 2086 2086 HOH HOH A . +F 4 HOH 87 2087 2087 HOH HOH A . +F 4 HOH 88 2088 2088 HOH HOH A . +F 4 HOH 89 2089 2089 HOH HOH A . +F 4 HOH 90 2090 2090 HOH HOH A . +F 4 HOH 91 2091 2091 HOH HOH A . +F 4 HOH 92 2092 2092 HOH HOH A . +F 4 HOH 93 2093 2093 HOH HOH A . +F 4 HOH 94 2094 2094 HOH HOH A . +F 4 HOH 95 2095 2095 HOH HOH A . +F 4 HOH 96 2096 2096 HOH HOH A . +F 4 HOH 97 2097 2097 HOH HOH A . +F 4 HOH 98 2098 2098 HOH HOH A . +F 4 HOH 99 2099 2099 HOH HOH A . +F 4 HOH 100 2100 2100 HOH HOH A . +F 4 HOH 101 2101 2101 HOH HOH A . +F 4 HOH 102 2102 2102 HOH HOH A . +F 4 HOH 103 2103 2103 HOH HOH A . +F 4 HOH 104 2104 2104 HOH HOH A . +F 4 HOH 105 2105 2105 HOH HOH A . +F 4 HOH 106 2106 2106 HOH HOH A . +F 4 HOH 107 2107 2107 HOH HOH A . +F 4 HOH 108 2108 2108 HOH HOH A . +F 4 HOH 109 2109 2109 HOH HOH A . +F 4 HOH 110 2110 2110 HOH HOH A . +F 4 HOH 111 2111 2111 HOH HOH A . +F 4 HOH 112 2112 2112 HOH HOH A . +F 4 HOH 113 2113 2113 HOH HOH A . +F 4 HOH 114 2114 2114 HOH HOH A . +F 4 HOH 115 2115 2115 HOH HOH A . +F 4 HOH 116 2116 2116 HOH HOH A . +F 4 HOH 117 2117 2117 HOH HOH A . +F 4 HOH 118 2118 2118 HOH HOH A . +F 4 HOH 119 2119 2119 HOH HOH A . +F 4 HOH 120 2120 2120 HOH HOH A . +F 4 HOH 121 2121 2121 HOH HOH A . +F 4 HOH 122 2122 2122 HOH HOH A . +F 4 HOH 123 2123 2123 HOH HOH A . +F 4 HOH 124 2124 2124 HOH HOH A . +F 4 HOH 125 2125 2125 HOH HOH A . +F 4 HOH 126 2126 2126 HOH HOH A . +F 4 HOH 127 2127 2127 HOH HOH A . +F 4 HOH 128 2128 2128 HOH HOH A . +F 4 HOH 129 2129 2129 HOH HOH A . +F 4 HOH 130 2130 2130 HOH HOH A . +F 4 HOH 131 2131 2131 HOH HOH A . +F 4 HOH 132 2132 2132 HOH HOH A . +F 4 HOH 133 2133 2133 HOH HOH A . +F 4 HOH 134 2134 2134 HOH HOH A . +F 4 HOH 135 2135 2135 HOH HOH A . +F 4 HOH 136 2136 2136 HOH HOH A . +F 4 HOH 137 2137 2137 HOH HOH A . +F 4 HOH 138 2138 2138 HOH HOH A . +F 4 HOH 139 2139 2139 HOH HOH A . +F 4 HOH 140 2140 2140 HOH HOH A . +F 4 HOH 141 2141 2141 HOH HOH A . +F 4 HOH 142 2142 2142 HOH HOH A . +F 4 HOH 143 2143 2143 HOH HOH A . +F 4 HOH 144 2144 2144 HOH HOH A . +F 4 HOH 145 2145 2145 HOH HOH A . +F 4 HOH 146 2146 2146 HOH HOH A . +# +loop_ +_pdbx_validate_close_contact.id +_pdbx_validate_close_contact.PDB_model_num +_pdbx_validate_close_contact.auth_atom_id_1 +_pdbx_validate_close_contact.auth_asym_id_1 +_pdbx_validate_close_contact.auth_comp_id_1 +_pdbx_validate_close_contact.auth_seq_id_1 +_pdbx_validate_close_contact.PDB_ins_code_1 +_pdbx_validate_close_contact.label_alt_id_1 +_pdbx_validate_close_contact.auth_atom_id_2 +_pdbx_validate_close_contact.auth_asym_id_2 +_pdbx_validate_close_contact.auth_comp_id_2 +_pdbx_validate_close_contact.auth_seq_id_2 +_pdbx_validate_close_contact.PDB_ins_code_2 +_pdbx_validate_close_contact.label_alt_id_2 +_pdbx_validate_close_contact.dist +1 1 O A HOH 2025 ? ? O A HOH 2026 ? ? 2.16 +2 1 O A HOH 2021 ? ? O A HOH 2025 ? ? 2.17 +3 1 O A HOH 2031 ? ? O A HOH 2137 ? ? 2.18 +# +loop_ +_pdbx_entity_nonpoly.entity_id +_pdbx_entity_nonpoly.name +_pdbx_entity_nonpoly.comp_id +2 4-FLUOROBENZAMIDOXIME ZYB +3 METHANOL MOH +4 water HOH +# From d3fcbc1e66d0dda0363196e5072066c2b400ec14 Mon Sep 17 00:00:00 2001 From: Aleix Lafita Date: Fri, 30 Jun 2017 12:02:28 -0700 Subject: [PATCH 002/769] Remove the warnings in MMTF reader --- .../io/mmtf/MmtfStructureReader.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java index 7eb07e806a..8b74ea3993 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java @@ -304,14 +304,15 @@ public void setAtomInfo(String atomName, * face#setGroupBonds(int, int, int) */ @Override - public void setGroupBond(int indOne, - int indTwo, int bondOrder) { - // Get the atom + public void setGroupBond(int indOne, int indTwo, int bondOrder) { + + // Get the atoms Atom atomOne = atomsInGroup.get(indOne); Atom atomTwo = atomsInGroup.get(indTwo); + // set the new bond - @SuppressWarnings("unused") - BondImpl bond = new BondImpl(atomOne, atomTwo, bondOrder); + new BondImpl(atomOne, atomTwo, bondOrder); + } /* (non-Javadoc) @@ -319,14 +320,14 @@ public void setGroupBond(int indOne, * Interface#setInterGroupBonds(int, int, int) */ @Override - public void setInterGroupBond(int indOne, - int indTwo, int bondOrder) { - // Get the atom + public void setInterGroupBond(int indOne, int indTwo, int bondOrder) { + + // Get the atoms Atom atomOne = allAtoms[indOne]; Atom atomTwo = allAtoms[indTwo]; - // set the new bond - @SuppressWarnings("unused") - BondImpl bond = new BondImpl(atomOne, atomTwo, bondOrder); + + // set the new bond (this + new BondImpl(atomOne, atomTwo, bondOrder); } From c6dddfd9b3c228ea7b8c4f8dfd36b0b09a48384c Mon Sep 17 00:00:00 2001 From: Aleix Lafita Date: Thu, 6 Jul 2017 15:09:13 +0100 Subject: [PATCH 003/769] Fix path bug in mmtf test --- .../nbio/structure/io/mmtf/MmtfUtils.java | 4 ++++ .../io/mmtf/TestMmtfStructureReader.java | 22 ++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index 929a5db4b8..8e14f7d1db 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -479,9 +479,12 @@ public static void insertSeqResGroup(Chain chain, Group group, int sequenceIndex * @param sequence the sequence of the construct */ public static void addSeqRes(Chain modelChain, String sequence) { + List seqResGroups = modelChain.getSeqResGroups(); GroupType chainType = getChainType(modelChain.getAtomGroups()); + for(int i=0; i Date: Tue, 20 Aug 2019 16:22:27 +0200 Subject: [PATCH 004/769] Add CITATION.cff This is a hand-coded CFF file for BioJava 5.2.1 --- CITATION.cff | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 CITATION.cff diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000000..37481303db --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,195 @@ +cff-version: 1.0.3 +message: If you use BioJava, please cite the software and the most recent paper reference (Lafita 2019). +title: BioJava +version: 5.2.1 +date-released: 2019-02-05 +doi: 10.5281/zenodo.2557853 +commit: 783065396f92f14c3fb6e2b9a684a17aa46bb974 +url: http://www.biojava.org +repository-code: https://github.com/biojava/biojava/ +license: LGPL-2.1-only +abstract: >- + BioJava is an open-source project dedicated to providing a Java framework for processing biological + data. It provides analytical and statistical routines, parsers for common file formats and allows the + manipulation of sequences and 3D structures. The goal of the biojava project is to facilitate rapid application + development for bioinformatics. + +authors: + - family-names: Prlić + given-names: Andreas + - family-names: Lafita + given-names: Aleix + - family-names: Al-Hossary + given-names: Amr + - family-names: Dräger + given-names: Andreas + - family-names: Yates + given-names: Andy + - family-names: Bradley + given-names: Anthony + - family-names: Foti + given-names: Carmelo + - family-names: Koh + given-names: Chuan Hock + - family-names: Myers-Turnbull + given-names: Douglas + - family-names: Rimsa + given-names: Gediminas + - family-names: Waldon + given-names: George + - family-names: Brandstätter-Müller + given-names: Hannes + - name: Elinow + - family-names: Gao + given-names: Jianjiong + - family-names: Warren + given-names: Jonathan + - family-names: Duarte + given-names: Jose Manuel + - family-names: Jacobsen + given-names: Jules + - family-names: Nicholas + given-names: Karl + - family-names: Chapman + given-names: Mark + - family-names: Heuer + given-names: Michael + - family-names: Rose + given-names: Peter + - family-names: Troshin + given-names: Peter + - family-names: Holland + given-names: Richard + - family-names: Thornton + given-names: Robert + - family-names: Willis + given-names: Scooter + - family-names: Bliven + given-names: Spencer + - family-names: Foisy + given-names: Sylvain + +references: + - type: article + authors: + - family-names: Lafita + given-names: Aleix + orcid: http://orcid.org/0000-0003-1549-3162 + - family-names: Bliven + given-names: Spencer E + orcid: http://orcid.org/0000-0002-1200-1698 + - family-names: Prlić + given-names: Andreas + orcid: https://orcid.org/0000-0001-6346-6391 + - family-names: Guzenko + given-names: Dmytro + orcid: https://orcid.org/0000-0002-8688-7460 + - family-names: Rose + given-names: Peter W + orcid: http://orcid.org/0000-0001-9981-9750 + - family-names: Bradley + given-names: Anthony + orcid: http://orcid.org/0000-0002-0881-3490 + - family-names: Pavan + given-names: Paolo + - family-names: Myers-Turnbull + given-names: Douglas + orcid: http://orcid.org/0000-0003-3610-4808 + - family-names: Valasatava + given-names: Yana + orcid: http://orcid.org/0000-0003-1018-5718 + - family-names: Heuer + given-names: Michael + orcid: http://orcid.org/0000-0002-9052-6000 + - family-names: Larson + given-names: Matt + orcid: http://orcid.org/0000-0003-2116-5747 + - family-names: Burley + given-names: Stephen K + - family-names: Duarte + given-names: Jose M + orcid: http://orcid.org/0000-0002-9544-5621 + title: "BioJava 5: A community driven open-source bioinformatics library" + year: 2019 + journal: PLOS Computational Biology + volume: 15 + number: "2" + section: e1006791 + doi: 10.1371/journal.pcbi.1006791 + url: http://dx.plos.org/10.1371/journal.pcbi.1006791 + + - type: article + authors: + - family-names: Prlić + given-names: Andreas + - family-names: Yates + given-names: Andrew + - family-names: Bliven + given-names: Spencer E + - family-names: Rose + given-names: Peter W + - family-names: Jacobsen + given-names: Julius + - family-names: Troshin + given-names: Peter V + - family-names: Chapman + given-names: Mark + - family-names: Gao + given-names: Jianjiong + - family-names: Koh + given-names: Chuan Hock + - family-names: Foisy + given-names: Sylvain + - family-names: Holland + given-names: Richard + - family-names: Rimša + given-names: Gediminas + - family-names: Heuer + given-names: Michael L + - family-names: Brandstätter-Müller + given-names: H + - family-names: Bourne + given-names: Philip E + - family-names: Willis + given-names: Scooter + title: "BioJava: an open-source framework for bioinformatics in 2012" + journal: Bioinformatics + year: 2012 + volume: 28 + number: "20" + section: 2693-2695 + doi: 10.1093/bioinformatics/bts494 + + - type: article + authors: + - family-names: Holland + given-names: R C G + - family-names: Down + given-names: T A + - family-names: Pocock + given-names: M + - family-names: Prlić + given-names: A + - family-names: Huen + given-names: D + - family-names: James + given-names: K + - family-names: Foisy + given-names: S + - family-names: Dräger + given-names: A + - family-names: Yates + given-names: A + - family-names: Heuer + given-names: M + - family-names: Schreiber + given-names: M J + title: "BioJava: an open-source framework for bioinformatics" + journal: Bioinformatics + year: 2008 + volume: 24 + number: "18" + section: 2096-2097 + doi: 10.1093/bioinformatics/btn397 + + From 407272c25ca264d4888c04514c51c4fc7518a95d Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Mon, 2 Sep 2019 10:09:15 -0700 Subject: [PATCH 005/769] Switching travis to jdk11 hoping to fix travis not starting issue See https://travis-ci.community/t/install-jdk-sh-failing-for-openjdk9-and-10/3998/19 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6be4786ae3..5c668648ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - oraclejdk8 + - openjdk11 sudo: required cache: directories: From 747633fc870df98914c66ca8726a4ceec3ea760d Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Mon, 2 Sep 2019 15:10:53 -0700 Subject: [PATCH 006/769] Cosmetics --- .../nbio/structure/io/mmtf/MmtfStructureReader.java | 4 ++-- .../org/biojava/nbio/structure/io/mmtf/MmtfUtils.java | 11 +++-------- .../structure/io/mmtf/TestMmtfStructureReader.java | 2 -- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java index 69744a3f19..7c7c24e9ec 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java @@ -229,7 +229,7 @@ public void setGroupInfo(String groupName, int groupNumber, group = new HetatomImpl(); break; } - atomsInGroup = new ArrayList(); + atomsInGroup = new ArrayList<>(); ChemComp chemComp = new ChemComp(); chemComp.setOne_letter_code(String.valueOf(singleLetterCode)); chemComp.setType(chemCompType.toUpperCase()); @@ -243,7 +243,7 @@ public void setGroupInfo(String groupName, int groupNumber, group.setResidueNumber(chain.getName().trim(), groupNumber, insertionCode); } - group.setAtoms(new ArrayList(atomCount)); + group.setAtoms(new ArrayList<>(atomCount)); if (polymerType==1 || polymerType==2) { MmtfUtils.insertSeqResGroup(chain, group, sequenceIndexId); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index 3b61957009..7085944462 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -371,7 +371,7 @@ public static int getSecStructType(Group group) { /** * Get the secondary structure as defined by DSSP. * @param group the input group to be calculated - * @param the integer index of the group type. + * @param dsspIndex integer index of the group type. */ public static void setSecStructType(Group group, int dsspIndex) { SecStrucType secStrucType = getSecStructTypeFromDsspIndex(dsspIndex); @@ -508,9 +508,7 @@ public static void addSeqRes(Chain modelChain, String sequence) { char singleLetterCode = sequence.charAt(i); Group group = null; - if(seqResGroups.size()<=i){ - } - else{ + if (seqResGroups.size() > i) { group=seqResGroups.get(i); } if(group!=null){ @@ -525,10 +523,7 @@ public static void addSeqRes(Chain modelChain, String sequence) { private static GroupType getChainType(List groups) { for(Group group : groups) { - if(group==null){ - continue; - } - else if(group.getType()!=GroupType.HETATM){ + if(group!=null && group.getType()!=GroupType.HETATM){ return group.getType(); } } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java index 3611a56c30..b591b02672 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java @@ -64,8 +64,6 @@ public void compareMmcif() throws IOException, StructureException { assertEquals(mmcif.getPDBHeader().getExperimentalTechniques(), mmtf.getPDBHeader().getExperimentalTechniques()); - - // Compare the SEQRES assertEquals(mmcif.getChainByIndex(0).getSeqResSequence(), mmtf.getChainByIndex(0).getSeqResSequence()); From 18f2b6e6625fae157cb427e603878930013899f9 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Mon, 2 Sep 2019 15:17:39 -0700 Subject: [PATCH 007/769] More cosmetics --- .../main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index 7085944462..fbe880d4e8 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -379,8 +379,6 @@ public static void setSecStructType(Group group, int dsspIndex) { if(secStrucType!=null){ group.setProperty("secstruc", secStrucState); } - else{ - } } From dc5639c4e057db63ab8b79820d4909c1a6ff0557 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Mon, 2 Sep 2019 15:42:22 -0700 Subject: [PATCH 008/769] Fixing potential bug --- .../java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java | 2 +- .../nbio/structure/io/mmtf/TestMmtfStructureReader.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index fbe880d4e8..afbb7bb40e 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -392,7 +392,7 @@ public static SecStrucType getSecStructTypeFromDsspIndex(int dsspIndex) { String dsspType = DsspType.dsspTypeFromInt(dsspIndex).getDsspType(); for(SecStrucType secStrucType : SecStrucType.values()) { - if(dsspType==secStrucType.name) + if(dsspType.equals(secStrucType.name)) { return secStrucType; } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java index b591b02672..43f20c801c 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java @@ -64,12 +64,10 @@ public void compareMmcif() throws IOException, StructureException { assertEquals(mmcif.getPDBHeader().getExperimentalTechniques(), mmtf.getPDBHeader().getExperimentalTechniques()); - // Compare the SEQRES + // Compare the SEQRES, see issue https://github.com/biojava/biojava/issues/671 assertEquals(mmcif.getChainByIndex(0).getSeqResSequence(), mmtf.getChainByIndex(0).getSeqResSequence()); - - } } From 93832066d86bff68fe1cebb4324aa693011f88b4 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Mon, 2 Sep 2019 16:30:01 -0700 Subject: [PATCH 009/769] Fixing #671 --- .../biojava/nbio/structure/io/mmtf/MmtfUtils.java | 12 ++++++++++-- .../nbio/structure/io/mmtf/TestMmtfRoundTrip.java | 1 - .../structure/io/mmtf/TestMmtfStructureReader.java | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index afbb7bb40e..93e7ab0f46 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -50,6 +50,7 @@ import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; +import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; import org.biojava.nbio.structure.io.mmcif.model.ChemComp; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; @@ -513,7 +514,7 @@ public static void addSeqRes(Chain modelChain, String sequence) { continue; } - group = getSeqResGroup(modelChain, singleLetterCode, chainType); + group = getSeqResGroup(singleLetterCode, chainType); addGroupAtId(seqResGroups, group, i); seqResGroups.set(i, group); } @@ -537,7 +538,7 @@ private static void addGroupAtId(List seqResGroups, T group, int sequence } } - private static Group getSeqResGroup(Chain modelChain, char singleLetterCode, GroupType type) { + private static Group getSeqResGroup(char singleLetterCode, GroupType type) { if(type==GroupType.AMINOACID){ AminoAcidImpl a = new AminoAcidImpl(); a.setRecordType(AminoAcid.SEQRESRECORD); @@ -545,6 +546,7 @@ private static Group getSeqResGroup(Chain modelChain, char singleLetterCode, Gro ChemComp chemComp = new ChemComp(); chemComp.setOne_letter_code(""+singleLetterCode); a.setChemComp(chemComp); + chemComp.setPolymerType(PolymerType.peptide); return a; } else if (type==GroupType.NUCLEOTIDE) { @@ -552,6 +554,12 @@ private static Group getSeqResGroup(Chain modelChain, char singleLetterCode, Gro ChemComp chemComp = new ChemComp(); chemComp.setOne_letter_code(""+singleLetterCode); n.setChemComp(chemComp); + // TODO this could be either dna or rna, how to distinguish properly? + if (singleLetterCode == 'U') { + chemComp.setPolymerType(PolymerType.rna); + } else { + chemComp.setPolymerType(PolymerType.dna); + } return n; } else{ diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java index c2124c983b..d9bdb05bc0 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java @@ -94,7 +94,6 @@ public void testRoundTrip() throws IOException, StructureException { * Broad test of atom similarity * @param structOne the first input structure * @param structTwo the second input structure - * @param mmtfParams * @return */ private boolean checkIfAtomsSame(Structure structOne, Structure structTwo) { diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java index 43f20c801c..b0928b3836 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java @@ -44,7 +44,7 @@ public void testRead() throws IOException { /** * Compare structures loaded from MMCIF and MMTF files. */ - @Test @Ignore + @Test public void compareMmcif() throws IOException, StructureException { // Get the MMTF and MMCIF files from the resources folder From ee6a478bbf36bdd1e82015a0500b8eb2d83658d1 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Mon, 2 Sep 2019 16:54:56 -0700 Subject: [PATCH 010/769] New test for #792 --- .../io/mmtf/TestMmtfStructureReader.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java index b0928b3836..ac2d81e8d5 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java @@ -4,11 +4,19 @@ import java.io.IOException; import java.nio.file.Paths; +import java.util.List; + +import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; +import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.io.FileParsingParameters; +import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; +import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import org.junit.Ignore; import org.junit.Test; +import static org.junit.Assert.*; /** * Test the Biojava MMTF reader. @@ -70,4 +78,31 @@ public void compareMmcif() throws IOException, StructureException { } + /** + * Test for issue https://github.com/biojava/biojava/issues/792 + */ + @Test + @Ignore("Issue not fixed yet") + public void checkNonStandardAminoSeqresGroupsPopulated() throws StructureException, IOException { + // 2X3T, see issue https://github.com/biojava/biojava/issues/792 + // Load a structure in mmtf format + AtomCache cache = new AtomCache(); + FileParsingParameters params = new FileParsingParameters(); + cache.setFileParsingParams(params); + cache.setUseMmCif(false); + cache.setUseMmtf(true); + + StructureIO.setAtomCache(cache); + + ChemCompGroupFactory.setChemCompProvider(new DownloadChemCompProvider()); + + Structure structure1 = StructureIO.getStructure("2X3T"); + // chain E is a glycopeptide with unobserved non-standard aminoacids. Because of mmtf limitations (representing seqres sequences as 1-letter strings) the non-standard unobserved residues are read as null + List seqresGroups = structure1.getChain("E").getSeqResGroups(); + for (Group g : seqresGroups) { + assertNotNull("SeqRes group should not be null", g); + } + + } + } From 3d0274b0891ea7c80445f87fb4abcf3936106a15 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Mon, 2 Sep 2019 21:33:38 -0700 Subject: [PATCH 011/769] Better solution --- .../nbio/structure/io/mmtf/MmtfUtils.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index 93e7ab0f46..2a25a270fc 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -50,7 +50,7 @@ import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; +import org.biojava.nbio.structure.io.mmcif.chem.ChemCompTools; import org.biojava.nbio.structure.io.mmcif.model.ChemComp; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; @@ -539,27 +539,27 @@ private static void addGroupAtId(List seqResGroups, T group, int sequence } private static Group getSeqResGroup(char singleLetterCode, GroupType type) { + if(type==GroupType.AMINOACID){ + String threeLetter = ChemCompTools.getAminoThreeLetter(singleLetterCode); + if (threeLetter == null) return null; + ChemComp chemComp = ChemCompGroupFactory.getChemComp(threeLetter); + AminoAcidImpl a = new AminoAcidImpl(); a.setRecordType(AminoAcid.SEQRESRECORD); a.setAminoType(singleLetterCode); - ChemComp chemComp = new ChemComp(); - chemComp.setOne_letter_code(""+singleLetterCode); + a.setPDBName(threeLetter); a.setChemComp(chemComp); - chemComp.setPolymerType(PolymerType.peptide); return a; } else if (type==GroupType.NUCLEOTIDE) { + String twoLetter = ChemCompTools.getDNATwoLetter(singleLetterCode); + if (twoLetter == null) return null; + ChemComp chemComp = ChemCompGroupFactory.getChemComp(twoLetter); + NucleotideImpl n = new NucleotideImpl(); - ChemComp chemComp = new ChemComp(); - chemComp.setOne_letter_code(""+singleLetterCode); + n.setPDBName(twoLetter); n.setChemComp(chemComp); - // TODO this could be either dna or rna, how to distinguish properly? - if (singleLetterCode == 'U') { - chemComp.setPolymerType(PolymerType.rna); - } else { - chemComp.setPolymerType(PolymerType.dna); - } return n; } else{ From 9afde8fc5e19807fb4e787ed57f5865ff8925e58 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 3 Sep 2019 10:19:46 -0700 Subject: [PATCH 012/769] Fixing test and clean up --- .../nbio/structure/io/mmtf/MmtfUtils.java | 1 - .../io/mmtf/TestMmtfPerformance.java | 58 +++---------------- 2 files changed, 8 insertions(+), 51 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index 2a25a270fc..bbd34c9610 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -516,7 +516,6 @@ public static void addSeqRes(Chain modelChain, String sequence) { group = getSeqResGroup(singleLetterCode, chainType); addGroupAtId(seqResGroups, group, i); - seqResGroups.set(i, group); } } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfPerformance.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfPerformance.java index d18f856cd8..e0b576d79a 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfPerformance.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfPerformance.java @@ -44,54 +44,14 @@ public class TestMmtfPerformance { private static final int NUMBER_OF_REPEATS = 10; - // Returns the contents of the file in a byte array. - public static byte[] getBytesFromFile(File file) throws IOException { - // Get the size of the file - long length = file.length(); - - // You cannot create an array using a long type. - // It needs to be an int type. - // Before converting to an int type, check - // to ensure that file is not larger than Integer.MAX_VALUE. - if (length > Integer.MAX_VALUE) { - // File is too large - throw new IOException("File is too large!"); - } - - // Create the byte array to hold the data - byte[] bytes = new byte[(int)length]; - - // Read in the bytes - int offset = 0; - int numRead = 0; - - InputStream is = new FileInputStream(file); - try { - while (offset < bytes.length - && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { - offset += numRead; - } - } finally { - is.close(); - } - - // Ensure all the bytes have been read in - if (offset < bytes.length) { - throw new IOException("Could not completely read file "+file.getName()); - } - return bytes; - } - - static String convertStreamToString(java.io.InputStream is) { + private static String convertStreamToString(java.io.InputStream is) { try ( java.util.Scanner s = new java.util.Scanner(is)){ return s.useDelimiter("\\A").hasNext() ? s.next() : ""; } - } - - public byte[] getByteArrayFromInputStream(InputStream is) throws IOException { + private byte[] getByteArrayFromInputStream(InputStream is) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; @@ -104,7 +64,6 @@ public byte[] getByteArrayFromInputStream(InputStream is) throws IOException { buffer.flush(); return buffer.toByteArray(); - } @Test @@ -128,31 +87,30 @@ public void test3HBX() throws Exception{ byte[] mmtfdata = getByteArrayFromInputStream(new GZIPInputStream((mmtfURL.openStream()))); + // first make sure chemcomp cache is warmed up (chemcomp files are parsed). Like that we count the parsing time without the influence of chemcomp parsing + MmtfActions.readFromInputStream(new ByteArrayInputStream(mmtfdata)); + parser.parsePDBFile(new ByteArrayInputStream(pdbBytes)); + for ( int i =0 ; i< NUMBER_OF_REPEATS ; i++) { long mmtfStart = System.nanoTime(); MmtfActions.readFromInputStream(new ByteArrayInputStream(mmtfdata)); long mmtfEnd = System.nanoTime(); - - long pdbStart = System.nanoTime(); parser.parsePDBFile(new ByteArrayInputStream(pdbBytes)); long pdbEnd = System.nanoTime(); totalTimePDB += (pdbEnd - pdbStart); - totalTimeMMTF += (mmtfEnd-mmtfStart); } - long timePDB = (totalTimePDB/NUMBER_OF_REPEATS); long timeMMTF = (totalTimeMMTF/NUMBER_OF_REPEATS); - - logger.warn("average time to parse mmtf: " + timeMMTF/(1000*1000) + " ms."); - logger.warn("average time to parse PDB : " + timePDB/(1000*1000) + " ms. "); + logger.info("average time to parse mmtf: " + timeMMTF/(1000*1000) + " ms."); + logger.info("average time to parse PDB : " + timePDB/(1000*1000) + " ms. "); assertTrue( "It should not be the case, but it is faster to parse a PDB file ("+timePDB+" ns.) than MMTF ("+( timeMMTF)+" ns.)!",( timePDB) > ( timeMMTF)); From 9e45ff52e7a2a6248d42b11e28c927a91afa65bd Mon Sep 17 00:00:00 2001 From: Michael L Heuer Date: Tue, 3 Sep 2019 13:31:48 -0500 Subject: [PATCH 013/769] Bump guava dependency version to 28.1-jre. --- biojava-genome/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index 19b7f0d791..1a0c7c571c 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -75,7 +75,7 @@ com.google.guava guava compile - 24.0-jre + 28.1-jre junit From 0c29e44a56db341de95e244a5b14a69633c1a6ed Mon Sep 17 00:00:00 2001 From: Michael L Heuer Date: Tue, 3 Sep 2019 13:40:56 -0500 Subject: [PATCH 014/769] Bump Maven plugin versions. --- pom.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index f4f327cb92..d7cf5a19de 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ data. It provides analytical and statistical routines, parsers for common file formats and allows the manipulation of sequences and 3D structures. The goal of the biojava project is to facilitate rapid application development for bioinformatics. - + http://www.biojava.org BioJava @@ -160,11 +160,11 @@ maven-clean-plugin - 3.0.0 + 3.1.0 maven-compiler-plugin - 3.7.0 + 3.8.0 ${jdk.version} ${jdk.version} @@ -176,7 +176,7 @@ maven-jar-plugin - 3.1.0 + 3.1.2 maven-scm-plugin @@ -188,7 +188,7 @@ maven-failsafe-plugin - 2.22.0 + 3.0.0-M3 net.sf @@ -221,7 +221,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.1 + 3.1.0 -Xdoclint:none @@ -239,7 +239,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.1 + 3.2.0 maven-assembly-plugin @@ -308,12 +308,12 @@ org.apache.maven.plugins maven-install-plugin - 2.5.2 + 3.0.0-M1 org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M1 + 3.0.0-M3 org.apache.maven.plugins @@ -324,7 +324,7 @@ org.apache.maven.plugins maven-deploy-plugin - 2.8.2 + 3.0.0-M1 From 4492f2d5fcb90ce5d965181e73f258740b591d97 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 3 Sep 2019 12:16:06 -0700 Subject: [PATCH 015/769] Latest mmtf-java and cif-tools-java --- biojava-structure/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index db9ed8f926..e5eff3836d 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -21,7 +21,7 @@ org.rcsb ciftools-java - 0.4.1 + 0.5.4 org.rcsb diff --git a/pom.xml b/pom.xml index f4f327cb92..1bee577bda 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ UTF-8 512M - 1.0.8 + 1.0.9 1.7.25 2.6.2 From c2335dfc2661d5781681f36facc008c339934bd9 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Fri, 6 Sep 2019 12:19:21 -0700 Subject: [PATCH 016/769] [maven-release-plugin] prepare release biojava-5.3.0 --- biojava-aa-prop/pom.xml | 6 +++--- biojava-alignment/pom.xml | 4 ++-- biojava-core/pom.xml | 2 +- biojava-genome/pom.xml | 6 +++--- biojava-integrationtest/pom.xml | 4 ++-- biojava-modfinder/pom.xml | 4 ++-- biojava-ontology/pom.xml | 2 +- biojava-protein-disorder/pom.xml | 4 ++-- biojava-structure-gui/pom.xml | 6 +++--- biojava-structure/pom.xml | 6 +++--- biojava-survival/pom.xml | 2 +- biojava-ws/pom.xml | 4 ++-- pom.xml | 4 ++-- 13 files changed, 27 insertions(+), 27 deletions(-) diff --git a/biojava-aa-prop/pom.xml b/biojava-aa-prop/pom.xml index 53a775287e..ac3d8aa645 100644 --- a/biojava-aa-prop/pom.xml +++ b/biojava-aa-prop/pom.xml @@ -2,7 +2,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 4.0.0 biojava-aa-prop @@ -70,12 +70,12 @@ org.biojava biojava-core - 5.2.2-SNAPSHOT + 5.3.0 org.biojava biojava-structure - 5.2.2-SNAPSHOT + 5.3.0 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index 0c14c04c1e..376eefa966 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 5.2.2-SNAPSHOT + 5.3.0 compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 5b0ed01b0b..63c44e9a46 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index 1a0c7c571c..6ba22d8c87 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 5.2.2-SNAPSHOT + 5.3.0 compile org.biojava biojava-alignment - 5.2.2-SNAPSHOT + 5.3.0 compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index f5f897bf34..abca836653 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 5.2.2-SNAPSHOT + 5.3.0 diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 99e399c4af..70caa2353b 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 5.2.2-SNAPSHOT + 5.3.0 jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 822b6633e1..5385fbc1ba 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.2.2-SNAPSHOT + 5.3.0 biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 4f174d45b3..329b532f18 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 5.2.2-SNAPSHOT + 5.3.0 diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index 3d3f4fc444..d2bd10620f 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 5.2.2-SNAPSHOT + 5.3.0 compile org.biojava biojava-core - 5.2.2-SNAPSHOT + 5.3.0 compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index e5eff3836d..e81be93d83 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 5.2.2-SNAPSHOT + 5.3.0 compile org.biojava biojava-core - 5.2.2-SNAPSHOT + 5.3.0 compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index 24d90c1229..c8cc614008 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.2.2-SNAPSHOT + 5.3.0 biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 921d13b025..08ccc0df63 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.2.2-SNAPSHOT + 5.3.0 biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 5.2.2-SNAPSHOT + 5.3.0 compile diff --git a/pom.xml b/pom.xml index b64643c44d..2a63a6f714 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 5.2.2-SNAPSHOT + 5.3.0 biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -49,7 +49,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - HEAD + biojava-5.3.0 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index 376eefa966..092dbc3d0b 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.3.0 + 5.3.1-SNAPSHOT biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 5.3.0 + 5.3.1-SNAPSHOT compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 63c44e9a46..b465a40a36 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.0 + 5.3.1-SNAPSHOT 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index 6ba22d8c87..bd67b30190 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.0 + 5.3.1-SNAPSHOT 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 5.3.0 + 5.3.1-SNAPSHOT compile org.biojava biojava-alignment - 5.3.0 + 5.3.1-SNAPSHOT compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index abca836653..7367654c01 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.3.0 + 5.3.1-SNAPSHOT biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 5.3.0 + 5.3.1-SNAPSHOT diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 70caa2353b..5367030867 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.3.0 + 5.3.1-SNAPSHOT biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 5.3.0 + 5.3.1-SNAPSHOT jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 5385fbc1ba..b6a4fa0967 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.3.0 + 5.3.1-SNAPSHOT biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 329b532f18..982a4d170b 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.0 + 5.3.1-SNAPSHOT biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 5.3.0 + 5.3.1-SNAPSHOT diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index d2bd10620f..e6605344bc 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.0 + 5.3.1-SNAPSHOT 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 5.3.0 + 5.3.1-SNAPSHOT compile org.biojava biojava-core - 5.3.0 + 5.3.1-SNAPSHOT compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index e81be93d83..688984e845 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.3.0 + 5.3.1-SNAPSHOT biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 5.3.0 + 5.3.1-SNAPSHOT compile org.biojava biojava-core - 5.3.0 + 5.3.1-SNAPSHOT compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index c8cc614008..479b57276b 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.3.0 + 5.3.1-SNAPSHOT biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 08ccc0df63..8df54334cf 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.0 + 5.3.1-SNAPSHOT biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 5.3.0 + 5.3.1-SNAPSHOT compile diff --git a/pom.xml b/pom.xml index 2a63a6f714..9ff4c461ee 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 5.3.0 + 5.3.1-SNAPSHOT biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -49,7 +49,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - biojava-5.3.0 + HEAD From 761799b7e8c727d573fa834a5bb36959a0292b10 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 9 Nov 2019 22:17:56 -0800 Subject: [PATCH 020/769] Fixing issue: no bonds between different altloc atoms --- .../org/biojava/nbio/structure/AtomImpl.java | 2 +- .../biojava/nbio/structure/HetatomImpl.java | 47 +++------- .../biojava/nbio/structure/io/BondMaker.java | 18 ++-- .../biojava/nbio/structure/TestAltLocs.java | 93 +++++++++++++++++++ 4 files changed, 115 insertions(+), 45 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomImpl.java index 10e16b4313..a270b06983 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomImpl.java @@ -309,7 +309,7 @@ public void setBonds(List bonds) { @Override public void addBond(Bond bond) { if (bonds==null) { - bonds = new ArrayList(BONDS_INITIAL_CAPACITY); + bonds = new ArrayList<>(BONDS_INITIAL_CAPACITY); } bonds.add(bond); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java index f89812487a..cc5356b942 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java @@ -77,7 +77,7 @@ public class HetatomImpl implements Group { * Behaviors for how to balance memory vs. performance. * @author Andreas Prlic */ - public static enum PerformanceBehavior { + public enum PerformanceBehavior { /** use a built-in HashMap for faster access to memory, at the price of more memory consumption */ BETTER_PERFORMANCE_MORE_MEMORY, @@ -87,7 +87,7 @@ public static enum PerformanceBehavior { } - public static PerformanceBehavior performanceBehavior=PerformanceBehavior.LESS_MEMORY_SLOWER_PERFORMANCE; + private static PerformanceBehavior performanceBehavior=PerformanceBehavior.LESS_MEMORY_SLOWER_PERFORMANCE; private Map atomNameLookup; @@ -105,42 +105,28 @@ public HetatomImpl() { pdb_name = null ; residueNumber = null; - atoms = new ArrayList(); - properties = new HashMap(); + atoms = new ArrayList<>(); + properties = new HashMap<>(); parent = null; chemComp = null; altLocs = null; if ( performanceBehavior == PerformanceBehavior.BETTER_PERFORMANCE_MORE_MEMORY) - atomNameLookup = new HashMap(); + atomNameLookup = new HashMap<>(); else atomNameLookup = null; } - - /** - * returns true or false, depending if this group has 3D coordinates or not. - * @return true if Group has 3D coordinates - */ @Override public boolean has3D() { return pdb_flag; } - /** flag if group has 3D data. - * - * @param flag true to set flag that this Group has 3D coordinates - */ @Override public void setPDBFlag(boolean flag){ pdb_flag = flag ; } - /** Set three character name of Group . - * - * @param s a String specifying the PDBName value - * @see #getPDBName - */ @Override public void setPDBName(String s) { // hetatoms can have pdb_name length < 3. e.g. CU (see 1a4a position 1200 ) @@ -152,12 +138,6 @@ public void setPDBName(String s) { } - /** - * Returns the PDBName. - * - * @return a String representing the PDBName value - * @see #setPDBName - */ @Override public String getPDBName() { return pdb_name;} @@ -187,12 +167,8 @@ public void addAtom(Atom atom){ logger.warn("An atom with name " + atom.getName() + " " + altLocStr + " is already present in group: " + this.toString() + ". The atom with serial " + atom.getPDBserial() + " will be ignored in look-ups."); } } - }; - + } - /** remove all atoms - * - */ @Override public void clearAtoms() { atoms.clear(); @@ -245,8 +221,7 @@ public Atom getAtom(String name) { if ( atomNameLookup != null) return atomNameLookup.get(name); else { - /** This is the performance penalty we pay for NOT using the atomnameLookup in PerformanceBehaviour.LESS_MEMORY_SLOWER_PERFORMANCE - */ + // This is the performance penalty we pay for NOT using the atomnameLookup in PerformanceBehaviour.LESS_MEMORY_SLOWER_PERFORMANCE for (Atom a : atoms) { if (a.getName().equals(name)) { return a; @@ -588,7 +563,7 @@ public boolean hasAltLoc() { @Override public List getAltLocs() { if ( altLocs == null) - return new ArrayList(); + return new ArrayList<>(); return altLocs; } @@ -629,7 +604,7 @@ public Group getAltLocGroup(Character altLoc) { @Override public void addAltLoc(Group group) { if ( altLocs == null) { - altLocs = new ArrayList(); + altLocs = new ArrayList<>(); } altLocs.add(group); @@ -663,10 +638,10 @@ public void trimToSize(){ } // now let's fit the hashmaps to size - properties = new HashMap(properties); + properties = new HashMap<>(properties); if ( atomNameLookup != null) - atomNameLookup = new HashMap(atomNameLookup); + atomNameLookup = new HashMap<>(atomNameLookup); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java index 2b184063c5..0715cf4792 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java @@ -200,10 +200,7 @@ private void formIntraResidueBonds() { // Now add support for altLocGroup List totList = new ArrayList(); totList.add(mainGroup); - for(Group altLoc: mainGroup.getAltLocs()){ - totList.add(altLoc); - } - + totList.addAll(mainGroup.getAltLocs()); // Now iterate through this list for(Group group : totList){ @@ -216,15 +213,19 @@ private void formIntraResidueBonds() { Atom a = getAtom(chemCompBond.getAtom_id_1(), group); Atom b = getAtom(chemCompBond.getAtom_id_2(), group); if ( a != null && b != null){ + + // if they are different altlocs there must be no bond + if (a.getAltLoc() != b.getAltLoc()) + continue; + int bondOrder = chemCompBond.getNumericalBondOrder(); logger.debug("Forming bond between atoms {}-{} and {}-{} with bond order {}", a.getPDBserial(), a.getName(), b.getPDBserial(), b.getName(), bondOrder); new BondImpl(a, b, bondOrder); } - else{ - // Some of the atoms were missing. That's fine, there's - // nothing to do in this case. - } + // Else: Some of the atoms were missing. That's fine, there's + // nothing to do in this case. + } } } @@ -235,6 +236,7 @@ private void formIntraResidueBonds() { private Atom getAtom(String atomId, Group group) { Atom a = group.getAtom(atomId); + // Check for deuteration if(a==null && atomId.startsWith("H")) { a = group.getAtom(atomId.replaceFirst("H", "D")); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java index 7224a29247..37e4ef62ea 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java @@ -754,4 +754,97 @@ public void testMmcifConversionAllAltlocs() throws IOException { } + /** + * Test that bonds between alt locs link atoms with same altloc codes + * https://github.com/rcsb/mmtf/issues/44 + */ + @Test + public void testBondsBetweenAltlocs() throws IOException { + String mmcifData = + "data_test\n" + + "loop_\n" + + "_atom_site.group_PDB \n" + + "_atom_site.id \n" + + "_atom_site.type_symbol \n" + + "_atom_site.label_atom_id \n" + + "_atom_site.label_alt_id \n" + + "_atom_site.label_comp_id \n" + + "_atom_site.label_asym_id \n" + + "_atom_site.label_entity_id \n" + + "_atom_site.label_seq_id \n" + + "_atom_site.pdbx_PDB_ins_code \n" + + "_atom_site.Cartn_x \n" + + "_atom_site.Cartn_y \n" + + "_atom_site.Cartn_z \n" + + "_atom_site.occupancy \n" + + "_atom_site.B_iso_or_equiv \n" + + "_atom_site.pdbx_formal_charge \n" + + "_atom_site.auth_seq_id \n" + + "_atom_site.auth_comp_id \n" + + "_atom_site.auth_asym_id \n" + + "_atom_site.auth_atom_id \n" + + "_atom_site.pdbx_PDB_model_num \n" + + "ATOM 1405 N N A MET A 1 86 ? 10.748 -17.610 -6.975 0.47 16.12 ? 104 MET A N 1 \n" + + "ATOM 1406 N N B MET A 1 86 ? 10.802 -17.694 -6.986 0.53 17.92 ? 104 MET A N 1 \n" + + "ATOM 1407 C CA A MET A 1 86 ? 11.189 -17.392 -5.610 0.47 15.78 ? 104 MET A CA 1 \n" + + "ATOM 1408 C CA B MET A 1 86 ? 11.033 -17.368 -5.587 0.53 18.29 ? 104 MET A CA 1 \n" + + "ATOM 1409 C C A MET A 1 86 ? 10.952 -18.663 -4.810 0.47 15.91 ? 104 MET A C 1 \n" + + "ATOM 1410 C C B MET A 1 86 ? 10.882 -18.643 -4.767 0.53 17.40 ? 104 MET A C 1 \n" + + "ATOM 1411 O O A MET A 1 86 ? 10.120 -19.504 -5.154 0.47 18.21 ? 104 MET A O 1 \n" + + "ATOM 1412 O O B MET A 1 86 ? 10.018 -19.474 -5.052 0.53 20.02 ? 104 MET A O 1 \n" + + "ATOM 1413 C CB A MET A 1 86 ? 10.477 -16.204 -4.933 0.47 17.14 ? 104 MET A CB 1 \n" + + "ATOM 1414 C CB B MET A 1 86 ? 10.001 -16.336 -5.111 0.53 18.92 ? 104 MET A CB 1 \n" + + "ATOM 1415 C CG A MET A 1 86 ? 9.019 -16.476 -4.619 0.47 20.01 ? 104 MET A CG 1 \n" + + "ATOM 1416 C CG B MET A 1 86 ? 10.030 -16.038 -3.634 0.53 19.12 ? 104 MET A CG 1 \n" + + "ATOM 1417 S SD A MET A 1 86 ? 8.207 -15.088 -3.838 0.47 22.06 ? 104 MET A SD 1 \n" + + "ATOM 1418 S SD B MET A 1 86 ? 8.874 -14.724 -3.205 0.53 20.16 ? 104 MET A SD 1 \n" + + "ATOM 1419 C CE A MET A 1 86 ? 9.151 -14.973 -2.340 0.47 25.15 ? 104 MET A CE 1 \n" + + "ATOM 1420 C CE B MET A 1 86 ? 7.269 -15.536 -3.380 0.53 20.38 ? 104 MET A CE 1 \n" + + "ATOM 1421 H H A MET A 1 86 ? 9.931 -18.207 -7.055 0.47 15.58 ? 104 MET A H 1 \n" + + "ATOM 1422 H H B MET A 1 86 ? 10.144 -18.461 -7.109 0.53 18.91 ? 104 MET A H 1 \n" + + "ATOM 1423 H HA A MET A 1 86 ? 12.256 -17.182 -5.644 0.47 15.14 ? 104 MET A HA 1 \n" + + "ATOM 1424 H HA B MET A 1 86 ? 12.033 -16.953 -5.465 0.53 19.55 ? 104 MET A HA 1 \n" + + "ATOM 1425 H HB2 A MET A 1 86 ? 10.986 -15.920 -4.008 0.47 17.68 ? 104 MET A HB2 1 \n" + + "ATOM 1426 H HB3 A MET A 1 86 ? 10.484 -15.364 -5.622 0.47 17.68 ? 104 MET A HB3 1 \n" + + "ATOM 1427 H HB3 B MET A 1 86 ? 9.001 -16.676 -5.398 0.53 20.49 ? 104 MET A HB3 1 \n" + + "ATOM 1428 H HG2 A MET A 1 86 ? 8.490 -16.704 -5.546 0.47 20.93 ? 104 MET A HG2 1 \n" + + "ATOM 1429 H HG3 A MET A 1 86 ? 8.956 -17.315 -3.927 0.47 20.93 ? 104 MET A HG3 1 \n" + + "ATOM 1430 H HE2 A MET A 1 86 ? 9.861 -14.153 -2.440 0.47 27.31 ? 104 MET A HE2 1 \n" + + "ATOM 1431 H HE2 B MET A 1 86 ? 7.346 -16.554 -2.998 0.53 23.03 ? 104 MET A HE2 1 \n" + + "ATOM 1432 H HE3 B MET A 1 86 ? 6.996 -15.566 -4.437 0.53 23.03 ? 104 MET A HE3 1 "; + + SimpleMMcifParser parser = new SimpleMMcifParser(); + SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); + parser.addMMcifConsumer(consumer); + + FileParsingParameters params = new FileParsingParameters(); + params.setCreateAtomBonds(true); + consumer.setFileParsingParameters(params); + + BufferedReader buf = new BufferedReader(new StringReader(mmcifData)); + parser.parse(buf); + buf.close(); + + Structure s = consumer.getStructure(); + Chain c = s.getPolyChains().get(0); + assertEquals(1, c.getAtomGroups().size()); + + Group g = c.getAtomGroup(0); + + assertEquals(1, g.getAltLocs().size()); + + for (Atom a : g.getAtoms()) { + for (Bond b : a.getBonds()) { +// if (b.getAtomA().getAltLoc() != b.getAtomB().getAltLoc()) { +// System.out.println( +// b.getAtomA().toString() + ":" + b.getAtomA().getAltLoc() + " --- " + +// b.getAtomB().toString() + ":" + b.getAtomB().getAltLoc()); +// } + assertEquals(b.getAtomA().toString() + " --- " + b.getAtomB().toString(), + b.getAtomA().getAltLoc(), b.getAtomB().getAltLoc()); + } + } + + } + } From 408c8accefb0863507e291b418599ec450667ff5 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 9 Nov 2019 22:43:37 -0800 Subject: [PATCH 021/769] Extending test --- .../java/org/biojava/nbio/structure/TestAltLocs.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java index 37e4ef62ea..28db8cd8f0 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java @@ -833,6 +833,7 @@ public void testBondsBetweenAltlocs() throws IOException { assertEquals(1, g.getAltLocs().size()); + boolean foundCEHE3bond = false; for (Atom a : g.getAtoms()) { for (Bond b : a.getBonds()) { // if (b.getAtomA().getAltLoc() != b.getAtomB().getAltLoc()) { @@ -840,11 +841,21 @@ public void testBondsBetweenAltlocs() throws IOException { // b.getAtomA().toString() + ":" + b.getAtomA().getAltLoc() + " --- " + // b.getAtomB().toString() + ":" + b.getAtomB().getAltLoc()); // } + // no bonds between atoms with different alt locs assertEquals(b.getAtomA().toString() + " --- " + b.getAtomB().toString(), b.getAtomA().getAltLoc(), b.getAtomB().getAltLoc()); + + // a bond should exist between CE and HE3 but only for altloc=B + if ((b.getAtomA().getName().equals("CE") && b.getAtomB().getName().equals("HE3")) || + (b.getAtomA().getName().equals("HE3") && b.getAtomB().getName().equals("CE")) ) { + foundCEHE3bond = true; + } } } + // there should be a bond between CE and HE3 but only for altloc=B + assertTrue(foundCEHE3bond); + } } From 7c7caa274420e3399d4c969b0feb795979e6d71d Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Mon, 11 Nov 2019 21:29:52 -0800 Subject: [PATCH 022/769] Now all tests pass --- .../java/org/biojava/nbio/structure/io/BondMaker.java | 9 +++++++-- .../java/org/biojava/nbio/structure/TestAltLocs.java | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java index 0715cf4792..f829f22718 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java @@ -214,9 +214,14 @@ private void formIntraResidueBonds() { Atom b = getAtom(chemCompBond.getAtom_id_2(), group); if ( a != null && b != null){ - // if they are different altlocs there must be no bond - if (a.getAltLoc() != b.getAltLoc()) + // if they are different altlocs (when different from the '.' case) there must be no bond + if (a.getAltLoc() != null && b.getAltLoc()!=null && + a.getAltLoc()!=' ' && b.getAltLoc()!=' ' && + a.getAltLoc() != b.getAltLoc()) { + logger.debug("Skipping bond between atoms with differently named alt locs {} (altLoc '{}') -- {} (altLoc '{}')", + a.toString(), a.getAltLoc(), b.toString(), b.getAltLoc()); continue; + } int bondOrder = chemCompBond.getNumericalBondOrder(); logger.debug("Forming bond between atoms {}-{} and {}-{} with bond order {}", diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java index 28db8cd8f0..c1e38280c6 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java @@ -838,8 +838,8 @@ public void testBondsBetweenAltlocs() throws IOException { for (Bond b : a.getBonds()) { // if (b.getAtomA().getAltLoc() != b.getAtomB().getAltLoc()) { // System.out.println( -// b.getAtomA().toString() + ":" + b.getAtomA().getAltLoc() + " --- " + -// b.getAtomB().toString() + ":" + b.getAtomB().getAltLoc()); +// b.getAtomA().toString() + ": '" + b.getAtomA().getAltLoc() + "' --- " + +// b.getAtomB().toString() + ": '" + b.getAtomB().getAltLoc() + "'"); // } // no bonds between atoms with different alt locs assertEquals(b.getAtomA().toString() + " --- " + b.getAtomB().toString(), From 0ff1823543a133e42e7f09e32003fca4a0fd894f Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Mon, 11 Nov 2019 21:39:04 -0800 Subject: [PATCH 023/769] Clarifying docs and some more cleanup --- .../java/org/biojava/nbio/structure/Atom.java | 3 +- .../org/biojava/nbio/structure/AtomImpl.java | 9 ------ .../biojava/nbio/structure/HetatomImpl.java | 30 +------------------ 3 files changed, 3 insertions(+), 39 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/Atom.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/Atom.java index ebd67c0a8c..7b1c722bd9 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/Atom.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/Atom.java @@ -163,7 +163,8 @@ public interface Atom extends Cloneable, PDBRecord { /** * Get alternate Location. - * @return a Character object representing the alt loc value + * @return a Character object representing the alt loc value. Default altLoc ('.' in mmCIF files) + * is represented by ' ' (space character, ascii 32). * @see #setAltLoc */ public Character getAltLoc(); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomImpl.java index a270b06983..36ccf49efb 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomImpl.java @@ -157,10 +157,6 @@ public void setZ(double z) { @Override public double getZ() { return coords.z; } - /** - * Set alternate Location. - * @see #getAltLoc - */ @Override public void setAltLoc(Character c) { // after changing altLoc from Character to char, we do this to keep the interface the same as it used to be - JD 2016-01-27 @@ -170,11 +166,6 @@ public void setAltLoc(Character c) { altLoc = c ; } - /** - * Get alternate Location. - * @return a Character object representing the alt loc value - * @see #setAltLoc - */ @Override public Character getAltLoc() { // after changing altLoc from Character to char, we do this to keep the interface the same as it used to be - JD 2016-01-27 diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java index cc5356b942..037dcb2b0b 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java @@ -254,16 +254,13 @@ public boolean hasAtom(String fullName) { Atom a = atomNameLookup.get(fullName.trim()); return a != null; } else { - /** This is the performance penalty we pay for NOT using the atomnameLookup in PerformanceBehaviour.LESS_MEMORY_SLOWER_PERFORMANCE - */ + // This is the performance penalty we pay for NOT using the atomnameLookup in PerformanceBehaviour.LESS_MEMORY_SLOWER_PERFORMANCE for (Atom a : atoms) { if (a.getName().equals(fullName)) { return true; } } return false; - - } } @@ -375,42 +372,21 @@ public void setProperties(Map props) { properties = props ; } - /** return properties. - * - * @return a HashMap object representing the properties value - * @see #setProperties - */ @Override public Map getProperties() { return properties ; } - /** set a single property . - * - * @see #getProperties - * @see #getProperty - */ @Override public void setProperty(String key, Object value){ properties.put(key,value); } - /** get a single property . - * @param key a String - * @return an Object - * @see #setProperty - * @see #setProperties - */ @Override public Object getProperty(String key){ return properties.get(key); } - - /** return an AtomIterator. - * - * @return an Iterator object - */ @Override public Iterator iterator() { return new AtomIterator(this); @@ -615,10 +591,6 @@ public boolean isWater() { return GroupType.WATERNAMES.contains(pdb_name); } - /** attempts to reduce the memory imprint of this group by trimming - * all internal Collection objects to the required size. - * - */ @Override public void trimToSize(){ From a29f88187b6871d21bfc5cab9918a95026ec4b28 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Tue, 12 Nov 2019 17:01:37 -0800 Subject: [PATCH 024/769] Covering another alt loc bond edge case --- .../biojava/nbio/structure/io/BondMaker.java | 45 +++-- .../io/mmcif/SimpleMMcifConsumer.java | 4 +- .../biojava/nbio/structure/TestAltLocs.java | 167 +++++++++++++++++- 3 files changed, 200 insertions(+), 16 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java index f829f22718..3689f459e3 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java @@ -128,30 +128,51 @@ private void formPeptideBonds() { continue; } - Atom carboxylC; - Atom aminoN; + List carboxylCs = getAtoms(tail, "C"); + List aminoNs = getAtoms(head, "N"); - carboxylC = tail.getC(); - aminoN = head.getN(); - - - if (carboxylC == null || aminoN == null) { + if (carboxylCs.isEmpty() || aminoNs.isEmpty()) { // some structures may be incomplete and not store info // about all of their atoms - continue; } - - if (Calc.getDistance(carboxylC, aminoN) < MAX_PEPTIDE_BOND_LENGTH) { - new BondImpl(carboxylC, aminoN, 1); + for (Atom carboxylC:carboxylCs) { + for (Atom aminoN:aminoNs) { + if (carboxylC.getAltLoc() != null && aminoN.getAltLoc()!=null && + carboxylC.getAltLoc()!=' ' && aminoN.getAltLoc()!=' ' && + carboxylC.getAltLoc() != aminoN.getAltLoc()) { + logger.debug("Skipping peptide bond between atoms with differently named alt locs {} (altLoc '{}') -- {} (altLoc '{}')", + carboxylC.toString(), carboxylC.getAltLoc(), aminoN.toString(), aminoN.getAltLoc()); + continue; + } + if (Calc.getDistance(carboxylC, aminoN) < MAX_PEPTIDE_BOND_LENGTH) { + new BondImpl(carboxylC, aminoN, 1); + } + } } - } } } } + /** + * Get all atoms (including possible alt locs) in given group that are name with the given atom name + * @param g the group + * @param name the atom name + * @return list of all atoms, or empty list if no atoms with the name + */ + private List getAtoms(Group g, String name) { + List atoms = new ArrayList<>(); + List groupsWithAltLocs = new ArrayList<>(); + groupsWithAltLocs.add(g); + groupsWithAltLocs.addAll(g.getAltLocs()); + for (Group group : groupsWithAltLocs) { + atoms.add(group.getAtom(name)); + } + return atoms; + } + private void formNucleotideBonds() { for (int modelInd=0; modelInd bonds = new ArrayList<>(); + for (Bond b : catom.getBonds()) { + if (b.getAtomA().getName().equals("N") || b.getAtomB().getName().equals("N")) { + bonds.add(b); + } + } + + assertEquals(2, bonds.size()); + + Set seenAltLocs = new HashSet<>(); + for (Bond b : bonds) { + Atom aAtom = b.getAtomA(); + Atom bAtom = b.getAtomB(); + Atom nAtom; + if (aAtom.getName().equals("N")) { + nAtom = aAtom; + } else { + nAtom = bAtom; + } + seenAltLocs.add(nAtom.getAltLoc()); + } + // 2 distinct N atoms: alt loc A and B + assertEquals(2, seenAltLocs.size()); + assertTrue(seenAltLocs.contains('A')); + assertTrue(seenAltLocs.contains('B')); + + } + + } From b889140cee99cd5b1745c6b4c4059e487d576489 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Tue, 12 Nov 2019 21:46:40 -0800 Subject: [PATCH 025/769] Extracted common method, now covering nucleotide bonds --- .../biojava/nbio/structure/io/BondMaker.java | 103 +++++++++--------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java index 3689f459e3..beed12e2e2 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java @@ -128,51 +128,12 @@ private void formPeptideBonds() { continue; } - List carboxylCs = getAtoms(tail, "C"); - List aminoNs = getAtoms(head, "N"); - - if (carboxylCs.isEmpty() || aminoNs.isEmpty()) { - // some structures may be incomplete and not store info - // about all of their atoms - continue; - } - - for (Atom carboxylC:carboxylCs) { - for (Atom aminoN:aminoNs) { - if (carboxylC.getAltLoc() != null && aminoN.getAltLoc()!=null && - carboxylC.getAltLoc()!=' ' && aminoN.getAltLoc()!=' ' && - carboxylC.getAltLoc() != aminoN.getAltLoc()) { - logger.debug("Skipping peptide bond between atoms with differently named alt locs {} (altLoc '{}') -- {} (altLoc '{}')", - carboxylC.toString(), carboxylC.getAltLoc(), aminoN.toString(), aminoN.getAltLoc()); - continue; - } - if (Calc.getDistance(carboxylC, aminoN) < MAX_PEPTIDE_BOND_LENGTH) { - new BondImpl(carboxylC, aminoN, 1); - } - } - } + formBondAltlocAware(tail, "C", head, "N", MAX_PEPTIDE_BOND_LENGTH, 1); } } } } - /** - * Get all atoms (including possible alt locs) in given group that are name with the given atom name - * @param g the group - * @param name the atom name - * @return list of all atoms, or empty list if no atoms with the name - */ - private List getAtoms(Group g, String name) { - List atoms = new ArrayList<>(); - List groupsWithAltLocs = new ArrayList<>(); - groupsWithAltLocs.add(g); - groupsWithAltLocs.addAll(g.getAltLocs()); - for (Group group : groupsWithAltLocs) { - atoms.add(group.getAtom(name)); - } - return atoms; - } - private void formNucleotideBonds() { for (int modelInd=0; modelInd a1s = getAtoms(g1, name1); + List a2s = getAtoms(g2, name2); - if (Calc.getDistance(phosphorous, oThreePrime) < MAX_NUCLEOTIDE_BOND_LENGTH) { - new BondImpl(phosphorous, oThreePrime, 1); - } + if (a1s.isEmpty() || a2s.isEmpty()) { + // some structures may be incomplete and not store info + // about all of their atoms + return; + } + for (Atom a1:a1s) { + for (Atom a2:a2s) { + if (a1.getAltLoc() != null && a2.getAltLoc()!=null && + a1.getAltLoc()!=' ' && a2.getAltLoc()!=' ' && + a1.getAltLoc() != a2.getAltLoc()) { + logger.debug("Skipping bond between atoms with differently named alt locs {} (altLoc '{}') -- {} (altLoc '{}')", + a1.toString(), a1.getAltLoc(), a2.toString(), a2.getAltLoc()); + continue; + } + if (Calc.getDistance(a1, a2) < maxAllowedLength) { + new BondImpl(a1, a2, bondOrder); } } } } + /** + * Get all atoms (including possible alt locs) in given group that are name with the given atom name + * @param g the group + * @param name the atom name + * @return list of all atoms, or empty list if no atoms with the name + */ + private List getAtoms(Group g, String name) { + List atoms = new ArrayList<>(); + List groupsWithAltLocs = new ArrayList<>(); + groupsWithAltLocs.add(g); + groupsWithAltLocs.addAll(g.getAltLocs()); + for (Group group : groupsWithAltLocs) { + Atom a = group.getAtom(name); + if (a!=null) + atoms.add(a); + } + return atoms; + } + private void formIntraResidueBonds() { for (int modelInd=0; modelInd Date: Tue, 12 Nov 2019 22:19:28 -0800 Subject: [PATCH 026/769] Consolidating on a single method call for all alt loc bond business --- .../biojava/nbio/structure/io/BondMaker.java | 127 ++++++++---------- 1 file changed, 57 insertions(+), 70 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java index beed12e2e2..bb92724aa4 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java @@ -159,14 +159,48 @@ private void formNucleotideBonds() { } } + private void formIntraResidueBonds() { + for (int modelInd=0; modelInd groups = chain.getAtomGroups(); + for (Group mainGroup : groups) { + // atoms with no residue number don't have atom information + if (mainGroup.getResidueNumber() == null) { + continue; + } + // Now add support for altLocGroup + List totList = new ArrayList(); + totList.add(mainGroup); + totList.addAll(mainGroup.getAltLocs()); + + // Now iterate through this list + for(Group group : totList){ + + ChemComp aminoChemComp = ChemCompGroupFactory.getChemComp(group.getPDBName()); + logger.debug("chemcomp for residue {}-{} has {} atoms and {} bonds", + group.getPDBName(), group.getResidueNumber(), aminoChemComp.getAtoms().size(), aminoChemComp.getBonds().size()); + + for (ChemCompBond chemCompBond : aminoChemComp.getBonds()) { + // note we don't check distance to make this call not too expensive + formBondAltlocAware(group, chemCompBond.getAtom_id_1(), + group, chemCompBond.getAtom_id_2(), -1, chemCompBond.getNumericalBondOrder()); + } + } + } + } + + } + } + /** * Form bond between atoms of the given names and groups, respecting alt loc rules to form bonds: - * no bonds between differently named alt locs (not default) and all bonds for default alt loc to named alt loc. + * no bonds between differently named alt locs (that are not the default alt loc '.') + * and multiple bonds for default alt loc to named alt loc. * @param g1 first group * @param name1 name of atom in first group * @param g2 second group * @param name2 name of atom in second group - * @param maxAllowedLength max length, if atoms distance above this length no bond will be added + * @param maxAllowedLength max length, if atoms distance above this length no bond will be added. If negative no check on distance is performed. * @param bondOrder the bond order to be set in the created bond(s) */ private void formBondAltlocAware(Group g1, String name1, Group g2, String name2, double maxAllowedLength, int bondOrder) { @@ -188,8 +222,20 @@ private void formBondAltlocAware(Group g1, String name1, Group g2, String name2, a1.toString(), a1.getAltLoc(), a2.toString(), a2.getAltLoc()); continue; } - if (Calc.getDistance(a1, a2) < maxAllowedLength) { + if (maxAllowedLength<0) { + // negative maxAllowedLength means we don't check distance and always add bond + logger.debug("Forming bond between atoms {}-{} and {}-{} with bond order {}", + a1.getPDBserial(), a1.getName(), a2.getPDBserial(), a2.getName(), bondOrder); new BondImpl(a1, a2, bondOrder); + } else { + if (Calc.getDistance(a1, a2) < maxAllowedLength) { + logger.debug("Forming bond between atoms {}-{} and {}-{} with bond order {}. Distance is below {}", + a1.getPDBserial(), a1.getName(), a2.getPDBserial(), a2.getName(), bondOrder, maxAllowedLength); + new BondImpl(a1, a2, bondOrder); + } else { + logger.debug("Not forming bond between atoms {}-{} and {}-{} with bond order {}, because distance is above {}", + a1.getPDBserial(), a1.getName(), a2.getPDBserial(), a2.getName(), bondOrder, maxAllowedLength); + } } } } @@ -208,77 +254,18 @@ private List getAtoms(Group g, String name) { groupsWithAltLocs.addAll(g.getAltLocs()); for (Group group : groupsWithAltLocs) { Atom a = group.getAtom(name); - if (a!=null) - atoms.add(a); - } - return atoms; - } - - private void formIntraResidueBonds() { - for (int modelInd=0; modelInd groups = chain.getAtomGroups(); - for (Group mainGroup : groups) { - // atoms with no residue number don't have atom information - if (mainGroup.getResidueNumber() == null) { - continue; - } - // Now add support for altLocGroup - List totList = new ArrayList(); - totList.add(mainGroup); - totList.addAll(mainGroup.getAltLocs()); - - // Now iterate through this list - for(Group group : totList){ - - ChemComp aminoChemComp = ChemCompGroupFactory.getChemComp(group.getPDBName()); - logger.debug("chemcomp for residue {}-{} has {} atoms and {} bonds", - group.getPDBName(), group.getResidueNumber(), aminoChemComp.getAtoms().size(), aminoChemComp.getBonds().size()); - - for (ChemCompBond chemCompBond : aminoChemComp.getBonds()) { - Atom a = getAtom(chemCompBond.getAtom_id_1(), group); - Atom b = getAtom(chemCompBond.getAtom_id_2(), group); - if ( a != null && b != null){ - - // if they are different altlocs (when different from the '.' case) there must be no bond - if (a.getAltLoc() != null && b.getAltLoc()!=null && - a.getAltLoc()!=' ' && b.getAltLoc()!=' ' && - a.getAltLoc() != b.getAltLoc()) { - logger.debug("Skipping bond between atoms with differently named alt locs {} (altLoc '{}') -- {} (altLoc '{}')", - a.toString(), a.getAltLoc(), b.toString(), b.getAltLoc()); - continue; - } - - int bondOrder = chemCompBond.getNumericalBondOrder(); - logger.debug("Forming bond between atoms {}-{} and {}-{} with bond order {}", - a.getPDBserial(), a.getName(), b.getPDBserial(), b.getName(), bondOrder); - new BondImpl(a, b, bondOrder); - } - // Else: Some of the atoms were missing. That's fine, there's - // nothing to do in this case. - - } - } - } - } - - } - } - - private Atom getAtom(String atomId, Group group) { - Atom a = group.getAtom(atomId); - - // Check for deuteration - if(a==null && atomId.startsWith("H")) { - a = group.getAtom(atomId.replaceFirst("H", "D")); - // Check it is actually deuterated - if(a!=null){ - if(!a.getElement().equals(Element.D)){ + // Check for deuteration + if (a==null && name.startsWith("H")) { + a = group.getAtom(name.replaceFirst("H", "D")); + // Check it is actually deuterated + if (a!=null && !a.getElement().equals(Element.D)){ a=null; } } + if (a!=null) + atoms.add(a); } - return a; + return atoms; } private void trimBondLists() { From c3633966cba32a6b007025f29e0675459d9a30e6 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Tue, 12 Nov 2019 22:26:28 -0800 Subject: [PATCH 027/769] Docs --- .../main/java/org/biojava/nbio/structure/Group.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java index 6a169dbee5..f2bc5a506a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java @@ -103,12 +103,13 @@ public interface Group extends Serializable { /** * Set the atoms of this group. - * @see {@link Atom} + * @see Atom * @param atoms a list of atoms */ public void setAtoms(List atoms); - /** Remove all atoms from this group. + /** + * Remove all atoms from this group. * */ public void clearAtoms(); @@ -118,13 +119,14 @@ public interface Group extends Serializable { * Beware that some PDB atom names are ambiguous (e.g. CA, which means C-alpha or Calcium), * ambiguities should not occur within the same group though. To solve these ambiguities * one would need to check the atom returned for the required element with {@link Atom#getElement()} + *

+ * Note this method will return only the atom in the default alternative location (be it '.' or a letter). * * @param name a trimmed String representing the atom's PDB name, e.g. "CA" * @return an Atom object or null if no such atom exists within this group */ public Atom getAtom(String name) ; - - + /** * Get at atom by position. * From 45f1d70ab3cc899355c34f5cfd2018a6c6adb642 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 12 Dec 2019 11:34:10 -0800 Subject: [PATCH 028/769] Logging, cleanups, cosmetics --- .../structure/cluster/SubunitCluster.java | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index 03d8a97749..24bea508a1 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -71,11 +71,10 @@ */ public class SubunitCluster { - private static final Logger logger = LoggerFactory - .getLogger(SubunitCluster.class); + private static final Logger logger = LoggerFactory.getLogger(SubunitCluster.class); - private List subunits = new ArrayList(); - private List> subunitEQR = new ArrayList>(); + private List subunits = new ArrayList<>(); + private List> subunitEQR = new ArrayList<>(); private int representative = -1; private SubunitClustererMethod method = SubunitClustererMethod.SEQUENCE; @@ -119,7 +118,7 @@ public SubunitCluster(Subunit subunit) { subunits.add(subunit); - List identity = new ArrayList(); + List identity = new ArrayList<>(); for (int i = 0; i < subunit.size(); i++) identity.add(i); subunitEQR.add(identity); @@ -296,13 +295,15 @@ public boolean mergeSequence(SubunitCluster other, SubunitClustererParameters pa return false; } - logger.info(String.format("SubunitClusters are similar in sequence " - + "with %.2f sequence identity and %.2f coverage", sequenceIdentity, - sequenceCoverage)); + logger.info(String.format("SubunitClusters %s-%s are similar in sequence " + + "with %.2f sequence identity and %.2f coverage", + this.subunits.get(this.representative).getName(), + other.subunits.get(other.representative).getName(), + sequenceIdentity, sequenceCoverage)); // If coverage and sequence identity sufficient, merge other and this - List thisAligned = new ArrayList(); - List otherAligned = new ArrayList(); + List thisAligned = new ArrayList<>(); + List otherAligned = new ArrayList<>(); // Extract the aligned residues of both Subunit for (int p = 1; p < aligner.getPair().getLength() + 1; p++) { @@ -318,16 +319,15 @@ public boolean mergeSequence(SubunitCluster other, SubunitClustererParameters pa // Only consider residues that are part of the SubunitCluster if (this.subunitEQR.get(this.representative).contains(thisIndex) - && other.subunitEQR.get(other.representative).contains( - otherIndex)) { + && other.subunitEQR.get(other.representative).contains(otherIndex)) { thisAligned.add(thisIndex); otherAligned.add(otherIndex); } } // Do a List intersection to find out which EQR columns to remove - List thisRemove = new ArrayList(); - List otherRemove = new ArrayList(); + List thisRemove = new ArrayList<>(); + List otherRemove = new ArrayList<>(); for (int t = 0; t < this.subunitEQR.get(this.representative).size(); t++) { // If the index is aligned do nothing, otherwise mark as removing @@ -348,16 +348,14 @@ public boolean mergeSequence(SubunitCluster other, SubunitClustererParameters pa Collections.sort(otherRemove); Collections.reverse(otherRemove); - for (int t = 0; t < thisRemove.size(); t++) { + for (Integer column : thisRemove) { for (List eqr : this.subunitEQR) { - int column = thisRemove.get(t); eqr.remove(column); } } - for (int t = 0; t < otherRemove.size(); t++) { + for (Integer column : otherRemove) { for (List eqr : other.subunitEQR) { - int column = otherRemove.get(t); eqr.remove(column); } } @@ -493,16 +491,14 @@ public boolean mergeStructure(SubunitCluster other, SubunitClustererParameters p Collections.sort(otherRemove); Collections.reverse(otherRemove); - for (int t = 0; t < thisRemove.size(); t++) { + for (Integer column : thisRemove) { for (List eqr : this.subunitEQR) { - int column = thisRemove.get(t); eqr.remove(column); } } - for (int t = 0; t < otherRemove.size(); t++) { + for (Integer column : otherRemove) { for (List eqr : other.subunitEQR) { - int column = otherRemove.get(t); eqr.remove(column); } } From 568a8d400b19eef912c2b60757909b3c1fbf0e16 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 27 Dec 2019 09:44:11 -0800 Subject: [PATCH 029/769] Extracting duplicate code to a method. Some cleanups --- .../structure/cluster/SubunitCluster.java | 79 +++++-------------- .../structure/cluster/SubunitClusterer.java | 8 +- .../structure/cluster/TestSubunitCluster.java | 10 +-- 3 files changed, 26 insertions(+), 71 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index 24bea508a1..4a5356b842 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -325,51 +325,9 @@ public boolean mergeSequence(SubunitCluster other, SubunitClustererParameters pa } } - // Do a List intersection to find out which EQR columns to remove - List thisRemove = new ArrayList<>(); - List otherRemove = new ArrayList<>(); - - for (int t = 0; t < this.subunitEQR.get(this.representative).size(); t++) { - // If the index is aligned do nothing, otherwise mark as removing - if (!thisAligned.contains(this.subunitEQR.get(this.representative) - .get(t))) - thisRemove.add(t); - } - - for (int t = 0; t < other.subunitEQR.get(other.representative).size(); t++) { - // If the index is aligned do nothing, otherwise mark as removing - if (!otherAligned.contains(other.subunitEQR.get( - other.representative).get(t))) - otherRemove.add(t); - } - // Now remove unaligned columns, from end to start - Collections.sort(thisRemove); - Collections.reverse(thisRemove); - Collections.sort(otherRemove); - Collections.reverse(otherRemove); - - for (Integer column : thisRemove) { - for (List eqr : this.subunitEQR) { - eqr.remove(column); - } - } - - for (Integer column : otherRemove) { - for (List eqr : other.subunitEQR) { - eqr.remove(column); - } - } - - // The representative is the longest sequence - if (this.subunits.get(this.representative).size() < other.subunits.get( - other.representative).size()) - this.representative = other.representative + subunits.size(); - - this.subunits.addAll(other.subunits); - this.subunitEQR.addAll(other.subunitEQR); + updateEquivResidues(other, thisAligned, otherAligned); this.method = SubunitClustererMethod.SEQUENCE; - pseudoStoichiometric = !params.isHighConfidenceScores(sequenceIdentity,sequenceCoverage); return true; @@ -443,8 +401,8 @@ public boolean mergeStructure(SubunitCluster other, SubunitClustererParameters p // Merge clusters List> alignedRes = msa.getBlock(0).getAlignRes(); - List thisAligned = new ArrayList(); - List otherAligned = new ArrayList(); + List thisAligned = new ArrayList<>(); + List otherAligned = new ArrayList<>(); // Extract the aligned residues of both Subunit for (int p = 0; p < msa.length(); p++) { @@ -467,24 +425,30 @@ public boolean mergeStructure(SubunitCluster other, SubunitClustererParameters p } } + updateEquivResidues(other, thisAligned, otherAligned); + + this.method = SubunitClustererMethod.STRUCTURE; + pseudoStoichiometric = true; + + return true; + } + + private void updateEquivResidues(SubunitCluster other, List thisAligned, List otherAligned) { // Do a List intersection to find out which EQR columns to remove - List thisRemove = new ArrayList(); - List otherRemove = new ArrayList(); + List thisRemove = new ArrayList<>(); + List otherRemove = new ArrayList<>(); for (int t = 0; t < this.subunitEQR.get(this.representative).size(); t++) { // If the index is aligned do nothing, otherwise mark as removing - if (!thisAligned.contains(this.subunitEQR.get(this.representative) - .get(t))) + if (!thisAligned.contains(this.subunitEQR.get(this.representative).get(t))) thisRemove.add(t); } for (int t = 0; t < other.subunitEQR.get(other.representative).size(); t++) { // If the index is aligned do nothing, otherwise mark as removing - if (!otherAligned.contains(other.subunitEQR.get( - other.representative).get(t))) + if (!otherAligned.contains(other.subunitEQR.get(other.representative).get(t))) otherRemove.add(t); } - // Now remove unaligned columns, from end to start Collections.sort(thisRemove); Collections.reverse(thisRemove); @@ -504,17 +468,12 @@ public boolean mergeStructure(SubunitCluster other, SubunitClustererParameters p } // The representative is the longest sequence - if (this.subunits.get(this.representative).size() < other.subunits.get( - other.representative).size()) + if (this.subunits.get(this.representative).size() < other.subunits.get(other.representative).size()) this.representative = other.representative + subunits.size(); this.subunits.addAll(other.subunits); this.subunitEQR.addAll(other.subunitEQR); - this.method = SubunitClustererMethod.STRUCTURE; - pseudoStoichiometric = true; - - return true; } /** @@ -564,9 +523,9 @@ public boolean divideInternally(SubunitClustererParameters clusterParams) List> alignedRes = result.getMultipleAlignment() .getBlock(0).getAlignRes(); - List> columns = new ArrayList>(); + List> columns = new ArrayList<>(); for (int s = 0; s < alignedRes.size(); s++) - columns.add(new ArrayList(alignedRes.get(s).size())); + columns.add(new ArrayList<>(alignedRes.get(s).size())); // Extract the aligned columns of each repeat in the Subunit for (int col = 0; col < alignedRes.get(0).size(); col++) { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java index 7c61472574..266b7a3f3e 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java @@ -56,12 +56,8 @@ public static Stoichiometry cluster(Structure structure, return cluster(subunits, params); } - public static Stoichiometry cluster(List subunits, - SubunitClustererParameters params) { - - // The collection of clusters to return - List clusters = new ArrayList(); - + public static Stoichiometry cluster(List subunits, SubunitClustererParameters params) { + List clusters = new ArrayList<>(); if (subunits.size() == 0) return new Stoichiometry(clusters); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java index a44309719e..52c7e305b7 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java @@ -52,8 +52,8 @@ public class TestSubunitCluster { @Test public void testMergeIdentical() { - // Create an Atom Array of ploy-alanine - List atoms = new ArrayList(10); + // Create an Atom Array of poly-alanine + List atoms = new ArrayList<>(10); for (int i = 0; i < 10; i++) { Group g = new AminoAcidImpl(); g.setPDBName("ALA"); @@ -79,7 +79,7 @@ public void testMergeIdentical() { assertEquals(sc1.length(), 10); // Create an Atom Array of poly-glycine - List atoms2 = new ArrayList(10); + List atoms2 = new ArrayList<>(10); for (int i = 0; i < 10; i++) { Group g = new AminoAcidImpl(); g.setPDBName("GLY"); @@ -112,7 +112,7 @@ public void testMergeIdentical() { public void testMergeSequence() throws CompoundNotFoundException { // Create an Atom Array of ploy-alanine - List atoms = new ArrayList(100); + List atoms = new ArrayList<>(100); for (int i = 0; i < 100; i++) { Group g = new AminoAcidImpl(); g.setPDBName("ALA"); @@ -163,7 +163,7 @@ public void testMergeSequence() throws CompoundNotFoundException { assertEquals(sc1.length(), 100); // Create an Atom Array of 9 glycine and 91 alanine - List atoms3 = new ArrayList(100); + List atoms3 = new ArrayList<>(100); for (int i = 0; i < 9; i++) { Group g = new AminoAcidImpl(); g.setPDBName("GLY"); From f3515a7e18c7ba6ca22590d8eae000897f602bf0 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 5 Jan 2020 09:15:34 -0800 Subject: [PATCH 030/769] Introduced optimization: now if switch is provided subunit clustering uses entity id infor. Some tests are failing --- .../structure/cluster/SubunitCluster.java | 65 ++++++++++++++++++- .../structure/cluster/SubunitClusterer.java | 13 +++- .../cluster/SubunitClustererParameters.java | 18 +++++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index 4a5356b842..ec051df33f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -31,6 +31,8 @@ import org.biojava.nbio.core.sequence.ProteinSequence; import org.biojava.nbio.core.sequence.compound.AminoAcidCompound; import org.biojava.nbio.structure.Atom; +import org.biojava.nbio.structure.Chain; +import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.align.StructureAlignment; import org.biojava.nbio.structure.align.StructureAlignmentFactory; @@ -45,6 +47,7 @@ import org.biojava.nbio.structure.align.multiple.MultipleAlignmentImpl; import org.biojava.nbio.structure.align.multiple.util.MultipleAlignmentScorer; import org.biojava.nbio.structure.align.multiple.util.ReferenceSuperimposer; +import org.biojava.nbio.structure.quaternary.BiologicalAssemblyBuilder; import org.biojava.nbio.structure.symmetry.core.QuatSymmetrySubunits; import org.biojava.nbio.structure.symmetry.internal.CESymmParameters; import org.biojava.nbio.structure.symmetry.internal.CeSymm; @@ -178,6 +181,38 @@ public boolean isIdenticalTo(SubunitCluster other) { return thisSequence.equals(otherSequence); } + /** + * Tells whether the other SubunitCluster contains exactly the same Subunit. + * This is checked by equality of their entity identifiers if they are present. + * + * @param other + * SubunitCluster + * @return true if the SubunitClusters are identical, false otherwise + */ + public boolean isIdenticalByEntityIdTo(SubunitCluster other) { + Structure thisStruct = this.subunits.get(this.representative).getStructure(); + Structure otherStruct = other.subunits.get(other.representative).getStructure(); + String thisName = this.subunits.get(this.representative).getName(); + String otherName = other.subunits.get(this.representative).getName(); + Chain thisChain = thisStruct.getChain(thisName); + Chain otherChain = otherStruct.getChain(otherName); + if (thisChain == null || otherChain == null) { + logger.info("Can't determine entity ids of SubunitClusters {}-{}. Ignoring identity check by entity id", + this.subunits.get(this.representative).getName(), + other.subunits.get(other.representative).getName()); + return false; + } + if (thisChain.getEntityInfo() == null || otherChain.getEntityInfo() == null) { + logger.info("Can't determine entity ids of SubunitClusters {}-{}. Ignoring identity check by entity id", + this.subunits.get(this.representative).getName(), + other.subunits.get(other.representative).getName()); + return false; + } + int thisEntityId = thisChain.getEntityInfo().getMolId(); + int otherEntityId = otherChain.getEntityInfo().getMolId(); + return thisEntityId == otherEntityId; + } + /** * Merges the other SubunitCluster into this one if it contains exactly the * same Subunit. This is checked by {@link #isIdenticalTo(SubunitCluster)}. @@ -191,7 +226,35 @@ public boolean mergeIdentical(SubunitCluster other) { if (!isIdenticalTo(other)) return false; - logger.info("SubunitClusters are identical"); + logger.info("SubunitClusters {}-{} are identical in sequence", + this.subunits.get(this.representative).getName(), + other.subunits.get(other.representative).getName()); + + this.subunits.addAll(other.subunits); + this.subunitEQR.addAll(other.subunitEQR); + + return true; + } + + /** + * Merges the other SubunitCluster into this one if it contains exactly the + * same Subunit. This is checked by comparing the entity identifiers of the subunits + * if one can be found. + * Thus this only makes sense when the subunits are complete chains of a + * deposited PDB entry. I + * + * @param other + * SubunitCluster + * @return true if the SubunitClusters were merged, false otherwise + */ + public boolean mergeIdenticalByEntityId(SubunitCluster other) { + + if (!isIdenticalByEntityIdTo(other)) + return false; + + logger.info("SubunitClusters {}-{} belong to same entity. Assuming they are identical", + this.subunits.get(this.representative).getName(), + other.subunits.get(other.representative).getName()); this.subunits.addAll(other.subunits); this.subunitEQR.addAll(other.subunitEQR); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java index 266b7a3f3e..92e0c135c1 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java @@ -71,7 +71,18 @@ public static Stoichiometry cluster(List subunits, SubunitClustererPara for (int c1 = 0; c1 < clusters.size(); c1++) { for (int c2 = clusters.size() - 1; c2 > c1; c2--) { try { - if (clusters.get(c1).mergeSequence(clusters.get(c2), params)) { + if (params.isUseEntityIdForSeqIdentityDetermination() && + clusters.get(c1).mergeIdenticalByEntityId(clusters.get(c2))) { + // This we will only do if the switch is for entity id comparison is on. + // In some cases in can save enormous amounts of time, e.g. for clustering full + // chains of deposited PDB entries. For instance for 6NHJ: with pure alignments it + // takes ~ 6 hours, with entity id comparisons it takes 2 minutes. + clusters.remove(c2); + } else if (clusters.get(c1).mergeIdentical(clusters.get(c2))) { + // This always makes sense as an optimization: it's far cheaper to compare the sequence + // string than doing a full S-W alignment + clusters.remove(c2); + } else if (clusters.get(c1).mergeSequence(clusters.get(c2), params)) { clusters.remove(c2); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClustererParameters.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClustererParameters.java index 5704012494..f3abae6c3e 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClustererParameters.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClustererParameters.java @@ -45,6 +45,8 @@ public class SubunitClustererParameters implements Serializable { private double sequenceIdentityThreshold; private double sequenceCoverageThreshold = 0.75; + private boolean useEntityIdForSeqIdentityDetermination = false; + private double rmsdThreshold = 3.0; private double structureCoverageThreshold = 0.75; private double tmThreshold = 0.5; @@ -506,5 +508,21 @@ public boolean isHighConfidenceScores(double sequenceIdentity, double sequenceCo return sequenceIdentity>=hcSequenceIdentityLocal && sequenceCoverage >= hcSequenceCoverageLocal; } + /** + * Whether to use the entity id of subunits to infer that sequences are identical. + * Only applies if the {@link SubunitClustererMethod} is a sequence based one. + * @return + */ + public boolean isUseEntityIdForSeqIdentityDetermination() { + return useEntityIdForSeqIdentityDetermination; + } + /** + * Whether to use the entity id of subunits to infer that sequences are identical. + * Only applies if the {@link SubunitClustererMethod} is a sequence based one. + * @param useEntityIdForSeqIdentityDetermination the flag to be set + */ + public void setUseEntityIdForSeqIdentityDetermination(boolean useEntityIdForSeqIdentityDetermination) { + this.useEntityIdForSeqIdentityDetermination = useEntityIdForSeqIdentityDetermination; + } } From 47e4cfb039c06a9e92368c9af07b5d1d154d383b Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 7 Jan 2020 10:51:53 -0800 Subject: [PATCH 031/769] Reverted change that caused TestQsAlignExamples to fail --- .../org/biojava/nbio/structure/cluster/SubunitCluster.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index ec051df33f..2ae2ccb83c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -518,14 +518,16 @@ private void updateEquivResidues(SubunitCluster other, List thisAligned Collections.sort(otherRemove); Collections.reverse(otherRemove); - for (Integer column : thisRemove) { + for (int t = 0; t < thisRemove.size(); t++) { for (List eqr : this.subunitEQR) { + int column = thisRemove.get(t); eqr.remove(column); } } - for (Integer column : otherRemove) { + for (int t = 0; t < otherRemove.size(); t++) { for (List eqr : other.subunitEQR) { + int column = otherRemove.get(t); eqr.remove(column); } } From 3b967b0da2d1eed31d6865da36e29f6cd85e2f88 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 7 Jan 2020 11:13:05 -0800 Subject: [PATCH 032/769] Using mergeIdentical breaks a test, reverting --- .../biojava/nbio/structure/cluster/SubunitClusterer.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java index 92e0c135c1..6295f8fdf0 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClusterer.java @@ -74,14 +74,10 @@ public static Stoichiometry cluster(List subunits, SubunitClustererPara if (params.isUseEntityIdForSeqIdentityDetermination() && clusters.get(c1).mergeIdenticalByEntityId(clusters.get(c2))) { // This we will only do if the switch is for entity id comparison is on. - // In some cases in can save enormous amounts of time, e.g. for clustering full + // In some cases it can save enormous amounts of time, e.g. for clustering full // chains of deposited PDB entries. For instance for 6NHJ: with pure alignments it // takes ~ 6 hours, with entity id comparisons it takes 2 minutes. clusters.remove(c2); - } else if (clusters.get(c1).mergeIdentical(clusters.get(c2))) { - // This always makes sense as an optimization: it's far cheaper to compare the sequence - // string than doing a full S-W alignment - clusters.remove(c2); } else if (clusters.get(c1).mergeSequence(clusters.get(c2), params)) { clusters.remove(c2); } From ae2c3bdebefb616e005ce3b7d41c452bb1b4c066 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 12 Jan 2020 10:20:57 -0800 Subject: [PATCH 033/769] Increasing the default num cells to explore in crystal reconstruction --- .../org/biojava/nbio/structure/xtal/CrystalBuilder.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/xtal/CrystalBuilder.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/xtal/CrystalBuilder.java index 5c8e2b2d7f..2bc6806b77 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/xtal/CrystalBuilder.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/xtal/CrystalBuilder.java @@ -59,8 +59,10 @@ public class CrystalBuilder { // is enormously long in comparison with the dimensions of the unit cell, some interfaces come at the 7th neighbor. // After a scan of the whole PDB (Oct 2013) using numCells=50, the highest one was 4jgc with // interfaces up to the 11th neighbor. Other high ones (9th neighbors) are 4jbm and 4k3t. - // We set the default value to 12 based on that (having not seen any difference in runtime) - public static final int DEF_NUM_CELLS = 12; + // We set the default value to 20 to be on the safe side. Runtime does not seem to be affected at all - JD 2020-01-12 + // Some good examples in this posting in CCP4: https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=CCP4BB;45b2755d.2001 + // in any case the 5m3h example in the posting seems to have contacts only up to the 11th neighbor. + public static final int DEF_NUM_CELLS = 20; /** * Default maximum distance between two chains to be considered an interface. From 6ac887746b1d7f7df93e7793e15d773557913961 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Mon, 20 Jan 2020 15:30:56 -0800 Subject: [PATCH 034/769] Extracting method in test --- .../structure/cluster/SubunitCluster.java | 2 +- .../structure/cluster/TestSubunitCluster.java | 97 ++++++++----------- 2 files changed, 39 insertions(+), 60 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index 2ae2ccb83c..392a102e51 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -241,7 +241,7 @@ public boolean mergeIdentical(SubunitCluster other) { * same Subunit. This is checked by comparing the entity identifiers of the subunits * if one can be found. * Thus this only makes sense when the subunits are complete chains of a - * deposited PDB entry. I + * deposited PDB entry. * * @param other * SubunitCluster diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java index 52c7e305b7..c54085fbe8 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java @@ -53,16 +53,7 @@ public class TestSubunitCluster { public void testMergeIdentical() { // Create an Atom Array of poly-alanine - List atoms = new ArrayList<>(10); - for (int i = 0; i < 10; i++) { - Group g = new AminoAcidImpl(); - g.setPDBName("ALA"); - Atom a = new AtomImpl(); - a.setName(StructureTools.CA_ATOM_NAME); - g.addAtom(a); - atoms.add(a); - } - Atom[] reprAtoms = atoms.toArray(new Atom[atoms.size()]); + Atom[] reprAtoms = mockAtomArray(10, "ALA", -1, null); // Create two identical SubunitCluster SubunitCluster sc1 = new SubunitCluster(new Subunit(reprAtoms, @@ -79,16 +70,7 @@ public void testMergeIdentical() { assertEquals(sc1.length(), 10); // Create an Atom Array of poly-glycine - List atoms2 = new ArrayList<>(10); - for (int i = 0; i < 10; i++) { - Group g = new AminoAcidImpl(); - g.setPDBName("GLY"); - Atom a = new AtomImpl(); - a.setName(StructureTools.CA_ATOM_NAME); - g.addAtom(a); - atoms2.add(a); - } - Atom[] reprAtoms2 = atoms2.toArray(new Atom[atoms2.size()]); + Atom[] reprAtoms2 = mockAtomArray(10, "GLY", -1, null); SubunitCluster sc3 = new SubunitCluster(new Subunit(reprAtoms2, "subunit 1", null, null)); @@ -111,17 +93,8 @@ public void testMergeIdentical() { @Test public void testMergeSequence() throws CompoundNotFoundException { - // Create an Atom Array of ploy-alanine - List atoms = new ArrayList<>(100); - for (int i = 0; i < 100; i++) { - Group g = new AminoAcidImpl(); - g.setPDBName("ALA"); - Atom a = new AtomImpl(); - a.setName(StructureTools.CA_ATOM_NAME); - g.addAtom(a); - atoms.add(a); - } - Atom[] reprAtoms = atoms.toArray(new Atom[atoms.size()]); + // Create an Atom Array of poly-alanine + Atom[] reprAtoms = mockAtomArray(100, "ALA", -1, null); // Create two identical SubunitCluster SubunitCluster sc1 = new SubunitCluster(new Subunit(reprAtoms, @@ -140,16 +113,7 @@ public void testMergeSequence() throws CompoundNotFoundException { assertEquals(sc1.length(), 100); // Create an Atom Array of poly-glycine - List atoms2 = new ArrayList(100); - for (int i = 0; i < 100; i++) { - Group g = new AminoAcidImpl(); - g.setPDBName("GLY"); - Atom a = new AtomImpl(); - a.setName(StructureTools.CA_ATOM_NAME); - g.addAtom(a); - atoms2.add(a); - } - Atom[] reprAtoms2 = atoms2.toArray(new Atom[atoms2.size()]); + Atom[] reprAtoms2 = mockAtomArray(100, "GLY", -1, null); SubunitCluster sc3 = new SubunitCluster(new Subunit(reprAtoms2, "subunit 3", null, null)); @@ -163,24 +127,7 @@ public void testMergeSequence() throws CompoundNotFoundException { assertEquals(sc1.length(), 100); // Create an Atom Array of 9 glycine and 91 alanine - List atoms3 = new ArrayList<>(100); - for (int i = 0; i < 9; i++) { - Group g = new AminoAcidImpl(); - g.setPDBName("GLY"); - Atom a = new AtomImpl(); - a.setName(StructureTools.CA_ATOM_NAME); - g.addAtom(a); - atoms3.add(a); - } - for (int i = 0; i < 91; i++) { - Group g = new AminoAcidImpl(); - g.setPDBName("ALA"); - Atom a = new AtomImpl(); - a.setName(StructureTools.CA_ATOM_NAME); - g.addAtom(a); - atoms3.add(a); - } - Atom[] reprAtoms3 = atoms3.toArray(new Atom[atoms3.size()]); + Atom[] reprAtoms3 = mockAtomArray(9, "GLY", 91, "ALA"); SubunitCluster sc4 = new SubunitCluster(new Subunit(reprAtoms3, "subunit 4", null, null)); @@ -283,4 +230,36 @@ public void testDivideInternally() throws StructureException, IOException { assertEquals(sc1.getAlignedAtomsSubunit(0).length, sc1.getAlignedAtomsSubunit(1).length); } + + /** + * Create a mock atom array, with size1 residues of type1, followed by size2 residues of type2 + * @param size1 the number of residues of type1 to add + * @param type1 the 3 letter code of residue + * @param size2 the number of residues of type2 to add, if -1 none are added + * @param type2 the 3 letter code of residue, if null none are added + * @return the mock atom array + */ + private Atom[] mockAtomArray(int size1, String type1, int size2, String type2) { + List atoms = new ArrayList<>(size1 + size2); + for (int i = 0; i < size1; i++) { + Group g = new AminoAcidImpl(); + g.setPDBName(type1); + Atom a = new AtomImpl(); + a.setName(StructureTools.CA_ATOM_NAME); + g.addAtom(a); + atoms.add(a); + } + + if (size2 >= 0 && type2 !=null) { + for (int i = 0; i < size2; i++) { + Group g = new AminoAcidImpl(); + g.setPDBName(type2); + Atom a = new AtomImpl(); + a.setName(StructureTools.CA_ATOM_NAME); + g.addAtom(a); + atoms.add(a); + } + } + return atoms.toArray(new Atom[0]); + } } From d415e3c8ace1ef49db25429f60bd928fd5767124 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Mon, 20 Jan 2020 16:10:47 -0800 Subject: [PATCH 035/769] New test --- .../structure/cluster/TestSubunitCluster.java | 94 ++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java index c54085fbe8..3947372521 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java @@ -30,10 +30,14 @@ import org.biojava.nbio.structure.AminoAcidImpl; import org.biojava.nbio.structure.Atom; import org.biojava.nbio.structure.AtomImpl; +import org.biojava.nbio.structure.Chain; +import org.biojava.nbio.structure.ChainImpl; +import org.biojava.nbio.structure.EntityInfo; import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; +import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; import org.junit.Test; @@ -85,6 +89,47 @@ public void testMergeIdentical() { } + @Test + public void testMergeIdenticalByEntityId() { + + // Create 2 Atom Arrays, with same entity id + Atom[] reprAtoms1 = mockAtomArray("A", 1, 10, "ALA", -1, null); + Structure structure1 = reprAtoms1[0].getGroup().getChain().getStructure(); + + Atom[] reprAtoms2 = mockAtomArray("B", 1, 10, "PRO", -1, null); + Structure structure2 = reprAtoms2[0].getGroup().getChain().getStructure(); + + // Create two SubunitCluster with same entity id + SubunitCluster sc1 = new SubunitCluster(new Subunit(reprAtoms1, + "A", null, structure1)); + SubunitCluster sc2 = new SubunitCluster(new Subunit(reprAtoms2, + "B", null, structure2)); + + boolean merged = sc1.mergeIdenticalByEntityId(sc2); + + // Merged have to be true, and the merged SubunitCluster is sc1 + assertTrue(merged); + assertEquals(2, sc1.size()); + assertEquals(1, sc2.size()); + assertEquals(10, sc1.length()); + + // Create an Atom Array of poly-glycine with a different entity id + Atom[] reprAtoms3 = mockAtomArray("A", 2, 10, "GLY", -1, null); + Structure structure3 = reprAtoms2[0].getGroup().getChain().getStructure(); + + SubunitCluster sc3 = new SubunitCluster(new Subunit(reprAtoms3, + "A", null, structure3)); + + merged = sc1.mergeIdenticalByEntityId(sc3); + + // Merged have to be false, and Clusters result unmodified + assertFalse(merged); + assertEquals(2, sc1.size()); + assertEquals(1, sc2.size()); + assertEquals(10, sc1.length()); + + } + /** * Test {@link SubunitCluster#mergeSequence(SubunitCluster, SubunitClustererParameters)} * @@ -232,7 +277,8 @@ public void testDivideInternally() throws StructureException, IOException { } /** - * Create a mock atom array, with size1 residues of type1, followed by size2 residues of type2 + * Create a mock atom array, with size1 residues of type1, followed by size2 residues of type2. + * * @param size1 the number of residues of type1 to add * @param type1 the 3 letter code of residue * @param size2 the number of residues of type2 to add, if -1 none are added @@ -240,10 +286,55 @@ public void testDivideInternally() throws StructureException, IOException { * @return the mock atom array */ private Atom[] mockAtomArray(int size1, String type1, int size2, String type2) { + + List atoms = new ArrayList<>(size1 + size2); + for (int i = 0; i < size1; i++) { + Group g = new AminoAcidImpl(); + g.setPDBName(type1); + Atom a = new AtomImpl(); + a.setName(StructureTools.CA_ATOM_NAME); + g.addAtom(a); + atoms.add(a); + } + + if (size2 >= 0 && type2 !=null) { + for (int i = 0; i < size2; i++) { + Group g = new AminoAcidImpl(); + g.setPDBName(type2); + Atom a = new AtomImpl(); + a.setName(StructureTools.CA_ATOM_NAME); + g.addAtom(a); + atoms.add(a); + } + } + return atoms.toArray(new Atom[0]); + } + + /** + * Create a mock atom array, with size1 residues of type1, followed by size2 residues of type2. + * + * @param chainId a chain with this chain id will be set as parent of groups + * @param entityId an entity with this id will be set as parent of chain + * @param size1 the number of residues of type1 to add + * @param type1 the 3 letter code of residue + * @param size2 the number of residues of type2 to add, if -1 none are added + * @param type2 the 3 letter code of residue, if null none are added + * @return the mock atom array + */ + private Atom[] mockAtomArray(String chainId, int entityId, int size1, String type1, int size2, String type2) { + Chain chain = new ChainImpl(); + Structure structure = new StructureImpl(); + chain.setId(chainId); + structure.addChain(chain); + EntityInfo entityInfo = new EntityInfo(); + entityInfo.setMolId(entityId); + chain.setEntityInfo(entityInfo); + List atoms = new ArrayList<>(size1 + size2); for (int i = 0; i < size1; i++) { Group g = new AminoAcidImpl(); g.setPDBName(type1); + chain.addGroup(g); Atom a = new AtomImpl(); a.setName(StructureTools.CA_ATOM_NAME); g.addAtom(a); @@ -254,6 +345,7 @@ private Atom[] mockAtomArray(int size1, String type1, int size2, String type2) { for (int i = 0; i < size2; i++) { Group g = new AminoAcidImpl(); g.setPDBName(type2); + chain.addGroup(g); Atom a = new AtomImpl(); a.setName(StructureTools.CA_ATOM_NAME); g.addAtom(a); From 679f84081a8afe5f0b162fd9a9ac8c3ebb971de5 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Mon, 20 Jan 2020 16:18:09 -0800 Subject: [PATCH 036/769] Right order of params --- .../structure/cluster/TestSubunitCluster.java | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java index 3947372521..585c4f1d1c 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java @@ -69,9 +69,9 @@ public void testMergeIdentical() { // Merged have to be true, and the merged SubunitCluster is sc1 assertTrue(merged); - assertEquals(sc1.size(), 2); - assertEquals(sc2.size(), 1); - assertEquals(sc1.length(), 10); + assertEquals(2, sc1.size()); + assertEquals(1, sc2.size()); + assertEquals(10, sc1.length()); // Create an Atom Array of poly-glycine Atom[] reprAtoms2 = mockAtomArray(10, "GLY", -1, null); @@ -83,9 +83,9 @@ public void testMergeIdentical() { // Merged have to be false, and Clusters result inmodified assertFalse(merged); - assertEquals(sc1.size(), 2); - assertEquals(sc2.size(), 1); - assertEquals(sc1.length(), 10); + assertEquals(2, sc1.size()); + assertEquals(1, sc2.size()); + assertEquals(10, sc1.length()); } @@ -153,9 +153,9 @@ public void testMergeSequence() throws CompoundNotFoundException { // Merged have to be true, and the merged SubunitCluster is sc1 assertTrue(merged); - assertEquals(sc1.size(), 2); - assertEquals(sc2.size(), 1); - assertEquals(sc1.length(), 100); + assertEquals(2, sc1.size()); + assertEquals(1, sc2.size()); + assertEquals(100, sc1.length()); // Create an Atom Array of poly-glycine Atom[] reprAtoms2 = mockAtomArray(100, "GLY", -1, null); @@ -167,9 +167,9 @@ public void testMergeSequence() throws CompoundNotFoundException { // Merged have to be false, and Clusters result inmodified assertFalse(merged); - assertEquals(sc1.size(), 2); - assertEquals(sc2.size(), 1); - assertEquals(sc1.length(), 100); + assertEquals(2, sc1.size()); + assertEquals(1, sc2.size()); + assertEquals(100, sc1.length()); // Create an Atom Array of 9 glycine and 91 alanine Atom[] reprAtoms3 = mockAtomArray(9, "GLY", 91, "ALA"); @@ -181,9 +181,9 @@ public void testMergeSequence() throws CompoundNotFoundException { // Merged have to be true, and the merged SubunitCluster is sc1 assertTrue(merged); - assertEquals(sc1.size(), 3); - assertEquals(sc2.size(), 1); - assertEquals(sc1.length(), 91); + assertEquals(3, sc1.size()); + assertEquals(1, sc2.size()); + assertEquals(91, sc1.length()); } @@ -224,10 +224,10 @@ public void testMergeStructure() throws StructureException, IOException { // Merged have to be true, and the merged SubunitCluster is sc1 assertTrue(merged13); assertTrue(merged24); - assertEquals(sc1.size(), 2); - assertEquals(sc2.size(), 2); - assertEquals(sc1.length(), 141); - assertEquals(sc2.length(), 146); + assertEquals(2, sc1.size()); + assertEquals(2, sc2.size()); + assertEquals(141, sc1.length()); + assertEquals(146, sc2.length()); assertEquals(sc1.getAlignedAtomsSubunit(0).length, sc1.getAlignedAtomsSubunit(1).length); assertEquals(sc2.getAlignedAtomsSubunit(0).length, @@ -237,8 +237,8 @@ public void testMergeStructure() throws StructureException, IOException { boolean merged = sc1.mergeStructure(sc2, clustererParameters); assertTrue(merged); - assertEquals(sc1.size(), 4); - assertEquals(sc1.length(), 140, 2); + assertEquals(4, sc1.size()); + assertEquals(140, sc1.length(), 2); assertEquals(sc1.getAlignedAtomsSubunit(0).length, sc1.getAlignedAtomsSubunit(2).length); @@ -270,7 +270,7 @@ public void testDivideInternally() throws StructureException, IOException { // Divided has to be true, and Subunit length shorter than half assertTrue(divided); - assertEquals(sc1.size(), 2); + assertEquals(2, sc1.size()); assertTrue(sc1.length() < 178); assertEquals(sc1.getAlignedAtomsSubunit(0).length, sc1.getAlignedAtomsSubunit(1).length); From 4d6a504c95e173ad9cd56a8cd44689a8c0bf6884 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 21 Jan 2020 15:34:48 -0800 Subject: [PATCH 037/769] Now testing for subunit clustering with entity ids --- .../TestQuatSymmetryDetectorExamples.java | 24 ++++ .../structure/cluster/TestSubunitCluster.java | 108 +++++++++++------- 2 files changed, 89 insertions(+), 43 deletions(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java index 1b69ec3efc..5f3d0b4881 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java @@ -366,4 +366,28 @@ public void testPseudoIdentity95() throws IOException, StructureException { assertEquals(SubunitClustererMethod.SEQUENCE, symmetry.getSubunitClusters().get(0).getClustererMethod()); } + + @Test + public void testSymDetectionWithSubunitClusterByEntityId() throws IOException, StructureException { + Structure pdb = StructureIO.getStructure("BIO:1SMT:1"); + + SubunitClustererParameters cp = new SubunitClustererParameters(); +// cp.setOptimizeAlignment(false); +// cp.setSequenceIdentityThreshold(0.75); +// cp.setMinimumSequenceLength(3); +// cp.setAbsoluteMinimumSequenceLength(3); +// cp.setUseSequenceCoverage(false); +// cp.setUseStructureCoverage(false); +// cp.setUseRMSD(false); + cp.setUseEntityIdForSeqIdentityDetermination(true); + cp.setClustererMethod(SubunitClustererMethod.SEQUENCE); + QuatSymmetryParameters symmParams = new QuatSymmetryParameters(); +// symmParams.setOnTheFly(true); + QuatSymmetryResults symmetry = QuatSymmetryDetector.calcGlobalSymmetry( + pdb, symmParams, cp); + + // C2 symmetry, A2 stoichiometry + assertEquals("C2", symmetry.getSymmetry()); + assertEquals("A2", symmetry.getStoichiometry().toString()); + } } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java index 585c4f1d1c..4b6e55ee28 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/cluster/TestSubunitCluster.java @@ -34,6 +34,7 @@ import org.biojava.nbio.structure.ChainImpl; import org.biojava.nbio.structure.EntityInfo; import org.biojava.nbio.structure.Group; +import org.biojava.nbio.structure.ResidueNumber; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; @@ -93,17 +94,15 @@ public void testMergeIdentical() { public void testMergeIdenticalByEntityId() { // Create 2 Atom Arrays, with same entity id - Atom[] reprAtoms1 = mockAtomArray("A", 1, 10, "ALA", -1, null); - Structure structure1 = reprAtoms1[0].getGroup().getChain().getStructure(); - - Atom[] reprAtoms2 = mockAtomArray("B", 1, 10, "PRO", -1, null); - Structure structure2 = reprAtoms2[0].getGroup().getChain().getStructure(); + Structure structure = mockStructure(); + Atom[] reprAtoms1 = getAtomArray(structure.getChain("A")); + Atom[] reprAtoms2 = getAtomArray(structure.getChain("B")); // Create two SubunitCluster with same entity id SubunitCluster sc1 = new SubunitCluster(new Subunit(reprAtoms1, - "A", null, structure1)); + "A", null, structure)); SubunitCluster sc2 = new SubunitCluster(new Subunit(reprAtoms2, - "B", null, structure2)); + "B", null, structure)); boolean merged = sc1.mergeIdenticalByEntityId(sc2); @@ -111,14 +110,13 @@ public void testMergeIdenticalByEntityId() { assertTrue(merged); assertEquals(2, sc1.size()); assertEquals(1, sc2.size()); - assertEquals(10, sc1.length()); + assertEquals(9, sc1.length()); // Create an Atom Array of poly-glycine with a different entity id - Atom[] reprAtoms3 = mockAtomArray("A", 2, 10, "GLY", -1, null); - Structure structure3 = reprAtoms2[0].getGroup().getChain().getStructure(); + Atom[] reprAtoms3 = getAtomArray(structure.getChain("C")); SubunitCluster sc3 = new SubunitCluster(new Subunit(reprAtoms3, - "A", null, structure3)); + "C", null, structure)); merged = sc1.mergeIdenticalByEntityId(sc3); @@ -126,7 +124,7 @@ public void testMergeIdenticalByEntityId() { assertFalse(merged); assertEquals(2, sc1.size()); assertEquals(1, sc2.size()); - assertEquals(10, sc1.length()); + assertEquals(9, sc1.length()); } @@ -311,47 +309,71 @@ private Atom[] mockAtomArray(int size1, String type1, int size2, String type2) { } /** - * Create a mock atom array, with size1 residues of type1, followed by size2 residues of type2. - * - * @param chainId a chain with this chain id will be set as parent of groups - * @param entityId an entity with this id will be set as parent of chain - * @param size1 the number of residues of type1 to add - * @param type1 the 3 letter code of residue - * @param size2 the number of residues of type2 to add, if -1 none are added - * @param type2 the 3 letter code of residue, if null none are added - * @return the mock atom array + * Create a mock structure with 2 entities 1 (chains A, B) and 2 (chain C). + * @return a structure */ - private Atom[] mockAtomArray(String chainId, int entityId, int size1, String type1, int size2, String type2) { - Chain chain = new ChainImpl(); + private Structure mockStructure() { Structure structure = new StructureImpl(); - chain.setId(chainId); - structure.addChain(chain); - EntityInfo entityInfo = new EntityInfo(); - entityInfo.setMolId(entityId); - chain.setEntityInfo(entityInfo); + EntityInfo entity1 = new EntityInfo(); + entity1.setMolId(1); + EntityInfo entity2 = new EntityInfo(); + entity2.setMolId(2); + structure.addEntityInfo(entity1); + structure.addEntityInfo(entity2); + + Chain chainA = new ChainImpl(); + chainA.setId("A"); + Chain chainB = new ChainImpl(); + chainB.setId("B"); + entity1.addChain(chainA); + entity1.addChain(chainB); + Chain chainC = new ChainImpl(); + chainC.setId("C"); + entity2.addChain(chainC); + + structure.addChain(chainA); + structure.addChain(chainB); + structure.addChain(chainC); + + // entity 1: chain A 10 observed residues, chain B 9 observed residues (first unobserved) + List aGroups = getGroupList(10, "ALA", chainA); + chainA.setAtomGroups(new ArrayList<>(aGroups)); + chainA.setSeqResGroups(aGroups); + chainA.setEntityInfo(entity1); + + List bGroups = getGroupList(10, "ALA", chainB); + chainB.setAtomGroups(new ArrayList<>(bGroups.subList(1,10))); + chainB.setSeqResGroups(bGroups); + chainB.setEntityInfo(entity1); + + List cGroups = getGroupList(20, "GLY", chainC); + chainC.setAtomGroups(new ArrayList<>(cGroups)); + chainC.setSeqResGroups(cGroups); + chainC.setEntityInfo(entity2); + + return structure; + } - List atoms = new ArrayList<>(size1 + size2); - for (int i = 0; i < size1; i++) { + private List getGroupList(int size, String type, Chain chain) { + List list = new ArrayList<>(); + for (int i=0;i= 0 && type2 !=null) { - for (int i = 0; i < size2; i++) { - Group g = new AminoAcidImpl(); - g.setPDBName(type2); - chain.addGroup(g); - Atom a = new AtomImpl(); - a.setName(StructureTools.CA_ATOM_NAME); - g.addAtom(a); - atoms.add(a); - } + private Atom[] getAtomArray(Chain chain) { + Atom[] atoms = new Atom[chain.getAtomGroups().size()]; + for (int i = 0; i Date: Tue, 21 Jan 2020 15:37:36 -0800 Subject: [PATCH 038/769] Removing comments --- .../test/symmetry/TestQuatSymmetryDetectorExamples.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java index 5f3d0b4881..364a9e0b42 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java @@ -372,17 +372,9 @@ public void testSymDetectionWithSubunitClusterByEntityId() throws IOException, S Structure pdb = StructureIO.getStructure("BIO:1SMT:1"); SubunitClustererParameters cp = new SubunitClustererParameters(); -// cp.setOptimizeAlignment(false); -// cp.setSequenceIdentityThreshold(0.75); -// cp.setMinimumSequenceLength(3); -// cp.setAbsoluteMinimumSequenceLength(3); -// cp.setUseSequenceCoverage(false); -// cp.setUseStructureCoverage(false); -// cp.setUseRMSD(false); cp.setUseEntityIdForSeqIdentityDetermination(true); cp.setClustererMethod(SubunitClustererMethod.SEQUENCE); QuatSymmetryParameters symmParams = new QuatSymmetryParameters(); -// symmParams.setOnTheFly(true); QuatSymmetryResults symmetry = QuatSymmetryDetector.calcGlobalSymmetry( pdb, symmParams, cp); From fc543afa5a69309f4a08b9a109878ca4db000e34 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 21 Jan 2020 15:39:39 -0800 Subject: [PATCH 039/769] Fixing the cluster by entity id alignment issue. Now tests pass --- .../structure/cluster/SubunitCluster.java | 47 +++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index 392a102e51..e270bcfe8a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -32,6 +32,8 @@ import org.biojava.nbio.core.sequence.compound.AminoAcidCompound; import org.biojava.nbio.structure.Atom; import org.biojava.nbio.structure.Chain; +import org.biojava.nbio.structure.EntityInfo; +import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.align.StructureAlignment; @@ -252,12 +254,49 @@ public boolean mergeIdenticalByEntityId(SubunitCluster other) { if (!isIdenticalByEntityIdTo(other)) return false; + Subunit thisSub = this.subunits.get(this.representative); + Subunit otherSub = other.subunits.get(other.representative); logger.info("SubunitClusters {}-{} belong to same entity. Assuming they are identical", - this.subunits.get(this.representative).getName(), - other.subunits.get(other.representative).getName()); + thisSub.getName(), + otherSub.getName()); - this.subunits.addAll(other.subunits); - this.subunitEQR.addAll(other.subunitEQR); + List thisAligned = new ArrayList<>(); + List otherAligned = new ArrayList<>(); + + // we've merged by entity id, we can assume structure, chain and entity are available + Structure thisStruct = thisSub.getStructure(); + Structure otherStruct = otherSub.getStructure(); + String thisName = thisSub.getName(); + String otherName = otherSub.getName(); + Chain thisChain = thisStruct.getChain(thisName); + Chain otherChain = otherStruct.getChain(otherName); + EntityInfo entityInfo = thisChain.getEntityInfo(); + + // Extract the aligned residues of both Subunits + for (int thisIndex=0; thisIndex < thisSub.size(); thisIndex++) { + + Group g = thisSub.getRepresentativeAtoms()[thisIndex].getGroup(); + + int seqresIndex = entityInfo.getAlignedResIndex(g, thisChain); + + Group otherG = otherChain.getSeqResGroups().get(seqresIndex - 1); + + if (!otherChain.getAtomGroups().contains(otherG)) { + // skip residues that are unobserved in other sequence ("gaps" in the entity alignment) + continue; + } + + int otherIndex = otherChain.getAtomGroups().indexOf(otherG); + + // Only consider residues that are part of the SubunitCluster + if (this.subunitEQR.get(this.representative).contains(thisIndex) + && other.subunitEQR.get(other.representative).contains(otherIndex)) { + thisAligned.add(thisIndex); + otherAligned.add(otherIndex); + } + } + + updateEquivResidues(other, thisAligned, otherAligned); return true; } From 8b76e96a7af6b0118025b8a906b64de11b0d9693 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 21 Jan 2020 16:01:52 -0800 Subject: [PATCH 040/769] Some improvements --- .../biojava/nbio/structure/EntityInfo.java | 6 +-- .../structure/cluster/SubunitCluster.java | 40 +++++++++++++------ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/EntityInfo.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/EntityInfo.java index b2438763f3..cc52262b12 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/EntityInfo.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/EntityInfo.java @@ -306,12 +306,12 @@ public List getChainIds() { * used and when all chains within the entity are numbered in the same way), but * in general they will be neither unique (because of insertion codes) nor aligned. *

- * @param g - * @param c + * @param g the group + * @param c the chain * @return the aligned residue index (1 to n), if no SEQRES groups are available at all then {@link ResidueNumber#getSeqNum()} * is returned as a fall-back, if the group is not found in the SEQRES groups then -1 is returned * for the given group and chain - * @throws IllegalArgumentException if the given Chain is not a member of this EnityInfo + * @throws IllegalArgumentException if the given Chain is not a member of this EntityInfo * @see Chain#getSeqResGroup(int) */ public int getAlignedResIndex(Group g, Chain c) { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index e270bcfe8a..32235d0ab7 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -192,22 +192,35 @@ public boolean isIdenticalTo(SubunitCluster other) { * @return true if the SubunitClusters are identical, false otherwise */ public boolean isIdenticalByEntityIdTo(SubunitCluster other) { - Structure thisStruct = this.subunits.get(this.representative).getStructure(); - Structure otherStruct = other.subunits.get(other.representative).getStructure(); - String thisName = this.subunits.get(this.representative).getName(); - String otherName = other.subunits.get(this.representative).getName(); + Subunit thisSub = this.subunits.get(this.representative); + Subunit otherSub = other.subunits.get(other.representative); + String thisName = thisSub.getName(); + String otherName = otherSub.getName(); + + Structure thisStruct = thisSub.getStructure(); + Structure otherStruct = otherSub.getStructure(); + if (thisStruct == null || otherStruct == null) { + logger.info("SubunitClusters {}-{} have no referenced structures. Ignoring identity check by entity id", + thisName, + otherName); + return false; + } + if (thisStruct != otherStruct) { + // different object references: will not cluster even if entity id is same + return false; + } Chain thisChain = thisStruct.getChain(thisName); Chain otherChain = otherStruct.getChain(otherName); if (thisChain == null || otherChain == null) { logger.info("Can't determine entity ids of SubunitClusters {}-{}. Ignoring identity check by entity id", - this.subunits.get(this.representative).getName(), - other.subunits.get(other.representative).getName()); + thisName, + otherName); return false; } if (thisChain.getEntityInfo() == null || otherChain.getEntityInfo() == null) { logger.info("Can't determine entity ids of SubunitClusters {}-{}. Ignoring identity check by entity id", - this.subunits.get(this.representative).getName(), - other.subunits.get(other.representative).getName()); + thisName, + otherName); return false; } int thisEntityId = thisChain.getEntityInfo().getMolId(); @@ -256,18 +269,19 @@ public boolean mergeIdenticalByEntityId(SubunitCluster other) { Subunit thisSub = this.subunits.get(this.representative); Subunit otherSub = other.subunits.get(other.representative); + String thisName = thisSub.getName(); + String otherName = otherSub.getName(); + logger.info("SubunitClusters {}-{} belong to same entity. Assuming they are identical", - thisSub.getName(), - otherSub.getName()); + thisName, + otherName); List thisAligned = new ArrayList<>(); List otherAligned = new ArrayList<>(); - // we've merged by entity id, we can assume structure, chain and entity are available + // we've merged by entity id, we can assume structure, chain and entity are available (checked in isIdenticalByEntityIdTo()) Structure thisStruct = thisSub.getStructure(); Structure otherStruct = otherSub.getStructure(); - String thisName = thisSub.getName(); - String otherName = otherSub.getName(); Chain thisChain = thisStruct.getChain(thisName); Chain otherChain = otherStruct.getChain(otherName); EntityInfo entityInfo = thisChain.getEntityInfo(); From d851f6078b50e7fbe5ffde3ff23d7bf16d4a211a Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 21 Jan 2020 16:40:53 -0800 Subject: [PATCH 041/769] More checks and a warning in case no aligned atoms found. Also a few minor fixes --- .../TestQuatSymmetryDetectorExamples.java | 8 ++++++++ .../structure/cluster/SubunitCluster.java | 11 +++++++++- .../symmetry/core/C2RotationSolver.java | 7 +++---- .../symmetry/core/QuatSymmetrySubunits.java | 20 +++++++++---------- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java index 364a9e0b42..550fb542a4 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java @@ -32,6 +32,7 @@ import org.biojava.nbio.structure.cluster.SubunitClusterer; import org.biojava.nbio.structure.cluster.SubunitClustererMethod; import org.biojava.nbio.structure.cluster.SubunitClustererParameters; +import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.symmetry.core.QuatSymmetryDetector; import org.biojava.nbio.structure.symmetry.core.QuatSymmetryParameters; import org.biojava.nbio.structure.symmetry.core.QuatSymmetryResults; @@ -369,6 +370,13 @@ public void testPseudoIdentity95() throws IOException, StructureException { @Test public void testSymDetectionWithSubunitClusterByEntityId() throws IOException, StructureException { + AtomCache cache = new AtomCache(); + cache.setUseMmtf(false); + cache.setUseMmCif(true); + FileParsingParameters params = new FileParsingParameters(); + params.setAlignSeqRes(true); + cache.setFileParsingParams(params); + StructureIO.setAtomCache(cache); Structure pdb = StructureIO.getStructure("BIO:1SMT:1"); SubunitClustererParameters cp = new SubunitClustererParameters(); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index 32235d0ab7..986f092775 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -293,6 +293,11 @@ public boolean mergeIdenticalByEntityId(SubunitCluster other) { int seqresIndex = entityInfo.getAlignedResIndex(g, thisChain); + if (seqresIndex == -1) { + // this might mean that FileParsingParameters.setAlignSeqRes() wasn't set to true during parsing + continue; + } + Group otherG = otherChain.getSeqResGroups().get(seqresIndex - 1); if (!otherChain.getAtomGroups().contains(otherG)) { @@ -310,6 +315,10 @@ public boolean mergeIdenticalByEntityId(SubunitCluster other) { } } + if (thisAligned.size() == 0 && otherAligned.size() == 0) { + logger.warn("No equivalent aligned atoms found between SubunitClusters {}-{} via entity seqres alignment. Is FileParsingParameters.setAlignSeqRes() set?", thisName, otherName); + } + updateEquivResidues(other, thisAligned, otherAligned); return true; @@ -743,7 +752,7 @@ public SubunitClustererMethod getClustererMethod() { */ public List getAlignedAtomsSubunits() { - List alignedAtoms = Collections.emptyList(); + List alignedAtoms = new ArrayList<>(); // Loop through all subunits and add the aligned positions for (int s = 0; s < subunits.size(); s++) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/C2RotationSolver.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/C2RotationSolver.java index 0d81d4ce5b..90b3a3f6e1 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/C2RotationSolver.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/C2RotationSolver.java @@ -39,8 +39,8 @@ * @author Peter */ public class C2RotationSolver implements QuatSymmetrySolver { - private QuatSymmetrySubunits subunits = null; - private QuatSymmetryParameters parameters = null; + private QuatSymmetrySubunits subunits; + private QuatSymmetryParameters parameters; private Vector3d centroid = new Vector3d(); private Matrix4d centroidInverse = new Matrix4d(); @@ -132,7 +132,7 @@ private void solve() { } private void addEOperation() { - List permutation = Arrays.asList(new Integer[]{0,1}); + List permutation = Arrays.asList(0,1); Matrix4d transformation = new Matrix4d(); transformation.setIdentity(); combineWithTranslation(transformation); @@ -145,7 +145,6 @@ private void addEOperation() { /** * Adds translational component to rotation matrix - * @param rotTrans * @param rotation * @return */ diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/QuatSymmetrySubunits.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/QuatSymmetrySubunits.java index 92b2786e8c..27d16cd6fe 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/QuatSymmetrySubunits.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/symmetry/core/QuatSymmetrySubunits.java @@ -21,6 +21,7 @@ package org.biojava.nbio.structure.symmetry.core; import org.biojava.nbio.structure.Atom; +import org.biojava.nbio.structure.Calc; import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.cluster.SubunitCluster; import org.biojava.nbio.structure.geometry.CalcPoint; @@ -34,7 +35,7 @@ import java.util.stream.Collectors; /** - * A bean to represent information about the set of {@link Subunit} being + * A bean to represent information about the set of {@link org.biojava.nbio.structure.cluster.Subunit}s being * considered for symmetry detection. This class is a helper for the * {@link QuatSymmetryDetector} algorithm, since it calculates and caches the * {@link MomentsOfInertia} and the centroids of each Subunit. @@ -45,13 +46,13 @@ */ public class QuatSymmetrySubunits { - private List caCoords = new ArrayList(); - private List originalCenters = new ArrayList(); - private List centers = new ArrayList(); - private List unitVectors = new ArrayList(); + private List caCoords = new ArrayList<>(); + private List originalCenters = new ArrayList<>(); + private List centers = new ArrayList<>(); + private List unitVectors = new ArrayList<>(); - private List folds = new ArrayList(); - private List clusterIds = new ArrayList(); + private List folds = new ArrayList<>(); + private List clusterIds = new ArrayList<>(); private List clusters; private Point3d centroid; @@ -75,10 +76,7 @@ public QuatSymmetrySubunits(List clusters) { clusterIds.add(c); Atom[] atoms = clusters.get(c).getAlignedAtomsSubunit(s); - // Convert atoms to points - Point3d[] points = new Point3d[atoms.length]; - for (int i = 0; i < atoms.length; i++) - points[i] = atoms[i].getCoordsAsPoint3d(); + Point3d[] points = Calc.atomsToPoints(atoms); caCoords.add(points); } From f54b62595cb799481a7e2aef3212388c74929335 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 21 Jan 2020 16:48:24 -0800 Subject: [PATCH 042/769] Small optimization --- .../biojava/nbio/structure/cluster/SubunitCluster.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java index 986f092775..d73d747cb6 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitCluster.java @@ -298,15 +298,15 @@ public boolean mergeIdenticalByEntityId(SubunitCluster other) { continue; } + // note the seqresindex is 1-based Group otherG = otherChain.getSeqResGroups().get(seqresIndex - 1); - if (!otherChain.getAtomGroups().contains(otherG)) { - // skip residues that are unobserved in other sequence ("gaps" in the entity alignment) + int otherIndex = otherChain.getAtomGroups().indexOf(otherG); + if (otherIndex == -1) { + // skip residues that are unobserved in other sequence ("gaps" in the entity SEQRES alignment) continue; } - int otherIndex = otherChain.getAtomGroups().indexOf(otherG); - // Only consider residues that are part of the SubunitCluster if (this.subunitEQR.get(this.representative).contains(thisIndex) && other.subunitEQR.get(other.representative).contains(otherIndex)) { @@ -316,7 +316,7 @@ public boolean mergeIdenticalByEntityId(SubunitCluster other) { } if (thisAligned.size() == 0 && otherAligned.size() == 0) { - logger.warn("No equivalent aligned atoms found between SubunitClusters {}-{} via entity seqres alignment. Is FileParsingParameters.setAlignSeqRes() set?", thisName, otherName); + logger.warn("No equivalent aligned atoms found between SubunitClusters {}-{} via entity SEQRES alignment. Is FileParsingParameters.setAlignSeqRes() set?", thisName, otherName); } updateEquivResidues(other, thisAligned, otherAligned); From ed322e387cd46344a7864ac58b60c38df7c37633 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 21 Jan 2020 17:12:29 -0800 Subject: [PATCH 043/769] Docs, a new StructureTools method and a new performance test (ignored) --- .../TestQuatSymmetryDetectorExamples.java | 41 ++++++++++++++++++- .../nbio/structure/StructureTools.java | 30 +++++++++++--- .../cluster/SubunitClustererParameters.java | 6 ++- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java index 550fb542a4..0d094a059a 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java @@ -28,15 +28,19 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; +import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.cluster.SubunitClusterer; import org.biojava.nbio.structure.cluster.SubunitClustererMethod; import org.biojava.nbio.structure.cluster.SubunitClustererParameters; import org.biojava.nbio.structure.io.FileParsingParameters; +import org.biojava.nbio.structure.quaternary.BiologicalAssemblyBuilder; +import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; import org.biojava.nbio.structure.symmetry.core.QuatSymmetryDetector; import org.biojava.nbio.structure.symmetry.core.QuatSymmetryParameters; import org.biojava.nbio.structure.symmetry.core.QuatSymmetryResults; import org.biojava.nbio.structure.symmetry.core.Stoichiometry; +import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -369,7 +373,7 @@ public void testPseudoIdentity95() throws IOException, StructureException { } @Test - public void testSymDetectionWithSubunitClusterByEntityId() throws IOException, StructureException { + public void testSymDetectionWithClusteringByEntityId() throws IOException, StructureException { AtomCache cache = new AtomCache(); cache.setUseMmtf(false); cache.setUseMmCif(true); @@ -390,4 +394,39 @@ public void testSymDetectionWithSubunitClusterByEntityId() throws IOException, S assertEquals("C2", symmetry.getSymmetry()); assertEquals("A2", symmetry.getStoichiometry().toString()); } + + /** + * A performance test that demonstrates how the SubunitClustererParameters.setUseEntityIdForSeqIdentityDetermination() + * has a dramatic effect in runtime versus doing alignments. + * This takes minutes with the parameter on, but hours without the parameter. + */ + @Ignore("This is a performance test to be run manually") + @Test + public void testSymDetectionPerformanceLargeCapsid() throws IOException, StructureException { + AtomCache cache = new AtomCache(); + cache.setUseMmtf(false); + cache.setUseMmCif(true); + FileParsingParameters params = new FileParsingParameters(); + params.setAlignSeqRes(true); + params.setParseBioAssembly(true); + cache.setFileParsingParams(params); + StructureIO.setAtomCache(cache); + + // making sure we remove all atoms but representative before we expand, otherwise memory requirements are huge + Structure au = StructureIO.getStructure("6NHJ"); + StructureTools.reduceToRepresentativeAtoms(au); + BiologicalAssemblyBuilder builder = new BiologicalAssemblyBuilder(); + List transforms = au.getPDBHeader().getBioAssemblies().get(1).getTransforms(); + Structure pdb =builder.rebuildQuaternaryStructure(au, transforms, true, false); + + SubunitClustererParameters cp = new SubunitClustererParameters(); + cp.setUseEntityIdForSeqIdentityDetermination(true); // this is the parameter that makes this fast + cp.setClustererMethod(SubunitClustererMethod.SEQUENCE); + QuatSymmetryParameters symmParams = new QuatSymmetryParameters(); + QuatSymmetryResults symmetry = QuatSymmetryDetector.calcGlobalSymmetry( + pdb, symmParams, cp); + + assertEquals("I", symmetry.getSymmetry()); + assertEquals("A960B960C600D480E300", symmetry.getStoichiometry().toString()); + } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureTools.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureTools.java index c62180176c..9ba8170ab5 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureTools.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureTools.java @@ -1264,7 +1264,7 @@ public static final Character get1LetterCode(String groupCode3) { * 3-character code for a group. * */ - public static final boolean isNucleotide(String groupCode3) { + public static boolean isNucleotide(String groupCode3) { String code = groupCode3.trim(); return nucleotides30.containsKey(code) || nucleotides23.containsKey(code); @@ -1283,7 +1283,7 @@ public static final boolean isNucleotide(String groupCode3) { * @deprecated Use {@link StructureIdentifier#reduce(Structure)} instead (v. 4.2.0) */ @Deprecated - public static final Structure getReducedStructure(Structure s, + public static Structure getReducedStructure(Structure s, String chainId) throws StructureException { // since we deal here with structure alignments, // only use Model 1... @@ -1338,7 +1338,7 @@ public static final Structure getReducedStructure(Structure s, return newS; } - public static final String convertAtomsToSeq(Atom[] atoms) { + public static String convertAtomsToSeq(Atom[] atoms) { StringBuilder buf = new StringBuilder(); Group prevGroup = null; @@ -1374,7 +1374,7 @@ public static final String convertAtomsToSeq(Atom[] atoms) { * @throws StructureException * if the group cannot be found. */ - public static final Group getGroupByPDBResidueNumber(Structure struc, + public static Group getGroupByPDBResidueNumber(Structure struc, ResidueNumber pdbResNum) throws StructureException { if (struc == null || pdbResNum == null) { throw new IllegalArgumentException("Null argument(s)."); @@ -1447,7 +1447,7 @@ public static AtomContactSet getAtomsInContact(Chain chain, double cutoff) { * @param chain * @param cutoff * @return - * @see {@link #getRepresentativeAtomsInContact(Chain, double)} + * @see #getRepresentativeAtomsInContact(Chain, double) */ public static AtomContactSet getAtomsCAInContact(Chain chain, double cutoff) { Grid grid = new Grid(cutoff); @@ -1921,4 +1921,24 @@ private static String replaceFirstChar(String name, char c, char d) { return name; } + /** + * Remove all atoms but the representative atoms (C alphas or phosphates) from the given structure. + * @param structure the structure + * @since 5.4.0 + */ + public static void reduceToRepresentativeAtoms(Structure structure) { + for (int modelIdx = 0; modelIdx atoms = g.getAtoms(); + if (g.isAminoAcid()) { + atoms.removeIf(a->!a.getName().equals(CA_ATOM_NAME)); + } else if (g.isNucleotide()) { + atoms.removeIf(a->!a.getName().equals(NUCLEOTIDE_REPRESENTATIVE)); + } + // else we keep all other atoms. We are concerned only about aminoacids and nucleotides that make up the bulk of the structures + } + } + } + } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClustererParameters.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClustererParameters.java index f3abae6c3e..4224c76d0c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClustererParameters.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/cluster/SubunitClustererParameters.java @@ -511,7 +511,8 @@ public boolean isHighConfidenceScores(double sequenceIdentity, double sequenceCo /** * Whether to use the entity id of subunits to infer that sequences are identical. * Only applies if the {@link SubunitClustererMethod} is a sequence based one. - * @return + * @return the flag + * @since 5.4.0 */ public boolean isUseEntityIdForSeqIdentityDetermination() { return useEntityIdForSeqIdentityDetermination; @@ -520,7 +521,10 @@ public boolean isUseEntityIdForSeqIdentityDetermination() { /** * Whether to use the entity id of subunits to infer that sequences are identical. * Only applies if the {@link SubunitClustererMethod} is a sequence based one. + * Note this requires {@link org.biojava.nbio.structure.io.FileParsingParameters#setAlignSeqRes(boolean)} to be + * set to true. * @param useEntityIdForSeqIdentityDetermination the flag to be set + * @since 5.4.0 */ public void setUseEntityIdForSeqIdentityDetermination(boolean useEntityIdForSeqIdentityDetermination) { this.useEntityIdForSeqIdentityDetermination = useEntityIdForSeqIdentityDetermination; From f779dc3d32958ca5a717a40129f73c20acca47b7 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Thu, 23 Jan 2020 11:56:24 -0800 Subject: [PATCH 044/769] Docs --- .../symmetry/TestQuatSymmetryDetectorExamples.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java index 0d094a059a..a5cd0a9fb4 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java @@ -398,7 +398,6 @@ public void testSymDetectionWithClusteringByEntityId() throws IOException, Struc /** * A performance test that demonstrates how the SubunitClustererParameters.setUseEntityIdForSeqIdentityDetermination() * has a dramatic effect in runtime versus doing alignments. - * This takes minutes with the parameter on, but hours without the parameter. */ @Ignore("This is a performance test to be run manually") @Test @@ -413,14 +412,20 @@ public void testSymDetectionPerformanceLargeCapsid() throws IOException, Structu StructureIO.setAtomCache(cache); // making sure we remove all atoms but representative before we expand, otherwise memory requirements are huge + // 6Q1F is another good example Structure au = StructureIO.getStructure("6NHJ"); StructureTools.reduceToRepresentativeAtoms(au); BiologicalAssemblyBuilder builder = new BiologicalAssemblyBuilder(); List transforms = au.getPDBHeader().getBioAssemblies().get(1).getTransforms(); - Structure pdb =builder.rebuildQuaternaryStructure(au, transforms, true, false); + Structure pdb = builder.rebuildQuaternaryStructure(au, transforms, true, false); SubunitClustererParameters cp = new SubunitClustererParameters(); - cp.setUseEntityIdForSeqIdentityDetermination(true); // this is the parameter that makes this fast + + // This is the parameter that makes this fast, set it to false to see the difference. + // As of git commit ed322e387cd46344a7864a, the difference in runtime is not that huge: + // 2 minutes with true, 10 minutes with false. I observed a much larger difference before, but can't reproduce anymore - JD 2020-01-23 + cp.setUseEntityIdForSeqIdentityDetermination(true); + cp.setClustererMethod(SubunitClustererMethod.SEQUENCE); QuatSymmetryParameters symmParams = new QuatSymmetryParameters(); QuatSymmetryResults symmetry = QuatSymmetryDetector.calcGlobalSymmetry( From 3747377ea45e5b66c97e5cbfcdf30183d871a33d Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 25 Jan 2020 10:38:25 -0800 Subject: [PATCH 045/769] Initial implementation and tests --- .../test/contact/TestInterfaceFinder.java | 43 ++++++ .../nbio/structure/StructureTools.java | 14 +- .../structure/contact/InterfaceFinder.java | 59 +++++++++ .../contact/TestInterfaceFinder.java | 123 ++++++++++++++++++ 4 files changed, 232 insertions(+), 7 deletions(-) create mode 100644 biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java create mode 100644 biojava-structure/src/test/java/org/biojava/nbio/structure/contact/TestInterfaceFinder.java diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java new file mode 100644 index 0000000000..b7e346437b --- /dev/null +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java @@ -0,0 +1,43 @@ +package org.biojava.nbio.structure.test.contact; + +import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureIO; +import org.biojava.nbio.structure.contact.AtomContact; +import org.biojava.nbio.structure.contact.AtomContactSet; +import org.biojava.nbio.structure.contact.InterfaceFinder; +import org.biojava.nbio.structure.contact.Pair; +import org.biojava.nbio.structure.contact.StructureInterface; +import org.biojava.nbio.structure.contact.StructureInterfaceList; +import org.junit.Test; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertEquals; + +public class TestInterfaceFinder { + + @Test + public void testGetAllInterfaces() throws StructureException, IOException { + Structure s = StructureIO.getStructure("3hbx"); + InterfaceFinder finder = new InterfaceFinder(s); + + StructureInterfaceList list = finder.getAllInterfaces(); + + assertEquals(12, list.size()); + + Set> unique = new HashSet<>(); + + for (StructureInterface interf : list) { + System.out.println("Interface " + interf.getMoleculeIds()); + AtomContactSet set = interf.getContacts(); + System.out.println("Number of contacts: " + set.size()); + + unique.add(interf.getMoleculeIds()); + + } + assertEquals(12, unique.size()); + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureTools.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureTools.java index c62180176c..1142602038 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureTools.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureTools.java @@ -474,7 +474,7 @@ public static List getUnalignedGroups(Atom[] ca) { * @see StructureTools#DEFAULT_LIGAND_PROXIMITY_CUTOFF */ public static List getLigandsByProximity(Collection target, Atom[] query, double cutoff) { - // Geometric hashing of the reduced structure + // Spatial hashing of the reduced structure Grid grid = new Grid(cutoff); grid.addAtoms(query); @@ -1387,7 +1387,7 @@ public static final Group getGroupByPDBResidueNumber(Structure struc, /** * Returns the set of intra-chain contacts for the given chain for given - * atom names, i.e. the contact map. Uses a geometric hashing algorithm that + * atom names, i.e. the contact map. Uses a spatial hashing algorithm that * speeds up the calculation without need of full distance matrix. The * parsing mode {@link FileParsingParameters#setAlignSeqRes(boolean)} needs * to be set to true for this to work. @@ -1422,7 +1422,7 @@ public static AtomContactSet getAtomsInContact(Chain chain, /** * Returns the set of intra-chain contacts for the given chain for all non-H - * atoms of non-hetatoms, i.e. the contact map. Uses a geometric hashing + * atoms of non-hetatoms, i.e. the contact map. Uses a spatial hashing * algorithm that speeds up the calculation without need of full distance * matrix. The parsing mode * {@link FileParsingParameters#setAlignSeqRes(boolean)} needs to be set to @@ -1439,7 +1439,7 @@ public static AtomContactSet getAtomsInContact(Chain chain, double cutoff) { /** * Returns the set of intra-chain contacts for the given chain for C-alpha * atoms (including non-standard aminoacids appearing as HETATM groups), - * i.e. the contact map. Uses a geometric hashing algorithm that speeds up + * i.e. the contact map. Uses a spatial hashing algorithm that speeds up * the calculation without need of full distance matrix. The parsing mode * {@link FileParsingParameters#setAlignSeqRes(boolean)} needs to be set to * true for this to work. @@ -1462,7 +1462,7 @@ public static AtomContactSet getAtomsCAInContact(Chain chain, double cutoff) { /** * Returns the set of intra-chain contacts for the given chain for C-alpha * or C3' atoms (including non-standard aminoacids appearing as HETATM - * groups), i.e. the contact map. Uses a geometric hashing algorithm that + * groups), i.e. the contact map. Uses a spatial hashing algorithm that * speeds up the calculation without need of full distance matrix. * * @param chain @@ -1483,7 +1483,7 @@ public static AtomContactSet getRepresentativeAtomsInContact(Chain chain, /** * Returns the set of inter-chain contacts between the two given chains for - * the given atom names. Uses a geometric hashing algorithm that speeds up + * the given atom names. Uses a spatial hashing algorithm that speeds up * the calculation without need of full distance matrix. The parsing mode * {@link FileParsingParameters#setAlignSeqRes(boolean)} needs to be set to * true for this to work. @@ -1518,7 +1518,7 @@ public static AtomContactSet getAtomsInContact(Chain chain1, Chain chain2, /** * Returns the set of inter-chain contacts between the two given chains for - * all non-H atoms. Uses a geometric hashing algorithm that speeds up the + * all non-H atoms. Uses a spatial hashing algorithm that speeds up the * calculation without need of full distance matrix. The parsing mode * {@link FileParsingParameters#setAlignSeqRes(boolean)} needs to be set to * true for this to work. diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java new file mode 100644 index 0000000000..4128e95902 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java @@ -0,0 +1,59 @@ +package org.biojava.nbio.structure.contact; + +import org.biojava.nbio.structure.Chain; +import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureTools; +import org.biojava.nbio.structure.xtal.CrystalTransform; +import org.biojava.nbio.structure.xtal.SpaceGroup; + +import java.util.List; + +public class InterfaceFinder { + + public static final double DEFAULT_CONTACT_CUTOFF = 6; + + private static final CrystalTransform IDENTITY_TRANSFORM = new CrystalTransform(SpaceGroup.parseSpaceGroup("P1")); + private static final boolean INCLUDE_HETATOMS = true; + + private Structure structure; + private double cutoff; + + public InterfaceFinder(Structure structure) { + this.structure = structure; + this.cutoff = DEFAULT_CONTACT_CUTOFF; + } + + public void setCutoff(double cutoff) { + this.cutoff = cutoff; + } + + public StructureInterfaceList getAllInterfaces() { + StructureInterfaceList list = new StructureInterfaceList(); + + List polyChains = structure.getPolyChains(); + for (int i = 0; i0) { + interf = new StructureInterface( + StructureTools.getAllAtomArray(chain1), StructureTools.getAllAtomArray(chain2), + chain1.getName(), chain2.getName(), + graph, + IDENTITY_TRANSFORM, IDENTITY_TRANSFORM); + } + + return interf; + } +} diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/contact/TestInterfaceFinder.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/contact/TestInterfaceFinder.java new file mode 100644 index 0000000000..7970b071fd --- /dev/null +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/contact/TestInterfaceFinder.java @@ -0,0 +1,123 @@ +package org.biojava.nbio.structure.contact; + +import org.biojava.nbio.structure.AminoAcidImpl; +import org.biojava.nbio.structure.Atom; +import org.biojava.nbio.structure.AtomImpl; +import org.biojava.nbio.structure.Chain; +import org.biojava.nbio.structure.ChainImpl; +import org.biojava.nbio.structure.EntityInfo; +import org.biojava.nbio.structure.Group; +import org.biojava.nbio.structure.ResidueNumber; +import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureImpl; +import org.biojava.nbio.structure.StructureTools; +import org.junit.Test; +import static org.junit.Assert.*; + +import javax.vecmath.Point3d; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class TestInterfaceFinder { + + @Test + public void testGetAllInterfaces() { + Structure s = mockStructure(); + InterfaceFinder finder = new InterfaceFinder(s); + + StructureInterfaceList list = finder.getAllInterfaces(); + + assertEquals(3, list.size()); + + Set> unique = new HashSet<>(); + + for (StructureInterface interf : list) { + System.out.println("Interface " + interf.getMoleculeIds()); + AtomContactSet set = interf.getContacts(); + for (AtomContact c : set) + System.out.println(c.getPair() +" - " + c.getDistance()); + + unique.add(interf.getMoleculeIds()); + + } + assertEquals(3, unique.size()); + } + + /** + * Create a mock structure with 2 entities 1 (chains A, B) and 2 (chain C). + * @return a structure + */ + private Structure mockStructure() { + Structure structure = new StructureImpl(); + EntityInfo entity1 = new EntityInfo(); + entity1.setMolId(1); + EntityInfo entity2 = new EntityInfo(); + entity2.setMolId(2); + structure.addEntityInfo(entity1); + structure.addEntityInfo(entity2); + + Chain chainA = new ChainImpl(); + chainA.setId("A"); + chainA.setName("A"); + Chain chainB = new ChainImpl(); + chainB.setId("B"); + chainB.setName("B"); + entity1.addChain(chainA); + entity1.addChain(chainB); + Chain chainC = new ChainImpl(); + chainC.setId("C"); + chainC.setName("C"); + entity2.addChain(chainC); + + structure.addChain(chainA); + structure.addChain(chainB); + structure.addChain(chainC); + + // entity 1: chain A 10 observed residues, chain B 9 observed residues (first unobserved) + List aGroups = getGroupList(10, "ALA", chainA, new Point3d(0,0,0)); + chainA.setAtomGroups(new ArrayList<>(aGroups)); + chainA.setSeqResGroups(aGroups); + chainA.setEntityInfo(entity1); + + List bGroups = getGroupList(10, "ALA", chainB, new Point3d(4, 0, 0)); + chainB.setAtomGroups(new ArrayList<>(bGroups.subList(1,10))); + chainB.setSeqResGroups(bGroups); + chainB.setEntityInfo(entity1); + + List cGroups = getGroupList(20, "GLY", chainC, new Point3d(0, 4, 0)); + chainC.setAtomGroups(new ArrayList<>(cGroups)); + chainC.setSeqResGroups(cGroups); + chainC.setEntityInfo(entity2); + + return structure; + } + + private List getGroupList(int size, String type, Chain chain, Point3d center) { + List list = new ArrayList<>(); + double offsetx = 0; + double offsety = 0; + double offsetz = 0; + for (int i=0;i Date: Sat, 25 Jan 2020 11:00:11 -0800 Subject: [PATCH 046/769] With bounding box optimization --- .../test/contact/TestInterfaceFinder.java | 1 + .../structure/contact/InterfaceFinder.java | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java index b7e346437b..5d09406743 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java @@ -22,6 +22,7 @@ public class TestInterfaceFinder { @Test public void testGetAllInterfaces() throws StructureException, IOException { Structure s = StructureIO.getStructure("3hbx"); + InterfaceFinder finder = new InterfaceFinder(s); StructureInterfaceList list = finder.getAllInterfaces(); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java index 4128e95902..540c64f574 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java @@ -1,11 +1,14 @@ package org.biojava.nbio.structure.contact; +import org.biojava.nbio.structure.Atom; +import org.biojava.nbio.structure.Calc; import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.xtal.CrystalTransform; import org.biojava.nbio.structure.xtal.SpaceGroup; +import javax.vecmath.Point3d; import java.util.List; public class InterfaceFinder { @@ -18,6 +21,8 @@ public class InterfaceFinder { private Structure structure; private double cutoff; + private BoundingBox[] boundingBoxes; + public InterfaceFinder(Structure structure) { this.structure = structure; this.cutoff = DEFAULT_CONTACT_CUTOFF; @@ -28,11 +33,16 @@ public void setCutoff(double cutoff) { } public StructureInterfaceList getAllInterfaces() { + initBoundingBoxes(); + StructureInterfaceList list = new StructureInterfaceList(); List polyChains = structure.getPolyChains(); for (int i = 0; i polyChains = structure.getPolyChains(); + boundingBoxes = new BoundingBox[polyChains.size()]; + for (int i = 0; i0) { interf = new StructureInterface( - StructureTools.getAllAtomArray(chain1), StructureTools.getAllAtomArray(chain2), + StructureTools.getAllNonHAtomArray(chain1, INCLUDE_HETATOMS), StructureTools.getAllNonHAtomArray(chain2, INCLUDE_HETATOMS), chain1.getName(), chain2.getName(), graph, IDENTITY_TRANSFORM, IDENTITY_TRANSFORM); From d4dc3239b5fcae70e22e279465197c78740b2322 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 25 Jan 2020 11:08:46 -0800 Subject: [PATCH 047/769] Docs --- .../test/contact/TestInterfaceFinder.java | 1 - .../nbio/structure/contact/InterfaceFinder.java | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java index 5d09406743..e34bf5f355 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java @@ -3,7 +3,6 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; -import org.biojava.nbio.structure.contact.AtomContact; import org.biojava.nbio.structure.contact.AtomContactSet; import org.biojava.nbio.structure.contact.InterfaceFinder; import org.biojava.nbio.structure.contact.Pair; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java index 540c64f574..eae89db2c8 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java @@ -11,6 +11,11 @@ import javax.vecmath.Point3d; import java.util.List; +/** + * A class containing methods to find interfaces in a given structure. + * @author Jose Duarte + * @since 5.4.0 + */ public class InterfaceFinder { public static final double DEFAULT_CONTACT_CUTOFF = 6; @@ -28,10 +33,20 @@ public InterfaceFinder(Structure structure) { this.cutoff = DEFAULT_CONTACT_CUTOFF; } + /** + * Set the contact distance cutoff. + * @param cutoff the distance value in Angstroms + */ public void setCutoff(double cutoff) { this.cutoff = cutoff; } + /** + * Find all inter polymer-chain interfaces in the structure. + * Two chains will be considered in contact if at least a pair of atoms from each is within the + * contact cutoff. + * @return the list of all interfaces + */ public StructureInterfaceList getAllInterfaces() { initBoundingBoxes(); From e70f0ef8131897137cc2f6b201b2eca4ff9c662f Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 25 Jan 2020 11:36:08 -0800 Subject: [PATCH 048/769] Fixes --- .../org/biojava/nbio/structure/contact/InterfaceFinder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java index eae89db2c8..a7b01400f2 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/InterfaceFinder.java @@ -20,7 +20,7 @@ public class InterfaceFinder { public static final double DEFAULT_CONTACT_CUTOFF = 6; - private static final CrystalTransform IDENTITY_TRANSFORM = new CrystalTransform(SpaceGroup.parseSpaceGroup("P1")); + private static final CrystalTransform IDENTITY_TRANSFORM = new CrystalTransform((SpaceGroup) null); private static final boolean INCLUDE_HETATOMS = true; private Structure structure; @@ -43,7 +43,7 @@ public void setCutoff(double cutoff) { /** * Find all inter polymer-chain interfaces in the structure. - * Two chains will be considered in contact if at least a pair of atoms from each is within the + * Two chains will be considered in contact if at least a pair of atoms (one from each chain) is within the * contact cutoff. * @return the list of all interfaces */ From 2807d3d1cc76128599d79410717327696feb45ef Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 25 Jan 2020 11:58:56 -0800 Subject: [PATCH 049/769] Cleanup --- .../test/contact/TestInterfaceFinder.java | 6 ++- .../structure/contact/StructureInterface.java | 40 +++++++++---------- .../contact/TestInterfaceFinder.java | 5 +++ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java index e34bf5f355..7eb07e95f6 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/contact/TestInterfaceFinder.java @@ -22,10 +22,14 @@ public class TestInterfaceFinder { public void testGetAllInterfaces() throws StructureException, IOException { Structure s = StructureIO.getStructure("3hbx"); - InterfaceFinder finder = new InterfaceFinder(s); + long start = System.currentTimeMillis(); + InterfaceFinder finder = new InterfaceFinder(s); StructureInterfaceList list = finder.getAllInterfaces(); + long end = System.currentTimeMillis(); + System.out.println("Took " + (end-start) + " ms to calculate interfaces"); + assertEquals(12, list.size()); Set> unique = new HashSet<>(); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java index e9150fcfbe..3d039ad32b 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java @@ -304,7 +304,7 @@ protected Atom[] getAtomsForAsa(int cofactorSizeToUse) { * non-Hydrogen atoms are not included * @return */ - private static final Atom[] getAllNonHAtomArray(Atom[] m, int minSizeHetAtomToInclude) { + private static Atom[] getAllNonHAtomArray(Atom[] m, int minSizeHetAtomToInclude) { List atoms = new ArrayList<>(); for (Atom a:m){ @@ -348,7 +348,7 @@ private static boolean isInChain(Group g) { ChemComp chemComp = g.getChemComp(); if (chemComp==null) { - logger.warn("Warning: can't determine PolymerType for group "+g.getResidueNumber()+" ("+g.getPDBName()+"). Will consider it as non-nucleotide/non-protein type."); + logger.warn("Can't determine PolymerType for group "+g.getResidueNumber()+" ("+g.getPDBName()+"). Will consider it as non-nucleotide/non-protein type."); return false; } @@ -458,8 +458,8 @@ public GroupAsa getSecondGroupAsa(ResidueNumber resNum) { */ public Pair> getCoreResidues(double bsaToAsaCutoff, double minAsaForSurface) { - List core1 = new ArrayList(); - List core2 = new ArrayList(); + List core1 = new ArrayList<>(); + List core2 = new ArrayList<>(); for (GroupAsa groupAsa:groupAsas1.values()) { @@ -482,7 +482,7 @@ public Pair> getCoreResidues(double bsaToAsaCutoff, double minAsaFor } } - return new Pair>(core1, core2); + return new Pair<>(core1, core2); } /** @@ -494,8 +494,8 @@ public Pair> getCoreResidues(double bsaToAsaCutoff, double minAsaFor */ public Pair> getRimResidues(double bsaToAsaCutoff, double minAsaForSurface) { - List rim1 = new ArrayList(); - List rim2 = new ArrayList(); + List rim1 = new ArrayList<>(); + List rim2 = new ArrayList<>(); for (GroupAsa groupAsa:groupAsas1.values()) { @@ -529,8 +529,8 @@ public Pair> getRimResidues(double bsaToAsaCutoff, double minAsaForS */ public Pair> getInterfacingResidues(double minAsaForSurface) { - List interf1 = new ArrayList(); - List interf2 = new ArrayList(); + List interf1 = new ArrayList<>(); + List interf2 = new ArrayList<>(); for (GroupAsa groupAsa:groupAsas1.values()) { @@ -545,7 +545,7 @@ public Pair> getInterfacingResidues(double minAsaForSurface) { } } - return new Pair>(interf1, interf2); + return new Pair<>(interf1, interf2); } /** @@ -554,8 +554,8 @@ public Pair> getInterfacingResidues(double minAsaForSurface) { * @return */ public Pair> getSurfaceResidues(double minAsaForSurface) { - List surf1 = new ArrayList(); - List surf2 = new ArrayList(); + List surf1 = new ArrayList<>(); + List surf2 = new ArrayList<>(); for (GroupAsa groupAsa:groupAsas1.values()) { @@ -570,7 +570,7 @@ public Pair> getSurfaceResidues(double minAsaForSurface) { } } - return new Pair>(surf1, surf2); + return new Pair<>(surf1, surf2); } public StructureInterfaceCluster getCluster() { @@ -585,12 +585,12 @@ public void setCluster(StructureInterfaceCluster cluster) { * Calculates the contact overlap score between this StructureInterface and * the given one. * The two sides of the given StructureInterface need to match this StructureInterface - * in the sense that they must come from the same Compound (Entity), i.e. + * in the sense that they must come from the same Entity, i.e. * their residue numbers need to align with 100% identity, except for unobserved * density residues. The SEQRES indices obtained through {@link EntityInfo#getAlignedResIndex(Group, Chain)} are * used to match residues, thus if no SEQRES is present or if {@link FileParsingParameters#setAlignSeqRes(boolean)} * is not used, this calculation is not guaranteed to work properly. - * @param other + * @param other the interface to be compared to this one * @param invert if false the comparison will be done first-to-first and second-to-second, * if true the match will be first-to-second and second-to-first * @return the contact overlap score, range [0.0,1.0] @@ -668,7 +668,7 @@ public GroupContactSet getGroupContacts() { /** * Tell whether the interface is isologous, i.e. it is formed - * by the same patches of same Compound on both sides. + * by the same patches of same entity on both sides. * * @return true if isologous, false if heterologous */ @@ -691,11 +691,11 @@ public Pair getParentChains() { return null; } - return new Pair(firstMol[0].getGroup().getChain(), secondMol[0].getGroup().getChain()); + return new Pair<>(firstMol[0].getGroup().getChain(), secondMol[0].getGroup().getChain()); } /** - * Finds the parent compounds by looking up the references of first atom of each side of this interface + * Finds the parent entities by looking up the references of first atom of each side of this interface * @return */ public Pair getParentCompounds() { @@ -720,7 +720,7 @@ private Structure getParentStructure() { * Return a String representing the 2 molecules of this interface in PDB format. * If the molecule ids (i.e. chain ids) are the same for both molecules, then the second * one will be replaced by the next letter in alphabet (or A for Z) - * @return + * @return the PDB-formatted string */ public String toPDB() { @@ -758,7 +758,7 @@ public String toPDB() { * Return a String representing the 2 molecules of this interface in mmCIF format. * If the molecule ids (i.e. chain ids) are the same for both molecules, then the second * one will be written as chainId_operatorId (with operatorId taken from {@link #getTransforms()} - * @return + * @return the mmCIF-formatted string */ public String toMMCIF() { StringBuilder sb = new StringBuilder(); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/contact/TestInterfaceFinder.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/contact/TestInterfaceFinder.java index 7970b071fd..0ad1d6544e 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/contact/TestInterfaceFinder.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/contact/TestInterfaceFinder.java @@ -12,6 +12,9 @@ import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import static org.junit.Assert.*; import javax.vecmath.Point3d; @@ -22,6 +25,8 @@ public class TestInterfaceFinder { + private static final Logger logger = LoggerFactory.getLogger(TestInterfaceFinder.class); + @Test public void testGetAllInterfaces() { Structure s = mockStructure(); From 196f2e7091f197e25eab55bd4368d625369230de Mon Sep 17 00:00:00 2001 From: Didik Supriadi Date: Thu, 27 Feb 2020 21:37:19 +0700 Subject: [PATCH 050/769] Update release in Version badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ccec106c71..9ff33d976b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Welcome to -[![Build Status](https://travis-ci.org/biojava/biojava.svg?branch=master)](https://travis-ci.org/biojava/biojava) [![Version](http://img.shields.io/badge/version-5.3.0-blue.svg?style=flat)](https://github.com/biojava/biojava/releases/tag/biojava-5.2.0) [![License](http://img.shields.io/badge/license-LGPL_2.1-blue.svg?style=flat)](https://github.com/biojava/biojava/blob/master/LICENSE) [![Join the chat at https://gitter.im/biojava/biojava](https://badges.gitter.im/biojava/biojava.svg)](https://gitter.im/biojava/biojava?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://travis-ci.org/biojava/biojava.svg?branch=master)](https://travis-ci.org/biojava/biojava) [![Version](http://img.shields.io/badge/version-5.3.0-blue.svg?style=flat)](https://github.com/biojava/biojava/releases/tag/biojava-5.3.0) [![License](http://img.shields.io/badge/license-LGPL_2.1-blue.svg?style=flat)](https://github.com/biojava/biojava/blob/master/LICENSE) [![Join the chat at https://gitter.im/biojava/biojava](https://badges.gitter.im/biojava/biojava.svg)](https://gitter.im/biojava/biojava?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) BioJava is an open-source project dedicated to providing a Java framework for **processing biological data**. It provides analytical and statistical routines, parsers for common file formats, reference implementations of popular algorithms, and allows the manipulation of sequences and 3D structures. The goal of the biojava project is to facilitate rapid application development for bioinformatics. From 41c36aef2fa755ca3ff9ffd91bd274939c1dfb6f Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 12 Apr 2020 22:27:28 -0700 Subject: [PATCH 051/769] Now biojava can parse mmcif files with carbohydrates, though it ignores the carbohydrate chains --- .../biojava/nbio/structure/EntityType.java | 12 +++++++++ .../structure/io/TestNonDepositedFiles.java | 25 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/EntityType.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/EntityType.java index 9abf52b423..de8b5ca4d1 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/EntityType.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/EntityType.java @@ -44,6 +44,18 @@ public enum EntityType { */ POLYMER("polymer"), + /** + * The 'branched' type use mainly to represent carbohydrates. + * The type was introduced in these versions of the mmcif dictionary: + * 5.101 2012-08-22 + * 5.291 2017-09-10 + * 5.304 2018-08-01 + * The type will only be used for PDB-deposited files from July 2020, as part of + * the carbohydrate remediation project. + * @since 5.4.0 + */ + BRANCHED("branched"), + /** * Non-polymeric entities: ligands, metal ions, buffer molecules, etc */ diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java index f5e8e5c27e..70e932bc01 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java @@ -27,6 +27,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.URL; import java.util.List; import java.util.zip.GZIPInputStream; @@ -443,4 +444,28 @@ private static int[] countEntityTypes(List entities) { return counts; } + + @Test + public void testCarbohydrates() throws IOException { + // Example carbohydrate remediation file to be released in July 2020 + URL url = new URL("https://raw.githubusercontent.com/pdbxmmcifwg/carbohydrate-extension/master/examples/models/1B5F-carb.cif"); + InputStream inStream = url.openStream(); + + MMcifParser parser = new SimpleMMcifParser(); + + SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); + parser.addMMcifConsumer(consumer); + parser.parse(new BufferedReader(new InputStreamReader(inStream))); + + Structure structure = consumer.getStructure(); + + assertEquals(7, structure.getEntityInfos().size()); + + assertEquals(2, structure.getEntityById(1).getChains().size()); + assertEquals(2, structure.getEntityById(2).getChains().size()); + + assertEquals(0, structure.getNonPolyChains().size()); + assertEquals(4, structure.getPolyChains().size()); + + } } From ab76f927265dfea8a3ffb12073823672ca3dda97 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 12 Apr 2020 23:39:43 -0700 Subject: [PATCH 052/769] Now considering branched entities as non-polymeric. Ends up in a more consistent state. Can be mmtf-encoded. --- .../org/biojava/nbio/structure/Model.java | 4 ++ .../io/mmtf/MmtfStructureWriter.java | 14 +++--- .../structure/io/TestNonDepositedFiles.java | 11 +++- .../structure/io/mmtf/TestMmtfRoundTrip.java | 50 +++++++++++++++++-- 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/Model.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/Model.java index 36cce008cb..7fe0abfed9 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/Model.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/Model.java @@ -110,6 +110,10 @@ public void addChain(Chain c) { logger.warn("Chain with asym id {} (author id {}) has entity type 'macrolide', considering it non-polymeric", c.getId(), c.getName()); nonPolyChains.add(c); + } else if (info.getType() == EntityType.BRANCHED) { + logger.warn("Chain with asym id {} (author id {}) has entity type 'branched', considering it non-polymeric", c.getId(), c.getName()); + nonPolyChains.add(c); + } else { logger.warn("Chain with asym id {} (author id {}) has unsupported entity type '{}'. Will not add it to the Structure.", c.getId(), c.getName(), info.getType().toString()); // ignore it diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java index dbc14ebbe4..47e4fb3d69 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java @@ -37,6 +37,8 @@ import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.rcsb.mmtf.api.StructureAdapterInterface; import org.rcsb.mmtf.dataholders.MmtfStructure; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Class to take Biojava structure data and covert to the DataApi for encoding. @@ -48,7 +50,9 @@ */ public class MmtfStructureWriter { - private StructureAdapterInterface mmtfDecoderInterface; + private static final Logger logger = LoggerFactory.getLogger(MmtfStructureWriter.class); + + private final StructureAdapterInterface mmtfDecoderInterface; /** * Pass data from Biojava structure to another generic output type. Loops through the data @@ -179,9 +183,8 @@ private void storeEntityInformation(List allChains, List enti List entityChains = entityInfo.getChains(); if (entityChains.isEmpty()){ // Error mapping chain to entity - System.err.println("ERROR MAPPING CHAIN TO ENTITY: "+description); + logger.error("ERROR MAPPING CHAIN TO ENTITY: "+description); mmtfDecoderInterface.setEntityInfo(new int[0], "", description, type); - continue; } else{ int[] chainIndices = new int[entityChains.size()]; @@ -194,7 +197,7 @@ private void storeEntityInformation(List allChains, List enti chainImpl = (ChainImpl) entityChains.get(0); } else{ - throw new RuntimeException(); + throw new RuntimeException("Encountered Chain of unexpected type"); } String sequence = chainImpl.getSeqResOneLetterSeq(); mmtfDecoderInterface.setEntityInfo(chainIndices, sequence, description, type); @@ -205,8 +208,7 @@ private void storeEntityInformation(List allChains, List enti /** * Generate the bioassembly information on in the desired form. - * @param bioJavaStruct the Biojava structure - * @param header the header + * */ private void storeBioassemblyInformation(Map chainIdToIndexMap, Map inputBioAss) { int bioAssemblyIndex = 0; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java index 70e932bc01..2e9ecc6140 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java @@ -446,7 +446,7 @@ private static int[] countEntityTypes(List entities) { } @Test - public void testCarbohydrates() throws IOException { + public void testStructureWithBranchedEntities() throws IOException { // Example carbohydrate remediation file to be released in July 2020 URL url = new URL("https://raw.githubusercontent.com/pdbxmmcifwg/carbohydrate-extension/master/examples/models/1B5F-carb.cif"); InputStream inStream = url.openStream(); @@ -464,8 +464,15 @@ public void testCarbohydrates() throws IOException { assertEquals(2, structure.getEntityById(1).getChains().size()); assertEquals(2, structure.getEntityById(2).getChains().size()); - assertEquals(0, structure.getNonPolyChains().size()); + // we consider the branched chains non-poly chains + assertEquals(4, structure.getNonPolyChains().size()); assertEquals(4, structure.getPolyChains().size()); + assertEquals(1, structure.getEntityById(3).getChains().size()); + + // chain asym_id="E" is from entity 3 + assertSame(structure.getNonPolyChain("E"), structure.getEntityById(3).getChains().get(0)); + + assertEquals(5, structure.getNonPolyChain("E").getAtomGroups().size()); } } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java index d9bdb05bc0..f787b1e908 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java @@ -20,12 +20,11 @@ */ package org.biojava.nbio.structure.io.mmtf; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -43,12 +42,17 @@ import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; +import org.biojava.nbio.structure.io.mmcif.MMcifParser; +import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; +import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; import org.junit.Test; import org.rcsb.mmtf.decoder.StructureDataToAdapter; import org.rcsb.mmtf.encoder.AdapterToStructureData; +import static org.junit.Assert.*; + /** * Tests to see if roundtripping of MMTF can be done. * @@ -350,4 +354,40 @@ private void checkBioAssemblies1(Structure structOne, Structure structTwo) throw } } } + + @Test + public void testStructWithBranchedEntitiesRoundTrip() throws IOException { + // Example carbohydrate remediation file to be released in July 2020 + URL url = new URL("https://raw.githubusercontent.com/pdbxmmcifwg/carbohydrate-extension/master/examples/models/1B5F-carb.cif"); + InputStream inStream = url.openStream(); + + MMcifParser parser = new SimpleMMcifParser(); + + SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); + parser.addMMcifConsumer(consumer); + parser.parse(new BufferedReader(new InputStreamReader(inStream))); + + Structure structure = consumer.getStructure(); + + AdapterToStructureData writerToEncoder = new AdapterToStructureData(); + new MmtfStructureWriter(structure, writerToEncoder); + MmtfStructureReader mmtfStructureReader = new MmtfStructureReader(); + new StructureDataToAdapter(writerToEncoder, mmtfStructureReader); + Structure structure2 = mmtfStructureReader.getStructure(); + + assertEquals(7, structure2.getEntityInfos().size()); + + assertEquals(2, structure2.getEntityById(1).getChains().size()); + assertEquals(2, structure2.getEntityById(2).getChains().size()); + + assertEquals(4, structure2.getNonPolyChains().size()); + assertEquals(4, structure2.getPolyChains().size()); + + assertEquals(1, structure2.getEntityById(3).getChains().size()); + + // chain asym_id="E" is from entity 3 + assertSame(structure2.getNonPolyChain("E"), structure2.getEntityById(3).getChains().get(0)); + + assertEquals(5, structure2.getNonPolyChain("E").getAtomGroups().size()); + } } From 3ac8e06fdaeb2cfbfcf7d3c31e5bc2985280ed89 Mon Sep 17 00:00:00 2001 From: Sebastian Jaenicke Date: Mon, 13 Apr 2020 14:04:25 +0200 Subject: [PATCH 053/769] slf4j update 1.7.25 -> 1.7.30 log4j update 2.6.2 -> 2.13.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9ff4c461ee..8514858e84 100644 --- a/pom.xml +++ b/pom.xml @@ -41,8 +41,8 @@ UTF-8 512M 1.0.9 - 1.7.25 - 2.6.2 + 1.7.30 + 2.13.1 scm:git:git://github.com/biojava/biojava.git From 3a93e1c2329d6b0be960c68832db5c15fb411bf8 Mon Sep 17 00:00:00 2001 From: Aleix Lafita Date: Wed, 15 Apr 2020 19:43:56 +0100 Subject: [PATCH 054/769] Comment out 3R8R from localSymmetry test --- .../test/symmetry/TestQuatSymmetryDetectorExamples.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java index a5cd0a9fb4..b5a8a5a2e1 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java @@ -183,11 +183,12 @@ public void testLocal() throws IOException, StructureException { localSymmetries.put("A8","D2"); testLocalSymmetries.add(localSymmetries); + /* Bioassembly for 3R8R changed in January 2020 (PR #867) testIds.add("BIO:3R8R:1"); testStoichiometries.add("A12"); localSymmetries = new HashMap<>(); localSymmetries.put("A10","D5"); - testLocalSymmetries.add(localSymmetries); + testLocalSymmetries.add(localSymmetries);*/ testIds.add("BIO:1O18:1"); testStoichiometries.add("A14B6C5D5"); From 0570329da0e2756b603d7380c6c65fbbba109219 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sat, 25 Apr 2020 19:31:46 +0100 Subject: [PATCH 055/769] Added sequence file mentioned in #855 --- ...ture-spans-zero-point-circular-sequence.gb | 283 ++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 biojava-core/src/test/resources/feature-spans-zero-point-circular-sequence.gb diff --git a/biojava-core/src/test/resources/feature-spans-zero-point-circular-sequence.gb b/biojava-core/src/test/resources/feature-spans-zero-point-circular-sequence.gb new file mode 100644 index 0000000000..1fcc731c0d --- /dev/null +++ b/biojava-core/src/test/resources/feature-spans-zero-point-circular-sequence.gb @@ -0,0 +1,283 @@ +LOCUS Exported 7602 bp ds-DNA circular SYN 06-AUG-2018 +DEFINITION synthetic circular DNA +ACCESSION . +VERSION . +KEYWORDS E1b-GFP-Tol2 +SOURCE synthetic DNA construct + ORGANISM synthetic DNA construct +REFERENCE 1 (bases 1 to 7602) + AUTHORS Birnbaum RY, Clowney EJ, Agamy O, Kim MJ, Zhao J, Yamanaka T, + Pappalardo Z, Clarke SL, Wenger AM, Nguyen L, Gurrieri F, Everman + DB, Schwartz CE, Birk OS, Bejerano G, Lomvardas S, Ahituv N + TITLE Coding exons function as tissue-specific enhancers of nearby genes. + JOURNAL Genome Res. 2012 Jun;22(6):1059-68. Epub 2012 Mar 22. + PUBMED 22442009 +REFERENCE 2 (bases 1 to 7602) + AUTHORS . + TITLE Direct Submission + JOURNAL Exported Aug 6, 2018 from SnapGene Server 1.1.58 + http://www.snapgene.com +FEATURES Location/Qualifiers + source 1..7602 + /organism="synthetic DNA construct" + /mol_type="other DNA" + primer_bind 49..68 + /label=Amp-R + /note="Ampicillin resistance gene, reverse primer" + promoter complement(287..391) + /gene="bla" + /label=AmpR promoter + rep_origin complement(417..872) + /direction=LEFT + /label=f1 ori + /note="f1 bacteriophage origin of replication; arrow + indicates direction of (+) strand synthesis" + primer_bind complement(554..575) + /label=F1ori-F + /note="F1 origin, forward primer" + primer_bind 766..785 + /label=F1ori-R + /note="F1 origin, reverse primer" + primer_bind 999..1021 + /label=M13/pUC Forward + /note="In lacZ gene" + primer_bind 1013..1030 + /label=M13 Forward + /note="In lacZ gene. Also called M13-F20 or M13 (-21) + Forward" + primer_bind 1014..1030 + /label=M13 fwd + /note="common sequencing primer, one of multiple similar + variants" + primer_bind 1040..1059 + /label=T7 + /note="T7 promoter, forward primer" + promoter 1040..1058 + /label=T7 promoter + /note="promoter for bacteriophage T7 RNA polymerase" + intron 3555..4127 + /label=-beta-globin intron + /note="intron from rabbit beta-globin gene" + regulatory 4201..4210 + /regulatory_class="other" + /note="vertebrate consensus sequence for strong initiation + of translation (Kozak, 1987)" + CDS 4207..4926 + /codon_start=1 + /product="enhanced GFP" + /label=EGFP + /note="mammalian codon-optimized" + /translation="MVSKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTL + KFICTTGKLPVPWPTLVTTLTYGVQCFSRYPDHMKQHDFFKSAMPEGYVQERTIFFKDD + GNYKTRAEVKFEGDTLVNRIELKGIDFKEDGNILGHKLEYNYNSHNVYIMADKQKNGIK + VNFKIRHNIEDGSVQLADHYQQNTPIGDGPVLLPDNHYLSTQSALSKDPNEKRDHMVLL + EFVTAAGITLGMDELYK" + primer_bind complement(4252..4273) + /label=EGFP-N + /note="EGFP, reverse primer" + primer_bind complement(4513..4532) + /label=EXFP-R + /note="For distinguishing EGFP variants, reverse primer" + primer_bind 4860..4881 + /label=EGFP-C + /note="EGFP, forward primer" + polyA_signal 4971..5105 + /label=SV40 poly(A) signal + /note="SV40 polyadenylation signal" + primer_bind complement(4995..5014) + /label=EBV-rev + /note="SV40 polyA terminator, reverse primer" + primer_bind 5049..5068 + /label=SV40pA-R + /note="SV40 polyA, reverse primer" + primer_bind complement(5775..5791) + /label=SK primer + /note="common sequencing primer, one of multiple similar + variants" + primer_bind complement(5775..5791) + /label=pBluescriptSK + /note="For pBluescript vector" + primer_bind complement(5828..5848) + /label=T3 + /note="T3 promoter, forward primer" + promoter complement(5828..5846) + /label=T3 promoter + /note="promoter for bacteriophage T3 RNA polymerase" + primer_bind complement(5867..5883) + /label=M13 rev + /note="common sequencing primer, one of multiple similar + variants" + primer_bind complement(5867..5883) + /label=M13 Reverse + /note="In lacZ gene. Also called M13-rev" + primer_bind complement(5880..5902) + /label=M13/pUC Reverse + /note="In lacZ gene" + protein_bind 5891..5907 + /label=lac operator + /bound_moiety="lac repressor encoded by lacI" + /note="The lac repressor binds to the lac operator to + inhibit transcription in E. coli. This inhibition can be + relieved by adding lactose or + isopropyl-beta-D-thiogalactopyranoside (IPTG)." + promoter complement(5915..5945) + /label=lac promoter + /note="promoter for the E. coli lac operon" + protein_bind 5960..5981 + /label=CAP binding site + /bound_moiety="E. coli catabolite activator protein" + /note="CAP binding activates transcription in the presence + of cAMP." + primer_bind complement(6098..6115) + /label=L4440 + /note="L4440 vector, forward primer" + rep_origin complement(6269..6857) + /direction=LEFT + /label=ori + /note="high-copy-number ColE1/pMB1/pBR322/pUC origin of + replication" + primer_bind complement(6349..6368) + /label=pBR322ori-F + /note="pBR322 origin, forward primer" + CDS complement(7028..286) + /codon_start=1 + /gene="bla" + /product="beta-lactamase" + /label=AmpR + /note="confers resistance to ampicillin, carbenicillin, and + related antibiotics" + /translation="MSIQHFRVALIPFFAAFCLPVFAHPETLVKVKDAEDQLGARVGYI + ELDLNSGKILESFRPEERFPMMSTFKVLLCGAVLSRIDAGQEQLGRRIHYSQNDLVEYS + PVTEKHLTDGMTVRELCSAAITMSDNTAANLLLTTIGGPKELTAFLHNMGDHVTRLDRW + EPELNEAIPNDERDTTMPVAMATTLRKLLTGELLTLASRQQLIDWMEADKVAGPLLRSA + LPAGWFIADKSGAGERGSRGIIAALGPDGKPSRIVVIYTTGSQATMDERNRQIAEIGAS + LIKHW" +ORIGIN + 1 aatagtgtat gcggcgaccg agttgctctt gcccggcgtc aatacgggat aataccgcgc + 61 cacatagcag aactttaaaa gtgctcatca ttggaaaacg ttcttcgggg cgaaaactct + 121 caaggatctt accgctgttg agatccagtt cgatgtaacc cactcgtgca cccaactgat + 181 cttcagcatc ttttactttc accagcgttt ctgggtgagc aaaaacagga aggcaaaatg + 241 ccgcaaaaaa gggaataagg gcgacacgga aatgttgaat actcatactc ttcctttttc + 301 aatattattg aagcatttat cagggttatt gtctcatgag cggatacata tttgaatgta + 361 tttagaaaaa taaacaaata ggggttccgc gcacatttcc ccgaaaagtg ccacctaaat + 421 tgtaagcgtt aatattttgt taaaattcgc gttaaatttt tgttaaatca gctcattttt + 481 taaccaatag gccgaaatcg gcaaaatccc ttataaatca aaagaataga ccgagatagg + 541 gttgagtgtt gttccagttt ggaacaagag tccactatta aagaacgtgg actccaacgt + 601 caaagggcga aaaaccgtct atcagggcga tggcccacta cgtgaaccat caccctaatc + 661 aagttttttg gggtcgaggt gccgtaaagc actaaatcgg aaccctaaag ggagcccccg + 721 atttagagct tgacggggaa agccggcgaa cgtggcgaga aaggaaggga agaaagcgaa + 781 aggagcgggc gctagggcgc tggcaagtgt agcggtcacg ctgcgcgtaa ccaccacacc + 841 cgccgcgctt aatgcgccgc tacagggcgc gtcccattcg ccattcaggc tgcgcaactg + 901 ttgggaaggg cgatcggtgc gggcctcttc gctattacgc cagctggcga aagggggatg + 961 tgctgcaagg cgattaagtt gggtaacgcc agggttttcc cagtcacgac gttgtaaaac + 1021 gacggccagt gagcgcgcgt aatacgactc actatagggc gaattgggta ccaaatagta + 1081 ggaattaccc acctgtacaa gtgctgaaaa cttggatgaa taagcccgtt tgccattttc + 1141 tactgctatt ttaaatcttt tctgtatttg tctgcatttg tctttaccct tgaataaatg + 1201 ttttagttgt tttttttcaa ttatgactgt gtttaacaga cattattaca ataatatgta + 1261 atagtagtac acactattat tatgtaatag tacttgttga ctgtatttga gaactggacc + 1321 gagtgagtgt tacgtcaccc attcaaaatg acttacttct ggctccaaca aaatgaagtt + 1381 aattcagttg ccatttttca ctgtatggac atcgccgtgt tggagctaga cgttgccaat + 1441 aagcaagaaa gagccgagat gcgtcgagtc tgagtcaccg ttcctatggc aacccctcta + 1501 accaatcaga agtaagcttg ttggaagtcc acagcctacc acttgaaagc gggctgcaca + 1561 aaatctgtca aacgttttga acgttggatg tgagagcaca tacttttatt aaggcatctg + 1621 gttggtcagt ttataatatc aacaacttgg gctacagaaa agaaaagtta ttacagaaat + 1681 tatgattaac aagtacatgt taaataaaga ttttaatatg aatgccacca ctggagcatt + 1741 catgccattt ggagcttctt cctgtttgga tcactagaag gaggaggtca ctcattacag + 1801 ttctcatata cagtcgttgg ttggttggtt ggttggtaga ttgattgatt gattgattga + 1861 ttgattgatt gattgattga ttgattgatt gattgattga ttgattgatt gattggtagt + 1921 caaaataaga aataatttcc acagattcat tacagaaatg attaaatgca tacataaaaa + 1981 actggggggg gggggataca acaacacact taagtcacat ttgcctacgt aaagaaaagt + 2041 aaagaaaatc aatagctata ttttacatct cctttttttg ctgtctttta attagccttg + 2101 ttttgctgtt atcttgattg aaactgtaac ttcttcacct gcttcttttc tttgtaggtt + 2161 ttgccagccc agaaacaggc atggctgtgc aaggccagag caccatgcac aatgcgctgc + 2221 atgtcttcat gaacggctca atgtcctcag tccagggctc agccaacgac cccatcttcc + 2281 tccttcacca tgctttcatt gacaggtaac aaacacgtca tgacattaga ctgcacagtt + 2341 tttgacaaag ttcatacaat ctgttgttta tagctgctac aattagtgaa gtttgtgaat + 2401 gtacttggat gagcagcgaa agatcaattg agatcaattg ttagagtttg gttgccctgc + 2461 agagcaaaga acaaaaaata atctggtggc tttactgcgt gaggttatta ttggtggaat + 2521 agaaacacaa aacataattg catttatttg tttaattttt tatcttatct taactttcat + 2581 cttgcatatt tgtttcttac atcatttcta gcatctttga gcgctggcta agaactcatc + 2641 agcctccccg gtccatctac ccacgtacca atgcaccaat tggccacaat gacggctact + 2701 acatggtgcc attccttcct ctttatagga atggagacta cctcctgtcc aacaatgctc + 2761 ttggatacga gtacgcctac ctgttggacc caggtcattg cacaacacca gaaatgccct + 2821 ctgatctgca aaagacgtga atatctgttc agacacccat atccactctg ttccacacag + 2881 gtcagaggtt tgtccaggag ttcttgacag aggtgtaaaa agtactcaaa aattttactc + 2941 aagtgaaagt acaagtactt agggaaaatt ttactcaatt aaaagtaaaa gtatctggct + 3001 agaatcttac ttgagtaaaa gtaaaaaagt actccattaa aattgtactt gagtattaag + 3061 gaagtaaaag taaaagcaag aaagaaaact agagattctt gtttaagctt ttaatctcaa + 3121 aaaacattaa atgaaatgca tacaaggttt tatcctgctt tagaactgtt tgtatttaat + 3181 tatcaaacta taagacagac aatctaatgc cagtacacgc tactcaaagt tgtaaaacct + 3241 cagatttaac ttcagtagaa gctgattctc aaaattgtta gtgtcaagcc tagctctttt + 3301 ggggctgaaa agcaatcctg cagtgctgaa aagcctctca caggcagccg atgcgggaag + 3361 aggtgtatta gtcttgatag agaggctgca aatagcagga aacgtgagca gagactccct + 3421 ggtgtctgaa acacaggcca gatgggccct cgagagatct ctcgactcta gagggtatat + 3481 aatggatccc atcgcgtctc agcctcactt tgagctcctc cacacgaatt tcgaccgatc + 3541 ctgagaactt cagggtgagt ttggggaccc ttgattgttc tttctttttc gctattgtaa + 3601 aattcatgtt atatggaggg ggcaaagttt tcagggtgtt gtttagaatg ggaagatgtc + 3661 ccttgtatca ccatggaccc tcatgataat tttgtttctt tcactttcta ctctgttgac + 3721 aaccattgtc tcctcttatt ttcttttcat tttctgtaac tttttcgtta aactttagct + 3781 tgcatttgta acgaattttt aaattcactt ttgtttattt gtcagattgt aagtactttc + 3841 tctaatcact tttttttcaa ggcaatcagg gtatattata ttgtacttca gcacagtttt + 3901 agagaacaat tgttataatt aaatgataag gtagaatatt tctgcatata aattctggct + 3961 ggcgtggaaa tattcttatt ggtagaaaca actacaccct ggtcatcatc ctgcctttct + 4021 ctttatggtt acaatgatat acactgtttg agatgaggat aaaatactct gagtccaaac + 4081 cgggcccctc tgctaaccat gttcatgcct tcttctcttt cctacagctc ctgggcaacg + 4141 tgctggttgt tgtgctgtct catcattttg gcaaagaatt cctcgacgga tccaccggtc + 4201 gccaccatgg tgagcaaggg cgaggagctg ttcaccgggg tggtgcccat cctggtcgag + 4261 ctggacggcg acgtaaacgg ccacaagttc agcgtgtccg gcgagggcga gggcgatgcc + 4321 acctacggca agctgaccct gaagttcatc tgcaccaccg gcaagctgcc cgtgccctgg + 4381 cccaccctcg tgaccaccct gacctacggc gtgcagtgct tcagccgcta ccccgaccac + 4441 atgaagcagc acgacttctt caagtccgcc atgcccgaag gctacgtcca ggagcgcacc + 4501 atcttcttca aggacgacgg caactacaag acccgcgccg aggtgaagtt cgagggcgac + 4561 accctggtga accgcatcga gctgaagggc atcgacttca aggaggacgg caacatcctg + 4621 gggcacaagc tggagtacaa ctacaacagc cacaacgtct atatcatggc cgacaagcag + 4681 aagaacggca tcaaggtgaa cttcaagatc cgccacaaca tcgaggacgg cagcgtgcag + 4741 ctcgccgacc actaccagca gaacaccccc atcggcgacg gccccgtgct gctgcccgac + 4801 aaccactacc tgagcaccca gtccgccctg agcaaagacc ccaacgagaa gcgcgatcac + 4861 atggtcctgc tggagttcgt gaccgccgcc gggatcactc tcggcatgga cgagctgtac + 4921 aagtaaagcg gccgccaccg cggtggagct cgaattaatt catcgatgat gatccagaca + 4981 tgataagata cattgatgag tttggacaaa ccacaactag aatgcagtga aaaaaatgct + 5041 ttatttgtga aatttgtgat gctattgctt tatttgtaac cattataagc tgcaataaac + 5101 aagttaacaa caacaattgc attcatttta tgtttcaggt tcagggggag gtgtgggagg + 5161 ttttttaaag caagtaaaac ctctacaaat gtggtatggc tgattatgat cctctagatc + 5221 agatccgaag atacggccac gggtgctctt gatcctgtgg ctgattttgg actgtgctgc + 5281 tcgcagctgc tgatgaatca catacttcct ccattttctt ccactgattg actgttataa + 5341 tttccctaat ttccaggtca aggtgctgtg cattgtggta atagatgtga catgacgtca + 5401 cttccaaagg accaatgaac atgtctgacc aatttcatat aatgtgaaaa cgattttcat + 5461 aggcagaata aataacattt aaattaaact gggcatcagc gcaattcaat tggtttggta + 5521 atagcaaggg aaaatagaat gaagtgatct ccaaaaaata agtacttttt gactgtaaat + 5581 aaaattgtaa ggagtaaaaa gtactttttt ttctaaaaaa atgtaattaa gtaaaagtaa + 5641 aagtattgat ttttaattgt actcaagtaa agtaaaaatc cccaaaaata atacttaagt + 5701 acagtaatca agtaaaatta ctcaagtact ttacacctct ggttcttgac cccctacctt + 5761 cagcaagccc agcagatcca ctagttctag agcggccgcc accgcggtgg agctccagct + 5821 tttgttccct ttagtgaggg ttaattgcgc gcttggcgta atcatggtca tagctgtttc + 5881 ctgtgtgaaa ttgttatccg ctcacaattc cacacaacat acgagccgga agcataaagt + 5941 gtaaagcctg gggtgcctaa tgagtgagct aactcacatt aattgcgttg cgctcactgc + 6001 ccgctttcca gtcgggaaac ctgtcgtgcc agctgcatta atgaatcggc caacgcgcgg + 6061 ggagaggcgg tttgcgtatt gggcgctctt ccgcttcctc gctcactgac tcgctgcgct + 6121 cggtcgttcg gctgcggcga gcggtatcag ctcactcaaa ggcggtaata cggttatcca + 6181 cagaatcagg ggataacgca ggaaagaaca tgtgagcaaa aggccagcaa aaggccagga + 6241 accgtaaaaa ggccgcgttg ctggcgtttt tccataggct ccgcccccct gacgagcatc + 6301 acaaaaatcg acgctcaagt cagaggtggc gaaacccgac aggactataa agataccagg + 6361 cgtttccccc tggaagctcc ctcgtgcgct ctcctgttcc gaccctgccg cttaccggat + 6421 acctgtccgc ctttctccct tcgggaagcg tggcgctttc tcatagctca cgctgtaggt + 6481 atctcagttc ggtgtaggtc gttcgctcca agctgggctg tgtgcacgaa ccccccgttc + 6541 agcccgaccg ctgcgcctta tccggtaact atcgtcttga gtccaacccg gtaagacacg + 6601 acttatcgcc actggcagca gccactggta acaggattag cagagcgagg tatgtaggcg + 6661 gtgctacaga gttcttgaag tggtggccta actacggcta cactagaaga acagtatttg + 6721 gtatctgcgc tctgctgaag ccagttacct tcggaaaaag agttggtagc tcttgatccg + 6781 gcaaacaaac caccgctggt agcggtggtt tttttgtttg caagcagcag attacgcgca + 6841 gaaaaaaagg atctcaagaa gatcctttga tcttttctac ggggtctgac gctcagtgga + 6901 acgaaaactc acgttaaggg attttggtca tgagattatc aaaaaggatc ttcacctaga + 6961 tccttttaaa ttaaaaatga agttttaaat caatctaaag tatatatgag taaacttggt + 7021 ctgacagtta ccaatgctta atcagtgagg cacctatctc agcgatctgt ctatttcgtt + 7081 catccatagt tgcctgactc cccgtcgtgt agataactac gatacgggag ggcttaccat + 7141 ctggccccag tgctgcaatg ataccgcgag acccacgctc accggctcca gatttatcag + 7201 caataaacca gccagccgga agggccgagc gcagaagtgg tcctgcaact ttatccgcct + 7261 ccatccagtc tattaattgt tgccgggaag ctagagtaag tagttcgcca gttaatagtt + 7321 tgcgcaacgt tgttgccatt gctacaggca tcgtggtgtc acgctcgtcg tttggtatgg + 7381 cttcattcag ctccggttcc caacgatcaa ggcgagttac atgatccccc atgttgtgca + 7441 aaaaagcggt tagctccttc ggtcctccga tcgttgtcag aagtaagttg gccgcagtgt + 7501 tatcactcat ggttatggca gcactgcata attctcttac tgtcatgcca tccgtaagat + 7561 gcttttctgt gactggtgag tactcaacca agtcattctg ag +// From e8be187268f0c720b21fbb25d7d9582a688ab37f Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sat, 25 Apr 2020 19:45:40 +0100 Subject: [PATCH 056/769] Added basic integration test to demonstrate the issue --- .../core/sequence/io/GenbankReaderTest.java | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java index 5bcbecf672..42eca4a3a1 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java @@ -22,41 +22,24 @@ import org.biojava.nbio.core.exceptions.CompoundNotFoundException; import org.biojava.nbio.core.sequence.DNASequence; -import org.biojava.nbio.core.sequence.RNASequence; import org.biojava.nbio.core.sequence.ProteinSequence; -import org.biojava.nbio.core.sequence.compound.AminoAcidCompound; -import org.biojava.nbio.core.sequence.compound.AminoAcidCompoundSet; -import org.biojava.nbio.core.sequence.compound.DNACompoundSet; -import org.biojava.nbio.core.sequence.compound.RNACompoundSet; -import org.biojava.nbio.core.sequence.compound.NucleotideCompound; +import org.biojava.nbio.core.sequence.RNASequence; +import org.biojava.nbio.core.sequence.compound.*; import org.biojava.nbio.core.sequence.features.FeatureInterface; import org.biojava.nbio.core.sequence.features.Qualifier; import org.biojava.nbio.core.sequence.template.AbstractSequence; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @@ -350,6 +333,14 @@ public void testLegacyLocusCompatable() throws IOException, CompoundNotFoundExce } + @Test + public void readSequenceWithZeroSpanFeature() throws IOException, CompoundNotFoundException { + logger.info("make or read genbank file error when feature spans zero point of circular sequence (issue #855)"); + final DNASequence seq = readGenbankResource("/feature-spans-zero-point-circular-sequence.gb"); + + assertNotNull(seq); + } + /** * Helper class to be able to verify the closed state of the input stream. */ From 0a86883f271ac3856e805d84c6491272e79ea9a0 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sat, 25 Apr 2020 21:34:54 +0100 Subject: [PATCH 057/769] retrieve information of circular sequence --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 9641a38894..c818cadd43 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -67,6 +67,7 @@ public class GenbankSequenceParser, C extends Comp private GenericGenbankHeaderParser headerParser; private String header; private String accession; + private boolean isCircularSequence; public LinkedHashMap> mapDB; /** * this data structure collects list of features extracted from the @@ -178,6 +179,8 @@ private String parse(BufferedReader bufferedReader) { } } + isCircularSequence = m.group(6).equalsIgnoreCase("circular"); + log.debug("compound type: {}", compoundType.getClass().getSimpleName()); } else { From a74c0152cc192ae7e7a71c61403034ca8d61e641 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sat, 25 Apr 2020 22:09:00 +0100 Subject: [PATCH 058/769] Propagate down this bit of information --- .../sequence/io/GenbankSequenceParser.java | 2 +- .../core/sequence/location/InsdcParser.java | 44 +++++++++++-------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index c818cadd43..023497545d 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -283,7 +283,7 @@ private String parse(BufferedReader bufferedReader) { // new feature! gbFeature = new TextFeature(key, val, key, key); Location l = - locationParser.parse(val); + locationParser.parse(val, isCircularSequence); gbFeature.setLocation((AbstractLocation)l); if (!featureCollection.containsKey(key)) { diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java index 2e8217ea43..19ac38258c 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java @@ -135,40 +135,45 @@ public DataSource getDataSource() { * @return The parsed location * @throws ParserException thrown in the event of any error during parsing */ - public Location parse(String locationString) throws ParserException { + public Location parse(String locationString, boolean isSequenceCircular) throws ParserException { featureGlobalStart = Integer.MAX_VALUE; featureGlobalEnd = 1; Location l; - List ll = parseLocationString(locationString, 1); + List ll = parseLocationString(locationString, 1, isSequenceCircular); if (ll.size() == 1) { l = ll.get(0); } else { l = new SimpleLocation( - featureGlobalStart, - featureGlobalEnd, + new SimplePoint(featureGlobalStart), + new SimplePoint(featureGlobalEnd), Strand.UNDEFINED, + isSequenceCircular, ll); } return l; } - /** - * Reader based version of the parse methods. - * - * @param reader The source of the data; assumes that end of the reader - * stream is the end of the location string to parse - * @return The parsed location - * @throws IOException Thrown with any reader error - * @throws ParserException Thrown with any error with parsing locations - */ + public Location parse(String locationString) throws ParserException { + return parse(locationString, false); + } + + /** + * Reader based version of the parse methods. + * + * @param reader The source of the data; assumes that end of the reader + * stream is the end of the location string to parse + * @return The parsed location + * @throws IOException Thrown with any reader error + * @throws ParserException Thrown with any error with parsing locations + */ public List parse(Reader reader) throws IOException, ParserException { // use parse(String s) instead! return null; } - private List parseLocationString(String string, int versus) throws ParserException { + private List parseLocationString(String string, int versus, boolean isSequenceCircular) throws ParserException { Matcher m; List boundedLocationsCollection = new ArrayList(); @@ -186,7 +191,8 @@ private List parseLocationString(String string, int versus) throws Par if (!splitQualifier.isEmpty()) { //recursive case int localVersus = splitQualifier.equalsIgnoreCase("complement") ? -1 : 1; - List subLocations = parseLocationString(splitString, versus * localVersus); + List subLocations = parseLocationString( + splitString, versus * localVersus, isSequenceCircular); switch (complexFeaturesAppendMode) { case FLATTEN: @@ -228,8 +234,8 @@ private List parseLocationString(String string, int versus) throws Par String accession = m.group(1); Strand s = versus == 1 ? Strand.POSITIVE : Strand.NEGATIVE; - int start = Integer.parseInt(m.group(3)); - int end = m.group(6) == null ? start : new Integer(m.group(6)); + int start = Integer.valueOf(m.group(3)); + int end = m.group(6) == null ? start : Integer.valueOf(m.group(6)); if (featureGlobalStart > start) { featureGlobalStart = start; @@ -239,8 +245,8 @@ private List parseLocationString(String string, int versus) throws Par } AbstractLocation l = new SimpleLocation( - start, - end, + new SimplePoint(start), + new SimplePoint(end), s ); From 4fd3fdbe353ebe00a621c46ff0c2f2aeb9f4d83e Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sat, 25 Apr 2020 22:33:00 +0100 Subject: [PATCH 059/769] Need to extract also the sequence length to correctly create two locations spanning sequence end. --- .../nbio/core/sequence/io/GenbankSequenceParser.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 023497545d..eb0c5550fd 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -68,6 +68,7 @@ public class GenbankSequenceParser, C extends Comp private String header; private String accession; private boolean isCircularSequence; + private long sequenceLength; public LinkedHashMap> mapDB; /** * this data structure collects list of features extracted from the @@ -110,7 +111,7 @@ public class GenbankSequenceParser, C extends Comp protected static final String START_SEQUENCE_TAG = "ORIGIN"; protected static final String END_SEQUENCE_TAG = "//"; // locus line - protected static final Pattern lp = Pattern.compile("^(\\S+)\\s+\\d+\\s+(bp|BP|aa|AA)\\s{0,4}(([dmsDMS][sS]-)?(\\S+))?\\s*(circular|CIRCULAR|linear|LINEAR)?\\s*(\\S+)?\\s*(\\S+)?$"); + protected static final Pattern lp = Pattern.compile("^(\\S+)\\s+(\\d+)\\s+(bp|BP|aa|AA)\\s{0,4}(([dmsDMS][sS]-)?(\\S+))?\\s*(circular|CIRCULAR|linear|LINEAR)?\\s*(\\S+)?\\s*(\\S+)?$"); // version line protected static final Pattern vp = Pattern.compile("^(\\S*?)(\\.(\\d+))?(\\s+GI:(\\S+))?$"); // reference line @@ -161,9 +162,9 @@ private String parse(BufferedReader bufferedReader) { if (m.matches()) { headerParser.setName(m.group(1)); headerParser.setAccession(m.group(1)); // default if no accession found - - String lengthUnits = m.group(2); - String type = m.group(5); + sequenceLength = Long.valueOf(m.group(2)); + String lengthUnits = m.group(3); + String type = m.group(6); if (lengthUnits.equalsIgnoreCase("aa")) { compoundType = AminoAcidCompoundSet.getAminoAcidCompoundSet(); @@ -179,7 +180,7 @@ private String parse(BufferedReader bufferedReader) { } } - isCircularSequence = m.group(6).equalsIgnoreCase("circular"); + isCircularSequence = m.group(7).equalsIgnoreCase("circular"); log.debug("compound type: {}", compoundType.getClass().getSimpleName()); From d724aec7d36dd4fdc314d3e7d5fa0da6f70942e9 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sat, 25 Apr 2020 22:43:02 +0100 Subject: [PATCH 060/769] Need to propagate down also this bit of information. Since two parameters more may be less readable I changed strategy and configured parser class. --- .../sequence/io/GenbankSequenceParser.java | 6 ++++- .../core/sequence/location/InsdcParser.java | 23 +++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index eb0c5550fd..1953de60dc 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -182,6 +182,10 @@ private String parse(BufferedReader bufferedReader) { isCircularSequence = m.group(7).equalsIgnoreCase("circular"); + // configure location parser with needed information + locationParser.setSequenceLength(sequenceLength); + locationParser.setSequenceCircular(isCircularSequence); + log.debug("compound type: {}", compoundType.getClass().getSimpleName()); } else { @@ -284,7 +288,7 @@ private String parse(BufferedReader bufferedReader) { // new feature! gbFeature = new TextFeature(key, val, key, key); Location l = - locationParser.parse(val, isCircularSequence); + locationParser.parse(val); gbFeature.setLocation((AbstractLocation)l); if (!featureCollection.containsKey(key)) { diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java index 19ac38258c..b802e9f3cb 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.io.Reader; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -49,6 +50,9 @@ */ public class InsdcParser , C extends Compound>{ + private boolean isSequenceCircular; + private long sequenceLength; + private final DataSource dataSource; /** @@ -80,7 +84,6 @@ public class InsdcParser , C extends Compound>{ * Not really sure that they are not declared obsolete but they are still in * several files. */ - //protected static final Pattern genbankSplitPattern = Pattern.compile("^\\s?(join|order|bond|complement|)\\(?([^\\)]+)\\)?"); protected static final Pattern genbankSplitPattern = Pattern.compile("^\\s?(join|order|bond|complement|)\\(?(.+)\\)?"); /** * designed to recursively split a location string in tokens. Valid tokens @@ -126,7 +129,13 @@ public DataSource getDataSource() { return dataSource; } + public void setSequenceCircular(boolean sequenceCircular) { + isSequenceCircular = sequenceCircular; + } + public void setSequenceLength(long sequenceLength) { + this.sequenceLength = sequenceLength; + } /** * Main method for parsing a location from a String instance @@ -135,12 +144,12 @@ public DataSource getDataSource() { * @return The parsed location * @throws ParserException thrown in the event of any error during parsing */ - public Location parse(String locationString, boolean isSequenceCircular) throws ParserException { + public Location parse(String locationString) throws ParserException { featureGlobalStart = Integer.MAX_VALUE; featureGlobalEnd = 1; Location l; - List ll = parseLocationString(locationString, 1, isSequenceCircular); + List ll = parseLocationString(locationString, 1); if (ll.size() == 1) { l = ll.get(0); @@ -155,10 +164,6 @@ public Location parse(String locationString, boolean isSequenceCircular) throws return l; } - public Location parse(String locationString) throws ParserException { - return parse(locationString, false); - } - /** * Reader based version of the parse methods. * @@ -173,7 +178,7 @@ public List parse(Reader reader) throws IOException, ParserExc return null; } - private List parseLocationString(String string, int versus, boolean isSequenceCircular) throws ParserException { + private List parseLocationString(String string, int versus) throws ParserException { Matcher m; List boundedLocationsCollection = new ArrayList(); @@ -192,7 +197,7 @@ private List parseLocationString(String string, int versus, boolean is //recursive case int localVersus = splitQualifier.equalsIgnoreCase("complement") ? -1 : 1; List subLocations = parseLocationString( - splitString, versus * localVersus, isSequenceCircular); + splitString, versus * localVersus); switch (complexFeaturesAppendMode) { case FLATTEN: From e49b69be3fc1f3734b871715ac73e34deeb72cc1 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sat, 25 Apr 2020 22:50:03 +0100 Subject: [PATCH 061/769] Implementation of exceptional complex location in case of location spanning the end point. Location contract wants sublocations --- .../sequence/io/GenbankSequenceParser.java | 4 +- .../core/sequence/location/InsdcParser.java | 37 +++++++++++++++---- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 1953de60dc..cada9a3238 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -68,7 +68,7 @@ public class GenbankSequenceParser, C extends Comp private String header; private String accession; private boolean isCircularSequence; - private long sequenceLength; + private int sequenceLength; public LinkedHashMap> mapDB; /** * this data structure collects list of features extracted from the @@ -162,7 +162,7 @@ private String parse(BufferedReader bufferedReader) { if (m.matches()) { headerParser.setName(m.group(1)); headerParser.setAccession(m.group(1)); // default if no accession found - sequenceLength = Long.valueOf(m.group(2)); + sequenceLength = Integer.valueOf(m.group(2)); String lengthUnits = m.group(3); String type = m.group(6); diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java index b802e9f3cb..8d7fcf9ee8 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java @@ -51,7 +51,7 @@ public class InsdcParser , C extends Compound>{ private boolean isSequenceCircular; - private long sequenceLength; + private int sequenceLength; private final DataSource dataSource; @@ -133,7 +133,7 @@ public void setSequenceCircular(boolean sequenceCircular) { isSequenceCircular = sequenceCircular; } - public void setSequenceLength(long sequenceLength) { + public void setSequenceLength(int sequenceLength) { this.sequenceLength = sequenceLength; } @@ -249,11 +249,34 @@ private List parseLocationString(String string, int versus) throws Par featureGlobalEnd = end; } - AbstractLocation l = new SimpleLocation( - new SimplePoint(start), - new SimplePoint(end), - s - ); + AbstractLocation l; + if (start < end) { + l = new SimpleLocation( + new SimplePoint(start), + new SimplePoint(end), + s + ); + } else { + // in case of location spanning the end point, Location contract wants sublocations + AbstractLocation l5prime = new SimpleLocation( + new SimplePoint(1), + new SimplePoint(end), + Strand.POSITIVE + ); + AbstractLocation l3prime = new SimpleLocation( + new SimplePoint(start), + new SimplePoint(sequenceLength), + Strand.POSITIVE + ); + + l = new SimpleLocation( + new SimplePoint(start), + new SimplePoint(end), // seq length + s, + isSequenceCircular, + Arrays.asList(l5prime, l3prime) + ); + } if(m.group(4) != null && m.group(4).equals("^")) l.setBetweenCompounds(true); From 75c29b693f06ab50b2818f7d634e6de05cf550c8 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sat, 25 Apr 2020 22:53:01 +0100 Subject: [PATCH 062/769] Modified the exception to take in account this particular case --- .../core/sequence/location/template/AbstractLocation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java index 10ee98d1e8..818554c395 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java @@ -128,9 +128,9 @@ protected void assertLocation() { int st = getStart().getPosition(); int e = getEnd().getPosition(); - if (st > e) { + if (st > e && ! circular) { throw new IllegalStateException( - String.format("Start (%d) is greater than end (%d); " + String.format("Start (%d) is greater than end (%d) in non circular sequence; " + "this is an incorrect format", st, e)); } From 5f4ab818e4bb8c6d3f030466eeef2a5f22336f1c Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sun, 26 Apr 2020 22:12:44 +0100 Subject: [PATCH 063/769] even better location management --- .../sequence/location/InsdcLocations.java | 4 +++ .../core/sequence/location/InsdcParser.java | 30 +++++++++---------- .../location/template/AbstractLocation.java | 2 +- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java index 25b8925c22..5e998c7f99 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java @@ -147,6 +147,10 @@ public GroupLocation(Location... subLocations) { this(Arrays.asList(subLocations)); } + public GroupLocation(boolean isCircular, Location... subLocations) { + this(Arrays.asList(subLocations)); + } + public GroupLocation(Point start, Point end, Strand strand, boolean circular, Location... subLocations) { super(start, end, strand, circular, subLocations); diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java index 8d7fcf9ee8..c40c00b1c5 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java @@ -35,7 +35,6 @@ import java.io.IOException; import java.io.Reader; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -250,32 +249,33 @@ private List parseLocationString(String string, int versus) throws Par } AbstractLocation l; - if (start < end) { + if (start <= end) { l = new SimpleLocation( - new SimplePoint(start), - new SimplePoint(end), + start, + end, s ); } else { // in case of location spanning the end point, Location contract wants sublocations AbstractLocation l5prime = new SimpleLocation( - new SimplePoint(1), - new SimplePoint(end), - Strand.POSITIVE - ); + 1, + end, + Strand.UNDEFINED + ); AbstractLocation l3prime = new SimpleLocation( - new SimplePoint(start), - new SimplePoint(sequenceLength), - Strand.POSITIVE - ); + start, + sequenceLength, + Strand.UNDEFINED + ); - l = new SimpleLocation( + l = new InsdcLocations.GroupLocation( new SimplePoint(start), - new SimplePoint(end), // seq length + new SimplePoint(end), s, isSequenceCircular, - Arrays.asList(l5prime, l3prime) + l5prime, l3prime ); + } if(m.group(4) != null && m.group(4).equals("^")) l.setBetweenCompounds(true); diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java index 818554c395..1b0c06bee1 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java @@ -128,7 +128,7 @@ protected void assertLocation() { int st = getStart().getPosition(); int e = getEnd().getPosition(); - if (st > e && ! circular) { + if (st > e && ! isCircular()) { throw new IllegalStateException( String.format("Start (%d) is greater than end (%d) in non circular sequence; " + "this is an incorrect format", From f014aefc4a6a50a89f6fbb9c5401ee7d6bf04620 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sun, 26 Apr 2020 23:24:26 +0100 Subject: [PATCH 064/769] Improved unit test --- .../nbio/core/sequence/io/GenbankReaderTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java index 42eca4a3a1..e8ac4cd8a7 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java @@ -24,9 +24,11 @@ import org.biojava.nbio.core.sequence.DNASequence; import org.biojava.nbio.core.sequence.ProteinSequence; import org.biojava.nbio.core.sequence.RNASequence; +import org.biojava.nbio.core.sequence.Strand; import org.biojava.nbio.core.sequence.compound.*; import org.biojava.nbio.core.sequence.features.FeatureInterface; import org.biojava.nbio.core.sequence.features.Qualifier; +import org.biojava.nbio.core.sequence.location.template.AbstractLocation; import org.biojava.nbio.core.sequence.template.AbstractSequence; import org.junit.*; import org.slf4j.Logger; @@ -339,6 +341,14 @@ public void readSequenceWithZeroSpanFeature() throws IOException, CompoundNotFou final DNASequence seq = readGenbankResource("/feature-spans-zero-point-circular-sequence.gb"); assertNotNull(seq); + + final FeatureInterface, NucleotideCompound> f = seq.getFeatures().get(33); + final AbstractLocation fLocation = f.getLocations(); + + assertEquals(true, fLocation.isCircular()); + assertEquals(7028, (int)fLocation.getStart().getPosition()); + assertEquals(286, (int)fLocation.getEnd().getPosition()); + assertEquals(Strand.NEGATIVE, fLocation.getStrand()); } /** From c1a6b157ac2ab74130487b62586ca49517f26172 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sun, 26 Apr 2020 23:39:38 +0100 Subject: [PATCH 065/769] Fixed failing unit test for sequence lengths not compatible with integer. This fix should be propagated to Location class and related. --- .../nbio/core/sequence/io/GenbankSequenceParser.java | 4 ++-- .../biojava/nbio/core/sequence/location/InsdcParser.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index cada9a3238..1953de60dc 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -68,7 +68,7 @@ public class GenbankSequenceParser, C extends Comp private String header; private String accession; private boolean isCircularSequence; - private int sequenceLength; + private long sequenceLength; public LinkedHashMap> mapDB; /** * this data structure collects list of features extracted from the @@ -162,7 +162,7 @@ private String parse(BufferedReader bufferedReader) { if (m.matches()) { headerParser.setName(m.group(1)); headerParser.setAccession(m.group(1)); // default if no accession found - sequenceLength = Integer.valueOf(m.group(2)); + sequenceLength = Long.valueOf(m.group(2)); String lengthUnits = m.group(3); String type = m.group(6); diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java index c40c00b1c5..5972882072 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java @@ -50,7 +50,7 @@ public class InsdcParser , C extends Compound>{ private boolean isSequenceCircular; - private int sequenceLength; + private long sequenceLength; private final DataSource dataSource; @@ -132,7 +132,7 @@ public void setSequenceCircular(boolean sequenceCircular) { isSequenceCircular = sequenceCircular; } - public void setSequenceLength(int sequenceLength) { + public void setSequenceLength(long sequenceLength) { this.sequenceLength = sequenceLength; } @@ -264,7 +264,7 @@ private List parseLocationString(String string, int versus) throws Par ); AbstractLocation l3prime = new SimpleLocation( start, - sequenceLength, + (int) sequenceLength, Strand.UNDEFINED ); From e98bfb7ea6917912e7d75852f2a7969ce6ad2a5f Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Sun, 26 Apr 2020 23:48:33 +0100 Subject: [PATCH 066/769] fixed failing unit test --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 1953de60dc..01c3f4a147 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -180,7 +180,7 @@ private String parse(BufferedReader bufferedReader) { } } - isCircularSequence = m.group(7).equalsIgnoreCase("circular"); + if (m.group(7) != null) isCircularSequence = m.group(7).equalsIgnoreCase("circular"); // configure location parser with needed information locationParser.setSequenceLength(sequenceLength); From 092d9b1603414a89fdc5eed4e49432032ba98c90 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 12:18:05 +0100 Subject: [PATCH 067/769] Usually expected preceeds tested --- .../org/biojava/nbio/core/sequence/io/GenbankReaderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java index e8ac4cd8a7..8cdbe00f66 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java @@ -214,7 +214,7 @@ public void CDStest() throws Exception { Assert.assertNotNull(codedBy); Assert.assertTrue(!codedBy.isEmpty()); - assertEquals(codedBy, "NM_000266.2:503..904"); + assertEquals("NM_000266.2:503..904", codedBy); assertEquals(5, dbrefs.size()); } From 4ead4890a18b61cbf1d863d45bcf4e2661096fb3 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 20:18:49 +0100 Subject: [PATCH 068/769] deleted unneeded Exception --- .../org/biojava/nbio/core/sequence/io/GenbankReaderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java index 8cdbe00f66..0bfdc80dd6 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java @@ -154,7 +154,7 @@ public void testProcess() throws Exception { * The underlying {@link InputStream} should remain open until the last call. */ @Test - public void testPartialProcess() throws IOException, CompoundNotFoundException, NoSuchFieldException { + public void testPartialProcess() throws IOException, CompoundNotFoundException { CheckableInputStream inStream = new CheckableInputStream(this.getClass().getResourceAsStream("/two-dnaseqs.gb")); GenbankReader genbankDNA From 87eeb7426d85b1fa5efe48931c91b0b89bc50ca0 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 20:21:22 +0100 Subject: [PATCH 069/769] assertion normalization --- .../biojava/nbio/core/sequence/io/GenbankReaderTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java index 0bfdc80dd6..b2ffdb32f2 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java @@ -202,7 +202,7 @@ public void CDStest() throws Exception { assertTrue(inStream.isclosed()); - Assert.assertTrue(proteinSequences.size() == 1); + Assert.assertEquals(1, proteinSequences.size()); logger.debug("protein sequences: {}", proteinSequences); ProteinSequence protein = new ArrayList<>(proteinSequences.values()).get(0); @@ -213,7 +213,7 @@ public void CDStest() throws Exception { List dbrefs = quals.get("db_xref"); Assert.assertNotNull(codedBy); - Assert.assertTrue(!codedBy.isEmpty()); + Assert.assertFalse(codedBy.isEmpty()); assertEquals("NM_000266.2:503..904", codedBy); assertEquals(5, dbrefs.size()); @@ -345,7 +345,7 @@ public void readSequenceWithZeroSpanFeature() throws IOException, CompoundNotFou final FeatureInterface, NucleotideCompound> f = seq.getFeatures().get(33); final AbstractLocation fLocation = f.getLocations(); - assertEquals(true, fLocation.isCircular()); + assertTrue(fLocation.isCircular()); assertEquals(7028, (int)fLocation.getStart().getPosition()); assertEquals(286, (int)fLocation.getEnd().getPosition()); assertEquals(Strand.NEGATIVE, fLocation.getStrand()); From 83152eddcd33406de7f1b23c6effbee3426e9586 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 20:25:55 +0100 Subject: [PATCH 070/769] deleted un needed methods --- .../core/sequence/io/GenbankReaderTest.java | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java index b2ffdb32f2..0e88790db2 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java @@ -53,25 +53,6 @@ public class GenbankReaderTest { private final static Logger logger = LoggerFactory.getLogger(GenbankReaderTest.class); - public GenbankReaderTest() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } - /** * Test of process method, of class GenbankReader. */ From 370304242e1e0d8eb9195e45c6fedaaae819d296 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 20:41:09 +0100 Subject: [PATCH 071/769] raw type checking fixes --- .../core/sequence/io/GenbankReaderTest.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java index 0e88790db2..aa078c3710 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java @@ -30,6 +30,8 @@ import org.biojava.nbio.core.sequence.features.Qualifier; import org.biojava.nbio.core.sequence.location.template.AbstractLocation; import org.biojava.nbio.core.sequence.template.AbstractSequence; +import org.biojava.nbio.core.sequence.template.Compound; +import org.biojava.nbio.core.sequence.template.Sequence; import org.junit.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -238,7 +240,7 @@ private ProteinSequence readGenbankProteinResource(final String resource) throws private AbstractSequence readUnknownGenbankResource(final String resource) throws IOException, CompoundNotFoundException { InputStream inputStream = getClass().getResourceAsStream(resource); - GenbankSequenceParser genbankParser = new GenbankSequenceParser(); + GenbankSequenceParser, Compound> genbankParser = new GenbankSequenceParser<>(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String seqString = genbankParser.getSequence(bufferedReader, 0); String compoundSet = genbankParser.getCompoundType().getClass().getSimpleName(); @@ -268,48 +270,48 @@ public void testNcbiExpandedAccessionFormats() throws IOException, CompoundNotFo public void testLegacyLocusCompatable() throws IOException, CompoundNotFoundException { // Testing opening a genbank file with uppercase units, strand and topology - AbstractSequence header0 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io/uppercase_locus0.gb"); + AbstractSequence header0 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io/uppercase_locus0.gb"); assertEquals("ABC12.3_DE 7071 BP DS-DNA CIRCULAR SYN 22-JUL-1994", header0.getOriginalHeader()); assertEquals("ABC12.3_DE", header0.getAccession().getID()); assertEquals("DNACompoundSet", header0.getCompoundSet().getClass().getSimpleName()); // Testing uppercase SS strand - AbstractSequence header1 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus1.gb"); + AbstractSequence header1 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus1.gb"); assertEquals("ABC12.3_DE 7071 BP SS-DNA CIRCULAR SYN 13-JUL-1994", header1.getOriginalHeader()); assertEquals("ABC12.3_DE", header1.getAccession().getID()); assertEquals("DNACompoundSet", header0.getCompoundSet().getClass().getSimpleName()); // Testing uppercase MS strand - AbstractSequence header2 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus2.gb"); + AbstractSequence header2 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus2.gb"); assertEquals("ABC12.3_DE 7071 BP MS-DNA CIRCULAR SYN 13-JUL-1994", header2.getOriginalHeader()); assertEquals("ABC12.3_DE", header2.getAccession().getID()); assertEquals("DNACompoundSet", header0.getCompoundSet().getClass().getSimpleName()); // Testing uppercase LINEAR topology - AbstractSequence header3 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus3.gb"); + AbstractSequence header3 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus3.gb"); assertEquals("ABC12.3_DE 7071 BP DNA LINEAR SYN 22-JUL-1994", header3.getOriginalHeader()); assertEquals("ABC12.3_DE", header3.getAccession().getID()); assertEquals("DNACompoundSet", header0.getCompoundSet().getClass().getSimpleName()); // Testing uppercase units with no strand or topology - AbstractSequence header4 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus4.gb"); + AbstractSequence header4 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus4.gb"); assertEquals("ABC12.3_DE 7071 BP RNA SYN 13-JUL-1994", header4.getOriginalHeader()); assertEquals("ABC12.3_DE", header4.getAccession().getID()); assertEquals("RNACompoundSet", header4.getCompoundSet().getClass().getSimpleName()); // Testing uppercase units with no strand, topology, division or date - AbstractSequence header5 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus5.gb"); + AbstractSequence header5 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus5.gb"); assertEquals("ABC12.3_DE 7071 BP DNA", header5.getOriginalHeader()); assertEquals("ABC12.3_DE", header5.getAccession().getID()); // Testing uppercase units with no strand, molecule type, topology, division or date - AbstractSequence header6 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus6.gb"); + AbstractSequence header6 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus6.gb"); assertEquals("ABC12.3_DE 7071 BP", header6.getOriginalHeader()); assertEquals("ABC12.3_DE", header6.getAccession().getID()); assertEquals("DNACompoundSet", header0.getCompoundSet().getClass().getSimpleName()); // Testing uppercase protein units - AbstractSequence header7 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus7.gb"); + AbstractSequence header7 = readUnknownGenbankResource("/org/biojava/nbio/core/sequence/io//uppercase_locus7.gb"); assertEquals("ABC12.3_DE 7071 AA Protein", header7.getOriginalHeader()); assertEquals("ABC12.3_DE", header7.getAccession().getID()); assertEquals("AminoAcidCompoundSet", header7.getCompoundSet().getClass().getSimpleName()); From 4a0cc44e212b1b05531d70d9cfaa377047cc8715 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 20:44:39 +0100 Subject: [PATCH 072/769] this is not suppressing anything --- .../java/org/biojava/nbio/core/sequence/io/GenbankReader.java | 1 - 1 file changed, 1 deletion(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankReader.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankReader.java index 951cce40c0..97cad4cf49 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankReader.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankReader.java @@ -153,7 +153,6 @@ public LinkedHashMap process(final int max) throws IOException, Compou } LinkedHashMap sequences = new LinkedHashMap<>(); - @SuppressWarnings("unchecked") int i=0; while(true) { if(max>0 && i>=max) break; From 590b0b52988499f498f6587abab853bde36a6ecc Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 20:59:46 +0100 Subject: [PATCH 073/769] increased type checking --- .../nbio/core/sequence/io/GenbankSequenceParser.java | 8 +++----- .../nbio/core/sequence/location/InsdcLocations.java | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 01c3f4a147..71b1b22e88 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -37,10 +37,7 @@ import org.biojava.nbio.core.sequence.compound.AminoAcidCompoundSet; import org.biojava.nbio.core.sequence.compound.DNACompoundSet; import org.biojava.nbio.core.sequence.compound.RNACompoundSet; -import org.biojava.nbio.core.sequence.features.AbstractFeature; -import org.biojava.nbio.core.sequence.features.DBReferenceInfo; -import org.biojava.nbio.core.sequence.features.Qualifier; -import org.biojava.nbio.core.sequence.features.TextFeature; +import org.biojava.nbio.core.sequence.features.*; import org.biojava.nbio.core.sequence.io.template.SequenceParserInterface; import org.biojava.nbio.core.sequence.location.InsdcParser; import org.biojava.nbio.core.sequence.location.template.AbstractLocation; @@ -49,6 +46,7 @@ import org.biojava.nbio.core.sequence.template.AbstractSequence; import org.biojava.nbio.core.sequence.template.Compound; import org.biojava.nbio.core.sequence.template.CompoundSet; +import org.biojava.nbio.core.sequence.template.Sequence; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -292,7 +290,7 @@ private String parse(BufferedReader bufferedReader) { gbFeature.setLocation((AbstractLocation)l); if (!featureCollection.containsKey(key)) { - featureCollection.put(key, new ArrayList()); + featureCollection.put(key, new ArrayList<>()); } featureCollection.get(key).add(gbFeature); } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java index 5e998c7f99..1aa27459ad 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java @@ -79,7 +79,7 @@ protected final void assertLocation() { * Used to describe a 5' to 3' ordering but no firm assurance it is correct */ public static class OrderLocation extends SimpleLocation { - public OrderLocation(List subLocations){ + public OrderLocation(List subLocations){ super( Location.Tools.getMin(subLocations).getStart(), Location.Tools.getMax(subLocations).getEnd() @@ -132,7 +132,7 @@ public OrderLocation(int start, int end, Strand strand, * locations */ public static class GroupLocation extends SimpleLocation { - public GroupLocation(List subLocations){ + public GroupLocation(List subLocations){ super( Location.Tools.getMin(subLocations).getStart(), Location.Tools.getMax(subLocations).getEnd() From e0e6ce4b248cd25bce4696a171437cc94d10bcba Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 21:02:06 +0100 Subject: [PATCH 074/769] this can be final --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 71b1b22e88..40f2f3ad60 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -75,7 +75,7 @@ public class GenbankSequenceParser, C extends Comp */ private HashMap> featureCollection; - private Logger log = LoggerFactory.getLogger(getClass()); + private final Logger log = LoggerFactory.getLogger(getClass()); // this is a compoundset parsed from header. private CompoundSet compoundType; From b342b92baa65f5c9e1e69b0ebccf34849732eba0 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 21:04:52 +0100 Subject: [PATCH 075/769] better management of not implemented methods --- .../org/biojava/nbio/core/sequence/location/InsdcParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java index 5972882072..d749a273da 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java @@ -174,7 +174,7 @@ public Location parse(String locationString) throws ParserException { */ public List parse(Reader reader) throws IOException, ParserException { // use parse(String s) instead! - return null; + throw new UnsupportedOperationException("Not implemented yet."); } private List parseLocationString(String string, int versus) throws ParserException { From d02c2d22cae8c5f17668d03d25b7e3b08555c7ab Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 21:05:41 +0100 Subject: [PATCH 076/769] maybe better to delete, can be recreated eventually needed --- .../nbio/core/sequence/location/InsdcParser.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java index d749a273da..d3ccd68b45 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java @@ -163,20 +163,6 @@ public Location parse(String locationString) throws ParserException { return l; } - /** - * Reader based version of the parse methods. - * - * @param reader The source of the data; assumes that end of the reader - * stream is the end of the location string to parse - * @return The parsed location - * @throws IOException Thrown with any reader error - * @throws ParserException Thrown with any error with parsing locations - */ - public List parse(Reader reader) throws IOException, ParserException { - // use parse(String s) instead! - throw new UnsupportedOperationException("Not implemented yet."); - } - private List parseLocationString(String string, int versus) throws ParserException { Matcher m; List boundedLocationsCollection = new ArrayList(); From 496ecdcb5f515aa18298e151c4a6d9d19e8bb218 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 21:14:48 +0100 Subject: [PATCH 077/769] never thrown exception --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 40f2f3ad60..820f0b5062 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -400,7 +400,7 @@ private List readSection(BufferedReader bufferedReader) { } @Override - public String getSequence(BufferedReader bufferedReader, int sequenceLength) throws IOException { + public String getSequence(BufferedReader bufferedReader, int sequenceLength) { featureCollection = new HashMap>(); mapDB = new LinkedHashMap>(); headerParser = new GenericGenbankHeaderParser(); From 6307f77bf46ea207d5033ec50d1f96c42f27add4 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 21:17:09 +0100 Subject: [PATCH 078/769] unused --- .../org/biojava/nbio/core/sequence/io/GenbankReaderTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java index aa078c3710..1bd3a04212 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java @@ -31,7 +31,6 @@ import org.biojava.nbio.core.sequence.location.template.AbstractLocation; import org.biojava.nbio.core.sequence.template.AbstractSequence; import org.biojava.nbio.core.sequence.template.Compound; -import org.biojava.nbio.core.sequence.template.Sequence; import org.junit.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; From c6d1475dc5231971f5f0825662f8638f7c7d44fb Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 21:18:30 +0100 Subject: [PATCH 079/769] static is better, wastes less memory --- .../org/biojava/nbio/core/sequence/io/GenbankReaderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java index 1bd3a04212..f38070c710 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/GenbankReaderTest.java @@ -336,7 +336,7 @@ public void readSequenceWithZeroSpanFeature() throws IOException, CompoundNotFou /** * Helper class to be able to verify the closed state of the input stream. */ - private class CheckableInputStream extends BufferedInputStream { + private static class CheckableInputStream extends BufferedInputStream { private boolean closed; From f013645fb02c86db1caf798d05b13876ed296097 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 21:27:34 +0100 Subject: [PATCH 080/769] Those are not used --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 1 - .../org/biojava/nbio/core/sequence/location/InsdcParser.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 820f0b5062..ad5a64ae1b 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -46,7 +46,6 @@ import org.biojava.nbio.core.sequence.template.AbstractSequence; import org.biojava.nbio.core.sequence.template.Compound; import org.biojava.nbio.core.sequence.template.CompoundSet; -import org.biojava.nbio.core.sequence.template.Sequence; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java index d3ccd68b45..011eb71001 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java @@ -32,8 +32,6 @@ import org.biojava.nbio.core.sequence.template.AbstractSequence; import org.biojava.nbio.core.sequence.template.Compound; -import java.io.IOException; -import java.io.Reader; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; From 23a02359bfb77ff72646cf2a69491ffe8dbc3b32 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 21:31:47 +0100 Subject: [PATCH 081/769] If read, a section exists. This is redundant --- .../sequence/io/GenbankSequenceParser.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index ad5a64ae1b..56ece5e08d 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -220,19 +220,18 @@ private String parse(BufferedReader bufferedReader) { } else if (sectionKey.equals(SOURCE_TAG)) { // ignore - can get all this from the first feature } else if (sectionKey.equals(REFERENCE_TAG)) { - if (!section.isEmpty()) { - GenbankReference genbankReference = new GenbankReference(); - for (String[] ref : section) { - if (ref[0].equals(AUTHORS_TAG)) { - genbankReference.setAuthors(ref[1]); - } else if (ref[0].equals(TITLE_TAG)) { - genbankReference.setTitle(ref[1]); - } else if (ref[0].equals(JOURNAL_TAG)) { - genbankReference.setJournal(ref[1]); - } + GenbankReference genbankReference = new GenbankReference(); + for (String[] ref : section) { + if (ref[0].equals(AUTHORS_TAG)) { + genbankReference.setAuthors(ref[1]); + } else if (ref[0].equals(TITLE_TAG)) { + genbankReference.setTitle(ref[1]); + } else if (ref[0].equals(JOURNAL_TAG)) { + genbankReference.setJournal(ref[1]); } - headerParser.addReference(genbankReference); } + headerParser.addReference(genbankReference); + } else if (sectionKey.equals(COMMENT_TAG)) { // Set up some comments headerParser.setComment(section.get(0)[1]); From e763320e72f3ba50469a1cbeee7424747cc0cafa Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 22:01:55 +0100 Subject: [PATCH 082/769] equals method must check the class of the object. --- .../nbio/core/sequence/location/template/AbstractLocation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java index 1b0c06bee1..efe1cc6d6f 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/template/AbstractLocation.java @@ -260,6 +260,7 @@ private List getAllSubLocations(Location location) { @Override public boolean equals(Object obj) { + if (obj.getClass() != this.getClass()) return false; boolean equals = false; if (classEqual(this, obj)) { AbstractLocation l = (AbstractLocation) obj; From 97332ca9f2383101ea13d135a413d7900fc8d950 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 22:05:52 +0100 Subject: [PATCH 083/769] This is a bug --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 56ece5e08d..6021f68c17 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -145,7 +145,7 @@ private String parse(BufferedReader bufferedReader) { sectionKey = section.get(0)[0]; if (sectionKey == null) { //if we reach the end of the file, section contains empty strings - if(section.get(0)[1]==null || section.get(0)[1]=="" || + if(section.get(0)[1]==null || section.get(0)[1].equals("") || section.get(0)[1].length()==0) { throw new ParserException(Messages.ENDOFFILE); } From 869af59b2a94d119c214ae0a450bba92435e433a Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 22:06:40 +0100 Subject: [PATCH 084/769] deleted redundant stuff --- .../nbio/core/sequence/io/GenbankSequenceParser.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 6021f68c17..cabb8f4e1b 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -137,7 +137,7 @@ public class GenbankSequenceParser, C extends Comp private String parse(BufferedReader bufferedReader) { - String sectionKey = null; + String sectionKey; List section; // Get an ordered list of key->value pairs in array-tuples do { @@ -330,8 +330,8 @@ private String parse(BufferedReader bufferedReader) { // reads an indented section, combining split lines and creating a list of // key->value tuples private List readSection(BufferedReader bufferedReader) { - List section = new ArrayList(); - String line = ""; + List section = new ArrayList<>(); + String line; String currKey = null; StringBuffer currVal = new StringBuffer(); From 5cedab4bd60383eea7b75ecac466342d17ed1b93 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 22:12:55 +0100 Subject: [PATCH 085/769] Refactored this, no need explicit cast if DBReferenceInfo is needed --- .../nbio/core/sequence/io/GenbankSequenceParser.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index cabb8f4e1b..338a90a95e 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -257,11 +257,11 @@ private String parse(BufferedReader bufferedReader) { if (m.matches()) { String dbname = m.group(1); String raccession = m.group(2); - Qualifier xref = new DBReferenceInfo(dbname, raccession); + DBReferenceInfo xref = new DBReferenceInfo(dbname, raccession); gbFeature.addQualifier(key, xref); - ArrayList listDBEntry = new ArrayList(); - listDBEntry.add((DBReferenceInfo) xref); + ArrayList listDBEntry = new ArrayList<>(); + listDBEntry.add(xref); mapDB.put(key, listDBEntry); } else { throw new ParserException("Bad dbxref"); From d02ed45466670665c8d5a2adf01accc7534da63d Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 22:14:55 +0100 Subject: [PATCH 086/769] used more appropriate property comment --- .../core/sequence/io/GenbankSequenceParser.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 338a90a95e..08cfe216ad 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -118,12 +118,14 @@ public class GenbankSequenceParser, C extends Comp protected static final Pattern dbxp = Pattern.compile("^([^:]+):(\\S+)$"); protected static final InsdcParser locationParser = new InsdcParser(DataSource.GENBANK); - //sections start at a line and continue till the first line afterwards with a - //non-whitespace first character - //we want to match any of the following as a new section within a section - // \s{0,8} word \s{0,7} value - // \s{21} /word = value - // \s{21} /word + /** + * sections start at a line and continue till the first line afterwards with a + * non-whitespace first character + * we want to match any of the following as a new section within a section + * \s{0,8} word \s{0,7} value + * \s{21} /word = value + * \s{21} /word + */ protected static final Pattern sectp = Pattern.compile("^(\\s{0,8}(\\S+)\\s{0,7}(.*)|\\s{21}(/\\S+?)=(.*)|\\s{21}(/\\S+))$"); protected static final Pattern readableFiles = Pattern.compile(".*(g[bp]k*$|\\u002eg[bp].*)"); @@ -132,9 +134,6 @@ public class GenbankSequenceParser, C extends Comp private static final String PRIMARY = "PRIMARY"; private static final String DBLINK = "DBLINK"; -// private NCBITaxon tax = null; - - private String parse(BufferedReader bufferedReader) { String sectionKey; From 0809c3f8e82c8b49310f97b045aa38b3bc4839b2 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 23:42:32 +0100 Subject: [PATCH 087/769] reduced complexity of this monster --- .../sequence/io/GenbankSequenceParser.java | 333 +++++++++--------- 1 file changed, 175 insertions(+), 158 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 08cfe216ad..3263a47af3 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -106,6 +106,9 @@ public class GenbankSequenceParser, C extends Comp protected static final String BASE_COUNT_TAG = "BASE"; // "CONTIG" protected static final String START_SEQUENCE_TAG = "ORIGIN"; + protected static final String DBSOURCE = "DBSOURCE"; + protected static final String PRIMARY = "PRIMARY"; + protected static final String DBLINK = "DBLINK"; protected static final String END_SEQUENCE_TAG = "//"; // locus line protected static final Pattern lp = Pattern.compile("^(\\S+)\\s+(\\d+)\\s+(bp|BP|aa|AA)\\s{0,4}(([dmsDMS][sS]-)?(\\S+))?\\s*(circular|CIRCULAR|linear|LINEAR)?\\s*(\\S+)?\\s*(\\S+)?$"); @@ -130,9 +133,6 @@ public class GenbankSequenceParser, C extends Comp protected static final Pattern readableFiles = Pattern.compile(".*(g[bp]k*$|\\u002eg[bp].*)"); protected static final Pattern headerLine = Pattern.compile("^LOCUS.*"); - private static final String DBSOURCE = "DBSOURCE"; - private static final String PRIMARY = "PRIMARY"; - private static final String DBLINK = "DBLINK"; private String parse(BufferedReader bufferedReader) { @@ -151,175 +151,192 @@ private String parse(BufferedReader bufferedReader) { throw new ParserException(Messages.SECTIONKEYNULL); } // process section-by-section - if (sectionKey.equals(LOCUS_TAG)) { - String loc = section.get(0)[1]; - header = loc; - Matcher m = lp.matcher(loc); - if (m.matches()) { - headerParser.setName(m.group(1)); - headerParser.setAccession(m.group(1)); // default if no accession found - sequenceLength = Long.valueOf(m.group(2)); - String lengthUnits = m.group(3); - String type = m.group(6); - - if (lengthUnits.equalsIgnoreCase("aa")) { - compoundType = AminoAcidCompoundSet.getAminoAcidCompoundSet(); - } else if (lengthUnits.equalsIgnoreCase("bp")) { - if (type != null) { - if (type.contains("RNA")) { - compoundType = RNACompoundSet.getRNACompoundSet(); - } else { - compoundType = DNACompoundSet.getDNACompoundSet(); - } - } else { - compoundType = DNACompoundSet.getDNACompoundSet(); - } + switch (sectionKey) { + case LOCUS_TAG: parseLocusTag(section); break; + case DEFINITION_TAG: parseDefinitionTag(section); break; + case ACCESSION_TAG: parseAccessionTag(section); break; + case VERSION_TAG: parseVersionTag(section); break; + case KEYWORDS_TAG: break; // not implemented yet + case SOURCE_TAG: break; // ignore - can get all this from the first feature + case REFERENCE_TAG: parseReferenceTag(section); break; + case COMMENT_TAG: parseCommentTag(section); break; + case FEATURE_TAG: parseFeatureTag(section); break; + case BASE_COUNT_TAG: break; // ignore - can calculate from sequence content later if needed + case START_SEQUENCE_TAG: parseStartSequenceTag(section); break; + case DBSOURCE: break; // not implemented yet + case PRIMARY: break; // not implemented yet + case DBLINK: break; // not implemented yet + default: + if(!sectionKey.equals(END_SEQUENCE_TAG)) { + log.info("found unknown section key: "+sectionKey); } + } + } while (!sectionKey.equals(END_SEQUENCE_TAG)); + return seqData; + } - if (m.group(7) != null) isCircularSequence = m.group(7).equalsIgnoreCase("circular"); - - // configure location parser with needed information - locationParser.setSequenceLength(sequenceLength); - locationParser.setSequenceCircular(isCircularSequence); - - log.debug("compound type: {}", compoundType.getClass().getSimpleName()); + private void parseStartSequenceTag(List section) { + // our first line is ignorable as it is the ORIGIN tag + // the second line onwards conveniently have the number as + // the [0] tuple, and sequence string as [1] so all we have + // to do is concat the [1] parts and then strip out spaces, + // and replace '.' and '~' with '-' for our parser. + StringBuffer seq = new StringBuffer(); + for (int i = 1; i < section.size(); i++) { + seq.append(section.get(i)[1]); + } + seqData = seq.toString().replaceAll("\\s+", "").replaceAll("[\\.|~]", "-").toUpperCase(); + } - } else { - throw new ParserException("Bad locus line"); + private void parseFeatureTag(List section) { + // starting from second line of input, start a new feature whenever we come across + // a key that does not start with / + AbstractFeature gbFeature = null; + for (int i = 1; i < section.size(); i++) { + String key = section.get(i)[0]; + String val = section.get(i)[1]; + if (key.startsWith("/")) { + if (gbFeature == null) { + throw new ParserException("Malformed GenBank file: found a qualifier without feature."); } - } else if (sectionKey.equals(DEFINITION_TAG)) { - headerParser.setDescription(section.get(0)[1]); - } else if (sectionKey.equals(ACCESSION_TAG)) { - // if multiple accessions, store only first as accession, - // and store rest in annotation - String[] accs = section.get(0)[1].split("\\s+"); - accession = accs[0].trim(); - headerParser.setAccession(accession); - } else if (sectionKey.equals(VERSION_TAG)) { - String ver = section.get(0)[1]; - Matcher m = vp.matcher(ver); - if (m.matches()) { - String verAcc = m.group(1); - if (!accession.equals(verAcc)) { - // the version refers to a different accession! - // believe the version line, and store the original - // accession away in the additional accession set - accession = verAcc; - } - if (m.group(3) != null) { - headerParser.setVersion(Integer.parseInt(m.group(3))); - } - if (m.group(5) != null) { - headerParser.setIdentifier(m.group(5)); - } - } else { - throw new ParserException("Bad version line"); + key = key.substring(1); // strip leading slash + val = val.replaceAll("\\s*[\\n\\r]+\\s*", " ").trim(); + if (val.endsWith("\"")) { + val = val.substring(1, val.length() - 1); // strip quotes } - } else if (sectionKey.equals(KEYWORDS_TAG)) { - } else if (sectionKey.equals(SOURCE_TAG)) { - // ignore - can get all this from the first feature - } else if (sectionKey.equals(REFERENCE_TAG)) { - GenbankReference genbankReference = new GenbankReference(); - for (String[] ref : section) { - if (ref[0].equals(AUTHORS_TAG)) { - genbankReference.setAuthors(ref[1]); - } else if (ref[0].equals(TITLE_TAG)) { - genbankReference.setTitle(ref[1]); - } else if (ref[0].equals(JOURNAL_TAG)) { - genbankReference.setJournal(ref[1]); + // parameter on old feature + if (key.equals("db_xref")) { + Matcher m = dbxp.matcher(val); + if (m.matches()) { + String dbname = m.group(1); + String raccession = m.group(2); + DBReferenceInfo xref = new DBReferenceInfo(dbname, raccession); + gbFeature.addQualifier(key, xref); + + ArrayList listDBEntry = new ArrayList<>(); + listDBEntry.add(xref); + mapDB.put(key, listDBEntry); + } else { + throw new ParserException("Bad dbxref"); } - } - headerParser.addReference(genbankReference); - - } else if (sectionKey.equals(COMMENT_TAG)) { - // Set up some comments - headerParser.setComment(section.get(0)[1]); - } else if (sectionKey.equals(FEATURE_TAG)) { - // starting from second line of input, start a new feature whenever we come across - // a key that does not start with / - AbstractFeature gbFeature = null; - for (int i = 1; i < section.size(); i++) { - String key = section.get(i)[0]; - String val = section.get(i)[1]; - if (key.startsWith("/")) { - if (gbFeature == null) { - throw new ParserException("Malformed GenBank file: found a qualifier without feature."); - } - key = key.substring(1); // strip leading slash - val = val.replaceAll("\\s*[\\n\\r]+\\s*", " ").trim(); - if (val.endsWith("\"")) { - val = val.substring(1, val.length() - 1); // strip quotes - } - // parameter on old feature - if (key.equals("db_xref")) { - Matcher m = dbxp.matcher(val); - if (m.matches()) { - String dbname = m.group(1); - String raccession = m.group(2); - DBReferenceInfo xref = new DBReferenceInfo(dbname, raccession); - gbFeature.addQualifier(key, xref); - - ArrayList listDBEntry = new ArrayList<>(); - listDBEntry.add(xref); - mapDB.put(key, listDBEntry); - } else { - throw new ParserException("Bad dbxref"); - } - } else if (key.equalsIgnoreCase("organism")) { - Qualifier q = new Qualifier(key, val.replace('\n', ' ')); - gbFeature.addQualifier(key, q); - } else { - if (key.equalsIgnoreCase("translation")) { - // strip spaces from sequence - val = val.replaceAll("\\s+", ""); - Qualifier q = new Qualifier(key, val); - gbFeature.addQualifier(key, q); - } else { - Qualifier q = new Qualifier(key, val); - gbFeature.addQualifier(key, q); - } - } + } else if (key.equalsIgnoreCase("organism")) { + Qualifier q = new Qualifier(key, val.replace('\n', ' ')); + gbFeature.addQualifier(key, q); + } else { + if (key.equalsIgnoreCase("translation")) { + // strip spaces from sequence + val = val.replaceAll("\\s+", ""); + Qualifier q = new Qualifier(key, val); + gbFeature.addQualifier(key, q); } else { - // new feature! - gbFeature = new TextFeature(key, val, key, key); - Location l = - locationParser.parse(val); - gbFeature.setLocation((AbstractLocation)l); - - if (!featureCollection.containsKey(key)) { - featureCollection.put(key, new ArrayList<>()); - } - featureCollection.get(key).add(gbFeature); + Qualifier q = new Qualifier(key, val); + gbFeature.addQualifier(key, q); } } - } else if (sectionKey.equals(BASE_COUNT_TAG)) { - // ignore - can calculate from sequence content later if needed - } else if (sectionKey.equals(START_SEQUENCE_TAG)) { - // our first line is ignorable as it is the ORIGIN tag - // the second line onwards conveniently have the number as - // the [0] tuple, and sequence string as [1] so all we have - // to do is concat the [1] parts and then strip out spaces, - // and replace '.' and '~' with '-' for our parser. - StringBuffer seq = new StringBuffer(); - for (int i = 1; i < section.size(); i++) { - seq.append(section.get(i)[1]); - } - seqData = seq.toString().replaceAll("\\s+", "").replaceAll("[\\.|~]", "-").toUpperCase(); - } else if(sectionKey.equals(DBSOURCE)) { - //TODO - } else if(sectionKey.equals(PRIMARY)) { - //TODO - } else if(sectionKey.equals(DBLINK)) { - //TODO } else { - if(!sectionKey.equals(END_SEQUENCE_TAG)) { - log.info("found unknown section key: "+sectionKey); + // new feature! + gbFeature = new TextFeature(key, val, key, key); + Location l = + locationParser.parse(val); + gbFeature.setLocation((AbstractLocation)l); + + if (!featureCollection.containsKey(key)) { + featureCollection.put(key, new ArrayList<>()); } + featureCollection.get(key).add(gbFeature); } - } while (!sectionKey.equals(END_SEQUENCE_TAG)); - return seqData; + } } + private void parseCommentTag(List section) { + headerParser.setComment(section.get(0)[1]); + } + + private void parseReferenceTag(List section) { + GenbankReference genbankReference = new GenbankReference(); + for (String[] ref : section) { + if (ref[0].equals(AUTHORS_TAG)) { + genbankReference.setAuthors(ref[1]); + } else if (ref[0].equals(TITLE_TAG)) { + genbankReference.setTitle(ref[1]); + } else if (ref[0].equals(JOURNAL_TAG)) { + genbankReference.setJournal(ref[1]); + } + } + headerParser.addReference(genbankReference); + } + + private void parseVersionTag(List section) { + String ver = section.get(0)[1]; + Matcher m = vp.matcher(ver); + if (m.matches()) { + String verAcc = m.group(1); + if (!accession.equals(verAcc)) { + // the version refers to a different accession! + // believe the version line, and store the original + // accession away in the additional accession set + accession = verAcc; + } + if (m.group(3) != null) { + headerParser.setVersion(Integer.parseInt(m.group(3))); + } + if (m.group(5) != null) { + headerParser.setIdentifier(m.group(5)); + } + } else { + throw new ParserException("Bad version line"); + } + } + + private void parseAccessionTag(List section) { + // if multiple accessions, store only first as accession, + // and store rest in annotation + String[] accs = section.get(0)[1].split("\\s+"); + accession = accs[0].trim(); + headerParser.setAccession(accession); + } + + private void parseDefinitionTag(List section) { + headerParser.setDescription(section.get(0)[1]); + } + + private void parseLocusTag(List section) { + String loc = section.get(0)[1]; + header = loc; + Matcher m = lp.matcher(loc); + if (m.matches()) { + headerParser.setName(m.group(1)); + headerParser.setAccession(m.group(1)); // default if no accession found + sequenceLength = Long.valueOf(m.group(2)); + String lengthUnits = m.group(3); + String type = m.group(6); + + if (lengthUnits.equalsIgnoreCase("aa")) { + compoundType = AminoAcidCompoundSet.getAminoAcidCompoundSet(); + } else if (lengthUnits.equalsIgnoreCase("bp")) { + if (type != null) { + if (type.contains("RNA")) { + compoundType = RNACompoundSet.getRNACompoundSet(); + } else { + compoundType = DNACompoundSet.getDNACompoundSet(); + } + } else { + compoundType = DNACompoundSet.getDNACompoundSet(); + } + } + + if (m.group(7) != null) isCircularSequence = m.group(7).equalsIgnoreCase("circular"); + + // configure location parser with needed information + locationParser.setSequenceLength(sequenceLength); + locationParser.setSequenceCircular(isCircularSequence); + + log.debug("compound type: {}", compoundType.getClass().getSimpleName()); + + } else { + throw new ParserException("Bad locus line"); + } + } // reads an indented section, combining split lines and creating a list of From 56138e5c4c9e4e18672016c7c35f5f98f1ace5f5 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 23:44:23 +0100 Subject: [PATCH 088/769] deleted un needed --- .../nbio/core/sequence/io/GenbankSequenceParser.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 3263a47af3..93ee112d69 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -415,9 +415,9 @@ private List readSection(BufferedReader bufferedReader) { @Override public String getSequence(BufferedReader bufferedReader, int sequenceLength) { - featureCollection = new HashMap>(); - mapDB = new LinkedHashMap>(); - headerParser = new GenericGenbankHeaderParser(); + featureCollection = new HashMap<>(); + mapDB = new LinkedHashMap<>(); + headerParser = new GenericGenbankHeaderParser<>(); try { parse(bufferedReader); } catch (ParserException e) { @@ -441,7 +441,7 @@ public LinkedHashMap> getDatabaseReferences() } public ArrayList getKeyWords() { - return new ArrayList(featureCollection.keySet()); + return new ArrayList<>(featureCollection.keySet()); } public ArrayList getFeatures(String keyword) { From 9bb6610efcc63f02ea4aef77d006dd047170fc3d Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 23:48:55 +0100 Subject: [PATCH 089/769] better log management --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 93ee112d69..ddd5c3312e 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -168,7 +168,7 @@ private String parse(BufferedReader bufferedReader) { case DBLINK: break; // not implemented yet default: if(!sectionKey.equals(END_SEQUENCE_TAG)) { - log.info("found unknown section key: "+sectionKey); + log.info("found unknown section key: %", sectionKey); } } } while (!sectionKey.equals(END_SEQUENCE_TAG)); From 545c18d7252150c3cd27544ab344c42a187711b6 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 27 Apr 2020 23:52:37 +0100 Subject: [PATCH 090/769] replaced obsolete StringBuffer with StringBuilder. It is much faster. --- .../nbio/core/sequence/io/GenbankSequenceParser.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index ddd5c3312e..24579164b5 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -181,7 +181,7 @@ private void parseStartSequenceTag(List section) { // the [0] tuple, and sequence string as [1] so all we have // to do is concat the [1] parts and then strip out spaces, // and replace '.' and '~' with '-' for our parser. - StringBuffer seq = new StringBuffer(); + StringBuilder seq = new StringBuilder(); for (int i = 1; i < section.size(); i++) { seq.append(section.get(i)[1]); } @@ -350,7 +350,7 @@ private List readSection(BufferedReader bufferedReader) { String line; String currKey = null; - StringBuffer currVal = new StringBuffer(); + StringBuilder currVal = new StringBuilder(); boolean done = false; int linecount = 0; @@ -385,7 +385,7 @@ private List readSection(BufferedReader bufferedReader) { // not null currKey = m.group(2) == null ? (m.group(4) == null ? m .group(6) : m.group(4)) : m.group(2); - currVal = new StringBuffer(); + currVal = new StringBuilder(); // val = group(3) if group(2) not null, group(5) if // group(4) not null, "" otherwise, trimmed currVal.append((m.group(2) == null ? (m.group(4) == null ? "" From a22ed4153873b66be7b44bedaf634bc29f7ec11b Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Tue, 28 Apr 2020 00:17:22 +0100 Subject: [PATCH 091/769] formatting --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 24579164b5..e1da7416a3 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -386,7 +386,7 @@ private List readSection(BufferedReader bufferedReader) { currKey = m.group(2) == null ? (m.group(4) == null ? m .group(6) : m.group(4)) : m.group(2); currVal = new StringBuilder(); - // val = group(3) if group(2) not null, group(5) if + // val = group(3) if group(2) not null, group(5) if // group(4) not null, "" otherwise, trimmed currVal.append((m.group(2) == null ? (m.group(4) == null ? "" : m.group(5)) From 7070bc6f4cc95d69563e5ade6a5b2859afd3a2b8 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Tue, 28 Apr 2020 00:38:16 +0100 Subject: [PATCH 092/769] combined exceptions --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index e1da7416a3..1d61a51708 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -405,9 +405,7 @@ private List readSection(BufferedReader bufferedReader) { } } } - } catch (IOException e) { - throw new ParserException(e.getMessage()); - } catch (RuntimeException e) { + } catch (IOException | RuntimeException e) { throw new ParserException(e.getMessage()); } return section; From dd585c96724d778c39c664494ed7afbb364afb24 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Tue, 28 Apr 2020 00:46:21 +0100 Subject: [PATCH 093/769] using interfaces instead of implementations --- .../core/sequence/io/GenbankSequenceParser.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 1d61a51708..82f7df4af3 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -51,10 +51,7 @@ import java.io.BufferedReader; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -434,18 +431,18 @@ public GenericGenbankHeaderParser getSequenceHeaderParser() { return headerParser; } - public LinkedHashMap> getDatabaseReferences() { + public Map> getDatabaseReferences() { return mapDB; } - public ArrayList getKeyWords() { + public List getKeyWords() { return new ArrayList<>(featureCollection.keySet()); } - public ArrayList getFeatures(String keyword) { + public List getFeatures(String keyword) { return featureCollection.get(keyword); } - public HashMap> getFeatures() { + public Map> getFeatures() { return featureCollection; } From b0ac102b880ebe32a184221e7b40d238aff76165 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Tue, 28 Apr 2020 00:48:42 +0100 Subject: [PATCH 094/769] again, substituted implementation with interface --- .../biojava/nbio/core/sequence/io/GenbankSequenceParser.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index 82f7df4af3..d2ccdbcf09 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -62,8 +62,7 @@ public class GenbankSequenceParser, C extends Comp private String header; private String accession; private boolean isCircularSequence; - private long sequenceLength; - public LinkedHashMap> mapDB; + public Map> mapDB; /** * this data structure collects list of features extracted from the * FEATURE_TAG section They are organized by list of the same type (i.e. @@ -304,7 +303,7 @@ private void parseLocusTag(List section) { if (m.matches()) { headerParser.setName(m.group(1)); headerParser.setAccession(m.group(1)); // default if no accession found - sequenceLength = Long.valueOf(m.group(2)); + long sequenceLength = Long.valueOf(m.group(2)); String lengthUnits = m.group(3); String type = m.group(6); From fc6352758ab5cfa3225c576d2806434eb376118b Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Tue, 28 Apr 2020 01:07:08 +0100 Subject: [PATCH 095/769] deep substitution of implementations with interfaces --- .../features/DatabaseReferenceInterface.java | 4 +++- .../core/sequence/features/FeatureRetriever.java | 7 ++++--- .../sequence/features/FeaturesKeyWordInterface.java | 4 ++-- .../nbio/core/sequence/io/GenbankReader.java | 2 +- .../core/sequence/io/GenbankSequenceParser.java | 8 ++++---- .../sequence/loader/GenbankProxySequenceReader.java | 12 +++++------- .../sequence/loader/UniprotProxySequenceReader.java | 13 +++++-------- .../core/sequence/template/AbstractSequence.java | 2 +- .../loader/GenbankProxySequenceReaderTest.java | 3 ++- 9 files changed, 27 insertions(+), 28 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/DatabaseReferenceInterface.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/DatabaseReferenceInterface.java index 0cb3ea5d8c..20c00034dd 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/DatabaseReferenceInterface.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/DatabaseReferenceInterface.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; /** * If a SequenceProxyReader implements this interface then that external source @@ -32,5 +34,5 @@ */ public interface DatabaseReferenceInterface { - public LinkedHashMap> getDatabaseReferences(); + public Map> getDatabaseReferences(); } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeatureRetriever.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeatureRetriever.java index bd2d48afee..3e2269f410 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeatureRetriever.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeatureRetriever.java @@ -22,13 +22,14 @@ package org.biojava.nbio.core.sequence.features; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * If a SequenceProxyReader implements this interface then that external source * has a list features * @author @author Paolo Pavan */ public interface FeatureRetriever { - HashMap> getFeatures(); + Map> getFeatures(); } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeaturesKeyWordInterface.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeaturesKeyWordInterface.java index 9674d1abee..1b1acd994e 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeaturesKeyWordInterface.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeaturesKeyWordInterface.java @@ -22,7 +22,7 @@ package org.biojava.nbio.core.sequence.features; -import java.util.ArrayList; +import java.util.List; /** * Models the keywords that are annotated for a protein sequence at Uniprot. If a ProxySequenceReader @@ -36,5 +36,5 @@ public interface FeaturesKeyWordInterface { * * @return */ - public ArrayList getKeyWords() ; + public List getKeyWords() ; } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankReader.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankReader.java index 97cad4cf49..129c47a733 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankReader.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankReader.java @@ -170,7 +170,7 @@ public LinkedHashMap process(final int max) throws IOException, Compou .forEach(sequence::addFeature); // add taxonomy ID to new sequence - ArrayList dbQualifier = genbankParser.getDatabaseReferences().get("db_xref"); + List dbQualifier = genbankParser.getDatabaseReferences().get("db_xref"); if (dbQualifier != null){ DBReferenceInfo q = dbQualifier.get(0); sequence.setTaxonomy(new TaxonomyID(q.getDatabase()+":"+q.getId(), DataSource.GENBANK)); diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index d2ccdbcf09..df2c31a985 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -62,13 +62,13 @@ public class GenbankSequenceParser, C extends Comp private String header; private String accession; private boolean isCircularSequence; - public Map> mapDB; + private Map> mapDB; /** * this data structure collects list of features extracted from the * FEATURE_TAG section They are organized by list of the same type (i.e. * same genbank Feature) and are provided with location */ - private HashMap> featureCollection; + private HashMap> featureCollection; private final Logger log = LoggerFactory.getLogger(getClass()); @@ -430,7 +430,7 @@ public GenericGenbankHeaderParser getSequenceHeaderParser() { return headerParser; } - public Map> getDatabaseReferences() { + public Map> getDatabaseReferences() { return mapDB; } @@ -441,7 +441,7 @@ public List getKeyWords() { public List getFeatures(String keyword) { return featureCollection.get(keyword); } - public Map> getFeatures() { + public Map> getFeatures() { return featureCollection; } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReader.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReader.java index 2b74f9cacd..99f8d1b779 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReader.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReader.java @@ -55,9 +55,7 @@ import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; +import java.util.*; /** * @author Karl Nicholas @@ -72,7 +70,7 @@ public class GenbankProxySequenceReader extends StringProxyS private GenbankSequenceParser, C> genbankParser; private GenericGenbankHeaderParser, C> headerParser; private String header; - private HashMap> features; + private Map> features; /** @@ -182,17 +180,17 @@ public GenericGenbankHeaderParser, C> getHeaderParser() { return headerParser; } @Override - public HashMap> getFeatures() { + public Map> getFeatures() { return features; } @Override - public LinkedHashMap> getDatabaseReferences() { + public Map> getDatabaseReferences() { return genbankParser.getDatabaseReferences(); } @Override - public ArrayList getKeyWords() { + public List getKeyWords() { return genbankParser.getKeyWords(); } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/UniprotProxySequenceReader.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/UniprotProxySequenceReader.java index f7f51d89bb..80c57649e0 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/UniprotProxySequenceReader.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/UniprotProxySequenceReader.java @@ -50,10 +50,7 @@ import java.net.HttpURLConnection; import java.net.URL; import java.rmi.RemoteException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; +import java.util.*; import java.util.regex.Pattern; /** @@ -816,8 +813,8 @@ public ArrayList getKeyWords() { * @return */ @Override - public LinkedHashMap> getDatabaseReferences() { - LinkedHashMap> databaseReferencesHashMap = new LinkedHashMap>(); + public Map> getDatabaseReferences() { + Map> databaseReferencesHashMap = new LinkedHashMap<>(); if (uniprotDoc == null) { return databaseReferencesHashMap; } @@ -829,7 +826,7 @@ public LinkedHashMap> getDatabaseReferences() for (Element element : dbreferenceElementList) { String type = element.getAttribute("type"); String id = element.getAttribute("id"); - ArrayList idlist = databaseReferencesHashMap.get(type); + List idlist = databaseReferencesHashMap.get(type); if (idlist == null) { idlist = new ArrayList(); databaseReferencesHashMap.put(type, idlist); @@ -846,7 +843,7 @@ public LinkedHashMap> getDatabaseReferences() } } catch (XPathExpressionException e) { logger.error("Problems while parsing db references in UniProt XML: {}. No db references will be available.",e.getMessage()); - return new LinkedHashMap>(); + return new LinkedHashMap<>(); } return databaseReferencesHashMap; diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractSequence.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractSequence.java index 7e0228a976..3a7da01d9e 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractSequence.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractSequence.java @@ -126,7 +126,7 @@ public void setProxySequenceReader(SequenceReader proxyLoader) { if (proxyLoader instanceof FeatureRetriever) { this.setFeatureRetriever((FeatureRetriever) sequenceStorage); - HashMap> ff = getFeatureRetriever().getFeatures(); + Map> ff = getFeatureRetriever().getFeatures(); for (String k: ff.keySet()){ for (AbstractFeature f: ff.get(k)){ this.addFeature(f); diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java index 647d86df4d..9ed0b4029b 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.List; /** * Testing example for issue #834 @@ -187,7 +188,7 @@ public void testProteinSequenceFactoring() throws Exception { ProteinSequence seq = new ProteinSequence(genbankReader); // if target protein contain CDS/coded_by than it should contain parent nucleotide seq - ArrayList CDSs = genbankReader.getFeatures().get("CDS"); + List CDSs = genbankReader.getFeatures().get("CDS"); if (CDSs != null) { if (CDSs.size() == 1) { From df609610758fa29112b2cc7e9b15d25ca34560a6 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Thu, 30 Apr 2020 09:42:29 +0100 Subject: [PATCH 096/769] deleted commented out old code --- .../nbio/core/sequence/location/InsdcParser.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java index 011eb71001..7071a4ce1b 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcParser.java @@ -23,14 +23,11 @@ import org.biojava.nbio.core.exceptions.ParserException; import org.biojava.nbio.core.sequence.AccessionID; -import org.biojava.nbio.core.sequence.DNASequence; import org.biojava.nbio.core.sequence.DataSource; import org.biojava.nbio.core.sequence.Strand; import org.biojava.nbio.core.sequence.location.template.AbstractLocation; import org.biojava.nbio.core.sequence.location.template.Location; import org.biojava.nbio.core.sequence.location.template.Point; -import org.biojava.nbio.core.sequence.template.AbstractSequence; -import org.biojava.nbio.core.sequence.template.Compound; import java.util.ArrayList; import java.util.List; @@ -45,7 +42,7 @@ * @author jgrzebyta * @author Paolo Pavan */ -public class InsdcParser , C extends Compound>{ +public class InsdcParser { private boolean isSequenceCircular; private long sequenceLength; @@ -56,10 +53,6 @@ public class InsdcParser , C extends Compound>{ * parse a location. if group(1) is null than the feature is on the positive * strand, group(2) start position, group(3) end position. */ - // why in the location the first character was ignored? - //protected static final Pattern singleLocationPattern = Pattern.compile("(?:[A-Z]([A-Za-z\\.0-9_]*?):)?(?)(\\d+)?(>?)?"); - - // fixed issue #254 protected static final Pattern singleLocationPattern = Pattern.compile("(?:([A-Za-z\\.0-9_]*?):)?(?)(\\d+)?(>?)?"); /** * Decodes a split pattern. Split patterns are a composition of multiple @@ -95,9 +88,6 @@ public class InsdcParser , C extends Compound>{ */ protected Integer featureGlobalStart, featureGlobalEnd; - //private S referenceSequence = new org.biojava.nbio.core.sequence.DNASequence(); - private AbstractSequence referenceSequence = new DNASequence(); - enum complexFeaturesAppendEnum { FLATTEN, HIERARCHICAL; @@ -165,7 +155,6 @@ private List parseLocationString(String string, int versus) throws Par Matcher m; List boundedLocationsCollection = new ArrayList(); - //String[] tokens = string.split(locationSplitPattern); List tokens = splitString(string); for (String t : tokens) { m = genbankSplitPattern.matcher(t); From 8040e3976f2f41a1e1671d8f347af12f3afa003e Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Thu, 30 Apr 2020 17:01:34 +0100 Subject: [PATCH 097/769] Fixed impact of refactoring on genome module --- .../genome/homology/GFF3FromUniprotBlastHits.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/biojava-genome/src/main/java/org/biojava/nbio/genome/homology/GFF3FromUniprotBlastHits.java b/biojava-genome/src/main/java/org/biojava/nbio/genome/homology/GFF3FromUniprotBlastHits.java index 0910b6b68d..b9696f7aaf 100644 --- a/biojava-genome/src/main/java/org/biojava/nbio/genome/homology/GFF3FromUniprotBlastHits.java +++ b/biojava-genome/src/main/java/org/biojava/nbio/genome/homology/GFF3FromUniprotBlastHits.java @@ -41,6 +41,8 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; /** * @@ -160,7 +162,7 @@ PairwiseSequenceAlignerType.LOCAL, new SimpleGapPenalty(), FeaturesKeyWordInterface featureKeyWords = proteinSequence.getFeaturesKeyWord(); String notes = ""; if (featureKeyWords != null) { - ArrayList keyWords = featureKeyWords.getKeyWords(); + List keyWords = featureKeyWords.getKeyWords(); if (keyWords.size() > 0) { notes = ";Note="; for (String note : keyWords) { @@ -180,11 +182,11 @@ PairwiseSequenceAlignerType.LOCAL, new SimpleGapPenalty(), DatabaseReferenceInterface databaseReferences = proteinSequence.getDatabaseReferences(); if (databaseReferences != null) { - LinkedHashMap> databaseReferenceHashMap = databaseReferences.getDatabaseReferences(); - ArrayList pfamList = databaseReferenceHashMap.get("Pfam"); - ArrayList cazyList = databaseReferenceHashMap.get("CAZy"); - ArrayList goList = databaseReferenceHashMap.get("GO"); - ArrayList eccList = databaseReferenceHashMap.get("BRENDA"); + Map> databaseReferenceHashMap = databaseReferences.getDatabaseReferences(); + List pfamList = databaseReferenceHashMap.get("Pfam"); + List cazyList = databaseReferenceHashMap.get("CAZy"); + List goList = databaseReferenceHashMap.get("GO"); + List eccList = databaseReferenceHashMap.get("BRENDA"); if (pfamList != null && pfamList.size() > 0) { if (notes.length() == 0) { notes = ";Note="; From b6fe385d7a23c8ccbdbfaec4afa2f9ba4cbd3a2c Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Fri, 1 May 2020 18:58:17 +0100 Subject: [PATCH 098/769] added type checking --- .../nbio/core/sequence/io/GenbankSequenceParser.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index df2c31a985..d5c5415107 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -37,7 +37,10 @@ import org.biojava.nbio.core.sequence.compound.AminoAcidCompoundSet; import org.biojava.nbio.core.sequence.compound.DNACompoundSet; import org.biojava.nbio.core.sequence.compound.RNACompoundSet; -import org.biojava.nbio.core.sequence.features.*; +import org.biojava.nbio.core.sequence.features.AbstractFeature; +import org.biojava.nbio.core.sequence.features.DBReferenceInfo; +import org.biojava.nbio.core.sequence.features.Qualifier; +import org.biojava.nbio.core.sequence.features.TextFeature; import org.biojava.nbio.core.sequence.io.template.SequenceParserInterface; import org.biojava.nbio.core.sequence.location.InsdcParser; import org.biojava.nbio.core.sequence.location.template.AbstractLocation; @@ -447,7 +450,7 @@ public Map> getFeatures() { public void parseFeatures(AbstractSequence sequence) { for (String k: featureCollection.keySet()) - for (AbstractFeature f: featureCollection.get(k)) + for (AbstractFeature, C> f: featureCollection.get(k)) sequence.addFeature(f); } From caaba8683de392b3268314abe037fa73a94ef6e6 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Fri, 1 May 2020 18:58:59 +0100 Subject: [PATCH 099/769] this cast is legal --- .../nbio/core/sequence/loader/UniprotProxySequenceReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/UniprotProxySequenceReader.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/UniprotProxySequenceReader.java index 80c57649e0..ae8c8207aa 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/UniprotProxySequenceReader.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/UniprotProxySequenceReader.java @@ -238,7 +238,7 @@ public boolean equals(Object o){ if(! Equals.classEqual(this, o)) { return false; } - + @SuppressWarnings("unchecked") Sequence other = (Sequence)o; if ( other.getCompoundSet() != getCompoundSet()) return false; From 5b213325d1a88eb68bae8bcfc6312cfd8f1b1924 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Fri, 1 May 2020 19:19:56 +0100 Subject: [PATCH 100/769] better typing fix --- .../sequence/loader/GenbankProxySequenceReaderTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java index 9ed0b4029b..33a2b3919e 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java @@ -42,10 +42,10 @@ import java.io.InputStream; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Map; /** * Testing example for issue #834 @@ -192,8 +192,9 @@ public void testProteinSequenceFactoring() throws Exception { if (CDSs != null) { if (CDSs.size() == 1) { - ArrayList qualifiers = (ArrayList)CDSs.get(0).getQualifiers().get("coded_by"); - Qualifier codedBy = qualifiers.get(0); + final Map> qualifiers = CDSs.get(0).getQualifiers(); + List codedByQualifiers = qualifiers.get("coded_by"); + Qualifier codedBy = codedByQualifiers.get(0); if (codedBy != null) { AbstractSequence parentSeq = seq.getParentSequence(); From e7407f98728560f73f45508c9224b4f54e1117df Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Fri, 1 May 2020 19:56:09 +0100 Subject: [PATCH 101/769] better typing fix --- .../sequence/features/FeatureRetriever.java | 7 ++++-- .../sequence/io/GenbankSequenceParser.java | 6 ++--- .../loader/GenbankProxySequenceReader.java | 22 +++++-------------- .../sequence/template/AbstractSequence.java | 2 +- .../GenbankProxySequenceReaderTest.java | 2 +- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeatureRetriever.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeatureRetriever.java index 3e2269f410..039b707081 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeatureRetriever.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/features/FeatureRetriever.java @@ -22,6 +22,9 @@ package org.biojava.nbio.core.sequence.features; +import org.biojava.nbio.core.sequence.template.AbstractSequence; +import org.biojava.nbio.core.sequence.template.Compound; + import java.util.List; import java.util.Map; @@ -30,6 +33,6 @@ * has a list features * @author @author Paolo Pavan */ -public interface FeatureRetriever { - Map> getFeatures(); +public interface FeatureRetriever { + Map, C>>> getFeatures(); } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java index d5c5415107..70462a9c0b 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/io/GenbankSequenceParser.java @@ -71,7 +71,7 @@ public class GenbankSequenceParser, C extends Comp * FEATURE_TAG section They are organized by list of the same type (i.e. * same genbank Feature) and are provided with location */ - private HashMap> featureCollection; + private Map, C>>> featureCollection; private final Logger log = LoggerFactory.getLogger(getClass()); @@ -441,10 +441,10 @@ public List getKeyWords() { return new ArrayList<>(featureCollection.keySet()); } - public List getFeatures(String keyword) { + public List, C>> getFeatures(String keyword) { return featureCollection.get(keyword); } - public Map> getFeatures() { + public Map, C>>> getFeatures() { return featureCollection; } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReader.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReader.java index 99f8d1b779..3a22d91f19 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReader.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReader.java @@ -32,11 +32,7 @@ import org.biojava.nbio.core.sequence.compound.AminoAcidCompoundSet; import org.biojava.nbio.core.sequence.compound.DNACompoundSet; import org.biojava.nbio.core.sequence.compound.NucleotideCompound; -import org.biojava.nbio.core.sequence.features.AbstractFeature; -import org.biojava.nbio.core.sequence.features.DBReferenceInfo; -import org.biojava.nbio.core.sequence.features.DatabaseReferenceInterface; -import org.biojava.nbio.core.sequence.features.FeatureRetriever; -import org.biojava.nbio.core.sequence.features.FeaturesKeyWordInterface; +import org.biojava.nbio.core.sequence.features.*; import org.biojava.nbio.core.sequence.io.GenbankSequenceParser; import org.biojava.nbio.core.sequence.io.GenericGenbankHeaderParser; import org.biojava.nbio.core.sequence.template.AbstractSequence; @@ -45,17 +41,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; import java.net.URL; import java.net.URLConnection; -import java.util.*; +import java.util.List; +import java.util.Map; /** * @author Karl Nicholas @@ -70,7 +60,7 @@ public class GenbankProxySequenceReader extends StringProxyS private GenbankSequenceParser, C> genbankParser; private GenericGenbankHeaderParser, C> headerParser; private String header; - private Map> features; + private Map, C>>> features; /** @@ -180,7 +170,7 @@ public GenericGenbankHeaderParser, C> getHeaderParser() { return headerParser; } @Override - public Map> getFeatures() { + public Map, C>>> getFeatures() { return features; } diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractSequence.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractSequence.java index 3a7da01d9e..8f32033869 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractSequence.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractSequence.java @@ -126,7 +126,7 @@ public void setProxySequenceReader(SequenceReader proxyLoader) { if (proxyLoader instanceof FeatureRetriever) { this.setFeatureRetriever((FeatureRetriever) sequenceStorage); - Map> ff = getFeatureRetriever().getFeatures(); + Map, C>>> ff = getFeatureRetriever().getFeatures(); for (String k: ff.keySet()){ for (AbstractFeature f: ff.get(k)){ this.addFeature(f); diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java index 33a2b3919e..6883637a49 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/loader/GenbankProxySequenceReaderTest.java @@ -188,7 +188,7 @@ public void testProteinSequenceFactoring() throws Exception { ProteinSequence seq = new ProteinSequence(genbankReader); // if target protein contain CDS/coded_by than it should contain parent nucleotide seq - List CDSs = genbankReader.getFeatures().get("CDS"); + List, AminoAcidCompound>> CDSs = genbankReader.getFeatures().get("CDS"); if (CDSs != null) { if (CDSs.size() == 1) { From 052791be606a1676bc89d9e6ce83af5bcd7c4f2a Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Mon, 4 May 2020 18:10:07 +0100 Subject: [PATCH 102/769] wasn't aware of this and no other... --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 8514858e84..c448f72feb 100644 --- a/pom.xml +++ b/pom.xml @@ -131,6 +131,10 @@ Michael Heuer + + paolopavan + Paolo Pavan + Peter Rose From d0f526b99237710b42c5879dde127d34fb45de85 Mon Sep 17 00:00:00 2001 From: Paolo Pavan Date: Fri, 8 May 2020 18:28:41 +0100 Subject: [PATCH 103/769] Forgot to forward the parameter. --- .../org/biojava/nbio/core/sequence/location/InsdcLocations.java | 1 + 1 file changed, 1 insertion(+) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java index 5e998c7f99..3e61105950 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/location/InsdcLocations.java @@ -149,6 +149,7 @@ public GroupLocation(Location... subLocations) { public GroupLocation(boolean isCircular, Location... subLocations) { this(Arrays.asList(subLocations)); + setCircular(isCircular); } public GroupLocation(Point start, Point end, Strand strand, From 8db52cb6ccf123a08b1f4b2d8f9859b80e371a9c Mon Sep 17 00:00:00 2001 From: Spencer Bliven Date: Mon, 18 May 2020 10:25:19 +0200 Subject: [PATCH 104/769] Fix compilation bug in ZipChemCompProvider With some JDKs (openjdk-11) there is an (undocumented?) `java.nio.file.FileSystems.newFileSystem(Path,Map)` method. This patch disambiguates which override to use for null. --- .../biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java index ef7c984946..9475a6d036 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java @@ -236,7 +236,7 @@ private synchronized ChemComp getFromZip(String recordName) { final String filename = "chemcomp/" + recordName+".cif.gz"; // try with resources block to read from the filesystem. - try (FileSystem fs = FileSystems.newFileSystem(m_zipFile, null)) { + try (FileSystem fs = FileSystems.newFileSystem(m_zipFile, (ClassLoader) null)) { Path cif = fs.getPath(filename); if (Files.exists(cif)) { From afd98d40e8dde815679acc4121922813de04d783 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 6 Jun 2020 23:22:21 -0700 Subject: [PATCH 105/769] Now possible to compare interfaces coming from different copies of same structure --- .../structure/contact/StructureInterface.java | 26 ++++++------------- .../contact/StructureInterfaceList.java | 6 ++++- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java index 3d039ad32b..40953a1ee2 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java @@ -583,7 +583,8 @@ public void setCluster(StructureInterfaceCluster cluster) { /** * Calculates the contact overlap score between this StructureInterface and - * the given one. + * the given one. The calculation assumes that both interfaces come from the same structure. The ouput + * will not necessarily make sense if the two interfaces come from different structures. * The two sides of the given StructureInterface need to match this StructureInterface * in the sense that they must come from the same Entity, i.e. * their residue numbers need to align with 100% identity, except for unobserved @@ -597,17 +598,6 @@ public void setCluster(StructureInterfaceCluster cluster) { */ public double getContactOverlapScore(StructureInterface other, boolean invert) { - Structure thisStruct = getParentStructure(); - Structure otherStruct = other.getParentStructure(); - - if (thisStruct!=otherStruct) { - // in the current implementation, comparison between different structure doesn't make much sense - // and won't even work since the compounds of both will never match. We warn because it - // really is not what this is intended for at the moment - logger.warn("Comparing interfaces from different structures, contact overlap score will be 0"); - return 0; - } - Pair thisChains = getParentChains(); Pair otherChains = other.getParentChains(); @@ -622,10 +612,10 @@ public double getContactOverlapScore(StructureInterface other, boolean invert) { Pair thisCompounds = new Pair(thisChains.getFirst().getEntityInfo(), thisChains.getSecond().getEntityInfo()); Pair otherCompounds = new Pair(otherChains.getFirst().getEntityInfo(), otherChains.getSecond().getEntityInfo()); - if ( ( (thisCompounds.getFirst() == otherCompounds.getFirst()) && - (thisCompounds.getSecond() == otherCompounds.getSecond()) ) || - ( (thisCompounds.getFirst() == otherCompounds.getSecond()) && - (thisCompounds.getSecond() == otherCompounds.getFirst()) ) ) { + if ( ( (thisCompounds.getFirst().getMolId() == otherCompounds.getFirst().getMolId()) && + (thisCompounds.getSecond().getMolId() == otherCompounds.getSecond().getMolId()) ) || + ( (thisCompounds.getFirst().getMolId() == otherCompounds.getSecond().getMolId()) && + (thisCompounds.getSecond().getMolId() == otherCompounds.getFirst().getMolId()) ) ) { int common = 0; GroupContactSet thisContacts = getGroupContacts(); @@ -633,8 +623,8 @@ public double getContactOverlapScore(StructureInterface other, boolean invert) { for (GroupContact thisContact:thisContacts) { - ResidueIdentifier first = null; - ResidueIdentifier second = null; + ResidueIdentifier first; + ResidueIdentifier second; if (!invert) { first = new ResidueIdentifier(thisContact.getPair().getFirst()); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterfaceList.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterfaceList.java index 8bc0b627d0..09c90d6373 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterfaceList.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterfaceList.java @@ -74,7 +74,7 @@ public class StructureInterfaceList implements Serializable, Iterable list; + private final List list; private List clusters = null; private List clustersNcs = null; @@ -93,6 +93,10 @@ public int size() { return this.list.size(); } + public List getList() { + return list; + } + /** * Gets the interface corresponding to given id. * The ids go from 1 to n From a39bd7d8ab9e4cfacc0aa7f63ba45423f83c8872 Mon Sep 17 00:00:00 2001 From: balaji-s Date: Thu, 11 Jun 2020 21:39:09 +0530 Subject: [PATCH 106/769] refactored code to use java 8 streams --- .../org/biojava/nbio/aaproperties/CommandPrompt.java | 4 +--- .../biojava/nbio/aaproperties/PeptideProperties.java | 7 +++++-- .../template/AbstractNucleotideCompoundSet.java | 12 +++++------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java index db9d1d7b69..4ebcec641f 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java @@ -327,9 +327,7 @@ private static void compute(PrintStream output, String header, String sequence, } } output.print(header.replace(delimiter, "_")); - for(int i = 0; i < dList.size(); i++){ - output.print(delimiter + Utils.roundToDecimals(dList.get(i), decimalPlace)); - } + dList.forEach(item -> System.out.print(delimiter + Utils.roundToDecimals(dList.get(item), decimalPlace))); output.println(); output.flush(); } diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java index b0918bf559..9d62a05c71 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java @@ -31,10 +31,12 @@ import javax.xml.bind.JAXBException; import java.io.File; import java.io.FileNotFoundException; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; /** * This is an adaptor class which enable the ease of generating protein properties. @@ -64,8 +66,9 @@ public enum SingleLetterAACode { W, C, M, H, Y, F, Q, N, I, R, D, P, T, K, E, V, * To initialize the standardAASet */ static{ - standardAASet = new HashSet(); - for(SingleLetterAACode c:SingleLetterAACode.values()) standardAASet.add(c.toString().charAt(0)); + standardAASet = Arrays.stream(SingleLetterAACode.values()) + .map(singleLetterAACode -> singleLetterAACode.toString().charAt(0)) + . .collect(Collectors.toCollection(HashSet::new)); } /** diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractNucleotideCompoundSet.java b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractNucleotideCompoundSet.java index cb682ef347..af6a8768e3 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractNucleotideCompoundSet.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/sequence/template/AbstractNucleotideCompoundSet.java @@ -23,6 +23,7 @@ import org.biojava.nbio.core.sequence.compound.NucleotideCompound; import java.util.*; +import java.util.stream.Collectors; /** * @@ -66,13 +67,10 @@ protected void addNucleotideCompound(String base, String complement, String... e protected void calculateIndirectAmbiguities() { Map> equivalentsMap = new HashMap>(); - List ambiguousCompounds = new ArrayList(); - for(NucleotideCompound compound: getAllCompounds()) { - if (!compound.isAmbiguous()) { - continue; - } - ambiguousCompounds.add(compound); - } + List ambiguousCompounds = getAllCompounds().stream() + .filter(compound -> compound.isAmbiguous()) + .collect(Collectors.toCollection(ArrayList::new)); + for(NucleotideCompound sourceCompound: ambiguousCompounds) { Set compoundConstituents = sourceCompound.getConstituents(); From 8773045e35bb632c9ee352e4e9276673d8371658 Mon Sep 17 00:00:00 2001 From: balaji-s Date: Thu, 11 Jun 2020 21:57:17 +0530 Subject: [PATCH 107/769] refactored code to use java 8 streams --- .../main/java/org/biojava/nbio/aaproperties/CommandPrompt.java | 2 +- .../java/org/biojava/nbio/aaproperties/PeptideProperties.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java index 4ebcec641f..a8d3d64e21 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java @@ -327,7 +327,7 @@ private static void compute(PrintStream output, String header, String sequence, } } output.print(header.replace(delimiter, "_")); - dList.forEach(item -> System.out.print(delimiter + Utils.roundToDecimals(dList.get(item), decimalPlace))); + dList.stream().forEach(item -> System.out.print(delimiter + Utils.roundToDecimals(item, decimalPlace))); output.println(); output.flush(); } diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java index 9d62a05c71..ee6ab16355 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java @@ -68,7 +68,7 @@ public enum SingleLetterAACode { W, C, M, H, Y, F, Q, N, I, R, D, P, T, K, E, V, static{ standardAASet = Arrays.stream(SingleLetterAACode.values()) .map(singleLetterAACode -> singleLetterAACode.toString().charAt(0)) - . .collect(Collectors.toCollection(HashSet::new)); + .collect(Collectors.toCollection(HashSet::new)); } /** From 1dedc35b20a8dd64d3f2aae85441db43698e1682 Mon Sep 17 00:00:00 2001 From: balaji-s Date: Thu, 11 Jun 2020 22:13:57 +0530 Subject: [PATCH 108/769] refactored code to use java 8 streams --- .../main/java/org/biojava/nbio/aaproperties/CommandPrompt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java index a8d3d64e21..7db641ade9 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/CommandPrompt.java @@ -327,7 +327,7 @@ private static void compute(PrintStream output, String header, String sequence, } } output.print(header.replace(delimiter, "_")); - dList.stream().forEach(item -> System.out.print(delimiter + Utils.roundToDecimals(item, decimalPlace))); + dList.stream().forEach(item -> output.print(delimiter + Utils.roundToDecimals(item, decimalPlace))); output.println(); output.flush(); } From 6f5f18b71e6a5b16e0e8bea4fe18e896650b87ef Mon Sep 17 00:00:00 2001 From: balaji-s Date: Thu, 11 Jun 2020 23:40:52 +0530 Subject: [PATCH 109/769] refactoring code for streams API --- .../org/biojava/nbio/aaproperties/PeptideProperties.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java index ee6ab16355..fdbfa2cc4e 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java @@ -37,6 +37,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * This is an adaptor class which enable the ease of generating protein properties. @@ -536,6 +537,10 @@ public static final Map getAACompositionString(String sequence){ for(AminoAcidCompound aaCompound:aa2Composition.keySet()){ aaString2Composition.put(aaCompound.getShortName(), aa2Composition.get(aaCompound)); } + aaString2Composition = aa2Composition.keySet() + .stream() + .collect(Collectors.toMap(aaCompound -> aaCompound.getShortName(), + aaCompound ->aa2Composition.get(aaCompound))); return aaString2Composition; } From 02fb4f07e256867e6785d522d48ce6b28c38e270 Mon Sep 17 00:00:00 2001 From: balaji-s Date: Fri, 12 Jun 2020 00:15:55 +0530 Subject: [PATCH 110/769] refactoring code java 8 streams api --- .../org/biojava/nbio/aaproperties/PeptideProperties.java | 3 --- .../src/main/java/org/biojava/nbio/ronn/Jronn.java | 7 ++++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java index fdbfa2cc4e..dc92e76d6a 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java @@ -534,9 +534,6 @@ public static final Map getAAComposition(String seque public static final Map getAACompositionString(String sequence){ Map aa2Composition = getAAComposition(sequence); Map aaString2Composition = new HashMap(); - for(AminoAcidCompound aaCompound:aa2Composition.keySet()){ - aaString2Composition.put(aaCompound.getShortName(), aa2Composition.get(aaCompound)); - } aaString2Composition = aa2Composition.keySet() .stream() .collect(Collectors.toMap(aaCompound -> aaCompound.getShortName(), diff --git a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java index 60b259aff2..8f8d7b0817 100644 --- a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java +++ b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; +import java.util.stream.Collectors; /** @@ -247,9 +248,7 @@ public static Range[] scoresToRanges(float[] scores, float probability) { */ public static Map getDisorderScores(List sequences) { Map results = new TreeMap(); - for(FastaSequence fsequence : sequences) { - results.put(fsequence, predictSerial(fsequence)); - } + results = sequences.stream().collect(Collectors.toMap(sequence -> sequence, sequence -> predictSerial(sequence))); return results; } @@ -262,6 +261,8 @@ public static Map getDisorderScores(List s */ public static Map getDisorder(List sequences) { Map disorderRanges = new TreeMap(); + disorderRanges = sequences.stream() + .collect(Collectors.toMap(sequence -> sequence, sequence -> getDisorder(sequence) )); for(FastaSequence fs: sequences) { disorderRanges.put(fs, getDisorder(fs)); } From 1461eeb38dc39d36753b020053faa079ae41c221 Mon Sep 17 00:00:00 2001 From: balaji-s Date: Fri, 12 Jun 2020 00:23:09 +0530 Subject: [PATCH 111/769] refactoring code java 8 streams api --- .../org/biojava/nbio/aaproperties/PeptideProperties.java | 5 ++--- .../src/main/java/org/biojava/nbio/ronn/Jronn.java | 6 +----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java index dc92e76d6a..6b4fef7ed6 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java @@ -534,9 +534,8 @@ public static final Map getAAComposition(String seque public static final Map getAACompositionString(String sequence){ Map aa2Composition = getAAComposition(sequence); Map aaString2Composition = new HashMap(); - aaString2Composition = aa2Composition.keySet() - .stream() - .collect(Collectors.toMap(aaCompound -> aaCompound.getShortName(), + aaString2Composition = aa2Composition.keySet().stream() + .collect(Collectors.toMap(aaCompound -> aaCompound.getShortName(), aaCompound ->aa2Composition.get(aaCompound))); return aaString2Composition; } diff --git a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java index 8f8d7b0817..fd09653979 100644 --- a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java +++ b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java @@ -261,11 +261,7 @@ public static Map getDisorderScores(List s */ public static Map getDisorder(List sequences) { Map disorderRanges = new TreeMap(); - disorderRanges = sequences.stream() - .collect(Collectors.toMap(sequence -> sequence, sequence -> getDisorder(sequence) )); - for(FastaSequence fs: sequences) { - disorderRanges.put(fs, getDisorder(fs)); - } + disorderRanges = sequences.stream().collect(Collectors.toMap(sequence -> sequence, sequence -> getDisorder(sequence) )); return disorderRanges; } From 8a9ddbe9b4cf0aab2334fa231644abd41b5f4672 Mon Sep 17 00:00:00 2001 From: balaji-s Date: Fri, 12 Jun 2020 00:24:54 +0530 Subject: [PATCH 112/769] refactoring code java 8 streams api --- .../java/org/biojava/nbio/aaproperties/PeptideProperties.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java index 6b4fef7ed6..a46b857314 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/PeptideProperties.java @@ -534,9 +534,7 @@ public static final Map getAAComposition(String seque public static final Map getAACompositionString(String sequence){ Map aa2Composition = getAAComposition(sequence); Map aaString2Composition = new HashMap(); - aaString2Composition = aa2Composition.keySet().stream() - .collect(Collectors.toMap(aaCompound -> aaCompound.getShortName(), - aaCompound ->aa2Composition.get(aaCompound))); + aaString2Composition = aa2Composition.keySet().stream() .collect(Collectors.toMap(aaCompound -> aaCompound.getShortName(),aaCompound ->aa2Composition.get(aaCompound))); return aaString2Composition; } From 44d82b382e02184f5d1f1f4458e5be94112d7f0d Mon Sep 17 00:00:00 2001 From: balaji-s Date: Fri, 12 Jun 2020 00:29:19 +0530 Subject: [PATCH 113/769] refactoring code java 8 streams api --- .../src/main/java/org/biojava/nbio/ronn/Jronn.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java index fd09653979..8806395564 100644 --- a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java +++ b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java @@ -248,7 +248,7 @@ public static Range[] scoresToRanges(float[] scores, float probability) { */ public static Map getDisorderScores(List sequences) { Map results = new TreeMap(); - results = sequences.stream().collect(Collectors.toMap(sequence -> sequence, sequence -> predictSerial(sequence))); + results = sequences.stream().collect(Collectors.toMap(fastaSequence -> fastaSequence, fastaSequence -> predictSerial(fastaSequence))); return results; } @@ -261,7 +261,7 @@ public static Map getDisorderScores(List s */ public static Map getDisorder(List sequences) { Map disorderRanges = new TreeMap(); - disorderRanges = sequences.stream().collect(Collectors.toMap(sequence -> sequence, sequence -> getDisorder(sequence) )); + disorderRanges = sequences.stream().collect(Collectors.toMap(fastaSequence -> fastaSequence, fastaSequence -> getDisorder(fastaSequence) )); return disorderRanges; } From e1fdf30b5cc9dcea1002de2b14b9f7d17e6a89df Mon Sep 17 00:00:00 2001 From: balaji-s Date: Sat, 13 Jun 2020 21:00:03 +0530 Subject: [PATCH 114/769] refactor code to java 8 streams --- .../org/biojava/nbio/aaproperties/Utils.java | 22 ++++++++----------- .../profeat/ProfeatPropertiesImpl.java | 4 +--- .../profeat/convertor/Convertor.java | 8 +++---- .../java/org/biojava/nbio/ronn/Jronn.java | 6 ++--- 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java index e69b083be7..43c5ef06c1 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java @@ -23,6 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.nio.CharBuffer; import java.util.HashSet; import java.util.Set; @@ -68,10 +69,10 @@ public final static double roundToDecimals(double d, int c) { * true if invalid characters are found, else return false. */ public final static boolean doesSequenceContainInvalidChar(String sequence, Set cSet){ - for(char c:sequence.toCharArray()){ - if(!cSet.contains(c)) return true; - } - return false; + boolean result = sequence.chars().filter(c -> !cSet.contains((char) c)) + .findFirst() + .isPresent(); + return result; } /** @@ -86,15 +87,10 @@ public final static boolean doesSequenceContainInvalidChar(String sequence, Set< * @return * the number of invalid characters in sequence. */ - public final static int getNumberOfInvalidChar(String sequence, Set cSet, boolean ignoreCase){ - int total = 0; - char[] cArray; - if(ignoreCase) cArray = sequence.toUpperCase().toCharArray(); - else cArray = sequence.toCharArray(); - if(cSet == null) cSet = PeptideProperties.standardAASet; - for(char c:cArray){ - if(!cSet.contains(c)) total++; - } + public final static int getNumberOfInvalidChar(String sequence, Set cSet, boolean ignoreCase){ + char[] cArray = ignoreCase ? sequence.toUpperCase().toCharArray(): sequence.toCharArray(); + final Set characterSet = cSet == null ? cSet : PeptideProperties.standardAASet; + int total = (int)CharBuffer.wrap(cArray).chars().filter(character -> !characterSet.contains((char)character)).count(); return total; } diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/profeat/ProfeatPropertiesImpl.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/profeat/ProfeatPropertiesImpl.java index 5408c127c5..75b0ff3064 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/profeat/ProfeatPropertiesImpl.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/profeat/ProfeatPropertiesImpl.java @@ -44,9 +44,7 @@ private int getTotalCount(String convertedSeq, GROUPING group) throws Exception{ default: throw new Exception("Unhandled Case: " + group); } int total = 0; - for(char c:convertedSeq.toCharArray()){ - if(c == g) total++; - } + total = (int)convertedSeq.chars().filter(c ->(char) c == g) .count(); return total; } diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/profeat/convertor/Convertor.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/profeat/convertor/Convertor.java index 0420bad8e3..a88d93add3 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/profeat/convertor/Convertor.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/profeat/convertor/Convertor.java @@ -20,6 +20,8 @@ */ package org.biojava.nbio.aaproperties.profeat.convertor; +import java.util.stream.Collectors; + import org.biojava.nbio.core.sequence.ProteinSequence; public abstract class Convertor { @@ -78,12 +80,8 @@ public abstract class Convertor { * @return the converted sequence */ public String convert(ProteinSequence sequence){ - String convertedSequence = ""; String uppercaseSequence = sequence.getSequenceAsString().toUpperCase(); - for(int x = 0; x < uppercaseSequence.length(); x++){ - convertedSequence += String.valueOf(convert(uppercaseSequence.charAt(x))); - } + String convertedSequence = uppercaseSequence.chars().mapToObj(upperCaseSeq -> String.valueOf(convert((char)(upperCaseSeq)))).collect(Collectors.joining()); return convertedSequence; } - } diff --git a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java index 8806395564..a91d7e9876 100644 --- a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java +++ b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/Jronn.java @@ -180,11 +180,9 @@ private static float[] predictSerial(FastaSequence fsequence) { try { ronn = new ORonn(fsequence, loader); disorder = ronn.call().getMeanScores(); - } catch (NumberFormatException e) { - throw new RuntimeException("Jronn fails to load models " + e.getLocalizedMessage(), e); - } catch (IOException e) { + } catch (NumberFormatException | IOException e) { throw new RuntimeException("Jronn fails to load models " + e.getLocalizedMessage(), e); - } + } return disorder; } From 8998cbcd3cdb4e63fedc0e922b567f9447aef68d Mon Sep 17 00:00:00 2001 From: balaji-s Date: Sat, 13 Jun 2020 22:17:24 +0530 Subject: [PATCH 115/769] refactor code to java 8 streams api --- .../org/biojava/nbio/phosphosite/Dataset.java | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/biojava-modfinder/src/main/java/org/biojava/nbio/phosphosite/Dataset.java b/biojava-modfinder/src/main/java/org/biojava/nbio/phosphosite/Dataset.java index 71604d9bb3..38a91b511d 100644 --- a/biojava-modfinder/src/main/java/org/biojava/nbio/phosphosite/Dataset.java +++ b/biojava-modfinder/src/main/java/org/biojava/nbio/phosphosite/Dataset.java @@ -29,7 +29,10 @@ import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Phosphosite is available under the PhosphoSitePlus® is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License and is freely available for non-commercial purposes from @@ -76,27 +79,12 @@ private String[] getRemoteFiles(){ } public File[] getLocalFiles(){ - String[] rfiles = getRemoteFiles(); - - File dir = getLocalDir(); - - List files = new ArrayList(); - for ( String f : rfiles) { - - - int slashIndex = f.lastIndexOf("/"); - - String fileName = f.substring(slashIndex); - - File localFile = new File(dir+"/" + fileName); - - if ( localFile.exists()){ - files.add(localFile); - } - - } + List files = Arrays.stream(rfiles).map(remoteFileName -> remoteFileName.substring(remoteFileName.lastIndexOf("/"))) + .map(localFile -> new File(dir+"/"+localFile)) + .filter(file -> file.exists()) + .collect(Collectors.toList()); return files.toArray(new File[files.size()]); } From 9a59362a2192817f79be71f2bd937bfc541d8aac Mon Sep 17 00:00:00 2001 From: balaji-s Date: Sat, 13 Jun 2020 22:35:06 +0530 Subject: [PATCH 116/769] refactor code to java 8 streams --- .../src/main/java/org/biojava/nbio/aaproperties/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java index 43c5ef06c1..c19918df4d 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java @@ -89,7 +89,7 @@ public final static boolean doesSequenceContainInvalidChar(String sequence, Set< */ public final static int getNumberOfInvalidChar(String sequence, Set cSet, boolean ignoreCase){ char[] cArray = ignoreCase ? sequence.toUpperCase().toCharArray(): sequence.toCharArray(); - final Set characterSet = cSet == null ? cSet : PeptideProperties.standardAASet; + final Set characterSet = cSet == null ?PeptideProperties.standardAASet: cSet ; int total = (int)CharBuffer.wrap(cArray).chars().filter(character -> !characterSet.contains((char)character)).count(); return total; } From d14b19cd7c66b9fe672fde2a56fbd1127b8338f6 Mon Sep 17 00:00:00 2001 From: balaji-s Date: Sat, 13 Jun 2020 23:24:43 +0530 Subject: [PATCH 117/769] refactor code to java 8 streams --- .../src/main/java/org/biojava/nbio/ronn/ORonn.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/ORonn.java b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/ORonn.java index 16dbcb72a1..f4ea7d0d42 100644 --- a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/ORonn.java +++ b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/ORonn.java @@ -39,6 +39,8 @@ import java.util.List; import java.util.Locale; import java.util.concurrent.*; +import java.util.stream.IntStream; +import java.util.stream.Stream; /** @@ -139,13 +141,9 @@ static boolean isValidSequence(final FastaSequence fsequence) { public ORonn call() throws NumberFormatException, IOException { final String seq = sequence.getSequence(); // Calculate for each model - for (int m = 0; m < ORonn.NUMBER_OF_MODELS; m++) { - final Model model = mloader.getModel(m); - final ORonnModel rmodel = new ORonnModel(seq, model, disorder); - final float[] scores = rmodel.detect(); - addScore(scores); - } - + Stream.iterate(0, n -> n +1).limit(10).map(modelNumber -> mloader.getModel(modelNumber)) + .map(rmodel -> new ORonnModel(seq, rmodel, disorder).detect()) + .forEach(score ->addScore(score)); final char[] ch = seq.toCharArray(); final float[] meanScores = getMeanScores(); assert meanScores.length == seq.length() : "Scores are not calculated for " From 91f4ad2dc34134637b09896d04556ce2dc9e8664 Mon Sep 17 00:00:00 2001 From: balaji-s Date: Sun, 14 Jun 2020 00:09:04 +0530 Subject: [PATCH 118/769] refactor code to java 8 streams --- .../align/ce/AbstractUserArgumentProcessor.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java index 2ffdbae748..e7e36cb128 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java @@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.stream.Stream; /** @@ -796,12 +797,9 @@ public String printHelp() { Iterator helpIt = paramHelp.iterator(); buf.append("--- ").append(alg.getAlgorithmName()).append(" parameters: ---").append(newline); - for(int i = 0; i< size; i++) { - String name = namesIt.next(); - buf.append(" -").append(Introspector.decapitalize(name)); - buf.append(" ").append(helpIt.next()); - buf.append(newline); - } + Stream.iterate(0, n -> n + 1).limit(size) + .map(i -> namesIt.next()) + .forEach(name -> buf.append(" -").append(Introspector.decapitalize(name)).append(" ").append(helpIt.next()).append(newline)); } buf.append(newline); From c8197c8af0f0ad25be5779530a5582129de4eb5c Mon Sep 17 00:00:00 2001 From: balaji-s Date: Sat, 20 Jun 2020 21:12:56 +0530 Subject: [PATCH 119/769] reverting code and added Number of models --- .../main/java/org/biojava/nbio/aaproperties/Utils.java | 8 ++++---- .../src/main/java/org/biojava/nbio/ronn/ORonn.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java index c19918df4d..b66e879d7a 100644 --- a/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java +++ b/biojava-aa-prop/src/main/java/org/biojava/nbio/aaproperties/Utils.java @@ -69,10 +69,10 @@ public final static double roundToDecimals(double d, int c) { * true if invalid characters are found, else return false. */ public final static boolean doesSequenceContainInvalidChar(String sequence, Set cSet){ - boolean result = sequence.chars().filter(c -> !cSet.contains((char) c)) - .findFirst() - .isPresent(); - return result; + for(char c:sequence.toCharArray()){ + if(!cSet.contains(c)) return true; + } + return false; } /** diff --git a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/ORonn.java b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/ORonn.java index f4ea7d0d42..f5c745aa20 100644 --- a/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/ORonn.java +++ b/biojava-protein-disorder/src/main/java/org/biojava/nbio/ronn/ORonn.java @@ -141,7 +141,7 @@ static boolean isValidSequence(final FastaSequence fsequence) { public ORonn call() throws NumberFormatException, IOException { final String seq = sequence.getSequence(); // Calculate for each model - Stream.iterate(0, n -> n +1).limit(10).map(modelNumber -> mloader.getModel(modelNumber)) + Stream.iterate(0, n -> n +1).limit(NUMBER_OF_MODELS).map(modelNumber -> mloader.getModel(modelNumber)) .map(rmodel -> new ORonnModel(seq, rmodel, disorder).detect()) .forEach(score ->addScore(score)); final char[] ch = seq.toCharArray(); From 4d1b30566978f55ff5073ecb4f9c51dbcbe6fe76 Mon Sep 17 00:00:00 2001 From: Yana Rose Date: Sat, 27 Jun 2020 15:49:39 -0700 Subject: [PATCH 120/769] case insensitive comparison of chem comp type --- .../org/biojava/nbio/structure/io/mmcif/chem/ResidueType.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ResidueType.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ResidueType.java index e1d7e55b25..d6f6b0a40a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ResidueType.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ResidueType.java @@ -140,9 +140,9 @@ public static ResidueType getResidueTypeFromString(String chem_comp_type) { return rt; } - if ( rt.chem_comp_type.startsWith(chem_comp_type)) + if ( rt.chem_comp_type.toLowerCase().startsWith(chem_comp_type.toLowerCase())) return rt; - if ( chem_comp_type.startsWith(rt.chem_comp_type)) + if ( chem_comp_type.toLowerCase().startsWith(rt.chem_comp_type.toLowerCase())) return rt; } return null; From 222a8ae3f7b1d0441763c5165f8624b1d592f0a6 Mon Sep 17 00:00:00 2001 From: Yana Rose Date: Sat, 27 Jun 2020 15:50:04 -0700 Subject: [PATCH 121/769] throw exception if residue type cannot be resolved --- .../biojava/nbio/structure/io/mmtf/MmtfStructureReader.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java index 7c7c24e9ec..09d8ca58a8 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java @@ -214,6 +214,9 @@ public void setGroupInfo(String groupName, int groupNumber, char singleLetterCode, int sequenceIndexId, int secStructType) { // Get the polymer type ResidueType residueType = ResidueType.getResidueTypeFromString(chemCompType); + if (residueType == null) + throw new IllegalStateException("Couldn't resolve residue type for "+ chemCompType); + int polymerType = getGroupTypIndicator(residueType.polymerType); switch (polymerType) { case 1: From 0cea7d21241591aef9eacb3fefd1509fa10c7985 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Sat, 27 Jun 2020 21:55:14 -0700 Subject: [PATCH 122/769] Upgrading to newest java-8 compatible ciftools --- biojava-structure/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index 688984e845..e8fb694c07 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -21,7 +21,7 @@ org.rcsb ciftools-java - 0.5.4 + 0.7.1 org.rcsb From 9dcddeb0072ecc29aca8d8b1d43c3b18a430ac30 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Sun, 28 Jun 2020 22:19:28 -0700 Subject: [PATCH 123/769] [maven-release-plugin] prepare release biojava-5.4.0 --- biojava-aa-prop/pom.xml | 6 +++--- biojava-alignment/pom.xml | 4 ++-- biojava-core/pom.xml | 2 +- biojava-genome/pom.xml | 6 +++--- biojava-integrationtest/pom.xml | 4 ++-- biojava-modfinder/pom.xml | 4 ++-- biojava-ontology/pom.xml | 2 +- biojava-protein-disorder/pom.xml | 4 ++-- biojava-structure-gui/pom.xml | 6 +++--- biojava-structure/pom.xml | 6 +++--- biojava-survival/pom.xml | 2 +- biojava-ws/pom.xml | 4 ++-- pom.xml | 4 ++-- 13 files changed, 27 insertions(+), 27 deletions(-) diff --git a/biojava-aa-prop/pom.xml b/biojava-aa-prop/pom.xml index c8da170664..8e1e35b52a 100644 --- a/biojava-aa-prop/pom.xml +++ b/biojava-aa-prop/pom.xml @@ -2,7 +2,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 4.0.0 biojava-aa-prop @@ -70,12 +70,12 @@ org.biojava biojava-core - 5.3.1-SNAPSHOT + 5.4.0 org.biojava biojava-structure - 5.3.1-SNAPSHOT + 5.4.0 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index 092dbc3d0b..f342cebeef 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 5.3.1-SNAPSHOT + 5.4.0 compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index b465a40a36..4b417fa752 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index bd67b30190..d0bcc1563d 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 5.3.1-SNAPSHOT + 5.4.0 compile org.biojava biojava-alignment - 5.3.1-SNAPSHOT + 5.4.0 compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index 7367654c01..f2bb2663ab 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 5.3.1-SNAPSHOT + 5.4.0 diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 5367030867..b680992bd7 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 5.3.1-SNAPSHOT + 5.4.0 jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index b6a4fa0967..3c32d3fa8e 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.3.1-SNAPSHOT + 5.4.0 biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 982a4d170b..1a4d8f45a8 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 5.3.1-SNAPSHOT + 5.4.0 diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index e6605344bc..d8c100dbb7 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 5.3.1-SNAPSHOT + 5.4.0 compile org.biojava biojava-core - 5.3.1-SNAPSHOT + 5.4.0 compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index e8fb694c07..f0746e6c25 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 5.3.1-SNAPSHOT + 5.4.0 compile org.biojava biojava-core - 5.3.1-SNAPSHOT + 5.4.0 compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index 479b57276b..aec8a52ac1 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.3.1-SNAPSHOT + 5.4.0 biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 8df54334cf..02072c46b2 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.3.1-SNAPSHOT + 5.4.0 biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 5.3.1-SNAPSHOT + 5.4.0 compile diff --git a/pom.xml b/pom.xml index 8514858e84..c68291d525 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 5.3.1-SNAPSHOT + 5.4.0 biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -49,7 +49,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - HEAD + biojava-5.4.0 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index f342cebeef..e1080222d3 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.4.0 + 5.4.1-SNAPSHOT biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 5.4.0 + 5.4.1-SNAPSHOT compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 4b417fa752..71d3fd5794 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.0 + 5.4.1-SNAPSHOT 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index d0bcc1563d..03ff9b2c56 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.0 + 5.4.1-SNAPSHOT 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 5.4.0 + 5.4.1-SNAPSHOT compile org.biojava biojava-alignment - 5.4.0 + 5.4.1-SNAPSHOT compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index f2bb2663ab..60d537046d 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.4.0 + 5.4.1-SNAPSHOT biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 5.4.0 + 5.4.1-SNAPSHOT diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index b680992bd7..458ee4a2fe 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.4.0 + 5.4.1-SNAPSHOT biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 5.4.0 + 5.4.1-SNAPSHOT jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 3c32d3fa8e..a50275e091 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.4.0 + 5.4.1-SNAPSHOT biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 1a4d8f45a8..42ac69b916 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.0 + 5.4.1-SNAPSHOT biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 5.4.0 + 5.4.1-SNAPSHOT diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index d8c100dbb7..0b375b2a89 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.0 + 5.4.1-SNAPSHOT 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 5.4.0 + 5.4.1-SNAPSHOT compile org.biojava biojava-core - 5.4.0 + 5.4.1-SNAPSHOT compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index f0746e6c25..fc4584ce37 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.4.0 + 5.4.1-SNAPSHOT biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 5.4.0 + 5.4.1-SNAPSHOT compile org.biojava biojava-core - 5.4.0 + 5.4.1-SNAPSHOT compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index aec8a52ac1..62d4eb3667 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.4.0 + 5.4.1-SNAPSHOT biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 02072c46b2..ff394e7444 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.0 + 5.4.1-SNAPSHOT biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 5.4.0 + 5.4.1-SNAPSHOT compile diff --git a/pom.xml b/pom.xml index c68291d525..85b3c182af 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 5.4.0 + 5.4.1-SNAPSHOT biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -49,7 +49,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - biojava-5.4.0 + HEAD From eca876a7658eb3693a0131ff9a9ccd72bc50ec2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Jul 2020 17:41:12 +0000 Subject: [PATCH 126/769] Bump log4j.version from 2.13.1 to 2.13.3 Bumps `log4j.version` from 2.13.1 to 2.13.3. Updates `log4j-slf4j-impl` from 2.13.1 to 2.13.3 Updates `log4j-api` from 2.13.1 to 2.13.3 Updates `log4j-core` from 2.13.1 to 2.13.3 Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 85b3c182af..2b2cd74ce8 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ 512M 1.0.9 1.7.30 - 2.13.1 + 2.13.3 scm:git:git://github.com/biojava/biojava.git From b3d6fbaebafc2f32e8936982128774d0dd75e615 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 3 Jul 2020 08:25:43 -0700 Subject: [PATCH 127/769] Clean up --- .../structure/align/client/JFatCatClient.java | 22 --- .../align/ce/TestWebStartClient.java | 146 ------------------ 2 files changed, 168 deletions(-) delete mode 100644 biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/TestWebStartClient.java diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java index 92c4577115..76cea2c39f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java @@ -74,28 +74,6 @@ public class JFatCatClient { } - public static void main(String[] args) throws Exception { - //System.out.println(hasPrecalculatedResult("http://source.rcsb.org/jfatcatserver/align/", "jCE Circular Permutation", "1CDG.A", "1TIM.A")); - AtomCache cache = new AtomCache(); - String name1= "2W72.A"; - String name2= "1D2Z.D"; - - Atom[] ca1 = cache.getAtoms(name1); - Atom[] ca2 = cache.getAtoms(name2); - - int timeout = 10000; - - String testServer = "http://source.rcsb.org/jfatcatserver/align/"; - - System.out.println(getAFPChainFromServer(testServer, FatCatRigid.algorithmName, name1, name2, ca1, ca2, timeout)); - - PdbPairsMessage msg = getPdbPairs(testServer, 1, "test"); - - System.out.println(msg); - - System.out.println(getRepresentatives(FarmJobParameters.DEFAULT_SERVER_URL, 40)); - } - public static boolean hasPrecalculatedResult(String serverLocation, String method, String name1, String name2 ){ return hasPrecalculatedResult(serverLocation, method, name1, name2, DEFAULT_TIMEOUT ); } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/TestWebStartClient.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/TestWebStartClient.java deleted file mode 100644 index f62b4b7beb..0000000000 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/TestWebStartClient.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on May 18, 2010 - * Author: Andreas Prlic - * - */ - -package org.biojava.nbio.structure.align.ce; - -import org.biojava.nbio.structure.Atom; -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.align.StructureAlignment; -import org.biojava.nbio.structure.align.StructureAlignmentFactory; -import org.biojava.nbio.structure.align.client.JFatCatClient; -import org.biojava.nbio.structure.align.model.AFPChain; -import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.align.xml.AFPChainFlipper; -import org.biojava.nbio.structure.align.xml.AFPChainXMLConverter; -import org.biojava.nbio.structure.align.xml.AFPChainXMLParser; -import org.biojava.nbio.core.util.PrettyXMLWriter; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; - - -public class TestWebStartClient { - - @Test - @SuppressWarnings("unused") - public void testCPAlignment(){ - - //String name1="1cdg.A"; - //String name2="1tim.A"; - String name1="1VHR.A"; - String name2="2IHB.A"; - - try { - //StructureAlignment algorithm = StructureAlignmentFactory.getAlgorithm(CeCPMain.algorithmName); - for (StructureAlignment algorithm : StructureAlignmentFactory.getAllAlgorithms()){ - // disable for now - //align(name1,name2,algorithm); - } - } catch (Exception e){ - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - } - - @SuppressWarnings("unused") - private void align(String name1, String name2, StructureAlignment algorithm) - throws StructureException, IOException { - if ( algorithm.getAlgorithmName().startsWith("Smith")) { - System.err.println("not testing SW, no need to run that on server..."); - return; - } - - //System.out.println("testing " + name1 + " " + name2 + " " + algorithm.getAlgorithmName()); - AtomCache cache = new AtomCache(); - - - Atom[] ca1 = cache.getAtoms(name1); - Atom[] ca2 = cache.getAtoms(name2); - - - AFPChain afpChain = algorithm.align(ca1,ca2); - afpChain.setName1(name1); - afpChain.setName2(name2); - - Assert.assertNotNull(afpChain); - Assert.assertNotNull(afpChain.getAlgorithmName()); - Assert.assertTrue(afpChain.getAlgorithmName().equals(algorithm.getAlgorithmName())); - - String xml = AFPChainXMLConverter.toXML(afpChain,ca1,ca2); - - /// SERVER part - String serverLocation = "http://beta.rcsb.org/pdb/rest/"; - AFPChain afpServer = JFatCatClient.getAFPChainFromServer(serverLocation,algorithm.getAlgorithmName(), name1, name2, ca1, ca2, 5000); - Assert.assertNotNull(afpServer); - - Assert.assertTrue("Algorithm names don't match!", afpServer.getAlgorithmName().equals(algorithm.getAlgorithmName())); - Assert.assertTrue("Alignment blockNum < 1", afpServer.getBlockNum() >= 1); - - String xml2 = AFPChainXMLConverter.toXML(afpServer, ca1, ca2); - //System.err.println(" tmp disabled comparison of server and client XML, a minor rounding diff..."); - Assert.assertEquals("The server and the locally calculated XML representations don;t match!", xml, xml2); - - AFPChain afpFlip = AFPChainFlipper.flipChain(afpChain); - String xmlFlipped = AFPChainXMLConverter.toXML(afpFlip, ca2, ca1); - //System.out.println(xmlFlipped); - AFPChain fromXmlFlipped = AFPChainXMLParser.fromXML(xmlFlipped, ca2, ca1); - Assert.assertEquals("The alignment lengths don't match", afpFlip.getNrEQR(), fromXmlFlipped.getNrEQR()); - - String xmlFromFlippled = AFPChainXMLConverter.toXML(fromXmlFlipped,ca2,ca1); - Assert.assertEquals("The XML of the flipped and the recreated from that XML don't match!", xmlFlipped, xmlFromFlippled); - - AFPChain afpBackToOrig = AFPChainFlipper.flipChain(fromXmlFlipped); - //String xml5 = AFPChainXMLConverter.toXML(afpBackToOrig, ca1, ca2); - // ok in the double flipping there are some minor after comma mismatches. - - String xmlShortOrig = getShortXML(afpChain,ca1, ca2); - String xmlShortFinal = getShortXML(afpBackToOrig, ca1, ca2); - Assert.assertEquals("The 2 x flipped alignment does not match the original", xmlShortOrig, xmlShortFinal); - - - - - } - - private String getShortXML(AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws IOException { - - StringWriter result = new StringWriter(); - PrintWriter writer = new PrintWriter(result); - PrettyXMLWriter xml = new PrettyXMLWriter(writer); - xml.openTag("AFPChain"); - //AFPChainXMLConverter.printXMLHeader(xml, afpChain); - int blockNum = afpChain.getBlockNum(); - for(int bk = 0; bk < blockNum; bk ++) { - - xml.openTag("block"); - AFPChainXMLConverter.printXMLEQRInferPositions(xml, afpChain, bk, ca1, ca2); - xml.closeTag("block"); - } - xml.closeTag("AFPChain"); - return result.toString(); - } -} From 13716a375d7eb1211ceb7cf6d43e35aaed252c9c Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 3 Jul 2020 14:56:00 -0700 Subject: [PATCH 128/769] Removing db-related gui tools --- .../structure/align/gui/AlignmentCalcDB.java | 195 --------- .../structure/align/gui/AlignmentGui.java | 113 ------ .../structure/align/gui/DBResultTable.java | 372 ------------------ .../nbio/structure/align/gui/DBSearchGUI.java | 253 ------------ .../nbio/structure/align/gui/MenuCreator.java | 43 +- .../webstart/WebStartDBSearchResults.java | 64 --- 6 files changed, 1 insertion(+), 1039 deletions(-) delete mode 100644 biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/AlignmentCalcDB.java delete mode 100644 biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/DBResultTable.java delete mode 100644 biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/DBSearchGUI.java delete mode 100644 biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartDBSearchResults.java diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/AlignmentCalcDB.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/AlignmentCalcDB.java deleted file mode 100644 index 74637e4617..0000000000 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/AlignmentCalcDB.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Nov 5, 2009 - * Author: Andreas Prlic - * - */ - -package org.biojava.nbio.structure.align.gui; - - -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.align.MultiThreadedDBSearch; -import org.biojava.nbio.structure.align.StructureAlignment; -import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.scop.ScopFactory; - -import java.io.File; -import java.util.concurrent.atomic.AtomicBoolean; -//import org.slf4j.Logger; -//import org.slf4j.LoggerFactory; - -public class AlignmentCalcDB implements AlignmentCalculationRunnable { - - - public static String SCOP_VERSION = "1.75"; - - //private static final Logger logger = LoggerFactory.getLogger(AlignmentCalcDB.class); - - AtomicBoolean interrupted ; - - - String name1; - - Structure structure1; - - AlignmentGui parent; - - UserConfiguration config; - - - String outFile; - - int nrCPUs; - Boolean domainSplit ; - - StructureAlignment customAlgorithm; - - MultiThreadedDBSearch job = null; - - public StructureAlignment getAlgorithm() { - return customAlgorithm; - } - - public void setAlgorithm(StructureAlignment algo) { - this.customAlgorithm = algo; - } - - public AlignmentCalcDB(AlignmentGui parent, Structure s1, String name1, UserConfiguration config,String outFile, Boolean domainSplit) { - - this.parent= parent; - - structure1 = s1; - - this.name1 = name1; - - this.config = config; - //this.representatives = representatives; - interrupted = new AtomicBoolean(false); - this.outFile = outFile; - this.domainSplit = domainSplit; - - System.out.println("AlignmentCalcDB: Using SCOP version " + SCOP_VERSION); - ScopFactory.setScopDatabase(SCOP_VERSION); - - } - - - - @Override - public void run() { - - StructureAlignment algorithm = null; - - if ( parent != null ) - algorithm = parent.getStructureAlignment(); - else { - algorithm = customAlgorithm; - } - - - if ( name1.startsWith("file:/")) - name1= "CUSTOM"; - - job = new MultiThreadedDBSearch(name1,structure1, outFile, algorithm, nrCPUs, domainSplit); - - AtomCache cache = new AtomCache(config); - System.out.println("using cache: " + cache.getPath()); - System.out.println("name1: " + name1); - System.out.println("structure:" + structure1.getName()); - job.setAtomCache(cache); - - if ( name1.equals("CUSTOM")) { - job.setCustomFile1(parent.getDBSearch().getPDBUploadPanel().getFilePath1()); - job.setCustomChain1(parent.getDBSearch().getPDBUploadPanel().getChain1()); - } - - job.run(); - - File resultList = job.getResultFile(); - // if ((now-startTime)/1000 > 30) { - - - // try { - // out.flush(); - // out.close(); - // } catch (Exception e) { - // e.printStackTrace(); - // } - if ( parent != null ) { - parent.notifyCalcFinished(); - if ( resultList != null) { - DBResultTable table = new DBResultTable(); - table.show(resultList,config); - } - } - - } - - - - - - /** stops what is currently happening and does not continue - * - * - */ - @Override - public void interrupt() { - interrupted.set(true); - if ( job != null) - job.interrupt(); - - - - } - - @Override - public void cleanup() - { - parent.notifyCalcFinished(); - - parent=null; - // cleanup... - - structure1 = null; - config = null; - - if ( job != null) - job.cleanup(); - - } - - @Override - public void setNrCPUs(int useNrCPUs) { - nrCPUs = useNrCPUs; - - } - - public synchronized boolean isInterrupted() { - return interrupted.get(); - } - - - - - -} diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/AlignmentGui.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/AlignmentGui.java index c55e6689e3..f334c09e0b 100644 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/AlignmentGui.java +++ b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/AlignmentGui.java @@ -82,9 +82,6 @@ public class AlignmentGui extends JFrame{ JProgressBar progress; - private DBSearchGUI dbsearch; - - public static void main(String[] args){ AlignmentGui.getInstance(); @@ -163,10 +160,6 @@ protected AlignmentGui() { masterPane.addTab("Pairwise Comparison", vBox); - dbsearch = new DBSearchGUI(); - - masterPane.addTab("Database Search",dbsearch); - //JPanel dir = tab1.getPDBDirPanel(pdbDir); Box vBoxMain = Box.createVerticalBox(); @@ -278,8 +271,6 @@ public void actionPerformed(ActionEvent evt) { int selectedIndex = masterPane.getSelectedIndex(); if (selectedIndex == 0) calcAlignment(); - else if ( selectedIndex == 1) - calcDBSearch(); else { System.err.println("Unknown TAB: " + selectedIndex); } @@ -408,110 +399,6 @@ private void calcAlignment() { } - - private void calcDBSearch() { - - JTabbedPane tabPane = dbsearch.getTabPane(); - System.out.println("run DB search " + tabPane.getSelectedIndex()); - - Structure s = null; - boolean domainSplit = dbsearch.isDomainSplit(); - - StructurePairSelector tab = null; - int pos = tabPane.getSelectedIndex(); - - if (pos == 0 ){ - - tab = dbsearch.getSelectPDBPanel(); - - } else if (pos == 1){ - - tab = dbsearch.getScopSelectPanel(); - - - } else if (pos == 2){ - - tab = dbsearch.getPDBUploadPanel(); - - } - - try { - - s = tab.getStructure1(); - - if ( s == null) { - JOptionPane.showMessageDialog(null,"please select structure 1"); - return ; - } - - } catch (Exception e){ - e.printStackTrace(); - } - - String name1 = s.getName(); - if ( name1 == null || name1.equals("")) - name1 = s.getPDBCode(); - - - - System.out.println("name1 in alig gui:" + name1); - String file = dbsearch.getOutFileLocation(); - if ( file == null || file.equals("") ){ - JOptionPane.showMessageDialog(null,"Please select a directory to contain the DB search results."); - return; - } - File outFile = new File(file); - if( !outFile.exists() ) { - outFile.mkdirs(); - } - if( !outFile.isDirectory() || !outFile.canWrite()) { - JOptionPane.showMessageDialog(null,"Unable to write to "+outFile.getAbsolutePath()); - return; - } - - UserConfiguration config = WebStartMain.getWebStartConfig(); - - int totalNrCPUs = Runtime.getRuntime().availableProcessors(); - - int useNrCPUs = 1; - if ( totalNrCPUs > 1){ - Object[] options = new Integer[totalNrCPUs]; - int posX = 0; - for ( int i = totalNrCPUs; i> 0 ; i--){ - options[posX] = i; - posX++; - } - int n = JOptionPane.showOptionDialog(null, - "How many would you like to use for the calculations?", - "We detected " + totalNrCPUs + " processors on your system.", - JOptionPane.OK_CANCEL_OPTION, - JOptionPane.QUESTION_MESSAGE, - null, - options, - options[0]); - - if ( n < 0) - return; - useNrCPUs = (Integer) options[n]; - System.out.println("will use " + useNrCPUs + " CPUs." ); - } - System.out.println("using domainSplit data"); - alicalc = new AlignmentCalcDB(this, s, name1,config,file, domainSplit); - alicalc.setNrCPUs(useNrCPUs); - abortB.setEnabled(true); - progress.setIndeterminate(true); - ProgressThreadDrawer drawer = new ProgressThreadDrawer(progress); - drawer.start(); - - Thread t = new Thread(alicalc); - t.start(); - } - - - public DBSearchGUI getDBSearch(){ - return dbsearch; - } - public void notifyCalcFinished(){ abortB.setEnabled(false); thread = null; diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/DBResultTable.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/DBResultTable.java deleted file mode 100644 index b71b040f8e..0000000000 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/DBResultTable.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Nov 6, 2009 - * Author: Andreas Prlic - * - */ - -package org.biojava.nbio.structure.align.gui; - -import org.biojava.nbio.structure.Atom; -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.align.StructureAlignment; -import org.biojava.nbio.structure.align.StructureAlignmentFactory; -import org.biojava.nbio.structure.align.ce.CeMain; -import org.biojava.nbio.structure.align.ce.CeParameters; -import org.biojava.nbio.structure.align.ce.CeParameters.ScoringStrategy; -import org.biojava.nbio.structure.align.ce.ConfigStrucAligParams; -import org.biojava.nbio.structure.align.gui.jmol.StructureAlignmentJmol; -import org.biojava.nbio.structure.align.model.AFPChain; -import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.align.webstart.WebStartMain; -import org.biojava.nbio.structure.io.PDBFileReader; -import org.biojava.nbio.structure.io.StructureIOFile; - -import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.table.TableModel; -import javax.swing.table.TableRowSorter; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.*; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - - -public class DBResultTable implements ActionListener{ - - public static final String[] ceColumnNames = {"name1","tname2","score","z-score" ,"rmsd","len1","len2","cov1","cov2","%ID","Description",""}; - public static final String[] fatColumnNames = {"name1","tname2","score","probability","rmsd","len1","len2","cov1","cov2","%ID","Description",""}; - - Object[][] data; - JTable table; - - String oldName1; - String oldName2; - - String algorithmName; - StructureAlignment algorithm; - - boolean isCE = true; - UserConfiguration config; - AtomCache cache ; - - String userPath ; - String userChain; - - - - public static void main(String[] args){ - - String file = "/tmp/results_4hhb.A.out"; - - DBResultTable table = new DBResultTable(); - UserConfiguration config = WebStartMain.getDefaultConfig(); - table.show(new File(file),config); - } - - public DBResultTable(){ - oldName1 = ""; - oldName2 = ""; - userPath = null; - userChain = null; - } - - public void show(BufferedReader in, UserConfiguration config) throws IOException{ - String str; - List tmpdat = new ArrayList(); - while ((str = in.readLine()) != null) { - if ( str.startsWith("#")) { - if ( str.startsWith("# algorithm:")) { - String[] spl = str.split(":"); - if ( spl.length == 2) { - algorithmName = spl[1]; - if (algorithmName.startsWith("jCE")) - isCE = true; - else - isCE = false; - } - initAlgorithm(algorithmName); - - } - - else if ( str.startsWith("#param:file1=")){ - String path = str.substring(13); - userPath = path.trim(); - } - - else if ( str.startsWith("#param:chain1=")){ - String chain = str.substring(14); - userChain = chain.trim(); - } - - else if ( str.startsWith("#param:scoring=")){ - try { - String[] spl = str.split("="); - ScoringStrategy scoreS; - try { - // try to convert from integer score - int stratNum = Integer.parseInt(spl[1]); - ScoringStrategy[] vals = ScoringStrategy.values(); - scoreS = vals[stratNum];//throws OutOfBounds if invalid; caught below - } catch(NumberFormatException e) { - scoreS = ScoringStrategy.valueOf(spl[1]); // - } - if (algorithm != null){ - // scoring is a parameter of CE... - ConfigStrucAligParams params = algorithm.getParameters(); - if ( params instanceof CeParameters){ - CeParameters ceParams = (CeParameters) params; - ceParams.setScoringStrategy(scoreS); - } - } - } catch (IndexOutOfBoundsException e){ - System.err.println("Unknown scoring strategy from line: " + str); - } catch (IllegalArgumentException e) { - System.err.println("Unknown scoring strategy from line: " + str); - } catch (Exception e) { - System.err.println("Unknown parameter can't read parameters from line: " + str); - e.printStackTrace(); - } - - } - continue; - } - String[] spl = str.split("\t"); - if ( spl.length != ceColumnNames.length -1) { - System.err.println("wrong table width! " + spl.length + " should be: " + (ceColumnNames.length -1 )); - System.err.println(str); - continue; - } - tmpdat.add(spl); - - } - in.close(); - - Object[][] d = new Object[tmpdat.size()][ceColumnNames.length + 1]; - - int i = -1; - for (String[] spl : tmpdat){ - - i++; - Object[] o = new Object[spl.length + 1]; - for ( int j=0; j< spl.length;j++){ - - if (( j >= 2 && j <= 4)|| (j==9)) { - o[j] = Double.parseDouble(spl[j]); - } else if ( j >4 && j< 10) { - - o[j] = Integer.parseInt(spl[j]); - } else { - o[j] = spl[j]; - } - } - - o[spl.length ] = "Align"; - - d[i] = o; - - } - data = d; - String[] columnNames = ceColumnNames; - if ( ! isCE) - columnNames = fatColumnNames; - table = new JTable(data, columnNames); - - TableRowSorter sorter = new MyTableRowSorter(table.getModel()); - table.setRowSorter(sorter); - //table.setAutoCreateRowSorter(true); - - JScrollPane scrollPane = new JScrollPane(table); - table.setFillsViewportHeight(true); - - // take care of selections: - table.setSelectionMode( ListSelectionModel.SINGLE_INTERVAL_SELECTION); - table.getSelectionModel().addListSelectionListener(new RowListener()); - - - JFrame f = new JFrame(); - f.getContentPane().add(scrollPane); - f.pack(); - f.setVisible(true); - - } - - public void show(File file, UserConfiguration config){ - this.config = config; - - cache = new AtomCache(config); - try { - BufferedReader in = new BufferedReader(new FileReader(file)); - show(in, config); - - } catch (IOException e) { - e.printStackTrace(); - } - - } - - public void show(URL url, UserConfiguration config){ - this.config = config; - - cache = new AtomCache(config); - try { - BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); - show(in, config); - - } catch (IOException e) { - e.printStackTrace(); - } - - } - - - private void initAlgorithm(String algorithmName) { - try { - algorithm = StructureAlignmentFactory.getAlgorithm(algorithmName); - } catch (Exception e){ - e.printStackTrace(); - System.err.println("Can't guess algorithm from output. Using jCE as default..."); - try { - algorithm = StructureAlignmentFactory.getAlgorithm(CeMain.algorithmName); - } catch (Exception ex){ - ex.printStackTrace(); - return; - } - } - - } - - private void outputSelection() { - StringBuffer output = new StringBuffer(); - output.append(String.format("Lead: %d, %d. ", - table.getSelectionModel().getLeadSelectionIndex(), - table.getColumnModel().getSelectionModel(). - getLeadSelectionIndex())); - output.append("Rows:"); - for (int c : table.getSelectedRows()) { - output.append(String.format(" %d", c)); - } - - output.append(". Columns:"); - for (int c : table.getSelectedColumns()) { - output.append(String.format(" %d", c)); - } - - System.out.println(output.toString()); - } - - private class RowListener implements ListSelectionListener { - @Override - public void valueChanged(ListSelectionEvent event) { - if (event.getValueIsAdjusting()) { - return; - } - int row = table.getSelectionModel().getLeadSelectionIndex(); - String name1 = (String)table.getValueAt(row, 0); - String name2 = (String)table.getValueAt(row, 1); - - if ( name1.equals(oldName1) && oldName2.equals(name2)){ - return; - } - System.out.println("recreating alignment of: " + name1 + " " + name2 + " using " + algorithmName); - outputSelection(); - showAlignment(name1,name2); - oldName1 = name1; - oldName2 = name2; - - - } - } - - private void showAlignment( String name1, String name2){ - - - if ( algorithm == null) { - initAlgorithm(null); - } - - try { - Structure structure1 = null; - if ( name1.equals("CUSTOM")) { - // user uploaded a custom PDB file... - structure1 = loadCustomStructure(userPath,userChain); - } else { - structure1 = cache.getStructure(name1); - } - Structure structure2 = cache.getStructure(name2); - - Atom[] ca1; - Atom[] ca2; - - ca1 = StructureTools.getRepresentativeAtomArray(structure1); - ca2 = StructureTools.getRepresentativeAtomArray(structure2); - - AFPChain afpChain; - - afpChain = algorithm.align(ca1, ca2); - afpChain.setName1(name1); - afpChain.setName2(name2); - - - - StructureAlignmentJmol jmol = StructureAlignmentDisplay.display(afpChain,ca1,ca2); - - //String result = afpChain.toFatcat(ca1, ca2); - - //String rot = afpChain.toRotMat(); - - DisplayAFP.showAlignmentPanel(afpChain, ca1,ca2,jmol); - - - } catch (Exception e){ - e.printStackTrace(); - } - } - - private Structure loadCustomStructure(String userPath2, String userChain2) throws StructureException{ - StructureIOFile reader = new PDBFileReader(); - Structure s = null; - try { - s = reader.getStructure(userPath2); - } catch (IOException e){ - - //e.printStackTrace(); - throw new StructureException(e); - } - - - return StructureTools.getReducedStructure(s, userChain2); - } - - @Override - public void actionPerformed(ActionEvent e) { - - - - } - - -} diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/DBSearchGUI.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/DBSearchGUI.java deleted file mode 100644 index 885a544d28..0000000000 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/DBSearchGUI.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Nov 3, 2009 - * Author: Andreas Prlic - * - */ - -package org.biojava.nbio.structure.align.gui; - - -import org.biojava.nbio.structure.align.StructureAlignment; -import org.biojava.nbio.structure.align.util.ResourceManager; -import org.biojava.nbio.structure.gui.util.PDBUploadPanel; -import org.biojava.nbio.structure.gui.util.ScopSelectPanel; - -import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; - -public class DBSearchGUI extends JPanel { - - /** - * - */ - private static final long serialVersionUID = -5657960663049062301L; - - - StructureAlignment algorithm; - SelectPDBPanel tab1; - JTabbedPane tabPane; - - PDBUploadPanel tab2; - ScopSelectPanel tab3; - - JPanel listPane; - JButton abortB; - AlignmentCalcDB alicalc; - JProgressBar progress; - ProgressThreadDrawer drawer; - JTextField outFileLocation; - - Boolean useDomainSplit = true; - static final ResourceManager resourceManager = ResourceManager.getResourceManager("ce"); - - - public DBSearchGUI(){ - - - tab1 = new SelectPDBPanel(false); - - tab2 = new PDBUploadPanel(false); - tab3 = new ScopSelectPanel(false); - - tabPane = new JTabbedPane(); - tabPane.addTab("Select PDB ID", null, tab1,"Select PDB ID to align"); - - tabPane.addTab("Domains",null, tab3,"Domains"); - - tabPane.addTab("Custom files",null, tab2,"Align your own files."); - - listPane = createListPane(); - - // build up UO - - Box vBox = Box.createVerticalBox(); - - vBox.add(tabPane); - - vBox.add(listPane); - - //domainSelectPane = createDomainSelectPane(); - - //vBox.add(domainSelectPane); - - //vBox.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); - vBox.add(Box.createGlue()); - - this.add(vBox); - - this.setVisible(true); - - } - - public boolean isDomainSplit(){ - return useDomainSplit; - } - - public JTabbedPane getTabPane() - { - return tabPane; - } - - public void setTabPane(JTabbedPane tabPane) - { - this.tabPane = tabPane; - } - - public ScopSelectPanel getScopSelectPanel(){ - return tab3; - } - - - public SelectPDBPanel getSelectPDBPanel(){ - return tab1; - } - public PDBUploadPanel getPDBUploadPanel(){ - return tab2; - } - public String getOutFileLocation(){ - return outFileLocation.getText(); - } - - - private JPanel createListPane() { - //JTabbedPane tabP = new JTabbedPane(); - - - JLabel lable = new JLabel("Select Output Directory"); - JPanel dir = new JPanel(); - - - outFileLocation = new JTextField(20); - JButton chB = new JButton("Select"); - - Box fileSelectBox = Box.createHorizontalBox(); - fileSelectBox.add(lable); - fileSelectBox.add(outFileLocation); - fileSelectBox.add(chB); - fileSelectBox.add(Box.createGlue()); - - - Box hBox = Box.createVerticalBox(); - hBox.add(fileSelectBox); - - Box panel =createDomainSelectPane(); - hBox.add(panel); - - dir.add(hBox); - - chB.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser chooser = new JFileChooser(); - chooser.setMultiSelectionEnabled(false); - chooser.setDialogTitle("Select Output Directory"); - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - // - // disable the "All files" option. - // - chooser.setAcceptAllFileFilterUsed(false); - // - - - // In response to a button click: - int returnVal = chooser.showSaveDialog(null); - if ( returnVal == JFileChooser.APPROVE_OPTION) { - File file = chooser.getSelectedFile(); - outFileLocation.setText(file.getPath()); - outFileLocation.repaint(); - } - - } - }); - - //tabP.addTab("Select Output Directory", null, dir, - // "Configure the folder that will contain the results."); - - - return dir; - } - - - private Box createDomainSelectPane() { - - - - - useDomainSplit = true; - - String[] petStrings = { "Split proteins in Domains", "Use whole chains" }; - - //Create the combo box, select item at index 4. - //Indices start at 0, so 4 specifies the pig. - JComboBox domainList = new JComboBox(petStrings); - domainList.setSelectedIndex(0); - domainList.setToolTipText("Either align whole chains or SCOP domains and domains assigned with PDP, where no SCOP available."); - domainList.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent arg0) { - JComboBox box = (JComboBox)arg0.getSource(); - int index = box.getSelectedIndex(); - if ( index == 0) - useDomainSplit = true; - else - useDomainSplit = false; - - } - }); - - JLabel label= new JLabel("Domains:"); - - Box domainBox = Box.createHorizontalBox(); - domainBox.add(label); - - domainBox.add(domainList); - domainBox.add(Box.createGlue()); - //Box hBox = Box.createHorizontalBox(); - - //hBox.add(Box.createGlue()); - - - - return domainBox; - } - - - - public void notifyCalcFinished(){ - if ( drawer != null) - drawer.interrupt(); - abortB.setEnabled(false); - progress.setIndeterminate(false); - - } - - - - public StructureAlignment getStructureAlignment() { - - return algorithm; - } -} - diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/MenuCreator.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/MenuCreator.java index 9484217af9..c5cac56b49 100644 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/MenuCreator.java +++ b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/MenuCreator.java @@ -113,10 +113,6 @@ public static JMenuBar initJmolMenu(JFrame frame, JMenuItem exportI = getExportPDBMenuItem(parent); file.add(exportI); } - //Open DBI - JMenuItem openDBI = getDBResultMenuItem(); - file.add(openDBI); - file.addSeparator(); //Print if ( parent != null){ JMenuItem print = getPrintMenuItem(); @@ -205,39 +201,6 @@ public static JMenuBar initJmolMenu(JFrame frame, return menu; } - - public static JMenuItem getDBResultMenuItem() { - - ImageIcon saveicon = createImageIcon("/icons/kpdf.png"); - JMenuItem saveI = null; - - if ( saveicon == null) - saveI = new JMenuItem(LOAD_DB_RESULTS); - else - saveI = new JMenuItem(LOAD_DB_RESULTS, saveicon); - - saveI.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - final JFileChooser fc = new JFileChooser(); - - // In response to a button click: - int returnVal = fc.showOpenDialog(null); - if ( returnVal == JFileChooser.APPROVE_OPTION) { - File file = fc.getSelectedFile(); - - UserConfiguration config = WebStartMain.getWebStartConfig(); - DBResultTable table = new DBResultTable(); - table.show(file,config); - } - - } - } ); - - return saveI; - } - public static JMenuItem getShowPDBMenuItem() { ImageIcon loadI = createImageIcon("/icons/background.png"); JMenuItem openI = null; @@ -290,7 +253,7 @@ public static JMenuItem getLoadMenuItem() { * @param frame * @param actionListener * @param afpChain - * @param MultipleAlignment + * @param msa * @return a JMenuBar */ public static JMenuBar getAlignmentPanelMenu(JFrame frame, @@ -798,10 +761,6 @@ public static JMenuBar initAlignmentGUIMenu(JFrame frame) { JMenuItem openI = MenuCreator.getOpenPDBMenuItem(); file.add(openI); - JMenuItem dbI = MenuCreator.getDBResultMenuItem(); - file.add(dbI); - file.addSeparator(); - JMenuItem configI = MenuCreator.getConfigMenuItem(); file.add(configI); file.addSeparator(); diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartDBSearchResults.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartDBSearchResults.java deleted file mode 100644 index 2e62b6bdd3..0000000000 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartDBSearchResults.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Sep 26, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.align.webstart; - -import org.biojava.nbio.structure.align.gui.DBResultTable; -import org.biojava.nbio.structure.align.util.UserConfiguration; - -import javax.swing.*; -import java.net.URL; - -public class WebStartDBSearchResults { - - public static void main(String[] argv){ - - if (argv.length == 0 ) { - - JOptionPane.showMessageDialog(null, - "Not enough arguments!"); - return; - - - } else if ( argv.length == 2){ - String path = argv[1]; - - DBResultTable table = new DBResultTable(); - UserConfiguration config = WebStartMain.getDefaultConfig(); - try { - URL u = new URL(path); - - //File f = new File(u.toURI()); - - table.show(u,config); - } catch (Exception e){ - JOptionPane.showMessageDialog(null, - e.getMessage()); - return; - } - } - - - } -} From a1b9be3573600bd6cc023fbb017f755b93dc541a Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 3 Jul 2020 15:21:58 -0700 Subject: [PATCH 129/769] Removing more db related code --- .../src/main/assembly/assembly.xml | 6 - .../src/main/assembly/startFarmJob.sh | 22 - .../gui/GUIAlignmentProgressListener.java | 162 ------ .../align/gui/GUIFarmJobRunnable.java | 86 ---- .../align/webstart/WebStartDBSearch.java | 124 ----- .../biojava/nbio/structure/align/FarmJob.java | 249 --------- .../align/MultiThreadedDBSearch.java | 473 ------------------ .../ce/AbstractUserArgumentProcessor.java | 119 ----- .../nbio/structure/align/ce/GuiWrapper.java | 36 +- 9 files changed, 2 insertions(+), 1275 deletions(-) delete mode 100755 biojava-protein-comparison-tool/src/main/assembly/startFarmJob.sh delete mode 100644 biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/GUIAlignmentProgressListener.java delete mode 100644 biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/GUIFarmJobRunnable.java delete mode 100644 biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartDBSearch.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/FarmJob.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/MultiThreadedDBSearch.java diff --git a/biojava-protein-comparison-tool/src/main/assembly/assembly.xml b/biojava-protein-comparison-tool/src/main/assembly/assembly.xml index 8ed510892f..1af2b92b9c 100644 --- a/biojava-protein-comparison-tool/src/main/assembly/assembly.xml +++ b/biojava-protein-comparison-tool/src/main/assembly/assembly.xml @@ -46,12 +46,6 @@ true 0755 - - src/main/assembly/startFarmJob.sh - / - true - 0755 - \ No newline at end of file diff --git a/biojava-protein-comparison-tool/src/main/assembly/startFarmJob.sh b/biojava-protein-comparison-tool/src/main/assembly/startFarmJob.sh deleted file mode 100755 index b324cc1701..0000000000 --- a/biojava-protein-comparison-tool/src/main/assembly/startFarmJob.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -# example: -# startFarmJob.sh -pdbFilePath /Users/ap3/WORK/PDB -nrAlignments 10 - -# send the arguments to the java app -# allows to specify a different config file - -if [ -f $OSG_APP/engage/jdk1.6.0_16/bin/java ]; then - $OSG_APP/engage/jdk1.6.0_16/bin/java -Xmx1G -cp "$PWD/${project.build.finalName}.jar" org.biojava.nbio.structure.align.FarmJob "$@" -else - if [ -f /osg/osg-app/engage/jdk1.6.0_03/bin/java ]; then - /osg/osg-app/engage/jdk1.6.0_03/bin/java -Xmx1G -cp "$PWD/${project.build.finalName}.jar" org.biojava.nbio.structure.align.FarmJob "$@" - else - which java - java -version - java -Xmx1G -cp "$PWD/${project.build.finalName}.jar" org.biojava.nbio.structure.align.FarmJob "$@" - fi -fi - -exit $? - diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/GUIAlignmentProgressListener.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/GUIAlignmentProgressListener.java deleted file mode 100644 index 8bbf28aad2..0000000000 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/GUIAlignmentProgressListener.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.align.gui; - -import org.biojava.nbio.structure.align.FarmJob; -import org.biojava.nbio.structure.align.events.AlignmentProgressListener; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -/** a GUI that allows to watch progress as multiple alignments are being processed. - * - * @author Andreas Prlic - * - */ -public class GUIAlignmentProgressListener extends JPanel implements AlignmentProgressListener, ActionListener { - - - - - /** - * - */ - private static final long serialVersionUID = 1L; - - int alignmentsProcessed; - - JProgressBar progressBar; - private JTextArea taskOutput; - private JButton stopButton; - - FarmJob farmJob; - - public GUIAlignmentProgressListener(){ - - super(new BorderLayout()); - stopButton = new JButton("Stop"); - stopButton.setActionCommand("Stop"); - stopButton.addActionListener(this); - - progressBar = new JProgressBar(0, 100); - progressBar.setValue(0); - progressBar.setStringPainted(true); - - taskOutput = new JTextArea(5, 20); - taskOutput.setMargin(new Insets(5,5,5,5)); - taskOutput.setEditable(false); - - JPanel panel = new JPanel(); - panel.add(stopButton); - panel.add(progressBar); - - add(panel, BorderLayout.PAGE_START); - add(new JScrollPane(taskOutput), BorderLayout.CENTER); - setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); - - } - - - - public FarmJob getFarmJob() { - return farmJob; - } - - - - public void setFarmJob(FarmJob parent) { - this.farmJob = parent; - } - - - - /** - * Invoked when the user presses the stop button. - */ - @Override - public void actionPerformed(ActionEvent evt) { - - //System.out.println("stopping!"); - logStatus("terminating"); - logStatus(" Total alignments processed: " + alignmentsProcessed); - stopButton.setEnabled(false); - setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - progressBar.setIndeterminate(true); - progressBar.setStringPainted(false); - System.out.println("terminating jobs"); - - farmJob.terminate(); - - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - progressBar.setIndeterminate(false); - - } - - - @Override - public void alignmentEnded() { - - alignmentsProcessed++; - - //System.out.println("aligned " + alignmentsProcessed ); - int v = progressBar.getValue(); - - progressBar.setValue(v+1); - progressBar.setString(String.valueOf(v)); - synchronized(this){notifyAll();} - - } - - @Override - public void alignmentStarted(String name1, String name2) { - logStatus("#" + progressBar.getValue() + " starting alignment of " + name1 + " " + name2); - } - - @Override - public void downloadingStructures(String name) { - logStatus("Downloading " + name ); - } - - @Override - public void logStatus(String message) { - taskOutput.append(message+"\n"); - } - - @Override - public void requestingAlignmentsFromServer(int nrAlignments) { - logStatus("Requesting " + nrAlignments + " alignments to be calculated"); - progressBar.setMaximum(nrAlignments); - progressBar.setValue(0); - synchronized(this){notifyAll();} - - } - - @Override - public void sentResultsToServer(int nrAlignments, String serverMessage) { - logStatus("sent alignment results back to server. Server responded: >"+serverMessage+"<"); - progressBar.setValue(0); - synchronized(this){notifyAll();} - } - - -} diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/GUIFarmJobRunnable.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/GUIFarmJobRunnable.java deleted file mode 100644 index 5a0006c29b..0000000000 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/GUIFarmJobRunnable.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.align.gui; - -import org.biojava.nbio.structure.align.FarmJob; -import org.biojava.nbio.structure.align.client.FarmJobParameters; - -import javax.swing.*; -import java.awt.*; - -public class GUIFarmJobRunnable implements Runnable{ - FarmJobParameters params; - GUIAlignmentProgressListener progressListener ; - public GUIFarmJobRunnable(FarmJobParameters params){ - this.params = params; - - - } - - /** - * Create the GUI and show it. As with all GUI code, this must run - * on the event-dispatching thread. - */ - private static void createAndShowGUI(GUIAlignmentProgressListener progressListener) { - //Create and set up the window. - JFrame frame = new JFrame("Monitor alignment process"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - //Create and set up the content pane. - JComponent newContentPane = progressListener; - newContentPane.setOpaque(true); //content panes must be opaque - newContentPane.setSize(new Dimension(400,400)); - frame.setContentPane(newContentPane); - - //Display the window. - frame.pack(); - frame.setVisible(true); - } - - @Override - public void run() { - - progressListener = new GUIAlignmentProgressListener(); - progressListener.logStatus(params.toString()); - - //createAndShowGUI(progressListener); - - FarmJob job = new FarmJob(); - - progressListener.setFarmJob(job); - - job.addAlignmentProgressListener(progressListener); - job.setParams(params); - - Thread t = new Thread(job); - t.start(); - - - javax.swing.SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - createAndShowGUI(progressListener); - } - }); - - } - -} diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartDBSearch.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartDBSearch.java deleted file mode 100644 index 05beef6b5d..0000000000 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartDBSearch.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.align.webstart; - -import org.biojava.nbio.structure.align.FarmJob; -import org.biojava.nbio.structure.align.client.FarmJobParameters; -import org.biojava.nbio.structure.align.gui.GUIFarmJobRunnable; -import org.biojava.nbio.structure.align.util.CliTools; -import org.biojava.nbio.structure.align.util.ConfigurationException; - -import javax.swing.*; -import java.util.Arrays; -import java.util.List; - - - - -/** A Web Start wrapper for a FarmJobRunnable. - * - */ -public class WebStartDBSearch { - - private static final String[] mandParams = new String[] {"pdbFilePath"}; - - private static final List mandatoryArgs= Arrays.asList(mandParams); - - public WebStartDBSearch(){ - } - - - - public static void main(String[] argv) { - - FarmJob job = new FarmJob(); - - - if (argv.length == 0 ) { - job.printHelp(); - JOptionPane.showMessageDialog(null, - "Not enough arguments!"); - return; - - - } - - if ( argv.length == 1){ - if (argv[0].equalsIgnoreCase("-h") || argv[0].equalsIgnoreCase("-help")|| argv[0].equalsIgnoreCase("--help")){ - job.printHelp(); - JOptionPane.showMessageDialog(null, - "Help not supported..."); - return; - } - } - - FarmJobParameters params = new FarmJobParameters(); - - - for (int i = 0 ; i < argv.length; i++){ - String arg = argv[i]; - - String value = null; - if ( i < argv.length -1) - value = argv[i+1]; - - // if value starts with - then the arg does not have a value. - if (value != null && value.startsWith("-")) - value = null; - else - i++; - - - String[] tmp = {arg,value}; - - try { - - CliTools.configureBean(params, tmp); - - } catch (ConfigurationException e){ - - e.printStackTrace(); - - if ( mandatoryArgs.contains(arg) ) { - // there must not be a ConfigurationException with mandatory arguments. - JOptionPane.showMessageDialog(null, - e.getMessage()); - return; - - } else { - // but there can be with optional ... - } - } - } - - params.setRunBackground(true); - GUIFarmJobRunnable runnable = new GUIFarmJobRunnable(params); - - //javax.swing.SwingUtilities.invokeLater(runnable); - runnable.run(); - - - - - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/FarmJob.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/FarmJob.java deleted file mode 100644 index fa749f2127..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/FarmJob.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.align; - -import org.biojava.nbio.structure.align.client.FarmJobParameters; -import org.biojava.nbio.structure.align.client.FarmJobRunnable; -import org.biojava.nbio.structure.align.events.AlignmentProgressListener; -import org.biojava.nbio.structure.align.util.CliTools; -import org.biojava.nbio.structure.align.util.ConfigurationException; -import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.scop.CachedRemoteScopInstallation; -import org.biojava.nbio.structure.scop.ScopDatabase; -import org.biojava.nbio.structure.scop.ScopFactory; -import org.biojava.nbio.core.util.InputStreamProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - - -/** A job as it can be run on the farm. - * - * @author Andreas Prlic - * - * for arguments see the printHelp() method. - * - * - * - */ -public class FarmJob implements Runnable { - - private final static Logger logger = LoggerFactory.getLogger(FarmJob.class); - - private static final String[] mandParams = new String[] {"pdbFilePath"}; - - private static final List mandatoryArgs= Arrays.asList(mandParams); - - List progressListeners; - List jobs; - - FarmJobParameters params ; - - public FarmJob(){ - progressListeners = null; - - // send a flag to the PDb file loader to cache the gzip compressed files. - System.setProperty(InputStreamProvider.CACHE_PROPERTY, "true"); - - - } - - public FarmJobParameters getParams() { - return params; - } - - public void setParams(FarmJobParameters params) { - this.params = params; - } - - public void addAlignmentProgressListener(AlignmentProgressListener listener){ - if (progressListeners == null) - progressListeners = new ArrayList(); - - progressListeners.add(listener); - } - - public void clearListeners(){ - progressListeners.clear(); - progressListeners = null; - } - - public static void main(String[] argv){ - - FarmJob job = new FarmJob(); - - if (argv.length == 0 ) { - job.printHelp(); - return; - } - - if ( argv.length == 1){ - if (argv[0].equalsIgnoreCase("-h") || argv[0].equalsIgnoreCase("-help")|| argv[0].equalsIgnoreCase("--help")){ - job.printHelp(); - return; - } - } - - FarmJobParameters params = new FarmJobParameters(); - - for (int i = 0 ; i < argv.length; i++){ - String arg = argv[i]; - - String value = null; - if ( i < argv.length -1) - value = argv[i+1]; - - // if value starts with - then the arg does not have a value. - if (value != null && value.startsWith("-")) - value = null; - else - i++; - - - String[] tmp = {arg,value}; - - try { - - CliTools.configureBean(params, tmp); - - } catch (ConfigurationException e){ - - logger.error("Exception", e); - - if ( mandatoryArgs.contains(arg) ) { - // there must not be a ConfigurationException with mandatory arguments. - return; - } else { - // but there can be with optional ... - } - } - } - - - if (( params.getNrAlignments() == -1) && (params.getTime() == -1)){ - logger.error("Please provide either the -time or the -nrAlignments argument!"); - return; - } - - - logger.info("Using parameters: {}", params); - - job.setParams(params); - job.run(); - - } - - @Override - public void run(){ - - - // set the system wide PDB path - - String path = params.getPdbFilePath(); - System.setProperty(UserConfiguration.PDB_DIR,path); - - String cachePath = params.getCacheFilePath(); - if ( cachePath != null && ! cachePath.equals("")) - System.setProperty(UserConfiguration.PDB_CACHE_DIR,cachePath); - else { - // if not provided, we use pdbFilePath as the default CACHE path - System.setProperty(UserConfiguration.PDB_CACHE_DIR,path); - } - // declare SCOP to be locally cached, but fetching new stuff from remote - ScopDatabase scop = null; - try { - scop = new CachedRemoteScopInstallation(true); - } catch (IOException e) { - throw new RuntimeException("Could not load " + CachedRemoteScopInstallation.class.getName(), e); - } - ScopFactory.setScopDatabase(scop); - - String username = params.getUsername(); - jobs = new ArrayList(); - for ( int i = 0 ; i < params.getThreads();i++){ - logger.info("starting thread #{}", (i+1)); - FarmJobRunnable runner = new FarmJobRunnable(params); - params.setUsername(username+"_thread_" + (i+1)); - jobs.add(runner); - - if ( progressListeners != null) { - for (AlignmentProgressListener li : progressListeners){ - runner.addAlignmentProgressListener(li); - } - } - - - Thread t = new Thread(runner); - if ( ( (params.getThreads() > 1 ) && ( i < params.getThreads() - 1) )|| ( params.isRunBackground())) { - logger.info("starting thread #{} in background.", (i + 1)); - t.start(); - } else { - // single CPU jobs are run in the main thread and the last job is also run in the main thread - logger.info("starting thread #{} in main thread.", (i + 1)); - t.run(); - } - } - } - - public void terminate(){ - - logger.info("terminating jobs"); - - if ( jobs == null) - return; - - int js = jobs.size(); - logger.info("number of jobs: {}", js); - - - for (FarmJobRunnable runner : jobs){ - // runner.terminate() is already synchronized - runner.terminate(); - } - - clearListeners(); - } - - public void printHelp(){ - System.out.println("-------------------"); - System.out.println("FarmJob help:"); - System.out.println("-------------------"); - - System.out.println("FarmJob accepts the following parameters:"); - System.out.println(""); - System.out.println(" Mandatory:"); - System.out.println(" -pdbFilePath (mandatory) Path to the directory in your file system that contains the PDB files."); - - System.out.println(" provide either -time or -nrAlignments. If both are provided the job stops as soon as any of the criteria has been reached."); - System.out.println(" -time maximum number of time to run (in seconds). -1 means no time limit, but run -nrAlignment arguments. Default: " + FarmJobParameters.DEFAULT_JOB_TIME ); - System.out.println(" -nrAlignments number of alignments to calculate. Default: " + FarmJobParameters.DEFAULT_NR_ALIGNMENTS) ; - System.out.println(""); - System.out.println(" Optional: "); - System.out.println(" -threads number of parallel threads to calculate alignments. Should be nr. of available CPUs. Default: " + FarmJobParameters.DEFAULT_NR_THREADS); - System.out.println(" -server the location of the server URL to talk to. Default : " + FarmJobParameters.DEFAULT_SERVER_URL); - System.out.println(" -username a unique name that can be given to this client. Can be used to give credit for who is doing the calculations. Default: IP and a random id"); - System.out.println(" -stepSize the number of pairs to be requsted from server. Default: " + FarmJobParameters.DEFAULT_BATCH_SIZE); - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/MultiThreadedDBSearch.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/MultiThreadedDBSearch.java deleted file mode 100644 index 636c2ce7a3..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/MultiThreadedDBSearch.java +++ /dev/null @@ -1,473 +0,0 @@ -package org.biojava.nbio.structure.align; - -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Feb 11, 2013 - * Author: Andreas Prlic - * - */ - -import org.biojava.nbio.structure.Atom; -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.align.ce.*; -import org.biojava.nbio.structure.align.client.FarmJobParameters; -import org.biojava.nbio.structure.align.client.JFatCatClient; -import org.biojava.nbio.structure.align.client.PdbPair; -import org.biojava.nbio.structure.align.client.StructureName; -import org.biojava.nbio.structure.align.model.AFPChain; -import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.align.util.SynchronizedOutFile; -import org.biojava.nbio.structure.domain.DomainProvider; -import org.biojava.nbio.structure.domain.DomainProviderFactory; -import org.biojava.nbio.structure.domain.RemoteDomainProvider; -import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; -import org.biojava.nbio.structure.io.PDBFileReader; -import org.biojava.nbio.core.util.ConcurrencyTools; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.util.SortedSet; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.atomic.AtomicBoolean; - - -/** Performs a multi threaded database search for an input protein structure - * - * @author Andreas Prlic - * - */ - -public class MultiThreadedDBSearch { - - private final static Logger logger = LoggerFactory.getLogger(MultiThreadedDBSearch.class); - - AtomicBoolean interrupted ; - - StructureAlignment algorithm; - - String outFile; - - String name1; - - int nrCPUs; - - AtomCache cache; - File resultList; - SortedSet representatives; - - boolean domainSplit; - - Structure structure1; - - String customFile1; - String customChain1; - - public MultiThreadedDBSearch(String name, Structure structure, - String outFile, - StructureAlignment algorithm, - int nrCPUs, boolean domainSplit){ - - interrupted = new AtomicBoolean(false); - this.name1= name; - this.structure1 = structure; - this.outFile = outFile; - this.algorithm = algorithm; - this.nrCPUs = nrCPUs; - this.domainSplit = domainSplit; - cache = new AtomCache(); - - String serverLocation = FarmJobParameters.DEFAULT_SERVER_URL; - if ( representatives == null){ - SortedSet repre = JFatCatClient.getRepresentatives(serverLocation,40); - logger.info("got {} representatives for comparison", repre.size()); - representatives = repre; - } - } - - - public String getCustomFile1() { - return customFile1; - } - - - /** set the file path for a custom, user provided file, not a standard PDB file. - * - * @param customFile1 - */ - public void setCustomFile1(String customFile1) { - this.customFile1 = customFile1; - } - - - - public String getCustomChain1() { - return customChain1; - } - - /** sets a chain in a custom, user provided file - * - * @param customChain1 - */ - public void setCustomChain1(String customChain1) { - this.customChain1 = customChain1; - } - - - public AtomCache getAtomCache() { - return cache; - } - - public void setAtomCache(AtomCache cache) { - this.cache = cache; - } - - - - public StructureAlignment getAlgorithm() { - return algorithm; - } - - public void setAlgorithm(StructureAlignment algo) { - this.algorithm = algo; - } - - - public String getOutFile() { - return outFile; - } - - - public void setOutFile(String outFile) { - this.outFile = outFile; - } - - - public static String getLegend(String algorithmName){ - - if ( algorithmName.equalsIgnoreCase(CeMain.algorithmName) || - algorithmName.equalsIgnoreCase(CeSideChainMain.algorithmName) || - algorithmName.equalsIgnoreCase(CeCPMain.algorithmName)) { - return "# name1\tname2\tscore\tz-score\trmsd\tlen1\tlen2\tcov1\tcov2\t%ID\tDescription\t " ; - } - - // looks like a FATCAT alignment - - return "# name1\tname2\tscore\tprobability\trmsd\tlen1\tlen2\tcov1\tcov2\t%ID\tDescription\t " ; - - } - - - - public File getResultFile() { - return resultList; - } - - - public void setResultFile(File resultList) { - this.resultList = resultList; - } - - - public void run(){ - - File outFileF = null; - SynchronizedOutFile out ; - - try { - checkLocalFiles(); - - if ( interrupted.get()) - return; - - String header = "# algorithm:" + algorithm.getAlgorithmName(); - String legend = getLegend(algorithm.getAlgorithmName()); - - - - outFileF = new File(outFile); - if ( ! outFileF.isDirectory()){ - logger.error("{} is not a directory, can't create result files in there...", outFileF.getAbsolutePath()); - interrupt(); - cleanup(); - } - - if ( name1 == null) - name1 = "CUSTOM"; - - - resultList = new File(outFileF,"results_" + name1 + ".out"); - - logger.info("writing results to {}", resultList.getAbsolutePath()); - - - - out = new SynchronizedOutFile(resultList); - - out.write(header); - out.write(AFPChain.newline); - out.write(legend); - out.write(AFPChain.newline); - - if ( name1.equals("CUSTOM")) { - - String config1 = "#param:file1=" + customFile1; - out.write(config1); - out.write(AFPChain.newline); - - if ( customChain1 != null) { - String config2 = "#param:chain1=" + customChain1; - out.write(config2); - out.write(AFPChain.newline); - } - - } - - if ( algorithm.getAlgorithmName().startsWith("jCE")){ - ConfigStrucAligParams params = algorithm.getParameters(); - if ( params instanceof CeParameters){ - CeParameters ceParams = (CeParameters) params; - if ( ceParams.getScoringStrategy() != CeParameters.ScoringStrategy.DEFAULT_SCORING_STRATEGY) { - String scoring = "#param:scoring=" + ceParams.getScoringStrategy(); - out.write(scoring); - out.write(AFPChain.newline); - } - } - } - - out.flush(); - } catch (IOException e){ - logger.error("Error while loading representative structure {}", name1, e); - interrupt(); - cleanup(); - return; - } catch (StructureException e) { - logger.error("Error while loading representative structure {}", name1, e); - interrupt(); - cleanup(); - return; - } - - - int nrJobs = 0; - DomainProvider domainProvider; - try { - domainProvider = DomainProviderFactory.getDomainProvider(); - - ConcurrencyTools.setThreadPoolSize(nrCPUs); - - Atom[] ca1 = StructureTools.getRepresentativeAtomArray(structure1); - - for (String repre : representatives){ - - if( domainSplit ) { - SortedSet domainNames = domainProvider.getDomainNames(repre); - //logger.debug(repre +" got domains: " +domainNames); - if( domainNames == null || domainNames.size()==0){ - // no domains found, use whole chain. - submit(name1, repre, ca1, algorithm, outFileF, out, cache); - nrJobs++; - continue; - } - //logger.debug("got " + domainNames.size() + " for " + repre); - for( String domain : domainNames){ - submit(name1, domain, ca1, algorithm, outFileF, out, cache); - nrJobs++; - } - } else { - submit(name1, repre, ca1, algorithm, outFileF, out, cache); - nrJobs++; - } - - } - } catch(IOException e) { - logger.error("Error while fetching representative domains", e); - interrupt(); - cleanup(); - return; - } catch (StructureException e) { - logger.error("Error while fetching representative domains", e); - interrupt(); - cleanup(); - return; - } - - - ThreadPoolExecutor pool = ConcurrencyTools.getThreadPool(); - logger.info("{}", pool.getPoolSize()); - - long startTime = System.currentTimeMillis(); - - try { - while ( pool.getCompletedTaskCount() < nrJobs-1 ) { - //long now = System.currentTimeMillis(); - //logger.debug( pool.getCompletedTaskCount() + " " + (now-startTime)/1000 + " " + pool.getPoolSize() + " " + pool.getActiveCount() + " " + pool.getTaskCount() ); - // if ((now-startTime)/1000 > 60) { - // - // interrupt(); - // logger.debug("completed: " + pool.getCompletedTaskCount()); - // } - - if ( interrupted.get()) - break; - - Thread.sleep(2000); - - } - out.close(); - } - catch (Exception e){ - logger.error("Exception: ", e); - interrupt(); - cleanup(); - } - - if (domainProvider instanceof RemoteDomainProvider){ - RemoteDomainProvider remote = (RemoteDomainProvider) domainProvider; - remote.flushCache(); - } - long now = System.currentTimeMillis(); - logger.info("Calculation took : {} sec.", (now-startTime)/1000); - logger.info("{} {} {} {}", pool.getCompletedTaskCount(), pool.getPoolSize(), pool.getActiveCount(), pool.getTaskCount()); - } - - - - private void checkLocalFiles() throws IOException, StructureException { - - logger.info("Checking local PDB installation in directory: {}", cache.getPath()); - - File f = new File(cache.getPath()); - if ( ! f.isDirectory()) { - logger.error("The path {} should point to a directory!", f.getAbsolutePath()); - } - - if ( ! f.canWrite()) { - logger.error("You do not have permission to write to {}. There could be a problem if the PDB installation is not up-to-date with fetching missing PDB files.", f.getAbsolutePath()); - } - - DomainProvider domainProvider = DomainProviderFactory.getDomainProvider(); - - - - for (String repre : representatives){ - - if ( interrupted.get()) - return; - - if( domainSplit ) { - SortedSet domainNames = domainProvider.getDomainNames(repre); - //logger.debug(repre +" got domains: " +domainNames); - if( domainNames == null || domainNames.size()==0){ - // no domains found, use whole chain. - //submit(name1, repre, ca1, algorithm, outFileF, out, cache); - checkFile(repre); - continue; - } - //logger.debug("got " + domainNames.size() + " for " + repre); - for( String domain : domainNames){ - //submit(name1, domain, ca1, algorithm, outFileF, out, cache); - checkFile(domain); - } - } else { - //submit(name1, repre, ca1, algorithm, outFileF, out, cache); - checkFile(repre); - } - - } - - if ( domainProvider instanceof RemoteDomainProvider ) { - RemoteDomainProvider remoteP = (RemoteDomainProvider) domainProvider; - remoteP.flushCache(); - } - - logger.info("done checking local files..."); - - } - - - private void checkFile(String repre) throws IOException, StructureException { - - StructureName name = new StructureName(repre); - - PDBFileReader reader = new PDBFileReader(); - reader.setFetchBehavior(FetchBehavior.FETCH_REMEDIATED); - reader.setPath(cache.getPath()); - reader.setFileParsingParameters(cache.getFileParsingParams()); - reader.prefetchStructure(name.getPdbId()); - } - - - private void submit(String name12, String repre, Atom[] ca1, StructureAlignment algorithm , File outFileF , SynchronizedOutFile out , AtomCache cache ) { - CallableStructureAlignment ali = new CallableStructureAlignment(); - - PdbPair pair = new PdbPair(name1, repre); - try { - ali.setCa1(ca1); - } catch (Exception e){ - logger.error("Exception: ", e); - ConcurrencyTools.shutdown(); - return; - } - ali.setAlgorithmName(algorithm.getAlgorithmName()); - ali.setParameters(algorithm.getParameters()); - ali.setPair(pair); - ali.setOutFile(out); - ali.setOutputDir(outFileF); - ali.setCache(cache); - - ConcurrencyTools.submit(ali); - - } - - - /** stops what is currently happening and does not continue - * - * - */ - public void interrupt() { - interrupted.set(true); - ExecutorService pool = ConcurrencyTools.getThreadPool(); - pool.shutdownNow(); - try { - DomainProvider domainProvider = DomainProviderFactory.getDomainProvider(); - if (domainProvider instanceof RemoteDomainProvider){ - RemoteDomainProvider remote = (RemoteDomainProvider) domainProvider; - remote.flushCache(); - } - } catch (IOException e) { - // If errors occur, the cache should be empty anyways - } - - } - - public void cleanup() - { - - structure1 = null; - - - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java index e7e36cb128..a8fb5c899c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java @@ -29,7 +29,6 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.align.MultiThreadedDBSearch; import org.biojava.nbio.structure.align.StructureAlignment; import org.biojava.nbio.structure.align.model.AFPChain; import org.biojava.nbio.structure.align.util.*; @@ -175,20 +174,6 @@ public void process(String[] argv){ } } - if ( params.getShowDBresult() != null){ - // user wants to view DB search results: - - - System.err.println("showing DB results..."); - try { - GuiWrapper.showDBResults(params); - } catch (Exception e){ - System.err.println(e.getMessage()); - e.printStackTrace(); - } - - } - String pdb1 = params.getPdb1(); String file1 = params.getFile1(); @@ -199,15 +184,7 @@ public void process(String[] argv){ return; } - if ( params.getAlignPairs() != null){ - runDBSearch(); - return; - } - if ( params.getSearchFile() != null){ - runDBSearch(); - return; - } } catch (ConfigurationException e) { System.err.println(e.getLocalizedMessage()); System.exit(1); return; @@ -237,102 +214,6 @@ public static void printAboutMe() { } - - private void runDBSearch() throws ConfigurationException{ - - - String pdbFilePath = params.getPdbFilePath(); - - if ( pdbFilePath == null || pdbFilePath.equals("")){ - - UserConfiguration c = new UserConfiguration(); - pdbFilePath = c.getPdbFilePath(); - System.err.println("You did not specify the -pdbFilePath parameter. Defaulting to "+pdbFilePath+"."); - } - - String cacheFilePath = params.getCacheFilePath(); - - if ( cacheFilePath == null || cacheFilePath.equals("")){ - cacheFilePath = pdbFilePath; - - } - - - AtomCache cache = new AtomCache(pdbFilePath, pdbFilePath); - - String alignPairs = params.getAlignPairs(); - - String searchFile = params.getSearchFile(); - - if ( alignPairs == null || alignPairs.equals("")) { - if ( searchFile == null || searchFile.equals("")){ - throw new ConfigurationException("Please specify -alignPairs or -searchFile !"); - } - } - - String outputFile = params.getOutFile(); - - if ( outputFile == null || outputFile.equals("")){ - throw new ConfigurationException("Please specify the mandatory argument -outFile!"); - } - - System.out.println("running DB search with parameters: " + params); - - if ( alignPairs != null && ! alignPairs.equals("")) { - runAlignPairs(cache, alignPairs, outputFile); - } else { - // must be a searchFile request... - - int useNrCPUs = params.getNrCPU(); - - runDbSearch(cache,searchFile, outputFile, useNrCPUs, params); - } - } - - - /** Do a DB search with the input file against representative PDB domains - * - * @param cache - * @param searchFile - * @param outputFile - * @throws ConfigurationException - */ - private void runDbSearch(AtomCache cache, String searchFile, - String outputFile,int useNrCPUs, StartupParameters params) throws ConfigurationException { - - - System.out.println("will use " + useNrCPUs + " CPUs."); - - PDBFileReader reader = new PDBFileReader(); - Structure structure1 = null ; - try { - structure1 = reader.getStructure(searchFile); - } catch (IOException e) { - throw new ConfigurationException("could not parse as PDB file: " + searchFile); - } - - File searchF = new File(searchFile); - String name1 = "CUSTOM"; - - - - StructureAlignment algorithm = getAlgorithm(); - - MultiThreadedDBSearch dbSearch = new MultiThreadedDBSearch(name1, - structure1, - outputFile, - algorithm, - useNrCPUs, - params.isDomainSplit()); - - dbSearch.setCustomFile1(searchF.getAbsolutePath()); - - dbSearch.run(); - - - } - - private void runAlignPairs(AtomCache cache, String alignPairs, String outputFile) { try { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/GuiWrapper.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/GuiWrapper.java index 687d2e625f..df5736e7de 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/GuiWrapper.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/GuiWrapper.java @@ -24,16 +24,15 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.align.model.AFPChain; -import org.biojava.nbio.structure.align.util.UserConfiguration; import org.biojava.nbio.structure.jama.Matrix; import javax.swing.*; -import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; -/** A class to wrap some of the strucutre.gui classes using Reflection +/** + * A class to wrap some of the strucutre.gui classes using Reflection * * @author Andreas Prlic * @@ -169,36 +168,5 @@ public static Atom[] getAtomArray(Atom[] ca, List hetatoms, List n } - /** - * @since 3.0.5 - */ - public static void showDBResults(StartupParameters params) { - //System.err.println("not implemented full yet"); - - // We want to do this, but because we don't know if structure-gui.jar is in the classpath we use reflection to hide the calls - - UserConfiguration config = UserConfiguration.fromStartupParams(params); - - String tableClass = "org.biojava.nbio.structure.align.gui.DBResultTable"; - - try { - Class c = Class.forName(tableClass); - Object table = c.newInstance(); - - Method show = c.getMethod("show", new Class[]{File.class, UserConfiguration.class }); - - show.invoke(table, new File(params.getShowDBresult()),config); - - } catch (Exception e){ - e.printStackTrace(); - - System.err.println("Probably structure-gui.jar is not in the classpath, can't show results..."); - } - - //DBResultTable table = new DBResultTable(); - - //table.show(new File(params.getShowDBresult()),config); - - } } From 2474aa93389f71cac5e25cbed6ddcd6261c66b55 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 3 Jul 2020 15:31:29 -0700 Subject: [PATCH 130/769] More removal of db code --- .../align/client/FarmJobParameters.java | 21 +- .../align/client/FarmJobRunnable.java | 635 ------------------ 2 files changed, 20 insertions(+), 636 deletions(-) delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobRunnable.java diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobParameters.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobParameters.java index 0415ce0439..def330b27d 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobParameters.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobParameters.java @@ -22,6 +22,10 @@ import org.biojava.nbio.structure.align.util.ResourceManager; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.UUID; + public class FarmJobParameters { @@ -65,13 +69,28 @@ public FarmJobParameters(){ stepSize = DEFAULT_BATCH_SIZE; - username = FarmJobRunnable.getRandomUsername(); + username = getRandomUsername(); if ( nrPairsProp != null){ stepSize = Integer.parseInt(nrPairsProp); } } + private static String getRandomUsername(){ + String name = ""; + try { + InetAddress i = InetAddress.getLocalHost(); + name += i.getHostAddress(); + name += "_"; + } catch (UnknownHostException e){ + throw new RuntimeException(e); + } + name += UUID.randomUUID(); + + return name; + + } + public String getPdbFilePath() { return pdbFilePath; } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobRunnable.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobRunnable.java deleted file mode 100644 index d592cc014d..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobRunnable.java +++ /dev/null @@ -1,635 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.align.client; - -import org.biojava.nbio.structure.Atom; -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.align.StructureAlignment; -import org.biojava.nbio.structure.align.StructureAlignmentFactory; -import org.biojava.nbio.structure.align.ce.CeCPMain; -import org.biojava.nbio.structure.align.ce.CeMain; -import org.biojava.nbio.structure.align.events.AlignmentProgressListener; -import org.biojava.nbio.structure.align.fatcat.FatCatFlexible; -import org.biojava.nbio.structure.align.fatcat.FatCatRigid; -import org.biojava.nbio.structure.align.model.AFPChain; -import org.biojava.nbio.structure.align.util.AFPChainScorer; -import org.biojava.nbio.structure.align.util.AlignmentTools; -import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.align.util.ResourceManager; -import org.biojava.nbio.structure.align.xml.AFPChainXMLConverter; -import org.biojava.nbio.structure.align.xml.PdbPairsMessage; -import org.biojava.nbio.structure.domain.RemotePDPProvider; -import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; -import org.biojava.nbio.structure.scop.RemoteScopInstallation; -import org.biojava.nbio.structure.scop.ScopFactory; -import org.biojava.nbio.core.util.FlatFileCache; -import org.biojava.nbio.core.util.PrettyXMLWriter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.*; - - - - -/** Contains the single thread for a job that can run multiple alignments. - * - * @author Andreas Prlic - * - */ -public class FarmJobRunnable implements Runnable { - - private static final Logger logger = LoggerFactory.getLogger(FarmJobRunnable.class); - - - //private static final int DEFAULT_PAIR_FETCH_DELAY = 30000; - //private static final String CONNECTION_PAIR_DELAY = "connection.pair.delay"; - private static final String JFATCAT_NAME = "jfatcat.name"; - private static final String JFATCAT_VERSION = "jfatcat.version"; - - private static ResourceManager resourceManager = ResourceManager.getResourceManager("jfatcat"); - - - //private static DateFormat dateFormat = new SimpleDateFormat("MMMM dd, yyyy h:mm a",Locale.US); - - FarmJobParameters params; - - String prevName1; - Atom[] ca1 ; - - - long startTime; - long maxTime; - int maxNrAlignments; - int alignmentsCalculated; - - boolean waitForAlignments; - - private static final String randomUsername = getRandomUsername(); - - boolean terminated ; - - List progressListeners; - CountProgressListener counter ; - - String userName = null; - protected AtomCache cache; - - boolean verbose = false; // TODO dmyersturnbull: we should probably remove this in favor of SLF4J - String version = null; - - private static final String alignURL = "/align/"; - public FarmJobRunnable(FarmJobParameters params){ - terminated = false; - this.params = params; - verbose = false; - - // multiple farm jobs share the same SoftHashMap for caching coordinates - cache = new AtomCache( params.getPdbFilePath(), params.getCacheFilePath()); - - - if ( params.getServer()!= null && (!params.getServer().equals("") ) ) { - - RemotePDPProvider pdpprovider = new RemotePDPProvider(); - - String serverURL = params.getServer(); - if ( ! serverURL.endsWith("/")) - serverURL += "/"; - - if ( serverURL.endsWith(alignURL)) { - serverURL = serverURL.substring(0,serverURL.length()-alignURL.length()); - } - - pdpprovider.setServer(serverURL+"/domains/"); - - cache.setPdpprovider(pdpprovider); - - RemoteScopInstallation scop = new RemoteScopInstallation(); - - scop.setServer(serverURL+"/domains/"); - ScopFactory.setScopDatabase(scop); - - } - - cache.setFetchBehavior(FetchBehavior.FETCH_FILES); - - maxNrAlignments = params.getNrAlignments(); - progressListeners = null; - if (params.getUsername() == null) { - userName = randomUsername; - } else { - userName = params.getUsername(); - } - counter = new CountProgressListener(); - addAlignmentProgressListener(counter); - waitForAlignments = true; - - if ( params.isVerbose()){ - verbose = true; - } - } - - public void addAlignmentProgressListener(AlignmentProgressListener listener){ - - if (progressListeners == null) - progressListeners = new ArrayList(); - - progressListeners.add(listener); - } - - public void clearListeners(){ - if ( progressListeners == null) - return; - progressListeners.clear(); - progressListeners = null; - } - - protected static String getRandomUsername(){ - String name = ""; - try { - InetAddress i = InetAddress.getLocalHost(); - name += i.getHostAddress(); - name += "_"; - } catch (UnknownHostException e){ - throw new RuntimeException(e); - } - name += UUID.randomUUID(); - - return name; - - } - - @Override - public void run() { - - // Retrieve resource - String appVersion = resourceManager.getString(JFATCAT_VERSION); - String appName = resourceManager.getString(JFATCAT_NAME); - logger.info("{} version: {}", appName, appVersion); - - - startTime = System.currentTimeMillis(); - // -t ime is in seconds. - long maxSec = params.getTime(); - - if ( maxSec < 5 ) - maxTime = Long.MAX_VALUE; - else - maxTime = startTime + params.getTime() * 1000; - - terminated = false; - - alignmentsCalculated = 0; - - maxNrAlignments = params.getNrAlignments(); - - if ( maxNrAlignments < 0 ){ - maxNrAlignments = Integer.MAX_VALUE; - } - - logger.info("running job for max {} alignments", maxNrAlignments); - - - while (! terminated){ - - // talk to server - // get list of alignments to run - // if maxNrAlignments > 100 we split up the calculations in chunks of 100. - // otherwise we request all of them at once. - // we request - PdbPairsMessage msg = getAlignmentPairsFromServer(); - if ( msg == null) { - logger.error("Got null instead of alignment pairs from server."); - randomSleep(); - continue; - } - SortedSet alignmentPairs = msg.getPairs(); - logger.debug("{}: Server responded with {} pairs.", userName, alignmentPairs.size()); - List results = new ArrayList(); - - String algorithmName = msg.getMethod(); - if ( version == null) { - setVersion(algorithmName); - - } - for(PdbPair pair : alignmentPairs){ - - if ( terminated) - break; - - long now = System.currentTimeMillis(); - if ( now >= maxTime) { - terminated = true; - break; - } - - if ( alignmentsCalculated >= maxNrAlignments) { - terminated = true; - break; - } - - - String name1 = pair.getName1(); - String name2 = pair.getName2(); - - if ( progressListeners != null) - notifyStartAlignment(name1,name2); - - - try { - String resultXML = alignPair(name1, name2,algorithmName); - - if ( progressListeners != null) - notifyEndAlignment(); - - results.add(resultXML); - - } catch (Exception e){ - logger.error("Problem aligning {} with {}", name1, name2, e); - - StringWriter sw = new StringWriter(); - - PrettyXMLWriter xml = new PrettyXMLWriter(new PrintWriter(sw)); - try { - xml.openTag("AFPChain"); - - xml.attribute("name1", name1); - xml.attribute("name2", name2); - xml.attribute("error", e.getMessage()); - xml.closeTag("AFPChain"); - } catch(IOException ex){ - logger.error("Error occured converting alignment for {} and {} to XML", name1, name2, ex); - } - - if ( progressListeners != null) - notifyEndAlignment(); - - results.add(sw.toString()); - - - } - - alignmentsCalculated++; - - } - - // send results back to server - sendResultsToServer(results); - - long end = System.currentTimeMillis(); - if ( end >= maxTime) { - logger.info("OK end of job: reached maxTime {}", maxTime); - terminated = true; - - } - - if ( alignmentsCalculated >= maxNrAlignments) { - logger.info("OK end of job: reached maxNrAlignments", maxNrAlignments); - terminated = true; - - } - - long tdiff = (end - startTime); - if ( tdiff != 0) { - - logger.info(userName + String.format(": job has run for : %.2f", (tdiff) / 1000.0 / 60) + " min."); - logger.info("{}: total nr of alignments calculated: {}", userName, alignmentsCalculated); - if ( alignmentsCalculated > 0) - logger.info(userName + String.format(": average time / alignment: %.2f", (tdiff / alignmentsCalculated / 1000.0)) + " sec."); - } - } - - logger.info(userName + ": jFATCAT job result: " + counter); - - // clean up in the end... - clearListeners(); - - cache.notifyShutdown(); - - } - - - private void setVersion(String algorithmName) { - StructureAlignment algorithm; - try { - algorithm = StructureAlignmentFactory.getAlgorithm(algorithmName); - version = algorithm.getVersion(); - } catch (StructureException e) { - throw new RuntimeException("Couldn't set version for algorithm \"" + algorithmName + "\"", e); -// version = resourceManager.getString(JFATCAT_VERSION); // dmyersturnbull: was this - } - - - } - - private void notifyStartAlignment(String name1, String name2) { - if ( progressListeners != null){ - for (AlignmentProgressListener li : progressListeners){ - li.alignmentStarted(name1, name2); - } - } - } - - private void notifyEndAlignment(){ - if ( progressListeners != null){ - for (AlignmentProgressListener li : progressListeners){ - li.alignmentEnded(); - - } - } - } - - private void notifyRequestingAlignments(int nrAlignments){ - if ( progressListeners != null){ - for (AlignmentProgressListener li : progressListeners){ - li.requestingAlignmentsFromServer(nrAlignments); - - } - } - } - - private void notifySubmittingAlignments(int nrAlignments, String message){ - if ( progressListeners != null){ - for (AlignmentProgressListener li : progressListeners){ - li.sentResultsToServer(nrAlignments,message); - - } - } - } - - - public String alignPair(String name1, String name2) - throws StructureException, IOException { - return alignPair(name1, name2, FatCatRigid.algorithmName); - } - - public String alignPair(String name1, String name2, String algorithmName) - throws StructureException, IOException { - - // make sure each thread has an independent instance of the algorithm object ... - - StructureAlignment algorithm = getAlgorithm(algorithmName); - - // we are running with default parameters - - if ( verbose ) { - logger.debug("aligning {} against {}", name1, name2); - } - - long startTime = System.currentTimeMillis(); - - if ( prevName1 == null) - initMaster(name1); - - if ( ! prevName1.equals(name1) ) { - // we need to reload the master - initMaster(name1); - } - - // get a copy of the atoms, but clone them, since they will be rotated... - Atom[] ca2 = cache.getAtoms(name2); - - AFPChain afpChain = algorithm.align(ca1, ca2); - - afpChain.setName1(name1); - afpChain.setName2(name2); - - try { - // add tmScore - double tmScore = AFPChainScorer.getTMScore(afpChain, ca1, ca2); - afpChain.setTMScore(tmScore); - } catch (RuntimeException e){ - logger.error("ca1 size: {} ca2 length: {} {} {}", ca1.length, ca2.length, afpChain.getName1(), afpChain.getName2(), e); - - } - long endTime = System.currentTimeMillis(); - - long calcTime = (endTime-startTime); - if ( verbose ){ - boolean isCP = !AlignmentTools.isSequentialAlignment(afpChain, false); - String msg = "finished alignment: " + name1 + " vs. " + name2 + " in " + (calcTime) / 1000.0 + " sec."; - msg += " algo: " + algorithmName + " v:" + version + " " + afpChain; - - if ( isCP ) msg += "HAS A CIRCULAR PERMUTATION!!!"; - logger.debug(msg); - } - if (verbose){ - printMemory(); - } - afpChain.setCalculationTime(calcTime); - - return AFPChainXMLConverter.toXML(afpChain, ca1, ca2); - } - - - - - private void printMemory() { - int size = 1048576; - long heapSize = Runtime.getRuntime().totalMemory() / size; - - // Get maximum size of heap in bytes. The heap cannot grow beyond this size. - // Any attempt will result in an OutOfMemoryException. - long heapMaxSize = Runtime.getRuntime().maxMemory() / size; - - // Get amount of free memory within the heap in bytes. This size will increase - // after garbage collection and decrease as new objects are created. - long heapFreeSize = Runtime.getRuntime().freeMemory() / size; - StringBuilder msg = new StringBuilder(); - msg.append(" total: ").append(heapSize).append(" M"); - msg.append(" max: "). append(heapMaxSize).append(" M"); - msg.append(" free: ").append(heapFreeSize).append(" M"); - - logger.debug(msg.toString()); - - } - - private StructureAlignment getAlgorithm(String algorithmName) throws StructureException { - - - StructureAlignment algorithm = null; - - if ( algorithmName == null){ - - algorithm = new FatCatRigid(); - - } else if ( algorithmName.equalsIgnoreCase(FatCatRigid.algorithmName)){ - - algorithm = new FatCatRigid(); - - } else if ( algorithmName.equalsIgnoreCase(CeMain.algorithmName)){ - - algorithm = new CeMain(); - - } else if ( algorithmName.equalsIgnoreCase(CeCPMain.algorithmName)){ - - algorithm = new CeCPMain(); - - } else if ( algorithmName.equalsIgnoreCase(FatCatFlexible.algorithmName)){ - - algorithm = new FatCatFlexible(); - - } else { - - algorithm = StructureAlignmentFactory.getAlgorithm(algorithmName); - - } - - if ( algorithm == null) { - - algorithm = new FatCatRigid(); - - } - - - return algorithm; - } - - private void initMaster(String name1) throws IOException, StructureException{ - - ca1 = cache.getAtoms(name1); - - prevName1 = name1; - - } - - - /** talk to centralized server and fetch all alignments to run. - * - * @return a list of pairs to align. - */ - protected PdbPairsMessage getAlignmentPairsFromServer() { - - - String url = params.getServer(); - - int nrPairs = params.getStepSize(); - - if ( maxNrAlignments < nrPairs ) - nrPairs = maxNrAlignments; - - SortedSet allPairs = new TreeSet(); - - PdbPairsMessage msg = null; - - - try { - - if ( progressListeners != null) - notifyRequestingAlignments(nrPairs); - - - - if ( ! waitForAlignments) { - msg = JFatCatClient.getPdbPairs(url, nrPairs, userName); - allPairs = msg.getPairs(); - - } else { - - while (allPairs.isEmpty()) { - msg = JFatCatClient.getPdbPairs(url, nrPairs, userName); - allPairs = msg.getPairs(); - - if (allPairs.isEmpty()) { - randomSleep(); - } - } - } - } catch ( JobKillException k ){ - - logger.debug("Terminating job", k); - terminate(); - - } catch (Exception e) { - logger.error("Error while requesting alignment pairs", e); - // an error has occured sleep 30 sec. - - randomSleep(); - - - } - - return msg; - } - - private void randomSleep() { - try { - - int delay = JFatCatClient.getRandomSleepTime(); - logger.debug("sleeping {} sec.", delay/1000); - Thread.sleep(delay); - } catch (InterruptedException ex){ - logger.trace("InterruptedException occurred while sleeping", ex); - } - - } - - protected void sendResultsToServer(List results) { - - String serverLocation = params.getServer(); - - if ( results.size() < 1) - return; - - String fullXml = ""; - - for (String xml: results){ - fullXml +=xml; - } - fullXml += ""; - String msg = ""; - try { - msg = JFatCatClient.sendMultiAFPChainToServer(serverLocation,fullXml, userName, version ); - } catch (JobKillException e){ - logger.info("{} Got Job Kill message from server, terminating...", userName, e); - terminate(); - } - - if ( progressListeners != null) - notifySubmittingAlignments(results.size(), msg); - logger.info("{}: Sent {} results to server. job status: {}", userName, results.size(), counter); - logger.info("{}: fileCache size: {}", userName, FlatFileCache.size()); - } - - - /** Send signal to terminate calculations - * - */ - public synchronized void terminate(){ - terminated = true; - } - - public boolean isWaitForAlignments() { - return waitForAlignments; - } - - public void setWaitForAlignments(boolean waitForAlignments) { - this.waitForAlignments = waitForAlignments; - } - - - -} From 31d29b5f42b275e72ab50843bb3cb70c7936c55d Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 3 Jul 2020 19:05:55 -0700 Subject: [PATCH 131/769] Some more removals --- .../align/webstart/WebStartMain.java | 11 +- .../align/client/CountProgressListener.java | 83 ------- .../align/client/FarmJobParameters.java | 209 ------------------ .../nbio/structure/align/client/PdbPair.java | 9 +- .../structure/align/client/StructureName.java | 2 +- .../structure/align/util/ResourceManager.java | 4 +- 6 files changed, 18 insertions(+), 300 deletions(-) delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/CountProgressListener.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobParameters.java diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartMain.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartMain.java index 27c0ceb322..a41dff849b 100644 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartMain.java +++ b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartMain.java @@ -25,7 +25,6 @@ import org.biojava.nbio.structure.align.StructureAlignmentFactory; import org.biojava.nbio.structure.align.ce.CeCPMain; import org.biojava.nbio.structure.align.ce.CeMain; -import org.biojava.nbio.structure.align.client.FarmJobParameters; import org.biojava.nbio.structure.align.client.JFatCatClient; import org.biojava.nbio.structure.align.client.PdbPair; import org.biojava.nbio.structure.align.fatcat.FatCatFlexible; @@ -38,6 +37,7 @@ import org.biojava.nbio.structure.align.model.AFPChain; import org.biojava.nbio.structure.align.seq.SmithWaterman3Daligner; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.align.util.ResourceManager; import org.biojava.nbio.structure.align.util.UserConfiguration; import javax.swing.*; @@ -47,6 +47,13 @@ public class WebStartMain { + private static final ResourceManager resourceManager; + private static final String DEFAULT_SERVER_URL; + static { + resourceManager = ResourceManager.getResourceManager("jfatcat"); + DEFAULT_SERVER_URL = resourceManager.getString("server.url"); + } + static UserConfiguration userConfig; /** @@ -113,7 +120,7 @@ public void run() { return; } - String serverLocation = FarmJobParameters.DEFAULT_SERVER_URL; + String serverLocation = DEFAULT_SERVER_URL; if ( args.length > 3 ) { // we have 4 arguments. diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/CountProgressListener.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/CountProgressListener.java deleted file mode 100644 index 0490594964..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/CountProgressListener.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Sep 15, 2009 - * Author: Andreas Prlic - * - */ - -package org.biojava.nbio.structure.align.client; - -import org.biojava.nbio.structure.align.events.AlignmentProgressListener; - -public class CountProgressListener implements AlignmentProgressListener { - - int nrCalculated ; - int nrSubmitted; - - public CountProgressListener(){ - nrCalculated = 0; - nrSubmitted = 0; - } - - @Override - public void alignmentEnded() { - nrCalculated++; - - } - - @Override - public void alignmentStarted(String name1, String name2) { - // TODO Auto-generated method stub - - } - - @Override - public void downloadingStructures(String name) { - // TODO Auto-generated method stub - - } - - @Override - public void logStatus(String message) { - // TODO Auto-generated method stub - - } - - @Override - public void requestingAlignmentsFromServer(int nrAlignments) { - // TODO Auto-generated method stub - - } - - @Override - public void sentResultsToServer(int nrAlignments, String serverMessage) { - nrSubmitted+=nrAlignments; - } - - - @Override - public String toString() { - return "[nrCalculated=" + nrCalculated - + ", nrSubmitted=" + nrSubmitted + "]"; - } - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobParameters.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobParameters.java deleted file mode 100644 index def330b27d..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/FarmJobParameters.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.align.client; - -import org.biojava.nbio.structure.align.util.ResourceManager; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.UUID; - -public class FarmJobParameters { - - - public static final int DEFAULT_JOB_TIME = -1; - public static final int DEFAULT_NR_ALIGNMENTS = -1; - public static final int DEFAULT_NR_THREADS = 1; - public static final String DEFAULT_SERVER_URL; - private static ResourceManager resourceManager; - static { - resourceManager = ResourceManager.getResourceManager("jfatcat"); - DEFAULT_SERVER_URL = resourceManager.getString("server.url"); - } - public static final String DEFAULT_PDB_PATH = "/tmp/"; - public static final int DEFAULT_BATCH_SIZE = 100; - - private static final String DEFAULT_BATCH_SIZE_PROP = "request.pair.size"; - - int nrAlignments; - int time; - int threads; - String server; - String pdbFilePath; - String username; - boolean runBackground; - boolean verbose; - boolean updateRemediatedFiles; - int stepSize; - String cacheFilePath; - - - public FarmJobParameters(){ - nrAlignments = DEFAULT_NR_ALIGNMENTS; - time = DEFAULT_JOB_TIME; - threads = DEFAULT_NR_THREADS; - server = DEFAULT_SERVER_URL; - pdbFilePath = DEFAULT_PDB_PATH; - runBackground = false; - cacheFilePath = DEFAULT_PDB_PATH; - updateRemediatedFiles = false; - String nrPairsProp = resourceManager.getString(DEFAULT_BATCH_SIZE_PROP); - - stepSize = DEFAULT_BATCH_SIZE; - - username = getRandomUsername(); - if ( nrPairsProp != null){ - stepSize = Integer.parseInt(nrPairsProp); - } - - } - - private static String getRandomUsername(){ - String name = ""; - try { - InetAddress i = InetAddress.getLocalHost(); - name += i.getHostAddress(); - name += "_"; - } catch (UnknownHostException e){ - throw new RuntimeException(e); - } - name += UUID.randomUUID(); - - return name; - - } - - public String getPdbFilePath() { - return pdbFilePath; - } - - public void setPdbFilePath(String pdbFilePath) { - this.pdbFilePath = pdbFilePath; - } - public String getCacheFilePath() { - return cacheFilePath; - } - - public void setCacheFilePath(String cacheFilePath) { - this.cacheFilePath = cacheFilePath; - } - - public int getNrAlignments() { - return nrAlignments; - } - - - public void setNrAlignments(int nrAlignments) { - this.nrAlignments = nrAlignments; - } - - - public int getTime() { - return time; - } - - public void setTime(int time) { - this.time = time; - } - - public int getThreads() { - return threads; - } - - public void setThreads(int threads) { - this.threads = threads; - } - - public String getServer() { - return server; - } - - public void setServer(String server) { - this.server = server; - } - - public String getUsername() { - return username; - } - public void setUsername(String username) { - this.username = username; - } - - /** Flag if a job that only runs one parallell job should be run in its own thread or in the main thread. - * For User interface related apps should be set to true. Default: false; - * @return flag - */ - public boolean isRunBackground() { - return runBackground; - } - public void setRunBackground(boolean runBackground) { - this.runBackground = runBackground; - } - - - /** how many pairs should be requested for alignment from server? - * - * @return stepsize - */ - public int getStepSize() { - return stepSize; - } - - public void setStepSize(int stepSize) { - this.stepSize = stepSize; - } - - - /** Flag if the job should be run in verbose mode. Default: false - * - * @return flag if the job should be run in verbose mode - */ - public boolean isVerbose() { - return verbose; - } - - public void setVerbose(boolean verbose) { - this.verbose = verbose; - } - - public boolean isUpdateRemediatedFiles() { - return updateRemediatedFiles; - } - - public void setUpdateRemediatedFiles(boolean updateRemediatedFiles) { - this.updateRemediatedFiles = updateRemediatedFiles; - } - - @Override - public String toString() { - return "FarmJobParameters [nrAlignments=" + nrAlignments + ", time=" - + time + ", threads=" + threads + ", server=" + server - + ", pdbFilePath=" + pdbFilePath - + ", username=" + username + ", runBackground=" - + runBackground + ", verbose=" + verbose - + ", updateRemediatedFiles=" + updateRemediatedFiles - + ", stepSize=" + stepSize + ", cacheFilePath=" + cacheFilePath - + "]"; - } - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/PdbPair.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/PdbPair.java index 29e7ab9e36..a752a2c51d 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/PdbPair.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/PdbPair.java @@ -22,7 +22,8 @@ import org.biojava.nbio.structure.StructureException; -/** A pair for structure alignment +/** + * A pair for structure alignment * * @author Andreas Prlic * @@ -31,11 +32,13 @@ */ public class PdbPair implements Comparable { - StructureName name1; - StructureName name2; + private StructureName name1; + private StructureName name2; + public PdbPair(String name1, String name2) { this(new StructureName(name1),new StructureName(name2)); } + public PdbPair(StructureName name1, StructureName name2) { super(); this.name1 = name1; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java index 4c682e624f..c81513edde 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java @@ -67,7 +67,7 @@ * information may be loaded from one of the factory classes: * {@link CathFactory},{@link ScopFactory}, etc. * - * @see #getName the name. e.g. 4hhb, 4hhb.A, d4hhba_, PDP:4HHBAa etc. + * @see #getIdentifier() the name. e.g. 4hhb, 4hhb.A, d4hhba_, PDP:4HHBAa etc. */ public class StructureName implements Comparable, Serializable, StructureIdentifier { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/ResourceManager.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/ResourceManager.java index c61478b1a1..9463f81483 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/ResourceManager.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/ResourceManager.java @@ -27,14 +27,14 @@ -/** A class that manages the Strings that are defined in the spice.properties file. +/** + * A class that manages the Strings that are defined in the spice.properties file. * This will be usefull for internationalisation. * * TODO: provide .properties files for other locales. * e.g. jfatcat_de_DE.properties, etc. * * @author Andreas Prlic - * @since 1:43:04 PM * @version %I% %G% */ public class ResourceManager { From 87a59b0f99d70e3f1d7e7a38933b74d5162574e5 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 3 Jul 2020 19:12:32 -0700 Subject: [PATCH 132/769] Removing jfatcatclient from WebStartMain --- .../align/webstart/WebStartMain.java | 39 ++----------------- .../structure/align/client/JFatCatClient.java | 5 ++- 2 files changed, 7 insertions(+), 37 deletions(-) diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartMain.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartMain.java index a41dff849b..e589f56140 100644 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartMain.java +++ b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/webstart/WebStartMain.java @@ -25,7 +25,6 @@ import org.biojava.nbio.structure.align.StructureAlignmentFactory; import org.biojava.nbio.structure.align.ce.CeCPMain; import org.biojava.nbio.structure.align.ce.CeMain; -import org.biojava.nbio.structure.align.client.JFatCatClient; import org.biojava.nbio.structure.align.client.PdbPair; import org.biojava.nbio.structure.align.fatcat.FatCatFlexible; import org.biojava.nbio.structure.align.fatcat.FatCatRigid; @@ -37,7 +36,6 @@ import org.biojava.nbio.structure.align.model.AFPChain; import org.biojava.nbio.structure.align.seq.SmithWaterman3Daligner; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.align.util.ResourceManager; import org.biojava.nbio.structure.align.util.UserConfiguration; import javax.swing.*; @@ -47,14 +45,7 @@ public class WebStartMain { - private static final ResourceManager resourceManager; - private static final String DEFAULT_SERVER_URL; - static { - resourceManager = ResourceManager.getResourceManager("jfatcat"); - DEFAULT_SERVER_URL = resourceManager.getString("server.url"); - } - - static UserConfiguration userConfig; + private static UserConfiguration userConfig; /** * If no arguments, shows AlignmentGui for pairwise alignments. @@ -120,14 +111,6 @@ public void run() { return; } - String serverLocation = DEFAULT_SERVER_URL; - - if ( args.length > 3 ) { - // we have 4 arguments. - // in this case the 4th has to be the server URL - serverLocation = args[3]; - } - try { String name1 = args[1]; @@ -175,7 +158,7 @@ else if ( arg0.equalsIgnoreCase("fatcat_flexible")) else algorithm = new SmithWaterman3Daligner(); - showStructureAlignment(serverLocation,algorithm ,ca1,ca2,pair.getName1(),pair.getName2()); + showStructureAlignment(algorithm ,ca1,ca2,pair.getName1(),pair.getName2()); } catch (Exception e){ e.printStackTrace(); @@ -304,36 +287,22 @@ public static UserConfiguration requestUserConfig(){ - private static void showStructureAlignment(String serverLocation, StructureAlignment algorithm, Atom[] ca1, Atom[] ca2, String name1, String name2) throws StructureException{ + private static void showStructureAlignment(StructureAlignment algorithm, Atom[] ca1, Atom[] ca2, String name1, String name2) throws StructureException{ JFrame tmpFrame = new JFrame(); tmpFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); String title = "Calculating " + algorithm.getAlgorithmName() + " V." + algorithm.getVersion()+" alignment... "; - showProgressBar(tmpFrame,title, "Calculating the structure alignment."); - //do the actual alignment - AFPChain afpChain = null; - - try { - // using 10 sec as timeout on server now, since we expect the server to be able to complete the calculation within that time... - afpChain = JFatCatClient.getAFPChainFromServer(serverLocation,algorithm.getAlgorithmName(), name1, name2, ca1, ca2, 10000); - } catch (Exception e){ - e.printStackTrace(); - } - - if ( afpChain == null ) { - afpChain = algorithm.align(ca1, ca2); - } + AFPChain afpChain = algorithm.align(ca1, ca2); afpChain.setName1(name1); afpChain.setName2(name2); tmpFrame.dispose(); - // show results StructureAlignmentJmol jmol = StructureAlignmentDisplay.display(afpChain,ca1,ca2); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java index 76cea2c39f..c6bbc744d7 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java @@ -42,9 +42,10 @@ import java.util.TreeSet; public class JFatCatClient { - private final static Logger logger = LoggerFactory.getLogger(JFatCatClient.class); + + private static final Logger logger = LoggerFactory.getLogger(JFatCatClient.class); - private static ResourceManager resourceManager = ResourceManager.getResourceManager("jfatcat"); + private static final ResourceManager resourceManager = ResourceManager.getResourceManager("jfatcat"); private static final String serverAPPEND = "show?name1=%s&name2=%s"; From cc1206375234636955a6fe2e25b4a00577c138dc Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 3 Jul 2020 22:19:56 -0700 Subject: [PATCH 133/769] Removing JFatCatClient and dependencies --- CHANGELOG.md | 7 + .../structure/align/client/JFatCatClient.java | 388 ------------------ .../align/client/JobKillException.java | 37 -- .../structure/align/client/StructureName.java | 30 +- .../nbio/structure/align/util/AtomCache.java | 20 - .../domain/DomainProviderFactory.java | 52 --- .../nbio/structure/domain/PDPDomain.java | 82 ---- .../nbio/structure/domain/PDPProvider.java | 69 ---- .../domain/RemoteDomainProvider.java | 234 ----------- .../structure/domain/RemotePDPProvider.java | 261 ------------ .../structure/rcsb/GetRepresentatives.java | 7 +- .../nbio/structure/rcsb/ReadUtils.java | 23 ++ .../scop/CachedRemoteScopInstallation.java | 4 +- .../scop/RemoteScopInstallation.java | 26 +- .../align/client/TestStructureName.java | 10 - 15 files changed, 51 insertions(+), 1199 deletions(-) delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JobKillException.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/domain/DomainProviderFactory.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDPDomain.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDPProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/domain/RemoteDomainProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/domain/RemotePDPProvider.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 195ca04996..bd6841d369 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ BioJava Changelog ----------------- +BioJava 6.0.0 (future release) +============================== +### Removed +* All code related to All-vs-All structural alignments db calculation and access +* JFatCatClient and all code depending on it +* PDP domain providers (depended on JFatCatClient) + BioJava 5.4.0 ============= ### Added diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java deleted file mode 100644 index c6bbc744d7..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JFatCatClient.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.align.client; - -import org.biojava.nbio.structure.Atom; -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.align.fatcat.FatCatRigid; -import org.biojava.nbio.structure.align.model.AFPChain; -import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.align.util.URLConnectionTools; -import org.biojava.nbio.structure.align.util.ResourceManager; -import org.biojava.nbio.structure.align.xml.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLEncoder; -import java.util.Random; -import java.util.SortedSet; -import java.util.TreeSet; - -public class JFatCatClient { - - private static final Logger logger = LoggerFactory.getLogger(JFatCatClient.class); - - private static final ResourceManager resourceManager = ResourceManager.getResourceManager("jfatcat"); - - private static final String serverAPPEND = "show?name1=%s&name2=%s"; - - private static final String sendAPPEND = "submit?name1=%s&name2=%s&version=%s"; - - private static final String multiSendAPPEND = "jobSubmit?username=%s&version=%s"; - - private static final String representAPPEND = "representatives?cluster=%s"; - - private static final String serverHasResult = "hasResult?method=%s&name1=%s&name2=%s"; - - private static final int DEFAULT_TIMEOUT = 5000; - - private static final String serverPositionInQueue = "queuePosition?method=%s&name1=%s&name2=%s"; - - private static Random generator; - - private static String newline = System.getProperty("line.separator"); - - private static String KILL_JOB = "KILL_JOB"; - - private static String COME_BACK_LATER = "COME_BACK_LATER"; - - static { - - generator = new Random(); - - } - - public static boolean hasPrecalculatedResult(String serverLocation, String method, String name1, String name2 ){ - return hasPrecalculatedResult(serverLocation, method, name1, name2, DEFAULT_TIMEOUT ); - } - - public static boolean hasPrecalculatedResult(String serverLocation, String method, String name1, String name2, int timeout){ - - String serverURL = serverLocation + serverHasResult; - - - boolean hasResults = false; - try { - String u = String.format(serverURL,URLEncoder.encode(method,"UTF-8"),name1,name2) ; - URL url = new URL(u); - //System.out.println("has result ? ..." + url); - - InputStream stream = URLConnectionTools.getInputStream(url,timeout); - - String xml = null; - - if ( stream != null) { - - xml = convertStreamToString(stream); - logger.info(" has PrecalcResults got XML from server: " + xml); - HasResultXMLConverter conv = new HasResultXMLConverter(); - hasResults = conv.fromXML(xml); - } - - } catch (IOException e){ - // log error and return false - logger.error("error in JFatCatClient: getAFPChainFromServer",e); - } - return hasResults; - } - - - public int getPositionInQueue(String serverLocation, String method, String name1, String name2){ - return getPositionInQueue(serverLocation, method, name1, name2, DEFAULT_TIMEOUT); - } - - public int getPositionInQueue(String serverLocation, String method, String name1, String name2, int timeout){ - String serverURL = serverLocation + serverPositionInQueue; - - - int position = Integer.MIN_VALUE; - try { - String u = String.format(serverURL,URLEncoder.encode(method,"UTF-8"),name1,name2) ; - URL url = new URL(u); - - InputStream stream = URLConnectionTools.getInputStream(url,timeout); - - String xml = null; - - if ( stream != null) { - - xml = convertStreamToString(stream); - //System.out.println("got XML from server: " + xml); - PositionInQueueXMLConverter conv = new PositionInQueueXMLConverter(); - position = conv.fromXML(xml); - } - - } catch (IOException e){ - logger.error("error in JFatCatClient: getAFPChainFromServer",e); // TODO dmyersturnbull: method should throw; we shouldn't catch here - } - return position; - - } - public static AFPChain getAFPChainFromServer(String serverLocation , String name1, String name2, Atom[] ca1, Atom[] ca2) { - String method = FatCatRigid.algorithmName; - return getAFPChainFromServer(serverLocation, method, name1, name2, ca1, ca2,DEFAULT_TIMEOUT); - } - - public static AFPChain getAFPChainFromServer(String serverLocation , String method, String name1, String name2, Atom[] ca1, Atom[] ca2, int timeout) - { - - String serverURL = serverLocation + serverAPPEND; - - try { - String u = String.format(serverURL,name1,name2) ; - - if ( method != null) - u+= "&method=" + URLEncoder.encode(method,"UTF-8"); - - URL url = new URL(u); - logger.info("requesting alignment from server..." + url); - // have a short timeout for this... - // 5 sec - InputStream stream = URLConnectionTools.getInputStream(url,timeout); - - String xml = null; - - if ( stream != null) { - - xml = convertStreamToString(stream); - } - if (xml != null) { - - return AFPChainXMLParser.fromXML (xml, name1, name2, ca1, ca2); - - } else { - return null; - } - // TODO dmyersturnbull: method should throw; we shouldn't catch here - } catch (IOException e){ - logger.error("error in JFatCatClient: getAFPChainFromServer",e); - } catch (StructureException e) { - logger.error("error in JFatCatClient: getAFPChainFromServer",e); - } - return null; - } - - - public static String convertStreamToString(InputStream stream){ - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - StringBuilder sb = new StringBuilder(); - - String line = null; - try { - while ((line = reader.readLine()) != null) { - sb.append(line).append(newline); - } - } catch (IOException e) { - logger.error("Couldn't convert stream to string", e); // TODO dmyersturnbull: method should throw; we shouldn't catch here - } finally { - try { - stream.close(); - } catch (IOException e) { - logger.warn("Can't close stream", e); - } - } - - return sb.toString(); - } - - public static String sendMultiAFPChainToServer(String serverLocation, String multiXML, String username) throws JobKillException{ - String version = resourceManager.getString("jfatcat.version"); - return sendMultiAFPChainToServer(serverLocation, multiXML, username, version); - } - - public static String sendMultiAFPChainToServer(String serverLocation, String multiXML, String username, String version) throws JobKillException{ - String multiSendURL = serverLocation + multiSendAPPEND; - - String responseS = ""; - - String u = String.format(multiSendURL,username,version); - - int timeout = getTimeout(); - - boolean submitted = false; - - while (! submitted ){ - try { - URL url = new URL(u); - InputStream response = URLConnectionTools.doPOST(url, multiXML,timeout); - responseS = convertStreamToString(response); - submitted = true; - if (! responseS.contains("OK")) - logger.error("server returned " + responseS); - - // server is busy... wait a bit and try again - if ( responseS.startsWith(COME_BACK_LATER)){ - submitted = false; - } - - } catch (Exception e){ - logger.error("Error in JFatCatClient: while sending results back to server",e); - - try { - int randomSleep = getRandomSleepTime(); - logger.warn("sleeping " + (randomSleep/1000) + " sec."); - Thread.sleep(randomSleep); - } catch (InterruptedException ex){ - logger.warn("Interrupted while sleeping", ex); - } - } - } - - if ( responseS.startsWith(KILL_JOB)){ - throw new JobKillException("Server responded with KILL message."); - - } - - - return responseS; - } - - public static int getRandomSleepTime() { - - // now wait between 7 and 13 min. - - int minTime = 560000; - - int maxTime = 7800000 - minTime; - - int nextId = generator.nextInt(maxTime); - return minTime + nextId; - - } - - - public static final void sendAFPChainToServer(String serverLocation, AFPChain afpChain,Atom[] ca1, Atom[] ca2) throws JobKillException - { - - String sendURL = serverLocation + sendAPPEND; - - String version = resourceManager.getString("jfatcat.version"); - - int timeout = getTimeout(); - - try { - - // just to make sure that similarity has been calculated! - afpChain.getSimilarity(); - - String xml = AFPChainXMLConverter.toXML(afpChain, ca1, ca2); - - String u = String.format(sendURL,afpChain.getName1() , afpChain.getName2(),version); - - URL url = new URL(u); - - InputStream response = URLConnectionTools.doPOST(url, xml,timeout); - - logger.debug("got response: {}", convertStreamToString(response)); - - if ( xml.startsWith("KILL_JOB")){ - throw new JobKillException("Server responded with KILL message."); - } - - } catch (IOException e){ - logger.error("error in JFatCatClient: sendAFPChainToServer",e); - } - - } - - public static final int getTimeout(){ - String timeoutS = resourceManager.getString("connection.timeout"); - int timeout = 60000; - - try { - timeout = Integer.parseInt(timeoutS); - } catch (NumberFormatException ex ){ - logger.error("Bad connection.timeout parameter",ex); - } - return timeout; - } - - - public static final PdbPairsMessage getPdbPairs(String url,int nrPair, String username) throws IOException, JobKillException { - - - String urlS= url + "getPairs?" + "nrPairs=" + nrPair + "&username=" + URLEncoder.encode(username, "UTF-8"); - int timeout = getTimeout(); - - PdbPairsMessage msg = null; - logger.info("requesting {}", urlS); - URL serverUrl = new URL(urlS); - // we are very tolerant with requesting a set of pairs, since we probably depend on getting it to get work started... - // 1 min... - InputStream stream = URLConnectionTools.getInputStream(serverUrl,timeout); - String xml = null; - - if ( stream != null) { - - xml = convertStreamToString(stream); - if (xml != null) { - if ( xml.startsWith("KILL_JOB")){ - // we got the KILL signal from the server... - throw new JobKillException("Server responded with KILL message."); - } - msg = PdbPairXMLConverter.convertXMLtoPairs(xml); - - } - } - - return msg; - } - - - public static final SortedSet getRepresentatives(String serverLocation, int cutoff){ - SortedSet representatives = new TreeSet(); - - String representURL = serverLocation + representAPPEND; - - if ( cutoff < 20) - cutoff = 40; - int timeout = getTimeout(); - String u = String.format(representURL,cutoff); - - logger.info("Fetching representatives from "+u); - try { - URL url = new URL(u); - - InputStream stream = URLConnectionTools.getInputStream(url,timeout); - - String xml = null; - - if ( stream != null) { - - xml = convertStreamToString(stream); - } - if (xml != null) { - representatives = RepresentativeXMLConverter.fromXML(xml); - } - } catch (IOException e){ // TODO dmyersturnbull: method should throw; we shouldn't catch here - logger.error("Error fetching representatives",e); - } - return representatives; - } - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JobKillException.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JobKillException.java deleted file mode 100644 index 012a7b0838..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/JobKillException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Sep 16, 2009 - * Author: Andreas Prlic - * - */ - -package org.biojava.nbio.structure.align.client; - -public class JobKillException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public JobKillException(String message){ - super(message); - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java index c81513edde..65598ad18f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java @@ -44,9 +44,6 @@ import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.cath.CathDomain; import org.biojava.nbio.structure.cath.CathFactory; -import org.biojava.nbio.structure.domain.PDPDomain; -import org.biojava.nbio.structure.domain.PDPProvider; -import org.biojava.nbio.structure.domain.RemotePDPProvider; import org.biojava.nbio.structure.ecod.EcodFactory; import org.biojava.nbio.core.util.FileDownloadUtils; import org.biojava.nbio.structure.scop.ScopDatabase; @@ -88,7 +85,6 @@ public class StructureName implements Comparable, Serializable, S public enum Source { PDB, SCOP, - PDP, CATH, URL, FILE, @@ -171,10 +167,6 @@ private void init(){ if( ! initFromScop(suffix) ) throw new IllegalArgumentException("Malformed SCOP domain name:"+suffix); return; - case PDP: - if( ! initFromPDP(name) ) - throw new IllegalArgumentException("Malformed PDP domain name:"+suffix); - return; case CATH: if( ! initFromCATH(suffix) ) throw new IllegalArgumentException("Malformed CATH domain name:"+suffix); @@ -266,15 +258,7 @@ private boolean initFromScop(String name) { } return false; } - private boolean initFromPDP(String name) { - Matcher matcher = PDPDomain.PDP_NAME_PATTERN.matcher(name); - if( matcher.matches() ) { - pdbId = matcher.group(1).toUpperCase(); - chainName = matcher.group(2); - return true; - } - return false; - } + private boolean initFromCATH(String name) { Matcher matcher = cathPattern.matcher(name); if ( matcher.matches() ){ @@ -399,10 +383,6 @@ public boolean isScopName() { return mySource == Source.SCOP; } - public boolean isPDPDomain(){ - return mySource == Source.PDP; - } - public boolean isCathID(){ return mySource == Source.CATH; } @@ -502,14 +482,6 @@ public StructureIdentifier getBaseIdentifier() throws StructureException { throw new StructureException("Invalid URL: "+name,e); } break; - case PDP: - try { - PDPProvider provider = new RemotePDPProvider(false); - base = provider.getPDPDomain(name); - } catch (IOException e) { - throw new StructureException("Unable to fetch PDP domain "+name, e); - } - break; case BIO: base = new BioAssemblyIdentifier(name); break; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java index 4b7ba3f0fc..53b4352696 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java @@ -33,8 +33,6 @@ import org.biojava.nbio.structure.cath.CathDatabase; import org.biojava.nbio.structure.cath.CathDomain; import org.biojava.nbio.structure.cath.CathFactory; -import org.biojava.nbio.structure.domain.PDPProvider; -import org.biojava.nbio.structure.domain.RemotePDPProvider; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; @@ -77,14 +75,11 @@ public class AtomCache { public static final String CHAIN_NR_SYMBOL = ":"; public static final String CHAIN_SPLIT_SYMBOL = "."; - public static final String PDP_DOMAIN_IDENTIFIER = "PDP:"; - public static final String UNDERSCORE = "_"; private static final String FILE_SEPARATOR = System.getProperty("file.separator"); protected FileParsingParameters params; - protected PDPProvider pdpprovider; private FetchBehavior fetchBehavior; private ObsoleteBehavior obsoleteBehavior; @@ -439,10 +434,6 @@ public String getPath() { return path; } - public PDPProvider getPdpprovider() { - return pdpprovider; - } - /** * Request a Structure based on a name. * @@ -667,13 +658,6 @@ public Structure getStructureForDomain(String scopId, ScopDatabase scopDatabase) * flush themselves... */ public void notifyShutdown() { - // System.out.println(" AtomCache got notify shutdown.."); - if (pdpprovider != null) { - if (pdpprovider instanceof RemotePDPProvider) { - RemotePDPProvider remotePDP = (RemotePDPProvider) pdpprovider; - remotePDP.flushCache(); - } - } // todo: use a SCOP implementation that is backed by SerializableCache ScopDatabase scopInstallation = ScopFactory.getSCOP(); @@ -764,10 +748,6 @@ public void setPath(String path) { this.path = FileDownloadUtils.expandUserHome(path); } - public void setPdpprovider(PDPProvider pdpprovider) { - this.pdpprovider = pdpprovider; - } - /** * @return the useMmCif */ diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/DomainProviderFactory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/DomainProviderFactory.java deleted file mode 100644 index 51735bc5bc..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/DomainProviderFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.domain; - -import java.io.IOException; - - -/** A simple factory object that returns the system wide default DomainProvider - * - * @author andreas - * - */ -public class DomainProviderFactory { - - private DomainProviderFactory(){ - - } - - static DomainProvider domainProvider ; - - - - public static void setDomainProvider(DomainProvider provider){ - domainProvider = provider; - - } - - public static DomainProvider getDomainProvider() throws IOException{ - if ( domainProvider == null) - domainProvider = new RemoteDomainProvider(true); - - return domainProvider; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDPDomain.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDPDomain.java deleted file mode 100644 index fe3f6b6beb..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDPDomain.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.domain; - -import java.io.IOException; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.biojava.nbio.structure.ResidueRange; -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureIdentifier; -import org.biojava.nbio.structure.SubstructureIdentifier; -import org.biojava.nbio.structure.align.util.AtomCache; - -public class PDPDomain implements StructureIdentifier { - private static final long serialVersionUID = 6894463080739943026L; - - private String identifier; - private SubstructureIdentifier canonical; - - public static final Pattern PDP_NAME_PATTERN = Pattern.compile("^(?:PDP:)([0-9][a-z0-9]{3})(\\w)(\\w)$",Pattern.CASE_INSENSITIVE); - - public PDPDomain(String pdpDomainName, List ranges) { - this.identifier = pdpDomainName; - Matcher matcher = PDP_NAME_PATTERN.matcher(identifier); - if(!matcher.matches()) { - throw new IllegalArgumentException("Malformed PDP domain name"); - } - String pdbId = matcher.group(1); - this.canonical = new SubstructureIdentifier(pdbId,ranges); - } - - @Override - public String getIdentifier() { - return identifier; - } - - public String getPdbId() { - return canonical.getPdbId(); - } - - @Override - public SubstructureIdentifier toCanonical() { - return canonical; - } - - @Override - public Structure reduce(Structure input) throws StructureException { - return canonical.reduce(input); - } - - @Override - public String toString() { - return getIdentifier(); - } - - @Override - public Structure loadStructure(AtomCache cache) throws StructureException, - IOException { - return canonical.loadStructure(cache); - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDPProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDPProvider.java deleted file mode 100644 index d621373bb1..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDPProvider.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on May 1, 2012 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.domain; - -import java.io.IOException; -import java.util.SortedSet; - -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.align.util.AtomCache; - -/** - * Decomposes a structure into representative PDP domains. - * - * Implementations will probably want to also implement {@link DomainProvider}, - * which provides a very similar set of methods for general structure domain - * decomposition. - * @author Andreas Prlic - * @since 3.0.2 - */ -public interface PDPProvider { - - /** - * Get a list of all PDP domains for a given PDB entry - * @param pdbId PDB ID - * @return Set of domain names, e.g. "PDP:4HHBAa" - * @throws IOException - */ - public SortedSet getPDPDomainNamesForPDB(String pdbId) throws IOException; - /** - * Get the structure for a particular PDP domain - * @param pdpDomainName PDP identifier, e.g. "PDP:4HHBAa" - * @param cache AtomCache, responsible for fetching and storing the coordinates - * @return Structure representing the PDP domain - * @throws IOException For IO errors, e.g. when parsing PDP information - * @throws StructureException For errors creating the structure - */ - public Structure getDomain(String pdpDomainName, AtomCache cache) throws IOException, StructureException; - /** - * Get a StructureIdentifier representing the specified PDP domain. - * - * @param pdpDomainName PDP domain name - * @return a PDPDomain representing this domain name - * @throws IOException - */ - public PDPDomain getPDPDomain(String pdpDomainName) throws IOException; -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/RemoteDomainProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/RemoteDomainProvider.java deleted file mode 100644 index 5d5aaaefd6..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/RemoteDomainProvider.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.domain; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.align.client.JFatCatClient; -import org.biojava.nbio.structure.align.client.StructureName; -import org.biojava.nbio.structure.align.util.URLConnectionTools; -import org.biojava.nbio.structure.scop.ScopDatabase; -import org.biojava.nbio.structure.scop.ScopDomain; -import org.biojava.nbio.structure.scop.ScopFactory; -import org.biojava.nbio.structure.scop.server.XMLUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * A DomainProvider that uses a mixture of SCOP and PDP domains. - * - * SCOP domains are preferred, with PDP providing a backup for structures where - * SCOP has not been assigned. - * - * As of 2015, this class is equivalent to the method used by RCSB to define - * representatives for structural similarity comparisons. - */ -public class RemoteDomainProvider extends SerializableCache> implements DomainProvider{ - private static final Logger logger = LoggerFactory.getLogger(RemoteDomainProvider.class); - - public String url = RemotePDPProvider.DEFAULT_SERVER; - - ScopDatabase scop; - PDPProvider pdp; - - private static String CACHE_FILE_NAME = "remotedomaincache.ser"; - - - public RemoteDomainProvider(){ - // equivalent to this(false) but without IOException - super(CACHE_FILE_NAME); - disableCache(); - scop = ScopFactory.getSCOP(); - pdp = new RemotePDPProvider(); - } - - /** initialize this provider with caching enabled - * - * @param cache - * @throws IOException - */ - public RemoteDomainProvider(boolean cache) throws IOException{ - super(CACHE_FILE_NAME); - - if( ! cache) { - disableCache(); - //} else if ( serializedCache.keySet().size() < 20000){ - } else { - // always load the representative assignments from server... - // this makes sure we always have the latest assignments - loadRepresentativeDomainAssignments(); - } - - scop = ScopFactory.getSCOP(); - pdp = new RemotePDPProvider(cache); - } - - /** Requests the domain assignments for the current PDB IDs from the PDB. - * @throws IOException if the server cannot be reached - * - */ - private void loadRepresentativeDomainAssignments() throws IOException { - AssignmentXMLSerializer results = null; - try { - URL u = new URL(url + "getRepresentativeDomains"); - logger.info("Fetching {}",u); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); - results = AssignmentXMLSerializer.fromXML(xml); - - Map data = results.getAssignments(); - logger.info("got {} ranges from server.",data.size()); - for (String key: data.keySet()){ - String range = data.get(key); - - // work around list in results; - - String[] spl = range.split(","); - SortedSet value = new TreeSet(); - - for (String s : spl){ - value.add(s); - - } - serializedCache.put(key, value); - } - - } catch (MalformedURLException e){ - logger.error("Malformed Domain server: "+url,e); - throw new IllegalArgumentException("Invalid Server: "+url, e); - } - } - - @Override - public SortedSet getDomainNames(String name) throws IOException, StructureException { - - - if ( name.length() < 4) - throw new IllegalArgumentException("Can't interpret IDs that are shorter than 4 residues!"); - - if ( serializedCache != null){ - if ( serializedCache.containsKey(name)){ - return serializedCache.get(name); - } - } - - StructureName n = new StructureName(name); - - ListscopDomains = scop.getDomainsForPDB(n.getPdbId()); - - String chainID = n.getChainId(); - - if ( scopDomains == null || scopDomains.size() == 0){ - SortedSet data= getPDPDomains(n); - cache(name,data); - return data; - } else { - SortedSet r = new TreeSet(); - for ( ScopDomain d: scopDomains){ - StructureName s = new StructureName(d.getScopId()); - - if( chainID == null){ - r.add(s.getIdentifier()); - - } else if( s.getChainId().equalsIgnoreCase(n.getChainId())) { - // SCOP IDS are case insensitive... - r.add(s.getIdentifier()); - } - } - cache(name,r); - return r; - } - - - - } - - - - - private SortedSet getPDPDomains(StructureName n) throws IOException, StructureException { - SortedSet pdpDomains = pdp.getPDPDomainNamesForPDB(n.getPdbId()); - - SortedSet r = new TreeSet(); - String chainID = n.getChainId(); - for ( String s : pdpDomains){ - StructureName d = new StructureName(s); - if ( chainID == null) - r.add(s); - else if ( d.getChainId().equals(n.getChainId())){ - r.add(s); - } - } - logger.info(n + " got PDP domains: "+ r); - return r; - } - - public static void main(String[] args) throws IOException, StructureException{ - String name ="3KIH.A"; - RemoteDomainProvider me = new RemoteDomainProvider(true); - System.out.println(me.getDomainNames(name)); - StructureName n = new StructureName(name); - System.out.println(n); - //System.out.println(new AtomCache().getStructure(name)); - me.flushCache(); - } - - @Override - public void flushCache() { - super.flushCache(); - if ( pdp instanceof RemotePDPProvider){ - RemotePDPProvider remotePDP = (RemotePDPProvider)pdp; - remotePDP.flushCache(); - } - } - - @Override - public SortedSet getRepresentativeDomains() throws IOException { - - String url = "http://source.rcsb.org/jfatcatserver/domains/getRepresentativeDomainNames"; - SortedSet domainRanges = null; - try { - URL u = new URL(url); - logger.info("Fetching {}",url); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); - //System.out.println(xml); - domainRanges = XMLUtil.getDomainRangesFromXML(xml); - } catch (MalformedURLException e){ - logger.error("Malformed Domain server: "+url,e); - throw new IllegalArgumentException("Invalid Server: "+url, e); - } - return domainRanges; - } - - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/RemotePDPProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/RemotePDPProvider.java deleted file mode 100644 index d45a0285bd..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/RemotePDPProvider.java +++ /dev/null @@ -1,261 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Aug 31, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.domain; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.biojava.nbio.structure.ResidueRange; -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.SubstructureIdentifier; -import org.biojava.nbio.structure.align.client.JFatCatClient; -import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.align.util.URLConnectionTools; -import org.biojava.nbio.structure.scop.server.XMLUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** A class that provided PDP assignments that are loaded from a remote web server - * - * @author Andreas Prlic - * - */ -public class RemotePDPProvider extends SerializableCache> implements PDPProvider{ - - private static final Logger logger = LoggerFactory.getLogger(RemotePDPProvider.class); - - public static final String DEFAULT_SERVER = "http://source.rcsb.org/jfatcatserver/domains/"; - - String server = DEFAULT_SERVER; - - private static String CACHE_FILE_NAME = "remotepdpdomaindefs.ser"; - - - public static void main(String[] args) throws IOException, StructureException{ - RemotePDPProvider me = new RemotePDPProvider(true); - - //System.out.println(scop.getByCategory(ScopCategory.Superfamily)); - SortedSet pdpdomains = me.getPDPDomainNamesForPDB("4HHB"); - System.out.println(pdpdomains); - - AtomCache cache = new AtomCache(); - Structure s = me.getDomain(pdpdomains.first(), cache); - System.out.println(s); - - me.flushCache(); - - } - - - public RemotePDPProvider(){ - // equivalent to this(false) but without IOException - super(CACHE_FILE_NAME); - disableCache(); - } - - - /** - * - * @param useCache - * @throws IOException - */ - public RemotePDPProvider(boolean useCache) throws IOException { - - super(CACHE_FILE_NAME); - - if ( ! useCache) { - disableCache(); - //else if ( serializedCache.keySet().size() < 10000){ - } else { - // make sure we always have the latest assignments... - loadRepresentativeDomains(); - } - - } - - - - /** get the ranges of representative domains from the centralized server - * @throws IOException if the server cannot be reached - */ - private void loadRepresentativeDomains() throws IOException { - - AssignmentXMLSerializer results = null; - try { - URL u = new URL(server + "getRepresentativePDPDomains"); - logger.info("Fetching {}",u); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); - results = AssignmentXMLSerializer.fromXML(xml); - - Map data = results.getAssignments(); - logger.info("got {} domain ranges for PDP domains from server.",data.size()); - for (String key: data.keySet()){ - String range = data.get(key); - - // work around list in results; - - String[] spl = range.split(","); - SortedSet value = new TreeSet(); - - for (String s : spl){ - value.add(s); - - } - serializedCache.put(key, value); - } - - } catch (MalformedURLException e){ - logger.error("Malformed PDP server: "+server,e); - throw new IllegalArgumentException("Invalid Server: "+server, e); - } - } - - - public String getServer() { - return server; - } - - public void setServer(String server) { - this.server = server; - } - - /** - * Get the structure for a particular PDP domain - * @param pdpDomainName PDP identifier, e.g. "PDP:4HHBAa" - * @param cache AtomCache, responsible for fetching and storing the coordinates - * @return Structure representing the PDP domain - * @throws IOException if the server cannot be reached - * @throws StructureException For errors parsing the structure - */ - @Override - public Structure getDomain(String pdpDomainName, AtomCache cache) throws IOException, StructureException { - return cache.getStructure(getPDPDomain(pdpDomainName)); - } - - /** - * Get a StructureIdentifier representing the specified PDP domain. - * - * @param pdpDomainName PDP domain name - * @return a PDPDomain representing this domain name - * @throws IOException if the server cannot be reached - */ - @Override - public PDPDomain getPDPDomain(String pdpDomainName) throws IOException{ - SortedSet domainRanges = null; - if ( serializedCache != null){ - if ( serializedCache.containsKey(pdpDomainName)){ - domainRanges= serializedCache.get(pdpDomainName); - - } - } - - - boolean shouldRequestDomainRanges = checkDomainRanges(domainRanges); - - try { - if (shouldRequestDomainRanges){ - URL u = new URL(server + "getPDPDomain?pdpId="+pdpDomainName); - logger.info("Fetching {}",u); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); - domainRanges = XMLUtil.getDomainRangesFromXML(xml); - if ( domainRanges != null) - cache(pdpDomainName,domainRanges); - } - } catch (MalformedURLException e){ - logger.error("Problem generating PDP request URL for "+pdpDomainName,e); - throw new IllegalArgumentException("Invalid PDP name: "+pdpDomainName, e); - } - - String pdbId = null; - List ranges = new ArrayList(); - for(String domainRange : domainRanges) { - SubstructureIdentifier strucId = new SubstructureIdentifier(domainRange); - if(pdbId == null) { - pdbId = strucId.getPdbId(); - } else if(!pdbId.equals(strucId.getPdbId())) { - // should never happen with correct server implementation - throw new RuntimeException("Don't know how to take the union of domains from multiple PDB IDs."); - } - - ranges.addAll(strucId.getResidueRanges()); - } - return new PDPDomain(pdpDomainName,ranges); - } - - /** returns true if client should fetch domain definitions from server - * - * @param domainRanges - * @return - */ - private boolean checkDomainRanges(SortedSet domainRanges) { - - if ( (domainRanges == null) || (domainRanges.size() == 0)){ - return true; - } - - for ( String d : domainRanges){ - //System.out.println("domainRange: >" + d +"< " + d.length()); - if ( (d != null) && (d.length() >0)){ - return false; - } - } - - return true; - } - - /** - * Get a list of all PDP domains for a given PDB entry - * @param pdbId PDB ID - * @return Set of domain names, e.g. "PDP:4HHBAa" - * @throws IOException if the server cannot be reached - */ - @Override - public SortedSet getPDPDomainNamesForPDB(String pdbId) throws IOException{ - SortedSet results = null; - try { - URL u = new URL(server + "getPDPDomainNamesForPDB?pdbId="+pdbId); - logger.info("Fetching {}",u); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); - results = XMLUtil.getDomainRangesFromXML(xml); - - } catch (MalformedURLException e){ - logger.error("Problem generating PDP request URL for "+pdbId,e); - throw new IllegalArgumentException("Invalid PDB name: "+pdbId, e); - } - return results; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/GetRepresentatives.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/GetRepresentatives.java index c3bbf1b907..6d37ab4b24 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/GetRepresentatives.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/GetRepresentatives.java @@ -20,10 +20,11 @@ */ package org.biojava.nbio.structure.rcsb; -import org.biojava.nbio.structure.align.client.JFatCatClient; import org.biojava.nbio.structure.align.client.StructureName; import org.biojava.nbio.structure.align.util.URLConnectionTools; import org.biojava.nbio.structure.align.xml.RepresentativeXMLConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.BufferedReader; import java.io.InputStream; @@ -39,6 +40,8 @@ */ public class GetRepresentatives { + private static final Logger logger = LoggerFactory.getLogger(GetRepresentatives.class); + private static String clusterUrl = "http://www.rcsb.org/pdb/rest/representatives?cluster="; private static String allUrl = "http://www.rcsb.org/pdb/rest/getCurrent/"; @@ -72,7 +75,7 @@ public static SortedSet getRepresentatives(int sequenceIdentity) String xml = null; if (stream != null) { - xml = JFatCatClient.convertStreamToString(stream); + xml = ReadUtils.convertStreamToString(stream); SortedSet reps = RepresentativeXMLConverter.fromXML(xml); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/ReadUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/ReadUtils.java index 27efb2e36d..ece82b16e3 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/ReadUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/ReadUtils.java @@ -34,8 +34,10 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; /** * Package-level static utilities for parsing XML. @@ -109,4 +111,25 @@ static Integer toInt(String s) { return null; } + public static String convertStreamToString(InputStream stream){ + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + StringBuilder sb = new StringBuilder(); + + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb.append(line).append("\n"); + } + } catch (IOException e) { + logger.error("Couldn't convert stream to string", e); // TODO dmyersturnbull: method should throw; we shouldn't catch here + } finally { + try { + stream.close(); + } catch (IOException e) { + logger.warn("Can't close stream", e); + } + } + + return sb.toString(); + } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/CachedRemoteScopInstallation.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/CachedRemoteScopInstallation.java index 5f7ca94589..b78dc5e4f4 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/CachedRemoteScopInstallation.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/CachedRemoteScopInstallation.java @@ -24,9 +24,9 @@ */ package org.biojava.nbio.structure.scop; -import org.biojava.nbio.structure.align.client.JFatCatClient; import org.biojava.nbio.structure.align.util.URLConnectionTools; import org.biojava.nbio.structure.domain.SerializableCache; +import org.biojava.nbio.structure.rcsb.ReadUtils; import org.biojava.nbio.structure.scop.server.ScopDomains; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -93,7 +93,7 @@ private void loadRepresentativeDomains() throws IOException { } logger.info("Using " + u + " to download representative domains"); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); ScopDomains results = ScopDomains.fromXML(xml); logger.info("got " + results.getScopDomain().size() + " domain ranges for Scop domains from server."); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/RemoteScopInstallation.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/RemoteScopInstallation.java index a1534f0071..96cda0e3e3 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/RemoteScopInstallation.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/RemoteScopInstallation.java @@ -24,8 +24,8 @@ */ package org.biojava.nbio.structure.scop; -import org.biojava.nbio.structure.align.client.JFatCatClient; import org.biojava.nbio.structure.align.util.URLConnectionTools; +import org.biojava.nbio.structure.rcsb.ReadUtils; import org.biojava.nbio.structure.scop.server.ScopDescriptions; import org.biojava.nbio.structure.scop.server.ScopDomains; import org.biojava.nbio.structure.scop.server.ScopNodes; @@ -75,7 +75,7 @@ public List getByCategory(ScopCategory category) { try { URL u = new URL(server + "getByCategory?category="+category+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if(! xml.trim().isEmpty()) { ScopDescriptions container = ScopDescriptions.fromXML(xml); @@ -93,7 +93,7 @@ public List filterByClassificationId(String query) { try { URL u = new URL(server + "filterByClassificationId?query="+query+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if(! xml.trim().isEmpty()) { ScopDescriptions container = ScopDescriptions.fromXML(xml); @@ -111,7 +111,7 @@ public List getTree(ScopDomain domain) { try { URL u = new URL(server + "getTree?scopId="+domain.getScopId()+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if(! xml.trim().isEmpty()) { ScopNodes container = ScopNodes.fromXML(xml); @@ -131,7 +131,7 @@ public List filterByDomainName(String query) { URL u = new URL(server + "filterByDomainName?query="+query+"&version="+getScopVersion()); //System.out.println(u); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if(! xml.trim().isEmpty()) { ScopDomains container = ScopDomains.fromXML(xml); @@ -149,7 +149,7 @@ public List filterByDescription(String query) { try { URL u = new URL(server + "filterByDescription?query="+query+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if(! xml.trim().isEmpty()) { ScopDescriptions container = ScopDescriptions.fromXML(xml); @@ -171,7 +171,7 @@ public ScopDescription getScopDescriptionBySunid(int sunid) { URL u = new URL(server + "getScopDescriptionBySunid?sunid="+sunid+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if(! xml.trim().isEmpty()) { desc = XMLUtil.getScopDescriptionFromXML(xml); @@ -189,7 +189,7 @@ public List getDomainsForPDB(String pdbId) { try { URL u = new URL(server + "getDomainsForPDB?pdbId="+pdbId+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if( !xml.trim().isEmpty()) { ScopDomains container = ScopDomains.fromXML(xml); @@ -206,7 +206,7 @@ private ScopDomain requestRemoteDomainByScopID(String scopId) scopId = scopId.trim(); URL u = new URL(server + "getDomainByScopID?scopId="+scopId+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if( !xml.trim().isEmpty()) { return XMLUtil.getScopDomainFromXML(xml); @@ -229,7 +229,7 @@ public ScopNode getScopNode(int sunid) { try { URL u = new URL(server + "getScopNode?sunid="+sunid+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if( !xml.trim().isEmpty()) { desc = XMLUtil.getScopNodeFromXML(xml); @@ -247,7 +247,7 @@ public String getScopVersion() { try { URL u = new URL(server + "getScopVersion"); InputStream response = URLConnectionTools.getInputStream(u); - version = JFatCatClient.convertStreamToString(response); + version = ReadUtils.convertStreamToString(response); if( version != null) version = version.trim(); @@ -269,7 +269,7 @@ public List getScopDomainsBySunid(Integer sunid) { try { URL u = new URL(server + "getScopDomainsBySunid?sunid="+sunid+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if( !xml.trim().isEmpty()) { ScopDomains container = ScopDomains.fromXML(xml); @@ -288,7 +288,7 @@ public List getComments(int sunid) { try { URL u = new URL(server + "getComments?sunid="+sunid+"&version="+getScopVersion()); InputStream response = URLConnectionTools.getInputStream(u); - String xml = JFatCatClient.convertStreamToString(response); + String xml = ReadUtils.convertStreamToString(response); if( !xml.trim().isEmpty()) { results = XMLUtil.getCommentsFromXML(xml); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/client/TestStructureName.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/client/TestStructureName.java index 3b197d733f..d68090047d 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/client/TestStructureName.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/client/TestStructureName.java @@ -135,11 +135,6 @@ public void testPrefixes() throws StructureException { assertTrue(sn.isCathID()); assertTrue(sn.getSource() == CATH); assertEquals("1QVR",sn.getPdbId()); - // PDP - sn = new StructureName("PDP:4HHBAa"); - assertTrue(sn.isPDPDomain()); - assertTrue(sn.getSource() == PDP); - assertEquals("4HHB",sn.getPdbId()); // URL sn = new StructureName("URL:http://www.rcsb.org/pdb/files/1B8G.pdb.gz"); assertTrue(sn.isURL()); @@ -215,11 +210,6 @@ public void testGuesses() throws StructureException { assertTrue(sn.isCathID()); assertTrue(sn.getSource() == CATH); assertEquals("1QVR",sn.getPdbId()); - // PDP is not guessed - sn = new StructureName("4HHBAa"); - assertFalse(sn.isPDPDomain()); - assertTrue(sn.getSource() == PDB); - assertEquals("4HHBAa",sn.getPdbId()); // URL sn = new StructureName("http://www.rcsb.org/pdb/files/1B8G.pdb.gz"); assertTrue(sn.isURL()); From 2d0387123b9b29854f42fd3609b9dd01066c93f7 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 3 Jul 2020 23:21:51 -0700 Subject: [PATCH 134/769] Fixing test, fixing docs, bumping SNAPSHOT --- CHANGELOG.md | 1 + biojava-aa-prop/pom.xml | 6 +++--- biojava-alignment/pom.xml | 4 ++-- biojava-core/pom.xml | 2 +- biojava-genome/pom.xml | 6 +++--- biojava-integrationtest/pom.xml | 4 ++-- biojava-modfinder/pom.xml | 4 ++-- biojava-ontology/pom.xml | 2 +- biojava-protein-disorder/pom.xml | 4 ++-- biojava-structure-gui/pom.xml | 6 +++--- biojava-structure/pom.xml | 6 +++--- .../biojava/nbio/structure/StructureIO.java | 1 - .../structure/align/client/StructureName.java | 4 +--- .../nbio/structure/align/ce/CeCPMainTest.java | 18 ++++++++++++++---- biojava-survival/pom.xml | 2 +- biojava-ws/pom.xml | 4 ++-- pom.xml | 2 +- 17 files changed, 42 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd6841d369..6f3acd48f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ BioJava 6.0.0 (future release) * All code related to All-vs-All structural alignments db calculation and access * JFatCatClient and all code depending on it * PDP domain providers (depended on JFatCatClient) +* Support for retrieving structure data with prefix "PDP:" (AtomCache, StructureIO) BioJava 5.4.0 ============= diff --git a/biojava-aa-prop/pom.xml b/biojava-aa-prop/pom.xml index a2e7342c8c..78344622b1 100644 --- a/biojava-aa-prop/pom.xml +++ b/biojava-aa-prop/pom.xml @@ -2,7 +2,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT 4.0.0 biojava-aa-prop @@ -70,12 +70,12 @@ org.biojava biojava-core - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT org.biojava biojava-structure - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index e1080222d3..a22b560d19 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 71d3fd5794..6cc9c6c9af 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index 03ff9b2c56..e219872582 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT compile org.biojava biojava-alignment - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index 60d537046d..0bd381f989 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 458ee4a2fe..4df1148dee 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index a50275e091..03787e7d7a 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 42ac69b916..9153de3e05 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index 0b375b2a89..a57bf73cdb 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index fc4584ce37..e59f89dc33 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT compile diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java index a90bc6db8c..193ed78e3d 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java @@ -61,7 +61,6 @@ public class StructureIO { chainID := [a-zA-Z0-9] scopID := 'd' pdbID [a-z_][0-9_] biol := 'BIO:' pdbID [:]? [0-9]+ - pdp := 'PDP:' pdbID[A-Za-z0-9_]+ resNum := [-+]?[0-9]+[A-Za-z]? diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java index 65598ad18f..58f244343c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/client/StructureName.java @@ -64,7 +64,7 @@ * information may be loaded from one of the factory classes: * {@link CathFactory},{@link ScopFactory}, etc. * - * @see #getIdentifier() the name. e.g. 4hhb, 4hhb.A, d4hhba_, PDP:4HHBAa etc. + * @see #getIdentifier() the name. e.g. 4hhb, 4hhb.A, d4hhba_ etc. */ public class StructureName implements Comparable, Serializable, StructureIdentifier { @@ -116,8 +116,6 @@ public enum Source { * Examples: 4hhb, 4hhb.A, 4hhb.A:1-50. *
  • SCOP SCOP domain (or SCOPe, depending on the * {@link ScopFactory#getSCOP()} version). Example: d1h6w.2 - *
  • PDP Protein Domain Parser domain. PDP domains are not guessed, - * making the PDP: prefix obligatory. Example: PDP:4HHBAa *
  • CATH Cath domains. Example: 1qvrC03 *
  • URL Arbitrary URLs. Most common protocols are handled, * including http://, ftp://, and file://. Some parsing information can diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java index 0d76dc98ce..20bc3901fe 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java @@ -34,7 +34,9 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; /** @@ -405,15 +407,23 @@ private Atom[] makeDummyCA(int len) throws PDBParseException { @Test public void testCECP1() throws IOException, StructureException{ - String name1 = "PDP:3A2KAc"; + //String name1 = "PDP:3A2KAc"; + String pdb1 = "3A2K"; String name2 = "d1wy5a2"; + AtomCache cache = new AtomCache(); - CeCPMain algorithm = new CeCPMain(); + // since BioJava 6.0.0, there's no PDP provider. The below corresponds to domain "PDP:3A2KAc" + List ranges = new ArrayList<>(); + // 234-333 + ranges.add(new ResidueRange("A", new ResidueNumber("A",234, null), new ResidueNumber("A", 333, null))); + SubstructureIdentifier ssi = new SubstructureIdentifier(pdb1, ranges); + Structure structure1 = cache.getStructure(pdb1); + ssi.reduce(structure1); - AtomCache cache = new AtomCache(); + CeCPMain algorithm = new CeCPMain(); - Atom[] ca1 = cache.getAtoms(name1); + Atom[] ca1 = StructureTools.getAtomCAArray(structure1); Atom[] ca2 = cache.getAtoms(name2); AFPChain afpChain = algorithm.align(ca1, ca2); diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index 62d4eb3667..8774d85478 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index ff394e7444..65b13c6730 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT compile diff --git a/pom.xml b/pom.xml index 2b2cd74ce8..c3ffa1ece2 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 5.4.1-SNAPSHOT + 6.0.0-SNAPSHOT biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the From 5a831abd7134aa840365a2d428d1ca3917823087 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 4 Jul 2020 10:07:43 -0700 Subject: [PATCH 135/769] Removing now unused class and package --- .../events/AlignmentProgressListener.java | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/events/AlignmentProgressListener.java diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/events/AlignmentProgressListener.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/events/AlignmentProgressListener.java deleted file mode 100644 index b8c898d251..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/events/AlignmentProgressListener.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.align.events; - -public interface AlignmentProgressListener { - - public void alignmentStarted(String name1, String name2); - - public void alignmentEnded(); - - public void logStatus(String message); - - public void downloadingStructures(String name); - - public void requestingAlignmentsFromServer(int nrAlignments); - - public void sentResultsToServer(int nrAlignments,String serverMessage); - - -} From 2f9e264a44c6ea9093c6b2ddf63b9352dcbf2d69 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 4 Jul 2020 13:33:15 -0700 Subject: [PATCH 136/769] Fixing pom versions --- biojava-protein-comparison-tool/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/biojava-protein-comparison-tool/pom.xml b/biojava-protein-comparison-tool/pom.xml index ad9bd325b6..8791985f38 100644 --- a/biojava-protein-comparison-tool/pom.xml +++ b/biojava-protein-comparison-tool/pom.xml @@ -5,7 +5,7 @@ biojava org.biojava - 5.0.0-SNAPSHOT + 6.0.0-SNAPSHOT biojava-protein-comparison-tool @@ -37,23 +37,23 @@ org.biojava biojava-alignment - 5.0.0-SNAPSHOT + 6.0.0-SNAPSHOT org.biojava biojava-core - 5.0.0-SNAPSHOT + 6.0.0-SNAPSHOT org.biojava biojava-structure - 5.0.0-SNAPSHOT + 6.0.0-SNAPSHOT org.biojava biojava-structure-gui - 5.0.0-SNAPSHOT + 6.0.0-SNAPSHOT net.sourceforge.jmol From a35adcf6f0ffe8841f92bcf2e60032bf9eb50c80 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 4 Jul 2020 14:29:07 -0700 Subject: [PATCH 137/769] Adjusting help strings --- .../ce/AbstractUserArgumentProcessor.java | 35 +++++-------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java index a8fb5c899c..85e2c100ab 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/AbstractUserArgumentProcessor.java @@ -297,8 +297,6 @@ private void runPairwise() throws ConfigurationException{ } } - - String name2 = params.getPdb2(); String file2 = params.getFile2(); if ( name2 == null && file2 == null ){ @@ -449,9 +447,9 @@ private void runPairwise() throws ConfigurationException{ } } - /** check if the result should be written to the local file system + /** + * check if the result should be written to the local file system * - * @param params2 * @param afpChain * @param ca1 * @param ca2 @@ -525,21 +523,17 @@ private void checkWriteFile( AFPChain afpChain, Atom[] ca1, Atom[] ca2, boolean FileOutputStream out; // declare a file output object PrintStream p; // declare a print stream object - // Create a new file output stream - out = new FileOutputStream(fileName); - - // Connect print stream to the output stream - p = new PrintStream( out ); - - p.println (output); - - p.close(); + // Create a new file output stream + out = new FileOutputStream(fileName); + // Connect print stream to the output stream + p = new PrintStream( out ); + p.println (output); + p.close(); } - private String getAutoFileName(AFPChain afpChain){ String fileName =afpChain.getName1()+"_" + afpChain.getName2()+"_"+afpChain.getAlgorithmName(); @@ -550,7 +544,6 @@ private String getAutoFileName(AFPChain afpChain){ return fileName; } - private Structure getStructure(AtomCache cache, String name1, String file) { @@ -654,18 +647,6 @@ public String printHelp() { buf.append(" -outFile (mandatory) a file that will contain the summary of all the pairwise alignments").append(newline); buf.append(newline); - buf.append("--- database searches ---").append(newline); - buf.append(" -searchFile (mandatory) path to a PDB file that should be used in the search").append(newline); - buf.append(" -outFile (mandatory) a directory that will contain the results of the DB search").append(newline); - buf.append(" -nrCPU (optional) Number of CPUs to use for the database search. By default will use the all, but one CPU in the system.").append(newline); - buf.append(" -pdbFilePath (mandatory) Path to the directory in your file system that contains the PDB files.").append(newline); - buf.append(" -saveOutputDir (optional) a directory that will contain the detailed outputs of the alignments. By default will write XML files, if used together with -outputPDB, will write PDB files of the alignment.").append(newline); - buf.append(newline); - - buf.append(" Once DB seaches are complete it is possible to view the results with:").append(newline); - buf.append(" -showDBresult (optional) path to a DB outFile to show. Also provide the -pdbFilePath parameter to enable visualisation of results.").append(newline); - buf.append(newline); - ConfigStrucAligParams params = alg.getParameters(); List paramNames = params.getUserConfigParameters(); List paramHelp = params.getUserConfigHelp(); From a73eee7c4562425d073fb30d6a38d85a9ecac646 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 5 Jul 2020 14:54:24 -0700 Subject: [PATCH 138/769] Removing RemoteScopInstallation and all downstream usages --- .../test/scop/RemoteScopInstallationTest.java | 64 ---- .../structure/test/scop/ScopFactoryTest.java | 6 - .../nbio/structure/align/util/AtomCache.java | 18 -- .../scop/CachedRemoteScopInstallation.java | 219 ------------- .../scop/RemoteScopInstallation.java | 302 ------------------ .../nbio/structure/scop/ScopFactory.java | 21 +- 6 files changed, 5 insertions(+), 625 deletions(-) delete mode 100644 biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/RemoteScopInstallationTest.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/scop/CachedRemoteScopInstallation.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/scop/RemoteScopInstallation.java diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/RemoteScopInstallationTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/RemoteScopInstallationTest.java deleted file mode 100644 index 2abe7d63ae..0000000000 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/RemoteScopInstallationTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.test.scop; - -import org.biojava.nbio.structure.scop.RemoteScopInstallation; -import org.biojava.nbio.structure.scop.ScopDatabase; -import org.biojava.nbio.structure.scop.ScopFactory; -import org.biojava.nbio.structure.scop.ScopInstallation; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * Tests {@link ScopInstallation}. - * @author Spencer Bliven - * @since 3.0.6 - */ -@RunWith(Parameterized.class) -public class RemoteScopInstallationTest extends ScopDatabaseTest { - - public RemoteScopInstallationTest(String tag,ScopDatabase scop) { - super(tag,scop); - } - - //@Parameters - @Parameters(name="{0}") - public static Collection availableDatabases() { - ArrayList databases = new ArrayList(); - RemoteScopInstallation scop; - for(String version : new String[] { - ScopFactory.LATEST_VERSION, - ScopFactory.VERSION_1_75A, - ScopFactory.VERSION_1_75B, - ScopFactory.VERSION_1_75, - ScopFactory.VERSION_1_73, - }) { - scop = new RemoteScopInstallation(); - scop.setScopVersion(version); - databases.add(new Object[] {scop.getScopVersion().trim(), scop}); - } - return databases; - } -} diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/ScopFactoryTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/ScopFactoryTest.java index 90efa438fc..dff28a9d79 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/ScopFactoryTest.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/ScopFactoryTest.java @@ -21,7 +21,6 @@ package org.biojava.nbio.structure.test.scop; import org.biojava.nbio.structure.scop.BerkeleyScopInstallation; -import org.biojava.nbio.structure.scop.RemoteScopInstallation; import org.biojava.nbio.structure.scop.ScopDatabase; import org.biojava.nbio.structure.scop.ScopFactory; import org.junit.Before; @@ -76,11 +75,6 @@ public void testVersions() { scop = ScopFactory.getSCOP(ScopFactory.VERSION_1_75); assertEquals(ScopFactory.VERSION_1_75, scop.getScopVersion()); - ScopFactory.setScopDatabase(ScopFactory.VERSION_1_75, false); - scop = ScopFactory.getSCOP(); - assertEquals(ScopFactory.VERSION_1_75, scop.getScopVersion()); - assertSame( RemoteScopInstallation.class,scop.getClass()); - ScopFactory.setScopDatabase(ScopFactory.VERSION_1_75, true); scop = ScopFactory.getSCOP(); assertEquals(ScopFactory.VERSION_1_75, scop.getScopVersion()); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java index 53b4352696..4b96d5f433 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java @@ -42,7 +42,6 @@ import org.biojava.nbio.core.util.FileDownloadUtils; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyBuilder; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; -import org.biojava.nbio.structure.scop.CachedRemoteScopInstallation; import org.biojava.nbio.structure.scop.ScopDatabase; import org.biojava.nbio.structure.scop.ScopDescription; import org.biojava.nbio.structure.scop.ScopDomain; @@ -653,23 +652,6 @@ public Structure getStructureForDomain(String scopId, ScopDatabase scopDatabase) return getStructureForDomain(domain, scopDatabase); } - /** - * Send a signal to the cache that the system is shutting down. Notifies underlying SerializableCache instances to - * flush themselves... - */ - public void notifyShutdown() { - - // todo: use a SCOP implementation that is backed by SerializableCache - ScopDatabase scopInstallation = ScopFactory.getSCOP(); - if (scopInstallation != null) { - if (scopInstallation instanceof CachedRemoteScopInstallation) { - CachedRemoteScopInstallation cacheScop = (CachedRemoteScopInstallation) scopInstallation; - cacheScop.flushCache(); - } - } - - } - /** * set the location at which utility data should be cached. * diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/CachedRemoteScopInstallation.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/CachedRemoteScopInstallation.java deleted file mode 100644 index b78dc5e4f4..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/CachedRemoteScopInstallation.java +++ /dev/null @@ -1,219 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Oct 12, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.scop; - -import org.biojava.nbio.structure.align.util.URLConnectionTools; -import org.biojava.nbio.structure.domain.SerializableCache; -import org.biojava.nbio.structure.rcsb.ReadUtils; -import org.biojava.nbio.structure.scop.server.ScopDomains; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - - -/** An extension of the RemoteScopInstallation that caches some of the data locally. - * - * @author Andreas Prlic - * - */ -public class CachedRemoteScopInstallation extends SerializableCache implements ScopDatabase { - - private static final Logger logger = LoggerFactory.getLogger(CachedRemoteScopInstallation.class); - - private static final String CACHE_FILE_NAME = "remotescopinstallation.ser"; - - RemoteScopInstallation proxy ; - - SerializableCache scopDescriptionCache ; - - public CachedRemoteScopInstallation() throws IOException { - this(true); - } - - public CachedRemoteScopInstallation(boolean useCache) throws IOException { - - super(CACHE_FILE_NAME); - - proxy = new RemoteScopInstallation(); - - scopDescriptionCache = new SerializableCache("scopDescriptionCache.ser"); - - if ( ! useCache) { - logger.warn(getClass().getSimpleName() + " disabling cache"); - disableCache(); - scopDescriptionCache.disableCache(); - } else { - - if ( serializedCache.size() < 8000){ - loadRepresentativeDomains(); - } - } - - } - - - /** get the ranges of representative domains from the centralized server - * - */ - private void loadRepresentativeDomains() throws IOException { - - URL u = null; - try { - u = new URL(RemoteScopInstallation.DEFAULT_SERVER + "getRepresentativeScopDomains"); - } catch (MalformedURLException e) { - throw new IOException("URL " + RemoteScopInstallation.DEFAULT_SERVER + "getRepresentativeScopDomains" + " is wrong", e); - } - logger.info("Using " + u + " to download representative domains"); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - ScopDomains results = ScopDomains.fromXML(xml); - - logger.info("got " + results.getScopDomain().size() + " domain ranges for Scop domains from server."); - for (ScopDomain dom : results.getScopDomain()){ - String scopId = dom.getScopId(); - serializedCache.put(scopId, dom); - } - - } - - - - @Override - public List getByCategory(ScopCategory category) { - return proxy.getByCategory(category); - } - - - @Override - public List filterByClassificationId(String query) { - return proxy.filterByClassificationId(query); - } - - - @Override - public List getTree(ScopDomain domain) { - return proxy.getTree(domain); - } - - - @Override - public List filterByDomainName(String query) { - return proxy.filterByDomainName(query); - } - - - @Override - public List filterByDescription(String query) { - return proxy.filterByClassificationId(query); - } - - - @Override - public ScopDescription getScopDescriptionBySunid(int sunid) { - - ScopDescription desc = scopDescriptionCache.get(sunid); - if ( desc != null) - return desc; - - - desc = proxy.getScopDescriptionBySunid(sunid); - if ( desc != null) - scopDescriptionCache.cache(sunid,desc); - return desc; - } - - - @Override - public List getDomainsForPDB(String pdbId) { - - return proxy.getDomainsForPDB(pdbId); - } - - - @Override - public ScopDomain getDomainByScopID(String scopId) { - ScopDomain dom; - - if ( serializedCache != null){ - if ( serializedCache.containsKey(scopId)) { - dom = serializedCache.get(scopId); - if ( dom != null) { - return dom; - } - } - } - - dom = proxy.getDomainByScopID(scopId); - - if ( dom != null) - cache(scopId, dom); - - - return dom; - } - - - @Override - public ScopNode getScopNode(int sunid) { - return proxy.getScopNode(sunid); - } - - - @Override - public String getScopVersion() { - return proxy.getScopVersion(); - } - - @Override - public void setScopVersion(String version) { - proxy.setScopVersion(version); - } - - - @Override - public List getScopDomainsBySunid(Integer sunid) { - return proxy.getScopDomainsBySunid(sunid); - } - - @Override - public void flushCache() { - logger.info("flushing " + getClass().getSimpleName()); - super.flushCache(); - scopDescriptionCache.flushCache(); - } - - @Override - public List getComments(int sunid) { - return new ArrayList(1); - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/RemoteScopInstallation.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/RemoteScopInstallation.java deleted file mode 100644 index 96cda0e3e3..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/RemoteScopInstallation.java +++ /dev/null @@ -1,302 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Aug 30, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.scop; - -import org.biojava.nbio.structure.align.util.URLConnectionTools; -import org.biojava.nbio.structure.rcsb.ReadUtils; -import org.biojava.nbio.structure.scop.server.ScopDescriptions; -import org.biojava.nbio.structure.scop.server.ScopDomains; -import org.biojava.nbio.structure.scop.server.ScopNodes; -import org.biojava.nbio.structure.scop.server.XMLUtil; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.List; - - -/** A class that fetches information about SCOP from a remote data-source. It requires port 80 to open for HTTP connection. - * - * @author Andreas Prlic - * - */ -public class RemoteScopInstallation implements ScopDatabase { - - public static final String DEFAULT_SERVER = "http://source.rcsb.org/jfatcatserver/domains/"; - - String server = DEFAULT_SERVER; - - private String version = null; - - public static void main(String[] args){ - - ScopDatabase scop = new RemoteScopInstallation(); - ScopFactory.setScopDatabase(scop); - - //System.out.println(scop.getByCategory(ScopCategory.Superfamily)); - - System.out.println(scop.getDomainsForPDB("4HHB")); - } - - - public String getServer() { - return server; - } - - public void setServer(String server) { - this.server = server; - } - - @Override - public List getByCategory(ScopCategory category) { - List results = null; - try { - URL u = new URL(server + "getByCategory?category="+category+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if(! xml.trim().isEmpty()) { - ScopDescriptions container = ScopDescriptions.fromXML(xml); - results = container.getScopDescription(); - } - } catch (IOException e) { - throw new RuntimeException("Unable to reach "+ server + "getByCategory?category="+category+"&version="+getScopVersion(), e); - } - return results; - } - - @Override - public List filterByClassificationId(String query) { - List results = null; - try { - URL u = new URL(server + "filterByClassificationId?query="+query+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if(! xml.trim().isEmpty()) { - ScopDescriptions container = ScopDescriptions.fromXML(xml); - results = container.getScopDescription(); - } - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "filterByClassificationId?query="+query+"&version="+getScopVersion(), e); - } - return results; - } - - @Override - public List getTree(ScopDomain domain) { - List results = null; - try { - URL u = new URL(server + "getTree?scopId="+domain.getScopId()+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if(! xml.trim().isEmpty()) { - ScopNodes container = ScopNodes.fromXML(xml); - results = container.getScopNode(); - } - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "getTree?scopId="+domain.getScopId()+"&version="+getScopVersion(), e); - } - return results; - } - - @Override - public List filterByDomainName(String query) { - query = query.trim(); - List results = null; - try { - URL u = new URL(server + "filterByDomainName?query="+query+"&version="+getScopVersion()); - //System.out.println(u); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if(! xml.trim().isEmpty()) { - ScopDomains container = ScopDomains.fromXML(xml); - results = container.getScopDomain(); - } - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "filterByDomainName?query="+query+"&version="+getScopVersion(), e); - } - return results; - } - - @Override - public List filterByDescription(String query) { - List results = null; - try { - URL u = new URL(server + "filterByDescription?query="+query+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if(! xml.trim().isEmpty()) { - ScopDescriptions container = ScopDescriptions.fromXML(xml); - results = container.getScopDescription(); - } - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "filterByDescription?query="+query+"&version="+getScopVersion(), e); - } - return results; - } - - @Override - public ScopDescription getScopDescriptionBySunid(int sunid) { - - ScopDescription desc = null; - - - try { - - URL u = new URL(server + "getScopDescriptionBySunid?sunid="+sunid+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if(! xml.trim().isEmpty()) { - desc = XMLUtil.getScopDescriptionFromXML(xml); - } - - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "getScopDescriptionBySunid?sunid="+sunid+"&version="+getScopVersion(), e); - } - return desc; - } - - @Override - public List getDomainsForPDB(String pdbId) { - List results = null; - try { - URL u = new URL(server + "getDomainsForPDB?pdbId="+pdbId+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if( !xml.trim().isEmpty()) { - ScopDomains container = ScopDomains.fromXML(xml); - results = container.getScopDomain(); - } - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "getDomainsForPDB?pdbId="+pdbId+"&version="+getScopVersion(), e); - } - return results; - } - - private ScopDomain requestRemoteDomainByScopID(String scopId) - throws IOException{ - scopId = scopId.trim(); - URL u = new URL(server + "getDomainByScopID?scopId="+scopId+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if( !xml.trim().isEmpty()) { - return XMLUtil.getScopDomainFromXML(xml); - } - return null; - } - - @Override - public ScopDomain getDomainByScopID(String scopId) { - try { - return requestRemoteDomainByScopID(scopId); - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "getDomainByScopID?scopId="+scopId+"&version="+getScopVersion(), e); - } - } - - @Override - public ScopNode getScopNode(int sunid) { - ScopNode desc = null; - try { - URL u = new URL(server + "getScopNode?sunid="+sunid+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if( !xml.trim().isEmpty()) { - desc = XMLUtil.getScopNodeFromXML(xml); - } - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "getScopNode?sunid="+sunid+"&version="+getScopVersion(), e); - } - return desc; - } - - @Override - public String getScopVersion() { - // If no version is set, request the default version from the website - if( version == null) { - try { - URL u = new URL(server + "getScopVersion"); - InputStream response = URLConnectionTools.getInputStream(u); - version = ReadUtils.convertStreamToString(response); - if( version != null) - version = version.trim(); - - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "getScopVersion", e); - } - } - return version; - } - - @Override - public void setScopVersion(String version) { - this.version = version; - } - - @Override - public List getScopDomainsBySunid(Integer sunid) { - List results = null; - try { - URL u = new URL(server + "getScopDomainsBySunid?sunid="+sunid+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if( !xml.trim().isEmpty()) { - ScopDomains container = ScopDomains.fromXML(xml); - results = container.getScopDomain(); - } - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "getScopDomainsBySunid?sunid="+sunid+"&version="+getScopVersion(), e); - } - return results; - } - - - @Override - public List getComments(int sunid) { - List results = null; - try { - URL u = new URL(server + "getComments?sunid="+sunid+"&version="+getScopVersion()); - InputStream response = URLConnectionTools.getInputStream(u); - String xml = ReadUtils.convertStreamToString(response); - - if( !xml.trim().isEmpty()) { - results = XMLUtil.getCommentsFromXML(xml); - } - } catch (Exception e){ - throw new RuntimeException("Unable to reach "+ server + "getComments?sunid="+sunid+"&version="+getScopVersion(), e); - } - return results; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/ScopFactory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/ScopFactory.java index 15363bd3e7..2a3ab6a8fc 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/ScopFactory.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/ScopFactory.java @@ -31,11 +31,8 @@ /** * Controls the global ScopDatabase being used. * - *

    Defaults to a {@link RemoteScopInstallation}, which is fast for small numbers - * of queries. For many queries, using {@link #getSCOP(String, boolean) getSCOP(version,true)} - * may be faster, since it makes only one network request. - * - *

    Example: Fetch the structure corresponding to an old version of scop + *

    + * Example: Fetch the structure corresponding to an old version of scop * *

      * ScopInstallation scop = new ScopInstallation();
    @@ -45,6 +42,7 @@
      * cache.setFetchFileEvenIfObsolete(true); //fetch older PDBs
      * cache.setStrictSCOP(false); // correct simple errors in domain names
      * Structure s = cache.getStructure("d3hbia_");
    + * 
    * @author sbliven * */ @@ -123,7 +121,7 @@ public static ScopDatabase getSCOP(String version){ *

    * The particular implementation returned is influenced by the forceLocalData * parameter. When false, the instance returned will generally be a - * {@link RemoteScopInstallation}, although this may be influenced by + * remote {@link ScopDatabase}, although this may be influenced by * previous calls to this class. When true, the result is guaranteed to * implement {@link LocalScopDatabase} (generally a {@link BerkeleyScopInstallation}). * @@ -147,17 +145,8 @@ public static ScopDatabase getSCOP(String version, boolean forceLocalData){ versionedScopDBs.put(version,berkeley); return berkeley; } - return scop; - } else { - // Use a remote installation - if( scop == null ) { - logger.info("Creating new {}, version {}", RemoteScopInstallation.class.getSimpleName(), version); - scop = new RemoteScopInstallation(); - scop.setScopVersion(version); - versionedScopDBs.put(version,scop); - } - return scop; } + return scop; } From 31939ad292d72261e2f6de906126b90be81a5213 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 5 Jul 2020 15:28:25 -0700 Subject: [PATCH 139/769] Bugfix: ScopFactory wasn't working after last commit --- .../structure/test/scop/ScopFactoryTest.java | 4 +- .../nbio/structure/scop/ScopFactory.java | 62 +++---------------- .../nbio/structure/align/ce/CeCPMainTest.java | 15 +++-- 3 files changed, 23 insertions(+), 58 deletions(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/ScopFactoryTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/ScopFactoryTest.java index dff28a9d79..b9bd782526 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/ScopFactoryTest.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/scop/ScopFactoryTest.java @@ -75,12 +75,12 @@ public void testVersions() { scop = ScopFactory.getSCOP(ScopFactory.VERSION_1_75); assertEquals(ScopFactory.VERSION_1_75, scop.getScopVersion()); - ScopFactory.setScopDatabase(ScopFactory.VERSION_1_75, true); + ScopFactory.setScopDatabase(ScopFactory.VERSION_1_75); scop = ScopFactory.getSCOP(); assertEquals(ScopFactory.VERSION_1_75, scop.getScopVersion()); assertSame( BerkeleyScopInstallation.class,scop.getClass()); - ScopFactory.setScopDatabase(ScopFactory.LATEST_VERSION, true); + ScopFactory.setScopDatabase(ScopFactory.LATEST_VERSION); scop = ScopFactory.getSCOP(); assertEquals(ScopFactory.LATEST_VERSION, scop.getScopVersion()); assertSame( BerkeleyScopInstallation.class,scop.getClass()); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/ScopFactory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/ScopFactory.java index 2a3ab6a8fc..69b3b61eb6 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/ScopFactory.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/ScopFactory.java @@ -81,7 +81,7 @@ public class ScopFactory { public static final String LATEST_VERSION = VERSION_2_0_7; // Hold one instance for each version - private static Map versionedScopDBs = new HashMap(); + private static Map versionedScopDBs = new HashMap<>(); private static String defaultVersion = LATEST_VERSION; /** @@ -92,64 +92,33 @@ public static ScopDatabase getSCOP(){ return getSCOP(defaultVersion); } - /** - * - * @param forceLocalData Whether to use a local installation or a remote installation - * @return - * @see #getSCOP(String, boolean) - */ - public static ScopDatabase getSCOP(boolean forceLocalData) { - return getSCOP(defaultVersion, forceLocalData); - } - - /** - * requests a particular version of SCOP. - * - * Where possible, this will be the current default instance. - * Otherwise a new instance will be created. - * @param version - * @return - */ - public static ScopDatabase getSCOP(String version){ - // Default to a remote installation - return getSCOP(version,false); - } - /** * Gets an instance of the specified scop version. * *

    - * The particular implementation returned is influenced by the forceLocalData - * parameter. When false, the instance returned will generally be a - * remote {@link ScopDatabase}, although this may be influenced by - * previous calls to this class. When true, the result is guaranteed to + * The particular implementation returned is guaranteed to * implement {@link LocalScopDatabase} (generally a {@link BerkeleyScopInstallation}). * - *

    - * Note that * @param version A version number, such as {@link #VERSION_1_75A} - * @param forceLocalData Whether to use a local installation or a remote installation * @return an */ - public static ScopDatabase getSCOP(String version, boolean forceLocalData){ + public static ScopDatabase getSCOP(String version){ if( version == null ) { version = defaultVersion; } + ScopDatabase scop = versionedScopDBs.get(version); - if ( forceLocalData) { + if (scop == null) { // Use a local installation - if( scop == null || !(scop instanceof LocalScopDatabase) ) { - logger.info("Creating new {}, version {}", BerkeleyScopInstallation.class.getSimpleName(), version); - BerkeleyScopInstallation berkeley = new BerkeleyScopInstallation(); - berkeley.setScopVersion(version); - versionedScopDBs.put(version,berkeley); - return berkeley; - } + logger.info("Creating new {}, version {}", BerkeleyScopInstallation.class.getSimpleName(), version); + BerkeleyScopInstallation berkeley = new BerkeleyScopInstallation(); + berkeley.setScopVersion(version); + versionedScopDBs.put(version, berkeley); + return berkeley; } return scop; } - /** * Set the default scop version * @param version A version number, such as {@link #VERSION_1_75A} @@ -159,17 +128,6 @@ public static void setScopDatabase(String version) { defaultVersion = version; } - /** - * Set the default scop version - * @param version A version number, such as {@link #VERSION_1_75A} - * @param forceLocalData Whether to use a local installation or a remote installation - */ - public static void setScopDatabase(String version, boolean forceLocalData) { - logger.debug("ScopFactory: Setting ScopDatabase to version: {}, forced local: {}", version, forceLocalData); - getSCOP(version,forceLocalData); - defaultVersion = version; - } - /** * Set the default scop version and instance * @param scop diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java index 20bc3901fe..319cf25f10 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java @@ -407,24 +407,31 @@ private Atom[] makeDummyCA(int len) throws PDBParseException { @Test public void testCECP1() throws IOException, StructureException{ - //String name1 = "PDP:3A2KAc"; String pdb1 = "3A2K"; - String name2 = "d1wy5a2"; + //String name1 = "PDP:3A2KAc"; // A : 234-333 + String pdb2 = "1WY5"; + //String name2 = "d1wy5a2"; // A : 217-311 AtomCache cache = new AtomCache(); // since BioJava 6.0.0, there's no PDP provider. The below corresponds to domain "PDP:3A2KAc" List ranges = new ArrayList<>(); - // 234-333 ranges.add(new ResidueRange("A", new ResidueNumber("A",234, null), new ResidueNumber("A", 333, null))); SubstructureIdentifier ssi = new SubstructureIdentifier(pdb1, ranges); Structure structure1 = cache.getStructure(pdb1); ssi.reduce(structure1); + // since BioJava 6.0.0, there's no RemoteSCOP provider. The below corresponds to domain "d1wy5a2" + ranges = new ArrayList<>(); + ranges.add(new ResidueRange("A", new ResidueNumber("A",217, null), new ResidueNumber("A", 311, null))); + ssi = new SubstructureIdentifier(pdb2, ranges); + Structure structure2 = cache.getStructure(pdb2); + ssi.reduce(structure2); + CeCPMain algorithm = new CeCPMain(); Atom[] ca1 = StructureTools.getAtomCAArray(structure1); - Atom[] ca2 = cache.getAtoms(name2); + Atom[] ca2 = StructureTools.getAtomCAArray(structure2); AFPChain afpChain = algorithm.align(ca1, ca2); CECalculator calculator = algorithm.getCECalculator(); From 2bc09aa6c25819a5c75bf0c02863d3e4ede1c5f7 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 5 Jul 2020 22:06:32 -0700 Subject: [PATCH 140/769] Removing server-related xml i/o code --- CHANGELOG.md | 1 + .../align/xml/HasResultXMLConverter.java | 142 ------- .../xml/PositionInQueueXMLConverter.java | 136 ------- .../domain/AssignmentXMLSerializer.java | 115 ------ .../scop/server/ListStringWrapper.java | 116 ------ .../scop/server/ScopDescriptions.java | 113 ------ .../structure/scop/server/ScopDomains.java | 116 ------ .../nbio/structure/scop/server/ScopNodes.java | 114 ------ .../scop/server/TreeSetStringWrapper.java | 115 ------ .../nbio/structure/scop/server/XMLUtil.java | 383 ------------------ 10 files changed, 1 insertion(+), 1350 deletions(-) delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/xml/HasResultXMLConverter.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/align/xml/PositionInQueueXMLConverter.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/domain/AssignmentXMLSerializer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ListStringWrapper.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopDescriptions.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopDomains.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopNodes.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/TreeSetStringWrapper.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/XMLUtil.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f3acd48f0..2218b88ed9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ BioJava 6.0.0 (future release) * JFatCatClient and all code depending on it * PDP domain providers (depended on JFatCatClient) * Support for retrieving structure data with prefix "PDP:" (AtomCache, StructureIO) +* RemoteScopInstallation consuming data provided by source.rcsb.org BioJava 5.4.0 ============= diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/xml/HasResultXMLConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/xml/HasResultXMLConverter.java deleted file mode 100644 index 023a891d2d..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/xml/HasResultXMLConverter.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on May 10, 2010 - * Author: Andreas Prlic - * - */ - -package org.biojava.nbio.structure.align.xml; - -import org.biojava.nbio.core.util.PrettyXMLWriter; -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; - -public class HasResultXMLConverter -{ - - - - - /** return flag if the server has a result - * - * @param hasResult - * @return flag if there is a result - */ - public String toXML(boolean hasResult) throws IOException{ - StringWriter swriter = new StringWriter(); - - PrintWriter writer = new PrintWriter(swriter); - PrettyXMLWriter xml = new PrettyXMLWriter(writer); - - xml.openTag("alignment"); - xml.attribute("hasResult", String.valueOf(hasResult)); - xml.closeTag("alignment"); - xml.close(); - return swriter.toString(); - } - - public boolean fromXML(String xml) { - - boolean hasResult = false; - - try - { - //Convert string to XML document - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = factory.newDocumentBuilder(); - InputSource inStream = new InputSource(); - inStream.setCharacterStream(new StringReader(xml)); - Document doc = db.parse(inStream); - - // normalize text representation - doc.getDocumentElement().normalize(); - - - //Element rootElement = doc.getDocumentElement(); - - NodeList listOfAlignments = doc.getElementsByTagName("alignment"); - //int numArrays = listOfAlignments.getLength(); - //System.out.println("got " + numArrays + " alignment results."); - // go over the blocks - - - for(int afpPos=0; afpPos assignments; - - static JAXBContext jaxbContext; - static { - try { - jaxbContext= JAXBContext.newInstance(AssignmentXMLSerializer.class); - } catch (Exception e){ - e.printStackTrace(); - } - } - - public AssignmentXMLSerializer(){ - assignments = new HashMap(); - - } - - public void setAssignments(Map assignments){ - - this.assignments = assignments; - - } - - public Map getAssignments(){ - return assignments; - } - - public String toXML(){ - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContext.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( this, ps); - - - } catch (Exception e){ - e.printStackTrace(); - } - - return baos.toString(); - - } - - public static AssignmentXMLSerializer fromXML(String xml){ - - AssignmentXMLSerializer job = null; - - try { - - Unmarshaller un = jaxbContext.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (AssignmentXMLSerializer) un.unmarshal(bais); - - } catch (Exception e){ - e.printStackTrace(); - } - - return job; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ListStringWrapper.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ListStringWrapper.java deleted file mode 100644 index 574052b86b..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ListStringWrapper.java +++ /dev/null @@ -1,116 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Aug 31, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.scop.server; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - - - -@XmlRootElement(name = "TreeSetStringWrapper", namespace ="http://source.rcsb.org") -@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) -public class ListStringWrapper implements Serializable{ - - - /** - * - */ - private static final long serialVersionUID = 4193799052494327416L; - List data; - - static JAXBContext jaxbContext; - static { - try { - jaxbContext= JAXBContext.newInstance(ListStringWrapper.class); - } catch (Exception e){ - throw new RuntimeException("Could not initialize JAXB context for " + ListStringWrapper.class, e); - } - } - - public ListStringWrapper(){ - data = new ArrayList(); - } - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - public String toXML(){ - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContext.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( this, ps); - - - } catch (Exception e){ - throw new RuntimeException("Could not convert " + getClass() + " to XML", e); - } - - return baos.toString(); - - } - - public static ListStringWrapper fromXML(String xml){ - - ListStringWrapper job = null; - - try { - - Unmarshaller un = jaxbContext.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (ListStringWrapper) un.unmarshal(bais); - - } catch (Exception e){ - throw new RuntimeException("Could not parse " + ListStringWrapper.class + " from XML", e); - } - - return job; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopDescriptions.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopDescriptions.java deleted file mode 100644 index 8d618f710e..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopDescriptions.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Aug 30, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.scop.server; - -import org.biojava.nbio.structure.scop.ScopDescription; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.io.Serializable; -import java.util.List; - - - -@XmlRootElement(name = "ScopDescriptions", namespace ="http://source.rcsb.org") -@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) -public class ScopDescriptions implements Serializable{ - - - private static final long serialVersionUID = 4924350548761431852L; - - static JAXBContext jaxbContext; - static { - try { - jaxbContext= JAXBContext.newInstance(ScopDescriptions.class); - } catch (Exception e){ - throw new RuntimeException("Could not initialize JAXB context for " + ScopDescriptions.class, e); - } - } - - - List scopDescriptions; - - public List getScopDescription() { - return scopDescriptions; - } - - public void setScopDescription(List descriptions) { - this.scopDescriptions = descriptions; - } - - public String toXML(){ - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContext.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( this, ps); - - - } catch (Exception e){ - throw new RuntimeException("Could not convert " + getClass() + " to XML", e); - } - - return baos.toString(); - - } - - public static ScopDescriptions fromXML(String xml){ - - ScopDescriptions job = null; - - try { - - Unmarshaller un = jaxbContext.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (ScopDescriptions) un.unmarshal(bais); - - } catch (Exception e){ - throw new RuntimeException("Could not parse " + ScopDescriptions.class + " from XML", e); - } - - return job; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopDomains.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopDomains.java deleted file mode 100644 index c9e8f8422b..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopDomains.java +++ /dev/null @@ -1,116 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Aug 30, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.scop.server; - -import org.biojava.nbio.structure.scop.ScopDomain; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.io.Serializable; -import java.util.List; - -@XmlRootElement(name = "ScopDomains", namespace ="http://source.rcsb.org") -@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) -public class ScopDomains implements Serializable{ - - /** - * - */ - private static final long serialVersionUID = 7693404355005856746L; - - List domains ; - - static JAXBContext jaxbContext; - static { - try { - jaxbContext= JAXBContext.newInstance(ScopDomains.class); - } catch (Exception e){ - throw new RuntimeException("Could not initialize JAXB context for " + ScopDomains.class, e); - } - } - - - public void setScopDomain(List domains) { - this.domains = domains; - - } - - public List getScopDomain() { - return domains; - } - - public String toXML(){ - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContext.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( this, ps); - - - } catch (Exception e){ - throw new RuntimeException("Could not convert " + getClass() + " to XML", e); - } - - return baos.toString(); - - } - - public static ScopDomains fromXML(String xml){ - - ScopDomains job = null; - - try { - - Unmarshaller un = jaxbContext.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (ScopDomains) un.unmarshal(bais); - - } catch (Exception e){ - throw new RuntimeException("Could not parse " + ScopDomains.class + " from XML", e); - } - - return job; - } - - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopNodes.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopNodes.java deleted file mode 100644 index 70e9965a5b..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/ScopNodes.java +++ /dev/null @@ -1,114 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Aug 30, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.scop.server; - -import org.biojava.nbio.structure.scop.ScopNode; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.io.Serializable; -import java.util.List; - - -@XmlRootElement(name = "ScopNodes", namespace ="http://source.rcsb.org") -@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) -public class ScopNodes implements Serializable { - - /** - * - */ - private static final long serialVersionUID = 5327454882500340305L; - - List scopNodes ; - - static JAXBContext jaxbContext; - static { - try { - jaxbContext= JAXBContext.newInstance(ScopNodes.class); - } catch (Exception e){ - throw new RuntimeException("Could not initialize JAXB context for " + ScopNodes.class, e); - } - } - - public List getScopNode() { - return scopNodes; - } - - public void setScopNode(List scopNodes) { - this.scopNodes = scopNodes; - } - - public String toXML(){ - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContext.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( this, ps); - - - } catch (Exception e){ - throw new RuntimeException("Could not convert " + getClass() + " to XML", e); - } - - return baos.toString(); - - } - - public static ScopNodes fromXML(String xml){ - - ScopNodes job = null; - - try { - - Unmarshaller un = jaxbContext.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (ScopNodes) un.unmarshal(bais); - - } catch (Exception e){ - throw new RuntimeException("Could not parse " + ScopNodes.class + " from XML", e); - } - - return job; - } - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/TreeSetStringWrapper.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/TreeSetStringWrapper.java deleted file mode 100644 index 004b81c069..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/TreeSetStringWrapper.java +++ /dev/null @@ -1,115 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Aug 31, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.scop.server; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.io.Serializable; -import java.util.TreeSet; - - - -@XmlRootElement(name = "TreeSetStringWrapper", namespace ="http://source.rcsb.org") -@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) -public class TreeSetStringWrapper implements Serializable{ - - - /** - * - */ - private static final long serialVersionUID = 4193799052494327416L; - TreeSet data; - - static JAXBContext jaxbContext; - static { - try { - jaxbContext= JAXBContext.newInstance(TreeSetStringWrapper.class); - } catch (Exception e){ - throw new RuntimeException("Could not initialize JAXB context for " + TreeSetStringWrapper.class, e); - } - } - - public TreeSetStringWrapper(){ - data = new TreeSet(); - } - - public TreeSet getData() { - return data; - } - - public void setData(TreeSet data) { - this.data = data; - } - public String toXML(){ - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContext.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( this, ps); - - - } catch (Exception e){ - throw new RuntimeException("Could not convert " + getClass() + " to XML", e); - } - - return baos.toString(); - - } - - public static TreeSetStringWrapper fromXML(String xml){ - - TreeSetStringWrapper job = null; - - try { - - Unmarshaller un = jaxbContext.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (TreeSetStringWrapper) un.unmarshal(bais); - - } catch (Exception e){ - throw new RuntimeException("Could not parse " + TreeSetStringWrapper.class + " from XML", e); - } - - return job; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/XMLUtil.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/XMLUtil.java deleted file mode 100644 index 8061e6ef6e..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/scop/server/XMLUtil.java +++ /dev/null @@ -1,383 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Aug 30, 2011 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.scop.server; - -import org.biojava.nbio.structure.domain.pdp.Domain; -import org.biojava.nbio.structure.scop.ScopDescription; -import org.biojava.nbio.structure.scop.ScopDomain; -import org.biojava.nbio.structure.scop.ScopNode; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; - - -/** Utility classes for the XML serialization and de-serialization of SCOP. - * - * @author Andreas Prlic - * @since 3.0.2 - * - */ -public class XMLUtil { - - static JAXBContext jaxbContextScopDescription; - static { - try { - jaxbContextScopDescription= JAXBContext.newInstance(ScopDescription.class); - } catch (JAXBException e){ - throw new RuntimeException("Could not initialize JAXB context", e); - } - } - - static JAXBContext jaxbContextScopDomain; - static { - try { - jaxbContextScopDomain= JAXBContext.newInstance(ScopDomain.class); - } catch (JAXBException e){ - throw new RuntimeException("Could not initialize JAXB context", e); - } - } - - static JAXBContext jaxbContextScopNode; - static { - try { - jaxbContextScopNode= JAXBContext.newInstance(ScopNode.class); - } catch (JAXBException e){ - throw new RuntimeException("Could not initialize JAXB context", e); - } - } - - static JAXBContext jaxbContextDomains; - static { - try { - jaxbContextDomains= JAXBContext.newInstance(TreeSet.class); - } catch (JAXBException e){ - throw new RuntimeException("Could not initialize JAXB context", e); - } - } - - static JAXBContext jaxbContextStringSortedSet; - static { - try { - jaxbContextStringSortedSet= JAXBContext.newInstance(TreeSetStringWrapper.class); - } catch (JAXBException e){ - throw new RuntimeException("Could not initialize JAXB context", e); - } - } - - static JAXBContext jaxbContextComments; - static { - try { - jaxbContextComments = JAXBContext.newInstance(ListStringWrapper.class); - } catch( JAXBException e){ - throw new RuntimeException("Could not initialize JAXB context", e); - } - } - - - public static String getScopDescriptionXML(ScopDescription desc){ - - return converScopDescription(desc); - - } - - public static ScopDescription getScopDescriptionFromXML(String xml){ - - ScopDescription job = null; - - try { - - Unmarshaller un = jaxbContextScopDescription.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (ScopDescription) un.unmarshal(bais); - - } catch (JAXBException e){ - throw new RuntimeException("Could not parse from XML", e); - } - - return job; - } - - private static String converScopDescription(ScopDescription desc) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContextScopDescription.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( desc, ps); - - - } catch (JAXBException e){ - throw new RuntimeException("Could not parse from XML", e); - } - - return baos.toString(); - } - - public static String getScopDescriptionsXML(List descriptions){ - - ScopDescriptions container = new ScopDescriptions(); - container.setScopDescription(descriptions); - - return container.toXML(); - - } - - - - public static String getCommentsXML(List comments ){ - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContextComments.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - ListStringWrapper wrapper = new ListStringWrapper(); - wrapper.setData(comments); - - m.marshal( wrapper, ps); - - - } catch (JAXBException e){ - throw new RuntimeException("Could not parse from XML", e); - } - - return baos.toString(); - } - public static List getCommentsFromXML(String xml){ - - List comments = null; - - try { - - Unmarshaller un = jaxbContextComments.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - ListStringWrapper wrapper = (ListStringWrapper) un.unmarshal(bais); - comments = wrapper.getData(); - - } catch (JAXBException e){ - throw new RuntimeException("Could not parse from XML", e); - } - - return comments; - } - - - public static String getScopNodeXML(ScopNode scopNode){ - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContextScopNode.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( scopNode, ps); - - - } catch (JAXBException e){ - throw new RuntimeException("Could not parse from XML", e); - } - - return baos.toString(); - } - - public static ScopNode getScopNodeFromXML(String xml){ - ScopNode job = null; - - try { - - Unmarshaller un = jaxbContextScopNode.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (ScopNode) un.unmarshal(bais); - - } catch (JAXBException e){ - throw new RuntimeException("Could not parse from XML", e); - } - - return job; - } - - public static String getScopNodesXML(List nodes) { - ScopNodes container = new ScopNodes(); - container.setScopNode(nodes); - - return container.toXML(); - } - - public static String getScopDomainXML(ScopDomain domain){ - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContextScopDomain.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( domain, ps); - - - } catch (JAXBException e){ - throw new RuntimeException("Could not serialize to XML", e); - } - - return baos.toString(); - } - - public static ScopDomain getScopDomainFromXML(String xml){ - ScopDomain job = null; - - try { - - Unmarshaller un = jaxbContextScopDomain.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (ScopDomain) un.unmarshal(bais); - - } catch (JAXBException e){ - throw new RuntimeException("Could not serialize to XML", e); - } - - return job; - } - - public static String getScopDomainsXML(List domains) { - ScopDomains container = new ScopDomains(); - container.setScopDomain(domains); - - return container.toXML(); - } - - - public static String getDomainsXML(SortedSet domains){ - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContextDomains.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( domains, ps); - - - } catch (JAXBException e){ - throw new RuntimeException("Could not serialize to XML", e); - } - - return baos.toString(); - } - @SuppressWarnings("unchecked") - public static SortedSet getDomainsFromXML(String xml) { - - SortedSet domains = null; - try { - - Unmarshaller un = jaxbContextDomains.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - domains = (SortedSet) un.unmarshal(bais); - - } catch (JAXBException e){ - throw new RuntimeException("Could not serialize to XML", e); - } - - return domains; - } - - public static String getDomainRangesXML(SortedSet domainRanges){ - if ( ! (domainRanges instanceof TreeSet)) { - throw new IllegalArgumentException("SortedSet needs to be a TreeSet!"); - } - TreeSet data = (TreeSet)domainRanges; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContextStringSortedSet.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - TreeSetStringWrapper wrapper = new TreeSetStringWrapper(); - wrapper.setData(data); - m.marshal( wrapper, ps); - - - } catch (JAXBException e){ - throw new RuntimeException("Could not serialize to XML", e); - } - - return baos.toString(); - } - - public static SortedSet getDomainRangesFromXML(String xml){ - SortedSet domains = null; - try { - - Unmarshaller un = jaxbContextStringSortedSet.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - TreeSetStringWrapper wrapper = (TreeSetStringWrapper) un.unmarshal(bais); - domains = wrapper.getData(); - - } catch (JAXBException e){ - throw new RuntimeException("Could not serialize to XML", e); - } - - return domains; - } -} From c5f42b62f647da55a00b93ddec929855dcfbefd0 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 7 Jul 2020 10:24:50 -0700 Subject: [PATCH 141/769] bump ciftools-java version to latest Java 8 release --- biojava-structure/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index fc4584ce37..fe0800fbda 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -21,7 +21,7 @@ org.rcsb ciftools-java - 0.7.1 + 0.10.1 org.rcsb From faae1a101f8f74589357c0eb7cefc170c0ec7ae7 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 7 Jul 2020 12:08:38 -0700 Subject: [PATCH 142/769] rewire ciftools-java --- .../structure/io/cif/CifFileConsumer.java | 94 +++++++++---------- .../structure/io/cif/CifFileConsumerImpl.java | 92 +++++++++--------- .../structure/io/cif/CifFileConverter.java | 7 +- .../structure/io/cif/CifFileSupplierImpl.java | 62 ++++++------ .../io/cif/CifFileConsumerImplTest.java | 9 +- 5 files changed, 134 insertions(+), 130 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java index 0a0c0e3fb5..d15c9cc140 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java @@ -1,50 +1,50 @@ package org.biojava.nbio.structure.io.cif; -import org.rcsb.cif.model.generated.AtomSite; -import org.rcsb.cif.model.generated.AtomSites; -import org.rcsb.cif.model.generated.AuditAuthor; -import org.rcsb.cif.model.generated.Cell; -import org.rcsb.cif.model.generated.ChemComp; -import org.rcsb.cif.model.generated.ChemCompBond; -import org.rcsb.cif.model.generated.DatabasePDBRemark; -import org.rcsb.cif.model.generated.DatabasePDBRev; -import org.rcsb.cif.model.generated.DatabasePDBRevRecord; -import org.rcsb.cif.model.generated.Entity; -import org.rcsb.cif.model.generated.EntityPoly; -import org.rcsb.cif.model.generated.EntityPolySeq; -import org.rcsb.cif.model.generated.EntitySrcGen; -import org.rcsb.cif.model.generated.EntitySrcNat; -import org.rcsb.cif.model.generated.Exptl; -import org.rcsb.cif.model.generated.PdbxAuditRevisionHistory; -import org.rcsb.cif.model.generated.PdbxChemCompIdentifier; -import org.rcsb.cif.model.generated.PdbxDatabaseStatus; -import org.rcsb.cif.model.generated.PdbxEntityDescriptor; -import org.rcsb.cif.model.generated.PdbxEntitySrcSyn; -import org.rcsb.cif.model.generated.PdbxMolecule; -import org.rcsb.cif.model.generated.PdbxMoleculeFeatures; -import org.rcsb.cif.model.generated.PdbxNonpolyScheme; -import org.rcsb.cif.model.generated.PdbxReferenceEntityLink; -import org.rcsb.cif.model.generated.PdbxReferenceEntityList; -import org.rcsb.cif.model.generated.PdbxReferenceEntityPolyLink; -import org.rcsb.cif.model.generated.PdbxStructAssembly; -import org.rcsb.cif.model.generated.PdbxStructAssemblyGen; -import org.rcsb.cif.model.generated.PdbxStructModResidue; -import org.rcsb.cif.model.generated.PdbxStructOperList; -import org.rcsb.cif.model.generated.Refine; -import org.rcsb.cif.model.generated.Struct; -import org.rcsb.cif.model.generated.StructAsym; -import org.rcsb.cif.model.generated.StructConf; -import org.rcsb.cif.model.generated.StructConn; -import org.rcsb.cif.model.generated.StructConnType; -import org.rcsb.cif.model.generated.StructKeywords; -import org.rcsb.cif.model.generated.StructNcsOper; -import org.rcsb.cif.model.generated.StructRef; -import org.rcsb.cif.model.generated.StructRefSeq; -import org.rcsb.cif.model.generated.StructRefSeqDif; -import org.rcsb.cif.model.generated.StructSheetRange; -import org.rcsb.cif.model.generated.StructSite; -import org.rcsb.cif.model.generated.StructSiteGen; -import org.rcsb.cif.model.generated.Symmetry; +import org.rcsb.cif.schema.mm.AtomSite; +import org.rcsb.cif.schema.mm.AtomSites; +import org.rcsb.cif.schema.mm.AuditAuthor; +import org.rcsb.cif.schema.mm.Cell; +import org.rcsb.cif.schema.mm.ChemComp; +import org.rcsb.cif.schema.mm.ChemCompBond; +import org.rcsb.cif.schema.mm.DatabasePDBRemark; +import org.rcsb.cif.schema.mm.DatabasePDBRev; +import org.rcsb.cif.schema.mm.DatabasePDBRevRecord; +import org.rcsb.cif.schema.mm.Entity; +import org.rcsb.cif.schema.mm.EntityPoly; +import org.rcsb.cif.schema.mm.EntityPolySeq; +import org.rcsb.cif.schema.mm.EntitySrcGen; +import org.rcsb.cif.schema.mm.EntitySrcNat; +import org.rcsb.cif.schema.mm.Exptl; +import org.rcsb.cif.schema.mm.PdbxAuditRevisionHistory; +import org.rcsb.cif.schema.mm.PdbxChemCompIdentifier; +import org.rcsb.cif.schema.mm.PdbxDatabaseStatus; +import org.rcsb.cif.schema.mm.PdbxEntityBranchDescriptor; +import org.rcsb.cif.schema.mm.PdbxEntitySrcSyn; +import org.rcsb.cif.schema.mm.PdbxMolecule; +import org.rcsb.cif.schema.mm.PdbxMoleculeFeatures; +import org.rcsb.cif.schema.mm.PdbxNonpolyScheme; +import org.rcsb.cif.schema.mm.PdbxReferenceEntityLink; +import org.rcsb.cif.schema.mm.PdbxReferenceEntityList; +import org.rcsb.cif.schema.mm.PdbxReferenceEntityPolyLink; +import org.rcsb.cif.schema.mm.PdbxStructAssembly; +import org.rcsb.cif.schema.mm.PdbxStructAssemblyGen; +import org.rcsb.cif.schema.mm.PdbxStructModResidue; +import org.rcsb.cif.schema.mm.PdbxStructOperList; +import org.rcsb.cif.schema.mm.Refine; +import org.rcsb.cif.schema.mm.Struct; +import org.rcsb.cif.schema.mm.StructAsym; +import org.rcsb.cif.schema.mm.StructConf; +import org.rcsb.cif.schema.mm.StructConn; +import org.rcsb.cif.schema.mm.StructConnType; +import org.rcsb.cif.schema.mm.StructKeywords; +import org.rcsb.cif.schema.mm.StructNcsOper; +import org.rcsb.cif.schema.mm.StructRef; +import org.rcsb.cif.schema.mm.StructRefSeq; +import org.rcsb.cif.schema.mm.StructRefSeqDif; +import org.rcsb.cif.schema.mm.StructSheetRange; +import org.rcsb.cif.schema.mm.StructSite; +import org.rcsb.cif.schema.mm.StructSiteGen; +import org.rcsb.cif.schema.mm.Symmetry; /** * Defines a rather generic interface which allows to populate some data structure with data parsed from a CIF file. @@ -175,9 +175,9 @@ interface CifFileConsumer { /** * Consume a particular Cif category. - * @param pdbxEntityDescriptor data + * @param pdbxEntityBranchDescriptor data */ - void consumePdbxEntityDescriptor(PdbxEntityDescriptor pdbxEntityDescriptor); + void consumePdbxEntityBranchDescriptor(PdbxEntityBranchDescriptor pdbxEntityBranchDescriptor); /** * Consume a particular Cif category. diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java index 66e2b6be04..c6d232d52a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java @@ -40,51 +40,51 @@ import org.rcsb.cif.model.FloatColumn; import org.rcsb.cif.model.IntColumn; import org.rcsb.cif.model.StrColumn; -import org.rcsb.cif.model.generated.AtomSite; -import org.rcsb.cif.model.generated.AtomSites; -import org.rcsb.cif.model.generated.AuditAuthor; -import org.rcsb.cif.model.generated.Cell; -import org.rcsb.cif.model.generated.ChemComp; -import org.rcsb.cif.model.generated.ChemCompBond; -import org.rcsb.cif.model.generated.DatabasePDBRemark; -import org.rcsb.cif.model.generated.DatabasePDBRev; -import org.rcsb.cif.model.generated.DatabasePDBRevRecord; -import org.rcsb.cif.model.generated.Entity; -import org.rcsb.cif.model.generated.EntityPoly; -import org.rcsb.cif.model.generated.EntityPolySeq; -import org.rcsb.cif.model.generated.EntitySrcGen; -import org.rcsb.cif.model.generated.EntitySrcNat; -import org.rcsb.cif.model.generated.Exptl; -import org.rcsb.cif.model.generated.PdbxAuditRevisionHistory; -import org.rcsb.cif.model.generated.PdbxChemCompIdentifier; -import org.rcsb.cif.model.generated.PdbxDatabaseStatus; -import org.rcsb.cif.model.generated.PdbxEntityDescriptor; -import org.rcsb.cif.model.generated.PdbxEntitySrcSyn; -import org.rcsb.cif.model.generated.PdbxMolecule; -import org.rcsb.cif.model.generated.PdbxMoleculeFeatures; -import org.rcsb.cif.model.generated.PdbxNonpolyScheme; -import org.rcsb.cif.model.generated.PdbxReferenceEntityLink; -import org.rcsb.cif.model.generated.PdbxReferenceEntityList; -import org.rcsb.cif.model.generated.PdbxReferenceEntityPolyLink; -import org.rcsb.cif.model.generated.PdbxStructAssembly; -import org.rcsb.cif.model.generated.PdbxStructAssemblyGen; -import org.rcsb.cif.model.generated.PdbxStructModResidue; -import org.rcsb.cif.model.generated.PdbxStructOperList; -import org.rcsb.cif.model.generated.Refine; -import org.rcsb.cif.model.generated.Struct; -import org.rcsb.cif.model.generated.StructAsym; -import org.rcsb.cif.model.generated.StructConf; -import org.rcsb.cif.model.generated.StructConn; -import org.rcsb.cif.model.generated.StructConnType; -import org.rcsb.cif.model.generated.StructKeywords; -import org.rcsb.cif.model.generated.StructNcsOper; -import org.rcsb.cif.model.generated.StructRef; -import org.rcsb.cif.model.generated.StructRefSeq; -import org.rcsb.cif.model.generated.StructRefSeqDif; -import org.rcsb.cif.model.generated.StructSheetRange; -import org.rcsb.cif.model.generated.StructSite; -import org.rcsb.cif.model.generated.StructSiteGen; -import org.rcsb.cif.model.generated.Symmetry; +import org.rcsb.cif.schema.mm.AtomSite; +import org.rcsb.cif.schema.mm.AtomSites; +import org.rcsb.cif.schema.mm.AuditAuthor; +import org.rcsb.cif.schema.mm.Cell; +import org.rcsb.cif.schema.mm.ChemComp; +import org.rcsb.cif.schema.mm.ChemCompBond; +import org.rcsb.cif.schema.mm.DatabasePDBRemark; +import org.rcsb.cif.schema.mm.DatabasePDBRev; +import org.rcsb.cif.schema.mm.DatabasePDBRevRecord; +import org.rcsb.cif.schema.mm.Entity; +import org.rcsb.cif.schema.mm.EntityPoly; +import org.rcsb.cif.schema.mm.EntityPolySeq; +import org.rcsb.cif.schema.mm.EntitySrcGen; +import org.rcsb.cif.schema.mm.EntitySrcNat; +import org.rcsb.cif.schema.mm.Exptl; +import org.rcsb.cif.schema.mm.PdbxAuditRevisionHistory; +import org.rcsb.cif.schema.mm.PdbxChemCompIdentifier; +import org.rcsb.cif.schema.mm.PdbxDatabaseStatus; +import org.rcsb.cif.schema.mm.PdbxEntityBranchDescriptor; +import org.rcsb.cif.schema.mm.PdbxEntitySrcSyn; +import org.rcsb.cif.schema.mm.PdbxMolecule; +import org.rcsb.cif.schema.mm.PdbxMoleculeFeatures; +import org.rcsb.cif.schema.mm.PdbxNonpolyScheme; +import org.rcsb.cif.schema.mm.PdbxReferenceEntityLink; +import org.rcsb.cif.schema.mm.PdbxReferenceEntityList; +import org.rcsb.cif.schema.mm.PdbxReferenceEntityPolyLink; +import org.rcsb.cif.schema.mm.PdbxStructAssembly; +import org.rcsb.cif.schema.mm.PdbxStructAssemblyGen; +import org.rcsb.cif.schema.mm.PdbxStructModResidue; +import org.rcsb.cif.schema.mm.PdbxStructOperList; +import org.rcsb.cif.schema.mm.Refine; +import org.rcsb.cif.schema.mm.Struct; +import org.rcsb.cif.schema.mm.StructAsym; +import org.rcsb.cif.schema.mm.StructConf; +import org.rcsb.cif.schema.mm.StructConn; +import org.rcsb.cif.schema.mm.StructConnType; +import org.rcsb.cif.schema.mm.StructKeywords; +import org.rcsb.cif.schema.mm.StructNcsOper; +import org.rcsb.cif.schema.mm.StructRef; +import org.rcsb.cif.schema.mm.StructRefSeq; +import org.rcsb.cif.schema.mm.StructRefSeqDif; +import org.rcsb.cif.schema.mm.StructSheetRange; +import org.rcsb.cif.schema.mm.StructSite; +import org.rcsb.cif.schema.mm.StructSiteGen; +import org.rcsb.cif.schema.mm.Symmetry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -770,7 +770,7 @@ public void consumePdbxDatabaseStatus(PdbxDatabaseStatus pdbxDatabaseStatus) { } @Override - public void consumePdbxEntityDescriptor(PdbxEntityDescriptor pdbxEntityDescriptor) { + public void consumePdbxEntityBranchDescriptor(PdbxEntityBranchDescriptor pdbxEntityBranchDescriptor) { // TODO not considered in ref } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java index 672e618613..8f82e310b6 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java @@ -3,8 +3,9 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.io.FileParsingParameters; import org.rcsb.cif.CifIO; -import org.rcsb.cif.model.Block; import org.rcsb.cif.model.CifFile; +import org.rcsb.cif.schema.StandardSchemata; +import org.rcsb.cif.schema.mm.MmCifBlock; import java.io.IOException; import java.io.InputStream; @@ -104,7 +105,7 @@ public static Structure fromCifFile(CifFile cifFile, FileParsingParameters param consumer.prepare(); // feed individual categories to consumer - Block cifBlock = cifFile.getFirstBlock(); + MmCifBlock cifBlock = cifFile.as(StandardSchemata.MMCIF).getFirstBlock(); consumer.consumeAuditAuthor(cifBlock.getAuditAuthor()); consumer.consumeAtomSite(cifBlock.getAtomSite()); @@ -125,7 +126,7 @@ public static Structure fromCifFile(CifFile cifFile, FileParsingParameters param consumer.consumePdbxAuditRevisionHistory(cifBlock.getPdbxAuditRevisionHistory()); consumer.consumePdbxChemCompIdentifier(cifBlock.getPdbxChemCompIdentifier()); consumer.consumePdbxDatabaseStatus(cifBlock.getPdbxDatabaseStatus()); - consumer.consumePdbxEntityDescriptor(cifBlock.getPdbxEntityDescriptor()); + consumer.consumePdbxEntityBranchDescriptor(cifBlock.getPdbxEntityBranchDescriptor()); consumer.consumePdbxMolecule(cifBlock.getPdbxMolecule()); consumer.consumePdbxMoleculeFeatures(cifBlock.getPdbxMoleculeFeatures()); consumer.consumePdbxNonpolyScheme(cifBlock.getPdbxNonpolyScheme()); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplierImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplierImpl.java index 9d839de4f2..6b39cf9c58 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplierImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplierImpl.java @@ -9,14 +9,16 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.xtal.CrystalCell; import org.biojava.nbio.structure.xtal.SpaceGroup; +import org.rcsb.cif.CifBuilder; import org.rcsb.cif.model.Category; import org.rcsb.cif.model.CifFile; -import org.rcsb.cif.model.builder.BlockBuilder; -import org.rcsb.cif.model.builder.CategoryBuilder; -import org.rcsb.cif.model.builder.CifBuilder; -import org.rcsb.cif.model.builder.FloatColumnBuilder; -import org.rcsb.cif.model.builder.IntColumnBuilder; -import org.rcsb.cif.model.builder.StrColumnBuilder; +import org.rcsb.cif.model.FloatColumnBuilder; +import org.rcsb.cif.model.IntColumnBuilder; +import org.rcsb.cif.model.StrColumnBuilder; +import org.rcsb.cif.schema.StandardSchemata; +import org.rcsb.cif.schema.mm.MmCifBlockBuilder; +import org.rcsb.cif.schema.mm.MmCifCategoryBuilder; +import org.rcsb.cif.schema.mm.MmCifFileBuilder; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -43,7 +45,7 @@ public CifFile get(Structure structure) { List wrappedAtoms = collectWrappedAtoms(structure); Category atomSite = wrappedAtoms.stream().collect(toAtomSite()); - BlockBuilder blockBuilder = new CifBuilder() + MmCifBlockBuilder blockBuilder = CifBuilder.enterFile(StandardSchemata.MMCIF) .enterBlock(structure.getPDBCode()); if (atomSite.isDefined() && atomSite.getRowCount() > 0) { @@ -187,30 +189,30 @@ int getAtomId() { } static class AtomSiteCollector implements Consumer { - private final CategoryBuilder.AtomSiteBuilder atomSiteBuilder; - private final StrColumnBuilder groupPDB; - private final IntColumnBuilder id; - private final StrColumnBuilder typeSymbol; - private final StrColumnBuilder labelAtomId; - private final StrColumnBuilder labelAltId; - private final StrColumnBuilder labelCompId; - private final StrColumnBuilder labelAsymId; - private final StrColumnBuilder labelEntityId; - private final IntColumnBuilder labelSeqId; - private final StrColumnBuilder pdbxPDBInsCode; - private final FloatColumnBuilder cartnX; - private final FloatColumnBuilder cartnY; - private final FloatColumnBuilder cartnZ; - private final FloatColumnBuilder occupancy; - private final FloatColumnBuilder bIsoOrEquiv; - private final IntColumnBuilder authSeqId; - private final StrColumnBuilder authCompId; - private final StrColumnBuilder authAsymId; - private final StrColumnBuilder authAtomId; - private final IntColumnBuilder pdbxPDBModelNum; + private final MmCifCategoryBuilder.AtomSiteBuilder atomSiteBuilder; + private final StrColumnBuilder groupPDB; + private final IntColumnBuilder id; + private final StrColumnBuilder typeSymbol; + private final StrColumnBuilder labelAtomId; + private final StrColumnBuilder labelAltId; + private final StrColumnBuilder labelCompId; + private final StrColumnBuilder labelAsymId; + private final StrColumnBuilder labelEntityId; + private final IntColumnBuilder labelSeqId; + private final StrColumnBuilder pdbxPDBInsCode; + private final FloatColumnBuilder cartnX; + private final FloatColumnBuilder cartnY; + private final FloatColumnBuilder cartnZ; + private final FloatColumnBuilder occupancy; + private final FloatColumnBuilder bIsoOrEquiv; + private final IntColumnBuilder authSeqId; + private final StrColumnBuilder authCompId; + private final StrColumnBuilder authAsymId; + private final StrColumnBuilder authAtomId; + private final IntColumnBuilder pdbxPDBModelNum; AtomSiteCollector() { - this.atomSiteBuilder = new CategoryBuilder.AtomSiteBuilder(null); + this.atomSiteBuilder = new MmCifCategoryBuilder.AtomSiteBuilder(null); this.groupPDB = atomSiteBuilder.enterGroupPDB(); this.id = atomSiteBuilder.enterId(); this.typeSymbol = atomSiteBuilder.enterTypeSymbol(); @@ -286,7 +288,7 @@ public void accept(WrappedAtom wrappedAtom) { } AtomSiteCollector combine(AtomSiteCollector other) { - throw new UnsupportedOperationException("impl by calling addAll for all collection - not feeling like writing that code"); + throw new UnsupportedOperationException("impl by calling addAll for all collection"); } Category get() { diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImplTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImplTest.java index 84d23a875e..0d2ddaf4f6 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImplTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImplTest.java @@ -9,9 +9,10 @@ import org.biojava.nbio.structure.io.PDBFileParser; import org.junit.Test; import org.rcsb.cif.CifIO; -import org.rcsb.cif.model.CifFile; -import org.rcsb.cif.model.Column; +import org.rcsb.cif.model.IntColumn; import org.rcsb.cif.model.ValueKind; +import org.rcsb.cif.schema.StandardSchemata; +import org.rcsb.cif.schema.mm.MmCifFile; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -210,8 +211,8 @@ public void specialCases() throws IOException { "7 1S32 . D . GB 30268542 MET 1 'INTIATING METHIONINE' ? ? 7\n"+ "8 1S32 . H . GB 30268542 MET 1 'INTIATING METHIONINE' ? ? 8\n" + "#" ; - CifFile cifFile = CifIO.readFromInputStream(new ByteArrayInputStream(mmcifStr.getBytes())); - Column column = cifFile.getFirstBlock().getCategory("struct_ref_seq_dif").getColumn("seq_num"); + MmCifFile cifFile = CifIO.readFromInputStream(new ByteArrayInputStream(mmcifStr.getBytes())).as(StandardSchemata.MMCIF); + IntColumn column = cifFile.getFirstBlock().getStructRefSeqDif().getSeqNum(); assertNotNull(column); assertTrue(column.isDefined()); From 2d7dbf72b336977193fecd7c7899b5f4580e50aa Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Wed, 22 Jul 2020 14:06:13 -0700 Subject: [PATCH 143/769] Avoid another external dependency in test --- .../biojava/nbio/structure/io/FastaAFPChainConverterTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/FastaAFPChainConverterTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/FastaAFPChainConverterTest.java index 8ae41a91cd..da9242e80f 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/FastaAFPChainConverterTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/FastaAFPChainConverterTest.java @@ -134,7 +134,9 @@ public void testBug1() throws IOException, StructureException, CompoundNotFoundE String b = "----------------------------------------------------------------------lsYFSKqtqtynigkLFTIIELQSVLVTTYTDILGV----LTINVtsmeELARDMLNSMN----VAVVSSLVKNVNKLMEEYLRRHNKSCICYGSYSLYLINPNIRYGDIDILQTNSRTFLIDLAFLIKFITGNNIILSKIPYLRNYMVIKDENDNHIIDSFNIRQDTMNVVPKIFIDNIYIVDPtfqLLNMIKMFSQ---IDRLEDLS----KDPEKFNARMATMLEYvrythgIVFDG--KRNNMPMKCIIDENNRIVTVTTKDYFSFKKCLVYLDENVLSSDILDLNADTSCDFESVTNSVYLIHDNIMYTYFSNTILLSDKGKV---HEISARGLCAHILlyqmltsGEYkqCLSDLLNSMMN--RDKIPIYS--HTERDKKPGRHGFINIEKDIIVFnitlkiietylgrvpsvneyhmlksqarniqkitvfnkdifvslvkknkkrffsdvntsaseikdri"; // ========================================================================KQTQ=========NIGKLFTIIELQSVLVTTYTD====LTINV====TSMEELARDML====VAVVSSLVKNVNKLMEEYLRRHNKSCICYGSYSLYLINPNIRYGDIDILQTNSRTFLIDLAFLIKFITGNNIILSKIPYLRNYMVIKDENDNHIIDSFNIRQDTMNVVPKIFIDNIYIVDP===TFQLLNMIKM===IDRLEDLS====KFNARMATMLEYVRYT======HGIVF==KRNNMPMKCIIDENNRIVTVTTKDYFSFKKCLVYLDENVLSSDILDLNADTSCDFESVTNSVYLIHDNIMYTYFSNTILLSDKGKV===SARGLCAHILLYQ=======TSG==EYKQCLSDLLN==MNRDKIPI==HTERDKKPGRHGFINIEKDIIVF=================================================================== // ========================================================================YFSK=========LFTIIELQSVLVTTYTDILGV====LTINV====ELARDMLNSMN====VAVVSSLVKNVNKLMEEYLRRHNKSCICYGSYSLYLINPNIRYGDIDILQTNSRTFLIDLAFLIKFITGNNIILSKIPYLRNYMVIKDENDNHIIDSFNIRQDTMNVVPKIFIDNIYIVDP===LLNMIKMFSQ===IDRLEDLS====KDPEKFNARMATMLEY======IVFDG==KRNNMPMKCIIDENNRIVTVTTKDYFSFKKCLVYLDENVLSSDILDLNADTSCDFESVTNSVYLIHDNIMYTYFSNTILLSDKGKV===HEISARGLCAHIL=======GEY==CLSDLLNSMMN==RDKIPIYS==HTERDKKPGRHGFINIEKDIIVF=================================================================== - Structure structure = StructureTools.getStructure("d3er9b_"); + // Note: before BioJava 6.0.0, this used to get scop id d3er9b. The domain happens to be the whole of chain B. To avoid dependence on Berkeley Scop provider in tests we use directly the chain + //Structure structure = StructureTools.getStructure("d3er9b_"); + Structure structure = StructureTools.getStructure("3er9.B"); AFPChain afpChain = FastaAFPChainConverter.cpFastaToAfpChain(a, b, structure, 67); assertEquals("Wrong RMSD", 2.681, afpChain.getTotalRmsdOpt(), 0.001); assertEquals("Wrong TM-score", 0.69848, afpChain.getTMScore(), 0.001); From a5f78faa30e9ecd5e3bab785c7e8445d80e4df85 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 23 Jul 2020 16:28:03 -0700 Subject: [PATCH 144/769] Replacing scop id by hard-coded range in test --- .../internal/TestSequenceFunctionOrderDetector.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/symmetry/internal/TestSequenceFunctionOrderDetector.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/symmetry/internal/TestSequenceFunctionOrderDetector.java index 6df1faf477..d59261195b 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/symmetry/internal/TestSequenceFunctionOrderDetector.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/symmetry/internal/TestSequenceFunctionOrderDetector.java @@ -37,7 +37,7 @@ import org.junit.Test; /** - * Originally part of {@link CeSymmTest}. + * Originally part of {@link TestCeSymm}. * @author Spencer Bliven */ public class TestSequenceFunctionOrderDetector { @@ -45,12 +45,13 @@ public class TestSequenceFunctionOrderDetector { @Test public void testGetSymmetryOrder() throws IOException, StructureException, RefinerFailedException { // List of alignments to try, along with proper symmetry - Map orderMap = new HashMap(); + Map orderMap = new HashMap<>(); orderMap.put("1itb.A",3); // b-trefoil, C3 orderMap.put("1tim.A",2); // tim-barrel, C8 //orderMap.put("d1p9ha_",-1); // not rotational symmetry orderMap.put("3HKE.A",2); // very questionable alignment - orderMap.put("d1jlya1",3); // a very nice trefoil + // Before BioJava 6.0.0, this used to get a scop domain directly (d1jlya1), now hardcoding range to avoid external resources + orderMap.put("1JLY.A_1-153", 3); // a very nice trefoil AtomCache cache = new AtomCache(); From c76aca83af2e0b94d3be49352cbe425f059c9be2 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 23 Jul 2020 16:32:30 -0700 Subject: [PATCH 145/769] Better way of specifying hard-coded domains --- .../nbio/structure/align/ce/CeCPMainTest.java | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java index 319cf25f10..1be0ed0e6f 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/ce/CeCPMainTest.java @@ -34,9 +34,7 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; /** @@ -407,26 +405,13 @@ private Atom[] makeDummyCA(int len) throws PDBParseException { @Test public void testCECP1() throws IOException, StructureException{ - String pdb1 = "3A2K"; - //String name1 = "PDP:3A2KAc"; // A : 234-333 - String pdb2 = "1WY5"; - //String name2 = "d1wy5a2"; // A : 217-311 - AtomCache cache = new AtomCache(); // since BioJava 6.0.0, there's no PDP provider. The below corresponds to domain "PDP:3A2KAc" - List ranges = new ArrayList<>(); - ranges.add(new ResidueRange("A", new ResidueNumber("A",234, null), new ResidueNumber("A", 333, null))); - SubstructureIdentifier ssi = new SubstructureIdentifier(pdb1, ranges); - Structure structure1 = cache.getStructure(pdb1); - ssi.reduce(structure1); + Structure structure1 = cache.getStructure("3A2K.A_234-333"); // since BioJava 6.0.0, there's no RemoteSCOP provider. The below corresponds to domain "d1wy5a2" - ranges = new ArrayList<>(); - ranges.add(new ResidueRange("A", new ResidueNumber("A",217, null), new ResidueNumber("A", 311, null))); - ssi = new SubstructureIdentifier(pdb2, ranges); - Structure structure2 = cache.getStructure(pdb2); - ssi.reduce(structure2); + Structure structure2 = cache.getStructure("1WY5.A_217-311"); CeCPMain algorithm = new CeCPMain(); From aae39db1e3f52750acf802a6b60c90e582a2bb28 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 23 Jul 2020 21:02:54 -0700 Subject: [PATCH 146/769] Removing all code that called the legacy rcsb pdb apis --- CHANGELOG.md | 1 + .../structure/rcsb/GetRepresentatives.java | 129 ------ .../nbio/structure/rcsb/PdbIdLists.java | 293 -------------- .../nbio/structure/rcsb/RCSBDescription.java | 64 --- .../rcsb/RCSBDescriptionFactory.java | 188 --------- .../nbio/structure/rcsb/RCSBLigand.java | 110 ------ .../nbio/structure/rcsb/RCSBLigands.java | 64 --- .../structure/rcsb/RCSBLigandsFactory.java | 366 ------------------ .../structure/rcsb/RCSBMacromolecule.java | 63 --- .../nbio/structure/rcsb/RCSBPolymer.java | 145 ------- .../nbio/structure/rcsb/RCSBTaxonomy.java | 53 --- .../nbio/structure/rcsb/RCSBUpdates.java | 89 ----- .../nbio/structure/rcsb/ReadUtils.java | 135 ------- 13 files changed, 1 insertion(+), 1699 deletions(-) delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/GetRepresentatives.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/PdbIdLists.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBDescription.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBDescriptionFactory.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigand.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigands.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigandsFactory.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBMacromolecule.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBPolymer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBTaxonomy.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBUpdates.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/ReadUtils.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 2218b88ed9..377e6fea62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ BioJava 6.0.0 (future release) * PDP domain providers (depended on JFatCatClient) * Support for retrieving structure data with prefix "PDP:" (AtomCache, StructureIO) * RemoteScopInstallation consuming data provided by source.rcsb.org +* The whole `org.biojava.nbio.structure.rcsb` package, a client for the now legacy RCSB PDB APIs (to be shutdown in Nov 2020) BioJava 5.4.0 ============= diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/GetRepresentatives.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/GetRepresentatives.java deleted file mode 100644 index 6d37ab4b24..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/GetRepresentatives.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.rcsb; - -import org.biojava.nbio.structure.align.client.StructureName; -import org.biojava.nbio.structure.align.util.URLConnectionTools; -import org.biojava.nbio.structure.align.xml.RepresentativeXMLConverter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.Arrays; -import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; - -/** - * TODO Move this to {@link Representatives}. - */ -public class GetRepresentatives { - - private static final Logger logger = LoggerFactory.getLogger(GetRepresentatives.class); - - private static String clusterUrl = "http://www.rcsb.org/pdb/rest/representatives?cluster="; - private static String allUrl = "http://www.rcsb.org/pdb/rest/getCurrent/"; - - // available sequence clusters - private static List seqIdentities = Arrays.asList(30, 40, 50, 70, 90, 95, 100); - - - /** - * Returns a representative set of PDB protein chains at the specified sequence - * identity cutoff. See http://www.pdb.org/pdb/statistics/clusterStatistics.do - * for more information. - * @param sequenceIdentity sequence identity threshold - * @return PdbChainKey set of representatives - */ - public static SortedSet getRepresentatives(int sequenceIdentity) { - SortedSet representatives = new TreeSet(); - - if (!seqIdentities.contains(sequenceIdentity)) { - System.err.println("Error: representative chains are not available for %sequence identity: " - + sequenceIdentity); - return representatives; - } - - - try { - - URL u = new URL(clusterUrl + sequenceIdentity); - - InputStream stream = URLConnectionTools.getInputStream(u, 60000); - - String xml = null; - - if (stream != null) { - xml = ReadUtils.convertStreamToString(stream); - - SortedSet reps = RepresentativeXMLConverter.fromXML(xml); - - for (String s : reps) { - StructureName k = new StructureName(s); - representatives.add(k); - } - - } - - } catch (Exception e) { - e.printStackTrace(); - } - - return representatives; - } - - /** - * Returns the current list of all PDB IDs. - * @return PdbChainKey set of all PDB IDs. - */ - public static SortedSet getAll() { - SortedSet representatives = new TreeSet(); - - try { - - URL u = new URL(allUrl); - - InputStream stream = URLConnectionTools.getInputStream(u, 60000); - - if (stream != null) { - BufferedReader reader = new BufferedReader( - new InputStreamReader(stream)); - - String line = null; - - while ((line = reader.readLine()) != null) { - int index = line.lastIndexOf("structureId="); - if (index > 0) { - representatives.add(line.substring(index + 13, index + 17)); - } - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - - return representatives; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/PdbIdLists.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/PdbIdLists.java deleted file mode 100644 index 78f1ea8c9e..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/PdbIdLists.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.rcsb; - -import java.io.*; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLEncoder; -import java.util.*; - -/** - * Utility classes for retrieving lists of PDB IDs. - * - * @author Andreas Prlic - * @since 4.2.0 - */ -public class PdbIdLists { - - /** get the list of current PDB IDs - * - * @return list of current PDB IDs - * @throws IOException - */ - public static Set getCurrentPDBIds() throws IOException { - String xml ="\n" + - " head\n" + - " org.pdb.query.simple.HoldingsQuery\n" + - " Holdings : All Structures\n" + - " ignore\n" + - " ignore\n" + - " "; - - return postQuery(xml); - } - - - /** Get the PDB IDs of all virus structures in the current PDB - * - * @return list of all virus structures - * @throws IOException - */ - public static Set getAllViruses() throws IOException{ - String xml = "\n" + - " head\n" + - " org.pdb.query.simple.EntriesOfEntitiesQuery\n" + - " Entries of :Oligomeric state Search : Min Number of oligomeric state=PAU\n" + - " and\n" + - " TaxonomyTree Search for Viruses\n" + - " \n" + - " \n" + - " \n" + - " 0\n" + - " \n" + - " head\n" + - " org.pdb.query.simple.BiolUnitQuery\n" + - " Oligomeric state Search : Min Number of oligomeric state=PAU \n" + - " PAU\n" + - " \n" + - " \n" + - " \n" + - " 1\n" + - " and\n" + - " \n" + - " head\n" + - " org.pdb.query.simple.TreeEntityQuery\n" + - " TaxonomyTree Search for Viruses\n" + - " 1\n" + - " 10239\n" + - " Viruses\n" + - " \n" + - " \n" + - " ]]>\n" + - " "; - - return postQuery(xml); - } - - - /** get list of all current NMR structures - * - * @return list of NMR structures - * @throws IOException - */ - public static Set getNMRStructures() throws IOException{ - String xml = "\n" + - " \n" + - " 0\n" + - " \n" + - " head\n" + - " org.pdb.query.simple.HoldingsQuery\n" + - " Holdings : All Structures\n" + - " ignore\n" + - " ignore\n" + - " \n" + - " \n" + - " \n" + - " 1\n" + - " and\n" + - " \n" + - " head\n" + - " org.pdb.query.simple.ExpTypeQuery\n" + - " Experimental Method is SOLUTION NMR\n" + - " SOLUTION NMR\n" + - " y\n" + - " \n" + - " \n" + - "\n"; - - - return postQuery(xml); - } - - - /** get all PDB IDs of gag-polyproteins - * - * @return list of PDB IDs - * @throws IOException - */ - public static Set getGagPolyproteins() throws IOException { - String xml = "\n" + - " \n" + - " 0\n" + - " \n" + - " head\n" + - " org.pdb.query.simple.HoldingsQuery\n" + - " Holdings : All Structures\n" + - " ignore\n" + - " ignore\n" + - " \n" + - " \n" + - " \n" + - " 1\n" + - " and\n" + - " \n" + - " head\n" + - " org.pdb.query.simple.MacroMoleculeQuery\n" + - " Molecule : Gag-Pol polyprotein [A1Z651, O12158, P03355, P03366, P03367, P03369, P04584, P04585, P04586, P04587, P04588, P05896, P05897, P05959, P05961, P0C6F2, P12497, P12499, P18042, P19505 ... ]\n" + - " A1Z651,O12158,P03355,P03366,P03367,P03369,P04584,P04585,P04586,P04587,P04588,P05896,P05897,P05959,P05961,P0C6F2,P12497,P12499,P18042,P19505,P19560,P20875,P24740,P35963,Q699E2,Q70XD7,Q72547,Q7SMT3,Q7SPG9,Q90VT5\n" + - " \n" + - " \n" + - ""; - - return postQuery(xml); - } - - /** get all Transmembrane proteins - * - * @return list of PDB IDs - * @throws IOException - */ - public static Set getTransmembraneProteins() throws IOException { - String xml = " \n" + - " head\n" + - " org.pdb.query.simple.TreeQuery\n" + - " TransmembraneTree Search for root\n" + - " 19\n" + - " 0\n" + - " root\n" + - " "; - - return postQuery(xml); - } - - public static Set getNucleotides() throws IOException{ - String xml ="\n" + - " head\n" + - " org.pdb.query.simple.ChainTypeQuery\n" + - " Chain Type: there is not any Protein chain\n" + - " N\n" + - " ?\n" + - " ?\n" + - " ?\n" + - " "; - return postQuery(xml); - } - - public static SetgetRibosomes() throws IOException{ - String xml = "\n" + - " head\n" + - " org.pdb.query.simple.StructureKeywordsQuery\n" + - " StructureKeywordsQuery: struct_keywords.pdbx_keywords.comparator=contains struct_keywords.pdbx_keywords.value=RIBOSOME \n" + - " contains\n" + - " RIBOSOME\n" + - " "; - - return postQuery(xml); - } - - public static final String SERVICELOCATION="http://www.rcsb.org/pdb/rest/search"; - - - /** post am XML query (PDB XML query format) to the RESTful RCSB web service - * - * @param xml - * @return a list of PDB ids. - */ - public static Set postQuery(String xml) - throws IOException{ - - //System.out.println(xml); - - - URL u = new URL(SERVICELOCATION); - - - String encodedXML = URLEncoder.encode(xml,"UTF-8"); - - - InputStream in = doPOST(u,encodedXML); - - Set pdbIds = new TreeSet(); - - - try (BufferedReader rd = new BufferedReader(new InputStreamReader(in))) { - - String line; - while ((line = rd.readLine()) != null) { - - pdbIds.add(line); - - } - rd.close(); - } - - - return pdbIds; - - - - } - - /** do a POST to a URL and return the response stream for further processing elsewhere. - * - * - * @param url - * @return - * @throws IOException - */ - public static InputStream doPOST(URL url, String data) - - throws IOException - { - - // Send data - - URLConnection conn = url.openConnection(); - - conn.setDoOutput(true); - - try(OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream())) { - - wr.write(data); - wr.flush(); - } - - - // Get the response - return conn.getInputStream(); - - }; - - public static void main(String[] args){ - try { - System.out.println("Current PDB status: " + getCurrentPDBIds().size()); - System.out.println("Virus structures: " + getAllViruses().size()); - System.out.println("NMR structures: " + getNMRStructures().size()); - System.out.println("Gag-polyproteins: " + getGagPolyproteins().size()); - System.out.println("Transmembrane proteins: " + getTransmembraneProteins().size()); - System.out.println("Nucleotide: " + getNucleotides().size()); - System.out.println("Ribosomes: " + getRibosomes().size()); - } catch ( Exception e){ - e.printStackTrace(); - } - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBDescription.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBDescription.java deleted file mode 100644 index 6c738697c9..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBDescription.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2012-11-20 - * Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -import java.util.ArrayList; -import java.util.List; - -/** - * Corresponds to the wrapper element in an RCSB {@code describeMol} XML file. - * - * @see RCSB RESTful - * - * @author dmyerstu - * @since 3.0.6 - */ -public class RCSBDescription { - - private String pdbId; - - private List polymers; - - public RCSBDescription() { - polymers = new ArrayList(); - } - - public void addPolymer(RCSBPolymer polymer) { - polymers.add(polymer); - } - - public String getPdbId() { - return pdbId; - } - - public List getPolymers() { - return polymers; - } - - void setPdbId(String pdbId) { - this.pdbId = pdbId; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBDescriptionFactory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBDescriptionFactory.java deleted file mode 100644 index f181a39e6b..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBDescriptionFactory.java +++ /dev/null @@ -1,188 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the terms of the GNU Lesser General Public Licence. This - * should be distributed with the code. If you do not have a copy, see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2012-11-20 Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; - -/** - * Fetches information from RCSB's RESTful Web Service - * Interface. A factory for {@link RCSBDescription RCSBDescriptions} from {@code describeMol} XML files. The factory - * methods will return null if the data was not found (rather than throwing an exception); client code should test for - * this. This is for consistency: if the factory could not read some part (corresponding to a field in a class in - * {@code rcsb.descriptions}) of the XML file, either because it was blank or contained an error that could not be - * safely ignored, that field will simply be null. This holds even for numerical values. On some parse errors, the error - * will additionally be printed to standard error. - * - * Example usage: - * - *

    - * RCSBDescription description = RCSBDescriptionFactory.get("1w0p");
    - * RCSBLigand firstLigand = ligands.getLigands().get(0);
    - * System.out.println(description.getPdbId()); // prints "1w0p"
    - * 
    - * - * @see RCSB RESTful - * - * TODO: Handle queries with more than 1 PDB Id. - * - * @author dmyerstu - * @since 3.0.6 - */ -public class RCSBDescriptionFactory { - - private static final Logger logger = LoggerFactory.getLogger(RCSBDescriptionFactory.class); - - private static final String URL_STUB = "http://www.rcsb.org/pdb/rest/describeMol?structureId="; - - /** - * @return An {@link RCSBDescription} from the XML file loaded as {@code stream}. Prefer calling - * {@link #get(String)} if you want data directly from RCSB's RESTful service. - * @see RCSBDescriptionFactory#get(String) - */ - public static RCSBDescription get(InputStream stream) { - - NodeList data; - try { - data = ReadUtils.getNodes(stream); - } catch (IOException e) { - logger.warn("Couldn't parse XML", e); - return null; - } - - // first get the main info - RCSBDescription description = new RCSBDescription(); - Element structureIdE = null; - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - structureIdE = (Element) data.item(i); - if (structureIdE.getNodeName().equals("structureId")) { - description.setPdbId(structureIdE.getAttribute("id")); - } - } - - // now get polymers - data = structureIdE.getChildNodes(); - Element polymerE = null; - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - polymerE = (Element) data.item(i); - if (polymerE.getNodeName().equals("polymer")) { - RCSBPolymer polymer = makePolymer(polymerE); - description.addPolymer(polymer); - } - } - - return description; - - } - - /** - * @return An {@link RCSBDescription} from the XML file at - * {@code "http://www.pdb.org/pdb/rest/describeMol?structureId=pdbId"}. This is the preferred factory - * method, unless a different URL or input source is required. - * @see RCSBDescriptionFactory#get(InputStream) - */ - public static RCSBDescription get(String pdbId) { - InputStream is; - try { - URL url = new URL(URL_STUB + pdbId); - is = url.openConnection().getInputStream(); - } catch (IOException e) { - logger.warn("Couldn't open connection", e); - return null; - } - return get(is); - } - - private static RCSBMacromolecule makeMolecule(Element moleculeE) { - RCSBMacromolecule molecule = new RCSBMacromolecule(); - molecule.setName(moleculeE.getAttribute("name")); - Element element = null; - NodeList data = moleculeE.getChildNodes(); - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - element = (Element) data.item(i); - if (element.getNodeName().equals("accession")) { - molecule.addAccession(element.getAttribute("id")); - } - } - return molecule; - } - - private static RCSBPolymer makePolymer(Element polymerE) { - - RCSBPolymer polymer = new RCSBPolymer(); - polymer.setIndex(ReadUtils.toInt(polymerE.getAttribute("entityNr"))); - polymer.setLength(ReadUtils.toInt(polymerE.getAttribute("length"))); - polymer.setWeight(ReadUtils.toDouble(polymerE.getAttribute("weight"))); - polymer.setType(ReadUtils.toStr(polymerE.getAttribute("type"))); - - Element element = null; - NodeList data = polymerE.getChildNodes(); - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - element = (Element) data.item(i); - if (element.getNodeName().equals("chain")) { - parseChains(polymer, element.getAttribute("id")); - } else if (element.getNodeName().equals("Taxonomy")) { - String name = element.getAttribute("name"); - int id = ReadUtils.toInt(element.getAttribute("id")); - RCSBTaxonomy taxonomy = new RCSBTaxonomy(name, id); - polymer.setTaxonomy(taxonomy); - } else if (element.getNodeName().equals("macroMolecule")) { - RCSBMacromolecule molecule = makeMolecule(element); - polymer.setMolecule(molecule); - } else if (element.getNodeName().equals("polymerDescription")) { - polymer.setDescription(element.getAttribute("description")); - } else if (element.getNodeName().equals("enzClass")) { - polymer.setEnzClass(element.getAttribute("ec")); - } else if (element.getNodeName().equals("synonym")) { - parseSynonyms(polymer, element.getAttribute("name")); - } - } - return polymer; - } - - private static void parseChains(RCSBPolymer polymer, String string) { - String[] parts = string.split("\\s*,\\s*"); - for (String part : parts) { - if (part.length() == 1) { - polymer.addChain(part.charAt(0)); - } else { - logger.warn("Chain id contained more than one character"); - } - } - } - - private static void parseSynonyms(RCSBPolymer polymer, String string) { - String[] parts = string.split("\\s*,\\s*"); - for (String part : parts) { - polymer.addSynonym(part); - } - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigand.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigand.java deleted file mode 100644 index 6eaf940eab..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigand.java +++ /dev/null @@ -1,110 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2013-06-13 - * Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -/** - * Corresponds to a ligand in a {@code ligandInfo} XML file. - * - * @see RCSB RESTful - * - * @author dmyerstu - * @since 3.0.6 - */ -public class RCSBLigand { - - private String formula; - private String id; - private String inChI; - private String inChIKey; - private String name; - private String smiles; - private String type; - private Double weight; - - public String getFormula() { - return formula; - } - - public String getId() { - return id; - } - - public String getInChI() { - return inChI; - } - - public String getInChIKey() { - return inChIKey; - } - - public String getName() { - return name; - } - - public String getSmiles() { - return smiles; - } - - public String getType() { - return type; - } - - public Double getWeight() { - return weight; - } - - public void setFormula(String formula) { - this.formula = formula; - } - - public void setId(String id) { - this.id = id; - } - - public void setInChI(String inChI) { - this.inChI = inChI; - } - - public void setInChIKey(String inChIKey) { - this.inChIKey = inChIKey; - } - - public void setName(String name) { - this.name = name; - } - - public void setSmiles(String smiles) { - this.smiles = smiles; - } - - public void setType(String type) { - this.type = type; - } - - public void setWeight(Double weight) { - this.weight = weight; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigands.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigands.java deleted file mode 100644 index 2b06448fd0..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigands.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2013-06-13 - * Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -import java.util.ArrayList; -import java.util.List; - -/** - * Corresponds to the wrapper element "ligandInfo" in an RCSB {@code ligandInfo} XML file. - * - * @see RCSB RESTful - * - * @author dmyerstu - * @since 3.0.6 - */ -public class RCSBLigands { - - private String pdbId; - - private List ligands; - - public RCSBLigands() { - ligands = new ArrayList(); - } - - public void addLigand(RCSBLigand ligand) { - ligands.add(ligand); - } - - public String getPdbId() { - return pdbId; - } - - public List getLigands() { - return ligands; - } - - void setPdbId(String pdbId) { - this.pdbId = pdbId; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigandsFactory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigandsFactory.java deleted file mode 100644 index 723bbfac5a..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBLigandsFactory.java +++ /dev/null @@ -1,366 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the terms of the GNU Lesser General Public Licence. This - * should be distributed with the code. If you do not have a copy, see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2013-06-13 Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -/** - * Fetches information from RCSB's RESTful Web Service - * Interface. A factory for {@link RCSBLigands RCSBLigands} from {@code ligandInfo} XML files. The factory methods - * will return null if the data was not found (rather than throwing an exception); client code should test for this. - * This is for consistency: if the factory could not read some part (corresponding to a field in a class in - * {@code rcsb.descriptions}) of the XML file, either because it was blank or contained an error that could not be - * safely ignored, that field will simply be null. This holds even for numerical values. On some parse errors, the error - * will additionally be printed to standard error. - * - * Example usage: - * - *
    - * RCSBLigands ligands = RCSBLigandsFactory.getFromPdbIds("1w0p");
    - * List<RCSBLigand> list = ligands.getLigands();
    - * System.out.println(list.get(0).getFormula()); // prints "CA 2"
    - * System.out.println(list.get(1).getFormula()); // prints "C11 H19 N O9"
    - * 
    - * - * @see RCSB RESTful - * - * @author dmyerstu - * @since 3.0.6 - */ - -public class RCSBLigandsFactory { - - private static final String HET_URL_STUB = "http://www.rcsb.org/pdb/rest/describeHet?chemicalID="; - - private static final Logger logger = LoggerFactory.getLogger(RCSBLigandsFactory.class); - - private static final String PDB_URL_STUB = "http://www.rcsb.org/pdb/rest/ligandInfo?structureId="; - - /** - * @return A list of {@link RCSBLigand RCSBLigands} from the XML file loaded as {@code stream}. Prefer calling - * {@link #getFromHeteroAtomId(String)} if you want data directly from RCSB's RESTful service. - * @see RCSBDescriptionFactory#get(String) - */ - public static RCSBLigand getFromHeteroAtomId(InputStream stream) { - return getFromHeteroAtomIds(stream).get(0); - } - - /** - * @return An {@link RCSBLigands} from the XML file at - * {@code "http://www.pdb.org/pdb/rest/describeHet?chemicalID=hetid"}. This is the preferred factory method, - * unless a different URL or input source is required. - * @see RCSBDescriptionFactory#get(InputStream) - */ - public static RCSBLigand getFromHeteroAtomId(String heteroAtomId) { - return getFromHeteroAtomIds(heteroAtomId).get(0); - } - - /** - * @return A list of {@link RCSBLigand RCSBLigands} from the XML file loaded as {@code stream}. Prefer calling - * {@link #getFromHeteroAtomId(String)} if you want data directly from RCSB's RESTful service. - * @see RCSBDescriptionFactory#get(String) - */ - public static List getFromHeteroAtomIds(InputStream stream) { - - NodeList data; - try { - data = ReadUtils.getNodes(stream); - } catch (IOException e) { - logger.warn("Couldn't parse XML", e); - return null; - } - - List ligands = new ArrayList(); - - // first get the ligandInfo - Element structureIdE = null; - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - structureIdE = (Element) data.item(i); - if (structureIdE.getNodeName().equals("ligandInfo")) { - break; - } - } - - // now get individual ligands - data = structureIdE.getChildNodes(); - Element ligandE = null; - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - ligandE = (Element) data.item(i); - if (ligandE.getNodeName().equals("ligand")) { - RCSBLigand ligand = makeLigand(ligandE); - ligands.add(ligand); - } - } - - return ligands; - - } - - /** - * @return An {@link RCSBLigands} from the XML file at - * {@code "http://www.pdb.org/pdb/rest/describeHet?chemicalID=hetid"}. This is the preferred factory method, - * unless a different URL or input source is required. - * @see RCSBDescriptionFactory#get(InputStream) - */ - public static List getFromHeteroAtomIds(List heteroAtomIds) { - String[] x = new String[heteroAtomIds.size()]; - heteroAtomIds.toArray(x); - return getFromHeteroAtomIds(x); // somewhat cheating here - } - - /** - * @return An {@link RCSBLigands} from the XML file at - * {@code "http://www.pdb.org/pdb/rest/describeHet?chemicalID=hetid"}. This is the preferred factory method, - * unless a different URL or input source is required. - * @see RCSBDescriptionFactory#get(InputStream) - */ - public static List getFromHeteroAtomIds(String... heteroAtomIds) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < heteroAtomIds.length; i++) { - if (i > 0) sb.append(","); - sb.append(heteroAtomIds[i]); - } - InputStream is; - try { - URL url = new URL(HET_URL_STUB + sb.toString()); - is = url.openConnection().getInputStream(); - } catch (IOException e) { - logger.warn("Couldn't open connection", e); - return null; - } - return getFromHeteroAtomIds(is); - } - - /** - * @return An {@link RCSBLigands} from the XML file loaded as {@code stream}. Prefer calling - * {@link #getFromPdbId(String)} if you want data directly from RCSB's RESTful service. - * @see RCSBDescriptionFactory#get(String) - */ - public static RCSBLigands getFromPdbId(InputStream stream) { - - NodeList data; - try { - data = ReadUtils.getNodes(stream); - } catch (IOException e) { - logger.warn("Couldn't parse XML", e); - return null; - } - - // first get the ligandInfo - RCSBLigands ligands = new RCSBLigands(); - Element structureIdE = null; - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - structureIdE = (Element) data.item(i); - if (structureIdE.getNodeName().equals("ligandInfo")) { - break; - } - } - - // now get individual ligands - data = structureIdE.getChildNodes(); - Element ligandE = null; - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - ligandE = (Element) data.item(i); - if (ligandE.getNodeName().equals("ligand")) { - if (ligands.getPdbId() == null) { - ligands.setPdbId(ligandE.getAttribute("structureId")); - } - RCSBLigand ligand = makeLigand(ligandE); - ligands.addLigand(ligand); - } - } - - return ligands; - - } - - /** - * @return An {@link RCSBLigands} from the XML file at - * {@code "http://www.pdb.org/pdb/rest/describeMol?structureId=pdbId"}. This is the preferred factory - * method, unless a different URL or input source is required. - * @see RCSBDescriptionFactory#get(InputStream) - */ - public static RCSBLigands getFromPdbId(String pdbId) { - InputStream is; - try { - URL url = new URL(PDB_URL_STUB + pdbId); - is = url.openConnection().getInputStream(); - } catch (IOException e) { - logger.warn("Couldn't open connection", e); - return null; - } - return getFromPdbId(is); - } - - /** - * @return An {@link RCSBLigands} from the XML file loaded as {@code stream}. Prefer calling - * {@link #getFromPdbId(String)} if you want data directly from RCSB's RESTful service. - * @see RCSBDescriptionFactory#get(String) - */ - public static List getFromPdbIds(InputStream stream) { - - NodeList dataaa; - try { - dataaa = ReadUtils.getNodes(stream); - } catch (IOException e) { - logger.warn("Couldn't parse XML", e); - return null; - } - - // first we have to handle the element "ligandsInEntry", which is not present if we have only 1 structure - - List ligandsList = new ArrayList(); - - Element structureIdE = null; - - for (int k = 0; k < dataaa.getLength(); k++) { - - if (dataaa.item(k).getNodeType() != 1) continue; - structureIdE = (Element) dataaa.item(k); - if (structureIdE.getNodeName().equals("structureId")) { - - // now get the ligandInfo - NodeList data = structureIdE.getChildNodes(); - RCSBLigands ligands = new RCSBLigands(); - Element ligandIdE = null; - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - ligandIdE = (Element) data.item(i); - if (ligandIdE.getNodeName().equals("ligandInfo")) { - break; - } - } - - // now get individual ligands - data = ligandIdE.getChildNodes(); - Element ligandE = null; - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - ligandE = (Element) data.item(i); - if (ligandE.getNodeName().equals("ligand")) { - if (ligands.getPdbId() == null) { - ligands.setPdbId(ligandE.getAttribute("structureId")); - } - RCSBLigand ligand = makeLigand(ligandE); - ligands.addLigand(ligand); - } - } - - ligandsList.add(ligands); - - } - } - - return ligandsList; - - } - - /** - * @return An {@link RCSBLigands} from the XML file at - * {@code "http://www.pdb.org/pdb/rest/describeMol?structureId=pdbId"}. This is the preferred factory - * method, unless a different URL or input source is required. - * @see RCSBDescriptionFactory#get(InputStream) - */ - public static List getFromPdbIds(List pdbIds) { - String[] x = new String[pdbIds.size()]; - pdbIds.toArray(x); - return getFromPdbIds(x); - } - - /** - * @return An {@link RCSBLigands} from the XML file at - * {@code "http://www.pdb.org/pdb/rest/describeMol?structureId=pdbId"}. This is the preferred factory - * method, unless a different URL or input source is required. - * @see RCSBDescriptionFactory#get(InputStream) - */ - public static RCSBLigands getFromPdbIds(String pdbId) { - InputStream is; - try { - URL url = new URL(PDB_URL_STUB + pdbId); - is = url.openConnection().getInputStream(); - } catch (IOException e) { - logger.warn("Couldn't open connection", e); - return null; - } - return getFromPdbId(is); - } - - /** - * @return An {@link RCSBLigands} from the XML file at - * {@code "http://www.pdb.org/pdb/rest/describeMol?structureId=pdbId"}. This is the preferred factory - * method, unless a different URL or input source is required. - * @see RCSBDescriptionFactory#get(InputStream) - */ - public static List getFromPdbIds(String... pdbIds) { - InputStream is; - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < pdbIds.length; i++) { - if (i > 0) sb.append(","); - sb.append(pdbIds[i]); - } - try { - URL url = new URL(PDB_URL_STUB + sb.toString()); - is = url.openConnection().getInputStream(); - } catch (IOException e) { - logger.warn("Couldn't open connection", e); - return null; - } - return getFromPdbIds(is); - } - - private static RCSBLigand makeLigand(Element ligandE) { - RCSBLigand ligand = new RCSBLigand(); - ligand.setId(ligandE.getAttribute("chemicalID")); - ligand.setType(ligandE.getAttribute("type")); - ligand.setWeight(ReadUtils.toDouble(ligandE.getAttribute("molecularWeight"))); - Element element = null; - NodeList data = ligandE.getChildNodes(); - for (int i = 0; i < data.getLength(); i++) { - if (data.item(i).getNodeType() != 1) continue; - element = (Element) data.item(i); - if (element.getNodeName().equals("chemicalName")) { - ligand.setName(element.getTextContent()); - } else if (element.getNodeName().equals("formula")) { - ligand.setFormula(element.getTextContent()); - } else if (element.getNodeName().equals("InChIKey")) { - ligand.setInChIKey(element.getTextContent()); - } else if (element.getNodeName().equals("InChI")) { - ligand.setInChI(element.getTextContent()); - } else if (element.getNodeName().equals("smiles")) { - ligand.setSmiles(element.getTextContent()); - } - } - return ligand; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBMacromolecule.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBMacromolecule.java deleted file mode 100644 index 5ab13502fa..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBMacromolecule.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2012-11-20 - * Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -import java.util.ArrayList; -import java.util.List; - -/** - * Corresponds to a macromolecule in an RCSB {@code describeMol} XML file. - * - * @see RCSB RESTful - * - * @author dmyerstu - * @since 3.0.6 - */ -public class RCSBMacromolecule { - - private List accessions; - private String name; - - public RCSBMacromolecule() { - accessions = new ArrayList(); - } - - public List getAccessions() { - return accessions; - } - - public String getName() { - return name; - } - - void addAccession(String e) { - accessions.add(e); - } - - void setName(String name) { - this.name = name; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBPolymer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBPolymer.java deleted file mode 100644 index 1d3113e73b..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBPolymer.java +++ /dev/null @@ -1,145 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2012-11-20 - * Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -import java.util.ArrayList; -import java.util.List; - -/** - * Corresponds to a polymer in a {@code describeMol} XML file. - * - * @see RCSB RESTful - * - * @author dmyerstu - * @since 3.0.6 - */ -public class RCSBPolymer { - - private List chains; - - private String description; - - private String enzClass; - - private Integer index; - - private Integer length; - - private RCSBMacromolecule molecule; - - private List synonyms; - - private RCSBTaxonomy taxonomy; - - private String type; - - private Double weight; - - public RCSBPolymer() { - chains = new ArrayList(); - synonyms = new ArrayList(); - } - - public List getChains() { - return chains; - } - - public String getDescription() { - return description; - } - - public String getEnzClass() { - return enzClass; - } - - public Integer getIndex() { - return index; - } - - public Integer getLength() { - return length; - } - - public RCSBMacromolecule getMolecule() { - return molecule; - } - - public List getSynonyms() { - return synonyms; - } - - public RCSBTaxonomy getTaxonomy() { - return taxonomy; - } - - public String getType() { - return type; - } - - public Double getWeight() { - return weight; - } - - void addChain(char chain) { - chains.add(chain); - } - - void addSynonym(String synonym) { - synonyms.add(synonym); - } - - void setDescription(String description) { - this.description = description; - } - - void setEnzClass(String enzClass) { - this.enzClass = enzClass; - } - - void setIndex(Integer index) { - this.index = index; - } - - void setLength(Integer length) { - this.length = length; - } - - void setMolecule(RCSBMacromolecule molecule) { - this.molecule = molecule; - } - - void setTaxonomy(RCSBTaxonomy taxonomy) { - this.taxonomy = taxonomy; - } - - void setType(String string) { - type = string; - } - - void setWeight(Double weight) { - this.weight = weight; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBTaxonomy.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBTaxonomy.java deleted file mode 100644 index 0f3c667c08..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBTaxonomy.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2012-11-20 - * Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -/** - * Corresponds to a taxonomy in a {@code describeMol} XML file. - * - * @see RCSB RESTful - * - * @author dmyerstu - * @since 3.0.6 - */ -public class RCSBTaxonomy { - - private final int id; - private final String name; - - public RCSBTaxonomy(String name, int id) { - this.name = name; - this.id = id; - } - - public int getId() { - return id; - } - - public String getName() { - return name; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBUpdates.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBUpdates.java deleted file mode 100644 index b4860b2cf1..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/RCSBUpdates.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.rcsb; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class RCSBUpdates { - - // The URL for acquiring the data - public static final String baseURL = "http://ftp.rcsb.org/pub/pdb/data/status/latest/"; - - /** - * - * @return A map mapping each field (defined by a separate FTP file) to the PDB ids in the field. The possible fields - * are: added.models, added.nmr, added.pdb, added.sf, modified.cs, modified.models, modified.nmr, modified.pdb, modified.sf, - * obsolete.cs, obsolete.models, obsolete.nmr, obsolete.pdb, obsolete.sf - * @throws IOException - */ - public Map getUpdates() throws IOException{ - - Map outMap = new HashMap(); - // A list of files to get - String[] newStringList = {"added.models","added.nmr","added.pdb","added.sf","modified.cs","modified.models", - "modified.nmr","modified.pdb","modified.sf","obsolete.cs","obsolete.models","obsolete.nmr","obsolete.pdb","obsolete.sf"}; - for(String fileName: newStringList){ - String[] thisList = readURL(baseURL+""+fileName); - outMap.put(fileName, thisList); - } - return outMap; - - } - - - /** - * - * @param urlIn The url to be read - * @return A list of PDB ids as strings - * @throws IOException - */ - private String[] readURL(String urlIn) throws IOException{ - List outList = new ArrayList(); - // create a url object - URL url = new URL(urlIn); - - // create a urlconnection object - URLConnection urlConnection = url.openConnection(); - - // wrap the urlconnection in a bufferedreader - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()))) { - - String line; - - // read from the urlconnection via the bufferedreader - while ((line = bufferedReader.readLine()) != null) - { - outList.add(line); - } - - } - - return outList.toArray(new String[outList.size()]); - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/ReadUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/ReadUtils.java deleted file mode 100644 index ece82b16e3..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/rcsb/ReadUtils.java +++ /dev/null @@ -1,135 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2013-06-13 - * Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -/** - * Package-level static utilities for parsing XML. - * @author dmyerstu - */ -public class ReadUtils { - - private static final Logger logger = LoggerFactory.getLogger(ReadUtils.class); - - // this IS needed - private static boolean documentBuilderFactorySet = false; - - /** - * @param s - * @return {@code s}, or null if {@code s} is the empty string - */ - static String toStr(String s) { - if (s.isEmpty()) return null; - return s; - } - - /** - * @param stream - * @return A {@link NodeList} of top-level {@link Node Nodes} in {@code stream}. - * @throws IOException - */ - static NodeList getNodes(InputStream stream) throws IOException { - - if (!documentBuilderFactorySet) { // it's really stupid, but we have to do this - System.setProperty("javax.xml.parsers.DocumentBuilderFactory", - "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"); - documentBuilderFactorySet = true; - } - DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = null; - Document document = null; - try { - builder = builderFactory.newDocumentBuilder(); - } catch (ParserConfigurationException e) { - logger.warn("Couldn't configure parser", e); - stream.close(); - throw new IOException(e); - } - try { - document = builder.parse(stream); - } catch (SAXException e) { - stream.close(); - throw new IOException(e); - } - Node root = document.getDocumentElement(); - return root.getChildNodes(); - } - - static Double toDouble(String s) { - if (s.isEmpty()) return null; - try { - return Double.parseDouble(s); - } catch (NumberFormatException e) { - logger.warn(s + " is not a floating-point number", e); - } - return null; - } - - static Integer toInt(String s) { - if (s.isEmpty()) return null; - try { - return Integer.parseInt(s); - } catch (NumberFormatException e) { - logger.warn(s + " is not an integer", e); - } - return null; - } - - public static String convertStreamToString(InputStream stream){ - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - StringBuilder sb = new StringBuilder(); - - String line = null; - try { - while ((line = reader.readLine()) != null) { - sb.append(line).append("\n"); - } - } catch (IOException e) { - logger.error("Couldn't convert stream to string", e); // TODO dmyersturnbull: method should throw; we shouldn't catch here - } finally { - try { - stream.close(); - } catch (IOException e) { - logger.warn("Can't close stream", e); - } - } - - return sb.toString(); - } -} From b3610759476dbcadcca2b875037513ca13212c9c Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 23 Jul 2020 21:14:00 -0700 Subject: [PATCH 147/769] Removing tests for rcsb legacy api code --- .../rcsb/RCSBDescriptionFactoryTest.java | 239 ------------------ .../rcsb/RCSBLigandsFactoryTest.java | 123 --------- 2 files changed, 362 deletions(-) delete mode 100644 biojava-structure/src/test/java/org/biojava/nbio/structure/rcsb/RCSBDescriptionFactoryTest.java delete mode 100644 biojava-structure/src/test/java/org/biojava/nbio/structure/rcsb/RCSBLigandsFactoryTest.java diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/rcsb/RCSBDescriptionFactoryTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/rcsb/RCSBDescriptionFactoryTest.java deleted file mode 100644 index bef0e232c1..0000000000 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/rcsb/RCSBDescriptionFactoryTest.java +++ /dev/null @@ -1,239 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2012-11-20 - * Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -import org.junit.Test; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.util.List; - -import static org.junit.Assert.assertEquals; - -/** - * Tests {@link RCSBDescriptionFactory}. - * @author dmyerstu - * @since 3.0.6 - */ -public class RCSBDescriptionFactoryTest { - - private static final String TEST_DIR = "src/test/resources/"; - - /** - * Opens the file as a {@link FileInputStream}. Copied from ResourceList, which is not in biojava. - */ - private FileInputStream openStream(String filename) { - File file = new File(TEST_DIR + filename); - FileInputStream fis; - try { - fis = new FileInputStream(file); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - return fis; - } - - /** - * Tests on the live database. Just makes sure the resource can be found. - * If this test fails, it may be because the database changed. - */ - @Test - public void testUrl() { - RCSBDescriptionFactory.get("1w0p"); // just make sure it doesn't throw an exception - } - - /** - * Covers all the basic features, including EC numbers. Does not cover multiple polymers or multiple chains. - */ - @Test - public void test1() { - RCSBDescription description = RCSBDescriptionFactory.get(openStream("describeMol/1w0p.xml")); - - assertEquals("1W0P", description.getPdbId()); - List polymers = description.getPolymers(); - assertEquals(1, polymers.size()); - - RCSBPolymer polymer = polymers.get(0); - assertEquals("protein", polymer.getType()); - assertEquals(1, polymer.getIndex().intValue()); - assertEquals("SIALIDASE", polymer.getDescription()); - assertEquals("3.2.1.18", polymer.getEnzClass()); - assertEquals(781, polymer.getLength().intValue()); - assertEquals(85675.5, polymer.getWeight(), 0); - - List chains = polymer.getChains(); - assertEquals(1, chains.size()); - assertEquals('A', (char) chains.get(0)); - - List synonyms = polymer.getSynonyms(); - assertEquals(2, synonyms.size()); - assertEquals("NEURAMINIDASE", synonyms.get(0)); - assertEquals("NANASE", synonyms.get(1)); - - RCSBTaxonomy tax = polymer.getTaxonomy(); - assertEquals(666, tax.getId()); - assertEquals("Vibrio cholerae", tax.getName()); - - RCSBMacromolecule mol = polymer.getMolecule(); - assertEquals("Sialidase", mol.getName()); - List accessions = mol.getAccessions(); - assertEquals(4, accessions.size()); - assertEquals("A5F7A4", accessions.get(0)); - assertEquals("C3M1H8", accessions.get(1)); - assertEquals("P37060", accessions.get(2)); - assertEquals("Q9KR59", accessions.get(3)); - } - - /** - * What if we have a structureId but no polymers? - */ - @Test - public void testEmpty() { - RCSBDescription description = RCSBDescriptionFactory.get(openStream("describeMol/empty.xml")); - assertEquals("empty", description.getPdbId()); - List polymers = description.getPolymers(); - assertEquals(0, polymers.size()); - } - - /** - * What if we have polymers but no macroMolecule or chains? - * And what if a polymer contains no attributes? - */ - @Test - public void testAlmostEmpty() { - - RCSBDescription description = RCSBDescriptionFactory.get(openStream("describeMol/almost_empty.xml")); - assertEquals("almost_empty", description.getPdbId()); - List polymers = description.getPolymers(); - assertEquals(2, polymers.size()); - - RCSBPolymer polymer = polymers.get(0); - assertEquals("notype", polymer.getType()); - assertEquals(1, polymer.getIndex().intValue()); - assertEquals("really close to empty", polymer.getDescription()); - assertEquals(null, polymer.getEnzClass()); - assertEquals(10, polymer.getLength().intValue()); - assertEquals(0, polymer.getWeight(), 0); - - polymer = polymers.get(1); - assertEquals(null, polymer.getType()); // make sure these are null and not "" - assertEquals(null, polymer.getIndex()); - assertEquals(null, polymer.getDescription()); - assertEquals(null, polymer.getEnzClass()); - assertEquals(null, polymer.getLength()); - assertEquals(null, polymer.getWeight()); - - } - - /** - * Covers multiple polymers and multiple chains. - */ - @Test - public void test2() { - RCSBDescription description = RCSBDescriptionFactory.get(openStream("describeMol/4hhb.xml")); - assertEquals("4HHB", description.getPdbId()); - List polymers = description.getPolymers(); - assertEquals(2, polymers.size()); - - // first polymer - RCSBPolymer polymer = polymers.get(0); - assertEquals("protein", polymer.getType()); - assertEquals(1, polymer.getIndex().intValue()); - assertEquals("HEMOGLOBIN (DEOXY) (ALPHA CHAIN)", polymer.getDescription()); - assertEquals(null, polymer.getEnzClass()); - assertEquals(141, polymer.getLength().intValue()); - assertEquals(15150.5, polymer.getWeight(), 0); - - List chains = polymer.getChains(); - assertEquals(2, chains.size()); - assertEquals('A', (char) chains.get(0)); - assertEquals('C', (char) chains.get(1)); - - List synonyms = polymer.getSynonyms(); - assertEquals(0, synonyms.size()); - - RCSBTaxonomy tax = polymer.getTaxonomy(); - assertEquals(9606, tax.getId()); - assertEquals("Homo sapiens", tax.getName()); - - RCSBMacromolecule mol = polymer.getMolecule(); - assertEquals("Hemoglobin subunit alpha", mol.getName()); - List accessions = mol.getAccessions(); - assertEquals(8, accessions.size()); - assertEquals("P69905", accessions.get(0)); - assertEquals("P01922", accessions.get(1)); - assertEquals("Q1HDT5", accessions.get(2)); - assertEquals("Q3MIF5", accessions.get(3)); - assertEquals("Q53F97", accessions.get(4)); - assertEquals("Q96KF1", accessions.get(5)); - assertEquals("Q9NYR7", accessions.get(6)); - assertEquals("Q9UCM0", accessions.get(7)); - - // second polymer - polymer = polymers.get(1); - assertEquals("protein", polymer.getType()); - assertEquals(2, polymer.getIndex().intValue()); - assertEquals("HEMOGLOBIN (DEOXY) (BETA CHAIN)", polymer.getDescription()); - assertEquals(null, polymer.getEnzClass()); - assertEquals(146, polymer.getLength().intValue()); - assertEquals(15890.4, polymer.getWeight(), 0); - - chains = polymer.getChains(); - assertEquals(2, chains.size()); - assertEquals('B', (char) chains.get(0)); - assertEquals('D', (char) chains.get(1)); - - synonyms = polymer.getSynonyms(); - assertEquals(0, synonyms.size()); - - tax = polymer.getTaxonomy(); - assertEquals(9606, tax.getId()); - assertEquals("Homo sapiens", tax.getName()); - - mol = polymer.getMolecule(); - assertEquals("Hemoglobin subunit beta", mol.getName()); - accessions = mol.getAccessions(); - assertEquals(16, accessions.size()); - assertEquals("P68871", accessions.get(0)); - assertEquals("A4GX73", accessions.get(1)); - assertEquals("B2ZUE0", accessions.get(2)); - assertEquals("P02023", accessions.get(3)); - assertEquals("Q13852", accessions.get(4)); - assertEquals("Q14481", accessions.get(5)); - assertEquals("Q14510", accessions.get(6)); - assertEquals("Q45KT0", accessions.get(7)); - assertEquals("Q549N7", accessions.get(8)); - assertEquals("Q6FI08", accessions.get(9)); - assertEquals("Q6R7N2", accessions.get(10)); - assertEquals("Q8IZI1", accessions.get(11)); - assertEquals("Q9BX96", accessions.get(12)); - assertEquals("Q9UCD6", accessions.get(13)); - assertEquals("Q9UCP8", accessions.get(14)); - assertEquals("Q9UCP9", accessions.get(15)); - - } - -} diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/rcsb/RCSBLigandsFactoryTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/rcsb/RCSBLigandsFactoryTest.java deleted file mode 100644 index b5ba6869c0..0000000000 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/rcsb/RCSBLigandsFactoryTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 2013-06-24 - * Created by Douglas Myers-Turnbull - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.rcsb; - -import org.junit.Test; - -import java.io.InputStream; -import java.util.List; - -import static org.junit.Assert.assertEquals; - - -/** - * Tests {@link RCSBLigandsFactory}. - * @author dmyerstu - */ -public class RCSBLigandsFactoryTest { - - /** - * Opens the file as a {@link InputStream}. - */ - private InputStream openStream(String filename) { - InputStream is = this.getClass().getClassLoader().getResourceAsStream(filename); - - return is; - } - - /** - * Tests on the live database. Just makes sure the resource can be found. - * If this test fails, it may be because the database changed. - */ - @Test - public void testFromPdbIdUrl() { - RCSBLigands ligands = RCSBLigandsFactory.getFromPdbId("1w0p"); - assertEquals(4, ligands.getLigands().size()); - assertEquals("CA", ligands.getLigands().get(0).getId()); - } - - /** - * Tests on the live database. Just makes sure the resource can be found. - * If this test fails, it may be because the database changed. - */ - @Test - public void testFromPdbIdsUrl() { - List ligands = RCSBLigandsFactory.getFromPdbIds("1w0p", "4hhb"); - assertEquals(4, ligands.get(0).getLigands().size()); - assertEquals("CA", ligands.get(0).getLigands().get(0).getId()); - assertEquals(2, ligands.get(1).getLigands().size()); - assertEquals("HEM", ligands.get(1).getLigands().get(0).getId()); - assertEquals("C34 H32 Fe N4 O4", ligands.get(1).getLigands().get(0).getFormula()); - assertEquals("O4 P -3", ligands.get(1).getLigands().get(1).getFormula()); - } - - @Test - public void testFromPdbId() { - RCSBLigands description = RCSBLigandsFactory.getFromPdbId(openStream("describeMol/4hhb_ligands.xml")); - - assertEquals("4HHB", description.getPdbId()); - List ligands = description.getLigands(); - assertEquals(2, ligands.size()); - - RCSBLigand ligand; - - ligand = ligands.get(0); - assertEquals("HEM", ligand.getId()); - assertEquals("non-polymer", ligand.getType()); - assertEquals(616.487, ligand.getWeight(), 0.0); - assertEquals("PROTOPORPHYRIN IX CONTAINING FE", ligand.getName()); - assertEquals("C34 H32 FE N4 O4", ligand.getFormula()); - assertEquals("FEDYMSUPMFCVOD-UJJXFSCMSA-N", ligand.getInChIKey()); - assertEquals("InChI=1S/C34H34N4O4/c1-7-21-17(3)25-13-26-19(5)23(9-11-33(39)40)31(37-26)16-32-24(10-12-34(41)42)20(6)28(38-32)15-30-22(8-2)18(4)27(36-30)14-29(21)35-25/h7-8,13-16,36-37H,1-2,9-12H2,3-6H3,(H,39,40)(H,41,42)/b25-13-,26-13-,27-14-,28-15-,29-14-,30-15-,31-16-,32-16-", ligand.getInChI()); - assertEquals("Cc1c2/cc/3\\nc(/cc\\4/c(c(/c(/[nH]4)c/c5n/c(c\\c(c1CCC(=O)O)[nH]2)/C(=C5C)CCC(=O)O)C=C)C)C(=C3C)C=C", ligand.getSmiles()); - - ligand = ligands.get(1); - assertEquals("PO4", ligand.getId()); - assertEquals("non-polymer", ligand.getType()); - assertEquals(94.971, ligand.getWeight(), 0.0); - assertEquals("PHOSPHATE ION", ligand.getName()); - assertEquals("O4 P -3", ligand.getFormula()); - assertEquals("NBIIXXVUZAFLBC-UHFFFAOYSA-K", ligand.getInChIKey()); - assertEquals("InChI=1S/H3O4P/c1-5(2,3)4/h(H3,1,2,3,4)/p-3", ligand.getInChI()); - assertEquals("[O-]P(=O)([O-])[O-]", ligand.getSmiles()); - } - - @Test - public void testFromHeteroAtomIdsUrl() { - List ligands = RCSBLigandsFactory.getFromHeteroAtomIds("NAG", "EBW"); - assertEquals("Wrong number of ligands", 2, ligands.size()); - assertEquals("Wrong formula", "C8 H15 N O6", ligands.get(0).getFormula()); - assertEquals("Wrong formula", "C27 H38 N2 O 2", ligands.get(1).getFormula()); - } - - @Test - public void testFromHeteroAtomIdUrl() { - List ligands = RCSBLigandsFactory.getFromHeteroAtomIds("NAG"); - assertEquals("Wrong number of ligands", 1, ligands.size()); - RCSBLigand ligand = ligands.get(0); - assertEquals("Wrong formula", "C8 H15 N O6", ligand.getFormula()); - } - -} From e647acb9bc0f0fd29deb77661fc36ed8653211c1 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 23 Jul 2020 21:23:39 -0700 Subject: [PATCH 148/769] Removing test files related to removed tests --- .../src/test/resources/describeMol/1w0p.xml | 18 -------- .../src/test/resources/describeMol/4hhb.xml | 45 ------------------- .../resources/describeMol/4hhb_ligands.xml | 19 -------- .../resources/describeMol/almost_empty.xml | 12 ----- .../test/resources/describeMol/diff_ecs.xml | 17 ------- .../src/test/resources/describeMol/empty.xml | 5 --- .../test/resources/describeMol/same_ecs.xml | 17 ------- 7 files changed, 133 deletions(-) delete mode 100644 biojava-structure/src/test/resources/describeMol/1w0p.xml delete mode 100644 biojava-structure/src/test/resources/describeMol/4hhb.xml delete mode 100644 biojava-structure/src/test/resources/describeMol/4hhb_ligands.xml delete mode 100644 biojava-structure/src/test/resources/describeMol/almost_empty.xml delete mode 100644 biojava-structure/src/test/resources/describeMol/diff_ecs.xml delete mode 100644 biojava-structure/src/test/resources/describeMol/empty.xml delete mode 100644 biojava-structure/src/test/resources/describeMol/same_ecs.xml diff --git a/biojava-structure/src/test/resources/describeMol/1w0p.xml b/biojava-structure/src/test/resources/describeMol/1w0p.xml deleted file mode 100644 index 4f3e2b60fb..0000000000 --- a/biojava-structure/src/test/resources/describeMol/1w0p.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/biojava-structure/src/test/resources/describeMol/4hhb.xml b/biojava-structure/src/test/resources/describeMol/4hhb.xml deleted file mode 100644 index 72c17fe690..0000000000 --- a/biojava-structure/src/test/resources/describeMol/4hhb.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/biojava-structure/src/test/resources/describeMol/4hhb_ligands.xml b/biojava-structure/src/test/resources/describeMol/4hhb_ligands.xml deleted file mode 100644 index 59105a5385..0000000000 --- a/biojava-structure/src/test/resources/describeMol/4hhb_ligands.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - PROTOPORPHYRIN IX CONTAINING FE - C34 H32 FE N4 O4 - FEDYMSUPMFCVOD-UJJXFSCMSA-N - InChI=1S/C34H34N4O4/c1-7-21-17(3)25-13-26-19(5)23(9-11-33(39)40)31(37-26)16-32-24(10-12-34(41)42)20(6)28(38-32)15-30-22(8-2)18(4)27(36-30)14-29(21)35-25/h7-8,13-16,36-37H,1-2,9-12H2,3-6H3,(H,39,40)(H,41,42)/b25-13-,26-13-,27-14-,28-15-,29-14-,30-15-,31-16-,32-16- - Cc1c2/cc/3\nc(/cc\4/c(c(/c(/[nH]4)c/c5n/c(c\c(c1CCC(=O)O)[nH]2)/C(=C5C)CCC(=O)O)C=C)C)C(=C3C)C=C - - - PHOSPHATE ION - O4 P -3 - NBIIXXVUZAFLBC-UHFFFAOYSA-K - InChI=1S/H3O4P/c1-5(2,3)4/h(H3,1,2,3,4)/p-3 - [O-]P(=O)([O-])[O-] - - - diff --git a/biojava-structure/src/test/resources/describeMol/almost_empty.xml b/biojava-structure/src/test/resources/describeMol/almost_empty.xml deleted file mode 100644 index 484c264a14..0000000000 --- a/biojava-structure/src/test/resources/describeMol/almost_empty.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/biojava-structure/src/test/resources/describeMol/diff_ecs.xml b/biojava-structure/src/test/resources/describeMol/diff_ecs.xml deleted file mode 100644 index b5f56d0d7e..0000000000 --- a/biojava-structure/src/test/resources/describeMol/diff_ecs.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/biojava-structure/src/test/resources/describeMol/empty.xml b/biojava-structure/src/test/resources/describeMol/empty.xml deleted file mode 100644 index 2123a8423a..0000000000 --- a/biojava-structure/src/test/resources/describeMol/empty.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/biojava-structure/src/test/resources/describeMol/same_ecs.xml b/biojava-structure/src/test/resources/describeMol/same_ecs.xml deleted file mode 100644 index b667fd20c6..0000000000 --- a/biojava-structure/src/test/resources/describeMol/same_ecs.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - From 377569f8648b395db64338453a6c219396314eb7 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 23 Jul 2020 21:33:50 -0700 Subject: [PATCH 149/769] Removing rcsb validation reports parsing code and tests --- .../structure/validation/AngleOutlier.java | 254 ---- .../structure/validation/BondOutlier.java | 225 --- .../nbio/structure/validation/Clash.java | 170 --- .../nbio/structure/validation/Entry.java | 1299 ----------------- .../validation/ModelledSubgroup.java | 981 ------------- .../structure/validation/MogAngleOutlier.java | 248 ---- .../structure/validation/MogBondOutlier.java | 248 ---- .../structure/validation/ObjectFactory.java | 147 -- .../nbio/structure/validation/Program.java | 143 -- .../nbio/structure/validation/Programs.java | 94 -- .../nbio/structure/validation/SymmClash.java | 199 --- .../WwPDBValidationInformation.java | 154 -- .../TestValidationReportParsing.java | 110 -- .../resources/validation/3vtq-valdata.xml.gz | Bin 11154 -> 0 bytes .../resources/validation/3vtu-valdata.xml.gz | Bin 11286 -> 0 bytes .../resources/validation/3vtv-valdata.xml.gz | Bin 10343 -> 0 bytes .../resources/validation/3vtw-valdata.xml.gz | Bin 20534 -> 0 bytes .../resources/validation/3vu8-valdata.xml.gz | Bin 24179 -> 0 bytes .../resources/validation/3vua-valdata.xml.gz | Bin 40822 -> 0 bytes .../resources/validation/3vv5-valdata.xml.gz | Bin 22960 -> 0 bytes .../resources/validation/3vvd-valdata.xml.gz | Bin 24768 -> 0 bytes .../resources/validation/3vve-valdata.xml.gz | Bin 24747 -> 0 bytes .../resources/validation/3vvf-valdata.xml.gz | Bin 21436 -> 0 bytes .../resources/validation/3vw5-valdata.xml.gz | Bin 43981 -> 0 bytes .../resources/validation/3w1f-valdata.xml.gz | Bin 11704 -> 0 bytes .../resources/validation/3w5p-valdata.xml.gz | Bin 13781 -> 0 bytes .../resources/validation/3w5q-valdata.xml.gz | Bin 13649 -> 0 bytes .../resources/validation/3w5r-valdata.xml.gz | Bin 12932 -> 0 bytes .../resources/validation/3w5t-valdata.xml.gz | Bin 13649 -> 0 bytes .../resources/validation/3w9y-valdata.xml.gz | Bin 8534 -> 0 bytes .../resources/validation/3wcp-valdata.xml.gz | Bin 40434 -> 0 bytes .../resources/validation/3zjh-valdata.xml.gz | Bin 21181 -> 0 bytes .../resources/validation/3zji-valdata.xml.gz | Bin 22163 -> 0 bytes .../resources/validation/3zjj-valdata.xml.gz | Bin 34089 -> 0 bytes .../resources/validation/3zjm-valdata.xml.gz | Bin 34412 -> 0 bytes .../resources/validation/3zjn-valdata.xml.gz | Bin 26368 -> 0 bytes .../resources/validation/3zjo-valdata.xml.gz | Bin 21103 -> 0 bytes .../resources/validation/3zjp-valdata.xml.gz | Bin 13107 -> 0 bytes .../resources/validation/3zjq-valdata.xml.gz | Bin 20391 -> 0 bytes .../resources/validation/3zjr-valdata.xml.gz | Bin 11047 -> 0 bytes .../resources/validation/3zjs-valdata.xml.gz | Bin 19225 -> 0 bytes .../resources/validation/3znv-valdata.xml.gz | Bin 16477 -> 0 bytes .../resources/validation/3znx-valdata.xml.gz | Bin 15848 -> 0 bytes .../resources/validation/3znz-valdata.xml.gz | Bin 20818 -> 0 bytes .../resources/validation/3zoi-valdata.xml.gz | Bin 19978 -> 0 bytes .../resources/validation/3zoj-valdata.xml.gz | Bin 14441 -> 0 bytes .../resources/validation/3zpy-valdata.xml.gz | Bin 35038 -> 0 bytes 47 files changed, 4272 deletions(-) delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/AngleOutlier.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/BondOutlier.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Clash.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Entry.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/ModelledSubgroup.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/MogAngleOutlier.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/MogBondOutlier.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/ObjectFactory.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Program.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Programs.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/SymmClash.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/validation/WwPDBValidationInformation.java delete mode 100644 biojava-structure/src/test/java/org/biojava/nbio/structure/validation/TestValidationReportParsing.java delete mode 100644 biojava-structure/src/test/resources/validation/3vtq-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vtu-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vtv-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vtw-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vu8-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vua-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vv5-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vvd-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vve-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vvf-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3vw5-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3w1f-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3w5p-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3w5q-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3w5r-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3w5t-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3w9y-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3wcp-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zjh-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zji-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zjj-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zjm-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zjn-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zjo-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zjp-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zjq-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zjr-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zjs-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3znv-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3znx-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3znz-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zoi-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zoj-valdata.xml.gz delete mode 100644 biojava-structure/src/test/resources/validation/3zpy-valdata.xml.gz diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/AngleOutlier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/AngleOutlier.java deleted file mode 100644 index 3893267119..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/AngleOutlier.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.math.BigDecimal; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="atom0" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="atom1" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="atom2" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="mean" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="obs" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="stdev" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="z" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "angle-outlier") -public class AngleOutlier { - - @XmlAttribute(name = "atom0", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String atom0; - @XmlAttribute(name = "atom1", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String atom1; - @XmlAttribute(name = "atom2", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String atom2; - @XmlAttribute(name = "mean", required = true) - protected BigDecimal mean; - @XmlAttribute(name = "obs", required = true) - protected BigDecimal obs; - @XmlAttribute(name = "stdev", required = true) - protected BigDecimal stdev; - @XmlAttribute(name = "z", required = true) - protected BigDecimal z; - - /** - * Gets the value of the atom0 property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAtom0() { - return atom0; - } - - /** - * Sets the value of the atom0 property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAtom0(String value) { - this.atom0 = value; - } - - /** - * Gets the value of the atom1 property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAtom1() { - return atom1; - } - - /** - * Sets the value of the atom1 property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAtom1(String value) { - this.atom1 = value; - } - - /** - * Gets the value of the atom2 property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAtom2() { - return atom2; - } - - /** - * Sets the value of the atom2 property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAtom2(String value) { - this.atom2 = value; - } - - /** - * Gets the value of the mean property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getMean() { - return mean; - } - - /** - * Sets the value of the mean property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setMean(BigDecimal value) { - this.mean = value; - } - - /** - * Gets the value of the obs property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getObs() { - return obs; - } - - /** - * Sets the value of the obs property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setObs(BigDecimal value) { - this.obs = value; - } - - /** - * Gets the value of the stdev property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getStdev() { - return stdev; - } - - /** - * Sets the value of the stdev property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setStdev(BigDecimal value) { - this.stdev = value; - } - - /** - * Gets the value of the z property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getZ() { - return z; - } - - /** - * Sets the value of the z property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setZ(BigDecimal value) { - this.z = value; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/BondOutlier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/BondOutlier.java deleted file mode 100644 index b91a4d6653..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/BondOutlier.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.math.BigDecimal; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="atom0" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="atom1" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="mean" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="obs" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="stdev" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="z" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "bond-outlier") -public class BondOutlier { - - @XmlAttribute(name = "atom0", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String atom0; - @XmlAttribute(name = "atom1", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String atom1; - @XmlAttribute(name = "mean", required = true) - protected BigDecimal mean; - @XmlAttribute(name = "obs", required = true) - protected BigDecimal obs; - @XmlAttribute(name = "stdev", required = true) - protected BigDecimal stdev; - @XmlAttribute(name = "z", required = true) - protected BigDecimal z; - - /** - * Gets the value of the atom0 property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAtom0() { - return atom0; - } - - /** - * Sets the value of the atom0 property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAtom0(String value) { - this.atom0 = value; - } - - /** - * Gets the value of the atom1 property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAtom1() { - return atom1; - } - - /** - * Sets the value of the atom1 property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAtom1(String value) { - this.atom1 = value; - } - - /** - * Gets the value of the mean property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getMean() { - return mean; - } - - /** - * Sets the value of the mean property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setMean(BigDecimal value) { - this.mean = value; - } - - /** - * Gets the value of the obs property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getObs() { - return obs; - } - - /** - * Sets the value of the obs property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setObs(BigDecimal value) { - this.obs = value; - } - - /** - * Gets the value of the stdev property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getStdev() { - return stdev; - } - - /** - * Sets the value of the stdev property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setStdev(BigDecimal value) { - this.stdev = value; - } - - /** - * Gets the value of the z property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getZ() { - return z; - } - - /** - * Sets the value of the z property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setZ(BigDecimal value) { - this.z = value; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Clash.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Clash.java deleted file mode 100644 index c1c0d14f60..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Clash.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.math.BigDecimal; -import java.math.BigInteger; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="atom" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="cid" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="clashmag" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="dist" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "clash") -public class Clash { - - @XmlAttribute(name = "atom", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String atom; - @XmlAttribute(name = "cid", required = true) - protected BigInteger cid; - @XmlAttribute(name = "clashmag", required = true) - protected BigDecimal clashmag; - @XmlAttribute(name = "dist", required = true) - protected BigDecimal dist; - - /** - * Gets the value of the atom property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAtom() { - return atom; - } - - /** - * Sets the value of the atom property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAtom(String value) { - this.atom = value; - } - - /** - * Gets the value of the cid property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getCid() { - return cid; - } - - /** - * Sets the value of the cid property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setCid(BigInteger value) { - this.cid = value; - } - - /** - * Gets the value of the clashmag property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getClashmag() { - return clashmag; - } - - /** - * Sets the value of the clashmag property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setClashmag(BigDecimal value) { - this.clashmag = value; - } - - /** - * Gets the value of the dist property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getDist() { - return dist; - } - - /** - * Sets the value of the dist property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setDist(BigDecimal value) { - this.dist = value; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Entry.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Entry.java deleted file mode 100644 index 0c392d437b..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Entry.java +++ /dev/null @@ -1,1299 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.math.BigDecimal; -import java.math.BigInteger; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="CCP4version" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="DCC_R" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="DCC_Rfree" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="DCC_refinement_program" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="DataAnisotropy" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="DataCompleteness" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="EDS_R" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="EDS_resolution" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="EDS_resolution_low" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="Fo_Fc_correlation" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="IoverSigma" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="PDB-revision-number" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="RefmacVersion" use="required" type="{http://www.w3.org/2001/XMLSchema}NMTOKEN" />
    - *       <attribute name="RestypesNotcheckedForBondAngleGeometry" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="TransNCS" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="TwinFraction" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="TwinL" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="TwinL2" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="WilsonBaniso" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="WilsonBestimate" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="XMLcreationDate" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="absolute-percentile-clashscore" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="absolute-percentile-percent-RSRZ-outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="absolute-percentile-percent-rama-outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="absolute-percentile-percent-rota-outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="acentric_outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="attemptedValidationSteps" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="bulk_solvent_b" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="bulk_solvent_k" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="centric_outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="clashscore" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="num-H-reduce" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="num-free-reflections" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="numMillerIndices" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="percent-RSRZ-outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="percent-free-reflections" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="percent-rama-outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="percent-rota-outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="relative-percentile-clashscore" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="relative-percentile-percent-RSRZ-outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="relative-percentile-percent-rama-outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="relative-percentile-percent-rota-outliers" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="xtriage_input_columns" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "Entry") -public class Entry { - - @XmlAttribute(name = "CCP4version", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String ccp4Version; - @XmlAttribute(name = "DCC_R", required = true) - protected BigDecimal dccr; - @XmlAttribute(name = "DCC_Rfree", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String dccRfree; - @XmlAttribute(name = "DCC_refinement_program", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String dccRefinementProgram; - @XmlAttribute(name = "DataAnisotropy", required = true) - protected BigDecimal dataAnisotropy; - @XmlAttribute(name = "DataCompleteness", required = true) - protected BigDecimal dataCompleteness; - @XmlAttribute(name = "EDS_R", required = true) - protected BigDecimal edsr; - @XmlAttribute(name = "EDS_resolution", required = true) - protected BigDecimal edsResolution; - @XmlAttribute(name = "EDS_resolution_low", required = true) - protected BigDecimal edsResolutionLow; - @XmlAttribute(name = "Fo_Fc_correlation", required = true) - protected BigDecimal foFcCorrelation; - @XmlAttribute(name = "IoverSigma", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String ioverSigma; - @XmlAttribute(name = "PDB-revision-number", required = true) - protected BigInteger pdbRevisionNumber; - @XmlAttribute(name = "RefmacVersion", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NMTOKEN") - protected String refmacVersion; - @XmlAttribute(name = "RestypesNotcheckedForBondAngleGeometry", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String restypesNotcheckedForBondAngleGeometry; - @XmlAttribute(name = "TransNCS", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String transNCS; - @XmlAttribute(name = "TwinFraction", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String twinFraction; - @XmlAttribute(name = "TwinL", required = true) - protected BigDecimal twinL; - @XmlAttribute(name = "TwinL2", required = true) - protected BigDecimal twinL2; - @XmlAttribute(name = "WilsonBaniso", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String wilsonBaniso; - @XmlAttribute(name = "WilsonBestimate", required = true) - protected BigDecimal wilsonBestimate; - @XmlAttribute(name = "XMLcreationDate", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String xmLcreationDate; - @XmlAttribute(name = "absolute-percentile-clashscore", required = true) - protected BigDecimal absolutePercentileClashscore; - @XmlAttribute(name = "absolute-percentile-percent-RSRZ-outliers", required = true) - protected BigDecimal absolutePercentilePercentRSRZOutliers; - @XmlAttribute(name = "absolute-percentile-percent-rama-outliers", required = true) - protected BigDecimal absolutePercentilePercentRamaOutliers; - @XmlAttribute(name = "absolute-percentile-percent-rota-outliers", required = true) - protected BigDecimal absolutePercentilePercentRotaOutliers; - - @XmlAttribute(name = "absolute-percentile-DCC_Rfree", required = false) - protected BigDecimal absolutePercentileDCCRfree; - @XmlAttribute(name = "relative-percentile-DCC_Rfree", required = false) - protected BigDecimal relativePercentileDCCRfree; - - - @XmlAttribute(name = "RNAsuiteness", required = false) - protected BigDecimal rnaSuiteness; - - @XmlAttribute(name = "absolute-percentile-RNAsuiteness", required = false) - protected BigDecimal absolutePercentialRNAsuiteness; - - @XmlAttribute(name = "relative-percentile-RNAsuiteness", required = false) - protected BigDecimal relativePercentileRNAsuiteness; - - - @XmlAttribute(name = "acentric_outliers", required = true) - protected BigInteger acentricOutliers; - @XmlAttribute(name = "attemptedValidationSteps", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String attemptedValidationSteps; - @XmlAttribute(name = "bulk_solvent_b", required = true) - protected BigDecimal bulkSolventB; - @XmlAttribute(name = "bulk_solvent_k", required = true) - protected BigDecimal bulkSolventK; - @XmlAttribute(name = "centric_outliers", required = true) - protected BigInteger centricOutliers; - @XmlAttribute(name = "clashscore", required = true) - protected BigDecimal clashscore; - @XmlAttribute(name = "num-H-reduce", required = true) - protected BigInteger numHReduce; - @XmlAttribute(name = "num-free-reflections", required = true) - protected BigInteger numFreeReflections; - @XmlAttribute(name = "numMillerIndices", required = true) - protected BigInteger numMillerIndices; - @XmlAttribute(name = "percent-RSRZ-outliers", required = true) - protected BigDecimal percentRSRZOutliers; - @XmlAttribute(name = "percent-free-reflections", required = true) - protected BigDecimal percentFreeReflections; - @XmlAttribute(name = "percent-rama-outliers", required = true) - protected BigDecimal percentRamaOutliers; - @XmlAttribute(name = "percent-rota-outliers", required = true) - protected BigDecimal percentRotaOutliers; - @XmlAttribute(name = "relative-percentile-clashscore", required = true) - protected BigDecimal relativePercentileClashscore; - @XmlAttribute(name = "relative-percentile-percent-RSRZ-outliers", required = true) - protected BigDecimal relativePercentilePercentRSRZOutliers; - @XmlAttribute(name = "relative-percentile-percent-rama-outliers", required = true) - protected BigDecimal relativePercentilePercentRamaOutliers; - @XmlAttribute(name = "relative-percentile-percent-rota-outliers", required = true) - protected BigDecimal relativePercentilePercentRotaOutliers; - @XmlAttribute(name = "xtriage_input_columns", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String xtriageInputColumns; - - /** - * Gets the value of the ccp4Version property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getCCP4Version() { - return ccp4Version; - } - - /** - * Sets the value of the ccp4Version property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setCCP4Version(String value) { - this.ccp4Version = value; - } - - /** - * Gets the value of the dccr property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getDCCR() { - return dccr; - } - - /** - * Sets the value of the dccr property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setDCCR(BigDecimal value) { - this.dccr = value; - } - - /** - * Gets the value of the dccRfree property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDCCRfree() { - return dccRfree; - } - - /** - * Sets the value of the dccRfree property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDCCRfree(String value) { - this.dccRfree = value; - } - - /** - * Gets the value of the dccRefinementProgram property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDCCRefinementProgram() { - return dccRefinementProgram; - } - - /** - * Sets the value of the dccRefinementProgram property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDCCRefinementProgram(String value) { - this.dccRefinementProgram = value; - } - - /** - * Gets the value of the dataAnisotropy property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getDataAnisotropy() { - return dataAnisotropy; - } - - /** - * Sets the value of the dataAnisotropy property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setDataAnisotropy(BigDecimal value) { - this.dataAnisotropy = value; - } - - /** - * Gets the value of the dataCompleteness property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getDataCompleteness() { - return dataCompleteness; - } - - /** - * Sets the value of the dataCompleteness property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setDataCompleteness(BigDecimal value) { - this.dataCompleteness = value; - } - - /** - * Gets the value of the edsr property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getEDSR() { - return edsr; - } - - /** - * Sets the value of the edsr property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setEDSR(BigDecimal value) { - this.edsr = value; - } - - /** - * Gets the value of the edsResolution property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getEDSResolution() { - return edsResolution; - } - - /** - * Sets the value of the edsResolution property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setEDSResolution(BigDecimal value) { - this.edsResolution = value; - } - - /** - * Gets the value of the edsResolutionLow property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getEDSResolutionLow() { - return edsResolutionLow; - } - - /** - * Sets the value of the edsResolutionLow property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setEDSResolutionLow(BigDecimal value) { - this.edsResolutionLow = value; - } - - /** - * Gets the value of the foFcCorrelation property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getFoFcCorrelation() { - return foFcCorrelation; - } - - /** - * Sets the value of the foFcCorrelation property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setFoFcCorrelation(BigDecimal value) { - this.foFcCorrelation = value; - } - - /** - * Gets the value of the ioverSigma property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getIoverSigma() { - return ioverSigma; - } - - /** - * Sets the value of the ioverSigma property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setIoverSigma(String value) { - this.ioverSigma = value; - } - - /** - * Gets the value of the pdbRevisionNumber property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getPDBRevisionNumber() { - return pdbRevisionNumber; - } - - /** - * Sets the value of the pdbRevisionNumber property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setPDBRevisionNumber(BigInteger value) { - this.pdbRevisionNumber = value; - } - - /** - * Gets the value of the refmacVersion property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getRefmacVersion() { - return refmacVersion; - } - - /** - * Sets the value of the refmacVersion property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setRefmacVersion(String value) { - this.refmacVersion = value; - } - - /** - * Gets the value of the restypesNotcheckedForBondAngleGeometry property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getRestypesNotcheckedForBondAngleGeometry() { - return restypesNotcheckedForBondAngleGeometry; - } - - /** - * Sets the value of the restypesNotcheckedForBondAngleGeometry property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setRestypesNotcheckedForBondAngleGeometry(String value) { - this.restypesNotcheckedForBondAngleGeometry = value; - } - - /** - * Gets the value of the transNCS property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTransNCS() { - return transNCS; - } - - /** - * Sets the value of the transNCS property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTransNCS(String value) { - this.transNCS = value; - } - - /** - * Gets the value of the twinFraction property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTwinFraction() { - return twinFraction; - } - - /** - * Sets the value of the twinFraction property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTwinFraction(String value) { - this.twinFraction = value; - } - - /** - * Gets the value of the twinL property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getTwinL() { - return twinL; - } - - /** - * Sets the value of the twinL property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setTwinL(BigDecimal value) { - this.twinL = value; - } - - /** - * Gets the value of the twinL2 property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getTwinL2() { - return twinL2; - } - - /** - * Sets the value of the twinL2 property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setTwinL2(BigDecimal value) { - this.twinL2 = value; - } - - /** - * Gets the value of the wilsonBaniso property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getWilsonBaniso() { - return wilsonBaniso; - } - - /** - * Sets the value of the wilsonBaniso property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setWilsonBaniso(String value) { - this.wilsonBaniso = value; - } - - /** - * Gets the value of the wilsonBestimate property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getWilsonBestimate() { - return wilsonBestimate; - } - - /** - * Sets the value of the wilsonBestimate property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setWilsonBestimate(BigDecimal value) { - this.wilsonBestimate = value; - } - - /** - * Gets the value of the xmLcreationDate property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getXMLcreationDate() { - return xmLcreationDate; - } - - /** - * Sets the value of the xmLcreationDate property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setXMLcreationDate(String value) { - this.xmLcreationDate = value; - } - - /** - * Gets the value of the absolutePercentileClashscore property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getAbsolutePercentileClashscore() { - return absolutePercentileClashscore; - } - - /** - * Sets the value of the absolutePercentileClashscore property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setAbsolutePercentileClashscore(BigDecimal value) { - this.absolutePercentileClashscore = value; - } - - /** - * Gets the value of the absolutePercentilePercentRSRZOutliers property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getAbsolutePercentilePercentRSRZOutliers() { - return absolutePercentilePercentRSRZOutliers; - } - - /** - * Sets the value of the absolutePercentilePercentRSRZOutliers property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setAbsolutePercentilePercentRSRZOutliers(BigDecimal value) { - this.absolutePercentilePercentRSRZOutliers = value; - } - - /** - * Gets the value of the absolutePercentilePercentRamaOutliers property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getAbsolutePercentilePercentRamaOutliers() { - return absolutePercentilePercentRamaOutliers; - } - - /** - * Sets the value of the absolutePercentilePercentRamaOutliers property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setAbsolutePercentilePercentRamaOutliers(BigDecimal value) { - this.absolutePercentilePercentRamaOutliers = value; - } - - /** - * Gets the value of the absolutePercentilePercentRotaOutliers property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getAbsolutePercentilePercentRotaOutliers() { - return absolutePercentilePercentRotaOutliers; - } - - /** - * Sets the value of the absolutePercentilePercentRotaOutliers property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setAbsolutePercentilePercentRotaOutliers(BigDecimal value) { - this.absolutePercentilePercentRotaOutliers = value; - } - - public BigDecimal getAbsolutePercentileDCCRfree() { - return absolutePercentileDCCRfree; - } - - public void setAbsolutePercentileDCCRfree( - BigDecimal absolutePercentileDCCRfree) { - this.absolutePercentileDCCRfree = absolutePercentileDCCRfree; - } - - public BigDecimal getRelativePercentileDCCRfree() { - return relativePercentileDCCRfree; - } - - public void setRelativePercentileDCCRfree( - BigDecimal relativePercentileDCCRfree) { - this.relativePercentileDCCRfree = absolutePercentileDCCRfree; - } - - /** - * Gets the value of the acentricOutliers property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getAcentricOutliers() { - return acentricOutliers; - } - - /** - * Sets the value of the acentricOutliers property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setAcentricOutliers(BigInteger value) { - this.acentricOutliers = value; - } - - /** - * Gets the value of the attemptedValidationSteps property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAttemptedValidationSteps() { - return attemptedValidationSteps; - } - - /** - * Sets the value of the attemptedValidationSteps property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAttemptedValidationSteps(String value) { - this.attemptedValidationSteps = value; - } - - /** - * Gets the value of the bulkSolventB property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getBulkSolventB() { - return bulkSolventB; - } - - /** - * Sets the value of the bulkSolventB property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setBulkSolventB(BigDecimal value) { - this.bulkSolventB = value; - } - - /** - * Gets the value of the bulkSolventK property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getBulkSolventK() { - return bulkSolventK; - } - - /** - * Sets the value of the bulkSolventK property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setBulkSolventK(BigDecimal value) { - this.bulkSolventK = value; - } - - /** - * Gets the value of the centricOutliers property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getCentricOutliers() { - return centricOutliers; - } - - /** - * Sets the value of the centricOutliers property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setCentricOutliers(BigInteger value) { - this.centricOutliers = value; - } - - /** - * Gets the value of the clashscore property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getClashscore() { - return clashscore; - } - - /** - * Sets the value of the clashscore property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setClashscore(BigDecimal value) { - this.clashscore = value; - } - - /** - * Gets the value of the numHReduce property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getNumHReduce() { - return numHReduce; - } - - /** - * Sets the value of the numHReduce property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setNumHReduce(BigInteger value) { - this.numHReduce = value; - } - - /** - * Gets the value of the numFreeReflections property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getNumFreeReflections() { - return numFreeReflections; - } - - /** - * Sets the value of the numFreeReflections property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setNumFreeReflections(BigInteger value) { - this.numFreeReflections = value; - } - - /** - * Gets the value of the numMillerIndices property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getNumMillerIndices() { - return numMillerIndices; - } - - /** - * Sets the value of the numMillerIndices property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setNumMillerIndices(BigInteger value) { - this.numMillerIndices = value; - } - - /** - * Gets the value of the percentRSRZOutliers property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getPercentRSRZOutliers() { - return percentRSRZOutliers; - } - - /** - * Sets the value of the percentRSRZOutliers property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setPercentRSRZOutliers(BigDecimal value) { - this.percentRSRZOutliers = value; - } - - /** - * Gets the value of the percentFreeReflections property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getPercentFreeReflections() { - return percentFreeReflections; - } - - /** - * Sets the value of the percentFreeReflections property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setPercentFreeReflections(BigDecimal value) { - this.percentFreeReflections = value; - } - - /** - * Gets the value of the percentRamaOutliers property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getPercentRamaOutliers() { - return percentRamaOutliers; - } - - /** - * Sets the value of the percentRamaOutliers property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setPercentRamaOutliers(BigDecimal value) { - this.percentRamaOutliers = value; - } - - /** - * Gets the value of the percentRotaOutliers property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getPercentRotaOutliers() { - return percentRotaOutliers; - } - - /** - * Sets the value of the percentRotaOutliers property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setPercentRotaOutliers(BigDecimal value) { - this.percentRotaOutliers = value; - } - - /** - * Gets the value of the relativePercentileClashscore property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getRelativePercentileClashscore() { - return relativePercentileClashscore; - } - - /** - * Sets the value of the relativePercentileClashscore property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setRelativePercentileClashscore(BigDecimal value) { - this.relativePercentileClashscore = value; - } - - /** - * Gets the value of the relativePercentilePercentRSRZOutliers property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getRelativePercentilePercentRSRZOutliers() { - return relativePercentilePercentRSRZOutliers; - } - - /** - * Sets the value of the relativePercentilePercentRSRZOutliers property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setRelativePercentilePercentRSRZOutliers(BigDecimal value) { - this.relativePercentilePercentRSRZOutliers = value; - } - - /** - * Gets the value of the relativePercentilePercentRamaOutliers property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getRelativePercentilePercentRamaOutliers() { - return relativePercentilePercentRamaOutliers; - } - - /** - * Sets the value of the relativePercentilePercentRamaOutliers property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setRelativePercentilePercentRamaOutliers(BigDecimal value) { - this.relativePercentilePercentRamaOutliers = value; - } - - /** - * Gets the value of the relativePercentilePercentRotaOutliers property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getRelativePercentilePercentRotaOutliers() { - return relativePercentilePercentRotaOutliers; - } - - /** - * Sets the value of the relativePercentilePercentRotaOutliers property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setRelativePercentilePercentRotaOutliers(BigDecimal value) { - this.relativePercentilePercentRotaOutliers = value; - } - - /** - * Gets the value of the xtriageInputColumns property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getXtriageInputColumns() { - return xtriageInputColumns; - } - - /** - * Sets the value of the xtriageInputColumns property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setXtriageInputColumns(String value) { - this.xtriageInputColumns = value; - } - - public BigDecimal getRnaSuiteness() { - return rnaSuiteness; - } - - public void setRnaSuiteness(BigDecimal rnaSuiteness) { - this.rnaSuiteness = rnaSuiteness; - } - - public BigDecimal getAbsolutePercentialRNAsuiteness() { - return absolutePercentialRNAsuiteness; - } - - public void setAbsolutePercentialRNAsuiteness( - BigDecimal absolutePercentialRNAsuiteness) { - this.absolutePercentialRNAsuiteness = absolutePercentialRNAsuiteness; - } - - public BigDecimal getRelativePercentileRNAsuiteness() { - return relativePercentileRNAsuiteness; - } - - public void setRelativePercentileRNAsuiteness( - BigDecimal relativePercentileRNAsuiteness) { - this.relativePercentileRNAsuiteness = relativePercentileRNAsuiteness; - } - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/ModelledSubgroup.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/ModelledSubgroup.java deleted file mode 100644 index 310bb9e1af..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/ModelledSubgroup.java +++ /dev/null @@ -1,981 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element ref="{}angle-outlier" maxOccurs="unbounded" minOccurs="0"/>
    - *         <element ref="{}clash" maxOccurs="unbounded" minOccurs="0"/>
    - *         <element ref="{}bond-outlier" maxOccurs="unbounded" minOccurs="0"/>
    - *         <element ref="{}mog-angle-outlier" maxOccurs="unbounded" minOccurs="0"/>
    - *         <choice>
    - *           <element ref="{}symm-clash" maxOccurs="unbounded" minOccurs="0"/>
    - *           <element ref="{}mog-bond-outlier" maxOccurs="unbounded" minOccurs="0"/>
    - *         </choice>
    - *       </sequence>
    - *       <attribute name="NatomsEDS" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="altcode" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="avgoccu" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="chain" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="ent" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="flippable-sidechain" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="icode" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="ligRSRZ" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="ligRSRnbrMean" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="ligRSRnbrStdev" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="ligRSRnumnbrs" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="model" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="mogul-ignore" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="num-H-reduce" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="owab" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="phi" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="psi" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="rama" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="resname" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="resnum" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="rota" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="rscc" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="rsr" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="rsrz" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="said" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="seq" use="required" type="{http://www.w3.org/2001/XMLSchema}NMTOKEN" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "angleOutlier", - "clash", - "bondOutlier", - "mogAngleOutlier", - "symmClash", - "mogBondOutlier" -}) -@XmlRootElement(name = "ModelledSubgroup") -public class ModelledSubgroup { - - @XmlElement(name = "angle-outlier") - protected List angleOutlier; - protected List clash; - @XmlElement(name = "bond-outlier") - protected List bondOutlier; - @XmlElement(name = "mog-angle-outlier") - protected List mogAngleOutlier; - @XmlElement(name = "symm-clash") - protected List symmClash; - @XmlElement(name = "mog-bond-outlier") - protected List mogBondOutlier; - @XmlAttribute(name = "NatomsEDS", required = true) - protected BigInteger natomsEDS; - @XmlAttribute(name = "altcode", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String altcode; - @XmlAttribute(name = "avgoccu", required = true) - protected BigDecimal avgoccu; - @XmlAttribute(name = "chain", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String chain; - @XmlAttribute(name = "ent", required = true) - protected BigInteger ent; - @XmlAttribute(name = "flippable-sidechain") - protected BigInteger flippableSidechain; - @XmlAttribute(name = "icode", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String icode; - @XmlAttribute(name = "ligRSRZ") - protected BigDecimal ligRSRZ; - @XmlAttribute(name = "ligRSRnbrMean") - protected BigDecimal ligRSRnbrMean; - @XmlAttribute(name = "ligRSRnbrStdev") - protected BigDecimal ligRSRnbrStdev; - @XmlAttribute(name = "ligRSRnumnbrs") - protected BigInteger ligRSRnumnbrs; - @XmlAttribute(name = "model", required = true) - protected BigInteger model; - @XmlAttribute(name = "mogul-ignore") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String mogulIgnore; - @XmlAttribute(name = "num-H-reduce") - protected BigInteger numHReduce; - @XmlAttribute(name = "owab", required = true) - protected BigDecimal owab; - @XmlAttribute(name = "phi") - protected BigDecimal phi; - @XmlAttribute(name = "psi") - protected BigDecimal psi; - @XmlAttribute(name = "rama") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String rama; - @XmlAttribute(name = "resname", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String resname; - @XmlAttribute(name = "resnum", required = true) - protected BigInteger resnum; - @XmlAttribute(name = "rota") - @XmlSchemaType(name = "anySimpleType") - protected String rota; - @XmlAttribute(name = "rscc", required = true) - protected BigDecimal rscc; - @XmlAttribute(name = "rsr", required = true) - protected BigDecimal rsr; - @XmlAttribute(name = "rsrz") - protected BigDecimal rsrz; - @XmlAttribute(name = "said", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String said; - @XmlAttribute(name = "seq", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NMTOKEN") - protected String seq; - - /** - * Gets the value of the angleOutlier property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the angleOutlier property. - * - *

    - * For example, to add a new item, do as follows: - *

    -	 *    getAngleOutlier().add(newItem);
    -	 * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link AngleOutlier } - * - * - */ - public List getAngleOutlier() { - if (angleOutlier == null) { - angleOutlier = new ArrayList(); - } - return this.angleOutlier; - } - - /** - * Gets the value of the clash property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the clash property. - * - *

    - * For example, to add a new item, do as follows: - *

    -	 *    getClash().add(newItem);
    -	 * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link Clash } - * - * - */ - public List getClash() { - if (clash == null) { - clash = new ArrayList(); - } - return this.clash; - } - - /** - * Gets the value of the bondOutlier property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the bondOutlier property. - * - *

    - * For example, to add a new item, do as follows: - *

    -	 *    getBondOutlier().add(newItem);
    -	 * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link BondOutlier } - * - * - */ - public List getBondOutlier() { - if (bondOutlier == null) { - bondOutlier = new ArrayList(); - } - return this.bondOutlier; - } - - /** - * Gets the value of the mogAngleOutlier property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the mogAngleOutlier property. - * - *

    - * For example, to add a new item, do as follows: - *

    -	 *    getMogAngleOutlier().add(newItem);
    -	 * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link MogAngleOutlier } - * - * - */ - public List getMogAngleOutlier() { - if (mogAngleOutlier == null) { - mogAngleOutlier = new ArrayList(); - } - return this.mogAngleOutlier; - } - - /** - * Gets the value of the symmClash property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the symmClash property. - * - *

    - * For example, to add a new item, do as follows: - *

    -	 *    getSymmClash().add(newItem);
    -	 * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link SymmClash } - * - * - */ - public List getSymmClash() { - if (symmClash == null) { - symmClash = new ArrayList(); - } - return this.symmClash; - } - - /** - * Gets the value of the mogBondOutlier property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the mogBondOutlier property. - * - *

    - * For example, to add a new item, do as follows: - *

    -	 *    getMogBondOutlier().add(newItem);
    -	 * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link MogBondOutlier } - * - * - */ - public List getMogBondOutlier() { - if (mogBondOutlier == null) { - mogBondOutlier = new ArrayList(); - } - return this.mogBondOutlier; - } - - /** - * Gets the value of the natomsEDS property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getNatomsEDS() { - return natomsEDS; - } - - /** - * Sets the value of the natomsEDS property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setNatomsEDS(BigInteger value) { - this.natomsEDS = value; - } - - /** - * Gets the value of the altcode property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAltcode() { - return altcode; - } - - /** - * Sets the value of the altcode property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAltcode(String value) { - this.altcode = value; - } - - /** - * Gets the value of the avgoccu property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getAvgoccu() { - return avgoccu; - } - - /** - * Sets the value of the avgoccu property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setAvgoccu(BigDecimal value) { - this.avgoccu = value; - } - - /** - * Gets the value of the chain property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getChain() { - return chain; - } - - /** - * Sets the value of the chain property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setChain(String value) { - this.chain = value; - } - - /** - * Gets the value of the ent property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getEnt() { - return ent; - } - - /** - * Sets the value of the ent property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setEnt(BigInteger value) { - this.ent = value; - } - - /** - * Gets the value of the flippableSidechain property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getFlippableSidechain() { - return flippableSidechain; - } - - /** - * Sets the value of the flippableSidechain property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setFlippableSidechain(BigInteger value) { - this.flippableSidechain = value; - } - - /** - * Gets the value of the icode property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getIcode() { - return icode; - } - - /** - * Sets the value of the icode property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setIcode(String value) { - this.icode = value; - } - - /** - * Gets the value of the ligRSRZ property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getLigRSRZ() { - return ligRSRZ; - } - - /** - * Sets the value of the ligRSRZ property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setLigRSRZ(BigDecimal value) { - this.ligRSRZ = value; - } - - /** - * Gets the value of the ligRSRnbrMean property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getLigRSRnbrMean() { - return ligRSRnbrMean; - } - - /** - * Sets the value of the ligRSRnbrMean property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setLigRSRnbrMean(BigDecimal value) { - this.ligRSRnbrMean = value; - } - - /** - * Gets the value of the ligRSRnbrStdev property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getLigRSRnbrStdev() { - return ligRSRnbrStdev; - } - - /** - * Sets the value of the ligRSRnbrStdev property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setLigRSRnbrStdev(BigDecimal value) { - this.ligRSRnbrStdev = value; - } - - /** - * Gets the value of the ligRSRnumnbrs property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getLigRSRnumnbrs() { - return ligRSRnumnbrs; - } - - /** - * Sets the value of the ligRSRnumnbrs property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setLigRSRnumnbrs(BigInteger value) { - this.ligRSRnumnbrs = value; - } - - /** - * Gets the value of the model property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getModel() { - return model; - } - - /** - * Sets the value of the model property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setModel(BigInteger value) { - this.model = value; - } - - /** - * Gets the value of the mogulIgnore property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMogulIgnore() { - return mogulIgnore; - } - - /** - * Sets the value of the mogulIgnore property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMogulIgnore(String value) { - this.mogulIgnore = value; - } - - /** - * Gets the value of the numHReduce property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getNumHReduce() { - return numHReduce; - } - - /** - * Sets the value of the numHReduce property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setNumHReduce(BigInteger value) { - this.numHReduce = value; - } - - /** - * Gets the value of the owab property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getOwab() { - return owab; - } - - /** - * Sets the value of the owab property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setOwab(BigDecimal value) { - this.owab = value; - } - - /** - * Gets the value of the phi property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getPhi() { - return phi; - } - - /** - * Sets the value of the phi property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setPhi(BigDecimal value) { - this.phi = value; - } - - /** - * Gets the value of the psi property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getPsi() { - return psi; - } - - /** - * Sets the value of the psi property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setPsi(BigDecimal value) { - this.psi = value; - } - - /** - * Gets the value of the rama property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getRama() { - return rama; - } - - /** - * Sets the value of the rama property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setRama(String value) { - this.rama = value; - } - - /** - * Gets the value of the resname property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getResname() { - return resname; - } - - /** - * Sets the value of the resname property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setResname(String value) { - this.resname = value; - } - - /** - * Gets the value of the resnum property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getResnum() { - return resnum; - } - - /** - * Sets the value of the resnum property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setResnum(BigInteger value) { - this.resnum = value; - } - - /** - * Gets the value of the rota property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getRota() { - return rota; - } - - /** - * Sets the value of the rota property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setRota(String value) { - this.rota = value; - } - - /** - * Gets the value of the rscc property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getRscc() { - return rscc; - } - - /** - * Sets the value of the rscc property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setRscc(BigDecimal value) { - this.rscc = value; - } - - /** - * Gets the value of the rsr property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getRsr() { - return rsr; - } - - /** - * Sets the value of the rsr property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setRsr(BigDecimal value) { - this.rsr = value; - } - - /** - * Gets the value of the rsrz property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getRsrz() { - return rsrz; - } - - /** - * Sets the value of the rsrz property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setRsrz(BigDecimal value) { - this.rsrz = value; - } - - /** - * Gets the value of the said property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSaid() { - return said; - } - - /** - * Sets the value of the said property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSaid(String value) { - this.said = value; - } - - /** - * Gets the value of the seq property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSeq() { - return seq; - } - - /** - * Sets the value of the seq property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSeq(String value) { - this.seq = value; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/MogAngleOutlier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/MogAngleOutlier.java deleted file mode 100644 index 02a982bced..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/MogAngleOutlier.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import java.math.BigDecimal; -import java.math.BigInteger; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="Zscore" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="atoms" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="mean" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="mindiff" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="numobs" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="obsval" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="stdev" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "mog-angle-outlier") -public class MogAngleOutlier { - - @XmlAttribute(name = "Zscore", required = true) - protected BigDecimal zscore; - @XmlAttribute(name = "atoms", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String atoms; - @XmlAttribute(name = "mean", required = true) - protected BigDecimal mean; - @XmlAttribute(name = "mindiff", required = true) - protected BigDecimal mindiff; - @XmlAttribute(name = "numobs", required = true) - protected BigInteger numobs; - @XmlAttribute(name = "obsval", required = true) - protected BigDecimal obsval; - @XmlAttribute(name = "stdev", required = true) - protected BigDecimal stdev; - - /** - * Gets the value of the zscore property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getZscore() { - return zscore; - } - - /** - * Sets the value of the zscore property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setZscore(BigDecimal value) { - this.zscore = value; - } - - /** - * Gets the value of the atoms property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAtoms() { - return atoms; - } - - /** - * Sets the value of the atoms property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAtoms(String value) { - this.atoms = value; - } - - /** - * Gets the value of the mean property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getMean() { - return mean; - } - - /** - * Sets the value of the mean property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setMean(BigDecimal value) { - this.mean = value; - } - - /** - * Gets the value of the mindiff property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getMindiff() { - return mindiff; - } - - /** - * Sets the value of the mindiff property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setMindiff(BigDecimal value) { - this.mindiff = value; - } - - /** - * Gets the value of the numobs property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getNumobs() { - return numobs; - } - - /** - * Sets the value of the numobs property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setNumobs(BigInteger value) { - this.numobs = value; - } - - /** - * Gets the value of the obsval property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getObsval() { - return obsval; - } - - /** - * Sets the value of the obsval property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setObsval(BigDecimal value) { - this.obsval = value; - } - - /** - * Gets the value of the stdev property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getStdev() { - return stdev; - } - - /** - * Sets the value of the stdev property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setStdev(BigDecimal value) { - this.stdev = value; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/MogBondOutlier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/MogBondOutlier.java deleted file mode 100644 index d9dab2627b..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/MogBondOutlier.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import java.math.BigDecimal; -import java.math.BigInteger; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="Zscore" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="atoms" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="mean" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="mindiff" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="numobs" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="obsval" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="stdev" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "mog-bond-outlier") -public class MogBondOutlier { - - @XmlAttribute(name = "Zscore", required = true) - protected BigDecimal zscore; - @XmlAttribute(name = "atoms", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String atoms; - @XmlAttribute(name = "mean", required = true) - protected BigDecimal mean; - @XmlAttribute(name = "mindiff", required = true) - protected BigDecimal mindiff; - @XmlAttribute(name = "numobs", required = true) - protected BigInteger numobs; - @XmlAttribute(name = "obsval", required = true) - protected BigDecimal obsval; - @XmlAttribute(name = "stdev", required = true) - protected BigDecimal stdev; - - /** - * Gets the value of the zscore property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getZscore() { - return zscore; - } - - /** - * Sets the value of the zscore property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setZscore(BigDecimal value) { - this.zscore = value; - } - - /** - * Gets the value of the atoms property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAtoms() { - return atoms; - } - - /** - * Sets the value of the atoms property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAtoms(String value) { - this.atoms = value; - } - - /** - * Gets the value of the mean property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getMean() { - return mean; - } - - /** - * Sets the value of the mean property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setMean(BigDecimal value) { - this.mean = value; - } - - /** - * Gets the value of the mindiff property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getMindiff() { - return mindiff; - } - - /** - * Sets the value of the mindiff property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setMindiff(BigDecimal value) { - this.mindiff = value; - } - - /** - * Gets the value of the numobs property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getNumobs() { - return numobs; - } - - /** - * Sets the value of the numobs property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setNumobs(BigInteger value) { - this.numobs = value; - } - - /** - * Gets the value of the obsval property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getObsval() { - return obsval; - } - - /** - * Sets the value of the obsval property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setObsval(BigDecimal value) { - this.obsval = value; - } - - /** - * Gets the value of the stdev property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getStdev() { - return stdev; - } - - /** - * Sets the value of the stdev property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setStdev(BigDecimal value) { - this.stdev = value; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/ObjectFactory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/ObjectFactory.java deleted file mode 100644 index 2d997f0c45..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/ObjectFactory.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.XmlRegistry; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the org.biojava.nbio.structure.validation package. - *

    An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.biojava.nbio.structure.validation - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link BondOutlier } - * - */ - public BondOutlier createBondOutlier() { - return new BondOutlier(); - } - - /** - * Create an instance of {@link Programs } - * - */ - public Programs createPrograms() { - return new Programs(); - } - - /** - * Create an instance of {@link Program } - * - */ - public Program createProgram() { - return new Program(); - } - - /** - * Create an instance of {@link Entry } - * - */ - public Entry createEntry() { - return new Entry(); - } - - /** - * Create an instance of {@link WwPDBValidationInformation } - * - */ - public WwPDBValidationInformation createWwPDBValidationInformation() { - return new WwPDBValidationInformation(); - } - - /** - * Create an instance of {@link ModelledSubgroup } - * - */ - public ModelledSubgroup createModelledSubgroup() { - return new ModelledSubgroup(); - } - - /** - * Create an instance of {@link AngleOutlier } - * - */ - public AngleOutlier createAngleOutlier() { - return new AngleOutlier(); - } - - /** - * Create an instance of {@link Clash } - * - */ - public Clash createClash() { - return new Clash(); - } - - /** - * Create an instance of {@link MogAngleOutlier } - * - */ - public MogAngleOutlier createMogAngleOutlier() { - return new MogAngleOutlier(); - } - - /** - * Create an instance of {@link SymmClash } - * - */ - public SymmClash createSymmClash() { - return new SymmClash(); - } - - /** - * Create an instance of {@link MogBondOutlier } - * - */ - public MogBondOutlier createMogBondOutlier() { - return new MogBondOutlier(); - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Program.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Program.java deleted file mode 100644 index 2d0c3f13c0..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Program.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="properties" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *       <attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "program") -public class Program { - - @XmlAttribute(name = "name", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String name; - @XmlAttribute(name = "properties", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String properties; - @XmlAttribute(name = "version", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String version; - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the properties property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getProperties() { - return properties; - } - - /** - * Sets the value of the properties property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setProperties(String value) { - this.properties = value; - } - - /** - * Gets the value of the version property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getVersion() { - return version; - } - - /** - * Sets the value of the version property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setVersion(String value) { - this.version = value; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Programs.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Programs.java deleted file mode 100644 index afd4ac4876..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/Programs.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import java.util.ArrayList; -import java.util.List; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element ref="{}program" maxOccurs="unbounded"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "program" -}) -@XmlRootElement(name = "programs") -public class Programs { - - @XmlElement(required = true) - protected List program; - - /** - * Gets the value of the program property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the program property. - * - *

    - * For example, to add a new item, do as follows: - *

    -	 *    getProgram().add(newItem);
    -	 * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link Program } - * - * - */ - public List getProgram() { - if (program == null) { - program = new ArrayList(); - } - return this.program; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/SymmClash.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/SymmClash.java deleted file mode 100644 index 78976deb81..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/SymmClash.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.math.BigDecimal; -import java.math.BigInteger; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <attribute name="atom" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
    - *       <attribute name="clashmag" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="dist" use="required" type="{http://www.w3.org/2001/XMLSchema}decimal" />
    - *       <attribute name="scid" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
    - *       <attribute name="symop" use="required" type="{http://www.w3.org/2001/XMLSchema}NMTOKEN" />
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "") -@XmlRootElement(name = "symm-clash") -public class SymmClash { - - @XmlAttribute(name = "atom", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String atom; - @XmlAttribute(name = "clashmag", required = true) - protected BigDecimal clashmag; - @XmlAttribute(name = "dist", required = true) - protected BigDecimal dist; - @XmlAttribute(name = "scid", required = true) - protected BigInteger scid; - @XmlAttribute(name = "symop", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NMTOKEN") - protected String symop; - - /** - * Gets the value of the atom property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAtom() { - return atom; - } - - /** - * Sets the value of the atom property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAtom(String value) { - this.atom = value; - } - - /** - * Gets the value of the clashmag property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getClashmag() { - return clashmag; - } - - /** - * Sets the value of the clashmag property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setClashmag(BigDecimal value) { - this.clashmag = value; - } - - /** - * Gets the value of the dist property. - * - * @return - * possible object is - * {@link BigDecimal } - * - */ - public BigDecimal getDist() { - return dist; - } - - /** - * Sets the value of the dist property. - * - * @param value - * allowed object is - * {@link BigDecimal } - * - */ - public void setDist(BigDecimal value) { - this.dist = value; - } - - /** - * Gets the value of the scid property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getScid() { - return scid; - } - - /** - * Sets the value of the scid property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setScid(BigInteger value) { - this.scid = value; - } - - /** - * Gets the value of the symop property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getSymop() { - return symop; - } - - /** - * Sets the value of the symop property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSymop(String value) { - this.symop = value; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/WwPDBValidationInformation.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/WwPDBValidationInformation.java deleted file mode 100644 index 85585a9770..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/validation/WwPDBValidationInformation.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2013.12.17 at 03:04:15 PM PST -// - - -package org.biojava.nbio.structure.validation; - -import javax.xml.bind.annotation.*; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - - -/** - *

    Java class for anonymous complex type. - * - *

    The following schema fragment specifies the expected content contained within this class. - * - *

    - * <complexType>
    - *   <complexContent>
    - *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    - *       <sequence>
    - *         <element ref="{}Entry"/>
    - *         <element ref="{}ModelledSubgroup" maxOccurs="unbounded"/>
    - *         <element ref="{}programs"/>
    - *       </sequence>
    - *     </restriction>
    - *   </complexContent>
    - * </complexType>
    - * 
    - * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "entry", - "modelledSubgroup", - "programs" -}) -@XmlRootElement(name = "wwPDB-validation-information") -public class WwPDBValidationInformation implements Serializable { - - private static final long serialVersionUID = -996804963717482650L; - - @XmlElement(name = "Entry", required = true) - protected Entry entry; - @XmlElement(name = "ModelledSubgroup", required = true) - protected List modelledSubgroup; - @XmlElement(required = true) - protected Programs programs; - - /** - * Gets the value of the entry property. - * - * @return - * possible object is - * {@link Entry } - * - */ - public Entry getEntry() { - return entry; - } - - /** - * Sets the value of the entry property. - * - * @param value - * allowed object is - * {@link Entry } - * - */ - public void setEntry(Entry value) { - this.entry = value; - } - - /** - * Gets the value of the modelledSubgroup property. - * - *

    - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the modelledSubgroup property. - * - *

    - * For example, to add a new item, do as follows: - *

    -	 *    getModelledSubgroup().add(newItem);
    -	 * 
    - * - * - *

    - * Objects of the following type(s) are allowed in the list - * {@link ModelledSubgroup } - * - * - */ - public List getModelledSubgroup() { - if (modelledSubgroup == null) { - modelledSubgroup = new ArrayList(); - } - return this.modelledSubgroup; - } - - /** - * Gets the value of the programs property. - * - * @return - * possible object is - * {@link Programs } - * - */ - public Programs getPrograms() { - return programs; - } - - /** - * Sets the value of the programs property. - * - * @param value - * allowed object is - * {@link Programs } - * - */ - public void setPrograms(Programs value) { - this.programs = value; - } - -} diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/validation/TestValidationReportParsing.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/validation/TestValidationReportParsing.java deleted file mode 100644 index da1b9a9b02..0000000000 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/validation/TestValidationReportParsing.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Sep 18, 2013 - * Author: ap3 - */ - -package org.biojava.nbio.structure.validation; - -import org.junit.Test; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Unmarshaller; -import java.io.InputStream; -import java.util.zip.GZIPInputStream; - -import static org.junit.Assert.fail; - -public class TestValidationReportParsing { - - @Test - public void test() { - - String[] testPDBids = new String[]{ - - "3vtq", - "3vtu", - "3vtv", - "3vtw", - "3vu8", - "3vua", - "3vv5", - "3vvd", - "3vve", - "3vvf", - "3vw5", - "3w1f", - "3w5p", - "3w5q", - "3w5r", - "3w5t", - "3w9y", - "3wcp", - "3zjh", - "3zji", - "3zjj", - "3zjm", - "3zjn", - "3zjo", - "3zjp", - "3zjq", - "3zjr", - "3zjs", - "3znv", - "3znx", - "3znz", - "3zoi", - "3zoj", - "3zpy", - }; - - for (String pdbId : testPDBids){ - testPDB(pdbId); - } - - } - - private void testPDB(String pdbId) { - try { - JAXBContext ctx = JAXBContext.newInstance(new Class[] {WwPDBValidationInformation.class}); - - Unmarshaller um = ctx.createUnmarshaller(); - - InputStream inStream = new GZIPInputStream(this.getClass().getResourceAsStream("/validation/"+pdbId+"-valdata.xml.gz")); - - WwPDBValidationInformation validationReport = (WwPDBValidationInformation) um.unmarshal(inStream); - - validationReport.getEntry(); - -// Entry entry = validationReport.getEntry(); -// System.out.println(pdbId + " " + entry.getPDBRevisionNumber() + -// "\t Rfree: " + entry.getDCCRfree() + -// "\t Clashscore " + entry.getClashscore() + -// "\t % Ramachandran outliers: " + entry.getPercentRamaOutliers() + -// "\t % RSRC outliers: " + entry.getPercentRSRZOutliers() ); - - - } catch (Exception e){ - e.printStackTrace(); - fail(e.getMessage()); - } - } - -} diff --git a/biojava-structure/src/test/resources/validation/3vtq-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3vtq-valdata.xml.gz deleted file mode 100644 index c08d37f7a0eca2baf57eb30431362cb1640f624b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11154 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 diff --git a/biojava-structure/src/test/resources/validation/3vtu-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3vtu-valdata.xml.gz deleted file mode 100644 index 3d3517897296847b718d1c980db837cf945c0432..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11286 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 M2aIE<{)asQ0Q$@coB#j- diff --git a/biojava-structure/src/test/resources/validation/3vtv-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3vtv-valdata.xml.gz deleted file mode 100644 index 58e3481cabe099f89a9a43d06f1d6d98bb809733..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10343 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 F0RS|zE{p&G diff --git a/biojava-structure/src/test/resources/validation/3vtw-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3vtw-valdata.xml.gz deleted file mode 100644 index b3e7994b20be0f1b06318c7738f79eaa5e03d609..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20534 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 Jk6C+B0sw-;Rxtno diff --git a/biojava-structure/src/test/resources/validation/3vu8-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3vu8-valdata.xml.gz deleted file mode 100644 index a9c114be3bc93f9ae8ac69879aac05b86f79e26f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24179 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 z 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 O)WYyi|S`zlKtHCD+mG$%mN}i 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 diff --git a/biojava-structure/src/test/resources/validation/3vvd-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3vvd-valdata.xml.gz deleted file mode 100644 index d86a67c784b0566be30dd284505a972c74695de1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24768 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 Ko*PrY6$1dk+0vi@ diff --git a/biojava-structure/src/test/resources/validation/3vvf-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3vvf-valdata.xml.gz deleted file mode 100644 index 7953d5b202151275d98df6f533d596ef09648a06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21436 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 bhRs-BeZIcA-2D09|MmX^Kz2EFA&~+A4#>-_ diff --git a/biojava-structure/src/test/resources/validation/3vw5-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3vw5-valdata.xml.gz deleted file mode 100644 index 36889ab313c858061f4c6feabc2c456913be1593..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43981 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 Oum20*IKo~)IspLvmiGAo diff --git a/biojava-structure/src/test/resources/validation/3w5p-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3w5p-valdata.xml.gz deleted file mode 100644 index 3906e5c6571bc3caa72e02164d87c9cb793ed712..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13781 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 diff --git a/biojava-structure/src/test/resources/validation/3w9y-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3w9y-valdata.xml.gz deleted file mode 100644 index 74883f5c1e729e6dbe92fe70dc6eddebe0dee892..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8534 zcmV-cA*tRUiwFo0<~dRT12cCyc`bHfY-C|{VJ>)WYyj0=Yi}Dzvi-dKD+B@;*b9(M zzo#3BcA?1518^L}%4U(hxDY65tPtS~H8(IBtE)&y6bW3 zRMpr2_+vghdta_M)8*oPz{hNG_K&~+_3IBG-n{r`^nNm%-c2h1r_prrZn>Us|NZyB z{^jeJi)#Jn+2!RM)x6h?<(QrQ?W(M*S^3|Cvlo|_*Kf}UY%JvNhj;6;-2S4df3Ys# zO&8_7TvXSq_40l_nV%2dzWnybi%b9aNj14xOgGDFy)YjeUCt); zd)U|sJ2?Ac=>@!+-p?oDW3>ER_^b;rUf7>?`FE_Iho%}EVmhDS^E2sCrRgXWxXN=EYFV8m9`^EI#^mekS&Q_c9 z;m&WQ|NdIK@L6|$2XCwLZtPd~VY+w~Bv!`leiGZQbpAp8YdZ7G_+}EG#rfcWlp1qg z40rz%dd!^|j+mE`4dK84+q}^WIrZnpKX_@zmWjdH+v&rVSjeko1RaTB&`>S^U9KF4I`|r{6p_)zoMxGA}Hn!ZdR9UK3K@Tc|k_8LCQ|JFax`O5G2FU_60s>+rB<9s>ur~hVJ{W+X3?;mEvKm5BV z_vNs>+YIBEZiXM$)2j5>b#Qj`F#G-5FYA4{Iye4{`Pdn~_xs<&Bb3sM@N_}pm#~@s z>iXxhSdM1X`^n;NGxB$Rv|Y^k;Lmd7|MV~)eeaL^-NUVaIage4fA`~bHY?XZEbgYa zWe`(v>-V_h0q}9b;~)1nI~*GLBi&auR{oFm)qI~gHoW~sD5+!N*tET>``GC88`_Ue z@*R8P$*~xG6}0M)%e&I==-t)B&HZ}$usVA^sh0DNS6u$U`!h7FZv89H2WS4@@9&ql zw+~yD9k%ZFx5?D2n~TBOw0X@ueBAc*(dXv{T7H=Lb7TFU+3jLCi^<&o<>Kmf{nLY2 z#f4P<2fx@U|0n!li{j&QgrjpPLENJt1s}^G$m+N0 z`C!Dg3y)y6@jvjwA8xF9_7{28@(tmE5fO+<@H)tCFK2{$ZHs4@qd&a>~CGkK1SWc2C6JbNrdRcR-64 zl+I33=rJ>}eI{&Ky?tIw+V1W9;nhpnzOBQt(-gRWVEH5-a_*01_aVRh<|C(^*C%;* z%Ke3O22MGHQ_jAm&Gw#)jau0{(8`~(*Sy(lG(!e8GM-iEL%d_UOHp1e#;SnBC4#A~ z1vX~ues&1_>g7LCV9|QG6dW!g@p4+-ayefFPpZ~!^l};#FQ;a$TCsU+(RHuAX!@B) zO&xCQ8~bl|w_v;Tc5AVA?p={`@4kEWEAG35-R1@CHbZ+Q*lC=)LXC^4y1WnD_;kwT zn`qTI?ZHGZ?!ZP{8?O{MjUVeBT$VD?myPmz9d*}>MtKQ_%1dZ}T+u{}o$~UAT%KNc zHD)#hg1R|SqA{{Tmp^Xx#ca0xK(_kFE26k`R9tY83kFtJ!!`#5>*-~D*<53_cNsYt zSAUXw@Z+_rZ`;ld)nT*ieU~g{F<$+8g&W_*Evu?R6)Mrc!O$fb^e6lG z`ro_#V|xm;h+0s50f$yKyXSQRk5Le7)Zj?5RMdBI^#*q@MnNM1F_6_@fE0`8mT`Wn zxGw}M(ZeuByryTtBS;Z*6JwpF7W-&Be2ot5bsWmq$eia^2ZBTxYM5) zaMApNblgB2FPu`J;G(%ftBb}#(E$(?EWj~6G}CzhAwY~KR5cFiNZXX3Kyfe4+AoMR zEV`s7x}<)^>bNdxqY;!HJ0dV^9xqP|j2c1n4uJ*S4%S$*00reZNj(XyI2w>f1$yV) zWD6|11cso)Aq-?h2GrNr4c0C`V%8uxBkvZv+?Zo~J)g!L8Vsf?;tl5JxR5l6>mv^U zs!ZbrkCaY%!Bk;s)hez62Uw!h&vTGm(*p#rxi>WkY&Pe4m(b`C_v$4AxjF*Z7~%+! z*1^NI8JG8f?wn@DU9#y_C(} zEksJ*H{X-94E|c}t~{C}M5DlWVSXo`_%4?(`D3&oyP^d#*3Sj=`Ur?aay~+#2HaiA z^8;etjae6PLAXM7kaI(N@$kLN5))aDHvp6R1mo5?YpW4QOS(=O|+>26>c5I`@=fXu0(eFkA;HO%_@D8mY z0N6q`7~;OCTH!^5KI}t*>;PJ!4=7L;em!yj%+_-3Kv=y^y=Q@eMxY{Kpa}4oFq`4n z_u&_Wgl7awoFnEix)|Ye6YD_e9=`^(RdBQ4TWeLFHWQ`1I7^DZ^NQ1s%^fyEE-qzsk*d@2W>)Yy*mZyUpN%=X%{++~4kjRRzAo00;ntsrGIW|y;V&Z1=WWIue_f~ZsFHoEe z32dR{?j*KfI&z^{%))W0QwRjL{k9cA)R=%nafNNGy7^8tIZT!yE)|Yhl~{#7I?P4$%{x z!`+y3P*v2OdXSNqfZHbY~&NJ z(1Wr77ZrrDk^zuqi~DXiU9BcJ-ezs4cjfN)JZBp$Ja}-djEDmWH{pXAjun)exmRMnH7@=h)PC8}GyT+6J>7PHp`eA$Pn>Zg$A3?9QX`{3BX$g9P z4GP5ZYiD$KWMn$b!kgouc8I_R1Q*f-YE>E5pdYrsz^Yy22z4>xnNq;hHJ+(gkC?}n zpdGCOZIMIx>LuKAP*f7w>QO7CtCUH&1 zr_?>^ae@7BWK85so-&+7v2MF_b-L%EY8V2aR%c+nx(BeqUlgpy*RdAJ`@hNJr&kv! zG**RM$h{dva8ek&}<=BT*4r=RuHUKEge3;8$yyAmsd-ny4pgDBB8nWU$}?ztefS*S068d8s%tQIk65HM zCiOWume^P%8>7#mSw`Z#C-N(_#B)%G#glbJBsFJwYl#i1j6fhlD*g=fE3hFRS_L0q!F)7^u~d1_jPsnzBz4gO;}!_+a9I*7&vc&FV9t?WG~0#SR{IWYb`x ziDOFg@0Pb0@L>MEwIASfD**72nz7=h#Yyys)O-Qmi7Y@@a7Z6}YjX`+y$VpPq z3Epu|jXqJjUSe0ZkdlhY++<2>?^YIV8W0O<7`kfGWk}l#lO@n3qO>9=>s2z~+Pg@t zWkYDg2|1x)Ilyy2Gs( z?dm0EWF$7egc>24LjFj?$cn}_d;(otILIP$c0*Dy;}Q1}UlGl0BP~KCTUgQHN?-_y z9VaC;V&g6Y-t4EbhrzOQE+lj_l}VI2BIF$~ZsVX`?gRyTprj635#GyId#@4by%s?hp^WRf6b01^ef|$qiB0d?wMvyGYp>anXbX3s}^9uQgj2z=5cNqndX%!Ms zE>$vura)hu7&Nc;nxv!kv0!}yc{$+}zKmYszZ@5R9mDvZ7W>J1#1qE<>xJ}2sWmU2_5uJ0I6 zM7j;{&%Qc|0S|@m8V&fPxanrO#C(&PK;0##IpmXGQj*13MK)FRJEcgW`+N5x))UP~ z3VkwCZBEN2jyu2sj<7epsK1s z9~2k|8qzpGw9FBS`N2NUOD}UZElyN6$UT+GDJ;ZR$B9Bu=V}78PsE1$Vr*>&wAss% z2_y=*BC(Zmx)H(NiD|s(C!7ichejCi?}R*&$qb%%>`-D%Bvm9G1Zps0v=BUA8x5w2 zsdv8h#7@$TB{)6X4wa171Y}R*q^CeVOlF8MZjBvM_d@joLRS$(SH7(nIT7q^HMUFF2u>Es zHmL-5hBm2t{8EcCr2AB+S|5N@QIL$0Bm=3kAt&sVYT+dF0-$xPj_Zp@-NJ0$<#J~( zBfsP$6BeloifvNoNH8%vLa-u|9{iWEmRgOUcAm!Gcw-GMp4f9K0KJ%9r|?P?09sQ6T7XVV@l>1I->KAJFcwJ@>XKawo%Z+ zD>XZ5`iYKIRKo z2l2QVEU&S!eJVM>aPPRZ_cSP=`hpjGVD@QH4P#N>5S%`01CdPMQJ*jNI;C~878xXQ zyoL9K?TH2vS%&TH6wcO84qv7Pq^;dfEp)69qVWs7PF1JUeFY)eDl+6D|1bjrOUe=o z;1~!2AYG9YL-#`HE&>P+AS?$eNlIc$=!RCO#JR|RvAmFiUQ{)+PW0KuiND$@7_|DELQzsi^9xfARG(^l; zr3ZUckUI80?F6YE06EMYcSv0{{Q?_*hYWI)uoB5GRh0Z3Tb~kXk*KuaCH^Fiu~k@T z$^{f*D3gYJ&@;wHrG%+e;Ft*qDIAkiXxaw@+IiKB*A~i~(xc)i1=;~y)?#ZL0qsdS z&oKFY)IWrJAsA5a(Bda&9nb;@=ub*VcL9*h4HT_OmmzQ;rYGPPFgnCS2fgG-oITUi zICW2JFEP0!F-pHsQ8karCULYDPbm6x-$idHXQUo#W4e<$rP!jEOKJ! zJ~WRvDA0?@um~LLbgu?fJT5jZCBPC=i8KVxS@f2Eyd$q^AawxQk~DpaI7g1PX7DZa z@DvPSL*Wt-GvA9AVt?Sz=%m!ov_*eaA)ReVfkT4rPk4KdMG%s5N3d@sa-l-&l#|pY z8A;Oj&<`O!YU2Xyk{rW{ODHggrKE*6Kk|r`I9tRU<){lZOcBt@LUQ6;I@aY|ItDE- z$k^v1Ck@=od`VW*WOot^7*m%VAWDJ<$J&zjr1h&rwi{ET6=aruYJ|ReEjZXd4ULVG z{Y^>M$w7b9y;ciIe*mvl@e?%*_SScDcJx9o`@bP zYL>)P6{zGVm`f<|LhuBmFw)fMWLd>fRNFe1Jk+t|wm5Jd9Y#5%5fFz|Iep1`8L72v zsod!MW(tT-j)RvVSj+lau)- z5(XN`WP`K4=h=9BEwd`H`|c8H!L*O3j5b6C6VOn&=54X z4(%vAeMWQGURs|!Z1hx@LF}}VOOBYrk_Z>uhK7=eKbGzHlUc+Vj7&C`{*>xPVa8hN zmg>b&bo4o6Z_`dVMjf$f>An*V>>%baY6~R-C+p~`NY&jV>SB`Q zzP$$ws3dv7thK?}w&&N$k`zS^Jhx{69kwQgcu~ZwDPrbcY*k`gX0Cx7_eqjP;7eWHcPDY^Ol z^>MT7`r5TVY+XXSE9NjJKYxAFYdVu!AGEu}N%p}9I?DQrx+JS}eaKG4zFvjw&J*?l ziycB%v&(LD$%sZU-s`bRT~NTYaL}P#=gjpw$o|!(NnPu+s0*-zdJbFn z^Vb(rJjwNunljAc=2UhbVE^2%mqf?<$dqPX9R2)xZ>_e>UF+lR&zI$t8Xn?)=&?)P z4>C#%;jJ91+#&XF$A#})AKD^z{PPz=*pw~jXp0;qG>`OrmE5(9>{=h%BJ8S}Gm!NV z>*Kr5j$P|R`{6h|-wYbxVb-Toz6J;Tff+ubj^nF&U&AHu2iT9I07`;6&iz$8K3(Vf zz-t0@+p>m&99r*UL(1`hLlS;~G8^hli`R#0`5)z0;i zHjMH4>YS!Khk3ptb$RcbjA2_Y>Nd9T4sYtF5>_;Kv{gC2F@rSMl40Wy#SP;}0lm$QmVj82=^dA8526*aqWB_Ra5~NbVoWpU3Aba#}ne==`PPBT}GP z0REgaE%Gq>xk%YJgYk#M{o9?t)p~iqp3FB}V$JS{v-+b}<@&Z&vU*i%B)PSWGv|%D?>2VffPZ^!B=0(a#^I zi&w+Rli&YqI@>H4-;|qbI-gW!{W>xHVdt3@Ot4*@_5SDG-QLnq+aASX`0u)W z=cSta{k-12XV{!me86KSI+i-~zqpxJf6{NbSuXA#57Kb;+jO|vOo!XEGbDWeAzZ%p zLx`l?VL0={jtk)5HGDUlu2x}lN1N$gxz$%7g&gyuRf_U%PoZ?&Mz6Pqjk+8L!tO9= zz2VKn?DuPbSKfzx{C#_hFPHPxtgOmKx$zgNR-{A!F2Cd3OXU}IJzIX*`_=Gm`EEYB z{iR;<@Z06}x3|}RbL!jee{*^HM(yMY-%r2!CUM5T{wgZgufO{6Ask&e-_wOZR`cz@ Q|Nhti1Ik3t`t0Wb07i`O{{R30 diff --git a/biojava-structure/src/test/resources/validation/3wcp-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3wcp-valdata.xml.gz deleted file mode 100644 index fb1e7d61082e96ad26ffc767d6e86b2b5e8eacf2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40434 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�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 alX!9c`R49w{qO(!kN*Sd7fguV-~s?_u>+z2 diff --git a/biojava-structure/src/test/resources/validation/3zjj-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3zjj-valdata.xml.gz deleted file mode 100644 index 21e1af6c5636f4a62d5f54784916309ebfe1d5b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34089 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

    ll$wIQ|34=r7GR?@?nq6XrA15E=2iAJT=P=YLF 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 diff --git a/biojava-structure/src/test/resources/validation/3zjm-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3zjm-valdata.xml.gz deleted file mode 100644 index 6e0a70b0bda540488ea981a37a65171452f75c41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34412 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

    f={lJ4 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

      g<10$Qn4_>O?OH^owSAdg$#PjKyE52;`-(9e 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

      All methods query the - * - * PDB website. + *

      + * All methods query the + * + * RCSB Data REST API * - *

      PDB supersessions form a directed acyclic graph, where edges point from an + *

      + * PDB supersessions form a directed acyclic graph, where edges point from an * obsolete ID to the entry that directly superseded it. For example, here are - * edges from one portion of the graph:
      - * + * edges from one portion of the graph: + *

      * 1CAT -> 3CAT
      * 3CAT -> 7CAT
      * 3CAT -> 8CAT
      * - *

      The methods {@link #getReplaces(String, boolean) getReplaces(pdbId, false)}/ + *

      + * The methods {@link #getReplaces(String, boolean) getReplaces(pdbId, false)}/ * {@link #getReplacement(String, boolean, boolean) getReplacement(pdbId, false, true)} * just get the incoming/outgoing edges for a single node. The recursive versions * ({@link #getReplaces(String, boolean) getReplaces(pdbId, true)}, @@ -63,39 +68,46 @@ * will do a depth-first search up/down the tree and return a list of all nodes ] * reached. * - *

      Finally, the getCurrent() method returns a single PDB ID from among the + *

      + * Finally, the {@link #getCurrent(String)} method returns a single PDB ID from among the * results of - * {@link #getReplacement(String, boolean) getReplacement(pdbId, true)}. + * {@link #getReplacement(String, boolean, boolean)}. * To be consistent with the old REST ordering, this is the PDB ID that occurs * last alphabetically. * - *

      Results are cached to reduce server load. + *

      + * Results are cached to reduce server load. * - * @author Spencer Bliven + * @author Spencer Bliven * @author Amr AL-Hossary + * @author Jose Duarte * @since 3.0.2 */ public class PDBStatus { private static final Logger logger = LoggerFactory.getLogger(PDBStatus.class); - public static final String DEFAULT_PDB_SERVER = "www.rcsb.org"; - public static final String PDB_SERVER_PROPERTY = "PDB.SERVER"; + //public static final String DEFAULT_PDB_SERVER = "www.rcsb.org"; + public static final String DEFAULT_RCSB_DATA_API_SERVER = "data.rcsb.org"; + public static final String ALL_CURRENT_ENDPOINT = "https://%s/rest/v1/holdings/current/entry_ids"; /** * saves the returned results for further use. * */ - //TODO Use SoftReferences to allow garbage collection - private static Map> recordsCache= new Hashtable>(); + private static final Map> recordsCache= new Hashtable<>(); /** * Represents the status of PDB IDs. 'OBSOLETE' and 'CURRENT' are the most * common. - * @author Spencer Bliven + * @author Spencer Bliven * */ public enum Status { + // this is the list for unreleased: "AUCO" "AUTH" "HOLD" "HPUB" "POLC" "PROC" "REFI" "REPL" "WAIT" "WDRN" + // The remaining from below are removed-related: OBSOLETE, MODEL (not available in Data API). + // In Data API in rcsb_repository_holdings_insilico_models.status_code: 3 values "OBS", "TRSF", "WDRN" and 1 in rcsb_repository_holdings_transferred.status_code: "TRSF" + // for current: CURRENT (not available in current API) OBSOLETE, CURRENT, AUTH, @@ -110,11 +122,7 @@ public enum Status { MODEL, UNKNOWN; - /** - * - * @param statusStr - * @return * @throws IllegalArgumentException If the string is not recognized */ public static Status fromString(String statusStr) { @@ -159,7 +167,7 @@ else if(statusStrUpper.equalsIgnoreCase("UNKNOWN")) * @param pdbId * @return The status, or null if an error occurred. */ - public static Status getStatus(String pdbId) { + public static Status getStatus(String pdbId) throws IOException { Status[] statuses = getStatus(new String[] {pdbId}); if(statuses != null) { assert(statuses.length == 1); @@ -176,7 +184,7 @@ public static Status getStatus(String pdbId) { * @param pdbIds * @return The status array, or null if an error occurred. */ - public static Status[] getStatus(String[] pdbIds) { + public static Status[] getStatus(String[] pdbIds) throws IOException { Status[] statuses = new Status[pdbIds.length]; List> attrList = getStatusIdRecords(pdbIds); @@ -234,8 +242,8 @@ public static Status[] getStatus(String[] pdbIds) { * @param oldPdbId * @return The replacement for oldPdbId, or null if none are found or if an error occurred. */ - public static String getCurrent(String oldPdbId) { - List replacements = getReplacement(oldPdbId,true, false); + public static String getCurrent(String oldPdbId) throws IOException { + List replacements = getReplacement(oldPdbId,true, false); if(replacements != null && !replacements.isEmpty()) return replacements.get(0); else @@ -260,7 +268,7 @@ public static String getCurrent(String oldPdbId) { * current records. A return value of null indicates that the ID has * been removed from the PDB or that an error has occurred. */ - public static List getReplacement(String oldPdbId, boolean recurse, boolean includeObsolete) { + public static List getReplacement(String oldPdbId, boolean recurse, boolean includeObsolete) throws IOException { List> attrList = getStatusIdRecords(new String[] {oldPdbId}); //Expect a single record if(attrList == null || attrList.size() != 1) { @@ -291,7 +299,7 @@ public static List getReplacement(String oldPdbId, boolean recurse, bool } // If we're current, just return - LinkedList results = new LinkedList(); + LinkedList results = new LinkedList<>(); switch(status) { case CURRENT: results.add(oldPdbId); @@ -459,7 +467,7 @@ private static void mergeReversed(List merged, * @return A (possibly empty) list of ID(s) of the ancestor(s) of * newPdbId, or null if an error occurred. */ - public static List getReplaces(String newPdbId, boolean recurse) { + public static List getReplaces(String newPdbId, boolean recurse) throws IOException { List> attrList = getStatusIdRecords(new String[] {newPdbId}); //Expect a single record if(attrList == null || attrList.size() != 1) { @@ -516,34 +524,34 @@ public static void clearCache() { /** * Fetches the status of one or more pdbIDs from the server. * - *

      Returns the results as a list of Attributes. + *

      + * Returns the results as a list of Attributes. * Each attribute should contain "structureId" and "status" attributes, and * possibly more. * - *

      Example:
      + *

      + * Example: + *

      * http://www.rcsb.org/pdb/rest/idStatus?structureID=1HHB,4HHB
      - *

      <idStatus>
      -	 *  <record structureId="1HHB" status="OBSOLETE" replacedBy="4HHB"/>
      -	 *  <record structureId="4HHB" status="CURRENT" replaces="1HHB"/>
      -	 *</idStatus>
      +	 * 
      +	 * <idStatus>
      +	 *   <record structureId="1HHB" status="OBSOLETE" replacedBy="4HHB"/>
      +	 *   <record structureId="4HHB" status="CURRENT" replaces="1HHB"/>
      +	 * </idStatus>
       	 * 
      * - *

      Results are not guaranteed to be returned in the same order as pdbIDs. + *

      + * Results are not guaranteed to be returned in the same order as pdbIDs. * Refer to the structureId property to match them. * - * @param pdbIDs + * @param pdbIDs the PDB identifiers * @return A map between attributes and values */ - private static List> getStatusIdRecords(String[] pdbIDs) { - - List> result = new ArrayList>(pdbIDs.length); + private static List> getStatusIdRecords(String[] pdbIDs) throws IOException { - String serverName = System.getProperty(PDB_SERVER_PROPERTY); + List> result = new ArrayList<>(pdbIDs.length); - if ( serverName == null) - serverName = DEFAULT_PDB_SERVER; - else - logger.info(String.format("Got System property %s=%s",PDB_SERVER_PROPERTY,serverName)); + String serverName = DEFAULT_RCSB_DATA_API_SERVER; // Build REST query URL if(pdbIDs.length < 1) { @@ -566,143 +574,65 @@ private static List> getStatusIdRecords(String[] pdbIDs) { return result; } - try { - logger.info("Fetching {}", urlStr); + logger.info("Fetching {}", urlStr); - URL url = new URL(urlStr); + URL url = new URL(urlStr); - InputStream uStream = url.openStream(); + InputStream uStream = url.openStream(); - InputSource source = new InputSource(uStream); - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - SAXParser parser = parserFactory.newSAXParser(); - XMLReader reader = parser.getXMLReader(); + InputSource source = new InputSource(uStream); + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + SAXParser parser = parserFactory.newSAXParser(); + XMLReader reader = parser.getXMLReader(); - PDBStatusXMLHandler handler = new PDBStatusXMLHandler(); + PDBStatusXMLHandler handler = new PDBStatusXMLHandler(); - reader.setContentHandler(handler); - reader.parse(source); + reader.setContentHandler(handler); + reader.parse(source); - // Fetch results of SAX parsing - List> records = handler.getRecords(); + // Fetch results of SAX parsing + List> records = handler.getRecords(); - //add to cache - for(Map record : records) { - String pdbId = record.get("structureId").toUpperCase(); - if(pdbId != null) { - recordsCache.put(pdbId, record); - } + //add to cache + for (Map record : records) { + String pdbId = record.get("structureId").toUpperCase(); + if (pdbId != null) { + recordsCache.put(pdbId, record); } - - // return results - result.addAll(handler.getRecords()); - - // TODO should throw these forward and let the caller log - } catch (IOException e){ - logger.error("Problem getting status for {} from PDB server. Error: {}", Arrays.toString(pdbIDs), e.getMessage()); - return null; - } catch (SAXException e) { - logger.error("Problem getting status for {} from PDB server. Error: {}", Arrays.toString(pdbIDs), e.getMessage()); - return null; - } catch (ParserConfigurationException e) { - logger.error("Problem getting status for {} from PDB server. Error: {}", Arrays.toString(pdbIDs), e.getMessage()); - return null; } + // return results + result.addAll(handler.getRecords()); + return result; } /** - * Handles idStatus xml by storing attributes for all record elements. - * - * @author Spencer Bliven - * - */ - private static class PDBStatusXMLHandler extends DefaultHandler { - private List> records; - - public PDBStatusXMLHandler() { - records = new ArrayList>(); - } - - /** - * @param uri - * @param localName - * @param qName - * @param attributes - * @throws SAXException - * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) - */ - @Override - public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException { - //System.out.format("Starting element: uri='%s' localName='%s' qName='%s'\n", uri, localName, qName); - if(qName.equals("record")) { - //Convert attributes into a Map, as it should have been. - //Important since SAX reuses Attributes objects for different calls - Map attrMap = new HashMap(attributes.getLength()*2); - for(int i=0;i> getRecords() { - return records; - } - } - - /** Returns a list of current PDB IDs + * Returns all current PDB IDs * - * @return a list of PDB IDs, or null if a problem occurred + * @return a list of PDB IDs + * @throws IOException if a problem occurs retrieving the information */ - public static SortedSet getCurrentPDBIds() throws IOException { - SortedSet allPDBs = new TreeSet(); - String serverName = System.getProperty(PDB_SERVER_PROPERTY); - - if ( serverName == null) - serverName = DEFAULT_PDB_SERVER; - else - logger.info(String.format("Got System property %s=%s",PDB_SERVER_PROPERTY,serverName)); + //String serverName = System.getProperty(PDB_SERVER_PROPERTY); + String serverName = DEFAULT_RCSB_DATA_API_SERVER; // Build REST query URL - - String urlStr = String.format("http://%s/pdb/rest/getCurrent",serverName); + String urlStr = String.format(ALL_CURRENT_ENDPOINT, serverName); URL u = new URL(urlStr); InputStream stream = URLConnectionTools.getInputStream(u, 60000); - if (stream != null) { - BufferedReader reader = new BufferedReader( - new InputStreamReader(stream)); - - String line = null; - - while ((line = reader.readLine()) != null) { - int index = line.lastIndexOf("structureId="); - if (index > 0) { - allPDBs.add(line.substring(index + 13, index + 17)); - } - } - } - return allPDBs; + ObjectMapper objectMapper = new ObjectMapper(); + TypeFactory typeFactory = objectMapper.getTypeFactory(); + List pdbIdList = objectMapper.readValue(stream, typeFactory.constructCollectionType(List.class, String.class)); + return new TreeSet<>(pdbIdList); } + public static void main(String[] args) throws Exception { + SortedSet all = getCurrentPDBIds(); + System.out.println("Number of current PDB ids is: " + all.size()); + } } From 0a70219111cbb9dfa5def02ec8368849724c2bf5 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 22 Nov 2020 14:44:25 -0800 Subject: [PATCH 177/769] Now PDBStatus uses the current RCSB Data API --- .../org/biojava/nbio/structure/PDBStatus.java | 558 ++---------------- .../nbio/structure/io/LocalPDBDirectory.java | 2 +- .../biojava/nbio/structure/PDBStatusTest.java | 167 +----- 3 files changed, 64 insertions(+), 663 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java index 1fc54f9410..7abd790fb4 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java @@ -18,65 +18,29 @@ * http://www.biojava.org/ * */ -/** - * - */ package org.biojava.nbio.structure; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; import org.biojava.nbio.structure.align.util.URLConnectionTools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.xml.sax.*; -import org.xml.sax.helpers.DefaultHandler; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.net.URL; import java.util.*; /** - * Methods for getting the status of a PDB file (current, obsolete, etc) + * Methods for getting the status of a PDB file (current, obsolete, unreleased) * and for accessing different versions of the structure. * *

      * All methods query the * * RCSB Data REST API - * - *

      - * PDB supersessions form a directed acyclic graph, where edges point from an - * obsolete ID to the entry that directly superseded it. For example, here are - * edges from one portion of the graph: - *

      - * 1CAT -> 3CAT
      - * 3CAT -> 7CAT
      - * 3CAT -> 8CAT
      - * - *

      - * The methods {@link #getReplaces(String, boolean) getReplaces(pdbId, false)}/ - * {@link #getReplacement(String, boolean, boolean) getReplacement(pdbId, false, true)} - * just get the incoming/outgoing edges for a single node. The recursive versions - * ({@link #getReplaces(String, boolean) getReplaces(pdbId, true)}, - * {@link #getReplacement(String, boolean, boolean) getReplacement(pdbId, true, false)}) - * will do a depth-first search up/down the tree and return a list of all nodes ] - * reached. - * *

      - * Finally, the {@link #getCurrent(String)} method returns a single PDB ID from among the - * results of - * {@link #getReplacement(String, boolean, boolean)}. - * To be consistent with the old REST ordering, this is the PDB ID that occurs - * last alphabetically. - * - *

      - * Results are cached to reduce server load. * * @author Spencer Bliven * @author Amr AL-Hossary @@ -87,40 +51,21 @@ public class PDBStatus { private static final Logger logger = LoggerFactory.getLogger(PDBStatus.class); - //public static final String DEFAULT_PDB_SERVER = "www.rcsb.org"; public static final String DEFAULT_RCSB_DATA_API_SERVER = "data.rcsb.org"; public static final String ALL_CURRENT_ENDPOINT = "https://%s/rest/v1/holdings/current/entry_ids"; + public static final String STATUS_ENDPOINT = "https://%s/rest/v1/holdings/status/%s"; + public static final String STATUS_LIST_ENDPOINT = "https://%s/rest/v1/holdings/status?ids=%s"; /** - * saves the returned results for further use. - * - */ - private static final Map> recordsCache= new Hashtable<>(); - - /** - * Represents the status of PDB IDs. 'OBSOLETE' and 'CURRENT' are the most - * common. + * Represents a simplified 3 state status of PDB IDs. * @author Spencer Bliven * */ public enum Status { - // this is the list for unreleased: "AUCO" "AUTH" "HOLD" "HPUB" "POLC" "PROC" "REFI" "REPL" "WAIT" "WDRN" - // The remaining from below are removed-related: OBSOLETE, MODEL (not available in Data API). - // In Data API in rcsb_repository_holdings_insilico_models.status_code: 3 values "OBS", "TRSF", "WDRN" and 1 in rcsb_repository_holdings_transferred.status_code: "TRSF" - // for current: CURRENT (not available in current API) - OBSOLETE, + // the simplified status enum in rcsb_repository_holdings_combined + REMOVED, CURRENT, - AUTH, - HOLD, - HPUB, - POLC, - PROC, - REFI, - REPL, - WAIT, - WDRN, - MODEL, - UNKNOWN; + UNRELEASED; /** * @throws IllegalArgumentException If the string is not recognized @@ -128,32 +73,12 @@ public enum Status { public static Status fromString(String statusStr) { Status status; String statusStrUpper = statusStr.toUpperCase(); - if(statusStrUpper.equalsIgnoreCase("OBSOLETE")) - status = Status.OBSOLETE; + if(statusStrUpper.equalsIgnoreCase("REMOVED")) + status = Status.REMOVED; else if(statusStrUpper.equalsIgnoreCase("CURRENT")) status = Status.CURRENT; - else if(statusStrUpper.equalsIgnoreCase("AUTH")) - status = Status.AUTH; - else if(statusStrUpper.equalsIgnoreCase("HOLD")) - status = Status.HOLD; - else if(statusStrUpper.equalsIgnoreCase("HPUB")) - status = Status.HPUB; - else if(statusStrUpper.equalsIgnoreCase("POLC")) - status = Status.POLC; - else if(statusStrUpper.equalsIgnoreCase("PROC")) - status = Status.PROC; - else if(statusStrUpper.equalsIgnoreCase("REFI")) - status = Status.REFI; - else if(statusStrUpper.equalsIgnoreCase("REPL")) - status = Status.REPL; - else if(statusStrUpper.equalsIgnoreCase("WAIT")) - status = Status.WAIT; - else if(statusStrUpper.equalsIgnoreCase("WDRN")) - status = Status.WDRN; - else if(statusStrUpper.equalsIgnoreCase("MODEL")) - status = Status.MODEL; - else if(statusStrUpper.equalsIgnoreCase("UNKNOWN")) - status = Status.UNKNOWN; + else if(statusStrUpper.equalsIgnoreCase("UNRELEASED")) + status = Status.UNRELEASED; else { throw new IllegalArgumentException("Unable to parse status '"+statusStrUpper+"'."); } @@ -164,447 +89,81 @@ else if(statusStrUpper.equalsIgnoreCase("UNKNOWN")) /** * Get the status of the PDB in question. * - * @param pdbId + * @param pdbId the id * @return The status, or null if an error occurred. */ public static Status getStatus(String pdbId) throws IOException { - Status[] statuses = getStatus(new String[] {pdbId}); - if(statuses != null) { - assert(statuses.length == 1); - return statuses[0]; - } else { - return null; - } + URL url = new URL(String.format(STATUS_ENDPOINT, DEFAULT_RCSB_DATA_API_SERVER, pdbId.toUpperCase())); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode node = objectMapper.readValue(url.openStream(), JsonNode.class); + return parseStatusRecord(node); } /** * Get the status of the a collection of PDBs in question in a single query. * * @see #getStatus(String) - * @param pdbIds + * @param pdbIds the ids * @return The status array, or null if an error occurred. */ public static Status[] getStatus(String[] pdbIds) throws IOException { - Status[] statuses = new Status[pdbIds.length]; - - List> attrList = getStatusIdRecords(pdbIds); - //Expect a single record - if(attrList == null || attrList.size() != pdbIds.length) { - logger.error("Error getting Status for {} from the PDB website.", Arrays.toString(pdbIds)); - return null; - } + URL url = new URL(String.format(STATUS_LIST_ENDPOINT, DEFAULT_RCSB_DATA_API_SERVER, String.join(",", pdbIds))); - for(int pdbNum = 0;pdbNum attrs : attrList) { + List statuses = new ArrayList<>(); - //Check that the record matches pdbId - String id = attrs.get("structureId"); - if(id == null || !id.equalsIgnoreCase(pdbIds[pdbNum])) { - continue; - } - - //Check that the status is given - String statusStr = attrs.get("status"); - Status status = null; - if(statusStr == null ) { - logger.error("No status returned for {}", pdbIds[pdbNum]); - statuses[pdbNum] = null; - } else { - status = Status.fromString(statusStr); - } - - if(status == null) { - logger.error("Unknown status '{}'", statusStr); - statuses[pdbNum] = null; - } + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode node = objectMapper.readValue(url.openStream(), JsonNode.class); - statuses[pdbNum] = status; - foundAttr = true; - } - if(!foundAttr) { - logger.error("No result found for {}", pdbIds[pdbNum]); - statuses[pdbNum] = null; + if (node !=null && node.isArray()) { + for (JsonNode record : node) { + Status status = parseStatusRecord(record); + statuses.add(status); } } - return statuses; - } - - /** - * Gets the current version of a PDB ID. This is equivalent to selecting - * the first element from - * {@link #getReplacement(String,boolean,boolean) - * - * @param oldPdbId - * @return The replacement for oldPdbId, or null if none are found or if an error occurred. - */ - public static String getCurrent(String oldPdbId) throws IOException { - List replacements = getReplacement(oldPdbId,true, false); - if(replacements != null && !replacements.isEmpty()) - return replacements.get(0); - else - return null; - } - - /** - * Gets the PDB which superseded oldPdbId. For CURRENT IDs, this will - * be itself. For obsolete IDs, the behavior depends on the recursion - * parameter. If false, only IDs which directly supersede oldPdbId are - * returned. If true, the replacements for obsolete records are recursively - * fetched, yielding a list of all current replacements of oldPdbId. - * - * - * - * @param oldPdbId A pdb ID - * @param recurse Indicates whether the replacements for obsolete records - * should be fetched. - * @param includeObsolete Indicates whether obsolete records should be - * included in the results. - * @return The PDB which replaced oldPdbId. This may be oldPdbId itself, for - * current records. A return value of null indicates that the ID has - * been removed from the PDB or that an error has occurred. - */ - public static List getReplacement(String oldPdbId, boolean recurse, boolean includeObsolete) throws IOException { - List> attrList = getStatusIdRecords(new String[] {oldPdbId}); - //Expect a single record - if(attrList == null || attrList.size() != 1) { - logger.error("Error getting Status for {} from the PDB website.", oldPdbId); - return null; - } - - Map attrs = attrList.get(0); - - //Check that the record matches pdbId - String id = attrs.get("structureId"); - if(id == null || !id.equalsIgnoreCase(oldPdbId)) { - logger.error("Results returned from the query don't match {}", oldPdbId); - return null; - } - - //Check that the status is given - String statusStr = attrs.get("status"); - if(statusStr == null ) { - logger.error("No status returned for {}", oldPdbId); - return null; - } - - Status status = Status.fromString(statusStr); - if(status == null ) { - logger.error("Unknown status '{}'", statusStr); - return null; + if (statuses.size() != pdbIds.length) { + logger.warn("RCSB status request was for {} ids, but {} were returned", pdbIds.length, statuses.size()); } - // If we're current, just return - LinkedList results = new LinkedList<>(); - switch(status) { - case CURRENT: - results.add(oldPdbId); - return results; - case OBSOLETE: { - String replacementStr = attrs.get("replacedBy"); - if(replacementStr == null) { - logger.error("{} is OBSOLETE but lacks a replacedBy attribute.", oldPdbId); - return null; - } - replacementStr = replacementStr.toUpperCase(); - //include this result - if(includeObsolete) { - results.add(oldPdbId); - } - // Some PDBs are not replaced. - if(replacementStr.equals("NONE")) { - return results; //empty - } - - String[] replacements = replacementStr.split(" "); - Arrays.sort(replacements, new Comparator() { - @Override - public int compare(String o1, String o2) { - return o2.compareToIgnoreCase(o1); - } - }); - for(String replacement : replacements) { - - // Return the replacement. - if(recurse) { - List others = PDBStatus.getReplacement(replacement, recurse, includeObsolete); - mergeReversed(results,others); - } - else { - if(includeObsolete) { - mergeReversed(results,Arrays.asList(replacement)); - } else { - // check status of replacement - Status replacementStatus = getStatus(replacement); - switch(replacementStatus) { - case OBSOLETE: - //ignore obsolete - break; - case CURRENT: - default: - // include it - mergeReversed(results,Arrays.asList(replacement)); - } - } - } - } - - - return results; - } - case UNKNOWN: - return null; - default: { //TODO handle other cases explicitly. They might have other syntax than "replacedBy" - String replacementStr = attrs.get("replacedBy"); - - if(replacementStr == null) { - // If no "replacedBy" attribute, treat like we're current - // TODO is this correct? - results.add(oldPdbId); - return results; - } - - replacementStr = replacementStr.toUpperCase(); - // Some PDBs are not replaced. - if(replacementStr.equals("NONE")) { - return null; - } - - - //include this result, since it's not obsolete - results.add(oldPdbId); - - String[] replacements = replacementStr.split(" "); - Arrays.sort(replacements, new Comparator() { - @Override - public int compare(String o1, String o2) { - return o2.compareToIgnoreCase(o1); - } - }); - for(String replacement : replacements) { - - // Return the replacement. - if(recurse) { - List others = PDBStatus.getReplacement(replacement, recurse, includeObsolete); - mergeReversed(results,others); - } - else { - mergeReversed(results,Arrays.asList(replacement)); - } - } - - - return results; - } - } + return statuses.toArray(new Status[0]); } - /** - * Takes two reverse sorted lists of strings and merges the second into the - * first. Duplicates are removed. - * - * @param merged A reverse sorted list. Modified by this method to contain - * the contents of other. - * @param other A reverse sorted list. Not modified. - */ - private static void mergeReversed(List merged, - final List other) { - - if(other.isEmpty()) - return; - - if(merged.isEmpty()) { - merged.addAll(other); - return; - } - - ListIterator m = merged.listIterator(); - ListIterator o = other.listIterator(); - - String nextM, prevO; - prevO = o.next(); - while(m.hasNext()) { - // peek at m - nextM = m.next(); - m.previous(); - - //insert from O until exhausted or occurs after nextM - while(prevO.compareTo(nextM) > 0) { - m.add(prevO); - if(!o.hasNext()) { - return; - } - prevO = o.next(); - } - //remove duplicates - if(prevO.equals(nextM)) { - if(!o.hasNext()) { - return; - } - prevO = o.next(); - } - - m.next(); - } - m.add(prevO); - while(o.hasNext()) { - m.add(o.next()); - } - + private static Status parseStatusRecord(JsonNode jsonNode) { + // "rcsb_repository_holdings_combined": { + //"id_code_replaced_by_latest": "4HHB", + //"status": "REMOVED", + //"status_code": "OBS" + //}, + JsonNode rcsbRepoHoldingsNode = jsonNode.get("rcsb_repository_holdings_combined"); + return Status.fromString(rcsbRepoHoldingsNode.get("status").asText()); } - /** - * Get the ID of the protein which was made obsolete by newPdbId. + * Gets the current version of a PDB ID. * - * @param newPdbId PDB ID of the newer structure - * @param recurse If true, return all ancestors of newPdbId. - * Otherwise, just go one step newer than oldPdbId. - * @return A (possibly empty) list of ID(s) of the ancestor(s) of - * newPdbId, or null if an error occurred. + * @param oldPdbId the id + * @return The replacement for oldPdbId, or null if none are found. + * If entry is current then the input PDB id is returned */ - public static List getReplaces(String newPdbId, boolean recurse) throws IOException { - List> attrList = getStatusIdRecords(new String[] {newPdbId}); - //Expect a single record - if(attrList == null || attrList.size() != 1) { - //TODO Is it possible to have multiple record per ID? - // They seem to be combined into one record with space-delimited 'replaces' - logger.error("Error getting Status for {} from the PDB website.", newPdbId); - return null; - } - - Map attrs = attrList.get(0); - - //Check that the record matches pdbId - String id = attrs.get("structureId"); - if(id == null || !id.equals(newPdbId)) { - logger.error("Results returned from the query don't match {}", newPdbId); - return null; - } - - - String replacedList = attrs.get("replaces"); //space-delimited list - if(replacedList == null) { - // no replaces value; assume root - return new ArrayList(); - } - String[] directDescendents = replacedList.split("\\s"); - - // Not the root! Return the replaced PDB. - if(recurse) { - // Note: Assumes a proper directed acyclic graph of revisions - // Cycles will cause infinite loops. - List allDescendents = new LinkedList(); - for(String replaced : directDescendents) { - List roots = PDBStatus.getReplaces(replaced, recurse); - mergeReversed(allDescendents,roots); - } - mergeReversed(allDescendents,Arrays.asList(directDescendents)); - - return allDescendents; + public static String getCurrent(String oldPdbId) throws IOException { + URL url = new URL(String.format(STATUS_ENDPOINT, DEFAULT_RCSB_DATA_API_SERVER, oldPdbId.toUpperCase())); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode node = objectMapper.readValue(url.openStream(), JsonNode.class); + JsonNode rcsbRepoHoldingsNode = node.get("rcsb_repository_holdings_combined"); + Status st = Status.fromString(rcsbRepoHoldingsNode.get("status").asText()); + if (st == Status.REMOVED) { + JsonNode replacedByNode = rcsbRepoHoldingsNode.get("id_code_replaced_by_latest"); + if (replacedByNode != null) + return replacedByNode.asText(); + else + return null; + } else if (st == Status.CURRENT) { + return oldPdbId; } else { - return Arrays.asList(directDescendents); - } - } - - - /** - * The status of PDB IDs are cached to reduce server overload. - * - * This method clears the cached records. - */ - public static void clearCache() { - recordsCache.clear(); - } - - /** - * Fetches the status of one or more pdbIDs from the server. - * - *

      - * Returns the results as a list of Attributes. - * Each attribute should contain "structureId" and "status" attributes, and - * possibly more. - * - *

      - * Example: - *

      - * http://www.rcsb.org/pdb/rest/idStatus?structureID=1HHB,4HHB
      - *

      -	 * <idStatus>
      -	 *   <record structureId="1HHB" status="OBSOLETE" replacedBy="4HHB"/>
      -	 *   <record structureId="4HHB" status="CURRENT" replaces="1HHB"/>
      -	 * </idStatus>
      -	 * 
      - * - *

      - * Results are not guaranteed to be returned in the same order as pdbIDs. - * Refer to the structureId property to match them. - * - * @param pdbIDs the PDB identifiers - * @return A map between attributes and values - */ - private static List> getStatusIdRecords(String[] pdbIDs) throws IOException { - - List> result = new ArrayList<>(pdbIDs.length); - - String serverName = DEFAULT_RCSB_DATA_API_SERVER; - - // Build REST query URL - if(pdbIDs.length < 1) { - throw new IllegalArgumentException("No pdbIDs specified"); - } - String urlStr = String.format("http://%s/pdb/rest/idStatus?structureId=",serverName); - for(String pdbId : pdbIDs) { - pdbId = pdbId.toUpperCase(); - //check the cache - if (recordsCache.containsKey(pdbId)) { - //logger.debug("Fetching "+pdbId+" from Cache"); - result.add( recordsCache.get(pdbId) ); - } else { - urlStr += pdbId + ","; - } - } - - // check if any ids still need fetching - if(urlStr.charAt(urlStr.length()-1) == '=') { - return result; - } - - logger.info("Fetching {}", urlStr); - - URL url = new URL(urlStr); - - InputStream uStream = url.openStream(); - - InputSource source = new InputSource(uStream); - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - SAXParser parser = parserFactory.newSAXParser(); - XMLReader reader = parser.getXMLReader(); - - PDBStatusXMLHandler handler = new PDBStatusXMLHandler(); - - reader.setContentHandler(handler); - reader.parse(source); - - // Fetch results of SAX parsing - List> records = handler.getRecords(); - - //add to cache - for (Map record : records) { - String pdbId = record.get("structureId").toUpperCase(); - if (pdbId != null) { - recordsCache.put(pdbId, record); - } + return null; } - // return results - result.addAll(handler.getRecords()); - - return result; } /** @@ -615,11 +174,8 @@ private static List> getStatusIdRecords(String[] pdbIDs) thr */ public static SortedSet getCurrentPDBIds() throws IOException { - //String serverName = System.getProperty(PDB_SERVER_PROPERTY); - String serverName = DEFAULT_RCSB_DATA_API_SERVER; - // Build REST query URL - String urlStr = String.format(ALL_CURRENT_ENDPOINT, serverName); + String urlStr = String.format(ALL_CURRENT_ENDPOINT, DEFAULT_RCSB_DATA_API_SERVER); URL u = new URL(urlStr); InputStream stream = URLConnectionTools.getInputStream(u, 60000); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java index 61735ecfa6..4dd31b25f6 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java @@ -492,7 +492,7 @@ protected File downloadStructure(String pdbId) throws IOException{ } return downloadStructure(current, splitDirURL,false, existing); } else if(obsoleteBehavior == ObsoleteBehavior.FETCH_OBSOLETE - && PDBStatus.getStatus(pdbId) == Status.OBSOLETE) { + && PDBStatus.getStatus(pdbId) == Status.REMOVED) { return downloadStructure(pdbId, obsoleteDirURL, true, existing); } else { return downloadStructure(pdbId, splitDirURL, false, existing); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/PDBStatusTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/PDBStatusTest.java index 8bcd2d1e98..bda33d98ab 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/PDBStatusTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/PDBStatusTest.java @@ -18,17 +18,14 @@ * http://www.biojava.org/ * */ -/** - * - */ package org.biojava.nbio.structure; import org.biojava.nbio.structure.PDBStatus.Status; import org.junit.Assert; import org.junit.Test; -import java.lang.reflect.Method; -import java.util.*; +import java.io.IOException; + /** * @author Spencer Bliven @@ -46,172 +43,20 @@ public class PDBStatusTest { *

      */ @Test - public void testGetStatus() { - Assert.assertEquals(Status.OBSOLETE, PDBStatus.getStatus("1HHB")); + public void testGetStatus() throws IOException { + Assert.assertEquals(Status.REMOVED, PDBStatus.getStatus("1HHB")); Assert.assertEquals(Status.CURRENT, PDBStatus.getStatus("3HHB")); Assert.assertEquals(Status.CURRENT, PDBStatus.getStatus("4HHB")); } @Test - public void testGetReplacement() { - Assert.assertFalse(Arrays.asList("YES").equals(Arrays.asList("NO"))); //check for deep equals - - // 1CMW is replacedBy NONE - Assert.assertEquals(Arrays.asList(), PDBStatus.getReplacement("1CMW", true, false)); - Assert.assertEquals(Arrays.asList("1CMW"), PDBStatus.getReplacement("1CMW", true, true)); - - // 1HHB is replacedBy 2-4HHB - Assert.assertEquals(Arrays.asList("3HHB"), PDBStatus.getReplacement("3HHB", false, false)); - Assert.assertEquals(Arrays.asList("3HHB"), PDBStatus.getReplacement("3HHB", false, true)); - Assert.assertEquals(Arrays.asList("4HHB", "3HHB", "2HHB"), PDBStatus.getReplacement("1HHB", false, false)); - Assert.assertEquals(Arrays.asList("4HHB", "3HHB", "2HHB", "1HHB"), PDBStatus.getReplacement("1HHB", false, true)); - - // 1CAT is replacedBy 3CAT is replacedBy 7-8CAT - Assert.assertEquals(Arrays.asList("8CAT", "7CAT", "3CAT", "1CAT"), PDBStatus.getReplacement("1CAT", true, true)); - Assert.assertEquals(Arrays.asList("8CAT", "7CAT"), PDBStatus.getReplacement("1CAT", true, false)); - Assert.assertEquals(Arrays.asList("8CAT", "7CAT", "3CAT"), PDBStatus.getReplacement("3CAT", true, true)); - Assert.assertEquals(Arrays.asList("8CAT", "7CAT"), PDBStatus.getReplacement("3CAT", true, false)); - } - - - @Test - public void testGetCurrent() { + public void testGetCurrent() throws IOException { Assert.assertEquals("4HHB", PDBStatus.getCurrent("1HHB")); Assert.assertEquals("3HHB", PDBStatus.getCurrent("3HHB")); - Assert.assertEquals(null, PDBStatus.getCurrent("1CMW")); + Assert.assertNull(PDBStatus.getCurrent("1CMW")); Assert.assertEquals("3ENI", PDBStatus.getCurrent("1KSA")); Assert.assertEquals("8CAT", PDBStatus.getCurrent("1CAT")); Assert.assertEquals("8CAT", PDBStatus.getCurrent("3CAT")); Assert.assertEquals("7CAT", PDBStatus.getCurrent("7CAT")); } - - @Test - public void testGetReplaces() { - Assert.assertEquals(new ArrayList(), Arrays.asList(new String[]{})); - - Assert.assertEquals(Arrays.asList("1HHB"), PDBStatus.getReplaces("4HHB", false)); - Assert.assertEquals(Arrays.asList("1HHB"), PDBStatus.getReplaces("3HHB", false)); - Assert.assertEquals(Arrays.asList(), PDBStatus.getReplaces("1HHB", false)); - Assert.assertEquals(Arrays.asList("1M50", "1KSA"), PDBStatus.getReplaces("3ENI", false)); - Assert.assertEquals(Arrays.asList("1M50", "1KSA"), PDBStatus.getReplaces("3ENI", true)); - Assert.assertEquals(Arrays.asList("3CAT"), PDBStatus.getReplaces("8CAT", false)); - Assert.assertEquals(Arrays.asList("3CAT", "1CAT"), PDBStatus.getReplaces("8CAT", true)); - - } - - /** - * Tests a helper method for merging that was giving me problems - */ - @Test - public void testMergeReversed() { - try { - Method mergeReversed = PDBStatus.class.getDeclaredMethod("mergeReversed", - List.class,List.class); - mergeReversed.setAccessible(true); - - - List a,b; - - b = Arrays.asList("F","A"); - a = new LinkedList(); - mergeReversed.invoke(null, a,b); - Assert.assertEquals(Arrays.asList("F", "A"), a); - - a = new LinkedList(); - a.add("B"); - mergeReversed.invoke(null, a,b); - Assert.assertEquals(Arrays.asList("F", "B", "A"), a); - - a = new LinkedList(); - a.add("G"); - mergeReversed.invoke(null, a,b); - Assert.assertEquals(Arrays.asList("G", "F", "A"), a); - - a = new LinkedList(); - a.add("1"); - mergeReversed.invoke(null, a,b); - Assert.assertEquals(Arrays.asList("F", "A", "1"), a); - - a = new LinkedList(); - a.add("G"); - a.add("1"); - mergeReversed.invoke(null, a,b); - Assert.assertEquals(Arrays.asList("G", "F", "A", "1"), a); - - b = Arrays.asList(); - mergeReversed.invoke(null, a,b); - Assert.assertEquals(Arrays.asList("G", "F", "A", "1"), a); - - b = Arrays.asList("G","D","C","A"); - a = new LinkedList(); - a.add("F"); - a.add("B"); - a.add("1"); - mergeReversed.invoke(null, a,b); - Assert.assertEquals(Arrays.asList("G", "F", "D", "C", "B", "A", "1"), a); - - } catch(Exception e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - } - - /** - * Test low-level connectivity to the PDB - */ - @Test - @SuppressWarnings("unchecked") - public void testGetStatusIdRecords() { - try { - Method getStatusIdRecords = PDBStatus.class.getDeclaredMethod("getStatusIdRecords", - String[].class); - getStatusIdRecords.setAccessible(true); - - - List> attrsList; - String[] pdbIds; - Map attrs; - - // Test invocation with a single ID - pdbIds = new String[] {"1HHB"}; - attrsList = (List>) getStatusIdRecords.invoke(null, (Object) pdbIds); - Assert.assertEquals("Wrong number of records.", 1, attrsList.size()); - attrs = attrsList.get(0); - Assert.assertEquals("Wrong number of attributes", 3, attrs.size()); - Assert.assertEquals("Wrong structureId", "1HHB", attrs.get("structureId")); - Assert.assertEquals("Wrong status", "OBSOLETE", attrs.get("status")); - Assert.assertEquals("Wrong replacedBy", "4HHB 3HHB 2HHB", attrs.get("replacedBy")); - - // Test with multiple IDs - pdbIds = new String[] {"1HHB","4HHB"}; - attrsList = (List>) getStatusIdRecords.invoke(null, (Object) pdbIds); - Assert.assertEquals("Wrong number of records.", 2, attrsList.size()); - attrs = attrsList.get(1); - Assert.assertEquals("Wrong number of attributes", 3, attrs.size()); - Assert.assertEquals("Wrong structureId", "4HHB", attrs.get("structureId")); - Assert.assertEquals("Wrong status", "CURRENT", attrs.get("status")); - Assert.assertEquals("Wrong replaces", "1HHB", attrs.get("replaces")); - attrs = attrsList.get(0); - Assert.assertEquals("Wrong number of attributes", 3, attrs.size()); - Assert.assertEquals("Wrong structureId", "1HHB", attrs.get("structureId")); - Assert.assertEquals("Wrong status", "OBSOLETE", attrs.get("status")); - Assert.assertEquals("Wrong replacedBy", "4HHB 3HHB 2HHB", attrs.get("replacedBy")); - - // Test invocation with a single ID - pdbIds = new String[] {"3ENI"}; - attrsList = (List>) getStatusIdRecords.invoke(null, (Object) pdbIds); - Assert.assertEquals("Wrong number of records.", 1, attrsList.size()); - attrs = attrsList.get(0); - Assert.assertEquals("Wrong number of attributes", 3, attrs.size()); - Assert.assertEquals("Wrong structureId", "3ENI", attrs.get("structureId")); - Assert.assertEquals("Wrong status", "CURRENT", attrs.get("status")); - Assert.assertEquals("Wrong replacedBy", "1M50 1KSA", attrs.get("replaces")); - - - } catch(Exception e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - } - } From ef35e93ecfab2f654f14d58299aa75f113e939bf Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 22 Nov 2020 15:54:01 -0800 Subject: [PATCH 178/769] Docs --- CHANGELOG.md | 2 ++ .../java/org/biojava/nbio/structure/PDBStatus.java | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00a530e652..22f265c548 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ BioJava 6.0.0 (future release) * The whole `org.biojava.nbio.structure.validation` package * The `org.biojava.nbio.structure.domain.PDBDomainProvider` class to pull domain definitions from legacy RCSB PDB APIs * Support for automatically fetching dssp files from RCSB (`org.biojava.nbio.structure.secstruc.DSSPParser.fetch()`) +* `org.biojava.nbio.structure.PDBStatus`: simplified `Status` enum to 3 states, with OBSOLETE now called REMOVED +* `org.biojava.nbio.structure.PDBStatus`: removed `getReplacement` and `getReplaces` BioJava 5.4.0 ============= diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java index 7abd790fb4..0ded68c05c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java @@ -59,7 +59,6 @@ public class PDBStatus { /** * Represents a simplified 3 state status of PDB IDs. * @author Spencer Bliven - * */ public enum Status { // the simplified status enum in rcsb_repository_holdings_combined @@ -87,10 +86,10 @@ else if(statusStrUpper.equalsIgnoreCase("UNRELEASED")) } /** - * Get the status of the PDB in question. + * Get the status of a PDB id. * * @param pdbId the id - * @return The status, or null if an error occurred. + * @return The status. */ public static Status getStatus(String pdbId) throws IOException { URL url = new URL(String.format(STATUS_ENDPOINT, DEFAULT_RCSB_DATA_API_SERVER, pdbId.toUpperCase())); @@ -100,11 +99,11 @@ public static Status getStatus(String pdbId) throws IOException { } /** - * Get the status of the a collection of PDBs in question in a single query. + * Get the status of a collection of PDB ids (in a single API query). * * @see #getStatus(String) * @param pdbIds the ids - * @return The status array, or null if an error occurred. + * @return The status array */ public static Status[] getStatus(String[] pdbIds) throws IOException { @@ -130,6 +129,7 @@ public static Status[] getStatus(String[] pdbIds) throws IOException { } private static Status parseStatusRecord(JsonNode jsonNode) { + // e.g. // "rcsb_repository_holdings_combined": { //"id_code_replaced_by_latest": "4HHB", //"status": "REMOVED", From 95db39cc4f17fdce3373e5145e52504f14d8643e Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 22 Nov 2020 16:30:08 -0800 Subject: [PATCH 179/769] One more test --- .../java/org/biojava/nbio/structure/PDBStatusTest.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/PDBStatusTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/PDBStatusTest.java index bda33d98ab..82e26bd802 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/PDBStatusTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/PDBStatusTest.java @@ -26,7 +26,6 @@ import java.io.IOException; - /** * @author Spencer Bliven * @@ -49,6 +48,15 @@ public void testGetStatus() throws IOException { Assert.assertEquals(Status.CURRENT, PDBStatus.getStatus("4HHB")); } + @Test + public void testGetStatusMultipleIds() throws IOException { + String[] ids = {"1HHB", "3HHB", "4HHB"}; + Status[] statuses = PDBStatus.getStatus(ids); + Assert.assertEquals(Status.REMOVED, statuses[0]); + Assert.assertEquals(Status.CURRENT, statuses[1]); + Assert.assertEquals(Status.CURRENT, statuses[2]); + } + @Test public void testGetCurrent() throws IOException { Assert.assertEquals("4HHB", PDBStatus.getCurrent("1HHB")); From 245742d522d12440ece32f5c2d665ff81c465e98 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Tue, 24 Nov 2020 14:11:19 -0800 Subject: [PATCH 180/769] Fixing test --- .../test/symmetry/TestQuatSymmetryDetectorExamples.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java index b5a8a5a2e1..aab2ec5c89 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java @@ -240,7 +240,7 @@ public void testLocal() throws IOException, StructureException { testIds.add("BIO:3JC9:1"); testStoichiometries.add("A12B12C12D12E12F12G5H2"); localSymmetries = new HashMap<>(); - localSymmetries.put("A12C12D12E12F12H2","C2"); + localSymmetries.put("A12B12C12D12E12H2","C2"); localSymmetries.put("A12B12C12D12E12F12","C12"); localSymmetries.put("G5","H"); testLocalSymmetries.add(localSymmetries); @@ -268,7 +268,7 @@ public void testLocal() throws IOException, StructureException { for (QuatSymmetryResults local:foundLocal) { logger.info("Found stoichiometry "+local.getStoichiometry().toString()+" with symmetry "+local.getSymmetry()); assertTrue("Stoichiometry "+local.getStoichiometry().toString()+" not expected for "+testIds.get(iTest), - refLocal.keySet().contains(local.getStoichiometry().toString())); + refLocal.containsKey(local.getStoichiometry().toString())); assertEquals("Symmetry "+local.getSymmetry()+" with stoichiometry "+local.getStoichiometry().toString()+ " not expected for "+testIds.get(iTest), From 203f5e38252958bf8ac145861d412d88a888f359 Mon Sep 17 00:00:00 2001 From: Bhat Date: Wed, 25 Nov 2020 13:30:52 -0600 Subject: [PATCH 181/769] Flaky Test Fixed in TestStructureSerialization --- .../src/main/java/org/biojava/nbio/structure/PDBHeader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java index dbcc0f794c..eb7245dffa 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java @@ -108,6 +108,7 @@ public String toString(){ Class c = Class.forName(PDBHeader.class.getName()); Method[] methods = c.getMethods(); + Arrays.sort(methods, (o1, o2)->o1.getName().compareTo(o2.getName())); for (Method m : methods) { String name = m.getName(); From 846c13f1f0e6257bd24ea1b6ae12380f74b60eb9 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Wed, 25 Nov 2020 11:51:37 -0800 Subject: [PATCH 182/769] Corrections suggested in review --- .../org/biojava/nbio/structure/PDBStatus.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java index 0ded68c05c..29203825a6 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java @@ -33,7 +33,7 @@ import java.util.*; /** - * Methods for getting the status of a PDB file (current, obsolete, unreleased) + * Methods for getting the status of a PDB file (current, removed, unreleased) * and for accessing different versions of the structure. * *

      @@ -70,18 +70,16 @@ public enum Status { * @throws IllegalArgumentException If the string is not recognized */ public static Status fromString(String statusStr) { - Status status; - String statusStrUpper = statusStr.toUpperCase(); - if(statusStrUpper.equalsIgnoreCase("REMOVED")) - status = Status.REMOVED; - else if(statusStrUpper.equalsIgnoreCase("CURRENT")) - status = Status.CURRENT; - else if(statusStrUpper.equalsIgnoreCase("UNRELEASED")) - status = Status.UNRELEASED; + if (statusStr == null) return null; + if(statusStr.equalsIgnoreCase("REMOVED")) + return Status.REMOVED; + else if(statusStr.equalsIgnoreCase("CURRENT")) + return Status.CURRENT; + else if(statusStr.equalsIgnoreCase("UNRELEASED")) + return Status.UNRELEASED; else { - throw new IllegalArgumentException("Unable to parse status '"+statusStrUpper+"'."); + throw new IllegalArgumentException("Unable to parse status '"+statusStr+"'."); } - return status; } } From f04effa094b239fbba573a110aeb02a75624cfa3 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Wed, 25 Nov 2020 11:55:12 -0800 Subject: [PATCH 183/769] Better handlng of null --- .../src/main/java/org/biojava/nbio/structure/PDBStatus.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java index 29203825a6..dd69115c91 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java @@ -70,7 +70,7 @@ public enum Status { * @throws IllegalArgumentException If the string is not recognized */ public static Status fromString(String statusStr) { - if (statusStr == null) return null; + if (statusStr == null) throw new IllegalArgumentException("Status string can't be null"); if(statusStr.equalsIgnoreCase("REMOVED")) return Status.REMOVED; else if(statusStr.equalsIgnoreCase("CURRENT")) From 13565b17d4d6729d4c3e86d7f42b53871133ce98 Mon Sep 17 00:00:00 2001 From: Spencer Bliven Date: Mon, 7 Dec 2020 17:32:47 +0100 Subject: [PATCH 184/769] Revert "Flaky Test Fixed in TestStructureSerialization" --- .../src/main/java/org/biojava/nbio/structure/PDBHeader.java | 1 - 1 file changed, 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java index eb7245dffa..dbcc0f794c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java @@ -108,7 +108,6 @@ public String toString(){ Class c = Class.forName(PDBHeader.class.getName()); Method[] methods = c.getMethods(); - Arrays.sort(methods, (o1, o2)->o1.getName().compareTo(o2.getName())); for (Method m : methods) { String name = m.getName(); From c290ea9af37a8e2c381437c488d426626259a3cd Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Wed, 13 Jan 2021 11:50:05 -0800 Subject: [PATCH 185/769] wip (most of structure parsing done) --- .../structure/gui/util/PDBUploadPanel.java | 1 - .../java/demo/DemoChangeChemCompProvider.java | 64 +- .../src/main/java/demo/DemoMMCIFReader.java | 1 - .../java/demo/DemoMmcifToPdbConverter.java | 47 +- .../nbio/structure/AtomPositionMap.java | 5 +- .../org/biojava/nbio/structure/Chain.java | 1 - .../org/biojava/nbio/structure/ChainImpl.java | 7 +- .../nbio/structure/DatabasePDBRevRecord.java | 62 + .../nbio/structure/DatabasePdbRevRecord.java | 43 - .../org/biojava/nbio/structure/Group.java | 99 +- .../org/biojava/nbio/structure/GroupType.java | 4 +- .../biojava/nbio/structure/HetatomImpl.java | 22 +- .../org/biojava/nbio/structure/PDBHeader.java | 6 +- .../biojava/nbio/structure/StructureIO.java | 7 +- .../biojava/nbio/structure/URLIdentifier.java | 42 +- .../nbio/structure/align/util/AtomCache.java | 5 +- .../structure/chem/AllChemCompProvider.java | 185 ++ .../biojava/nbio/structure/chem/ChemComp.java | 405 +++ .../nbio/structure/chem/ChemCompAtom.java | 205 ++ .../nbio/structure/chem/ChemCompBond.java | 114 + .../structure/chem/ChemCompContainer.java | 13 + .../structure/chem/ChemCompDescriptor.java | 80 + .../structure/chem/ChemCompGroupFactory.java | 131 + .../nbio/structure/chem/ChemCompProvider.java | 15 + .../nbio/structure/chem/ChemCompTools.java | 209 ++ .../chem/ChemicalComponentDictionary.java | 104 + .../chem/DownloadChemCompProvider.java | 420 ++++ .../nbio/structure/chem/PolymerType.java | 161 ++ .../chem/ReducedChemCompProvider.java | 56 + .../nbio/structure/chem/ResidueType.java | 125 + .../structure/contact/StructureInterface.java | 7 +- .../biojava/nbio/structure/io/BondMaker.java | 69 +- .../nbio/structure/io/FileConvert.java | 64 +- .../nbio/structure/io/MMCIFFileReader.java | 143 -- ...Impl.java => AbstractCifFileSupplier.java} | 68 +- .../structure/io/cif/ChainSupplierImpl.java | 20 + .../structure/io/cif/ChemCompConsumer.java | 14 + .../io/cif/ChemCompConsumerImpl.java | 70 + .../nbio/structure/io/cif/CifBean.java | 12 + .../structure/io/cif/CifFileConsumer.java | 274 +-- .../structure/io/cif/CifFileConverter.java | 52 +- .../structure/io/cif/CifFileSupplier.java | 4 +- .../structure/io/cif/StructureConsumer.java | 320 +++ ...erImpl.java => StructureConsumerImpl.java} | 152 +- .../io/cif/StructureSupplierImpl.java | 28 + .../io/mmcif/AllChemCompProvider.java | 246 -- .../structure/io/mmcif/ChemCompConsumer.java | 327 --- .../io/mmcif/ChemCompGroupFactory.java | 168 -- .../structure/io/mmcif/ChemCompProvider.java | 39 - .../io/mmcif/ChemicalComponentDictionary.java | 143 -- .../io/mmcif/DownloadChemCompProvider.java | 507 ---- .../structure/io/mmcif/MMCIFFileTools.java | 575 ----- .../structure/io/mmcif/MMcifConsumer.java | 116 - .../nbio/structure/io/mmcif/MMcifParser.java | 66 - .../structure/io/mmcif/MetalBondConsumer.java | 294 --- .../structure/io/mmcif/MetalBondParser.java | 86 - .../io/mmcif/ReducedChemCompProvider.java | 91 - .../io/mmcif/SimpleMMcifConsumer.java | 2167 ----------------- .../structure/io/mmcif/SimpleMMcifParser.java | 1281 ---------- .../io/mmcif/ZipChemCompProvider.java | 313 --- .../io/mmcif/chem/ChemCompTools.java | 261 -- .../io/mmcif/chem/MetalBondDistance.java | 76 - .../structure/io/mmcif/chem/PolymerType.java | 191 -- .../structure/io/mmcif/chem/ResidueType.java | 150 -- .../io/mmcif/model/AbstractBean.java | 103 - .../structure/io/mmcif/model/AtomSite.java | 218 -- .../structure/io/mmcif/model/AtomSites.java | 421 ---- .../structure/io/mmcif/model/AuditAuthor.java | 51 - .../structure/io/mmcif/model/CIFLabel.java | 38 - .../nbio/structure/io/mmcif/model/Cell.java | 143 -- .../structure/io/mmcif/model/ChemComp.java | 618 ----- .../io/mmcif/model/ChemCompAtom.java | 219 -- .../io/mmcif/model/ChemCompBond.java | 133 - .../io/mmcif/model/ChemCompDescriptor.java | 136 -- .../io/mmcif/model/DatabasePDBremark.java | 41 - .../io/mmcif/model/DatabasePDBrev.java | 83 - .../io/mmcif/model/DatabasePdbrevRecord.java | 69 - .../nbio/structure/io/mmcif/model/Entity.java | 123 - .../structure/io/mmcif/model/EntityPoly.java | 152 -- .../io/mmcif/model/EntityPolySeq.java | 72 - .../io/mmcif/model/EntitySrcGen.java | 427 ---- .../io/mmcif/model/EntitySrcNat.java | 224 -- .../io/mmcif/model/EntitySrcSyn.java | 75 - .../nbio/structure/io/mmcif/model/Exptl.java | 98 - .../structure/io/mmcif/model/IgnoreField.java | 37 - .../mmcif/model/PdbxAuditRevisionHistory.java | 66 - .../mmcif/model/PdbxChemCompDescriptor.java | 71 - .../mmcif/model/PdbxChemCompIdentifier.java | 73 - .../io/mmcif/model/PdbxDatabaseStatus.java | 101 - .../io/mmcif/model/PdbxEntityNonPoly.java | 51 - .../io/mmcif/model/PdbxNonPolyScheme.java | 107 - .../io/mmcif/model/PdbxPolySeqScheme.java | 117 - .../io/mmcif/model/PdbxStructAssembly.java | 85 - .../io/mmcif/model/PdbxStructAssemblyGen.java | 67 - .../PdbxStructAssemblyGenXMLContainer.java | 101 - .../model/PdbxStructAssemblyXMLContainer.java | 99 - .../io/mmcif/model/PdbxStructOperList.java | 222 -- .../model/PdbxStructOperListXMLContainer.java | 101 - .../nbio/structure/io/mmcif/model/Refine.java | 658 ----- .../nbio/structure/io/mmcif/model/Struct.java | 86 - .../structure/io/mmcif/model/StructAsym.java | 68 - .../structure/io/mmcif/model/StructConn.java | 466 ---- .../io/mmcif/model/StructKeywords.java | 46 - .../io/mmcif/model/StructNcsOper.java | 282 --- .../structure/io/mmcif/model/StructRef.java | 89 - .../io/mmcif/model/StructRefSeq.java | 146 -- .../io/mmcif/model/StructRefSeqDif.java | 147 -- .../structure/io/mmcif/model/StructSite.java | 114 - .../io/mmcif/model/StructSiteGen.java | 166 -- .../structure/io/mmcif/model/Symmetry.java | 71 - .../io/mmcif/model/package-info.java | 24 - .../nbio/structure/io/mmcif/package-info.java | 26 - .../quaternary/BiologicalAssemblyBuilder.java | 157 +- .../biojava/nbio/structure/TestAtomCache.java | 1 - .../structure/align/util/AtomCacheTest.java | 1 - 115 files changed, 3085 insertions(+), 15238 deletions(-) create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePdbRevRecord.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompBond.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompContainer.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompDescriptor.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompGroupFactory.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/PolymerType.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ResidueType.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/MMCIFFileReader.java rename biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/{CifFileSupplierImpl.java => AbstractCifFileSupplier.java} (84%) create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChainSupplierImpl.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifBean.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumer.java rename biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/{CifFileConsumerImpl.java => StructureConsumerImpl.java} (89%) create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureSupplierImpl.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/AllChemCompProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompConsumer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompGroupFactory.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemicalComponentDictionary.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/DownloadChemCompProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMCIFFileTools.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMcifConsumer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMcifParser.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MetalBondConsumer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MetalBondParser.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ReducedChemCompProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/SimpleMMcifConsumer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/SimpleMMcifParser.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ChemCompTools.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/MetalBondDistance.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/PolymerType.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ResidueType.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AbstractBean.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AtomSite.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AtomSites.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AuditAuthor.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/CIFLabel.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Cell.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemComp.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompAtom.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompBond.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompDescriptor.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePDBremark.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePDBrev.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePdbrevRecord.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Entity.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntityPoly.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntityPolySeq.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcGen.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcNat.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcSyn.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Exptl.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/IgnoreField.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxAuditRevisionHistory.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxChemCompDescriptor.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxChemCompIdentifier.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxDatabaseStatus.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxEntityNonPoly.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxNonPolyScheme.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxPolySeqScheme.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssembly.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyGen.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyGenXMLContainer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyXMLContainer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructOperList.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructOperListXMLContainer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Refine.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Struct.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructAsym.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructConn.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructKeywords.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructNcsOper.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRef.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRefSeq.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRefSeqDif.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructSite.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructSiteGen.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Symmetry.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/package-info.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/package-info.java diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/gui/util/PDBUploadPanel.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/gui/util/PDBUploadPanel.java index 2c542f0797..92efbeaf36 100644 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/gui/util/PDBUploadPanel.java +++ b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/gui/util/PDBUploadPanel.java @@ -26,7 +26,6 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.MMCIFFileReader; import org.biojava.nbio.structure.io.PDBFileReader; import org.biojava.nbio.structure.io.StructureIOFile; import org.slf4j.Logger; diff --git a/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java b/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java index 756c44302f..b8e4eb5430 100644 --- a/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java +++ b/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java @@ -23,35 +23,33 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.chem.AllChemCompProvider; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemCompProvider; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileReader; -import org.biojava.nbio.structure.io.mmcif.AllChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.ChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import java.util.List; - /** - * This demo shows how to use an alternative ChemCompProvider. The default mechanism in BioJava is to access chemical components - * by using the {@link DownloadChemCompProvider}. It fetches and locally caches chemical component definitions as they are encountered during file parsing. - * It can be enabled by using the {@link FileParsingParameters#setLoadChemCompInfo(boolean)} method. + * This demo shows how to use an alternative ChemCompProvider. The default mechanism in BioJava is to access chemical + * componentsby using the {@link DownloadChemCompProvider}. It fetches and locally caches chemical component + * definitions as they are encountered during file parsing. It can be enabled by using the + * {@link FileParsingParameters#setLoadChemCompInfo(boolean)} method. * - * The {@link AllChemCompProvider} downloads and unpacks all chemcomps. It is slower and requires more memory than the default {@link DownloadChemCompProvider}, - * but it avoids network access to the FTP site, if a new chemcomp is detected, that has not been downloaded yet. + * The {@link AllChemCompProvider} downloads and unpacks all chemcomps. It is slower and requires more memory than the + * default {@link DownloadChemCompProvider}, but it avoids network access to the FTP site, if a new chemcomp is + * detected, that has not been downloaded yet. * * Since all chemcomps will be kept in memory, the standard memory that is available to a JVM will not be sufficient * in order to run this demo. Please start with -Xmx200M * * @author Andreas Prlic - * */ public class DemoChangeChemCompProvider { - public static void main(String[] args){ String pdbId = "1O1G"; - boolean loadChemComp = true; ////// @@ -66,82 +64,60 @@ public static void main(String[] args){ // or via // by setting the PDB_PATH environmental variable or system property // when running the demo (e.g. -DPDB_DIR=/path/to/pdb) - - if ( loadChemComp) { - + if (loadChemComp) { // The AllChemCompProvider loads all chem comps at startup. // This is slow (13 sec on my laptop) and requires more // memory than the default DownloadChemCompProvider. // In contrast to it it keeps all definitions in memory. ChemCompProvider all = new AllChemCompProvider(); - ChemCompGroupFactory.setChemCompProvider(all); } DemoChangeChemCompProvider demo = new DemoChangeChemCompProvider(); // run the demo - demo.basicLoad(reader,loadChemComp, pdbId); - + demo.basicLoad(reader, pdbId); } - public void basicLoad(PDBFileReader reader, boolean loadChemComp, String pdbId){ - + public void basicLoad(PDBFileReader reader, String pdbId) { try { // configure the parameters of file parsing - FileParsingParameters params = new FileParsingParameters(); - // should the ATOM and SEQRES residues be aligned when creating the internal data model? // only do this if you need to work with SEQRES sequences. If all you need are ATOMs, then // set it to false to have quicker file loading. params.setAlignSeqRes(true); - // // should secondary structure get parsed from the file params.setParseSecStruc(false); - reader.setFileParsingParameters(params); - Structure struc = reader.getStructureById(pdbId); - printStructure(struc); - - } catch (Exception e){ e.printStackTrace(); } - } private void printStructure(Structure struc) { - System.out.println(struc); - - //Chain c = struc.getChainByPDB("C"); String pdbid = struc.getPDBCode(); for (int i = 0; i < struc.nrModels(); i++) { - // loop chain for (Chain ch : struc.getModel(i)) { - if (! ch.getName().equals("A") ) + if (!ch.getName().equals("A")) { continue; - System.out.println(pdbid + ">>>" + ch.getName() + ">>>" - + ch.getAtomSequence()); - System.out.println(pdbid + ">>>" + ch.getName() + ">>>" - + ch.getSeqResSequence()); + } + System.out.println(pdbid + ">>>" + ch.getName() + ">>>" + ch.getAtomSequence()); + System.out.println(pdbid + ">>>" + ch.getName() + ">>>" + ch.getSeqResSequence()); // Test the getAtomGroups() and getSeqResGroups() method - List group = ch.getSeqResGroups(); int seqPos = 0; for (Group gp : group) { - System.out.println(ch.getName() + ":"+seqPos + ":" + gp.getResidueNumber() + ":" - + gp.getPDBName() + " " + gp.getType()); + System.out.println(ch.getName() + ":" + seqPos + ":" + gp.getResidueNumber() + ":" + + gp.getPDBName() + " " + gp.getType()); seqPos++; } } } - - } } diff --git a/biojava-structure/src/main/java/demo/DemoMMCIFReader.java b/biojava-structure/src/main/java/demo/DemoMMCIFReader.java index 8ed28e9c58..d5ae3fea58 100644 --- a/biojava-structure/src/main/java/demo/DemoMMCIFReader.java +++ b/biojava-structure/src/main/java/demo/DemoMMCIFReader.java @@ -26,7 +26,6 @@ import org.biojava.nbio.structure.*; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.MMCIFFileReader; import org.biojava.nbio.structure.io.StructureProvider; import java.util.List; diff --git a/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java b/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java index 5a5c1a222f..bd84ae8f1e 100644 --- a/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java +++ b/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java @@ -23,9 +23,6 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.io.mmcif.MMcifParser; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; import java.io.BufferedReader; import java.io.File; @@ -38,42 +35,32 @@ * An example of how to convert mmCIF file to PDB file * * @author Jose Duarte - * */ -public class DemoMmcifToPdbConverter -{ - +public class DemoMmcifToPdbConverter { public static void main(String[] args) throws Exception { - File inFile = new File(args[0]); File outFile = new File(args[1]); convert(inFile, outFile); } - - public static void convert(File inFile, File outFile) throws IOException { - - MMcifParser parser = new SimpleMMcifParser(); - - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - parser.addMMcifConsumer(consumer); - parser.parse(new BufferedReader(new InputStreamReader(new FileInputStream(inFile)))); - - // now get the protein structure. - Structure cifStructure = consumer.getStructure(); - - // and write it out as PDB format - PrintWriter pr = new PrintWriter(outFile); - for (Chain c : cifStructure.getChains()) { - // we can override the chain name, the mmCIF chain names might have more than 1 character - c.setName(c.getName().substring(0, 1)); - pr.print(c.toPDB()); - pr.println("TER"); - } + MMcifParser parser = new SimpleMMcifParser(); + SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); + parser.addMMcifConsumer(consumer); + parser.parse(new BufferedReader(new InputStreamReader(new FileInputStream(inFile)))); + + // now get the protein structure. + Structure cifStructure = consumer.getStructure(); + + // and write it out as PDB format + PrintWriter pr = new PrintWriter(outFile); + for (Chain c : cifStructure.getChains()) { + // we can override the chain name, the mmCIF chain names might have more than 1 character + c.setName(c.getName().substring(0, 1)); + pr.print(c.toPDB()); + pr.println("TER"); + } pr.close(); - - } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomPositionMap.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomPositionMap.java index b6c806417e..d6d6f778ff 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomPositionMap.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomPositionMap.java @@ -32,9 +32,8 @@ import java.util.NavigableMap; import java.util.TreeMap; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; +import org.biojava.nbio.structure.chem.PolymerType; +import org.biojava.nbio.structure.chem.ResidueType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/Chain.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/Chain.java index 150d806995..c8413228ee 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/Chain.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/Chain.java @@ -25,7 +25,6 @@ import org.biojava.nbio.core.sequence.template.Sequence; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; import java.io.Serializable; import java.util.List; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java index 9400333aba..7275fb07a9 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java @@ -24,10 +24,9 @@ package org.biojava.nbio.structure; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.io.FileConvert; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; import org.biojava.nbio.core.exceptions.CompoundNotFoundException; import org.biojava.nbio.core.sequence.ProteinSequence; import org.biojava.nbio.core.sequence.compound.AminoAcidCompound; @@ -686,7 +685,7 @@ public String toPDB() { @Override public String toMMCIF() { - return FileConvert.toMMCIF(this, true); + return FileConvert.toMMCIF(this); } @Override diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java new file mode 100644 index 0000000000..e14ef16776 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java @@ -0,0 +1,62 @@ +package org.biojava.nbio.structure; + +import org.biojava.nbio.structure.io.cif.CifBean; + +import java.util.ArrayList; +import java.util.List; + +public class DatabasePDBRevRecord implements CifBean { + private static final long serialVersionUID = 1L; + private String revNum; + private String type; + private String details; + + public DatabasePDBRevRecord() { + + } + + public DatabasePDBRevRecord(String revNum, String type, String details) { + this.revNum = revNum; + this.type = type; + this.details = details; + } + + public DatabasePDBRevRecord(org.rcsb.cif.schema.mm.DatabasePDBRevRecord cif, int row) { + this(cif.getDetails().get(row), + cif.getRevNum().getStringData(row), + cif.getType().get(row)); + } + + public String getRevNum() { + return revNum; + } + + public void setRevNum(String revNum) { + this.revNum = revNum; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + @Override + public String toString() { + return "DatabasePDBRevRecord{" + + "revNum='" + revNum + '\'' + + ", type='" + type + '\'' + + ", details='" + details + '\'' + + '}'; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePdbRevRecord.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePdbRevRecord.java deleted file mode 100644 index 91ec85549f..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePdbRevRecord.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.biojava.nbio.structure; - -import java.io.Serializable; - -public class DatabasePdbRevRecord implements Serializable { - private static final long serialVersionUID = -791924804009516791L; - private String rev_num; - private String type; - private String details; - - public String getRev_num() { - return rev_num; - } - - public void setRev_num(String rev_num) { - this.rev_num = rev_num; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getDetails() { - return details; - } - - public void setDetails(String details) { - this.details = details; - } - - @Override - public String toString() { - return "DatabasePdbrevRecord{" + - "rev_num='" + rev_num + '\'' + - ", type='" + type + '\'' + - ", details='" + details + '\'' + - '}'; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java index f2bc5a506a..36b8d3b1cd 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java @@ -23,7 +23,7 @@ */ package org.biojava.nbio.structure; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; +import org.biojava.nbio.structure.chem.ChemComp; import java.io.Serializable; import java.util.Iterator; @@ -53,29 +53,28 @@ * */ public interface Group extends Serializable { - /** Group property key for secondary structure annotation */ - public static final String SEC_STRUC = "secstruc"; + String SEC_STRUC = "secstruc"; /** * Get number of atoms. * @return number of atoms of this Group */ - public int size(); + int size(); /** * Return true or false, depending if this group has 3D coordinates or not. * * @return true if Group has 3D coordinates */ - public boolean has3D (); + boolean has3D(); /** * Flag if group has 3D data . * * @param flag true to set flag that this Group has 3D coordinates */ - public void setPDBFlag(boolean flag); + void setPDBFlag(boolean flag); /** * Get Type of group, one of {@link GroupType#AMINOACID}, {@link GroupType#HETATM} @@ -83,14 +82,14 @@ public interface Group extends Serializable { * * @return a String representing the type value */ - public GroupType getType(); + GroupType getType(); /** * Add an atom to this group. * * @param atom an Atom object */ - public void addAtom(Atom atom); + void addAtom(Atom atom); /** * Get list of atoms. @@ -98,21 +97,20 @@ public interface Group extends Serializable { * @return a List object representing the atoms * @see #setAtoms(List) */ - public List getAtoms() ; - + List getAtoms(); /** * Set the atoms of this group. * @see Atom * @param atoms a list of atoms */ - public void setAtoms(List atoms); + void setAtoms(List atoms); /** * Remove all atoms from this group. * */ - public void clearAtoms(); + void clearAtoms(); /** * Get an atom given its PDB name. @@ -125,15 +123,15 @@ public interface Group extends Serializable { * @param name a trimmed String representing the atom's PDB name, e.g. "CA" * @return an Atom object or null if no such atom exists within this group */ - public Atom getAtom(String name) ; - + Atom getAtom(String name); + /** * Get at atom by position. * * @param position an int * @return an Atom object or null if no Atom exists for given position */ - public Atom getAtom(int position) ; + Atom getAtom(int position); /** * Tell whether a particular atom exists within this group. @@ -143,7 +141,7 @@ public interface Group extends Serializable { * @param name a trimmed String representing the atom's PDB name, e.g. "CA" * @return true if Atom with name exists within this group */ - public boolean hasAtom(String name); + boolean hasAtom(String name); /** * Get the PDB 3-letter name for this group. (e.g. ALA) @@ -151,7 +149,7 @@ public interface Group extends Serializable { * @return a String representing the PDBName value * @see #setPDBName */ - public String getPDBName(); + String getPDBName(); /** * Set the PDB 3-letter name for this group. (e.g. ALA) @@ -159,8 +157,7 @@ public interface Group extends Serializable { * @param s a String specifying the PDBName value * @see #getPDBName */ - public void setPDBName(String s) ; - + void setPDBName(String s); /** * Calculate if this group has all atoms required for an amino acid backbone. @@ -183,33 +180,28 @@ public interface Group extends Serializable { * @return true if all Atoms required for an AminoAcid are available (N, CA, C, O) * @see #getType */ - public boolean hasAminoAtoms() ; - + boolean hasAminoAtoms(); /** * Check if this group is a polymeric group, from the definition in Chemical Component Dictionary * * @return true if a polymeric group */ - public boolean isPolymeric(); - + boolean isPolymeric(); /** * Check if this group is an aminoacid group, from the definition in Chemical Component Dictionary * * @return true if an amino acid */ - public boolean isAminoAcid(); - + boolean isAminoAcid(); /** * Check if this group is a nucleotide group, from the definition in Chemical Component Dictionary * * @return true if a nucleotide */ - public boolean isNucleotide(); - - + boolean isNucleotide(); /** * Properties of this amino acid. Currently available properties are: @@ -220,7 +212,7 @@ public interface Group extends Serializable { * @param properties a Map object specifying the properties value * @see #getProperties */ - public void setProperties(Map properties) ; + void setProperties(Map properties); /** * Return properties. @@ -228,7 +220,7 @@ public interface Group extends Serializable { * * @return a HashMap object representing the properties value */ - public Map getProperties() ; + Map getProperties(); /** * Set a single property . @@ -237,7 +229,7 @@ public interface Group extends Serializable { * @param value an Object * @see #getProperty */ - public void setProperty(String key, Object value) ; + void setProperty(String key, Object value); /** * Get a single property . @@ -246,21 +238,20 @@ public interface Group extends Serializable { * @return an Object * @see #setProperty */ - public Object getProperty(String key) ; + Object getProperty(String key); /** * Get an Atom Iterator. * * @return an Iterator object */ - public Iterator iterator() ; - + Iterator iterator(); /** * Returns and identical copy of this Group object . * @return and identical copy of this Group object */ - public Object clone(); + Object clone(); /** * Sets the back-reference to its parent Chain. @@ -268,7 +259,7 @@ public interface Group extends Serializable { * @see #getChain() * @since 3.0 */ - public void setChain(Chain chain); + void setChain(Chain chain); /** * Returns the parent Chain of the Group. @@ -277,7 +268,7 @@ public interface Group extends Serializable { * @see #setChain(Chain) * @since 3.0 */ - public Chain getChain() ; + Chain getChain(); /** * Returns a dynamically created ResidueNumber for the group - this @@ -286,15 +277,14 @@ public interface Group extends Serializable { * @return ResidueNumber for the group. * @since 3.0 */ - public ResidueNumber getResidueNumber(); - + ResidueNumber getResidueNumber(); /** * Sets the ResidueNumber for this Group * * @param residueNumber the PDB residueNumber */ - public void setResidueNumber(ResidueNumber residueNumber); + void setResidueNumber(ResidueNumber residueNumber); /** * Utility method to temporarily set a chainID for a group, if a parent chain object does not exist yet. @@ -304,7 +294,7 @@ public interface Group extends Serializable { * @param residueNumber * @param iCode */ - public void setResidueNumber(String chainId, Integer residueNumber, Character iCode); + void setResidueNumber(String chainId, Integer residueNumber, Character iCode); /** * Utility method for returning the chainId of the Group or null if no @@ -314,22 +304,21 @@ public interface Group extends Serializable { * @since 3.0 * @return the ID of the chain */ - public String getChainId(); + String getChainId(); /** * Set the Chemical Component that closer describes this group. * * @param cc the chemical component */ - public void setChemComp(ChemComp cc); + void setChemComp(ChemComp cc); /** * Get the chemical component that closer describes this group. If the information does not exist yet, fetches the information from PDB web site. * * @return the Chemical Component definition for this Group. */ - public ChemComp getChemComp(); - + ChemComp getChemComp(); /** * Check if this group has alternate location groups. @@ -337,8 +326,7 @@ public interface Group extends Serializable { * @return boolean flag if there are alternate locations. * @see #getAltLocs() */ - public boolean hasAltLoc(); - + boolean hasAltLoc(); /** * Get the list of other alternate location groups. @@ -363,14 +351,14 @@ public interface Group extends Serializable { * * @return List of other groups that are on alternate locations */ - public List getAltLocs(); + List getAltLocs(); /** * Add a group that is an alternate location for this group. * * @param g the altloc group to add */ - public void addAltLoc(Group g); + void addAltLoc(Group g); /** * Determines if this group is water. @@ -378,7 +366,7 @@ public interface Group extends Serializable { * @see GroupType#WATERNAMES * @return true if it's water, false otherwise. */ - public boolean isWater(); + boolean isWater(); /** * Gets the alternate location group to this group that has the alt-loc character code passed. @@ -386,21 +374,20 @@ public interface Group extends Serializable { * @param altLoc the alternate location code of the group desired * @return the alternate location group if found, or null otherwise */ - public Group getAltLocGroup(Character altLoc); - + Group getAltLocGroup(Character altLoc); /** * Attempts to reduce the memory imprint of this group by trimming * all internal Collection objects to the required size. * */ - public void trimToSize(); + void trimToSize(); /** * Function to get the Group as an MDL molblock * @return the string of the MDL molblock */ - public String toSDF(); + String toSDF(); /** * Tells whether the group is annotated as HETATM in the file. @@ -408,7 +395,7 @@ public interface Group extends Serializable { * polymeric group is in a ligand chain or not. * @return */ - public boolean isHetAtomInFile(); + boolean isHetAtomInFile(); /** * Sets the field isHetAtomInFile which is intented only for @@ -416,5 +403,5 @@ public interface Group extends Serializable { * or in a polymeric chain. * @param isHetAtomInFile */ - public void setHetAtomInFile(boolean isHetAtomInFile); + void setHetAtomInFile(boolean isHetAtomInFile); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/GroupType.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/GroupType.java index 234813ef42..7fa92f7363 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/GroupType.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/GroupType.java @@ -20,8 +20,8 @@ */ package org.biojava.nbio.structure; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; +import org.biojava.nbio.structure.chem.PolymerType; +import org.biojava.nbio.structure.chem.ResidueType; import java.util.*; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java index 037dcb2b0b..ddc4f2f636 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java @@ -23,15 +23,19 @@ */ package org.biojava.nbio.structure; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.PolymerType; +import org.biojava.nbio.structure.chem.ResidueType; import org.biojava.nbio.structure.io.GroupToSDF; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; +import org.rcsb.cif.schema.mm.ChemComp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; /** * @@ -332,9 +336,9 @@ public boolean isAminoAcid() { return getType().equals(GroupType.AMINOACID); - ResidueType rt = cc.getResidueType(); + ResidueType rt = ResidueType.getResidueTypeFromString(cc.getType().get(0)); - if ( rt.equals(ResidueType.nonPolymer)) + if (ResidueType.nonPolymer.equals(rt)) return false; PolymerType pt = rt.getPolymerType(); @@ -351,9 +355,9 @@ public boolean isNucleotide() { if ( cc == null) return getType().equals(GroupType.NUCLEOTIDE); - ResidueType rt = cc.getResidueType(); + ResidueType rt = ResidueType.getResidueTypeFromString(cc.getType().get(0)); - if ( rt.equals(ResidueType.nonPolymer)) + if (ResidueType.nonPolymer.equals(rt)) return false; PolymerType pt = rt.getPolymerType(); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java index 1071c52c23..d65c61ae95 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java @@ -76,7 +76,7 @@ public class PDBHeader implements PDBRecord { private Map bioAssemblies ; - List revisionRecords; + List revisionRecords; public PDBHeader(){ @@ -662,11 +662,11 @@ public int getNrBioAssemblies() { return this.bioAssemblies.size(); } - public List getRevisionRecords() { + public List getRevisionRecords() { return revisionRecords; } - public void setRevisionRecords(List revisionRecords) { + public void setRevisionRecords(List revisionRecords) { this.revisionRecords = revisionRecords; } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java index 193ed78e3d..e0592dfae3 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java @@ -25,8 +25,10 @@ import java.util.List; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.MMCIFFileReader; +import org.biojava.nbio.structure.io.BcifFileReader; +import org.biojava.nbio.structure.io.CifFileReader; import org.biojava.nbio.structure.io.PDBFileReader; +import org.rcsb.cif.binary.BinaryCifReader; /** * A class that provides static access methods for easy lookup of protein structure related components @@ -282,7 +284,8 @@ public static void setPdbPath(String pathToPDBFiles){ public static enum StructureFiletype { PDB( (new PDBFileReader()).getExtensions()), - CIF( new MMCIFFileReader().getExtensions()), + CIF(new CifFileReader().getExtensions()), + BCIF(new BcifFileReader().getExtensions()), UNKNOWN(Collections.emptyList()); private List extensions; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java index 653683ee0f..91cccd6a38 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java @@ -20,10 +20,14 @@ */ package org.biojava.nbio.structure; -import java.io.BufferedReader; +import org.biojava.nbio.structure.StructureIO.StructureFiletype; +import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.io.PDBFileReader; +import org.biojava.nbio.structure.io.cif.CifFileConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; @@ -36,16 +40,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.biojava.nbio.core.util.InputStreamProvider; -import org.biojava.nbio.structure.StructureIO.StructureFiletype; -import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.PDBFileReader; -import org.biojava.nbio.structure.io.mmcif.MMcifParser; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * Represents a structure loaded from a URL (including a file URL) * @@ -159,27 +153,7 @@ public Structure loadStructure(AtomCache cache) throws StructureException, switch(format) { case CIF: - // need to do mmcif parsing! - - InputStreamProvider prov = new InputStreamProvider(); - InputStream inStream = prov.getInputStream(url); - - MMcifParser parser = new SimpleMMcifParser(); - - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - consumer.setFileParsingParameters(cache.getFileParsingParams()); - - - parser.addMMcifConsumer(consumer); - - try { - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - } catch (IOException e){ - e.printStackTrace(); - } - - // now get the protein structure. - return consumer.getStructure(); + return CifFileConverter.fromURL(url); default: case PDB: // pdb file based parsing diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java index 4b96d5f433..cc0220da07 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java @@ -33,10 +33,10 @@ import org.biojava.nbio.structure.cath.CathDatabase; import org.biojava.nbio.structure.cath.CathDomain; import org.biojava.nbio.structure.cath.CathFactory; +import org.biojava.nbio.structure.io.CifFileReader; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; -import org.biojava.nbio.structure.io.MMCIFFileReader; import org.biojava.nbio.structure.io.MMTFFileReader; import org.biojava.nbio.structure.io.PDBFileReader; import org.biojava.nbio.core.util.FileDownloadUtils; @@ -879,12 +879,11 @@ protected Structure loadStructureFromCifByPdbId(String pdbId) throws IOException Structure s; flagLoading(pdbId); try { - MMCIFFileReader reader = new MMCIFFileReader(path); + CifFileReader reader = new CifFileReader(path); reader.setFetchBehavior(fetchBehavior); reader.setObsoleteBehavior(obsoleteBehavior); reader.setFileParsingParameters(params); s = reader.getStructureById(pdbId.toLowerCase()); - } finally { flagLoadingFinished(pdbId); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java new file mode 100644 index 0000000000..ef3b7414b8 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java @@ -0,0 +1,185 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.core.util.InputStreamProvider; +import org.biojava.nbio.structure.align.util.UserConfiguration; +import org.biojava.nbio.structure.io.LocalPDBDirectory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * A ChemComp provider that downloads and caches the components.cif file from the wwPDB site. It then loads + * all chemical components at startup and keeps them in memory. This provider is not used as a default + * since it is slower at startup and requires more memory than the {@link DownloadChemCompProvider} that is used by default. + * + * @author Andreas Prlic + * + */ +public class AllChemCompProvider implements ChemCompProvider, Runnable{ + private static final Logger logger = LoggerFactory.getLogger(AllChemCompProvider.class); + public static final String COMPONENTS_FILE_LOCATION = "pub/pdb/data/monomers/components.cif.gz"; + + private static String path; + private static String serverName; + + // there will be only one copy of the dictionary across all instances + // to reduce memory impact + static ChemicalComponentDictionary dict; + + // flags to make sure there is only one thread running that is loading the dictionary + static AtomicBoolean loading = new AtomicBoolean(false); + static AtomicBoolean isInitialized = new AtomicBoolean(false); + + public AllChemCompProvider(){ + if (loading.get()) { + logger.warn("other thread is already loading all chemcomps, no need to init twice"); + return; + } + if (isInitialized.get()) { + return; + } + + loading.set(true); + + Thread t = new Thread(this); + t.start(); + } + + /** + * make sure all paths are initialized correctly + */ + private static void initPath(){ + if (path == null) { + UserConfiguration config = new UserConfiguration(); + path = config.getCacheFilePath(); + } + } + + private static void initServerName() { + if (serverName == null) { + serverName = LocalPDBDirectory.getServerName(); + } + } + + private void ensureFileExists() { + String fileName = getLocalFileName(); + File f = new File(fileName); + + if (!f.exists()) { + try { + downloadFile(); + } catch (IOException e) { + logger.error("Caught IOException", e); + } + } + } + + /** + * Downloads the components.cif.gz file from the wwPDB site. + */ + public static void downloadFile() throws IOException { + initPath(); + initServerName(); + + String localName = getLocalFileName(); + String u = serverName + "/" + COMPONENTS_FILE_LOCATION; + + downloadFileFromRemote(new URL(u), new File(localName)); + } + + private static void downloadFileFromRemote(URL remoteURL, File localFile) throws IOException { + logger.info("Downloading " + remoteURL + " to: " + localFile); + FileOutputStream out = new FileOutputStream(localFile); + + InputStream in = remoteURL.openStream(); + byte[] buf = new byte[4 * 1024]; // 4K buffer + int bytesRead; + while ((bytesRead = in.read(buf)) != -1) { + out.write(buf, 0, bytesRead); + } + in.close(); + out.close(); + } + + private static String getLocalFileName(){ + File dir = new File(path, DownloadChemCompProvider.CHEM_COMP_CACHE_DIRECTORY); + + if (!dir.exists()) { + logger.info("Creating directory {}", dir.toString()); + dir.mkdir(); + } + + return new File(dir, "components.cif.gz").toString(); + } + + /** + * Load all {@link ChemComp} definitions into memory. + */ + private void loadAllChemComps() throws IOException { + String fileName = getLocalFileName(); + logger.debug("Loading " + fileName); + InputStreamProvider isp = new InputStreamProvider(); + + InputStream inStream = isp.getInputStream(fileName); + MMcifParser parser = new SimpleMMcifParser(); + ChemCompConsumer consumer = new ChemCompConsumer(); + + // The Consumer builds up the BioJava - structure object. + // you could also hook in your own and build up you own data model. + parser.addMMcifConsumer(consumer); + parser.parse(new BufferedReader(new InputStreamReader(inStream))); + dict = consumer.getDictionary(); + inStream.close(); + } + + /** + * {@inheritDoc} + */ + @Override + public ChemComp getChemComp(String recordName) { + while (loading.get()) { + // another thread is still initializing the definitions + try { + // wait half a second + Thread.sleep(500); + } catch (InterruptedException e) { + logger.error("Interrupted thread while waiting: " + e.getMessage()); + //e.printStackTrace(); + } + } + + return dict.getChemComp(recordName); + } + + + /** + * Do the actual loading of the dictionary in a thread. + */ + @Override + public void run() { + long timeS = System.currentTimeMillis(); + initPath(); + ensureFileExists(); + + try { + loadAllChemComps(); + + long timeE = System.currentTimeMillis(); + logger.debug("Time to init chem comp dictionary: " + (timeE - timeS) / 1000 + " sec."); + } catch (IOException e) { + logger.error("Could not load chemical components definition file {}. Error: {}", getLocalFileName(), e.getMessage()); + } finally { + loading.set(false); + isInitialized.set(true); + } + } +} + diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java new file mode 100644 index 0000000000..96631fe736 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java @@ -0,0 +1,405 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.structure.io.cif.CifBean; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Properties of a chemical component. + */ +public class ChemComp implements CifBean, Comparable { + private static final long serialVersionUID = -4736341142030215915L; + + private String id; + private String name; + private String type; + private String pdbxType; + private String formula; + private String monNstdParentCompId; + private String pdbxSynonyms; + private String pdbxFormalCharge; + private String pdbxInitialDate; + private String pdbxModifiedDate; + private String pdbxAmbiguousFlag; + private String pdbxReleaseStatus; + private String pdbxReplacedBy; + private String pdbxReplaces; + private String formulaWeight; + private String oneLetterCode; + private String threeLetterCode; + private String pdbxModelCoordinatesDetails; + private String pdbxModelCoordinatesMissingFlag; + private String pdbxIdealCoordinatesDetails; + private String pdbxIdealCoordinatesMissingFlag; + private String pdbxModelCoordinatesDbCode; + private String pdbxSubcomponentList; + private String pdbxProcessingSite; + private String monNstdFlag; + + private List descriptors = new ArrayList<>(); + private List bonds = new ArrayList<>(); + private List atoms = new ArrayList<>(); + + // and some derived data for easier processing... + private ResidueType residueType; + private PolymerType polymerType; + private boolean standard; + + @Override + public String toString(){ + StringBuffer buf = new StringBuffer("ChemComp "); + buf.append(id) + .append(" ") + .append(oneLetterCode) + .append(" ") + .append(threeLetterCode) + .append(" poly:") + .append(getPolymerType()) + .append(" resi:") + .append(getResidueType()) + .append(isStandard() ? " standard" : " modified") + .append(" ") + .append(name) + .append(" ") + .append(pdbxType) + .append(" ") + .append(formula) + .append(" parent:") + .append(monNstdParentCompId); + return buf.toString(); + } + + public boolean hasParent(){ + String pid = monNstdParentCompId; + return (pid != null) && (!pid.equals("?")); + } + + public boolean isStandard(){ + return standard; + } + + private void setStandardFlag(){ + standard = ChemCompTools.isStandardChemComp(this); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + this.residueType = ResidueType.getResidueTypeFromString(type); + if (residueType != null) { + polymerType = residueType.polymerType; + } + } + + public ResidueType getResidueType() { + return residueType; + } + + public void setResidueType(ResidueType residueType) { + this.residueType = residueType; + } + + public PolymerType getPolymerType() { + return polymerType; + } + + public void setPolymerType(PolymerType polymerType) { + this.polymerType = polymerType; + } + + public String getPdbxType() { + return pdbxType; + } + + public void setPdbxType(String pdbxType) { + this.pdbxType = pdbxType; + } + + public String getFormula() { + return formula; + } + + public void setFormula(String formula) { + this.formula = formula; + } + + public String getMonNstdParentCompId() { + return monNstdParentCompId; + } + + public void setMonNstdParentCompId(String monNstdParentCompId) { + this.monNstdParentCompId = monNstdParentCompId; + setStandardFlag(); + } + + public String getPdbxSynonyms() { + return pdbxSynonyms; + } + + public void setPdbxSynonyms(String pdbxSynonyms) { + this.pdbxSynonyms = pdbxSynonyms; + } + + public String getPdbxFormalCharge() { + return pdbxFormalCharge; + } + + public void setPdbxFormalCharge(String pdbxFormalCharge) { + this.pdbxFormalCharge = pdbxFormalCharge; + } + + public String getPdbxInitialDate() { + return pdbxInitialDate; + } + + public void setPdbxInitialDate(String pdbxInitialDate) { + this.pdbxInitialDate = pdbxInitialDate; + } + + public String getPdbxModifiedDate() { + return pdbxModifiedDate; + } + + public void setPdbxModifiedDate(String pdbxModifiedDate) { + this.pdbxModifiedDate = pdbxModifiedDate; + } + + public String getPdbxAmbiguousFlag() { + return pdbxAmbiguousFlag; + } + + public void setPdbxAmbiguousFlag(String pdbxAmbiguousFlag) { + this.pdbxAmbiguousFlag = pdbxAmbiguousFlag; + } + + public String getPdbxReleaseStatus() { + return pdbxReleaseStatus; + } + + public void setPdbxReleaseStatus(String pdbxReleaseStatus) { + this.pdbxReleaseStatus = pdbxReleaseStatus; + } + + public String getPdbxReplacedBy() { + return pdbxReplacedBy; + } + + public void setPdbxReplacedBy(String pdbxReplacedBy) { + this.pdbxReplacedBy = pdbxReplacedBy; + } + + public String getPdbxReplaces() { + return pdbxReplaces; + } + + public void setPdbxReplaces(String pdbxReplaces) { + this.pdbxReplaces = pdbxReplaces; + } + + public String getFormulaWeight() { + return formulaWeight; + } + + public void setFormulaWeight(String formulaWeight) { + this.formulaWeight = formulaWeight; + } + + public String getOneLetterCode() { + return oneLetterCode; + } + + public void setOneLetterCode(String oneLetterCode) { + this.oneLetterCode = oneLetterCode; + setStandardFlag(); + } + + public String getThreeLetterCode() { + return threeLetterCode; + } + + public void setThreeLetterCode(String threeLetterCode) { + this.threeLetterCode = threeLetterCode; + } + + public String getPdbxModelCoordinatesDetails() { + return pdbxModelCoordinatesDetails; + } + + public void setPdbxModelCoordinatesDetails(String pdbxModelCoordinatesDetails) { + this.pdbxModelCoordinatesDetails = pdbxModelCoordinatesDetails; + } + + public String getPdbxModelCoordinatesMissingFlag() { + return pdbxModelCoordinatesMissingFlag; + } + + public void setPdbxModelCoordinatesMissingFlag(String pdbxModelCoordinatesMissingFlag) { + this.pdbxModelCoordinatesMissingFlag = pdbxModelCoordinatesMissingFlag; + } + + public String getPdbxIdealCoordinatesDetails() { + return pdbxIdealCoordinatesDetails; + } + + public void setPdbxIdealCoordinatesDetails(String pdbxIdealCoordinatesDetails) { + this.pdbxIdealCoordinatesDetails = pdbxIdealCoordinatesDetails; + } + + public String getPdbxIdealCoordinatesMissingFlag() { + return pdbxIdealCoordinatesMissingFlag; + } + + public void setPdbxIdealCoordinatesMissingFlag(String pdbxIdealCoordinatesMissingFlag) { + this.pdbxIdealCoordinatesMissingFlag = pdbxIdealCoordinatesMissingFlag; + } + + public String getPdbxModelCoordinatesDbCode() { + return pdbxModelCoordinatesDbCode; + } + + public void setPdbxModelCoordinatesDbCode(String pdbxModelCoordinatesDbCode) { + this.pdbxModelCoordinatesDbCode = pdbxModelCoordinatesDbCode; + } + + public String getPdbxSubcomponentList() { + return pdbxSubcomponentList; + } + + public void setPdbxSubcomponentList(String pdbxSubcomponentList) { + this.pdbxSubcomponentList = pdbxSubcomponentList; + } + + public String getPdbxProcessingSite() { + return pdbxProcessingSite; + } + + public void setPdbxProcessingSite(String pdbxProcessingSite) { + this.pdbxProcessingSite = pdbxProcessingSite; + } + + public String getMonNstdFlag() { + return monNstdFlag; + } + + public void setMonNstdFlag(String monNstdFlag) { + this.monNstdFlag = monNstdFlag; + } + + public List getDescriptors() { + return descriptors; + } + + public void setDescriptors(List descriptors) { + this.descriptors = descriptors; + } + + public List getBonds() { + return bonds; + } + + public void setBonds(List bonds) { + this.bonds = bonds; + } + + public List getAtoms() { + return atoms; + } + + public void setAtoms(List atoms) { + this.atoms = atoms; + } + + @Override + public int compareTo(ChemComp arg0) { + if (this.equals(arg0)) + return 0; + return this.getId().compareTo(arg0.getId()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ChemComp chemComp = (ChemComp) o; + return standard == chemComp.standard && + Objects.equals(id, chemComp.id) && + Objects.equals(name, chemComp.name) && + Objects.equals(type, chemComp.type) && + Objects.equals(pdbxType, chemComp.pdbxType) && + Objects.equals(formula, chemComp.formula) && + Objects.equals(monNstdParentCompId, chemComp.monNstdParentCompId) && + Objects.equals(pdbxSynonyms, chemComp.pdbxSynonyms) && + Objects.equals(pdbxFormalCharge, chemComp.pdbxFormalCharge) && + Objects.equals(pdbxInitialDate, chemComp.pdbxInitialDate) && + Objects.equals(pdbxModifiedDate, chemComp.pdbxModifiedDate) && + Objects.equals(pdbxAmbiguousFlag, chemComp.pdbxAmbiguousFlag) && + Objects.equals(pdbxReleaseStatus, chemComp.pdbxReleaseStatus) && + Objects.equals(pdbxReplacedBy, chemComp.pdbxReplacedBy) && + Objects.equals(pdbxReplaces, chemComp.pdbxReplaces) && + Objects.equals(formulaWeight, chemComp.formulaWeight) && + Objects.equals(oneLetterCode, chemComp.oneLetterCode) && + Objects.equals(threeLetterCode, chemComp.threeLetterCode) && + Objects.equals(pdbxModelCoordinatesDetails, chemComp.pdbxModelCoordinatesDetails) && + Objects.equals(pdbxModelCoordinatesMissingFlag, chemComp.pdbxModelCoordinatesMissingFlag) && + Objects.equals(pdbxIdealCoordinatesDetails, chemComp.pdbxIdealCoordinatesDetails) && + Objects.equals(pdbxIdealCoordinatesMissingFlag, chemComp.pdbxIdealCoordinatesMissingFlag) && + Objects.equals(pdbxModelCoordinatesDbCode, chemComp.pdbxModelCoordinatesDbCode) && + Objects.equals(pdbxSubcomponentList, chemComp.pdbxSubcomponentList) && + Objects.equals(pdbxProcessingSite, chemComp.pdbxProcessingSite) && + Objects.equals(monNstdFlag, chemComp.monNstdFlag) && + Objects.equals(descriptors, chemComp.descriptors) && + Objects.equals(bonds, chemComp.bonds) && + Objects.equals(atoms, chemComp.atoms) && + residueType == chemComp.residueType && + polymerType == chemComp.polymerType; + } + + @Override + public int hashCode() { + return Objects.hash(id, name, type, pdbxType, formula, monNstdParentCompId, pdbxSynonyms, pdbxFormalCharge, pdbxInitialDate, pdbxModifiedDate, pdbxAmbiguousFlag, pdbxReleaseStatus, pdbxReplacedBy, pdbxReplaces, formulaWeight, oneLetterCode, threeLetterCode, pdbxModelCoordinatesDetails, pdbxModelCoordinatesMissingFlag, pdbxIdealCoordinatesDetails, pdbxIdealCoordinatesMissingFlag, pdbxModelCoordinatesDbCode, pdbxSubcomponentList, pdbxProcessingSite, monNstdFlag, descriptors, bonds, atoms, residueType, polymerType, standard); + } + + /** + * Creates a new instance of the dummy empty ChemComp. + * @return a ChemComp + */ + public static ChemComp getEmptyChemComp() { + ChemComp comp = new ChemComp(); + + comp.setOneLetterCode("?"); + comp.setThreeLetterCode("???"); // Main signal for isEmpty() + comp.setPolymerType(PolymerType.unknown); + comp.setResidueType(ResidueType.atomn); + return comp; + } + + /** + * Indicates whether this compound was created with + * @return a boolean + */ + public boolean isEmpty() { + // Is this the best flag for it being empty? + return id == null || getThreeLetterCode() == null || getThreeLetterCode().equals("???"); + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java new file mode 100644 index 0000000000..cad290820e --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java @@ -0,0 +1,205 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.structure.io.cif.CifBean; + +public class ChemCompAtom implements CifBean { + private static final long serialVersionUID = 4070599340294758941L; + private String compId; + private String atomId; + private String altAtomId; + private String typeSymbol; + private String charge; + private String pdbxAlign; + private String pdbxAromaticFlag; + private String pdbxLeavingAtomFlag; + private String pdbxStereoConfig; + private String modelCartnX; + private String modelCartnY; + private String modelCartnZ; + private String pdbxModelCartnXIdeal; + private String pdbxModelCartnYIdeal; + private String pdbxModelCartnZIdeal; + private String pdbxComponentCompId; + private String pdbxResidueNumbering; + private String pdbxComponentAtomId; + private String pdbxPolymerType; + private String pdbxRefId; + private String pdbxComponentId; + private String pdbxOrdinal; + + public String getCompId() { + return compId; + } + + public void setCompId(String compId) { + this.compId = compId; + } + + public String getAtomId() { + return atomId; + } + + public void setAtomId(String atomId) { + this.atomId = atomId; + } + + public String getAltAtomId() { + return altAtomId; + } + + public void setAltAtomId(String altAtomId) { + this.altAtomId = altAtomId; + } + + public String getTypeSymbol() { + return typeSymbol; + } + + public void setTypeSymbol(String typeSymbol) { + this.typeSymbol = typeSymbol; + } + + public String getCharge() { + return charge; + } + + public void setCharge(String charge) { + this.charge = charge; + } + + public String getPdbxAlign() { + return pdbxAlign; + } + + public void setPdbxAlign(String pdbxAlign) { + this.pdbxAlign = pdbxAlign; + } + + public String getPdbxAromaticFlag() { + return pdbxAromaticFlag; + } + + public void setPdbxAromaticFlag(String pdbxAromaticFlag) { + this.pdbxAromaticFlag = pdbxAromaticFlag; + } + + public String getPdbxLeavingAtomFlag() { + return pdbxLeavingAtomFlag; + } + + public void setPdbxLeavingAtomFlag(String pdbxLeavingAtomFlag) { + this.pdbxLeavingAtomFlag = pdbxLeavingAtomFlag; + } + + public String getPdbxStereoConfig() { + return pdbxStereoConfig; + } + + public void setPdbxStereoConfig(String pdbxStereoConfig) { + this.pdbxStereoConfig = pdbxStereoConfig; + } + + public String getModelCartnX() { + return modelCartnX; + } + + public void setModelCartnX(String modelCartnX) { + this.modelCartnX = modelCartnX; + } + + public String getModelCartnY() { + return modelCartnY; + } + + public void setModelCartnY(String modelCartnY) { + this.modelCartnY = modelCartnY; + } + + public String getModelCartnZ() { + return modelCartnZ; + } + + public void setModelCartnZ(String modelCartnZ) { + this.modelCartnZ = modelCartnZ; + } + + public String getPdbxModelCartnXIdeal() { + return pdbxModelCartnXIdeal; + } + + public void setPdbxModelCartnXIdeal(String pdbxModelCartnXIdeal) { + this.pdbxModelCartnXIdeal = pdbxModelCartnXIdeal; + } + + public String getPdbxModelCartnYIdeal() { + return pdbxModelCartnYIdeal; + } + + public void setPdbxModelCartnYIdeal(String pdbxModelCartnYIdeal) { + this.pdbxModelCartnYIdeal = pdbxModelCartnYIdeal; + } + + public String getPdbxModelCartnZIdeal() { + return pdbxModelCartnZIdeal; + } + + public void setPdbxModelCartnZIdeal(String pdbxModelCartnZIdeal) { + this.pdbxModelCartnZIdeal = pdbxModelCartnZIdeal; + } + + public String getPdbxComponentCompId() { + return pdbxComponentCompId; + } + + public void setPdbxComponentCompId(String pdbxComponentCompId) { + this.pdbxComponentCompId = pdbxComponentCompId; + } + + public String getPdbxResidueNumbering() { + return pdbxResidueNumbering; + } + + public void setPdbxResidueNumbering(String pdbxResidueNumbering) { + this.pdbxResidueNumbering = pdbxResidueNumbering; + } + + public String getPdbxComponentAtomId() { + return pdbxComponentAtomId; + } + + public void setPdbxComponentAtomId(String pdbxComponentAtomId) { + this.pdbxComponentAtomId = pdbxComponentAtomId; + } + + public String getPdbxPolymerType() { + return pdbxPolymerType; + } + + public void setPdbxPolymerType(String pdbxPolymerType) { + this.pdbxPolymerType = pdbxPolymerType; + } + + public String getPdbxRefId() { + return pdbxRefId; + } + + public void setPdbxRefId(String pdbxRefId) { + this.pdbxRefId = pdbxRefId; + } + + public String getPdbxComponentId() { + return pdbxComponentId; + } + + public void setPdbxComponentId(String pdbxComponentId) { + this.pdbxComponentId = pdbxComponentId; + } + + public String getPdbxOrdinal() { + return pdbxOrdinal; + } + + public void setPdbxOrdinal(String pdbxOrdinal) { + this.pdbxOrdinal = pdbxOrdinal; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompBond.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompBond.java new file mode 100644 index 0000000000..b5a4d4e7f4 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompBond.java @@ -0,0 +1,114 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.structure.io.cif.CifBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ChemCompBond implements CifBean { + private static final long serialVersionUID = 5905371029161975421L; + private static final Logger logger = LoggerFactory.getLogger(ChemCompBond.class); + + private String compId; + private String atomId1; + private String atomId2; + private String valueOrder; + private String pdbxAromaticFlag; + private String pdbxStereoConfig; + private String pdbxOrdinal; + + public static Logger getLogger() { + return logger; + } + + public String getCompId() { + return compId; + } + + public void setCompId(String compId) { + this.compId = compId; + } + + public String getAtomId1() { + return atomId1; + } + + public void setAtomId1(String atomId1) { + this.atomId1 = atomId1; + } + + public String getAtomId2() { + return atomId2; + } + + public void setAtomId2(String atomId2) { + this.atomId2 = atomId2; + } + + public String getValueOrder() { + return valueOrder; + } + + public void setValueOrder(String valueOrder) { + this.valueOrder = valueOrder; + } + + public String getPdbxAromaticFlag() { + return pdbxAromaticFlag; + } + + public void setPdbxAromaticFlag(String pdbxAromaticFlag) { + this.pdbxAromaticFlag = pdbxAromaticFlag; + } + + public String getPdbxStereoConfig() { + return pdbxStereoConfig; + } + + public void setPdbxStereoConfig(String pdbxStereoConfig) { + this.pdbxStereoConfig = pdbxStereoConfig; + } + + public String getPdbxOrdinal() { + return pdbxOrdinal; + } + + public void setPdbxOrdinal(String pdbxOrdinal) { + this.pdbxOrdinal = pdbxOrdinal; + } + + /** + * Converts this ChemCompBond's value_order attribute into an int using the + * conversion: + * + *

      +     * 	SING -> 1
      +     * 	DOUB -> 2
      +     * 	TRIP -> 3
      +     * 	QUAD -> 4
      +     * 
      + * + * Any other values will return -1. + *

      + * (Source: + * http://mmcif.rcsb.org/dictionaries/mmcif_mdb.dic/Items/_chem_comp_bond. + * value_order.html) + * + * @return the numerical value of this ChemCompBond's bond order, or -1 if + * the value is non-numeric or unknown. + */ + public int getNumericalBondOrder() { + switch (valueOrder) { + case "SING": + return 1; + case "DOUB": + return 2; + case "TRIP": + return 3; + case "QUAD": + return 4; + default: + logger.error("Unknown or non-numeric value for value_order: " + valueOrder); + return -1; + } + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompContainer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompContainer.java new file mode 100644 index 0000000000..322f927895 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompContainer.java @@ -0,0 +1,13 @@ +package org.biojava.nbio.structure.chem; + +import org.rcsb.cif.schema.mm.ChemComp; + +public class ChemCompContainer { + private final ChemComp delegate; + + public ChemCompContainer(ChemComp chemComp) { + this.delegate = chemComp; + } + + +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompDescriptor.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompDescriptor.java new file mode 100644 index 0000000000..7628caef53 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompDescriptor.java @@ -0,0 +1,80 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.structure.io.cif.CifBean; + +import java.util.Objects; + +public class ChemCompDescriptor implements CifBean { + private static final long serialVersionUID = 1078685833800736278L; + private String compId; + private String type; + private String program; + private String programVersion; + private String descriptor; + + public String getCompId() { + return compId; + } + + public void setCompId(String compId) { + this.compId = compId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getProgram() { + return program; + } + + public void setProgram(String program) { + this.program = program; + } + + public String getProgramVersion() { + return programVersion; + } + + public void setProgramVersion(String programVersion) { + this.programVersion = programVersion; + } + + public String getDescriptor() { + return descriptor; + } + + public void setDescriptor(String descriptor) { + this.descriptor = descriptor; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ChemCompDescriptor that = (ChemCompDescriptor) o; + return Objects.equals(compId, that.compId) && + Objects.equals(type, that.type) && + Objects.equals(program, that.program) && + Objects.equals(programVersion, that.programVersion) && + Objects.equals(descriptor, that.descriptor); + } + + @Override + public int hashCode() { + return Objects.hash(compId, type, program, programVersion, descriptor); + } + + @Override + public String toString() { + return "ChemCompDescriptor [comp_id=" + compId + + ", type=" + type + + ", program=" + program + + ", program_version=" + programVersion + + ", descriptor=" + descriptor + "]"; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompGroupFactory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompGroupFactory.java new file mode 100644 index 0000000000..cad709223f --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompGroupFactory.java @@ -0,0 +1,131 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.core.util.SoftHashMap; +import org.biojava.nbio.structure.AminoAcid; +import org.biojava.nbio.structure.AminoAcidImpl; +import org.biojava.nbio.structure.Group; +import org.biojava.nbio.structure.HetatomImpl; +import org.biojava.nbio.structure.NucleotideImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; + +public class ChemCompGroupFactory { + private static final Logger logger = LoggerFactory.getLogger(ChemCompGroupFactory.class); + private static ChemCompProvider chemCompProvider = new DownloadChemCompProvider(); + private static Map cache = new SoftHashMap<>(0); + + public static ChemComp getChemComp(String recordName) { + recordName = recordName.toUpperCase().trim(); + + // we are using the cache, to avoid hitting the file system too often. + ChemComp chemComp = cache.get(recordName); + if (chemComp != null) { + logger.debug("Chem comp " + chemComp.getThreeLetterCode() + " read from cache"); + return chemComp; + } + + // not cached, get the chem comp from the provider + logger.debug("Chem comp " + recordName + " read from provider " + chemCompProvider.getClass().getCanonicalName()); + chemComp = chemCompProvider.getChemComp(recordName); + + // Note that this also caches null or empty responses + cache.put(recordName, chemComp); + return chemComp; + } + + /** + * The new ChemCompProvider will be set in the static variable, + * so this provider will be used from now on until it is changed + * again. Note that this change can have unexpected behavior of + * code executed afterwards. + *

      + * Changing the provider also resets the cache, so any groups + * previously accessed will be reread or re-downloaded. + * + * @param provider + */ + public static void setChemCompProvider(ChemCompProvider provider) { + logger.debug("Setting new chem comp provider to " + provider.getClass().getCanonicalName()); + chemCompProvider = provider; + // clear cache + cache.clear(); + } + + public static ChemCompProvider getChemCompProvider(){ + return chemCompProvider; + } + + /** + * Force the in-memory cache to be reset. + * + * Note that the ChemCompProvider may have additional memory or disk caches that need to be cleared too. + */ + public static void clearCache() { + cache.clear(); + } + + public static Group getGroupFromChemCompDictionary(String recordName) { + // make sure we work with upper case records + recordName = recordName.toUpperCase().trim(); + ChemComp chemComp = getChemComp(recordName); + Group group; + + if (chemComp == null) { + return null; + } + + PolymerType polymerType = PolymerType.polymerTypeFromString(chemComp.getType()); + if (PolymerType.PROTEIN_ONLY.contains(polymerType)) { + AminoAcid aminoAcid = new AminoAcidImpl(); + + String oneLetterCode = chemComp.getOneLetterCode(); + if (oneLetterCode == null || oneLetterCode.equals("X") || oneLetterCode.equals("?") || oneLetterCode.length() == 0) { + String parent = chemComp.getMonNstdParentCompId(); + if (parent != null && parent.length() == 3) { + String parentId = chemComp.getMonNstdParentCompId(); + ChemComp parentChemComp = getChemComp(parentId); + oneLetterCode = parentChemComp.getOneLetterCode(); + } + } + + if (oneLetterCode == null || oneLetterCode.length() == 0 || oneLetterCode.equals("?")) { + // e.g. problem with PRR, which probably should have a parent of ALA, but as of 20110127 does not. + logger.warn("Problem with chemical component: " + recordName + " Did not find one letter code! Setting it to 'X'"); + aminoAcid.setAminoType('X'); + } else { + aminoAcid.setAminoType(oneLetterCode.charAt(0)); + } + + group = aminoAcid; + } else if (PolymerType.POLYNUCLEOTIDE_ONLY.contains(polymerType)) { + group = new NucleotideImpl(); + } else { + group = new HetatomImpl(); + } + + group.setChemComp(chemComp); + return group; + } + + public static String getOneLetterCode(ChemComp chemComp) { + String oneLetterCode = chemComp.getOneLetterCode(); + if (oneLetterCode == null || oneLetterCode.equals("X") || oneLetterCode.equals("?")) { + String parentId = chemComp.getMonNstdParentCompId(); + if (parentId == null) { + return oneLetterCode; + } + // cases like OIM have multiple parents (comma separated), we shouldn't try grab a chemcomp for those strings + if (parentId.length() > 3) { + return oneLetterCode; + } + ChemComp parentChemComp = ChemCompGroupFactory.getChemComp(parentId); + if (parentChemComp == null) { + return oneLetterCode; + } + oneLetterCode = parentChemComp.getOneLetterCode(); + } + return oneLetterCode; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java new file mode 100644 index 0000000000..936f5ef8cf --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java @@ -0,0 +1,15 @@ +package org.biojava.nbio.structure.chem; + +/** + * Interface that is implemented by all classes that can provide {@link ChemComp} definitions. + * @author Andreas Prlic + * @since 3.0 + */ +public interface ChemCompProvider { + /** + * Returns a new instance of a chemical component definition. + * @param recordName the ID of the {@link ChemComp} + * @return a new {@link ChemComp} definition. + */ + ChemComp getChemComp(String recordName); +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java new file mode 100644 index 0000000000..b24fd5d51a --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java @@ -0,0 +1,209 @@ +package org.biojava.nbio.structure.chem; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ChemCompTools { + private static final Character UNKNOWN_ONE_LETTER_CODE = 'X'; + private static final Character UNKNOWN_NUCLEOTIDE = 'N'; + /** + * Lookup table to convert standard amino acid's monomer ids to one-letter-codes + */ + private static final Map AMINO_ACID_LOOKUP_3TO1; + /** + * Lookup table to convert standard amino acid's one-letter-codes to monomer ids + */ + private static final Map AMINO_ACID_LOOKUP_1TO3; + /** + * Lookup table to convert standard nucleic acid's monomer ids to one-letter-codes + */ + private static final Map DNA_LOOKUP_2TO1; + /** + * Lookup table to convert standard nucleic acid's one-letter-codes to monomer ids + */ + private static final Map DNA_LOOKUP_1TO2; + /* + Static block that initializes lookup maps and initializes their ResidueInfo instances + */ + static { + Map foo = new HashMap<>(); + foo.put("ALA", 'A'); + foo.put("ASP", 'D'); + foo.put("ASN", 'N'); + foo.put("ASX", 'B'); + foo.put("ARG", 'R'); + foo.put("CYS", 'C'); + foo.put("GLU", 'E'); + foo.put("GLN", 'Q'); + foo.put("GLY", 'G'); + foo.put("GLX", 'Z'); + foo.put("HIS", 'H'); + foo.put("ILE", 'I'); + foo.put("LYS", 'K'); + foo.put("LEU", 'L'); + foo.put("MET", 'M'); + foo.put("PHE", 'F'); + foo.put("PRO", 'P'); + foo.put("SER", 'S'); + foo.put("THR", 'T'); + foo.put("TRP", 'W'); + foo.put("TYR", 'Y'); + foo.put("VAL", 'V'); + AMINO_ACID_LOOKUP_3TO1 = Collections.unmodifiableMap((Collections.synchronizedMap(foo))); + + Map bar = new HashMap<>(); + bar.put('A', "ALA"); + bar.put('D', "ASP"); + bar.put('N', "ASN"); + bar.put('B', "ASX"); + bar.put('R', "ARG"); + bar.put('C', "CYS"); + bar.put('E', "GLU"); + bar.put('Q', "GLN"); + bar.put('G', "GLY"); + bar.put('Z', "GLX"); + bar.put('H', "HIS"); + bar.put('I', "ILE"); + bar.put('K', "LYS"); + bar.put('L', "LEU"); + bar.put('M', "MET"); + bar.put('F', "PHE"); + bar.put('P', "PRO"); + bar.put('S', "SER"); + bar.put('T', "THR"); + bar.put('W', "TRP"); + bar.put('Y', "TYR"); + bar.put('V', "VAL"); + AMINO_ACID_LOOKUP_1TO3 = Collections.unmodifiableMap(Collections.synchronizedMap(bar)); + + foo = new HashMap<>(); + foo.put("DA",'A'); + foo.put("DC",'C'); + foo.put("DG",'G'); + foo.put("DI",'I'); + foo.put("DU",'U'); + foo.put("DT",'T'); + DNA_LOOKUP_2TO1 = Collections.unmodifiableMap((Collections.synchronizedMap(foo))); + + bar = new HashMap<>(); + bar.put('A',"DA"); + bar.put('C',"DC"); + bar.put('G',"DG"); + bar.put('I',"DI"); + bar.put('U',"DU"); + bar.put('T',"DT"); + DNA_LOOKUP_1TO2 = Collections.unmodifiableMap(Collections.synchronizedMap(bar)); + + + // initialise standard chemical components + List stdMonIds = new ArrayList<>(); + stdMonIds.addAll(AMINO_ACID_LOOKUP_3TO1.keySet()); + stdMonIds.addAll(DNA_LOOKUP_2TO1.keySet()); + } + + public static Character getAminoOneLetter(String chemCompId){ + return AMINO_ACID_LOOKUP_3TO1.get(chemCompId); + } + + public static Character getDNAOneLetter(String chemCompId){ + return DNA_LOOKUP_2TO1.get(chemCompId); + } + + public static String getAminoThreeLetter(Character c){ + return AMINO_ACID_LOOKUP_1TO3.get(c); + } + + public static String getDNATwoLetter(Character c){ + return DNA_LOOKUP_1TO2.get(c); + } + + public static boolean isStandardChemComp(ChemComp cc){ + String pid = cc.getMonNstdParentCompId(); + String one = cc.getOneLetterCode(); + + PolymerType polymerType = cc.getPolymerType(); + + // standard residues have no parent + if ((pid == null) || (pid.equals("?"))) { + // and they have a one letter code + if ((one != null) && (!one.equals("?"))) { + // peptides and dpeptides must not have X + if (polymerType == PolymerType.peptide || polymerType == PolymerType.dpeptide) { + return performPeptideCheck(cc, one); + } + if (polymerType == PolymerType.rna) { + return performRNACheck(cc); + } + if (polymerType == PolymerType.dna) { + return performDNACheck(cc); + } + + //System.err.println("Non standard chem comp: " + cc); + return false; + } + } + return false; + } + + private static boolean performRNACheck(ChemComp cc) { + return cc.getId().length() == 1; + } + + private static boolean performDNACheck(ChemComp cc) { + if (cc.getId().equals(UNKNOWN_NUCLEOTIDE.toString())) { + return false; + } + + Character c = getDNAOneLetter(cc.getId()); + // we did not find it in the list of standard nucleotides + return c != null; + } + + private static boolean performPeptideCheck(ChemComp cc, String one) { + if (one.equals(UNKNOWN_ONE_LETTER_CODE.toString())) { + return false; + } + Character c = getAminoOneLetter(cc.getId()); + // we did not find it in the list of standard aminos + return c != null; + } + + // TODO: component 175 has 3 chars as a one letter code... + // Figure out what to do with it... + // so does: 4F3,5ZA and others + public static Character getOneLetterCode(ChemComp cc, ChemicalComponentDictionary dictionary) { + if (cc.getResidueType() == ResidueType.nonPolymer) { + return null; + } + + if (cc.isStandard()) { + return cc.getOneLetterCode().charAt(0); + } + + ChemComp parent = dictionary.getParent(cc); + if (parent == null) { + //System.err.println("parent is null " + cc); + return cc.getOneLetterCode().charAt(0); + } + PolymerType poly = cc.getPolymerType(); + if (poly == PolymerType.peptide || poly == PolymerType.dpeptide) { + Character c = getAminoOneLetter(parent.getId()); + if (c == null) { + c = UNKNOWN_ONE_LETTER_CODE; + } + return c; + } + if (poly == PolymerType.dna) { + Character c = getDNAOneLetter(parent.getId()); + if (c == null) { + c = UNKNOWN_NUCLEOTIDE; + } + return c; + + } + return cc.getMonNstdParentCompId().charAt(0); + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java new file mode 100644 index 0000000000..2f48e612d7 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java @@ -0,0 +1,104 @@ +package org.biojava.nbio.structure.chem; + +import java.util.HashMap; +import java.util.Map; + +public class ChemicalComponentDictionary { + private final Map dictionary; + private final Map replaces; + private final Map isReplacedBy; + + public ChemicalComponentDictionary() { + this.dictionary = new HashMap<>(); + this.replaces = new HashMap<>(); + this.isReplacedBy = new HashMap<>(); + } + + public boolean isReplaced(ChemComp c) { + return isReplaced(c.getId()); + } + + public boolean isReplaced(String id) { + return isReplacedBy.containsKey(id); + } + + public boolean isReplacer(ChemComp c){ + return isReplacer(c.getId()); + } + + public boolean isReplacer(String id) { + return replaces.containsKey(id); + } + + /** if ChemComp is replaced by another one, get the newer version + * otherwise return the same ChemComp again. + * @param c + * @return get the component that replaced ChemComp. + */ + public ChemComp getReplacer(ChemComp c){ + return getReplacer(c.getId()); + } + + public ChemComp getReplacer(String id){ + if (isReplaced(id)) { + return dictionary.get(isReplacedBy.get(id)); + } + return dictionary.get(id); + } + + /** if ChemComp is replacing another one, get the old version + * otherwise return the same ChemComp again. + * @param c the ChemComp for which older versions should be looked up. + */ + public ChemComp getReplaced(ChemComp c){ + return getReplaced(c.getId()); + } + + public ChemComp getReplaced(String id){ + if (isReplacer(id)) { + return dictionary.get(replaces.get(id)); + } + return dictionary.get(id); + } + + /** + * Get the parent of a component. If component has no parent, return null + * @param c + * @return get the parent component or null if ChemComp has no parent. + */ + public ChemComp getParent(ChemComp c) { + if (c.hasParent()) { + return dictionary.get(c.getMonNstdParentCompId()); + } + return null; + } + + /** + * Add a new component to the dictionary + * @param comp + */ + public void addChemComp(ChemComp comp) { + dictionary.put(comp.getId(), comp); + String rep = comp.getPdbxReplaces(); + if (rep != null && !rep.equals("?")) { + replaces.put(comp.getId(), rep); + } + + String isRep = comp.getPdbxReplacedBy(); + if (isRep != null && !isRep.equals("?")) { + isReplacedBy.put(comp.getId(), isRep); + } + } + + /** + * Returns the number of ChemComps in this dictionary + * @return nr. of ChemComps + */ + public int size(){ + return dictionary.size(); + } + + public ChemComp getChemComp(String id){ + return dictionary.get(id); + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java new file mode 100644 index 0000000000..5b52bcab52 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java @@ -0,0 +1,420 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.core.util.InputStreamProvider; +import org.biojava.nbio.structure.align.util.URLConnectionTools; +import org.biojava.nbio.structure.align.util.UserConfiguration; +import org.biojava.nbio.structure.io.LocalPDBDirectory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.zip.GZIPOutputStream; + +/** + * This provider of chemical components can download and cache chemical component definition files from the RCSB PDB web + * site. It is the default way to access these definitions. If this provider is called he first time, it will download + * and install all chemical component definitions in a local directory. Once the definition files have been installed, + * it has quick startup time and low memory requirements. + * + * An alternative provider, that keeps all definitions in memory is the {@link AllChemCompProvider}. Another provider, + * that does not require any network access, but only can support a limited set of chemical component definitions, is + * the {@link ReducedChemCompProvider}. + * + * @author Andreas Prlic + */ +public class DownloadChemCompProvider implements ChemCompProvider { + private static final Logger logger = LoggerFactory.getLogger(DownloadChemCompProvider.class); + public static final String CHEM_COMP_CACHE_DIRECTORY = "chemcomp"; + public static final String DEFAULT_SERVER_URL = "http://files.rcsb.org/ligands/download/"; + public static String serverBaseUrl = DEFAULT_SERVER_URL; + + /** + * Use default RCSB server layout (true) or internal RCSB server layout (false) + */ + public static boolean useDefaultUrlLayout = true; + + private static File path; + private static final String NEWLINE = System.getProperty("line.separator"); + + // flags to make sure there is only one thread running that is loading the dictionary + static AtomicBoolean loading = new AtomicBoolean(false); + + static final List protectedIDs = new ArrayList<>(); + static { + protectedIDs.add("CON"); + protectedIDs.add("PRN"); + protectedIDs.add("AUX"); + protectedIDs.add("NUL"); + } + + private static ChemCompProvider fallback = null; // Fallback provider if the download fails + /** + * by default we will download only some of the files. User has to request that all files should be downloaded... + */ + boolean downloadAll = false; + + public DownloadChemCompProvider() { + this(null); + } + + public DownloadChemCompProvider(String cacheFilePath) { + logger.debug("Initialising DownloadChemCompProvider"); + + // note that path is static, so this is just to make sure that all non-static methods will have path initialised + if (cacheFilePath != null) { + path = new File(cacheFilePath); + } + } + + /** + * Get this provider's cache path + * @return + */ + public static File getPath(){ + if (path == null) { + UserConfiguration config = new UserConfiguration(); + path = new File(config.getCacheFilePath()); + } + return path; + } + + /** + * Checks if the chemical components already have been installed into the PDB directory. + * If not, will download the chemical components definitions file and split it up into small + * subfiles. + */ + public void checkDoFirstInstall(){ + if (!downloadAll) { + return; + } + + // this makes sure there is a file separator between every component, + // if path has a trailing file separator or not, it will work for both cases + File dir = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); + File f = new File(dir, "components.cif.gz"); + + if (!f.exists()) { + downloadAllDefinitions(); + } else { + // file exists.. did it get extracted? + FilenameFilter filter = (dir1, file) -> file.endsWith(".cif.gz"); + String[] files = dir.list(filter); + if (files.length < 500) { + // not all did get unpacked + try { + split(); + } catch (IOException e) { + logger.error("Could not split file {} into individual chemical component files. Error: {}", + f.toString(), e.getMessage()); + } + } + } + } + + private void split() throws IOException { + logger.info("Installing individual chem comp files ..."); + + File dir = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); + File f = new File(dir, "components.cif.gz"); + + int counter = 0; + InputStreamProvider prov = new InputStreamProvider(); + + try (BufferedReader buf = new BufferedReader(new InputStreamReader(prov.getInputStream(f)))) { + String line; + line = buf.readLine(); + StringWriter writer = new StringWriter(); + + String currentID = null; + while (line != null) { + if (line.startsWith("data_")) { + // a new record found! + if (currentID != null) { + writeID(writer.toString(), currentID); + counter++; + } + + currentID = line.substring(5); + writer = new StringWriter(); + } + + writer.append(line); + writer.append(NEWLINE); + + line = buf.readLine (); + } + + // write the last record... + writeID(writer.toString(), currentID); + counter++; + } + + logger.info("Created " + counter + " chemical component files."); + } + + /** + * Output chemical contents to a file + * @param contents File contents + * @param currentID Chemical ID, used to determine the filename + * @throws IOException + */ + private void writeID(String contents, String currentID) throws IOException { + String localName = getLocalFileName(currentID); + + try (PrintWriter pw = new PrintWriter(new GZIPOutputStream(new FileOutputStream(localName)))) { + pw.print(contents); + pw.flush(); + } + } + + /** + * Loads the definitions for this {@link ChemComp} from a local file and instantiates a new object. + * + * @param recordName the ID of the {@link ChemComp} + * @return a new {@link ChemComp} definition. + */ + @Override + public ChemComp getChemComp(String recordName) { + // make sure we work with upper case records + recordName = recordName.toUpperCase().trim(); + + boolean haveFile = true; + if (recordName.equals("?")) { + return null; + } + + if (fileIsAbsent(recordName)) { + // check if we should install all components + checkDoFirstInstall(); + } + if (fileIsAbsent(recordName)) { + // we previously have installed already the definitions, + // just do an incrememntal update + haveFile = downloadChemCompRecord(recordName); + } + + // Added check that download was successful and chemical component is available. + if (haveFile) { + String filename = getLocalFileName(recordName); + InputStream inStream = null; + try { + InputStreamProvider isp = new InputStreamProvider(); + inStream = isp.getInputStream(filename); + + MMcifParser parser = new SimpleMMcifParser(); + ChemCompConsumer consumer = new ChemCompConsumer(); + + // The Consumer builds up the BioJava - structure object. + // you could also hook in your own and build up you own data model. + parser.addMMcifConsumer(consumer); + parser.parse(new BufferedReader(new InputStreamReader(inStream))); + + ChemicalComponentDictionary dict = consumer.getDictionary(); + ChemComp chemComp = dict.getChemComp(recordName); + + // May be null if the file was corrupt. Fall back on ReducedChemCompProvider in that case + if (chemComp != null) { + return chemComp; + } + } catch (IOException e) { + logger.warn("Could not download chemical component file {} for {}. Error: {}. Now trying to use the " + + "local chemical component definitions.", + filename, recordName, e.getMessage()); + } finally { + // Now close it + if (inStream != null) { + try { + inStream.close(); + } catch (IOException e) { + // This would be weird... + logger.error("Could not close chemical component file {}. A resource leak could occur!!", filename); + } + } + } + } + + // see https://github.com/biojava/biojava/issues/315 + // probably a network error happened. Try to use the ReducedChemCOmpProvider + if (fallback == null) { + fallback = new ReducedChemCompProvider(); + } + + logger.warn("Falling back to ReducedChemCompProvider for {}. This could indicate a network error.", recordName); + return fallback.getChemComp(recordName); + + } + + /** + * Returns the file name that contains the definition for this {@link ChemComp} + * + * @param recordName the ID of the {@link ChemComp} + * @return full path to the file + */ + public static String getLocalFileName(String recordName) { + if (protectedIDs.contains(recordName)) { + recordName = "_" + recordName; + } + + File f = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); + if (!f.exists()) { + logger.info("Creating directory " + f); + boolean success = f.mkdir(); + // we've checked in initPath that path is writable, so there's no need to check if it succeeds + // in the unlikely case that in the meantime it isn't writable at least we log an error + if (!success) { + logger.error("Directory {} could not be created", f); + } + } + + File theFile = new File(f,recordName + ".cif.gz"); + return theFile.toString(); + } + + private static boolean fileIsAbsent(String recordName){ + String fileName = getLocalFileName(recordName); + File f = new File(fileName); + + // delete files that are too short to have contents + if (f.length() < LocalPDBDirectory.MIN_PDB_FILE_SIZE) { + // Delete defensively. + // Note that if delete is unsuccessful, we re-download the file anyways + f.delete(); + return true; + } + + return !f.exists(); + } + + /** + * @param recordName three-letter name + * @return true if successful download + */ + private static boolean downloadChemCompRecord(String recordName) { + String localName = getLocalFileName(recordName); + File newFile; + try { + newFile = File.createTempFile("chemcomp" + recordName, "cif"); + logger.debug("Will write chem comp file to temp file {}", newFile.toString()); + } catch (IOException e) { + logger.error("Could not write to temp directory {} to create the chemical component download temp file", + System.getProperty("java.io.tmpdir")); + return false; + } + String u; + if (useDefaultUrlLayout) { + u = serverBaseUrl + recordName + ".cif"; + } else { + u = serverBaseUrl + recordName.charAt(0) + "/" + recordName +"/" + recordName + ".cif"; + } + + logger.debug("downloading " + u); + URL url = null; + try { + url = new URL(u); + URLConnection uconn = URLConnectionTools.openURLConnection(url); + + try (PrintWriter pw = new PrintWriter(new GZIPOutputStream(new FileOutputStream(newFile))); + BufferedReader fileBuffer = new BufferedReader(new InputStreamReader(uconn.getInputStream()))) { + + String line; + while ((line = fileBuffer.readLine()) != null) { + pw.println(line); + } + pw.flush(); + } + // Now we move this across to where it actually wants to be + Files.move(newFile.toPath(), Paths.get(localName), StandardCopyOption.REPLACE_EXISTING); + + return true; + } catch (IOException e) { + logger.error("Could not download " + url.toString() + " OR store locally to " + localName + " Error =" + e.getMessage()); + newFile.delete(); + } + return false; + } + + private void downloadAllDefinitions() { + if (loading.get()) { + logger.info("Waiting for other thread to install chemical components..."); + } + + while (loading.get()) { + // another thread is already downloading the components definitions + // wait for the other thread to finish... + try { + // wait half a second + Thread.sleep(500); + } catch (InterruptedException e) { + //e.printStackTrace(); + logger.error("Thread interrupted "+e.getMessage()); + } + + logger.info("Another thread installed the chemical components."); + return; + } + + loading.set(true); + long timeS = System.currentTimeMillis(); + + logger.info("Performing first installation of chemical components."); + logger.info("Downloading components.cif.gz ..."); + + try { + AllChemCompProvider.downloadFile(); + } catch (IOException e) { + logger.error("Could not download the all chemical components file. Error: {}. " + + "Chemical components information won't be available", e.getMessage()); + // no point in trying to split if the file could not be downloaded + loading.set(false); + return; + } + + try { + split(); + } catch (IOException e) { + logger.error("Could not split all chem comp file into individual chemical component files. Error: {}", + e.getMessage()); + // no point in reporting time + loading.set(false); + return; + } + + long timeE = System.currentTimeMillis(); + logger.info("time to install chem comp dictionary: " + (timeE - timeS) / 1000 + " sec."); + loading.set(false); + } + + /** + * By default this provider will download only some of the {@link ChemComp} files. + * The user has to request that all files should be downloaded by setting this parameter to true. + * @return flag if the all components should be downloaded and installed at startup. (default: false) + */ + public boolean isDownloadAll() { + return downloadAll; + } + + /** + * By default this provider will download only some of the {@link ChemComp} files. + * The user has to request that all files should be downloaded by setting this parameter to true. + * @param downloadAll if the all components should be downloaded and installed at startup. (default: false) + */ + public void setDownloadAll(boolean downloadAll) { + this.downloadAll = downloadAll; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/PolymerType.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/PolymerType.java new file mode 100644 index 0000000000..78bae77f86 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/PolymerType.java @@ -0,0 +1,161 @@ +package org.biojava.nbio.structure.chem; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Enumerates the classification of polymers. + * This information is derived from the mmcif dictionary + * @author mulvaney + * @author Andreas Prlic + * @see link into mmCIF dictionary + * @since 1.7 + */ +public enum PolymerType implements Serializable { + /** + * polypeptide(L) + */ + peptide("polypeptide(L)"), + /** + * polypeptide(D) + */ + dpeptide("polypeptide(D)"), + /** + * polydeoxyribonucleotide + */ + dna("polydeoxyribonucleotide"), + /** + * polyribonucleotide + */ + rna("polyribonucleotide"), + /** + * polydeoxyribonucleotide/polyribonucleotide hybrid + */ + dnarna("polydeoxyribonucleotide/polyribonucleotide hybrid"), + /** + * polysaccharide(D) + */ + polysaccharide("polysaccharide(D)"), + /** + * polysaccharide(L) + */ + lpolysaccharide("polysaccharide(L)"), + /** + * other + */ + otherPolymer("other"), + /** + * cyclic peptides + */ + cyclicPeptide("cyclic-pseudo-peptide"), + /** + * Peptide nucleic acids + */ + peptideNucleicAcid("peptide nucleic acid"), + /** + * if all else fails... + */ + unknown(null); + + static Map lookupTable = new HashMap<>(); + + static { + for (PolymerType polymerType : PolymerType.values()) { + if (polymerType == unknown) { + continue; + } + + lookupTable.put(polymerType.entity_poly_type,polymerType); + lookupTable.put(polymerType.entity_poly_type.toLowerCase(), polymerType); + } + } + + public final String entity_poly_type; + + PolymerType(String entity_poly_type) { + this.entity_poly_type = entity_poly_type; + } + + public static PolymerType polymerTypeFromString(String polymerTypeString) { + if (polymerTypeString.equalsIgnoreCase(peptide.entity_poly_type)) { + return peptide; + } + + PolymerType lookedUpPolymerType = lookupTable.get(polymerTypeString); + if (lookedUpPolymerType != null) { + return lookedUpPolymerType; + } + + lookedUpPolymerType = lookupTable.get(polymerTypeString.toLowerCase()); + if (lookedUpPolymerType != null) { + return lookedUpPolymerType; + } + + for (PolymerType polymerType : PolymerType.values()) { + if (polymerTypeString.equals(polymerType.entity_poly_type)) { + return polymerType; + } + } + + return unknown; + } + + /** + * Convenience Set of polymer types classified as protein. This only contains {@link #peptide} + */ + public static final Set PROTEIN_ONLY; + + /** + * Convenience Set of polymer types classified as DNA. This only contains {@link #dna} + */ + public static final Set DNA_ONLY; + + /** + * Convenience Set of polymer types classified as RNA. This only contains {@link #rna} + */ + public static final Set RNA_ONLY; + + /** + * Convenience Set of polymer types classified as DNA. This contains: + *

        + *
      • {@link #dna}
      • + *
      • {@link #rna}
      • + *
      • {@link #dnarna}
      • + *
      + */ + public static final Set POLYNUCLEOTIDE_ONLY; + + /** + * Convenience Set of all polymer types. + */ + public static final Set ALL_POLYMER_TYPES; + + static { + Set tmp; + + tmp = new HashSet<>(); + tmp.add(peptide); + PROTEIN_ONLY = Collections.unmodifiableSet(tmp); + + tmp = new HashSet<>(); + tmp.add(dna); + DNA_ONLY = Collections.unmodifiableSet(tmp); + + tmp = new HashSet<>(); + tmp.add(rna); + RNA_ONLY = Collections.unmodifiableSet(tmp); + + tmp = new HashSet<>(); + tmp.add(dna); + tmp.add(rna); + tmp.add(dnarna); + POLYNUCLEOTIDE_ONLY = Collections.unmodifiableSet(tmp); + + ALL_POLYMER_TYPES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(values()))); + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java new file mode 100644 index 0000000000..9841fdc161 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java @@ -0,0 +1,56 @@ +package org.biojava.nbio.structure.chem; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.zip.GZIPInputStream; + +/** + * Unlike the {@link DownloadChemCompProvider}, this {@link ChemCompProvider} does not download any chem comp + * definitions. It has access to a limited set of files that are part of the biojava distribution. + * @author Andreas Prlic + * @since 3.0 + */ +public class ReducedChemCompProvider implements ChemCompProvider { + private static final Logger logger = LoggerFactory.getLogger(ReducedChemCompProvider.class); + + public ReducedChemCompProvider(){ + logger.debug("Initialising ReducedChemCompProvider"); + } + + @Override + public ChemComp getChemComp(String recordName) { + String name = recordName.toUpperCase().trim(); + try (InputStream inStream = this.getClass().getResourceAsStream("/chemcomp/" + name + ".cif.gz")) { + logger.debug("Reading chemcomp/{}.cif.gz", name); + + if (inStream == null) { + // could not find the chem comp definition for this in the jar file + logger.debug("Getting empty chem comp for {}", name); + ChemComp cc = ChemComp.getEmptyChemComp(); + cc.setId(name); + return cc; + } + + MMcifParser parser = new SimpleMMcifParser(); + ChemCompConsumer consumer = new ChemCompConsumer(); + // The Consumer builds up the BioJava - structure object. + // you could also hook in your own and build up you own data model. + parser.addMMcifConsumer(consumer); + parser.parse(new BufferedReader(new InputStreamReader(new GZIPInputStream(inStream)))); + + ChemicalComponentDictionary dict = consumer.getDictionary(); + return dict.getChemComp(name); + } catch (IOException e){ + logger.error("IOException caught while reading chem comp {}.", name, e); + } + logger.warn("Problem when loading chem comp {}, will use an empty chem comp for it", name); + ChemComp cc = ChemComp.getEmptyChemComp(); + cc.setId(name); + return cc; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ResidueType.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ResidueType.java new file mode 100644 index 0000000000..ddcaac453c --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ResidueType.java @@ -0,0 +1,125 @@ +package org.biojava.nbio.structure.chem; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * Enumerates the possible classifications of residues. These are generally more specific than PolymerTypes + * This information is derived from the mmcif dictionary. + * @author mulvaney + * @author Andreas Prlic + * @see link into mmCIF dictionary + * @since 1.7 + */ +public enum ResidueType implements Serializable { + atomn(null, "null"), // present in db for _chem_comp.id_ = 'CFL' but not enumerated in dictionary + // Peptides + dPeptideLinking(PolymerType.dpeptide, "D-peptide linking"), + lPeptideLinking(PolymerType.peptide, "L-peptide linking"), + glycine(PolymerType.peptide,"PEPTIDE LINKING"), + peptideLike(PolymerType.otherPolymer, "peptide-like"), + dPeptideAminoTerminus(PolymerType.dpeptide, "D-peptide NH3 amino terminus"), + lPeptideAminoTerminus(PolymerType.peptide, "L-peptide NH3 amino terminus"), + dPeptideCarboxyTerminus(PolymerType.dpeptide, "D-peptide COOH carboxy terminus"), + lPeptideCarboxyTerminus(PolymerType.peptide, "L-peptide COOH carboxy terminus"), + // Nucleotides + dnaLinking(PolymerType.dna, "DNA linking"), + rnaLinking(PolymerType.rna, "RNA linking"), + dna3PrimeTerminus(PolymerType.dna, "DNA OH 3 prime terminus"), + rna3PrimeTerminus(PolymerType.rna, "RNA OH 3 prime terminus"), + dna5PrimeTerminus(PolymerType.dna, "DNA OH 5 prime terminus"), + rna5PrimeTerminus(PolymerType.rna, "RNA OH 5 prime terminus"), + // Sugars + dSaccharide(PolymerType.polysaccharide, "D-saccharide"), + dSaccharide14and14linking(PolymerType.polysaccharide, "D-saccharide 1,4 and 1,4 linking"), + dSaccharide14and16linking(PolymerType.polysaccharide, "D-saccharide 1,4 and 1,6 linking"), + lSaccharide(PolymerType.lpolysaccharide, "L-saccharide"), + lSaccharide14and14linking(PolymerType.lpolysaccharide, "L-saccharide 1,4 and 1,4 linking"), + lSaccharide14and16linking(PolymerType.lpolysaccharide, "L-saccharide 1,4 and 1,6 linking"), + saccharide(PolymerType.polysaccharide, "saccharide"), + // Iso-peptides + dBetaPeptideCGammaLinking(PolymerType.dpeptide,"D-beta-peptide, C-gamma linking"), + dGammaPeptideCDeltaLinking(PolymerType.dpeptide,"D-gamma-peptide, C-delta linking"), + lBetaPeptideCGammaLinking(PolymerType.peptide,"L-beta-peptide, C-gamma linking"), + lGammaPeptideCDeltaLinking(PolymerType.peptide,"L-gamma-peptide, C-delta linking"), + // L nucleotides. As of 2015-04, these are only found in D-DNA hybrids, so they don't have their own PolymerType + lDNALinking(PolymerType.dna,"L-DNA linking"), + lRNALinking(PolymerType.dna,"L-RNA linking"), + // Other + nonPolymer(null, "non-polymer"), + otherChemComp(null, "other"); + + static Map lookupTable = new HashMap<>(); + + static { + for (ResidueType residueType : ResidueType.values() ) { + lookupTable.put(residueType.chem_comp_type, residueType); + lookupTable.put(residueType.chem_comp_type.toLowerCase(), residueType); + } + } + + ResidueType(PolymerType polymerType, String chem_comp_type) { + this.polymerType = polymerType; + this.chem_comp_type = chem_comp_type; + } + + /** + * The associated {@link PolymerType} + */ + public final PolymerType polymerType; + + /** + * Gets the associated PolymerType, which are less specific + * @return + */ + public PolymerType getPolymerType() { + return polymerType; + } + + /** + * String value of the type + */ + public final String chem_comp_type; + + /** Get ResidueType by chem_comp_type + * + * @param chem_comp_type e.g. L-peptide linking + * @return + */ + public static ResidueType getResidueTypeFromString(String chem_comp_type) { + // Almost all calls to this method are for L-peptide linking. Use this knowledge for a shortcut. + if (chem_comp_type.equalsIgnoreCase(lPeptideLinking.chem_comp_type)) { + return lPeptideLinking; + } + + ResidueType lookedUpResidueType = lookupTable.get(chem_comp_type); + if (lookedUpResidueType != null) { + return lookedUpResidueType; + } + + /* + * Unfortunately it can be guaranteed that chem_comp_type case sensitivity is preserved. + * E.g. mmtf has it all upper-case. As such we need to do a second check + */ + lookedUpResidueType = lookupTable.get(chem_comp_type.toLowerCase()); + if (lookedUpResidueType != null) { + return lookedUpResidueType; + } + + // preserving previous behaviour. Not sure if this is really necessary? + for (ResidueType residueType : ResidueType.values()) { + if(residueType.chem_comp_type.equalsIgnoreCase(chem_comp_type)) { + return residueType; + } + + if (residueType.chem_comp_type.toLowerCase().startsWith(chem_comp_type.toLowerCase())) { + return residueType; + } + if (chem_comp_type.toLowerCase().startsWith(residueType.chem_comp_type.toLowerCase())) { + return residueType; + } + } + return null; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java index 40953a1ee2..b8e10ffbb8 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java @@ -36,13 +36,10 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.asa.AsaCalculator; import org.biojava.nbio.structure.asa.GroupAsa; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.io.FileConvert; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.MMCIFFileTools; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.model.AtomSite; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; import org.biojava.nbio.structure.xtal.CrystalTransform; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java index bb92724aa4..aee22b0767 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java @@ -23,12 +23,9 @@ package org.biojava.nbio.structure.io; import org.biojava.nbio.structure.*; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.ChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompBond; -import org.biojava.nbio.structure.io.mmcif.model.StructConn; import org.biojava.nbio.structure.io.util.PDBTemporaryStorageUtils.LinkRecord; +import org.rcsb.cif.model.ValueKind; +import org.rcsb.cif.schema.mm.StructConn; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,8 +50,6 @@ * */ public class BondMaker { - - private static final Logger logger = LoggerFactory.getLogger(BondMaker.class); /** @@ -366,41 +361,44 @@ public void formLinkRecordBond(LinkRecord linkRecord) { } - public void formBondsFromStructConn(List structConn) { - + public void formBondsFromStructConn(StructConn conn) { final String symop = "1_555"; // For now - accept bonds within origin asymmetric unit. - List ssbonds = new ArrayList<>(); - for (StructConn conn : structConn) { - - if (!BOND_TYPES_TO_PARSE.contains(conn.getConn_type_id())) continue; + for (int i = 0; i < conn.getRowCount(); i++) { + if (!BOND_TYPES_TO_PARSE.contains(conn.getConnTypeId().get(i))) continue; String chainId1; String chainId2; - chainId1 = conn.getPtnr1_label_asym_id(); - chainId2 = conn.getPtnr2_label_asym_id(); + chainId1 = conn.getPtnr1LabelAsymId().get(i); + chainId2 = conn.getPtnr2LabelAsymId().get(i); String insCode1 = ""; - if (conn.getPdbx_ptnr1_PDB_ins_code() != null && - !conn.getPdbx_ptnr1_PDB_ins_code().equals("?")) insCode1 = conn.getPdbx_ptnr1_PDB_ins_code(); + if (conn.getPdbxPtnr1PDBInsCode().getValueKind(i) == ValueKind.PRESENT) { + insCode1 = conn.getPdbxPtnr1PDBInsCode().get(i); + } String insCode2 = ""; - if (conn.getPdbx_ptnr2_PDB_ins_code() != null && - !conn.getPdbx_ptnr2_PDB_ins_code().equals("?")) insCode2 = conn.getPdbx_ptnr2_PDB_ins_code(); - - String seqId1 = conn.getPtnr1_auth_seq_id(); - String seqId2 = conn.getPtnr2_auth_seq_id(); - String resName1 = conn.getPtnr1_label_comp_id(); - String resName2 = conn.getPtnr2_label_comp_id(); - String atomName1 = conn.getPtnr1_label_atom_id(); - String atomName2 = conn.getPtnr2_label_atom_id(); + if (conn.getPdbxPtnr2PDBInsCode().getValueKind(i) == ValueKind.PRESENT) { + insCode2 = conn.getPdbxPtnr2PDBInsCode().get(i); + } + + String seqId1 = conn.getPtnr1AuthSeqId().getStringData(i); + String seqId2 = conn.getPtnr2AuthSeqId().getStringData(i); + String resName1 = conn.getPtnr1LabelCompId().get(i); + String resName2 = conn.getPtnr2LabelCompId().get(i); + String atomName1 = conn.getPtnr1LabelAtomId().get(i); + String atomName2 = conn.getPtnr2LabelAtomId().get(i); String altLoc1 = ""; - if (!conn.getPdbx_ptnr1_label_alt_id().equals("?")) altLoc1 = conn.getPdbx_ptnr1_label_alt_id(); + if (conn.getPdbxPtnr1LabelAltId().getValueKind(i) == ValueKind.PRESENT) { + altLoc1 = conn.getPdbxPtnr1LabelAltId().get(i); + } String altLoc2 = ""; - if (!conn.getPdbx_ptnr2_label_alt_id().equals("?")) altLoc2 = conn.getPdbx_ptnr2_label_alt_id(); + if (conn.getPdbxPtnr2LabelAltId().getValueKind(i) == ValueKind.PRESENT) { + altLoc2 = conn.getPdbxPtnr2LabelAltId().get(i); + } // TODO: when issue 220 is implemented, add robust symmetry handling to allow bonds between symmetry-related molecules. - if (!conn.getPtnr1_symmetry().equals(symop) || !conn.getPtnr2_symmetry().equals(symop) ) { + if (!conn.getPtnr1Symmetry().get(i).equals(symop) || !conn.getPtnr2Symmetry().get(i).equals(symop) ) { logger.info("Skipping bond between atoms {}(residue {}{}) and {}(residue {}{}) belonging to different symmetry partners, because it is not supported yet", atomName1, seqId1, insCode1, atomName2, seqId2, insCode2); continue; @@ -441,20 +439,19 @@ public void formBondsFromStructConn(List structConn) { } // assuming order 1 for all bonds, no information is provided by struct_conn - for(int i=0; i list = MMCIFFileTools.convertStructureToAtomSites(structure); - - - str.append(MMCIFFileTools.toMMCIF(list,AtomSite.class)); - - return str.toString(); + public static String toMMCIF(Chain chain, String authId, String asymId) { + return CifFileConverter.toText(chain, authId, asymId); } - public static String toMMCIF(Chain chain, String authId, String asymId, boolean writeHeader) { - StringBuilder str = new StringBuilder(); - - if (writeHeader) - str.append(getAtomSiteHeader()); - - - List list = MMCIFFileTools.convertChainToAtomSites(chain, 1, authId, asymId); - - str.append(MMCIFFileTools.toMMCIF(list,AtomSite.class)); - return str.toString(); - } - - public static String toMMCIF(Chain chain, boolean writeHeader) { - StringBuilder sb = new StringBuilder(); - sb.append(SimpleMMcifParser.MMCIF_TOP_HEADER+"BioJava_mmCIF_file"+newline); - sb.append(toMMCIF(chain, chain.getName(), chain.getId(),writeHeader)); - return sb.toString(); - } - - public static String getAtomSiteHeader() { - String header; - try { - header = MMCIFFileTools.toLoopMmCifHeaderString("_atom_site", AtomSite.class.getName()); - - } catch (ClassNotFoundException e) { - logger.error("Class not found, will not have a header for this MMCIF category: "+e.getMessage()); - header = ""; - } - - return header; + public static String toMMCIF(Chain chain) { + return CifFileConverter.toText(chain); } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/MMCIFFileReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/MMCIFFileReader.java deleted file mode 100644 index ca91f8d70d..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/MMCIFFileReader.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Oct 18, 2008 - */ -package org.biojava.nbio.structure.io; - -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.mmcif.MMcifParser; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - - -/** How to parse an mmCif file: - *
      -public static void main(String[] args) throws Exception {
      -	String filename =  "/path/to/something.cif.gz" ;
      -
      -	StructureIOFile reader = new MMCIFFileReader();
      -
      -	Structure struc = reader.getStructure(filename);
      -	System.out.println(struc);
      -}
      -
      - * - * @author Andreas Prlic - * @since 1.7 - * - */ -public class MMCIFFileReader extends LocalPDBDirectory { - - //private static final Logger logger = LoggerFactory.getLogger(MMCIFFileReader.class); - - public static final String[] MMCIF_SPLIT_DIR = new String[]{"data","structures","divided" ,"mmCIF"}; - public static final String[] MMCIF_OBSOLETE_DIR = new String[]{"data","structures","obsolete","mmCIF"}; - - private SimpleMMcifConsumer consumer; - - public static void main(String[] args) throws Exception { - - MMCIFFileReader reader = new MMCIFFileReader(); - FileParsingParameters params = new FileParsingParameters(); - reader.setFileParsingParameters(params); - - - Structure struc = reader.getStructureById("1m4x"); - System.out.println(struc); - System.out.println(struc.toPDB()); - - - } - - /** - * Constructs a new MMCIFFileReader, initializing the extensions member variable. - * The path is initialized in the same way as {@link UserConfiguration}, - * i.e. to system property/environment variable {@link UserConfiguration#PDB_DIR}. - * Both autoFetch and splitDir are initialized to false - */ - public MMCIFFileReader(){ - this(null); - } - - /** - * Constructs a new PDBFileReader, initializing the extensions member variable. - * The path is initialized to the given path, both autoFetch and splitDir are initialized to false. - */ - public MMCIFFileReader(String path){ - super(path); - addExtension(".cif"); - addExtension(".mmcif"); - addExtension(".cif.gz"); - addExtension(".mmcif.gz"); - } - - @Override - public Structure getStructure(InputStream inStream) throws IOException{ - - MMcifParser parser = new SimpleMMcifParser(); - - consumer = new SimpleMMcifConsumer(); - - consumer.setFileParsingParameters(getFileParsingParameters()); - - - // The Consumer builds up the BioJava - structure object. - // you could also hook in your own and build up you own data model. - parser.addMMcifConsumer(consumer); - - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - - - // now get the protein structure. - Structure cifStructure = consumer.getStructure(); - - return cifStructure; - } - - public SimpleMMcifConsumer getMMcifConsumer(){ - return consumer; - } - -// public void setMMCifConsumer(SimpleMMcifConsumer consumer){ -// this.consumer = consumer; -// } - - @Override - protected String getFilename(String pdbId) { - return pdbId.toLowerCase()+".cif.gz"; - } - - @Override - protected String[] getSplitDirPath() { - return MMCIF_SPLIT_DIR; - } - - @Override - protected String[] getObsoleteDirPath() { - return MMCIF_OBSOLETE_DIR; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplierImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java similarity index 84% rename from biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplierImpl.java rename to biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java index 6b39cf9c58..0c039467c1 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplierImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java @@ -20,7 +20,6 @@ import org.rcsb.cif.schema.mm.MmCifCategoryBuilder; import org.rcsb.cif.schema.mm.MmCifFileBuilder; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -28,13 +27,12 @@ import java.util.stream.Collector; /** - * Convert a BioJava {@link Structure} to a CifFile. + * Convert a BioJava object to a CifFile. * @author Sebastian Bittrich * @since 5.3.0 */ -class CifFileSupplierImpl implements CifFileSupplier { - @Override - public CifFile get(Structure structure) { +public abstract class AbstractCifFileSupplier implements CifFileSupplier { + protected CifFile getInternal(Structure structure, List wrappedAtoms) { // for now BioJava only considered 3 categories for create a Cif representation of a structure // cell @@ -42,7 +40,6 @@ public CifFile get(Structure structure) { // symmetry SpaceGroup spaceGroup = structure.getPDBHeader().getCrystallographicInfo().getSpaceGroup(); // atom_site - List wrappedAtoms = collectWrappedAtoms(structure); Category atomSite = wrappedAtoms.stream().collect(toAtomSite()); MmCifBlockBuilder blockBuilder = CifBuilder.enterFile(StandardSchemata.MMCIF) @@ -94,49 +91,40 @@ public CifFile get(Structure structure) { return blockBuilder.leaveBlock().leaveFile(); } - private static List collectWrappedAtoms(Structure structure) { - List wrappedAtoms = new ArrayList<>(); - - for (int modelIndex = 0; modelIndex < structure.nrModels(); modelIndex++) { - final int model = modelIndex + 1; - for (Chain chain : structure.getChains(modelIndex)) { - final String chainName = chain.getName(); - final String chainId = chain.getId(); - for (Group group : chain.getAtomGroups()) { - // The alt locs can have duplicates, since at parsing time we make sure that all alt loc groups have - // all atoms (see StructureTools#cleanUpAltLocs) - // Thus we have to remove duplicates here by using the atom id - // See issue https://github.com/biojava/biojava/issues/778 and - // TestAltLocs.testMmcifWritingAllAltlocs/testMmcifWritingPartialAltlocs - Map uniqueAtoms = new LinkedHashMap<>(); - for (int atomIndex = 0; atomIndex < group.size(); atomIndex++) { - Atom atom = group.getAtom(atomIndex); + protected void handleChain(Chain chain, int model, List wrappedAtoms) { + final String chainName = chain.getName(); + final String chainId = chain.getId(); + for (Group group : chain.getAtomGroups()) { + // The alt locs can have duplicates, since at parsing time we make sure that all alt loc groups have + // all atoms (see StructureTools#cleanUpAltLocs) + // Thus we have to remove duplicates here by using the atom id + // See issue https://github.com/biojava/biojava/issues/778 and + // TestAltLocs.testMmcifWritingAllAltlocs/testMmcifWritingPartialAltlocs + Map uniqueAtoms = new LinkedHashMap<>(); + for (int atomIndex = 0; atomIndex < group.size(); atomIndex++) { + Atom atom = group.getAtom(atomIndex); + if (atom == null) { + continue; + } + + uniqueAtoms.put(atom.getPDBserial(), new WrappedAtom(chain, model, chainName, chainId, atom, atom.getPDBserial())); + } + + if (group.hasAltLoc()) { + for (Group alt : group.getAltLocs()) { + for (int atomIndex = 0; atomIndex < alt.size(); atomIndex++) { + Atom atom = alt.getAtom(atomIndex); if (atom == null) { continue; } uniqueAtoms.put(atom.getPDBserial(), new WrappedAtom(chain, model, chainName, chainId, atom, atom.getPDBserial())); } - - if (group.hasAltLoc()) { - for (Group alt : group.getAltLocs()) { - for (int atomIndex = 0; atomIndex < alt.size(); atomIndex++) { - Atom atom = alt.getAtom(atomIndex); - if (atom == null) { - continue; - } - - uniqueAtoms.put(atom.getPDBserial(), new WrappedAtom(chain, model, chainName, chainId, atom, atom.getPDBserial())); - } - } - } - - wrappedAtoms.addAll(uniqueAtoms.values()); } } - } - return wrappedAtoms; + wrappedAtoms.addAll(uniqueAtoms.values()); + } } static class WrappedAtom { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChainSupplierImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChainSupplierImpl.java new file mode 100644 index 0000000000..08516d47b3 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChainSupplierImpl.java @@ -0,0 +1,20 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.Chain; +import org.rcsb.cif.model.CifFile; + +import java.util.ArrayList; +import java.util.List; + +public class ChainSupplierImpl extends AbstractCifFileSupplier { + @Override + public CifFile get(Chain container) { + return getInternal(container.getStructure(), collectWrappedAtoms(container)); + } + + private List collectWrappedAtoms(Chain chain) { + List wrappedAtoms = new ArrayList<>(); + handleChain(chain, 1, wrappedAtoms); + return wrappedAtoms; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java new file mode 100644 index 0000000000..c8553b21c7 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java @@ -0,0 +1,14 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.chem.ChemComp; +import org.rcsb.cif.schema.mm.ChemCompAtom; +import org.rcsb.cif.schema.mm.ChemCompBond; +import org.rcsb.cif.schema.mm.PdbxChemCompDescriptor; + +public interface ChemCompConsumer extends CifFileConsumer { + void consumeChemCompAtom(ChemCompAtom chemCompAtom); + + void consumeChemCompBond(ChemCompBond chemCompBond); + + void consumePdbxChemCompDescriptor(PdbxChemCompDescriptor pdbxChemCompDescriptor); +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java new file mode 100644 index 0000000000..f97a89d271 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java @@ -0,0 +1,70 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemicalComponentDictionary; +import org.biojava.nbio.structure.chem.ResidueType; +import org.rcsb.cif.schema.mm.ChemCompAtom; +import org.rcsb.cif.schema.mm.ChemCompBond; +import org.rcsb.cif.schema.mm.PdbxChemCompDescriptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ChemCompConsumerImpl implements ChemCompConsumer { + private static final Logger logger = LoggerFactory.getLogger(ChemCompConsumerImpl.class); + private ChemicalComponentDictionary dictionary; + private String latestChemCompId; + + public ChemCompConsumerImpl(){ + dictionary = new ChemicalComponentDictionary(); + } + + @Override + public void prepare() { + + } + + public ChemicalComponentDictionary getDictionary(){ + return dictionary; + } + + @Override + public void consumeChemCompAtom(ChemCompAtom chemCompAtom) { + dictionary.getChemComp(latestChemCompId).getAtoms().add(chemCompAtom); + } + + @Override + public void consumeChemCompBond(ChemCompBond chemCompBond) { + dictionary.getChemComp(latestChemCompId).getBonds().add(chemCompBond); + } + + @Override + public void consumePdbxChemCompDescriptor(PdbxChemCompDescriptor pdbxChemCompDescriptor) { + ChemComp cc = dictionary.getChemComp(latestChemCompId); + cc.getDescriptors().add(pdbxChemCompDescriptor); + } + + @Override + public void finish() { + + } + + @Override + public ChemComp getContainer() { + if (c.getId() == null) + logger.warn("chem comp ID == null " + c); + + latestChemCompId = c.getId(); + dictionary.addChemComp(c); + if (c.getResidueType() == ResidueType.nonPolymer) { + return; + } + + if (c.getResidueType() == ResidueType.saccharide) { + return; + } + + if (c.getResidueType() == ResidueType.dSaccharide) { + return; + } + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifBean.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifBean.java new file mode 100644 index 0000000000..1196aafada --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifBean.java @@ -0,0 +1,12 @@ +package org.biojava.nbio.structure.io.cif; + +import org.rcsb.cif.model.Category; + +import java.io.Serializable; + +/** + * Flag for BioJava beans that actually resemble categories defined by the mmCIF schema. + * @param the modeled ciftools-java category + */ +public interface CifBean extends Serializable { +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java index d15c9cc140..198f288305 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java @@ -1,5 +1,7 @@ package org.biojava.nbio.structure.io.cif; +import org.biojava.nbio.structure.chem.ChemCompAtom; +import org.biojava.nbio.structure.chem.ChemCompDescriptor; import org.rcsb.cif.schema.mm.AtomSite; import org.rcsb.cif.schema.mm.AtomSites; import org.rcsb.cif.schema.mm.AuditAuthor; @@ -53,282 +55,12 @@ * @author Sebastian Bittrich * @since 5.3.0 */ -interface CifFileConsumer { +public interface CifFileConsumer { /** * Setup routine which initializes a new container. */ void prepare(); - /** - * Consume a particular Cif category. - * @param atomSite data - */ - void consumeAtomSite(AtomSite atomSite); - - /** - * Consume a particular Cif category. - * @param atomSites data - */ - void consumeAtomSites(AtomSites atomSites); - - /** - * Consume a particular Cif category. - * @param auditAuthor data - */ - void consumeAuditAuthor(AuditAuthor auditAuthor); - - /** - * Consume a particular Cif category. - * @param cell data - */ - void consumeCell(Cell cell); - - /** - * Consume a particular Cif category. - * @param chemComp data - */ - void consumeChemComp(ChemComp chemComp); - - /** - * Consume a particular Cif category. - * @param chemCompBond data - */ - void consumeChemCompBond(ChemCompBond chemCompBond); - - /** - * Consume a particular Cif category. - * @param databasePDBremark data - */ - void consumeDatabasePDBremark(DatabasePDBRemark databasePDBremark); - - /** - * Consume a particular Cif category. - * @param databasePDBrev data - */ - void consumeDatabasePDBrev(DatabasePDBRev databasePDBrev); - - /** - * Consume a particular Cif category. - * @param databasePDBrevRecord data - */ - void consumeDatabasePDBrevRecord(DatabasePDBRevRecord databasePDBrevRecord); - - /** - * Consume a particular Cif category. - * @param entity data - */ - void consumeEntity(Entity entity); - - /** - * Consume a particular Cif category. - * @param entityPoly data - */ - void consumeEntityPoly(EntityPoly entityPoly); - - /** - * Consume a particular Cif category. - * @param entitySrcGen data - */ - void consumeEntitySrcGen(EntitySrcGen entitySrcGen); - - /** - * Consume a particular Cif category. - * @param entitySrcNat data - */ - void consumeEntitySrcNat(EntitySrcNat entitySrcNat); - - /** - * Consume a particular Cif category. - * @param entitySrcSyn data - */ - void consumeEntitySrcSyn(PdbxEntitySrcSyn entitySrcSyn); - - /** - * Consume a particular Cif category. - * @param entityPolySeq data - */ - void consumeEntityPolySeq(EntityPolySeq entityPolySeq); - - /** - * Consume a particular Cif category. - * @param exptl data - */ - void consumeExptl(Exptl exptl); - - /** - * Consume a particular Cif category. - * @param pdbxAuditRevisionHistory data - */ - void consumePdbxAuditRevisionHistory(PdbxAuditRevisionHistory pdbxAuditRevisionHistory); - - /** - * Consume a particular Cif category. - * @param pdbxChemCompIdentifier data - */ - void consumePdbxChemCompIdentifier(PdbxChemCompIdentifier pdbxChemCompIdentifier); - - /** - * Consume a particular Cif category. - * @param pdbxDatabaseStatus data - */ - void consumePdbxDatabaseStatus(PdbxDatabaseStatus pdbxDatabaseStatus); - - /** - * Consume a particular Cif category. - * @param pdbxEntityBranchDescriptor data - */ - void consumePdbxEntityBranchDescriptor(PdbxEntityBranchDescriptor pdbxEntityBranchDescriptor); - - /** - * Consume a particular Cif category. - * @param pdbxMolecule data - */ - void consumePdbxMolecule(PdbxMolecule pdbxMolecule); - - /** - * Consume a particular Cif category. - * @param pdbxMoleculeFeatures data - */ - void consumePdbxMoleculeFeatures(PdbxMoleculeFeatures pdbxMoleculeFeatures); - - /** - * Consume a particular Cif category. - * @param pdbxNonpolyScheme data - */ - void consumePdbxNonpolyScheme(PdbxNonpolyScheme pdbxNonpolyScheme); - - /** - * Consume a particular Cif category. - * @param pdbxReferenceEntityLink data - */ - void consumePdbxReferenceEntityLink(PdbxReferenceEntityLink pdbxReferenceEntityLink); - - /** - * Consume a particular Cif category. - * @param pdbxReferenceEntityList data - */ - void consumePdbxReferenceEntityList(PdbxReferenceEntityList pdbxReferenceEntityList); - - /** - * Consume a particular Cif category. - * @param pdbxReferenceEntityPolyLink data - */ - void consumePdbxReferenceEntityPolyLink(PdbxReferenceEntityPolyLink pdbxReferenceEntityPolyLink); - - /** - * Consume a particular Cif category. - * @param pdbxStructAssembly data - */ - void consumePdbxStructAssembly(PdbxStructAssembly pdbxStructAssembly); - - /** - * Consume a particular Cif category. - * @param pdbxStructAssemblyGen data - */ - void consumePdbxStructAssemblyGen(PdbxStructAssemblyGen pdbxStructAssemblyGen); - - /** - * Consume a particular Cif category. - * @param pdbxStructModResidue data - */ - void consumePdbxStructModResidue(PdbxStructModResidue pdbxStructModResidue); - - /** - * Consume a particular Cif category. - * @param pdbxStructOperList data - */ - void consumePdbxStructOperList(PdbxStructOperList pdbxStructOperList); - - /** - * Consume a particular Cif category. - * @param refine data - */ - void consumeRefine(Refine refine); - - /** - * Consume a particular Cif category. - * @param struct data - */ - void consumeStruct(Struct struct); - - /** - * Consume a particular Cif category. - * @param structAsym data - */ - void consumeStructAsym(StructAsym structAsym); - - /** - * Consume a particular Cif category. - * @param structConf data - */ - void consumeStructConf(StructConf structConf); - - /** - * Consume a particular Cif category. - * @param structConn data - */ - void consumeStructConn(StructConn structConn); - - /** - * Consume a particular Cif category. - * @param structConnType data - */ - void consumeStructConnType(StructConnType structConnType); - - /** - * Consume a particular Cif category. - * @param structKeywords data - */ - void consumeStructKeywords(StructKeywords structKeywords); - - /** - * Consume a particular Cif category. - * @param structNcsOper data - */ - void consumeStructNcsOper(StructNcsOper structNcsOper); - - /** - * Consume a particular Cif category. - * @param structRef data - */ - void consumeStructRef(StructRef structRef); - - /** - * Consume a particular Cif category. - * @param structRefSeq data - */ - void consumeStructRefSeq(StructRefSeq structRefSeq); - - /** - * Consume a particular Cif category. - * @param structRefSeqDif data - */ - void consumeStructRefSeqDif(StructRefSeqDif structRefSeqDif); - - /** - * Consume a particular Cif category. - * @param structSheetRange data - */ - void consumeStructSheetRange(StructSheetRange structSheetRange); - - /** - * Consume a particular Cif category. - * @param structSite data - */ - void consumeStructSite(StructSite structSite); - - /** - * Consume a particular Cif category. - * @param structSiteGen data - */ - void consumeStructSiteGen(StructSiteGen structSiteGen); - - /** - * Consume a particular Cif category. - * @param symmetry data - */ - void consumeSymmetry(Symmetry symmetry); - /** * Ultimate setup which can include steps which require several categories to be available and integrate them into * the final container. diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java index 8f82e310b6..30e5682b69 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java @@ -1,5 +1,6 @@ package org.biojava.nbio.structure.io.cif; +import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.io.FileParsingParameters; import org.rcsb.cif.CifIO; @@ -9,6 +10,7 @@ import java.io.IOException; import java.io.InputStream; +import java.io.UncheckedIOException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; @@ -99,7 +101,7 @@ public static Structure fromCifFile(CifFile cifFile) { */ public static Structure fromCifFile(CifFile cifFile, FileParsingParameters parameters) { // initialize consumer - CifFileConsumer consumer = new CifFileConsumerImpl(parameters); + StructureConsumer consumer = new StructureConsumerImpl(parameters); // init structure consumer.prepare(); @@ -113,9 +115,9 @@ public static Structure fromCifFile(CifFile cifFile, FileParsingParameters param consumer.consumeCell(cifBlock.getCell()); consumer.consumeChemComp(cifBlock.getChemComp()); consumer.consumeChemCompBond(cifBlock.getChemCompBond()); - consumer.consumeDatabasePDBremark(cifBlock.getDatabasePDBRemark()); - consumer.consumeDatabasePDBrev(cifBlock.getDatabasePDBRev()); - consumer.consumeDatabasePDBrevRecord(cifBlock.getDatabasePDBRevRecord()); + consumer.consumeDatabasePDBRemark(cifBlock.getDatabasePDBRemark()); + consumer.consumeDatabasePDBRev(cifBlock.getDatabasePDBRev()); + consumer.consumeDatabasePDBRevRecord(cifBlock.getDatabasePDBRevRecord()); consumer.consumeEntity(cifBlock.getEntity()); consumer.consumeEntityPoly(cifBlock.getEntityPoly()); consumer.consumeEntitySrcGen(cifBlock.getEntitySrcGen()); @@ -183,20 +185,39 @@ public static void toBinaryFile(Structure structure, Path path) throws IOExcepti * Convert a structure to BCIF format. * @param structure the source * @return the binary representation of the structure - * @throws IOException thrown when writing fails */ - public static byte[] toBinary(Structure structure) throws IOException { - return CifIO.writeText(toCifFile(structure)); + public static byte[] toBinary(Structure structure) { + try { + return CifIO.writeText(toCifFile(structure)); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } /** * Convert a structure to mmCIF format. * @param structure the source * @return the mmCIF String representation of the structure - * @throws IOException thrown when writing fails */ - public static String toText(Structure structure) throws IOException { - return new String(CifIO.writeText(toCifFile(structure))); + public static String toText(Structure structure) { + try { + return new String(CifIO.writeText(toCifFile(structure))); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * Convert a chain to mmCIF format. + * @param chain the source + * @return the mmCIF String representation of the chain + */ + public static String toText(Chain chain) { + try { + return new String(CifIO.writeText(toCifFile(chain))); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } /** @@ -205,6 +226,15 @@ public static String toText(Structure structure) throws IOException { * @return the target */ public static CifFile toCifFile(Structure structure) { - return new CifFileSupplierImpl().get(structure); + return new AbstractCifFileSupplier().getStructure(structure); + } + + /** + * Convert Chain to CifFile + * @param chain the source + * @return the target + */ + public static CifFile toCifFile(Chain chain) { + return new AbstractCifFileSupplier().getChain(chain); } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java index a4fcbe4c90..08f35fce54 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java @@ -2,13 +2,15 @@ import org.rcsb.cif.model.CifFile; +import java.util.function.Supplier; + /** * Create a CifFile instance for a given container of structure data. * @param the container type used as source * @author Sebastian Bittrich * @since 5.3.0 */ -interface CifFileSupplier { +public interface CifFileSupplier { /** * Convert some model instance describing structure information to a CifFile instance. * @param container the source of structure information diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumer.java new file mode 100644 index 0000000000..9594a2c71d --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumer.java @@ -0,0 +1,320 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.Structure; +import org.rcsb.cif.schema.mm.AtomSite; +import org.rcsb.cif.schema.mm.AtomSites; +import org.rcsb.cif.schema.mm.AuditAuthor; +import org.rcsb.cif.schema.mm.Cell; +import org.rcsb.cif.schema.mm.ChemComp; +import org.rcsb.cif.schema.mm.ChemCompBond; +import org.rcsb.cif.schema.mm.DatabasePDBRemark; +import org.rcsb.cif.schema.mm.DatabasePDBRev; +import org.rcsb.cif.schema.mm.DatabasePDBRevRecord; +import org.rcsb.cif.schema.mm.Entity; +import org.rcsb.cif.schema.mm.EntityPoly; +import org.rcsb.cif.schema.mm.EntityPolySeq; +import org.rcsb.cif.schema.mm.EntitySrcGen; +import org.rcsb.cif.schema.mm.EntitySrcNat; +import org.rcsb.cif.schema.mm.Exptl; +import org.rcsb.cif.schema.mm.PdbxAuditRevisionHistory; +import org.rcsb.cif.schema.mm.PdbxChemCompIdentifier; +import org.rcsb.cif.schema.mm.PdbxDatabaseStatus; +import org.rcsb.cif.schema.mm.PdbxEntityBranchDescriptor; +import org.rcsb.cif.schema.mm.PdbxEntitySrcSyn; +import org.rcsb.cif.schema.mm.PdbxMolecule; +import org.rcsb.cif.schema.mm.PdbxMoleculeFeatures; +import org.rcsb.cif.schema.mm.PdbxNonpolyScheme; +import org.rcsb.cif.schema.mm.PdbxReferenceEntityLink; +import org.rcsb.cif.schema.mm.PdbxReferenceEntityList; +import org.rcsb.cif.schema.mm.PdbxReferenceEntityPolyLink; +import org.rcsb.cif.schema.mm.PdbxStructAssembly; +import org.rcsb.cif.schema.mm.PdbxStructAssemblyGen; +import org.rcsb.cif.schema.mm.PdbxStructModResidue; +import org.rcsb.cif.schema.mm.PdbxStructOperList; +import org.rcsb.cif.schema.mm.Refine; +import org.rcsb.cif.schema.mm.Struct; +import org.rcsb.cif.schema.mm.StructAsym; +import org.rcsb.cif.schema.mm.StructConf; +import org.rcsb.cif.schema.mm.StructConn; +import org.rcsb.cif.schema.mm.StructConnType; +import org.rcsb.cif.schema.mm.StructKeywords; +import org.rcsb.cif.schema.mm.StructNcsOper; +import org.rcsb.cif.schema.mm.StructRef; +import org.rcsb.cif.schema.mm.StructRefSeq; +import org.rcsb.cif.schema.mm.StructRefSeqDif; +import org.rcsb.cif.schema.mm.StructSheetRange; +import org.rcsb.cif.schema.mm.StructSite; +import org.rcsb.cif.schema.mm.StructSiteGen; +import org.rcsb.cif.schema.mm.Symmetry; + +public interface StructureConsumer extends CifFileConsumer { + /** + * Consume a particular Cif category. + * @param atomSite data + */ + void consumeAtomSite(AtomSite atomSite); + + /** + * Consume a particular Cif category. + * @param atomSites data + */ + void consumeAtomSites(AtomSites atomSites); + + /** + * Consume a particular Cif category. + * @param auditAuthor data + */ + void consumeAuditAuthor(AuditAuthor auditAuthor); + + /** + * Consume a particular Cif category. + * @param cell data + */ + void consumeCell(Cell cell); + + /** + * Consume a particular Cif category. + * @param chemComp data + */ + void consumeChemComp(ChemComp chemComp); + + /** + * Consume a particular Cif category. + * @param chemCompBond data + */ + void consumeChemCompBond(ChemCompBond chemCompBond); + + /** + * Consume a particular Cif category. + * @param databasePDBremark data + */ + void consumeDatabasePDBRemark(DatabasePDBRemark databasePDBremark); + + /** + * Consume a particular Cif category. + * @param databasePDBrev data + */ + void consumeDatabasePDBRev(DatabasePDBRev databasePDBrev); + + /** + * Consume a particular Cif category. + * @param databasePDBrevRecord data + */ + void consumeDatabasePDBRevRecord(DatabasePDBRevRecord databasePDBrevRecord); + + /** + * Consume a particular Cif category. + * @param entity data + */ + void consumeEntity(Entity entity); + + /** + * Consume a particular Cif category. + * @param entityPoly data + */ + void consumeEntityPoly(EntityPoly entityPoly); + + /** + * Consume a particular Cif category. + * @param entitySrcGen data + */ + void consumeEntitySrcGen(EntitySrcGen entitySrcGen); + + /** + * Consume a particular Cif category. + * @param entitySrcNat data + */ + void consumeEntitySrcNat(EntitySrcNat entitySrcNat); + + /** + * Consume a particular Cif category. + * @param entitySrcSyn data + */ + void consumeEntitySrcSyn(PdbxEntitySrcSyn entitySrcSyn); + + /** + * Consume a particular Cif category. + * @param entityPolySeq data + */ + void consumeEntityPolySeq(EntityPolySeq entityPolySeq); + + /** + * Consume a particular Cif category. + * @param exptl data + */ + void consumeExptl(Exptl exptl); + + /** + * Consume a particular Cif category. + * @param pdbxAuditRevisionHistory data + */ + void consumePdbxAuditRevisionHistory(PdbxAuditRevisionHistory pdbxAuditRevisionHistory); + + /** + * Consume a particular Cif category. + * @param pdbxChemCompIdentifier data + */ + void consumePdbxChemCompIdentifier(PdbxChemCompIdentifier pdbxChemCompIdentifier); + + /** + * Consume a particular Cif category. + * @param pdbxDatabaseStatus data + */ + void consumePdbxDatabaseStatus(PdbxDatabaseStatus pdbxDatabaseStatus); + + /** + * Consume a particular Cif category. + * @param pdbxEntityBranchDescriptor data + */ + void consumePdbxEntityBranchDescriptor(PdbxEntityBranchDescriptor pdbxEntityBranchDescriptor); + + /** + * Consume a particular Cif category. + * @param pdbxMolecule data + */ + void consumePdbxMolecule(PdbxMolecule pdbxMolecule); + + /** + * Consume a particular Cif category. + * @param pdbxMoleculeFeatures data + */ + void consumePdbxMoleculeFeatures(PdbxMoleculeFeatures pdbxMoleculeFeatures); + + /** + * Consume a particular Cif category. + * @param pdbxNonpolyScheme data + */ + void consumePdbxNonpolyScheme(PdbxNonpolyScheme pdbxNonpolyScheme); + + /** + * Consume a particular Cif category. + * @param pdbxReferenceEntityLink data + */ + void consumePdbxReferenceEntityLink(PdbxReferenceEntityLink pdbxReferenceEntityLink); + + /** + * Consume a particular Cif category. + * @param pdbxReferenceEntityList data + */ + void consumePdbxReferenceEntityList(PdbxReferenceEntityList pdbxReferenceEntityList); + + /** + * Consume a particular Cif category. + * @param pdbxReferenceEntityPolyLink data + */ + void consumePdbxReferenceEntityPolyLink(PdbxReferenceEntityPolyLink pdbxReferenceEntityPolyLink); + + /** + * Consume a particular Cif category. + * @param pdbxStructAssembly data + */ + void consumePdbxStructAssembly(PdbxStructAssembly pdbxStructAssembly); + + /** + * Consume a particular Cif category. + * @param pdbxStructAssemblyGen data + */ + void consumePdbxStructAssemblyGen(PdbxStructAssemblyGen pdbxStructAssemblyGen); + + /** + * Consume a particular Cif category. + * @param pdbxStructModResidue data + */ + void consumePdbxStructModResidue(PdbxStructModResidue pdbxStructModResidue); + + /** + * Consume a particular Cif category. + * @param pdbxStructOperList data + */ + void consumePdbxStructOperList(PdbxStructOperList pdbxStructOperList); + + /** + * Consume a particular Cif category. + * @param refine data + */ + void consumeRefine(Refine refine); + + /** + * Consume a particular Cif category. + * @param struct data + */ + void consumeStruct(Struct struct); + + /** + * Consume a particular Cif category. + * @param structAsym data + */ + void consumeStructAsym(StructAsym structAsym); + + /** + * Consume a particular Cif category. + * @param structConf data + */ + void consumeStructConf(StructConf structConf); + + /** + * Consume a particular Cif category. + * @param structConn data + */ + void consumeStructConn(StructConn structConn); + + /** + * Consume a particular Cif category. + * @param structConnType data + */ + void consumeStructConnType(StructConnType structConnType); + + /** + * Consume a particular Cif category. + * @param structKeywords data + */ + void consumeStructKeywords(StructKeywords structKeywords); + + /** + * Consume a particular Cif category. + * @param structNcsOper data + */ + void consumeStructNcsOper(StructNcsOper structNcsOper); + + /** + * Consume a particular Cif category. + * @param structRef data + */ + void consumeStructRef(StructRef structRef); + + /** + * Consume a particular Cif category. + * @param structRefSeq data + */ + void consumeStructRefSeq(StructRefSeq structRefSeq); + + /** + * Consume a particular Cif category. + * @param structRefSeqDif data + */ + void consumeStructRefSeqDif(StructRefSeqDif structRefSeqDif); + + /** + * Consume a particular Cif category. + * @param structSheetRange data + */ + void consumeStructSheetRange(StructSheetRange structSheetRange); + + /** + * Consume a particular Cif category. + * @param structSite data + */ + void consumeStructSite(StructSite structSite); + + /** + * Consume a particular Cif category. + * @param structSiteGen data + */ + void consumeStructSiteGen(StructSiteGen structSiteGen); + + /** + * Consume a particular Cif category. + * @param symmetry data + */ + void consumeSymmetry(Symmetry symmetry); +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java similarity index 89% rename from biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java rename to biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java index a3af75fc91..d858536847 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java @@ -7,7 +7,6 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.ChainImpl; import org.biojava.nbio.structure.DBRef; -import org.biojava.nbio.structure.DatabasePdbRevRecord; import org.biojava.nbio.structure.Element; import org.biojava.nbio.structure.EntityInfo; import org.biojava.nbio.structure.EntityType; @@ -25,12 +24,12 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.io.BondMaker; import org.biojava.nbio.structure.io.ChargeAdder; import org.biojava.nbio.structure.io.EntityFinder; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.SeqRes2AtomAligner; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyBuilder; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; @@ -99,15 +98,12 @@ /** * An implementation of a CifFileConsumer for BioJava. Will process the information provided by a CifFile instance and - * use it to build up a {@link Structure} object. The implementation is for the most part really close to that in - * {@link org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer} and associated classes. The main difference is that - * all internally used model classes are generated from the MMCIF schema and a standardized interface to CifFile data is - * provided. This allows to readily parse files in CIF format as well as binary CIF (BCIF) format. + * use it to build up a {@link Structure} object. * @author Sebastian Bittrich - * @since 5.3.0 + * @since 6.0.0 */ -class CifFileConsumerImpl implements CifFileConsumer { - private static final Logger logger = LoggerFactory.getLogger(CifFileConsumerImpl.class); +public class StructureConsumerImpl implements StructureConsumer { + private static final Logger logger = LoggerFactory.getLogger(StructureConsumerImpl.class); private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder() .parseCaseInsensitive() .appendPattern("yyyy-MM-dd") @@ -144,7 +140,7 @@ class CifFileConsumerImpl implements CifFileConsumer { private final FileParsingParameters params; - public CifFileConsumerImpl(FileParsingParameters params) { + public StructureConsumerImpl(FileParsingParameters params) { this.params = params; } @@ -575,7 +571,7 @@ public void consumeChemCompBond(ChemCompBond chemCompBond) { } @Override - public void consumeDatabasePDBremark(DatabasePDBRemark databasePDBremark) { + public void consumeDatabasePDBRemark(DatabasePDBRemark databasePDBremark) { for (int rowIndex = 0; rowIndex < databasePDBremark.getRowCount(); rowIndex++) { int id = databasePDBremark.getId().get(rowIndex); if (id == 2) { @@ -603,7 +599,7 @@ private Date convert(LocalDate localDate) { } @Override - public void consumeDatabasePDBrev(DatabasePDBRev databasePDBrev) { + public void consumeDatabasePDBRev(DatabasePDBRev databasePDBrev) { logger.debug("got a database revision:" + databasePDBrev); for (int rowIndex = 0; rowIndex < databasePDBrev.getRowCount(); rowIndex++) { @@ -621,26 +617,16 @@ public void consumeDatabasePDBrev(DatabasePDBRev databasePDBrev) { } @Override - public void consumeDatabasePDBrevRecord(DatabasePDBRevRecord databasePDBrevRecord) { - List revRecords = pdbHeader.getRevisionRecords(); + public void consumeDatabasePDBRevRecord(DatabasePDBRevRecord databasePDBrevRecord) { + List revRecords = pdbHeader.getRevisionRecords(); if (revRecords == null) { revRecords = new ArrayList<>(); pdbHeader.setRevisionRecords(revRecords); } - revRecords.addAll(convert(databasePDBrevRecord)); - } - - private List convert(DatabasePDBRevRecord databasePDBrevRecord) { - List revRecords = new ArrayList<>(); - for (int rowIndex = 0; rowIndex < databasePDBrevRecord.getRowCount(); rowIndex++) { - DatabasePdbRevRecord revRecord = new DatabasePdbRevRecord(); - revRecord.setDetails(databasePDBrevRecord.getDetails().get(rowIndex)); - revRecord.setRev_num(databasePDBrevRecord.getRevNum().getStringData(rowIndex)); - revRecord.setType(databasePDBrevRecord.getType().get(rowIndex)); - revRecords.add(revRecord); + for (int i = 0; i < databasePDBrevRecord.getRowCount(); i++) { + revRecords.add(new org.biojava.nbio.structure.DatabasePDBRevRecord(databasePDBrevRecord, i)); } - return revRecords; } @Override @@ -1183,25 +1169,24 @@ public void finish() { // the more detailed mapping of chains to rotation operations happens in StructureIO... Map bioAssemblies = new LinkedHashMap<>(); - List structAssemblies = convert(structAssembly); - List structAssemblyGens = convert(structAssemblyGen); - - for (org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssembly pdbxStructAssembly : structAssemblies) { - List pdbxStructAssemblyGens = structAssemblyGens.stream() - .filter(sag -> sag.getAssembly_id().equals(pdbxStructAssembly.getId())) - .collect(Collectors.toList()); - + for (int i = 0; i < structAssembly.getRowCount(); i++) { + String assemblyId = structAssembly.getId().get(i); + List structAssemblyGenIndices = new ArrayList<>(); + for (int j = 0; j < structAssemblyGen.getRowCount(); j++) { + if (structAssemblyGen.getAssemblyId().get(j).equals(assemblyId)) { + structAssemblyGenIndices.add(j); + } + } BiologicalAssemblyBuilder builder = new BiologicalAssemblyBuilder(); - // these are the transformations that need to be applied to our model - List transformations = builder.getBioUnitTransformationList(pdbxStructAssembly, - pdbxStructAssemblyGens, convert(structOpers)); + List transformations = builder.getBioUnitTransformationList(structAssembly, + i, structAssemblyGen, structOpers); int bioAssemblyId = -1; try { - bioAssemblyId = Integer.parseInt(pdbxStructAssembly.getId()); + bioAssemblyId = Integer.parseInt(assemblyId); } catch (NumberFormatException e) { - logger.info("Could not parse a numerical bio assembly id from '{}'", pdbxStructAssembly.getId()); + logger.info("Could not parse a numerical bio assembly id from '{}'", assemblyId); } // if bioassembly id is not numerical we throw it away @@ -1418,68 +1403,6 @@ private void setStructNcsOps() { } } - private List convert(PdbxStructOperList structOpers) { - List re = new ArrayList<>(); - for (int rowIndex = 0; rowIndex < structOpers.getRowCount(); rowIndex++) { - org.biojava.nbio.structure.io.mmcif.model.PdbxStructOperList pdbxStructOperList = - new org.biojava.nbio.structure.io.mmcif.model.PdbxStructOperList(); - - pdbxStructOperList.setId(structOpers.getId().get(rowIndex)); - pdbxStructOperList.setName(structOpers.getName().get(rowIndex)); - pdbxStructOperList.setSymmetry_operation(structOpers.getSymmetryOperation().get(rowIndex)); - pdbxStructOperList.setType(structOpers.getType().get(rowIndex)); - - pdbxStructOperList.setMatrix11(String.valueOf(structOpers.getMatrix11().get(rowIndex))); - pdbxStructOperList.setMatrix12(String.valueOf(structOpers.getMatrix12().get(rowIndex))); - pdbxStructOperList.setMatrix13(String.valueOf(structOpers.getMatrix13().get(rowIndex))); - pdbxStructOperList.setMatrix21(String.valueOf(structOpers.getMatrix21().get(rowIndex))); - pdbxStructOperList.setMatrix22(String.valueOf(structOpers.getMatrix22().get(rowIndex))); - pdbxStructOperList.setMatrix23(String.valueOf(structOpers.getMatrix23().get(rowIndex))); - pdbxStructOperList.setMatrix31(String.valueOf(structOpers.getMatrix31().get(rowIndex))); - pdbxStructOperList.setMatrix32(String.valueOf(structOpers.getMatrix32().get(rowIndex))); - pdbxStructOperList.setMatrix33(String.valueOf(structOpers.getMatrix33().get(rowIndex))); - - pdbxStructOperList.setVector1(String.valueOf(structOpers.getVector1().get(rowIndex))); - pdbxStructOperList.setVector2(String.valueOf(structOpers.getVector2().get(rowIndex))); - pdbxStructOperList.setVector3(String.valueOf(structOpers.getVector3().get(rowIndex))); - - re.add(pdbxStructOperList); - } - return re; - } - - private List convert(PdbxStructAssemblyGen structAssemblyGen) { - List re = new ArrayList<>(); - for (int rowIndex = 0; rowIndex < structAssemblyGen.getRowCount(); rowIndex++) { - org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssemblyGen pdbxStructAssemblyGen = - new org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssemblyGen(); - - pdbxStructAssemblyGen.setAssembly_id(structAssemblyGen.getAssemblyId().get(rowIndex)); - pdbxStructAssemblyGen.setAsym_id_list(structAssemblyGen.getAsymIdList().get(rowIndex)); - pdbxStructAssemblyGen.setOper_expression(structAssemblyGen.getOperExpression().get(rowIndex)); - - re.add(pdbxStructAssemblyGen); - } - return re; - } - - private List convert(PdbxStructAssembly structAssembly) { - List re = new ArrayList<>(); - for (int rowIndex = 0; rowIndex < structAssembly.getRowCount(); rowIndex++) { - org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssembly pdbxStructAssembly = - new org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssembly(); - - pdbxStructAssembly.setDetails(structAssembly.getDetails().get(rowIndex)); - pdbxStructAssembly.setId(structAssembly.getId().get(rowIndex)); - pdbxStructAssembly.setMethod_details(structAssembly.getMethodDetails().get(rowIndex)); - pdbxStructAssembly.setOligomeric_count(structAssembly.getOligomericCount().getStringData(rowIndex)); - pdbxStructAssembly.setOligomeric_details(structAssembly.getOligomericDetails().get(rowIndex)); - - re.add(pdbxStructAssembly); - } - return re; - } - private void setCrystallographicInfoMetadata() { if (parsedScaleMatrix != null) { PDBCrystallographicInfo crystalInfo = structure.getCrystallographicInfo(); @@ -1610,32 +1533,7 @@ private static Chain removeSeqResHeterogeneity(Chain c) { private void addBonds() { BondMaker maker = new BondMaker(structure, params); maker.makeBonds(); - maker.formBondsFromStructConn(convert(structConn)); - } - - private List convert(StructConn structConn) { - return IntStream.range(0, structConn.getRowCount()) - .mapToObj(rowIndex -> { - org.biojava.nbio.structure.io.mmcif.model.StructConn sc = - new org.biojava.nbio.structure.io.mmcif.model.StructConn(); - - sc.setPdbx_ptnr1_PDB_ins_code(structConn.getPdbxPtnr1PDBInsCode().get(rowIndex)); - sc.setPdbx_ptnr2_PDB_ins_code(structConn.getPdbxPtnr2PDBInsCode().get(rowIndex)); - sc.setPtnr1_auth_seq_id(structConn.getPtnr1AuthSeqId().getStringData(rowIndex)); - sc.setPtnr2_auth_seq_id(structConn.getPtnr2AuthSeqId().getStringData(rowIndex)); - sc.setPtnr1_label_comp_id(structConn.getPtnr1LabelCompId().get(rowIndex)); - sc.setPtnr2_label_comp_id(structConn.getPtnr2LabelCompId().get(rowIndex)); - sc.setPtnr1_label_atom_id(structConn.getPtnr1LabelAtomId().get(rowIndex)); - sc.setPtnr2_label_atom_id(structConn.getPtnr2LabelAtomId().get(rowIndex)); - sc.setPdbx_ptnr1_label_alt_id(structConn.getPdbxPtnr1LabelAltId().get(rowIndex)); - sc.setPdbx_ptnr2_label_alt_id(structConn.getPdbxPtnr2LabelAltId().get(rowIndex)); - sc.setPtnr1_symmetry(structConn.getPtnr1Symmetry().get(rowIndex)); - sc.setPtnr2_symmetry(structConn.getPtnr2Symmetry().get(rowIndex)); - sc.setConn_type_id(structConn.getConnTypeId().get(rowIndex)); - - return sc; - }) - .collect(Collectors.toList()); + maker.formBondsFromStructConn(structConn); } private void alignSeqRes() { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureSupplierImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureSupplierImpl.java new file mode 100644 index 0000000000..ef377ad52a --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureSupplierImpl.java @@ -0,0 +1,28 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.Chain; +import org.biojava.nbio.structure.Structure; +import org.rcsb.cif.model.CifFile; + +import java.util.ArrayList; +import java.util.List; + +public class StructureSupplierImpl extends AbstractCifFileSupplier { + @Override + public CifFile get(Structure container) { + return getInternal(container, collectWrappedAtoms(container)); + } + + private List collectWrappedAtoms(Structure structure) { + List wrappedAtoms = new ArrayList<>(); + + for (int modelIndex = 0; modelIndex < structure.nrModels(); modelIndex++) { + final int model = modelIndex + 1; + for (Chain chain : structure.getChains(modelIndex)) { + handleChain(chain, model, wrappedAtoms); + } + } + + return wrappedAtoms; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/AllChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/AllChemCompProvider.java deleted file mode 100644 index b2b3222d58..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/AllChemCompProvider.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - -import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.LocalPDBDirectory; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.biojava.nbio.core.util.InputStreamProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.net.URL; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * A ChemComp provider that downloads and caches the components.cif file from the wwPDB site. It then loads - * all chemical components at startup and keeps them in memory. This provider is not used as a default - * since it is slower at startup and requires more memory than the {@link DownloadChemCompProvider} that is used by default. - * - * @author Andreas Prlic - * - */ -public class AllChemCompProvider implements ChemCompProvider, Runnable{ - - private static final Logger logger = LoggerFactory.getLogger(AllChemCompProvider.class); - - public static final String COMPONENTS_FILE_LOCATION = "pub/pdb/data/monomers/components.cif.gz"; - - - private static String path; - - private static String serverName; - - - // there will be only one copy of the dictionary across all instances - // to reduce memory impact - static ChemicalComponentDictionary dict; - - // flags to make sure there is only one thread running that is loading the dictionary - static AtomicBoolean loading = new AtomicBoolean(false); - static AtomicBoolean isInitialized = new AtomicBoolean(false); - - public AllChemCompProvider(){ - - if ( loading.get()) { - logger.warn("other thread is already loading all chemcomps, no need to init twice"); - return; - } - if ( isInitialized.get()) - return; - - loading.set(true); - - Thread t = new Thread(this); - t.start(); - - } - - - /** make sure all paths are initialized correctly - * - */ - private static void initPath(){ - - if (path==null) { - UserConfiguration config = new UserConfiguration(); - path = config.getCacheFilePath(); - } - } - - private static void initServerName() { - - if (serverName==null) { - serverName = LocalPDBDirectory.getServerName(); - } - } - - private void ensureFileExists() { - - - String fileName = getLocalFileName(); - File f = new File(fileName); - - if ( ! f.exists()) { - try { - downloadFile(); - } catch (IOException e) { - logger.error("Caught IOException",e); - } - } - - - - } - - /** Downloads the components.cif.gz file from the wwPDB site. - * - */ - public static void downloadFile() throws IOException { - - initPath(); - - initServerName(); - - String localName = getLocalFileName(); - - String u = serverName + "/" + COMPONENTS_FILE_LOCATION; - - downloadFileFromRemote(new URL(u), new File(localName)); - - - } - - - private static void downloadFileFromRemote(URL remoteURL, File localFile) throws FileNotFoundException, IOException{ - logger.info("Downloading " + remoteURL + " to: " + localFile); - FileOutputStream out = new FileOutputStream(localFile); - - InputStream in = remoteURL.openStream(); - byte[] buf = new byte[4 * 1024]; // 4K buffer - int bytesRead; - while ((bytesRead = in.read(buf)) != -1) { - out.write(buf, 0, bytesRead); - } - in.close(); - out.close(); - - - } - - - private static String getLocalFileName(){ - - File dir = new File(path, DownloadChemCompProvider.CHEM_COMP_CACHE_DIRECTORY); - - if (! dir.exists()){ - logger.info("Creating directory {}", dir.toString()); - dir.mkdir(); - } - - String fileName = new File(dir, "components.cif.gz").toString(); - - return fileName; - } - - /** Load all {@link ChemComp} definitions into memory. - * - */ - private void loadAllChemComps() throws IOException { - String fileName = getLocalFileName(); - logger.debug("Loading " + fileName); - InputStreamProvider isp = new InputStreamProvider(); - - - InputStream inStream = isp.getInputStream(fileName); - - MMcifParser parser = new SimpleMMcifParser(); - - ChemCompConsumer consumer = new ChemCompConsumer(); - - // The Consumer builds up the BioJava - structure object. - // you could also hook in your own and build up you own data model. - parser.addMMcifConsumer(consumer); - - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - - dict = consumer.getDictionary(); - - inStream.close(); - - } - - - /** {@inheritDoc} - * - */ - @Override - public ChemComp getChemComp(String recordName) { - - while ( loading.get()) { - - // another thread is still initializing the definitions - try { - // wait half a second - - Thread.sleep(500); - } catch (InterruptedException e) { - logger.error("Interrepted thread while waiting: "+e.getMessage()); - //e.printStackTrace(); - } - } - - - - return dict.getChemComp(recordName); - } - - - /** Do the actual loading of the dictionary in a thread. - * - */ - @Override - public void run() { - long timeS = System.currentTimeMillis(); - - initPath(); - - ensureFileExists(); - - try { - loadAllChemComps(); - - long timeE = System.currentTimeMillis(); - logger.debug("Time to init chem comp dictionary: " + (timeE - timeS) / 1000 + " sec."); - - - } catch (IOException e) { - logger.error("Could not load chemical components definition file {}. Error: {}", getLocalFileName(), e.getMessage()); - - } finally { - loading.set(false); - isInitialized.set(true); - } - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompConsumer.java deleted file mode 100644 index f2d043a5b9..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompConsumer.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - -import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; -import org.biojava.nbio.structure.io.mmcif.model.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -public class ChemCompConsumer implements MMcifConsumer { - - private static final Logger logger = LoggerFactory.getLogger(ChemCompConsumer.class); - - ChemicalComponentDictionary dictionary; - - String latestChemCompId; - public ChemCompConsumer(){ - dictionary = new ChemicalComponentDictionary(); - } - - @Override - public void documentStart() { - - - } - - public ChemicalComponentDictionary getDictionary(){ - return dictionary; - } - - @Override - public void newChemComp(ChemComp c) { - - if ( c.getId() == null) - logger.warn("chem comp ID == null " + c); - - latestChemCompId = c.getId(); - dictionary.addChemComp(c); - if ( c.getResidueType() == ResidueType.nonPolymer) - return; - - if ( c.getResidueType() == ResidueType.saccharide) - return; - - if ( c.getResidueType() == ResidueType.dSaccharide) - return; - - //if ( c.isStandard()) - // System.out.println(c); - } - - @Override - public void documentEnd() { - - - } - - @Override - public void newAtomSite(AtomSite atom) { - - - } - - @Override - public void newDatabasePDBremark(DatabasePDBremark remark) { - - - } - - @Override - public void newDatabasePDBrev(DatabasePDBrev dbrev) { - - - } - - @Override - public void newDatabasePDBrevRecord(DatabasePdbrevRecord dbrev) { - - } - - @Override - public void newEntity(Entity entity) { - - - } - - @Override - public void newEntityPolySeq(EntityPolySeq epolseq) { - - - } - - @Override - public void newExptl(Exptl exptl) { - - - } - - @Override - public void newCell(Cell cell) { - - } - - @Override - public void newSymmetry(Symmetry symmetry) { - - } - - @Override - public void newStructNcsOper(StructNcsOper sNcsOper) { - - } - - @Override - public void newAtomSites(AtomSites atomSites) { - - } - - @Override - public void newPdbxEntityNonPoly(PdbxEntityNonPoly pen) { - - - } - - @Override - public void newPdbxNonPolyScheme(PdbxNonPolyScheme ppss) { - - - } - - @Override - public void newPdbxPolySeqScheme(PdbxPolySeqScheme ppss) { - - - } - - @Override - public void newRefine(Refine r) { - - - } - - @Override - public void newStructAsym(StructAsym sasym) { - - - } - - @Override - public void newStructKeywords(StructKeywords kw) { - - - } - - @Override - public void newStructRef(StructRef sref) { - - - } - - @Override - public void newStructRefSeq(StructRefSeq sref) { - - - } - - @Override - public void newStructRefSeqDif(StructRefSeqDif sref) { - - - } - - @Override - public void setStruct(Struct struct) { - - - } - - @Override - public void newGenericData(String category, List loopFields, - List lineData) { - //System.out.println("unhandled category: " + category); - - } - - - @Override - public void newAuditAuthor(AuditAuthor aa) - { - - - } - - @Override - public FileParsingParameters getFileParsingParameters() - { - // can be ingored in this case... - return null; - } - - @Override - public void setFileParsingParameters(FileParsingParameters params) - { - - - } - - @Override - public void newChemCompDescriptor(ChemCompDescriptor ccd) { - ChemComp cc = dictionary.getChemComp(latestChemCompId); - cc.getDescriptors().add(ccd); - - } - - @Override - public void newPdbxStructOperList(PdbxStructOperList structOper) { - - - } - - @Override - public void newPdbxStrucAssembly(PdbxStructAssembly strucAssembly) { - - - } - - @Override - public void newPdbxStrucAssemblyGen(PdbxStructAssemblyGen strucAssembly) { - - - } - - @Override - public void newChemCompAtom(ChemCompAtom atom) { - dictionary.getChemComp(latestChemCompId).getAtoms().add(atom); - } - - @Override - public void newPdbxChemCompIndentifier(PdbxChemCompIdentifier id) { - - - } - - @Override - public void newChemCompBond(ChemCompBond bond) { - dictionary.getChemComp(latestChemCompId).getBonds().add(bond); - } - - @Override - public void newPdbxChemCompDescriptor(PdbxChemCompDescriptor desc) { - - - } - - @Override - public void newEntitySrcGen(EntitySrcGen entitySrcGen) { - - - } - @Override - public void newEntitySrcNat(EntitySrcNat entitySrcNat) { - - - } - - @Override - public void newEntitySrcSyn(EntitySrcSyn entitySrcSyn) { - - - } - - @Override - public void newStructConn(StructConn structConn) { - - - } - - @Override - public void newStructSiteGen(StructSiteGen gen) { - - } - - @Override - public void newStructSite(StructSite site) { - - } - - @Override - public void newEntityPoly(EntityPoly entityPoly) { - - - } - - @Override - public void newPdbxAuditRevisionHistory(PdbxAuditRevisionHistory history) { - // TODO Auto-generated method stub - - } - - @Override - public void newPdbxDatabaseStatus(PdbxDatabaseStatus status) { - // TODO Auto-generated method stub - - } -} - diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompGroupFactory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompGroupFactory.java deleted file mode 100644 index 87f6408e86..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompGroupFactory.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on May 23, 2010 - * - */ -package org.biojava.nbio.structure.io.mmcif; - -import org.biojava.nbio.core.util.SoftHashMap; -import org.biojava.nbio.structure.AminoAcid; -import org.biojava.nbio.structure.AminoAcidImpl; -import org.biojava.nbio.structure.Group; -import org.biojava.nbio.structure.HetatomImpl; -import org.biojava.nbio.structure.NucleotideImpl; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class ChemCompGroupFactory { - - private static final Logger logger = LoggerFactory.getLogger(ChemCompGroupFactory.class); - - private static ChemCompProvider chemCompProvider = new DownloadChemCompProvider(); - - private static SoftHashMap cache = new SoftHashMap(0); - - public static ChemComp getChemComp(String recordName){ - - recordName = recordName.toUpperCase().trim(); - - // we are using the cache, to avoid hitting the file system too often. - ChemComp cc = cache.get(recordName); - if ( cc != null) { - logger.debug("Chem comp "+cc.getThree_letter_code()+" read from cache"); - return cc; - } - - // not cached, get the chem comp from the provider - logger.debug("Chem comp "+recordName+" read from provider "+chemCompProvider.getClass().getCanonicalName()); - cc = chemCompProvider.getChemComp(recordName); - - // Note that this also caches null or empty responses - cache.put(recordName, cc); - return cc; - } - - /** - * The new ChemCompProvider will be set in the static variable, - * so this provider will be used from now on until it is changed - * again. Note that this change can have unexpected behavior of - * code executed afterwards. - *

      - * Changing the provider also resets the cache, so any groups - * previously accessed will be reread or re-downloaded. - * - * @param provider - */ - public static void setChemCompProvider(ChemCompProvider provider) { - logger.debug("Setting new chem comp provider to "+provider.getClass().getCanonicalName()); - chemCompProvider = provider; - // clear cache - cache.clear(); - } - - public static ChemCompProvider getChemCompProvider(){ - return chemCompProvider; - } - - /** - * Force the in-memory cache to be reset. - * - * Note that the ChemCompProvider may have additional memory or disk caches that need to be cleared too. - */ - public static void clearCache() { - cache.clear(); - } - - public static Group getGroupFromChemCompDictionary(String recordName) { - - // make sure we work with upper case records - recordName = recordName.toUpperCase().trim(); - - Group g = null; - - - ChemComp cc = getChemComp(recordName); - - if ( cc == null) - return null; - - if ( PolymerType.PROTEIN_ONLY.contains( cc.getPolymerType() ) ){ - AminoAcid aa = new AminoAcidImpl(); - - String one_letter = cc.getOne_letter_code(); - if ( one_letter == null || one_letter.equals("X") || one_letter.equals("?") || one_letter.length()==0){ - String parent = cc.getMon_nstd_parent_comp_id(); - if ( parent != null && parent.length() == 3){ - String parentid = cc.getMon_nstd_parent_comp_id() ; - ChemComp parentCC = getChemComp(parentid); - one_letter = parentCC.getOne_letter_code(); - } - } - - if ( one_letter == null || one_letter.length()==0 || one_letter.equals("?")) { - // e.g. problem with PRR, which probably should have a parent of ALA, but as of 20110127 does not. - logger.warn("Problem with chemical component: " + recordName + " Did not find one letter code! Setting it to 'X'"); - aa.setAminoType('X'); - - } else { - aa.setAminoType(one_letter.charAt(0)); - } - - - g = aa; - } else if ( PolymerType.POLYNUCLEOTIDE_ONLY.contains(cc.getPolymerType())) { - NucleotideImpl nuc = new NucleotideImpl(); - - g = nuc; - - - } else { - - g = new HetatomImpl(); - } - - g.setChemComp(cc); - - - return g; - } - - - public static String getOneLetterCode(ChemComp cc){ - String oneLetter = cc.getOne_letter_code(); - if ( oneLetter == null || oneLetter.equals("X") || oneLetter.equals("?")) { - String parentId = cc.getMon_nstd_parent_comp_id() ; - if ( parentId == null) - return oneLetter; - // cases like OIM have multiple parents (comma separated), we shouldn't try grab a chemcomp for those strings - if (parentId.length()>3) - return oneLetter; - ChemComp parentCC = ChemCompGroupFactory.getChemComp(parentId); - if ( parentCC == null) - return oneLetter; - oneLetter = parentCC.getOne_letter_code(); - } - return oneLetter; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompProvider.java deleted file mode 100644 index a31affeaae..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemCompProvider.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; - -/** Interface that is implemented by all classes that can provide {@link ChemComp} definitions. - * - * @author Andreas Prlic - * @since 3.0 - */ -public interface ChemCompProvider { - - /** Returns a new instance of a chemical component definition. - * - * @param recordName the ID of the {@link ChemComp} - * @return a new {@link ChemComp} definition. - */ - ChemComp getChemComp(String recordName) ; - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemicalComponentDictionary.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemicalComponentDictionary.java deleted file mode 100644 index 19c97f9aed..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ChemicalComponentDictionary.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * - */ - -package org.biojava.nbio.structure.io.mmcif; - -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; - -import java.util.HashMap; -import java.util.Map; - -/** A representation of the Chemical Component Dictionary. - * - * @author Andreas Prlic - * @since 1.7 - * @see link into mmCIF dictionary - * - */ -public class ChemicalComponentDictionary { - - private Map dictionary; - private Map replaces; - private Map isreplacedby; - - public ChemicalComponentDictionary(){ - dictionary = new HashMap(); - replaces = new HashMap(); - isreplacedby = new HashMap(); - } - - public boolean isReplaced(ChemComp c){ - return isReplaced(c.getId()); - - } - public boolean isReplaced(String id){ - if ( isreplacedby.containsKey(id)) - return true; - return false; - } - public boolean isReplacer(ChemComp c){ - return isReplacer(c.getId()); - } - public boolean isReplacer(String id){ - if ( replaces.containsKey(id) ) - return true; - return false; - } - - /** if ChemComp is replaced by another one, get the newer version - * otherwise return the same ChemComp again. - * @param c - * @return get the component that replaced ChemComp. - */ - public ChemComp getReplacer(ChemComp c){ - return getReplacer(c.getId()); - } - public ChemComp getReplacer(String id){ - if (isReplaced(id)){ - return dictionary.get(isreplacedby.get(id)); - } - return dictionary.get(id); - } - - /** if ChemComp is replacing another one, get the old version - * otherwise return the same ChemComp again. - * @param c the ChemComp for which older versions should be looked up. - */ - - public ChemComp getReplaced(ChemComp c){ - return getReplaced(c.getId()); - } - public ChemComp getReplaced(String id){ - if (isReplacer(id)){ - return dictionary.get(replaces.get(id)); - } - return dictionary.get(id); - } - - /** Get the parent of a component. If component has no parent, return null - * - * @param c - * @return get the parent component or null if ChemComp has no parent. - */ - public ChemComp getParent(ChemComp c){ - - if (c.hasParent()){ - return dictionary.get(c.getMon_nstd_parent_comp_id()); - } - return null; - } - - - - /** add a new component to the dictionary - * - * @param comp - */ - public void addChemComp(ChemComp comp){ - - dictionary.put(comp.getId(),comp); - String rep = comp.getPdbx_replaces(); - if ( (rep != null) && ( ! rep.equals("?"))){ - replaces.put(comp.getId(),rep); - } - - String isrep = comp.getPdbx_replaced_by(); - if ( (isrep != null) && ( ! isrep.equals("?"))){ - isreplacedby.put(comp.getId(),isrep); - } - } - - /** Returns the number of ChemComps in this dictionary - * - * @return nr. of ChemComps - */ - public int size(){ - - return dictionary.size(); - - } - - public ChemComp getChemComp(String id){ - return dictionary.get(id); - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/DownloadChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/DownloadChemCompProvider.java deleted file mode 100644 index 86355e40b6..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/DownloadChemCompProvider.java +++ /dev/null @@ -1,507 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.net.URL; -import java.net.URLConnection; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.zip.GZIPOutputStream; - -import org.biojava.nbio.core.util.InputStreamProvider; -import org.biojava.nbio.structure.align.util.URLConnectionTools; -import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.LocalPDBDirectory; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - - -/** - * This provider of chemical components can download and cache chemical component definition files from the RCSB PDB web site. - * It is the default way to access these definitions. - * If this provider is called he first time, it will download and install all chemical - * component definitions in a local directory. - * Once the definition files have been installed, it has quick startup time and low memory requirements. - * - * An alternative provider, that keeps all definitions in memory is the {@link AllChemCompProvider}. Another provider, that - * does not require any network access, but only can support a limited set of chemical component definitions, is the {@link ReducedChemCompProvider}. - * - * - * @author Andreas Prlic - * - */ -public class DownloadChemCompProvider implements ChemCompProvider { - - private static final Logger logger = LoggerFactory.getLogger(DownloadChemCompProvider.class); - - public static final String CHEM_COMP_CACHE_DIRECTORY = "chemcomp"; - - public static final String DEFAULT_SERVER_URL = "http://files.rcsb.org/ligands/download/"; - - public static String serverBaseUrl = DEFAULT_SERVER_URL; - - /** - * Use default RCSB server layout (true) or internal RCSB server layout (false) - */ - public static boolean useDefaultUrlLayout = true; - - - private static File path; - //private static final String FILE_SEPARATOR = System.getProperty("file.separator"); - private static final String NEWLINE = System.getProperty("line.separator"); - - - // flags to make sure there is only one thread running that is loading the dictionary - static AtomicBoolean loading = new AtomicBoolean(false); - - static final List protectedIDs = new ArrayList (); - static { - protectedIDs.add("CON"); - protectedIDs.add("PRN"); - protectedIDs.add("AUX"); - protectedIDs.add("NUL"); - } - - private static ChemCompProvider fallback = null; // Fallback provider if the download fails - - /** by default we will download only some of the files. User has to request that all files should be downloaded... - * - */ - boolean downloadAll = false; - - public DownloadChemCompProvider(){ - this(null); - } - - public DownloadChemCompProvider(String cacheFilePath){ - logger.debug("Initialising DownloadChemCompProvider"); - - // note that path is static, so this is just to make sure that all non-static methods will have path initialised - if(cacheFilePath != null) { - path = new File(cacheFilePath); - } - } - - /** - * Get this provider's cache path - * @return - */ - public static File getPath(){ - if (path==null) { - UserConfiguration config = new UserConfiguration(); - path = new File(config.getCacheFilePath()); - } - return path; - } - - /** - * Checks if the chemical components already have been installed into the PDB directory. - * If not, will download the chemical components definitions file and split it up into small - * subfiles. - */ - public void checkDoFirstInstall(){ - - if ( ! downloadAll ) { - return; - } - - - // this makes sure there is a file separator between every component, - // if path has a trailing file separator or not, it will work for both cases - File dir = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); - File f = new File(dir, "components.cif.gz"); - - if ( ! f.exists()) { - - downloadAllDefinitions(); - - } else { - // file exists.. did it get extracted? - - FilenameFilter filter =new FilenameFilter() { - - @Override - public boolean accept(File dir, String file) { - return file.endsWith(".cif.gz"); - } - }; - String[] files = dir.list(filter); - if ( files.length < 500) { - // not all did get unpacked - try { - split(); - } catch (IOException e) { - logger.error("Could not split file {} into individual chemical component files. Error: {}", - f.toString(), e.getMessage()); - } - } - } - } - - private void split() throws IOException { - - logger.info("Installing individual chem comp files ..."); - - File dir = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); - File f = new File(dir, "components.cif.gz"); - - - int counter = 0; - InputStreamProvider prov = new InputStreamProvider(); - - try( BufferedReader buf = new BufferedReader (new InputStreamReader (prov.getInputStream(f))); - ) { - String line = null; - line = buf.readLine (); - StringWriter writer = new StringWriter(); - - String currentID = null; - while (line != null){ - - if ( line.startsWith("data_")) { - // a new record found! - - if ( currentID != null) { - writeID(writer.toString(), currentID); - counter++; - } - - currentID = line.substring(5); - writer = new StringWriter(); - } - - writer.append(line); - writer.append(NEWLINE); - - line = buf.readLine (); - } - - // write the last record... - writeID(writer.toString(),currentID); - counter++; - - } - - logger.info("Created " + counter + " chemical component files."); - } - - /** - * Output chemical contents to a file - * @param contents File contents - * @param currentID Chemical ID, used to determine the filename - * @throws IOException - */ - private void writeID(String contents, String currentID) throws IOException{ - - String localName = getLocalFileName(currentID); - - try ( PrintWriter pw = new PrintWriter(new GZIPOutputStream(new FileOutputStream(localName))) ) { - - pw.print(contents); - pw.flush(); - } - } - - /** - * Loads the definitions for this {@link ChemComp} from a local file and instantiates a new object. - * - * @param recordName the ID of the {@link ChemComp} - * @return a new {@link ChemComp} definition. - */ - @Override - public ChemComp getChemComp(String recordName) { - - // make sure we work with upper case records - recordName = recordName.toUpperCase().trim(); - - boolean haveFile = true; - if ( recordName.equals("?")){ - return null; - } - - if ( ! fileExists(recordName)) { - // check if we should install all components - checkDoFirstInstall(); - } - if ( ! fileExists(recordName)) { - // we previously have installed already the definitions, - // just do an incrememntal update - haveFile = downloadChemCompRecord(recordName); - } - - // Added check that download was successful and chemical component is available. - if (haveFile) { - String filename = getLocalFileName(recordName); - InputStream inStream = null; - try { - - InputStreamProvider isp = new InputStreamProvider(); - - inStream = isp.getInputStream(filename); - - MMcifParser parser = new SimpleMMcifParser(); - - ChemCompConsumer consumer = new ChemCompConsumer(); - - // The Consumer builds up the BioJava - structure object. - // you could also hook in your own and build up you own data model. - parser.addMMcifConsumer(consumer); - - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - - ChemicalComponentDictionary dict = consumer.getDictionary(); - - ChemComp chemComp = dict.getChemComp(recordName); - - // May be null if the file was corrupt. Fall back on ReducedChemCompProvider in that case - if(chemComp != null) { - return chemComp; - } - - } catch (IOException e) { - - logger.warn( - "Could not download chemical component file {} for {}. Error: {}. Now trying to use the local chemical component definitions.", - filename, recordName, e.getMessage()); - - } - finally{ - // Now close it - if(inStream!=null){ - try { - inStream.close(); - } catch (IOException e) { - // This would be weird... - logger.error("Could not close chemical component file {}. A resource leak could occur!!", filename); - } - } - - } - } - - // see https://github.com/biojava/biojava/issues/315 - // probably a network error happened. Try to use the ReducedChemCOmpProvider - if( fallback == null) { - fallback = new ReducedChemCompProvider(); - } - - logger.warn("Falling back to ReducedChemCompProvider for {}. This could indicate a network error.", recordName); - return fallback.getChemComp(recordName); - - } - - /** - * Returns the file name that contains the definition for this {@link ChemComp} - * - * @param recordName the ID of the {@link ChemComp} - * @return full path to the file - */ - public static String getLocalFileName(String recordName){ - - if ( protectedIDs.contains(recordName)){ - recordName = "_" + recordName; - } - - File f = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); - if (! f.exists()){ - logger.info("Creating directory " + f); - - boolean success = f.mkdir(); - // we've checked in initPath that path is writable, so there's no need to check if it succeeds - // in the unlikely case that in the meantime it isn't writable at least we log an error - if (!success) - logger.error("Directory {} could not be created",f); - - } - - File theFile = new File(f,recordName + ".cif.gz"); - - return theFile.toString(); - } - - private static boolean fileExists(String recordName){ - - String fileName = getLocalFileName(recordName); - - File f = new File(fileName); - - // delete files that are too short to have contents - if( f.length() < LocalPDBDirectory.MIN_PDB_FILE_SIZE ) { - // Delete defensively. - // Note that if delete is unsuccessful, we re-download the file anyways - f.delete(); - return false; - } - - return f.exists(); - - } - - /** - * @param recordName : three-letter name - * @return true if successful download - */ - private static boolean downloadChemCompRecord(String recordName) { - - String localName = getLocalFileName(recordName); - File newFile; - try{ - newFile = File.createTempFile("chemcomp"+recordName, "cif"); - logger.debug("Will write chem comp file to temp file {}", newFile.toString()); - } - catch(IOException e){ - logger.error("Could not write to temp directory {} to create the chemical component download temp file", System.getProperty("java.io.tmpdir")); - return false; - } - String u; - if(useDefaultUrlLayout){ - u = serverBaseUrl + recordName + ".cif"; - } - else{ - u = serverBaseUrl + recordName.charAt(0) + "/" + recordName +"/" + recordName + ".cif"; - } - - logger.debug("downloading " + u); - - URL url = null; - - - try { - url = new URL(u); - URLConnection uconn = URLConnectionTools.openURLConnection(url); - - try( PrintWriter pw = new PrintWriter(new GZIPOutputStream(new FileOutputStream(newFile))); - BufferedReader fileBuffer = new BufferedReader(new InputStreamReader(uconn.getInputStream())); - ) { - - String line; - - while ((line = fileBuffer.readLine()) != null) { - pw.println(line); - } - - pw.flush(); - } - // Now we move this across to where it actually wants to be - Files.move(newFile.toPath(), Paths.get(localName), StandardCopyOption.REPLACE_EXISTING); - - return true; - } catch (IOException e){ - logger.error("Could not download "+url.toString()+" OR store locally to "+localName+" Error ="+e.getMessage()); - newFile.delete(); - } - return false; - } - - private void downloadAllDefinitions() { - - if ( loading.get()){ - logger.info("Waiting for other thread to install chemical components..."); - } - - while ( loading.get() ) { - - // another thread is already downloading the components definitions - // wait for the other thread to finish... - - try { - // wait half a second - - Thread.sleep(500); - } catch (InterruptedException e) { - //e.printStackTrace(); - logger.error("Thread interrupted "+e.getMessage()); - } - - logger.info("Another thread installed the chemical components."); - return; - - } - - loading.set(true); - long timeS = System.currentTimeMillis(); - - logger.info("Performing first installation of chemical components."); - logger.info("Downloading components.cif.gz ..."); - - - try { - AllChemCompProvider.downloadFile(); - } catch (IOException e){ - logger.error("Could not download the all chemical components file. Error: {}. " - + "Chemical components information won't be available", e.getMessage()); - // no point in trying to split if the file could not be downloaded - loading.set(false); - return; - } - try { - split(); - } catch (IOException e) { - logger.error("Could not split all chem comp file into individual chemical component files. Error: {}", - e.getMessage()); - // no point in reporting time - loading.set(false); - return; - } - long timeE = System.currentTimeMillis(); - logger.info("time to install chem comp dictionary: " + (timeE - timeS) / 1000 + " sec."); - loading.set(false); - - } - - /** By default this provider will download only some of the {@link ChemComp} files. - * The user has to request that all files should be downloaded by setting this parameter to true. - * - * @return flag if the all components should be downloaded and installed at startup. (default: false) - */ - public boolean isDownloadAll() { - return downloadAll; - } - - /** By default this provider will download only some of the {@link ChemComp} files. - * The user has to request that all files should be downloaded by setting this parameter to true. - * - * @param flag if the all components should be downloaded and installed at startup. (default: false) - */ - public void setDownloadAll(boolean downloadAll) { - this.downloadAll = downloadAll; - } - - - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMCIFFileTools.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMCIFFileTools.java deleted file mode 100644 index 14fdac7d3e..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMCIFFileTools.java +++ /dev/null @@ -1,575 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - - -import java.lang.reflect.Field; -import java.util.*; - -import org.biojava.nbio.structure.Atom; -import org.biojava.nbio.structure.Chain; -import org.biojava.nbio.structure.Element; -import org.biojava.nbio.structure.EntityType; -import org.biojava.nbio.structure.Group; -import org.biojava.nbio.structure.GroupType; -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.io.FileConvert; -import org.biojava.nbio.structure.io.mmcif.model.AbstractBean; -import org.biojava.nbio.structure.io.mmcif.model.AtomSite; -import org.biojava.nbio.structure.io.mmcif.model.CIFLabel; -import org.biojava.nbio.structure.io.mmcif.model.Cell; -import org.biojava.nbio.structure.io.mmcif.model.IgnoreField; -import org.biojava.nbio.structure.io.mmcif.model.Symmetry; -import org.biojava.nbio.structure.xtal.CrystalCell; -import org.biojava.nbio.structure.xtal.SpaceGroup; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Some tools for mmCIF file writing. - * - * See http://www.iucr.org/__data/assets/pdf_file/0019/22618/cifguide.pdf - * - * CIF categories are represented as a simple bean, typically extending {@link AbstractBean}. - * By default, all fields from the bean are taken as the CIF labels. Fields - * may be omitted by annotating them as {@link IgnoreField @IgnoreField}. - * The CIF label for a field may be changed (for instance, for fields that - * are not valid Java identifiers) by defining a function - * static Map getCIFLabelMap() - * mapping from the field's name to the correct label. - * - * @author Jose Duarte - * @author Spencer Bliven - */ -public class MMCIFFileTools { - - private static final Logger logger = LoggerFactory.getLogger(MMCIFFileTools.class); - - private static final String newline = System.getProperty("line.separator"); - - /** - * The character to be printed out in cases where a value is not assigned in mmCIF files - */ - public static final String MMCIF_MISSING_VALUE = "?"; - - /** - * The character to be printed out as a default value in mmCIF files, e.g. for the default alt_locs - */ - public static final String MMCIF_DEFAULT_VALUE = "."; - - - /** - * Produces a mmCIF loop header string for the given categoryName and className. - * className must be one of the beans in the {@link org.biojava.nbio.structure.io.mmcif.model} package - * @param categoryName - * @param className - * @return - * @throws ClassNotFoundException if the given className can not be found - */ - public static String toLoopMmCifHeaderString(String categoryName, String className) throws ClassNotFoundException { - StringBuilder str = new StringBuilder(); - - str.append(SimpleMMcifParser.LOOP_START+newline); - - Class c = Class.forName(className); - - for (Field f : getFields(c)) { - str.append(categoryName+"."+f.getName()+newline); - } - - return str.toString(); - } - - /** - * Converts a mmCIF bean (see {@link org.biojava.nbio.structure.io.mmcif.model} to - * a String representing it in mmCIF (single-record) format. - * @param categoryName - * @param o - * @return - */ - public static String toMMCIF(String categoryName, Object o) { - - StringBuilder sb = new StringBuilder(); - - Class c = o.getClass(); - - - Field[] fields = getFields(c); - String[] names = getFieldNames(fields); - - int maxFieldNameLength = getMaxStringLength(names); - - for (int i=0;i c) { - Field[] allFields = c.getDeclaredFields(); - Field[] fields = new Field[allFields.length]; - int n = 0; - for(Field f : allFields) { - f.setAccessible(true); - IgnoreField anno = f.getAnnotation(IgnoreField.class); - if(anno == null) { - fields[n] = f; - n++; - } - } - return Arrays.copyOf(fields, n); - } - - /** - * Gets the mmCIF record name for each field. This is generally just - * the name of the field or the value specified by the {@link CIFLabel @CIFLabel} annotation. - * - * As a side effect, calls {@link Field#setAccessible(boolean) setAccessible(true)} - * on all fields. - * @param fields - * @return - */ - public static String[] getFieldNames(Field[] fields) { - String[] names = new String[fields.length]; - for(int i=0;i String toMMCIF(List list, Class klass) { - if (list.isEmpty()) throw new IllegalArgumentException("List of beans is empty!"); - - Field[] fields = getFields(klass); - int[] sizes = getFieldSizes(list,fields); - - StringBuilder sb = new StringBuilder(); - - for (T o:list) { - sb.append(toSingleLoopLineMmCifString(o, fields, sizes)); - } - - sb.append(SimpleMMcifParser.COMMENT_CHAR+newline); - - return sb.toString(); - } - - /** - * Given a mmCIF bean produces a String representing it in mmCIF loop format as a single record line - * @param record - * @param fields Set of fields for the record. If null, will be calculated from the class of the record - * @param sizes the size of each of the fields - * @return - */ - private static String toSingleLoopLineMmCifString(Object record, Field[] fields, int[] sizes) { - - StringBuilder str = new StringBuilder(); - - Class c = record.getClass(); - - if(fields == null) - fields = getFields(c); - - if (sizes.length!=fields.length) - throw new IllegalArgumentException("The given sizes of fields differ from the number of declared fields"); - - int i = -1; - for (Field f : fields) { - i++; - f.setAccessible(true); - - try { - Object obj = f.get(record); - String val; - if (obj==null) { - logger.debug("Field {} is null, will write it out as {}",f.getName(),MMCIF_MISSING_VALUE); - val = MMCIF_MISSING_VALUE; - } else { - val = (String) obj; - } - - str.append(String.format("%-"+sizes[i]+"s ", addMmCifQuoting(val))); - - - } catch (IllegalAccessException e) { - logger.warn("Field {} is inaccessible", f.getName()); - continue; - } catch (ClassCastException e) { - logger.warn("Could not cast value to String for field {}",f.getName()); - continue; - } - } - - str.append(newline); - - return str.toString(); - - } - - /** - * Adds quoting to a String according to the STAR format (mmCIF) rules - * @param val - * @return - */ - private static String addMmCifQuoting(String val) { - String newval; - - if (val.contains("'")) { - // double quoting for strings containing single quotes (not strictly necessary but it's what the PDB usually does) - newval = "\""+val+"\""; - } else if (val.contains(" ")) { - // single quoting for stings containing spaces - newval = "'"+val+"'"; - } else { - if (val.contains(" ") && val.contains("'")) { - // TODO deal with this case - logger.warn("Value contains both spaces and single quotes, won't format it: {}. CIF ouptut will likely be invalid.",val); - } - newval = val; - } - // TODO deal with all the other cases: e.g. multi-line quoting with ;; - - return newval; - } - - /** - * Converts a SpaceGroup object to a {@link Symmetry} object. - * @param sg - * @return - */ - public static Symmetry convertSpaceGroupToSymmetry(SpaceGroup sg) { - Symmetry sym = new Symmetry(); - sym.setSpace_group_name_H_M(sg.getShortSymbol()); - // TODO do we need to fill any of the other values? - return sym; - } - - /** - * Converts a CrystalCell object to a {@link Cell} object. - * @param c - * @return - */ - public static Cell convertCrystalCellToCell(CrystalCell c) { - Cell cell = new Cell(); - cell.setLength_a(String.format("%.3f",c.getA())); - cell.setLength_b(String.format("%.3f",c.getB())); - cell.setLength_c(String.format("%.3f",c.getC())); - cell.setAngle_alpha(String.format("%.3f",c.getAlpha())); - cell.setAngle_beta(String.format("%.3f",c.getBeta())); - cell.setAngle_gamma(String.format("%.3f",c.getGamma())); - - return cell; - } - - /** - * Converts an Atom object to an {@link AtomSite} object. - * @param a - * @param model the model number for the output AtomSites - * @param chainName the chain identifier (author id) for the output AtomSites - * @param chainId the internal chain identifier (asym id) for the output AtomSites - * @return - */ - public static AtomSite convertAtomToAtomSite(Atom a, int model, String chainName, String chainId) { - return convertAtomToAtomSite(a, model, chainName, chainId, a.getPDBserial()); - } - - /** - * Converts an Atom object to an {@link AtomSite} object. - * @param a the atom - * @param model the model number for the output AtomSites - * @param chainName the chain identifier (author id) for the output AtomSites - * @param chainId the internal chain identifier (asym id) for the output AtomSites - * @param atomId the atom id to be written to AtomSite - * @return - */ - public static AtomSite convertAtomToAtomSite(Atom a, int model, String chainName, String chainId, int atomId) { - - /* - ATOM 7 C CD . GLU A 1 24 ? -10.109 15.374 38.853 1.00 50.05 ? ? ? ? ? ? 24 GLU A CD 1 - ATOM 8 O OE1 . GLU A 1 24 ? -9.659 14.764 37.849 1.00 49.80 ? ? ? ? ? ? 24 GLU A OE1 1 - ATOM 9 O OE2 . GLU A 1 24 ? -11.259 15.171 39.310 1.00 50.51 ? ? ? ? ? ? 24 GLU A OE2 1 - ATOM 10 N N . LEU A 1 25 ? -5.907 18.743 37.412 1.00 41.55 ? ? ? ? ? ? 25 LEU A N 1 - ATOM 11 C CA . LEU A 1 25 ? -5.168 19.939 37.026 1.00 37.55 ? ? ? ? ? ? 25 LEU A CA 1 - */ - - Group g = a.getGroup(); - - String record ; - if ( g.getType().equals(GroupType.HETATM) ) { - record = "HETATM"; - } else { - record = "ATOM"; - } - - String entityId = "0"; - String labelSeqId = Integer.toString(g.getResidueNumber().getSeqNum()); - if (g.getChain()!=null && g.getChain().getEntityInfo()!=null) { - entityId = Integer.toString(g.getChain().getEntityInfo().getMolId()); - if (g.getChain().getEntityInfo().getType() == EntityType.POLYMER) { - // this only makes sense for polymeric chains, non-polymer chains will never have seqres groups and there's no point in calling getAlignedResIndex - labelSeqId = Integer.toString(g.getChain().getEntityInfo().getAlignedResIndex(g, g.getChain())); - } - } - - Character altLoc = a.getAltLoc(); - String altLocStr; - if (altLoc==null || altLoc == ' ') { - altLocStr = MMCIF_DEFAULT_VALUE; - } else { - altLocStr = altLoc.toString(); - } - - Element e = a.getElement(); - String eString = e.toString().toUpperCase(); - if ( e.equals(Element.R)) { - eString = "X"; - } - - String insCode = MMCIF_MISSING_VALUE; - if (g.getResidueNumber().getInsCode()!=null ) { - insCode = Character.toString(g.getResidueNumber().getInsCode()); - } - - AtomSite atomSite = new AtomSite(); - atomSite.setGroup_PDB(record); - atomSite.setId(Integer.toString(atomId)); - atomSite.setType_symbol(eString); - atomSite.setLabel_atom_id(a.getName()); - atomSite.setLabel_alt_id(altLocStr); - atomSite.setLabel_comp_id(g.getPDBName()); - atomSite.setLabel_asym_id(chainId); - atomSite.setLabel_entity_id(entityId); - atomSite.setLabel_seq_id(labelSeqId); - atomSite.setPdbx_PDB_ins_code(insCode); - atomSite.setCartn_x(FileConvert.d3.format(a.getX())); - atomSite.setCartn_y(FileConvert.d3.format(a.getY())); - atomSite.setCartn_z(FileConvert.d3.format(a.getZ())); - atomSite.setOccupancy(FileConvert.d2.format(a.getOccupancy())); - atomSite.setB_iso_or_equiv(FileConvert.d2.format(a.getTempFactor())); - atomSite.setAuth_seq_id(Integer.toString(g.getResidueNumber().getSeqNum())); - atomSite.setAuth_comp_id(g.getPDBName()); - atomSite.setAuth_asym_id(chainName); - atomSite.setAuth_atom_id(a.getName()); - atomSite.setPdbx_PDB_model_num(Integer.toString(model)); - - return atomSite; - } - - /** - * Converts a Group into a List of {@link AtomSite} objects. - * Atoms in other altloc groups (different from the main group) are also included, removing possible duplicates - * via using the atom identifier to assess uniqueness. - * @param g the group - * @param model the model number for the output AtomSites - * @param chainName the chain identifier (author id) for the output AtomSites - * @param chainId the internal chain identifier (asym id) for the output AtomSites - * @return - */ - public static List convertGroupToAtomSites(Group g, int model, String chainName, String chainId) { - - // The alt locs can have duplicates, since at parsing time we make sure that all alt loc groups have - // all atoms (see StructureTools#cleanUpAltLocs) - // Thus we have to remove duplicates here by using the atom id - // See issue https://github.com/biojava/biojava/issues/778 and TestAltLocs.testMmcifWritingAllAltlocs/testMmcifWritingPartialAltlocs - Map uniqueAtomSites = new LinkedHashMap<>(); - - int groupsize = g.size(); - - for ( int atompos = 0 ; atompos < groupsize; atompos++) { - Atom a = g.getAtom(atompos); - if ( a == null) - continue ; - - uniqueAtomSites.put(a.getPDBserial(), convertAtomToAtomSite(a, model, chainName, chainId)); - } - - if ( g.hasAltLoc()){ - for (Group alt : g.getAltLocs() ) { - for (AtomSite atomSite : convertGroupToAtomSites(alt, model, chainName, chainId)) { - uniqueAtomSites.put(Integer.parseInt(atomSite.getId()), atomSite); - } - } - } - return new ArrayList<>(uniqueAtomSites.values()); - } - - /** - * Converts a Chain into a List of {@link AtomSite} objects - * @param c the chain - * @param model the model number for the output AtomSites - * @param chainName the chain identifier (author id) for the output AtomSites - * @param chainId the internal chain identifier (asym id) for the output AtomSites - * @return - */ - public static List convertChainToAtomSites(Chain c, int model, String chainName, String chainId) { - - List list = new ArrayList<>(); - - if (c.getEntityInfo()==null) { - logger.warn("No entity found for chain {}: entity_id will be set to 0, label_seq_id will be the same as auth_seq_id", c.getName()); - } - - for ( int h=0; h convertStructureToAtomSites(Structure s) { - List list = new ArrayList(); - - for (int m=0;m int[] getFieldSizes(List list, Field[] fields) { - - if (list.isEmpty()) throw new IllegalArgumentException("List of beans is empty!"); - - if(fields == null) - fields = getFields(list.get(0).getClass()); - - int[] sizes = new int [fields.length]; - - - for (T a:list) { - int i = -1; - for (Field f : fields) { - i++; - - f.setAccessible(true); - - try { - Object obj = f.get(a); - int length; - if (obj==null) { - length = MMCIF_MISSING_VALUE.length(); - } else { - String val = (String) obj; - length = addMmCifQuoting(val).length(); - } - - if (length>sizes[i]) sizes[i] = length; - - } catch (IllegalAccessException e) { - logger.warn("Field {} is inaccessible", f.getName()); - continue; - } catch (ClassCastException e) { - logger.warn("Could not cast value to String for field {}",f.getName()); - continue; - } - } - } - return sizes; - } - - /** - * Finds the max length of a list of strings - * Useful for producing mmCIF single-record data that is aligned for all values. - * @param names - * @return - * @see #toMMCIF(String, Object) - */ - private static int getMaxStringLength(String[] names) { - int size = 0; - for(String s : names) { - if(s.length()>size) { - size = s.length(); - } - } - return size; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMcifConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMcifConsumer.java deleted file mode 100644 index 9284c2ad31..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMcifConsumer.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Mar 4, 2008 - */ -package org.biojava.nbio.structure.io.mmcif; - -import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.model.*; - -import java.util.List; - -/** An interface for the events triggered by a MMcifParser. - * The Consumer listens to the events and builds up the protein structure. - * - * @author Andreas Prlic - * @since 1.7 - * - */ -public interface MMcifConsumer { - /** called at start of document - * - */ - public void documentStart(); - - /** called at end of document - * - */ - public void documentEnd(); - - - /** A new AtomSite record has been read. Contains the Atom data - * - * @param atom - */ - public void newAtomSite(AtomSite atom); - public void newEntity(Entity entity); - public void newEntityPoly(EntityPoly entityPoly); - public void newEntityPolySeq(EntityPolySeq epolseq); - public void newStructAsym(StructAsym sasym); - public void setStruct(Struct struct); - public void newDatabasePDBrev(DatabasePDBrev dbrev); - public void newDatabasePDBrevRecord(DatabasePdbrevRecord dbrev); - public void newDatabasePDBremark(DatabasePDBremark remark); - public void newExptl(Exptl exptl); - public void newCell(Cell cell); - public void newSymmetry(Symmetry symmetry); - public void newStructNcsOper(StructNcsOper sNcsOper); - public void newAtomSites(AtomSites atomSites); - public void newStructRef(StructRef sref); - public void newStructRefSeq(StructRefSeq sref); - public void newStructRefSeqDif(StructRefSeqDif sref); - public void newStructSite(StructSite sref); - public void newStructSiteGen(StructSiteGen sref); - public void newPdbxAuditRevisionHistory(PdbxAuditRevisionHistory history); - public void newPdbxDatabaseStatus(PdbxDatabaseStatus status); - public void newPdbxPolySeqScheme(PdbxPolySeqScheme ppss); - public void newPdbxNonPolyScheme(PdbxNonPolyScheme ppss); - public void newPdbxEntityNonPoly(PdbxEntityNonPoly pen); - public void newStructKeywords(StructKeywords kw); - public void newRefine(Refine r); - public void newChemComp(ChemComp c); - public void newChemCompDescriptor(ChemCompDescriptor ccd); - public void newPdbxStructOperList(PdbxStructOperList structOper); - public void newPdbxStrucAssembly(PdbxStructAssembly strucAssembly); - public void newPdbxStrucAssemblyGen(PdbxStructAssemblyGen strucAssembly); - public void newChemCompAtom(ChemCompAtom atom); - public void newPdbxChemCompIndentifier(PdbxChemCompIdentifier id); - public void newChemCompBond(ChemCompBond bond); - public void newPdbxChemCompDescriptor(PdbxChemCompDescriptor desc); - public void newEntitySrcGen(EntitySrcGen entitySrcGen); - public void newEntitySrcNat(EntitySrcNat entitySrcNat); - public void newEntitySrcSyn(EntitySrcSyn entitySrcSyn); - public void newStructConn(StructConn structConn); - - /** AuditAuthor contains the info from the PDB-AUTHOR records. - * - * @param aa - */ - public void newAuditAuthor(AuditAuthor aa); - - /** This method is called if no particular handler for the provided cif category - * has been implemented so far. - * @param category The category that is being processed. - * @param loopFields the fields of this category. - * @param lineData the data that is being provided. - */ - public void newGenericData(String category, List loopFields, List lineData); - - public void setFileParsingParameters(FileParsingParameters params); - public FileParsingParameters getFileParsingParameters(); - - - - - - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMcifParser.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMcifParser.java deleted file mode 100644 index e20a35d87c..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MMcifParser.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Mar 4, 2008 - */ -package org.biojava.nbio.structure.io.mmcif; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; - -/** Interface that needs to be implemented by an MMcifParser - * - * @author Andreas Prlic - * @since 1.7 - */ -public interface MMcifParser { - - /** Add a MMcifConsumer that listens to even being triggered by the parser and processes the data into a backend provided by the Consumer. - * - * @param consumer a consumer object. - */ - public void addMMcifConsumer(MMcifConsumer consumer); - - /** Remove all consumers from the parser. - * - */ - public void clearConsumers(); - - /** remove a single consumer from the parser - * - * @param consumer - */ - public void removeMMcifConsumer(MMcifConsumer consumer); - - - /** Start the actual parsing. The parser will trigger events that are defined by the MMcifConsumer class. - * - * @param buf a BufferedReader. - */ - public void parse(BufferedReader buf) throws IOException; - - /** Start the actual parsing. The parser will trigger events that are defined by the MMcifConsumer class. - * - * @param inStream InputStream to parse from. - */ - public void parse(InputStream inStream) throws IOException; - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MetalBondConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MetalBondConsumer.java deleted file mode 100644 index dbb91bd71f..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MetalBondConsumer.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - -import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.chem.MetalBondDistance; -import org.biojava.nbio.structure.io.mmcif.model.*; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by andreas on 6/9/16. - */ -public class MetalBondConsumer implements MMcifConsumer{ - - - Map> definitions = new HashMap<>(); - - @Override - public void documentStart() { - definitions.clear(); - } - - @Override - public void documentEnd() { - - // minimize memory consumption - - for (List d : definitions.values()){ - ArrayList a = (ArrayList)d; - - a.trimToSize(); - } - - } - - @Override - public void newAtomSite(AtomSite atom) { - - } - - @Override - public void newEntity(Entity entity) { - - } - - @Override - public void newEntityPoly(EntityPoly entityPoly) { - - } - - @Override - public void newEntityPolySeq(EntityPolySeq epolseq) { - - } - - @Override - public void newStructAsym(StructAsym sasym) { - - } - - @Override - public void setStruct(Struct struct) { - - } - - @Override - public void newDatabasePDBrev(DatabasePDBrev dbrev) { - - } - - @Override - public void newDatabasePDBrevRecord(DatabasePdbrevRecord dbrev) { - - } - - @Override - public void newDatabasePDBremark(DatabasePDBremark remark) { - - } - - @Override - public void newExptl(Exptl exptl) { - - } - - @Override - public void newCell(Cell cell) { - - } - - @Override - public void newSymmetry(Symmetry symmetry) { - - } - - @Override - public void newStructNcsOper(StructNcsOper sNcsOper) { - - } - - @Override - public void newAtomSites(AtomSites atomSites) { - - } - - @Override - public void newStructRef(StructRef sref) { - - } - - @Override - public void newStructRefSeq(StructRefSeq sref) { - - } - - @Override - public void newStructRefSeqDif(StructRefSeqDif sref) { - - } - - @Override - public void newStructSite(StructSite sref) { - - } - - @Override - public void newStructSiteGen(StructSiteGen sref) { - - } - - @Override - public void newPdbxPolySeqScheme(PdbxPolySeqScheme ppss) { - - } - - @Override - public void newPdbxNonPolyScheme(PdbxNonPolyScheme ppss) { - - } - - @Override - public void newPdbxEntityNonPoly(PdbxEntityNonPoly pen) { - - } - - @Override - public void newStructKeywords(StructKeywords kw) { - - } - - @Override - public void newRefine(Refine r) { - - } - - @Override - public void newChemComp(ChemComp c) { - - } - - @Override - public void newChemCompDescriptor(ChemCompDescriptor ccd) { - - } - - @Override - public void newPdbxStructOperList(PdbxStructOperList structOper) { - - } - - @Override - public void newPdbxStrucAssembly(PdbxStructAssembly strucAssembly) { - - } - - @Override - public void newPdbxStrucAssemblyGen(PdbxStructAssemblyGen strucAssembly) { - - } - - @Override - public void newChemCompAtom(ChemCompAtom atom) { - - } - - @Override - public void newPdbxChemCompIndentifier(PdbxChemCompIdentifier id) { - - } - - @Override - public void newChemCompBond(ChemCompBond bond) { - - } - - @Override - public void newPdbxChemCompDescriptor(PdbxChemCompDescriptor desc) { - - } - - @Override - public void newEntitySrcGen(EntitySrcGen entitySrcGen) { - - } - - @Override - public void newEntitySrcNat(EntitySrcNat entitySrcNat) { - - } - - @Override - public void newEntitySrcSyn(EntitySrcSyn entitySrcSyn) { - - } - - @Override - public void newStructConn(StructConn structConn) { - - } - - @Override - public void newAuditAuthor(AuditAuthor aa) { - - } - - @Override - public void newGenericData(String category, List loopFields, List lineData) { - - MetalBondDistance d = new MetalBondDistance(); - - d.setAtomType1(lineData.get(0)); - d.setAtomType2(lineData.get(1)); - d.setLowerLimit(Float.parseFloat(lineData.get(2))); - d.setUpperLimit(Float.parseFloat(lineData.get(3))); - - List defs = definitions.get(d.getAtomType1()); - - if ( defs == null){ - defs = new ArrayList<>(); - definitions.put(d.getAtomType1(),defs); - } - - defs.add(d); - - } - - @Override - public void setFileParsingParameters(FileParsingParameters params) { - - } - - @Override - public FileParsingParameters getFileParsingParameters() { - return null; - } - - public Map> getDefinitions(){ - return definitions; - } - - @Override - public void newPdbxAuditRevisionHistory(PdbxAuditRevisionHistory history) { - // TODO Auto-generated method stub - - } - - @Override - public void newPdbxDatabaseStatus(PdbxDatabaseStatus status) { - // TODO Auto-generated method stub - - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MetalBondParser.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MetalBondParser.java deleted file mode 100644 index 03d6789c5c..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/MetalBondParser.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - -import org.biojava.nbio.structure.io.mmcif.chem.MetalBondDistance; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.InputStream; -import java.util.*; - -import java.util.zip.GZIPInputStream; - -/** - * Created by andreas on 6/6/16. - */ -public class MetalBondParser { - - private static final Logger logger = LoggerFactory.getLogger(MetalBondParser.class); - - private static final String BONDS_FILE = "org/biojava/nbio/structure/bond_distance_limits.cif.gz"; - - - static Map> definitions; - - static { - definitions = init(); - } - - - public static Map> getMetalBondDefinitions(){ - return definitions; - - } - - - private static Map> init(){ - - InputStream inputStream = MetalBondParser.class.getClassLoader().getResourceAsStream(BONDS_FILE); - - if (inputStream == null) { - throw new RuntimeException("Could not find resource "+BONDS_FILE+". This probably means that your biojava.jar file is corrupt or incorrectly built."); - } - - try { - GZIPInputStream gzIS = new GZIPInputStream(inputStream); - - SimpleMMcifParser parser = new SimpleMMcifParser(); - - MetalBondConsumer consumer = new MetalBondConsumer(); - parser.addMMcifConsumer(consumer); - - parser.parse(gzIS); - - Map> defs = consumer.getDefinitions(); - - return defs; - - } catch ( Exception e){ - logger.error(e.getMessage(),e); - - } - return null; - } - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ReducedChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ReducedChemCompProvider.java deleted file mode 100644 index 0d752cea04..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ReducedChemCompProvider.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.zip.GZIPInputStream; - -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** Unlike the {@link DownloadChemCompProvider}, this {@link ChemCompProvider} does not download any chem comp definitions. - * It has access to a limited set of files that are part of the biojava distribution. - * - * @author Andreas Prlic - * @since 3.0 - */ -public class ReducedChemCompProvider implements ChemCompProvider { - - private static final Logger logger = LoggerFactory.getLogger(ReducedChemCompProvider.class); - - public ReducedChemCompProvider(){ - logger.debug("Initialising ReducedChemCompProvider"); - } - - - @Override - public ChemComp getChemComp(String recordName) { - String name = recordName.toUpperCase().trim(); - try(InputStream inStream = this.getClass().getResourceAsStream("/chemcomp/"+name + ".cif.gz")) { - - logger.debug("Reading chemcomp/"+name+".cif.gz"); - - if ( inStream == null){ - //System.out.println("Could not find chem comp: " + name + " ... using generic Chem Comp"); - // could not find the chem comp definition for this in the jar file - logger.debug("Getting empty chem comp for {}",name); - ChemComp cc = ChemComp.getEmptyChemComp(); - cc.setId(name); - return cc; - } - - MMcifParser parser = new SimpleMMcifParser(); - - ChemCompConsumer consumer = new ChemCompConsumer(); - - // The Consumer builds up the BioJava - structure object. - // you could also hook in your own and build up you own data model. - parser.addMMcifConsumer(consumer); - - parser.parse(new BufferedReader(new InputStreamReader(new GZIPInputStream(inStream)))); - - ChemicalComponentDictionary dict = consumer.getDictionary(); - - ChemComp chemComp = dict.getChemComp(name); - - return chemComp; - - } catch (IOException e){ - logger.error("IOException caught while reading chem comp {}.",name,e); - } - logger.warn("Problem when loading chem comp {}, will use an empty chem comp for it", name); - ChemComp cc = ChemComp.getEmptyChemComp(); - cc.setId(name); - return cc; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/SimpleMMcifConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/SimpleMMcifConsumer.java deleted file mode 100644 index b0cdecdc14..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/SimpleMMcifConsumer.java +++ /dev/null @@ -1,2167 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Apr 26, 2008 - */ -package org.biojava.nbio.structure.io.mmcif; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import javax.vecmath.Matrix4d; - -import org.biojava.nbio.structure.AminoAcid; -import org.biojava.nbio.structure.AminoAcidImpl; -import org.biojava.nbio.structure.Atom; -import org.biojava.nbio.structure.AtomImpl; -import org.biojava.nbio.structure.Chain; -import org.biojava.nbio.structure.ChainImpl; -import org.biojava.nbio.structure.EntityInfo; -import org.biojava.nbio.structure.EntityType; -import org.biojava.nbio.structure.DBRef; -import org.biojava.nbio.structure.Element; -import org.biojava.nbio.structure.Group; -import org.biojava.nbio.structure.GroupType; -import org.biojava.nbio.structure.HetatomImpl; -import org.biojava.nbio.structure.NucleotideImpl; -import org.biojava.nbio.structure.PDBCrystallographicInfo; -import org.biojava.nbio.structure.PDBHeader; -import org.biojava.nbio.structure.ResidueNumber; -import org.biojava.nbio.structure.SeqMisMatch; -import org.biojava.nbio.structure.SeqMisMatchImpl; -import org.biojava.nbio.structure.Site; -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureImpl; -import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.io.BondMaker; -import org.biojava.nbio.structure.io.ChargeAdder; -import org.biojava.nbio.structure.io.EntityFinder; -import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.SeqRes2AtomAligner; -import org.biojava.nbio.structure.io.mmcif.model.AtomSite; -import org.biojava.nbio.structure.io.mmcif.model.AtomSites; -import org.biojava.nbio.structure.io.mmcif.model.AuditAuthor; -import org.biojava.nbio.structure.io.mmcif.model.Cell; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompAtom; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompBond; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompDescriptor; -import org.biojava.nbio.structure.io.mmcif.model.DatabasePDBremark; -import org.biojava.nbio.structure.io.mmcif.model.DatabasePDBrev; -import org.biojava.nbio.structure.io.mmcif.model.DatabasePdbrevRecord; -import org.biojava.nbio.structure.io.mmcif.model.Entity; -import org.biojava.nbio.structure.io.mmcif.model.EntityPoly; -import org.biojava.nbio.structure.io.mmcif.model.EntityPolySeq; -import org.biojava.nbio.structure.io.mmcif.model.EntitySrcGen; -import org.biojava.nbio.structure.io.mmcif.model.EntitySrcNat; -import org.biojava.nbio.structure.io.mmcif.model.EntitySrcSyn; -import org.biojava.nbio.structure.io.mmcif.model.Exptl; -import org.biojava.nbio.structure.io.mmcif.model.PdbxAuditRevisionHistory; -import org.biojava.nbio.structure.io.mmcif.model.PdbxChemCompDescriptor; -import org.biojava.nbio.structure.io.mmcif.model.PdbxChemCompIdentifier; -import org.biojava.nbio.structure.io.mmcif.model.PdbxDatabaseStatus; -import org.biojava.nbio.structure.io.mmcif.model.PdbxEntityNonPoly; -import org.biojava.nbio.structure.io.mmcif.model.PdbxNonPolyScheme; -import org.biojava.nbio.structure.io.mmcif.model.PdbxPolySeqScheme; -import org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssembly; -import org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssemblyGen; -import org.biojava.nbio.structure.io.mmcif.model.PdbxStructOperList; -import org.biojava.nbio.structure.io.mmcif.model.Refine; -import org.biojava.nbio.structure.io.mmcif.model.Struct; -import org.biojava.nbio.structure.io.mmcif.model.StructAsym; -import org.biojava.nbio.structure.io.mmcif.model.StructConn; -import org.biojava.nbio.structure.io.mmcif.model.StructKeywords; -import org.biojava.nbio.structure.io.mmcif.model.StructNcsOper; -import org.biojava.nbio.structure.io.mmcif.model.StructRef; -import org.biojava.nbio.structure.io.mmcif.model.StructRefSeq; -import org.biojava.nbio.structure.io.mmcif.model.StructRefSeqDif; -import org.biojava.nbio.structure.io.mmcif.model.StructSite; -import org.biojava.nbio.structure.io.mmcif.model.StructSiteGen; -import org.biojava.nbio.structure.io.mmcif.model.Symmetry; -import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; -import org.biojava.nbio.structure.quaternary.BiologicalAssemblyBuilder; -import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; -import org.biojava.nbio.structure.xtal.CrystalCell; -import org.biojava.nbio.structure.xtal.SpaceGroup; -import org.biojava.nbio.structure.xtal.SymoplibParser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A MMcifConsumer implementation that builds an in-memory representation of the - * content of a mmcif file as a BioJava Structure object. - * - * @author Andreas Prlic - * @since 1.7 - */ - -public class SimpleMMcifConsumer implements MMcifConsumer { - - private static final Logger logger = LoggerFactory.getLogger(SimpleMMcifConsumer.class); - - private Structure structure; - private Chain currentChain; - private Group currentGroup; - - /** - * A temporary data structure to hold all parsed chains - */ - private ArrayList> allModels; - /** - * The current set of chains per model - */ - private List currentModel; - private List entities; - /** - * Needed in header only mode to get mapping between asym ids and author ids - */ - private List entityPolys; - private List strucRefs; - private List seqResChains; - private List entityChains; // needed to link entities, chains and compounds... - private List structAsyms; // needed to link entities, chains and compounds... - private List structOpers ; // - private List strucAssemblies; - private List strucAssemblyGens; - private List entitySrcGens; - private List entitySrcNats; - private List entitySrcSyns; - private List structConn; - private List structNcsOper; - private List sequenceDifs; - private List structSiteGens; - - private Matrix4d parsedScaleMatrix; - - - - /** - * A map of asym ids (internal chain ids) to entity ids extracted from - * the _struct_asym category - */ - private Map asymId2entityId; - - /** - * A map of asym ids (internal chain ids) to author ids extracted from - * the _entity_poly category. Used in header only parsing. - */ - private Map asymId2authorId; - - private String currentNmrModelNumber ; - - private FileParsingParameters params; - - public SimpleMMcifConsumer(){ - params = new FileParsingParameters(); - documentStart(); - - } - - @Override - public void newEntity(Entity entity) { - logger.debug("New entity: {}",entity.toString()); - entities.add(entity); - } - - @Override - public void newEntityPoly(EntityPoly entityPoly) { - entityPolys.add(entityPoly); - } - - @Override - public void newPdbxStructOperList(PdbxStructOperList structOper){ - - structOpers.add(structOper); - } - - @Override - public void newStructAsym(StructAsym sasym){ - - structAsyms.add(sasym); - } - - private Entity getEntity(int entity_id){ - try { - for (Entity e: entities){ - int eId = Integer.parseInt(e.getId()); - if (eId== entity_id){ - return e; - } - } - } catch (NumberFormatException e) { - logger.warn("Entity id does not look like a number: {}", e.getMessage()); - } - return null; - } - - @Override - public void newStructKeywords(StructKeywords kw){ - PDBHeader header = structure.getPDBHeader(); - if ( header == null) - header = new PDBHeader(); - header.setDescription(kw.getPdbx_keywords()); - header.setClassification(kw.getPdbx_keywords()); - } - - @Override - public void setStruct(Struct struct) { - - PDBHeader header = structure.getPDBHeader(); - if ( header == null) - header = new PDBHeader(); - - header.setTitle(struct.getTitle()); - header.setIdCode(struct.getEntry_id()); - //header.setDescription(struct.getPdbx_descriptor()); - //header.setClassification(struct.getPdbx_descriptor()); - //header.setDescription(struct.getPdbx_descriptor()); - - - - structure.setPDBHeader(header); - structure.setPDBCode(struct.getEntry_id()); - } - - /** initiate new group, either Hetatom, Nucleotide, or AminoAcid */ - private Group getNewGroup(String recordName,Character aminoCode1, long seq_id,String groupCode3) { - - Group g = ChemCompGroupFactory.getGroupFromChemCompDictionary(groupCode3); - if ( g != null && !g.getChemComp().isEmpty()) { - if ( g instanceof AminoAcidImpl) { - AminoAcidImpl aa = (AminoAcidImpl) g; - aa.setId(seq_id); - } else if ( g instanceof NucleotideImpl) { - NucleotideImpl nuc = (NucleotideImpl) g; - nuc.setId(seq_id); - } else if ( g instanceof HetatomImpl) { - HetatomImpl het = (HetatomImpl)g; - het.setId(seq_id); - } - return g; - } - - - - Group group; - if ( recordName.equals("ATOM") ) { - if (StructureTools.isNucleotide(groupCode3)) { - // it is a nucleotide - NucleotideImpl nu = new NucleotideImpl(); - group = nu; - nu.setId(seq_id); - - } else if (aminoCode1==null || aminoCode1 == StructureTools.UNKNOWN_GROUP_LABEL){ - HetatomImpl h = new HetatomImpl(); - h.setId(seq_id); - group = h; - - } else { - AminoAcidImpl aa = new AminoAcidImpl() ; - aa.setAminoType(aminoCode1); - aa.setId(seq_id); - group = aa ; - } - } - else { - if (StructureTools.isNucleotide(groupCode3)) { - // it is a nucleotide - NucleotideImpl nu = new NucleotideImpl(); - group = nu; - nu.setId(seq_id); - } - else if (aminoCode1 != null ) { - AminoAcidImpl aa = new AminoAcidImpl() ; - aa.setAminoType(aminoCode1); - aa.setId(seq_id); - group = aa ; - } else { - HetatomImpl h = new HetatomImpl(); - h.setId(seq_id); - group = h; - } - } - return group ; - } - - /** - * Test if the given asymId is already present in the list of chains given. If yes, returns the chain - * otherwise returns null. - */ - private static Chain isKnownChain(String asymId, List chains){ - - for (int i = 0; i< chains.size();i++){ - Chain testchain = chains.get(i); - //System.out.println("comparing chainID >"+chainID+"< against testchain " + i+" >" +testchain.getName()+"<"); - if (asymId.equals(testchain.getId())) { - //System.out.println("chain "+ chainID+" already known ..."); - return testchain; - } - } - - return null; - } - - @Override - public void newAtomSite(AtomSite atom) { - - if (params.isHeaderOnly()) return; - - // Warning: getLabel_asym_id is not the "chain id" in the PDB file - // it is the internally used chain id. - // later on we will fix this... - - // later one needs to map the asym id to the pdb_strand_id - - //TODO: add support for FileParsingParams.getMaxAtoms() - - boolean startOfNewChain = false; - - String asymId = atom.getLabel_asym_id(); - String authId = atom.getAuth_asym_id(); - - String recordName = atom.getGroup_PDB(); - String residueNumberS = atom.getAuth_seq_id(); - Integer residueNrInt = Integer.parseInt(residueNumberS); - - // the 3-letter name of the group: - String groupCode3 = atom.getLabel_comp_id(); - - boolean isHetAtomInFile = false; - - Character aminoCode1 = null; - if ( recordName.equals("ATOM") ) - aminoCode1 = StructureTools.get1LetterCodeAmino(groupCode3); - else { - aminoCode1 = StructureTools.get1LetterCodeAmino(groupCode3); - - // for nucleotides this will be null.. - if (aminoCode1 != null && aminoCode1.equals(StructureTools.UNKNOWN_GROUP_LABEL)) - aminoCode1 = null; - - isHetAtomInFile = true; - } - String insCodeS = atom.getPdbx_PDB_ins_code(); - Character insCode = null; - if (! insCodeS.equals("?")) { - insCode = insCodeS.charAt(0); - } - // we store the internal seq id in the Atom._id field - // this is not a PDB file field but we need this to internally assign the insertion codes later - // from the pdbx_poly_seq entries.. - - long seq_id = -1; - try { - seq_id = Long.parseLong(atom.getLabel_seq_id()); - } catch (NumberFormatException e){ - // non polymer chains (ligands and small molecules) will have a label_seq_id set to '.', thus it is ok to - // silently ignore this - //logger.debug("Could not parse number for _atom_site.label_seq_id: "+e.getMessage()); - } - - String nmrModelNumber = atom.getPdbx_PDB_model_num(); - - if ( currentNmrModelNumber == null) { - currentNmrModelNumber = nmrModelNumber; - } - - if (! currentNmrModelNumber.equals(nmrModelNumber)){ - currentNmrModelNumber = nmrModelNumber; - - // add previous data - if ( currentChain != null ) { - currentChain.addGroup(currentGroup); - currentGroup.trimToSize(); - } - - // we came to the beginning of a new NMR model - allModels.add(currentModel); - currentModel = new ArrayList(); - currentChain = null; - currentGroup = null; - } - - - if (currentChain == null) { - - currentChain = new ChainImpl(); - currentChain.setName(authId); - currentChain.setId(asymId); - currentModel.add(currentChain); - startOfNewChain = true; - } - - //System.out.println("BEFORE: " + chain_id + " " + current_chain.getName()); - if ( ! asymId.equals(currentChain.getId()) ) { - //logger.info("unknown chain. creating new chain. authId:" + authId + " asymId: " + asymId); - startOfNewChain = true; - - // end up old chain... - currentChain.addGroup(currentGroup); - - // see if old chain is known ... - Chain testchain = isKnownChain(asymId,currentModel); - - if ( testchain == null) { - //logger.info("unknown chain. creating new chain. authId:" + authId + " asymId: " + asymId); - - currentChain = new ChainImpl(); - currentChain.setName(authId); - currentChain.setId(asymId); - - } else { - currentChain = testchain; - } - - if ( ! currentModel.contains(currentChain)) - currentModel.add(currentChain); - - } - - - ResidueNumber residueNumber = new ResidueNumber(authId,residueNrInt, insCode); - - if (currentGroup == null) { - - - currentGroup = getNewGroup(recordName,aminoCode1,seq_id, groupCode3); - - currentGroup.setResidueNumber(residueNumber); - currentGroup.setPDBName(groupCode3); - currentGroup.setHetAtomInFile(isHetAtomInFile); - } - - // SET UP THE ALT LOC GROUP - Group altGroup = null; - String altLocS = atom.getLabel_alt_id(); - Character altLoc = ' '; - if ( altLocS.length()>0) { - altLoc = altLocS.charAt(0); - if ( altLoc.equals('.') ) - altLoc = ' '; - - } - // If it's the start of the new chain - if ( startOfNewChain){ - currentGroup = getNewGroup(recordName,aminoCode1,seq_id, groupCode3); - currentGroup.setResidueNumber(residueNumber); - currentGroup.setPDBName(groupCode3); - currentGroup.setHetAtomInFile(isHetAtomInFile); - } - // ANTHONY BRADLEY ADDED THIS -> WE ONLY WAN'T TO CHECK FOR ALT LOCS WHEN IT's NOT THE FIRST GROUP IN CHAIN - else{ - // check if residue number is the same ... - // insertion code is part of residue number - if ( ! residueNumber.equals(currentGroup.getResidueNumber())) { - //System.out.println("end of residue: "+current_group.getPDBCode()+" "+residueNrInt); - currentChain.addGroup(currentGroup); - currentGroup.trimToSize(); - currentGroup = getNewGroup(recordName,aminoCode1,seq_id,groupCode3); - currentGroup.setPDBName(groupCode3); - currentGroup.setResidueNumber(residueNumber); - currentGroup.setHetAtomInFile(isHetAtomInFile); - - - } else { - // same residueNumber, but altLocs... - // test altLoc - - if ( ! altLoc.equals(' ') && ( ! altLoc.equals('.'))) { - logger.debug("found altLoc! " + altLoc + " " + currentGroup + " " + altGroup); - altGroup = getCorrectAltLocGroup( altLoc,recordName,aminoCode1,groupCode3, seq_id); - if (altGroup.getChain()==null) { - altGroup.setChain(currentChain); - } - } - } - } - //atomCount++; - //System.out.println("fixing atom name for >" + atom.getLabel_atom_id() + "< >" + fullname + "<"); - - - if ( params.isParseCAOnly() ){ - // yes , user wants to get CA only - // only parse CA atoms... - if (! (atom.getLabel_atom_id().equals(StructureTools.CA_ATOM_NAME) && atom.getType_symbol().equals("C"))) { - //System.out.println("ignoring " + line); - //atomCount--; - return; - } - } - - //see if chain_id is one of the previous chains ... - - Atom a = convertAtom(atom); - - //see if chain_id is one of the previous chains ... - if ( altGroup != null) { - altGroup.addAtom(a); - altGroup = null; - } - else { - currentGroup.addAtom(a); - } - - - String atomName = a.getName(); - // make sure that main group has all atoms - // GitHub issue: #76 - if ( ! currentGroup.hasAtom(atomName)) { - // Unless it's microheterogenity https://github.com/rcsb/codec-devel/issues/81 - if (currentGroup.getPDBName().equals(a.getGroup().getPDBName())) { - if(!StructureTools.hasNonDeuteratedEquiv(a,currentGroup)){ - currentGroup.addAtom(a); - } - } - - } - } - - /** - * Convert a mmCIF AtomSite object to a BioJava Atom object - * - * @param atom the mmmcif AtomSite record - * @return an Atom - */ - private Atom convertAtom(AtomSite atom){ - - - Atom a = new AtomImpl(); - - a.setPDBserial(Integer.parseInt(atom.getId())); - a.setName(atom.getLabel_atom_id()); - - double x = Double.parseDouble (atom.getCartn_x()); - double y = Double.parseDouble (atom.getCartn_y()); - double z = Double.parseDouble (atom.getCartn_z()); - a.setX(x); - a.setY(y); - a.setZ(z); - - float occupancy = Float.parseFloat (atom.getOccupancy()); - a.setOccupancy(occupancy); - - float temp = Float.parseFloat (atom.getB_iso_or_equiv()); - a.setTempFactor(temp); - - String alt = atom.getLabel_alt_id(); - if (( alt != null ) && ( alt.length() > 0) && (! alt.equals("."))){ - a.setAltLoc(new Character(alt.charAt(0))); - } else { - a.setAltLoc(new Character(' ')); - } - - Element element = Element.R; - try { - element = Element.valueOfIgnoreCase(atom.getType_symbol()); - } catch (IllegalArgumentException e) { - logger.info("Element {} was not recognised as a BioJava-known element, the element will be represented as the generic element {}", atom.getType_symbol(), Element.R.name()); - } - a.setElement(element); - - return a; - - } - - - private Group getCorrectAltLocGroup( Character altLoc, - String recordName, - Character aminoCode1, - String groupCode3, - long seq_id) { - - // see if we know this altLoc already; - List atoms = currentGroup.getAtoms(); - if ( atoms.size() > 0) { - Atom a1 = atoms.get(0); - // we are just adding atoms to the current group - // probably there is a second group following later... - if (a1.getAltLoc().equals(altLoc)) { - - return currentGroup; - } - } - - List altLocs = currentGroup.getAltLocs(); - for ( Group altLocG : altLocs ){ - atoms = altLocG.getAtoms(); - if ( atoms.size() > 0) { - for ( Atom a1 : atoms) { - if (a1.getAltLoc().equals( altLoc)) { - - return altLocG; - } - } - } - } - - // no matching altLoc group found. - // build it up. - - if ( groupCode3.equals(currentGroup.getPDBName())) { - if ( currentGroup.getAtoms().size() == 0) { - //System.out.println("current group is empty " + current_group + " " + altLoc); - return currentGroup; - } - //System.out.println("cloning current group " + current_group + " " + current_group.getAtoms().get(0).getAltLoc() + " altLoc " + altLoc); - Group altLocG = (Group) currentGroup.clone(); - // drop atoms from cloned group... - // https://redmine.open-bio.org/issues/3307 - altLocG.setAtoms(new ArrayList()); - altLocG.getAltLocs().clear(); - currentGroup.addAltLoc(altLocG); - return altLocG; - } - - // System.out.println("new group " + recordName + " " + aminoCode1 + " " +groupCode3); - //String recordName,Character aminoCode1, long seq_id,String groupCode3) { - Group altLocG = getNewGroup(recordName,aminoCode1,seq_id,groupCode3); - - altLocG.setPDBName(groupCode3); - altLocG.setResidueNumber(currentGroup.getResidueNumber()); - currentGroup.addAltLoc(altLocG); - return altLocG; - } - - /** - * Start the parsing - */ - @Override - public void documentStart() { - structure = new StructureImpl(); - - currentChain = null; - currentGroup = null; - currentNmrModelNumber = null; - //atomCount = 0; - - allModels = new ArrayList>(); - currentModel = new ArrayList(); - entities = new ArrayList(); - entityPolys = new ArrayList<>(); - strucRefs = new ArrayList(); - seqResChains = new ArrayList(); - entityChains = new ArrayList(); - structAsyms = new ArrayList(); - - asymId2entityId = new HashMap(); - asymId2authorId = new HashMap<>(); - structOpers = new ArrayList(); - strucAssemblies = new ArrayList(); - strucAssemblyGens = new ArrayList(); - entitySrcGens = new ArrayList(); - entitySrcNats = new ArrayList(); - entitySrcSyns = new ArrayList(); - structConn = new ArrayList(); - structNcsOper = new ArrayList(); - sequenceDifs = new ArrayList(); - structSiteGens = new ArrayList(); - } - - - @Override - public void documentEnd() { - - // Expected that there is one current_chain that needs to be added to the model - // When in headerOnly mode, no Atoms are read, and there will not be an active - // current_chain. - if ( currentChain != null ) { - - currentChain.addGroup(currentGroup); - if (isKnownChain(currentChain.getId(),currentModel) == null) { - currentModel.add(currentChain); - } - } else if (!params.isHeaderOnly()){ - logger.warn("current chain is null at end of document."); - } - - allModels.add(currentModel); - - // this populates the asymId2authorId and asymId2entityId maps, needed in header only mode to get the mapping - // between the 2 chain identifiers. - initMaps(); - - for (StructAsym asym : structAsyms) { - - logger.debug("Entity {} matches asym_id: {}", asym.getEntity_id(), asym.getId() ); - - Chain s = getEntityChain(asym.getEntity_id()); - Chain seqres = (Chain)s.clone(); - // to solve issue #160 (e.g. 3u7t) - seqres = removeSeqResHeterogeneity(seqres); - seqres.setId(asym.getId()); - if (asymId2authorId.get(asym.getId()) !=null ){ - seqres.setName(asymId2authorId.get(asym.getId())); - } else { - seqres.setName(asym.getId()); - } - - EntityType type = null; - try { - Entity ent = getEntity(Integer.parseInt(asym.getEntity_id())); - type = EntityType.entityTypeFromString(ent.getType()); - } catch (NumberFormatException e) { - logger.debug("Could not parse integer from entity id field {}", asym.getEntity_id()); - } - - // we'll only add seqres chains that are polymeric or unknown - if (type==null || type==EntityType.POLYMER ) { - seqResChains.add(seqres); - } - - logger.debug(" seqres: " + asym.getId() + " " + seqres + "<") ; - // adding the entities to structure - addEntities(asym); - - } - - if (structAsyms.isEmpty()) { - logger.warn("No _struct_asym category in file, no SEQRES groups will be added."); - } - - // entities - // In addEntities above we created the entities if they were present in the file - // Now we need to make sure that they are linked to chains and also that if they are not present in the file we need to add them now - linkEntities(); - - // now that we know the entities, we can add all chains to structure so that they are stored - // properly as polymer/nonpolymer/water chains inside structure - for (List model:allModels) { - structure.addModel(model); - } - - // Only align if requested (default) and not when headerOnly mode with no Atoms. - // Otherwise, we store the empty SeqRes Groups unchanged in the right chains. - if ( params.isAlignSeqRes() && !params.isHeaderOnly() ){ - logger.debug("Parsing mode align_seqres, will parse SEQRES and align to ATOM sequence"); - alignSeqRes(); - } else { - logger.debug("Parsing mode unalign_seqres, will parse SEQRES but not align it to ATOM sequence"); - SeqRes2AtomAligner.storeUnAlignedSeqRes(structure, seqResChains, params.isHeaderOnly()); - } - - - // Now make sure all altlocgroups have all the atoms in all the groups - StructureTools.cleanUpAltLocs(structure); - - // NOTE bonds and charges can only be done at this point that the chain id mapping is properly sorted out - if (!params.isHeaderOnly()) { - if ( params.shouldCreateAtomBonds()) { - addBonds(); - } - - if ( params.shouldCreateAtomCharges()) { - addCharges(); - } - } - - if (!params.isHeaderOnly()) { - - // Do structure.setSites(sites) after any chain renaming to be like PDB. - addSites(); - } - - - - // set the oligomeric state info in the header... - if (params.isParseBioAssembly()) { - - // the more detailed mapping of chains to rotation operations happens in StructureIO... - - Map bioAssemblies = new LinkedHashMap(); - - for ( PdbxStructAssembly psa : strucAssemblies){ - - List psags = new ArrayList(1); - - for ( PdbxStructAssemblyGen psag: strucAssemblyGens ) { - if ( psag.getAssembly_id().equals(psa.getId())) { - psags.add(psag); - } - } - - BiologicalAssemblyBuilder builder = new BiologicalAssemblyBuilder(); - - // these are the transformations that need to be applied to our model - List transformations = builder.getBioUnitTransformationList(psa, psags, structOpers); - - int bioAssemblyId = -1; - try { - bioAssemblyId = Integer.parseInt(psa.getId()); - } catch (NumberFormatException e) { - logger.info("Could not parse a numerical bio assembly id from '{}'",psa.getId()); - } - - // if bioassembly id is not numerical we throw it away - // this happens usually for viral capsid entries, like 1ei7 - // see issue #230 in github - if (bioAssemblyId!=-1) { - int mmSize = 0; - // note that the transforms contain asym ids of both polymers and non-polymers - // For the mmsize, we are only interested in the polymers - for (BiologicalAssemblyTransformation transf:transformations) { - Chain c = structure.getChain(transf.getChainId()); - if (c==null) { - logger.info("Could not find asym id {} specified in struct_assembly_gen", transf.getChainId()); - continue; - } - if (c.getEntityType() == EntityType.POLYMER && - // for entries like 4kro, sugars are annotated as polymers but we - // don't want them in the macromolecularSize count - !c.getEntityInfo().getDescription().contains("SUGAR") ) { - - mmSize++; - } - } - - BioAssemblyInfo bioAssembly = new BioAssemblyInfo(); - bioAssembly.setId(bioAssemblyId); - bioAssembly.setMacromolecularSize(mmSize); - bioAssembly.setTransforms(transformations); - bioAssemblies.put(bioAssemblyId,bioAssembly); - } - - } - structure.getPDBHeader().setBioAssemblies(bioAssemblies); - } - - setStructNcsOps(); - - setCrystallographicInfoMetadata(); - - - Map> misMatchMap = new HashMap>(); - for (StructRefSeqDif sdif : sequenceDifs) { - SeqMisMatch misMatch = new SeqMisMatchImpl(); - misMatch.setDetails(sdif.getDetails()); - - String insCode = sdif.getPdbx_pdb_ins_code(); - if ( insCode != null && insCode.equals("?")) - insCode = null; - misMatch.setInsCode(insCode); - misMatch.setOrigGroup(sdif.getDb_mon_id()); - misMatch.setPdbGroup(sdif.getMon_id()); - misMatch.setPdbResNum(sdif.getPdbx_auth_seq_num()); - misMatch.setUniProtId(sdif.getPdbx_seq_db_accession_code()); - misMatch.setSeqNum(sdif.getSeq_num()); - - - List mms = misMatchMap.get(sdif.getPdbx_pdb_strand_id()); - if ( mms == null) { - mms = new ArrayList(); - misMatchMap.put(sdif.getPdbx_pdb_strand_id(),mms); - } - mms.add(misMatch); - - } - - for (String chainId : misMatchMap.keySet()){ - - Chain chain = structure.getPolyChainByPDB(chainId); - - if ( chain == null) { - logger.warn("Could not set mismatches for chain with author id" + chainId); - continue; - } - - chain.setSeqMisMatches(misMatchMap.get(chainId)); - - - } - - } - - /** - * Here we link entities to chains. - * Also if entities are not present in file, this initialises the entities with some heuristics, see {@link org.biojava.nbio.structure.io.EntityFinder} - */ - private void linkEntities() { - - for (int i =0; i< allModels.size() ; i++){ - for (Chain chain : allModels.get(i)) { - //logger.info("linking entities for " + chain.getId() + " " + chain.getName()); - String entityId = asymId2entityId.get(chain.getId()); - - if (entityId==null) { - // this can happen for instance if the cif file didn't have _struct_asym category at all - // and thus we have no asymId2entityId mapping at all - logger.info("No entity id could be found for chain {}", chain.getId()); - continue; - } - int eId = Integer.parseInt(entityId); - - // Entities are not added for non-polymeric entities, if a chain is non-polymeric its entity won't be found. - // TODO: add all entities and unique compounds and add methods to directly get polymer or non-polymer - // asyms (chains). Either create a unique StructureImpl or modify existing for a better representation of the - // mmCIF internal data structures but is compatible with Structure interface. - // Some examples of PDB entries with this kind of problem: - // - 2uub: asym_id X, chainName Z, entity_id 24: fully non-polymeric but still with its own chainName - // - 3o6j: asym_id K, chainName Z, entity_id 6 : a single water molecule - // - 1dz9: asym_id K, chainName K, entity_id 6 : a potassium ion alone - - EntityInfo entityInfo = structure.getEntityById(eId); - if (entityInfo==null) { - // Supports the case where the only chain members were from non-polymeric entity that is missing. - // Solved by creating a new Compound(entity) to which this chain will belong. - logger.info("Could not find an Entity for entity_id {}, for chain id {}, creating a new Entity.", - eId, chain.getId()); - entityInfo = new EntityInfo(); - entityInfo.setMolId(eId); - entityInfo.addChain(chain); - if (chain.isWaterOnly()) { - entityInfo.setType(EntityType.WATER); - } else { - entityInfo.setType(EntityType.NONPOLYMER); - } - chain.setEntityInfo(entityInfo); - structure.addEntityInfo(entityInfo); - } else { - logger.debug("Adding chain with chain id {} (auth id {}) to Entity with entity_id {}", - chain.getId(), chain.getName(), eId); - entityInfo.addChain(chain); - chain.setEntityInfo(entityInfo); - } - - } - - } - - // if no entity information was present in file we then go and find the entities heuristically with EntityFinder - List entityInfos = structure.getEntityInfos(); - if (entityInfos==null || entityInfos.isEmpty()) { - - List> polyModels = new ArrayList<>(); - List> nonPolyModels = new ArrayList<>(); - List> waterModels = new ArrayList<>(); - - for (List model:allModels) { - - List polyChains = new ArrayList<>(); - List nonPolyChains = new ArrayList<>(); - List waterChains = new ArrayList<>(); - - polyModels.add(polyChains); - nonPolyModels.add(nonPolyChains); - waterModels.add(waterChains); - - for (Chain c:model) { - - // we only have entities for polymeric chains, all others are ignored for assigning entities - if (c.isWaterOnly()) { - waterChains.add(c); - - } else if (c.isPureNonPolymer()) { - nonPolyChains.add(c); - - } else { - polyChains.add(c); - } - } - } - - entityInfos = EntityFinder.findPolyEntities(polyModels); - EntityFinder.createPurelyNonPolyEntities(nonPolyModels, waterModels, entityInfos); - - - structure.setEntityInfos(entityInfos); - } - - // final sanity check: it can happen that from the annotated entities some are not linked to any chains - // e.g. 3s26: a sugar entity does not have any chains associated to it (it seems to be happening with many sugar compounds) - // we simply log it, this can sign some other problems if the entities are used down the line - for (EntityInfo e:entityInfos) { - if (e.getChains().isEmpty()) { - logger.info("Entity {} '{}' has no chains associated to it", - e.getMolId()<0?"with no entity id":e.getMolId(), e.getDescription()); - } - } - - } - - private void addCharges() { - ChargeAdder.addCharges(structure); - } - - /** - * The method will return a new reference to a Chain with any consecutive groups - * having same residue numbers removed. - * This is necessary to solve the microheterogeneity issue in entries like 3u7t (see github issue #160) - * @param c - * @return - */ - private static Chain removeSeqResHeterogeneity(Chain c) { - - Chain trimmedChain = new ChainImpl(); - - ResidueNumber lastResNum = null; - - for (Group g:c.getAtomGroups()) { - - // note we have to deep copy this, otherwise they stay linked and would get altered in addGroup(g) - ResidueNumber currentResNum = new ResidueNumber( - g.getResidueNumber().getChainName(), - g.getResidueNumber().getSeqNum(), - g.getResidueNumber().getInsCode()); - - if (lastResNum == null || !lastResNum.equals(currentResNum) ) { - trimmedChain.addGroup(g); - } else { - logger.debug("Removing seqres group because it seems to be repeated in entity_poly_seq, most likely has hetero='y': "+g); - } - - lastResNum = currentResNum; - - } - return trimmedChain; - } - - private void addBonds() { - BondMaker maker = new BondMaker(structure, params); - maker.makeBonds(); - maker.formBondsFromStructConn(structConn); - } - - private void alignSeqRes() { - - logger.debug("Parsing mode align_seqres, will align to ATOM to SEQRES sequence"); - - // fix SEQRES residue numbering for all models - - for (int model=0;model atomList = structure.getModel(model); - - for (Chain seqResChain: seqResChains){ - - // this extracts the matching atom chain from atomList - Chain atomChain = SeqRes2AtomAligner.getMatchingAtomRes(seqResChain, atomList, true); - - if (atomChain == null) { - // most likely there's no observed residues at all for the seqres chain: can't map - // e.g. 3zyb: chains with asym_id L,M,N,O,P have no observed residues - logger.info("Could not map SEQRES chain with asym_id={} to any ATOM chain. Most likely there's no observed residues in the chain.", - seqResChain.getId()); - continue; - } - - //map the atoms to the seqres... - - // we need to first clone the seqres so that they stay independent for different models - List seqResGroups = new ArrayList(); - for (int i=0;i> entityId2asymId = new HashMap<>(); - - for (StructAsym asym : structAsyms) { - - logger.debug("Entity {} matches asym_id: {}", asym.getEntity_id(), asym.getId() ); - - asymId2entityId.put(asym.getId(), asym.getEntity_id()); - - if (entityId2asymId.containsKey(asym.getEntity_id())) { - List asymIds = entityId2asymId.get(asym.getEntity_id()); - asymIds.add(asym.getId()); - } else { - List asymIds = new ArrayList<>(); - asymIds.add(asym.getId()); - entityId2asymId.put(asym.getEntity_id(), asymIds); - } - } - - if (entityPolys==null || entityPolys.isEmpty()) { - logger.info("No _entity_poly category found in file. No asym id to author id mapping will be available for header only parsing"); - return; - } - - for (EntityPoly ep:entityPolys) { - if (ep.getPdbx_strand_id()==null) { - logger.info("_entity_poly.pdbx_strand_id is null for entity {}. Won't be able to map asym ids to author ids for this entity.", ep.getEntity_id()); - continue; - } - String[] chainNames = ep.getPdbx_strand_id().split(","); - List asymIds = entityId2asymId.get(ep.getEntity_id()); - if (chainNames.length!=asymIds.size()) { - logger.warn("The list of asym ids (from _struct_asym) and the list of author ids (from _entity_poly) for entity {} have different lengths! Can't provide a mapping from asym ids to author chain ids", ep.getEntity_id()); - continue; - } - for (int i=0; i ncsOperators = new ArrayList(); - - for (StructNcsOper sNcsOper:structNcsOper) { - - if (!sNcsOper.getCode().equals("generate")) continue; - - try { - Matrix4d op = new Matrix4d(); - op.setElement(3, 0, 0.0); - op.setElement(3, 1, 0.0); - op.setElement(3, 2, 0.0); - op.setElement(3, 3, 1.0); - - - op.setElement(0, 0, Double.parseDouble(sNcsOper.getMatrix11())); - op.setElement(0, 1, Double.parseDouble(sNcsOper.getMatrix12())); - op.setElement(0, 2, Double.parseDouble(sNcsOper.getMatrix13())); - - op.setElement(1, 0, Double.parseDouble(sNcsOper.getMatrix21())); - op.setElement(1, 1, Double.parseDouble(sNcsOper.getMatrix22())); - op.setElement(1, 2, Double.parseDouble(sNcsOper.getMatrix23())); - - op.setElement(2, 0, Double.parseDouble(sNcsOper.getMatrix31())); - op.setElement(2, 1, Double.parseDouble(sNcsOper.getMatrix32())); - op.setElement(2, 2, Double.parseDouble(sNcsOper.getMatrix33())); - - op.setElement(0, 3, Double.parseDouble(sNcsOper.getVector1())); - op.setElement(1, 3, Double.parseDouble(sNcsOper.getVector2())); - op.setElement(2, 3, Double.parseDouble(sNcsOper.getVector3())); - - ncsOperators.add(op); - - } catch (NumberFormatException e) { - logger.warn("Error parsing doubles in NCS operator list, skipping operator {}", structNcsOper.indexOf(sNcsOper)+1); - } - - } - - // we only set it if not empty, otherwise remains null - if (ncsOperators.size()>0) { - structure.getCrystallographicInfo().setNcsOperators( - ncsOperators.toArray(new Matrix4d[ncsOperators.size()])); - } - } - - private void setCrystallographicInfoMetadata() { - if (parsedScaleMatrix!=null) { - - PDBCrystallographicInfo crystalInfo = structure.getCrystallographicInfo(); - - boolean nonStd = false; - if (crystalInfo.getCrystalCell()!=null && !crystalInfo.getCrystalCell().checkScaleMatrix(parsedScaleMatrix)) { - nonStd = true; - } - - crystalInfo.setNonStandardCoordFrameConvention(nonStd); - } - } - - - /** This method will return the parsed protein structure, once the parsing has been finished - * - * @return a BioJava protein structure object - */ - public Structure getStructure() { - - return structure; - } - - @Override - public void newDatabasePDBrevRecord(DatabasePdbrevRecord record) { - - PDBHeader header = structure.getPDBHeader(); - - if ( header == null) { - header = new PDBHeader(); - structure.setPDBHeader(header); - } - - List revRecords = header.getRevisionRecords(); - if ( revRecords == null) { - revRecords = new ArrayList(); - header.setRevisionRecords(revRecords); - } - revRecords.add(record); - - - } - - - @Override - public void newDatabasePDBrev(DatabasePDBrev dbrev) { - - logger.debug("got a database revision:" + dbrev); - - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd",Locale.US); - PDBHeader header = structure.getPDBHeader(); - - if ( header == null) { - header = new PDBHeader(); - } - - if (dbrev.getNum().equals("1")){ - - try { - Date dep = dateFormat.parse(dbrev.getDate_original()); - header.setDepDate(dep); - - } catch (ParseException e){ - logger.warn("Could not parse date string '{}', deposition date will be unavailable", dbrev.getDate_original()); - } - - try { - Date rel = dateFormat.parse(dbrev.getDate()); - header.setRelDate(rel); - - } catch (ParseException e){ - logger.warn("Could not parse date string '{}', modification date will be unavailable", dbrev.getDate()); - } - - - } else { - try { - - Date mod = dateFormat.parse(dbrev.getDate()); - header.setModDate(mod); - - } catch (ParseException e){ - logger.warn("Could not parse date string '{}', modification date will be unavailable", dbrev.getDate()); - } - } - - structure.setPDBHeader(header); - } - - @Override - public void newPdbxAuditRevisionHistory(PdbxAuditRevisionHistory history) { - - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd",Locale.US); - PDBHeader header = structure.getPDBHeader(); - - if ( header == null) { - header = new PDBHeader(); - } - - // first entry in revision history is the release date - if (history.getOrdinal().equals("1")){ - try { - Date releaseDate = dateFormat.parse(history.getRevision_date()); - header.setRelDate(releaseDate); - - } catch (ParseException e){ - logger.warn("Could not parse date string '{}', release date will be unavailable", history.getRevision_date()); - } - } else { - // all other dates are revision dates; - // since this method may be called multiple times, - // the last revision date will "stick" - try { - Date revisionDate = dateFormat.parse(history.getRevision_date()); - header.setModDate(revisionDate); - } catch (ParseException e){ - logger.warn("Could not parse date string '{}', revision date will be unavailable", history.getRevision_date()); - } - } - - structure.setPDBHeader(header); - } - - @Override - public void newPdbxDatabaseStatus(PdbxDatabaseStatus status) { - - // the deposition date field is only available in mmCIF 5.0 - - if (status.getRecvd_initial_deposition_date() == null) { - // skip this method for older mmCIF versions - return; - } - - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd",Locale.US); - PDBHeader header = structure.getPDBHeader(); - - if (header == null) { - header = new PDBHeader(); - } - - try { - Date depositionDate = dateFormat.parse(status.getRecvd_initial_deposition_date()); - header.setDepDate(depositionDate); - } catch (ParseException e){ - logger.warn("Could not parse date string '{}', deposition date will be unavailable", status.getRecvd_initial_deposition_date()); - } - - structure.setPDBHeader(header); - } - - @Override - public void newDatabasePDBremark(DatabasePDBremark remark) { - //System.out.println(remark); - String id = remark.getId(); - if (id.equals("2")){ - - //this remark field contains the resolution information: - String line = remark.getText(); - - int i = line.indexOf("ANGSTROM"); - if ( i > 5) { - // line contains ANGSTROM info... - String resolution = line.substring(i-5,i).trim(); - // convert string to float - float res = 99 ; - try { - res = Float.parseFloat(resolution); - - } catch (NumberFormatException e) { - logger.info("could not parse resolution from line and ignoring it " + line); - return ; - - - } - // support for old style header - - PDBHeader pdbHeader = structure.getPDBHeader(); - pdbHeader.setResolution(res); - - } - - } - } - - @Override - public void newRefine(Refine r){ - - PDBHeader pdbHeader = structure.getPDBHeader(); - // RESOLUTION - // in very rare cases (for instance hybrid methods x-ray + neutron diffraction, e.g. 3ins, 4n9m) - // there are 2 resolution values, one for each method - // we take the last one found so that behaviour is like in PDB file parsing - if (pdbHeader.getResolution()!=PDBHeader.DEFAULT_RESOLUTION) { - logger.warn("More than 1 resolution value present, will use last one {} and discard previous {} " - ,r.getLs_d_res_high(), String.format("%4.2f",pdbHeader.getResolution())); - } - try { - pdbHeader.setResolution(Float.parseFloat(r.getLs_d_res_high())); - } catch (NumberFormatException e){ - logger.info("Could not parse resolution from " + r.getLs_d_res_high() + " " + e.getMessage()); - } - - - // RFREE - if (pdbHeader.getRfree()!=PDBHeader.DEFAULT_RFREE) { - logger.warn("More than 1 Rfree value present, will use last one {} and discard previous {} ", - r.getLs_R_factor_R_free(), String.format("%4.2f",pdbHeader.getRfree())); - } - if (r.getLs_R_factor_R_free()==null) { - // some entries like 2ifo haven't got this field at all - logger.info("_refine.ls_R_factor_R_free not present, not parsing Rfree value"); - } else { - try { - pdbHeader.setRfree(Float.parseFloat(r.getLs_R_factor_R_free())); - } catch (NumberFormatException e){ - // no rfree present ('?') is very usual, that's why we set it to debug - logger.debug("Could not parse Rfree from string '{}'", r.getLs_R_factor_R_free()); - } - } - - // RWORK - if(pdbHeader.getRwork()!=PDBHeader.DEFAULT_RFREE) { - logger.warn("More than 1 R work value present, will use last one {} and discard previous {} ", - r.getLs_R_factor_R_work(), String.format("%4.2f",pdbHeader.getRwork())); - } - if(r.getLs_R_factor_R_work()==null){ - logger.info("_refine.ls_R_factor_R_work not present, not parsing R-work value"); - } - else{ - try{ - pdbHeader.setRwork(Float.parseFloat(r.getLs_R_factor_R_work())); - } - catch (NumberFormatException e){ - logger.debug("Could not parse R-work from string '{}'", r.getLs_R_factor_R_work()); - } - - } - - } - - - @Override - public void newAuditAuthor(AuditAuthor aa){ - - String name = aa.getName(); - - StringBuffer famName = new StringBuffer(); - StringBuffer initials = new StringBuffer(); - boolean afterComma = false; - for ( char c: name.toCharArray()) { - if ( c == ' ') - continue; - if ( c == ','){ - afterComma = true; - continue; - } - - if ( afterComma) - initials.append(c); - else - famName.append(c); - } - - StringBuffer newaa = new StringBuffer(); - newaa.append(initials); - newaa.append(famName); - - PDBHeader header = structure.getPDBHeader(); - String auth = header.getAuthors(); - if (auth == null) { - header.setAuthors(newaa.toString()); - }else { - auth += "," + newaa.toString(); - header.setAuthors(auth); - - } - } - - @Override - public void newExptl(Exptl exptl) { - - PDBHeader pdbHeader = structure.getPDBHeader(); - String method = exptl.getMethod(); - pdbHeader.setExperimentalTechnique(method); - - } - - @Override - public void newCell(Cell cell) { - - try { - float a = Float.parseFloat(cell.getLength_a()); - float b = Float.parseFloat(cell.getLength_b()); - float c = Float.parseFloat(cell.getLength_c()); - float alpha = Float.parseFloat(cell.getAngle_alpha()); - float beta = Float.parseFloat(cell.getAngle_beta()); - float gamma = Float.parseFloat(cell.getAngle_gamma()); - - CrystalCell xtalCell = new CrystalCell(); - xtalCell.setA(a); - xtalCell.setB(b); - xtalCell.setC(c); - xtalCell.setAlpha(alpha); - xtalCell.setBeta(beta); - xtalCell.setGamma(gamma); - - if (!xtalCell.isCellReasonable()) { - // If the entry describes a structure determined by a technique other than X-ray crystallography, - // cell is (sometimes!) a = b = c = 1.0, alpha = beta = gamma = 90 degrees - // if so we don't add and CrystalCell will be null - logger.debug("The crystal cell read from file does not have reasonable dimensions (at least one dimension is below {}), discarding it.", - CrystalCell.MIN_VALID_CELL_SIZE); - return; - } - - structure.getPDBHeader().getCrystallographicInfo().setCrystalCell(xtalCell); - - } catch (NumberFormatException e){ - structure.getPDBHeader().getCrystallographicInfo().setCrystalCell(null); - logger.info("could not parse some cell parameters ("+e.getMessage()+"), ignoring _cell "); - } - } - - @Override - public void newSymmetry(Symmetry symmetry) { - String spaceGroup = symmetry.getSpace_group_name_H_M(); - SpaceGroup sg = SymoplibParser.getSpaceGroup(spaceGroup); - if (sg==null) { - logger.warn("Space group '"+spaceGroup+"' not recognised as a standard space group"); - structure.getPDBHeader().getCrystallographicInfo().setNonStandardSg(true); - } else { - structure.getPDBHeader().getCrystallographicInfo().setSpaceGroup(sg); - structure.getPDBHeader().getCrystallographicInfo().setNonStandardSg(false); - } - } - - @Override - public void newStructNcsOper(StructNcsOper sNcsOper) { - structNcsOper.add(sNcsOper); - } - - public void newAtomSites(AtomSites atomSites) { - - try { - Matrix4d m = new Matrix4d( - Double.parseDouble(atomSites.getFract_transf_matrix11()), Double.parseDouble(atomSites.getFract_transf_matrix12()), Double.parseDouble(atomSites.getFract_transf_matrix13()), Double.parseDouble(atomSites.getFract_transf_vector1()), - Double.parseDouble(atomSites.getFract_transf_matrix21()), Double.parseDouble(atomSites.getFract_transf_matrix22()), Double.parseDouble(atomSites.getFract_transf_matrix23()), Double.parseDouble(atomSites.getFract_transf_vector2()), - Double.parseDouble(atomSites.getFract_transf_matrix31()), Double.parseDouble(atomSites.getFract_transf_matrix32()), Double.parseDouble(atomSites.getFract_transf_matrix33()), Double.parseDouble(atomSites.getFract_transf_vector3()), - 0,0,0,1); - - parsedScaleMatrix = m; - - } catch (NumberFormatException e) { - logger.warn("Some values in _atom_sites.fract_transf_matrix or _atom_sites.fract_transf_vector could not be parsed as numbers. Can't check whether coordinate frame convention is correct! Error: {}", e.getMessage()); - structure.getPDBHeader().getCrystallographicInfo().setNonStandardCoordFrameConvention(false); - - // in this case parsedScaleMatrix stays null and can't be used in documentEnd() - } - } - - @Override - public void newStructRef(StructRef sref) { - logger.debug(sref.toString()); - strucRefs.add(sref); - } - - private StructRef getStructRef(String ref_id){ - for (StructRef structRef : strucRefs) { - - if (structRef.getId().equals(ref_id)){ - return structRef; - } - - } - return null; - - } - - /** - * create a DBRef record from the StrucRefSeq record: - *

      -	 * PDB record                    DBREF
      -	 * Field Name                    mmCIF Data Item
      -	 * Section                       n.a.
      -	 * PDB_ID_Code                   _struct_ref_seq.pdbx_PDB_id_code
      -	 * Strand_ID                     _struct_ref_seq.pdbx_strand_id
      -	 * Begin_Residue_Number          _struct_ref_seq.pdbx_auth_seq_align_beg
      -	 * Begin_Ins_Code                _struct_ref_seq.pdbx_seq_align_beg_ins_code
      -	 * End_Residue_Number            _struct_ref_seq.pdbx_auth_seq_align_end
      -	 * End_Ins_Code                  _struct_ref_seq.pdbx_seq_align_end_ins_code
      -	 * Database                      _struct_ref.db_name
      -	 * Database_Accession_No         _struct_ref_seq.pdbx_db_accession
      -	 * Database_ID_Code              _struct_ref.db_code
      -	 * Database_Begin_Residue_Number _struct_ref_seq.db_align_beg
      -	 * Databaes_Begin_Ins_Code       _struct_ref_seq.pdbx_db_align_beg_ins_code
      -	 * Database_End_Residue_Number   _struct_ref_seq.db_align_end
      -	 * Databaes_End_Ins_Code         _struct_ref_seq.pdbx_db_align_end_ins_code
      -	 * 
      - * - * - */ - @Override - public void newStructRefSeq(StructRefSeq sref) { - DBRef r = new DBRef(); - - r.setIdCode(sref.getPdbx_PDB_id_code()); - r.setDbAccession(sref.getPdbx_db_accession()); - r.setDbIdCode(sref.getPdbx_db_accession()); - - r.setChainName(sref.getPdbx_strand_id()); - StructRef structRef = getStructRef(sref.getRef_id()); - if (structRef == null){ - logger.info("could not find StructRef " + sref.getRef_id() + " for StructRefSeq " + sref); - } else { - r.setDatabase(structRef.getDb_name()); - r.setDbIdCode(structRef.getDb_code()); - } - - int seqbegin; - int seqend; - try{ - seqbegin = Integer.parseInt(sref.getPdbx_auth_seq_align_beg()); - seqend = Integer.parseInt(sref.getPdbx_auth_seq_align_end()); - } - catch(NumberFormatException e){ - // this happens in a few entries, annotation error? e.g. 6eoj - logger.warn("Couldn't parse pdbx_auth_seq_align_beg/end in _struct_ref_seq. Will not store dbref alignment info for accession {}. Error: {}", r.getDbAccession(), e.getMessage()); - return; - } - - Character begin_ins_code = ' '; - if (sref.getPdbx_seq_align_beg_ins_code() != null ) { - begin_ins_code = new Character(sref.getPdbx_seq_align_beg_ins_code().charAt(0)); - } - - Character end_ins_code = ' '; - if (sref.getPdbx_seq_align_end_ins_code() != null) { - end_ins_code = new Character(sref.getPdbx_seq_align_end_ins_code().charAt(0)); - } - - if (begin_ins_code == '?') - begin_ins_code = ' '; - - if (end_ins_code == '?') - end_ins_code = ' '; - - r.setSeqBegin(seqbegin); - r.setInsertBegin(begin_ins_code); - - r.setSeqEnd(seqend); - r.setInsertEnd(end_ins_code); - - int dbseqbegin = Integer.parseInt(sref.getDb_align_beg()); - int dbseqend = Integer.parseInt(sref.getDb_align_end()); - - Character db_begin_in_code = ' '; - if (sref.getPdbx_db_align_beg_ins_code() != null) { - db_begin_in_code = new Character(sref.getPdbx_db_align_beg_ins_code().charAt(0)); - } - - Character db_end_in_code = ' '; - if (sref.getPdbx_db_align_end_ins_code() != null) { - db_end_in_code = new Character(sref.getPdbx_db_align_end_ins_code().charAt(0)); - } - - if (db_begin_in_code == '?') - db_begin_in_code = ' '; - - if (db_end_in_code == '?') - db_end_in_code = ' '; - - - r.setDbSeqBegin(dbseqbegin); - r.setIdbnsBegin(db_begin_in_code); - - r.setDbSeqEnd(dbseqend); - r.setIdbnsEnd(db_end_in_code); - - List dbrefs = structure.getDBRefs(); - if ( dbrefs == null) - dbrefs = new ArrayList(); - dbrefs.add(r); - - logger.debug(r.toPDB()); - - structure.setDBRefs(dbrefs); - - } - - @Override - public void newStructRefSeqDif(StructRefSeqDif sref) { - sequenceDifs.add(sref); - } - - private Chain getEntityChain(String entity_id){ - - for (Chain chain : entityChains) { - if ( chain.getId().equals(entity_id)){ - - return chain; - } - } - // does not exist yet, so create... - - Chain chain = new ChainImpl(); - chain.setId(entity_id); - entityChains.add(chain); - - return chain; - - } - - //private Chain getSeqResChain(String chainID){ - // return getChainFromList(seqResChains, chainID); - //} - - - /** - * Data items in the ENTITY_SRC_GEN category record details of - * the source from which the entity was obtained in cases - * where the source was genetically manipulated. The - * following are treated separately: items pertaining to the tissue - * from which the gene was obtained, items pertaining to the host - * organism for gene expression and items pertaining to the actual - * producing organism (plasmid). - */ - @Override - public void newEntitySrcGen(EntitySrcGen entitySrcGen){ - - // add to internal list. Map to Compound object later on... - entitySrcGens.add(entitySrcGen); - } - - @Override - public void newEntitySrcNat(EntitySrcNat entitySrcNat){ - - // add to internal list. Map to Compound object later on... - entitySrcNats.add(entitySrcNat); - } - - @Override - public void newEntitySrcSyn(EntitySrcSyn entitySrcSyn){ - - // add to internal list. Map to Compound object later on... - entitySrcSyns.add(entitySrcSyn); - } - - /** - * The EntityPolySeq object provide the amino acid sequence objects for the Entities. - * Later on the entities are mapped to the BioJava {@link Chain} and {@link EntityInfo} objects. - * @param epolseq the EntityPolySeq record for one amino acid - */ - @Override - public void newEntityPolySeq(EntityPolySeq epolseq) { - - logger.debug("NEW entity poly seq " + epolseq); - - int eId = -1; - try { - eId = Integer.parseInt(epolseq.getEntity_id()); - } catch (NumberFormatException e) { - logger.warn("Could not parse entity id from EntityPolySeq: "+e.getMessage()); - } - Entity e = getEntity(eId); - - if (e == null){ - logger.info("Could not find entity "+ epolseq.getEntity_id()+". Can not match sequence to it."); - return; - } - - Chain entityChain = getEntityChain(epolseq.getEntity_id()); - - // first we check through the chemcomp provider, if it fails we do some heuristics to guess the type of group - // TODO some of this code is analogous to getNewGroup() and we should try to unify them - JD 2016-03-08 - - Group g = ChemCompGroupFactory.getGroupFromChemCompDictionary(epolseq.getMon_id()); - //int seqId = Integer.parseInt(epolseq.getNum()); - if ( g != null && !g.getChemComp().isEmpty()) { - if ( g instanceof AminoAcidImpl) { - AminoAcidImpl aa = (AminoAcidImpl) g; - aa.setRecordType(AminoAcid.SEQRESRECORD); - //aa.setId(seqId); - } - } else { - - if (epolseq.getMon_id().length()==3 && StructureTools.get1LetterCodeAmino(epolseq.getMon_id())!=null){ - AminoAcidImpl a = new AminoAcidImpl(); - a.setRecordType(AminoAcid.SEQRESRECORD); - Character code1 = StructureTools.get1LetterCodeAmino(epolseq.getMon_id()); - a.setAminoType(code1); - g = a; - - } else if ( StructureTools.isNucleotide(epolseq.getMon_id())) { - // the group is actually a nucleotide group... - NucleotideImpl n = new NucleotideImpl(); - g = n; - - } else { - logger.debug("Residue {} {} is not a standard aminoacid or nucleotide, will create a het group for it", epolseq.getNum(),epolseq.getMon_id()); - HetatomImpl h = new HetatomImpl(); - g = h; - - } - - - } - // at this stage we don't know about author residue numbers (insertion codes) - // we abuse now the ResidueNumber field setting the internal residue numbers (label_seq_id, strictly sequential and follow the seqres sequence 1 to n) - // later the actual ResidueNumbers (author residue numbers) have to be corrected in alignSeqRes() - g.setResidueNumber(ResidueNumber.fromString(epolseq.getNum())); - - g.setPDBName(epolseq.getMon_id()); - - entityChain.addGroup(g); - - } - - @Override - public void newPdbxPolySeqScheme(PdbxPolySeqScheme ppss) { - - //if ( headerOnly) - // return; - - // replace the group asym ids with the real PDB ids! - // replaceGroupSeqPos(ppss); // This might be incorrect in some pdb, to use auth_seq_id of the pdbx_poly_seq_scheme. - - - } - - - @Override - public void newPdbxNonPolyScheme(PdbxNonPolyScheme ppss) { - - //if (headerOnly) - // return; - - // merge the EntityPolySeq info and the AtomSite chains into one... - //already known ignore: - - } - - @Override - public void newPdbxEntityNonPoly(PdbxEntityNonPoly pen){ - // TODO: do something with them... - // not implemented yet... - logger.debug(pen.getEntity_id() + " " + pen.getName() + " " + pen.getComp_id()); - - } - - @Override - public void newChemComp(ChemComp c) { - // TODO: do something with them... - - } - - @Override - public void newGenericData(String category, List loopFields, - List lineData) { - - //logger.debug("unhandled category so far: " + category); - } - - @Override - public FileParsingParameters getFileParsingParameters() - { - return params; - } - - @Override - public void setFileParsingParameters(FileParsingParameters params) - { - this.params = params; - - } - - @Override - public void newChemCompDescriptor(ChemCompDescriptor ccd) { - - // TODO nothing happening here yet. - - } - - - - public List getStructOpers() { - return structOpers; - } - - @Override - public void newPdbxStrucAssembly(PdbxStructAssembly strucAssembly) { - strucAssemblies.add(strucAssembly); - - } - - public List getStructAssemblies(){ - return strucAssemblies; - } - - @Override - public void newPdbxStrucAssemblyGen(PdbxStructAssemblyGen strucAssembly) { - strucAssemblyGens.add(strucAssembly); - - } - - public List getStructAssemblyGens(){ - return strucAssemblyGens; - } - - @Override - public void newChemCompAtom(ChemCompAtom atom) { - - } - - @Override - public void newPdbxChemCompIndentifier(PdbxChemCompIdentifier id) { - - } - - @Override - public void newChemCompBond(ChemCompBond bond) { - - } - - @Override - public void newPdbxChemCompDescriptor(PdbxChemCompDescriptor desc) { - - } - - @Override - public void newStructConn(StructConn structConn) { - this.structConn.add(structConn); - } - - @Override - public void newStructSiteGen(StructSiteGen siteGen) { this.structSiteGens.add(siteGen); } - - @Override - public void newStructSite(StructSite structSite) { - - if (params.isHeaderOnly()) { - return; - } - - // Simply implement the method. - List sites = structure.getSites(); - if (sites == null) sites = new ArrayList(); - - Site site = null; - for (Site asite : sites) { - if (asite.getSiteID().equals(structSite.getId())) { - site = asite; // Prevent duplicate siteIds - } - } - boolean addSite = false; - if (site == null) { site = new Site(); addSite = true; } - site.setSiteID(structSite.getId()); - site.setDescription(structSite.getDetails()); - // site.setPdbxEvidenceCode(structSite.getPdbxEvidenceCode()); // TODO - add addition fields in Sites - if (addSite) sites.add(site); - - structure.setSites(sites); - } - - /** - * Build sites in a BioJava Structure using the original author chain id & residue numbers. - * Sites are built from struct_site_gen records that have been parsed. - */ - private void addSites() { - List sites = structure.getSites(); - if (sites == null) sites = new ArrayList(); - - for (StructSiteGen siteGen : structSiteGens) { - // For each StructSiteGen, find the residues involved, if they exist then - String site_id = siteGen.getSite_id(); // multiple could be in same site. - if (site_id == null) site_id = ""; - String comp_id = siteGen.getLabel_comp_id(); // PDBName - - // Assumption: the author chain ID and residue number for the site is consistent with the original - // author chain id and residue numbers. - - String asymId = siteGen.getLabel_asym_id(); // chain name - String authId = siteGen.getAuth_asym_id(); // chain Id - String auth_seq_id = siteGen.getAuth_seq_id(); // Res num - - String insCode = siteGen.getPdbx_auth_ins_code(); - if ( insCode != null && insCode.equals("?")) - insCode = null; - - // Look for asymID = chainID and seqID = seq_ID. Check that comp_id matches the resname. - Group g = null; - try { - Chain chain = structure.getChain(asymId); - - if (null != chain) { - try { - Character insChar = null; - if (null != insCode && insCode.length() > 0) insChar = insCode.charAt(0); - g = chain.getGroupByPDB(new ResidueNumber(null, Integer.parseInt(auth_seq_id), insChar)); - } catch (NumberFormatException e) { - logger.warn("Could not lookup residue : " + authId + auth_seq_id); - } - } - } catch (StructureException e) { - logger.warn("Problem finding residue in site entry " + siteGen.getSite_id() + " - " + e.getMessage(), e.getMessage()); - } - - if (g != null) { - // 2. find the site_id, if not existing, create anew. - Site site = null; - for (Site asite: sites) { - if (site_id.equals(asite.getSiteID())) site = asite; - } - - boolean addSite = false; - - // 3. add this residue to the site. - if (site == null) { - addSite = true; - site = new Site(); - site.setSiteID(site_id); - } - - List groups = site.getGroups(); - if (groups == null) groups = new ArrayList(); - - // Check the self-consistency of the residue reference from auth_seq_id and chain_id - if (!comp_id.equals(g.getPDBName())) { - logger.warn("comp_id doesn't match the residue at " + authId + " " + auth_seq_id + " - skipping"); - } else { - groups.add(g); - site.setGroups(groups); - } - if (addSite) sites.add(site); - } - } - structure.setSites(sites); - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/SimpleMMcifParser.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/SimpleMMcifParser.java deleted file mode 100644 index 7e9b23d3c2..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/SimpleMMcifParser.java +++ /dev/null @@ -1,1281 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Mar 4, 2008 - */ -package org.biojava.nbio.structure.io.mmcif; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - - -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.io.MMCIFFileReader; -import org.biojava.nbio.structure.io.StructureIOFile; -import org.biojava.nbio.structure.io.mmcif.model.AtomSite; -import org.biojava.nbio.structure.io.mmcif.model.AtomSites; -import org.biojava.nbio.structure.io.mmcif.model.AuditAuthor; -import org.biojava.nbio.structure.io.mmcif.model.CIFLabel; -import org.biojava.nbio.structure.io.mmcif.model.Cell; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompAtom; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompBond; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompDescriptor; -import org.biojava.nbio.structure.io.mmcif.model.DatabasePDBremark; -import org.biojava.nbio.structure.io.mmcif.model.DatabasePDBrev; -import org.biojava.nbio.structure.io.mmcif.model.DatabasePdbrevRecord; -import org.biojava.nbio.structure.io.mmcif.model.Entity; -import org.biojava.nbio.structure.io.mmcif.model.EntityPoly; -import org.biojava.nbio.structure.io.mmcif.model.EntityPolySeq; -import org.biojava.nbio.structure.io.mmcif.model.EntitySrcGen; -import org.biojava.nbio.structure.io.mmcif.model.EntitySrcNat; -import org.biojava.nbio.structure.io.mmcif.model.EntitySrcSyn; -import org.biojava.nbio.structure.io.mmcif.model.Exptl; -import org.biojava.nbio.structure.io.mmcif.model.IgnoreField; -import org.biojava.nbio.structure.io.mmcif.model.PdbxAuditRevisionHistory; -import org.biojava.nbio.structure.io.mmcif.model.PdbxChemCompDescriptor; -import org.biojava.nbio.structure.io.mmcif.model.PdbxChemCompIdentifier; -import org.biojava.nbio.structure.io.mmcif.model.PdbxDatabaseStatus; -import org.biojava.nbio.structure.io.mmcif.model.PdbxEntityNonPoly; -import org.biojava.nbio.structure.io.mmcif.model.PdbxNonPolyScheme; -import org.biojava.nbio.structure.io.mmcif.model.PdbxPolySeqScheme; -import org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssembly; -import org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssemblyGen; -import org.biojava.nbio.structure.io.mmcif.model.PdbxStructOperList; -import org.biojava.nbio.structure.io.mmcif.model.Refine; -import org.biojava.nbio.structure.io.mmcif.model.Struct; -import org.biojava.nbio.structure.io.mmcif.model.StructAsym; -import org.biojava.nbio.structure.io.mmcif.model.StructConn; -import org.biojava.nbio.structure.io.mmcif.model.StructKeywords; -import org.biojava.nbio.structure.io.mmcif.model.StructNcsOper; -import org.biojava.nbio.structure.io.mmcif.model.StructRef; -import org.biojava.nbio.structure.io.mmcif.model.StructRefSeq; -import org.biojava.nbio.structure.io.mmcif.model.StructRefSeqDif; -import org.biojava.nbio.structure.io.mmcif.model.StructSite; -import org.biojava.nbio.structure.io.mmcif.model.StructSiteGen; -import org.biojava.nbio.structure.io.mmcif.model.Symmetry; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A simple mmCif file parser - * - * - * Usage: - *
      -String file = "path/to/mmcif/file";
      -StructureIOFile pdbreader = new MMCIFFileReader();
      -
      -Structure s = pdbreader.getStructure(file);
      -System.out.println(s);
      -
      -// you can convert it to a PDB file...
      -System.out.println(s.toPDB());
      -
      - * 
      - * For more documentation see http://biojava.org/wiki/BioJava:CookBook#Protein_Structure. - * - * @author Andreas Prlic - * @author Jose Duarte - * @since 1.7 - */ -public class SimpleMMcifParser implements MMcifParser { - - - - /** - * The header appearing at the beginning of a mmCIF file. - * A "block code" can be added to it of no more than 32 chars. - * See http://www.iucr.org/__data/assets/pdf_file/0019/22618/cifguide.pdf - */ - public static final String MMCIF_TOP_HEADER = "data_"; - - public static final String COMMENT_CHAR = "#"; - public static final String LOOP_START = "loop_"; - public static final String FIELD_LINE = "_"; - - // the following are the 3 valid quoting characters in CIF - /** - * Quoting character ' - */ - private static final char S1 = '\''; - - /** - * Quoting character " - */ - private static final char S2 = '\"'; - - /** - * Quoting character ; (multi-line quoting) - */ - public static final String STRING_LIMIT = ";"; - - - private List consumers ; - - private Struct struct ; - - private static final Logger logger = LoggerFactory.getLogger(SimpleMMcifParser.class); - - public SimpleMMcifParser(){ - consumers = new ArrayList(); - struct = null; - } - - @Override - public void addMMcifConsumer(MMcifConsumer consumer) { - consumers.add(consumer); - - } - - @Override - public void clearConsumers() { - consumers.clear(); - - } - - @Override - public void removeMMcifConsumer(MMcifConsumer consumer) { - consumers.remove(consumer); - } - - public static void main(String[] args){ - String file = "/Users/andreas/WORK/PDB/mmCif/a9/1a9n.cif.gz"; - //String file = "/Users/andreas/WORK/PDB/MMCIF/1gav.mmcif"; - //String file = "/Users/andreas/WORK/PDB/MMCIF/100d.cif"; - //String file = "/Users/andreas/WORK/PDB/MMCIF/1a4a.mmcif"; - System.out.println("parsing " + file); - - StructureIOFile pdbreader = new MMCIFFileReader(); - try { - Structure s = pdbreader.getStructure(file); - System.out.println(s); - // convert it to a PDB file... - System.out.println(s.toPDB()); - } catch (IOException e) { - e.printStackTrace(); - } - - } - - @Override - public void parse(InputStream inStream) throws IOException { - parse(new BufferedReader(new InputStreamReader(inStream))); - - } - - @Override - public void parse(BufferedReader buf) - throws IOException { - - triggerDocumentStart(); - - - // init container objects... - struct = new Struct(); - String line = null; - - boolean inLoop = false; - boolean inLoopData = false; - - - List loopFields = new ArrayList(); - List lineData = new ArrayList(); - Set loopWarnings = new HashSet(); // used only to reduce logging statements - - String category = null; - - boolean foundHeader = false; - - while ( (line = buf.readLine ()) != null ){ - - if (line.isEmpty() || line.startsWith(COMMENT_CHAR)) continue; - - if (!foundHeader) { - // the first non-comment line is a data_PDBCODE line, test if this looks like a mmcif file - if (line.startsWith(MMCIF_TOP_HEADER)){ - foundHeader = true; - continue; - } else { - triggerDocumentEnd(); - throw new IOException("This does not look like a valid mmCIF file! The first line should start with 'data_', but is: '" + line+"'"); - } - } - - logger.debug(inLoop + " " + line); - - if (line.startsWith(MMCIF_TOP_HEADER)){ - // either first line in file, or beginning of new section (data block in CIF parlance) - if ( inLoop) { - //System.out.println("new data and in loop: " + line); - inLoop = false; - inLoopData = false; - lineData.clear(); - loopFields.clear(); - } - - } - - - if ( inLoop) { - - - if ( line.startsWith(LOOP_START)){ - loopFields.clear(); - inLoop = true; - inLoopData = false; - continue; - } - - if ( line.matches("\\s*"+FIELD_LINE+"\\w+.*")) { - - if (inLoopData && line.startsWith(FIELD_LINE)) { - logger.debug("Found a field line after reading loop data. Toggling to inLoop=false"); - inLoop = false; - inLoopData = false; - loopFields.clear(); - - - // a boring normal line - List data = processLine(line, buf, 2); - - if ( data.size() < 1){ - // this can happen if empty lines at end of file - lineData.clear(); - continue; - } - String key = data.get(0); - int pos = key.indexOf("."); - if ( pos < 0 ) { - // looks like a chem_comp file - // line should start with data, otherwise something is wrong! - if (! line.startsWith(MMCIF_TOP_HEADER)){ - logger.warn("This does not look like a valid mmCIF file! The first line should start with 'data_', but is '" + line+"'"); - triggerDocumentEnd(); - return; - } - // ignore the first line... - category=null; - lineData.clear(); - continue; - } - category = key.substring(0,pos); - String value = data.get(1); - loopFields.add(key.substring(pos+1,key.length())); - lineData.add(value); - - logger.debug("Found data for category {}: {}", key, value); - continue; - } - - // found another field. - String txt = line.trim(); - if ( txt.indexOf('.') > -1){ - - String[] spl = txt.split("\\."); - category = spl[0]; - String attribute = spl[1]; - loopFields.add(attribute); - logger.debug("Found category: {}, attribute: {}",category, attribute); - if ( spl.length > 2){ - logger.warn("Found nested attribute in {}, not supported yet!",txt); - } - - } else { - category = txt; - logger.debug("Found category without attribute: {}",category); - } - - - } else { - - // in loop and we found a data line - lineData = processLine(line, buf, loopFields.size()); - logger.debug("Found a loop data line with {} data fields", lineData.size()); - logger.debug("Data fields: {}", lineData.toString()); - if ( lineData.size() != loopFields.size()){ - logger.warn("Expected {} data fields, but found {} in line: {}",loopFields.size(),lineData.size(),line); - - } - - endLineChecks(category, loopFields, lineData, loopWarnings); - - lineData.clear(); - - inLoopData = true; - } - - } else { - // not in loop - - if ( line.startsWith(LOOP_START)){ - if ( category != null) - endLineChecks(category, loopFields, lineData, loopWarnings); - - resetBuffers(loopFields, lineData, loopWarnings); - category = null; - inLoop = true; - inLoopData = false; - logger.debug("Detected LOOP_START: '{}'. Toggling to inLoop=true", LOOP_START); - continue; - } else { - logger.debug("Normal line "); - inLoop = false; - - // a boring normal line - List data = processLine(line, buf, 2); - - if ( data.size() < 1){ - // this can happen if empty lines at end of file - lineData.clear(); - continue; - } - String key = data.get(0); - int pos = key.indexOf("."); - if ( pos < 0 ) { - // looks like a chem_comp file - // line should start with data, otherwise something is wrong! - if (! line.startsWith(MMCIF_TOP_HEADER)){ - logger.warn("This does not look like a valid mmCIF file! The first line should start with 'data_', but is '" + line+"'"); - triggerDocumentEnd(); - return; - } - // ignore the first line... - category=null; - lineData.clear(); - continue; - } - - if (category!=null && !key.substring(0,pos).equals(category)) { - // we've changed category: need to flush the previous one - endLineChecks(category, loopFields, lineData, loopWarnings); - resetBuffers(loopFields, lineData, loopWarnings); - } - - category = key.substring(0,pos); - - String value = data.get(1); - loopFields.add(key.substring(pos+1,key.length())); - lineData.add(value); - - logger.debug("Found data for category {}: {}", key, value); - - } - } - } - - if (category!=null && lineData.size()>0 && lineData.size()==loopFields.size()) { - // the last category in the file will still be missing, we add it now - endLineChecks(category, loopFields, lineData, loopWarnings); - resetBuffers(loopFields, lineData, loopWarnings); - } - - if (struct != null){ - triggerStructData(struct); - } - - triggerDocumentEnd(); - - } - - private void resetBuffers(List loopFields, List lineData, Set loopWarnings) { - loopFields.clear(); - lineData.clear(); - loopWarnings.clear(); - } - - private List processSingleLine(String line){ - - List data = new ArrayList(); - - if ( line.trim().length() == 0){ - return data; - } - - if ( line.trim().length() == 1){ - if ( line.startsWith(STRING_LIMIT)) - return data; - } - boolean inString = false; // semicolon (;) quoting - boolean inS1 = false; // single quote (') quoting - boolean inS2 = false; // double quote (") quoting - String word = ""; - - for (int i=0; i< line.length(); i++ ){ - - Character c = line.charAt(i); - - Character nextC = null; - if (i < line.length() - 1) - nextC = line.charAt(i+1); - - Character prevC = null; - if (i>0) - prevC = line.charAt(i-1); - - if (c == ' ') { - - if ( ! inString){ - if ( ! word.equals("")) - data.add(word.trim()); - word = ""; - } else { - // we are in a string, add the space - word += c; - } - - } else if (c == S1 ) { - - if ( inString){ - - boolean wordEnd = false; - if (! inS2) { - if (nextC==null || Character.isWhitespace(nextC)){ - i++; - wordEnd = true; - } - } - - - if ( wordEnd ) { - - // at end of string - if ( ! word.equals("")) - data.add(word.trim()); - word = ""; - inString = false; - inS1 = false; - } else { - word += c; - } - - } else if (prevC==null || prevC==' ') { - // the beginning of a new string - inString = true; - inS1 = true; - } else { - word += c; - } - } else if ( c == S2 ){ - if ( inString){ - - boolean wordEnd = false; - if (! inS1) { - if (nextC==null || Character.isWhitespace(nextC)){ - i++; - wordEnd = true; - } - } - - if ( wordEnd ) { - - // at end of string - if ( ! word.equals("")) - data.add(word.trim()); - word = ""; - inString = false; - inS2 = false; - } else { - word += c; - } - } else if (prevC==null || prevC==' ') { - // the beginning of a new string - inString = true; - inS2 = true; - } else { - word += c; - } - } else { - word += c; - } - - } - if ( ! word.trim().equals("")) - data.add(word); - - - return data; - - } - - /** - * Get the content of a cif entry - * - * @param line - * @param buf - * @return - */ - private List processLine(String line, - BufferedReader buf, - int fieldLength) - throws IOException{ - - //System.out.println("XX processLine " + fieldLength + " " + line); - // go through the line and process each character - List lineData = new ArrayList(); - - boolean inString = false; - - StringBuilder bigWord = null; - - while ( true ){ - - if ( line.startsWith(STRING_LIMIT)){ - if (! inString){ - - inString = true; - if ( line.length() > 1) - bigWord = new StringBuilder(line.substring(1)); - else - bigWord = new StringBuilder(""); - - - } else { - // the end of a word - lineData.add(bigWord.toString()); - bigWord = null; - inString = false; - - } - } else { - if ( inString ) - bigWord.append(line); - else { - - List dat = processSingleLine(line); - - for (String d : dat){ - lineData.add(d); - } - } - } - - //System.out.println("in process line : " + lineData.size() + " " + fieldLength); - - if ( lineData.size() > fieldLength){ - - logger.warn("wrong data length ("+lineData.size()+ - ") should be ("+fieldLength+") at line " + line + " got lineData: " + lineData); - return lineData; - } - - if ( lineData.size() == fieldLength) - return lineData; - - - line = buf.readLine(); - if ( line == null) - break; - } - return lineData; - - } - - - - private void endLineChecks(String category,List loopFields, List lineData, Set loopWarnings ) throws IOException{ - - logger.debug("Processing category {}, with fields: {}",category,loopFields.toString()); - // System.out.println("parsed the following data: " +category + " fields: "+ - // loopFields + " DATA: " + - // lineData); - - if ( loopFields.size() != lineData.size()){ - logger.warn("looks like we got a problem with nested string quote characters:"); - throw new IOException("data length ("+ lineData.size() + - ") != fields length ("+loopFields.size()+ - ") category: " +category + " fields: "+ - loopFields + " DATA: " + - lineData ); - } - - if ( category.equals("_entity")){ - - Entity e = (Entity) buildObject( - Entity.class.getName(), - loopFields,lineData, loopWarnings); - triggerNewEntity(e); - - } else if (category.equals("_entity_poly")) { - EntityPoly ep = (EntityPoly) buildObject(EntityPoly.class.getName(), loopFields, lineData, loopWarnings); - triggerNewEntityPoly(ep); - - } else if ( category.equals("_struct")){ - - struct = (Struct) buildObject( - Struct.class.getName(), - loopFields, lineData, loopWarnings); - - } else if ( category.equals("_atom_site")){ - - AtomSite a = (AtomSite) buildObject( - AtomSite.class.getName(), - loopFields, lineData, loopWarnings); - triggerNewAtomSite(a); - - } else if ( category.equals("_database_PDB_rev")){ - DatabasePDBrev dbrev = (DatabasePDBrev) buildObject( - DatabasePDBrev.class.getName(), - loopFields, lineData, loopWarnings); - - triggerNewDatabasePDBrev(dbrev); - - } else if ( category.equals("_database_PDB_rev_record")){ - DatabasePdbrevRecord dbrev = (DatabasePdbrevRecord) buildObject( - DatabasePdbrevRecord.class.getName(), - loopFields, lineData, loopWarnings); - - triggerNewDatabasePDBrevRecord(dbrev); - - // MMCIF version 5 dates - } else if ( category.equals("_pdbx_audit_revision_history")) { - PdbxAuditRevisionHistory history = (PdbxAuditRevisionHistory) buildObject( - PdbxAuditRevisionHistory.class.getName(), - loopFields, lineData, loopWarnings); - - triggerNewPdbxAuditRevisionHistory(history); - - // MMCIF version 5 dates - } else if ( category.equals("_pdbx_database_status")) { - PdbxDatabaseStatus status = (PdbxDatabaseStatus) buildObject( - PdbxDatabaseStatus.class.getName(), - loopFields, lineData, loopWarnings); - - triggerNewPdbxDatabaseStatus(status); - - }else if ( category.equals("_database_PDB_remark")){ - DatabasePDBremark remark = (DatabasePDBremark) buildObject( - DatabasePDBremark.class.getName(), - loopFields, lineData, loopWarnings); - - triggerNewDatabasePDBremark(remark); - - } else if ( category.equals("_exptl")){ - Exptl exptl = (Exptl) buildObject( - Exptl.class.getName(), - loopFields,lineData, loopWarnings); - - triggerExptl(exptl); - - } else if ( category.equals("_cell")){ - Cell cell = (Cell) buildObject( - Cell.class.getName(), - loopFields,lineData, loopWarnings); - - triggerNewCell(cell); - - } else if ( category.equals("_symmetry")){ - Symmetry symmetry = (Symmetry) buildObject( - Symmetry.class.getName(), - loopFields,lineData, loopWarnings); - - triggerNewSymmetry(symmetry); - } else if ( category.equals("_struct_ncs_oper")) { - - StructNcsOper sNcsOper = (StructNcsOper) buildObject( - StructNcsOper.class.getName(), - loopFields, lineData, loopWarnings); - triggerNewStructNcsOper(sNcsOper); - } else if ( category.equals("_atom_sites")) { - - AtomSites atomSites = (AtomSites) buildObject( - AtomSites.class.getName(), - loopFields, lineData, loopWarnings); - triggerNewAtomSites(atomSites); - - } else if ( category.equals("_struct_ref")){ - StructRef sref = (StructRef) buildObject( - StructRef.class.getName(), - loopFields,lineData, loopWarnings); - - triggerNewStrucRef(sref); - - } else if ( category.equals("_struct_ref_seq")){ - StructRefSeq sref = (StructRefSeq) buildObject( - StructRefSeq.class.getName(), - loopFields,lineData, loopWarnings); - - triggerNewStrucRefSeq(sref); - } else if ( category.equals("_struct_ref_seq_dif")) { - StructRefSeqDif sref = (StructRefSeqDif) buildObject( - StructRefSeqDif.class.getName(), - loopFields, lineData, loopWarnings); - - triggerNewStrucRefSeqDif(sref); - } else if ( category.equals("_struct_site_gen")) { - StructSiteGen sref = (StructSiteGen) buildObject( - StructSiteGen.class.getName(), - loopFields, lineData, loopWarnings); - - triggerNewStructSiteGen(sref); - } else if ( category.equals("_struct_site")) { - StructSite sref = (StructSite) buildObject( - StructSite.class.getName(), - loopFields, lineData, loopWarnings); - triggerNewStructSite(sref); - } else if ( category.equals("_entity_poly_seq")){ - EntityPolySeq exptl = (EntityPolySeq) buildObject( - EntityPolySeq.class.getName(), - loopFields,lineData, loopWarnings); - - triggerNewEntityPolySeq(exptl); - } else if ( category.equals("_entity_src_gen")){ - EntitySrcGen entitySrcGen = (EntitySrcGen) buildObject( - EntitySrcGen.class.getName(), - loopFields,lineData, loopWarnings); - triggerNewEntitySrcGen(entitySrcGen); - } else if ( category.equals("_entity_src_nat")){ - EntitySrcNat entitySrcNat = (EntitySrcNat) buildObject( - EntitySrcNat.class.getName(), - loopFields,lineData, loopWarnings); - triggerNewEntitySrcNat(entitySrcNat); - } else if ( category.equals("_pdbx_entity_src_syn")){ - EntitySrcSyn entitySrcSyn = (EntitySrcSyn) buildObject( - EntitySrcSyn.class.getName(), - loopFields,lineData, loopWarnings); - triggerNewEntitySrcSyn(entitySrcSyn); - } else if ( category.equals("_struct_asym")){ - StructAsym sasym = (StructAsym) buildObject( - StructAsym.class.getName(), - loopFields,lineData, loopWarnings); - - triggerNewStructAsym(sasym); - - } else if ( category.equals("_pdbx_poly_seq_scheme")){ - PdbxPolySeqScheme ppss = (PdbxPolySeqScheme) buildObject( - PdbxPolySeqScheme.class.getName(), - loopFields,lineData, loopWarnings); - - triggerNewPdbxPolySeqScheme(ppss); - - } else if ( category.equals("_pdbx_nonpoly_scheme")){ - PdbxNonPolyScheme ppss = (PdbxNonPolyScheme) buildObject( - PdbxNonPolyScheme.class.getName(), - loopFields,lineData, loopWarnings); - - triggerNewPdbxNonPolyScheme(ppss); - - } else if ( category.equals("_pdbx_entity_nonpoly")){ - PdbxEntityNonPoly pen = (PdbxEntityNonPoly) buildObject( - PdbxEntityNonPoly.class.getName(), - loopFields,lineData, loopWarnings - ); - triggerNewPdbxEntityNonPoly(pen); - } else if ( category.equals("_struct_keywords")){ - StructKeywords kw = (StructKeywords)buildObject( - StructKeywords.class.getName(), - loopFields,lineData, loopWarnings - ); - triggerNewStructKeywords(kw); - } else if (category.equals("_refine")){ - Refine r = (Refine)buildObject( - Refine.class.getName(), - loopFields,lineData, loopWarnings - ); - triggerNewRefine(r); - } else if (category.equals("_chem_comp")){ - ChemComp c = (ChemComp)buildObject( - ChemComp.class.getName(), - loopFields, lineData, loopWarnings - ); - triggerNewChemComp(c); - } else if (category.equals("_audit_author")) { - AuditAuthor aa = (AuditAuthor)buildObject( - AuditAuthor.class.getName(), - loopFields, lineData, loopWarnings); - triggerNewAuditAuthor(aa); - } else if (category.equals("_pdbx_chem_comp_descriptor")) { - ChemCompDescriptor ccd = (ChemCompDescriptor) buildObject( - ChemCompDescriptor.class.getName(), - loopFields, lineData, loopWarnings); - triggerNewChemCompDescriptor(ccd); - } else if (category.equals("_pdbx_struct_oper_list")) { - - PdbxStructOperList structOper = (PdbxStructOperList) buildObject( - PdbxStructOperList.class.getName(), - loopFields, lineData, loopWarnings - ); - triggerNewPdbxStructOper(structOper); - - } else if (category.equals("_pdbx_struct_assembly")) { - PdbxStructAssembly sa = (PdbxStructAssembly) buildObject( - PdbxStructAssembly.class.getName(), - loopFields, lineData, loopWarnings); - triggerNewPdbxStructAssembly(sa); - - } else if (category.equals("_pdbx_struct_assembly_gen")) { - PdbxStructAssemblyGen sa = (PdbxStructAssemblyGen) buildObject( - PdbxStructAssemblyGen.class.getName(), - loopFields, lineData, loopWarnings); - triggerNewPdbxStructAssemblyGen(sa); - } else if ( category.equals("_chem_comp_atom")){ - ChemCompAtom atom = (ChemCompAtom)buildObject( - ChemCompAtom.class.getName(), - loopFields,lineData, loopWarnings); - triggerNewChemCompAtom(atom); - - }else if ( category.equals("_chem_comp_bond")){ - ChemCompBond bond = (ChemCompBond)buildObject( - ChemCompBond.class.getName(), - loopFields,lineData, loopWarnings); - triggerNewChemCompBond(bond); - } else if ( category.equals("_pdbx_chem_comp_identifier")){ - PdbxChemCompIdentifier id = (PdbxChemCompIdentifier)buildObject( - PdbxChemCompIdentifier.class.getName(), - loopFields,lineData, loopWarnings); - triggerNewPdbxChemCompIdentifier(id); - } else if ( category.equals("_pdbx_chem_comp_descriptor")){ - PdbxChemCompDescriptor id = (PdbxChemCompDescriptor)buildObject( - PdbxChemCompDescriptor.class.getName(), - loopFields,lineData, loopWarnings); - triggerNewPdbxChemCompDescriptor(id); - } else if ( category.equals("_struct_conn")){ - StructConn id = (StructConn)buildObject( - StructConn.class.getName(), - loopFields,lineData, loopWarnings); - triggerNewStructConn(id); - - } else { - - logger.debug("Using a generic bean for category {}",category); - - // trigger a generic bean that can deal with all missing data types... - triggerGeneric(category,loopFields,lineData); - } - - - } - - -// private PdbxStructOperList getPdbxStructOperList(List loopFields, -// List lineData) { -// PdbxStructOperList so = new PdbxStructOperList(); -// -// //System.out.println(loopFields); -// //System.out.println(lineData); -// -// String id = lineData.get(loopFields.indexOf("id")); -// so.setId(id); -// so.setType(lineData.get(loopFields.indexOf("type"))); -// Matrix matrix = new Matrix(3,3); -// for (int i = 1 ; i <=3 ; i++){ -// for (int j =1 ; j <= 3 ; j++){ -// String max = String.format("matrix[%d][%d]",j,i); -// -// String val = lineData.get(loopFields.indexOf(max)); -// Double d = Double.parseDouble(val); -// matrix.set(j-1,i-1,d); -// // matrix.set(i-1,j-1,d); -// } -// } -// -// double[] coords =new double[3]; -// -// for ( int i = 1; i <=3 ; i++){ -// String v = String.format("vector[%d]",i); -// String val = lineData.get(loopFields.indexOf(v)); -// Double d = Double.parseDouble(val); -// coords[i-1] = d; -// } -// -// so.setMatrix(matrix); -// so.setVector(coords); -// -// -// -// return so; -// } - - public void triggerNewPdbxStructOper(PdbxStructOperList structOper) { - for(MMcifConsumer c : consumers){ - c.newPdbxStructOperList(structOper); - } - - } - - public void triggerNewStructNcsOper(StructNcsOper sNcsOper) { - for(MMcifConsumer c : consumers){ - c.newStructNcsOper(sNcsOper); - } - - } - - public void triggerNewAtomSites(AtomSites atomSites) { - for(MMcifConsumer c : consumers){ - c.newAtomSites(atomSites); - } - } - - /** - * Populates a bean object from the {@link org.biojava.nbio.structure.io.mmcif.model} package, - * from the data read from a CIF file. - * It uses reflection to lookup the field and setter method names given the category - * found in the CIF file. - *

      - * Due to limitations in variable names in java, not all fields can have names - * exactly as defined in the CIF categories. In those cases the {@link CIFLabel} tag - * can be used in the field names to give the appropriate name that corresponds to the - * CIF category, which is the name that will be then looked up here. - * The {@link IgnoreField} tag can also be used to exclude fields from being looked up. - * @param className - * @param loopFields - * @param lineData - * @param warnings - * @return - */ - private Object buildObject(String className, List loopFields, List lineData, Set warnings) { - - Object o = null; - Class c = null; - - try { - // build up the Entity object from the line data... - c = Class.forName(className); - - o = c.newInstance(); - - } catch (InstantiationException|ClassNotFoundException|IllegalAccessException e){ - logger.error( "Error while constructing {}: {}", className, e.getMessage()); - return null; - } - - // these methods get the fields but also looking at the IgnoreField and CIFLabel annotations - Field[] fields = MMCIFFileTools.getFields(c); - String[] names = MMCIFFileTools.getFieldNames(fields); - - // let's build a map of all methods so that we can look up the setter methods later - Method[] methods = c.getMethods(); - - Map methodMap = new HashMap(); - for (Method m : methods) { - methodMap.put(m.getName(),m); - } - - // and a map of all the fields so that we can lookup them up later - Map names2fields = new HashMap<>(); - for (int i=0;i[] pType = setter.getParameterTypes(); - - - try { - if ( pType[0].getName().equals(Integer.class.getName())) { - if ( val != null && ! val.equals("?") && !val.equals(".")) { - - Integer intVal = Integer.parseInt(val); - setter.invoke(o, intVal); - - } - } else { - // default val is a String - setter.invoke(o, val); - } - } catch (IllegalAccessException|InvocationTargetException e) { - logger.error("Could not invoke setter {} with value {} for class {}", setterMethodName, val, className); - } - - } - - return o; - } - - private void produceWarning(String key, String val, Class c, Set warnings) { - - String warning = "Trying to set field " + key + " in "+ c.getName() +" found in file, but no corresponding field could be found in model class (value:" + val + ")"; - String warnkey = key+"-"+c.getName(); - // Suppress duplicate warnings or attempts to store empty data - if( val.equals("?") || val.equals(".") || ( warnings != null && warnings.contains(warnkey)) ) { - logger.debug(warning); - } else { - logger.info(warning); - } - - if(warnings != null) { - warnings.add(warnkey); - } - - } - - public void triggerGeneric(String category, List loopFields, List lineData){ - for(MMcifConsumer c : consumers){ - c.newGenericData(category, loopFields, lineData); - } - } - - public void triggerNewEntity(Entity entity){ - for(MMcifConsumer c : consumers){ - c.newEntity(entity); - } - } - - public void triggerNewEntityPoly(EntityPoly entityPoly) { - for(MMcifConsumer c : consumers){ - c.newEntityPoly(entityPoly); - } - } - - public void triggerNewEntityPolySeq(EntityPolySeq epolseq){ - for(MMcifConsumer c : consumers){ - c.newEntityPolySeq(epolseq); - } - } - public void triggerNewEntitySrcGen(EntitySrcGen entitySrcGen){ - for(MMcifConsumer c : consumers){ - c.newEntitySrcGen(entitySrcGen); - } - } - public void triggerNewEntitySrcNat(EntitySrcNat entitySrcNat){ - for(MMcifConsumer c : consumers){ - c.newEntitySrcNat(entitySrcNat); - } - } - public void triggerNewEntitySrcSyn(EntitySrcSyn entitySrcSyn){ - for(MMcifConsumer c : consumers){ - c.newEntitySrcSyn(entitySrcSyn); - } - } - public void triggerNewChemComp(ChemComp cc){ - - for(MMcifConsumer c : consumers){ - c.newChemComp(cc); - } - } - public void triggerNewStructAsym(StructAsym sasym){ - for(MMcifConsumer c : consumers){ - c.newStructAsym(sasym); - } - } - - private void triggerStructData(Struct struct){ - for(MMcifConsumer c : consumers){ - c.setStruct(struct); - } - } - - private void triggerNewAtomSite(AtomSite atom){ - for(MMcifConsumer c : consumers){ - c.newAtomSite(atom); - } - } - - private void triggerNewAuditAuthor(AuditAuthor aa){ - for(MMcifConsumer c : consumers){ - c.newAuditAuthor(aa); - } - } - - private void triggerNewPdbxAuditRevisionHistory(PdbxAuditRevisionHistory history) { - for(MMcifConsumer c : consumers){ - c.newPdbxAuditRevisionHistory(history); - } - } - - private void triggerNewPdbxDatabaseStatus(PdbxDatabaseStatus status) { - for(MMcifConsumer c : consumers){ - c.newPdbxDatabaseStatus(status); - } - } - - private void triggerNewDatabasePDBrev(DatabasePDBrev dbrev){ - for(MMcifConsumer c : consumers){ - c.newDatabasePDBrev(dbrev); - } - } - private void triggerNewDatabasePDBrevRecord(DatabasePdbrevRecord dbrev){ - for(MMcifConsumer c : consumers){ - c.newDatabasePDBrevRecord(dbrev); - } - } - - private void triggerNewDatabasePDBremark(DatabasePDBremark remark){ - for(MMcifConsumer c : consumers){ - c.newDatabasePDBremark(remark); - } - } - - private void triggerExptl(Exptl exptl){ - for(MMcifConsumer c : consumers){ - c.newExptl(exptl); - } - } - - private void triggerNewCell(Cell cell) { - for(MMcifConsumer c : consumers){ - c.newCell(cell); - } - } - - private void triggerNewSymmetry(Symmetry symmetry) { - for(MMcifConsumer c : consumers){ - c.newSymmetry(symmetry); - } - } - - private void triggerNewStrucRef(StructRef sref){ - for(MMcifConsumer c : consumers){ - c.newStructRef(sref); - } - } - - private void triggerNewStrucRefSeq(StructRefSeq sref){ - for(MMcifConsumer c : consumers){ - c.newStructRefSeq(sref); - } - } - - private void triggerNewStrucRefSeqDif(StructRefSeqDif sref){ - for(MMcifConsumer c : consumers){ - c.newStructRefSeqDif(sref); - } - } - - private void triggerNewPdbxPolySeqScheme(PdbxPolySeqScheme ppss){ - for(MMcifConsumer c : consumers){ - c.newPdbxPolySeqScheme(ppss); - } - } - private void triggerNewPdbxNonPolyScheme(PdbxNonPolyScheme ppss){ - for(MMcifConsumer c : consumers){ - c.newPdbxNonPolyScheme(ppss); - } - } - public void triggerNewPdbxEntityNonPoly(PdbxEntityNonPoly pen){ - for (MMcifConsumer c: consumers){ - c.newPdbxEntityNonPoly(pen); - } - } - public void triggerNewStructKeywords(StructKeywords kw){ - for (MMcifConsumer c: consumers){ - c.newStructKeywords(kw); - } - } - public void triggerNewRefine(Refine r){ - for (MMcifConsumer c: consumers){ - c.newRefine(r); - } - } - public void triggerDocumentStart(){ - for(MMcifConsumer c : consumers){ - c.documentStart(); - } - } - public void triggerDocumentEnd(){ - for(MMcifConsumer c : consumers){ - c.documentEnd(); - } - } - public void triggerNewChemCompDescriptor(ChemCompDescriptor ccd) { - for(MMcifConsumer c : consumers){ - c.newChemCompDescriptor(ccd); - } - } - private void triggerNewPdbxStructAssembly(PdbxStructAssembly sa) { - for(MMcifConsumer c : consumers){ - c.newPdbxStrucAssembly(sa); - } - } - private void triggerNewPdbxStructAssemblyGen(PdbxStructAssemblyGen sa) { - for(MMcifConsumer c : consumers){ - c.newPdbxStrucAssemblyGen(sa); - } - } - - private void triggerNewChemCompAtom(ChemCompAtom atom) { - for(MMcifConsumer c : consumers){ - c.newChemCompAtom(atom); - } - } - - private void triggerNewChemCompBond(ChemCompBond bond) { - for(MMcifConsumer c : consumers){ - c.newChemCompBond(bond); - } - } - - private void triggerNewPdbxChemCompIdentifier(PdbxChemCompIdentifier id) { - for(MMcifConsumer c : consumers){ - c.newPdbxChemCompIndentifier(id); - } - } - private void triggerNewPdbxChemCompDescriptor(PdbxChemCompDescriptor id) { - for(MMcifConsumer c : consumers){ - c.newPdbxChemCompDescriptor(id); - } - } - private void triggerNewStructConn(StructConn id) { - for(MMcifConsumer c : consumers){ - c.newStructConn(id); - } - } - private void triggerNewStructSiteGen(StructSiteGen id) { - for (MMcifConsumer c : consumers) { - c.newStructSiteGen(id); - } - } - private void triggerNewStructSite(StructSite id) { - for (MMcifConsumer c : consumers) { - c.newStructSite(id); - } - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java deleted file mode 100644 index 9475a6d036..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/ZipChemCompProvider.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.HashSet; -import java.util.Set; -import java.util.zip.GZIPInputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** This chemical component provider retrieves and caches chemical component definition files from a - * zip archive specified in its construction. If the archive does not contain the record, an attempt is - * made to download it using DownloadChemCompProvider. The downloaded file is then added to the archive. - * - * The class is thread-safe and the same ZipChemCompProvider should be used by all threads to prevent - * simultaneous read or write to the zip archive. A zip archive will be created if missing. - * - * @author edlunde - * @author larsonm - * @since 12/05/12 - * updated 3/5/2016 for Java 7 ZipFileSystem - */ -public class ZipChemCompProvider implements ChemCompProvider{ - private static final Logger s_logger = LoggerFactory.getLogger(ZipChemCompProvider.class); - - private final Path m_tempDir; // Base path where $m_zipRootDir/ will be downloaded to. - private final Path m_zipRootDir; - private final Path m_zipFile; - private final DownloadChemCompProvider m_dlProvider; - - private boolean m_removeCif; - - // Missing IDs from library that cannot be download added here to prevent delays. - private Set unavailable = new HashSet(); - - /** - * ZipChemCompProvider is a Chemical Component provider that stores chemical components - * in a zip archive. Missing chemical components are downloaded and appended to the - * archive. If non-existent a new zip archive will be created. - * - * @param chemicalComponentDictionaryFile : path to zip archive for chemical components. - * @param tempDir : path for temporary directory, (null) defaults to path in property "java.io.tmpdir". - * @throws IOException - */ - public ZipChemCompProvider(String chemicalComponentDictionaryFile, String tempDir) throws IOException { - this.m_zipFile = Paths.get(chemicalComponentDictionaryFile); - - // Use a default temporary directory if not passed a value. - if (tempDir == null || tempDir.equals("")) { - this.m_tempDir = Paths.get(System.getProperty("java.io.tmpdir")); - } else { - this.m_tempDir = Paths.get(tempDir); - } - - this.m_zipRootDir = Paths.get("chemcomp"); - - // Setup an instance of the download chemcomp provider. - this.m_dlProvider = new DownloadChemCompProvider(m_tempDir.toString()); - this.m_removeCif = true; - initializeZip(); - } - - // See comments in addToZipFileSystem for why initialization is required with - // ZipFileSystems - due to URI issues in Java7. - private void initializeZip() throws IOException { - s_logger.info("Using chemical component dictionary: " + m_zipFile.toString()); - final File f = m_zipFile.toFile(); - if (!f.exists()) { - s_logger.info("Creating missing zip archive: " + m_zipFile.toString()); - FileOutputStream fo = new FileOutputStream(f); - ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(fo)); - try { - zip.putNextEntry(new ZipEntry("chemcomp/")); - zip.closeEntry(); - } finally { - zip.close(); - } - } - } - - /** - * Remove downloaded .cif.gz after adding to zip archive? - * Default is true. - * @param doRemove - */ - public void setRemoveCif(boolean doRemove) { - m_removeCif = doRemove; - } - - /* (non-Javadoc) - * @see org.biojava.nbio.structure.io.mmcif.ChemCompProvider#getChemComp(java.lang.String) - * - * @param recordName : three letter PDB name for a residue - * @return ChemComp from .zip or ChemComp from repository. Will return empty ChemComp when unable to find a residue and will return null if not provided a valid recordName. - */ - @Override - public ChemComp getChemComp(String recordName) { - if (null == recordName) return null; - - // handle non-existent ChemComp codes and do not repeatedly attempt to add these. - for (String str : unavailable) { - if (recordName.equals(str)) return getEmptyChemComp(recordName); - } - - // Try to pull from zip, if fail then download. - ChemComp cc = getFromZip(recordName); - if (cc == null) { - s_logger.info("File "+recordName+" not found in archive. Attempting download from PDB."); - cc = downloadAndAdd(recordName); - } - - // If a null record or an empty chemcomp, return a default ChemComp and blacklist. - if (cc == null || (null == cc.getName() && cc.getAtoms().size() == 0)) { - s_logger.info("Unable to find or download " + recordName + " - excluding from future searches."); - unavailable.add(recordName); - return getEmptyChemComp(recordName); - } - return cc; - } - - /** Use DownloadChemCompProvider to grab a gzipped cif record from the PDB. - * Zip all downloaded cif.gz files into the dictionary. - * - * @param recordName is the three-letter chemical component code (i.e. residue name). - * @return ChemComp matching recordName - */ - private ChemComp downloadAndAdd(String recordName){ - final ChemComp cc = m_dlProvider.getChemComp(recordName); - - // final File [] files = finder(m_tempDir.resolve("chemcomp").toString(), "cif.gz"); - final File [] files = new File[1]; - Path cif = m_tempDir.resolve("chemcomp").resolve(recordName + ".cif.gz"); - files[0] = cif.toFile(); - if (files[0] != null) { - addToZipFileSystem(m_zipFile, files, m_zipRootDir); - if (m_removeCif) for (File f : files) f.delete(); - } - return cc; - } - - /** - * Cleanup chemical component (.cif.gz) files downloaded to tmpdir. - * @param tempdir : path to temporary directory for chemical components - */ - public static void purgeTempFiles(String tempdir) { - if (tempdir == null) return; - - s_logger.info("Removing: "+tempdir); - Path dlPath = Paths.get(tempdir).resolve("chemcomp"); - File[] chemCompOutFiles = finder(dlPath.toString(), "cif.gz"); - if (null != chemCompOutFiles) for (File f : chemCompOutFiles) f.delete(); - dlPath.toFile().delete(); - } - - /** - * Return an empty ChemComp group for a three-letter resName. - * @param resName - * @return - */ - private ChemComp getEmptyChemComp(String resName){ - String pdbName = ""; // Empty string is default - if (null != resName && resName.length() >= 3) { - pdbName = resName.substring(0,3); - } - final ChemComp comp = new ChemComp(); - comp.setOne_letter_code("?"); - comp.setThree_letter_code(pdbName); - comp.setPolymerType(PolymerType.unknown); - comp.setResidueType(ResidueType.atomn); - return comp; - } - - /** - * Return File(s) in dirName that match suffix. - * @param dirName - * @param suffix - * @return - */ - static private File[] finder( String dirName, final String suffix){ - if (null == dirName || null == suffix) { - return null; - } - - final File dir = new File(dirName); - return dir.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String filename) - { return filename.endsWith(suffix); } - } ); - } - - /** - * This is synchronized, along with addToFileSystem to prevent simulatenous reading/writing. - * @param recordName to find in zipfile. - * @return ChemComp if found or null if missing. - */ - private synchronized ChemComp getFromZip(String recordName) { - ChemComp cc = null; - if (!m_zipFile.toFile().exists()) return cc; - final String filename = "chemcomp/" + recordName+".cif.gz"; - - // try with resources block to read from the filesystem. - try (FileSystem fs = FileSystems.newFileSystem(m_zipFile, (ClassLoader) null)) { - Path cif = fs.getPath(filename); - - if (Files.exists(cif)) { - final InputStream zipStream = Files.newInputStream(cif); - final InputStream inputStream = new GZIPInputStream(zipStream); - s_logger.debug("reading " + recordName + " from " + m_zipFile); - final MMcifParser parser = new SimpleMMcifParser(); - final ChemCompConsumer consumer = new ChemCompConsumer(); - parser.addMMcifConsumer(consumer); - parser.parse(inputStream); - inputStream.close(); - - final ChemicalComponentDictionary dict = consumer.getDictionary(); - cc = dict.getChemComp(recordName); - } - } catch (IOException e) { - s_logger.error("Unable to read from zip file : " + e.getMessage()); - } - - return cc; - } - - /** - * Add an array of files to a zip archive. - * Synchronized to prevent simultaneous reading/writing. - * - * @param zipFile is a destination zip archive - * @param files is an array of files to be added - * @param pathWithinArchive is the path within the archive to add files to - * @return true if successfully appended these files. - */ - private synchronized boolean addToZipFileSystem(Path zipFile, File[] files, Path pathWithinArchive) { - boolean ret = false; - - /* URIs in Java 7 cannot have spaces, must use Path instead - * and so, cannot use the properties map to describe need to create - * a new zip archive. ZipChemCompProvider.initilizeZip to creates the - * missing zip file */ - - /* - // convert the filename to a URI - String uriString = "jar:file:" + zipFile.toUri().getPath(); - final URI uri = URI.create(uriString); - - // if filesystem doesn't exist, create one. - final Map env = new HashMap<>(); - // Create a new zip if one isn't present. - if (!zipFile.toFile().exists()) { - System.out.println("Need to create " + zipFile.toString()); - } - env.put("create", String.valueOf(!zipFile.toFile().exists())); - // Specify the encoding as UTF -8 - env.put("encoding", "UTF-8"); - */ - - // Copy in each file. - try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, null)) { - Files.createDirectories(pathWithinArchive); - for (File f : files) { - if (!f.isDirectory() && f.exists()) { - Path externalFile = f.toPath(); - Path pathInZipFile = zipfs.getPath(pathWithinArchive.resolve(f.getName()).toString()); - Files.copy(externalFile, pathInZipFile, - StandardCopyOption.REPLACE_EXISTING); - } - } - ret = true; - } catch (IOException ex) { - s_logger.error("Unable to add entries to Chemical Component zip archive : " + ex.getMessage()); - ret = false; - } - return ret; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ChemCompTools.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ChemCompTools.java deleted file mode 100644 index d1392f5117..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ChemCompTools.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Mar 4, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.chem; - -import org.biojava.nbio.structure.io.mmcif.ChemicalComponentDictionary; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; - -import java.util.*; - -/** Some tools for working with chemical compounds. - * - * @author Andreas Prlic - * @since 1.7 - * - */ -public class ChemCompTools { - - private static final Character UNKNOWN_ONE_LETTER_CODE = 'X'; - private static final Character UNKNOWN_NUCLEOTIDE = 'N'; - - /** - * Lookup table to convert standard amino acid's monomer ids to one-letter-codes - */ - private static final Map AMINO_ACID_LOOKUP_3TO1; - - /** - * Lookup table to convert standard amino acid's one-letter-codes to monomer ids - */ - private static final Map AMINO_ACID_LOOKUP_1TO3; - - /** - * Lookup table to convert standard nucleic acid's monomer ids to one-letter-codes - */ - private static final Map DNA_LOOKUP_2TO1; - - /** - * Lookup table to convert standard nucleic acid's one-letter-codes to monomer ids - */ - private static final Map DNA_LOOKUP_1TO2; - - /** - * Static block that initializes lookup maps and initializes their ResidueInfo instances - */ - static - { - Map foo = new HashMap(); - foo.put("ALA", 'A'); - foo.put("ASP", 'D'); - foo.put("ASN", 'N'); - foo.put("ASX", 'B'); - foo.put("ARG", 'R'); - foo.put("CYS", 'C'); - foo.put("GLU", 'E'); - foo.put("GLN", 'Q'); - foo.put("GLY", 'G'); - foo.put("GLX", 'Z'); - foo.put("HIS", 'H'); - foo.put("ILE", 'I'); - foo.put("LYS", 'K'); - foo.put("LEU", 'L'); - foo.put("MET", 'M'); - foo.put("PHE", 'F'); - foo.put("PRO", 'P'); - foo.put("SER", 'S'); - foo.put("THR", 'T'); - foo.put("TRP", 'W'); - foo.put("TYR", 'Y'); - foo.put("VAL", 'V'); - AMINO_ACID_LOOKUP_3TO1 = Collections.unmodifiableMap((Collections.synchronizedMap(foo))); - - Map bar = new HashMap(); - bar.put('A', "ALA"); - bar.put('D', "ASP"); - bar.put('N', "ASN"); - bar.put('B', "ASX"); - bar.put('R', "ARG"); - bar.put('C', "CYS"); - bar.put('E', "GLU"); - bar.put('Q', "GLN"); - bar.put('G', "GLY"); - bar.put('Z', "GLX"); - bar.put('H', "HIS"); - bar.put('I', "ILE"); - bar.put('K', "LYS"); - bar.put('L', "LEU"); - bar.put('M', "MET"); - bar.put('F', "PHE"); - bar.put('P', "PRO"); - bar.put('S', "SER"); - bar.put('T', "THR"); - bar.put('W', "TRP"); - bar.put('Y', "TYR"); - bar.put('V', "VAL"); - AMINO_ACID_LOOKUP_1TO3 = Collections.unmodifiableMap(Collections.synchronizedMap(bar)); - - foo = new HashMap(); - foo.put("DA",'A'); - foo.put("DC",'C'); - foo.put("DG",'G'); - foo.put("DI",'I'); - foo.put("DU",'U'); - foo.put("DT",'T'); - DNA_LOOKUP_2TO1 = Collections.unmodifiableMap((Collections.synchronizedMap(foo))); - - bar = new HashMap(); - bar.put('A',"DA"); - bar.put('C',"DC"); - bar.put('G',"DG"); - bar.put('I',"DI"); - bar.put('U',"DU"); - bar.put('T',"DT"); - DNA_LOOKUP_1TO2 = Collections.unmodifiableMap(Collections.synchronizedMap(bar)); - - - // initialise standard chemical components - List stdMonIds = new ArrayList(); - stdMonIds.addAll(AMINO_ACID_LOOKUP_3TO1.keySet()); - stdMonIds.addAll(DNA_LOOKUP_2TO1.keySet()); - - - - } - - public static Character getAminoOneLetter(String chemCompId){ - return AMINO_ACID_LOOKUP_3TO1.get(chemCompId); - } - - - public static Character getDNAOneLetter(String chemCompId){ - return DNA_LOOKUP_2TO1.get(chemCompId) ; - } - - public static String getAminoThreeLetter(Character c){ - return AMINO_ACID_LOOKUP_1TO3.get(c); - } - - public static String getDNATwoLetter(Character c){ - return DNA_LOOKUP_1TO2.get(c); - } - - public static final boolean isStandardChemComp(ChemComp cc){ - - String pid = cc.getMon_nstd_parent_comp_id(); - String one = cc.getOne_letter_code(); - - PolymerType polymerType = cc.getPolymerType(); - - // standard residues have no parent - if ((pid == null) || (pid.equals("?"))){ - - // and they have a one letter code - if ( ( one != null) && ( ! one.equals("?") )){ - - // peptides and dpeptides must not have X - if ( (polymerType == PolymerType.peptide) || - ( polymerType == PolymerType.dpeptide)) { - return performPeptideCheck(cc, one); - - } - if (polymerType == PolymerType.rna){ - return performRNACheck(cc); - } - if (polymerType == PolymerType.dna) { - - return performDNACheck(cc); - - } - - //System.err.println("Non standard chem comp: " + cc); - return false; - } - } - return false; - } - - - private static boolean performRNACheck(ChemComp cc) { - if (cc.getId().length() == 1) - return true; - else - return false; - } - - - private static boolean performDNACheck(ChemComp cc) { - if ( cc.getId().equals(UNKNOWN_NUCLEOTIDE.toString())) - return false; - - Character c = getDNAOneLetter(cc.getId()); - if ( c==null){ - // we did not find it in the list of standard nucleotides - return false; - } - return true; - } - - - private static boolean performPeptideCheck(ChemComp cc, String one) { - if (one.equals(UNKNOWN_ONE_LETTER_CODE.toString())) { - return false; - } - Character c = getAminoOneLetter(cc.getId()); - if ( c==null){ - // we did not find it in the list of standard aminos - return false; - } - return true; - } - - - // TODO: component 175 has 3 chars as a one letter code... - // Figure out what to do with it... - // so does: 4F3,5ZA and others - public static Character getOneLetterCode(ChemComp cc, ChemicalComponentDictionary dictionary){ - if ( cc.getResidueType() == ResidueType.nonPolymer ) - return null; - - if ( cc.isStandard()) - return cc.getOne_letter_code().charAt(0); - - ChemComp parent = dictionary.getParent(cc); - if ( parent == null){ - //System.err.println("parent is null " + cc); - return cc.getOne_letter_code().charAt(0); - } - PolymerType poly = cc.getPolymerType(); - if (( poly == PolymerType.peptide) || ( poly == PolymerType.dpeptide)){ - Character c = getAminoOneLetter(parent.getId()); - if ( c == null) - c = UNKNOWN_ONE_LETTER_CODE; - return c; - } - if ( poly == PolymerType.dna){ - Character c = getDNAOneLetter(parent.getId()); - if (c == null) - c = UNKNOWN_NUCLEOTIDE; - return c; - - } - return cc.getMon_nstd_parent_comp_id().charAt(0); - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/MetalBondDistance.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/MetalBondDistance.java deleted file mode 100644 index ab2658c7e3..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/MetalBondDistance.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.chem; - -/** A bean that contains cutoffs for correctly detecting metal bonds. - * Definitions are in file bond_distance_limits.cif.gz - * - * Created by andreas on 6/9/16. - */ -public class MetalBondDistance { - - private String atomType1; - private String atomType2; - private float lowerLimit; - private float upperLimit; - - public String getAtomType1() { - return atomType1; - } - - public void setAtomType1(String atomType1) { - this.atomType1 = atomType1; - } - - public String getAtomType2() { - return atomType2; - } - - public void setAtomType2(String atomType2) { - this.atomType2 = atomType2; - } - - public float getLowerLimit() { - return lowerLimit; - } - - public void setLowerLimit(float lowerLimit) { - this.lowerLimit = lowerLimit; - } - - public float getUpperLimit() { - return upperLimit; - } - - public void setUpperLimit(float upperLimit) { - this.upperLimit = upperLimit; - } - - @Override - public String toString() { - return "MetalBindDistance{" + - "atomType1='" + atomType1 + '\'' + - ", atomType2='" + atomType2 + '\'' + - ", lowerLimit=" + lowerLimit + - ", upperLimit=" + upperLimit + - '}'; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/PolymerType.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/PolymerType.java deleted file mode 100644 index d7b4853cf0..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/PolymerType.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * - */ -package org.biojava.nbio.structure.io.mmcif.chem; - -import java.io.Serializable; -import java.util.*; - -/** - * Enumerates the classification of polymers. - * This information is derived from the mmcif dictionary - * @author mulvaney - * @author Andreas Prlic - * @see link into mmCIF dictionary - * @since 1.7 - */ -public enum PolymerType implements Serializable -{ - - /** - * polypeptide(L) - */ - peptide("polypeptide(L)"), - - /** - * polypeptide(D) - */ - dpeptide("polypeptide(D)"), - - /** - * polydeoxyribonucleotide - */ - dna("polydeoxyribonucleotide"), - - /** - * polyribonucleotide - */ - rna("polyribonucleotide"), - - /** - * polydeoxyribonucleotide/polyribonucleotide hybrid - */ - dnarna("polydeoxyribonucleotide/polyribonucleotide hybrid"), - - /** - * polysaccharide(D) - */ - polysaccharide("polysaccharide(D)"), - - /** - * polysaccharide(L) - */ - lpolysaccharide("polysaccharide(L)"), - - /** - * other - */ - otherPolymer("other"), - - /** - * cyclic peptides - */ - cyclicPeptide("cyclic-pseudo-peptide"), - - /** - * Peptide nucleic acids - */ - peptideNucleicAcid("peptide nucleic acid"), - - /** - * if all else fails... - */ - unknown(null); - - static Map lookupTable = new HashMap<>(); - - static { - - for (PolymerType rt : PolymerType.values() ) { - if ( rt == unknown) - continue; - lookupTable.put(rt.entity_poly_type,rt); - lookupTable.put(rt.entity_poly_type.toLowerCase(),rt); - } - } - - - PolymerType(String entity_poly_type) - { - this.entity_poly_type = entity_poly_type; - } - public final String entity_poly_type; - - public static PolymerType polymerTypeFromString(String polymerType) - { - - if ( polymerType.equalsIgnoreCase(peptide.entity_poly_type)) - return peptide; - - PolymerType ptype = lookupTable.get(polymerType); - if ( ptype != null) - return ptype; - - ptype = lookupTable.get(polymerType.toLowerCase()); - if ( ptype != null) - return ptype; - - - for(PolymerType pt : PolymerType.values()) - { - if(polymerType.equals(pt.entity_poly_type)) - { - return pt; - } - } - return unknown; - } - - /** - * Convenience Set of polymer types classified as protein. This only contains {@link #peptide} - */ - public static final Set PROTEIN_ONLY; - - /** - * Convenience Set of polymer types classified as DNA. This only contains {@link #dna} - */ - public static final Set DNA_ONLY; - - /** - * Convenience Set of polymer types classified as RNA. This only contains {@link #rna} - */ - public static final Set RNA_ONLY; - - /** - * Convenience Set of polymer types classified as DNA. This contains: - *

        - *
      • {@link #dna}
      • - *
      • {@link #rna}
      • - *
      • {@link #dnarna}
      • - *
      - */ - public static final Set POLYNUCLEOTIDE_ONLY; - - /** - * Convenience Set of all polymer types. - */ - public static final Set ALL_POLYMER_TYPES; - - static { - Set tmp; - - tmp = new HashSet(); - tmp.add(peptide); - PROTEIN_ONLY = Collections.unmodifiableSet(tmp); - - tmp = new HashSet(); - tmp.add(dna); - DNA_ONLY = Collections.unmodifiableSet(tmp); - - tmp = new HashSet(); - tmp.add(rna); - RNA_ONLY = Collections.unmodifiableSet(tmp); - - tmp = new HashSet(); - tmp.add(dna); - tmp.add(rna); - tmp.add(dnarna); - POLYNUCLEOTIDE_ONLY = Collections.unmodifiableSet(tmp); - - ALL_POLYMER_TYPES = Collections.unmodifiableSet(new HashSet(Arrays.asList(values()))); - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ResidueType.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ResidueType.java deleted file mode 100644 index d6f6b0a40a..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/chem/ResidueType.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * - */ -package org.biojava.nbio.structure.io.mmcif.chem; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - - -/** - * Enumerates the possible classifications of residues. These are generally more specific than PolymerTypes - * This information is derived from the mmcif dictionary. - * @author mulvaney - * @author Andreas Prlic - * @see link into mmCIF dictionary - * @since 1.7 - */ - -public enum ResidueType implements Serializable { - - atomn(null, "null"), // present in db for _chem_comp.id_ = 'CFL' but not enumerated in dictionary - // Peptides - dPeptideLinking(PolymerType.dpeptide, "D-peptide linking"), - lPeptideLinking(PolymerType.peptide, "L-peptide linking"), - glycine(PolymerType.peptide,"PEPTIDE LINKING"), - peptideLike(PolymerType.otherPolymer, "peptide-like"), - dPeptideAminoTerminus(PolymerType.dpeptide, "D-peptide NH3 amino terminus"), - lPeptideAminoTerminus(PolymerType.peptide, "L-peptide NH3 amino terminus"), - dPeptideCarboxyTerminus(PolymerType.dpeptide, "D-peptide COOH carboxy terminus"), - lPeptideCarboxyTerminus(PolymerType.peptide, "L-peptide COOH carboxy terminus"), - // Nucleotides - dnaLinking(PolymerType.dna, "DNA linking"), - rnaLinking(PolymerType.rna, "RNA linking"), - dna3PrimeTerminus(PolymerType.dna, "DNA OH 3 prime terminus"), - rna3PrimeTerminus(PolymerType.rna, "RNA OH 3 prime terminus"), - dna5PrimeTerminus(PolymerType.dna, "DNA OH 5 prime terminus"), - rna5PrimeTerminus(PolymerType.rna, "RNA OH 5 prime terminus"), - // Sugars - dSaccharide(PolymerType.polysaccharide, "D-saccharide"), - dSaccharide14and14linking(PolymerType.polysaccharide, "D-saccharide 1,4 and 1,4 linking"), - dSaccharide14and16linking(PolymerType.polysaccharide, "D-saccharide 1,4 and 1,6 linking"), - lSaccharide(PolymerType.lpolysaccharide, "L-saccharide"), - lSaccharide14and14linking(PolymerType.lpolysaccharide, "L-saccharide 1,4 and 1,4 linking"), - lSaccharide14and16linking(PolymerType.lpolysaccharide, "L-saccharide 1,4 and 1,6 linking"), - saccharide(PolymerType.polysaccharide, "saccharide"), - // Iso-peptides - dBetaPeptideCGammaLinking(PolymerType.dpeptide,"D-beta-peptide, C-gamma linking"), - dGammaPeptideCDeltaLinking(PolymerType.dpeptide,"D-gamma-peptide, C-delta linking"), - lBetaPeptideCGammaLinking(PolymerType.peptide,"L-beta-peptide, C-gamma linking"), - lGammaPeptideCDeltaLinking(PolymerType.peptide,"L-gamma-peptide, C-delta linking"), - // L nucleotides. As of 2015-04, these are only found in D-DNA hybrids, so they don't have their own PolymerType - lDNALinking(PolymerType.dna,"L-DNA linking"), - lRNALinking(PolymerType.dna,"L-RNA linking"), - // Other - nonPolymer(null, "non-polymer"), - otherChemComp(null, "other"); - - - static Map lookupTable = new HashMap<>(); - - static { - - for (ResidueType rt : ResidueType.values() ) { - lookupTable.put(rt.chem_comp_type,rt); - lookupTable.put(rt.chem_comp_type.toLowerCase(),rt); - } - } - ResidueType(PolymerType pt, String chem_comp_type) - { - this.polymerType = pt; - this.chem_comp_type = chem_comp_type; - - } - - /** - * The associated {@link PolymerType} - */ - public final PolymerType polymerType; - - /** - * Gets the associated PolymerType, which are less specific - * @return - */ - public PolymerType getPolymerType() {return polymerType;} - - /** - * String value of the type - */ - public final String chem_comp_type; - - /** Get ResidueType by chem_comp_type - * - * @param chem_comp_type e.g. L-peptide linking - * @return - */ - public static ResidueType getResidueTypeFromString(String chem_comp_type) - { - - // Almost all calls to this method are for L-peptide linking. Use this knowledge for a shortcut. - - if ( chem_comp_type.equalsIgnoreCase(lPeptideLinking.chem_comp_type) ) - return lPeptideLinking; - - ResidueType rtype = lookupTable.get(chem_comp_type); - if ( rtype != null) - return rtype; - - /** Unfortunately it can be guaranteed that chem_comp_type case sensitivity is preserved. - * E.g. mmtf has it all upper-case. As such we need to do a second check - */ - rtype = lookupTable.get(chem_comp_type.toLowerCase()); - if ( rtype != null) - return rtype; - - - - // preserving previous behaviour. Not sure if this is really necessary? - for(ResidueType rt : ResidueType.values()) - { - if(rt.chem_comp_type.equalsIgnoreCase(chem_comp_type)) - { - return rt; - } - if ( rt.chem_comp_type.toLowerCase().startsWith(chem_comp_type.toLowerCase())) - return rt; - if ( chem_comp_type.toLowerCase().startsWith(rt.chem_comp_type.toLowerCase())) - return rt; - } - return null; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AbstractBean.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AbstractBean.java deleted file mode 100644 index 7dc7b869f5..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AbstractBean.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at May 31, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import org.biojava.nbio.structure.Chain; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; - -/** a generic class that implements the toString method for a bean - * - * @author Andreas Prlic - * - */ -public abstract class AbstractBean { - - private static final Logger logger = LoggerFactory.getLogger(AbstractBean.class); - - @Override - @SuppressWarnings({ "unchecked" }) - public String toString(){ - StringBuffer buf = new StringBuffer(); - buf.append(this.getClass().getName()).append(": "); - /* disabled for the moment - - buf.append(" chains: " ); - Iterator iter = chainList.iterator(); - while (iter.hasNext()){ - Chain c = iter.next(); - buf.append (c.getName() + " "); - } - - */ - try { - Class c = this.getClass(); - Method[] methods = c.getMethods(); - - for (int i = 0; i < methods.length; i++) { - Method m = methods[i]; - - String name = m.getName(); - if ( name.substring(0,3).equals("get")) { - - Object o = m.invoke(this, new Object[]{}); - if ( o instanceof String){ - buf.append(name.substring(3, name.length())+": "+ o + " "); - } - else if ( o instanceof List){ - buf.append(name.substring(3, name.length())).append(": "); - - Listlst = (List)o; - for (Object obj : lst){ - if ( obj instanceof Chain){ - continue; - } - buf.append(obj).append(" "); - } - - } - else { - // ignore... - } - } - - } - - } catch (InvocationTargetException e){ - logger.error("Exception caught while producing toString",e); - } catch (IllegalAccessException e) { - logger.error("Exception caught while producing toString",e); - } - - - //if ( organismScientific != null) - // buf.append(" organism scientific: " + organismScientific); - - - return buf.toString(); - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AtomSite.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AtomSite.java deleted file mode 100644 index 93ded0ca45..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AtomSite.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Apr 26, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -public class AtomSite extends AbstractBean{ - - String group_PDB; - String id; - String type_symbol; - String label_atom_id; - String label_alt_id; - String label_comp_id; - String label_asym_id; - String label_entity_id; - String label_seq_id; - String pdbx_PDB_ins_code; - - String Cartn_x; - String Cartn_y; - String Cartn_z; - String occupancy; - String B_iso_or_equiv; - - String Cartn_x_esd; - String Cartn_y_esd; - String Cartn_z_esd; - String occupancy_esd; - String B_iso_or_equiv_esd; - String pdbx_formal_charge; - - String auth_seq_id; - String auth_comp_id; - String auth_asym_id; - String auth_atom_id; - String pdbx_PDB_model_num; - - - public String getGroup_PDB() { - return group_PDB; - } - public void setGroup_PDB(String group_PDB) { - this.group_PDB = group_PDB; - } - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getType_symbol() { - return type_symbol; - } - public void setType_symbol(String type_symbol) { - this.type_symbol = type_symbol; - } - - public String getLabel_alt_id() { - return label_alt_id; - } - public void setLabel_alt_id(String label_alt_id) { - this.label_alt_id = label_alt_id; - } - public String getLabel_comp_id() { - return label_comp_id; - } - public void setLabel_comp_id(String label_comp_id) { - this.label_comp_id = label_comp_id; - } - public String getLabel_entity_id() { - return label_entity_id; - } - public void setLabel_entity_id(String label_entity_id) { - this.label_entity_id = label_entity_id; - } - public String getLabel_seq_id() { - return label_seq_id; - } - public void setLabel_seq_id(String label_seq_id) { - this.label_seq_id = label_seq_id; - } - public String getPdbx_PDB_ins_code() { - return pdbx_PDB_ins_code; - } - public void setPdbx_PDB_ins_code(String pdbx_PDB_ins_code) { - this.pdbx_PDB_ins_code = pdbx_PDB_ins_code; - } - public String getCartn_x() { - return Cartn_x; - } - public void setCartn_x(String cartn_x) { - Cartn_x = cartn_x; - } - public String getCartn_y() { - return Cartn_y; - } - public void setCartn_y(String cartn_y) { - Cartn_y = cartn_y; - } - public String getCartn_z() { - return Cartn_z; - } - public void setCartn_z(String cartn_z) { - Cartn_z = cartn_z; - } - public String getOccupancy() { - return occupancy; - } - public void setOccupancy(String occupancy) { - this.occupancy = occupancy; - } - public String getB_iso_or_equiv() { - return B_iso_or_equiv; - } - public void setB_iso_or_equiv(String b_iso_or_equiv) { - B_iso_or_equiv = b_iso_or_equiv; - } - public String getCartn_x_esd() { - return Cartn_x_esd; - } - public void setCartn_x_esd(String cartn_x_esd) { - Cartn_x_esd = cartn_x_esd; - } - public String getCartn_y_esd() { - return Cartn_y_esd; - } - public void setCartn_y_esd(String cartn_y_esd) { - Cartn_y_esd = cartn_y_esd; - } - public String getCartn_z_esd() { - return Cartn_z_esd; - } - public void setCartn_z_esd(String cartn_z_esd) { - Cartn_z_esd = cartn_z_esd; - } - public String getAuth_seq_id() { - return auth_seq_id; - } - public void setAuth_seq_id(String auth_seq_id) { - this.auth_seq_id = auth_seq_id; - } - public String getAuth_comp_id() { - return auth_comp_id; - } - public void setAuth_comp_id(String auth_comp_id) { - this.auth_comp_id = auth_comp_id; - } - public String getAuth_asym_id() { - return auth_asym_id; - } - public void setAuth_asym_id(String auth_asym_id) { - this.auth_asym_id = auth_asym_id; - } - public String getAuth_atom_id() { - return auth_atom_id; - } - public void setAuth_atom_id(String auth_atom_id) { - this.auth_atom_id = auth_atom_id; - } - public String getPdbx_PDB_model_num() { - return pdbx_PDB_model_num; - } - public void setPdbx_PDB_model_num(String pdbx_PDB_model_num) { - this.pdbx_PDB_model_num = pdbx_PDB_model_num; - } - public String getLabel_atom_id() { - return label_atom_id; - } - public void setLabel_atom_id(String label_atom_id) { - this.label_atom_id = label_atom_id; - } - public String getLabel_asym_id() { - return label_asym_id; - } - public void setLabel_asym_id(String label_asym_id) { - this.label_asym_id = label_asym_id; - } - public String getOccupancy_esd() { - return occupancy_esd; - } - public void setOccupancy_esd(String occupancy_esd) { - this.occupancy_esd = occupancy_esd; - } - public String getB_iso_or_equiv_esd() { - return B_iso_or_equiv_esd; - } - public void setB_iso_or_equiv_esd(String b_iso_or_equiv_esd) { - B_iso_or_equiv_esd = b_iso_or_equiv_esd; - } - public String getPdbx_formal_charge() { - return pdbx_formal_charge; - } - public void setPdbx_formal_charge(String pdbx_formal_charge) { - this.pdbx_formal_charge = pdbx_formal_charge; - } - - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AtomSites.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AtomSites.java deleted file mode 100644 index 9e4db8b683..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AtomSites.java +++ /dev/null @@ -1,421 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** - * A class containing the _atom_sites data. Equivalent to the SCALE records in PDB files. - * - * - * @author Jose Duarte - * - */ -public class AtomSites extends AbstractBean { - - String entry_id; - - // to my knowledge this field is not used - JD 2016-11-22 - String Cartn_transform_axes; - - @CIFLabel(label="fract_transf_matrix[1][1]") - String fract_transf_matrix11; - - @CIFLabel(label="fract_transf_matrix[1][2]") - String fract_transf_matrix12; - - @CIFLabel(label="fract_transf_matrix[1][3]") - String fract_transf_matrix13; - - - @CIFLabel(label="fract_transf_matrix[2][1]") - String fract_transf_matrix21; - - @CIFLabel(label="fract_transf_matrix[2][2]") - String fract_transf_matrix22; - - @CIFLabel(label="fract_transf_matrix[2][3]") - String fract_transf_matrix23; - - - @CIFLabel(label="fract_transf_matrix[3][1]") - String fract_transf_matrix31; - - @CIFLabel(label="fract_transf_matrix[3][2]") - String fract_transf_matrix32; - - @CIFLabel(label="fract_transf_matrix[3][3]") - String fract_transf_matrix33; - - - @CIFLabel(label="fract_transf_vector[1]") - String fract_transf_vector1; - - @CIFLabel(label="fract_transf_vector[2]") - String fract_transf_vector2; - - @CIFLabel(label="fract_transf_vector[3]") - String fract_transf_vector3; - - // these fields are unusual but appear in some entries like 5e5j - JD 2016-11-22 - @CIFLabel(label="Cartn_transf_matrix[1][1]") - String Cartn_transf_matrix11; - - @CIFLabel(label="Cartn_transf_matrix[1][2]") - String Cartn_transf_matrix12; - - @CIFLabel(label="Cartn_transf_matrix[1][3]") - String Cartn_transf_matrix13; - - @CIFLabel(label="Cartn_transf_matrix[2][1]") - String Cartn_transf_matrix21; - - @CIFLabel(label="Cartn_transf_matrix[2][2]") - String Cartn_transf_matrix22; - - @CIFLabel(label="Cartn_transf_matrix[2][3]") - String Cartn_transf_matrix23; - - @CIFLabel(label="Cartn_transf_matrix[3][1]") - String Cartn_transf_matrix31; - - @CIFLabel(label="Cartn_transf_matrix[3][2]") - String Cartn_transf_matrix32; - - @CIFLabel(label="Cartn_transf_matrix[3][3]") - String Cartn_transf_matrix33; - - @CIFLabel(label="Cartn_transf_vector[1]") - String Cartn_transf_vector1; - - @CIFLabel(label="Cartn_transf_vector[2]") - String Cartn_transf_vector2; - - @CIFLabel(label="Cartn_transf_vector[3]") - String Cartn_transf_vector3; - - - public String getEntry_id() { - return entry_id; - } - public void setEntry_id(String entry_id) { - this.entry_id = entry_id; - } - /** - * @return the cartn_transform_axes - */ - public String getCartn_transform_axes() { - return Cartn_transform_axes; - } - /** - * @param cartn_transform_axes the cartn_transform_axes to set - */ - public void setCartn_transform_axes(String cartn_transform_axes) { - Cartn_transform_axes = cartn_transform_axes; - } - /** - * @return the fract_transf_matrix11 - */ - public String getFract_transf_matrix11() { - return fract_transf_matrix11; - } - /** - * @param fract_transf_matrix11 the fract_transf_matrix11 to set - */ - public void setFract_transf_matrix11(String fract_transf_matrix11) { - this.fract_transf_matrix11 = fract_transf_matrix11; - } - /** - * @return the fract_transf_matrix12 - */ - public String getFract_transf_matrix12() { - return fract_transf_matrix12; - } - /** - * @param fract_transf_matrix12 the fract_transf_matrix12 to set - */ - public void setFract_transf_matrix12(String fract_transf_matrix12) { - this.fract_transf_matrix12 = fract_transf_matrix12; - } - /** - * @return the fract_transf_matrix13 - */ - public String getFract_transf_matrix13() { - return fract_transf_matrix13; - } - /** - * @param fract_transf_matrix13 the fract_transf_matrix13 to set - */ - public void setFract_transf_matrix13(String fract_transf_matrix13) { - this.fract_transf_matrix13 = fract_transf_matrix13; - } - /** - * @return the fract_transf_matrix21 - */ - public String getFract_transf_matrix21() { - return fract_transf_matrix21; - } - /** - * @param fract_transf_matrix21 the fract_transf_matrix21 to set - */ - public void setFract_transf_matrix21(String fract_transf_matrix21) { - this.fract_transf_matrix21 = fract_transf_matrix21; - } - /** - * @return the fract_transf_matrix22 - */ - public String getFract_transf_matrix22() { - return fract_transf_matrix22; - } - /** - * @param fract_transf_matrix22 the fract_transf_matrix22 to set - */ - public void setFract_transf_matrix22(String fract_transf_matrix22) { - this.fract_transf_matrix22 = fract_transf_matrix22; - } - /** - * @return the fract_transf_matrix23 - */ - public String getFract_transf_matrix23() { - return fract_transf_matrix23; - } - /** - * @param fract_transf_matrix23 the fract_transf_matrix23 to set - */ - public void setFract_transf_matrix23(String fract_transf_matrix23) { - this.fract_transf_matrix23 = fract_transf_matrix23; - } - /** - * @return the fract_transf_matrix31 - */ - public String getFract_transf_matrix31() { - return fract_transf_matrix31; - } - /** - * @param fract_transf_matrix31 the fract_transf_matrix31 to set - */ - public void setFract_transf_matrix31(String fract_transf_matrix31) { - this.fract_transf_matrix31 = fract_transf_matrix31; - } - /** - * @return the fract_transf_matrix32 - */ - public String getFract_transf_matrix32() { - return fract_transf_matrix32; - } - /** - * @param fract_transf_matrix32 the fract_transf_matrix32 to set - */ - public void setFract_transf_matrix32(String fract_transf_matrix32) { - this.fract_transf_matrix32 = fract_transf_matrix32; - } - /** - * @return the fract_transf_matrix33 - */ - public String getFract_transf_matrix33() { - return fract_transf_matrix33; - } - /** - * @param fract_transf_matrix33 the fract_transf_matrix33 to set - */ - public void setFract_transf_matrix33(String fract_transf_matrix33) { - this.fract_transf_matrix33 = fract_transf_matrix33; - } - /** - * @return the fract_transf_vector1 - */ - public String getFract_transf_vector1() { - return fract_transf_vector1; - } - /** - * @param fract_transf_vector1 the fract_transf_vector1 to set - */ - public void setFract_transf_vector1(String fract_transf_vector1) { - this.fract_transf_vector1 = fract_transf_vector1; - } - /** - * @return the fract_transf_vector2 - */ - public String getFract_transf_vector2() { - return fract_transf_vector2; - } - /** - * @param fract_transf_vector2 the fract_transf_vector2 to set - */ - public void setFract_transf_vector2(String fract_transf_vector2) { - this.fract_transf_vector2 = fract_transf_vector2; - } - /** - * @return the fract_transf_vector3 - */ - public String getFract_transf_vector3() { - return fract_transf_vector3; - } - /** - * @param fract_transf_vector3 the fract_transf_vector3 to set - */ - public void setFract_transf_vector3(String fract_transf_vector3) { - this.fract_transf_vector3 = fract_transf_vector3; - } - /** - * @return the cartn_transf_matrix11 - */ - public String getCartn_transf_matrix11() { - return Cartn_transf_matrix11; - } - /** - * @param cartn_transf_matrix11 the cartn_transf_matrix11 to set - */ - public void setCartn_transf_matrix11(String cartn_transf_matrix11) { - Cartn_transf_matrix11 = cartn_transf_matrix11; - } - /** - * @return the cartn_transf_matrix12 - */ - public String getCartn_transf_matrix12() { - return Cartn_transf_matrix12; - } - /** - * @param cartn_transf_matrix12 the cartn_transf_matrix12 to set - */ - public void setCartn_transf_matrix12(String cartn_transf_matrix12) { - Cartn_transf_matrix12 = cartn_transf_matrix12; - } - /** - * @return the cartn_transf_matrix13 - */ - public String getCartn_transf_matrix13() { - return Cartn_transf_matrix13; - } - /** - * @param cartn_transf_matrix13 the cartn_transf_matrix13 to set - */ - public void setCartn_transf_matrix13(String cartn_transf_matrix13) { - Cartn_transf_matrix13 = cartn_transf_matrix13; - } - /** - * @return the cartn_transf_matrix21 - */ - public String getCartn_transf_matrix21() { - return Cartn_transf_matrix21; - } - /** - * @param cartn_transf_matrix21 the cartn_transf_matrix21 to set - */ - public void setCartn_transf_matrix21(String cartn_transf_matrix21) { - Cartn_transf_matrix21 = cartn_transf_matrix21; - } - /** - * @return the cartn_transf_matrix22 - */ - public String getCartn_transf_matrix22() { - return Cartn_transf_matrix22; - } - /** - * @param cartn_transf_matrix22 the cartn_transf_matrix22 to set - */ - public void setCartn_transf_matrix22(String cartn_transf_matrix22) { - Cartn_transf_matrix22 = cartn_transf_matrix22; - } - /** - * @return the cartn_transf_matrix23 - */ - public String getCartn_transf_matrix23() { - return Cartn_transf_matrix23; - } - /** - * @param cartn_transf_matrix23 the cartn_transf_matrix23 to set - */ - public void setCartn_transf_matrix23(String cartn_transf_matrix23) { - Cartn_transf_matrix23 = cartn_transf_matrix23; - } - /** - * @return the cartn_transf_matrix31 - */ - public String getCartn_transf_matrix31() { - return Cartn_transf_matrix31; - } - /** - * @param cartn_transf_matrix31 the cartn_transf_matrix31 to set - */ - public void setCartn_transf_matrix31(String cartn_transf_matrix31) { - Cartn_transf_matrix31 = cartn_transf_matrix31; - } - /** - * @return the cartn_transf_matrix32 - */ - public String getCartn_transf_matrix32() { - return Cartn_transf_matrix32; - } - /** - * @param cartn_transf_matrix32 the cartn_transf_matrix32 to set - */ - public void setCartn_transf_matrix32(String cartn_transf_matrix32) { - Cartn_transf_matrix32 = cartn_transf_matrix32; - } - /** - * @return the cartn_transf_matrix33 - */ - public String getCartn_transf_matrix33() { - return Cartn_transf_matrix33; - } - /** - * @param cartn_transf_matrix33 the cartn_transf_matrix33 to set - */ - public void setCartn_transf_matrix33(String cartn_transf_matrix33) { - Cartn_transf_matrix33 = cartn_transf_matrix33; - } - /** - * @return the cartn_transf_vector1 - */ - public String getCartn_transf_vector1() { - return Cartn_transf_vector1; - } - /** - * @param cartn_transf_vector1 the cartn_transf_vector1 to set - */ - public void setCartn_transf_vector1(String cartn_transf_vector1) { - Cartn_transf_vector1 = cartn_transf_vector1; - } - /** - * @return the cartn_transf_vector2 - */ - public String getCartn_transf_vector2() { - return Cartn_transf_vector2; - } - /** - * @param cartn_transf_vector2 the cartn_transf_vector2 to set - */ - public void setCartn_transf_vector2(String cartn_transf_vector2) { - Cartn_transf_vector2 = cartn_transf_vector2; - } - /** - * @return the cartn_transf_vector3 - */ - public String getCartn_transf_vector3() { - return Cartn_transf_vector3; - } - /** - * @param cartn_transf_vector3 the cartn_transf_vector3 to set - */ - public void setCartn_transf_vector3(String cartn_transf_vector3) { - Cartn_transf_vector3 = cartn_transf_vector3; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AuditAuthor.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AuditAuthor.java deleted file mode 100644 index 4cfc0962c7..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/AuditAuthor.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * PDB web development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * - * Created on Jul 25, 2009 - * Created by Andreas Prlic - * - */ - -package org.biojava.nbio.structure.io.mmcif.model; - -public class AuditAuthor -{ - String name; - String pdbx_ordinal; - String address; - public String getName() - { - return name; - } - public void setName(String name) - { - this.name = name; - } - public String getPdbx_ordinal() - { - return pdbx_ordinal; - } - public void setPdbx_ordinal(String pdbx_ordinal) - { - this.pdbx_ordinal = pdbx_ordinal; - } - public String getAddress() { - return address; - } - public void setAddress(String address) { - this.address = address; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/CIFLabel.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/CIFLabel.java deleted file mode 100644 index 17775df70f..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/CIFLabel.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation indicating that a specific field of a bean should be mapped to - * a different label - * @author Spencer Bliven - * - */ -@Target(value=ElementType.FIELD) -@Retention(value=RetentionPolicy.RUNTIME) -public @interface CIFLabel { - String label(); -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Cell.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Cell.java deleted file mode 100644 index 59804fa821..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Cell.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -public class Cell extends AbstractBean { - - String entry_id; - String length_a; - String length_b; - String length_c; - String angle_alpha; - String angle_beta; - String angle_gamma; - String Z_PDB; - String pdbx_unique_axis; - - // some PDB entries like 1aac have the extra esd fields - String length_a_esd; - String length_b_esd; - String length_c_esd; - String angle_alpha_esd; - String angle_beta_esd; - String angle_gamma_esd; - - String volume; - - public String getEntry_id() { - return entry_id; - } - public void setEntry_id(String entry_id) { - this.entry_id = entry_id; - } - public String getLength_a() { - return length_a; - } - public void setLength_a(String length_a) { - this.length_a = length_a; - } - public String getLength_b() { - return length_b; - } - public void setLength_b(String length_b) { - this.length_b = length_b; - } - public String getLength_c() { - return length_c; - } - public void setLength_c(String length_c) { - this.length_c = length_c; - } - public String getAngle_alpha() { - return angle_alpha; - } - public void setAngle_alpha(String angle_alpha) { - this.angle_alpha = angle_alpha; - } - public String getAngle_beta() { - return angle_beta; - } - public void setAngle_beta(String angle_beta) { - this.angle_beta = angle_beta; - } - public String getAngle_gamma() { - return angle_gamma; - } - public void setAngle_gamma(String angle_gamma) { - this.angle_gamma = angle_gamma; - } - public String getZ_PDB() { - return Z_PDB; - } - public void setZ_PDB(String z_PDB) { - Z_PDB = z_PDB; - } - public String getPdbx_unique_axis() { - return pdbx_unique_axis; - } - public void setPdbx_unique_axis(String pdbx_unique_axis) { - this.pdbx_unique_axis = pdbx_unique_axis; - } - public String getLength_a_esd() { - return length_a_esd; - } - public void setLength_a_esd(String length_a_esd) { - this.length_a_esd = length_a_esd; - } - public String getLength_b_esd() { - return length_b_esd; - } - public void setLength_b_esd(String length_b_esd) { - this.length_b_esd = length_b_esd; - } - public String getLength_c_esd() { - return length_c_esd; - } - public void setLength_c_esd(String length_c_esd) { - this.length_c_esd = length_c_esd; - } - public String getAngle_alpha_esd() { - return angle_alpha_esd; - } - public void setAngle_alpha_esd(String angle_alpha_esd) { - this.angle_alpha_esd = angle_alpha_esd; - } - public String getAngle_beta_esd() { - return angle_beta_esd; - } - public void setAngle_beta_esd(String angle_beta_esd) { - this.angle_beta_esd = angle_beta_esd; - } - public String getAngle_gamma_esd() { - return angle_gamma_esd; - } - public void setAngle_gamma_esd(String angle_gamma_esd) { - this.angle_gamma_esd = angle_gamma_esd; - } - public String getVolume() { - return volume; - } - public void setVolume(String volume) { - this.volume = volume; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemComp.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemComp.java deleted file mode 100644 index cb38de1755..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemComp.java +++ /dev/null @@ -1,618 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import org.biojava.nbio.structure.io.mmcif.chem.ChemCompTools; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** A definition for a Chemical Component, as maintained by the wwPDB. For access to all definitions, - * please download the components.cif.gz file from the wwPDB website. - * - * @author Andreas Prlic - * - */ -public class ChemComp implements Serializable, Comparable{ - /** - * - */ - private static final long serialVersionUID = -4736341142030215915L; - - private String id ; - private String name; - private String type; - private String pdbx_type; - private String formula; - private String mon_nstd_parent_comp_id; - private String pdbx_synonyms; - private String pdbx_formal_charge; - private String pdbx_initial_date ; - private String pdbx_modified_date; - private String pdbx_ambiguous_flag; - private String pdbx_release_status ; - private String pdbx_replaced_by; - private String pdbx_replaces; - private String formula_weight; - private String one_letter_code; - private String three_letter_code; - private String pdbx_model_coordinates_details; - private String pdbx_model_coordinates_missing_flag; - private String pdbx_ideal_coordinates_details; - private String pdbx_ideal_coordinates_missing_flag; - private String pdbx_model_coordinates_db_code; - private String pdbx_subcomponent_list; - private String pdbx_processing_site; - private String mon_nstd_flag; - - @IgnoreField - private List descriptors = new ArrayList(); - @IgnoreField - private List bonds = new ArrayList(); - @IgnoreField - private List atoms = new ArrayList(); - - // and some derived data for easier processing... - @IgnoreField - private ResidueType residueType; - @IgnoreField - private PolymerType polymerType; - @IgnoreField - private boolean standard; - - @Override - public String toString(){ - StringBuffer buf = new StringBuffer("ChemComp "); - buf.append(id); - buf.append(" "); - buf.append(one_letter_code); - buf.append(" "); - buf.append(three_letter_code); - buf.append(" poly:"); - buf.append(getPolymerType()); - buf.append(" resi:"); - buf.append(getResidueType()); - if (isStandard()) - buf.append(" standard"); - else - buf.append(" modified"); - buf.append(" "); - - buf.append(name); - buf.append(" "); - buf.append(pdbx_type); - buf.append(" "); - buf.append(formula); - buf.append(" parent:"); - buf.append(mon_nstd_parent_comp_id); - return buf.toString(); - } - - public boolean hasParent(){ - String pid = mon_nstd_parent_comp_id; - if ((pid != null ) && (! pid.equals("?"))){ - return true; - } - return false; - } - - public boolean isStandard(){ - return standard; - } - - private void setStandardFlag(){ - standard = ChemCompTools.isStandardChemComp(this); - } - - - - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - - residueType = ResidueType.getResidueTypeFromString(type); - if ( residueType != null){ - polymerType = residueType.polymerType; - } - - } - - - public ResidueType getResidueType() { - return residueType; - } - - public void setResidueType(ResidueType residueType) { - this.residueType = residueType; - } - - public PolymerType getPolymerType() { - return polymerType; - } - - public void setPolymerType(PolymerType polymerType) { - this.polymerType = polymerType; - } - - public String getPdbx_type() { - return pdbx_type; - } - public void setPdbx_type(String pdbx_type) { - this.pdbx_type = pdbx_type; - } - public String getFormula() { - return formula; - } - public void setFormula(String formula) { - this.formula = formula; - } - public String getMon_nstd_parent_comp_id() { - return mon_nstd_parent_comp_id; - } - public void setMon_nstd_parent_comp_id(String mon_nstd_parent_comp_id) { - this.mon_nstd_parent_comp_id = mon_nstd_parent_comp_id; - setStandardFlag(); - } - public String getPdbx_synonyms() { - return pdbx_synonyms; - } - public void setPdbx_synonyms(String pdbx_synonyms) { - this.pdbx_synonyms = pdbx_synonyms; - } - public String getPdbx_formal_charge() { - return pdbx_formal_charge; - } - public void setPdbx_formal_charge(String pdbx_formal_charge) { - this.pdbx_formal_charge = pdbx_formal_charge; - } - public String getPdbx_initial_date() { - return pdbx_initial_date; - } - public void setPdbx_initial_date(String pdbx_initial_date) { - this.pdbx_initial_date = pdbx_initial_date; - } - public String getPdbx_modified_date() { - return pdbx_modified_date; - } - public void setPdbx_modified_date(String pdbx_modified_date) { - this.pdbx_modified_date = pdbx_modified_date; - } - public String getPdbx_ambiguous_flag() { - return pdbx_ambiguous_flag; - } - public void setPdbx_ambiguous_flag(String pdbx_ambiguous_flag) { - this.pdbx_ambiguous_flag = pdbx_ambiguous_flag; - } - public String getPdbx_release_status() { - return pdbx_release_status; - } - public void setPdbx_release_status(String pdbx_release_status) { - this.pdbx_release_status = pdbx_release_status; - } - public String getPdbx_replaced_by() { - return pdbx_replaced_by; - } - public void setPdbx_replaced_by(String pdbx_replaced_by) { - this.pdbx_replaced_by = pdbx_replaced_by; - } - public String getPdbx_replaces() { - return pdbx_replaces; - } - public void setPdbx_replaces(String pdbx_replaces) { - this.pdbx_replaces = pdbx_replaces; - } - public String getFormula_weight() { - return formula_weight; - } - public void setFormula_weight(String formula_weight) { - this.formula_weight = formula_weight; - } - public String getOne_letter_code() { - return one_letter_code; - } - public void setOne_letter_code(String one_letter_code) { - this.one_letter_code = one_letter_code; - setStandardFlag(); - } - public String getThree_letter_code() { - return three_letter_code; - } - public void setThree_letter_code(String three_letter_code) { - this.three_letter_code = three_letter_code; - } - public String getPdbx_model_coordinates_details() { - return pdbx_model_coordinates_details; - } - public void setPdbx_model_coordinates_details( - String pdbx_model_coordinates_details) { - this.pdbx_model_coordinates_details = pdbx_model_coordinates_details; - } - public String getPdbx_model_coordinates_missing_flag() { - return pdbx_model_coordinates_missing_flag; - } - public void setPdbx_model_coordinates_missing_flag( - String pdbx_model_coordinates_missing_flag) { - this.pdbx_model_coordinates_missing_flag = pdbx_model_coordinates_missing_flag; - } - public String getPdbx_ideal_coordinates_details() { - return pdbx_ideal_coordinates_details; - } - public void setPdbx_ideal_coordinates_details( - String pdbx_ideal_coordinates_details) { - this.pdbx_ideal_coordinates_details = pdbx_ideal_coordinates_details; - } - public String getPdbx_ideal_coordinates_missing_flag() { - return pdbx_ideal_coordinates_missing_flag; - } - public void setPdbx_ideal_coordinates_missing_flag( - String pdbx_ideal_coordinates_missing_flag) { - this.pdbx_ideal_coordinates_missing_flag = pdbx_ideal_coordinates_missing_flag; - } - public String getPdbx_model_coordinates_db_code() { - return pdbx_model_coordinates_db_code; - } - public void setPdbx_model_coordinates_db_code( - String pdbx_model_coordinates_db_code) { - this.pdbx_model_coordinates_db_code = pdbx_model_coordinates_db_code; - } - public String getPdbx_subcomponent_list() { - return pdbx_subcomponent_list; - } - public void setPdbx_subcomponent_list(String pdbx_subcomponent_list) { - this.pdbx_subcomponent_list = pdbx_subcomponent_list; - } - public String getPdbx_processing_site() { - return pdbx_processing_site; - } - public void setPdbx_processing_site(String pdbx_processing_site) { - this.pdbx_processing_site = pdbx_processing_site; - } - - public void setStandard(boolean standard) { - this.standard = standard; - } - - public String getMon_nstd_flag() - { - return mon_nstd_flag; - } - - public void setMon_nstd_flag(String mon_nstd_flag) - { - this.mon_nstd_flag = mon_nstd_flag; - } - - public List getDescriptors() { - return descriptors; - } - - public void setDescriptors(List descriptors) { - this.descriptors = descriptors; - } - - public List getBonds() { - return bonds; - } - - public void setBonds(List bonds) { - this.bonds = bonds; - } - - public List getAtoms() { - return atoms; - } - - public void setAtoms(List atoms) { - this.atoms = atoms; - } - - @Override - public int compareTo(ChemComp arg0) { - if ( this.equals(arg0)) - return 0; - return this.getId().compareTo(arg0.getId()); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((descriptors == null) ? 0 : descriptors.hashCode()); - result = prime * result + ((formula == null) ? 0 : formula.hashCode()); - result = prime * result - + ((formula_weight == null) ? 0 : formula_weight.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result - + ((mon_nstd_flag == null) ? 0 : mon_nstd_flag.hashCode()); - result = prime - * result - + ((mon_nstd_parent_comp_id == null) ? 0 - : mon_nstd_parent_comp_id.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result - + ((one_letter_code == null) ? 0 : one_letter_code.hashCode()); - result = prime - * result - + ((pdbx_ambiguous_flag == null) ? 0 : pdbx_ambiguous_flag - .hashCode()); - result = prime - * result - + ((pdbx_formal_charge == null) ? 0 : pdbx_formal_charge - .hashCode()); - result = prime - * result - + ((pdbx_ideal_coordinates_details == null) ? 0 - : pdbx_ideal_coordinates_details.hashCode()); - result = prime - * result - + ((pdbx_ideal_coordinates_missing_flag == null) ? 0 - : pdbx_ideal_coordinates_missing_flag.hashCode()); - result = prime - * result - + ((pdbx_initial_date == null) ? 0 : pdbx_initial_date - .hashCode()); - result = prime - * result - + ((pdbx_model_coordinates_db_code == null) ? 0 - : pdbx_model_coordinates_db_code.hashCode()); - result = prime - * result - + ((pdbx_model_coordinates_details == null) ? 0 - : pdbx_model_coordinates_details.hashCode()); - result = prime - * result - + ((pdbx_model_coordinates_missing_flag == null) ? 0 - : pdbx_model_coordinates_missing_flag.hashCode()); - result = prime - * result - + ((pdbx_modified_date == null) ? 0 : pdbx_modified_date - .hashCode()); - result = prime - * result - + ((pdbx_processing_site == null) ? 0 : pdbx_processing_site - .hashCode()); - result = prime - * result - + ((pdbx_release_status == null) ? 0 : pdbx_release_status - .hashCode()); - result = prime - * result - + ((pdbx_replaced_by == null) ? 0 : pdbx_replaced_by.hashCode()); - result = prime * result - + ((pdbx_replaces == null) ? 0 : pdbx_replaces.hashCode()); - result = prime - * result - + ((pdbx_subcomponent_list == null) ? 0 - : pdbx_subcomponent_list.hashCode()); - result = prime * result - + ((pdbx_synonyms == null) ? 0 : pdbx_synonyms.hashCode()); - result = prime * result - + ((pdbx_type == null) ? 0 : pdbx_type.hashCode()); - result = prime * result - + ((polymerType == null) ? 0 : polymerType.hashCode()); - result = prime * result - + ((residueType == null) ? 0 : residueType.hashCode()); - result = prime * result + (standard ? 1231 : 1237); - result = prime - * result - + ((three_letter_code == null) ? 0 : three_letter_code - .hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ChemComp other = (ChemComp) obj; - if (descriptors == null) { - if (other.descriptors != null) - return false; - } else if (!descriptors.equals(other.descriptors)) - return false; - if (formula == null) { - if (other.formula != null) - return false; - } else if (!formula.equals(other.formula)) - return false; - if (formula_weight == null) { - if (other.formula_weight != null) - return false; - } else if (!formula_weight.equals(other.formula_weight)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (mon_nstd_flag == null) { - if (other.mon_nstd_flag != null) - return false; - } else if (!mon_nstd_flag.equals(other.mon_nstd_flag)) - return false; - if (mon_nstd_parent_comp_id == null) { - if (other.mon_nstd_parent_comp_id != null) - return false; - } else if (!mon_nstd_parent_comp_id - .equals(other.mon_nstd_parent_comp_id)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (one_letter_code == null) { - if (other.one_letter_code != null) - return false; - } else if (!one_letter_code.equals(other.one_letter_code)) - return false; - if (pdbx_ambiguous_flag == null) { - if (other.pdbx_ambiguous_flag != null) - return false; - } else if (!pdbx_ambiguous_flag.equals(other.pdbx_ambiguous_flag)) - return false; - if (pdbx_formal_charge == null) { - if (other.pdbx_formal_charge != null) - return false; - } else if (!pdbx_formal_charge.equals(other.pdbx_formal_charge)) - return false; - if (pdbx_ideal_coordinates_details == null) { - if (other.pdbx_ideal_coordinates_details != null) - return false; - } else if (!pdbx_ideal_coordinates_details - .equals(other.pdbx_ideal_coordinates_details)) - return false; - if (pdbx_ideal_coordinates_missing_flag == null) { - if (other.pdbx_ideal_coordinates_missing_flag != null) - return false; - } else if (!pdbx_ideal_coordinates_missing_flag - .equals(other.pdbx_ideal_coordinates_missing_flag)) - return false; - if (pdbx_initial_date == null) { - if (other.pdbx_initial_date != null) - return false; - } else if (!pdbx_initial_date.equals(other.pdbx_initial_date)) - return false; - if (pdbx_model_coordinates_db_code == null) { - if (other.pdbx_model_coordinates_db_code != null) - return false; - } else if (!pdbx_model_coordinates_db_code - .equals(other.pdbx_model_coordinates_db_code)) - return false; - if (pdbx_model_coordinates_details == null) { - if (other.pdbx_model_coordinates_details != null) - return false; - } else if (!pdbx_model_coordinates_details - .equals(other.pdbx_model_coordinates_details)) - return false; - if (pdbx_model_coordinates_missing_flag == null) { - if (other.pdbx_model_coordinates_missing_flag != null) - return false; - } else if (!pdbx_model_coordinates_missing_flag - .equals(other.pdbx_model_coordinates_missing_flag)) - return false; - if (pdbx_modified_date == null) { - if (other.pdbx_modified_date != null) - return false; - } else if (!pdbx_modified_date.equals(other.pdbx_modified_date)) - return false; - if (pdbx_processing_site == null) { - if (other.pdbx_processing_site != null) - return false; - } else if (!pdbx_processing_site.equals(other.pdbx_processing_site)) - return false; - if (pdbx_release_status == null) { - if (other.pdbx_release_status != null) - return false; - } else if (!pdbx_release_status.equals(other.pdbx_release_status)) - return false; - if (pdbx_replaced_by == null) { - if (other.pdbx_replaced_by != null) - return false; - } else if (!pdbx_replaced_by.equals(other.pdbx_replaced_by)) - return false; - if (pdbx_replaces == null) { - if (other.pdbx_replaces != null) - return false; - } else if (!pdbx_replaces.equals(other.pdbx_replaces)) - return false; - if (pdbx_subcomponent_list == null) { - if (other.pdbx_subcomponent_list != null) - return false; - } else if (!pdbx_subcomponent_list.equals(other.pdbx_subcomponent_list)) - return false; - if (pdbx_synonyms == null) { - if (other.pdbx_synonyms != null) - return false; - } else if (!pdbx_synonyms.equals(other.pdbx_synonyms)) - return false; - if (pdbx_type == null) { - if (other.pdbx_type != null) - return false; - } else if (!pdbx_type.equals(other.pdbx_type)) - return false; - if (polymerType != other.polymerType) - return false; - if (residueType != other.residueType) - return false; - if (standard != other.standard) - return false; - if (three_letter_code == null) { - if (other.three_letter_code != null) - return false; - } else if (!three_letter_code.equals(other.three_letter_code)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - return true; - } - - /** - * Creates a new instance of the dummy empty ChemComp. - * @return - */ - public static ChemComp getEmptyChemComp(){ - ChemComp comp = new ChemComp(); - - comp.setOne_letter_code("?"); - comp.setThree_letter_code("???"); // Main signal for isEmpty() - comp.setPolymerType(PolymerType.unknown); - comp.setResidueType(ResidueType.atomn); - return comp; - } - - /** - * Indicates whether this compound was created with - * @return - */ - public boolean isEmpty() { - // Is this the best flag for it being empty? - return id == null || getThree_letter_code() == null || getThree_letter_code().equals("???"); - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompAtom.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompAtom.java deleted file mode 100644 index 81d0f64b4b..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompAtom.java +++ /dev/null @@ -1,219 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Feb 5, 2013 - * Created by Andreas Prlic - * - * @since 3.0.6 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import java.io.Serializable; - -/** stores these fields: - * - * _chem_comp_atom.comp_id -_chem_comp_atom.atom_id -_chem_comp_atom.alt_atom_id -_chem_comp_atom.type_symbol -_chem_comp_atom.charge -_chem_comp_atom.pdbx_align -_chem_comp_atom.pdbx_aromatic_flag -_chem_comp_atom.pdbx_leaving_atom_flag -_chem_comp_atom.pdbx_stereo_config -_chem_comp_atom.model_Cartn_x -_chem_comp_atom.model_Cartn_y -_chem_comp_atom.model_Cartn_z -_chem_comp_atom.pdbx_model_Cartn_x_ideal -_chem_comp_atom.pdbx_model_Cartn_y_ideal -_chem_comp_atom.pdbx_model_Cartn_z_ideal -_chem_comp_atom.pdbx_component_comp_id -_chem_comp_atom.pdbx_residue_numbering -_chem_comp_atom.pdbx_component_atom_id -_chem_comp_atom.pdbx_polymer_type -_chem_comp_atom.pdbx_ref_id -_chem_comp_atom.pdbx_component_id -_chem_comp_atom.pdbx_ordinal - * - * @author Andreas Prlic - * - */ -public class ChemCompAtom implements Serializable{ - /** - * - */ - private static final long serialVersionUID = 4070599340294758941L; - String comp_id; - String atom_id; - String alt_atom_id; - String type_symbol; - String charge; - String pdbx_align; - String pdbx_aromatic_flag; - String pdbx_leaving_atom_flag; - String pdbx_stereo_config; - String model_Cartn_x; - String model_Cartn_y; - String model_Cartn_z; - String pdbx_model_Cartn_x_ideal; - String pdbx_model_Cartn_y_ideal; - String pdbx_model_Cartn_z_ideal; - String pdbx_component_comp_id; - String pdbx_residue_numbering; - String pdbx_component_atom_id; - String pdbx_polymer_type; - String pdbx_ref_id; - String pdbx_component_id; - String pdbx_ordinal; - public String getComp_id() { - return comp_id; - } - public void setComp_id(String comp_id) { - this.comp_id = comp_id; - } - public String getAtom_id() { - return atom_id; - } - public void setAtom_id(String atom_id) { - this.atom_id = atom_id; - } - public String getAlt_atom_id() { - return alt_atom_id; - } - public void setAlt_atom_id(String alt_atom_id) { - this.alt_atom_id = alt_atom_id; - } - public String getType_symbol() { - return type_symbol; - } - public void setType_symbol(String type_symbol) { - this.type_symbol = type_symbol; - } - public String getCharge() { - return charge; - } - public void setCharge(String charge) { - this.charge = charge; - } - public String getPdbx_align() { - return pdbx_align; - } - public void setPdbx_align(String pdbx_align) { - this.pdbx_align = pdbx_align; - } - public String getPdbx_aromatic_flag() { - return pdbx_aromatic_flag; - } - public void setPdbx_aromatic_flag(String pdbx_aromatic_flag) { - this.pdbx_aromatic_flag = pdbx_aromatic_flag; - } - public String getPdbx_leaving_atom_flag() { - return pdbx_leaving_atom_flag; - } - public void setPdbx_leaving_atom_flag(String pdbx_leaving_atom_flag) { - this.pdbx_leaving_atom_flag = pdbx_leaving_atom_flag; - } - public String getPdbx_stereo_config() { - return pdbx_stereo_config; - } - public void setPdbx_stereo_config(String pdbx_stereo_config) { - this.pdbx_stereo_config = pdbx_stereo_config; - } - public String getModel_Cartn_x() { - return model_Cartn_x; - } - public void setModel_Cartn_x(String model_Cartn_x) { - this.model_Cartn_x = model_Cartn_x; - } - public String getModel_Cartn_y() { - return model_Cartn_y; - } - public void setModel_Cartn_y(String model_Cartn_y) { - this.model_Cartn_y = model_Cartn_y; - } - public String getModel_Cartn_z() { - return model_Cartn_z; - } - public void setModel_Cartn_z(String model_Cartn_z) { - this.model_Cartn_z = model_Cartn_z; - } - public String getPdbx_model_Cartn_x_ideal() { - return pdbx_model_Cartn_x_ideal; - } - public void setPdbx_model_Cartn_x_ideal(String pdbx_model_Cartn_x_ideal) { - this.pdbx_model_Cartn_x_ideal = pdbx_model_Cartn_x_ideal; - } - public String getPdbx_model_Cartn_y_ideal() { - return pdbx_model_Cartn_y_ideal; - } - public void setPdbx_model_Cartn_y_ideal(String pdbx_model_Cartn_y_ideal) { - this.pdbx_model_Cartn_y_ideal = pdbx_model_Cartn_y_ideal; - } - public String getPdbx_model_Cartn_z_ideal() { - return pdbx_model_Cartn_z_ideal; - } - public void setPdbx_model_Cartn_z_ideal(String pdbx_model_Cartn_z_ideal) { - this.pdbx_model_Cartn_z_ideal = pdbx_model_Cartn_z_ideal; - } - public String getPdbx_component_comp_id() { - return pdbx_component_comp_id; - } - public void setPdbx_component_comp_id(String pdbx_component_comp_id) { - this.pdbx_component_comp_id = pdbx_component_comp_id; - } - public String getPdbx_residue_numbering() { - return pdbx_residue_numbering; - } - public void setPdbx_residue_numbering(String pdbx_residue_numbering) { - this.pdbx_residue_numbering = pdbx_residue_numbering; - } - public String getPdbx_component_atom_id() { - return pdbx_component_atom_id; - } - public void setPdbx_component_atom_id(String pdbx_component_atom_id) { - this.pdbx_component_atom_id = pdbx_component_atom_id; - } - public String getPdbx_polymer_type() { - return pdbx_polymer_type; - } - public void setPdbx_polymer_type(String pdbx_polymer_type) { - this.pdbx_polymer_type = pdbx_polymer_type; - } - public String getPdbx_ref_id() { - return pdbx_ref_id; - } - public void setPdbx_ref_id(String pdbx_ref_id) { - this.pdbx_ref_id = pdbx_ref_id; - } - public String getPdbx_component_id() { - return pdbx_component_id; - } - public void setPdbx_component_id(String pdbx_component_id) { - this.pdbx_component_id = pdbx_component_id; - } - public String getPdbx_ordinal() { - return pdbx_ordinal; - } - public void setPdbx_ordinal(String pdbx_ordinal) { - this.pdbx_ordinal = pdbx_ordinal; - } - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompBond.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompBond.java deleted file mode 100644 index cd49d3b116..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompBond.java +++ /dev/null @@ -1,133 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Feb 5, 2013 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import java.io.Serializable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* - * _chem_comp_bond.comp_id -_chem_comp_bond.atom_id_1 -_chem_comp_bond.atom_id_2 -_chem_comp_bond.value_order -_chem_comp_bond.pdbx_aromatic_flag -_chem_comp_bond.pdbx_stereo_config -_chem_comp_bond.pdbx_ordinal - */ -public class ChemCompBond implements Serializable { - - private static final long serialVersionUID = 5905371029161975421L; - - private static final Logger logger = LoggerFactory.getLogger(ChemCompBond.class); - - String comp_id; - String atom_id_1; - String atom_id_2; - String value_order; - String pdbx_aromatic_flag; - String pdbx_stereo_config; - String pdbx_ordinal; - public String getComp_id() { - return comp_id; - } - public void setComp_id(String comp_id) { - this.comp_id = comp_id; - } - public String getAtom_id_1() { - return atom_id_1; - } - public void setAtom_id_1(String atom_id_1) { - this.atom_id_1 = atom_id_1; - } - public String getAtom_id_2() { - return atom_id_2; - } - public void setAtom_id_2(String atom_id_2) { - this.atom_id_2 = atom_id_2; - } - public String getValue_order() { - return value_order; - } - public void setValue_order(String value_order) { - this.value_order = value_order; - } - public String getPdbx_aromatic_flag() { - return pdbx_aromatic_flag; - } - public void setPdbx_aromatic_flag(String pdbx_aromatic_flag) { - this.pdbx_aromatic_flag = pdbx_aromatic_flag; - } - public String getPdbx_stereo_config() { - return pdbx_stereo_config; - } - public void setPdbx_stereo_config(String pdbx_stereo_config) { - this.pdbx_stereo_config = pdbx_stereo_config; - } - public String getPdbx_ordinal() { - return pdbx_ordinal; - } - public void setPdbx_ordinal(String pdbx_ordinal) { - this.pdbx_ordinal = pdbx_ordinal; - } - - /** - * Converts this ChemCompBond's value_order attribute into an int using the - * conversion: - * - *
      -	 * 	SING -> 1
      -	 * 	DOUB -> 2
      -	 * 	TRIP -> 3
      -	 * 	QUAD -> 4
      -	 * 
      - * - * Any other values will return -1. - *

      - * (Source: - * http://mmcif.rcsb.org/dictionaries/mmcif_mdb.dic/Items/_chem_comp_bond. - * value_order.html) - * - * @return the numerical value of this ChemCompBond's bond order, or -1 if - * the value is non-numeric or unknown. - */ - public int getNumericalBondOrder() { - if (value_order.equals("SING")) { - return 1; - } else if (value_order.equals("DOUB")) { - return 2; - } else if (value_order.equals("TRIP")) { - return 3; - } else if (value_order.equals("QUAD")) { - return 4; - } else { - logger.error("Unknown or non-numeric value for value_order: " - + value_order); - return -1; - } - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompDescriptor.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompDescriptor.java deleted file mode 100644 index 7441e59a5a..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/ChemCompDescriptor.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Feb 22, 2011 - */ - -package org.biojava.nbio.structure.io.mmcif.model; - -import java.io.Serializable; - - -/** Container object for _pdbx_chem_comp_descriptor - * - * @author Andreas Prlic - * @since 3.2 - * - */ -public class ChemCompDescriptor implements Serializable { - /** - * - */ - private static final long serialVersionUID = 1078685833800736278L; - String comp_id; - String type; - String program; - String program_version; - String descriptor; - - public ChemCompDescriptor(){ - - } - public String getComp_id() { - return comp_id; - } - public void setComp_id(String comp_id) { - this.comp_id = comp_id; - } - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - public String getProgram() { - return program; - } - public void setProgram(String program) { - this.program = program; - } - public String getProgram_version() { - return program_version; - } - public void setProgram_version(String program_version) { - this.program_version = program_version; - } - public String getDescriptor() { - return descriptor; - } - public void setDescriptor(String descriptor) { - this.descriptor = descriptor; - } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((comp_id == null) ? 0 : comp_id.hashCode()); - result = prime * result - + ((descriptor == null) ? 0 : descriptor.hashCode()); - result = prime * result + ((program == null) ? 0 : program.hashCode()); - result = prime * result - + ((program_version == null) ? 0 : program_version.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ChemCompDescriptor other = (ChemCompDescriptor) obj; - if (comp_id == null) { - if (other.comp_id != null) - return false; - } else if (!comp_id.equals(other.comp_id)) - return false; - if (descriptor == null) { - if (other.descriptor != null) - return false; - } else if (!descriptor.equals(other.descriptor)) - return false; - if (program == null) { - if (other.program != null) - return false; - } else if (!program.equals(other.program)) - return false; - if (program_version == null) { - if (other.program_version != null) - return false; - } else if (!program_version.equals(other.program_version)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - return true; - } - @Override - public String toString() { - return "ChemCompDescriptor [comp_id=" + comp_id + ", type=" + type - + ", program=" + program + ", program_version=" - + program_version + ", descriptor=" + descriptor + "]"; - } - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePDBremark.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePDBremark.java deleted file mode 100644 index cc30c0a226..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePDBremark.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at May 31, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -public class DatabasePDBremark extends AbstractBean { - String id; - String text; - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getText() { - return text; - } - public void setText(String text) { - this.text = text; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePDBrev.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePDBrev.java deleted file mode 100644 index ef884327e3..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePDBrev.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Apr 27, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -public class DatabasePDBrev { - String date; - String date_original; - String status; - String replaces; - String mod_type; - String num; - - @Override - public String toString(){ - StringBuffer buf = new StringBuffer(); - buf.append("DatabasePDBrev "); - buf.append("mod_type :"); - buf.append(mod_type); - buf.append(" "); - buf.append(this.getDate()); - buf.append( " "); - buf.append( this.getDate_original()); - - return buf.toString(); - } - public String getNum() { - return num; - } - public void setNum(String num) { - this.num = num; - } - public String getDate() { - return date; - } - public void setDate(String date) { - this.date = date; - } - public String getDate_original() { - return date_original; - } - public void setDate_original(String date_original) { - this.date_original = date_original; - } - public String getStatus() { - return status; - } - public void setStatus(String status) { - this.status = status; - } - public String getReplaces() { - return replaces; - } - public void setReplaces(String replaces) { - this.replaces = replaces; - } - public String getMod_type() { - return mod_type; - } - public void setMod_type(String mod_type) { - this.mod_type = mod_type; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePdbrevRecord.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePdbrevRecord.java deleted file mode 100644 index 72beda99c8..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/DatabasePdbrevRecord.java +++ /dev/null @@ -1,69 +0,0 @@ - -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created by andreas on 10/12/15. - */ - -package org.biojava.nbio.structure.io.mmcif.model; - -import java.io.Serializable; - -public class DatabasePdbrevRecord implements Serializable { - - - private static final long serialVersionUID = 1L; - - String rev_num; - String type; - String details; - - public String getRev_num() { - return rev_num; - } - - public void setRev_num(String rev_num) { - this.rev_num = rev_num; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getDetails() { - return details; - } - - public void setDetails(String details) { - this.details = details; - } - - @Override - public String toString() { - return "DatabasePdbrevRecord{" + - "rev_num='" + rev_num + '\'' + - ", type='" + type + '\'' + - ", details='" + details + '\'' + - '}'; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Entity.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Entity.java deleted file mode 100644 index cae779dee2..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Entity.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Mar 4, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** A simple class to represent Entity records in mmCif files - * - * @author Andreas Prlic - * - */ -public class Entity { - String id; - - String type; - String src_method; - String pdbx_description; - String formula_weight; - String pdbx_number_of_molecules; - String details; - String pdbx_mutation; - String pdbx_fragment; - String pdbx_ec; - - @Override - public String toString(){ - StringBuffer buf = new StringBuffer(); - - buf.append("Entity - id:").append(id); - - buf.append(" type:").append(type); - buf.append(" src_method:").append(src_method); - buf.append(" pdbx_description:").append(pdbx_description); - buf.append(" formula_weight:").append(formula_weight); - buf.append(" pdbx_number_f_molecules:").append(pdbx_number_of_molecules); - buf.append(" details:").append(details); - buf.append(" pdbx_mutation:").append(pdbx_mutation); - buf.append(" pdbx_fragment:").append(pdbx_fragment); - buf.append(" pdbx_ec:").append(pdbx_ec); - - return buf.toString(); - } - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - public String getSrc_method() { - return src_method; - } - public void setSrc_method(String src_method) { - this.src_method = src_method; - } - public String getPdbx_description() { - return pdbx_description; - } - public void setPdbx_description(String pdbx_description) { - this.pdbx_description = pdbx_description; - } - public String getFormula_weight() { - return formula_weight; - } - public void setFormula_weight(String formula_weight) { - this.formula_weight = formula_weight; - } - public String getPdbx_number_of_molecules() { - return pdbx_number_of_molecules; - } - public void setPdbx_number_of_molecules(String pdbx_number_of_molecules) { - this.pdbx_number_of_molecules = pdbx_number_of_molecules; - } - public String getDetails() { - return details; - } - public void setDetails(String details) { - this.details = details; - } - public String getPdbx_mutation() { - return pdbx_mutation; - } - public void setPdbx_mutation(String pdbx_mutation) { - this.pdbx_mutation = pdbx_mutation; - } - public String getPdbx_fragment() { - return pdbx_fragment; - } - public void setPdbx_fragment(String pdbx_fragment) { - this.pdbx_fragment = pdbx_fragment; - } - public String getPdbx_ec() { - return pdbx_ec; - } - public void setPdbx_ec(String pdbx_ec) { - this.pdbx_ec = pdbx_ec; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntityPoly.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntityPoly.java deleted file mode 100644 index 9c27e34a14..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntityPoly.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Jun 1, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - - -/** - * Container for _entity_poly records - * - * - * @since 5.0 - * @author Jose Duarte - */ -public class EntityPoly extends AbstractBean{ - String entity_id; - String type; - String nstd_chirality; - String nstd_linkage; - String nstd_monomer; - String type_details; - String pdbx_seq_one_letter_code; - String pdbx_seq_one_letter_code_can; - String pdbx_strand_id; - String pdbx_target_identifier; - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - /** - * @return the type - */ - public String getType() { - return type; - } - /** - * @param type the type to set - */ - public void setType(String type) { - this.type = type; - } - /** - * @return the nstd_chirality - */ - public String getNstd_chirality() { - return nstd_chirality; - } - /** - * @param nstd_chirality the nstd_chirality to set - */ - public void setNstd_chirality(String nstd_chirality) { - this.nstd_chirality = nstd_chirality; - } - /** - * @return the nstd_linkage - */ - public String getNstd_linkage() { - return nstd_linkage; - } - /** - * @param nstd_linkage the nstd_linkage to set - */ - public void setNstd_linkage(String nstd_linkage) { - this.nstd_linkage = nstd_linkage; - } - /** - * @return the nstd_monomer - */ - public String getNstd_monomer() { - return nstd_monomer; - } - /** - * @param nstd_monomer the nstd_monomer to set - */ - public void setNstd_monomer(String nstd_monomer) { - this.nstd_monomer = nstd_monomer; - } - /** - * @return the type_details - */ - public String getType_details() { - return type_details; - } - /** - * @param type_details the type_details to set - */ - public void setType_details(String type_details) { - this.type_details = type_details; - } - /** - * @return the pdbx_seq_one_letter_code - */ - public String getPdbx_seq_one_letter_code() { - return pdbx_seq_one_letter_code; - } - /** - * @param pdbx_seq_one_letter_code the pdbx_seq_one_letter_code to set - */ - public void setPdbx_seq_one_letter_code(String pdbx_seq_one_letter_code) { - this.pdbx_seq_one_letter_code = pdbx_seq_one_letter_code; - } - /** - * @return the pdbx_seq_one_letter_code_can - */ - public String getPdbx_seq_one_letter_code_can() { - return pdbx_seq_one_letter_code_can; - } - /** - * @param pdbx_seq_one_letter_code_can the pdbx_seq_one_letter_code_can to set - */ - public void setPdbx_seq_one_letter_code_can(String pdbx_seq_one_letter_code_can) { - this.pdbx_seq_one_letter_code_can = pdbx_seq_one_letter_code_can; - } - /** - * @return the pdbx_strand_id - */ - public String getPdbx_strand_id() { - return pdbx_strand_id; - } - /** - * @param pdbx_strand_id the pdbx_strand_id to set - */ - public void setPdbx_strand_id(String pdbx_strand_id) { - this.pdbx_strand_id = pdbx_strand_id; - } - public String getPdbx_target_identifier() { - return pdbx_target_identifier; - } - public void setPdbx_target_identifier(String pdbx_target_identifier) { - this.pdbx_target_identifier = pdbx_target_identifier; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntityPolySeq.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntityPolySeq.java deleted file mode 100644 index 968ab47acd..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntityPolySeq.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Jun 1, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - - -/** Container for _entity_poly_seq records - * -

      -Field Name     mmCIF Data Item
      -Section        n.a.
      -Serial_No      n.a.
      -Strand_ID      PDB strand ID corresponding to _entity_poly_seq.entity_id (*)
      -Strand_Length  derived
      -Residue_Names  _entity_poly_seq.mon_id
      -
      - * (*) Chemically distinct polymer strands are mapped to mmCIF entities. Two - * instances or the same polymer molecule in the PDB data file are mapped to a - * single mmCIF entity (eg. a homodimer). For convenience a table of monomer - * label correspondences is stored in category PDBX_POLY_SEQ_SCHEME - * @author Andreas Prlic - * @since 1.7 - */ -public class EntityPolySeq extends AbstractBean{ - String entity_id; - String num; - String mon_id; - String hetero; - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - public String getNum() { - return num; - } - public void setNum(String num) { - this.num = num; - } - public String getMon_id() { - return mon_id; - } - public void setMon_id(String mon_id) { - this.mon_id = mon_id; - } - public String getHetero() { - return hetero; - } - public void setHetero(String hetero) { - this.hetero = hetero; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcGen.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcGen.java deleted file mode 100644 index 19082a8932..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcGen.java +++ /dev/null @@ -1,427 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - - -/** - * Data items in the ENTITY_SRC_GEN category record details of - * the source from which the entity was obtained in cases - * where the source was genetically manipulated. The - * following are treated separately: items pertaining to the tissue - * from which the gene was obtained, items pertaining to the host - * organism for gene expression and items pertaining to the actual - * producing organism (plasmid). - * - * @author Andreas Prlic - * - */ -public class EntitySrcGen { - String entity_id; - String expression_system_id; - String gene_src_common_name; - String gene_src_details ; - String gene_src_dev_stage ; - String gene_src_genus ; - String gene_src_species ; - String gene_src_strain ; - String gene_src_tissue ; - String gene_src_tissue_fraction; - String host_org_common_name ; - String host_org_details ; - String host_org_genus ; - String host_org_species; - String host_org_strain ; - String pdbx_src_id; - String pdbx_seq_type; - String pdbx_alt_source_flag; - String pdbx_beg_seq_num; - String pdbx_end_seq_num; - String pdbx_description; - String pdbx_gene_src_atcc; - String pdbx_gene_src_cell ; - String pdbx_gene_src_cell_line; - String pdbx_gene_src_cellular_location; - String pdbx_gene_src_fragment ; - String pdbx_gene_src_gene ; - String pdbx_gene_src_ncbi_taxonomy_id; - String pdbx_gene_src_organ ; - String pdbx_gene_src_organelle ; - String pdbx_gene_src_plasmid ; - String pdbx_gene_src_plasmid_name ; - String pdbx_gene_src_scientific_name; - String pdbx_gene_src_variant ; - String pdbx_host_org_atcc ; - String pdbx_host_org_cell ; - String pdbx_host_org_cell_line ; - String pdbx_host_org_cellular_location ; - String pdbx_host_org_culture_collection ; - String pdbx_host_org_gene ; - String pdbx_host_org_ncbi_taxonomy_id ; - String pdbx_host_org_organ ; - String pdbx_host_org_organelle ; - String pdbx_host_org_scientific_name ; - String pdbx_host_org_strain ; - String pdbx_host_org_tissue ; - String pdbx_host_org_tissue_fraction ; - String pdbx_host_org_variant ; - String pdbx_host_org_vector ; - String pdbx_host_org_vector_type; - String plasmid_details ; - String plasmid_name ; - String start_construct_id ; - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - public String getExpression_system_id() { - return expression_system_id; - } - public void setExpression_system_id(String expression_system_id) { - this.expression_system_id = expression_system_id; - } - public String getGene_src_common_name() { - return gene_src_common_name; - } - public void setGene_src_common_name(String gene_src_common_name) { - this.gene_src_common_name = gene_src_common_name; - } - public String getGene_src_details() { - return gene_src_details; - } - public void setGene_src_details(String gene_src_details) { - this.gene_src_details = gene_src_details; - } - public String getGene_src_dev_stage() { - return gene_src_dev_stage; - } - public void setGene_src_dev_stage(String gene_src_dev_stage) { - this.gene_src_dev_stage = gene_src_dev_stage; - } - public String getGene_src_genus() { - return gene_src_genus; - } - public void setGene_src_genus(String gene_src_genus) { - this.gene_src_genus = gene_src_genus; - } - public String getGene_src_species() { - return gene_src_species; - } - public void setGene_src_species(String gene_src_species) { - this.gene_src_species = gene_src_species; - } - public String getGene_src_strain() { - return gene_src_strain; - } - public void setGene_src_strain(String gene_src_strain) { - this.gene_src_strain = gene_src_strain; - } - public String getGene_src_tissue() { - return gene_src_tissue; - } - public void setGene_src_tissue(String gene_src_tissue) { - this.gene_src_tissue = gene_src_tissue; - } - public String getGene_src_tissue_fraction() { - return gene_src_tissue_fraction; - } - public void setGene_src_tissue_fraction(String gene_src_tissue_fraction) { - this.gene_src_tissue_fraction = gene_src_tissue_fraction; - } - public String getHost_org_common_name() { - return host_org_common_name; - } - public void setHost_org_common_name(String host_org_common_name) { - this.host_org_common_name = host_org_common_name; - } - public String getHost_org_details() { - return host_org_details; - } - public void setHost_org_details(String host_org_details) { - this.host_org_details = host_org_details; - } - public String getHost_org_genus() { - return host_org_genus; - } - public void setHost_org_genus(String host_org_genus) { - this.host_org_genus = host_org_genus; - } - public String getHost_org_species() { - return host_org_species; - } - public void setHost_org_species(String host_org_species) { - this.host_org_species = host_org_species; - } - public String getHost_org_strain() { - return host_org_strain; - } - public void setHost_org_strain(String host_org_strain) { - this.host_org_strain = host_org_strain; - } - public String getPdbx_src_id() { - return pdbx_src_id; - } - public void setPdbx_src_id(String pdbx_src_id) { - this.pdbx_src_id = pdbx_src_id; - } - public String getPdbx_seq_type() { - return pdbx_seq_type; - } - public void setPdbx_seq_type(String pdbx_seq_type) { - this.pdbx_seq_type = pdbx_seq_type; - } - /** - * @return the pdbx_alt_source_flag - */ - public String getPdbx_alt_source_flag() { - return pdbx_alt_source_flag; - } - /** - * @param pdbx_alt_source_flag the pdbx_alt_source_flag to set - */ - public void setPdbx_alt_source_flag(String pdbx_alt_source_flag) { - this.pdbx_alt_source_flag = pdbx_alt_source_flag; - } - public String getPdbx_beg_seq_num() { - return pdbx_beg_seq_num; - } - public void setPdbx_beg_seq_num(String pdbx_beg_seq_num) { - this.pdbx_beg_seq_num = pdbx_beg_seq_num; - } - public String getPdbx_end_seq_num() { - return pdbx_end_seq_num; - } - public void setPdbx_end_seq_num(String pdbx_end_seq_num) { - this.pdbx_end_seq_num = pdbx_end_seq_num; - } - public String getPdbx_description() { - return pdbx_description; - } - public void setPdbx_description(String pdbx_description) { - this.pdbx_description = pdbx_description; - } - public String getPdbx_gene_src_atcc() { - return pdbx_gene_src_atcc; - } - public void setPdbx_gene_src_atcc(String pdbx_gene_src_atcc) { - this.pdbx_gene_src_atcc = pdbx_gene_src_atcc; - } - public String getPdbx_gene_src_cell() { - return pdbx_gene_src_cell; - } - public void setPdbx_gene_src_cell(String pdbx_gene_src_cell) { - this.pdbx_gene_src_cell = pdbx_gene_src_cell; - } - public String getPdbx_gene_src_cell_line() { - return pdbx_gene_src_cell_line; - } - public void setPdbx_gene_src_cell_line(String pdbx_gene_src_cell_line) { - this.pdbx_gene_src_cell_line = pdbx_gene_src_cell_line; - } - public String getPdbx_gene_src_cellular_location() { - return pdbx_gene_src_cellular_location; - } - public void setPdbx_gene_src_cellular_location( - String pdbx_gene_src_cellular_location) { - this.pdbx_gene_src_cellular_location = pdbx_gene_src_cellular_location; - } - public String getPdbx_gene_src_fragment() { - return pdbx_gene_src_fragment; - } - public void setPdbx_gene_src_fragment(String pdbx_gene_src_fragment) { - this.pdbx_gene_src_fragment = pdbx_gene_src_fragment; - } - public String getPdbx_gene_src_gene() { - return pdbx_gene_src_gene; - } - public void setPdbx_gene_src_gene(String pdbx_gene_src_gene) { - this.pdbx_gene_src_gene = pdbx_gene_src_gene; - } - public String getPdbx_gene_src_ncbi_taxonomy_id() { - return pdbx_gene_src_ncbi_taxonomy_id; - } - public void setPdbx_gene_src_ncbi_taxonomy_id( - String pdbx_gene_src_ncbi_taxonomy_id) { - this.pdbx_gene_src_ncbi_taxonomy_id = pdbx_gene_src_ncbi_taxonomy_id; - } - public String getPdbx_gene_src_organ() { - return pdbx_gene_src_organ; - } - public void setPdbx_gene_src_organ(String pdbx_gene_src_organ) { - this.pdbx_gene_src_organ = pdbx_gene_src_organ; - } - public String getPdbx_gene_src_organelle() { - return pdbx_gene_src_organelle; - } - public void setPdbx_gene_src_organelle(String pdbx_gene_src_organelle) { - this.pdbx_gene_src_organelle = pdbx_gene_src_organelle; - } - public String getPdbx_gene_src_plasmid() { - return pdbx_gene_src_plasmid; - } - public void setPdbx_gene_src_plasmid(String pdbx_gene_src_plasmid) { - this.pdbx_gene_src_plasmid = pdbx_gene_src_plasmid; - } - public String getPdbx_gene_src_plasmid_name() { - return pdbx_gene_src_plasmid_name; - } - public void setPdbx_gene_src_plasmid_name(String pdbx_gene_src_plasmid_name) { - this.pdbx_gene_src_plasmid_name = pdbx_gene_src_plasmid_name; - } - public String getPdbx_gene_src_scientific_name() { - return pdbx_gene_src_scientific_name; - } - public void setPdbx_gene_src_scientific_name( - String pdbx_gene_src_scientific_name) { - this.pdbx_gene_src_scientific_name = pdbx_gene_src_scientific_name; - } - public String getPdbx_gene_src_variant() { - return pdbx_gene_src_variant; - } - public void setPdbx_gene_src_variant(String pdbx_gene_src_variant) { - this.pdbx_gene_src_variant = pdbx_gene_src_variant; - } - public String getPdbx_host_org_atcc() { - return pdbx_host_org_atcc; - } - public void setPdbx_host_org_atcc(String pdbx_host_org_atcc) { - this.pdbx_host_org_atcc = pdbx_host_org_atcc; - } - public String getPdbx_host_org_cell() { - return pdbx_host_org_cell; - } - public void setPdbx_host_org_cell(String pdbx_host_org_cell) { - this.pdbx_host_org_cell = pdbx_host_org_cell; - } - public String getPdbx_host_org_cell_line() { - return pdbx_host_org_cell_line; - } - public void setPdbx_host_org_cell_line(String pdbx_host_org_cell_line) { - this.pdbx_host_org_cell_line = pdbx_host_org_cell_line; - } - public String getPdbx_host_org_cellular_location() { - return pdbx_host_org_cellular_location; - } - public void setPdbx_host_org_cellular_location( - String pdbx_host_org_cellular_location) { - this.pdbx_host_org_cellular_location = pdbx_host_org_cellular_location; - } - public String getPdbx_host_org_culture_collection() { - return pdbx_host_org_culture_collection; - } - public void setPdbx_host_org_culture_collection( - String pdbx_host_org_culture_collection) { - this.pdbx_host_org_culture_collection = pdbx_host_org_culture_collection; - } - public String getPdbx_host_org_gene() { - return pdbx_host_org_gene; - } - public void setPdbx_host_org_gene(String pdbx_host_org_gene) { - this.pdbx_host_org_gene = pdbx_host_org_gene; - } - public String getPdbx_host_org_ncbi_taxonomy_id() { - return pdbx_host_org_ncbi_taxonomy_id; - } - public void setPdbx_host_org_ncbi_taxonomy_id( - String pdbx_host_org_ncbi_taxonomy_id) { - this.pdbx_host_org_ncbi_taxonomy_id = pdbx_host_org_ncbi_taxonomy_id; - } - public String getPdbx_host_org_organ() { - return pdbx_host_org_organ; - } - public void setPdbx_host_org_organ(String pdbx_host_org_organ) { - this.pdbx_host_org_organ = pdbx_host_org_organ; - } - public String getPdbx_host_org_organelle() { - return pdbx_host_org_organelle; - } - public void setPdbx_host_org_organelle(String pdbx_host_org_organelle) { - this.pdbx_host_org_organelle = pdbx_host_org_organelle; - } - public String getPdbx_host_org_scientific_name() { - return pdbx_host_org_scientific_name; - } - public void setPdbx_host_org_scientific_name( - String pdbx_host_org_scientific_name) { - this.pdbx_host_org_scientific_name = pdbx_host_org_scientific_name; - } - public String getPdbx_host_org_strain() { - return pdbx_host_org_strain; - } - public void setPdbx_host_org_strain(String pdbx_host_org_strain) { - this.pdbx_host_org_strain = pdbx_host_org_strain; - } - public String getPdbx_host_org_tissue() { - return pdbx_host_org_tissue; - } - public void setPdbx_host_org_tissue(String pdbx_host_org_tissue) { - this.pdbx_host_org_tissue = pdbx_host_org_tissue; - } - public String getPdbx_host_org_tissue_fraction() { - return pdbx_host_org_tissue_fraction; - } - public void setPdbx_host_org_tissue_fraction( - String pdbx_host_org_tissue_fraction) { - this.pdbx_host_org_tissue_fraction = pdbx_host_org_tissue_fraction; - } - public String getPdbx_host_org_variant() { - return pdbx_host_org_variant; - } - public void setPdbx_host_org_variant(String pdbx_host_org_variant) { - this.pdbx_host_org_variant = pdbx_host_org_variant; - } - public String getPdbx_host_org_vector() { - return pdbx_host_org_vector; - } - public void setPdbx_host_org_vector(String pdbx_host_org_vector) { - this.pdbx_host_org_vector = pdbx_host_org_vector; - } - public String getPdbx_host_org_vector_type() { - return pdbx_host_org_vector_type; - } - public void setPdbx_host_org_vector_type(String pdbx_host_org_vector_type) { - this.pdbx_host_org_vector_type = pdbx_host_org_vector_type; - } - public String getPlasmid_details() { - return plasmid_details; - } - public void setPlasmid_details(String plasmid_details) { - this.plasmid_details = plasmid_details; - } - public String getPlasmid_name() { - return plasmid_name; - } - public void setPlasmid_name(String plasmid_name) { - this.plasmid_name = plasmid_name; - } - public String getStart_construct_id() { - return start_construct_id; - } - public void setStart_construct_id(String start_construct_id) { - this.start_construct_id = start_construct_id; - } - - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcNat.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcNat.java deleted file mode 100644 index 2429751685..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcNat.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do t have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Aug 12, 2013 - * Author: Andreas Prlic - */ - -package org.biojava.nbio.structure.io.mmcif.model; - -/** Data items in the ENTITY_SRC_NAT category record details of - the source from which the entity was obtained in cases - where the entity was isolated directly from a natural tissue. - */ -public class EntitySrcNat { - String common_name ; - String details ; - String entity_id ; - String genus ; - String pdbx_atcc ; - String pdbx_cell ; - String pdbx_cell_line ; - String pdbx_cellular_location; - String pdbx_fragment ; - String pdbx_ncbi_taxonomy_id; - String pdbx_organ ; - String pdbx_organelle; - String pdbx_organism_scientific; - String pdbx_plasmid_details ; - String pdbx_plasmid_name ; - String pdbx_secretion ; - String pdbx_variant ; - String pdbx_src_id; - String pdbx_alt_source_flag; - String pdbx_beg_seq_num; - String pdbx_end_seq_num; - String pdbx_leaving_atom_flag; - String species ; - String strain ; - String tissue ; - String tissue_fraction; - - public String getCommon_name() { - return common_name; - } - public void setCommon_name(String common_name) { - this.common_name = common_name; - } - public String getDetails() { - return details; - } - public void setDetails(String details) { - this.details = details; - } - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - public String getGenus() { - return genus; - } - public void setGenus(String genus) { - this.genus = genus; - } - public String getPdbx_atcc() { - return pdbx_atcc; - } - public void setPdbx_atcc(String pdbx_atcc) { - this.pdbx_atcc = pdbx_atcc; - } - public String getPdbx_cell() { - return pdbx_cell; - } - public void setPdbx_cell(String pdbx_cell) { - this.pdbx_cell = pdbx_cell; - } - public String getPdbx_cell_line() { - return pdbx_cell_line; - } - public void setPdbx_cell_line(String pdbx_cell_line) { - this.pdbx_cell_line = pdbx_cell_line; - } - public String getPdbx_cellular_location() { - return pdbx_cellular_location; - } - public void setPdbx_cellular_location(String pdbx_cellular_location) { - this.pdbx_cellular_location = pdbx_cellular_location; - } - public String getPdbx_fragment() { - return pdbx_fragment; - } - public void setPdbx_fragment(String pdbx_fragment) { - this.pdbx_fragment = pdbx_fragment; - } - public String getPdbx_ncbi_taxonomy_id() { - return pdbx_ncbi_taxonomy_id; - } - public void setPdbx_ncbi_taxonomy_id(String pdbx_ncbi_taxonomy_id) { - this.pdbx_ncbi_taxonomy_id = pdbx_ncbi_taxonomy_id; - } - public String getPdbx_organ() { - return pdbx_organ; - } - public void setPdbx_organ(String pdbx_organ) { - this.pdbx_organ = pdbx_organ; - } - public String getPdbx_organelle() { - return pdbx_organelle; - } - public void setPdbx_organelle(String pdbx_organelle) { - this.pdbx_organelle = pdbx_organelle; - } - public String getPdbx_organism_scientific() { - return pdbx_organism_scientific; - } - public void setPdbx_organism_scientific(String pdbx_organism_scientific) { - this.pdbx_organism_scientific = pdbx_organism_scientific; - } - public String getPdbx_plasmid_details() { - return pdbx_plasmid_details; - } - public void setPdbx_plasmid_details(String pdbx_plasmid_details) { - this.pdbx_plasmid_details = pdbx_plasmid_details; - } - public String getPdbx_plasmid_name() { - return pdbx_plasmid_name; - } - public void setPdbx_plasmid_name(String pdbx_plasmid_name) { - this.pdbx_plasmid_name = pdbx_plasmid_name; - } - public String getPdbx_secretion() { - return pdbx_secretion; - } - public void setPdbx_secretion(String pdbx_secretion) { - this.pdbx_secretion = pdbx_secretion; - } - public String getPdbx_variant() { - return pdbx_variant; - } - public void setPdbx_variant(String pdbx_variant) { - this.pdbx_variant = pdbx_variant; - } - public String getSpecies() { - return species; - } - public void setSpecies(String species) { - this.species = species; - } - public String getStrain() { - return strain; - } - public void setStrain(String strain) { - this.strain = strain; - } - public String getTissue() { - return tissue; - } - public void setTissue(String tissue) { - this.tissue = tissue; - } - public String getTissue_fraction() { - return tissue_fraction; - } - public void setTissue_fraction(String tissue_fraction) { - this.tissue_fraction = tissue_fraction; - } - - public String getPdbx_src_id() { - return pdbx_src_id; - } - - public void setPdbx_src_id(String pdbx_src_id) { - this.pdbx_src_id = pdbx_src_id; - } - - public String getPdbx_alt_source_flag() { - return pdbx_alt_source_flag; - } - - public void setPdbx_alt_source_flag(String pdbx_alt_source_flag) { - this.pdbx_alt_source_flag = pdbx_alt_source_flag; - } - - public String getPdbx_beg_seq_num() { - return pdbx_beg_seq_num; - } - - public void setPdbx_beg_seq_num(String pdbx_beg_seq_num) { - this.pdbx_beg_seq_num = pdbx_beg_seq_num; - } - - public String getPdbx_end_seq_num() { - return pdbx_end_seq_num; - } - - public void setPdbx_end_seq_num(String pdbx_end_seq_num) { - this.pdbx_end_seq_num = pdbx_end_seq_num; - } - - public String getPdbx_leaving_atom_flag() { - return pdbx_leaving_atom_flag; - } - - public void setPdbx_leaving_atom_flag(String pdbx_leaving_atom_flag) { - this.pdbx_leaving_atom_flag = pdbx_leaving_atom_flag; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcSyn.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcSyn.java deleted file mode 100644 index eb1511990f..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/EntitySrcSyn.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Aug 12, 2013 - * Author: Andreas Prlic - */ - -package org.biojava.nbio.structure.io.mmcif.model; - -/** - * PDBX_ENTITY_SRC_SYN records the details about each chemically - * synthesized molecule (entity) in the asymmetric unit. - * @author Andreas Prlic - * - */ -public class EntitySrcSyn { - String details; - String entity_id; - String ncbi_taxonomy_id; - String organism_common_name; - String organism_scientific; - String strain; - public String getDetails() { - return details; - } - public void setDetails(String details) { - this.details = details; - } - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - public String getNcbi_taxonomy_id() { - return ncbi_taxonomy_id; - } - public void setNcbi_taxonomy_id(String ncbi_taxonomy_id) { - this.ncbi_taxonomy_id = ncbi_taxonomy_id; - } - public String getOrganism_common_name() { - return organism_common_name; - } - public void setOrganism_common_name(String organism_common_name) { - this.organism_common_name = organism_common_name; - } - public String getOrganism_scientific() { - return organism_scientific; - } - public void setOrganism_scientific(String organism_scientific) { - this.organism_scientific = organism_scientific; - } - public String getStrain() { - return strain; - } - public void setStrain(String strain) { - this.strain = strain; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Exptl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Exptl.java deleted file mode 100644 index ee6644cc34..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Exptl.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at May 31, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -public class Exptl extends AbstractBean{ - String entry_id; - String method; - String crystals_number; - String absorpt_coefficient_mu; - String absorpt_correction_T_max; - String absorpt_correction_T_min ; - String absorpt_correction_type ; - String absorpt_process_details ; - String details; - String method_details; - - public String getEntry_id() { - return entry_id; - } - public void setEntry_id(String entry_id) { - this.entry_id = entry_id; - } - public String getMethod() { - return method; - } - public void setMethod(String method) { - this.method = method; - } - public String getCrystals_number() { - return crystals_number; - } - public void setCrystals_number(String crystals_number) { - this.crystals_number = crystals_number; - } - public String getAbsorpt_coefficient_mu() { - return absorpt_coefficient_mu; - } - public void setAbsorpt_coefficient_mu(String absorpt_coefficient_mu) { - this.absorpt_coefficient_mu = absorpt_coefficient_mu; - } - public String getAbsorpt_correction_T_max() { - return absorpt_correction_T_max; - } - public void setAbsorpt_correction_T_max(String absorpt_correction_T_max) { - this.absorpt_correction_T_max = absorpt_correction_T_max; - } - public String getAbsorpt_correction_T_min() { - return absorpt_correction_T_min; - } - public void setAbsorpt_correction_T_min(String absorpt_correction_T_min) { - this.absorpt_correction_T_min = absorpt_correction_T_min; - } - public String getAbsorpt_correction_type() { - return absorpt_correction_type; - } - public void setAbsorpt_correction_type(String absorpt_correction_type) { - this.absorpt_correction_type = absorpt_correction_type; - } - public String getAbsorpt_process_details() { - return absorpt_process_details; - } - public void setAbsorpt_process_details(String absorpt_process_details) { - this.absorpt_process_details = absorpt_process_details; - } - public String getDetails() { - return details; - } - public void setDetails(String details) { - this.details = details; - } - public String getMethod_details() { - return method_details; - } - public void setMethod_details(String method_details) { - this.method_details = method_details; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/IgnoreField.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/IgnoreField.java deleted file mode 100644 index 8c6db21e92..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/IgnoreField.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation indicating that a specific field of a bean should be ignored - * @author Spencer Bliven - * - */ -@Target(value=ElementType.FIELD) -@Retention(value=RetentionPolicy.RUNTIME) -public @interface IgnoreField { - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxAuditRevisionHistory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxAuditRevisionHistory.java deleted file mode 100644 index 8c298f84f1..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxAuditRevisionHistory.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** - * Bean to hold data for _pdbx_audit_revision_history mmCIF category. - * - * @author Peter Rose - * @since 5.0 - */ -public class PdbxAuditRevisionHistory extends AbstractBean { - private String ordinal; - private String data_content_type; - private String major_revision; - private String minor_revision; - private String revision_date; - - public String getOrdinal() { - return ordinal; - } - public void setOrdinal(String ordinal) { - this.ordinal = ordinal; - } - public String getData_content_type() { - return data_content_type; - } - public void setData_content_type(String data_content_type) { - this.data_content_type = data_content_type; - } - public String getMajor_revision() { - return major_revision; - } - public void setMajor_revision(String major_revision) { - this.major_revision = major_revision; - } - public String getMinor_revision() { - return minor_revision; - } - public void setMinor_revision(String minor_revision) { - this.minor_revision = minor_revision; - } - public String getRevision_date() { - return revision_date; - } - public void setRevision_date(String revision_date) { - this.revision_date = revision_date; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxChemCompDescriptor.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxChemCompDescriptor.java deleted file mode 100644 index 95eb36ce7a..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxChemCompDescriptor.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on 7 Feb 2013 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/* -_pdbx_chem_comp_descriptor.comp_id -_pdbx_chem_comp_descriptor.type -_pdbx_chem_comp_descriptor.program -_pdbx_chem_comp_descriptor.program_version -_pdbx_chem_comp_descriptor.descriptor - */ -public class PdbxChemCompDescriptor { - String comp_id; - String type; - String program; - String program_version; - String identifier; - - public String getComp_id() { - return comp_id; - } - public void setComp_id(String comp_id) { - this.comp_id = comp_id; - } - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - public String getProgram() { - return program; - } - public void setProgram(String program) { - this.program = program; - } - public String getProgram_version() { - return program_version; - } - public void setProgram_version(String program_version) { - this.program_version = program_version; - } - public String getIdentifier() { - return identifier; - } - public void setIdentifier(String identifier) { - this.identifier = identifier; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxChemCompIdentifier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxChemCompIdentifier.java deleted file mode 100644 index d47ee1b9d7..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxChemCompIdentifier.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created on Feb 5, 2013 - * Created by Andreas Prlic - * - * @since 3.0.2 - */ -package org.biojava.nbio.structure.io.mmcif.model; - - - -/** -_pdbx_chem_comp_identifier.comp_id -_pdbx_chem_comp_identifier.type -_pdbx_chem_comp_identifier.program -_pdbx_chem_comp_identifier.program_version -_pdbx_chem_comp_identifier.identifier - */ -public class PdbxChemCompIdentifier { - String comp_id; - String type; - String program; - String program_version; - String identifier; - - public String getComp_id() { - return comp_id; - } - public void setComp_id(String comp_id) { - this.comp_id = comp_id; - } - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - public String getProgram() { - return program; - } - public void setProgram(String program) { - this.program = program; - } - public String getProgram_version() { - return program_version; - } - public void setProgram_version(String program_version) { - this.program_version = program_version; - } - public String getIdentifier() { - return identifier; - } - public void setIdentifier(String identifier) { - this.identifier = identifier; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxDatabaseStatus.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxDatabaseStatus.java deleted file mode 100644 index e96672c441..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxDatabaseStatus.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** - * Bean to hold data for _pdbx_database_status mmCIF category. - * - * @author Peter Rose - * @since 5.0 - */ -public class PdbxDatabaseStatus extends AbstractBean { - private String status_code; - private String entry_id; - private String recvd_initial_deposition_date; - private String deposit_site; - private String process_site; - private String SG_entry; - private String pdb_format_compatible; - private String status_code_mr; - private String status_code_sf; - private String status_code_cs; - - public String getStatus_code() { - return status_code; - } - public void setStatus_code(String status_code) { - this.status_code = status_code; - } - public String getEntry_id() { - return entry_id; - } - public void setEntry_id(String entry_id) { - this.entry_id = entry_id; - } - public String getRecvd_initial_deposition_date() { - return recvd_initial_deposition_date; - } - public void setRecvd_initial_deposition_date(String recvd_initial_deposition_date) { - this.recvd_initial_deposition_date = recvd_initial_deposition_date; - } - public String getDeposit_site() { - return deposit_site; - } - public void setDeposit_site(String deposit_site) { - this.deposit_site = deposit_site; - } - public String getProcess_site() { - return process_site; - } - public void setProcess_site(String process_site) { - this.process_site = process_site; - } - public String getSG_entry() { - return SG_entry; - } - public void setSG_entry(String sG_entry) { - SG_entry = sG_entry; - } - public String getPdb_format_compatible() { - return pdb_format_compatible; - } - public void setPdb_format_compatible(String pdb_format_compatible) { - this.pdb_format_compatible = pdb_format_compatible; - } - public String getStatus_code_mr() { - return status_code_mr; - } - public void setStatus_code_mr(String status_code_mr) { - this.status_code_mr = status_code_mr; - } - public String getStatus_code_sf() { - return status_code_sf; - } - public void setStatus_code_sf(String status_code_sf) { - this.status_code_sf = status_code_sf; - } - public String getStatus_code_cs() { - return status_code_cs; - } - public void setStatus_code_cs(String status_code_cs) { - this.status_code_cs = status_code_cs; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxEntityNonPoly.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxEntityNonPoly.java deleted file mode 100644 index f3776d14e7..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxEntityNonPoly.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** A bean for the Pdbx_entity_nonpoly category. - * - * @author Andreas Prlic - * @since 1.7 - */ -public class PdbxEntityNonPoly { - String entity_id; - String name; - String comp_id; - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public String getComp_id() { - return comp_id; - } - public void setComp_id(String comp_id) { - this.comp_id = comp_id; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxNonPolyScheme.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxNonPolyScheme.java deleted file mode 100644 index 25900b2451..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxNonPolyScheme.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** A bean for the PDBX_NONPOLY_SCHEME category, which provides residue level nomenclature - * mapping for non-polymer entities. - * @author Andreas Prlic - * @since 1.7 - */ -public class PdbxNonPolyScheme { - String asym_id; - String entity_id; - String seq_id; - String mon_id; - String ndb_seq_num; - String pdb_seq_num ; - String auth_seq_num ; - String pdb_mon_id; - String auth_mon_id; - String pdb_strand_id; - String pdb_ins_code; - public String getAsym_id() { - return asym_id; - } - public void setAsym_id(String asym_id) { - this.asym_id = asym_id; - } - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - public String getSeq_id() { - return seq_id; - } - public void setSeq_id(String seq_id) { - this.seq_id = seq_id; - } - public String getMon_id() { - return mon_id; - } - public void setMon_id(String mon_id) { - this.mon_id = mon_id; - } - public String getNdb_seq_num() { - return ndb_seq_num; - } - public void setNdb_seq_num(String ndb_seq_num) { - this.ndb_seq_num = ndb_seq_num; - } - public String getPdb_seq_num() { - return pdb_seq_num; - } - public void setPdb_seq_num(String pdb_seq_num) { - this.pdb_seq_num = pdb_seq_num; - } - public String getAuth_seq_num() { - return auth_seq_num; - } - public void setAuth_seq_num(String auth_seq_num) { - this.auth_seq_num = auth_seq_num; - } - public String getPdb_mon_id() { - return pdb_mon_id; - } - public void setPdb_mon_id(String pdb_mon_id) { - this.pdb_mon_id = pdb_mon_id; - } - public String getAuth_mon_id() { - return auth_mon_id; - } - public void setAuth_mon_id(String auth_mon_id) { - this.auth_mon_id = auth_mon_id; - } - public String getPdb_strand_id() { - return pdb_strand_id; - } - public void setPdb_strand_id(String pdb_strand_id) { - this.pdb_strand_id = pdb_strand_id; - } - public String getPdb_ins_code() { - return pdb_ins_code; - } - public void setPdb_ins_code(String pdb_ins_code) { - this.pdb_ins_code = pdb_ins_code; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxPolySeqScheme.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxPolySeqScheme.java deleted file mode 100644 index 42f470e0c2..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxPolySeqScheme.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Jun 5, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** A bean for the PDBX_POLY_SEQ_SCHEME category, which provides residue level nomenclature - * mapping for polymer entities. - * @author Andreas Prlic - * @since 1.7 - */ - -public class PdbxPolySeqScheme extends AbstractBean{ - String asym_id; - String entity_id; - String seq_id; - String mon_id; - String ndb_seq_num; - String pdb_seq_num ; - String auth_seq_num ; - String pdb_mon_id; - String auth_mon_id; - String pdb_strand_id; - String pdb_ins_code; - String hetero; - public String getAsym_id() { - return asym_id; - } - public void setAsym_id(String asym_id) { - this.asym_id = asym_id; - } - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - public String getSeq_id() { - return seq_id; - } - public void setSeq_id(String seq_id) { - this.seq_id = seq_id; - } - public String getMon_id() { - return mon_id; - } - public void setMon_id(String mon_id) { - this.mon_id = mon_id; - } - public String getNdb_seq_num() { - return ndb_seq_num; - } - public void setNdb_seq_num(String ndb_seq_num) { - this.ndb_seq_num = ndb_seq_num; - } - public String getPdb_seq_num() { - return pdb_seq_num; - } - public void setPdb_seq_num(String pdb_seq_num) { - this.pdb_seq_num = pdb_seq_num; - } - public String getAuth_seq_num() { - return auth_seq_num; - } - public void setAuth_seq_num(String auth_seq_num) { - this.auth_seq_num = auth_seq_num; - } - public String getPdb_mon_id() { - return pdb_mon_id; - } - public void setPdb_mon_id(String pdb_mon_id) { - this.pdb_mon_id = pdb_mon_id; - } - public String getAuth_mon_id() { - return auth_mon_id; - } - public void setAuth_mon_id(String auth_mon_id) { - this.auth_mon_id = auth_mon_id; - } - public String getPdb_strand_id() { - return pdb_strand_id; - } - public void setPdb_strand_id(String pdb_strand_id) { - this.pdb_strand_id = pdb_strand_id; - } - public String getPdb_ins_code() { - return pdb_ins_code; - } - public void setPdb_ins_code(String pdb_ins_code) { - this.pdb_ins_code = pdb_ins_code; - } - public String getHetero() { - return hetero; - } - public void setHetero(String hetero) { - this.hetero = hetero; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssembly.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssembly.java deleted file mode 100644 index 11b40c8a59..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssembly.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import java.io.Serializable; - - - -@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) -public class PdbxStructAssembly implements Serializable{ - - /** - * - */ - private static final long serialVersionUID = 3104504686693887219L; - - String id; - String details; - String method_details; - String oligomeric_details; - String oligomeric_count ; - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getDetails() { - return details; - } - public void setDetails(String details) { - this.details = details; - } - public String getMethod_details() { - return method_details; - } - public void setMethod_details(String method_details) { - this.method_details = method_details; - } - public String getOligomeric_details() { - return oligomeric_details; - } - public void setOligomeric_details(String oligomeric_details) { - this.oligomeric_details = oligomeric_details; - } - public String getOligomeric_count() { - return oligomeric_count; - } - public void setOligomeric_count(String oligomeric_count) { - this.oligomeric_count = oligomeric_count; - } - @Override - public String toString() { - return "PdbxStructAssembly [id=" + id + ", details=" + details - + ", method_details=" + method_details - + ", oligomeric_details=" + oligomeric_details - + ", oligomeric_count=" + oligomeric_count + "]"; - } - - - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyGen.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyGen.java deleted file mode 100644 index d672ee9f33..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyGen.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import java.io.Serializable; - -@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) -public class PdbxStructAssemblyGen implements Serializable{ - /** - * - */ - private static final long serialVersionUID = 6739568389242514332L; - String assembly_id; - String oper_expression; - String asym_id_list; - - - public String getAssembly_id() { - return assembly_id; - } - public void setAssembly_id(String assembly_id) { - this.assembly_id = assembly_id; - } - public String getOper_expression() { - return oper_expression; - } - public void setOper_expression(String oper_expression) { - this.oper_expression = oper_expression; - } - public String getAsym_id_list() { - return asym_id_list; - } - public void setAsym_id_list(String asym_id_list) { - this.asym_id_list = asym_id_list; - } - @Override - public String toString() { - return "PdbxStructAssemblyGen [assembly_id=" + assembly_id - + ", oper_expression=" + oper_expression + ", asym_id_list=" - + asym_id_list + "]"; - } - - - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyGenXMLContainer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyGenXMLContainer.java deleted file mode 100644 index aae7534df2..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyGenXMLContainer.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.List; - -@XmlRootElement(name="PdbxStructAssemblyGenXMLContainer") -public class PdbxStructAssemblyGenXMLContainer { - - private List data ; - - static JAXBContext jaxbContext; - static { - try { - jaxbContext= JAXBContext.newInstance(PdbxStructAssemblyGenXMLContainer.class); - } catch (Exception e){ - e.printStackTrace(); - } - } - - @XmlElementWrapper - public List getPdbxStructAssemblyGens(){ - return data; - - } - - public void setPdbxStructAssemblies(List d){ - data = d; - } - - public String toXML(){ - - System.out.println("converting to XML: " + data); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContext.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( this, ps); - - - } catch (Exception e){ - e.printStackTrace(); - } - - return baos.toString(); - - } - - public static PdbxStructAssemblyGenXMLContainer fromXML(String xml){ - - PdbxStructAssemblyGenXMLContainer job = null; - - try { - - Unmarshaller un = jaxbContext.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (PdbxStructAssemblyGenXMLContainer) un.unmarshal(bais); - - } catch (Exception e){ - e.printStackTrace(); - } - - return job; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyXMLContainer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyXMLContainer.java deleted file mode 100644 index d9cf2fb167..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructAssemblyXMLContainer.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.List; - -@XmlRootElement(name="PdbxStructAssemblyXMLContainer") -public class PdbxStructAssemblyXMLContainer { - - private List data ; - - static JAXBContext jaxbContext; - static { - try { - jaxbContext= JAXBContext.newInstance(PdbxStructAssemblyXMLContainer.class); - } catch (Exception e){ - e.printStackTrace(); - } - } - - @XmlElementWrapper - public List getPdbxStructAssemblies(){ - return data; - - } - - public void setPdbxStructAssemblies(List d){ - data = d; - } - - public String toXML(){ - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContext.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( this, ps); - - - } catch (Exception e){ - e.printStackTrace(); - } - - return baos.toString(); - - } - - public static PdbxStructAssemblyXMLContainer fromXML(String xml){ - - PdbxStructAssemblyXMLContainer job = null; - - try { - - Unmarshaller un = jaxbContext.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (PdbxStructAssemblyXMLContainer) un.unmarshal(bais); - - } catch (Exception e){ - e.printStackTrace(); - } - - return job; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructOperList.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructOperList.java deleted file mode 100644 index 4d2f35e614..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructOperList.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import java.io.Serializable; - -/** - * The bean for pdbx_struct_oper_list category - *
      - * _pdbx_struct_oper_list.id
      - * _pdbx_struct_oper_list.type
      - * _pdbx_struct_oper_list.symmetry_operation
      - * _pdbx_struct_oper_list.matrix[1][1]
      - * _pdbx_struct_oper_list.matrix[1][2]
      - * _pdbx_struct_oper_list.matrix[1][3]
      - * _pdbx_struct_oper_list.vector[1]
      - * _pdbx_struct_oper_list.matrix[2][1]
      - * _pdbx_struct_oper_list.matrix[2][2]
      - * _pdbx_struct_oper_list.matrix[2][3]
      - * _pdbx_struct_oper_list.vector[2]
      - * _pdbx_struct_oper_list.matrix[3][1]
      - * _pdbx_struct_oper_list.matrix[3][2]
      - * _pdbx_struct_oper_list.matrix[3][3]
      - * _pdbx_struct_oper_list.vector[3]
      - * _pdbx_struct_oper_list.name
      - * 
      - */ -@XmlAccessorType(XmlAccessType.PROPERTY) -public class PdbxStructOperList implements Serializable{ - - - private static final long serialVersionUID = 8933552854747969787L; - - @Override - public String toString() { - return "PdbxStructOperList [id=" + id + ", type=" + type + "]"; - } - - - private String id; - - private String type; - - private String symmetry_operation; - - @CIFLabel(label="matrix[1][1]") - String matrix11; - @CIFLabel(label="matrix[1][2]") - String matrix12; - @CIFLabel(label="matrix[1][3]") - String matrix13; - - @CIFLabel(label="vector[1]") - String vector1; - - @CIFLabel(label="matrix[2][1]") - String matrix21; - @CIFLabel(label="matrix[2][2]") - String matrix22; - @CIFLabel(label="matrix[2][3]") - String matrix23; - - @CIFLabel(label="vector[2]") - String vector2; - - @CIFLabel(label="matrix[3][1]") - String matrix31; - @CIFLabel(label="matrix[3][2]") - String matrix32; - @CIFLabel(label="matrix[3][3]") - String matrix33; - - @CIFLabel(label="vector[3]") - String vector3; - - String name; - - - // from here fields that are not in the cif category - - - public PdbxStructOperList(){ - - } - - @XmlAttribute - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - @XmlAttribute - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public void setMatrix11(String val){ - this.matrix11 = val; - } - public void setMatrix21(String val){ - this.matrix21 = val; - } - public void setMatrix31(String val){ - this.matrix31 = val; - } - - public void setMatrix12(String val){ - this.matrix12 = val; - } - public void setMatrix22(String val){ - this.matrix22 = val; - } - public void setMatrix32(String val){ - this.matrix32 = val; - } - public void setMatrix13(String val){ - this.matrix13 = val; - } - public void setMatrix23(String val){ - this.matrix23 = val; - } - public void setMatrix33(String val){ - this.matrix33 =val; - } - - public void setName(String name) { - this.name = name; - } - - public String getVector1() { - return vector1; - } - public void setVector1(String vector1) { - this.vector1 = vector1; - } - public String getVector2() { - return vector2; - } - public void setVector2(String vector2) { - this.vector2 = vector2; - } - public String getVector3() { - return vector3; - } - public void setVector3(String vector3) { - this.vector3 = vector3; - } - public String getName() { - return name; - } - public String getSymmetry_operation() { - return symmetry_operation; - } - public void setSymmetry_operation(String symmetry_operation) { - this.symmetry_operation = symmetry_operation; - } - @XmlElement - public String getMatrix11(){ - return matrix11; - } - @XmlElement - public String getMatrix21(){ - return matrix21; - } - @XmlElement - public String getMatrix31(){ - return matrix31; - } - @XmlElement - public String getMatrix12(){ - return matrix12; - } - @XmlElement - public String getMatrix22(){ - return matrix22; - } - @XmlElement - public String getMatrix32(){ - return matrix32; - } - @XmlElement - public String getMatrix13(){ - return matrix13; - } - @XmlElement - public String getMatrix23(){ - return matrix23; - } - @XmlElement - public String getMatrix33(){ - return matrix33; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructOperListXMLContainer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructOperListXMLContainer.java deleted file mode 100644 index a1e94e4d03..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/PdbxStructOperListXMLContainer.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.List; - -@XmlRootElement(name="PdbxStructOperListXMLContainer") -public class PdbxStructOperListXMLContainer { - - - - private List data ; - - static JAXBContext jaxbContext; - static { - try { - jaxbContext= JAXBContext.newInstance(PdbxStructOperList.class); - } catch (Exception e){ - e.printStackTrace(); - } - } - - @XmlElementWrapper - public List getPdbxStructOperLists(){ - return data; - - } - - public void setPdbxStructOperLists(List d){ - data = d; - } - - public String toXML(){ - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - PrintStream ps = new PrintStream(baos); - - try { - - Marshaller m = jaxbContext.createMarshaller(); - - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - m.marshal( this, ps); - - - } catch (Exception e){ - e.printStackTrace(); - } - - return baos.toString(); - - } - - public static PdbxStructOperListXMLContainer fromXML(String xml){ - - PdbxStructOperListXMLContainer job = null; - - try { - - Unmarshaller un = jaxbContext.createUnmarshaller(); - - ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); - - job = (PdbxStructOperListXMLContainer) un.unmarshal(bais); - - } catch (Exception e){ - e.printStackTrace(); - } - - return job; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Refine.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Refine.java deleted file mode 100644 index dceb35b5ac..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Refine.java +++ /dev/null @@ -1,658 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -public class Refine { - String entry_id; - String ls_number_reflns_obs; - String ls_number_reflns_all; - String pdbx_ls_sigma_I; - String pdbx_ls_sigma_F; - String pdbx_data_cutoff_high_absF; - String pdbx_data_cutoff_low_absF ; - String pdbx_data_cutoff_high_rms_absF; - String ls_d_res_low ; - String ls_d_res_high ; - String ls_percent_reflns_obs; - String ls_R_factor_obs ; - String ls_R_factor_all ; - String ls_R_factor_R_work; - String ls_R_factor_R_free ; - String ls_R_factor_R_free_error; - String ls_R_factor_R_free_error_details; - String ls_percent_reflns_R_free; - String ls_number_reflns_R_free; - String ls_number_parameters; - String ls_number_restraints; - String occupancy_min; - String occupancy_max; - String B_iso_mean; - @CIFLabel(label="aniso_B[1][1]") - String aniso_B11; - @CIFLabel(label="aniso_B[2][2]") - String aniso_B22; - @CIFLabel(label="aniso_B[3][3]") - String aniso_B33; - @CIFLabel(label="aniso_B[1][2]") - String aniso_B12; - @CIFLabel(label="aniso_B[1][3]") - String aniso_B13; - @CIFLabel(label="aniso_B[2][3]") - String aniso_B23; - String solvent_model_details ; - String solvent_model_param_ksol; - String solvent_model_param_bsol; - String pdbx_ls_cross_valid_method; - String details; - String pdbx_starting_model; - String pdbx_method_to_determine_struct; - String pdbx_isotropic_thermal_model; - String pdbx_stereochemistry_target_values; - String pdbx_stereochem_target_val_spec_case; - String pdbx_R_Free_selection_details; - String pdbx_overall_ESU_R; - String pdbx_overall_ESU_R_Free; - String overall_SU_ML; - String overall_SU_B; - String ls_redundancy_reflns_obs; - String pdbx_overall_phase_error ; - String B_iso_min; - String B_iso_max; - String correlation_coeff_Fo_to_Fc; - String correlation_coeff_Fo_to_Fc_free; - String pdbx_solvent_vdw_probe_radii; - String pdbx_solvent_ion_probe_radii; - String pdbx_solvent_shrinkage_radii; - String overall_SU_R_Cruickshank_DPI; - String overall_SU_R_free; - String ls_wR_factor_R_free; - String ls_wR_factor_R_work; - String overall_FOM_free_R_set; - String overall_FOM_work_R_set; - String pdbx_refine_id; - String pdbx_diffrn_id; - String pdbx_TLS_residual_ADP_flag; - String pdbx_overall_SU_R_free_Cruickshank_DPI; - String pdbx_overall_SU_R_Blow_DPI; - String pdbx_overall_SU_R_free_Blow_DPI; - // these 2 fields are present only in some files (e.g. 4lnc, a hybrid X-RAY/NEUTRON DIFFRACTION) - String ls_matrix_type; - String ls_number_reflns_R_work; - - public Refine(){ - //aniso_B = new String[3][3]; - } - - public String getEntry_id() { - return entry_id; - } - - public void setEntry_id(String entry_id) { - this.entry_id = entry_id; - } - - public String getLs_number_reflns_obs() { - return ls_number_reflns_obs; - } - - public void setLs_number_reflns_obs(String ls_number_reflns_obs) { - this.ls_number_reflns_obs = ls_number_reflns_obs; - } - - public String getLs_number_reflns_all() { - return ls_number_reflns_all; - } - - public void setLs_number_reflns_all(String ls_number_reflns_all) { - this.ls_number_reflns_all = ls_number_reflns_all; - } - - public String getPdbx_ls_sigma_I() { - return pdbx_ls_sigma_I; - } - - public void setPdbx_ls_sigma_I(String pdbx_ls_sigma_I) { - this.pdbx_ls_sigma_I = pdbx_ls_sigma_I; - } - - public String getPdbx_ls_sigma_F() { - return pdbx_ls_sigma_F; - } - - public void setPdbx_ls_sigma_F(String pdbx_ls_sigma_F) { - this.pdbx_ls_sigma_F = pdbx_ls_sigma_F; - } - - public String getPdbx_data_cutoff_high_absF() { - return pdbx_data_cutoff_high_absF; - } - - public void setPdbx_data_cutoff_high_absF(String pdbx_data_cutoff_high_absF) { - this.pdbx_data_cutoff_high_absF = pdbx_data_cutoff_high_absF; - } - - public String getPdbx_data_cutoff_low_absF() { - return pdbx_data_cutoff_low_absF; - } - - public void setPdbx_data_cutoff_low_absF(String pdbx_data_cutoff_low_absF) { - this.pdbx_data_cutoff_low_absF = pdbx_data_cutoff_low_absF; - } - - public String getPdbx_data_cutoff_high_rms_absF() { - return pdbx_data_cutoff_high_rms_absF; - } - - public void setPdbx_data_cutoff_high_rms_absF( - String pdbx_data_cutoff_high_rms_absF) { - this.pdbx_data_cutoff_high_rms_absF = pdbx_data_cutoff_high_rms_absF; - } - - public String getLs_d_res_low() { - return ls_d_res_low; - } - - public void setLs_d_res_low(String ls_d_res_low) { - this.ls_d_res_low = ls_d_res_low; - } - - public String getLs_d_res_high() { - return ls_d_res_high; - } - - public void setLs_d_res_high(String ls_d_res_high) { - this.ls_d_res_high = ls_d_res_high; - } - - public String getLs_percent_reflns_obs() { - return ls_percent_reflns_obs; - } - - public void setLs_percent_reflns_obs(String ls_percent_reflns_obs) { - this.ls_percent_reflns_obs = ls_percent_reflns_obs; - } - - public String getLs_R_factor_obs() { - return ls_R_factor_obs; - } - - public void setLs_R_factor_obs(String ls_R_factor_obs) { - this.ls_R_factor_obs = ls_R_factor_obs; - } - - public String getLs_R_factor_all() { - return ls_R_factor_all; - } - - public void setLs_R_factor_all(String ls_R_factor_all) { - this.ls_R_factor_all = ls_R_factor_all; - } - - public String getLs_R_factor_R_work() { - return ls_R_factor_R_work; - } - - public void setLs_R_factor_R_work(String ls_R_factor_R_work) { - this.ls_R_factor_R_work = ls_R_factor_R_work; - } - - public String getLs_R_factor_R_free() { - return ls_R_factor_R_free; - } - - public void setLs_R_factor_R_free(String ls_R_factor_R_free) { - this.ls_R_factor_R_free = ls_R_factor_R_free; - } - - public String getLs_R_factor_R_free_error() { - return ls_R_factor_R_free_error; - } - - public void setLs_R_factor_R_free_error(String ls_R_factor_R_free_error) { - this.ls_R_factor_R_free_error = ls_R_factor_R_free_error; - } - - public String getLs_R_factor_R_free_error_details() { - return ls_R_factor_R_free_error_details; - } - - public void setLs_R_factor_R_free_error_details( - String ls_R_factor_R_free_error_details) { - this.ls_R_factor_R_free_error_details = ls_R_factor_R_free_error_details; - } - - public String getLs_percent_reflns_R_free() { - return ls_percent_reflns_R_free; - } - - public void setLs_percent_reflns_R_free(String ls_percent_reflns_R_free) { - this.ls_percent_reflns_R_free = ls_percent_reflns_R_free; - } - - public String getLs_number_reflns_R_free() { - return ls_number_reflns_R_free; - } - - public void setLs_number_reflns_R_free(String ls_number_reflns_R_free) { - this.ls_number_reflns_R_free = ls_number_reflns_R_free; - } - - public String getLs_number_parameters() { - return ls_number_parameters; - } - - public void setLs_number_parameters(String ls_number_parameters) { - this.ls_number_parameters = ls_number_parameters; - } - - public String getLs_number_restraints() { - return ls_number_restraints; - } - - public void setLs_number_restraints(String ls_number_restraints) { - this.ls_number_restraints = ls_number_restraints; - } - - public String getOccupancy_min() { - return occupancy_min; - } - - public void setOccupancy_min(String occupancy_min) { - this.occupancy_min = occupancy_min; - } - - public String getOccupancy_max() { - return occupancy_max; - } - - public void setOccupancy_max(String occupancy_max) { - this.occupancy_max = occupancy_max; - } - - public String getB_iso_mean() { - return B_iso_mean; - } - - public void setB_iso_mean(String b_iso_mean) { - B_iso_mean = b_iso_mean; - } - - public String getSolvent_model_details() { - return solvent_model_details; - } - - public void setSolvent_model_details(String solvent_model_details) { - this.solvent_model_details = solvent_model_details; - } - - public String getSolvent_model_param_ksol() { - return solvent_model_param_ksol; - } - - public void setSolvent_model_param_ksol(String solvent_model_param_ksol) { - this.solvent_model_param_ksol = solvent_model_param_ksol; - } - - public String getSolvent_model_param_bsol() { - return solvent_model_param_bsol; - } - - public void setSolvent_model_param_bsol(String solvent_model_param_bsol) { - this.solvent_model_param_bsol = solvent_model_param_bsol; - } - - public String getPdbx_ls_cross_valid_method() { - return pdbx_ls_cross_valid_method; - } - - public void setPdbx_ls_cross_valid_method(String pdbx_ls_cross_valid_method) { - this.pdbx_ls_cross_valid_method = pdbx_ls_cross_valid_method; - } - - public String getDetails() { - return details; - } - - public void setDetails(String details) { - this.details = details; - } - - public String getPdbx_starting_model() { - return pdbx_starting_model; - } - - public void setPdbx_starting_model(String pdbx_starting_model) { - this.pdbx_starting_model = pdbx_starting_model; - } - - public String getPdbx_method_to_determine_struct() { - return pdbx_method_to_determine_struct; - } - - public void setPdbx_method_to_determine_struct( - String pdbx_method_to_determine_struct) { - this.pdbx_method_to_determine_struct = pdbx_method_to_determine_struct; - } - - public String getPdbx_isotropic_thermal_model() { - return pdbx_isotropic_thermal_model; - } - - public void setPdbx_isotropic_thermal_model(String pdbx_isotropic_thermal_model) { - this.pdbx_isotropic_thermal_model = pdbx_isotropic_thermal_model; - } - - public String getPdbx_stereochemistry_target_values() { - return pdbx_stereochemistry_target_values; - } - - public void setPdbx_stereochemistry_target_values( - String pdbx_stereochemistry_target_values) { - this.pdbx_stereochemistry_target_values = pdbx_stereochemistry_target_values; - } - - public String getPdbx_stereochem_target_val_spec_case() { - return pdbx_stereochem_target_val_spec_case; - } - - public void setPdbx_stereochem_target_val_spec_case( - String pdbx_stereochem_target_val_spec_case) { - this.pdbx_stereochem_target_val_spec_case = pdbx_stereochem_target_val_spec_case; - } - - public String getPdbx_R_Free_selection_details() { - return pdbx_R_Free_selection_details; - } - - public void setPdbx_R_Free_selection_details( - String pdbx_R_Free_selection_details) { - this.pdbx_R_Free_selection_details = pdbx_R_Free_selection_details; - } - - public String getPdbx_overall_ESU_R() { - return pdbx_overall_ESU_R; - } - - public void setPdbx_overall_ESU_R(String pdbx_overall_ESU_R) { - this.pdbx_overall_ESU_R = pdbx_overall_ESU_R; - } - - public String getPdbx_overall_ESU_R_Free() { - return pdbx_overall_ESU_R_Free; - } - - public void setPdbx_overall_ESU_R_Free(String pdbx_overall_ESU_R_Free) { - this.pdbx_overall_ESU_R_Free = pdbx_overall_ESU_R_Free; - } - - public String getOverall_SU_ML() { - return overall_SU_ML; - } - - public void setOverall_SU_ML(String overall_SU_ML) { - this.overall_SU_ML = overall_SU_ML; - } - - public String getOverall_SU_B() { - return overall_SU_B; - } - - public void setOverall_SU_B(String overall_SU_B) { - this.overall_SU_B = overall_SU_B; - } - - public String getPdbx_refine_id() { - return pdbx_refine_id; - } - - public void setPdbx_refine_id(String pdbx_refine_id) { - this.pdbx_refine_id = pdbx_refine_id; - } - - public String getLs_redundancy_reflns_obs() { - return ls_redundancy_reflns_obs; - } - - public void setLs_redundancy_reflns_obs(String ls_redundancy_reflns_obs) { - this.ls_redundancy_reflns_obs = ls_redundancy_reflns_obs; - } - - public String getPdbx_overall_phase_error() { - return pdbx_overall_phase_error; - } - - public void setPdbx_overall_phase_error(String pdbx_overall_phase_error) { - this.pdbx_overall_phase_error = pdbx_overall_phase_error; - } - - public String getB_iso_min() { - return B_iso_min; - } - - public void setB_iso_min(String b_iso_min) { - B_iso_min = b_iso_min; - } - - public String getB_iso_max() { - return B_iso_max; - } - - public void setB_iso_max(String b_iso_max) { - B_iso_max = b_iso_max; - } - - public String getCorrelation_coeff_Fo_to_Fc() { - return correlation_coeff_Fo_to_Fc; - } - - public void setCorrelation_coeff_Fo_to_Fc(String correlation_coeff_Fo_to_Fc) { - this.correlation_coeff_Fo_to_Fc = correlation_coeff_Fo_to_Fc; - } - - public String getCorrelation_coeff_Fo_to_Fc_free() { - return correlation_coeff_Fo_to_Fc_free; - } - - public void setCorrelation_coeff_Fo_to_Fc_free( - String correlation_coeff_Fo_to_Fc_free) { - this.correlation_coeff_Fo_to_Fc_free = correlation_coeff_Fo_to_Fc_free; - } - - public String getPdbx_solvent_vdw_probe_radii() { - return pdbx_solvent_vdw_probe_radii; - } - - public void setPdbx_solvent_vdw_probe_radii(String pdbx_solvent_vdw_probe_radii) { - this.pdbx_solvent_vdw_probe_radii = pdbx_solvent_vdw_probe_radii; - } - - public String getPdbx_solvent_ion_probe_radii() { - return pdbx_solvent_ion_probe_radii; - } - - public void setPdbx_solvent_ion_probe_radii(String pdbx_solvent_ion_probe_radii) { - this.pdbx_solvent_ion_probe_radii = pdbx_solvent_ion_probe_radii; - } - - public String getPdbx_solvent_shrinkage_radii() { - return pdbx_solvent_shrinkage_radii; - } - - public void setPdbx_solvent_shrinkage_radii(String pdbx_solvent_shrinkage_radii) { - this.pdbx_solvent_shrinkage_radii = pdbx_solvent_shrinkage_radii; - } - - public String getOverall_SU_R_Cruickshank_DPI() { - return overall_SU_R_Cruickshank_DPI; - } - - public void setOverall_SU_R_Cruickshank_DPI(String overall_SU_R_Cruickshank_DPI) { - this.overall_SU_R_Cruickshank_DPI = overall_SU_R_Cruickshank_DPI; - } - - public String getOverall_SU_R_free() { - return overall_SU_R_free; - } - - public void setOverall_SU_R_free(String overall_SU_R_free) { - this.overall_SU_R_free = overall_SU_R_free; - } - - public String getLs_wR_factor_R_free() { - return ls_wR_factor_R_free; - } - - public void setLs_wR_factor_R_free(String ls_wR_factor_R_free) { - this.ls_wR_factor_R_free = ls_wR_factor_R_free; - } - - public String getLs_wR_factor_R_work() { - return ls_wR_factor_R_work; - } - - public void setLs_wR_factor_R_work(String ls_wR_factor_R_work) { - this.ls_wR_factor_R_work = ls_wR_factor_R_work; - } - - public String getOverall_FOM_free_R_set() { - return overall_FOM_free_R_set; - } - - public void setOverall_FOM_free_R_set(String overall_FOM_free_R_set) { - this.overall_FOM_free_R_set = overall_FOM_free_R_set; - } - - public String getOverall_FOM_work_R_set() { - return overall_FOM_work_R_set; - } - - public void setOverall_FOM_work_R_set(String overall_FOM_work_R_set) { - this.overall_FOM_work_R_set = overall_FOM_work_R_set; - } - - public String getPdbx_diffrn_id() { - return pdbx_diffrn_id; - } - - public void setPdbx_diffrn_id(String pdbx_diffrn_id) { - this.pdbx_diffrn_id = pdbx_diffrn_id; - } - - public String getPdbx_TLS_residual_ADP_flag() { - return pdbx_TLS_residual_ADP_flag; - } - - public void setPdbx_TLS_residual_ADP_flag(String pdbx_TLS_residual_ADP_flag) { - this.pdbx_TLS_residual_ADP_flag = pdbx_TLS_residual_ADP_flag; - } - - public String getPdbx_overall_SU_R_free_Cruickshank_DPI() { - return pdbx_overall_SU_R_free_Cruickshank_DPI; - } - - public void setPdbx_overall_SU_R_free_Cruickshank_DPI( - String pdbx_overall_SU_R_free_Cruickshank_DPI) { - this.pdbx_overall_SU_R_free_Cruickshank_DPI = pdbx_overall_SU_R_free_Cruickshank_DPI; - } - - public String getPdbx_overall_SU_R_Blow_DPI() { - return pdbx_overall_SU_R_Blow_DPI; - } - - public void setPdbx_overall_SU_R_Blow_DPI(String pdbx_overall_SU_R_Blow_DPI) { - this.pdbx_overall_SU_R_Blow_DPI = pdbx_overall_SU_R_Blow_DPI; - } - - public String getPdbx_overall_SU_R_free_Blow_DPI() { - return pdbx_overall_SU_R_free_Blow_DPI; - } - - public void setPdbx_overall_SU_R_free_Blow_DPI( - String pdbx_overall_SU_R_free_Blow_DPI) { - this.pdbx_overall_SU_R_free_Blow_DPI = pdbx_overall_SU_R_free_Blow_DPI; - } - - public String getLs_matrix_type() { - return ls_matrix_type; - } - - public void setLs_matrix_type(String ls_matrix_type) { - this.ls_matrix_type = ls_matrix_type; - } - - public String getLs_number_reflns_R_work() { - return ls_number_reflns_R_work; - } - - public void setLs_number_reflns_R_work(String ls_number_reflns_R_work) { - this.ls_number_reflns_R_work = ls_number_reflns_R_work; - } - - public String getAniso_B11() { - return aniso_B11; - } - - public void setAniso_B11(String aniso_B11) { - this.aniso_B11 = aniso_B11; - } - - public String getAniso_B22() { - return aniso_B22; - } - - public void setAniso_B22(String aniso_B22) { - this.aniso_B22 = aniso_B22; - } - - public String getAniso_B33() { - return aniso_B33; - } - - public void setAniso_B33(String aniso_B33) { - this.aniso_B33 = aniso_B33; - } - - public String getAniso_B12() { - return aniso_B12; - } - - public void setAniso_B12(String aniso_B12) { - this.aniso_B12 = aniso_B12; - } - - public String getAniso_B13() { - return aniso_B13; - } - - public void setAniso_B13(String aniso_B13) { - this.aniso_B13 = aniso_B13; - } - - public String getAniso_B23() { - return aniso_B23; - } - - public void setAniso_B23(String aniso_B23) { - this.aniso_B23 = aniso_B23; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Struct.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Struct.java deleted file mode 100644 index 09a711febe..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Struct.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Apr 26, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** a bean to contain the data of the _struct lines - * - * @author Andreas Prlic - * - */ -public class Struct { - String entry_id; - String title; - String pdbx_descriptor; - String pdbx_model_details; - String pdbx_model_type_details; - String pdbx_CASP_flag; - - @Override - public String toString(){ - return "entry_id:" +entry_id + " title:" + title + " pdbx_descriptor:" +pdbx_descriptor + " pdbx_model_details:"+pdbx_model_details; - } - - public String getEntry_id() { - return entry_id; - } - public void setEntry_id(String entry_id) { - this.entry_id = entry_id; - } - public String getTitle() { - return title; - } - public void setTitle(String title) { - this.title = title; - } - public String getPdbx_descriptor() { - return pdbx_descriptor; - } - public void setPdbx_descriptor(String pdbx_descriptor) { - this.pdbx_descriptor = pdbx_descriptor; - } - public String getPdbx_model_details() { - return pdbx_model_details; - } - public void setPdbx_model_details(String pdbx_model_details) { - this.pdbx_model_details = pdbx_model_details; - } - - public String getPdbx_model_type_details() { - return pdbx_model_type_details; - } - - public void setPdbx_model_type_details(String pdbx_model_type_details) { - this.pdbx_model_type_details = pdbx_model_type_details; - } - - public String getPdbx_CASP_flag() { - return pdbx_CASP_flag; - } - - public void setPdbx_CASP_flag(String pdbx_CASP_flag) { - this.pdbx_CASP_flag = pdbx_CASP_flag; - } - - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructAsym.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructAsym.java deleted file mode 100644 index f4c182b767..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructAsym.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Jun 1, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** Contains the data for _struct_asym - * - * @author Andreas Prlic - * @since 1.7 - * - */ -public class StructAsym extends AbstractBean{ - String id; - String pdbx_blank_PDB_chainid_flag; - String pdbx_modified; - String entity_id; - String details; - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getPdbx_blank_PDB_chainid_flag() { - return pdbx_blank_PDB_chainid_flag; - } - public void setPdbx_blank_PDB_chainid_flag(String pdbx_blank_PDB_chainid_flag) { - this.pdbx_blank_PDB_chainid_flag = pdbx_blank_PDB_chainid_flag; - } - public String getPdbx_modified() { - return pdbx_modified; - } - public void setPdbx_modified(String pdbx_modified) { - this.pdbx_modified = pdbx_modified; - } - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - public String getDetails() { - return details; - } - public void setDetails(String details) { - this.details = details; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructConn.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructConn.java deleted file mode 100644 index dbcb865dbd..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructConn.java +++ /dev/null @@ -1,466 +0,0 @@ -/* - * PDB web development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * - * Created on Mar 05, 2014 - * Created by Peter Rose - * - */ - -package org.biojava.nbio.structure.io.mmcif.model; -/** - * A bean that stores data from the mmcif category _struct_conn - * @author Peter Rose - * - */ -public class StructConn extends AbstractBean -{ - private String id; - private String conn_type_id; - private String pdbx_PDB_id; - private String ptnr1_label_asym_id; - private String ptnr1_label_comp_id; - private String ptnr1_label_seq_id; - private String ptnr1_label_atom_id; - private String pdbx_ptnr1_label_alt_id; - private String pdbx_ptnr1_PDB_ins_code; - private String pdbx_ptnr1_standard_comp_id; - private String ptnr1_symmetry; - private String ptnr2_label_asym_id; - private String ptnr2_label_comp_id; - private String ptnr2_label_seq_id; - private String ptnr2_label_atom_id; - private String pdbx_ptnr2_label_alt_id; - private String pdbx_ptnr2_PDB_ins_code; - private String ptnr1_auth_asym_id; - private String ptnr1_auth_comp_id; - private String ptnr1_auth_seq_id; - private String ptnr2_auth_asym_id; - private String ptnr2_auth_comp_id; - private String ptnr2_auth_seq_id; - private String ptnr2_symmetry; - private String pdbx_ptnr3_label_atom_id; - private String pdbx_ptnr3_label_seq_id; - private String pdbx_ptnr3_label_comp_id; - private String pdbx_ptnr3_label_asym_id; - private String pdbx_ptnr3_label_alt_id; - private String pdbx_ptnr3_PDB_ins_code; - private String details; - private String pdbx_dist_value; - private String pdbx_value_order; - private String pdbx_leaving_atom_flag; - /** - * @return the id - */ - public String getId() { - return id; - } - /** - * @param id the id to set - */ - public void setId(String id) { - this.id = id; - } - /** - * @return the conn_type_id - */ - public String getConn_type_id() { - return conn_type_id; - } - /** - * @param conn_type_id the conn_type_id to set - */ - public void setConn_type_id(String conn_type_id) { - this.conn_type_id = conn_type_id; - } - /** - * @return the pdbx_PDB_id - */ - public String getPdbx_PDB_id() { - return pdbx_PDB_id; - } - /** - * @param pdbx_PDB_id the pdbx_PDB_id to set - */ - public void setPdbx_PDB_id(String pdbx_PDB_id) { - this.pdbx_PDB_id = pdbx_PDB_id; - } - /** - * @return the ptnr1_label_asym_id - */ - public String getPtnr1_label_asym_id() { - return ptnr1_label_asym_id; - } - /** - * @param ptnr1_label_asym_id the ptnr1_label_asym_id to set - */ - public void setPtnr1_label_asym_id(String ptnr1_label_asym_id) { - this.ptnr1_label_asym_id = ptnr1_label_asym_id; - } - /** - * @return the ptnr1_label_comp_id - */ - public String getPtnr1_label_comp_id() { - return ptnr1_label_comp_id; - } - /** - * @param ptnr1_label_comp_id the ptnr1_label_comp_id to set - */ - public void setPtnr1_label_comp_id(String ptnr1_label_comp_id) { - this.ptnr1_label_comp_id = ptnr1_label_comp_id; - } - /** - * @return the ptnr1_label_seq_id - */ - public String getPtnr1_label_seq_id() { - return ptnr1_label_seq_id; - } - /** - * @param ptnr1_label_seq_id the ptnr1_label_seq_id to set - */ - public void setPtnr1_label_seq_id(String ptnr1_label_seq_id) { - this.ptnr1_label_seq_id = ptnr1_label_seq_id; - } - /** - * @return the ptnr1_label_atom_id - */ - public String getPtnr1_label_atom_id() { - return ptnr1_label_atom_id; - } - /** - * @param ptnr1_label_atom_id the ptnr1_label_atom_id to set - */ - public void setPtnr1_label_atom_id(String ptnr1_label_atom_id) { - this.ptnr1_label_atom_id = ptnr1_label_atom_id; - } - /** - * @return the pdbx_ptnr1_label_alt_id - */ - public String getPdbx_ptnr1_label_alt_id() { - return pdbx_ptnr1_label_alt_id; - } - /** - * @param pdbx_ptnr1_label_alt_id the pdbx_ptnr1_label_alt_id to set - */ - public void setPdbx_ptnr1_label_alt_id(String pdbx_ptnr1_label_alt_id) { - this.pdbx_ptnr1_label_alt_id = pdbx_ptnr1_label_alt_id; - } - /** - * @return the pdbx_ptnr1_PDB_ins_code - */ - public String getPdbx_ptnr1_PDB_ins_code() { - return pdbx_ptnr1_PDB_ins_code; - } - /** - * @param pdbx_ptnr1_PDB_ins_code the pdbx_ptnr1_PDB_ins_code to set - */ - public void setPdbx_ptnr1_PDB_ins_code(String pdbx_ptnr1_PDB_ins_code) { - this.pdbx_ptnr1_PDB_ins_code = pdbx_ptnr1_PDB_ins_code; - } - /** - * @return the pdbx_ptnr1_standard_comp_id - */ - public String getPdbx_ptnr1_standard_comp_id() { - return pdbx_ptnr1_standard_comp_id; - } - /** - * @param pdbx_ptnr1_standard_comp_id the pdbx_ptnr1_standard_comp_id to set - */ - public void setPdbx_ptnr1_standard_comp_id(String pdbx_ptnr1_standard_comp_id) { - this.pdbx_ptnr1_standard_comp_id = pdbx_ptnr1_standard_comp_id; - } - /** - * @return the ptnr1_symmetry - */ - public String getPtnr1_symmetry() { - return ptnr1_symmetry; - } - /** - * @param ptnr1_symmetry the ptnr1_symmetry to set - */ - public void setPtnr1_symmetry(String ptnr1_symmetry) { - this.ptnr1_symmetry = ptnr1_symmetry; - } - /** - * @return the ptnr2_label_asym_id - */ - public String getPtnr2_label_asym_id() { - return ptnr2_label_asym_id; - } - /** - * @param ptnr2_label_asym_id the ptnr2_label_asym_id to set - */ - public void setPtnr2_label_asym_id(String ptnr2_label_asym_id) { - this.ptnr2_label_asym_id = ptnr2_label_asym_id; - } - /** - * @return the ptnr2_label_comp_id - */ - public String getPtnr2_label_comp_id() { - return ptnr2_label_comp_id; - } - /** - * @param ptnr2_label_comp_id the ptnr2_label_comp_id to set - */ - public void setPtnr2_label_comp_id(String ptnr2_label_comp_id) { - this.ptnr2_label_comp_id = ptnr2_label_comp_id; - } - /** - * @return the ptnr2_label_seq_id - */ - public String getPtnr2_label_seq_id() { - return ptnr2_label_seq_id; - } - /** - * @param ptnr2_label_seq_id the ptnr2_label_seq_id to set - */ - public void setPtnr2_label_seq_id(String ptnr2_label_seq_id) { - this.ptnr2_label_seq_id = ptnr2_label_seq_id; - } - /** - * @return the ptnr2_label_atom_id - */ - public String getPtnr2_label_atom_id() { - return ptnr2_label_atom_id; - } - /** - * @param ptnr2_label_atom_id the ptnr2_label_atom_id to set - */ - public void setPtnr2_label_atom_id(String ptnr2_label_atom_id) { - this.ptnr2_label_atom_id = ptnr2_label_atom_id; - } - /** - * @return the pdbx_ptnr2_label_alt_id - */ - public String getPdbx_ptnr2_label_alt_id() { - return pdbx_ptnr2_label_alt_id; - } - /** - * @param pdbx_ptnr2_label_alt_id the pdbx_ptnr2_label_alt_id to set - */ - public void setPdbx_ptnr2_label_alt_id(String pdbx_ptnr2_label_alt_id) { - this.pdbx_ptnr2_label_alt_id = pdbx_ptnr2_label_alt_id; - } - /** - * @return the pdbx_ptnr2_PDB_ins_code - */ - public String getPdbx_ptnr2_PDB_ins_code() { - return pdbx_ptnr2_PDB_ins_code; - } - /** - * @param pdbx_ptnr2_PDB_ins_code the pdbx_ptnr2_PDB_ins_code to set - */ - public void setPdbx_ptnr2_PDB_ins_code(String pdbx_ptnr2_PDB_ins_code) { - this.pdbx_ptnr2_PDB_ins_code = pdbx_ptnr2_PDB_ins_code; - } - /** - * @return the ptnr1_auth_asym_id - */ - public String getPtnr1_auth_asym_id() { - return ptnr1_auth_asym_id; - } - /** - * @param ptnr1_auth_asym_id the ptnr1_auth_asym_id to set - */ - public void setPtnr1_auth_asym_id(String ptnr1_auth_asym_id) { - this.ptnr1_auth_asym_id = ptnr1_auth_asym_id; - } - /** - * @return the ptnr1_auth_comp_id - */ - public String getPtnr1_auth_comp_id() { - return ptnr1_auth_comp_id; - } - /** - * @param ptnr1_auth_comp_id the ptnr1_auth_comp_id to set - */ - public void setPtnr1_auth_comp_id(String ptnr1_auth_comp_id) { - this.ptnr1_auth_comp_id = ptnr1_auth_comp_id; - } - /** - * @return the ptnr1_auth_seq_id - */ - public String getPtnr1_auth_seq_id() { - return ptnr1_auth_seq_id; - } - /** - * @param ptnr1_auth_seq_id the ptnr1_auth_seq_id to set - */ - public void setPtnr1_auth_seq_id(String ptnr1_auth_seq_id) { - this.ptnr1_auth_seq_id = ptnr1_auth_seq_id; - } - /** - * @return the ptnr2_auth_asym_id - */ - public String getPtnr2_auth_asym_id() { - return ptnr2_auth_asym_id; - } - /** - * @param ptnr2_auth_asym_id the ptnr2_auth_asym_id to set - */ - public void setPtnr2_auth_asym_id(String ptnr2_auth_asym_id) { - this.ptnr2_auth_asym_id = ptnr2_auth_asym_id; - } - /** - * @return the ptnr2_auth_comp_id - */ - public String getPtnr2_auth_comp_id() { - return ptnr2_auth_comp_id; - } - /** - * @param ptnr2_auth_comp_id the ptnr2_auth_comp_id to set - */ - public void setPtnr2_auth_comp_id(String ptnr2_auth_comp_id) { - this.ptnr2_auth_comp_id = ptnr2_auth_comp_id; - } - /** - * @return the ptnr2_auth_seq_id - */ - public String getPtnr2_auth_seq_id() { - return ptnr2_auth_seq_id; - } - /** - * @param ptnr2_auth_seq_id the ptnr2_auth_seq_id to set - */ - public void setPtnr2_auth_seq_id(String ptnr2_auth_seq_id) { - this.ptnr2_auth_seq_id = ptnr2_auth_seq_id; - } - /** - * @return the ptnr2_symmetry - */ - public String getPtnr2_symmetry() { - return ptnr2_symmetry; - } - /** - * @param ptnr2_symmetry the ptnr2_symmetry to set - */ - public void setPtnr2_symmetry(String ptnr2_symmetry) { - this.ptnr2_symmetry = ptnr2_symmetry; - } - /** - * @return the pdbx_ptnr3_label_atom_id - */ - public String getPdbx_ptnr3_label_atom_id() { - return pdbx_ptnr3_label_atom_id; - } - /** - * @param pdbx_ptnr3_label_atom_id the pdbx_ptnr3_label_atom_id to set - */ - public void setPdbx_ptnr3_label_atom_id(String pdbx_ptnr3_label_atom_id) { - this.pdbx_ptnr3_label_atom_id = pdbx_ptnr3_label_atom_id; - } - /** - * @return the pdbx_ptnr3_label_seq_id - */ - public String getPdbx_ptnr3_label_seq_id() { - return pdbx_ptnr3_label_seq_id; - } - /** - * @param pdbx_ptnr3_label_seq_id the pdbx_ptnr3_label_seq_id to set - */ - public void setPdbx_ptnr3_label_seq_id(String pdbx_ptnr3_label_seq_id) { - this.pdbx_ptnr3_label_seq_id = pdbx_ptnr3_label_seq_id; - } - /** - * @return the pdbx_ptnr3_label_comp_id - */ - public String getPdbx_ptnr3_label_comp_id() { - return pdbx_ptnr3_label_comp_id; - } - /** - * @param pdbx_ptnr3_label_comp_id the pdbx_ptnr3_label_comp_id to set - */ - public void setPdbx_ptnr3_label_comp_id(String pdbx_ptnr3_label_comp_id) { - this.pdbx_ptnr3_label_comp_id = pdbx_ptnr3_label_comp_id; - } - /** - * @return the pdbx_ptnr3_label_asym_id - */ - public String getPdbx_ptnr3_label_asym_id() { - return pdbx_ptnr3_label_asym_id; - } - /** - * @param pdbx_ptnr3_label_asym_id the pdbx_ptnr3_label_asym_id to set - */ - public void setPdbx_ptnr3_label_asym_id(String pdbx_ptnr3_label_asym_id) { - this.pdbx_ptnr3_label_asym_id = pdbx_ptnr3_label_asym_id; - } - /** - * @return the pdbx_ptnr3_label_alt_id - */ - public String getPdbx_ptnr3_label_alt_id() { - return pdbx_ptnr3_label_alt_id; - } - /** - * @param pdbx_ptnr3_label_alt_id the pdbx_ptnr3_label_alt_id to set - */ - public void setPdbx_ptnr3_label_alt_id(String pdbx_ptnr3_label_alt_id) { - this.pdbx_ptnr3_label_alt_id = pdbx_ptnr3_label_alt_id; - } - /** - * @return the pdbx_ptnr3_PDB_ins_code - */ - public String getPdbx_ptnr3_PDB_ins_code() { - return pdbx_ptnr3_PDB_ins_code; - } - /** - * @param pdbx_ptnr3_PDB_ins_code the pdbx_ptnr3_PDB_ins_code to set - */ - public void setPdbx_ptnr3_PDB_ins_code(String pdbx_ptnr3_PDB_ins_code) { - this.pdbx_ptnr3_PDB_ins_code = pdbx_ptnr3_PDB_ins_code; - } - /** - * @return the details - */ - public String getDetails() { - return details; - } - /** - * @param details the details to set - */ - public void setDetails(String details) { - this.details = details; - } - /** - * @return the pdbx_dist_value - */ - public String getPdbx_dist_value() { - return pdbx_dist_value; - } - /** - * @param pdbx_dist_value the pdbx_dist_value to set - */ - public void setPdbx_dist_value(String pdbx_dist_value) { - this.pdbx_dist_value = pdbx_dist_value; - } - /** - * @return the pdbx_value_order - */ - public String getPdbx_value_order() { - return pdbx_value_order; - } - /** - * @param pdbx_value_order the pdbx_value_order to set - */ - public void setPdbx_value_order(String pdbx_value_order) { - this.pdbx_value_order = pdbx_value_order; - } - - public String getPdbx_leaving_atom_flag() { - return pdbx_leaving_atom_flag; - } - - public void setPdbx_leaving_atom_flag(String pdbx_leaving_atom_flag) { - this.pdbx_leaving_atom_flag = pdbx_leaving_atom_flag; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructKeywords.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructKeywords.java deleted file mode 100644 index f09fa63d62..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructKeywords.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -public class StructKeywords { - String entry_id; - String pdbx_keywords; - String text; - public String getEntry_id() { - return entry_id; - } - public void setEntry_id(String entry_id) { - this.entry_id = entry_id; - } - public String getPdbx_keywords() { - return pdbx_keywords; - } - public void setPdbx_keywords(String pdbx_keywords) { - this.pdbx_keywords = pdbx_keywords; - } - public String getText() { - return text; - } - public void setText(String text) { - this.text = text; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructNcsOper.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructNcsOper.java deleted file mode 100644 index 2ec97bfb32..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructNcsOper.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - - -/** - * A class containing the _struct_ncs_oper data - * - *
      - *  _struct_ncs_oper.id
      - *  _struct_ncs_oper.code
      - *  _struct_ncs_oper.details
      - * 	_struct_ncs_oper.matrix[1][1]
      - *	_struct_ncs_oper.matrix[1][2]
      - *	_struct_ncs_oper.matrix[1][3]
      - *	_struct_ncs_oper.matrix[2][1]
      - *	_struct_ncs_oper.matrix[2][2]
      - *	_struct_ncs_oper.matrix[2][3]
      - *	_struct_ncs_oper.matrix[3][1]
      - *	_struct_ncs_oper.matrix[3][2]
      - *	_struct_ncs_oper.matrix[3][3]
      - *	_struct_ncs_oper.vector[1]
      - *	_struct_ncs_oper.vector[2]
      - *	_struct_ncs_oper.vector[3]
      - * 
      - * - * @author Jose Duarte - */ -public class StructNcsOper extends AbstractBean { - - private String id; - private String code; - private String details; - - @CIFLabel(label="matrix[1][1]") - private String matrix11; - - @CIFLabel(label="matrix[1][2]") - private String matrix12; - - @CIFLabel(label="matrix[1][3]") - private String matrix13; - - @CIFLabel(label="matrix[2][1]") - private String matrix21; - - @CIFLabel(label="matrix[2][2]") - private String matrix22; - - @CIFLabel(label="matrix[2][3]") - private String matrix23; - - @CIFLabel(label="matrix[3][1]") - private String matrix31; - - @CIFLabel(label="matrix[3][2]") - private String matrix32; - - @CIFLabel(label="matrix[3][3]") - private String matrix33; - - @CIFLabel(label="vector[1]") - private String vector1; - - @CIFLabel(label="vector[2]") - private String vector2; - - @CIFLabel(label="vector[3]") - private String vector3; - - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getDetails() { - return details; - } - - public void setDetails(String details) { - this.details = details; - } - - /** - * @return the matrix11 - */ - public String getMatrix11() { - return matrix11; - } - - /** - * @param matrix11 the matrix11 to set - */ - public void setMatrix11(String matrix11) { - this.matrix11 = matrix11; - } - - /** - * @return the matrix12 - */ - public String getMatrix12() { - return matrix12; - } - - /** - * @param matrix12 the matrix12 to set - */ - public void setMatrix12(String matrix12) { - this.matrix12 = matrix12; - } - - /** - * @return the matrix13 - */ - public String getMatrix13() { - return matrix13; - } - - /** - * @param matrix13 the matrix13 to set - */ - public void setMatrix13(String matrix13) { - this.matrix13 = matrix13; - } - - /** - * @return the matrix21 - */ - public String getMatrix21() { - return matrix21; - } - - /** - * @param matrix21 the matrix21 to set - */ - public void setMatrix21(String matrix21) { - this.matrix21 = matrix21; - } - - /** - * @return the matrix22 - */ - public String getMatrix22() { - return matrix22; - } - - /** - * @param matrix22 the matrix22 to set - */ - public void setMatrix22(String matrix22) { - this.matrix22 = matrix22; - } - - /** - * @return the matrix23 - */ - public String getMatrix23() { - return matrix23; - } - - /** - * @param matrix23 the matrix23 to set - */ - public void setMatrix23(String matrix23) { - this.matrix23 = matrix23; - } - - /** - * @return the matrix31 - */ - public String getMatrix31() { - return matrix31; - } - - /** - * @param matrix31 the matrix31 to set - */ - public void setMatrix31(String matrix31) { - this.matrix31 = matrix31; - } - - /** - * @return the matrix32 - */ - public String getMatrix32() { - return matrix32; - } - - /** - * @param matrix32 the matrix32 to set - */ - public void setMatrix32(String matrix32) { - this.matrix32 = matrix32; - } - - /** - * @return the matrix33 - */ - public String getMatrix33() { - return matrix33; - } - - /** - * @param matrix33 the matrix33 to set - */ - public void setMatrix33(String matrix33) { - this.matrix33 = matrix33; - } - - /** - * @return the vector1 - */ - public String getVector1() { - return vector1; - } - - /** - * @param vector1 the vector1 to set - */ - public void setVector1(String vector1) { - this.vector1 = vector1; - } - - /** - * @return the vector2 - */ - public String getVector2() { - return vector2; - } - - /** - * @param vector2 the vector2 to set - */ - public void setVector2(String vector2) { - this.vector2 = vector2; - } - - /** - * @return the vector3 - */ - public String getVector3() { - return vector3; - } - - /** - * @param vector3 the vector3 to set - */ - public void setVector3(String vector3) { - this.vector3 = vector3; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRef.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRef.java deleted file mode 100644 index 750f4c7b68..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRef.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at May 31, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** A class to containt the _struct_ref field data - * - * @author Andreas Prlic - * - */ -public class StructRef extends AbstractBean { - String id; - String db_name; - String db_code; - String entity_id; - String pdbx_db_accession; - String pdbx_align_begin; - String pdbx_seq_one_letter_code; - String biol_id; - public String getBiol_id() { - return biol_id; - } - public void setBiol_id(String biol_id) { - this.biol_id = biol_id; - } - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getDb_name() { - return db_name; - } - public void setDb_name(String db_name) { - this.db_name = db_name; - } - public String getDb_code() { - return db_code; - } - public void setDb_code(String db_code) { - this.db_code = db_code; - } - public String getEntity_id() { - return entity_id; - } - public void setEntity_id(String entity_id) { - this.entity_id = entity_id; - } - public String getPdbx_db_accession() { - return pdbx_db_accession; - } - public void setPdbx_db_accession(String pdbx_db_accession) { - this.pdbx_db_accession = pdbx_db_accession; - } - public String getPdbx_align_begin() { - return pdbx_align_begin; - } - public void setPdbx_align_begin(String pdbx_align_begin) { - this.pdbx_align_begin = pdbx_align_begin; - } - public String getPdbx_seq_one_letter_code() { - return pdbx_seq_one_letter_code; - } - public void setPdbx_seq_one_letter_code(String pdbx_seq_one_letter_code) { - this.pdbx_seq_one_letter_code = pdbx_seq_one_letter_code; - } - - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRefSeq.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRefSeq.java deleted file mode 100644 index 32d14314bf..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRefSeq.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at May 31, 2008 - */ -package org.biojava.nbio.structure.io.mmcif.model; - -public class StructRefSeq extends AbstractBean{ - String align_id; - String ref_id; - String pdbx_PDB_id_code; - String pdbx_strand_id; - String seq_align_beg; - String pdbx_seq_align_beg_ins_code; - String seq_align_end; - String pdbx_seq_align_end_ins_code; - String pdbx_db_accession; - String db_align_beg; - String pdbx_db_align_beg_ins_code; - String db_align_end; - String pdbx_db_align_end_ins_code; - String pdbx_auth_seq_align_beg; - String pdbx_auth_seq_align_end; - String details; - - public StructRefSeq(){ - super(); - pdbx_db_align_beg_ins_code = "?"; - pdbx_db_align_end_ins_code = "?"; - - } - - public String getAlign_id() { - return align_id; - } - public void setAlign_id(String align_id) { - this.align_id = align_id; - } - public String getRef_id() { - return ref_id; - } - public void setRef_id(String ref_id) { - this.ref_id = ref_id; - } - public String getPdbx_PDB_id_code() { - return pdbx_PDB_id_code; - } - public void setPdbx_PDB_id_code(String pdbx_PDB_id_code) { - this.pdbx_PDB_id_code = pdbx_PDB_id_code; - } - public String getPdbx_strand_id() { - return pdbx_strand_id; - } - public void setPdbx_strand_id(String pdbx_strand_id) { - this.pdbx_strand_id = pdbx_strand_id; - } - public String getSeq_align_beg() { - return seq_align_beg; - } - public void setSeq_align_beg(String seq_align_beg) { - this.seq_align_beg = seq_align_beg; - } - public String getPdbx_seq_align_beg_ins_code() { - return pdbx_seq_align_beg_ins_code; - } - public void setPdbx_seq_align_beg_ins_code(String pdbx_seq_align_beg_ins_code) { - this.pdbx_seq_align_beg_ins_code = pdbx_seq_align_beg_ins_code; - } - public String getSeq_align_end() { - return seq_align_end; - } - public void setSeq_align_end(String seq_align_end) { - this.seq_align_end = seq_align_end; - } - public String getPdbx_seq_align_end_ins_code() { - return pdbx_seq_align_end_ins_code; - } - public void setPdbx_seq_align_end_ins_code(String pdbx_seq_align_end_ins_code) { - this.pdbx_seq_align_end_ins_code = pdbx_seq_align_end_ins_code; - } - public String getPdbx_db_accession() { - return pdbx_db_accession; - } - public void setPdbx_db_accession(String pdbx_db_accession) { - this.pdbx_db_accession = pdbx_db_accession; - } - public String getDb_align_beg() { - return db_align_beg; - } - public void setDb_align_beg(String db_align_beg) { - this.db_align_beg = db_align_beg; - } - public String getPdbx_db_align_beg_ins_code() { - return pdbx_db_align_beg_ins_code; - } - public void setPdbx_db_align_beg_ins_code(String pdbx_db_align_beg_ins_code) { - this.pdbx_db_align_beg_ins_code = pdbx_db_align_beg_ins_code; - } - public String getDb_align_end() { - return db_align_end; - } - public void setDb_align_end(String db_align_end) { - this.db_align_end = db_align_end; - } - public String getPdbx_db_align_end_ins_code() { - return pdbx_db_align_end_ins_code; - } - public void setPdbx_db_align_end_ins_code(String pdbx_db_align_end_ins_code) { - this.pdbx_db_align_end_ins_code = pdbx_db_align_end_ins_code; - } - public String getPdbx_auth_seq_align_beg() { - return pdbx_auth_seq_align_beg; - } - public void setPdbx_auth_seq_align_beg(String pdbx_auth_seq_align_beg) { - this.pdbx_auth_seq_align_beg = pdbx_auth_seq_align_beg; - } - public String getPdbx_auth_seq_align_end() { - return pdbx_auth_seq_align_end; - } - public void setPdbx_auth_seq_align_end(String pdbx_auth_seq_align_end) { - this.pdbx_auth_seq_align_end = pdbx_auth_seq_align_end; - } - public String getDetails() { - return details; - } - public void setDetails(String details) { - this.details = details; - } - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRefSeqDif.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRefSeqDif.java deleted file mode 100644 index 0b70bcb00e..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructRefSeqDif.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.biojava.nbio.structure.io.mmcif.model; - -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * Created by andreas on 9/11/15. - */ - -/** A class to store sequence mismatch annotations - * - */ -public class StructRefSeqDif { - - String align_id; - String pdbx_pdb_id_code; - String mon_id; - String pdbx_pdb_strand_id; - Integer seq_num; - String pdbx_pdb_ins_code; - String pdbx_seq_db_name; - String pdbx_seq_db_accession_code; - String db_mon_id; - String pdbx_seq_db_seq_num; - String details; - String pdbx_auth_seq_num; - Integer pdbx_ordinal; - - public String getAlign_id() { - return align_id; - } - - public void setAlign_id(String align_id) { - this.align_id = align_id; - } - - public String getPdbx_pdb_id_code() { - return pdbx_pdb_id_code; - } - - public void setPdbx_pdb_id_code(String pdbx_pdb_id_code) { - this.pdbx_pdb_id_code = pdbx_pdb_id_code; - } - - public String getMon_id() { - return mon_id; - } - - public void setMon_id(String mon_id) { - this.mon_id = mon_id; - } - - public String getPdbx_pdb_strand_id() { - return pdbx_pdb_strand_id; - } - - public void setPdbx_pdb_strand_id(String pdbx_pdb_strand_id) { - this.pdbx_pdb_strand_id = pdbx_pdb_strand_id; - } - - public Integer getSeq_num() { - return seq_num; - } - - public void setSeq_num(Integer seq_num) { - this.seq_num = seq_num; - } - - public String getPdbx_pdb_ins_code() { - return pdbx_pdb_ins_code; - } - - public void setPdbx_pdb_ins_code(String pdbx_pdb_ins_code) { - this.pdbx_pdb_ins_code = pdbx_pdb_ins_code; - } - - public String getPdbx_seq_db_name() { - return pdbx_seq_db_name; - } - - public void setPdbx_seq_db_name(String pdbx_seq_db_name) { - this.pdbx_seq_db_name = pdbx_seq_db_name; - } - - public String getPdbx_seq_db_accession_code() { - return pdbx_seq_db_accession_code; - } - - public void setPdbx_seq_db_accession_code(String pdbx_seq_db_accession_code) { - this.pdbx_seq_db_accession_code = pdbx_seq_db_accession_code; - } - - public String getDb_mon_id() { - return db_mon_id; - } - - public void setDb_mon_id(String db_mon_id) { - this.db_mon_id = db_mon_id; - } - - public String getPdbx_seq_db_seq_num() { - return pdbx_seq_db_seq_num; - } - - public void setPdbx_seq_db_seq_num(String pdbx_seq_db_seq_num) { - this.pdbx_seq_db_seq_num = pdbx_seq_db_seq_num; - } - - public String getDetails() { - return details; - } - - public void setDetails(String details) { - this.details = details; - } - - public String getPdbx_auth_seq_num() { - return pdbx_auth_seq_num; - } - - public void setPdbx_auth_seq_num(String pdbx_auth_seq_num) { - this.pdbx_auth_seq_num = pdbx_auth_seq_num; - } - - public Integer getPdbx_ordinal() { - return pdbx_ordinal; - } - - public void setPdbx_ordinal(Integer pdbx_ordinal) { - this.pdbx_ordinal = pdbx_ordinal; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructSite.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructSite.java deleted file mode 100644 index 21179b51f5..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructSite.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** - * Created by Matt on 11/1/2015. - */ -public class StructSite { - String id; - String details; - String pdbx_evidence_code; - String pdbx_auth_asym_id; - String pdbx_auth_comp_id; - String pdbx_auth_seq_id; - String pdbx_num_residues; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getDetails() { - return details; - } - - public void setDetails(String details) { - this.details = details; - } - - public String getPdbx_evidence_code() { - return pdbx_evidence_code; - } - - public void setPdbx_evidence_code(String pdbx_evidence_code) { - this.pdbx_evidence_code = pdbx_evidence_code; - } - - /** - * @return the pdbx_auth_asym_id - */ - public String getPdbx_auth_asym_id() { - return pdbx_auth_asym_id; - } - - /** - * @param pdbx_auth_asym_id the pdbx_auth_asym_id to set - */ - public void setPdbx_auth_asym_id(String pdbx_auth_asym_id) { - this.pdbx_auth_asym_id = pdbx_auth_asym_id; - } - - /** - * @return the pdbx_auth_comp_id - */ - public String getPdbx_auth_comp_id() { - return pdbx_auth_comp_id; - } - - /** - * @param pdbx_auth_comp_id the pdbx_auth_comp_id to set - */ - public void setPdbx_auth_comp_id(String pdbx_auth_comp_id) { - this.pdbx_auth_comp_id = pdbx_auth_comp_id; - } - - /** - * @return the pdbx_auth_seq_id - */ - public String getPdbx_auth_seq_id() { - return pdbx_auth_seq_id; - } - - /** - * @param pdbx_auth_seq_id the pdbx_auth_seq_id to set - */ - public void setPdbx_auth_seq_id(String pdbx_auth_seq_id) { - this.pdbx_auth_seq_id = pdbx_auth_seq_id; - } - - /** - * @return the pdbx_num_residues - */ - public String getPdbx_num_residues() { - return pdbx_num_residues; - } - - /** - * @param pdbx_num_residues the pdbx_num_residues to set - */ - public void setPdbx_num_residues(String pdbx_num_residues) { - this.pdbx_num_residues = pdbx_num_residues; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructSiteGen.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructSiteGen.java deleted file mode 100644 index 8cb91fe6dc..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/StructSiteGen.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - -/** - * Created by Matt on 10/31/2015. - */ -public class StructSiteGen extends AbstractBean { - String id; - String site_id; - String auth_asym_id; - String auth_atom_id; - String auth_comp_id; - String auth_seq_id; - String label_alt_id; - String label_asym_id; - String label_atom_id; - String label_comp_id; - String label_seq_id; - String details; - String pdbx_auth_ins_code; - String pdbx_num_res; - String symmetry; - - public StructSiteGen() { - super(); - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getSite_id() { - return site_id; - } - - public void setSite_id(String site_id) { - this.site_id = site_id; - } - - public String getAuth_asym_id() { - return auth_asym_id; - } - - public void setAuth_asym_id(String auth_asym_id) { - this.auth_asym_id = auth_asym_id; - } - - public String getAuth_atom_id() { - return auth_atom_id; - } - - public void setAuth_atom_id(String auth_atom_id) { - this.auth_atom_id = auth_atom_id; - } - - public String getAuth_comp_id() { - return auth_comp_id; - } - - public void setAuth_comp_id(String auth_comp_id) { - this.auth_comp_id = auth_comp_id; - } - - public String getAuth_seq_id() { - return auth_seq_id; - } - - public void setAuth_seq_id(String auth_seq_id) { - this.auth_seq_id = auth_seq_id; - } - - public String getLabel_alt_id() { - return label_alt_id; - } - - public void setLabel_alt_id(String label_alt_id) { - this.label_alt_id = label_alt_id; - } - - public String getLabel_asym_id() { - return label_asym_id; - } - - public void setLabel_asym_id(String label_asym_id) { - this.label_asym_id = label_asym_id; - } - - public String getLabel_atom_id() { - return label_atom_id; - } - - public void setLabel_atom_id(String label_atom_id) { - this.label_atom_id = label_atom_id; - } - - public String getLabel_comp_id() { - return label_comp_id; - } - - public void setLabel_comp_id(String label_comp_id) { - this.label_comp_id = label_comp_id; - } - - public String getLabel_seq_id() { - return label_seq_id; - } - - public void setLabel_seq_id(String label_seq_id) { - this.label_seq_id = label_seq_id; - } - - public String getDetails() { - return details; - } - - public void setDetails(String details) { - this.details = details; - } - - public String getPdbx_auth_ins_code() { - return pdbx_auth_ins_code; - } - - public void setPdbx_auth_ins_code(String pdbx_auth_ins_code) { - this.pdbx_auth_ins_code = pdbx_auth_ins_code; - } - - public String getPdbx_num_res() { - return pdbx_num_res; - } - - public void setPdbx_num_res(String pdbx_num_res) { - this.pdbx_num_res = pdbx_num_res; - } - - public String getSymmetry() { - return symmetry; - } - - public void setSymmetry(String symmetry) { - this.symmetry = symmetry; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Symmetry.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Symmetry.java deleted file mode 100644 index d91ef11718..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/Symmetry.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io.mmcif.model; - - -public class Symmetry extends AbstractBean { - - String entry_id; - @CIFLabel(label="space_group_name_H-M") - String space_group_name_H_M; - @CIFLabel(label="pdbx_full_space_group_name_H-M") - String pdbx_full_space_group_name_H_M; - String cell_setting; - String Int_Tables_number; - String space_group_name_Hall; - public String getEntry_id() { - return entry_id; - } - public void setEntry_id(String entry_id) { - this.entry_id = entry_id; - } - public String getSpace_group_name_H_M() { - return space_group_name_H_M; - } - public void setSpace_group_name_H_M(String space_group_name_H_M) { - this.space_group_name_H_M = space_group_name_H_M; - } - public String getPdbx_full_space_group_name_H_M() { - return pdbx_full_space_group_name_H_M; - } - public void setPdbx_full_space_group_name_H_M( - String pdbx_full_space_group_name_H_M) { - this.pdbx_full_space_group_name_H_M = pdbx_full_space_group_name_H_M; - } - public String getCell_setting() { - return cell_setting; - } - public void setCell_setting(String cell_setting) { - this.cell_setting = cell_setting; - } - public String getInt_Tables_number() { - return Int_Tables_number; - } - public void setInt_Tables_number(String int_Tables_number) { - Int_Tables_number = int_Tables_number; - } - public String getSpace_group_name_Hall() { - return space_group_name_Hall; - } - public void setSpace_group_name_Hall(String space_group_name_Hall) { - this.space_group_name_Hall = space_group_name_Hall; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/package-info.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/package-info.java deleted file mode 100644 index 7f362f0d27..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/model/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -/** - * Datamodel objects used for processing mmcif files. This are beans that can represent the data from a category in mmcif. - */ -package org.biojava.nbio.structure.io.mmcif.model; \ No newline at end of file diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/package-info.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/package-info.java deleted file mode 100644 index 02a4328875..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmcif/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -/** - * Input and Output of mmcif files. - * - * See also the BioJava 3 tutorial for more information on mmCif parsing. - */ -package org.biojava.nbio.structure.io.mmcif; \ No newline at end of file diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/quaternary/BiologicalAssemblyBuilder.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/quaternary/BiologicalAssemblyBuilder.java index 502730dcf3..083633c28f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/quaternary/BiologicalAssemblyBuilder.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/quaternary/BiologicalAssemblyBuilder.java @@ -25,9 +25,9 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.EntityInfo; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssembly; -import org.biojava.nbio.structure.io.mmcif.model.PdbxStructAssemblyGen; -import org.biojava.nbio.structure.io.mmcif.model.PdbxStructOperList; +import org.rcsb.cif.schema.mm.PdbxStructAssembly; +import org.rcsb.cif.schema.mm.PdbxStructAssemblyGen; +import org.rcsb.cif.schema.mm.PdbxStructOperList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -242,121 +242,118 @@ private void addChainFlattened(Structure s, Chain newChain, String transformId) * Returns a list of transformation matrices for the generation of a macromolecular * assembly for the specified assembly Id. * - * @param psa - * @param psags - * @param operators + * @param pdbxStructAssembly + * @param assemblyIndex + * @param pdbxStructAssemblyGen + * @param pdbxStructOperList * @return list of transformation matrices to generate macromolecular assembly */ - public ArrayList getBioUnitTransformationList(PdbxStructAssembly psa, List psags, List operators) { + public List getBioUnitTransformationList(PdbxStructAssembly pdbxStructAssembly, + int assemblyIndex, + PdbxStructAssemblyGen pdbxStructAssemblyGen, + PdbxStructOperList pdbxStructOperList) { init(); // first we populate the list of all operators from pdbx_struct_oper_list so that we can then // get them from getBioUnitTransformationsListUnaryOperators() and getBioUnitTransformationsListBinaryOperators() - for (PdbxStructOperList oper: operators){ + for (int i = 0; i < pdbxStructOperList.getRowCount(); i++) { try { Matrix4d m = new Matrix4d(); - m.m00 = Double.parseDouble(oper.getMatrix11()); - m.m01 = Double.parseDouble(oper.getMatrix12()); - m.m02 = Double.parseDouble(oper.getMatrix13()); + m.m00 = pdbxStructOperList.getMatrix11().get(i); + m.m01 = pdbxStructOperList.getMatrix12().get(i); + m.m02 = pdbxStructOperList.getMatrix13().get(i); - m.m10 = Double.parseDouble(oper.getMatrix21()); - m.m11 = Double.parseDouble(oper.getMatrix22()); - m.m12 = Double.parseDouble(oper.getMatrix23()); + m.m10 = pdbxStructOperList.getMatrix21().get(i); + m.m11 = pdbxStructOperList.getMatrix22().get(i); + m.m12 = pdbxStructOperList.getMatrix23().get(i); - m.m20 = Double.parseDouble(oper.getMatrix31()); - m.m21 = Double.parseDouble(oper.getMatrix32()); - m.m22 = Double.parseDouble(oper.getMatrix33()); + m.m20 = pdbxStructOperList.getMatrix31().get(i); + m.m21 = pdbxStructOperList.getMatrix32().get(i); + m.m22 = pdbxStructOperList.getMatrix33().get(i); - m.m03 = Double.parseDouble(oper.getVector1()); - m.m13 = Double.parseDouble(oper.getVector2()); - m.m23 = Double.parseDouble(oper.getVector3()); + m.m03 = pdbxStructOperList.getVector1().get(i); + m.m13 = pdbxStructOperList.getVector2().get(i); + m.m23 = pdbxStructOperList.getVector3().get(i); m.m30 = 0; m.m31 = 0; m.m32 = 0; m.m33 = 1; - allTransformations.put(oper.getId(), m); - + allTransformations.put(pdbxStructOperList.getId().get(i), m); } catch (NumberFormatException e) { - logger.warn("Could not parse a matrix value from pdbx_struct_oper_list for id {}. The operator id will be ignored. Error: {}", oper.getId(), e.getMessage()); + logger.warn("Could not parse a matrix value from pdbx_struct_oper_list for id {}. The operator id will be ignored. Error: {}", pdbxStructOperList.getId().get(i), e.getMessage()); } } - ArrayList transformations = getBioUnitTransformationsListUnaryOperators(psa.getId(), psags); - transformations.addAll(getBioUnitTransformationsListBinaryOperators(psa.getId(), psags)); + String assemblyId = pdbxStructAssembly.getId().get(assemblyIndex); + ArrayList transformations = getBioUnitTransformationsListUnaryOperators(assemblyId, pdbxStructAssemblyGen); + transformations.addAll(getBioUnitTransformationsListBinaryOperators(assemblyId, pdbxStructAssemblyGen)); transformations.trimToSize(); return transformations; } - - private ArrayList getBioUnitTransformationsListBinaryOperators(String assemblyId, List psags) { - + private ArrayList getBioUnitTransformationsListBinaryOperators(String assemblyId, PdbxStructAssemblyGen pdbxStructAssemblyGen) { ArrayList transformations = new ArrayList<>(); - List> operators = operatorResolver.getBinaryOperators(); + for (int i = 0; i < pdbxStructAssemblyGen.getRowCount(); i++) { + if (!pdbxStructAssemblyGen.getAssemblyId().get(i).equals(assemblyId)) { + continue; + } - for ( PdbxStructAssemblyGen psag : psags){ - if ( psag.getAssembly_id().equals(assemblyId)) { - - ListasymIds= Arrays.asList(psag.getAsym_id_list().split(",")); - - operatorResolver.parseOperatorExpressionString(psag.getOper_expression()); - - // apply binary operators to the specified chains - // Example 1M4X: generates all products of transformation matrices (1-60)(61-88) - for (String chainId : asymIds) { - - for (OrderedPair operator : operators) { - Matrix4d original1 = allTransformations.get(operator.getElement1()); - Matrix4d original2 = allTransformations.get(operator.getElement2()); - if (original1 == null || original2 == null) { - logger.warn("Could not find matrix operator for operator id {} or {}. Assembly id {} will not contain the composed operator.", operator.getElement1(), operator.getElement2(), assemblyId); - continue; - } - Matrix4d composed = new Matrix4d(original1); - composed.mul(original2); - BiologicalAssemblyTransformation transform = new BiologicalAssemblyTransformation(); - transform.setChainId(chainId); - transform.setId(operator.getElement1() + COMPOSED_OPERATOR_SEPARATOR + operator.getElement2()); - transform.setTransformationMatrix(composed); - transformations.add(transform); + String[] asymIds= pdbxStructAssemblyGen.getAsymIdList().get(i).split(","); + operatorResolver.parseOperatorExpressionString(pdbxStructAssemblyGen.getOperExpression().get(i)); + + // apply binary operators to the specified chains + // Example 1M4X: generates all products of transformation matrices (1-60)(61-88) + for (String chainId : asymIds) { + for (OrderedPair operator : operators) { + Matrix4d original1 = allTransformations.get(operator.getElement1()); + Matrix4d original2 = allTransformations.get(operator.getElement2()); + if (original1 == null || original2 == null) { + logger.warn("Could not find matrix operator for operator id {} or {}. Assembly id {} will not contain the composed operator.", operator.getElement1(), operator.getElement2(), assemblyId); + continue; } + Matrix4d composed = new Matrix4d(original1); + composed.mul(original2); + BiologicalAssemblyTransformation transform = new BiologicalAssemblyTransformation(); + transform.setChainId(chainId); + transform.setId(operator.getElement1() + COMPOSED_OPERATOR_SEPARATOR + operator.getElement2()); + transform.setTransformationMatrix(composed); + transformations.add(transform); } } - } return transformations; } - private ArrayList getBioUnitTransformationsListUnaryOperators(String assemblyId, List psags) { - ArrayList transformations = new ArrayList(); - - - for ( PdbxStructAssemblyGen psag : psags){ - if ( psag.getAssembly_id().equals(assemblyId)) { - - operatorResolver.parseOperatorExpressionString(psag.getOper_expression()); - List operators = operatorResolver.getUnaryOperators(); + private ArrayList getBioUnitTransformationsListUnaryOperators(String assemblyId, PdbxStructAssemblyGen pdbxStructAssemblyGen) { + ArrayList transformations = new ArrayList<>(); - ListasymIds= Arrays.asList(psag.getAsym_id_list().split(",")); + for (int i = 0; i < pdbxStructAssemblyGen.getRowCount(); i++) { + if (!pdbxStructAssemblyGen.getAssemblyId().get(i).equals(assemblyId)) { + continue; + } - // apply unary operators to the specified chains - for (String chainId : asymIds) { - for (String operator : operators) { - Matrix4d original = allTransformations.get(operator); - if (original == null) { - logger.warn("Could not find matrix operator for operator id {}. Assembly id {} will not contain the operator.", operator, assemblyId); - continue; - } - BiologicalAssemblyTransformation transform = new BiologicalAssemblyTransformation(); - transform.setChainId(chainId); - transform.setId(operator); - transform.setTransformationMatrix(original); - transformations.add(transform); + operatorResolver.parseOperatorExpressionString(pdbxStructAssemblyGen.getOperExpression().get(i)); + List operators = operatorResolver.getUnaryOperators(); + String[] asymIds = pdbxStructAssemblyGen.getAsymIdList().get(i).split(","); + + // apply unary operators to the specified chains + for (String chainId : asymIds) { + for (String operator : operators) { + Matrix4d original = allTransformations.get(operator); + if (original == null) { + logger.warn("Could not find matrix operator for operator id {}. Assembly id {} will not contain the operator.", operator, assemblyId); + continue; } + BiologicalAssemblyTransformation transform = new BiologicalAssemblyTransformation(); + transform.setChainId(chainId); + transform.setId(operator); + transform.setTransformationMatrix(original); + transformations.add(transform); } } } @@ -364,8 +361,8 @@ private ArrayList getBioUnitTransformationsLis return transformations; } - private void init(){ - operatorResolver= new OperatorResolver(); + private void init() { + operatorResolver = new OperatorResolver(); allTransformations = new HashMap<>(); } } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java index bb46670bae..87fc80a314 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java @@ -28,7 +28,6 @@ import org.biojava.nbio.structure.io.LocalPDBDirectory; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; -import org.biojava.nbio.structure.io.MMCIFFileReader; import org.biojava.nbio.structure.io.PDBFileReader; import org.junit.Before; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java index 58a2623062..6ba61088b4 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java @@ -54,7 +54,6 @@ import org.biojava.nbio.structure.io.LocalPDBDirectory; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; -import org.biojava.nbio.structure.io.MMCIFFileReader; import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import org.biojava.nbio.structure.io.mmcif.model.ChemComp; From 993665a74da8e35e27641eebdf6ac0b506455e30 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Thu, 14 Jan 2021 09:48:15 -0800 Subject: [PATCH 186/769] wip (TODO chemcomp parsing) --- .../java/demo/DemoChangeChemCompProvider.java | 4 - .../src/main/java/demo/DemoMMCIFReader.java | 3 +- .../nbio/structure/AtomPositionMap.java | 1 + .../org/biojava/nbio/structure/ChainImpl.java | 2 +- .../nbio/structure/DatabasePDBRevRecord.java | 3 - .../biojava/nbio/structure/HetatomImpl.java | 7 +- .../nbio/structure/align/ce/CECalculator.java | 4 +- .../align/ce/CeCalculatorEnhanced.java | 6 +- .../structure/chem/AllChemCompProvider.java | 185 -------- .../biojava/nbio/structure/chem/ChemComp.java | 38 +- .../structure/chem/ChemCompContainer.java | 13 - .../structure/chem/ChemCompGroupFactory.java | 131 ------ .../nbio/structure/chem/ChemCompProvider.java | 15 - .../nbio/structure/chem/ChemCompTools.java | 32 +- .../chem/ChemicalComponentDictionary.java | 54 ++- .../chem/DownloadChemCompProvider.java | 420 ------------------ .../chem/ReducedChemCompProvider.java | 56 --- .../biojava/nbio/structure/io/BondMaker.java | 6 +- .../nbio/structure/io/ChargeAdder.java | 48 +- .../nbio/structure/io/FileConvert.java | 5 +- .../nbio/structure/io/PDBFileParser.java | 6 +- .../nbio/structure/io/SeqRes2AtomAligner.java | 8 +- .../structure/io/cif/ChemCompConsumer.java | 14 - .../io/cif/ChemCompConsumerImpl.java | 70 --- .../structure/io/cif/CifFileConsumer.java | 48 -- .../structure/io/cif/CifFileConverter.java | 4 +- .../io/cif/StructureConsumerImpl.java | 1 - .../io/mmtf/MmtfStructureReader.java | 22 +- .../io/mmtf/MmtfStructureWriter.java | 8 +- .../nbio/structure/io/mmtf/MmtfUtils.java | 12 +- 30 files changed, 135 insertions(+), 1091 deletions(-) delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompContainer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompGroupFactory.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java diff --git a/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java b/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java index b8e4eb5430..1285d8488b 100644 --- a/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java +++ b/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java @@ -23,10 +23,6 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.chem.AllChemCompProvider; -import org.biojava.nbio.structure.chem.ChemCompGroupFactory; -import org.biojava.nbio.structure.chem.ChemCompProvider; -import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileReader; diff --git a/biojava-structure/src/main/java/demo/DemoMMCIFReader.java b/biojava-structure/src/main/java/demo/DemoMMCIFReader.java index d5ae3fea58..b94dbd2e19 100644 --- a/biojava-structure/src/main/java/demo/DemoMMCIFReader.java +++ b/biojava-structure/src/main/java/demo/DemoMMCIFReader.java @@ -26,6 +26,7 @@ import org.biojava.nbio.structure.*; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.io.CifFileReader; import org.biojava.nbio.structure.io.StructureProvider; import java.util.List; @@ -79,7 +80,7 @@ public void loadSimple(){ public void loadFromDirectAccess(){ String pdbId = "1A4W"; - StructureProvider pdbreader = new MMCIFFileReader(); + StructureProvider pdbreader = new CifFileReader(); try { Structure s = pdbreader.getStructureById(pdbId); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomPositionMap.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomPositionMap.java index d6d6f778ff..efe8822397 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomPositionMap.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/AtomPositionMap.java @@ -32,6 +32,7 @@ import java.util.NavigableMap; import java.util.TreeMap; +import org.biojava.nbio.structure.chem.ChemComp; import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.chem.ResidueType; import org.slf4j.Logger; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java index 7275fb07a9..8f548be835 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java @@ -24,7 +24,7 @@ package org.biojava.nbio.structure; -import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemComp; import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.io.FileConvert; import org.biojava.nbio.core.exceptions.CompoundNotFoundException; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java index e14ef16776..039c2f0cc4 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java @@ -2,9 +2,6 @@ import org.biojava.nbio.structure.io.cif.CifBean; -import java.util.ArrayList; -import java.util.List; - public class DatabasePDBRevRecord implements CifBean { private static final long serialVersionUID = 1L; private String revNum; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java index ddc4f2f636..c9c05a704c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java @@ -23,11 +23,10 @@ */ package org.biojava.nbio.structure; -import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemComp; import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.chem.ResidueType; import org.biojava.nbio.structure.io.GroupToSDF; -import org.rcsb.cif.schema.mm.ChemComp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -336,7 +335,7 @@ public boolean isAminoAcid() { return getType().equals(GroupType.AMINOACID); - ResidueType rt = ResidueType.getResidueTypeFromString(cc.getType().get(0)); + ResidueType rt = ResidueType.getResidueTypeFromString(cc.getType()); if (ResidueType.nonPolymer.equals(rt)) return false; @@ -355,7 +354,7 @@ public boolean isNucleotide() { if ( cc == null) return getType().equals(GroupType.NUCLEOTIDE); - ResidueType rt = ResidueType.getResidueTypeFromString(cc.getType().get(0)); + ResidueType rt = ResidueType.getResidueTypeFromString(cc.getType()); if (ResidueType.nonPolymer.equals(rt)) return false; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/CECalculator.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/CECalculator.java index e70efd5183..2fb8b1184d 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/CECalculator.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/CECalculator.java @@ -1545,9 +1545,9 @@ public static double[][] updateMatrixWithSequenceConservation(double[][] max, At Atom a2 = ca2[j]; AminoAcidCompound ac1 = - set.getCompoundForString(a1.getGroup().getChemComp().getOne_letter_code()); + set.getCompoundForString(a1.getGroup().getChemComp().getOneLetterCode()); AminoAcidCompound ac2 = - set.getCompoundForString(a2.getGroup().getChemComp().getOne_letter_code()); + set.getCompoundForString(a2.getGroup().getChemComp().getOneLetterCode()); if ( ac1 == null || ac2 == null) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/CeCalculatorEnhanced.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/CeCalculatorEnhanced.java index 8610b10d0b..940111d3c8 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/CeCalculatorEnhanced.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/ce/CeCalculatorEnhanced.java @@ -1442,7 +1442,7 @@ private int optimizeSuperposition(AFPChain afpChain, int nse1, int nse2, int str for ( int i =0 ; i < strBuf1.length; i++){ if ( strBuf1[i] == null) break; - System.out.print(strBuf1[i].getGroup().getChemComp().getOne_letter_code()); + System.out.print(strBuf1[i].getGroup().getChemComp().getOneLetterCode()); } System.out.println(); @@ -1551,9 +1551,9 @@ public static double[][] updateMatrixWithSequenceConservation(double[][] max, At Atom a2 = ca2[j]; AminoAcidCompound ac1 = - set.getCompoundForString(a1.getGroup().getChemComp().getOne_letter_code()); + set.getCompoundForString(a1.getGroup().getChemComp().getOneLetterCode()); AminoAcidCompound ac2 = - set.getCompoundForString(a2.getGroup().getChemComp().getOne_letter_code()); + set.getCompoundForString(a2.getGroup().getChemComp().getOneLetterCode()); if ( ac1 == null || ac2 == null) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java deleted file mode 100644 index ef3b7414b8..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java +++ /dev/null @@ -1,185 +0,0 @@ -package org.biojava.nbio.structure.chem; - -import org.biojava.nbio.core.util.InputStreamProvider; -import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.LocalPDBDirectory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * A ChemComp provider that downloads and caches the components.cif file from the wwPDB site. It then loads - * all chemical components at startup and keeps them in memory. This provider is not used as a default - * since it is slower at startup and requires more memory than the {@link DownloadChemCompProvider} that is used by default. - * - * @author Andreas Prlic - * - */ -public class AllChemCompProvider implements ChemCompProvider, Runnable{ - private static final Logger logger = LoggerFactory.getLogger(AllChemCompProvider.class); - public static final String COMPONENTS_FILE_LOCATION = "pub/pdb/data/monomers/components.cif.gz"; - - private static String path; - private static String serverName; - - // there will be only one copy of the dictionary across all instances - // to reduce memory impact - static ChemicalComponentDictionary dict; - - // flags to make sure there is only one thread running that is loading the dictionary - static AtomicBoolean loading = new AtomicBoolean(false); - static AtomicBoolean isInitialized = new AtomicBoolean(false); - - public AllChemCompProvider(){ - if (loading.get()) { - logger.warn("other thread is already loading all chemcomps, no need to init twice"); - return; - } - if (isInitialized.get()) { - return; - } - - loading.set(true); - - Thread t = new Thread(this); - t.start(); - } - - /** - * make sure all paths are initialized correctly - */ - private static void initPath(){ - if (path == null) { - UserConfiguration config = new UserConfiguration(); - path = config.getCacheFilePath(); - } - } - - private static void initServerName() { - if (serverName == null) { - serverName = LocalPDBDirectory.getServerName(); - } - } - - private void ensureFileExists() { - String fileName = getLocalFileName(); - File f = new File(fileName); - - if (!f.exists()) { - try { - downloadFile(); - } catch (IOException e) { - logger.error("Caught IOException", e); - } - } - } - - /** - * Downloads the components.cif.gz file from the wwPDB site. - */ - public static void downloadFile() throws IOException { - initPath(); - initServerName(); - - String localName = getLocalFileName(); - String u = serverName + "/" + COMPONENTS_FILE_LOCATION; - - downloadFileFromRemote(new URL(u), new File(localName)); - } - - private static void downloadFileFromRemote(URL remoteURL, File localFile) throws IOException { - logger.info("Downloading " + remoteURL + " to: " + localFile); - FileOutputStream out = new FileOutputStream(localFile); - - InputStream in = remoteURL.openStream(); - byte[] buf = new byte[4 * 1024]; // 4K buffer - int bytesRead; - while ((bytesRead = in.read(buf)) != -1) { - out.write(buf, 0, bytesRead); - } - in.close(); - out.close(); - } - - private static String getLocalFileName(){ - File dir = new File(path, DownloadChemCompProvider.CHEM_COMP_CACHE_DIRECTORY); - - if (!dir.exists()) { - logger.info("Creating directory {}", dir.toString()); - dir.mkdir(); - } - - return new File(dir, "components.cif.gz").toString(); - } - - /** - * Load all {@link ChemComp} definitions into memory. - */ - private void loadAllChemComps() throws IOException { - String fileName = getLocalFileName(); - logger.debug("Loading " + fileName); - InputStreamProvider isp = new InputStreamProvider(); - - InputStream inStream = isp.getInputStream(fileName); - MMcifParser parser = new SimpleMMcifParser(); - ChemCompConsumer consumer = new ChemCompConsumer(); - - // The Consumer builds up the BioJava - structure object. - // you could also hook in your own and build up you own data model. - parser.addMMcifConsumer(consumer); - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - dict = consumer.getDictionary(); - inStream.close(); - } - - /** - * {@inheritDoc} - */ - @Override - public ChemComp getChemComp(String recordName) { - while (loading.get()) { - // another thread is still initializing the definitions - try { - // wait half a second - Thread.sleep(500); - } catch (InterruptedException e) { - logger.error("Interrupted thread while waiting: " + e.getMessage()); - //e.printStackTrace(); - } - } - - return dict.getChemComp(recordName); - } - - - /** - * Do the actual loading of the dictionary in a thread. - */ - @Override - public void run() { - long timeS = System.currentTimeMillis(); - initPath(); - ensureFileExists(); - - try { - loadAllChemComps(); - - long timeE = System.currentTimeMillis(); - logger.debug("Time to init chem comp dictionary: " + (timeE - timeS) / 1000 + " sec."); - } catch (IOException e) { - logger.error("Could not load chemical components definition file {}. Error: {}", getLocalFileName(), e.getMessage()); - } finally { - loading.set(false); - isInitialized.set(true); - } - } -} - diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java index 96631fe736..52aa39c604 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java @@ -49,26 +49,24 @@ public class ChemComp implements CifBean, Compa @Override public String toString(){ - StringBuffer buf = new StringBuffer("ChemComp "); - buf.append(id) - .append(" ") - .append(oneLetterCode) - .append(" ") - .append(threeLetterCode) - .append(" poly:") - .append(getPolymerType()) - .append(" resi:") - .append(getResidueType()) - .append(isStandard() ? " standard" : " modified") - .append(" ") - .append(name) - .append(" ") - .append(pdbxType) - .append(" ") - .append(formula) - .append(" parent:") - .append(monNstdParentCompId); - return buf.toString(); + return "ChemComp " + id + + " " + + oneLetterCode + + " " + + threeLetterCode + + " poly:" + + getPolymerType() + + " resi:" + + getResidueType() + + (isStandard() ? " standard" : " modified") + + " " + + name + + " " + + pdbxType + + " " + + formula + + " parent:" + + monNstdParentCompId; } public boolean hasParent(){ diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompContainer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompContainer.java deleted file mode 100644 index 322f927895..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompContainer.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.biojava.nbio.structure.chem; - -import org.rcsb.cif.schema.mm.ChemComp; - -public class ChemCompContainer { - private final ChemComp delegate; - - public ChemCompContainer(ChemComp chemComp) { - this.delegate = chemComp; - } - - -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompGroupFactory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompGroupFactory.java deleted file mode 100644 index cad709223f..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompGroupFactory.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.biojava.nbio.structure.chem; - -import org.biojava.nbio.core.util.SoftHashMap; -import org.biojava.nbio.structure.AminoAcid; -import org.biojava.nbio.structure.AminoAcidImpl; -import org.biojava.nbio.structure.Group; -import org.biojava.nbio.structure.HetatomImpl; -import org.biojava.nbio.structure.NucleotideImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; - -public class ChemCompGroupFactory { - private static final Logger logger = LoggerFactory.getLogger(ChemCompGroupFactory.class); - private static ChemCompProvider chemCompProvider = new DownloadChemCompProvider(); - private static Map cache = new SoftHashMap<>(0); - - public static ChemComp getChemComp(String recordName) { - recordName = recordName.toUpperCase().trim(); - - // we are using the cache, to avoid hitting the file system too often. - ChemComp chemComp = cache.get(recordName); - if (chemComp != null) { - logger.debug("Chem comp " + chemComp.getThreeLetterCode() + " read from cache"); - return chemComp; - } - - // not cached, get the chem comp from the provider - logger.debug("Chem comp " + recordName + " read from provider " + chemCompProvider.getClass().getCanonicalName()); - chemComp = chemCompProvider.getChemComp(recordName); - - // Note that this also caches null or empty responses - cache.put(recordName, chemComp); - return chemComp; - } - - /** - * The new ChemCompProvider will be set in the static variable, - * so this provider will be used from now on until it is changed - * again. Note that this change can have unexpected behavior of - * code executed afterwards. - *

      - * Changing the provider also resets the cache, so any groups - * previously accessed will be reread or re-downloaded. - * - * @param provider - */ - public static void setChemCompProvider(ChemCompProvider provider) { - logger.debug("Setting new chem comp provider to " + provider.getClass().getCanonicalName()); - chemCompProvider = provider; - // clear cache - cache.clear(); - } - - public static ChemCompProvider getChemCompProvider(){ - return chemCompProvider; - } - - /** - * Force the in-memory cache to be reset. - * - * Note that the ChemCompProvider may have additional memory or disk caches that need to be cleared too. - */ - public static void clearCache() { - cache.clear(); - } - - public static Group getGroupFromChemCompDictionary(String recordName) { - // make sure we work with upper case records - recordName = recordName.toUpperCase().trim(); - ChemComp chemComp = getChemComp(recordName); - Group group; - - if (chemComp == null) { - return null; - } - - PolymerType polymerType = PolymerType.polymerTypeFromString(chemComp.getType()); - if (PolymerType.PROTEIN_ONLY.contains(polymerType)) { - AminoAcid aminoAcid = new AminoAcidImpl(); - - String oneLetterCode = chemComp.getOneLetterCode(); - if (oneLetterCode == null || oneLetterCode.equals("X") || oneLetterCode.equals("?") || oneLetterCode.length() == 0) { - String parent = chemComp.getMonNstdParentCompId(); - if (parent != null && parent.length() == 3) { - String parentId = chemComp.getMonNstdParentCompId(); - ChemComp parentChemComp = getChemComp(parentId); - oneLetterCode = parentChemComp.getOneLetterCode(); - } - } - - if (oneLetterCode == null || oneLetterCode.length() == 0 || oneLetterCode.equals("?")) { - // e.g. problem with PRR, which probably should have a parent of ALA, but as of 20110127 does not. - logger.warn("Problem with chemical component: " + recordName + " Did not find one letter code! Setting it to 'X'"); - aminoAcid.setAminoType('X'); - } else { - aminoAcid.setAminoType(oneLetterCode.charAt(0)); - } - - group = aminoAcid; - } else if (PolymerType.POLYNUCLEOTIDE_ONLY.contains(polymerType)) { - group = new NucleotideImpl(); - } else { - group = new HetatomImpl(); - } - - group.setChemComp(chemComp); - return group; - } - - public static String getOneLetterCode(ChemComp chemComp) { - String oneLetterCode = chemComp.getOneLetterCode(); - if (oneLetterCode == null || oneLetterCode.equals("X") || oneLetterCode.equals("?")) { - String parentId = chemComp.getMonNstdParentCompId(); - if (parentId == null) { - return oneLetterCode; - } - // cases like OIM have multiple parents (comma separated), we shouldn't try grab a chemcomp for those strings - if (parentId.length() > 3) { - return oneLetterCode; - } - ChemComp parentChemComp = ChemCompGroupFactory.getChemComp(parentId); - if (parentChemComp == null) { - return oneLetterCode; - } - oneLetterCode = parentChemComp.getOneLetterCode(); - } - return oneLetterCode; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java deleted file mode 100644 index 936f5ef8cf..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.biojava.nbio.structure.chem; - -/** - * Interface that is implemented by all classes that can provide {@link ChemComp} definitions. - * @author Andreas Prlic - * @since 3.0 - */ -public interface ChemCompProvider { - /** - * Returns a new instance of a chemical component definition. - * @param recordName the ID of the {@link ChemComp} - * @return a new {@link ChemComp} definition. - */ - ChemComp getChemComp(String recordName); -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java index b24fd5d51a..6b8f74dbd8 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java @@ -1,9 +1,7 @@ package org.biojava.nbio.structure.chem; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; public class ChemCompTools { @@ -96,40 +94,42 @@ public class ChemCompTools { bar.put('U',"DU"); bar.put('T',"DT"); DNA_LOOKUP_1TO2 = Collections.unmodifiableMap(Collections.synchronizedMap(bar)); - - - // initialise standard chemical components - List stdMonIds = new ArrayList<>(); - stdMonIds.addAll(AMINO_ACID_LOOKUP_3TO1.keySet()); - stdMonIds.addAll(DNA_LOOKUP_2TO1.keySet()); } - public static Character getAminoOneLetter(String chemCompId){ + public static Character getAminoOneLetter(String chemCompId) { return AMINO_ACID_LOOKUP_3TO1.get(chemCompId); } - public static Character getDNAOneLetter(String chemCompId){ + public static Character getDNAOneLetter(String chemCompId) { return DNA_LOOKUP_2TO1.get(chemCompId); } - public static String getAminoThreeLetter(Character c){ + public static String getAminoThreeLetter(Character c) { return AMINO_ACID_LOOKUP_1TO3.get(c); } - public static String getDNATwoLetter(Character c){ + public static String getDNATwoLetter(Character c) { return DNA_LOOKUP_1TO2.get(c); } - public static boolean isStandardChemComp(ChemComp cc){ + public static PolymerType getPolymerType(ResidueType residueType) { + if (residueType != null) { + return residueType.polymerType; + } + return null; + } + + public static boolean isStandardChemComp(ChemComp cc) { String pid = cc.getMonNstdParentCompId(); String one = cc.getOneLetterCode(); - PolymerType polymerType = cc.getPolymerType(); + ResidueType residueType = ResidueType.getResidueTypeFromString(cc.getType()); + PolymerType polymerType = getPolymerType(residueType); // standard residues have no parent - if ((pid == null) || (pid.equals("?"))) { + if (pid == null || pid.equals("?")) { // and they have a one letter code - if ((one != null) && (!one.equals("?"))) { + if (one != null && !one.equals("?")) { // peptides and dpeptides must not have X if (polymerType == PolymerType.peptide || polymerType == PolymerType.dpeptide) { return performPeptideCheck(cc, one); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java index 2f48e612d7..63b38ed2e2 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java @@ -3,15 +3,23 @@ import java.util.HashMap; import java.util.Map; +/** + * A representation of the Chemical Component Dictionary. + * + * @author Andreas Prlic + * @since 1.7 + * @see link into mmCIF dictionary + * + */ public class ChemicalComponentDictionary { - private final Map dictionary; - private final Map replaces; - private final Map isReplacedBy; - - public ChemicalComponentDictionary() { - this.dictionary = new HashMap<>(); - this.replaces = new HashMap<>(); - this.isReplacedBy = new HashMap<>(); + private Map dictionary; + private Map replaces; + private Map isReplacedBy; + + public ChemicalComponentDictionary(){ + dictionary = new HashMap<>(); + replaces = new HashMap<>(); + isReplacedBy = new HashMap<>(); } public boolean isReplaced(ChemComp c) { @@ -22,7 +30,7 @@ public boolean isReplaced(String id) { return isReplacedBy.containsKey(id); } - public boolean isReplacer(ChemComp c){ + public boolean isReplacer(ChemComp c) { return isReplacer(c.getId()); } @@ -30,27 +38,27 @@ public boolean isReplacer(String id) { return replaces.containsKey(id); } - /** if ChemComp is replaced by another one, get the newer version - * otherwise return the same ChemComp again. + /** + * If ChemComp is replaced by another one, get the newer version otherwise return the same ChemComp again. * @param c * @return get the component that replaced ChemComp. */ - public ChemComp getReplacer(ChemComp c){ + public ChemComp getReplacer(ChemComp c) { return getReplacer(c.getId()); } - public ChemComp getReplacer(String id){ + public ChemComp getReplacer(String id) { if (isReplaced(id)) { return dictionary.get(isReplacedBy.get(id)); } return dictionary.get(id); } - /** if ChemComp is replacing another one, get the old version - * otherwise return the same ChemComp again. + /** + * If ChemComp is replacing another one, get the old version otherwise return the same ChemComp again. * @param c the ChemComp for which older versions should be looked up. */ - public ChemComp getReplaced(ChemComp c){ + public ChemComp getReplaced(ChemComp c) { return getReplaced(c.getId()); } @@ -78,15 +86,15 @@ public ChemComp getParent(ChemComp c) { * @param comp */ public void addChemComp(ChemComp comp) { - dictionary.put(comp.getId(), comp); + dictionary.put(comp.getId(),comp); String rep = comp.getPdbxReplaces(); if (rep != null && !rep.equals("?")) { - replaces.put(comp.getId(), rep); + replaces.put(comp.getId(),rep); } - String isRep = comp.getPdbxReplacedBy(); - if (isRep != null && !isRep.equals("?")) { - isReplacedBy.put(comp.getId(), isRep); + String isrep = comp.getPdbxReplacedBy(); + if (isrep != null && !isrep.equals("?")) { + isReplacedBy.put(comp.getId(), isrep); } } @@ -94,11 +102,11 @@ public void addChemComp(ChemComp comp) { * Returns the number of ChemComps in this dictionary * @return nr. of ChemComps */ - public int size(){ + public int size() { return dictionary.size(); } - public ChemComp getChemComp(String id){ + public ChemComp getChemComp(String id) { return dictionary.get(id); } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java deleted file mode 100644 index 5b52bcab52..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java +++ /dev/null @@ -1,420 +0,0 @@ -package org.biojava.nbio.structure.chem; - -import org.biojava.nbio.core.util.InputStreamProvider; -import org.biojava.nbio.structure.align.util.URLConnectionTools; -import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.LocalPDBDirectory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.net.URL; -import java.net.URLConnection; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.zip.GZIPOutputStream; - -/** - * This provider of chemical components can download and cache chemical component definition files from the RCSB PDB web - * site. It is the default way to access these definitions. If this provider is called he first time, it will download - * and install all chemical component definitions in a local directory. Once the definition files have been installed, - * it has quick startup time and low memory requirements. - * - * An alternative provider, that keeps all definitions in memory is the {@link AllChemCompProvider}. Another provider, - * that does not require any network access, but only can support a limited set of chemical component definitions, is - * the {@link ReducedChemCompProvider}. - * - * @author Andreas Prlic - */ -public class DownloadChemCompProvider implements ChemCompProvider { - private static final Logger logger = LoggerFactory.getLogger(DownloadChemCompProvider.class); - public static final String CHEM_COMP_CACHE_DIRECTORY = "chemcomp"; - public static final String DEFAULT_SERVER_URL = "http://files.rcsb.org/ligands/download/"; - public static String serverBaseUrl = DEFAULT_SERVER_URL; - - /** - * Use default RCSB server layout (true) or internal RCSB server layout (false) - */ - public static boolean useDefaultUrlLayout = true; - - private static File path; - private static final String NEWLINE = System.getProperty("line.separator"); - - // flags to make sure there is only one thread running that is loading the dictionary - static AtomicBoolean loading = new AtomicBoolean(false); - - static final List protectedIDs = new ArrayList<>(); - static { - protectedIDs.add("CON"); - protectedIDs.add("PRN"); - protectedIDs.add("AUX"); - protectedIDs.add("NUL"); - } - - private static ChemCompProvider fallback = null; // Fallback provider if the download fails - /** - * by default we will download only some of the files. User has to request that all files should be downloaded... - */ - boolean downloadAll = false; - - public DownloadChemCompProvider() { - this(null); - } - - public DownloadChemCompProvider(String cacheFilePath) { - logger.debug("Initialising DownloadChemCompProvider"); - - // note that path is static, so this is just to make sure that all non-static methods will have path initialised - if (cacheFilePath != null) { - path = new File(cacheFilePath); - } - } - - /** - * Get this provider's cache path - * @return - */ - public static File getPath(){ - if (path == null) { - UserConfiguration config = new UserConfiguration(); - path = new File(config.getCacheFilePath()); - } - return path; - } - - /** - * Checks if the chemical components already have been installed into the PDB directory. - * If not, will download the chemical components definitions file and split it up into small - * subfiles. - */ - public void checkDoFirstInstall(){ - if (!downloadAll) { - return; - } - - // this makes sure there is a file separator between every component, - // if path has a trailing file separator or not, it will work for both cases - File dir = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); - File f = new File(dir, "components.cif.gz"); - - if (!f.exists()) { - downloadAllDefinitions(); - } else { - // file exists.. did it get extracted? - FilenameFilter filter = (dir1, file) -> file.endsWith(".cif.gz"); - String[] files = dir.list(filter); - if (files.length < 500) { - // not all did get unpacked - try { - split(); - } catch (IOException e) { - logger.error("Could not split file {} into individual chemical component files. Error: {}", - f.toString(), e.getMessage()); - } - } - } - } - - private void split() throws IOException { - logger.info("Installing individual chem comp files ..."); - - File dir = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); - File f = new File(dir, "components.cif.gz"); - - int counter = 0; - InputStreamProvider prov = new InputStreamProvider(); - - try (BufferedReader buf = new BufferedReader(new InputStreamReader(prov.getInputStream(f)))) { - String line; - line = buf.readLine(); - StringWriter writer = new StringWriter(); - - String currentID = null; - while (line != null) { - if (line.startsWith("data_")) { - // a new record found! - if (currentID != null) { - writeID(writer.toString(), currentID); - counter++; - } - - currentID = line.substring(5); - writer = new StringWriter(); - } - - writer.append(line); - writer.append(NEWLINE); - - line = buf.readLine (); - } - - // write the last record... - writeID(writer.toString(), currentID); - counter++; - } - - logger.info("Created " + counter + " chemical component files."); - } - - /** - * Output chemical contents to a file - * @param contents File contents - * @param currentID Chemical ID, used to determine the filename - * @throws IOException - */ - private void writeID(String contents, String currentID) throws IOException { - String localName = getLocalFileName(currentID); - - try (PrintWriter pw = new PrintWriter(new GZIPOutputStream(new FileOutputStream(localName)))) { - pw.print(contents); - pw.flush(); - } - } - - /** - * Loads the definitions for this {@link ChemComp} from a local file and instantiates a new object. - * - * @param recordName the ID of the {@link ChemComp} - * @return a new {@link ChemComp} definition. - */ - @Override - public ChemComp getChemComp(String recordName) { - // make sure we work with upper case records - recordName = recordName.toUpperCase().trim(); - - boolean haveFile = true; - if (recordName.equals("?")) { - return null; - } - - if (fileIsAbsent(recordName)) { - // check if we should install all components - checkDoFirstInstall(); - } - if (fileIsAbsent(recordName)) { - // we previously have installed already the definitions, - // just do an incrememntal update - haveFile = downloadChemCompRecord(recordName); - } - - // Added check that download was successful and chemical component is available. - if (haveFile) { - String filename = getLocalFileName(recordName); - InputStream inStream = null; - try { - InputStreamProvider isp = new InputStreamProvider(); - inStream = isp.getInputStream(filename); - - MMcifParser parser = new SimpleMMcifParser(); - ChemCompConsumer consumer = new ChemCompConsumer(); - - // The Consumer builds up the BioJava - structure object. - // you could also hook in your own and build up you own data model. - parser.addMMcifConsumer(consumer); - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - - ChemicalComponentDictionary dict = consumer.getDictionary(); - ChemComp chemComp = dict.getChemComp(recordName); - - // May be null if the file was corrupt. Fall back on ReducedChemCompProvider in that case - if (chemComp != null) { - return chemComp; - } - } catch (IOException e) { - logger.warn("Could not download chemical component file {} for {}. Error: {}. Now trying to use the " + - "local chemical component definitions.", - filename, recordName, e.getMessage()); - } finally { - // Now close it - if (inStream != null) { - try { - inStream.close(); - } catch (IOException e) { - // This would be weird... - logger.error("Could not close chemical component file {}. A resource leak could occur!!", filename); - } - } - } - } - - // see https://github.com/biojava/biojava/issues/315 - // probably a network error happened. Try to use the ReducedChemCOmpProvider - if (fallback == null) { - fallback = new ReducedChemCompProvider(); - } - - logger.warn("Falling back to ReducedChemCompProvider for {}. This could indicate a network error.", recordName); - return fallback.getChemComp(recordName); - - } - - /** - * Returns the file name that contains the definition for this {@link ChemComp} - * - * @param recordName the ID of the {@link ChemComp} - * @return full path to the file - */ - public static String getLocalFileName(String recordName) { - if (protectedIDs.contains(recordName)) { - recordName = "_" + recordName; - } - - File f = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); - if (!f.exists()) { - logger.info("Creating directory " + f); - boolean success = f.mkdir(); - // we've checked in initPath that path is writable, so there's no need to check if it succeeds - // in the unlikely case that in the meantime it isn't writable at least we log an error - if (!success) { - logger.error("Directory {} could not be created", f); - } - } - - File theFile = new File(f,recordName + ".cif.gz"); - return theFile.toString(); - } - - private static boolean fileIsAbsent(String recordName){ - String fileName = getLocalFileName(recordName); - File f = new File(fileName); - - // delete files that are too short to have contents - if (f.length() < LocalPDBDirectory.MIN_PDB_FILE_SIZE) { - // Delete defensively. - // Note that if delete is unsuccessful, we re-download the file anyways - f.delete(); - return true; - } - - return !f.exists(); - } - - /** - * @param recordName three-letter name - * @return true if successful download - */ - private static boolean downloadChemCompRecord(String recordName) { - String localName = getLocalFileName(recordName); - File newFile; - try { - newFile = File.createTempFile("chemcomp" + recordName, "cif"); - logger.debug("Will write chem comp file to temp file {}", newFile.toString()); - } catch (IOException e) { - logger.error("Could not write to temp directory {} to create the chemical component download temp file", - System.getProperty("java.io.tmpdir")); - return false; - } - String u; - if (useDefaultUrlLayout) { - u = serverBaseUrl + recordName + ".cif"; - } else { - u = serverBaseUrl + recordName.charAt(0) + "/" + recordName +"/" + recordName + ".cif"; - } - - logger.debug("downloading " + u); - URL url = null; - try { - url = new URL(u); - URLConnection uconn = URLConnectionTools.openURLConnection(url); - - try (PrintWriter pw = new PrintWriter(new GZIPOutputStream(new FileOutputStream(newFile))); - BufferedReader fileBuffer = new BufferedReader(new InputStreamReader(uconn.getInputStream()))) { - - String line; - while ((line = fileBuffer.readLine()) != null) { - pw.println(line); - } - pw.flush(); - } - // Now we move this across to where it actually wants to be - Files.move(newFile.toPath(), Paths.get(localName), StandardCopyOption.REPLACE_EXISTING); - - return true; - } catch (IOException e) { - logger.error("Could not download " + url.toString() + " OR store locally to " + localName + " Error =" + e.getMessage()); - newFile.delete(); - } - return false; - } - - private void downloadAllDefinitions() { - if (loading.get()) { - logger.info("Waiting for other thread to install chemical components..."); - } - - while (loading.get()) { - // another thread is already downloading the components definitions - // wait for the other thread to finish... - try { - // wait half a second - Thread.sleep(500); - } catch (InterruptedException e) { - //e.printStackTrace(); - logger.error("Thread interrupted "+e.getMessage()); - } - - logger.info("Another thread installed the chemical components."); - return; - } - - loading.set(true); - long timeS = System.currentTimeMillis(); - - logger.info("Performing first installation of chemical components."); - logger.info("Downloading components.cif.gz ..."); - - try { - AllChemCompProvider.downloadFile(); - } catch (IOException e) { - logger.error("Could not download the all chemical components file. Error: {}. " - + "Chemical components information won't be available", e.getMessage()); - // no point in trying to split if the file could not be downloaded - loading.set(false); - return; - } - - try { - split(); - } catch (IOException e) { - logger.error("Could not split all chem comp file into individual chemical component files. Error: {}", - e.getMessage()); - // no point in reporting time - loading.set(false); - return; - } - - long timeE = System.currentTimeMillis(); - logger.info("time to install chem comp dictionary: " + (timeE - timeS) / 1000 + " sec."); - loading.set(false); - } - - /** - * By default this provider will download only some of the {@link ChemComp} files. - * The user has to request that all files should be downloaded by setting this parameter to true. - * @return flag if the all components should be downloaded and installed at startup. (default: false) - */ - public boolean isDownloadAll() { - return downloadAll; - } - - /** - * By default this provider will download only some of the {@link ChemComp} files. - * The user has to request that all files should be downloaded by setting this parameter to true. - * @param downloadAll if the all components should be downloaded and installed at startup. (default: false) - */ - public void setDownloadAll(boolean downloadAll) { - this.downloadAll = downloadAll; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java deleted file mode 100644 index 9841fdc161..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.biojava.nbio.structure.chem; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.zip.GZIPInputStream; - -/** - * Unlike the {@link DownloadChemCompProvider}, this {@link ChemCompProvider} does not download any chem comp - * definitions. It has access to a limited set of files that are part of the biojava distribution. - * @author Andreas Prlic - * @since 3.0 - */ -public class ReducedChemCompProvider implements ChemCompProvider { - private static final Logger logger = LoggerFactory.getLogger(ReducedChemCompProvider.class); - - public ReducedChemCompProvider(){ - logger.debug("Initialising ReducedChemCompProvider"); - } - - @Override - public ChemComp getChemComp(String recordName) { - String name = recordName.toUpperCase().trim(); - try (InputStream inStream = this.getClass().getResourceAsStream("/chemcomp/" + name + ".cif.gz")) { - logger.debug("Reading chemcomp/{}.cif.gz", name); - - if (inStream == null) { - // could not find the chem comp definition for this in the jar file - logger.debug("Getting empty chem comp for {}", name); - ChemComp cc = ChemComp.getEmptyChemComp(); - cc.setId(name); - return cc; - } - - MMcifParser parser = new SimpleMMcifParser(); - ChemCompConsumer consumer = new ChemCompConsumer(); - // The Consumer builds up the BioJava - structure object. - // you could also hook in your own and build up you own data model. - parser.addMMcifConsumer(consumer); - parser.parse(new BufferedReader(new InputStreamReader(new GZIPInputStream(inStream)))); - - ChemicalComponentDictionary dict = consumer.getDictionary(); - return dict.getChemComp(name); - } catch (IOException e){ - logger.error("IOException caught while reading chem comp {}.", name, e); - } - logger.warn("Problem when loading chem comp {}, will use an empty chem comp for it", name); - ChemComp cc = ChemComp.getEmptyChemComp(); - cc.setId(name); - return cc; - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java index aee22b0767..df077cde9b 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java @@ -23,6 +23,8 @@ package org.biojava.nbio.structure.io; import org.biojava.nbio.structure.*; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemCompBond; import org.biojava.nbio.structure.io.util.PDBTemporaryStorageUtils.LinkRecord; import org.rcsb.cif.model.ValueKind; import org.rcsb.cif.schema.mm.StructConn; @@ -177,8 +179,8 @@ private void formIntraResidueBonds() { for (ChemCompBond chemCompBond : aminoChemComp.getBonds()) { // note we don't check distance to make this call not too expensive - formBondAltlocAware(group, chemCompBond.getAtom_id_1(), - group, chemCompBond.getAtom_id_2(), -1, chemCompBond.getNumericalBondOrder()); + formBondAltlocAware(group, chemCompBond.getAtomId1(), + group, chemCompBond.getAtomId2(), -1, chemCompBond.getNumericalBondOrder()); } } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/ChargeAdder.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/ChargeAdder.java index 28fbddb9a9..311414f9da 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/ChargeAdder.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/ChargeAdder.java @@ -28,19 +28,17 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemCompAtom; import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompAtom; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A class to add appropriate charge information to a structure. * @author Anthony Bradley - * */ public class ChargeAdder { - private static final Logger logger = LoggerFactory.getLogger(ChargeAdder.class); /** @@ -48,44 +46,44 @@ public class ChargeAdder { */ public static void addCharges(Structure structure) { // Loop through the models - for(int i=0; i chemAtoms = thisChemComp.getAtoms(); - for(ChemCompAtom chemCompAtom : chemAtoms) { - Atom atom = g.getAtom(chemCompAtom.getAtom_id()); + for (ChemCompAtom chemCompAtom : chemAtoms) { + Atom atom = g.getAtom(chemCompAtom.getAtomId()); String stringCharge = chemCompAtom.getCharge(); short shortCharge = 0; - if (stringCharge!=null){ - if(!stringCharge.equals("?")){ - try{ + if (stringCharge != null) { + if (!stringCharge.equals("?")) { + try { shortCharge = Short.parseShort(stringCharge); + } catch(NumberFormatException e) { + logger.warn("Number format exception. Parsing '{}' to short", stringCharge); } - catch(NumberFormatException e){ - logger.warn("Number format exception. Parsing '"+stringCharge+"' to short"); - } + } else { + logger.warn("? charge on atom {} in group {}", + chemCompAtom.getAtomId(), + thisChemComp.getId()); } - else{ - logger.warn("? charge on atom "+chemCompAtom.getAtom_id()+" in group "+thisChemComp.getId()); - } - } - else{ - logger.warn("Null charge on atom "+chemCompAtom.getAtom_id()+" in group "+thisChemComp.getId()); + } else { + logger.warn("Null charge on atom {} in group {}", + chemCompAtom.getAtomId(), + thisChemComp.getId()); } - if(atom!=null){ + if (atom != null) { atom.setCharge(shortCharge); } // Now do the same for alt locs for (Group altLoc : g.getAltLocs()) { - Atom altAtom = altLoc.getAtom(chemCompAtom.getAtom_id()); - if(altAtom!=null){ + Atom altAtom = altLoc.getAtom(chemCompAtom.getAtomId()); + if (altAtom != null) { altAtom.setCharge(shortCharge); } } } } - } } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java index 7cb62beffc..d6da021e63 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java @@ -593,10 +593,7 @@ else if (name.length()==1) public String toMMCIF() { - return CifFileConverter.toText(this.structure); } - - public static String toMMCIF(Chain chain, String authId, String asymId) { - return CifFileConverter.toText(chain, authId, asymId); + return CifFileConverter.toText(this.structure); } public static String toMMCIF(Chain chain) { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/PDBFileParser.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/PDBFileParser.java index 41014e1ec4..6200c90b1a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/PDBFileParser.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/PDBFileParser.java @@ -69,8 +69,8 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; +import org.biojava.nbio.structure.chem.ChemCompAtom; import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompAtom; import org.biojava.nbio.structure.io.util.PDBTemporaryStorageUtils.LinkRecord; import org.biojava.nbio.structure.secstruc.SecStrucInfo; import org.biojava.nbio.structure.secstruc.SecStrucType; @@ -1878,8 +1878,8 @@ private void pdb_ATOM_Handler(String line) { String elementSymbol = null; if (currentGroup.getChemComp() != null) { for (ChemCompAtom a : currentGroup.getChemComp().getAtoms()) { - if (a.getAtom_id().equals(fullname.trim())) { - elementSymbol = a.getType_symbol(); + if (a.getAtomId().equals(fullname.trim())) { + elementSymbol = a.getTypeSymbol(); break; } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/SeqRes2AtomAligner.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/SeqRes2AtomAligner.java index 580a8af158..0d677a4161 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/SeqRes2AtomAligner.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/SeqRes2AtomAligner.java @@ -60,9 +60,9 @@ import org.biojava.nbio.structure.NucleotideImpl; import org.biojava.nbio.structure.ResidueNumber; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.PolymerType; +import org.biojava.nbio.structure.chem.ResidueType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -410,7 +410,7 @@ public static String getFullAtomSequence(List groups, Map { - void consumeChemCompAtom(ChemCompAtom chemCompAtom); - - void consumeChemCompBond(ChemCompBond chemCompBond); - - void consumePdbxChemCompDescriptor(PdbxChemCompDescriptor pdbxChemCompDescriptor); -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java deleted file mode 100644 index f97a89d271..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.biojava.nbio.structure.io.cif; - -import org.biojava.nbio.structure.chem.ChemComp; -import org.biojava.nbio.structure.chem.ChemicalComponentDictionary; -import org.biojava.nbio.structure.chem.ResidueType; -import org.rcsb.cif.schema.mm.ChemCompAtom; -import org.rcsb.cif.schema.mm.ChemCompBond; -import org.rcsb.cif.schema.mm.PdbxChemCompDescriptor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ChemCompConsumerImpl implements ChemCompConsumer { - private static final Logger logger = LoggerFactory.getLogger(ChemCompConsumerImpl.class); - private ChemicalComponentDictionary dictionary; - private String latestChemCompId; - - public ChemCompConsumerImpl(){ - dictionary = new ChemicalComponentDictionary(); - } - - @Override - public void prepare() { - - } - - public ChemicalComponentDictionary getDictionary(){ - return dictionary; - } - - @Override - public void consumeChemCompAtom(ChemCompAtom chemCompAtom) { - dictionary.getChemComp(latestChemCompId).getAtoms().add(chemCompAtom); - } - - @Override - public void consumeChemCompBond(ChemCompBond chemCompBond) { - dictionary.getChemComp(latestChemCompId).getBonds().add(chemCompBond); - } - - @Override - public void consumePdbxChemCompDescriptor(PdbxChemCompDescriptor pdbxChemCompDescriptor) { - ChemComp cc = dictionary.getChemComp(latestChemCompId); - cc.getDescriptors().add(pdbxChemCompDescriptor); - } - - @Override - public void finish() { - - } - - @Override - public ChemComp getContainer() { - if (c.getId() == null) - logger.warn("chem comp ID == null " + c); - - latestChemCompId = c.getId(); - dictionary.addChemComp(c); - if (c.getResidueType() == ResidueType.nonPolymer) { - return; - } - - if (c.getResidueType() == ResidueType.saccharide) { - return; - } - - if (c.getResidueType() == ResidueType.dSaccharide) { - return; - } - } -} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java index 198f288305..d95f7b9422 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java @@ -1,53 +1,5 @@ package org.biojava.nbio.structure.io.cif; -import org.biojava.nbio.structure.chem.ChemCompAtom; -import org.biojava.nbio.structure.chem.ChemCompDescriptor; -import org.rcsb.cif.schema.mm.AtomSite; -import org.rcsb.cif.schema.mm.AtomSites; -import org.rcsb.cif.schema.mm.AuditAuthor; -import org.rcsb.cif.schema.mm.Cell; -import org.rcsb.cif.schema.mm.ChemComp; -import org.rcsb.cif.schema.mm.ChemCompBond; -import org.rcsb.cif.schema.mm.DatabasePDBRemark; -import org.rcsb.cif.schema.mm.DatabasePDBRev; -import org.rcsb.cif.schema.mm.DatabasePDBRevRecord; -import org.rcsb.cif.schema.mm.Entity; -import org.rcsb.cif.schema.mm.EntityPoly; -import org.rcsb.cif.schema.mm.EntityPolySeq; -import org.rcsb.cif.schema.mm.EntitySrcGen; -import org.rcsb.cif.schema.mm.EntitySrcNat; -import org.rcsb.cif.schema.mm.Exptl; -import org.rcsb.cif.schema.mm.PdbxAuditRevisionHistory; -import org.rcsb.cif.schema.mm.PdbxChemCompIdentifier; -import org.rcsb.cif.schema.mm.PdbxDatabaseStatus; -import org.rcsb.cif.schema.mm.PdbxEntityBranchDescriptor; -import org.rcsb.cif.schema.mm.PdbxEntitySrcSyn; -import org.rcsb.cif.schema.mm.PdbxMolecule; -import org.rcsb.cif.schema.mm.PdbxMoleculeFeatures; -import org.rcsb.cif.schema.mm.PdbxNonpolyScheme; -import org.rcsb.cif.schema.mm.PdbxReferenceEntityLink; -import org.rcsb.cif.schema.mm.PdbxReferenceEntityList; -import org.rcsb.cif.schema.mm.PdbxReferenceEntityPolyLink; -import org.rcsb.cif.schema.mm.PdbxStructAssembly; -import org.rcsb.cif.schema.mm.PdbxStructAssemblyGen; -import org.rcsb.cif.schema.mm.PdbxStructModResidue; -import org.rcsb.cif.schema.mm.PdbxStructOperList; -import org.rcsb.cif.schema.mm.Refine; -import org.rcsb.cif.schema.mm.Struct; -import org.rcsb.cif.schema.mm.StructAsym; -import org.rcsb.cif.schema.mm.StructConf; -import org.rcsb.cif.schema.mm.StructConn; -import org.rcsb.cif.schema.mm.StructConnType; -import org.rcsb.cif.schema.mm.StructKeywords; -import org.rcsb.cif.schema.mm.StructNcsOper; -import org.rcsb.cif.schema.mm.StructRef; -import org.rcsb.cif.schema.mm.StructRefSeq; -import org.rcsb.cif.schema.mm.StructRefSeqDif; -import org.rcsb.cif.schema.mm.StructSheetRange; -import org.rcsb.cif.schema.mm.StructSite; -import org.rcsb.cif.schema.mm.StructSiteGen; -import org.rcsb.cif.schema.mm.Symmetry; - /** * Defines a rather generic interface which allows to populate some data structure with data parsed from a CIF file. * diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java index 30e5682b69..2a53746297 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java @@ -226,7 +226,7 @@ public static String toText(Chain chain) { * @return the target */ public static CifFile toCifFile(Structure structure) { - return new AbstractCifFileSupplier().getStructure(structure); + return new StructureSupplierImpl().get(structure); } /** @@ -235,6 +235,6 @@ public static CifFile toCifFile(Structure structure) { * @return the target */ public static CifFile toCifFile(Chain chain) { - return new AbstractCifFileSupplier().getChain(chain); + return new ChainSupplierImpl().get(chain); } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java index d858536847..6a952029ee 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java @@ -24,7 +24,6 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.io.BondMaker; import org.biojava.nbio.structure.io.ChargeAdder; import org.biojava.nbio.structure.io.EntityFinder; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java index 09d8ca58a8..bc5c93cb2c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java @@ -50,9 +50,9 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.PolymerType; +import org.biojava.nbio.structure.chem.ResidueType; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; import org.biojava.nbio.structure.xtal.CrystalCell; @@ -69,7 +69,7 @@ * * @author Anthony Bradley * @since 5.0 - * + * */ public class MmtfStructureReader implements StructureAdapterInterface, Serializable { @@ -234,7 +234,7 @@ public void setGroupInfo(String groupName, int groupNumber, } atomsInGroup = new ArrayList<>(); ChemComp chemComp = new ChemComp(); - chemComp.setOne_letter_code(String.valueOf(singleLetterCode)); + chemComp.setOneLetterCode(String.valueOf(singleLetterCode)); chemComp.setType(chemCompType.toUpperCase()); chemComp.setResidueType(residueType); chemComp.setPolymerType(residueType.polymerType); @@ -333,14 +333,14 @@ public void setAtomInfo(String atomName, */ @Override public void setGroupBond(int indOne, int indTwo, int bondOrder) { - + // Get the atoms Atom atomOne = atomsInGroup.get(indOne); Atom atomTwo = atomsInGroup.get(indTwo); - + // set the new bond new BondImpl(atomOne, atomTwo, bondOrder); - + } /* (non-Javadoc) @@ -349,12 +349,12 @@ public void setGroupBond(int indOne, int indTwo, int bondOrder) { */ @Override public void setInterGroupBond(int indOne, int indTwo, int bondOrder) { - + // Get the atoms Atom atomOne = allAtoms[indOne]; Atom atomTwo = allAtoms[indTwo]; - - // set the new bond (this + + // set the new bond (this new BondImpl(atomOne, atomTwo, bondOrder); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java index 47e4fb3d69..c55e67da30 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureWriter.java @@ -33,7 +33,7 @@ import org.biojava.nbio.structure.PDBCrystallographicInfo; import org.biojava.nbio.structure.PDBHeader; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; +import org.biojava.nbio.structure.chem.ChemComp; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.rcsb.mmtf.api.StructureAdapterInterface; import org.rcsb.mmtf.dataholders.MmtfStructure; @@ -43,7 +43,7 @@ /** * Class to take Biojava structure data and covert to the DataApi for encoding. * Must implement all the functions in {@link StructureAdapterInterface}. - * + * * @author Anthony Bradley * @since 5.0 * @@ -103,8 +103,8 @@ public MmtfStructureWriter(Structure structure, StructureAdapterInterface dataTr insCode=MmtfStructure.UNAVAILABLE_CHAR_VALUE; } char singleLetterCode = 'X'; - if (chemComp.getOne_letter_code().length()==1){ - singleLetterCode = chemComp.getOne_letter_code().charAt(0); + if (chemComp.getOneLetterCode().length()==1){ + singleLetterCode = chemComp.getOneLetterCode().charAt(0); } mmtfDecoderInterface.setGroupInfo(group.getPDBName(), group.getResidueNumber().getSeqNum(), insCode.charValue(), chemComp.getType().toUpperCase(), atomsInGroup.size(), MmtfUtils.getNumBondsInGroup(atomsInGroup), singleLetterCode, diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index bbd34c9610..0a6cd9739c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -47,11 +47,11 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemCompTools; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.chem.ChemCompTools; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; import org.biojava.nbio.structure.secstruc.DSSPParser; @@ -499,12 +499,12 @@ public static void insertSeqResGroup(Chain chain, Group group, int sequenceIndex * @param sequence the sequence of the construct */ public static void addSeqRes(Chain modelChain, String sequence) { - + List seqResGroups = modelChain.getSeqResGroups(); GroupType chainType = getChainType(modelChain.getAtomGroups()); - + for(int i=0; i i) { @@ -513,7 +513,7 @@ public static void addSeqRes(Chain modelChain, String sequence) { if(group!=null){ continue; } - + group = getSeqResGroup(singleLetterCode, chainType); addGroupAtId(seqResGroups, group, i); } From 1b164a99720e8b48c928883bb2d471dd994ea46e Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Wed, 20 Jan 2021 15:35:47 -0800 Subject: [PATCH 187/769] compiling --- .../nbio/structure/test/MMcifTest.java | 295 ------------- .../structure/test/StructureToolsTest.java | 6 +- .../biojava/nbio/structure/test/Test1a4w.java | 17 +- .../cif/CifFileSupplierIntegrationTest.java | 10 +- .../nbio/protmod/structure/StructureUtil.java | 18 +- .../src/main/java/demo/DemoCE.java | 4 +- .../structure/gui/util/PDBUploadPanel.java | 3 +- .../main/java/demo/ChemCompDistribution.java | 5 +- .../java/demo/DemoChangeChemCompProvider.java | 4 + .../java/demo/DemoMmcifToPdbConverter.java | 11 +- .../org/biojava/nbio/structure/ChainImpl.java | 1 + .../biojava/nbio/structure/HetatomImpl.java | 7 +- .../biojava/nbio/structure/URLIdentifier.java | 4 +- .../structure/chem/AllChemCompProvider.java | 167 ++++++++ .../biojava/nbio/structure/chem/ChemComp.java | 12 +- .../nbio/structure/chem/ChemCompAtom.java | 54 +-- .../nbio/structure/chem/ChemCompBond.java | 6 +- .../structure/chem/ChemCompGroupFactory.java | 129 ++++++ .../nbio/structure/chem/ChemCompProvider.java | 15 + .../nbio/structure/chem/ChemCompTools.java | 24 +- .../chem/ChemicalComponentDictionary.java | 6 +- .../chem/DownloadChemCompProvider.java | 403 ++++++++++++++++++ .../structure/chem/MetalBondDistance.java | 56 +++ .../chem/ReducedChemCompProvider.java | 58 +++ .../structure/chem/ZipChemCompProvider.java | 275 ++++++++++++ .../structure/contact/StructureInterface.java | 69 +-- .../nbio/structure/io/BcifFileReader.java | 4 +- .../biojava/nbio/structure/io/BondMaker.java | 1 + .../nbio/structure/io/ChargeAdder.java | 22 +- .../nbio/structure/io/CifFileReader.java | 4 +- .../nbio/structure/io/FileConvert.java | 6 +- .../nbio/structure/io/PDBFileParser.java | 4 +- .../structure/io/cif/ChemCompConsumer.java | 16 + .../io/cif/ChemCompConsumerImpl.java | 108 +++++ .../structure/io/cif/ChemCompConverter.java | 79 ++++ .../structure/io/cif/MetalBondConsumer.java | 11 + .../io/cif/MetalBondConsumerImpl.java | 55 +++ .../structure/io/cif/MetalBondConverter.java | 60 +++ .../io/cif/StructureConsumerImpl.java | 1 + ...Converter.java => StructureConverter.java} | 8 +- .../nbio/structure/io/mmtf/MmtfUtils.java | 4 +- .../biojava/nbio/structure/ChemCompTest.java | 24 +- .../nbio/structure/PdbFileFormat30Test.java | 4 +- .../org/biojava/nbio/structure/Test4hhb.java | 12 +- .../biojava/nbio/structure/TestAltLocs.java | 72 +--- .../biojava/nbio/structure/TestAtomCache.java | 3 +- .../org/biojava/nbio/structure/TestBond.java | 4 +- .../TestDownloadChemCompProvider.java | 4 +- .../nbio/structure/TestNucleotides.java | 8 +- .../structure/align/util/AtomCacheTest.java | 9 +- .../nbio/structure/asa/TestAsaCalc.java | 6 +- .../structure/io/TestDifficultMmCIFFiles.java | 18 +- .../nbio/structure/io/TestHeaderOnly.java | 18 +- .../nbio/structure/io/TestMMCIFWriting.java | 61 +-- .../structure/io/TestMmCIFSpecialCases.java | 82 ---- .../structure/io/TestNonDepositedFiles.java | 37 +- .../structure/io/TestParseMmCIFLigands.java | 6 +- .../io/mmcif/TestChemCompProvider.java | 2 + .../io/mmcif/TestEntityNameAndType.java | 2 + .../structure/io/mmtf/TestBondFinding.java | 4 +- .../structure/io/mmtf/TestMmtfRoundTrip.java | 26 +- .../io/mmtf/TestMmtfStructureReader.java | 36 +- .../io/mmtf/TestMmtfStructureWriter.java | 4 +- .../structure/redmine/Test1DARSeqAlign.java | 8 +- .../structure/test/util/GlobalsHelper.java | 6 +- 65 files changed, 1689 insertions(+), 809 deletions(-) delete mode 100644 biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/MMcifTest.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompGroupFactory.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/MetalBondDistance.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ZipChemCompProvider.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumer.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConverter.java rename biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/{CifFileConverter.java => StructureConverter.java} (97%) delete mode 100644 biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMmCIFSpecialCases.java diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/MMcifTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/MMcifTest.java deleted file mode 100644 index 4947e0077a..0000000000 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/MMcifTest.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Apr 26, 2008 - */ -package org.biojava.nbio.structure.test; - -import org.biojava.nbio.structure.*; -import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.PDBFileParser; -import org.biojava.nbio.structure.io.mmcif.MMcifParser; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; -import org.junit.Test; -import static org.junit.Assert.*; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.List; - -public class MMcifTest { - - private static boolean headerOnly; - - @Test - public void testLoad() throws IOException { - - headerOnly = false; - - doTestLoad(); - - } - - @Test - public void testLoadHeaderOnly() throws IOException { - - headerOnly = true; - - doTestLoad(); - - } - - private void doTestLoad() throws IOException { - // a structure with microheterogeneity - //comparePDB2cif("2CI1","A"); - - // test a simple protein - comparePDB2cif("5pti","A"); - - // test a protein with modified residues - comparePDB2cif("1a4w","L"); - comparePDB2cif("1a4w","H"); - comparePDB2cif("1a4w","I"); - //non-standard encoded amino acid - comparePDB2cif("1fdo","A"); - - // test a DNA binding protein - comparePDB2cif("1j59","A"); - //comparePDB2cif("1j59","B"); - //comparePDB2cif("1j59","C"); - //comparePDB2cif("1j59","D"); - comparePDB2cif("1j59","E"); - //comparePDB2cif("1j59","F"); - - // test a NMR protein - comparePDB2cif("2kc9","A"); - } - - private void comparePDB2cif(String id, String chainId) throws IOException { - String fileName = "/"+id+".cif"; - InputStream inStream = this.getClass().getResourceAsStream(fileName); - assertNotNull("Could not find file " + fileName + ". Config problem?" , inStream); - - MMcifParser parser = new SimpleMMcifParser(); - - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - FileParsingParameters params = new FileParsingParameters(); - params.setHeaderOnly(headerOnly); - consumer.setFileParsingParameters(params); - - - parser.addMMcifConsumer(consumer); - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - // remove to avoid memory leaks - parser.clearConsumers(); - Structure cifStructure = consumer.getStructure(); - assertNotNull(cifStructure); - - - // load the PDB file via the PDB parser - Structure pdbStructure = null; - InputStream pinStream = this.getClass().getResourceAsStream("/"+id+".pdb"); - assertNotNull(inStream); - - PDBFileParser pdbpars = new PDBFileParser(); - pdbpars.setFileParsingParameters(params); - - - pdbStructure = pdbpars.parsePDBFile(pinStream) ; - - - assertNotNull(pdbStructure); - - // now compare the results - - - // chech NMR data - assertEquals(id + ": the isNMR flag is not the same!", pdbStructure.isNmr(), cifStructure.isNmr()); - - if ( pdbStructure.isNmr()){ - assertEquals(id + ": the nr of NMR models is not the same!", pdbStructure.nrModels(), pdbStructure.nrModels()); - checkNMR(pdbStructure); - checkNMR(cifStructure); - } - - //System.out.println(pdbStructure); - //System.out.println(cifStructure); - - // compare amino acids in chain 1: - Chain a_pdb = pdbStructure.getPolyChainByPDB(chainId); - Chain a_cif = cifStructure.getPolyChainByPDB(chainId); - //System.out.println(a_pdb.getAtomGroups()); - - //System.out.println(id + "_" + chainName + " pdb atom groups: " + a_pdb.getAtomGroups(GroupType.AMINOACID).size()); - //System.out.println(id + "_" + chainName + " cif atom groups: " + a_cif.getAtomGroups(GroupType.AMINOACID).size()); - - //for (Group g: a_cif.getAtomGroups()){ - // System.out.println(g); - //} - //System.out.println("--"); - String pdb_SEQseq = a_pdb.getSeqResSequence(); - - String cif_SEQseq = a_cif.getSeqResSequence(); - - // System.out.println(id + "_" + chainName + " pdbSEQ: " + pdb_SEQseq); - // System.out.println(id + "_" + chainName + " cifSEQ: " + cif_SEQseq); - - assertEquals(id + ": the SEQRES sequences don't match!", pdb_SEQseq,cif_SEQseq); - - assertEquals(id + ": The nr of ATOM groups does not match!",a_pdb.getAtomGroups(GroupType.AMINOACID).size(),a_cif.getAtomGroups(GroupType.AMINOACID).size() ); - - // actually this check not necessarily works, since there can be waters in PDB that we don;t deal with yet in cif... - //assertEquals("the nr of ATOM record groups is not the same!" , a_pdb.getAtomLength(),a_cif.getAtomLength()); - for (int i = 0 ; i < a_pdb.getAtomGroups(GroupType.AMINOACID).size(); i++){ - Group gp = a_pdb.getAtomGroups(GroupType.AMINOACID).get(i); - - List cifGroups = a_cif.getAtomGroups(GroupType.AMINOACID); - Group gc = cifGroups.get(i); - checkGroups(gp, gc); - } - - - - String pdb_seq = a_pdb.getAtomSequence(); - String cif_seq = a_cif.getAtomSequence(); - - //System.out.println(pdb_seq); - //System.out.println(cif_seq); - - assertEquals("the sequences obtained from PDB and mmCif don't match!",pdb_seq, cif_seq); - - List pdb_dbrefs= pdbStructure.getDBRefs(); - List cif_dbrefs= cifStructure.getDBRefs(); - - assertEquals("nr of DBrefs found does not match!", pdb_dbrefs.size(),cif_dbrefs.size()); - - DBRef p = pdb_dbrefs.get(0); - DBRef c = cif_dbrefs.get(0); - - //System.out.println(p.toPDB()); - //System.out.println(c.toPDB()); - String pdb_dbref = p.toPDB(); - String cif_dbref = c.toPDB(); - assertEquals("DBRef is not equal",pdb_dbref,cif_dbref); - - PDBHeader h1 = pdbStructure.getPDBHeader(); - PDBHeader h2 = cifStructure.getPDBHeader(); - - //compareString(h1.toPDB() ,h2.toPDB()); - //System.out.println(h1.toPDB()); - //System.out.println(h2.toPDB()); - if ( ! h1.toPDB().toUpperCase().equals(h2.toPDB().toUpperCase()) ){ - System.err.println(h1.toPDB()); - System.err.println(h2.toPDB()); - compareString(h1.toPDB(), h2.toPDB()); - } - assertEquals("the PDBHeader.toPDB representation is not equivalent", h1.toPDB().toUpperCase(),h2.toPDB().toUpperCase()); - - // and the ultimate test! - // but we are not there yet... - // TODO: still need to parse SSBOND equivalent info from cif files... - //assertEquals("the Structure.toPDB representation is not equivalent", pdbStructure.toPDB(),cifStructure.toPDB()); - - - - } - - private void checkGroups(Group g1, Group g2){ - - //System.out.print("comparing " +g1 + " " + g2); - String pdbId1 = g1.getChain().getStructure().getPDBCode(); - String pdbId2 = g1.getChain().getStructure().getPDBCode(); - assertEquals(pdbId1, pdbId2); - - assertEquals(g1.getType(),g2.getType()); - assertEquals(g1.getResidueNumber().getSeqNum(),g2.getResidueNumber().getSeqNum()); - assertEquals(g1.getResidueNumber().getInsCode(),g2.getResidueNumber().getInsCode()); - assertEquals(g1.getPDBName(),g2.getPDBName()); - assertEquals(g1.has3D(),g2.has3D()); - - assertEquals(g1.hasAltLoc(), g2.hasAltLoc()); - - assertEquals(pdbId1 + ":" + g1 + " - " + pdbId2+":"+ g2,g1.getAltLocs().size(), g2.getAltLocs().size()); - - assertEquals(pdbId1 + ":" + g1 + " - " + pdbId2+":"+ g2 , g1.getAtoms().size(), g2.getAtoms().size()); - if ( g1.has3D()){ - - Atom a1 = g1.getAtom(0); - Atom a2 = g2.getAtom(0); - if ( a1 == null) - fail("could not get atom for group " + g1); - if (a2 == null) - fail("could not get atom for group " + g2); - assertEquals(a1.getX(),a2.getX(), 0.0001); - assertEquals(a1.getOccupancy(),a2.getOccupancy(), 0.0001); - assertEquals(a1.getTempFactor(),a2.getTempFactor(), 0.0001); - assertEquals(a1.getName(),a2.getName()); - - - } - //System.out.println(" ... done"); - - } - - private void checkNMR(Structure s){ - assertTrue(s.isNmr()); - - int models = s.nrModels(); - assertTrue(models > 0); - - List model0 = s.getModel(0); - - // compare with all others - for (int i = 1 ; i < models; i++){ - List modelX = s.getModel(i); - - assertEquals(model0.size(),modelX.size()); - - // compare lengths: - for (int j=0 ; j< model0.size();j++){ - Chain c1 = model0.get(j); - Chain cx = modelX.get(j); - assertEquals(c1.getAtomLength(),cx.getAtomLength()); - // can;t compare seq res, since this is only done for 1st... - //assertEquals("c1.getSeqResLength(),cx.getSeqResLength()); - assertEquals(c1.getAtomSequence(),cx.getAtomSequence()); - assertEquals(c1.getAtomGroups(GroupType.AMINOACID).size(),cx.getAtomGroups(GroupType.AMINOACID).size()); - assertEquals(c1.getAtomGroups(GroupType.NUCLEOTIDE).size(),cx.getAtomGroups(GroupType.NUCLEOTIDE).size()); - assertEquals(c1.getAtomGroups(GroupType.HETATM).size(),cx.getAtomGroups(GroupType.HETATM).size()); - } - - - } - } - - private void compareString(String t, String pdb){ - for (int i =0 ; i < t.length() ; i++){ - System.out.println(">"+t.charAt(i)+":"+ pdb.charAt(i)+"<"); - if ( Character.toUpperCase(t.charAt(i)) != Character.toUpperCase(pdb.charAt(i))){ - System.out.println("Mismatch!"); - break; - } - } - } - - -} diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java index b2ae39611c..170694a6e2 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java @@ -24,11 +24,11 @@ import org.biojava.nbio.structure.*; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemCompProvider; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileParser; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.ChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import org.junit.Before; import org.junit.Test; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1a4w.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1a4w.java index 870c74a13a..ba6266cb2b 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1a4w.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1a4w.java @@ -26,14 +26,13 @@ import org.biojava.nbio.structure.*; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.io.CifFileReader; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileParser; -import org.biojava.nbio.structure.io.mmcif.MMcifParser; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.rcsb.cif.model.CifFile; import java.io.IOException; import java.io.InputStream; @@ -87,17 +86,11 @@ public void test1a4wPDBFile() throws IOException InputStream inStream = this.getClass().getResourceAsStream("/1a4w.cif"); Assert.assertNotNull(inStream); - MMcifParser pdbpars = new SimpleMMcifParser(); - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); - consumer.setFileParsingParameters(params); - pdbpars.addMMcifConsumer(consumer); - - pdbpars.parse(inStream) ; - structure2 = consumer.getStructure(); - - + CifFileReader reader = new CifFileReader(); + reader.setFileParsingParameters(params); + structure2 = reader.getStructure(inStream); Assert.assertNotNull(structure2); diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/cif/CifFileSupplierIntegrationTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/cif/CifFileSupplierIntegrationTest.java index 03e2f6f060..8e59c8a931 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/cif/CifFileSupplierIntegrationTest.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/cif/CifFileSupplierIntegrationTest.java @@ -12,7 +12,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.io.cif.CifFileConverter; +import org.biojava.nbio.structure.io.cif.StructureConverter; import org.junit.Test; import java.io.ByteArrayInputStream; @@ -49,10 +49,10 @@ public void test1A2C() throws IOException { private static void testRoundTrip(String pdbId) throws IOException { URL url = new URL("https://files.rcsb.org/download/" + pdbId + ".cif"); - Structure originalStruct = CifFileConverter.fromURL(url); + Structure originalStruct = StructureConverter.fromURL(url); - InputStream inputStream = new ByteArrayInputStream(CifFileConverter.toText(originalStruct).getBytes()); - Structure readStruct = CifFileConverter.fromInputStream(inputStream); + InputStream inputStream = new ByteArrayInputStream(StructureConverter.toText(originalStruct).getBytes()); + Structure readStruct = StructureConverter.fromInputStream(inputStream); assertNotNull(readStruct); assertEquals(originalStruct.getChains().size(), readStruct.getChains().size()); @@ -113,7 +113,7 @@ private static void testRoundTrip(String pdbId) throws IOException { @Test public void testBiounitWriting() throws IOException { Structure s = createDummyStructure(); - String mmcif = CifFileConverter.toText(s); + String mmcif = StructureConverter.toText(s); String[] lines = mmcif.split("\n"); long atomLines = Arrays.stream(lines).filter(l -> l.startsWith("ATOM")).count(); assertNotNull(mmcif); diff --git a/biojava-modfinder/src/main/java/org/biojava/nbio/protmod/structure/StructureUtil.java b/biojava-modfinder/src/main/java/org/biojava/nbio/protmod/structure/StructureUtil.java index 0245018ca2..4842864b2d 100644 --- a/biojava-modfinder/src/main/java/org/biojava/nbio/protmod/structure/StructureUtil.java +++ b/biojava-modfinder/src/main/java/org/biojava/nbio/protmod/structure/StructureUtil.java @@ -25,8 +25,8 @@ package org.biojava.nbio.protmod.structure; import org.biojava.nbio.structure.*; -import org.biojava.nbio.structure.io.mmcif.MetalBondParser; -import org.biojava.nbio.structure.io.mmcif.chem.MetalBondDistance; +import org.biojava.nbio.structure.chem.MetalBondDistance; +import org.biojava.nbio.structure.io.cif.MetalBondConverter; import java.util.ArrayList; import java.util.Collections; @@ -279,18 +279,14 @@ public static Atom[] findLinkage(final Group group1, final Group group2, } private static boolean hasMetalBond(Atom a1, Atom a2, MetalBondDistance definition) { - - double distance = Calc.getDistance(a1,a2); - - Float min = definition.getLowerLimit(); - Float max = definition.getUpperLimit(); - - return ( min < distance && max > distance); - + double distance = Calc.getDistance(a1, a2); + float min = definition.getLowerLimit(); + float max = definition.getUpperLimit(); + return (min < distance && max > distance); } private static MetalBondDistance getMetalDistanceCutoff(String name1, String name2) { - Map> defs= MetalBondParser.getMetalBondDefinitions(); + Map> defs = MetalBondConverter.getMetalBondDefinitions(); List distances = defs.get(name1); diff --git a/biojava-structure-gui/src/main/java/demo/DemoCE.java b/biojava-structure-gui/src/main/java/demo/DemoCE.java index 5e2bb0aabb..88c5c8f307 100644 --- a/biojava-structure-gui/src/main/java/demo/DemoCE.java +++ b/biojava-structure-gui/src/main/java/demo/DemoCE.java @@ -36,8 +36,8 @@ import org.biojava.nbio.structure.align.model.AfpChainWriter; import org.biojava.nbio.structure.align.util.AFPChainScorer; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; public class DemoCE { diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/gui/util/PDBUploadPanel.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/gui/util/PDBUploadPanel.java index 92efbeaf36..0e36624830 100644 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/gui/util/PDBUploadPanel.java +++ b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/gui/util/PDBUploadPanel.java @@ -26,6 +26,7 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.UserConfiguration; +import org.biojava.nbio.structure.io.CifFileReader; import org.biojava.nbio.structure.io.PDBFileReader; import org.biojava.nbio.structure.io.StructureIOFile; import org.slf4j.Logger; @@ -133,7 +134,7 @@ private Structure getStructure(JTextField filePath,JTextField chainId) throws St if ( fileFormat.equals(UserConfiguration.PDB_FORMAT)){ reader = new PDBFileReader(); } else if ( fileFormat.equals(UserConfiguration.MMCIF_FORMAT)){ - reader = new MMCIFFileReader(); + reader = new CifFileReader(); } else { throw new StructureException("Unkown file format " + fileFormat); } diff --git a/biojava-structure/src/main/java/demo/ChemCompDistribution.java b/biojava-structure/src/main/java/demo/ChemCompDistribution.java index 7e4e847e52..a1ae74166b 100644 --- a/biojava-structure/src/main/java/demo/ChemCompDistribution.java +++ b/biojava-structure/src/main/java/demo/ChemCompDistribution.java @@ -20,15 +20,12 @@ */ package demo; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; public class ChemCompDistribution { - public static void main(String[] args){ - DownloadChemCompProvider c = new DownloadChemCompProvider(); c.setDownloadAll(true); c.checkDoFirstInstall(); - } } diff --git a/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java b/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java index 1285d8488b..b8e4eb5430 100644 --- a/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java +++ b/biojava-structure/src/main/java/demo/DemoChangeChemCompProvider.java @@ -23,6 +23,10 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.chem.AllChemCompProvider; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemCompProvider; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileReader; diff --git a/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java b/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java index bd84ae8f1e..67de1031c0 100644 --- a/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java +++ b/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java @@ -23,12 +23,10 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.io.cif.StructureConverter; -import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStreamReader; import java.io.PrintWriter; /** @@ -44,13 +42,8 @@ public static void main(String[] args) throws Exception { } public static void convert(File inFile, File outFile) throws IOException { - MMcifParser parser = new SimpleMMcifParser(); - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - parser.addMMcifConsumer(consumer); - parser.parse(new BufferedReader(new InputStreamReader(new FileInputStream(inFile)))); - // now get the protein structure. - Structure cifStructure = consumer.getStructure(); + Structure cifStructure = StructureConverter.fromPath(inFile.toPath()); // and write it out as PDB format PrintWriter pr = new PrintWriter(outFile); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java index 8f548be835..5a395ee417 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/ChainImpl.java @@ -25,6 +25,7 @@ import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.io.FileConvert; import org.biojava.nbio.core.exceptions.CompoundNotFoundException; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java index c9c05a704c..27a7e6a3a5 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java @@ -24,6 +24,7 @@ package org.biojava.nbio.structure; import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.chem.ResidueType; import org.biojava.nbio.structure.io.GroupToSDF; @@ -466,9 +467,11 @@ public void setId(long id) { @Override public ChemComp getChemComp() { - if ( chemComp == null ) { + if (chemComp == null) { chemComp = ChemCompGroupFactory.getChemComp(pdb_name); - if (chemComp == null) logger.info("getChemComp: " + pdb_name); + if (chemComp == null) { + logger.info("getChemComp: {}", pdb_name); + } } return chemComp; } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java index 91cccd6a38..a36e93b508 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java @@ -23,7 +23,7 @@ import org.biojava.nbio.structure.StructureIO.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.PDBFileReader; -import org.biojava.nbio.structure.io.cif.CifFileConverter; +import org.biojava.nbio.structure.io.cif.StructureConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -153,7 +153,7 @@ public Structure loadStructure(AtomCache cache) throws StructureException, switch(format) { case CIF: - return CifFileConverter.fromURL(url); + return StructureConverter.fromURL(url); default: case PDB: // pdb file based parsing diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java new file mode 100644 index 0000000000..77881edb44 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/AllChemCompProvider.java @@ -0,0 +1,167 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.structure.align.util.UserConfiguration; +import org.biojava.nbio.structure.io.LocalPDBDirectory; +import org.biojava.nbio.structure.io.cif.ChemCompConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Paths; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * A ChemComp provider that downloads and caches the components.cif file from the wwPDB site. It then loads all chemical + * components at startup and keeps them in memory. This provider is not used as a default since it is slower at startup + * and requires more memory than the {@link DownloadChemCompProvider} that is used by default. + * + * @author Andreas Prlic + */ +public class AllChemCompProvider implements ChemCompProvider, Runnable { + private static final Logger logger = LoggerFactory.getLogger(AllChemCompProvider.class); + public static final String COMPONENTS_FILE_LOCATION = "pub/pdb/data/monomers/components.cif.gz"; + private static String path; + private static String serverName; + + // there will be only one copy of the dictionary across all instances + // to reduce memory impact + static ChemicalComponentDictionary dict; + + // flags to make sure there is only one thread running that is loading the dictionary + static AtomicBoolean loading = new AtomicBoolean(false); + static AtomicBoolean isInitialized = new AtomicBoolean(false); + + public AllChemCompProvider() { + if (loading.get()) { + logger.warn("other thread is already loading all chemcomps, no need to init twice"); + return; + } + if (isInitialized.get()) { + return; + } + + loading.set(true); + + Thread t = new Thread(this); + t.start(); + } + + /** + * make sure all paths are initialized correctly + */ + private static void initPath() { + if (path == null) { + UserConfiguration config = new UserConfiguration(); + path = config.getCacheFilePath(); + } + } + + private static void initServerName() { + if (serverName == null) { + serverName = LocalPDBDirectory.getServerName(); + } + } + + private void ensureFileExists() { + String fileName = getLocalFileName(); + File f = new File(fileName); + + if (!f.exists()) { + try { + downloadFile(); + } catch (IOException e) { + logger.error("Caught IOException", e); + } + } + } + + /** + * Downloads the components.cif.gz file from the wwPDB site. + */ + public static void downloadFile() throws IOException { + initPath(); + initServerName(); + String localName = getLocalFileName(); + String u = serverName + "/" + COMPONENTS_FILE_LOCATION; + downloadFileFromRemote(new URL(u), new File(localName)); + } + + private static void downloadFileFromRemote(URL remoteURL, File localFile) throws IOException { + logger.info("Downloading {} to: {}", remoteURL, localFile); + FileOutputStream out = new FileOutputStream(localFile); + + InputStream in = remoteURL.openStream(); + byte[] buf = new byte[4 * 1024]; // 4K buffer + int bytesRead; + while ((bytesRead = in.read(buf)) != -1) { + out.write(buf, 0, bytesRead); + } + in.close(); + out.close(); + } + + private static String getLocalFileName(){ + File dir = new File(path, DownloadChemCompProvider.CHEM_COMP_CACHE_DIRECTORY); + + if (!dir.exists()) { + logger.info("Creating directory {}", dir.toString()); + dir.mkdir(); + } + + return new File(dir, "components.cif.gz").toString(); + } + + /** + * Load all {@link ChemComp} definitions into memory. + */ + private void loadAllChemComps() throws IOException { + String fileName = getLocalFileName(); + logger.debug("Loading {}", fileName); + dict = ChemCompConverter.fromPath(Paths.get(fileName)); + } + + /** + * {@inheritDoc} + */ + @Override + public ChemComp getChemComp(String recordName) { + while (loading.get()) { + // another thread is still initializing the definitions + try { + // wait half a second + Thread.sleep(500); + } catch (InterruptedException e) { + logger.error("Interrepted thread while waiting: {}", e.getMessage()); + //e.printStackTrace(); + } + } + + return dict.getChemComp(recordName); + } + + /** + * Do the actual loading of the dictionary in a thread. + */ + @Override + public void run() { + long timeS = System.currentTimeMillis(); + initPath(); + ensureFileExists(); + + try { + loadAllChemComps(); + long timeE = System.currentTimeMillis(); + logger.debug("Time to init chem comp dictionary: {} sec.", (timeE - timeS) / 1000); + } catch (IOException e) { + logger.error("Could not load chemical components definition file {}. Error: {}", getLocalFileName(), e.getMessage()); + } finally { + loading.set(false); + isInitialized.set(true); + } + } +} + diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java index 52aa39c604..7109d60204 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java @@ -19,14 +19,14 @@ public class ChemComp implements CifBean, Compa private String formula; private String monNstdParentCompId; private String pdbxSynonyms; - private String pdbxFormalCharge; + private int pdbxFormalCharge; private String pdbxInitialDate; private String pdbxModifiedDate; private String pdbxAmbiguousFlag; private String pdbxReleaseStatus; private String pdbxReplacedBy; private String pdbxReplaces; - private String formulaWeight; + private double formulaWeight; private String oneLetterCode; private String threeLetterCode; private String pdbxModelCoordinatesDetails; @@ -159,11 +159,11 @@ public void setPdbxSynonyms(String pdbxSynonyms) { this.pdbxSynonyms = pdbxSynonyms; } - public String getPdbxFormalCharge() { + public int getPdbxFormalCharge() { return pdbxFormalCharge; } - public void setPdbxFormalCharge(String pdbxFormalCharge) { + public void setPdbxFormalCharge(int pdbxFormalCharge) { this.pdbxFormalCharge = pdbxFormalCharge; } @@ -215,11 +215,11 @@ public void setPdbxReplaces(String pdbxReplaces) { this.pdbxReplaces = pdbxReplaces; } - public String getFormulaWeight() { + public double getFormulaWeight() { return formulaWeight; } - public void setFormulaWeight(String formulaWeight) { + public void setFormulaWeight(double formulaWeight) { this.formulaWeight = formulaWeight; } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java index cad290820e..d87a51e720 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java @@ -8,24 +8,24 @@ public class ChemCompAtom implements CifBean cache = new SoftHashMap<>(0); + + public static ChemComp getChemComp(String recordName) { + recordName = recordName.toUpperCase().trim(); + + // we are using the cache, to avoid hitting the file system too often. + ChemComp cc = cache.get(recordName); + if (cc != null) { + logger.debug("Chem comp {} read from cache", cc.getThreeLetterCode()); + return cc; + } + + // not cached, get the chem comp from the provider + logger.debug("Chem comp {} read from provider {}", recordName, chemCompProvider.getClass().getCanonicalName()); + cc = chemCompProvider.getChemComp(recordName); + + // Note that this also caches null or empty responses + cache.put(recordName, cc); + return cc; + } + + /** + * The new ChemCompProvider will be set in the static variable, + * so this provider will be used from now on until it is changed + * again. Note that this change can have unexpected behavior of + * code executed afterwards. + *

      + * Changing the provider also resets the cache, so any groups + * previously accessed will be reread or re-downloaded. + * + * @param provider + */ + public static void setChemCompProvider(ChemCompProvider provider) { + logger.debug("Setting new chem comp provider to {}", provider.getClass().getCanonicalName()); + chemCompProvider = provider; + // clear cache + cache.clear(); + } + + public static ChemCompProvider getChemCompProvider(){ + return chemCompProvider; + } + + /** + * Force the in-memory cache to be reset. + * + * Note that the ChemCompProvider may have additional memory or disk caches that need to be cleared too. + */ + public static void clearCache() { + cache.clear(); + } + + public static Group getGroupFromChemCompDictionary(String recordName) { + // make sure we work with upper case records + recordName = recordName.toUpperCase().trim(); + Group g; + ChemComp cc = getChemComp(recordName); + + if (cc == null) { + return null; + } + + if (PolymerType.PROTEIN_ONLY.contains(cc.getPolymerType())) { + AminoAcid aa = new AminoAcidImpl(); + + String one_letter = cc.getOneLetterCode(); + if (one_letter == null || one_letter.equals("X") || one_letter.equals("?") || one_letter.length() == 0) { + String parent = cc.getMonNstdParentCompId(); + if (parent != null && parent.length() == 3) { + String parentid = cc.getMonNstdParentCompId(); + ChemComp parentCC = getChemComp(parentid); + one_letter = parentCC.getOneLetterCode(); + } + } + + if (one_letter == null || one_letter.length() == 0 || one_letter.equals("?")) { + // e.g. problem with PRR, which probably should have a parent of ALA, but as of 20110127 does not. + logger.warn("Problem with chemical component: {} Did not find one letter code! Setting it to 'X'", + recordName); + aa.setAminoType('X'); + } else { + aa.setAminoType(one_letter.charAt(0)); + } + + g = aa; + } else if (PolymerType.POLYNUCLEOTIDE_ONLY.contains(cc.getPolymerType())) { + g = new NucleotideImpl(); + } else { + g = new HetatomImpl(); + } + + g.setChemComp(cc); + return g; + } + + public static String getOneLetterCode(ChemComp cc) { + String oneLetter = cc.getOneLetterCode(); + if (oneLetter == null || oneLetter.equals("X") || oneLetter.equals("?")) { + String parentId = cc.getMonNstdParentCompId(); + if (parentId == null) { + return oneLetter; + } + // cases like OIM have multiple parents (comma separated), we shouldn't try grab a chemcomp for those strings + if (parentId.length() > 3) { + return oneLetter; + } + ChemComp parentCC = ChemCompGroupFactory.getChemComp(parentId); + if (parentCC == null) { + return oneLetter; + } + oneLetter = parentCC.getOneLetterCode(); + } + return oneLetter; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java new file mode 100644 index 0000000000..936f5ef8cf --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompProvider.java @@ -0,0 +1,15 @@ +package org.biojava.nbio.structure.chem; + +/** + * Interface that is implemented by all classes that can provide {@link ChemComp} definitions. + * @author Andreas Prlic + * @since 3.0 + */ +public interface ChemCompProvider { + /** + * Returns a new instance of a chemical component definition. + * @param recordName the ID of the {@link ChemComp} + * @return a new {@link ChemComp} definition. + */ + ChemComp getChemComp(String recordName); +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java index 6b8f74dbd8..929223040a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompTools.java @@ -78,21 +78,21 @@ public class ChemCompTools { AMINO_ACID_LOOKUP_1TO3 = Collections.unmodifiableMap(Collections.synchronizedMap(bar)); foo = new HashMap<>(); - foo.put("DA",'A'); - foo.put("DC",'C'); - foo.put("DG",'G'); - foo.put("DI",'I'); - foo.put("DU",'U'); - foo.put("DT",'T'); + foo.put("DA", 'A'); + foo.put("DC", 'C'); + foo.put("DG", 'G'); + foo.put("DI", 'I'); + foo.put("DU", 'U'); + foo.put("DT", 'T'); DNA_LOOKUP_2TO1 = Collections.unmodifiableMap((Collections.synchronizedMap(foo))); bar = new HashMap<>(); - bar.put('A',"DA"); - bar.put('C',"DC"); - bar.put('G',"DG"); - bar.put('I',"DI"); - bar.put('U',"DU"); - bar.put('T',"DT"); + bar.put('A', "DA"); + bar.put('C', "DC"); + bar.put('G', "DG"); + bar.put('I', "DI"); + bar.put('U', "DU"); + bar.put('T', "DT"); DNA_LOOKUP_1TO2 = Collections.unmodifiableMap(Collections.synchronizedMap(bar)); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java index 63b38ed2e2..c191e67118 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemicalComponentDictionary.java @@ -12,9 +12,9 @@ * */ public class ChemicalComponentDictionary { - private Map dictionary; - private Map replaces; - private Map isReplacedBy; + private final Map dictionary; + private final Map replaces; + private final Map isReplacedBy; public ChemicalComponentDictionary(){ dictionary = new HashMap<>(); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java new file mode 100644 index 0000000000..71a17b7292 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java @@ -0,0 +1,403 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.core.util.InputStreamProvider; +import org.biojava.nbio.structure.align.util.URLConnectionTools; +import org.biojava.nbio.structure.align.util.UserConfiguration; +import org.biojava.nbio.structure.io.LocalPDBDirectory; +import org.biojava.nbio.structure.io.cif.ChemCompConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.zip.GZIPOutputStream; + +/** + * This provider of chemical components can download and cache chemical component definition files from the RCSB PDB web + * site. It is the default way to access these definitions. If this provider is called he first time, it will download + * and install all chemical component definitions in a local directory. Once the definition files have been installed, + * it has quick startup time and low memory requirements. + * + * An alternative provider, that keeps all definitions in memory is the {@link AllChemCompProvider}. Another provider, + * that does not require any network access, but only can support a limited set of chemical component definitions, is + * the {@link ReducedChemCompProvider}. + * + * @author Andreas Prlic + */ +public class DownloadChemCompProvider implements ChemCompProvider { + private static final Logger logger = LoggerFactory.getLogger(DownloadChemCompProvider.class); + + public static final String CHEM_COMP_CACHE_DIRECTORY = "chemcomp"; + public static final String DEFAULT_SERVER_URL = "http://files.rcsb.org/ligands/download/"; + public static String serverBaseUrl = DEFAULT_SERVER_URL; + /** + * Use default RCSB server layout (true) or internal RCSB server layout (false) + */ + public static boolean useDefaultUrlLayout = true; + + private static File path; + //private static final String FILE_SEPARATOR = System.getProperty("file.separator"); + private static final String NEWLINE = System.getProperty("line.separator"); + + + // flags to make sure there is only one thread running that is loading the dictionary + static AtomicBoolean loading = new AtomicBoolean(false); + + static final List protectedIDs = new ArrayList<>(); + static { + protectedIDs.add("CON"); + protectedIDs.add("PRN"); + protectedIDs.add("AUX"); + protectedIDs.add("NUL"); + } + + private static ChemCompProvider fallback = null; // Fallback provider if the download fails + + /** + * by default we will download only some of the files. User has to request that all files should be downloaded... + */ + boolean downloadAll = false; + + public DownloadChemCompProvider() { + this(null); + } + + public DownloadChemCompProvider(String cacheFilePath) { + logger.debug("Initialising DownloadChemCompProvider"); + + // note that path is static, so this is just to make sure that all non-static methods will have path initialised + if (cacheFilePath != null) { + path = new File(cacheFilePath); + } + } + + /** + * Get this provider's cache path + * @return + */ + public static File getPath() { + if (path == null) { + UserConfiguration config = new UserConfiguration(); + path = new File(config.getCacheFilePath()); + } + return path; + } + + /** + * Checks if the chemical components already have been installed into the PDB directory. + * If not, will download the chemical components definitions file and split it up into small + * subfiles. + */ + public void checkDoFirstInstall() { + if (!downloadAll) { + return; + } + + // this makes sure there is a file separator between every component, + // if path has a trailing file separator or not, it will work for both cases + File dir = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); + File f = new File(dir, "components.cif.gz"); + + if (!f.exists()) { + downloadAllDefinitions(); + } else { + // file exists.. did it get extracted? + FilenameFilter filter = (dir1, file) -> file.endsWith(".cif.gz"); + String[] files = dir.list(filter); + if (files.length < 500) { + // not all did get unpacked + try { + split(); + } catch (IOException e) { + logger.error("Could not split file {} into individual chemical component files. Error: {}", + f.toString(), e.getMessage()); + } + } + } + } + + private void split() throws IOException { + logger.info("Installing individual chem comp files ..."); + + File dir = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); + File f = new File(dir, "components.cif.gz"); + + int counter = 0; + InputStreamProvider prov = new InputStreamProvider(); + + try (BufferedReader buf = new BufferedReader (new InputStreamReader(prov.getInputStream(f)))) { + String line; + line = buf.readLine (); + StringWriter writer = new StringWriter(); + + String currentID = null; + while (line != null) { + if (line.startsWith("data_")) { + // a new record found! + + if (currentID != null) { + writeID(writer.toString(), currentID); + counter++; + } + + currentID = line.substring(5); + writer = new StringWriter(); + } + + writer.append(line); + writer.append(NEWLINE); + + line = buf.readLine(); + } + + // write the last record... + writeID(writer.toString(), currentID); + counter++; + } + + logger.info("Created {} chemical component files.", counter); + } + + /** + * Output chemical contents to a file + * @param contents File contents + * @param currentID Chemical ID, used to determine the filename + * @throws IOException + */ + private void writeID(String contents, String currentID) throws IOException { + String localName = getLocalFileName(currentID); + try (PrintWriter pw = new PrintWriter(new GZIPOutputStream(new FileOutputStream(localName)))) { + pw.print(contents); + pw.flush(); + } + } + + /** + * Loads the definitions for this {@link ChemComp} from a local file and instantiates a new object. + * + * @param recordName the ID of the {@link ChemComp} + * @return a new {@link ChemComp} definition. + */ + @Override + public ChemComp getChemComp(String recordName) { + // make sure we work with upper case records + recordName = recordName.toUpperCase().trim(); + + boolean haveFile = true; + if (recordName.equals("?")) { + return null; + } + + if (fileIsAbsent(recordName)) { + // check if we should install all components + checkDoFirstInstall(); + } + if (fileIsAbsent(recordName)) { + // we previously have installed already the definitions, + // just do an incrememntal update + haveFile = downloadChemCompRecord(recordName); + } + + // Added check that download was successful and chemical component is available. + if (haveFile) { + String filename = getLocalFileName(recordName); + try { + ChemicalComponentDictionary dict = ChemCompConverter.fromPath(Paths.get(filename)); + ChemComp chemComp = dict.getChemComp(recordName); + + // May be null if the file was corrupt. Fall back on ReducedChemCompProvider in that case + if (chemComp != null) { + return chemComp; + } + } catch (IOException e) { + logger.warn("Could not download chemical component file {} for {}. Error: {}. Now trying to use the " + + "local chemical component definitions.", filename, recordName, e.getMessage()); + } + } + + // see https://github.com/biojava/biojava/issues/315 + // probably a network error happened. Try to use the ReducedChemCOmpProvider + if (fallback == null) { + fallback = new ReducedChemCompProvider(); + } + + logger.warn("Falling back to ReducedChemCompProvider for {}. This could indicate a network error.", recordName); + return fallback.getChemComp(recordName); + } + + /** + * Returns the file name that contains the definition for this {@link ChemComp} + * + * @param recordName the ID of the {@link ChemComp} + * @return full path to the file + */ + public static String getLocalFileName(String recordName) { + if (protectedIDs.contains(recordName)) { + recordName = "_" + recordName; + } + + File f = new File(getPath(), CHEM_COMP_CACHE_DIRECTORY); + if (!f.exists()) { + logger.info("Creating directory {}", f); + + boolean success = f.mkdir(); + // we've checked in initPath that path is writable, so there's no need to check if it succeeds + // in the unlikely case that in the meantime it isn't writable at least we log an error + if (!success) { + logger.error("Directory {} could not be created", f); + } + } + + File theFile = new File(f, recordName + ".cif.gz"); + return theFile.toString(); + } + + private static boolean fileIsAbsent(String recordName) { + String fileName = getLocalFileName(recordName); + File f = new File(fileName); + + // delete files that are too short to have contents + if (f.length() < LocalPDBDirectory.MIN_PDB_FILE_SIZE) { + // Delete defensively. + // Note that if delete is unsuccessful, we re-download the file anyways + f.delete(); + return true; + } + + return !f.exists(); + } + + /** + * @param recordName : three-letter name + * @return true if successful download + */ + private static boolean downloadChemCompRecord(String recordName) { + String localName = getLocalFileName(recordName); + File newFile; + try { + newFile = File.createTempFile("chemcomp" + recordName, "cif"); + logger.debug("Will write chem comp file to temp file {}", newFile.toString()); + } catch(IOException e) { + logger.error("Could not write to temp directory {} to create the chemical component download temp file", System.getProperty("java.io.tmpdir")); + return false; + } + String u; + if (useDefaultUrlLayout) { + u = serverBaseUrl + recordName + ".cif"; + } else { + u = serverBaseUrl + recordName.charAt(0) + "/" + recordName + "/" + recordName + ".cif"; + } + + logger.debug("downloading {}", u); + + URL url = null; + try { + url = new URL(u); + URLConnection uconn = URLConnectionTools.openURLConnection(url); + + try (PrintWriter pw = new PrintWriter(new GZIPOutputStream(new FileOutputStream(newFile))); + BufferedReader fileBuffer = new BufferedReader(new InputStreamReader(uconn.getInputStream()))) { + String line; + while ((line = fileBuffer.readLine()) != null) { + pw.println(line); + } + + pw.flush(); + } + // Now we move this across to where it actually wants to be + Files.move(newFile.toPath(), Paths.get(localName), StandardCopyOption.REPLACE_EXISTING); + + return true; + } catch (IOException e) { + logger.error("Could not download {} OR store locally to {} Error ={}", + url, + localName, + e.getMessage()); + newFile.delete(); + } + return false; + } + + private void downloadAllDefinitions() { + if (loading.get()) { + logger.info("Waiting for other thread to install chemical components..."); + } + + while (loading.get()) { + // another thread is already downloading the components definitions + // wait for the other thread to finish... + try { + // wait half a second + Thread.sleep(500); + } catch (InterruptedException e) { + //e.printStackTrace(); + logger.error("Thread interrupted "+e.getMessage()); + } + + logger.info("Another thread installed the chemical components."); + return; + } + + loading.set(true); + long timeS = System.currentTimeMillis(); + + logger.info("Performing first installation of chemical components."); + logger.info("Downloading components.cif.gz ..."); + + try { + AllChemCompProvider.downloadFile(); + } catch (IOException e) { + logger.error("Could not download the all chemical components file. Error: {}. " + + "Chemical components information won't be available", e.getMessage()); + // no point in trying to split if the file could not be downloaded + loading.set(false); + return; + } + try { + split(); + } catch (IOException e) { + logger.error("Could not split all chem comp file into individual chemical component files. Error: {}", + e.getMessage()); + // no point in reporting time + loading.set(false); + return; + } + long timeE = System.currentTimeMillis(); + logger.info("time to install chem comp dictionary: " + (timeE - timeS) / 1000 + " sec."); + loading.set(false); + } + + /** + * By default this provider will download only some of the {@link ChemComp} files. + * The user has to request that all files should be downloaded by setting this parameter to true. + * + * @return flag if the all components should be downloaded and installed at startup. (default: false) + */ + public boolean isDownloadAll() { + return downloadAll; + } + + /** By default this provider will download only some of the {@link ChemComp} files. + * The user has to request that all files should be downloaded by setting this parameter to true. + * + * @param downloadAll if the all components should be downloaded and installed at startup. (default: false) + */ + public void setDownloadAll(boolean downloadAll) { + this.downloadAll = downloadAll; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/MetalBondDistance.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/MetalBondDistance.java new file mode 100644 index 0000000000..1b64b73b35 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/MetalBondDistance.java @@ -0,0 +1,56 @@ +package org.biojava.nbio.structure.chem; + +/** + * A bean that contains cutoffs for correctly detecting metal bonds. + * Definitions are in file bond_distance_limits.cif.gz + * + * Created by andreas on 6/9/16. + */ +public class MetalBondDistance { + private String atomType1; + private String atomType2; + private float lowerLimit; + private float upperLimit; + + public String getAtomType1() { + return atomType1; + } + + public void setAtomType1(String atomType1) { + this.atomType1 = atomType1; + } + + public String getAtomType2() { + return atomType2; + } + + public void setAtomType2(String atomType2) { + this.atomType2 = atomType2; + } + + public float getLowerLimit() { + return lowerLimit; + } + + public void setLowerLimit(float lowerLimit) { + this.lowerLimit = lowerLimit; + } + + public float getUpperLimit() { + return upperLimit; + } + + public void setUpperLimit(float upperLimit) { + this.upperLimit = upperLimit; + } + + @Override + public String toString() { + return "MetalBindDistance{" + + "atomType1='" + atomType1 + '\'' + + ", atomType2='" + atomType2 + '\'' + + ", lowerLimit=" + lowerLimit + + ", upperLimit=" + upperLimit + + '}'; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java new file mode 100644 index 0000000000..5321869139 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ReducedChemCompProvider.java @@ -0,0 +1,58 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.structure.io.cif.ChemCompConsumer; +import org.biojava.nbio.structure.io.cif.ChemCompConsumerImpl; +import org.biojava.nbio.structure.io.cif.ChemCompConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.zip.GZIPInputStream; + +/** + * Unlike the {@link DownloadChemCompProvider}, this {@link ChemCompProvider} does not download any chem comp + * definitions. It has access to a limited set of files that are part of the biojava distribution. + * + * @author Andreas Prlic + * @since 3.0 + */ +public class ReducedChemCompProvider implements ChemCompProvider { + private static final Logger logger = LoggerFactory.getLogger(ReducedChemCompProvider.class); + + public ReducedChemCompProvider(){ + logger.debug("Initialising ReducedChemCompProvider"); + } + + @Override + public ChemComp getChemComp(String recordName) { + String name = recordName.toUpperCase().trim(); + try (InputStream inStream = this.getClass().getResourceAsStream("/chemcomp/" + name + ".cif.gz")) { + logger.debug("Reading chemcomp/{}.cif.gz", recordName); + + if (inStream == null) { + //System.out.println("Could not find chem comp: " + name + " ... using generic Chem Comp"); + // could not find the chem comp definition for this in the jar file + logger.debug("Getting empty chem comp for {}", name); + ChemComp cc = ChemComp.getEmptyChemComp(); + cc.setId(name); + return cc; + } + + // The Consumer builds up the BioJava - structure object. + // you could also hook in your own and build up you own data model. + ChemicalComponentDictionary dict = ChemCompConverter.fromInputStream(inStream); + + return dict.getChemComp(name); + } catch (IOException e) { + logger.error("IOException caught while reading chem comp {}.", name, e); + } + logger.warn("Problem when loading chem comp {}, will use an empty chem comp for it", name); + ChemComp cc = ChemComp.getEmptyChemComp(); + cc.setId(name); + return cc; + } +} + diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ZipChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ZipChemCompProvider.java new file mode 100644 index 0000000000..34d7eea4db --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ZipChemCompProvider.java @@ -0,0 +1,275 @@ +package org.biojava.nbio.structure.chem; + +import org.biojava.nbio.structure.io.cif.ChemCompConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.HashSet; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * This chemical component provider retrieves and caches chemical component definition files from a + * zip archive specified in its construction. If the archive does not contain the record, an attempt is + * made to download it using DownloadChemCompProvider. The downloaded file is then added to the archive. + * + * The class is thread-safe and the same ZipChemCompProvider should be used by all threads to prevent + * simultaneous read or write to the zip archive. A zip archive will be created if missing. + * + * @author edlunde + * @author larsonm + * @since 12/05/12 + * updated 3/5/2016 for Java 7 ZipFileSystem + */ +public class ZipChemCompProvider implements ChemCompProvider{ + private static final Logger s_logger = LoggerFactory.getLogger(ZipChemCompProvider.class); + + private final Path m_tempDir; // Base path where $m_zipRootDir/ will be downloaded to. + private final Path m_zipRootDir; + private final Path m_zipFile; + private final DownloadChemCompProvider m_dlProvider; + + private boolean m_removeCif; + + // Missing IDs from library that cannot be download added here to prevent delays. + private Set unavailable = new HashSet<>(); + + /** + * ZipChemCompProvider is a Chemical Component provider that stores chemical components + * in a zip archive. Missing chemical components are downloaded and appended to the + * archive. If non-existent a new zip archive will be created. + * + * @param chemicalComponentDictionaryFile : path to zip archive for chemical components. + * @param tempDir : path for temporary directory, (null) defaults to path in property "java.io.tmpdir". + * @throws IOException + */ + public ZipChemCompProvider(String chemicalComponentDictionaryFile, String tempDir) throws IOException { + this.m_zipFile = Paths.get(chemicalComponentDictionaryFile); + + // Use a default temporary directory if not passed a value. + if (tempDir == null || tempDir.equals("")) { + this.m_tempDir = Paths.get(System.getProperty("java.io.tmpdir")); + } else { + this.m_tempDir = Paths.get(tempDir); + } + + this.m_zipRootDir = Paths.get("chemcomp"); + + // Setup an instance of the download chemcomp provider. + this.m_dlProvider = new DownloadChemCompProvider(m_tempDir.toString()); + this.m_removeCif = true; + initializeZip(); + } + + // See comments in addToZipFileSystem for why initialization is required with + // ZipFileSystems - due to URI issues in Java7. + private void initializeZip() throws IOException { + s_logger.info("Using chemical component dictionary: {}", m_zipFile.toString()); + final File f = m_zipFile.toFile(); + if (!f.exists()) { + s_logger.info("Creating missing zip archive: {}", m_zipFile.toString()); + FileOutputStream fo = new FileOutputStream(f); + try (ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(fo))) { + zip.putNextEntry(new ZipEntry("chemcomp/")); + zip.closeEntry(); + } + } + } + + /** + * Remove downloaded .cif.gz after adding to zip archive? + * Default is true. + * @param doRemove + */ + public void setRemoveCif(boolean doRemove) { + m_removeCif = doRemove; + } + + /** + * (non-Javadoc) + * @see ChemCompProvider#getChemComp(java.lang.String) + * + * @param recordName : three letter PDB name for a residue + * @return ChemComp from .zip or ChemComp from repository. Will return empty ChemComp when unable to find a residue and will return null if not provided a valid recordName. + */ + @Override + public ChemComp getChemComp(String recordName) { + if (null == recordName) return null; + + // handle non-existent ChemComp codes and do not repeatedly attempt to add these. + for (String str : unavailable) { + if (recordName.equals(str)) return getEmptyChemComp(recordName); + } + + // Try to pull from zip, if fail then download. + ChemComp cc = getFromZip(recordName); + if (cc == null) { + s_logger.info("File {} not found in archive. Attempting download from PDB.", recordName); + cc = downloadAndAdd(recordName); + } + + // If a null record or an empty chemcomp, return a default ChemComp and blacklist. + if (cc == null || (null == cc.getName() && cc.getAtoms().size() == 0)) { + s_logger.info("Unable to find or download {} - excluding from future searches.", recordName); + unavailable.add(recordName); + return getEmptyChemComp(recordName); + } + return cc; + } + + /** Use DownloadChemCompProvider to grab a gzipped cif record from the PDB. + * Zip all downloaded cif.gz files into the dictionary. + * + * @param recordName is the three-letter chemical component code (i.e. residue name). + * @return ChemComp matching recordName + */ + private ChemComp downloadAndAdd(String recordName){ + final ChemComp cc = m_dlProvider.getChemComp(recordName); + + // final File [] files = finder(m_tempDir.resolve("chemcomp").toString(), "cif.gz"); + final File [] files = new File[1]; + Path cif = m_tempDir.resolve("chemcomp").resolve(recordName + ".cif.gz"); + files[0] = cif.toFile(); + if (files[0] != null) { + addToZipFileSystem(m_zipFile, files, m_zipRootDir); + if (m_removeCif) for (File f : files) f.delete(); + } + return cc; + } + + /** + * Cleanup chemical component (.cif.gz) files downloaded to tmpdir. + * @param tempdir : path to temporary directory for chemical components + */ + public static void purgeTempFiles(String tempdir) { + if (tempdir == null) return; + + s_logger.info("Removing: "+tempdir); + Path dlPath = Paths.get(tempdir).resolve("chemcomp"); + File[] chemCompOutFiles = finder(dlPath.toString(), "cif.gz"); + if (null != chemCompOutFiles) for (File f : chemCompOutFiles) f.delete(); + dlPath.toFile().delete(); + } + + /** + * Return an empty ChemComp group for a three-letter resName. + * @param resName + * @return + */ + private ChemComp getEmptyChemComp(String resName){ + String pdbName = ""; // Empty string is default + if (null != resName && resName.length() >= 3) { + pdbName = resName.substring(0,3); + } + final ChemComp comp = new ChemComp(); + comp.setOneLetterCode("?"); + comp.setThreeLetterCode(pdbName); + comp.setPolymerType(PolymerType.unknown); + comp.setResidueType(ResidueType.atomn); + return comp; + } + + /** + * Return File(s) in dirName that match suffix. + * @param dirName + * @param suffix + * @return + */ + static private File[] finder(String dirName, final String suffix) { + if (null == dirName || null == suffix) { + return null; + } + + final File dir = new File(dirName); + return dir.listFiles((dir1, filename) -> filename.endsWith(suffix)); + } + + /** + * This is synchronized, along with addToFileSystem to prevent simulatenous reading/writing. + * @param recordName to find in zipfile. + * @return ChemComp if found or null if missing. + */ + private synchronized ChemComp getFromZip(String recordName) { + ChemComp cc = null; + if (!m_zipFile.toFile().exists()) return cc; + final String filename = "chemcomp/" + recordName + ".cif.gz"; + + // try with resources block to read from the filesystem. + try (FileSystem fs = FileSystems.newFileSystem(m_zipFile, null)) { + Path cif = fs.getPath(filename); + + if (Files.exists(cif)) { + s_logger.debug("reading {} from {}", recordName, m_zipFile); + final ChemicalComponentDictionary dict = ChemCompConverter.fromPath(cif); + cc = dict.getChemComp(recordName); + } + } catch (IOException e) { + s_logger.error("Unable to read from zip file : {}", e.getMessage()); + } + + return cc; + } + + /** + * Add an array of files to a zip archive. + * Synchronized to prevent simultaneous reading/writing. + * + * @param zipFile is a destination zip archive + * @param files is an array of files to be added + * @param pathWithinArchive is the path within the archive to add files to + * @return true if successfully appended these files. + */ + private synchronized boolean addToZipFileSystem(Path zipFile, File[] files, Path pathWithinArchive) { + boolean ret = false; + + /* URIs in Java 7 cannot have spaces, must use Path instead + * and so, cannot use the properties map to describe need to create + * a new zip archive. ZipChemCompProvider.initilizeZip to creates the + * missing zip file */ + + /* + // convert the filename to a URI + String uriString = "jar:file:" + zipFile.toUri().getPath(); + final URI uri = URI.create(uriString); + + // if filesystem doesn't exist, create one. + final Map env = new HashMap<>(); + // Create a new zip if one isn't present. + if (!zipFile.toFile().exists()) { + System.out.println("Need to create " + zipFile.toString()); + } + env.put("create", String.valueOf(!zipFile.toFile().exists())); + // Specify the encoding as UTF -8 + env.put("encoding", "UTF-8"); + */ + + // Copy in each file. + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, null)) { + Files.createDirectories(pathWithinArchive); + for (File f : files) { + if (!f.isDirectory() && f.exists()) { + Path externalFile = f.toPath(); + Path pathInZipFile = zipfs.getPath(pathWithinArchive.resolve(f.getName()).toString()); + Files.copy(externalFile, pathInZipFile, + StandardCopyOption.REPLACE_EXISTING); + } + } + ret = true; + } catch (IOException ex) { + s_logger.error("Unable to add entries to Chemical Component zip archive : {}", ex.getMessage()); + ret = false; + } + return ret; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java index b8e10ffbb8..de50722b34 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java @@ -750,40 +750,41 @@ public String toPDB() { public String toMMCIF() { StringBuilder sb = new StringBuilder(); - String molecId1 = getMoleculeIds().getFirst(); - String molecId2 = getMoleculeIds().getSecond(); - - if (isSymRelated()) { - // if both chains are named equally we want to still named them differently in the output mmcif file - // so that molecular viewers can handle properly the 2 chains as separate entities - molecId2 = molecId2 + "_" +getTransforms().getSecond().getTransformId(); - } - - sb.append(SimpleMMcifParser.MMCIF_TOP_HEADER).append("BioJava_interface_").append(getId()).append(System.getProperty("line.separator")); - - sb.append(FileConvert.getAtomSiteHeader()); - - // we reassign atom ids if sym related (otherwise atom ids would be duplicated and some molecular viewers can't cope with that) - int atomId = 1; - List atomSites = new ArrayList<>(); - for (Atom atom:this.molecules.getFirst()) { - if (isSymRelated()) { - atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId1, molecId1, atomId)); - } else { - atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId1, molecId1)); - } - atomId++; - } - for (Atom atom:this.molecules.getSecond()) { - if (isSymRelated()) { - atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId2, molecId2, atomId)); - } else { - atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId2, molecId2)); - } - atomId++; - } - - sb.append(MMCIFFileTools.toMMCIF(atomSites,AtomSite.class)); + // TODO impl +// String molecId1 = getMoleculeIds().getFirst(); +// String molecId2 = getMoleculeIds().getSecond(); +// +// if (isSymRelated()) { +// // if both chains are named equally we want to still named them differently in the output mmcif file +// // so that molecular viewers can handle properly the 2 chains as separate entities +// molecId2 = molecId2 + "_" +getTransforms().getSecond().getTransformId(); +// } +// +// sb.append(SimpleMMcifParser.MMCIF_TOP_HEADER).append("BioJava_interface_").append(getId()).append(System.getProperty("line.separator")); +// +// sb.append(FileConvert.getAtomSiteHeader()); +// +// // we reassign atom ids if sym related (otherwise atom ids would be duplicated and some molecular viewers can't cope with that) +// int atomId = 1; +// List atomSites = new ArrayList<>(); +// for (Atom atom:this.molecules.getFirst()) { +// if (isSymRelated()) { +// atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId1, molecId1, atomId)); +// } else { +// atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId1, molecId1)); +// } +// atomId++; +// } +// for (Atom atom:this.molecules.getSecond()) { +// if (isSymRelated()) { +// atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId2, molecId2, atomId)); +// } else { +// atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId2, molecId2)); +// } +// atomId++; +// } +// +// sb.append(MMCIFFileTools.toMMCIF(atomSites,AtomSite.class)); return sb.toString(); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BcifFileReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BcifFileReader.java index f0325b5b3e..a122158aee 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BcifFileReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BcifFileReader.java @@ -2,7 +2,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.cif.CifFileConverter; +import org.biojava.nbio.structure.io.cif.StructureConverter; import java.io.IOException; import java.io.InputStream; @@ -38,7 +38,7 @@ public BcifFileReader(String path) { @Override public Structure getStructure(InputStream inStream) throws IOException { - return CifFileConverter.fromInputStream(inStream, getFileParsingParameters()); + return StructureConverter.fromInputStream(inStream, getFileParsingParameters()); } @Override diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java index df077cde9b..7c4fe74144 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BondMaker.java @@ -25,6 +25,7 @@ import org.biojava.nbio.structure.*; import org.biojava.nbio.structure.chem.ChemComp; import org.biojava.nbio.structure.chem.ChemCompBond; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.io.util.PDBTemporaryStorageUtils.LinkRecord; import org.rcsb.cif.model.ValueKind; import org.rcsb.cif.schema.mm.StructConn; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/ChargeAdder.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/ChargeAdder.java index 311414f9da..607cf8e150 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/ChargeAdder.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/ChargeAdder.java @@ -30,7 +30,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.chem.ChemComp; import org.biojava.nbio.structure.chem.ChemCompAtom; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,25 +53,7 @@ public static void addCharges(Structure structure) { List chemAtoms = thisChemComp.getAtoms(); for (ChemCompAtom chemCompAtom : chemAtoms) { Atom atom = g.getAtom(chemCompAtom.getAtomId()); - String stringCharge = chemCompAtom.getCharge(); - short shortCharge = 0; - if (stringCharge != null) { - if (!stringCharge.equals("?")) { - try { - shortCharge = Short.parseShort(stringCharge); - } catch(NumberFormatException e) { - logger.warn("Number format exception. Parsing '{}' to short", stringCharge); - } - } else { - logger.warn("? charge on atom {} in group {}", - chemCompAtom.getAtomId(), - thisChemComp.getId()); - } - } else { - logger.warn("Null charge on atom {} in group {}", - chemCompAtom.getAtomId(), - thisChemComp.getId()); - } + short shortCharge = (short) chemCompAtom.getCharge(); if (atom != null) { atom.setCharge(shortCharge); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/CifFileReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/CifFileReader.java index a5977931c2..edfe601b8d 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/CifFileReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/CifFileReader.java @@ -2,7 +2,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.cif.CifFileConverter; +import org.biojava.nbio.structure.io.cif.StructureConverter; import java.io.IOException; import java.io.InputStream; @@ -40,7 +40,7 @@ public CifFileReader(String path) { @Override public Structure getStructure(InputStream inStream) throws IOException{ - return CifFileConverter.fromInputStream(inStream, getFileParsingParameters()); + return StructureConverter.fromInputStream(inStream, getFileParsingParameters()); } @Override diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java index d6da021e63..8264fb2b3f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java @@ -40,7 +40,7 @@ import org.biojava.nbio.structure.PDBHeader; import org.biojava.nbio.structure.Site; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.io.cif.CifFileConverter; +import org.biojava.nbio.structure.io.cif.StructureConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -593,10 +593,10 @@ else if (name.length()==1) public String toMMCIF() { - return CifFileConverter.toText(this.structure); + return StructureConverter.toText(this.structure); } public static String toMMCIF(Chain chain) { - return CifFileConverter.toText(chain); + return StructureConverter.toText(chain); } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/PDBFileParser.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/PDBFileParser.java index 6200c90b1a..a1f16e27b6 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/PDBFileParser.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/PDBFileParser.java @@ -70,7 +70,7 @@ import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.chem.ChemCompAtom; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.io.util.PDBTemporaryStorageUtils.LinkRecord; import org.biojava.nbio.structure.secstruc.SecStrucInfo; import org.biojava.nbio.structure.secstruc.SecStrucType; @@ -301,7 +301,7 @@ public PDBFileParser() { /** initiate new resNum, either Hetatom, Nucleotide, or AminoAcid */ private Group getNewGroup(String recordName,Character aminoCode1, String aminoCode3) { - Group g = ChemCompGroupFactory.getGroupFromChemCompDictionary(aminoCode3); + Group g = ChemCompGroupFactory.getGroupFromChemCompDictionary(aminoCode3); if ( g != null && !g.getChemComp().isEmpty()) return g; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java new file mode 100644 index 0000000000..5bbb3f7a6a --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java @@ -0,0 +1,16 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.chem.ChemCompDescriptor; +import org.biojava.nbio.structure.chem.ChemicalComponentDictionary; +import org.rcsb.cif.schema.mm.ChemComp; +import org.rcsb.cif.schema.mm.ChemCompAtom; +import org.rcsb.cif.schema.mm.ChemCompBond; + +public interface ChemCompConsumer extends CifFileConsumer { + void consumeChemComp(ChemComp c); + + void consumeChemCompAtom(ChemCompAtom atom); + + void consumeChemCompBond(ChemCompBond bond); +} + diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java new file mode 100644 index 0000000000..ffe61f2d0b --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java @@ -0,0 +1,108 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.chem.ChemicalComponentDictionary; +import org.rcsb.cif.schema.mm.ChemComp; +import org.rcsb.cif.schema.mm.ChemCompAtom; +import org.rcsb.cif.schema.mm.ChemCompBond; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ChemCompConsumerImpl implements ChemCompConsumer { + private static final Logger logger = LoggerFactory.getLogger(ChemCompConsumerImpl.class); + private final ChemicalComponentDictionary dictionary; + private String latestChemCompId; + + public ChemCompConsumerImpl() { + this.dictionary = new ChemicalComponentDictionary(); + } + + @Override + public void consumeChemComp(ChemComp c) { + org.biojava.nbio.structure.chem.ChemComp chemComp = new org.biojava.nbio.structure.chem.ChemComp(); + chemComp.setId(c.getId().get(0)); + chemComp.setName(c.getName().get(0)); + chemComp.setType(c.getType().get(0)); + chemComp.setPdbxType(c.getPdbxType().get(0)); + chemComp.setFormula(c.getFormula().get(0)); + chemComp.setMonNstdParentCompId(c.getMonNstdParentCompId().get(0)); + chemComp.setPdbxSynonyms(c.getPdbxSynonyms().get(0)); + chemComp.setPdbxFormalCharge(c.getPdbxFormalCharge().get(0)); + chemComp.setPdbxInitialDate(c.getPdbxInitialDate().get(0)); + chemComp.setPdbxModifiedDate(c.getPdbxModifiedDate().get(0)); + chemComp.setPdbxAmbiguousFlag(c.getPdbxAmbiguousFlag().get(0)); + chemComp.setPdbxReleaseStatus(c.getPdbxReleaseStatus().get(0)); + chemComp.setPdbxReplacedBy(c.getPdbxReplacedBy().get(0)); + chemComp.setPdbxReplaces(c.getPdbxReplaces().get(0)); + chemComp.setFormulaWeight(c.getFormulaWeight().get(0)); + chemComp.setOneLetterCode(c.getOneLetterCode().get(0)); + chemComp.setThreeLetterCode(c.getThreeLetterCode().get(0)); + chemComp.setPdbxModelCoordinatesDetails(c.getPdbxModelCoordinatesDetails().get(0)); + chemComp.setPdbxModelCoordinatesMissingFlag(c.getPdbxModelCoordinatesMissingFlag().get(0)); + chemComp.setPdbxIdealCoordinatesDetails(c.getPdbxIdealCoordinatesDetails().get(0)); + chemComp.setPdbxIdealCoordinatesMissingFlag(c.getPdbxIdealCoordinatesMissingFlag().get(0)); + chemComp.setPdbxModelCoordinatesDbCode(c.getPdbxModelCoordinatesDbCode().get(0)); + chemComp.setPdbxSubcomponentList(c.getPdbxSubcomponentList().get(0)); + chemComp.setPdbxProcessingSite(c.getPdbxProcessingSite().get(0)); + if (chemComp.getId() == null) { + logger.warn("chem comp ID == null {}", c); + } + latestChemCompId = chemComp.getId(); + dictionary.addChemComp(chemComp); + } + + @Override + public void consumeChemCompAtom(ChemCompAtom atom) { + for (int i = 0; i < atom.getRowCount(); i++) { + org.biojava.nbio.structure.chem.ChemCompAtom a = new org.biojava.nbio.structure.chem.ChemCompAtom(); + a.setCompId(atom.getCompId().get(i)); + a.setAtomId(atom.getAtomId().get(i)); + a.setAltAtomId(atom.getAltAtomId().get(i)); + a.setTypeSymbol(atom.getTypeSymbol().get(i)); + a.setCharge(atom.getCharge().get(i)); + a.setPdbxAlign(atom.getPdbxAlign().get(i)); + a.setPdbxAromaticFlag(atom.getPdbxAromaticFlag().get(i)); + a.setPdbxLeavingAtomFlag(atom.getPdbxLeavingAtomFlag().get(i)); + a.setPdbxStereoConfig(atom.getPdbxStereoConfig().get(i)); + a.setModelCartnX(atom.getModelCartnX().get(i)); + a.setModelCartnY(atom.getModelCartnY().get(i)); + a.setModelCartnZ(atom.getModelCartnZ().get(i)); + a.setPdbxModelCartnXIdeal(atom.getPdbxModelCartnXIdeal().get(i)); + a.setPdbxModelCartnYIdeal(atom.getPdbxModelCartnYIdeal().get(i)); + a.setPdbxModelCartnZIdeal(atom.getPdbxModelCartnZIdeal().get(i)); + a.setPdbxComponentAtomId(atom.getPdbxComponentAtomId().get(i)); + a.setPdbxComponentCompId(atom.getPdbxComponentCompId().get(i)); + a.setPdbxOrdinal(atom.getPdbxOrdinal().get(i)); + dictionary.getChemComp(latestChemCompId).getAtoms().add(a); + } + } + + @Override + public void consumeChemCompBond(ChemCompBond bond) { + for (int i = 0; i < bond.getRowCount(); i++) { + org.biojava.nbio.structure.chem.ChemCompBond b = new org.biojava.nbio.structure.chem.ChemCompBond(); + b.setAtomId1(bond.getAtomId1().get(i)); + b.setAtomId2(bond.getAtomId2().get(i)); + b.setCompId(bond.getCompId().get(i)); + b.setPdbxAromaticFlag(bond.getPdbxAromaticFlag().get(i)); + b.setPdbxOrdinal(bond.getPdbxOrdinal().get(i)); + b.setPdbxStereoConfig(bond.getPdbxStereoConfig().get(i)); + b.setValueOrder(bond.getValueOrder().get(i)); + dictionary.getChemComp(latestChemCompId).getBonds().add(b); + } + } + + @Override + public void prepare() { + + } + + @Override + public void finish() { + + } + + @Override + public ChemicalComponentDictionary getContainer() { + return dictionary; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java new file mode 100644 index 0000000000..d234d27dc4 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java @@ -0,0 +1,79 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.chem.ChemicalComponentDictionary; +import org.biojava.nbio.structure.io.FileParsingParameters; +import org.rcsb.cif.CifIO; +import org.rcsb.cif.model.CifFile; +import org.rcsb.cif.schema.StandardSchemata; +import org.rcsb.cif.schema.mm.MmCifBlock; +import org.rcsb.cif.schema.mm.MmCifFile; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Convert CifFiles to chem comps. + * @author Sebastian Bittrich + * @since 6.0.0 + */ +public class ChemCompConverter { + /** + * Read data from a file and convert to chem comp dictionary. + * @param path the source of information - can be gzipped or binary or text data + * @return the target + */ + public static ChemicalComponentDictionary fromPath(Path path) throws IOException { + return fromInputStream(Files.newInputStream(path)); + } + + /** + * Get data from a URL and convert to chem comp dictionary. + * @param url the source of information - can be gzipped or binary or text data + * @return the target + * @throws IOException thrown when reading fails + */ + public static ChemicalComponentDictionary fromURL(URL url) throws IOException { + return fromInputStream(url.openStream()); + } + + /** + * Convert InputStream to chem comp dictionary. + * @param inputStream the InputStream of information - can be gzipped or binary or text data + * @return the target + * @throws IOException thrown when reading fails + * @see StructureConverter#fromInputStream(InputStream, FileParsingParameters) + */ + public static ChemicalComponentDictionary fromInputStream(InputStream inputStream) throws IOException { + return fromCifFile(CifIO.readFromInputStream(inputStream)); + } + + /** + * Convert CifFile to chem comp dictionary. + * @param cifFile the source + * @return the target + */ + public static ChemicalComponentDictionary fromCifFile(CifFile cifFile) { + // initialize consumer + ChemCompConsumer consumer = new ChemCompConsumerImpl(); + + // init structure + consumer.prepare(); + + // feed individual categories to consumer + MmCifFile mmCifFile = cifFile.as(StandardSchemata.MMCIF); + for (MmCifBlock cifBlock : mmCifFile.getBlocks()) { + consumer.consumeChemComp(cifBlock.getChemComp()); + consumer.consumeChemCompAtom(cifBlock.getChemCompAtom()); + consumer.consumeChemCompBond(cifBlock.getChemCompBond()); + } + + // prepare structure to be retrieved + consumer.finish(); + + return consumer.getContainer(); + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumer.java new file mode 100644 index 0000000000..d76d91d1e7 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumer.java @@ -0,0 +1,11 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.chem.MetalBondDistance; +import org.rcsb.cif.model.Category; + +import java.util.List; +import java.util.Map; + +public interface MetalBondConsumer extends CifFileConsumer>> { + void consume(Category category); +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java new file mode 100644 index 0000000000..28833bc559 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java @@ -0,0 +1,55 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.chem.MetalBondDistance; +import org.rcsb.cif.model.Category; +import org.rcsb.cif.model.FloatColumn; +import org.rcsb.cif.model.StrColumn; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by andreas on 6/9/16. + */ +public class MetalBondConsumerImpl implements MetalBondConsumer { + private final Map> definitions = new HashMap<>(); + + @Override + public void prepare() { + definitions.clear(); + } + + @Override + public void finish() { + // minimize memory consumption + for (List d : definitions.values()){ + ((ArrayList) d).trimToSize(); + } + } + + @Override + public void consume(Category category) { + StrColumn atomType1 = (StrColumn) category.getColumn(""); + StrColumn atomType2 = (StrColumn) category.getColumn(""); + FloatColumn lowerLimit = (FloatColumn) category.getColumn(""); + FloatColumn upperLimit = (FloatColumn) category.getColumn(""); + for (int i = 0; i < category.getRowCount(); i++) { + MetalBondDistance d = new MetalBondDistance(); + + d.setAtomType1(atomType1.get(i)); + d.setAtomType2(atomType2.get(i)); + d.setLowerLimit((float) lowerLimit.get(i)); + d.setUpperLimit((float) upperLimit.get(i)); + + List defs = definitions.computeIfAbsent(d.getAtomType1(), k -> new ArrayList<>()); + defs.add(d); + } + } + + @Override + public Map> getContainer(){ + return definitions; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConverter.java new file mode 100644 index 0000000000..0f28fe6493 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConverter.java @@ -0,0 +1,60 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.chem.MetalBondDistance; +import org.rcsb.cif.CifIO; +import org.rcsb.cif.model.Block; +import org.rcsb.cif.model.CifFile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.InputStream; +import java.util.List; +import java.util.Map; + +/** + * Created by andreas on 6/6/16. + */ +public class MetalBondConverter { + private static final Logger logger = LoggerFactory.getLogger(MetalBondConverter.class); + private static final String BONDS_FILE = "org/biojava/nbio/structure/bond_distance_limits.cif.gz"; + private static Map> definitions; + + static { + definitions = init(); + } + + public static Map> getMetalBondDefinitions() { + return definitions; + } + + private static Map> init() { + InputStream inputStream = MetalBondConverter.class.getClassLoader().getResourceAsStream(BONDS_FILE); + + if (inputStream == null) { + throw new RuntimeException("Could not find resource " + BONDS_FILE + ". This probably means that your " + + "biojava.jar file is corrupt or incorrectly built."); + } + + try { + CifFile cifFile = CifIO.readFromInputStream(inputStream); + // initialize consumer + MetalBondConsumerImpl consumer = new MetalBondConsumerImpl(); + + // init structure + consumer.prepare(); + + // feed individual categories to consumer + for (Block cifBlock : cifFile.getBlocks()) { + cifBlock.categories().forEach(consumer::consume); + } + + // prepare structure to be retrieved + consumer.finish(); + + return consumer.getContainer(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return null; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java index 6a952029ee..d858536847 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java @@ -24,6 +24,7 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.io.BondMaker; import org.biojava.nbio.structure.io.ChargeAdder; import org.biojava.nbio.structure.io.EntityFinder; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConverter.java similarity index 97% rename from biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java rename to biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConverter.java index 2a53746297..45a5b97c76 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConverter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConverter.java @@ -18,9 +18,9 @@ /** * Convert BioJava structures to CifFiles and vice versa. * @author Sebastian Bittrich - * @since 5.3.0 + * @since 6.0.0 */ -public class CifFileConverter { +public class StructureConverter { /** * Read data from a file and convert to Structure without any FileParsingParameters. * @param path the source of information - can be gzipped or binary or text data @@ -66,7 +66,7 @@ private static Structure fromURL(URL url, FileParsingParameters parameters) thro * @param inputStream the InputStream of information - can be gzipped or binary or text data * @return the target * @throws IOException thrown when reading fails - * @see CifFileConverter#fromInputStream(InputStream, FileParsingParameters) + * @see StructureConverter#fromInputStream(InputStream, FileParsingParameters) */ public static Structure fromInputStream(InputStream inputStream) throws IOException { return fromInputStream(inputStream, new FileParsingParameters()); @@ -87,7 +87,7 @@ public static Structure fromInputStream(InputStream inputStream, FileParsingPara * Convert CifFile to Structure without any FileParsingParameters. * @param cifFile the source * @return the target - * @see CifFileConverter#fromCifFile(CifFile, FileParsingParameters) + * @see StructureConverter#fromCifFile(CifFile, FileParsingParameters) */ public static Structure fromCifFile(CifFile cifFile) { return fromCifFile(cifFile, new FileParsingParameters()); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index 0a6cd9739c..0f1394424a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -48,10 +48,10 @@ import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.chem.ChemCompTools; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; import org.biojava.nbio.structure.secstruc.DSSPParser; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/ChemCompTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/ChemCompTest.java index fd37644fd4..c937ad0978 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/ChemCompTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/ChemCompTest.java @@ -20,13 +20,13 @@ */ package org.biojava.nbio.structure; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.ChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.ReducedChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemCompProvider; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; +import org.biojava.nbio.structure.chem.PolymerType; +import org.biojava.nbio.structure.chem.ReducedChemCompProvider; +import org.biojava.nbio.structure.chem.ResidueType; import org.junit.Test; import static org.junit.Assert.*; @@ -69,9 +69,9 @@ public void testMEA(){ assertTrue(" is not mea" , cc.getId().equals(chemID)); - assertEquals(" one letter code is not correct", "F", cc.getOne_letter_code()); + assertEquals(" one letter code is not correct", "F", cc.getOneLetterCode()); - assertEquals("MEA",cc.getThree_letter_code()); + assertEquals("MEA",cc.getThreeLetterCode()); assertNotNull(cc.getPolymerType()); @@ -141,7 +141,7 @@ public void testChangingProviders(){ assertTrue(" is not mea" , cc.getId().equals(chemID)); - assertEquals("MEA",cc.getThree_letter_code()); + assertEquals("MEA",cc.getThreeLetterCode()); @@ -157,7 +157,7 @@ public void testChangingProviders(){ assertTrue(" is not mea" , cc.getId().equals(chemID)); - assertEquals("MEA",cc.getThree_letter_code()); + assertEquals("MEA",cc.getThreeLetterCode()); // now we change to reduced chem comp provider ChemCompGroupFactory.setChemCompProvider(new ReducedChemCompProvider()); @@ -169,7 +169,7 @@ public void testChangingProviders(){ assertTrue(" is not mea" , cc.getId().equals(chemID)); //the cached description contains all information even with the ReducedProvider - assertNotNull(cc.getThree_letter_code()); + assertNotNull(cc.getThreeLetterCode()); } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/PdbFileFormat30Test.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/PdbFileFormat30Test.java index 9daf7d7e18..f6968c7af5 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/PdbFileFormat30Test.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/PdbFileFormat30Test.java @@ -23,10 +23,10 @@ package org.biojava.nbio.structure; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ReducedChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileParser; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.ReducedChemCompProvider; import java.io.IOException; import java.io.InputStream; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/Test4hhb.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/Test4hhb.java index afb5de1d59..bcf289cebc 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/Test4hhb.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/Test4hhb.java @@ -26,9 +26,7 @@ import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileParser; -import org.biojava.nbio.structure.io.mmcif.MMcifParser; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; +import org.biojava.nbio.structure.io.cif.StructureConverter; import org.junit.Test; import java.io.IOException; @@ -75,15 +73,9 @@ public void test4hhbPDBFile() throws IOException inStream = new GZIPInputStream(this.getClass().getResourceAsStream("/4hhb.cif.gz")); assertNotNull(inStream); - MMcifParser mmcifpars = new SimpleMMcifParser(); - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); params = new FileParsingParameters(); params.setAlignSeqRes(true); - consumer.setFileParsingParameters(params); - mmcifpars.addMMcifConsumer(consumer); - - mmcifpars.parse(inStream) ; - structure2 = consumer.getStructure(); + structure2 = StructureConverter.fromInputStream(inStream, params); assertNotNull(structure2); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java index d1c6779e7c..3aa86bacd0 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java @@ -21,19 +21,17 @@ package org.biojava.nbio.structure; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemCompBond; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.PolymerType; +import org.biojava.nbio.structure.chem.ResidueType; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.MMCIFFileTools; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; -import org.biojava.nbio.structure.io.mmcif.chem.ResidueType; -import org.biojava.nbio.structure.io.mmcif.model.AtomSite; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; -import org.biojava.nbio.structure.io.mmcif.model.ChemCompBond; +import org.biojava.nbio.structure.io.cif.StructureConverter; import org.junit.Test; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; @@ -397,10 +395,10 @@ public void testAddBondsDoesntChangeGroups() throws IOException, StructureExcept for (ChemCompBond chemCompBond : aminoChemComp.getBonds()) { // - if(chemCompBond.getAtom_id_1().equals(atomA.getName())){ + if(chemCompBond.getAtomId1().equals(atomA.getName())){ // Get the other atom in the group for(Atom atomB : atomsList) { - if(chemCompBond.getAtom_id_2().equals(atomB.getName())){ + if(chemCompBond.getAtomId2().equals(atomB.getName())){ int bondOrder = chemCompBond.getNumericalBondOrder(); new BondImpl(atomA, atomB, bondOrder); } @@ -641,15 +639,7 @@ public void testMmcifConversionPartialAltlocs() throws IOException { "ATOM 117 N NH2 A ARG A 1 13 ? 7.812 17.972 17.172 0.50 24.80 ? 102 ARG A NH2 1\n" + "ATOM 118 N NH2 B ARG A 1 13 ? 8.013 18.115 17.888 0.50 26.52 ? 102 ARG A NH2 1\n"; - SimpleMMcifParser parser = new SimpleMMcifParser(); - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - parser.addMMcifConsumer(consumer); - - BufferedReader buf = new BufferedReader(new StringReader(mmcifData)); - parser.parse(buf); - buf.close(); - - Structure s = consumer.getStructure(); + Structure s = StructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes())); Chain c = s.getPolyChains().get(0); assertEquals(1, c.getAtomGroups().size()); Group g = c.getAtomGroup(0); @@ -681,8 +671,9 @@ public void testMmcifConversionPartialAltlocs() throws IOException { assertEquals('B', a.getAltLoc().charValue()); } - List atomSites = MMCIFFileTools.convertChainToAtomSites(c, 1, "A", "A"); - assertEquals(17, atomSites.size()); + // TODO reimpl +// List atomSites = MMCIFFileTools.convertChainToAtomSites(c, 1, "A", "A"); +// assertEquals(17, atomSites.size()); } @@ -727,15 +718,7 @@ public void testMmcifConversionAllAltlocs() throws IOException { "ATOM 216 C CD A PRO A 1 23 ? 14.980 32.886 23.580 0.50 6.98 ? 112 PRO A CD 1 \n" + "ATOM 217 C CD B PRO A 1 23 ? 14.558 33.235 23.153 0.50 14.91 ? 112 PRO A CD 1 \n"; - SimpleMMcifParser parser = new SimpleMMcifParser(); - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - parser.addMMcifConsumer(consumer); - - BufferedReader buf = new BufferedReader(new StringReader(mmcifData)); - parser.parse(buf); - buf.close(); - - Structure s = consumer.getStructure(); + Structure s = StructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes())); Chain c = s.getPolyChains().get(0); assertEquals(1, c.getAtomGroups().size()); @@ -751,8 +734,9 @@ public void testMmcifConversionAllAltlocs() throws IOException { assertEquals('B', a.getAltLoc().charValue()); } - List atomSites = MMCIFFileTools.convertChainToAtomSites(c, 1, "A", "A"); - assertEquals(14, atomSites.size()); + // TODO reimpl +// List atomSites = MMCIFFileTools.convertChainToAtomSites(c, 1, "A", "A"); +// assertEquals(14, atomSites.size()); } @@ -816,19 +800,10 @@ public void testIntraResidueBondsBetweenAltlocs() throws IOException { "ATOM 1431 H HE2 B MET A 1 86 ? 7.346 -16.554 -2.998 0.53 23.03 ? 104 MET A HE2 1 \n" + "ATOM 1432 H HE3 B MET A 1 86 ? 6.996 -15.566 -4.437 0.53 23.03 ? 104 MET A HE3 1 "; - SimpleMMcifParser parser = new SimpleMMcifParser(); - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - parser.addMMcifConsumer(consumer); - FileParsingParameters params = new FileParsingParameters(); params.setCreateAtomBonds(true); - consumer.setFileParsingParameters(params); - - BufferedReader buf = new BufferedReader(new StringReader(mmcifData)); - parser.parse(buf); - buf.close(); - Structure s = consumer.getStructure(); + Structure s = StructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes()), params); Chain c = s.getPolyChains().get(0); assertEquals(1, c.getAtomGroups().size()); @@ -971,19 +946,10 @@ public void testInterResidueBondsBetweenAltlocs() throws IOException { "ATOM 1431 H HE2 B MET A 1 2 ? 7.346 -16.554 -2.998 0.53 23.03 ? 104 MET A HE2 1 \n" + "ATOM 1432 H HE3 B MET A 1 2 ? 6.996 -15.566 -4.437 0.53 23.03 ? 104 MET A HE3 1 "; - SimpleMMcifParser parser = new SimpleMMcifParser(); - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - parser.addMMcifConsumer(consumer); - FileParsingParameters params = new FileParsingParameters(); params.setCreateAtomBonds(true); - consumer.setFileParsingParameters(params); - - BufferedReader buf = new BufferedReader(new StringReader(mmcifData)); - parser.parse(buf); - buf.close(); - Structure s = consumer.getStructure(); + Structure s = StructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes()), params); Chain c = s.getPolyChains().get(0); assertEquals(2, c.getAtomGroups().size()); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java index 87fc80a314..d3c61130ae 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java @@ -25,6 +25,7 @@ package org.biojava.nbio.structure; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.io.CifFileReader; import org.biojava.nbio.structure.io.LocalPDBDirectory; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; @@ -54,7 +55,7 @@ public void setUp() throws IOException { }; List readers = new ArrayList(); - readers.add(new MMCIFFileReader(cache.getPath()) ); + readers.add(new CifFileReader(cache.getPath()) ); readers.add(new PDBFileReader(cache.getPath()) ); for(LocalPDBDirectory reader : readers) { reader.setFetchBehavior(cache.getFetchBehavior()); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java index d1b7b24122..9a3022d0a1 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java @@ -25,9 +25,9 @@ import java.util.List; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestDownloadChemCompProvider.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestDownloadChemCompProvider.java index bc2a8dcd41..3c1b1626db 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestDownloadChemCompProvider.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestDownloadChemCompProvider.java @@ -21,9 +21,9 @@ package org.biojava.nbio.structure; import org.biojava.nbio.core.util.FlatFileCache; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.LocalPDBDirectory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; import org.junit.Test; import static org.junit.Assert.*; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestNucleotides.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestNucleotides.java index dc865eb366..1eb7f88cfa 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestNucleotides.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestNucleotides.java @@ -25,12 +25,12 @@ package org.biojava.nbio.structure; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemCompProvider; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; +import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileReader; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.ChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; import org.junit.BeforeClass; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java index 6ba61088b4..0882ae08a1 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java @@ -51,12 +51,13 @@ import org.biojava.nbio.structure.StructureIdentifier; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.SubstructureIdentifier; +import org.biojava.nbio.structure.chem.ChemComp; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; +import org.biojava.nbio.structure.io.CifFileReader; import org.biojava.nbio.structure.io.LocalPDBDirectory; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; import org.biojava.nbio.structure.scop.ScopDatabase; import org.biojava.nbio.structure.scop.ScopFactory; import org.biojava.nbio.structure.test.util.GlobalsHelper; @@ -203,7 +204,7 @@ public void testNewInstanceWithTilder() throws Exception { public void testFetchBehavior() throws IOException, ParseException { // really more of a LocalPDBDirectory test, but throw it in with AtomCache String pdbId = "1hh0"; // A small structure, since we download it multiple times - LocalPDBDirectory reader = new MMCIFFileReader(cache.getPath()); + LocalPDBDirectory reader = new CifFileReader(cache.getPath()); // delete reader.deleteStructure(pdbId); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java index 79598bd410..72a8fb57a0 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java @@ -28,10 +28,10 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import static org.junit.Assert.*; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.junit.Test; import java.io.IOException; @@ -116,7 +116,7 @@ public void testNeighborIndicesFinding() throws StructureException, IOException } } } - + // for (int i = 0; i seqres) { for (Group g : seqres) { ChemComp c = g.getChemComp(); - sb.append(c.getOne_letter_code()); + sb.append(c.getOneLetterCode()); } return sb.toString(); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java index f64d5595a5..31d4b86dd8 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java @@ -44,12 +44,7 @@ import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.mmcif.MMCIFFileTools; -import org.biojava.nbio.structure.io.mmcif.MMcifParser; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; -import org.biojava.nbio.structure.io.mmcif.model.CIFLabel; -import org.biojava.nbio.structure.io.mmcif.model.IgnoreField; +import org.biojava.nbio.structure.io.cif.StructureConverter; import org.junit.Test; public class TestMMCIFWriting { @@ -77,46 +72,6 @@ public void test1A2C() throws IOException, StructureException { testRoundTrip("1A2C"); } - private static class DemoBean { - @IgnoreField - String not_a_field; - - @SuppressWarnings("unused")//used by reflection - String default_field; - - @CIFLabel(label="custom_label") - String custom_field; - - public void setNot_a_field(String not_a_field) { - this.not_a_field = not_a_field; - } - public void setDefault_field(String default_field) { - this.default_field = default_field; - } - public void setCustom_field(String custom_field) { - this.custom_field = custom_field; - } - } - - @Test - public void testBeanAnnotations() { - DemoBean bean = new DemoBean(); - bean.setCustom_field("custom_field"); - bean.setDefault_field(null); - bean.setNot_a_field("not_a_field"); - - - // Test (1) should have custom_label (@CIFLabel) - // (2) shouldn't have not_a_field (@IgnoreField) - String newline = System.getProperty("line.separator"); - String mmcif = MMCIFFileTools.toMMCIF("_demo", bean); - String expected = - "_demo.default_field ?" + newline - + "_demo.custom_label custom_field" + newline - + "#" + newline; - assertEquals(expected, mmcif); - } - private static void testRoundTrip(String pdbId) throws IOException, StructureException { AtomCache cache = new AtomCache(); @@ -138,21 +93,9 @@ private static void testRoundTrip(String pdbId) throws IOException, StructureExc fw.write(originalStruct.toMMCIF()); fw.close(); - - MMcifParser parser = new SimpleMMcifParser(); - - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - FileParsingParameters fileParsingParams = new FileParsingParameters(); fileParsingParams.setAlignSeqRes(true); - - consumer.setFileParsingParameters(fileParsingParams); - - parser.addMMcifConsumer(consumer); - - parser.parse(new BufferedReader(new FileReader(outputFile))); - - Structure readStruct = consumer.getStructure(); + Structure readStruct = StructureConverter.fromPath(outputFile.toPath(), params); assertNotNull(readStruct); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMmCIFSpecialCases.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMmCIFSpecialCases.java deleted file mode 100644 index 95bb0c29b9..0000000000 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMmCIFSpecialCases.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.io; - -//import static org.junit.Assert.*; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; - -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; -import org.junit.Test; - -public class TestMmCIFSpecialCases { - - /** - * This tests for cases where dots appear in integer fields. - * Unusual but it happens in some PDB entries like 1s32 - * See issue https://github.com/biojava/biojava/issues/368 - * @throws IOException - */ - @Test - public void testDotsInIntFields() throws IOException { - - // taken from 1s32 - String mmcifStr = - "data_\n" + - "loop_\n" + - "_struct_ref_seq_dif.align_id\n" + - "_struct_ref_seq_dif.pdbx_pdb_id_code\n"+ - "_struct_ref_seq_dif.mon_id\n"+ - "_struct_ref_seq_dif.pdbx_pdb_strand_id\n"+ - "_struct_ref_seq_dif.seq_num\n"+ // integer field that contains '.' - "_struct_ref_seq_dif.pdbx_seq_db_name\n"+ - "_struct_ref_seq_dif.pdbx_seq_db_accession_code\n"+ - "_struct_ref_seq_dif.db_mon_id\n"+ - "_struct_ref_seq_dif.pdbx_seq_db_seq_num\n"+ - "_struct_ref_seq_dif.details\n"+ - "_struct_ref_seq_dif.pdbx_auth_seq_num\n"+ - "_struct_ref_seq_dif.pdbx_pdb_ins_code\n"+ - "_struct_ref_seq_dif.pdbx_ordinal\n"+ - "1 1S32 . A . GB 30268544 MET 1 'INTIATING METHIONINE' ? ? 1\n"+ - "2 1S32 . E . GB 30268544 MET 1 'INTIATING METHIONINE' ? ? 2\n"+ - "3 1S32 . B . UNP P02304 MET 0 'INTIATING METHIONINE' ? ? 3\n"+ - "4 1S32 . F . UNP P02304 MET 0 'INTIATING METHIONINE' ? ? 4\n"+ - "5 1S32 . C . GB 30268540 MET 1 'INTIATING METHIONINE' ? ? 5\n"+ - "6 1S32 . G . GB 30268540 MET 1 'INTIATING METHIONINE' ? ? 6\n"+ - "7 1S32 . D . GB 30268542 MET 1 'INTIATING METHIONINE' ? ? 7\n"+ - "8 1S32 . H . GB 30268542 MET 1 'INTIATING METHIONINE' ? ? 8" ; - - SimpleMMcifParser parser = new SimpleMMcifParser(); - - BufferedReader buf = new BufferedReader(new StringReader(mmcifStr)); - - parser.parse(buf); - - buf.close(); - - // nothing to assert, the test just makes sure it doesn't throw an exception - - - } - -} diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java index 2e9ecc6140..b0c7c8fe55 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java @@ -38,9 +38,7 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.mmcif.MMcifParser; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; +import org.biojava.nbio.structure.io.cif.StructureConverter; import org.biojava.nbio.structure.xtal.CrystalCell; import org.junit.Test; @@ -207,20 +205,10 @@ private void checkChains(Structure s) { @Test public void testPhenixCifFile() throws IOException { InputStream inStream = new GZIPInputStream(this.getClass().getResourceAsStream("/org/biojava/nbio/structure/io/4lup_phenix_output.cif.gz")); - MMcifParser parser = new SimpleMMcifParser(); - - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); FileParsingParameters fileParsingParams = new FileParsingParameters(); fileParsingParams.setAlignSeqRes(true); - - consumer.setFileParsingParameters(fileParsingParams); - - parser.addMMcifConsumer(consumer); - - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - - Structure s = consumer.getStructure(); + Structure s = StructureConverter.fromInputStream(inStream, fileParsingParams); assertNotNull(s); @@ -344,12 +332,7 @@ public void testNewLigandChain() throws IOException { int expectedNumLigands = 1; assertEquals(expectedNumLigands, c1.getAtomGroups().size()); - MMcifParser mmcifpars = new SimpleMMcifParser(); - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - consumer.setFileParsingParameters(params); - mmcifpars.addMMcifConsumer(consumer); - mmcifpars.parse(cifStream) ; - Structure s2 = consumer.getStructure(); + Structure s2 = StructureConverter.fromInputStream(cifStream, params); // The chain B should be present with 1 ligand HEM Chain c2 = s2.getNonPolyChainsByPDB("B").get(0); @@ -389,11 +372,7 @@ public void testWaterOnlyChainCif() throws IOException { // following file is cut-down versions of 4a10 InputStream cifStream = new GZIPInputStream(this.getClass().getResourceAsStream("/org/biojava/nbio/structure/io/4a10_short.cif.gz")); - MMcifParser mmcifpars = new SimpleMMcifParser(); - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - mmcifpars.addMMcifConsumer(consumer); - mmcifpars.parse(cifStream) ; - Structure s2 = consumer.getStructure(); + Structure s2 = StructureConverter.fromInputStream(cifStream); assertEquals(2, s2.getChains().size()); @@ -451,13 +430,7 @@ public void testStructureWithBranchedEntities() throws IOException { URL url = new URL("https://raw.githubusercontent.com/pdbxmmcifwg/carbohydrate-extension/master/examples/models/1B5F-carb.cif"); InputStream inStream = url.openStream(); - MMcifParser parser = new SimpleMMcifParser(); - - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - parser.addMMcifConsumer(consumer); - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - - Structure structure = consumer.getStructure(); + Structure structure = StructureConverter.fromInputStream(inStream); assertEquals(7, structure.getEntityInfos().size()); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java index c97aed8d88..2a997118f2 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java @@ -31,9 +31,9 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.chem.PolymerType; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; +import org.biojava.nbio.structure.chem.PolymerType; import org.junit.Test; /** diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java index 4791f21fe7..89af60dc65 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java @@ -33,6 +33,8 @@ import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.align.util.UserConfiguration; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ZipChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileReader; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java index 780aad41c4..94a9a18fa5 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java @@ -30,6 +30,8 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; import org.junit.Test; /** diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java index ab5268578c..9e850585b6 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java @@ -20,6 +20,8 @@ */ package org.biojava.nbio.structure.io.mmtf; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.junit.Test; import static org.junit.Assert.*; @@ -36,8 +38,6 @@ import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; /** * Test bond finding in BioJava diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java index f787b1e908..96f9dd8c43 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java @@ -39,12 +39,10 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.MMcifParser; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifConsumer; -import org.biojava.nbio.structure.io.mmcif.SimpleMMcifParser; +import org.biojava.nbio.structure.io.cif.StructureConverter; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; import org.junit.Test; @@ -76,7 +74,7 @@ public void testRoundTrip() throws IOException, StructureException { params.setParseBioAssembly(true); cache.setFileParsingParams(params); cache.setUseMmCif(true); - + StructureIO.setAtomCache(cache); ChemCompGroupFactory.setChemCompProvider(new DownloadChemCompProvider()); @@ -146,11 +144,11 @@ private boolean checkIfAtomsSame(Structure structOne, Structure structTwo) { System.out.println(groupTwo.getPDBName() + " and type: "+groupTwo.getType());; } // Check the single letter amino acid is correct - if(groupOne.getChemComp().getOne_letter_code().length()==1 && groupTwo.getChemComp().getOne_letter_code().length()==1){ - if(!groupOne.getChemComp().getOne_letter_code().equals(groupTwo.getChemComp().getOne_letter_code())){ + if(groupOne.getChemComp().getOneLetterCode().length()==1 && groupTwo.getChemComp().getOneLetterCode().length()==1){ + if(!groupOne.getChemComp().getOneLetterCode().equals(groupTwo.getChemComp().getOneLetterCode())){ System.out.println(groupOne.getPDBName()); } - assertEquals(groupOne.getChemComp().getOne_letter_code(), groupTwo.getChemComp().getOne_letter_code()); + assertEquals(groupOne.getChemComp().getOneLetterCode(), groupTwo.getChemComp().getOneLetterCode()); } assertEquals(groupOne.getType(), groupTwo.getType()); assertEquals(groupOne.getPDBName(), groupTwo.getPDBName()); @@ -307,7 +305,7 @@ private void checkSeqresGroups(Chain chainOne, Chain chainTwo) { Group gTwo = chainTwo.getSeqResGroup(i); assertNotNull(gOne.getChemComp()); assertNotNull(gTwo.getChemComp()); - assertEquals(gOne.getChemComp().getOne_letter_code(), gTwo.getChemComp().getOne_letter_code()); + assertEquals(gOne.getChemComp().getOneLetterCode(), gTwo.getChemComp().getOneLetterCode()); assertEquals(gOne.getResidueNumber(), gTwo.getResidueNumber()); //assertEquals(gOne.getPDBName(), gTwo.getPDBName()); @@ -361,13 +359,7 @@ public void testStructWithBranchedEntitiesRoundTrip() throws IOException { URL url = new URL("https://raw.githubusercontent.com/pdbxmmcifwg/carbohydrate-extension/master/examples/models/1B5F-carb.cif"); InputStream inStream = url.openStream(); - MMcifParser parser = new SimpleMMcifParser(); - - SimpleMMcifConsumer consumer = new SimpleMMcifConsumer(); - parser.addMMcifConsumer(consumer); - parser.parse(new BufferedReader(new InputStreamReader(inStream))); - - Structure structure = consumer.getStructure(); + Structure structure = StructureConverter.fromInputStream(inStream); AdapterToStructureData writerToEncoder = new AdapterToStructureData(); new MmtfStructureWriter(structure, writerToEncoder); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java index ac2d81e8d5..0bed40a6be 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java @@ -11,16 +11,16 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.*; /** * Test the Biojava MMTF reader. - * + * * @author Anthony Bradley * @author Aleix Lafita * @@ -32,50 +32,50 @@ public class TestMmtfStructureReader { */ @Test public void testRead() throws IOException { - + // Get the MMTF file from the resources folder ClassLoader classLoader = getClass().getClassLoader(); String resource = "org/biojava/nbio/structure/io/mmtf/4CUP.mmtf"; - + // Load the structure into memory Structure structure = MmtfActions.readFromFile(( Paths.get(classLoader.getResource(resource).getPath()))); - + // Check header properties of the structure assertEquals(structure.getPDBCode(), "4CUP"); - assertEquals(MmtfUtils.dateToIsoString(structure.getPDBHeader().getDepDate()), + assertEquals(MmtfUtils.dateToIsoString(structure.getPDBHeader().getDepDate()), "2014-03-21"); - + assertEquals(structure.getChains().size(), 6); } - + /** * Compare structures loaded from MMCIF and MMTF files. */ @Test public void compareMmcif() throws IOException, StructureException { - + // Get the MMTF and MMCIF files from the resources folder ClassLoader classLoader = getClass().getClassLoader(); String resource = "org/biojava/nbio/structure/io/mmtf/4CUP"; - + // Load the structures into memory Structure mmtf = MmtfActions.readFromFile(( Paths.get(classLoader.getResource(resource + ".mmtf").getPath()))); Structure mmcif = StructureIO.getStructure(classLoader.getResource(resource + ".cif").getPath()); - + // Compare the dates of the structure - assertEquals(mmcif.getPDBHeader().getDepDate(), + assertEquals(mmcif.getPDBHeader().getDepDate(), mmtf.getPDBHeader().getDepDate()); - + // Compare the experimental method - assertEquals(mmcif.getPDBHeader().getExperimentalTechniques(), + assertEquals(mmcif.getPDBHeader().getExperimentalTechniques(), mmtf.getPDBHeader().getExperimentalTechniques()); - + // Compare the SEQRES, see issue https://github.com/biojava/biojava/issues/671 - assertEquals(mmcif.getChainByIndex(0).getSeqResSequence(), + assertEquals(mmcif.getChainByIndex(0).getSeqResSequence(), mmtf.getChainByIndex(0).getSeqResSequence()); - + } /** diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureWriter.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureWriter.java index 6f98b250d3..efc9929916 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureWriter.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureWriter.java @@ -37,7 +37,7 @@ import org.biojava.nbio.structure.ResidueNumber; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureImpl; -import org.biojava.nbio.structure.io.mmcif.model.ChemComp; +import org.biojava.nbio.structure.chem.ChemComp; import org.junit.Rule; import org.junit.Test; import static org.junit.Assert.*; @@ -95,7 +95,7 @@ public void testWrite() throws IOException { group.setPDBName("FKF"); ChemComp chemComp = new ChemComp(); chemComp.setType("TYPfdl"); - chemComp.setOne_letter_code("A"); + chemComp.setOneLetterCode("A"); group.setChemComp(chemComp); // Create one Atom diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/redmine/Test1DARSeqAlign.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/redmine/Test1DARSeqAlign.java index 4f351d3c74..0aefbc5713 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/redmine/Test1DARSeqAlign.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/redmine/Test1DARSeqAlign.java @@ -23,10 +23,10 @@ import org.biojava.nbio.structure.*; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemCompProvider; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.ChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import org.junit.Test; import static org.junit.Assert.*; @@ -50,7 +50,7 @@ public void test1DAR() throws StructureException, IOException { boolean usingReducedChemCompProvider = false; - ChemCompProvider ccp =ChemCompGroupFactory.getChemCompProvider(); + ChemCompProvider ccp = ChemCompGroupFactory.getChemCompProvider(); if (ccp.getClass().getName().contains("ReducedChemCompProvider") ) { usingReducedChemCompProvider = true; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/test/util/GlobalsHelper.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/test/util/GlobalsHelper.java index 9d7e5ae57d..0d5766d8f9 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/test/util/GlobalsHelper.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/test/util/GlobalsHelper.java @@ -28,9 +28,9 @@ import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.ChemCompProvider; -import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; +import org.biojava.nbio.structure.chem.ChemCompGroupFactory; +import org.biojava.nbio.structure.chem.ChemCompProvider; +import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.scop.ScopDatabase; import org.biojava.nbio.structure.scop.ScopFactory; From b992e74865f878dd054e367e1a3bb05ae6897707 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Mon, 25 Jan 2021 11:14:35 -0800 Subject: [PATCH 188/769] metal parsing --- .../nbio/structure/io/cif/MetalBondConsumerImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java index 28833bc559..d9d03a9590 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java @@ -31,10 +31,10 @@ public void finish() { @Override public void consume(Category category) { - StrColumn atomType1 = (StrColumn) category.getColumn(""); - StrColumn atomType2 = (StrColumn) category.getColumn(""); - FloatColumn lowerLimit = (FloatColumn) category.getColumn(""); - FloatColumn upperLimit = (FloatColumn) category.getColumn(""); + StrColumn atomType1 = (StrColumn) category.getColumn("atom_type_1"); + StrColumn atomType2 = (StrColumn) category.getColumn("atom_type_2"); + FloatColumn lowerLimit = (FloatColumn) category.getColumn("lower_limit"); + FloatColumn upperLimit = (FloatColumn) category.getColumn("upper_limit"); for (int i = 0; i < category.getRowCount(); i++) { MetalBondDistance d = new MetalBondDistance(); From 61bd8e8f51479951d4dd13b661f58b0f9c56c0b9 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Mon, 25 Jan 2021 12:50:40 -0800 Subject: [PATCH 189/769] new filetype param --- .../structure/test/StructureToolsTest.java | 4 +- .../biojava/nbio/structure/test/Test1o2f.java | 3 +- .../test/io/TestAtomCachePerformance.java | 5 +- .../structure/test/io/TestBioassemblies.java | 9 +- .../test/io/TestCrystallographicMetadata.java | 7 +- .../test/io/TestLongPdbVsMmCifParsing.java | 4 +- .../io/TestStructWithMultiparentChemComp.java | 3 +- .../TestQuatSymmetryDetectorExamples.java | 9 +- .../test/xtal/TestCrystalBuilder.java | 17 +- .../main/java/demo/DemoQuatSymmetryJmol.java | 3 +- .../main/java/demo/DemoShowLargeAssembly.java | 3 +- .../src/main/java/demo/DemoAsa.java | 3 +- .../src/main/java/demo/DemoContacts.java | 2 +- .../main/java/demo/DemoCrystalInterfaces.java | 5 +- .../src/main/java/demo/DemoLoadSecStruc.java | 3 +- .../src/main/java/demo/DemoMMCIFReader.java | 5 +- .../nbio/structure/StructureFiletype.java | 36 ++++ .../biojava/nbio/structure/StructureIO.java | 85 ++------ .../biojava/nbio/structure/URLIdentifier.java | 74 +++---- .../nbio/structure/align/util/AtomCache.java | 198 +++++++----------- .../align/util/UserConfiguration.java | 166 ++++++--------- .../biojava/nbio/structure/chem/ChemComp.java | 3 +- .../nbio/structure/io/mmtf/MmtfUtils.java | 5 +- .../org/biojava/nbio/structure/Test2JA5.java | 4 +- .../biojava/nbio/structure/TestAltLocs.java | 14 +- .../biojava/nbio/structure/TestAtomCache.java | 36 ++-- .../org/biojava/nbio/structure/TestBond.java | 2 +- .../biojava/nbio/structure/TestCloning.java | 2 +- .../structure/TestEntityResIndexMapping.java | 4 +- .../structure/TestExperimentalTechniques.java | 16 +- .../structure/TestLoadStructureFromURL.java | 3 +- .../nbio/structure/TestParsingCalcium.java | 2 +- .../TestStructureCrossReferences.java | 8 +- .../structure/align/util/AtomCacheTest.java | 5 +- .../structure/io/TestDifficultMmCIFFiles.java | 13 +- .../nbio/structure/io/TestHardBioUnits.java | 4 +- .../nbio/structure/io/TestHeaderOnly.java | 9 +- .../nbio/structure/io/TestMMCIFWriting.java | 3 +- .../io/TestMMcifOrganismParsing.java | 3 +- .../structure/io/TestNonDepositedFiles.java | 3 +- .../structure/io/TestParseMmCIFFeatures.java | 9 +- .../structure/io/TestParseMmCIFLigands.java | 9 +- .../nbio/structure/io/TestParseOnAsymId.java | 3 +- .../io/TestQuaternaryStructureProviders.java | 8 +- .../nbio/structure/io/TestTitleParsing.java | 5 +- .../io/TestWriteLargeCoordinatePDB.java | 3 +- .../io/mmcif/TestChemCompProvider.java | 6 +- .../io/mmcif/TestEntityNameAndType.java | 3 +- .../io/mmcif/TestParseInternalChainId.java | 3 +- .../io/mmcif/TestParseMmcifHeader.java | 3 +- .../structure/io/mmtf/TestBondFinding.java | 3 +- .../structure/io/mmtf/TestMmtfRoundTrip.java | 3 +- .../io/mmtf/TestMmtfStructureReader.java | 4 +- .../nbio/structure/xtal/TestCrystalInfo.java | 16 +- .../xtal/TestInterfaceClustering.java | 5 +- 55 files changed, 392 insertions(+), 474 deletions(-) create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/StructureFiletype.java diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java index 170694a6e2..510b071200 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java @@ -186,12 +186,12 @@ public void testCAmmCIF() throws StructureException { //mmCIF files left justify their atom names (eg "CA "), so can have different behavior AtomCache pdbCache = new AtomCache(); - pdbCache.setUseMmCif(false); + pdbCache.setFiletype(StructureFiletype.PDB); FileParsingParameters params = new FileParsingParameters(); pdbCache.setFileParsingParams(params); AtomCache mmcifCache = new AtomCache(); - mmcifCache.setUseMmCif(true); + mmcifCache.setFiletype(StructureFiletype.CIF); FileParsingParameters params2 = new FileParsingParameters(); mmcifCache.setFileParsingParams(params2); diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1o2f.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1o2f.java index 7acde4166e..af1ec695f7 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1o2f.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1o2f.java @@ -22,6 +22,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; @@ -38,7 +39,7 @@ public class Test1o2f { @Before public void setUp() throws Exception { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); cache.setFetchBehavior(FetchBehavior.FETCH_FILES); StructureIO.setAtomCache(cache); String pdbId = "1O2F"; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestAtomCachePerformance.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestAtomCachePerformance.java index 7df8c8bb10..03bf297484 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestAtomCachePerformance.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestAtomCachePerformance.java @@ -22,6 +22,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.junit.BeforeClass; @@ -94,14 +95,14 @@ public void testDownload() throws IOException, StructureException { } private Structure getCifStructure(String pdbId) throws IOException, StructureException { - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); return cache.getStructure(pdbId); } private Structure getPdbStructure(String pdbId) throws IOException, StructureException { - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); return cache.getStructure(pdbId); diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestBioassemblies.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestBioassemblies.java index 23a73a7ae8..001dd5434e 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestBioassemblies.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestBioassemblies.java @@ -28,6 +28,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; @@ -47,7 +48,7 @@ public void test1E17() throws IOException, StructureException { AtomCache prevAtomCache = StructureIO.getAtomCache(); AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); List multiModelBioAssemblies = StructureIO.getBiologicalAssemblies("1E17", true); @@ -79,7 +80,7 @@ public void test4TTX() throws IOException, StructureException { AtomCache prevAtomCache = StructureIO.getAtomCache(); AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); List multiModelBioAssemblies = StructureIO.getBiologicalAssemblies("4TTX", true); @@ -124,7 +125,7 @@ public void test1M4X() throws IOException, StructureException { AtomCache prevAtomCache = StructureIO.getAtomCache(); AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); Structure flattenedBioAssembly5 = StructureIO.getBiologicalAssembly("1M4X" , 5); @@ -153,7 +154,7 @@ public void test4OPJ() throws IOException, StructureException { AtomCache prevAtomCache = StructureIO.getAtomCache(); AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); List multiModelBioAssemblies = StructureIO.getBiologicalAssemblies("4OPJ", true); diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestCrystallographicMetadata.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestCrystallographicMetadata.java index 26f83b7a28..c41ac34410 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestCrystallographicMetadata.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestCrystallographicMetadata.java @@ -20,6 +20,7 @@ */ package org.biojava.nbio.structure.test.io; +import org.biojava.nbio.structure.StructureFiletype; import org.junit.Test; import static org.junit.Assert.*; @@ -46,7 +47,7 @@ public void test4hhb() throws Exception { AtomCache cache = new AtomCache(); // at the moment implemented only in mmcif - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); Structure s = StructureIO.getStructure("4hhb"); @@ -64,7 +65,7 @@ public void test1smt() throws Exception { AtomCache cache = new AtomCache(); // at the moment implemented only in mmcif - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); Structure s = StructureIO.getStructure("1smt"); @@ -82,7 +83,7 @@ public void test1smt() throws Exception { public void test1zna() throws Exception { AtomCache cache = new AtomCache(); // at the moment implemented only in mmcif - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); Structure s = StructureIO.getStructure("1zna"); diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestLongPdbVsMmCifParsing.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestLongPdbVsMmCifParsing.java index daadcc7023..fc529b75e3 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestLongPdbVsMmCifParsing.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestLongPdbVsMmCifParsing.java @@ -567,7 +567,7 @@ private void testSingleChain(Chain cPdb, Chain cCif) { private Structure getPdbStructure(String pdbId) throws IOException, StructureException { - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); // set parsing params here: params.setAlignSeqRes(true); //params.setLoadChemCompInfo(true); @@ -578,7 +578,7 @@ private Structure getPdbStructure(String pdbId) throws IOException, StructureExc } private Structure getCifStructure(String pdbId) throws IOException, StructureException { - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); // set parsing params here: params.setAlignSeqRes(true); //params.setLoadChemCompInfo(true); diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestStructWithMultiparentChemComp.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestStructWithMultiparentChemComp.java index cbedb5b108..83059e7ea4 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestStructWithMultiparentChemComp.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestStructWithMultiparentChemComp.java @@ -20,6 +20,7 @@ */ package org.biojava.nbio.structure.test.io; +import org.biojava.nbio.structure.StructureFiletype; import org.junit.Test; import static org.junit.Assert.*; @@ -35,7 +36,7 @@ public class TestStructWithMultiparentChemComp { public void test4Q7U() throws Exception { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); Structure s = StructureIO.getStructure("4q7u"); diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java index b5a8a5a2e1..3c153cde22 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java @@ -27,6 +27,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.AtomCache; @@ -146,7 +147,7 @@ public void testPseudosymmetry() throws IOException, StructureException { public void testLocal() throws IOException, StructureException { AtomCache atomCache = new AtomCache(); - atomCache.setUseMmtf(true); + atomCache.setFiletype(StructureFiletype.MMTF); List testIds = new ArrayList<>(); List testStoichiometries = new ArrayList<>(); @@ -376,8 +377,7 @@ public void testPseudoIdentity95() throws IOException, StructureException { @Test public void testSymDetectionWithClusteringByEntityId() throws IOException, StructureException { AtomCache cache = new AtomCache(); - cache.setUseMmtf(false); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); cache.setFileParsingParams(params); @@ -404,8 +404,7 @@ public void testSymDetectionWithClusteringByEntityId() throws IOException, Struc @Test public void testSymDetectionPerformanceLargeCapsid() throws IOException, StructureException { AtomCache cache = new AtomCache(); - cache.setUseMmtf(false); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); params.setParseBioAssembly(true); diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/xtal/TestCrystalBuilder.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/xtal/TestCrystalBuilder.java index 898e108a8e..4851c03ba9 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/xtal/TestCrystalBuilder.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/xtal/TestCrystalBuilder.java @@ -22,6 +22,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.contact.StructureInterfaceList; @@ -46,7 +47,7 @@ public void test1NMR() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s1 = StructureIO.getStructure("1NMR"); CrystalBuilder cb = new CrystalBuilder(s1); @@ -64,7 +65,7 @@ public void test1B8G() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s1 = StructureIO.getStructure("1B8G"); CrystalBuilder cb = new CrystalBuilder(s1); StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5); @@ -82,7 +83,7 @@ public void test2MFZ() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s1 = StructureIO.getStructure("2MFZ"); CrystalBuilder cb = new CrystalBuilder(s1); StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5); @@ -99,7 +100,7 @@ public void test4MF8() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s1 = StructureIO.getStructure("4MF8"); CrystalBuilder cb = new CrystalBuilder(s1); StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5); @@ -112,7 +113,7 @@ public void test1AUY() throws IOException, StructureException { // a virus with NCS operators AtomCache cache = new AtomCache(); StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s1 = StructureIO.getStructure("1AUY"); Map chainNcsOps = new HashMap<>(); @@ -139,7 +140,7 @@ public void test1A37() throws IOException, StructureException { // a smaller structure with NCS operators AtomCache cache = new AtomCache(); StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s1 = StructureIO.getStructure("1A37"); Map chainNcsOps = new HashMap<>(); @@ -164,7 +165,7 @@ public void test2H2Z() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s1 = StructureIO.getStructure("2H2Z"); CrystalBuilder cb = new CrystalBuilder(s1); StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5); @@ -181,7 +182,7 @@ public void test4HHB() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s1 = StructureIO.getStructure("4HHB"); CrystalBuilder cb = new CrystalBuilder(s1); StructureInterfaceList interfaces = cb.getUniqueInterfaces(5.5); diff --git a/biojava-structure-gui/src/main/java/demo/DemoQuatSymmetryJmol.java b/biojava-structure-gui/src/main/java/demo/DemoQuatSymmetryJmol.java index deadf35e43..674c846d4a 100644 --- a/biojava-structure-gui/src/main/java/demo/DemoQuatSymmetryJmol.java +++ b/biojava-structure-gui/src/main/java/demo/DemoQuatSymmetryJmol.java @@ -22,6 +22,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.cluster.SubunitClustererMethod; import org.biojava.nbio.structure.cluster.SubunitClustererParameters; @@ -65,7 +66,7 @@ public static void main(String[] args) throws IOException, // Download the biological assembly AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure structure = cache.getStructure("BIO:" + name + ":1"); QuatSymmetryParameters sp = new QuatSymmetryParameters(); diff --git a/biojava-structure-gui/src/main/java/demo/DemoShowLargeAssembly.java b/biojava-structure-gui/src/main/java/demo/DemoShowLargeAssembly.java index c626e90f8a..4aa053e70a 100644 --- a/biojava-structure-gui/src/main/java/demo/DemoShowLargeAssembly.java +++ b/biojava-structure-gui/src/main/java/demo/DemoShowLargeAssembly.java @@ -1,6 +1,7 @@ package demo; import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; @@ -77,7 +78,7 @@ public static Structure readStructure(String pdbId, int bioAssemblyId) { // we just need this to track where to store PDB files // this checks the PDB_DIR property (and uses a tmp location if not set) AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters p = cache.getFileParsingParams(); // some bio assemblies are large, we want an all atom representation and avoid diff --git a/biojava-structure/src/main/java/demo/DemoAsa.java b/biojava-structure/src/main/java/demo/DemoAsa.java index caeacbd5d0..1df3d9feeb 100644 --- a/biojava-structure/src/main/java/demo/DemoAsa.java +++ b/biojava-structure/src/main/java/demo/DemoAsa.java @@ -24,6 +24,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.asa.AsaCalculator; @@ -46,7 +47,7 @@ public static void main(String[] args) throws IOException, StructureException { private static void demoAsa(String pdbCode, int numThreads) throws IOException, StructureException { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); diff --git a/biojava-structure/src/main/java/demo/DemoContacts.java b/biojava-structure/src/main/java/demo/DemoContacts.java index 0d2d95ab82..0eed99e807 100644 --- a/biojava-structure/src/main/java/demo/DemoContacts.java +++ b/biojava-structure/src/main/java/demo/DemoContacts.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws IOException, StructureException { private static void demoContacts(String pdbCode) throws IOException, StructureException { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); diff --git a/biojava-structure/src/main/java/demo/DemoCrystalInterfaces.java b/biojava-structure/src/main/java/demo/DemoCrystalInterfaces.java index caeef006ed..76fd4f6823 100644 --- a/biojava-structure/src/main/java/demo/DemoCrystalInterfaces.java +++ b/biojava-structure/src/main/java/demo/DemoCrystalInterfaces.java @@ -23,6 +23,7 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.contact.*; import org.biojava.nbio.structure.io.FileParsingParameters; @@ -60,12 +61,10 @@ public class DemoCrystalInterfaces { * @param args */ public static void main(String[] args) throws Exception { - - String pdbCode = "1smt"; AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); diff --git a/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java b/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java index 8684ba1257..e0efc501c7 100644 --- a/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java +++ b/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java @@ -25,6 +25,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.secstruc.DSSPParser; @@ -55,7 +56,7 @@ public static void main(String[] args) throws IOException, cache.setFileParsingParams(params); // Use PDB format, because SS cannot be parsed from mmCIF yet - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.CIF); // The loaded Structure contains the SS assigned by Author (simple) Structure s = cache.getStructure(pdbID); diff --git a/biojava-structure/src/main/java/demo/DemoMMCIFReader.java b/biojava-structure/src/main/java/demo/DemoMMCIFReader.java index b94dbd2e19..e6b5eab186 100644 --- a/biojava-structure/src/main/java/demo/DemoMMCIFReader.java +++ b/biojava-structure/src/main/java/demo/DemoMMCIFReader.java @@ -57,15 +57,12 @@ public void loadSimple(){ String pdbId = "4hhb"; AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); - try { Structure s = StructureIO.getStructure(pdbId); - System.out.println(pdbId + " has nr atoms: " + StructureTools.getNrAtoms(s)); - } catch (Exception e){ e.printStackTrace(); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureFiletype.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureFiletype.java new file mode 100644 index 0000000000..6d56257f24 --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureFiletype.java @@ -0,0 +1,36 @@ +package org.biojava.nbio.structure; + +import org.biojava.nbio.structure.io.BcifFileReader; +import org.biojava.nbio.structure.io.CifFileReader; +import org.biojava.nbio.structure.io.MMTFFileReader; +import org.biojava.nbio.structure.io.PDBFileReader; + +import java.util.Collections; +import java.util.List; + +/** + * An enum of supported file formats. + */ +public enum StructureFiletype { + PDB(new PDBFileReader().getExtensions()), + CIF(new CifFileReader().getExtensions()), + BCIF(new BcifFileReader().getExtensions()), + MMTF(new MMTFFileReader().getExtensions()), + UNKNOWN(Collections.emptyList()); + + private final List extensions; + + /** + * @param extensions List of supported extensions, including leading period + */ + StructureFiletype(List extensions) { + this.extensions = extensions; + } + + /** + * @return a list of file extensions associated with this type + */ + public List getExtensions() { + return extensions; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java index e0592dfae3..fb2967b101 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java @@ -20,16 +20,11 @@ */ package org.biojava.nbio.structure; +import org.biojava.nbio.structure.align.util.AtomCache; + import java.io.IOException; -import java.util.Collections; import java.util.List; -import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.BcifFileReader; -import org.biojava.nbio.structure.io.CifFileReader; -import org.biojava.nbio.structure.io.PDBFileReader; -import org.rcsb.cif.binary.BinaryCifReader; - /** * A class that provides static access methods for easy lookup of protein structure related components * @@ -38,12 +33,8 @@ * @since 3.0.5 */ public class StructureIO { - - //private static final Logger logger = LoggerFactory.getLogger(StructureIO.class); - private static AtomCache cache ; - /** * Loads a structure based on a name. Supported naming conventions are: * @@ -94,22 +85,16 @@ public class StructureIO { * @throws StructureException The name appeared valid but did not correspond to a structure. * Also thrown by some submethods upon errors, eg for poorly formatted subranges. */ - public static Structure getStructure(String name) throws IOException, StructureException{ - + public static Structure getStructure(String name) throws IOException, StructureException { checkInitAtomCache(); - // delegate this functionality to AtomCache... - return cache.getStructure(name); - } - private static void checkInitAtomCache() { - if ( cache == null){ + if (cache == null) { cache = new AtomCache(); } - } public static void setAtomCache(AtomCache c){ @@ -121,7 +106,6 @@ public static AtomCache getAtomCache() { return cache; } - /** * Returns the first biological assembly that is available for the given PDB id. *

      @@ -146,15 +130,10 @@ public static AtomCache getAtomCache() { * @throws StructureException * @throws IOException */ - public static Structure getBiologicalAssembly(String pdbId, boolean multiModel) throws IOException, StructureException{ - + public static Structure getBiologicalAssembly(String pdbId, boolean multiModel) throws IOException, StructureException { checkInitAtomCache(); - pdbId = pdbId.toLowerCase(); - - Structure s = cache.getBiologicalAssembly(pdbId, multiModel); - - return s; + return cache.getBiologicalAssembly(pdbId, multiModel); } /** @@ -170,7 +149,7 @@ public static Structure getBiologicalAssembly(String pdbId, boolean multiModel) * @throws StructureException * @throws IOException */ - public static Structure getBiologicalAssembly(String pdbId) throws IOException, StructureException{ + public static Structure getBiologicalAssembly(String pdbId) throws IOException, StructureException { return getBiologicalAssembly(pdbId, AtomCache.DEFAULT_BIOASSEMBLY_STYLE); } @@ -195,14 +174,9 @@ public static Structure getBiologicalAssembly(String pdbId) throws IOException, * @throws IOException */ public static Structure getBiologicalAssembly(String pdbId, int biolAssemblyNr, boolean multiModel) throws IOException, StructureException { - checkInitAtomCache(); - pdbId = pdbId.toLowerCase(); - - Structure s = cache.getBiologicalAssembly(pdbId, biolAssemblyNr, multiModel); - - return s; + return cache.getBiologicalAssembly(pdbId, biolAssemblyNr, multiModel); } /** @@ -218,7 +192,6 @@ public static Structure getBiologicalAssembly(String pdbId, int biolAssemblyNr) return getBiologicalAssembly(pdbId, biolAssemblyNr, AtomCache.DEFAULT_BIOASSEMBLY_STYLE); } - /** * Returns all biological assemblies for the given PDB id. *

      @@ -241,15 +214,9 @@ public static Structure getBiologicalAssembly(String pdbId, int biolAssemblyNr) * @since 5.0 */ public static List getBiologicalAssemblies(String pdbId, boolean multiModel) throws IOException, StructureException { - checkInitAtomCache(); - pdbId = pdbId.toLowerCase(); - - List s = cache.getBiologicalAssemblies(pdbId, multiModel); - - return s; - + return cache.getBiologicalAssemblies(pdbId, multiModel); } /** @@ -267,7 +234,6 @@ public static List getBiologicalAssemblies(String pdbId) throws IOExc return getBiologicalAssemblies(pdbId, AtomCache.DEFAULT_BIOASSEMBLY_STYLE); } - private static final String FILE_SEPARATOR = System.getProperty("file.separator"); /** @@ -275,34 +241,11 @@ public static List getBiologicalAssemblies(String pdbId) throws IOExc * * @param pathToPDBFiles */ - public static void setPdbPath(String pathToPDBFiles){ - - if ( ! pathToPDBFiles.endsWith(FILE_SEPARATOR)) + public static void setPdbPath(String pathToPDBFiles) { + if (!pathToPDBFiles.endsWith(FILE_SEPARATOR)) pathToPDBFiles += FILE_SEPARATOR; } - - public static enum StructureFiletype { - PDB( (new PDBFileReader()).getExtensions()), - CIF(new CifFileReader().getExtensions()), - BCIF(new BcifFileReader().getExtensions()), - UNKNOWN(Collections.emptyList()); - - private List extensions; - /** - * @param extensions List of supported extensions, including leading period - */ - private StructureFiletype(List extensions) { - this.extensions = extensions; - } - /** - * @return a list of file extensions associated with this type - */ - public List getExtensions() { - return extensions; - } - } - /** * Attempts to guess the type of a structure file based on the extension * @param filename @@ -310,9 +253,9 @@ public List getExtensions() { */ public static StructureFiletype guessFiletype(String filename) { String lower = filename.toLowerCase(); - for(StructureFiletype type : StructureFiletype.values()) { - for(String ext : type.getExtensions()) { - if(lower.endsWith(ext.toLowerCase())) { + for (StructureFiletype type : StructureFiletype.values()) { + for (String ext : type.getExtensions()) { + if (lower.endsWith(ext.toLowerCase())) { return type; } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java index a36e93b508..00b624d95f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java @@ -20,10 +20,11 @@ */ package org.biojava.nbio.structure; -import org.biojava.nbio.structure.StructureIO.StructureFiletype; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.PDBFileReader; import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.mmtf.MmtfActions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,13 +58,11 @@ * */ public class URLIdentifier implements StructureIdentifier { - private static final long serialVersionUID = -5161230822868926035L; - private static final Logger logger = LoggerFactory.getLogger(URLIdentifier.class); // Used for guessing the PDB ID from the filename - private static final Pattern PDBID_REGEX = Pattern.compile("^([0-9][a-z0-9]{3})([._-]|\\s).*",Pattern.CASE_INSENSITIVE); + private static final Pattern PDBID_REGEX = Pattern.compile("^([0-9][a-z0-9]{3})([._-]|\\s).*", Pattern.CASE_INSENSITIVE); /** URL parameter specifying the file format (PDB or CIF) */ public static final String FORMAT_PARAM = "format"; @@ -73,7 +72,8 @@ public class URLIdentifier implements StructureIdentifier { //TODO: should this get renamed to chainname or asymid? public static final String CHAINID_PARAM = "chainid"; - /** URL parameter specifying residue ranges to include, e.g. residues=A:1-70 + /** + * URL parameter specifying residue ranges to include, e.g. residues=A:1-70 * @see SubstructureIdentifier */ public static final String RESIDUES_PARAM = "residues"; @@ -90,6 +90,7 @@ public URLIdentifier(String url) throws MalformedURLException { public URL getURL() { return url; } + @Override public String getIdentifier() { return url.toString(); @@ -104,20 +105,20 @@ public SubstructureIdentifier toCanonical() { List ranges = Collections.emptyList(); try { Map params = parseQuery(url); - if(params.containsKey(PDBID_PARAM)) { + if (params.containsKey(PDBID_PARAM)) { pdbId = params.get(PDBID_PARAM); } - if(params.containsKey(RESIDUES_PARAM)) { + if (params.containsKey(RESIDUES_PARAM)) { ranges = ResidueRange.parseMultiple(params.get(RESIDUES_PARAM)); - } else if(params.containsKey(CHAINID_PARAM)) { - ranges = Arrays.asList(new ResidueRange(params.get(CHAINID_PARAM),(ResidueNumber)null,(ResidueNumber)null)); + } else if (params.containsKey(CHAINID_PARAM)) { + ranges = Collections.singletonList(new ResidueRange(params.get(CHAINID_PARAM), (ResidueNumber) null, (ResidueNumber) null)); } } catch (UnsupportedEncodingException e) { - logger.error("Unable to decode URL "+url,e); + logger.error("Unable to decode URL {}", url, e); } - if(pdbId == null) { + if (pdbId == null) { String path = url.getPath(); - pdbId = guessPDBID(path.substring(path.lastIndexOf("/")+1)); + pdbId = guessPDBID(path.substring(path.lastIndexOf("/") + 1)); } return new SubstructureIdentifier(pdbId, ranges); } @@ -126,47 +127,46 @@ public SubstructureIdentifier toCanonical() { public Structure reduce(Structure input) throws StructureException { return toCanonical().reduce(input); } + /** * Load the structure from the URL * @return null */ @Override - public Structure loadStructure(AtomCache cache) throws StructureException, - IOException { + public Structure loadStructure(AtomCache cache) throws StructureException, IOException { StructureFiletype format = StructureFiletype.UNKNOWN; // Use user-specified format try { Map params = parseQuery(url); - if(params.containsKey(FORMAT_PARAM)) { + if (params.containsKey(FORMAT_PARAM)) { String formatStr = params.get(FORMAT_PARAM); - format = StructureIO.guessFiletype("."+formatStr); + format = StructureIO.guessFiletype("." + formatStr); } } catch (UnsupportedEncodingException e) { - logger.error("Unable to decode URL "+url,e); + logger.error("Unable to decode URL {}", url, e); } // Guess format from extension - if(format == StructureFiletype.UNKNOWN) { + if (format == StructureFiletype.UNKNOWN) { format = StructureIO.guessFiletype(url.getPath()); } switch(format) { - case CIF: - return StructureConverter.fromURL(url); - default: - case PDB: - // pdb file based parsing - - PDBFileReader reader = new PDBFileReader(cache.getPath()); - reader.setFetchBehavior(cache.getFetchBehavior()); - reader.setObsoleteBehavior(cache.getObsoleteBehavior()); - reader.setFileParsingParameters(cache.getFileParsingParams()); - return reader.getStructure(url); + case CIF: case BCIF: + return StructureConverter.fromURL(url); + case MMTF: + return MmtfActions.readFromInputStream(url.openStream()); + default: case PDB: + // pdb file based parsing + PDBFileReader reader = new PDBFileReader(cache.getPath()); + reader.setFetchBehavior(cache.getFetchBehavior()); + reader.setObsoleteBehavior(cache.getObsoleteBehavior()); + reader.setFileParsingParameters(cache.getFileParsingParams()); + return reader.getStructure(url); } } - /** * Recognizes PDB IDs that occur at the beginning of name followed by some * delimiter. @@ -175,7 +175,7 @@ public Structure loadStructure(AtomCache cache) throws StructureException, */ public static String guessPDBID(String name) { Matcher match = PDBID_REGEX.matcher(name); - if(match.matches()) { + if (match.matches()) { return match.group(1).toUpperCase(); } else { // Give up if doesn't match @@ -191,22 +191,22 @@ public static String guessPDBID(String name) { * @throws UnsupportedEncodingException */ private static Map parseQuery(URL url) throws UnsupportedEncodingException { - Map params = new LinkedHashMap(); + Map params = new LinkedHashMap<>(); String query = url.getQuery(); - if( query == null || query.isEmpty()) { + if (query == null || query.isEmpty()) { // empty query return params; } String[] pairs = url.getQuery().split("&"); - for(String pair: pairs) { + for (String pair : pairs) { int i = pair.indexOf("="); String key = pair; - if(i > 0) { + if (i > 0) { key = URLDecoder.decode(pair.substring(0, i), "UTF-8"); } String value = null; - if(i > 0 && pair.length() > i+1) { - value = URLDecoder.decode(pair.substring(i+1), "UTF-8"); + if(i > 0 && pair.length() > i + 1) { + value = URLDecoder.decode(pair.substring(i + 1), "UTF-8"); } // note that this uses the last instance if a parameter is specified multiple times params.put(key.toLowerCase(), value); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java index cc0220da07..4181792515 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java @@ -33,6 +33,7 @@ import org.biojava.nbio.structure.cath.CathDatabase; import org.biojava.nbio.structure.cath.CathDomain; import org.biojava.nbio.structure.cath.CathFactory; +import org.biojava.nbio.structure.io.BcifFileReader; import org.biojava.nbio.structure.io.CifFileReader; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; @@ -61,7 +62,6 @@ * @since 3.0 */ public class AtomCache { - private static final Logger logger = LoggerFactory.getLogger(AtomCache.class); /** @@ -73,25 +73,20 @@ public class AtomCache { public static final String BIOL_ASSEMBLY_IDENTIFIER = "BIO:"; public static final String CHAIN_NR_SYMBOL = ":"; public static final String CHAIN_SPLIT_SYMBOL = "."; - public static final String UNDERSCORE = "_"; private static final String FILE_SEPARATOR = System.getProperty("file.separator"); protected FileParsingParameters params; - private FetchBehavior fetchBehavior; private ObsoleteBehavior obsoleteBehavior; - private String cachePath; // make sure IDs are loaded uniquely - private Collection currentlyLoading = Collections.synchronizedCollection(new TreeSet()); + private final Collection currentlyLoading = Collections.synchronizedCollection(new TreeSet<>()); private String path; - - private boolean useMmCif; - private boolean useMmtf; + private StructureFiletype filetype = StructureFiletype.BCIF; /** * Default AtomCache constructor. @@ -122,9 +117,7 @@ public AtomCache(String pdbFilePath) { * @param cachePath */ public AtomCache(String pdbFilePath, String cachePath) { - - logger.debug("Initialising AtomCache with pdbFilePath={}, cachePath={}",pdbFilePath, cachePath); - + logger.debug("Initialising AtomCache with pdbFilePath={}, cachePath={}", pdbFilePath, cachePath); if (!pdbFilePath.endsWith(FILE_SEPARATOR)) { pdbFilePath += FILE_SEPARATOR; } @@ -144,9 +137,7 @@ public AtomCache(String pdbFilePath, String cachePath) { currentlyLoading.clear(); params = new FileParsingParameters(); - setUseMmCif(false); - setUseMmtf(true); - + setFiletype(StructureFiletype.BCIF); } /** @@ -159,11 +150,7 @@ public AtomCache(UserConfiguration config) { this(config.getPdbFilePath(), config.getCacheFilePath()); fetchBehavior = config.getFetchBehavior(); obsoleteBehavior = config.getObsoleteBehavior(); - useMmCif = config.getFileFormat().equals( UserConfiguration.MMCIF_FORMAT ); - - if ( useMmCif) - useMmtf = false; - + filetype = config.getStructureFiletype(); } /** @@ -180,21 +167,20 @@ public AtomCache(UserConfiguration config) { public Atom[] getAtoms(String name) throws IOException, StructureException { return getAtoms(new StructureName(name)); } - public Atom[] getAtoms(StructureIdentifier name) throws IOException, StructureException { - Atom[] atoms = null; + public Atom[] getAtoms(StructureIdentifier name) throws IOException, StructureException { + Atom[] atoms; // System.out.println("loading " + name); Structure s = getStructure(name); - atoms = StructureTools.getAtomCAArray(s); /* * synchronized (cache){ cache.put(name, atoms); } */ - return atoms; } + /** * Returns the representative atoms for the provided name. * See {@link #getStructure(String)} for supported naming conventions. @@ -210,17 +196,14 @@ public Atom[] getRepresentativeAtoms(String name) throws IOException, StructureE } public Atom[] getRepresentativeAtoms(StructureIdentifier name) throws IOException, StructureException { - - Atom[] atoms = null; + Atom[] atoms; Structure s = getStructure(name); - atoms = StructureTools.getRepresentativeAtomArray(s); /* * synchronized (cache){ cache.put(name, atoms); } */ - return atoms; } @@ -246,7 +229,6 @@ public Atom[] getRepresentativeAtoms(StructureIdentifier name) throws IOExceptio */ public Structure getBiologicalAssembly(String pdbId, int bioAssemblyId, boolean multiModel) throws StructureException, IOException { - if (bioAssemblyId < 0) { throw new StructureException("bioAssemblyID must be nonnegative: " + pdbId + " bioAssemblyId " + bioAssemblyId); @@ -262,14 +244,14 @@ public Structure getBiologicalAssembly(String pdbId, int bioAssemblyId, boolean getFileParsingParams().setParseBioAssembly(prevIsParseBioAssembly); - if (asymUnit.getPDBHeader() == null || asymUnit.getPDBHeader().getBioAssemblies()==null) { + if (asymUnit.getPDBHeader() == null || asymUnit.getPDBHeader().getBioAssemblies() == null) { logger.info("No bioassembly information found for {}, returning asymmetric unit as biological assembly", pdbId); return asymUnit; } // 0 ... asym unit - if ( bioAssemblyId == 0) { - logger.info("Requested biological assembly 0 for PDB id "+pdbId+", returning asymmetric unit"); + if (bioAssemblyId == 0) { + logger.info("Requested biological assembly 0 for PDB id {}, returning asymmetric unit", pdbId); return asymUnit; } // does it exist? @@ -281,20 +263,18 @@ public Structure getBiologicalAssembly(String pdbId, int bioAssemblyId, boolean asymUnit.getPDBHeader().getBioAssemblies().get(bioAssemblyId).getTransforms(); - if ( transformations == null || transformations.size() == 0){ - + if (transformations == null || transformations.size() == 0) { throw new StructureException("Could not load transformations to recreate biological assembly id " + bioAssemblyId + " of " + pdbId); - } BiologicalAssemblyBuilder builder = new BiologicalAssemblyBuilder(); // if we use mmcif or mmtf, then we need to pass useAsymIds=true boolean useAsymIds = false; - if (useMmCif) useAsymIds = true; - if (useMmtf) useAsymIds = true; + if (filetype == StructureFiletype.CIF || filetype == StructureFiletype.BCIF || filetype == StructureFiletype.MMTF) { + useAsymIds = true; + } return builder.rebuildQuaternaryStructure(asymUnit, transformations, useAsymIds, multiModel); - } /** @@ -312,7 +292,6 @@ public Structure getBiologicalAssembly(String pdbId, int bioAssemblyId, boolean * @since 4.2 */ public Structure getBiologicalAssembly(String pdbId, boolean multiModel) throws StructureException, IOException { - boolean prevIsParseBioAssembly = getFileParsingParams().isParseBioAssembly(); if (!getFileParsingParams().isParseBioAssembly()) { @@ -320,11 +299,10 @@ public Structure getBiologicalAssembly(String pdbId, boolean multiModel) throws } Structure asymUnit = getStructureForPdbId(pdbId); - getFileParsingParams().setParseBioAssembly(prevIsParseBioAssembly); - if (asymUnit.getPDBHeader() == null || asymUnit.getPDBHeader().getBioAssemblies()==null) { + if (asymUnit.getPDBHeader() == null || asymUnit.getPDBHeader().getBioAssemblies() == null) { logger.info("No bioassembly information found for {}, returning asymmetric unit as biological assembly", pdbId); return asymUnit; } @@ -340,20 +318,18 @@ public Structure getBiologicalAssembly(String pdbId, boolean multiModel) throws asymUnit.getPDBHeader().getBioAssemblies().get(bioAssemblyId).getTransforms(); - if ( transformations == null || transformations.size() == 0){ - + if (transformations == null || transformations.size() == 0) { throw new StructureException("Could not load transformations to recreate biological assembly id " + bioAssemblyId + " of " + pdbId); - } BiologicalAssemblyBuilder builder = new BiologicalAssemblyBuilder(); // if we use mmcif or mmtf, then we need to pass useAsymIds=true boolean useAsymIds = false; - if (useMmCif) useAsymIds = true; - if (useMmtf) useAsymIds = true; + if (filetype == StructureFiletype.CIF || filetype == StructureFiletype.BCIF || filetype == StructureFiletype.MMTF) { + useAsymIds = true; + } return builder.rebuildQuaternaryStructure(asymUnit, transformations, useAsymIds, multiModel); - } /** @@ -367,7 +343,6 @@ public Structure getBiologicalAssembly(String pdbId, boolean multiModel) throws * @since 5.0 */ public List getBiologicalAssemblies(String pdbId, boolean multiModel) throws StructureException, IOException { - List assemblies = new ArrayList<>(); boolean prevIsParseBioAssembly = getFileParsingParams().isParseBioAssembly(); @@ -377,25 +352,21 @@ public List getBiologicalAssemblies(String pdbId, boolean multiModel) } Structure asymUnit = getStructureForPdbId(pdbId); - getFileParsingParams().setParseBioAssembly(prevIsParseBioAssembly); - - if (asymUnit.getPDBHeader() == null || asymUnit.getPDBHeader().getBioAssemblies()==null) { + if (asymUnit.getPDBHeader() == null || asymUnit.getPDBHeader().getBioAssemblies() == null) { logger.info("No bioassembly information found for {}, returning asymmetric unit as the only biological assembly", pdbId); assemblies.add(asymUnit); return assemblies; } - for (int bioAssemblyId : asymUnit.getPDBHeader().getBioAssemblies().keySet()) { List transformations = asymUnit.getPDBHeader().getBioAssemblies().get(bioAssemblyId).getTransforms(); - - if ( transformations == null || transformations.size() == 0){ - - logger.info("Could not load transformations to recreate biological assembly id " + bioAssemblyId + " of " + pdbId+". Assembly id will be missing in biological assemblies."); + if (transformations == null || transformations.size() == 0) { + logger.info("Could not load transformations to recreate biological assembly id {} of {}. Assembly " + + "id will be missing in biological assemblies.", bioAssemblyId, pdbId); continue; } @@ -403,8 +374,9 @@ public List getBiologicalAssemblies(String pdbId, boolean multiModel) // if we use mmcif or mmtf, then we need to pass useAsymIds=true boolean useAsymIds = false; - if (useMmCif) useAsymIds = true; - if (useMmtf) useAsymIds = true; + if (filetype == StructureFiletype.CIF || filetype == StructureFiletype.BCIF || filetype == StructureFiletype.MMTF) { + useAsymIds = true; + } Structure s = builder.rebuildQuaternaryStructure(asymUnit, transformations, useAsymIds, multiModel); assemblies.add(s); } @@ -483,7 +455,6 @@ public String getPath() { */ public Structure getStructure(String name) throws IOException, StructureException { StructureName structureName = new StructureName(name); - return getStructure(structureName); } @@ -552,7 +523,6 @@ public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatab */ public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatabase, boolean strictLigandHandling) throws IOException, StructureException { - String pdbId = domain.getPdbId(); Structure fullStructure = getStructureForPdbId(pdbId); Structure structure = domain.reduce(fullStructure); @@ -569,13 +539,12 @@ public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatab rrs = ResidueRangeAndLength.parseMultiple(domain.getRanges(), map); } for (Chain chain : fullStructure.getNonPolyChains()) { - if (!structure.hasPdbChain(chain.getName())) { continue; // we can't do anything with a chain our domain } Chain newChain; - if (! structure.hasNonPolyChain(chain.getId())) { + if (!structure.hasNonPolyChain(chain.getId())) { newChain = new ChainImpl(); newChain.setId(chain.getId()); newChain.setName(chain.getName()); @@ -584,6 +553,7 @@ public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatab } else { newChain = structure.getNonPolyChain(chain.getId()); } + List ligands = StructureTools.filterLigands(chain.getAtomGroups()); for (Group group : ligands) { boolean shouldContain = true; @@ -598,9 +568,7 @@ public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatab boolean alreadyContains = newChain.getAtomGroups().contains(group); // we don't want to add duplicate // ligands if (shouldContain && !alreadyContains) { - newChain.addGroup(group); - } } } @@ -619,7 +587,6 @@ public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatab structure.getPDBHeader().setDescription(header.toString()); return structure; - } /** @@ -665,7 +632,6 @@ public void setFileParsingParams(FileParsingParameters params) { this.params = params; } - /** * [Optional] This method changes the behavior when obsolete entries * are requested. Current behaviors are: @@ -712,6 +678,7 @@ public ObsoleteBehavior getObsoleteBehavior() { public FetchBehavior getFetchBehavior() { return fetchBehavior; } + /** * Set the behavior for fetching files from the server * @param fetchBehavior @@ -731,45 +698,23 @@ public void setPath(String path) { } /** - * @return the useMmCif + * Returns the currently active file type that will be parsed. + * @return a StructureFiletype */ - public boolean isUseMmCif() { - return useMmCif; + public StructureFiletype getFiletype() { + return filetype; } /** - * @param useMmCif - * the useMmCif to set - */ - public void setUseMmCif(boolean useMmCif) { - this.useMmCif = useMmCif; - // Either way the user wants to use PDB or MMCIF - this.useMmtf = false; - } - - /** - * Set whether to use mmtf. - * @param useMmtf the input boolean to set - */ - public void setUseMmtf(boolean useMmtf) { - this.useMmtf = useMmtf; - if(useMmtf){ - useMmCif=false; - } - - } - - /** Returns useMmtf flag - * - * @return true if will load data via mmtf file format + * Set the file type that will be parsed. + * @param filetype a StructureFiletype */ - public boolean isUseMmtf(){ - return this.useMmtf; + public void setFiletype(StructureFiletype filetype) { + this.filetype = filetype; } private boolean checkLoading(String name) { return currentlyLoading.contains(name); - } /** @@ -784,17 +729,15 @@ public Structure getStructureForCathDomain(StructureName structureName) throws I * Returns a {@link Structure} corresponding to the CATH identifier supplied in {@code structureName}, using the specified {@link CathDatabase}. */ public Structure getStructureForCathDomain(StructureName structureName, CathDatabase cathInstall) throws IOException, StructureException { - CathDomain cathDomain = cathInstall.getDomainByCathId(structureName.getIdentifier()); Structure s = getStructureForPdbId(cathDomain.getIdentifier()); Structure n = cathDomain.reduce(s); // add the ligands of the chain... - Chain newChain = n.getPolyChainByPDB(structureName.getChainId()); List origChains = s.getNonPolyChainsByPDB(structureName.getChainId()); - for ( Chain origChain : origChains) { + for (Chain origChain : origChains) { List ligands = origChain.getAtomGroups(); for (Group g : ligands) { @@ -815,7 +758,6 @@ protected void flagLoading(String name) { } protected void flagLoadingFinished(String name) { - currentlyLoading.remove(name); } @@ -827,10 +769,10 @@ protected void flagLoadingFinished(String name) { * @throws StructureException */ public Structure getStructureForPdbId(String pdbId) throws IOException, StructureException { - if(pdbId == null) + if (pdbId == null) return null; - if(pdbId.length() != 4) { - throw new StructureException("Unrecognized PDB ID: "+pdbId); + if (pdbId.length() != 4) { + throw new StructureException("Unrecognized PDB ID: " + pdbId); } while (checkLoading(pdbId)) { // waiting for loading to be finished... @@ -840,22 +782,22 @@ public Structure getStructureForPdbId(String pdbId) throws IOException, Structur } catch (InterruptedException e) { logger.error(e.getMessage()); } - } - Structure s; - if (useMmtf) { - logger.debug("loading from mmtf"); - s = loadStructureFromMmtfByPdbId(pdbId); - } - else if (useMmCif) { - logger.debug("loading from mmcif"); - s = loadStructureFromCifByPdbId(pdbId); - } else { - logger.debug("loading from pdb"); - s = loadStructureFromPdbByPdbId(pdbId); + switch (filetype) { + case CIF: + logger.debug("loading from mmcif"); + return loadStructureFromCifByPdbId(pdbId); + case BCIF: + logger.debug("loading from bcif"); + return loadStructureFromBcifByPdbId(pdbId); + case MMTF: + logger.debug("loading from mmtf"); + return loadStructureFromMmtfByPdbId(pdbId); + case PDB: default: + logger.debug("loading from pdb"); + return loadStructureFromPdbByPdbId(pdbId); } - return s; } /** @@ -869,12 +811,10 @@ private Structure loadStructureFromMmtfByPdbId(String pdbId) throws IOException MMTFFileReader reader = new MMTFFileReader(); reader.setFetchBehavior(fetchBehavior); reader.setObsoleteBehavior(obsoleteBehavior); - Structure structure = reader.getStructureById(pdbId.toLowerCase()); - return structure; + return reader.getStructureById(pdbId.toLowerCase()); } - protected Structure loadStructureFromCifByPdbId(String pdbId) throws IOException, StructureException { - + protected Structure loadStructureFromCifByPdbId(String pdbId) throws IOException { logger.debug("Loading structure {} from mmCIF file {}.", pdbId, path); Structure s; flagLoading(pdbId); @@ -891,8 +831,24 @@ protected Structure loadStructureFromCifByPdbId(String pdbId) throws IOException return s; } - protected Structure loadStructureFromPdbByPdbId(String pdbId) throws IOException, StructureException { + protected Structure loadStructureFromBcifByPdbId(String pdbId) throws IOException { + logger.debug("Loading structure {} from BinaryCIF file {}.", pdbId, path); + Structure s; + flagLoading(pdbId); + try { + BcifFileReader reader = new BcifFileReader(path); + reader.setFetchBehavior(fetchBehavior); + reader.setObsoleteBehavior(obsoleteBehavior); + reader.setFileParsingParameters(params); + s = reader.getStructureById(pdbId.toLowerCase()); + } finally { + flagLoadingFinished(pdbId); + } + + return s; + } + protected Structure loadStructureFromPdbByPdbId(String pdbId) throws IOException { logger.debug("Loading structure {} from PDB file {}.", pdbId, path); Structure s; flagLoading(pdbId); @@ -904,12 +860,10 @@ protected Structure loadStructureFromPdbByPdbId(String pdbId) throws IOException reader.setFileParsingParameters(params); s = reader.getStructureById(pdbId.toLowerCase()); - } finally { flagLoadingFinished(pdbId); } return s; } - } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/UserConfiguration.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/UserConfiguration.java index e23f8e6db1..ebcf3aaba6 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/UserConfiguration.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/UserConfiguration.java @@ -19,6 +19,7 @@ package org.biojava.nbio.structure.align.util; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.align.ce.StartupParameters; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; @@ -33,19 +34,17 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; - -/** A container to persist config to the file system +/** + * A container to persist config to the file system * * @author Andreas Prlic - * */ -public class UserConfiguration -{ - +public class UserConfiguration { private static final Logger logger = LoggerFactory.getLogger(UserConfiguration.class); public static final String PDB_FORMAT = "PDB"; - public static final String MMCIF_FORMAT = "mmCif"; + public static final String MMCIF_FORMAT = "cif"; + public static final String BINARY_CIF = "bcif"; public static final String MMTF_FORMAT = "mmtf"; public static final String TMP_DIR = "java.io.tmpdir"; @@ -63,8 +62,7 @@ public class UserConfiguration private String fileFormat; - private static AtomicBoolean warningShown = new AtomicBoolean(false); - + private static final AtomicBoolean warningShown = new AtomicBoolean(false); /** * Default UserConfiguration: @@ -98,66 +96,51 @@ public UserConfiguration(){ // note that in initCacheFilePath, we set to the provided one (if readable) or to the same as pdbFilePath cacheFilePath = initCacheFilePath(); - fileFormat = MMTF_FORMAT; + fileFormat = BINARY_CIF; } private String initPdbFilePath() { - String path = null; - String propertyName = PDB_DIR; - String userProvidedDir = System.getProperty(propertyName); - if ( userProvidedDir != null && !userProvidedDir.trim().isEmpty()) { - + if (userProvidedDir != null && !userProvidedDir.trim().isEmpty()) { path = userProvidedDir; logger.debug("Read PDB dir from system property {}: {}", propertyName, path); File f = new File(path); if (!f.isDirectory()) { - logger.warn( - "Provided path {} (with system property {}) is not a directory. Using system's temp directory instead {}", - path, propertyName, System.getProperty(TMP_DIR)); + logger.warn("Provided path {} (with system property {}) is not a directory. Using system's temp " + + "directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } else if (!f.canWrite()) { - logger.warn( - "Provided path {} (with system property {}) is not writable. Will not be able to write cached files.", - path, propertyName); + logger.warn("Provided path {} (with system property {}) is not writable. Will not be able to write " + + "cached files.", path, propertyName); // we don't require the PDB_DIR to be writable, so that it can be used with a pre-rsynced dir // thus if not writable, we only warn and go ahead using it } - - } else { Map env = System.getenv(); - - if( env.containsKey(propertyName) && !env.get(propertyName).trim().isEmpty()) { + if (env.containsKey(propertyName) && !env.get(propertyName).trim().isEmpty()) { path = env.get(propertyName); logger.debug("Read dir from environment variable {}: {}", propertyName, path); File f = new File(path); if (!f.isDirectory()) { - logger.warn( - "Provided path {} (with environment variable {}) is not a directory. Using system's temp directory instead {}", - path, propertyName, System.getProperty(TMP_DIR)); + logger.warn("Provided path {} (with environment variable {}) is not a directory. Using system's " + + "temp directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } else if (!f.canWrite()) { - logger.warn( - "Provided path {} (with environment variable {}) is not writable. Will not be able to write cached files", - path, propertyName); + logger.warn("Provided path {} (with environment variable {}) is not writable. Will not be able " + + "to write cached files", path, propertyName); // we don't require the PDB_DIR to be writable, so that it can be used with a pre-rsynced dir // thus if not writable, we only warn and go ahead using it } - } else { path = System.getProperty(TMP_DIR); - if ( ! warningShown.get()) { - - logger.warn("Could not read dir from system property {} or environment variable {}, " - + "using system's temp directory {}", - propertyName, propertyName, path); - + if (! warningShown.get()) { + logger.warn("Could not read dir from system property {} or environment variable {}, " + + "using system's temp directory {}", propertyName, propertyName, path); warningShown.set(true); } @@ -165,95 +148,79 @@ private String initPdbFilePath() { } } - if ( ! path.endsWith(lineSplit) ) + if (!path.endsWith(lineSplit)) { path = path + lineSplit; + } return path; - } private String initCacheFilePath() { - String path = null; - String propertyName = PDB_CACHE_DIR; - String userProvidedDir = System.getProperty(propertyName); - if ( userProvidedDir != null ) { - + if (userProvidedDir != null) { path = userProvidedDir; logger.debug("Read cache dir from system property {}: {}", propertyName, path); File f = new File(path); if (!f.isDirectory()) { - logger.warn( - "Provided path {} (with system property {}) is not a directory. Using system's temp directory instead {}", - path, propertyName, System.getProperty(TMP_DIR)); + logger.warn("Provided path {} (with system property {}) is not a directory. Using system's temp " + + "directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } else if (!f.canWrite()) { - logger.warn( - "Provided path {} (with system property {}) is not writable. Using system's temp directory instead {}", - path, propertyName, System.getProperty(TMP_DIR)); + logger.warn("Provided path {} (with system property {}) is not writable. Using system's temp " + + "directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); System.setProperty(propertyName,path); } - - } else { Map env = System.getenv(); - if( env.containsKey(propertyName)) { + if (env.containsKey(propertyName)) { path = env.get(propertyName); logger.debug("Read dir from environment variable {}: {}", propertyName, path); File f = new File(path); if (!f.isDirectory()) { - logger.warn( - "Provided path {} (with environment variable {}) is not a directory. Using system's temp directory instead {}", - path, propertyName, System.getProperty(TMP_DIR)); + logger.warn("Provided path {} (with environment variable {}) is not a directory. Using system's " + + "temp directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } else if (!f.canWrite()) { - logger.warn( - "Provided path {} (with environment variable {}) is not writable. Using system's temp directory instead {}", - path, propertyName, System.getProperty(TMP_DIR)); + logger.warn("Provided path {} (with environment variable {}) is not writable. Using system's " + + "temp directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } - } else { // NOTE in case of not provided, then it is set to same as pdbFilePath // as PDB_DIR is not checked for being writable, we have to do that check here in case if (new File(pdbFilePath).canWrite()){ path = pdbFilePath; - logger.info("Could not read cache dir from system property {} or environment variable {}, " - + "using PDB directory instead {}", - propertyName, propertyName, path); + logger.info("Could not read cache dir from system property {} or environment variable {}, " + + "using PDB directory instead {}", propertyName, propertyName, path); System.setProperty(propertyName,path); - } else { path = System.getProperty(TMP_DIR); logger.warn("Could not read cache dir from system property {} or environment variable {}, " + "and PDB directory {} is not writable. Using system's temp directory instead {}", propertyName, propertyName, pdbFilePath, path); System.setProperty(propertyName,path); - } } } - if ( ! path.endsWith(lineSplit) ) + if (!path.endsWith(lineSplit)) { path = path + lineSplit; + } return path; - } - public String getPdbFilePath() - { + public String getPdbFilePath() { return pdbFilePath; } - public void setPdbFilePath(String pdbFilePath) - { + public void setPdbFilePath(String pdbFilePath) { this.pdbFilePath = pdbFilePath; } @@ -281,24 +248,22 @@ public void setObsoleteBehavior(ObsoleteBehavior obsoleteBehavior) { this.obsoleteBehavior = obsoleteBehavior; } - /** convert Configuration to an XML file so it can be serialized + /** + * convert Configuration to an XML file so it can be serialized * * @param pw * @return XMLWriter * @throws IOException */ - public XMLWriter toXML(PrintWriter pw) - throws IOException - { - - XMLWriter xw = new PrettyXMLWriter( pw); - + public XMLWriter toXML(PrintWriter pw) throws IOException { + XMLWriter xw = new PrettyXMLWriter(pw); toXML(xw); - return xw ; - } + return xw; + } - /** convert Configuration to an XML file so it can be serialized + /** + * convert Configuration to an XML file so it can be serialized * add to an already existing xml file. * * @param xw the XML writer to use @@ -306,10 +271,7 @@ public XMLWriter toXML(PrintWriter pw) * @throws IOException * @see org.biojava.nbio.structure.align.webstart.ConfigXMLHandler */ - - public XMLWriter toXML(XMLWriter xw) - throws IOException - { + public XMLWriter toXML(XMLWriter xw) throws IOException { xw.printRaw(""); //xw.printRaw(""); xw.openTag("JFatCatConfig"); @@ -317,18 +279,18 @@ public XMLWriter toXML(XMLWriter xw) xw.openTag("PDBFILEPATH"); // we don;t serialize the tempdir... String tempdir = System.getProperty(TMP_DIR); - if (! pdbFilePath.equals(tempdir)) + if (!pdbFilePath.equals(tempdir)) { xw.attribute("path", pdbFilePath); + } - xw.attribute("fetchBehavior", fetchBehavior+""); - xw.attribute("obsoleteBehavior", obsoleteBehavior+""); + xw.attribute("fetchBehavior", fetchBehavior + ""); + xw.attribute("obsoleteBehavior", obsoleteBehavior + ""); xw.attribute("fileFormat", fileFormat); xw.closeTag("PDBFILEPATH"); xw.closeTag("JFatCatConfig"); return xw ; - - } + } public static UserConfiguration fromStartupParams(StartupParameters params) { UserConfiguration config = new UserConfiguration(); @@ -349,14 +311,22 @@ public void setFileFormat (String fileFormat){ this.fileFormat = fileFormat; } - public String getFileFormat() - { + public String getFileFormat() { return fileFormat; } - - - - - + public StructureFiletype getStructureFiletype() { + switch (fileFormat) { + case MMCIF_FORMAT: + return StructureFiletype.CIF; + case BINARY_CIF: + return StructureFiletype.BCIF; + case MMTF_FORMAT: + return StructureFiletype.MMTF; + case PDB_FORMAT: + return StructureFiletype.PDB; + default: + return StructureFiletype.BCIF; + } + } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java index 7109d60204..f550d82a96 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java @@ -228,7 +228,8 @@ public String getOneLetterCode() { } public void setOneLetterCode(String oneLetterCode) { - this.oneLetterCode = oneLetterCode; + // backwards compatibility that treats missing olc as ? + this.oneLetterCode = "".equals(oneLetterCode) ? "?" : oneLetterCode; setStandardFlag(); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index 0f1394424a..53d4c6e42f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -45,6 +45,7 @@ import org.biojava.nbio.structure.PDBCrystallographicInfo; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemComp; @@ -80,7 +81,7 @@ public class MmtfUtils { public static AtomCache setUpBioJava() { // Set up the atom cache etc AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.MMTF); FileParsingParameters params = cache.getFileParsingParams(); params.setCreateAtomBonds(true); params.setAlignSeqRes(true); @@ -101,7 +102,7 @@ public static AtomCache setUpBioJava() { public static AtomCache setUpBioJava(String extraUrl) { // Set up the atom cache etc AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.MMTF); FileParsingParameters params = cache.getFileParsingParams(); params.setCreateAtomBonds(true); params.setAlignSeqRes(true); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/Test2JA5.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/Test2JA5.java index 8d42461300..eb7008d0cb 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/Test2JA5.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/Test2JA5.java @@ -41,7 +41,7 @@ public void test2JA5() throws IOException, StructureException { fileParsingParameters.setHeaderOnly(false); // Need header only off to have chains to match. AtomCache cache = new AtomCache(); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); cache.setFileParsingParams(fileParsingParameters); StructureIO.setAtomCache(cache); @@ -70,7 +70,7 @@ public void test2JA5noHeader() throws IOException, StructureException { fileParsingParameters.setHeaderOnly(true); AtomCache cache = new AtomCache(); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); cache.setFileParsingParams(fileParsingParameters); StructureIO.setAtomCache(cache); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java index 3aa86bacd0..ef9f830ae1 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java @@ -47,7 +47,7 @@ public class TestAltLocs { public void testAltLocParsing() throws StructureException, IOException{ AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s = cache.getStructure("2CI1"); Chain a = s.getPolyChainByPDB("A"); @@ -210,7 +210,7 @@ private void ensureAllAtomsSameAltCode(Group groupInputAltLocGroup, Group inputM public void test1AAC() throws IOException, StructureException{ AtomCache cache = new AtomCache(); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); StructureIO.setAtomCache(cache); Structure s = StructureIO.getStructure("1AAC"); @@ -221,7 +221,7 @@ public void test1AAC() throws IOException, StructureException{ testCBAtomInMainGroup(g); cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); Structure s1 = cache.getStructure("1AAC"); @@ -262,7 +262,7 @@ public void test3PIUpdb() throws IOException, StructureException{ StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure structure = StructureIO.getStructure("3PIU"); @@ -428,7 +428,7 @@ public void test4CUPBonds() throws IOException, StructureException{ StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure structure = StructureIO.getStructure("4CUP"); @@ -489,7 +489,7 @@ public void test3PIUmmcif() throws IOException, StructureException{ StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure structure = StructureIO.getStructure("3PIU"); @@ -549,7 +549,7 @@ public void test3U7Tmmcif() throws IOException, StructureException{ StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); cache.setFileParsingParams(params); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java index d3c61130ae..17c6836a4f 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java @@ -156,7 +156,7 @@ public void testObsoleteId() throws StructureException, IOException { cache.setObsoleteBehavior(ObsoleteBehavior.THROW_EXCEPTION); // OBSOLETE PDB; should throw an exception - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); cache.getStructure("1HHB"); } @@ -168,13 +168,13 @@ public void testFetchCurrent1CMW() throws IOException, StructureException { cache.setObsoleteBehavior(ObsoleteBehavior.FETCH_CURRENT); // OBSOLETE PDB; should throw an exception - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); try { cache.getStructure("1CMW"); fail("Obsolete structure should throw exception"); } catch(IOException e) {} - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); try { cache.getStructure("1CMW"); fail("Obsolete structure should throw exception"); @@ -188,11 +188,11 @@ public void testFetchCurrent1HHB() throws IOException, StructureException { cache.setFetchBehavior(FetchBehavior.FETCH_FILES); cache.setObsoleteBehavior(ObsoleteBehavior.FETCH_CURRENT); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure s = cache.getStructure("1HHB"); assertEquals("Failed to get the current ID for 1HHB.","4HHB",s.getPDBCode()); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); s = cache.getStructure("1HHB"); assertEquals("Failed to get the current ID for 1HHB.","4HHB",s.getPDBCode()); } @@ -204,15 +204,14 @@ public void testFetchObsolete() throws IOException, StructureException { cache.setObsoleteBehavior(ObsoleteBehavior.FETCH_OBSOLETE); Structure s; - cache.setUseMmtf(false); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); s = cache.getStructure("1CMW"); assertEquals("Failed to get OBSOLETE file 1CMW.","1CMW", s.getPDBCode()); s = cache.getStructure("1HHB"); assertEquals("Failed to get OBSOLETE file 1HHB.","1HHB", s.getPDBCode()); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); s = cache.getStructure("1CMW"); assertEquals("Failed to get OBSOLETE file 1CMW.","1CMW", s.getPDBCode()); @@ -229,35 +228,32 @@ public void testSettingFileParsingType(){ //test defaults - // by default we either use mmtf or mmcif, but not both. - assertNotEquals(cache.isUseMmtf(), cache.isUseMmCif()); - // first is mmtf, second is mmcif testFlags(cache,true,false); // now change the values - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); testFlags(cache,false,true); - cache.setUseMmtf(true); + cache.setFiletype(StructureFiletype.MMTF); testFlags(cache,true,false); // this sets to use PDB! - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); testFlags(cache,false,false); // back to defaults - cache.setUseMmtf(true); + cache.setFiletype(StructureFiletype.MMTF); testFlags(cache,true,false); // back to parsing PDB - cache.setUseMmtf(false); + cache.setFiletype(StructureFiletype.PDB); testFlags(cache,false,false); @@ -274,10 +270,10 @@ public void testSettingFileParsingType(){ */ private void testFlags(AtomCache cache ,boolean useMmTf, boolean useMmCif) { - assertEquals("flag for parsing mmtf is set to " + cache.isUseMmtf() + " but should be " + useMmTf, - cache.isUseMmtf(), useMmTf); - assertEquals("flag for parsing mmcif is set to " + cache.isUseMmCif() + " but should be set to " + useMmCif, - cache.isUseMmCif(), useMmCif); + assertEquals("flag for parsing mmtf is set to " + cache.getFiletype() + " but should be " + useMmTf, + cache.getFiletype() == StructureFiletype.MMTF, useMmTf); + assertEquals("flag for parsing mmcif is set to " + cache.getFiletype() + " but should be set to " + useMmCif, + cache.getFiletype() == StructureFiletype.CIF, useMmCif); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java index 9a3022d0a1..cd64006861 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java @@ -52,7 +52,7 @@ public static void setUp() { cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = cache.getFileParsingParams(); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestCloning.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestCloning.java index ac8b728d93..4ce757bc91 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestCloning.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestCloning.java @@ -191,7 +191,7 @@ private void compareCloned(final Structure s, final Structure c) throws Structur public void testBondCloning() throws IOException, StructureException { final AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); final FileParsingParameters params = cache.getFileParsingParams(); params.setCreateAtomBonds(true); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestEntityResIndexMapping.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestEntityResIndexMapping.java index f0926364b9..401a42f2cb 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestEntityResIndexMapping.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestEntityResIndexMapping.java @@ -54,7 +54,7 @@ public void test1B8G() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure s = StructureIO.getStructure("1B8G"); Chain chainA = s.getPolyChainByPDB("A"); @@ -76,7 +76,7 @@ public void test1SMT() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure s = StructureIO.getStructure("1SMT"); Chain chainA = s.getPolyChainByPDB("A"); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestExperimentalTechniques.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestExperimentalTechniques.java index 25436297a6..6ef6224f8d 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestExperimentalTechniques.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestExperimentalTechniques.java @@ -39,9 +39,9 @@ public void test6F2Q() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure sPdb = StructureIO.getStructure("6F2Q"); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("6F2Q"); comparePdbToCif(sPdb, sCif); @@ -69,9 +69,9 @@ public void test3ZPK() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure sPdb = StructureIO.getStructure("3ZPK"); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("3ZPK"); comparePdbToCif(sPdb, sCif); @@ -99,9 +99,9 @@ public void test2B6O() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure sPdb = StructureIO.getStructure("2B6O"); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("2B6O"); comparePdbToCif(sPdb, sCif); @@ -129,9 +129,9 @@ public void test4CSO() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure sPdb = StructureIO.getStructure("4CSO"); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("4CSO"); comparePdbToCif(sPdb, sCif); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestLoadStructureFromURL.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestLoadStructureFromURL.java index c7cf3ede33..fb182535f1 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestLoadStructureFromURL.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestLoadStructureFromURL.java @@ -50,8 +50,7 @@ public void testLoadStructureFromURL() throws IOException, StructureException{ f.mkdir(); } AtomCache c = new AtomCache(f.toString(), f.toString()); - c.setUseMmCif(false); - c.setUseMmtf(false); + c.setFiletype(StructureFiletype.PDB); // fetch a random small structure c.getStructure("1znf"); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestParsingCalcium.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestParsingCalcium.java index 783ca74dba..c3212fac8c 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestParsingCalcium.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestParsingCalcium.java @@ -46,7 +46,7 @@ public void testCalciumParsing() throws StructureException, IOException { AtomCache cache = new AtomCache(); Structure s = cache.getStructure(pdbID); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure m = cache.getStructure(pdbID); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestStructureCrossReferences.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestStructureCrossReferences.java index d2c5b2d0b8..ebcea45acf 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestStructureCrossReferences.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestStructureCrossReferences.java @@ -50,7 +50,7 @@ public void testCrossReferencesMmCif() throws IOException, StructureException { boolean emptySeqRes = true; AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(false); // Store empty seqres groups. @@ -73,7 +73,7 @@ public void testCrossReferencesMmCifAlignSeqRes() throws IOException, StructureE boolean emptySeqRes = false; AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); @@ -97,7 +97,7 @@ public void testCrossReferencesMmCifAlignSeqRes() throws IOException, StructureE public void testCrossReferencesPdb() throws IOException, StructureException { boolean emptySeqRes = true; AtomCache cache = new AtomCache(); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(false); // Store empty seqres groups @@ -119,7 +119,7 @@ public void testCrossReferencesPdb() throws IOException, StructureException { public void testCrossReferencesPdbAlignSeqRes() throws IOException, StructureException { boolean emptySeqRes = false; AtomCache cache = new AtomCache(); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java index 0882ae08a1..1b30f95ad6 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java @@ -47,6 +47,7 @@ import org.biojava.nbio.structure.ResidueRangeAndLength; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.StructureIdentifier; import org.biojava.nbio.structure.StructureTools; @@ -372,7 +373,7 @@ public void testEmptyChemComp() throws IOException, StructureException { try { cache.setPath(tmpCache.toString()); cache.setCachePath(tmpCache.toString()); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); ChemCompGroupFactory.setChemCompProvider(new DownloadChemCompProvider(tmpCache.toString())); // Create an empty chemcomp @@ -431,7 +432,7 @@ public void testEmptyGZChemComp() throws IOException, StructureException { try { cache.setPath(tmpCache.toString()); cache.setCachePath(tmpCache.toString()); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); ChemCompGroupFactory.setChemCompProvider(new DownloadChemCompProvider(tmpCache.toString())); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestDifficultMmCIFFiles.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestDifficultMmCIFFiles.java index 81695918a9..690f877f08 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestDifficultMmCIFFiles.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestDifficultMmCIFFiles.java @@ -42,6 +42,7 @@ import org.biojava.nbio.structure.ResidueNumber; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.cif.StructureConverter; @@ -77,7 +78,7 @@ public void test2KSA() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("2KSA"); assertNotNull(sCif); @@ -105,7 +106,7 @@ public void test2BI6() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("2BI6"); assertNotNull(sCif); @@ -134,10 +135,10 @@ public void test1GQO() throws IOException, StructureException { params.setParseBioAssembly(true); StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure sPdb = StructureIO.getStructure("1GQO"); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("1GQO"); assertNotNull(sCif); @@ -168,7 +169,7 @@ public void test1GQO() throws IOException, StructureException { @Test public void testResidueNumbers() throws IOException, StructureException { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s = cache.getStructure("2PTC"); Chain c = s.getChainByIndex(0); @@ -248,7 +249,7 @@ public void test2KLI() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("2KLI"); assertNotNull(sCif); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java index 6362dc2a84..b205bd2140 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java @@ -24,6 +24,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.AtomCache; @@ -56,8 +57,7 @@ public void test4A1Immcif() throws IOException, StructureException { int biolAssemblyNr = 2; AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); - cache.setUseMmtf(false); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); Structure bioAssembly = StructureIO.getBiologicalAssembly(pdbId,biolAssemblyNr); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHeaderOnly.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHeaderOnly.java index f447953a32..7d246fc25e 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHeaderOnly.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHeaderOnly.java @@ -31,6 +31,7 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemComp; @@ -60,7 +61,7 @@ public void testHeaderOnly() throws StructureException, IOException { // Test 1: with PDB AtomCache cache = new AtomCache(); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); FileParsingParameters params = new FileParsingParameters(); params.setHeaderOnly(true); @@ -74,7 +75,7 @@ public void testHeaderOnly() throws StructureException, IOException { Assert.assertEquals(false, doSeqResHaveAtoms(sPDB)); // Test 2: with mmCIF - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCIF = StructureIO.getStructure(pdbID); Assert.assertEquals(false, doSeqResHaveAtoms(sCIF)); @@ -95,7 +96,7 @@ public void testAlignSeqres() throws StructureException, IOException { // Test 1: with PDB AtomCache cache = new AtomCache(); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); FileParsingParameters params = new FileParsingParameters(); params.setHeaderOnly(false); @@ -109,7 +110,7 @@ public void testAlignSeqres() throws StructureException, IOException { check1REPChainC(sPDB); // Check particular residues to be aligned. // Test 2: with mmCIF - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCIF = StructureIO.getStructure(pdbID); Assert.assertEquals(true, doSeqResHaveAtoms(sCIF)); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java index 31d4b86dd8..6187f2127b 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java @@ -40,6 +40,7 @@ import org.biojava.nbio.structure.ResidueNumber; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; @@ -77,7 +78,7 @@ private static void testRoundTrip(String pdbId) throws IOException, StructureExc StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMcifOrganismParsing.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMcifOrganismParsing.java index 71733aabaa..31c309f68e 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMcifOrganismParsing.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMcifOrganismParsing.java @@ -28,6 +28,7 @@ import org.biojava.nbio.structure.EntityType; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.BeforeClass; @@ -48,7 +49,7 @@ public class TestMMcifOrganismParsing { public static void setUp() throws Exception { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java index b0c7c8fe55..a604fffcaa 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java @@ -36,6 +36,7 @@ import org.biojava.nbio.structure.EntityType; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.cif.StructureConverter; @@ -117,7 +118,7 @@ public void test1B8G() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s = StructureIO.getStructure("1B8G"); System.out.println("Chains from full deposited file: "); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFFeatures.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFFeatures.java index f0c10f5e17..f4d5a6d9d2 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFFeatures.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFFeatures.java @@ -31,6 +31,7 @@ import org.biojava.nbio.structure.Site; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; @@ -45,7 +46,7 @@ public void testSSBond()throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = new FileParsingParameters(); params.setCreateAtomBonds(true); cache.setFileParsingParams(params); @@ -77,7 +78,7 @@ public void testSSBondAltLocs() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = new FileParsingParameters(); params.setCreateAtomBonds(true); cache.setFileParsingParams(params); @@ -147,7 +148,7 @@ public void testSites()throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("4HHB"); assertNotNull(sCif); @@ -181,7 +182,7 @@ public void testSites1a4w()throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("1A4W"); assertNotNull(sCif); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java index 2a997118f2..76d7d74a3d 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java @@ -29,6 +29,7 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; @@ -50,10 +51,10 @@ public class TestParseMmCIFLigands { public void testLigandConnections()throws IOException, StructureException { AtomCache cache = new AtomCache(); // This needs MMCIF - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); ChemCompGroupFactory.setChemCompProvider(new DownloadChemCompProvider()); FileParsingParameters params = cache.getFileParsingParams(); @@ -93,10 +94,10 @@ private int countBondedAtomsInLigandGroups(Structure s){ public void testMultipleConformations()throws IOException, StructureException { AtomCache cache = new AtomCache(); // This needs MMCIF - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); ChemCompGroupFactory.setChemCompProvider(new DownloadChemCompProvider()); FileParsingParameters params = cache.getFileParsingParams(); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseOnAsymId.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseOnAsymId.java index 448aed4750..fda734d668 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseOnAsymId.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseOnAsymId.java @@ -27,6 +27,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; @@ -39,7 +40,7 @@ public class TestParseOnAsymId { public void test4cup() throws IOException, StructureException { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = cache.getFileParsingParams(); cache.setFileParsingParams(params); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestQuaternaryStructureProviders.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestQuaternaryStructureProviders.java index c2d4ec71ad..0b67e66aaa 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestQuaternaryStructureProviders.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestQuaternaryStructureProviders.java @@ -59,7 +59,7 @@ public void test5LDH() throws IOException, StructureException{ boolean gotException = false; try { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); StructureIO.getBiologicalAssembly("5LDH",3); } catch (StructureException e) { @@ -72,7 +72,7 @@ public void test5LDH() throws IOException, StructureException{ gotException = false; try { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); StructureIO.getBiologicalAssembly("5LDH",2); } catch (StructureException e) { @@ -198,7 +198,7 @@ private void comparePdbVsMmcif(String pdbId, int bioMolecule, int mmSize) throws private Structure getPdbBioAssembly(String pdbId, int bioMolecule, boolean multiModel) throws IOException, StructureException { // get bio assembly from PDB file AtomCache cache = new AtomCache(); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); StructureIO.setAtomCache(cache); Structure pdbS = StructureIO.getBiologicalAssembly(pdbId, bioMolecule, multiModel); return pdbS; @@ -207,7 +207,7 @@ private Structure getPdbBioAssembly(String pdbId, int bioMolecule, boolean multi private Structure getMmcifBioAssembly(String pdbId, int bioMolecule, boolean multiModel) throws IOException, StructureException { // get bio assembly from mmcif file AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); Structure mmcifS = StructureIO.getBiologicalAssembly(pdbId, bioMolecule, multiModel); return mmcifS; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestTitleParsing.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestTitleParsing.java index 6b0be0663e..40b1368027 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestTitleParsing.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestTitleParsing.java @@ -22,6 +22,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; @@ -48,9 +49,9 @@ public void test2W6E() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure sPdb = StructureIO.getStructure("2W6E"); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure sCif = StructureIO.getStructure("2W6E"); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestWriteLargeCoordinatePDB.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestWriteLargeCoordinatePDB.java index 78137f73e2..0588d54d01 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestWriteLargeCoordinatePDB.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestWriteLargeCoordinatePDB.java @@ -28,6 +28,7 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; @@ -41,7 +42,7 @@ public class TestWriteLargeCoordinatePDB { public void TestWrite5D9Q() throws IOException, StructureException { AtomCache cache = new AtomCache(); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); FileParsingParameters params = new FileParsingParameters(); params.setHeaderOnly(false); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java index 89af60dc65..cf818c5c18 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestChemCompProvider.java @@ -46,7 +46,6 @@ public class TestChemCompProvider { // Short test with bad ligand name (QNA is bogus) final String DNAexample = - "ATOM 1 H MET A 1 11.756 -15.759 11.647 1.00 7.95\n" + "ATOM 2 N MET A 1 12.461 -16.373 11.329 1.00 7.95\n" + "ATOM 3 CA MET A 1 12.297 -17.782 11.674 1.00 7.95\n" + @@ -181,7 +180,7 @@ public void testNormalStructure() throws StructureException, IOException { long startTime = System.currentTimeMillis(); StructureIO.getStructure("4HHM"); long finishTime = System.currentTimeMillis(); - s_logger.info("ZipChemComp time: "+(finishTime-startTime)+ " ms"); + s_logger.info("ZipChemComp time: {} ms", finishTime - startTime); // Not wanted here for testing, but useful for cleaning up downloaded .cif.gz files. // ZipChemCompProvider.purgeTempFiles(pdbdir.toString()); @@ -189,7 +188,6 @@ public void testNormalStructure() throws StructureException, IOException { @Test public void testGetOneLetterCode() throws Exception { - String oneLetter; oneLetter = ChemCompGroupFactory.getOneLetterCode(ChemCompGroupFactory.getChemComp("ALA")); @@ -202,7 +200,5 @@ public void testGetOneLetterCode() throws Exception { // multiparent case, we should return ? oneLetter = ChemCompGroupFactory.getOneLetterCode(ChemCompGroupFactory.getChemComp("OIM")); assertEquals("?", oneLetter); - } - } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java index 94a9a18fa5..9f1fea5eb4 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java @@ -28,6 +28,7 @@ import org.biojava.nbio.structure.EntityInfo; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; @@ -46,7 +47,7 @@ public void testEntityId() throws IOException, StructureException { // Set up the atom cache to parse on Internal chain id AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); FileParsingParameters params = cache.getFileParsingParams(); DownloadChemCompProvider cc = new DownloadChemCompProvider(); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseInternalChainId.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseInternalChainId.java index 0132d29de4..8c4084745d 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseInternalChainId.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseInternalChainId.java @@ -26,6 +26,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; import static org.junit.Assert.*; @@ -40,7 +41,7 @@ public void test2I13() throws IOException, StructureException { AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s = cache.getStructure("2I13"); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseMmcifHeader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseMmcifHeader.java index 52c76422ec..c0d2423d35 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseMmcifHeader.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseMmcifHeader.java @@ -31,6 +31,7 @@ import org.biojava.nbio.structure.PDBHeader; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; @@ -51,7 +52,7 @@ public class TestParseMmcifHeader { public void testRfactors() throws IOException, StructureException { AtomCache atomCache = new AtomCache(); - atomCache.setUseMmCif(true); + atomCache.setFiletype(StructureFiletype.CIF); Structure structure = atomCache.getStructure("4cup"); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java index 9e850585b6..e400465ecb 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java @@ -20,6 +20,7 @@ */ package org.biojava.nbio.structure.io.mmtf; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.junit.Test; @@ -81,7 +82,7 @@ public int getInterBonds(String pdbId) throws IOException, StructureException { // Download parameters AtomCache cache = new AtomCache(); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); cache.setFetchBehavior(FetchBehavior.FETCH_FILES); FileParsingParameters params = cache.getFileParsingParams(); params.setCreateAtomBonds(true); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java index 96f9dd8c43..04e4cc93df 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java @@ -37,6 +37,7 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; @@ -73,7 +74,7 @@ public void testRoundTrip() throws IOException, StructureException { FileParsingParameters params = new FileParsingParameters(); params.setParseBioAssembly(true); cache.setFileParsingParams(params); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java index 0bed40a6be..acf23d4f88 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java @@ -9,6 +9,7 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; @@ -89,8 +90,7 @@ public void checkNonStandardAminoSeqresGroupsPopulated() throws StructureExcepti AtomCache cache = new AtomCache(); FileParsingParameters params = new FileParsingParameters(); cache.setFileParsingParams(params); - cache.setUseMmCif(false); - cache.setUseMmtf(true); + cache.setFiletype(StructureFiletype.MMTF); StructureIO.setAtomCache(cache); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestCrystalInfo.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestCrystalInfo.java index 501d6eb2af..775588a2ae 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestCrystalInfo.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestCrystalInfo.java @@ -45,13 +45,13 @@ public void test1NMR() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure s1 = StructureIO.getStructure("1NMR"); assertFalse(s1.isCrystallographic()); assertTrue(s1.isNmr()); assertEquals(s1.getPDBHeader().getExperimentalTechniques().iterator().next(),ExperimentalTechnique.SOLUTION_NMR); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s2 = StructureIO.getStructure("1NMR"); assertFalse(s2.isCrystallographic()); assertTrue(s2.isNmr()); @@ -69,14 +69,14 @@ public void test1B8G() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure s1 = StructureIO.getStructure("1B8G"); assertTrue(s1.isCrystallographic()); assertFalse(s1.isNmr()); assertEquals(s1.getPDBHeader().getExperimentalTechniques().iterator().next(),ExperimentalTechnique.XRAY_DIFFRACTION); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s2 = StructureIO.getStructure("1B8G"); assertTrue(s2.isCrystallographic()); assertFalse(s2.isNmr()); @@ -95,7 +95,7 @@ public void test4M7P() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure s1 = StructureIO.getStructure("4M7P"); assertTrue(s1.isCrystallographic()); assertFalse(s1.isNmr()); @@ -103,7 +103,7 @@ public void test4M7P() throws IOException, StructureException { assertEquals(s1.getPDBHeader().getExperimentalTechniques().iterator().next(),ExperimentalTechnique.XRAY_DIFFRACTION); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s2 = StructureIO.getStructure("4M7P"); assertTrue(s2.isCrystallographic()); assertFalse(s2.isNmr()); @@ -123,7 +123,7 @@ public void test2MBQ() throws IOException, StructureException { StructureIO.setAtomCache(cache); - cache.setUseMmCif(false); + cache.setFiletype(StructureFiletype.PDB); Structure s1 = StructureIO.getStructure("2MBQ"); assertFalse(s1.isCrystallographic()); assertTrue(s1.isNmr()); @@ -131,7 +131,7 @@ public void test2MBQ() throws IOException, StructureException { assertEquals(s1.getPDBHeader().getExperimentalTechniques().iterator().next(),ExperimentalTechnique.SOLUTION_NMR); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); Structure s2 = StructureIO.getStructure("2MBQ"); assertFalse(s2.isCrystallographic()); assertTrue(s2.isNmr()); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestInterfaceClustering.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestInterfaceClustering.java index af80c99ae1..bb5fe0b74c 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestInterfaceClustering.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestInterfaceClustering.java @@ -32,6 +32,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.asa.GroupAsa; @@ -55,7 +56,7 @@ public void test3DDO() throws IOException, StructureException { FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); cache.setFileParsingParams(params); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); @@ -103,7 +104,7 @@ public void test1AUY() throws IOException, StructureException { FileParsingParameters params = new FileParsingParameters(); params.setAlignSeqRes(true); cache.setFileParsingParams(params); - cache.setUseMmCif(true); + cache.setFiletype(StructureFiletype.CIF); StructureIO.setAtomCache(cache); From e7f563d78c31227d4f09736f5e6c6050da2d6a7d Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Mon, 25 Jan 2021 13:13:45 -0800 Subject: [PATCH 190/769] fix bcif download --- .../org/biojava/nbio/structure/io/LocalPDBDirectory.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java index 61735ecfa6..72ff6dee38 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java @@ -517,8 +517,11 @@ private File downloadStructure(String pdbId, String pathOnServer, boolean obsole String ftp; - if (getFilename(pdbId).endsWith(".mmtf.gz")){ + String filename = getFilename(pdbId); + if (filename.endsWith(".mmtf.gz")){ ftp = CodecUtils.getMmtfEntryUrl(pdbId, true, false); + } else if (filename.endsWith(".bcif") || filename.endsWith(".bcif.gz")) { + ftp = "https://models.rcsb.org/" + filename; } else { ftp = String.format("%s%s/%s/%s", serverName, pathOnServer, pdbId.substring(1,3).toLowerCase(), getFilename(pdbId)); From 0c00caca270976872b4423d0d344e00bd1e8fe28 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Mon, 25 Jan 2021 15:59:53 -0800 Subject: [PATCH 191/769] fix chemcomp type --- .../java/org/biojava/nbio/structure/chem/ResidueType.java | 4 ++++ .../nbio/structure/io/mmcif/TestEntityNameAndType.java | 3 +++ 2 files changed, 7 insertions(+) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ResidueType.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ResidueType.java index ddcaac453c..33390df136 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ResidueType.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ResidueType.java @@ -88,6 +88,10 @@ public PolymerType getPolymerType() { * @return */ public static ResidueType getResidueTypeFromString(String chem_comp_type) { + if (chem_comp_type == null) { + return null; + } + // Almost all calls to this method are for L-peptide linking. Use this knowledge for a shortcut. if (chem_comp_type.equalsIgnoreCase(lPeptideLinking.chem_comp_type)) { return lPeptideLinking; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java index 9f1fea5eb4..88b5c3cc40 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertArrayEquals; import java.io.IOException; +import java.util.Arrays; import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.EntityInfo; @@ -97,6 +98,8 @@ public void testEntityId() throws IOException, StructureException { assertArrayEquals(descriptionInformation, testDescInfo); assertArrayEquals(typeInformation, testTypeInfo); // Now check these work too + System.out.println(Arrays.toString(geneSourceSciName)); + System.out.println(Arrays.toString(testGeneSourceSciName)); assertArrayEquals(geneSourceSciName, testGeneSourceSciName); assertArrayEquals(geneSourceTaxId, testGeneSourceTaxId); assertArrayEquals(hostOrganismSciName, testHostOrganismSciName); From 85b6c6b3e7794f38a2cf916c865e8981163f9028 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 26 Jan 2021 10:39:34 -0800 Subject: [PATCH 192/769] chem comp parsing errors & missing crystal translation --- .../chem/DownloadChemCompProvider.java | 11 ++++-- .../structure/io/cif/ChemCompConverter.java | 1 - .../io/cif/StructureConsumerImpl.java | 3 ++ .../biojava/nbio/structure/TestAtomCache.java | 36 ++++++------------- 4 files changed, 22 insertions(+), 29 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java index 71a17b7292..e250a1ebd8 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/DownloadChemCompProvider.java @@ -5,6 +5,7 @@ import org.biojava.nbio.structure.align.util.UserConfiguration; import org.biojava.nbio.structure.io.LocalPDBDirectory; import org.biojava.nbio.structure.io.cif.ChemCompConverter; +import org.rcsb.cif.ParsingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -217,8 +218,14 @@ public ChemComp getChemComp(String recordName) { if (haveFile) { String filename = getLocalFileName(recordName); try { - ChemicalComponentDictionary dict = ChemCompConverter.fromPath(Paths.get(filename)); - ChemComp chemComp = dict.getChemComp(recordName); + ChemComp chemComp; + try { + ChemicalComponentDictionary dict = ChemCompConverter.fromPath(Paths.get(filename)); + chemComp = dict.getChemComp(recordName); + } catch (ParsingException e) { + // happens for corrupt files + chemComp = null; + } // May be null if the file was corrupt. Fall back on ReducedChemCompProvider in that case if (chemComp != null) { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java index d234d27dc4..aec300e717 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java @@ -1,6 +1,5 @@ package org.biojava.nbio.structure.io.cif; -import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.chem.ChemicalComponentDictionary; import org.biojava.nbio.structure.io.FileParsingParameters; import org.rcsb.cif.CifIO; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java index d858536847..346ac12d41 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java @@ -1377,14 +1377,17 @@ private void setStructNcsOps() { operator.setElement(0, 0, structNcsOper.getMatrix11().get(rowIndex)); operator.setElement(0, 1, structNcsOper.getMatrix12().get(rowIndex)); operator.setElement(0, 2, structNcsOper.getMatrix13().get(rowIndex)); + operator.setElement(0, 3, structNcsOper.getVector1().get(rowIndex)); operator.setElement(1, 0, structNcsOper.getMatrix21().get(rowIndex)); operator.setElement(1, 1, structNcsOper.getMatrix22().get(rowIndex)); operator.setElement(1, 2, structNcsOper.getMatrix23().get(rowIndex)); + operator.setElement(1, 3, structNcsOper.getVector2().get(rowIndex)); operator.setElement(2, 0, structNcsOper.getMatrix31().get(rowIndex)); operator.setElement(2, 1, structNcsOper.getMatrix32().get(rowIndex)); operator.setElement(2, 2, structNcsOper.getMatrix33().get(rowIndex)); + operator.setElement(2, 3, structNcsOper.getVector3().get(rowIndex)); operator.setElement(3, 0, 0); operator.setElement(3, 1, 0); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java index 17c6836a4f..5de3eca23a 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java @@ -220,45 +220,32 @@ public void testFetchObsolete() throws IOException, StructureException { } - @Test public void testSettingFileParsingType(){ - AtomCache cache = new AtomCache(); //test defaults - // first is mmtf, second is mmcif - testFlags(cache,true,false); + testFlags(cache, false, false, true); // now change the values - cache.setFiletype(StructureFiletype.CIF); - - testFlags(cache,false,true); + testFlags(cache, false, true, false); cache.setFiletype(StructureFiletype.MMTF); - - testFlags(cache,true,false); + testFlags(cache, true, false, false); // this sets to use PDB! cache.setFiletype(StructureFiletype.PDB); + testFlags(cache, false, false, false); - testFlags(cache,false,false); - - // back to defaults + // back to MMTF cache.setFiletype(StructureFiletype.MMTF); - - testFlags(cache,true,false); - + testFlags(cache, true, false, false); // back to parsing PDB cache.setFiletype(StructureFiletype.PDB); - - testFlags(cache,false,false); - - - + testFlags(cache, false, false, false); } @@ -268,15 +255,12 @@ public void testSettingFileParsingType(){ * @param useMmTf * @param useMmCif */ - private void testFlags(AtomCache cache ,boolean useMmTf, boolean useMmCif) { - + private void testFlags(AtomCache cache ,boolean useMmTf, boolean useMmCif, boolean useBcif) { assertEquals("flag for parsing mmtf is set to " + cache.getFiletype() + " but should be " + useMmTf, cache.getFiletype() == StructureFiletype.MMTF, useMmTf); assertEquals("flag for parsing mmcif is set to " + cache.getFiletype() + " but should be set to " + useMmCif, cache.getFiletype() == StructureFiletype.CIF, useMmCif); - - - + assertEquals("flag for parsing bcif is set to " + cache.getFiletype() + " but should be set to " + useBcif, + cache.getFiletype() == StructureFiletype.BCIF, useBcif); } - } From e9c59f677f33a4d89bb539be80df36dd91af2e9b Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 26 Jan 2021 11:10:00 -0800 Subject: [PATCH 193/769] fix entity parsing --- .../nbio/structure/io/cif/StructureConsumerImpl.java | 6 +++--- .../nbio/structure/io/mmcif/TestEntityNameAndType.java | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java index 346ac12d41..e49d9aaefe 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java @@ -1315,7 +1315,7 @@ private void addAncilliaryEntityData(int asymRowIndex, EntityInfo entityInfo) { // This is a potentially huge assumption... for (int rowIndex = 0; rowIndex < entitySrcGen.getRowCount(); rowIndex++) { - if (entitySrcGen.getEntityId().get(rowIndex).equals(structAsym.getEntityId().get(asymRowIndex))) { + if (!entitySrcGen.getEntityId().get(rowIndex).equals(structAsym.getEntityId().get(asymRowIndex))) { continue; } @@ -1323,7 +1323,7 @@ private void addAncilliaryEntityData(int asymRowIndex, EntityInfo entityInfo) { } for (int rowIndex = 0; rowIndex < entitySrcNat.getRowCount(); rowIndex++) { - if (entitySrcNat.getEntityId().get(rowIndex).equals(structAsym.getEntityId().get(asymRowIndex))) { + if (!entitySrcNat.getEntityId().get(rowIndex).equals(structAsym.getEntityId().get(asymRowIndex))) { continue; } @@ -1331,7 +1331,7 @@ private void addAncilliaryEntityData(int asymRowIndex, EntityInfo entityInfo) { } for (int rowIndex = 0; rowIndex < entitySrcSyn.getRowCount(); rowIndex++) { - if (entitySrcSyn.getEntityId().get(rowIndex).equals(structAsym.getEntityId().get(asymRowIndex))) { + if (!entitySrcSyn.getEntityId().get(rowIndex).equals(structAsym.getEntityId().get(asymRowIndex))) { continue; } diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java index 88b5c3cc40..444a7b800e 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java @@ -98,8 +98,6 @@ public void testEntityId() throws IOException, StructureException { assertArrayEquals(descriptionInformation, testDescInfo); assertArrayEquals(typeInformation, testTypeInfo); // Now check these work too - System.out.println(Arrays.toString(geneSourceSciName)); - System.out.println(Arrays.toString(testGeneSourceSciName)); assertArrayEquals(geneSourceSciName, testGeneSourceSciName); assertArrayEquals(geneSourceTaxId, testGeneSourceTaxId); assertArrayEquals(hostOrganismSciName, testHostOrganismSciName); From c30ab8f4a329279b04c0c2d7e351678cb6533f28 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Tue, 26 Jan 2021 11:19:17 -0800 Subject: [PATCH 194/769] Solving jaxb warning --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 411aa6d1be..66521c8b2f 100644 --- a/pom.xml +++ b/pom.xml @@ -519,17 +519,17 @@ javax.xml.bind jaxb-api - 2.3.0 + 2.3.1 com.sun.xml.bind jaxb-core - 2.3.0 + 2.3.0.1 com.sun.xml.bind jaxb-impl - 2.3.0 + 2.3.3 javax.activation From 28815dbd5c5d08cdad8a7b2e486cefb3b7a02106 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 26 Jan 2021 11:41:12 -0800 Subject: [PATCH 195/769] handle missing rfree/rwork --- .../biojava/nbio/structure/io/cif/StructureConsumerImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java index e49d9aaefe..35f46dc066 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java @@ -39,6 +39,7 @@ import org.rcsb.cif.model.FloatColumn; import org.rcsb.cif.model.IntColumn; import org.rcsb.cif.model.StrColumn; +import org.rcsb.cif.model.ValueKind; import org.rcsb.cif.schema.mm.AtomSite; import org.rcsb.cif.schema.mm.AtomSites; import org.rcsb.cif.schema.mm.AuditAuthor; @@ -829,7 +830,7 @@ public void consumeRefine(Refine refine) { logger.warn("More than 1 Rfree value present, will use last one {} and discard previous {}", lsRFactorRFree, String.format("%4.2f",pdbHeader.getRfree())); } - if (lsRFactorRFree.isDefined()) { + if (lsRFactorRFree.isDefined() && lsRFactorRFree.getValueKind(rowIndex) == ValueKind.PRESENT) { pdbHeader.setRfree((float) lsRFactorRFree.get(rowIndex)); } else { // some entries like 2ifo haven't got this field at all @@ -842,7 +843,7 @@ public void consumeRefine(Refine refine) { logger.warn("More than 1 R work value present, will use last one {} and discard previous {} ", lsRFactorRWork, String.format("%4.2f",pdbHeader.getRwork())); } - if (lsRFactorRWork.isDefined()) { + if (lsRFactorRWork.isDefined() && lsRFactorRWork.getValueKind(rowIndex) == ValueKind.PRESENT) { pdbHeader.setRwork((float) lsRFactorRWork.get(rowIndex)); } else { logger.info("_refine.ls_R_factor_R_work not present, not parsing R-work value"); From f36f82cb601895aa2f78f1dd440a072762cb0516 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 26 Jan 2021 11:59:45 -0800 Subject: [PATCH 196/769] SCOP hack to force loading of MMTF --- .../nbio/structure/align/util/AtomCache.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java index 4181792515..3067e5955d 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java @@ -524,7 +524,8 @@ public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatab public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatabase, boolean strictLigandHandling) throws IOException, StructureException { String pdbId = domain.getPdbId(); - Structure fullStructure = getStructureForPdbId(pdbId); + // SMB 1/26/21 - forcing loading MMTF here - TODO why doesn't mmCIF/CIF/BCIF parsing work here? + Structure fullStructure = getStructureForPdbIdByMmtf(pdbId); Structure structure = domain.reduce(fullStructure); // TODO It would be better to move all of this into the reduce method, @@ -800,6 +801,33 @@ public Structure getStructureForPdbId(String pdbId) throws IOException, Structur } } + /** + * SCOP parsing depends on MMTF, this a dedicated method to allow for that. + * @param pdbId what to load + * @return a Structure object + * @throws IOException + * @throws StructureException + */ + private Structure getStructureForPdbIdByMmtf(String pdbId) throws IOException, StructureException { + if (pdbId == null) + return null; + if (pdbId.length() != 4) { + throw new StructureException("Unrecognized PDB ID: " + pdbId); + } + while (checkLoading(pdbId)) { + // waiting for loading to be finished... + + try { + Thread.sleep(100); + } catch (InterruptedException e) { + logger.error(e.getMessage()); + } + } + + logger.debug("loading from mmtf"); + return loadStructureFromMmtfByPdbId(pdbId); + } + /** * Load a {@link Structure} from MMTF either from the local file system. * @param pdbId the input PDB id From 63d2ee7d2e25f929b9630cc5eebe4b102fa4bb58 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 26 Jan 2021 12:23:10 -0800 Subject: [PATCH 197/769] bcif/models URL is a constant --- .../org/biojava/nbio/structure/io/LocalPDBDirectory.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java index d207c5c886..2db30b046f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/LocalPDBDirectory.java @@ -63,6 +63,11 @@ public abstract class LocalPDBDirectory implements StructureIOFile { public static final String DEFAULT_PDB_FILE_SERVER = "http://ftp.wwpdb.org"; public static final String PDB_FILE_SERVER_PROPERTY = "PDB.FILE.SERVER"; + /** + * The default server to retrieve BinaryCIF files. + */ + public static final String DEFAULT_BCIF_FILE_SERVER = "https://models.rcsb.org/"; + /** * Behaviors for when an obsolete structure is requested. * @author Spencer Bliven @@ -521,7 +526,8 @@ private File downloadStructure(String pdbId, String pathOnServer, boolean obsole if (filename.endsWith(".mmtf.gz")){ ftp = CodecUtils.getMmtfEntryUrl(pdbId, true, false); } else if (filename.endsWith(".bcif") || filename.endsWith(".bcif.gz")) { - ftp = "https://models.rcsb.org/" + filename; + // TODO this should be configurable + ftp = DEFAULT_BCIF_FILE_SERVER + filename; } else { ftp = String.format("%s%s/%s/%s", serverName, pathOnServer, pdbId.substring(1,3).toLowerCase(), getFilename(pdbId)); From 2d4cc74edd6f3a88689a6de40b579a701230a351 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 26 Jan 2021 14:41:25 -0800 Subject: [PATCH 198/769] StructureInterface#toMMCIF --- .../structure/contact/StructureInterface.java | 95 ++++++++++--------- .../io/cif/AbstractCifFileSupplier.java | 20 ++-- .../structure/io/cif/CifFileSupplier.java | 2 - 3 files changed, 59 insertions(+), 58 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java index de50722b34..72a4cc2178 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/contact/StructureInterface.java @@ -20,12 +20,6 @@ */ package org.biojava.nbio.structure.contact; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - import org.biojava.nbio.structure.Atom; import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Element; @@ -40,10 +34,24 @@ import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.io.FileConvert; import org.biojava.nbio.structure.io.FileParsingParameters; +import org.biojava.nbio.structure.io.cif.AbstractCifFileSupplier; import org.biojava.nbio.structure.xtal.CrystalTransform; +import org.rcsb.cif.CifBuilder; +import org.rcsb.cif.CifIO; +import org.rcsb.cif.model.Category; +import org.rcsb.cif.schema.StandardSchemata; +import org.rcsb.cif.schema.mm.MmCifBlockBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.io.Serializable; +import java.io.UncheckedIOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + /** * An interface between 2 molecules (2 sets of atoms). @@ -748,45 +756,46 @@ public String toPDB() { * @return the mmCIF-formatted string */ public String toMMCIF() { - StringBuilder sb = new StringBuilder(); + String molecId1 = getMoleculeIds().getFirst(); + String molecId2 = getMoleculeIds().getSecond(); - // TODO impl -// String molecId1 = getMoleculeIds().getFirst(); -// String molecId2 = getMoleculeIds().getSecond(); -// -// if (isSymRelated()) { -// // if both chains are named equally we want to still named them differently in the output mmcif file -// // so that molecular viewers can handle properly the 2 chains as separate entities -// molecId2 = molecId2 + "_" +getTransforms().getSecond().getTransformId(); -// } -// -// sb.append(SimpleMMcifParser.MMCIF_TOP_HEADER).append("BioJava_interface_").append(getId()).append(System.getProperty("line.separator")); -// -// sb.append(FileConvert.getAtomSiteHeader()); -// -// // we reassign atom ids if sym related (otherwise atom ids would be duplicated and some molecular viewers can't cope with that) -// int atomId = 1; -// List atomSites = new ArrayList<>(); -// for (Atom atom:this.molecules.getFirst()) { -// if (isSymRelated()) { -// atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId1, molecId1, atomId)); -// } else { -// atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId1, molecId1)); -// } -// atomId++; -// } -// for (Atom atom:this.molecules.getSecond()) { -// if (isSymRelated()) { -// atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId2, molecId2, atomId)); -// } else { -// atomSites.add(MMCIFFileTools.convertAtomToAtomSite(atom, 1, molecId2, molecId2)); -// } -// atomId++; -// } -// -// sb.append(MMCIFFileTools.toMMCIF(atomSites,AtomSite.class)); + if (isSymRelated()) { + // if both chains are named equally we want to still named them differently in the output mmcif file + // so that molecular viewers can handle properly the 2 chains as separate entities + molecId2 = molecId2 + "_" + getTransforms().getSecond().getTransformId(); + } - return sb.toString(); + MmCifBlockBuilder mmCifBlockBuilder = CifBuilder.enterFile(StandardSchemata.MMCIF) + .enterBlock("BioJava_interface_" + getId()); + + // we reassign atom ids if sym related (otherwise atom ids would be duplicated and some molecular viewers can't cope with that) + int atomId = 1; + List wrappedAtoms = new ArrayList<>(); + for (Atom atom : this.molecules.getFirst()) { + if (isSymRelated()) { + wrappedAtoms.add(new AbstractCifFileSupplier.WrappedAtom(1, molecId1, molecId1, atom, atomId)); + } else { + wrappedAtoms.add(new AbstractCifFileSupplier.WrappedAtom(1, molecId1, molecId1, atom, atom.getPDBserial())); + } + atomId++; + } + for (Atom atom : this.molecules.getSecond()) { + if (isSymRelated()) { + wrappedAtoms.add(new AbstractCifFileSupplier.WrappedAtom(1, molecId2, molecId2, atom, atomId)); + } else { + wrappedAtoms.add(new AbstractCifFileSupplier.WrappedAtom(1, molecId2, molecId2, atom, atom.getPDBserial())); + } + atomId++; + } + + Category atomSite = wrappedAtoms.stream().collect(AbstractCifFileSupplier.toAtomSite()); + mmCifBlockBuilder.addCategory(atomSite); + + try { + return new String(CifIO.writeText(mmCifBlockBuilder.leaveBlock().leaveFile())); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } @Override diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java index 0c039467c1..2cb5e11acf 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java @@ -107,7 +107,7 @@ protected void handleChain(Chain chain, int model, List wrappedAtom continue; } - uniqueAtoms.put(atom.getPDBserial(), new WrappedAtom(chain, model, chainName, chainId, atom, atom.getPDBserial())); + uniqueAtoms.put(atom.getPDBserial(), new WrappedAtom(model, chainName, chainId, atom, atom.getPDBserial())); } if (group.hasAltLoc()) { @@ -118,7 +118,7 @@ protected void handleChain(Chain chain, int model, List wrappedAtom continue; } - uniqueAtoms.put(atom.getPDBserial(), new WrappedAtom(chain, model, chainName, chainId, atom, atom.getPDBserial())); + uniqueAtoms.put(atom.getPDBserial(), new WrappedAtom(model, chainName, chainId, atom, atom.getPDBserial())); } } } @@ -127,16 +127,14 @@ protected void handleChain(Chain chain, int model, List wrappedAtom } } - static class WrappedAtom { - private final Chain chain; + public static class WrappedAtom { private final int model; private final String chainName; private final String chainId; private final Atom atom; private final int atomId; - WrappedAtom(Chain chain, int model, String chainName, String chainId, Atom atom, int atomId) { - this.chain = chain; + public WrappedAtom(int model, String chainName, String chainId, Atom atom, int atomId) { this.model = model; this.chainName = chainName; this.chainId = chainId; @@ -144,10 +142,6 @@ static class WrappedAtom { this.atomId = atomId; } - Chain getChain() { - return chain; - } - int getModel() { return model; } @@ -169,7 +163,7 @@ int getAtomId() { } } - private static Collector toAtomSite() { + public static Collector toAtomSite() { return Collector.of(AtomSiteCollector::new, AtomSiteCollector::accept, AtomSiteCollector::combine, @@ -255,7 +249,7 @@ public void accept(WrappedAtom wrappedAtom) { labelEntityId.add(entityId); labelSeqId.add(seqId); String insCode = ""; - if (group.getResidueNumber().getInsCode() != null ) { + if (group.getResidueNumber().getInsCode() != null) { insCode = Character.toString(group.getResidueNumber().getInsCode()); } if (insCode.isEmpty()) { @@ -276,7 +270,7 @@ public void accept(WrappedAtom wrappedAtom) { } AtomSiteCollector combine(AtomSiteCollector other) { - throw new UnsupportedOperationException("impl by calling addAll for all collection"); + throw new UnsupportedOperationException("impl by calling addAll for all collections"); } Category get() { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java index 08f35fce54..e46a0bf058 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java @@ -2,8 +2,6 @@ import org.rcsb.cif.model.CifFile; -import java.util.function.Supplier; - /** * Create a CifFile instance for a given container of structure data. * @param the container type used as source From b7a40c545ff7aad55ee12433a51ea87fc8e09957 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 26 Jan 2021 18:04:43 -0800 Subject: [PATCH 199/769] TODO TestHardBioUnits --- .../java/org/biojava/nbio/structure/io/TestHardBioUnits.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java index b205bd2140..2c73fe0e0d 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java @@ -108,6 +108,10 @@ public void test4A1I() throws IOException, StructureException { String pdbId = "4A1I"; int biolAssemblyNr = 2; + AtomCache atomCache = new AtomCache(); + // TODO there seem to be numerical instabilities when parsing BCIF + atomCache.setFiletype(StructureFiletype.CIF); + StructureIO.setAtomCache(atomCache); Structure bioAssembly = StructureIO.getBiologicalAssembly(pdbId,biolAssemblyNr); if ( bioAssembly == null){ From 2f91dbf2d3085076f2b38f0e90c5c304c2c86727 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 26 Jan 2021 18:23:12 -0800 Subject: [PATCH 200/769] those aren't the FloatColumns you're looking for --- .../nbio/structure/io/cif/MetalBondConsumerImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java index d9d03a9590..4d484e5465 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java @@ -33,15 +33,15 @@ public void finish() { public void consume(Category category) { StrColumn atomType1 = (StrColumn) category.getColumn("atom_type_1"); StrColumn atomType2 = (StrColumn) category.getColumn("atom_type_2"); - FloatColumn lowerLimit = (FloatColumn) category.getColumn("lower_limit"); - FloatColumn upperLimit = (FloatColumn) category.getColumn("upper_limit"); + StrColumn lowerLimit = (StrColumn) category.getColumn("lower_limit"); + StrColumn upperLimit = (StrColumn) category.getColumn("upper_limit"); for (int i = 0; i < category.getRowCount(); i++) { MetalBondDistance d = new MetalBondDistance(); d.setAtomType1(atomType1.get(i)); d.setAtomType2(atomType2.get(i)); - d.setLowerLimit((float) lowerLimit.get(i)); - d.setUpperLimit((float) upperLimit.get(i)); + d.setLowerLimit(Float.parseFloat(lowerLimit.get(i))); + d.setUpperLimit(Float.parseFloat(upperLimit.get(i))); List defs = definitions.computeIfAbsent(d.getAtomType1(), k -> new ArrayList<>()); defs.add(d); From 9f42c9c142207737970489115a9880096cacc111 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 26 Jan 2021 18:51:31 -0800 Subject: [PATCH 201/769] trigger build --- .../org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java index 4d484e5465..7a5d600c79 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumerImpl.java @@ -2,7 +2,6 @@ import org.biojava.nbio.structure.chem.MetalBondDistance; import org.rcsb.cif.model.Category; -import org.rcsb.cif.model.FloatColumn; import org.rcsb.cif.model.StrColumn; import java.util.ArrayList; From 454830a223fb4a2b90c7d7650033b99ffad4783c Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Wed, 27 Jan 2021 09:20:52 -0800 Subject: [PATCH 202/769] docs --- .../structure/test/StructureToolsTest.java | 1 + .../biojava/nbio/structure/test/Test1o2f.java | 2 +- .../test/io/TestAtomCachePerformance.java | 2 +- .../structure/test/io/TestBioassemblies.java | 2 +- .../test/io/TestCrystallographicMetadata.java | 2 +- .../test/io/TestLongPdbVsMmCifParsing.java | 1 + .../io/TestStructWithMultiparentChemComp.java | 2 +- .../cif/CifFileSupplierIntegrationTest.java | 10 +- .../TestQuatSymmetryDetectorExamples.java | 2 +- .../test/xtal/TestCrystalBuilder.java | 2 +- .../main/java/demo/DemoQuatSymmetryJmol.java | 2 +- .../main/java/demo/DemoShowLargeAssembly.java | 2 +- .../src/main/java/demo/DemoAsa.java | 2 +- .../src/main/java/demo/DemoContacts.java | 1 + .../main/java/demo/DemoCrystalInterfaces.java | 2 +- .../src/main/java/demo/DemoLoadSecStruc.java | 2 +- .../src/main/java/demo/DemoMMCIFReader.java | 1 + .../java/demo/DemoMmcifToPdbConverter.java | 4 +- .../org/biojava/nbio/structure/Chain.java | 1 + .../nbio/structure/DatabasePDBRevRecord.java | 7 +- .../org/biojava/nbio/structure/Group.java | 103 ++++++------ .../biojava/nbio/structure/StructureIO.java | 1 + .../biojava/nbio/structure/URLIdentifier.java | 7 +- .../nbio/structure/align/util/AtomCache.java | 1 + .../align/util/UserConfiguration.java | 156 +++++++++++------- .../biojava/nbio/structure/chem/ChemComp.java | 4 +- .../nbio/structure/chem/ChemCompAtom.java | 7 +- .../nbio/structure/chem/ChemCompBond.java | 7 +- .../structure/chem/ChemCompDescriptor.java | 7 +- .../nbio/structure/io/BcifFileReader.java | 6 +- .../nbio/structure/io/CifFileReader.java | 6 +- .../nbio/structure/io/FileConvert.java | 15 +- .../structure/{ => io}/StructureFiletype.java | 9 +- .../io/cif/AbstractCifFileSupplier.java | 28 +++- .../structure/io/cif/ChemCompConsumer.java | 18 +- .../io/cif/ChemCompConsumerImpl.java | 4 + .../structure/io/cif/ChemCompConverter.java | 4 +- .../nbio/structure/io/cif/CifBean.java | 9 +- ...ierImpl.java => CifChainSupplierImpl.java} | 6 +- .../structure/io/cif/CifFileConsumer.java | 3 +- .../structure/io/cif/CifFileSupplier.java | 2 +- ...onsumer.java => CifStructureConsumer.java} | 7 +- ...mpl.java => CifStructureConsumerImpl.java} | 8 +- ...verter.java => CifStructureConverter.java} | 14 +- ...mpl.java => CifStructureSupplierImpl.java} | 6 +- .../structure/io/cif/MetalBondConsumer.java | 7 +- .../structure/io/cif/MetalBondConverter.java | 2 +- .../nbio/structure/io/mmtf/MmtfUtils.java | 3 +- .../org/biojava/nbio/structure/Test2JA5.java | 1 + .../org/biojava/nbio/structure/Test4hhb.java | 4 +- .../biojava/nbio/structure/TestAltLocs.java | 13 +- .../biojava/nbio/structure/TestAtomCache.java | 1 + .../org/biojava/nbio/structure/TestBond.java | 1 + .../biojava/nbio/structure/TestCloning.java | 1 + .../structure/TestEntityResIndexMapping.java | 1 + .../structure/TestExperimentalTechniques.java | 1 + .../structure/TestLoadStructureFromURL.java | 1 + .../nbio/structure/TestParsingCalcium.java | 1 + .../TestStructureCrossReferences.java | 1 + .../structure/align/util/AtomCacheTest.java | 2 +- .../structure/io/TestDifficultMmCIFFiles.java | 7 +- .../nbio/structure/io/TestHardBioUnits.java | 1 - .../nbio/structure/io/TestHeaderOnly.java | 5 +- .../nbio/structure/io/TestMMCIFWriting.java | 7 +- .../io/TestMMcifOrganismParsing.java | 1 - .../structure/io/TestNonDepositedFiles.java | 13 +- .../structure/io/TestParseMmCIFFeatures.java | 1 - .../structure/io/TestParseMmCIFLigands.java | 1 - .../nbio/structure/io/TestParseOnAsymId.java | 1 - .../nbio/structure/io/TestTitleParsing.java | 1 - .../io/TestWriteLargeCoordinatePDB.java | 1 - .../io/mmcif/TestEntityNameAndType.java | 3 +- .../io/mmcif/TestParseInternalChainId.java | 2 +- .../io/mmcif/TestParseMmcifHeader.java | 2 +- .../structure/io/mmtf/TestBondFinding.java | 2 +- .../structure/io/mmtf/TestMmtfRoundTrip.java | 8 +- .../io/mmtf/TestMmtfStructureReader.java | 2 +- .../nbio/structure/xtal/TestCrystalInfo.java | 1 + .../xtal/TestInterfaceClustering.java | 2 +- 79 files changed, 357 insertions(+), 232 deletions(-) rename biojava-structure/src/main/java/org/biojava/nbio/structure/{ => io}/StructureFiletype.java (75%) rename biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/{ChainSupplierImpl.java => CifChainSupplierImpl.java} (77%) rename biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/{StructureConsumer.java => CifStructureConsumer.java} (98%) rename biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/{StructureConsumerImpl.java => CifStructureConsumerImpl.java} (99%) rename biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/{StructureConverter.java => CifStructureConverter.java} (95%) rename biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/{StructureSupplierImpl.java => CifStructureSupplierImpl.java} (83%) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java index 510b071200..53bf6fe9ad 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/StructureToolsTest.java @@ -29,6 +29,7 @@ import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileParser; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Before; import org.junit.Test; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1o2f.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1o2f.java index af1ec695f7..d2795e28c4 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1o2f.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/Test1o2f.java @@ -22,7 +22,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestAtomCachePerformance.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestAtomCachePerformance.java index 03bf297484..5a89995450 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestAtomCachePerformance.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestAtomCachePerformance.java @@ -22,7 +22,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.junit.BeforeClass; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestBioassemblies.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestBioassemblies.java index 001dd5434e..f85c2a275b 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestBioassemblies.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestBioassemblies.java @@ -28,7 +28,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestCrystallographicMetadata.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestCrystallographicMetadata.java index c41ac34410..1c4db79571 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestCrystallographicMetadata.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestCrystallographicMetadata.java @@ -20,7 +20,7 @@ */ package org.biojava.nbio.structure.test.io; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Test; import static org.junit.Assert.*; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestLongPdbVsMmCifParsing.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestLongPdbVsMmCifParsing.java index fc529b75e3..3d788e830c 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestLongPdbVsMmCifParsing.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestLongPdbVsMmCifParsing.java @@ -24,6 +24,7 @@ import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.xtal.CrystalCell; import org.junit.After; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestStructWithMultiparentChemComp.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestStructWithMultiparentChemComp.java index 83059e7ea4..8aa6643fa4 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestStructWithMultiparentChemComp.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/TestStructWithMultiparentChemComp.java @@ -20,7 +20,7 @@ */ package org.biojava.nbio.structure.test.io; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Test; import static org.junit.Assert.*; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/cif/CifFileSupplierIntegrationTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/cif/CifFileSupplierIntegrationTest.java index 8e59c8a931..5cda83225d 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/cif/CifFileSupplierIntegrationTest.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/io/cif/CifFileSupplierIntegrationTest.java @@ -12,7 +12,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import org.junit.Test; import java.io.ByteArrayInputStream; @@ -49,10 +49,10 @@ public void test1A2C() throws IOException { private static void testRoundTrip(String pdbId) throws IOException { URL url = new URL("https://files.rcsb.org/download/" + pdbId + ".cif"); - Structure originalStruct = StructureConverter.fromURL(url); + Structure originalStruct = CifStructureConverter.fromURL(url); - InputStream inputStream = new ByteArrayInputStream(StructureConverter.toText(originalStruct).getBytes()); - Structure readStruct = StructureConverter.fromInputStream(inputStream); + InputStream inputStream = new ByteArrayInputStream(CifStructureConverter.toText(originalStruct).getBytes()); + Structure readStruct = CifStructureConverter.fromInputStream(inputStream); assertNotNull(readStruct); assertEquals(originalStruct.getChains().size(), readStruct.getChains().size()); @@ -113,7 +113,7 @@ private static void testRoundTrip(String pdbId) throws IOException { @Test public void testBiounitWriting() throws IOException { Structure s = createDummyStructure(); - String mmcif = StructureConverter.toText(s); + String mmcif = CifStructureConverter.toText(s); String[] lines = mmcif.split("\n"); long atomLines = Arrays.stream(lines).filter(l -> l.startsWith("ATOM")).count(); assertNotNull(mmcif); diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java index c46087eb58..08946e3e0a 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/symmetry/TestQuatSymmetryDetectorExamples.java @@ -27,7 +27,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.AtomCache; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/xtal/TestCrystalBuilder.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/xtal/TestCrystalBuilder.java index 4851c03ba9..d90241dbe0 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/xtal/TestCrystalBuilder.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/xtal/TestCrystalBuilder.java @@ -22,7 +22,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.contact.StructureInterfaceList; diff --git a/biojava-structure-gui/src/main/java/demo/DemoQuatSymmetryJmol.java b/biojava-structure-gui/src/main/java/demo/DemoQuatSymmetryJmol.java index 674c846d4a..999e4305fc 100644 --- a/biojava-structure-gui/src/main/java/demo/DemoQuatSymmetryJmol.java +++ b/biojava-structure-gui/src/main/java/demo/DemoQuatSymmetryJmol.java @@ -22,7 +22,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.cluster.SubunitClustererMethod; import org.biojava.nbio.structure.cluster.SubunitClustererParameters; diff --git a/biojava-structure-gui/src/main/java/demo/DemoShowLargeAssembly.java b/biojava-structure-gui/src/main/java/demo/DemoShowLargeAssembly.java index 4aa053e70a..343e50d226 100644 --- a/biojava-structure-gui/src/main/java/demo/DemoShowLargeAssembly.java +++ b/biojava-structure-gui/src/main/java/demo/DemoShowLargeAssembly.java @@ -1,7 +1,7 @@ package demo; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; diff --git a/biojava-structure/src/main/java/demo/DemoAsa.java b/biojava-structure/src/main/java/demo/DemoAsa.java index 1df3d9feeb..72d2b096d5 100644 --- a/biojava-structure/src/main/java/demo/DemoAsa.java +++ b/biojava-structure/src/main/java/demo/DemoAsa.java @@ -24,7 +24,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.asa.AsaCalculator; diff --git a/biojava-structure/src/main/java/demo/DemoContacts.java b/biojava-structure/src/main/java/demo/DemoContacts.java index 0eed99e807..f5ee18934c 100644 --- a/biojava-structure/src/main/java/demo/DemoContacts.java +++ b/biojava-structure/src/main/java/demo/DemoContacts.java @@ -25,6 +25,7 @@ import org.biojava.nbio.structure.contact.AtomContact; import org.biojava.nbio.structure.contact.AtomContactSet; import org.biojava.nbio.structure.contact.GroupContactSet; +import org.biojava.nbio.structure.io.StructureFiletype; import java.io.IOException; diff --git a/biojava-structure/src/main/java/demo/DemoCrystalInterfaces.java b/biojava-structure/src/main/java/demo/DemoCrystalInterfaces.java index 76fd4f6823..f5b76d86bf 100644 --- a/biojava-structure/src/main/java/demo/DemoCrystalInterfaces.java +++ b/biojava-structure/src/main/java/demo/DemoCrystalInterfaces.java @@ -23,7 +23,7 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.contact.*; import org.biojava.nbio.structure.io.FileParsingParameters; diff --git a/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java b/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java index 3254ff64ae..a9eaf67e41 100644 --- a/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java +++ b/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java @@ -25,7 +25,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.secstruc.SecStrucCalc; diff --git a/biojava-structure/src/main/java/demo/DemoMMCIFReader.java b/biojava-structure/src/main/java/demo/DemoMMCIFReader.java index e6b5eab186..1954ad99a4 100644 --- a/biojava-structure/src/main/java/demo/DemoMMCIFReader.java +++ b/biojava-structure/src/main/java/demo/DemoMMCIFReader.java @@ -28,6 +28,7 @@ import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.CifFileReader; import org.biojava.nbio.structure.io.StructureProvider; +import org.biojava.nbio.structure.io.StructureFiletype; import java.util.List; diff --git a/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java b/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java index 67de1031c0..e5c9f5cda6 100644 --- a/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java +++ b/biojava-structure/src/main/java/demo/DemoMmcifToPdbConverter.java @@ -23,7 +23,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import java.io.File; import java.io.IOException; @@ -43,7 +43,7 @@ public static void main(String[] args) throws Exception { public static void convert(File inFile, File outFile) throws IOException { // now get the protein structure. - Structure cifStructure = StructureConverter.fromPath(inFile.toPath()); + Structure cifStructure = CifStructureConverter.fromPath(inFile.toPath()); // and write it out as PDB format PrintWriter pr = new PrintWriter(outFile); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/Chain.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/Chain.java index c8413228ee..73827d2434 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/Chain.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/Chain.java @@ -24,6 +24,7 @@ package org.biojava.nbio.structure; import org.biojava.nbio.core.sequence.template.Sequence; +import org.biojava.nbio.structure.chem.ChemComp; import org.biojava.nbio.structure.io.FileParsingParameters; import java.io.Serializable; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java index 039c2f0cc4..ad6945ac70 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePDBRevRecord.java @@ -2,7 +2,12 @@ import org.biojava.nbio.structure.io.cif.CifBean; -public class DatabasePDBRevRecord implements CifBean { +/** + * Represents revision records for use by {@link PDBHeader}. + * @author Sebastian Bittrich + * @since 6.0.0 + */ +public class DatabasePDBRevRecord implements CifBean { private static final long serialVersionUID = 1L; private String revNum; private String type; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java index 36b8d3b1cd..d1e5f34963 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java @@ -53,28 +53,29 @@ * */ public interface Group extends Serializable { + /** Group property key for secondary structure annotation */ - String SEC_STRUC = "secstruc"; + public static final String SEC_STRUC = "secstruc"; /** * Get number of atoms. * @return number of atoms of this Group */ - int size(); + public int size(); /** * Return true or false, depending if this group has 3D coordinates or not. * * @return true if Group has 3D coordinates */ - boolean has3D(); + public boolean has3D (); /** * Flag if group has 3D data . * * @param flag true to set flag that this Group has 3D coordinates */ - void setPDBFlag(boolean flag); + public void setPDBFlag(boolean flag); /** * Get Type of group, one of {@link GroupType#AMINOACID}, {@link GroupType#HETATM} @@ -82,14 +83,14 @@ public interface Group extends Serializable { * * @return a String representing the type value */ - GroupType getType(); + public GroupType getType(); /** * Add an atom to this group. * * @param atom an Atom object */ - void addAtom(Atom atom); + public void addAtom(Atom atom); /** * Get list of atoms. @@ -97,33 +98,32 @@ public interface Group extends Serializable { * @return a List object representing the atoms * @see #setAtoms(List) */ - List getAtoms(); + public List getAtoms() ; + /** * Set the atoms of this group. - * @see Atom + * @see {@link Atom} * @param atoms a list of atoms */ - void setAtoms(List atoms); + public void setAtoms(List atoms); - /** - * Remove all atoms from this group. + /** Remove all atoms from this group. * */ - void clearAtoms(); + public void clearAtoms(); /** * Get an atom given its PDB name. * Beware that some PDB atom names are ambiguous (e.g. CA, which means C-alpha or Calcium), * ambiguities should not occur within the same group though. To solve these ambiguities * one would need to check the atom returned for the required element with {@link Atom#getElement()} - *

      - * Note this method will return only the atom in the default alternative location (be it '.' or a letter). * * @param name a trimmed String representing the atom's PDB name, e.g. "CA" * @return an Atom object or null if no such atom exists within this group */ - Atom getAtom(String name); + public Atom getAtom(String name) ; + /** * Get at atom by position. @@ -131,7 +131,7 @@ public interface Group extends Serializable { * @param position an int * @return an Atom object or null if no Atom exists for given position */ - Atom getAtom(int position); + public Atom getAtom(int position) ; /** * Tell whether a particular atom exists within this group. @@ -141,7 +141,7 @@ public interface Group extends Serializable { * @param name a trimmed String representing the atom's PDB name, e.g. "CA" * @return true if Atom with name exists within this group */ - boolean hasAtom(String name); + public boolean hasAtom(String name); /** * Get the PDB 3-letter name for this group. (e.g. ALA) @@ -149,7 +149,7 @@ public interface Group extends Serializable { * @return a String representing the PDBName value * @see #setPDBName */ - String getPDBName(); + public String getPDBName(); /** * Set the PDB 3-letter name for this group. (e.g. ALA) @@ -157,7 +157,8 @@ public interface Group extends Serializable { * @param s a String specifying the PDBName value * @see #getPDBName */ - void setPDBName(String s); + public void setPDBName(String s) ; + /** * Calculate if this group has all atoms required for an amino acid backbone. @@ -180,28 +181,33 @@ public interface Group extends Serializable { * @return true if all Atoms required for an AminoAcid are available (N, CA, C, O) * @see #getType */ - boolean hasAminoAtoms(); + public boolean hasAminoAtoms() ; + /** * Check if this group is a polymeric group, from the definition in Chemical Component Dictionary * * @return true if a polymeric group */ - boolean isPolymeric(); + public boolean isPolymeric(); + /** * Check if this group is an aminoacid group, from the definition in Chemical Component Dictionary * * @return true if an amino acid */ - boolean isAminoAcid(); + public boolean isAminoAcid(); + /** * Check if this group is a nucleotide group, from the definition in Chemical Component Dictionary * * @return true if a nucleotide */ - boolean isNucleotide(); + public boolean isNucleotide(); + + /** * Properties of this amino acid. Currently available properties are: @@ -212,7 +218,7 @@ public interface Group extends Serializable { * @param properties a Map object specifying the properties value * @see #getProperties */ - void setProperties(Map properties); + public void setProperties(Map properties) ; /** * Return properties. @@ -220,7 +226,7 @@ public interface Group extends Serializable { * * @return a HashMap object representing the properties value */ - Map getProperties(); + public Map getProperties() ; /** * Set a single property . @@ -229,7 +235,7 @@ public interface Group extends Serializable { * @param value an Object * @see #getProperty */ - void setProperty(String key, Object value); + public void setProperty(String key, Object value) ; /** * Get a single property . @@ -238,20 +244,21 @@ public interface Group extends Serializable { * @return an Object * @see #setProperty */ - Object getProperty(String key); + public Object getProperty(String key) ; /** * Get an Atom Iterator. * * @return an Iterator object */ - Iterator iterator(); + public Iterator iterator() ; + /** * Returns and identical copy of this Group object . * @return and identical copy of this Group object */ - Object clone(); + public Object clone(); /** * Sets the back-reference to its parent Chain. @@ -259,7 +266,7 @@ public interface Group extends Serializable { * @see #getChain() * @since 3.0 */ - void setChain(Chain chain); + public void setChain(Chain chain); /** * Returns the parent Chain of the Group. @@ -268,7 +275,7 @@ public interface Group extends Serializable { * @see #setChain(Chain) * @since 3.0 */ - Chain getChain(); + public Chain getChain() ; /** * Returns a dynamically created ResidueNumber for the group - this @@ -277,14 +284,15 @@ public interface Group extends Serializable { * @return ResidueNumber for the group. * @since 3.0 */ - ResidueNumber getResidueNumber(); + public ResidueNumber getResidueNumber(); + /** * Sets the ResidueNumber for this Group * * @param residueNumber the PDB residueNumber */ - void setResidueNumber(ResidueNumber residueNumber); + public void setResidueNumber(ResidueNumber residueNumber); /** * Utility method to temporarily set a chainID for a group, if a parent chain object does not exist yet. @@ -294,7 +302,7 @@ public interface Group extends Serializable { * @param residueNumber * @param iCode */ - void setResidueNumber(String chainId, Integer residueNumber, Character iCode); + public void setResidueNumber(String chainId, Integer residueNumber, Character iCode); /** * Utility method for returning the chainId of the Group or null if no @@ -304,21 +312,22 @@ public interface Group extends Serializable { * @since 3.0 * @return the ID of the chain */ - String getChainId(); + public String getChainId(); /** * Set the Chemical Component that closer describes this group. * * @param cc the chemical component */ - void setChemComp(ChemComp cc); + public void setChemComp(ChemComp cc); /** * Get the chemical component that closer describes this group. If the information does not exist yet, fetches the information from PDB web site. * * @return the Chemical Component definition for this Group. */ - ChemComp getChemComp(); + public ChemComp getChemComp(); + /** * Check if this group has alternate location groups. @@ -326,7 +335,8 @@ public interface Group extends Serializable { * @return boolean flag if there are alternate locations. * @see #getAltLocs() */ - boolean hasAltLoc(); + public boolean hasAltLoc(); + /** * Get the list of other alternate location groups. @@ -351,14 +361,14 @@ public interface Group extends Serializable { * * @return List of other groups that are on alternate locations */ - List getAltLocs(); + public List getAltLocs(); /** * Add a group that is an alternate location for this group. * * @param g the altloc group to add */ - void addAltLoc(Group g); + public void addAltLoc(Group g); /** * Determines if this group is water. @@ -366,7 +376,7 @@ public interface Group extends Serializable { * @see GroupType#WATERNAMES * @return true if it's water, false otherwise. */ - boolean isWater(); + public boolean isWater(); /** * Gets the alternate location group to this group that has the alt-loc character code passed. @@ -374,20 +384,21 @@ public interface Group extends Serializable { * @param altLoc the alternate location code of the group desired * @return the alternate location group if found, or null otherwise */ - Group getAltLocGroup(Character altLoc); + public Group getAltLocGroup(Character altLoc); + /** * Attempts to reduce the memory imprint of this group by trimming * all internal Collection objects to the required size. * */ - void trimToSize(); + public void trimToSize(); /** * Function to get the Group as an MDL molblock * @return the string of the MDL molblock */ - String toSDF(); + public String toSDF(); /** * Tells whether the group is annotated as HETATM in the file. @@ -395,7 +406,7 @@ public interface Group extends Serializable { * polymeric group is in a ligand chain or not. * @return */ - boolean isHetAtomInFile(); + public boolean isHetAtomInFile(); /** * Sets the field isHetAtomInFile which is intented only for @@ -403,5 +414,5 @@ public interface Group extends Serializable { * or in a polymeric chain. * @param isHetAtomInFile */ - void setHetAtomInFile(boolean isHetAtomInFile); + public void setHetAtomInFile(boolean isHetAtomInFile); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java index fb2967b101..c556d4444c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureIO.java @@ -21,6 +21,7 @@ package org.biojava.nbio.structure; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.io.StructureFiletype; import java.io.IOException; import java.util.List; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java index 00b624d95f..69b5833766 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/URLIdentifier.java @@ -20,10 +20,10 @@ */ package org.biojava.nbio.structure; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.PDBFileReader; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.io.mmtf.MmtfActions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +33,6 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; -import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -154,7 +153,7 @@ public Structure loadStructure(AtomCache cache) throws StructureException, IOExc switch(format) { case CIF: case BCIF: - return StructureConverter.fromURL(url); + return CifStructureConverter.fromURL(url); case MMTF: return MmtfActions.readFromInputStream(url.openStream()); default: case PDB: diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java index 3067e5955d..552f0427ef 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java @@ -41,6 +41,7 @@ import org.biojava.nbio.structure.io.MMTFFileReader; import org.biojava.nbio.structure.io.PDBFileReader; import org.biojava.nbio.core.util.FileDownloadUtils; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyBuilder; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; import org.biojava.nbio.structure.scop.ScopDatabase; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/UserConfiguration.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/UserConfiguration.java index ebcf3aaba6..70e85acec3 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/UserConfiguration.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/UserConfiguration.java @@ -19,12 +19,12 @@ package org.biojava.nbio.structure.align.util; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.align.ce.StartupParameters; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; import org.biojava.nbio.core.util.PrettyXMLWriter; import org.biojava.nbio.core.util.XMLWriter; +import org.biojava.nbio.structure.io.StructureFiletype; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,18 +34,21 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -/** - * A container to persist config to the file system + +/** A container to persist config to the file system * * @author Andreas Prlic + * */ -public class UserConfiguration { +public class UserConfiguration +{ + private static final Logger logger = LoggerFactory.getLogger(UserConfiguration.class); public static final String PDB_FORMAT = "PDB"; - public static final String MMCIF_FORMAT = "cif"; - public static final String BINARY_CIF = "bcif"; + public static final String MMCIF_FORMAT = "mmCif"; public static final String MMTF_FORMAT = "mmtf"; + public static final String BCIF_FORMAT = "bcif"; public static final String TMP_DIR = "java.io.tmpdir"; @@ -62,7 +65,8 @@ public class UserConfiguration { private String fileFormat; - private static final AtomicBoolean warningShown = new AtomicBoolean(false); + private static AtomicBoolean warningShown = new AtomicBoolean(false); + /** * Default UserConfiguration: @@ -96,51 +100,66 @@ public UserConfiguration(){ // note that in initCacheFilePath, we set to the provided one (if readable) or to the same as pdbFilePath cacheFilePath = initCacheFilePath(); - fileFormat = BINARY_CIF; + fileFormat = BCIF_FORMAT; } private String initPdbFilePath() { + String path = null; + String propertyName = PDB_DIR; + String userProvidedDir = System.getProperty(propertyName); - if (userProvidedDir != null && !userProvidedDir.trim().isEmpty()) { + if ( userProvidedDir != null && !userProvidedDir.trim().isEmpty()) { + path = userProvidedDir; logger.debug("Read PDB dir from system property {}: {}", propertyName, path); File f = new File(path); if (!f.isDirectory()) { - logger.warn("Provided path {} (with system property {}) is not a directory. Using system's temp " + - "directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); + logger.warn( + "Provided path {} (with system property {}) is not a directory. Using system's temp directory instead {}", + path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } else if (!f.canWrite()) { - logger.warn("Provided path {} (with system property {}) is not writable. Will not be able to write " + - "cached files.", path, propertyName); + logger.warn( + "Provided path {} (with system property {}) is not writable. Will not be able to write cached files.", + path, propertyName); // we don't require the PDB_DIR to be writable, so that it can be used with a pre-rsynced dir // thus if not writable, we only warn and go ahead using it } + + } else { Map env = System.getenv(); - if (env.containsKey(propertyName) && !env.get(propertyName).trim().isEmpty()) { + + if( env.containsKey(propertyName) && !env.get(propertyName).trim().isEmpty()) { path = env.get(propertyName); logger.debug("Read dir from environment variable {}: {}", propertyName, path); File f = new File(path); if (!f.isDirectory()) { - logger.warn("Provided path {} (with environment variable {}) is not a directory. Using system's " + - "temp directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); + logger.warn( + "Provided path {} (with environment variable {}) is not a directory. Using system's temp directory instead {}", + path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } else if (!f.canWrite()) { - logger.warn("Provided path {} (with environment variable {}) is not writable. Will not be able " + - "to write cached files", path, propertyName); + logger.warn( + "Provided path {} (with environment variable {}) is not writable. Will not be able to write cached files", + path, propertyName); // we don't require the PDB_DIR to be writable, so that it can be used with a pre-rsynced dir // thus if not writable, we only warn and go ahead using it } + } else { path = System.getProperty(TMP_DIR); - if (! warningShown.get()) { - logger.warn("Could not read dir from system property {} or environment variable {}, " + - "using system's temp directory {}", propertyName, propertyName, path); + if ( ! warningShown.get()) { + + logger.warn("Could not read dir from system property {} or environment variable {}, " + + "using system's temp directory {}", + propertyName, propertyName, path); + warningShown.set(true); } @@ -148,79 +167,95 @@ private String initPdbFilePath() { } } - if (!path.endsWith(lineSplit)) { + if ( ! path.endsWith(lineSplit) ) path = path + lineSplit; - } return path; + } private String initCacheFilePath() { + String path = null; + String propertyName = PDB_CACHE_DIR; + String userProvidedDir = System.getProperty(propertyName); - if (userProvidedDir != null) { + if ( userProvidedDir != null ) { + path = userProvidedDir; logger.debug("Read cache dir from system property {}: {}", propertyName, path); File f = new File(path); if (!f.isDirectory()) { - logger.warn("Provided path {} (with system property {}) is not a directory. Using system's temp " + - "directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); + logger.warn( + "Provided path {} (with system property {}) is not a directory. Using system's temp directory instead {}", + path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } else if (!f.canWrite()) { - logger.warn("Provided path {} (with system property {}) is not writable. Using system's temp " + - "directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); + logger.warn( + "Provided path {} (with system property {}) is not writable. Using system's temp directory instead {}", + path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); System.setProperty(propertyName,path); } + + } else { Map env = System.getenv(); - if (env.containsKey(propertyName)) { + if( env.containsKey(propertyName)) { path = env.get(propertyName); logger.debug("Read dir from environment variable {}: {}", propertyName, path); File f = new File(path); if (!f.isDirectory()) { - logger.warn("Provided path {} (with environment variable {}) is not a directory. Using system's " + - "temp directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); + logger.warn( + "Provided path {} (with environment variable {}) is not a directory. Using system's temp directory instead {}", + path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } else if (!f.canWrite()) { - logger.warn("Provided path {} (with environment variable {}) is not writable. Using system's " + - "temp directory instead {}", path, propertyName, System.getProperty(TMP_DIR)); + logger.warn( + "Provided path {} (with environment variable {}) is not writable. Using system's temp directory instead {}", + path, propertyName, System.getProperty(TMP_DIR)); path = System.getProperty(TMP_DIR); } + } else { // NOTE in case of not provided, then it is set to same as pdbFilePath // as PDB_DIR is not checked for being writable, we have to do that check here in case if (new File(pdbFilePath).canWrite()){ path = pdbFilePath; - logger.info("Could not read cache dir from system property {} or environment variable {}, " + - "using PDB directory instead {}", propertyName, propertyName, path); + logger.info("Could not read cache dir from system property {} or environment variable {}, " + + "using PDB directory instead {}", + propertyName, propertyName, path); System.setProperty(propertyName,path); + } else { path = System.getProperty(TMP_DIR); logger.warn("Could not read cache dir from system property {} or environment variable {}, " + "and PDB directory {} is not writable. Using system's temp directory instead {}", propertyName, propertyName, pdbFilePath, path); System.setProperty(propertyName,path); + } } } - if (!path.endsWith(lineSplit)) { + if ( ! path.endsWith(lineSplit) ) path = path + lineSplit; - } return path; + } - public String getPdbFilePath() { + public String getPdbFilePath() + { return pdbFilePath; } - public void setPdbFilePath(String pdbFilePath) { + public void setPdbFilePath(String pdbFilePath) + { this.pdbFilePath = pdbFilePath; } @@ -248,22 +283,24 @@ public void setObsoleteBehavior(ObsoleteBehavior obsoleteBehavior) { this.obsoleteBehavior = obsoleteBehavior; } - /** - * convert Configuration to an XML file so it can be serialized + /** convert Configuration to an XML file so it can be serialized * * @param pw * @return XMLWriter * @throws IOException */ - public XMLWriter toXML(PrintWriter pw) throws IOException { - XMLWriter xw = new PrettyXMLWriter(pw); + public XMLWriter toXML(PrintWriter pw) + throws IOException + { + + XMLWriter xw = new PrettyXMLWriter( pw); + toXML(xw); - return xw; - } + return xw ; + } - /** - * convert Configuration to an XML file so it can be serialized + /** convert Configuration to an XML file so it can be serialized * add to an already existing xml file. * * @param xw the XML writer to use @@ -271,7 +308,10 @@ public XMLWriter toXML(PrintWriter pw) throws IOException { * @throws IOException * @see org.biojava.nbio.structure.align.webstart.ConfigXMLHandler */ - public XMLWriter toXML(XMLWriter xw) throws IOException { + + public XMLWriter toXML(XMLWriter xw) + throws IOException + { xw.printRaw(""); //xw.printRaw(""); xw.openTag("JFatCatConfig"); @@ -279,18 +319,18 @@ public XMLWriter toXML(XMLWriter xw) throws IOException { xw.openTag("PDBFILEPATH"); // we don;t serialize the tempdir... String tempdir = System.getProperty(TMP_DIR); - if (!pdbFilePath.equals(tempdir)) { + if (! pdbFilePath.equals(tempdir)) xw.attribute("path", pdbFilePath); - } - xw.attribute("fetchBehavior", fetchBehavior + ""); - xw.attribute("obsoleteBehavior", obsoleteBehavior + ""); + xw.attribute("fetchBehavior", fetchBehavior+""); + xw.attribute("obsoleteBehavior", obsoleteBehavior+""); xw.attribute("fileFormat", fileFormat); xw.closeTag("PDBFILEPATH"); xw.closeTag("JFatCatConfig"); return xw ; - } + + } public static UserConfiguration fromStartupParams(StartupParameters params) { UserConfiguration config = new UserConfiguration(); @@ -311,7 +351,8 @@ public void setFileFormat (String fileFormat){ this.fileFormat = fileFormat; } - public String getFileFormat() { + public String getFileFormat() + { return fileFormat; } @@ -319,12 +360,11 @@ public StructureFiletype getStructureFiletype() { switch (fileFormat) { case MMCIF_FORMAT: return StructureFiletype.CIF; - case BINARY_CIF: - return StructureFiletype.BCIF; - case MMTF_FORMAT: - return StructureFiletype.MMTF; case PDB_FORMAT: return StructureFiletype.PDB; + case MMTF_FORMAT: + return StructureFiletype.MMTF; + case BCIF_FORMAT: default: return StructureFiletype.BCIF; } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java index f550d82a96..76043374fc 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java @@ -8,8 +8,10 @@ /** * Properties of a chemical component. + * @author Sebastian Bittrich + * @since 6.0.0 */ -public class ChemComp implements CifBean, Comparable { +public class ChemComp implements CifBean, Comparable { private static final long serialVersionUID = -4736341142030215915L; private String id; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java index d87a51e720..f99b3d6f74 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompAtom.java @@ -2,7 +2,12 @@ import org.biojava.nbio.structure.io.cif.CifBean; -public class ChemCompAtom implements CifBean { +/** + * Properties of an atom of a chemical component. + * @author Sebastian Bittrich + * @since 6.0.0 + */ +public class ChemCompAtom implements CifBean { private static final long serialVersionUID = 4070599340294758941L; private String compId; private String atomId; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompBond.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompBond.java index 6ac2ea25fd..8bc3b1ebdb 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompBond.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompBond.java @@ -4,7 +4,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ChemCompBond implements CifBean { +/** + * Properties of a bond in a chemical component. + * @author Sebastian Bittrich + * @since 6.0.0 + */ +public class ChemCompBond implements CifBean { private static final long serialVersionUID = 5905371029161975421L; private static final Logger logger = LoggerFactory.getLogger(ChemCompBond.class); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompDescriptor.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompDescriptor.java index 7628caef53..eb0cb13b5f 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompDescriptor.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemCompDescriptor.java @@ -4,7 +4,12 @@ import java.util.Objects; -public class ChemCompDescriptor implements CifBean { +/** + * Properties of the chemical component descriptor. + * @author Sebastian Bittrich + * @since 6.0.0 + */ +public class ChemCompDescriptor implements CifBean { private static final long serialVersionUID = 1078685833800736278L; private String compId; private String type; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BcifFileReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BcifFileReader.java index a122158aee..70e4b5fcf5 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BcifFileReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/BcifFileReader.java @@ -2,14 +2,14 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import java.io.IOException; import java.io.InputStream; /** * Parse binary Cif files and provide capabilities to store them locally. - * @author Sebastian Bittrich + * @author Sebastian Bittrich * @since 5.3.0 */ public class BcifFileReader extends LocalPDBDirectory { @@ -38,7 +38,7 @@ public BcifFileReader(String path) { @Override public Structure getStructure(InputStream inStream) throws IOException { - return StructureConverter.fromInputStream(inStream, getFileParsingParameters()); + return CifStructureConverter.fromInputStream(inStream, getFileParsingParameters()); } @Override diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/CifFileReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/CifFileReader.java index edfe601b8d..6afaf14717 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/CifFileReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/CifFileReader.java @@ -2,14 +2,14 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.align.util.UserConfiguration; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import java.io.IOException; import java.io.InputStream; /** * Parse text Cif files and provide capabilities to store them locally. - * @author Sebastian Bittrich + * @author Sebastian Bittrich * @since 5.3.0 */ public class CifFileReader extends LocalPDBDirectory { @@ -40,7 +40,7 @@ public CifFileReader(String path) { @Override public Structure getStructure(InputStream inStream) throws IOException{ - return StructureConverter.fromInputStream(inStream, getFileParsingParameters()); + return CifStructureConverter.fromInputStream(inStream, getFileParsingParameters()); } @Override diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java index 8264fb2b3f..35654bcb17 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/FileConvert.java @@ -40,7 +40,7 @@ import org.biojava.nbio.structure.PDBHeader; import org.biojava.nbio.structure.Site; import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -592,11 +592,20 @@ else if (name.length()==1) } + /** + * Convert this structure to its CIF representation. + * @return a String representing this structure as CIF + */ public String toMMCIF() { - return StructureConverter.toText(this.structure); + return CifStructureConverter.toText(this.structure); } + /** + * Convert a chain to its CIF representation. + * @param chain data + * @return a String representing this chain as CIF + */ public static String toMMCIF(Chain chain) { - return StructureConverter.toText(chain); + return CifStructureConverter.toText(chain); } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureFiletype.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureFiletype.java similarity index 75% rename from biojava-structure/src/main/java/org/biojava/nbio/structure/StructureFiletype.java rename to biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureFiletype.java index 6d56257f24..04a74a6220 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/StructureFiletype.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureFiletype.java @@ -1,15 +1,12 @@ -package org.biojava.nbio.structure; - -import org.biojava.nbio.structure.io.BcifFileReader; -import org.biojava.nbio.structure.io.CifFileReader; -import org.biojava.nbio.structure.io.MMTFFileReader; -import org.biojava.nbio.structure.io.PDBFileReader; +package org.biojava.nbio.structure.io; import java.util.Collections; import java.util.List; /** * An enum of supported file formats. + * @author Sebastian Bittrich + * @since 6.0.0 */ public enum StructureFiletype { PDB(new PDBFileReader().getExtensions()), diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java index 2cb5e11acf..4b9c3045b6 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/AbstractCifFileSupplier.java @@ -28,7 +28,7 @@ /** * Convert a BioJava object to a CifFile. - * @author Sebastian Bittrich + * @author Sebastian Bittrich * @since 5.3.0 */ public abstract class AbstractCifFileSupplier implements CifFileSupplier { @@ -127,6 +127,10 @@ protected void handleChain(Chain chain, int model, List wrappedAtom } } + /** + * Wrapped atoms represent individual atoms enriched with model- and chain-level information. Also, gives control + * over the atomId field. Useful to convert structures (and subsets thereof) to their mmCIF representation. + */ public static class WrappedAtom { private final int model; private final String chainName; @@ -134,6 +138,14 @@ public static class WrappedAtom { private final Atom atom; private final int atomId; + /** + * Construct a new atoms. + * @param model the model number + * @param chainName the label_asym_id + * @param chainId the auth_asym_id + * @param atom the atom instance itself + * @param atomId the label_atom_id + */ public WrappedAtom(int model, String chainName, String chainId, Atom atom, int atomId) { this.model = model; this.chainName = chainName; @@ -142,27 +154,31 @@ public WrappedAtom(int model, String chainName, String chainId, Atom atom, int a this.atomId = atomId; } - int getModel() { + public int getModel() { return model; } - String getChainName() { + public String getChainName() { return chainName; } - String getChainId() { + public String getChainId() { return chainId; } - Atom getAtom() { + public Atom getAtom() { return atom; } - int getAtomId() { + public int getAtomId() { return atomId; } } + /** + * Collects {@link WrappedAtom} instances into one {@link org.rcsb.cif.schema.mm.AtomSite}. + * @return an atom site record containing all atoms + */ public static Collector toAtomSite() { return Collector.of(AtomSiteCollector::new, AtomSiteCollector::accept, diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java index 5bbb3f7a6a..26bd53884d 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumer.java @@ -1,16 +1,32 @@ package org.biojava.nbio.structure.io.cif; -import org.biojava.nbio.structure.chem.ChemCompDescriptor; import org.biojava.nbio.structure.chem.ChemicalComponentDictionary; import org.rcsb.cif.schema.mm.ChemComp; import org.rcsb.cif.schema.mm.ChemCompAtom; import org.rcsb.cif.schema.mm.ChemCompBond; +/** + * Create the {@link ChemicalComponentDictionary} from CIF data. + * @author Sebastian Bittrich + * @since 6.0.0 + */ public interface ChemCompConsumer extends CifFileConsumer { + /** + * Consume a particular Cif category. + * @param c data + */ void consumeChemComp(ChemComp c); + /** + * Consume a particular Cif category. + * @param atom data + */ void consumeChemCompAtom(ChemCompAtom atom); + /** + * Consume a particular Cif category. + * @param bond data + */ void consumeChemCompBond(ChemCompBond bond); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java index ffe61f2d0b..584d8c6dfa 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConsumerImpl.java @@ -7,6 +7,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * Consumes a CCD file to create the {@link ChemicalComponentDictionary}. + * @author Sebastian Bittrich + */ public class ChemCompConsumerImpl implements ChemCompConsumer { private static final Logger logger = LoggerFactory.getLogger(ChemCompConsumerImpl.class); private final ChemicalComponentDictionary dictionary; diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java index aec300e717..497af0f0da 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChemCompConverter.java @@ -16,7 +16,7 @@ /** * Convert CifFiles to chem comps. - * @author Sebastian Bittrich + * @author Sebastian Bittrich * @since 6.0.0 */ public class ChemCompConverter { @@ -44,7 +44,7 @@ public static ChemicalComponentDictionary fromURL(URL url) throws IOException { * @param inputStream the InputStream of information - can be gzipped or binary or text data * @return the target * @throws IOException thrown when reading fails - * @see StructureConverter#fromInputStream(InputStream, FileParsingParameters) + * @see CifStructureConverter#fromInputStream(InputStream, FileParsingParameters) */ public static ChemicalComponentDictionary fromInputStream(InputStream inputStream) throws IOException { return fromCifFile(CifIO.readFromInputStream(inputStream)); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifBean.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifBean.java index 1196aafada..9adf3b3e43 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifBean.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifBean.java @@ -1,12 +1,11 @@ package org.biojava.nbio.structure.io.cif; -import org.rcsb.cif.model.Category; - import java.io.Serializable; /** - * Flag for BioJava beans that actually resemble categories defined by the mmCIF schema. - * @param the modeled ciftools-java category + * Flag for BioJava beans that resemble categories defined by the mmCIF schema. + * @author Sebastian Bittrich + * @since 6.0.0 */ -public interface CifBean extends Serializable { +public interface CifBean extends Serializable { } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChainSupplierImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifChainSupplierImpl.java similarity index 77% rename from biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChainSupplierImpl.java rename to biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifChainSupplierImpl.java index 08516d47b3..98e9da2f4e 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/ChainSupplierImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifChainSupplierImpl.java @@ -6,7 +6,11 @@ import java.util.ArrayList; import java.util.List; -public class ChainSupplierImpl extends AbstractCifFileSupplier { +/** + * Convert a chain to a {@link CifFile}. + * @author Sebastian Bittrich + */ +public class CifChainSupplierImpl extends AbstractCifFileSupplier { @Override public CifFile get(Chain container) { return getInternal(container.getStructure(), collectWrappedAtoms(container)); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java index d95f7b9422..565868e516 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumer.java @@ -2,9 +2,8 @@ /** * Defines a rather generic interface which allows to populate some data structure with data parsed from a CIF file. - * * @param the type of container an implementing class will return - * @author Sebastian Bittrich + * @author Sebastian Bittrich * @since 5.3.0 */ public interface CifFileConsumer { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java index e46a0bf058..0ea1e06bd7 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileSupplier.java @@ -5,7 +5,7 @@ /** * Create a CifFile instance for a given container of structure data. * @param the container type used as source - * @author Sebastian Bittrich + * @author Sebastian Bittrich * @since 5.3.0 */ public interface CifFileSupplier { diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumer.java similarity index 98% rename from biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumer.java rename to biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumer.java index 9594a2c71d..c6c5318217 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumer.java @@ -47,7 +47,12 @@ import org.rcsb.cif.schema.mm.StructSiteGen; import org.rcsb.cif.schema.mm.Symmetry; -public interface StructureConsumer extends CifFileConsumer { +/** + * Defines the categories to consume during CIF parsing. + * @author Sebastian Bittrich + * @since 6.0.0 + */ +public interface CifStructureConsumer extends CifFileConsumer { /** * Consume a particular Cif category. * @param atomSite data diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java similarity index 99% rename from biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java rename to biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java index 35f46dc066..c64f1ac412 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java @@ -100,11 +100,11 @@ /** * An implementation of a CifFileConsumer for BioJava. Will process the information provided by a CifFile instance and * use it to build up a {@link Structure} object. - * @author Sebastian Bittrich + * @author Sebastian Bittrich * @since 6.0.0 */ -public class StructureConsumerImpl implements StructureConsumer { - private static final Logger logger = LoggerFactory.getLogger(StructureConsumerImpl.class); +public class CifStructureConsumerImpl implements CifStructureConsumer { + private static final Logger logger = LoggerFactory.getLogger(CifStructureConsumerImpl.class); private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder() .parseCaseInsensitive() .appendPattern("yyyy-MM-dd") @@ -141,7 +141,7 @@ public class StructureConsumerImpl implements StructureConsumer { private final FileParsingParameters params; - public StructureConsumerImpl(FileParsingParameters params) { + public CifStructureConsumerImpl(FileParsingParameters params) { this.params = params; } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConverter.java similarity index 95% rename from biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConverter.java rename to biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConverter.java index 45a5b97c76..98ef24561b 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureConverter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConverter.java @@ -17,10 +17,10 @@ /** * Convert BioJava structures to CifFiles and vice versa. - * @author Sebastian Bittrich + * @author Sebastian Bittrich * @since 6.0.0 */ -public class StructureConverter { +public class CifStructureConverter { /** * Read data from a file and convert to Structure without any FileParsingParameters. * @param path the source of information - can be gzipped or binary or text data @@ -66,7 +66,7 @@ private static Structure fromURL(URL url, FileParsingParameters parameters) thro * @param inputStream the InputStream of information - can be gzipped or binary or text data * @return the target * @throws IOException thrown when reading fails - * @see StructureConverter#fromInputStream(InputStream, FileParsingParameters) + * @see CifStructureConverter#fromInputStream(InputStream, FileParsingParameters) */ public static Structure fromInputStream(InputStream inputStream) throws IOException { return fromInputStream(inputStream, new FileParsingParameters()); @@ -87,7 +87,7 @@ public static Structure fromInputStream(InputStream inputStream, FileParsingPara * Convert CifFile to Structure without any FileParsingParameters. * @param cifFile the source * @return the target - * @see StructureConverter#fromCifFile(CifFile, FileParsingParameters) + * @see CifStructureConverter#fromCifFile(CifFile, FileParsingParameters) */ public static Structure fromCifFile(CifFile cifFile) { return fromCifFile(cifFile, new FileParsingParameters()); @@ -101,7 +101,7 @@ public static Structure fromCifFile(CifFile cifFile) { */ public static Structure fromCifFile(CifFile cifFile, FileParsingParameters parameters) { // initialize consumer - StructureConsumer consumer = new StructureConsumerImpl(parameters); + CifStructureConsumer consumer = new CifStructureConsumerImpl(parameters); // init structure consumer.prepare(); @@ -226,7 +226,7 @@ public static String toText(Chain chain) { * @return the target */ public static CifFile toCifFile(Structure structure) { - return new StructureSupplierImpl().get(structure); + return new CifStructureSupplierImpl().get(structure); } /** @@ -235,6 +235,6 @@ public static CifFile toCifFile(Structure structure) { * @return the target */ public static CifFile toCifFile(Chain chain) { - return new ChainSupplierImpl().get(chain); + return new CifChainSupplierImpl().get(chain); } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureSupplierImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureSupplierImpl.java similarity index 83% rename from biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureSupplierImpl.java rename to biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureSupplierImpl.java index ef377ad52a..4b0eb79eb3 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/StructureSupplierImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureSupplierImpl.java @@ -7,7 +7,11 @@ import java.util.ArrayList; import java.util.List; -public class StructureSupplierImpl extends AbstractCifFileSupplier { +/** + * Convert a structure to a CifFile. + * @author Sebastian Bittrich + */ +public class CifStructureSupplierImpl extends AbstractCifFileSupplier { @Override public CifFile get(Structure container) { return getInternal(container, collectWrappedAtoms(container)); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumer.java index d76d91d1e7..df86c2c216 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConsumer.java @@ -6,6 +6,11 @@ import java.util.List; import java.util.Map; -public interface MetalBondConsumer extends CifFileConsumer>> { +/** + * Consume metal bond data. + * @author Sebastian Bittrich + * @since 6.0.0 + */ +public interface MetalBondConsumer extends CifFileConsumer>> { void consume(Category category); } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConverter.java index 0f28fe6493..c1ac0f3d2c 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConverter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/MetalBondConverter.java @@ -17,7 +17,7 @@ public class MetalBondConverter { private static final Logger logger = LoggerFactory.getLogger(MetalBondConverter.class); private static final String BONDS_FILE = "org/biojava/nbio/structure/bond_distance_limits.cif.gz"; - private static Map> definitions; + private static final Map> definitions; static { definitions = init(); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index a6c52c95bd..c41eb33033 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -45,7 +45,7 @@ import org.biojava.nbio.structure.PDBCrystallographicInfo; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemComp; @@ -55,7 +55,6 @@ import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; -import org.biojava.nbio.structure.secstruc.DSSPParser; import org.biojava.nbio.structure.secstruc.SecStrucCalc; import org.biojava.nbio.structure.secstruc.SecStrucState; import org.biojava.nbio.structure.secstruc.SecStrucType; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/Test2JA5.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/Test2JA5.java index eb7008d0cb..0d2a6d5742 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/Test2JA5.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/Test2JA5.java @@ -26,6 +26,7 @@ import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Test; /** diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/Test4hhb.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/Test4hhb.java index bcf289cebc..52e088261e 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/Test4hhb.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/Test4hhb.java @@ -26,7 +26,7 @@ import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileParser; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import org.junit.Test; import java.io.IOException; @@ -75,7 +75,7 @@ public void test4hhbPDBFile() throws IOException params = new FileParsingParameters(); params.setAlignSeqRes(true); - structure2 = StructureConverter.fromInputStream(inStream, params); + structure2 = CifStructureConverter.fromInputStream(inStream, params); assertNotNull(structure2); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java index ef9f830ae1..9c5bdcf0be 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAltLocs.java @@ -27,13 +27,12 @@ import org.biojava.nbio.structure.chem.PolymerType; import org.biojava.nbio.structure.chem.ResidueType; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Test; -import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.StringReader; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -639,7 +638,7 @@ public void testMmcifConversionPartialAltlocs() throws IOException { "ATOM 117 N NH2 A ARG A 1 13 ? 7.812 17.972 17.172 0.50 24.80 ? 102 ARG A NH2 1\n" + "ATOM 118 N NH2 B ARG A 1 13 ? 8.013 18.115 17.888 0.50 26.52 ? 102 ARG A NH2 1\n"; - Structure s = StructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes())); + Structure s = CifStructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes())); Chain c = s.getPolyChains().get(0); assertEquals(1, c.getAtomGroups().size()); Group g = c.getAtomGroup(0); @@ -718,7 +717,7 @@ public void testMmcifConversionAllAltlocs() throws IOException { "ATOM 216 C CD A PRO A 1 23 ? 14.980 32.886 23.580 0.50 6.98 ? 112 PRO A CD 1 \n" + "ATOM 217 C CD B PRO A 1 23 ? 14.558 33.235 23.153 0.50 14.91 ? 112 PRO A CD 1 \n"; - Structure s = StructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes())); + Structure s = CifStructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes())); Chain c = s.getPolyChains().get(0); assertEquals(1, c.getAtomGroups().size()); @@ -803,7 +802,7 @@ public void testIntraResidueBondsBetweenAltlocs() throws IOException { FileParsingParameters params = new FileParsingParameters(); params.setCreateAtomBonds(true); - Structure s = StructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes()), params); + Structure s = CifStructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes()), params); Chain c = s.getPolyChains().get(0); assertEquals(1, c.getAtomGroups().size()); @@ -949,7 +948,7 @@ public void testInterResidueBondsBetweenAltlocs() throws IOException { FileParsingParameters params = new FileParsingParameters(); params.setCreateAtomBonds(true); - Structure s = StructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes()), params); + Structure s = CifStructureConverter.fromInputStream(new ByteArrayInputStream(mmcifData.getBytes()), params); Chain c = s.getPolyChains().get(0); assertEquals(2, c.getAtomGroups().size()); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java index 5de3eca23a..bb9ec5ba2a 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java @@ -30,6 +30,7 @@ import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; import org.biojava.nbio.structure.io.LocalPDBDirectory.ObsoleteBehavior; import org.biojava.nbio.structure.io.PDBFileReader; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Before; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java index cd64006861..6cc9b2d05e 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java @@ -28,6 +28,7 @@ import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestCloning.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestCloning.java index 4ce757bc91..516e96fce5 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestCloning.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestCloning.java @@ -30,6 +30,7 @@ import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Test; import static org.junit.Assert.*; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestEntityResIndexMapping.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestEntityResIndexMapping.java index 401a42f2cb..61b3812a46 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestEntityResIndexMapping.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestEntityResIndexMapping.java @@ -31,6 +31,7 @@ import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.PDBFileParser; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Ignore; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestExperimentalTechniques.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestExperimentalTechniques.java index 6ef6224f8d..1edea84097 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestExperimentalTechniques.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestExperimentalTechniques.java @@ -21,6 +21,7 @@ package org.biojava.nbio.structure; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Test; import java.io.IOException; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestLoadStructureFromURL.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestLoadStructureFromURL.java index fb182535f1..5ba56deb19 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestLoadStructureFromURL.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestLoadStructureFromURL.java @@ -23,6 +23,7 @@ import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.align.util.UserConfiguration; import org.biojava.nbio.structure.io.PDBFileReader; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Test; import java.io.File; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestParsingCalcium.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestParsingCalcium.java index c3212fac8c..096dff1e1a 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestParsingCalcium.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestParsingCalcium.java @@ -25,6 +25,7 @@ package org.biojava.nbio.structure; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Test; import java.io.IOException; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestStructureCrossReferences.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestStructureCrossReferences.java index ebcea45acf..816d817231 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestStructureCrossReferences.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestStructureCrossReferences.java @@ -33,6 +33,7 @@ import org.biojava.nbio.structure.contact.StructureInterface; import org.biojava.nbio.structure.contact.StructureInterfaceList; import org.biojava.nbio.structure.io.FileParsingParameters; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.xtal.CrystalBuilder; import org.junit.Test; import org.slf4j.Logger; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java index 1b30f95ad6..25a711e0b1 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java @@ -47,7 +47,7 @@ import org.biojava.nbio.structure.ResidueRangeAndLength; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.StructureIdentifier; import org.biojava.nbio.structure.StructureTools; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestDifficultMmCIFFiles.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestDifficultMmCIFFiles.java index 690f877f08..0edf607c86 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestDifficultMmCIFFiles.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestDifficultMmCIFFiles.java @@ -27,11 +27,9 @@ import static org.junit.Assume.assumeNotNull; import static org.junit.Assume.assumeTrue; -import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.net.URISyntaxException; import java.net.URL; import java.util.List; @@ -42,10 +40,9 @@ import org.biojava.nbio.structure.ResidueNumber; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.junit.Test; @@ -222,7 +219,7 @@ public void testQuotingCornerCase () throws IOException { FileParsingParameters fileParsingParams = new FileParsingParameters(); fileParsingParams.setAlignSeqRes(true); - Structure s = StructureConverter.fromInputStream(inStream, fileParsingParams); + Structure s = CifStructureConverter.fromInputStream(inStream, fileParsingParams); assertNotNull(s); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java index 2c73fe0e0d..b50b4524fc 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java @@ -24,7 +24,6 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.AtomCache; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHeaderOnly.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHeaderOnly.java index 7d246fc25e..5ac9537412 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHeaderOnly.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHeaderOnly.java @@ -31,12 +31,11 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemComp; import org.biojava.nbio.structure.io.LocalPDBDirectory.FetchBehavior; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; @@ -170,7 +169,7 @@ public void testSpeed2() throws StructureException, IOException { logger.info("Testing mmCIF parsing speed"); start = System.nanoTime(); - Structure s2 = StructureConverter.fromInputStream(cifStream, params); + Structure s2 = CifStructureConverter.fromInputStream(cifStream, params); stop = System.nanoTime(); diff = (stop - start) / 1000000000.0; logger.info(String.format("[%s] Elapsed time: %.3f s", s2.getIdentifier(), diff)); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java index 6187f2127b..12b3d1a3b7 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMCIFWriting.java @@ -22,9 +22,7 @@ import static org.junit.Assert.*; -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Arrays; @@ -40,12 +38,11 @@ import org.biojava.nbio.structure.ResidueNumber; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.StructureImpl; import org.biojava.nbio.structure.StructureTools; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import org.junit.Test; public class TestMMCIFWriting { @@ -96,7 +93,7 @@ private static void testRoundTrip(String pdbId) throws IOException, StructureExc FileParsingParameters fileParsingParams = new FileParsingParameters(); fileParsingParams.setAlignSeqRes(true); - Structure readStruct = StructureConverter.fromPath(outputFile.toPath(), params); + Structure readStruct = CifStructureConverter.fromPath(outputFile.toPath(), params); assertNotNull(readStruct); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMcifOrganismParsing.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMcifOrganismParsing.java index 31c309f68e..8d018f6c0a 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMcifOrganismParsing.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestMMcifOrganismParsing.java @@ -28,7 +28,6 @@ import org.biojava.nbio.structure.EntityType; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.BeforeClass; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java index a604fffcaa..a04deda47d 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestNonDepositedFiles.java @@ -22,11 +22,9 @@ import static org.junit.Assert.*; -import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.net.URL; import java.util.List; import java.util.zip.GZIPInputStream; @@ -36,10 +34,9 @@ import org.biojava.nbio.structure.EntityType; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import org.biojava.nbio.structure.xtal.CrystalCell; import org.junit.Test; @@ -209,7 +206,7 @@ public void testPhenixCifFile() throws IOException { FileParsingParameters fileParsingParams = new FileParsingParameters(); fileParsingParams.setAlignSeqRes(true); - Structure s = StructureConverter.fromInputStream(inStream, fileParsingParams); + Structure s = CifStructureConverter.fromInputStream(inStream, fileParsingParams); assertNotNull(s); @@ -333,7 +330,7 @@ public void testNewLigandChain() throws IOException { int expectedNumLigands = 1; assertEquals(expectedNumLigands, c1.getAtomGroups().size()); - Structure s2 = StructureConverter.fromInputStream(cifStream, params); + Structure s2 = CifStructureConverter.fromInputStream(cifStream, params); // The chain B should be present with 1 ligand HEM Chain c2 = s2.getNonPolyChainsByPDB("B").get(0); @@ -373,7 +370,7 @@ public void testWaterOnlyChainCif() throws IOException { // following file is cut-down versions of 4a10 InputStream cifStream = new GZIPInputStream(this.getClass().getResourceAsStream("/org/biojava/nbio/structure/io/4a10_short.cif.gz")); - Structure s2 = StructureConverter.fromInputStream(cifStream); + Structure s2 = CifStructureConverter.fromInputStream(cifStream); assertEquals(2, s2.getChains().size()); @@ -431,7 +428,7 @@ public void testStructureWithBranchedEntities() throws IOException { URL url = new URL("https://raw.githubusercontent.com/pdbxmmcifwg/carbohydrate-extension/master/examples/models/1B5F-carb.cif"); InputStream inStream = url.openStream(); - Structure structure = StructureConverter.fromInputStream(inStream); + Structure structure = CifStructureConverter.fromInputStream(inStream); assertEquals(7, structure.getEntityInfos().size()); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFFeatures.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFFeatures.java index f4d5a6d9d2..3042cc6269 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFFeatures.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFFeatures.java @@ -31,7 +31,6 @@ import org.biojava.nbio.structure.Site; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java index 76d7d74a3d..43017bf5d9 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseMmCIFLigands.java @@ -29,7 +29,6 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseOnAsymId.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseOnAsymId.java index fda734d668..45ca5f2211 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseOnAsymId.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestParseOnAsymId.java @@ -27,7 +27,6 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestTitleParsing.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestTitleParsing.java index 40b1368027..06e9f48484 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestTitleParsing.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestTitleParsing.java @@ -22,7 +22,6 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestWriteLargeCoordinatePDB.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestWriteLargeCoordinatePDB.java index 0588d54d01..eeb488a5d4 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestWriteLargeCoordinatePDB.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestWriteLargeCoordinatePDB.java @@ -28,7 +28,6 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java index 444a7b800e..5c6b132cbb 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestEntityNameAndType.java @@ -23,13 +23,12 @@ import static org.junit.Assert.assertArrayEquals; import java.io.IOException; -import java.util.Arrays; import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.EntityInfo; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseInternalChainId.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseInternalChainId.java index 8c4084745d..01fcc953c3 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseInternalChainId.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseInternalChainId.java @@ -26,7 +26,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; import static org.junit.Assert.*; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseMmcifHeader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseMmcifHeader.java index c0d2423d35..8c789ea2d6 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseMmcifHeader.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmcif/TestParseMmcifHeader.java @@ -31,7 +31,7 @@ import org.biojava.nbio.structure.PDBHeader; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java index e400465ecb..fd94dff8f5 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestBondFinding.java @@ -20,7 +20,7 @@ */ package org.biojava.nbio.structure.io.mmtf; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.junit.Test; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java index 04e4cc93df..e362c2a35f 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfRoundTrip.java @@ -20,10 +20,8 @@ */ package org.biojava.nbio.structure.io.mmtf; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.Collections; @@ -37,13 +35,13 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; import org.biojava.nbio.structure.chem.DownloadChemCompProvider; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.io.cif.StructureConverter; +import org.biojava.nbio.structure.io.cif.CifStructureConverter; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; import org.junit.Test; @@ -360,7 +358,7 @@ public void testStructWithBranchedEntitiesRoundTrip() throws IOException { URL url = new URL("https://raw.githubusercontent.com/pdbxmmcifwg/carbohydrate-extension/master/examples/models/1B5F-carb.cif"); InputStream inStream = url.openStream(); - Structure structure = StructureConverter.fromInputStream(inStream); + Structure structure = CifStructureConverter.fromInputStream(inStream); AdapterToStructureData writerToEncoder = new AdapterToStructureData(); new MmtfStructureWriter(structure, writerToEncoder); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java index acf23d4f88..095deecb64 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/mmtf/TestMmtfStructureReader.java @@ -9,7 +9,7 @@ import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.chem.ChemCompGroupFactory; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestCrystalInfo.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestCrystalInfo.java index 775588a2ae..4e48bab634 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestCrystalInfo.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestCrystalInfo.java @@ -22,6 +22,7 @@ import org.biojava.nbio.structure.*; import org.biojava.nbio.structure.align.util.AtomCache; +import org.biojava.nbio.structure.io.StructureFiletype; import org.junit.Test; import java.io.IOException; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestInterfaceClustering.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestInterfaceClustering.java index bb5fe0b74c..d69ce237d3 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestInterfaceClustering.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/xtal/TestInterfaceClustering.java @@ -32,7 +32,7 @@ import org.biojava.nbio.structure.Structure; import org.biojava.nbio.structure.StructureException; -import org.biojava.nbio.structure.StructureFiletype; +import org.biojava.nbio.structure.io.StructureFiletype; import org.biojava.nbio.structure.StructureIO; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.asa.GroupAsa; From 9e501a9e3bfee814f00bd5d23746ea2a01debcb5 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Wed, 27 Jan 2021 12:27:26 -0800 Subject: [PATCH 203/769] Further optimization: sort by distance. Achieves ~1/3 of runtime --- .../nbio/structure/asa/AsaCalculator.java | 83 +++++++++++-------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java index 19ece0ab72..59ba0dc138 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java @@ -30,8 +30,7 @@ import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; - - +import java.util.stream.Collectors; /** @@ -86,8 +85,8 @@ public class AsaCalculator { private class AsaCalcWorker implements Runnable { - private int i; - private double[] asas; + private final int i; + private final double[] asas; public AsaCalcWorker(int i, double[] asas) { this.i = i; @@ -100,12 +99,21 @@ public void run() { } } + private static class IndexAndDistance { + private final int index; + private final double dist; + public IndexAndDistance(int index, double dist) { + this.index = index; + this.dist = dist; + } + } + - private Point3d[] atomCoords; - private Atom[] atoms; - private double[] radii; - private double probe; - private int nThreads; + private final Point3d[] atomCoords; + private final Atom[] atoms; + private final double[] radii; + private final double probe; + private final int nThreads; private Point3d[] spherePoints; private double cons; private int[][] neighborIndices; @@ -123,7 +131,6 @@ public void run() { * @param nThreads the number of parallel threads to use for the calculation * @param hetAtoms if true HET residues are considered, if false they aren't, equivalent to * NACCESS' -h option - * @see StructureTools#getAllNonHAtomArray */ public AsaCalculator(Structure structure, double probe, int nSpherePoints, int nThreads, boolean hetAtoms) { this.atoms = StructureTools.getAllNonHAtomArray(structure, hetAtoms); @@ -312,10 +319,8 @@ public double[] calculateAsas() { //12 threads, time: 0.9s -- x11.4 - ExecutorService threadPool = Executors.newFixedThreadPool(nThreads); - for (int i=0;i contactList = calcContacts(); - Map> indices = new HashMap<>(atomCoords.length); + Map> indices = new HashMap<>(atomCoords.length); for (Contact contact : contactList) { // note contacts are stored 1-way only, with j>i int i = contact.getI(); int j = contact.getJ(); - List iIndices; - List jIndices; + List iIndices; + List jIndices; if (!indices.containsKey(i)) { iIndices = new ArrayList<>(initialCapacity); indices.put(i, iIndices); @@ -428,17 +433,21 @@ int[][] findNeighborIndicesSpatialHashing() { double radius = radii[i] + probe + probe; double dist = contact.getDistance(); if (dist < radius + radii[j]) { - iIndices.add(j); - jIndices.add(i); + iIndices.add(new IndexAndDistance(j, dist)); + jIndices.add(new IndexAndDistance(i, dist)); } } // convert map to array for fast access int[][] nbsIndices = new int[atomCoords.length][]; - for (Map.Entry> entry : indices.entrySet()) { - List list = entry.getValue(); + for (Map.Entry> entry : indices.entrySet()) { + List list = entry.getValue(); + // Sorting by closest to farthest away neighbors achieves faster runtimes when checking for occluded sphere sample points in calcSingleAsa. + // This follows the ideas exposed in Eisenhaber et al, J Comp Chemistry 1994 (https://onlinelibrary.wiley.com/doi/epdf/10.1002/jcc.540160303) + list = list.stream().sorted(Comparator.comparingDouble(o -> o.dist)).collect(Collectors.toList()); int[] indicesArray = new int[list.size()]; - for (int i=0;i Date: Wed, 27 Jan 2021 14:51:55 -0800 Subject: [PATCH 204/769] Small optimisation: avoid recalculating radii --- .../nbio/structure/asa/AsaCalculator.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java index 59ba0dc138..9a5f6edd75 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java @@ -491,22 +491,31 @@ private double calcSingleAsa(int i) { int[] numDistsCalced = null; if (logger.isDebugEnabled()) numDistsCalced = new int[n_neighbor]; + // now we precalculate the squared j radii to compare to in inner loop (which does not depend on each sphere point, but only on i, j + double[] sqRadii = new double[n_neighbor]; + for (int nbArrayInd =0; nbArrayInd Date: Wed, 27 Jan 2021 17:11:11 -0800 Subject: [PATCH 205/769] Another optimisation from Eisenhaber 1994 --- .../nbio/structure/asa/AsaCalculator.java | 64 ++++++++++--------- .../nbio/structure/asa/TestAsaCalc.java | 20 +++--- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java index 9a5f6edd75..2deed82865 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java @@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; import javax.vecmath.Point3d; +import javax.vecmath.Vector3d; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -99,9 +100,9 @@ public void run() { } } - private static class IndexAndDistance { - private final int index; - private final double dist; + public static class IndexAndDistance { + public final int index; + public final double dist; public IndexAndDistance(int index, double dist) { this.index = index; this.dist = dist; @@ -116,7 +117,7 @@ public IndexAndDistance(int index, double dist) { private final int nThreads; private Point3d[] spherePoints; private double cons; - private int[][] neighborIndices; + private IndexAndDistance[][] neighborIndices; private boolean useSpatialHashingForNeighbors; @@ -369,17 +370,17 @@ private Point3d[] generateSpherePoints(int nSpherePoints) { * Returns the 2-dimensional array with neighbor indices for every atom. * @return 2-dimensional array of size: n_atoms x n_neighbors_per_atom */ - int[][] findNeighborIndices() { + IndexAndDistance[][] findNeighborIndices() { // looking at a typical protein case, number of neighbours are from ~10 to ~50, with an average of ~30 int initialCapacity = 60; - int[][] nbsIndices = new int[atomCoords.length][]; + IndexAndDistance[][] nbsIndices = new IndexAndDistance[atomCoords.length][]; for (int k=0; k thisNbIndices = new ArrayList<>(initialCapacity); + List thisNbIndices = new ArrayList<>(initialCapacity); for (int i = 0; i < atomCoords.length; i++) { if (i == k) continue; @@ -387,12 +388,11 @@ int[][] findNeighborIndices() { double dist = atomCoords[i].distance(atomCoords[k]); if (dist < radius + radii[i]) { - thisNbIndices.add(i); + thisNbIndices.add(new IndexAndDistance(i, dist)); } } - int[] indicesArray = new int[thisNbIndices.size()]; - for (int i=0;i> entry : indices.entrySet()) { List list = entry.getValue(); // Sorting by closest to farthest away neighbors achieves faster runtimes when checking for occluded sphere sample points in calcSingleAsa. // This follows the ideas exposed in Eisenhaber et al, J Comp Chemistry 1994 (https://onlinelibrary.wiley.com/doi/epdf/10.1002/jcc.540160303) list = list.stream().sorted(Comparator.comparingDouble(o -> o.dist)).collect(Collectors.toList()); - int[] indicesArray = new int[list.size()]; - for (int i=0; i sqRadii[nbArrayInd]) { is_accessible = false; break; } @@ -527,11 +529,11 @@ private double calcSingleAsa(int i) { if (numDistsCalced!=null) { int sum = 0; - for (int j = 0; j < n_neighbor; j++) sum += numDistsCalced[j]; + for (int nbArrayInd = 0; nbArrayInd < n_neighbor; nbArrayInd++) sum += numDistsCalced[nbArrayInd]; logger.debug("Number of sample points distances calculated for neighbors of i={} : average {}, all {}", i, (double) sum / (double) n_neighbor, numDistsCalced); } - return cons*n_accessible_point*radius*radius; + return cons*n_accessible_point*radius_i*radius_i; } /** diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java index 79598bd410..941d85c06d 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java @@ -98,19 +98,19 @@ public void testNeighborIndicesFinding() throws StructureException, IOException AsaCalculator.DEFAULT_PROBE_SIZE, 1000, 1, false); - int[][] allNbsSh = asaCalc.findNeighborIndicesSpatialHashing(); + AsaCalculator.IndexAndDistance[][] allNbsSh = asaCalc.findNeighborIndicesSpatialHashing(); - int[][] allNbs = asaCalc.findNeighborIndices(); + AsaCalculator.IndexAndDistance[][] allNbs = asaCalc.findNeighborIndices(); for (int indexToTest =0; indexToTest < asaCalc.getAtomCoords().length; indexToTest++) { //int indexToTest = 198; - int[] nbsSh = allNbsSh[indexToTest]; - int[] nbs = allNbs[indexToTest]; + AsaCalculator.IndexAndDistance[] nbsSh = allNbsSh[indexToTest]; + AsaCalculator.IndexAndDistance[] nbs = allNbs[indexToTest]; List listOfMatchingIndices = new ArrayList<>(); for (int i = 0; i < nbsSh.length; i++) { for (int j = 0; j < nbs.length; j++) { - if (nbs[j] == nbsSh[i]) { + if (nbs[j].index == nbsSh[i].index) { listOfMatchingIndices.add(j); break; } @@ -201,21 +201,21 @@ public void testNoNeighborsIssue() { AsaCalculator.DEFAULT_PROBE_SIZE, 1000, 1); - int[][] allNbsSh = asaCalc.findNeighborIndicesSpatialHashing(); + AsaCalculator.IndexAndDistance[][] allNbsSh = asaCalc.findNeighborIndicesSpatialHashing(); - int[][] allNbs = asaCalc.findNeighborIndices(); + AsaCalculator.IndexAndDistance[][] allNbs = asaCalc.findNeighborIndices(); assertEquals(3, allNbs.length); assertEquals(3, allNbsSh.length); for (int indexToTest =0; indexToTest < asaCalc.getAtomCoords().length; indexToTest++) { - int[] nbsSh = allNbsSh[indexToTest]; - int[] nbs = allNbs[indexToTest]; + AsaCalculator.IndexAndDistance[] nbsSh = allNbsSh[indexToTest]; + AsaCalculator.IndexAndDistance[] nbs = allNbs[indexToTest]; List listOfMatchingIndices = new ArrayList<>(); for (int i = 0; i < nbsSh.length; i++) { for (int j = 0; j < nbs.length; j++) { - if (nbs[j] == nbsSh[i]) { + if (nbs[j].index == nbsSh[i].index) { listOfMatchingIndices.add(j); break; } From f3e7e00977bcfe21c2b831411f17f402e5f556a8 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Wed, 27 Jan 2021 22:30:06 -0800 Subject: [PATCH 206/769] Some reorg and docs --- .../nbio/structure/asa/AsaCalculator.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java index 2deed82865..6693490029 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java @@ -31,7 +31,6 @@ import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.stream.Collectors; /** @@ -42,6 +41,9 @@ * (now source is available at https://github.com/boscoh/asa). * Thanks to Bosco K. Ho for a great piece of code and for his fantastic blog. *

      + * A few optimizations come from Eisenhaber et al, J Comp Chemistry 1994 + * (https://onlinelibrary.wiley.com/doi/epdf/10.1002/jcc.540160303) + *

      * See * Shrake, A., and J. A. Rupley. "Environment and Exposure to Solvent of Protein Atoms. * Lysozyme and Insulin." JMB (1973) 79:351-371. @@ -49,7 +51,6 @@ * Static Accessibility" JMB (1971) 55:379-400 * * @author Jose Duarte - * */ public class AsaCalculator { @@ -251,7 +252,7 @@ public GroupAsa[] getGroupAsas() { } } - return asas.values().toArray(new GroupAsa[asas.size()]); + return asas.values().toArray(new GroupAsa[0]); } /** @@ -442,11 +443,7 @@ IndexAndDistance[][] findNeighborIndicesSpatialHashing() { IndexAndDistance[][] nbsIndices = new IndexAndDistance[atomCoords.length][]; for (Map.Entry> entry : indices.entrySet()) { List list = entry.getValue(); - // Sorting by closest to farthest away neighbors achieves faster runtimes when checking for occluded sphere sample points in calcSingleAsa. - // This follows the ideas exposed in Eisenhaber et al, J Comp Chemistry 1994 (https://onlinelibrary.wiley.com/doi/epdf/10.1002/jcc.540160303) - list = list.stream().sorted(Comparator.comparingDouble(o -> o.dist)).collect(Collectors.toList()); IndexAndDistance[] indexAndDistances = list.toArray(new IndexAndDistance[0]); - nbsIndices[entry.getKey()] = indexAndDistances; } @@ -483,6 +480,11 @@ private double calcSingleAsa(int i) { int n_neighbor = neighborIndices[i].length; IndexAndDistance[] neighbor_indices = neighborIndices[i]; + // Sorting by closest to farthest away neighbors achieves faster runtimes when checking for occluded + // sphere sample points below. This follows the ideas exposed in + // Eisenhaber et al, J Comp Chemistry 1994 (https://onlinelibrary.wiley.com/doi/epdf/10.1002/jcc.540160303) + Arrays.sort(neighbor_indices, Comparator.comparingDouble(o -> o.dist)); + double radius_i = probe + radii[i]; int n_accessible_point = 0; @@ -508,11 +510,13 @@ private double calcSingleAsa(int i) { boolean is_accessible = true; // note that the neighbors are sorted by distance, achieving optimal performance in this inner loop - // See Eisenhaber et al, J Comp Chemistry 1994 (https://onlinelibrary.wiley.com/doi/epdf/10.1002/jcc.540160303) + // See Eisenhaber et al, J Comp Chemistry 1994 for (int nbArrayInd =0; nbArrayInd Date: Wed, 27 Jan 2021 22:47:26 -0800 Subject: [PATCH 207/769] A scaling test (ignored) --- .../nbio/structure/asa/AsaCalculator.java | 35 ------------------- .../nbio/structure/asa/TestAsaCalc.java | 30 +++++++++++++++- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java index 6693490029..ad6b464805 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java @@ -285,41 +285,6 @@ public double[] calculateAsas() { } else { logger.debug("Will use {} threads for ASA calculation", nThreads); - // NOTE the multithreaded calculation does not scale up well in some systems, - // why? I guess some memory/garbage collect problem? I tried increasing Xmx in pc8201 but didn't help - - // Following scaling tests are for 3hbx, calculating ASA of full asym unit (6 chains): - - // SCALING test done in merlinl01 (12 cores, Xeon X5670 @ 2.93GHz, 24GB RAM) - //1 threads, time: 8.8s -- x1.0 - //2 threads, time: 4.4s -- x2.0 - //3 threads, time: 2.9s -- x3.0 - //4 threads, time: 2.2s -- x3.9 - //5 threads, time: 1.8s -- x4.9 - //6 threads, time: 1.6s -- x5.5 - //7 threads, time: 1.4s -- x6.5 - //8 threads, time: 1.3s -- x6.9 - - // SCALING test done in pc8201 (4 cores, Core2 Quad Q9550 @ 2.83GHz, 8GB RAM) - //1 threads, time: 17.2s -- x1.0 - //2 threads, time: 9.7s -- x1.8 - //3 threads, time: 7.7s -- x2.2 - //4 threads, time: 7.9s -- x2.2 - - // SCALING test done in eppic01 (16 cores, Xeon E5-2650 0 @ 2.00GHz, 128GB RAM) - //1 threads, time: 10.7s -- x1.0 - //2 threads, time: 5.6s -- x1.9 - //3 threads, time: 3.6s -- x3.0 - //4 threads, time: 2.8s -- x3.9 - //5 threads, time: 2.3s -- x4.8 - //6 threads, time: 1.8s -- x6.0 - //7 threads, time: 1.6s -- x6.8 - //8 threads, time: 1.3s -- x8.0 - //9 threads, time: 1.3s -- x8.5 - //10 threads, time: 1.1s -- x10.0 - //11 threads, time: 1.0s -- x10.9 - //12 threads, time: 0.9s -- x11.4 - ExecutorService threadPool = Executors.newFixedThreadPool(nThreads); diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java index 941d85c06d..7add4cf1e7 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/asa/TestAsaCalc.java @@ -32,6 +32,7 @@ import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import static org.junit.Assert.*; +import org.junit.Ignore; import org.junit.Test; import java.io.IOException; @@ -57,7 +58,6 @@ public void testAsa3PIU() throws StructureException, IOException { Structure structure = StructureIO.getStructure("3PIU"); - AsaCalculator asaCalc = new AsaCalculator(structure, AsaCalculator.DEFAULT_PROBE_SIZE, 1000, 1, false); @@ -86,6 +86,34 @@ public void testAsa3PIU() throws StructureException, IOException { } + @Ignore("This is a performance test to be run manually") + @Test + public void testMultithreadScaling() throws StructureException, IOException { + + // important: without this the tests can fail when running in maven (but not in IDE) + // that's because it depends on the order on how tests were run - JD 2018-03-10 + ChemCompGroupFactory.setChemCompProvider(new DownloadChemCompProvider()); + + Structure structure = StructureIO.getStructure("3hbx"); + int[] numThreads = {1, 2, 3, 4}; + long timeSingleThread = 0; + for (int numThread : numThreads) { + AsaCalculator asaCalc = new AsaCalculator(structure, + AsaCalculator.DEFAULT_PROBE_SIZE, + 100, numThread, false); + + long start = System.currentTimeMillis(); + asaCalc.calculateAsas(); + long end = System.currentTimeMillis(); + long time = end - start; + if (numThread == 1) { + timeSingleThread = time; + } + System.out.printf("%6d threads : %6d ms (x%3.1f)\n", numThread, time, (double)timeSingleThread/time); + } + // nothing to assert + } + @Test public void testNeighborIndicesFinding() throws StructureException, IOException { // important: without this the tests can fail when running in maven (but not in IDE) From 8e9535c070fdafea32609bd9f5065b00b641dd27 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Wed, 27 Jan 2021 22:52:22 -0800 Subject: [PATCH 208/769] Logging --- .../java/org/biojava/nbio/structure/asa/AsaCalculator.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java index ad6b464805..4edb428df0 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java @@ -568,7 +568,7 @@ else if (atomCode.equals("CA") || atomCode.equals("CB") || else if (atomCode.equals("CG")) return TETRAHEDRAL_CARBON_VDW; default: - logger.info("Unexpected carbon atom "+atomCode+" for aminoacid "+aa+", assigning its standard vdw radius"); + logger.info("Unexpected carbon atom {} for aminoacid {}, assigning its standard vdw radius", atomCode, aa); return Element.C.getVDWRadius(); } } @@ -576,8 +576,7 @@ else if (atomCode.equals("CA") || atomCode.equals("CB") || // not any of the expected atoms } else { // non standard aas, (e.g. MSE, LLP) will always have this problem, - logger.info("Unexpected atom "+atomCode+" for aminoacid "+aa+ " ("+amino.getPDBName()+"), assigning its standard vdw radius"); - + logger.debug("Unexpected atom {} for aminoacid {} ({}), assigning its standard vdw radius", atomCode, aa, amino.getPDBName()); return atom.getElement().getVDWRadius(); } From f27295efe12f15a8b7ff196682da9ae7726375ca Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 28 Jan 2021 09:57:29 -0800 Subject: [PATCH 209/769] Visibility --- .../org/biojava/nbio/structure/asa/AsaCalculator.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java index 4edb428df0..387e60ed68 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java @@ -90,7 +90,7 @@ private class AsaCalcWorker implements Runnable { private final int i; private final double[] asas; - public AsaCalcWorker(int i, double[] asas) { + private AsaCalcWorker(int i, double[] asas) { this.i = i; this.asas = asas; } @@ -101,10 +101,10 @@ public void run() { } } - public static class IndexAndDistance { - public final int index; - public final double dist; - public IndexAndDistance(int index, double dist) { + static class IndexAndDistance { + final int index; + final double dist; + IndexAndDistance(int index, double dist) { this.index = index; this.dist = dist; } From 6a447d61226aeb1ab287750f99b5be8dc72ab84a Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 28 Jan 2021 11:52:05 -0800 Subject: [PATCH 210/769] Use Vector3d for points, more docs --- .../nbio/structure/asa/AsaCalculator.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java index 387e60ed68..144bcd1209 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/asa/AsaCalculator.java @@ -116,7 +116,7 @@ static class IndexAndDistance { private final double[] radii; private final double probe; private final int nThreads; - private Point3d[] spherePoints; + private Vector3d[] spherePoints; private double cons; private IndexAndDistance[][] neighborIndices; @@ -314,20 +314,20 @@ void setUseSpatialHashingForNeighbors(boolean useSpatialHashingForNeighbors) { } /** - * Returns list of 3d coordinates of points on a sphere using the + * Returns list of 3d coordinates of points on a unit sphere using the * Golden Section Spiral algorithm. * @param nSpherePoints the number of points to be used in generating the spherical dot-density - * @return + * @return the array of points as Vector3d objects */ - private Point3d[] generateSpherePoints(int nSpherePoints) { - Point3d[] points = new Point3d[nSpherePoints]; + private Vector3d[] generateSpherePoints(int nSpherePoints) { + Vector3d[] points = new Vector3d[nSpherePoints]; double inc = Math.PI * (3.0 - Math.sqrt(5.0)); double offset = 2.0 / nSpherePoints; for (int k=0;k o.dist)); double radius_i = probe + radii[i]; int n_accessible_point = 0; - + // purely for debugging int[] numDistsCalced = null; if (logger.isDebugEnabled()) numDistsCalced = new int[n_neighbor]; @@ -471,7 +473,7 @@ private double calcSingleAsa(int i) { aj_minus_ais[nbArrayInd] = aj_minus_ai; } - for (Point3d point: spherePoints){ + for (Vector3d point: spherePoints){ boolean is_accessible = true; // note that the neighbors are sorted by distance, achieving optimal performance in this inner loop @@ -482,7 +484,7 @@ private double calcSingleAsa(int i) { // see equation 3 in Eisenhaber 1994. This is slightly more efficient than // calculating distances to the actual sphere points on atom_i (which would be obtained with: // Point3d test_point = new Point3d(point.x*radius + atom_i.x,point.y*radius + atom_i.y,point.z*radius + atom_i.z)) - double dotProd = aj_minus_ais[nbArrayInd].dot(new Vector3d(point)); + double dotProd = aj_minus_ais[nbArrayInd].dot(point); if (numDistsCalced!=null) numDistsCalced[nbArrayInd]++; @@ -496,6 +498,7 @@ private double calcSingleAsa(int i) { } } + // purely for debugging if (numDistsCalced!=null) { int sum = 0; for (int numDistCalcedForJ : numDistsCalced) sum += numDistCalcedForJ; From 4f44fce6e278582f612286b23eed866e5bb67ebc Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Mon, 1 Feb 2021 15:33:36 -0800 Subject: [PATCH 211/769] Group.java from upstream --- .../src/main/java/org/biojava/nbio/structure/Group.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java index d1e5f34963..8b7b5cb809 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java @@ -103,12 +103,13 @@ public interface Group extends Serializable { /** * Set the atoms of this group. - * @see {@link Atom} + * @see Atom * @param atoms a list of atoms */ public void setAtoms(List atoms); - /** Remove all atoms from this group. + /** + * Remove all atoms from this group. * */ public void clearAtoms(); @@ -118,13 +119,14 @@ public interface Group extends Serializable { * Beware that some PDB atom names are ambiguous (e.g. CA, which means C-alpha or Calcium), * ambiguities should not occur within the same group though. To solve these ambiguities * one would need to check the atom returned for the required element with {@link Atom#getElement()} + *

      + * Note this method will return only the atom in the default alternative location (be it '.' or a letter). * * @param name a trimmed String representing the atom's PDB name, e.g. "CA" * @return an Atom object or null if no such atom exists within this group */ public Atom getAtom(String name) ; - /** * Get at atom by position. * From 53982b0ba820e020c37596d25d6af27639f4a053 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 2 Feb 2021 09:37:02 -0800 Subject: [PATCH 212/769] update CHANGELOG.md --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22f265c548..2403e0f6ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,16 @@ BioJava 6.0.0 (future release) * Support for automatically fetching dssp files from RCSB (`org.biojava.nbio.structure.secstruc.DSSPParser.fetch()`) * `org.biojava.nbio.structure.PDBStatus`: simplified `Status` enum to 3 states, with OBSOLETE now called REMOVED * `org.biojava.nbio.structure.PDBStatus`: removed `getReplacement` and `getReplaces` +* Removed `org.biojava.nbio.structure.io.mmcif` package +* Removed functionality to write isolated CIF headers from `FileConvert` + +### Breaking API changes +* Extracted `StructureIO.StructureFiletype` enum to `org.biojava.nbio.structure.io.StructureFiletype` (supports `PDB`, `MMTF`, `CIF`, and `BCIF`) +* `org.biojava.nbio.structure.align.util.AtomCache`: removed `setUseMmCif`, `setUseMmtf`, `isUseMmCif`, and `isUseMmtf` - replaced by `setFiletype` and `getFiletype` that controls parsed content via the `StructureFiletype` +* `org.biojava.nbio.structure.io.MMCIFFileReader` is now effectively `org.biojava.nbio.structure.io.CifFileReader` +* Moved `org.biojava.nbio.structure.io.mmcif.model.DatabasePdbrevRecord` to `org.biojava.nbio.structure.DatabasePDBRevRecord.java` +* Moved all chem-comp model classes from `org.biojava.nbio.structure.io.mmcif.chem` to `org.biojava.nbio.structure.chem` +* Moved all chem-comp parsing classes from `org.biojava.nbio.structure.io.mmcif.chem` to `org.biojava.nbio.structure.io.cif` BioJava 5.4.0 ============= From 19766ca1414f3cc701a03e99e918c466a070d516 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 2 Feb 2021 17:29:15 -0800 Subject: [PATCH 213/769] update AtomCacheTest --- .../nbio/structure/align/util/AtomCache.java | 30 +------------------ .../structure/align/util/AtomCacheTest.java | 11 ++++--- 2 files changed, 6 insertions(+), 35 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java index 552f0427ef..d4d1638c12 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/align/util/AtomCache.java @@ -525,8 +525,7 @@ public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatab public Structure getStructureForDomain(ScopDomain domain, ScopDatabase scopDatabase, boolean strictLigandHandling) throws IOException, StructureException { String pdbId = domain.getPdbId(); - // SMB 1/26/21 - forcing loading MMTF here - TODO why doesn't mmCIF/CIF/BCIF parsing work here? - Structure fullStructure = getStructureForPdbIdByMmtf(pdbId); + Structure fullStructure = getStructureForPdbId(pdbId); Structure structure = domain.reduce(fullStructure); // TODO It would be better to move all of this into the reduce method, @@ -802,33 +801,6 @@ public Structure getStructureForPdbId(String pdbId) throws IOException, Structur } } - /** - * SCOP parsing depends on MMTF, this a dedicated method to allow for that. - * @param pdbId what to load - * @return a Structure object - * @throws IOException - * @throws StructureException - */ - private Structure getStructureForPdbIdByMmtf(String pdbId) throws IOException, StructureException { - if (pdbId == null) - return null; - if (pdbId.length() != 4) { - throw new StructureException("Unrecognized PDB ID: " + pdbId); - } - while (checkLoading(pdbId)) { - // waiting for loading to be finished... - - try { - Thread.sleep(100); - } catch (InterruptedException e) { - logger.error(e.getMessage()); - } - } - - logger.debug("loading from mmtf"); - return loadStructureFromMmtfByPdbId(pdbId); - } - /** * Load a {@link Structure} from MMTF either from the local file system. * @param pdbId the input PDB id diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java index 25a711e0b1..ce332f4f70 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/align/util/AtomCacheTest.java @@ -178,13 +178,12 @@ public void testGetStructureForChainlessDomains() throws IOException, StructureE int expectedLengthA = 135; assertEquals(expectedLengthA, a.getAtomGroups().size()); + assertEquals(2, structure.getNonPolyChains().size()); - assertTrue(structure.hasNonPolyChain("G")); - assertTrue(structure.hasNonPolyChain("H")); - - Chain copper = structure.getNonPolyChain("I"); - assertEquals(1,copper.getAtomGroups().size()); - + Chain copperM = structure.getNonPolyChain("M"); + assertEquals(1, copperM.getAtomGroups().size()); + Chain copperN = structure.getNonPolyChain("N"); + assertEquals(1, copperN.getAtomGroups().size()); } @Test From e94f047cad95ccc1bf1acd4f6341f5569cf8a75c Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Wed, 10 Feb 2021 11:04:07 -0800 Subject: [PATCH 214/769] increase QCP precision threshold (try to fix #914) --- .../org/biojava/nbio/structure/geometry/SuperPositionQCP.java | 2 +- .../java/org/biojava/nbio/structure/io/TestHardBioUnits.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/geometry/SuperPositionQCP.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/geometry/SuperPositionQCP.java index a3d5728f19..a45a854bbf 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/geometry/SuperPositionQCP.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/geometry/SuperPositionQCP.java @@ -111,7 +111,7 @@ public final class SuperPositionQCP extends SuperPositionAbstract { private static final Logger logger = LoggerFactory.getLogger(SuperPositionQCP.class); - private double evec_prec = 1E-6; + private double evec_prec = 1E-3; private double eval_prec = 1E-11; private Point3d[] x; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java index b50b4524fc..797307d0c0 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java @@ -107,10 +107,6 @@ public void test4A1I() throws IOException, StructureException { String pdbId = "4A1I"; int biolAssemblyNr = 2; - AtomCache atomCache = new AtomCache(); - // TODO there seem to be numerical instabilities when parsing BCIF - atomCache.setFiletype(StructureFiletype.CIF); - StructureIO.setAtomCache(atomCache); Structure bioAssembly = StructureIO.getBiologicalAssembly(pdbId,biolAssemblyNr); if ( bioAssembly == null){ From 83cf763e0f4b91da5b45fb2deaa8bb63ecbe9857 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Thu, 11 Feb 2021 16:57:33 -0800 Subject: [PATCH 215/769] Revert "increase QCP precision threshold (try to fix #914)" This reverts commit e94f047c --- .../org/biojava/nbio/structure/geometry/SuperPositionQCP.java | 2 +- .../java/org/biojava/nbio/structure/io/TestHardBioUnits.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/geometry/SuperPositionQCP.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/geometry/SuperPositionQCP.java index a45a854bbf..a3d5728f19 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/geometry/SuperPositionQCP.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/geometry/SuperPositionQCP.java @@ -111,7 +111,7 @@ public final class SuperPositionQCP extends SuperPositionAbstract { private static final Logger logger = LoggerFactory.getLogger(SuperPositionQCP.class); - private double evec_prec = 1E-3; + private double evec_prec = 1E-6; private double eval_prec = 1E-11; private Point3d[] x; diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java index 797307d0c0..b50b4524fc 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java @@ -107,6 +107,10 @@ public void test4A1I() throws IOException, StructureException { String pdbId = "4A1I"; int biolAssemblyNr = 2; + AtomCache atomCache = new AtomCache(); + // TODO there seem to be numerical instabilities when parsing BCIF + atomCache.setFiletype(StructureFiletype.CIF); + StructureIO.setAtomCache(atomCache); Structure bioAssembly = StructureIO.getBiologicalAssembly(pdbId,biolAssemblyNr); if ( bioAssembly == null){ From 069126ced7e1a85ea188ada0df77181de4d90c2b Mon Sep 17 00:00:00 2001 From: Michael L Heuer Date: Mon, 22 Feb 2021 09:26:59 -0600 Subject: [PATCH 216/769] Update guava dependency version to 29.0-jre. --- biojava-genome/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index e219872582..c4d667cf50 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -75,7 +75,7 @@ com.google.guava guava compile - 28.1-jre + 29.0-jre junit From 1e59bb59883c3d2afe88671d60f48924fc3ece73 Mon Sep 17 00:00:00 2001 From: Michael L Heuer Date: Mon, 22 Feb 2021 09:27:35 -0600 Subject: [PATCH 217/769] Collect to ArrayList rather than LinkedList. --- .../org/biojava/nbio/genome/io/fastq/AbstractFastqReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/AbstractFastqReader.java b/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/AbstractFastqReader.java index 17ca61205c..b10a005fc7 100755 --- a/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/AbstractFastqReader.java +++ b/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/AbstractFastqReader.java @@ -152,7 +152,7 @@ public final Iterable read(final InputStream inputStream) throws IOExcept private static final class Collect implements StreamListener { /** List of FASTQ formatted sequences. */ - private final List result = Lists.newLinkedList(); + private final List result = Lists.newArrayList(); @Override public void fastq(final Fastq fastq) From 02b0ece17db3dc6ace817c231ea0ae7998cfcc1b Mon Sep 17 00:00:00 2001 From: Michael L Heuer Date: Mon, 22 Feb 2021 09:48:37 -0600 Subject: [PATCH 218/769] Add copy constructor to FastqBuilder. --- .../biojava/nbio/genome/io/fastq/Fastq.java | 15 ++++++++ .../nbio/genome/io/fastq/FastqBuilder.java | 19 ++++++++++ .../genome/io/fastq/FastqBuilderTest.java | 35 +++++++++++++++++++ .../nbio/genome/io/fastq/FastqTest.java | 14 ++++++++ 4 files changed, 83 insertions(+) diff --git a/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/Fastq.java b/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/Fastq.java index 2de9e05713..11e1d959f8 100755 --- a/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/Fastq.java +++ b/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/Fastq.java @@ -145,4 +145,19 @@ public static final FastqBuilder builder() { return new FastqBuilder(); } + + /** + * Create and return a new FastqBuilder configured from the + * specified FASTQ formatted sequence. + * The FastqBuilder will not be null. + * + * @since 6.0.0 + * @param fastq FASTQ formatted sequence, must not be null + * @return a new FastqBuilder configured from the specified FASTQ + * formatted sequence + */ + public static final FastqBuilder builder(final Fastq fastq) + { + return new FastqBuilder(fastq); + } } diff --git a/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/FastqBuilder.java b/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/FastqBuilder.java index 4067e90b9c..8b2ced15f2 100755 --- a/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/FastqBuilder.java +++ b/biojava-genome/src/main/java/org/biojava/nbio/genome/io/fastq/FastqBuilder.java @@ -51,6 +51,25 @@ public FastqBuilder() // empty } + /** + * Create a new FASTQ formatted sequence builder configured + * from the specified FASTQ formatted sequence. + * + * @since 6.0.0 + * @param fastq FASTQ formatted sequence, must not be null + */ + public FastqBuilder(final Fastq fastq) + { + if (fastq == null) + { + throw new IllegalArgumentException("fastq must not be null"); + } + withDescription(fastq.getDescription()); + withSequence(fastq.getSequence()); + withQuality(fastq.getQuality()); + withVariant(fastq.getVariant()); + } + /** * Return the description for this FASTQ formatted sequence builder. diff --git a/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqBuilderTest.java b/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqBuilderTest.java index b013e996d2..8d68673989 100755 --- a/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqBuilderTest.java +++ b/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqBuilderTest.java @@ -36,6 +36,41 @@ public void testConstructor() Assert.assertNotNull(fastqBuilder); } + @Test + public void testConstructorFastq() + { + FastqBuilder fastqBuilder = new FastqBuilder() + .withDescription("description") + .withSequence("sequence") + .withQuality("quality_") + .withVariant(FastqVariant.FASTQ_SOLEXA); + + Fastq fastq = fastqBuilder.build(); + + FastqBuilder fastqBuilder2 = new FastqBuilder(fastq); + Assert.assertNotNull(fastqBuilder2); + + Fastq fastq2 = fastqBuilder2.build(); + Assert.assertEquals("description", fastq2.getDescription()); + Assert.assertEquals("sequence", fastq2.getSequence()); + Assert.assertEquals("quality_", fastq2.getQuality()); + Assert.assertEquals(FastqVariant.FASTQ_SOLEXA, fastq2.getVariant()); + } + + @Test + public void testConstructorNullFastq() + { + try + { + new FastqBuilder(null); + Assert.fail("builder(null) expected IllegalArgumentException"); + } + catch (IllegalArgumentException e) + { + // expected + } + } + @Test public void testBuildDefault() { diff --git a/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqTest.java b/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqTest.java index b6fc3c98b0..564f8eed1c 100755 --- a/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqTest.java +++ b/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqTest.java @@ -111,6 +111,20 @@ public void testBuilder() Assert.assertNotNull(Fastq.builder()); } + @Test + public void testBuilderNullFastq() + { + try + { + Fastq.builder(null); + Assert.fail("builder(null) expected IllegalArgumentException"); + } + catch (IllegalArgumentException e) + { + // expected + } + } + @Test public void testEquals() { From 54f4c2b1797d55ff034ac27e897cfc0cb5e55e2f Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Wed, 24 Feb 2021 10:27:35 -0800 Subject: [PATCH 219/769] dedicated test for SuperPositionQCP issues (#914) --- .../geometry/TestSuperPositionQCP.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/geometry/TestSuperPositionQCP.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/geometry/TestSuperPositionQCP.java index 8928c26cbd..f5080786fb 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/geometry/TestSuperPositionQCP.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/geometry/TestSuperPositionQCP.java @@ -20,20 +20,19 @@ */ package org.biojava.nbio.structure.geometry; -import static org.junit.Assert.*; - -import java.util.Random; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.vecmath.AxisAngle4d; import javax.vecmath.Matrix4d; import javax.vecmath.Point3d; import javax.vecmath.Vector3d; +import java.util.Random; -import org.biojava.nbio.structure.geometry.SuperPositionQuat; -import org.biojava.nbio.structure.geometry.SuperPositionQCP; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * Test the Quaternion-Based Characteristic Polynomial {@link SuperPositionQCP} @@ -166,4 +165,23 @@ public void testAlternativeUsageQCP() { } + @Ignore("test for https://github.com/biojava/biojava/issues/914") + @Test + public void shouldHandleTwoFoldSymmetry() { + Matrix4d operator = new Matrix4d(-1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, 1); + + // add some jitter - otherwise rotation matrix will contain NaN + Point3d[] original = new Point3d[] { new Point3d(0, 0, 0), new Point3d(1.001, 0, 0) }; + Point3d[] transformed = new Point3d[] { new Point3d(0, 0, 0), new Point3d(-1, 0, 0) }; + + SuperPosition sqcp = new SuperPositionQCP(false); + + // operator 2 is a 2-fold, trace should be == -1 + Matrix4d m = sqcp.superposeAndTransform(original, transformed); + assertEquals(-1.0, m.m00 + m.m11 + m.m22, 0.001); + assertEquals(0.0, CalcPoint.rmsd(original, transformed), 0.001); + } } From 288b18c88181b422ff9fafbc50ee5748350554f4 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Wed, 24 Feb 2021 10:29:57 -0800 Subject: [PATCH 220/769] switch from QCP to SVD --- .../biojava/nbio/structure/io/TestHardBioUnits.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java index b50b4524fc..41e2394cb5 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/TestHardBioUnits.java @@ -29,7 +29,7 @@ import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.geometry.CalcPoint; import org.biojava.nbio.structure.geometry.SuperPosition; -import org.biojava.nbio.structure.geometry.SuperPositionQCP; +import org.biojava.nbio.structure.geometry.SuperPositionSVD; import org.junit.Test; import static org.junit.Assert.*; @@ -107,10 +107,6 @@ public void test4A1I() throws IOException, StructureException { String pdbId = "4A1I"; int biolAssemblyNr = 2; - AtomCache atomCache = new AtomCache(); - // TODO there seem to be numerical instabilities when parsing BCIF - atomCache.setFiletype(StructureFiletype.CIF); - StructureIO.setAtomCache(atomCache); Structure bioAssembly = StructureIO.getBiologicalAssembly(pdbId,biolAssemblyNr); if ( bioAssembly == null){ @@ -177,16 +173,16 @@ public void test4A1I() throws IOException, StructureException { Point3d[] atomsTransfChainG = Calc.atomsToPoints(StructureTools.getAtomCAArray(transfChainG)); Point3d[] atomsTransfChainB = Calc.atomsToPoints(StructureTools.getAtomCAArray(transfChainB)); - SuperPosition sqcp = new SuperPositionQCP(false); + SuperPosition superPosition = new SuperPositionSVD(false); // operator 1 is the identity, trace should be == 3 - Matrix4d m1 = sqcp.superposeAndTransform(atomsOrigChainG, atomsTransfChainG); + Matrix4d m1 = superPosition.superposeAndTransform(atomsOrigChainG, atomsTransfChainG); assertEquals(3.0, m1.m00 + m1.m11 + m1.m22, 0.00001); assertEquals(0.0, CalcPoint.rmsd(atomsOrigChainG, atomsTransfChainG), 0.00001); // operator 2 is a 2-fold, trace should be == -1 - Matrix4d m2 = sqcp.superposeAndTransform(atomsOrigChainB, atomsTransfChainB); + Matrix4d m2 = superPosition.superposeAndTransform(atomsOrigChainB, atomsTransfChainB); assertEquals(-1.0, m2.m00 + m2.m11 + m2.m22, 0.00001); assertEquals(0.0, CalcPoint.rmsd(atomsOrigChainB, atomsTransfChainB), 0.00001); From 71368bebfc9e3cd9113df9031978d5f7c8e2ebb5 Mon Sep 17 00:00:00 2001 From: Michael L Heuer Date: Fri, 26 Feb 2021 11:33:21 -0600 Subject: [PATCH 221/769] Address review comments. --- .../nbio/genome/io/fastq/FastqBuilderTest.java | 18 ++++++++---------- .../nbio/genome/io/fastq/FastqTest.java | 16 +++++++--------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqBuilderTest.java b/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqBuilderTest.java index 8d68673989..5803068276 100755 --- a/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqBuilderTest.java +++ b/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqBuilderTest.java @@ -20,10 +20,11 @@ */ package org.biojava.nbio.genome.io.fastq; - import org.junit.Assert; import org.junit.Test; +import org.junit.function.ThrowingRunnable; + /** * Unit test for FastqBuilder. */ @@ -60,15 +61,12 @@ public void testConstructorFastq() @Test public void testConstructorNullFastq() { - try - { - new FastqBuilder(null); - Assert.fail("builder(null) expected IllegalArgumentException"); - } - catch (IllegalArgumentException e) - { - // expected - } + Assert.assertThrows(IllegalArgumentException.class, new ThrowingRunnable() { + @Override + public void run() { + new FastqBuilder(null); + } + }); } @Test diff --git a/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqTest.java b/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqTest.java index 564f8eed1c..62d7ee9368 100755 --- a/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqTest.java +++ b/biojava-genome/src/test/java/org/biojava/nbio/genome/io/fastq/FastqTest.java @@ -23,6 +23,7 @@ import org.junit.Assert; import org.junit.Test; +import org.junit.function.ThrowingRunnable; /** * Unit test for Fastq. @@ -114,15 +115,12 @@ public void testBuilder() @Test public void testBuilderNullFastq() { - try - { - Fastq.builder(null); - Assert.fail("builder(null) expected IllegalArgumentException"); - } - catch (IllegalArgumentException e) - { - // expected - } + Assert.assertThrows(IllegalArgumentException.class, new ThrowingRunnable() { + @Override + public void run() { + Fastq.builder(null); + } + }); } @Test From 1f80b1976518a108e143db9e34104abe8aa68098 Mon Sep 17 00:00:00 2001 From: Michael L Heuer Date: Fri, 26 Feb 2021 16:25:38 -0600 Subject: [PATCH 222/769] Update junit dependency version to 4.13.2, log4j to 2.14.0. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 66521c8b2f..368b6ab568 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ 512M 1.0.9 1.7.30 - 2.13.3 + 2.14.0 ciftools-java-jdk8 2.0.2 @@ -480,7 +480,7 @@ junit junit - 4.13.1 + 4.13.2 test From 20c72bfe109719a03f2dde3c497be3ec687aadd2 Mon Sep 17 00:00:00 2001 From: Michael L Heuer Date: Fri, 26 Feb 2021 17:03:13 -0600 Subject: [PATCH 223/769] Update maven plugin dependency versions. --- pom.xml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index 368b6ab568..afee698d7b 100644 --- a/pom.xml +++ b/pom.xml @@ -170,7 +170,7 @@ maven-compiler-plugin - 3.8.0 + 3.8.1 ${jdk.version} ${jdk.version} @@ -178,23 +178,23 @@ maven-dependency-plugin - 3.1.1 + 3.1.2 maven-jar-plugin - 3.1.2 + 3.2.0 maven-scm-plugin - 1.10.0 + 1.11.2 maven-source-plugin - 3.0.1 + 3.2.1 maven-failsafe-plugin - 3.0.0-M3 + 3.0.0-M5 net.sf @@ -209,7 +209,7 @@ org.apache.maven.plugins maven-release-plugin - 2.5.3 + 3.0.0-M1 true clean install @@ -227,7 +227,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.1.0 + 3.2.0 -Xdoclint:none @@ -245,11 +245,11 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.0 + 3.2.4 maven-assembly-plugin - 3.1.0 + 3.3.0 src/main/assembly/assembly.xml @@ -283,18 +283,18 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.0.0 + 3.1.1 org.apache.maven.plugins maven-resources-plugin - 3.1.0 + 3.2.0 maven-enforcer-plugin - 3.0.0-M2 + 3.0.0-M3 enforce-java @@ -319,12 +319,12 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M3 + 3.0.0-M5 org.apache.maven.plugins maven-site-plugin - 3.7.1 + 3.9.1 @@ -343,7 +343,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.7 + 1.6.8 true ossrh From e40d0efdd0d1337741264d3e6389605bf822f440 Mon Sep 17 00:00:00 2001 From: Spencer Bliven Date: Mon, 1 Mar 2021 17:35:50 +0100 Subject: [PATCH 224/769] Fix #917: Symmetry doesn't display with non-US locales - Always use the US locale when printing jmol scripts - Update Jmol to 14.31.10 while we're at it. --- biojava-structure-gui/pom.xml | 2 +- .../symmetry/jmolScript/JmolSymmetryScriptGenerator.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index a57bf73cdb..154f7c229d 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -42,7 +42,7 @@ net.sourceforge.jmol jmol - 14.29.17 + 14.31.10 diff --git a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/symmetry/jmolScript/JmolSymmetryScriptGenerator.java b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/symmetry/jmolScript/JmolSymmetryScriptGenerator.java index dd2401b2c8..8d3e89b4bf 100644 --- a/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/symmetry/jmolScript/JmolSymmetryScriptGenerator.java +++ b/biojava-structure-gui/src/main/java/org/biojava/nbio/structure/symmetry/jmolScript/JmolSymmetryScriptGenerator.java @@ -29,6 +29,7 @@ import javax.vecmath.Tuple3d; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; @@ -226,11 +227,11 @@ protected static String getJmolPoint(Tuple3d point) { } protected static String f1Dot2(float number) { - return String.format("%1.2f", number); + return String.format(Locale.US, "%1.2f", number); } protected static String fDot2(double number) { - return String.format("%.2f", number); + return String.format(Locale.US, "%.2f", number); } /** From 802abb832c3295ff32b589f5190956dfb57515b6 Mon Sep 17 00:00:00 2001 From: Spencer Bliven Date: Mon, 1 Mar 2021 17:38:24 +0100 Subject: [PATCH 225/769] Test that Jmol polygons scripts generate correctly. This runs QuatSymmetryDetector. It would be better to mock the results, but this is nontrivial with the current implementation. --- .../TestJmolSymmetryScriptGenerator.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 biojava-structure-gui/src/test/java/org/biojava/nbio/structure/symmetry/TestJmolSymmetryScriptGenerator.java diff --git a/biojava-structure-gui/src/test/java/org/biojava/nbio/structure/symmetry/TestJmolSymmetryScriptGenerator.java b/biojava-structure-gui/src/test/java/org/biojava/nbio/structure/symmetry/TestJmolSymmetryScriptGenerator.java new file mode 100644 index 0000000000..164319e977 --- /dev/null +++ b/biojava-structure-gui/src/test/java/org/biojava/nbio/structure/symmetry/TestJmolSymmetryScriptGenerator.java @@ -0,0 +1,67 @@ +/* + * BioJava development code + * + * This code may be freely distributed and modified under the + * terms of the GNU Lesser General Public Licence. This should + * be distributed with the code. If you do not have a copy, + * see: + * + * http://www.gnu.org/copyleft/lesser.html + * + * Copyright for this code is held jointly by the individual + * authors. These should be listed in @author doc comments. + * + * For more information on the BioJava project and its aims, + * or to join the biojava-l mailing list, visit the home page + * at: + * + * http://www.biojava.org/ + * + */ +package org.biojava.nbio.structure.symmetry; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; + +import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureException; +import org.biojava.nbio.structure.StructureIO; +import org.biojava.nbio.structure.cluster.SubunitCluster; +import org.biojava.nbio.structure.cluster.SubunitClustererParameters; +import org.biojava.nbio.structure.symmetry.axis.RotationAxisAligner; +import org.biojava.nbio.structure.symmetry.core.QuatSymmetryDetector; +import org.biojava.nbio.structure.symmetry.core.QuatSymmetryParameters; +import org.biojava.nbio.structure.symmetry.core.QuatSymmetryResults; +import org.biojava.nbio.structure.symmetry.core.RotationGroup; +import org.biojava.nbio.structure.symmetry.core.Stoichiometry; +import org.biojava.nbio.structure.symmetry.core.SymmetryPerceptionMethod; +import org.biojava.nbio.structure.symmetry.jmolScript.JmolSymmetryScriptGeneratorDn; +import org.junit.Before; +import org.junit.Test; + +/** + * + * @author Spencer Bliven + */ +public class TestJmolSymmetryScriptGenerator { + @Before + public void setUp() { + } + + @Test + public void testPolygon() throws IOException, StructureException { + Structure struc = StructureIO.getStructure("4hhb"); + QuatSymmetryParameters sp = new QuatSymmetryParameters(); + SubunitClustererParameters cp = new SubunitClustererParameters(); + + QuatSymmetryResults results = QuatSymmetryDetector.calcGlobalSymmetry(struc, sp, cp); + RotationAxisAligner axis = new RotationAxisAligner(results); + JmolSymmetryScriptGeneratorDn gen = new JmolSymmetryScriptGeneratorDn(axis, "D3"); + + String poly = gen.drawPolyhedron(); + String expected = "draw polyhedronD30 line{30.02,-39.95,0.59}{29.24,-0.53,40.00}{30.02,38.89,0.59}{30.80,-0.53,-38.82}{30.02,-39.95,0.59}{-30.00,-39.95,-0.60}{-30.79,-0.53,38.81}{-30.00,38.89,-0.60}{-29.22,-0.53,-40.01}{-30.00,-39.95,-0.60}width 0.45 color [x42ffd9] off;draw polyhedronD31 line{29.24,-0.53,40.00}{-30.79,-0.53,38.81}width 0.45 color [x42ffd9] off;draw polyhedronD32 line{30.02,38.89,0.59}{-30.00,38.89,-0.60}width 0.45 color [x42ffd9] off;draw polyhedronD33 line{30.80,-0.53,-38.82}{-29.22,-0.53,-40.01}width 0.45 color [x42ffd9] off;"; + assertEquals(expected, poly); + } +} \ No newline at end of file From 6a10ba505aadf845d0c7a9eec8fed85f81f783e3 Mon Sep 17 00:00:00 2001 From: Spencer Bliven Date: Mon, 1 Mar 2021 17:39:02 +0100 Subject: [PATCH 226/769] Test that fetching structures by SCOP domain works. --- .../java/org/biojava/nbio/structure/TestAtomCache.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java index bb9ec5ba2a..ab7988ae3f 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestAtomCache.java @@ -221,6 +221,15 @@ public void testFetchObsolete() throws IOException, StructureException { } + @Test + public void testGetScopDomain() throws IOException, StructureException { + String name = "d2gs2a_"; + + Structure s = cache.getStructure(name); + assertNotNull("Failed to fetch structure from SCOP ID", s); + assertEquals("2gs2.A", s.getName()); + } + @Test public void testSettingFileParsingType(){ AtomCache cache = new AtomCache(); From 55b61461d3ddbc449c3ca5ecbbccc9ef97f2c393 Mon Sep 17 00:00:00 2001 From: Spencer Bliven Date: Mon, 1 Mar 2021 17:53:50 +0100 Subject: [PATCH 227/769] Fix compilation issues. These seem to be regularly deleted by IDEs running on different JDKs. If you see a warning, please find the correct syntax to silence it rather than deleting the cast. --- .../biojava/nbio/structure/chem/ZipChemCompProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ZipChemCompProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ZipChemCompProvider.java index 34d7eea4db..5888213c5b 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ZipChemCompProvider.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ZipChemCompProvider.java @@ -206,7 +206,8 @@ private synchronized ChemComp getFromZip(String recordName) { final String filename = "chemcomp/" + recordName + ".cif.gz"; // try with resources block to read from the filesystem. - try (FileSystem fs = FileSystems.newFileSystem(m_zipFile, null)) { + // Don't remove the (ClassLoader) cast! It is required for openjdk 11. + try (FileSystem fs = FileSystems.newFileSystem(m_zipFile, (ClassLoader)null)) { Path cif = fs.getPath(filename); if (Files.exists(cif)) { @@ -255,7 +256,8 @@ private synchronized boolean addToZipFileSystem(Path zipFile, File[] files, Path */ // Copy in each file. - try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, null)) { + // Don't remove the (ClassLoader) cast! It is required for openjdk 11. + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, (ClassLoader)null)) { Files.createDirectories(pathWithinArchive); for (File f : files) { if (!f.isDirectory() && f.exists()) { From b8d7edd62a3b8ed5b366844da66f3f2d5865441b Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Tue, 2 Mar 2021 10:37:09 -0800 Subject: [PATCH 228/769] [maven-release-plugin] prepare release biojava-6.0.0-alpha1 --- biojava-aa-prop/pom.xml | 6 +++--- biojava-alignment/pom.xml | 4 ++-- biojava-core/pom.xml | 2 +- biojava-genome/pom.xml | 6 +++--- biojava-integrationtest/pom.xml | 4 ++-- biojava-modfinder/pom.xml | 4 ++-- biojava-ontology/pom.xml | 2 +- biojava-protein-disorder/pom.xml | 4 ++-- biojava-structure-gui/pom.xml | 6 +++--- biojava-structure/pom.xml | 6 +++--- biojava-survival/pom.xml | 2 +- biojava-ws/pom.xml | 4 ++-- pom.xml | 4 ++-- 13 files changed, 27 insertions(+), 27 deletions(-) diff --git a/biojava-aa-prop/pom.xml b/biojava-aa-prop/pom.xml index 78344622b1..7ad442f3b9 100644 --- a/biojava-aa-prop/pom.xml +++ b/biojava-aa-prop/pom.xml @@ -2,7 +2,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 4.0.0 biojava-aa-prop @@ -70,12 +70,12 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha1 org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha1 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index a22b560d19..5c45f050df 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha1 compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 6cc9c6c9af..ee5b63903a 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index c4d667cf50..84017f41f8 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha1 compile org.biojava biojava-alignment - 6.0.0-SNAPSHOT + 6.0.0-alpha1 compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index 0bd381f989..ad8bccc314 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha1 diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 4df1148dee..130a9a8e8b 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha1 jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 03787e7d7a..92a8733da7 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 9153de3e05..103e19986c 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha1 diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index 154f7c229d..56087dedb3 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha1 compile org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha1 compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index 87b34d4dcb..8e7cfa717a 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 6.0.0-SNAPSHOT + 6.0.0-alpha1 compile org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha1 compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index 8774d85478..f579e85eb5 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 65b13c6730..628f4782e4 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha1 biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha1 compile diff --git a/pom.xml b/pom.xml index afee698d7b..48009bd348 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 6.0.0-SNAPSHOT + 6.0.0-alpha1 biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -51,7 +51,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - HEAD + biojava-6.0.0-alpha1 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index 5c45f050df..a22b560d19 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 6.0.0-alpha1 + 6.0.0-SNAPSHOT compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index ee5b63903a..6cc9c6c9af 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index 84017f41f8..c4d667cf50 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 6.0.0-alpha1 + 6.0.0-SNAPSHOT compile org.biojava biojava-alignment - 6.0.0-alpha1 + 6.0.0-SNAPSHOT compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index ad8bccc314..0bd381f989 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 6.0.0-alpha1 + 6.0.0-SNAPSHOT diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 130a9a8e8b..4df1148dee 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 6.0.0-alpha1 + 6.0.0-SNAPSHOT jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 92a8733da7..03787e7d7a 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 103e19986c..9153de3e05 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 6.0.0-alpha1 + 6.0.0-SNAPSHOT diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index 56087dedb3..154f7c229d 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 6.0.0-alpha1 + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 6.0.0-alpha1 + 6.0.0-SNAPSHOT compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index 8e7cfa717a..87b34d4dcb 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 6.0.0-alpha1 + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 6.0.0-alpha1 + 6.0.0-SNAPSHOT compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index f579e85eb5..8774d85478 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 628f4782e4..65b13c6730 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha1 + 6.0.0-SNAPSHOT biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 6.0.0-alpha1 + 6.0.0-SNAPSHOT compile diff --git a/pom.xml b/pom.xml index 48009bd348..afee698d7b 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 6.0.0-alpha1 + 6.0.0-SNAPSHOT biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -51,7 +51,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - biojava-6.0.0-alpha1 + HEAD forked-path - - true - -Pgpg-release + + false + @@ -339,35 +339,6 @@ - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.8 - true - - ossrh - https://oss.sonatype.org/ - true - - - - - - - - - - - - - - - - - - - org.apache.maven.plugins @@ -379,7 +350,6 @@ - org.apache.maven.plugins maven-jar-plugin @@ -403,7 +373,6 @@ - org.codehaus.mojo findbugs-maven-plugin @@ -418,49 +387,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -471,8 +397,6 @@ - - @@ -589,12 +513,96 @@ + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + release + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + ossrh + https://oss.sonatype.org/ + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar-no-fork + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + + attach-javadocs + + jar + + + + + + + + + codesigning @@ -636,35 +644,6 @@ - - - - - - - release-sign-artifacts - - - performRelease - true - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - From 71b02ebc68a40c605fdd5b8d15ce1e65cce45e7e Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Wed, 3 Mar 2021 22:14:53 -0800 Subject: [PATCH 231/769] Adding some gpg config that works in other projects --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 039670095e..d1940f9add 100644 --- a/pom.xml +++ b/pom.xml @@ -561,6 +561,13 @@ sign + + + + --pinentry-mode + loopback + + From fce9a51f295673968ae23cd2e9d21eb94f64d706 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Wed, 3 Mar 2021 22:54:30 -0800 Subject: [PATCH 232/769] Can't test relase:perform without pushing --- pom.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pom.xml b/pom.xml index d1940f9add..6d307acc49 100644 --- a/pom.xml +++ b/pom.xml @@ -218,9 +218,6 @@ forked-path - - false - From 58eb57015d303d980d07b4c66a8a79d80aea3b57 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Thu, 4 Mar 2021 17:06:51 -0800 Subject: [PATCH 233/769] ChemComp#monNstdParentCompId now returns null instead of empty String (#921) --- .../src/main/java/org/biojava/nbio/structure/chem/ChemComp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java index 76043374fc..0323e82489 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java @@ -149,7 +149,7 @@ public String getMonNstdParentCompId() { } public void setMonNstdParentCompId(String monNstdParentCompId) { - this.monNstdParentCompId = monNstdParentCompId; + this.monNstdParentCompId = monNstdParentCompId.isEmpty() ? null : monNstdParentCompId; setStandardFlag(); } From 4dcc024c9de0d6c85701186bf8557a47e408735a Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Thu, 4 Mar 2021 17:25:26 -0800 Subject: [PATCH 234/769] null check --- .../src/main/java/org/biojava/nbio/structure/chem/ChemComp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java index 0323e82489..cb33e369b3 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/chem/ChemComp.java @@ -149,7 +149,7 @@ public String getMonNstdParentCompId() { } public void setMonNstdParentCompId(String monNstdParentCompId) { - this.monNstdParentCompId = monNstdParentCompId.isEmpty() ? null : monNstdParentCompId; + this.monNstdParentCompId = (monNstdParentCompId == null || monNstdParentCompId.isEmpty()) ? null : monNstdParentCompId; setStandardFlag(); } From c9f58cec9d661672c10b0c08aa2c618bc90caf44 Mon Sep 17 00:00:00 2001 From: Jose Manuel Duarte Date: Thu, 4 Mar 2021 22:01:44 -0800 Subject: [PATCH 235/769] [maven-release-plugin] prepare release biojava-6.0.0-alpha2 --- biojava-aa-prop/pom.xml | 6 +++--- biojava-alignment/pom.xml | 4 ++-- biojava-core/pom.xml | 2 +- biojava-genome/pom.xml | 6 +++--- biojava-integrationtest/pom.xml | 4 ++-- biojava-modfinder/pom.xml | 4 ++-- biojava-ontology/pom.xml | 2 +- biojava-protein-disorder/pom.xml | 4 ++-- biojava-structure-gui/pom.xml | 6 +++--- biojava-structure/pom.xml | 6 +++--- biojava-survival/pom.xml | 2 +- biojava-ws/pom.xml | 4 ++-- pom.xml | 4 ++-- 13 files changed, 27 insertions(+), 27 deletions(-) diff --git a/biojava-aa-prop/pom.xml b/biojava-aa-prop/pom.xml index 78344622b1..698b5ad850 100644 --- a/biojava-aa-prop/pom.xml +++ b/biojava-aa-prop/pom.xml @@ -2,7 +2,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 4.0.0 biojava-aa-prop @@ -70,12 +70,12 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha2 org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha2 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index a22b560d19..f6e899ebd5 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha2 compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 6cc9c6c9af..f0c4a02483 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index c4d667cf50..fbf64183da 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha2 compile org.biojava biojava-alignment - 6.0.0-SNAPSHOT + 6.0.0-alpha2 compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index 0bd381f989..9630da7a40 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha2 diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 4df1148dee..a80d79fa8c 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha2 jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 03787e7d7a..ff59bfea06 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 9153de3e05..ac7c1cb0a4 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha2 diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index 154f7c229d..5f78ed2113 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha2 compile org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha2 compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index 87b34d4dcb..1642df61e4 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 6.0.0-SNAPSHOT + 6.0.0-alpha2 compile org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha2 compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index 8774d85478..082f35dc01 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 65b13c6730..05ea584fc4 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha2 biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha2 compile diff --git a/pom.xml b/pom.xml index 6d307acc49..c8c3d67ebe 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 6.0.0-SNAPSHOT + 6.0.0-alpha2 biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -51,7 +51,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - HEAD + biojava-6.0.0-alpha2 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index f6e899ebd5..a22b560d19 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 6.0.0-alpha2 + 6.0.0-SNAPSHOT compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index f0c4a02483..6cc9c6c9af 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index fbf64183da..c4d667cf50 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 6.0.0-alpha2 + 6.0.0-SNAPSHOT compile org.biojava biojava-alignment - 6.0.0-alpha2 + 6.0.0-SNAPSHOT compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index 9630da7a40..0bd381f989 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 6.0.0-alpha2 + 6.0.0-SNAPSHOT diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index a80d79fa8c..4df1148dee 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 6.0.0-alpha2 + 6.0.0-SNAPSHOT jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index ff59bfea06..03787e7d7a 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index ac7c1cb0a4..9153de3e05 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 6.0.0-alpha2 + 6.0.0-SNAPSHOT diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index 5f78ed2113..154f7c229d 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 6.0.0-alpha2 + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 6.0.0-alpha2 + 6.0.0-SNAPSHOT compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index 1642df61e4..87b34d4dcb 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 6.0.0-alpha2 + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 6.0.0-alpha2 + 6.0.0-SNAPSHOT compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index 082f35dc01..8774d85478 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 05ea584fc4..65b13c6730 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha2 + 6.0.0-SNAPSHOT biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 6.0.0-alpha2 + 6.0.0-SNAPSHOT compile diff --git a/pom.xml b/pom.xml index c8c3d67ebe..6d307acc49 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 6.0.0-alpha2 + 6.0.0-SNAPSHOT biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -51,7 +51,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - biojava-6.0.0-alpha2 + HEAD diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index a22b560d19..108cdee778 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha3 compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 6cc9c6c9af..7b38b5bddd 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index c4d667cf50..f23c858b42 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha3 compile org.biojava biojava-alignment - 6.0.0-SNAPSHOT + 6.0.0-alpha3 compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index 0bd381f989..404c462ad6 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha3 diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 4df1148dee..67f3440a0a 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha3 jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 03787e7d7a..414e38f0b0 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 9153de3e05..06d6ff0013 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha3 diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index 154f7c229d..f09fb9ae90 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha3 compile org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha3 compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index 87b34d4dcb..2307cd5f17 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 6.0.0-SNAPSHOT + 6.0.0-alpha3 compile org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha3 compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index 8774d85478..d13042e8dc 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 65b13c6730..e848c5e84f 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha3 biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha3 compile diff --git a/pom.xml b/pom.xml index 6d307acc49..c6b236e951 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 6.0.0-SNAPSHOT + 6.0.0-alpha3 biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -51,7 +51,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - HEAD + biojava-6.0.0-alpha3 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index 108cdee778..a22b560d19 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 6.0.0-alpha3 + 6.0.0-SNAPSHOT compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 7b38b5bddd..6cc9c6c9af 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index f23c858b42..c4d667cf50 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 6.0.0-alpha3 + 6.0.0-SNAPSHOT compile org.biojava biojava-alignment - 6.0.0-alpha3 + 6.0.0-SNAPSHOT compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index 404c462ad6..0bd381f989 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 6.0.0-alpha3 + 6.0.0-SNAPSHOT diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 67f3440a0a..4df1148dee 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 6.0.0-alpha3 + 6.0.0-SNAPSHOT jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 414e38f0b0..03787e7d7a 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 06d6ff0013..9153de3e05 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 6.0.0-alpha3 + 6.0.0-SNAPSHOT diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index f09fb9ae90..154f7c229d 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 6.0.0-alpha3 + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 6.0.0-alpha3 + 6.0.0-SNAPSHOT compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index 2307cd5f17..87b34d4dcb 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 6.0.0-alpha3 + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 6.0.0-alpha3 + 6.0.0-SNAPSHOT compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index d13042e8dc..8774d85478 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index e848c5e84f..65b13c6730 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha3 + 6.0.0-SNAPSHOT biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 6.0.0-alpha3 + 6.0.0-SNAPSHOT compile diff --git a/pom.xml b/pom.xml index c6b236e951..6d307acc49 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 6.0.0-alpha3 + 6.0.0-SNAPSHOT biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -51,7 +51,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - biojava-6.0.0-alpha3 + HEAD diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index a22b560d19..e23155c7ba 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha4 compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 6cc9c6c9af..0413c71f63 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index 2fb8e78426..311bb549c7 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha4 compile org.biojava biojava-alignment - 6.0.0-SNAPSHOT + 6.0.0-alpha4 compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index 0bd381f989..0070072c52 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha4 diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 4df1148dee..11d57a9fce 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha4 jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 03787e7d7a..4542ede6e2 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index 9153de3e05..dfe2fbd64e 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha4 diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index 154f7c229d..51efcc3262 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 6.0.0-SNAPSHOT + 6.0.0-alpha4 compile org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha4 compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index 87b34d4dcb..fa75d6e5fa 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 6.0.0-SNAPSHOT + 6.0.0-alpha4 compile org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha4 compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index 8774d85478..6f1e37a73e 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 65b13c6730..1b3941438f 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-SNAPSHOT + 6.0.0-alpha4 biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 6.0.0-SNAPSHOT + 6.0.0-alpha4 compile diff --git a/pom.xml b/pom.xml index 6d307acc49..90a22f63b7 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 6.0.0-SNAPSHOT + 6.0.0-alpha4 biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -51,7 +51,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - HEAD + biojava-6.0.0-alpha4 diff --git a/biojava-alignment/pom.xml b/biojava-alignment/pom.xml index e23155c7ba..a22b560d19 100644 --- a/biojava-alignment/pom.xml +++ b/biojava-alignment/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT biojava-alignment biojava-alignment @@ -47,7 +47,7 @@ org.biojava biojava-core - 6.0.0-alpha4 + 6.0.0-SNAPSHOT compile diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 0413c71f63..6cc9c6c9af 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT 4.0.0 biojava-core diff --git a/biojava-genome/pom.xml b/biojava-genome/pom.xml index 311bb549c7..2fb8e78426 100644 --- a/biojava-genome/pom.xml +++ b/biojava-genome/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT 4.0.0 biojava-genome @@ -85,13 +85,13 @@ org.biojava biojava-core - 6.0.0-alpha4 + 6.0.0-SNAPSHOT compile org.biojava biojava-alignment - 6.0.0-alpha4 + 6.0.0-SNAPSHOT compile diff --git a/biojava-integrationtest/pom.xml b/biojava-integrationtest/pom.xml index 0070072c52..0bd381f989 100644 --- a/biojava-integrationtest/pom.xml +++ b/biojava-integrationtest/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT biojava-integrationtest jar @@ -28,7 +28,7 @@ org.biojava biojava-structure - 6.0.0-alpha4 + 6.0.0-SNAPSHOT diff --git a/biojava-modfinder/pom.xml b/biojava-modfinder/pom.xml index 11d57a9fce..4df1148dee 100644 --- a/biojava-modfinder/pom.xml +++ b/biojava-modfinder/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT biojava-modfinder biojava-modfinder @@ -31,7 +31,7 @@ org.biojava biojava-structure - 6.0.0-alpha4 + 6.0.0-SNAPSHOT jar compile diff --git a/biojava-ontology/pom.xml b/biojava-ontology/pom.xml index 4542ede6e2..03787e7d7a 100644 --- a/biojava-ontology/pom.xml +++ b/biojava-ontology/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT biojava-ontology diff --git a/biojava-protein-disorder/pom.xml b/biojava-protein-disorder/pom.xml index dfe2fbd64e..9153de3e05 100644 --- a/biojava-protein-disorder/pom.xml +++ b/biojava-protein-disorder/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT biojava-protein-disorder jar @@ -63,7 +63,7 @@ org.biojava biojava-core - 6.0.0-alpha4 + 6.0.0-SNAPSHOT diff --git a/biojava-structure-gui/pom.xml b/biojava-structure-gui/pom.xml index 51efcc3262..154f7c229d 100644 --- a/biojava-structure-gui/pom.xml +++ b/biojava-structure-gui/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT 4.0.0 biojava-structure-gui @@ -27,13 +27,13 @@ org.biojava biojava-structure - 6.0.0-alpha4 + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 6.0.0-alpha4 + 6.0.0-SNAPSHOT compile diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index fa75d6e5fa..87b34d4dcb 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -4,7 +4,7 @@ biojava org.biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT biojava-structure biojava-structure @@ -44,13 +44,13 @@ org.biojava biojava-alignment - 6.0.0-alpha4 + 6.0.0-SNAPSHOT compile org.biojava biojava-core - 6.0.0-alpha4 + 6.0.0-SNAPSHOT compile diff --git a/biojava-survival/pom.xml b/biojava-survival/pom.xml index 6f1e37a73e..8774d85478 100644 --- a/biojava-survival/pom.xml +++ b/biojava-survival/pom.xml @@ -4,7 +4,7 @@ org.biojava biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT biojava-survival diff --git a/biojava-ws/pom.xml b/biojava-ws/pom.xml index 1b3941438f..65b13c6730 100644 --- a/biojava-ws/pom.xml +++ b/biojava-ws/pom.xml @@ -3,7 +3,7 @@ biojava org.biojava - 6.0.0-alpha4 + 6.0.0-SNAPSHOT biojava-ws biojava-ws @@ -19,7 +19,7 @@ org.biojava biojava-core - 6.0.0-alpha4 + 6.0.0-SNAPSHOT compile diff --git a/pom.xml b/pom.xml index 90a22f63b7..6d307acc49 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.biojava biojava pom - 6.0.0-alpha4 + 6.0.0-SNAPSHOT biojava BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statistical routines, parsers for common file formats and allows the @@ -51,7 +51,7 @@ scm:git:git@github.com:biojava/biojava.git https://github.com/biojava/biojava - biojava-6.0.0-alpha4 + HEAD UTF-8 512M - 1.0.9 + 1.0.10 1.7.30 2.14.0 ciftools-java-jdk8 From eac22bc94bf684d92363dd0bff5ea705845af733 Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Fri, 2 Jul 2021 17:05:20 +0100 Subject: [PATCH 273/769] test getTrace() to improve test coverage --- .../nbio/core/sequence/io/ABITracerTest.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java index 89aef23cbb..df77b7c00a 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java @@ -21,9 +21,14 @@ package org.biojava.nbio.core.sequence.io; +import static org.junit.Assert.assertEquals; + import java.awt.image.BufferedImage; import java.io.File; import java.net.URL; +import java.util.Arrays; + +import org.biojava.nbio.core.exceptions.CompoundNotFoundException; import org.junit.*; /** @@ -79,7 +84,8 @@ public void testLocal() throws Exception { Assert.assertNotNull(tracer); //Test length of tracer for file 3730.ab1 - Assert.assertEquals(16302, tracer.getTraceLength()); + final int EXPECTED_TRACE_LENGTH = 16302; + Assert.assertEquals(EXPECTED_TRACE_LENGTH, tracer.getTraceLength()); //Test length of sequence for file 3730.ab1 Assert.assertEquals(1165, tracer.getSequenceLength()); @@ -92,5 +98,10 @@ public void testLocal() throws Exception { //Test image of tracer for file 3730.ab1 BufferedImage image = tracer.getImage(100,100); Assert.assertNotNull(image); + + Assert.assertThrows(CompoundNotFoundException.class, ()->tracer.getTrace("D")); + for (String base: Arrays.asList(new String []{"A","T","C","G"})){ + assertEquals(EXPECTED_TRACE_LENGTH, tracer.getTrace(base).length); + } } } From d8d5a7b4519eef2807948733912c08fc159526ad Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Fri, 2 Jul 2021 17:09:26 +0100 Subject: [PATCH 274/769] organise imports --- .../nbio/core/sequence/io/ABITracerTest.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java index df77b7c00a..6d42ba48fc 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java @@ -21,7 +21,10 @@ package org.biojava.nbio.core.sequence.io; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.awt.image.BufferedImage; import java.io.File; @@ -66,9 +69,9 @@ public void tearDown() { @Test public void testURL() throws Exception { URL resource = this.getClass().getResource("/3730.ab1"); - Assert.assertNotNull(resource); + assertNotNull(resource); ABITrace tracer = new ABITrace(resource); - Assert.assertNotNull(tracer); + assertNotNull(tracer); } /** @@ -77,27 +80,27 @@ public void testURL() throws Exception { @Test public void testLocal() throws Exception { URL resource = this.getClass().getResource("/3730.ab1"); - Assert.assertNotNull(resource); + assertNotNull(resource); File file = new File(resource.toURI()); - Assert.assertNotNull(file); + assertNotNull(file); ABITrace tracer = new ABITrace(file); - Assert.assertNotNull(tracer); + assertNotNull(tracer); //Test length of tracer for file 3730.ab1 final int EXPECTED_TRACE_LENGTH = 16302; - Assert.assertEquals(EXPECTED_TRACE_LENGTH, tracer.getTraceLength()); + assertEquals(EXPECTED_TRACE_LENGTH, tracer.getTraceLength()); //Test length of sequence for file 3730.ab1 - Assert.assertEquals(1165, tracer.getSequenceLength()); + assertEquals(1165, tracer.getSequenceLength()); //Test sequence of tracer for file 3730.ab1 - Assert.assertTrue(sequence.equals(tracer.getSequence().getSequenceAsString())); + assertTrue(sequence.equals(tracer.getSequence().getSequenceAsString())); //Test array that represents the quality of tracer for file 3730.ab1 - Assert.assertArrayEquals(qual, tracer.getQcalls()); + assertArrayEquals(qual, tracer.getQcalls()); //Test array that represents the baseline of tracer for file 3730.ab1 - Assert.assertArrayEquals(base, tracer.getBasecalls()); + assertArrayEquals(base, tracer.getBasecalls()); //Test image of tracer for file 3730.ab1 BufferedImage image = tracer.getImage(100,100); - Assert.assertNotNull(image); + assertNotNull(image); Assert.assertThrows(CompoundNotFoundException.class, ()->tracer.getTrace("D")); for (String base: Arrays.asList(new String []{"A","T","C","G"})){ From 281e915d59aa359fdc3cad36d49b2fe094d945b7 Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Sun, 4 Jul 2021 00:19:25 +0100 Subject: [PATCH 275/769] initial addition of junit 5 --- biojava-core/pom.xml | 12 ++++++ .../nbio/core/TestAmbiguityCompoundSet.java | 14 ++++--- pom.xml | 42 ++++++++++++++++--- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 6cc9c6c9af..4637ab6534 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -44,6 +44,18 @@ junit test + + org.junit.jupiter + junit-jupiter-api + + + org.junit.jupiter + junit-jupiter-engine + + + org.junit.vintage + junit-vintage-engine + org.slf4j diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java b/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java index 56abb5d802..6951fbc4d4 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java @@ -30,8 +30,10 @@ import org.biojava.nbio.core.sequence.template.CompoundSet; import org.biojava.nbio.core.sequence.template.Sequence; import org.biojava.nbio.core.sequence.transcription.DNAToRNATranslator; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.DisplayName; + +import static org.junit.jupiter.api.Assertions.assertEquals; /** * A Test case for https://github.com/biojava/biojava/issues/344 @@ -39,9 +41,11 @@ * Created by andreas on 12/4/15. */ + public class TestAmbiguityCompoundSet { @Test + @DisplayName("Convert DNA to RNA") public void testCompountSet() throws Exception { CompoundSet dnaSet = AmbiguityDNACompoundSet.getDNACompoundSet(); @@ -49,13 +53,13 @@ public void testCompountSet() throws Exception { DNASequence dna = new DNASequence("AGTCS", dnaSet); - Assert.assertEquals("AGTCS", dna.toString()); + assertEquals("AGTCS", dna.toString()); RNASequence rna = dna.getRNASequence(); rna = new RNASequence(dna.getSequenceAsString().replaceAll("T", "U"), AmbiguityRNACompoundSet.getRNACompoundSet()); //fails with missing compound S - Assert.assertEquals("AGUCS", rna.toString()); + assertEquals("AGUCS", rna.toString()); /* now, do the translation also using the underlying API (should not be needed for a user) * @@ -65,7 +69,7 @@ public void testCompountSet() throws Exception { Sequence translated = translator.createSequence(dna); - Assert.assertEquals("AGUCS", translated.toString()); + assertEquals("AGUCS", translated.toString()); } diff --git a/pom.xml b/pom.xml index 6e55a71501..d5a7d30e65 100644 --- a/pom.xml +++ b/pom.xml @@ -239,6 +239,24 @@ + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + true + true + true + true + + + true + true + true + + + org.apache.maven.plugins maven-shade-plugin @@ -313,11 +331,7 @@ maven-install-plugin 3.0.0-M1 - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - + org.apache.maven.plugins maven-site-plugin @@ -404,6 +418,24 @@ 4.13.2 test + + org.junit.vintage + junit-vintage-engine + 5.7.2 + test + + + org.junit.jupiter + junit-jupiter-api + 5.7.2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.7.2 + test + org.slf4j slf4j-api From 30cd5ef614166827ce672fcac32a35ecdbc7f4ba Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Sun, 4 Jul 2021 10:29:24 +0100 Subject: [PATCH 276/769] refactor 2 tests to use junit5 features --- biojava-core/pom.xml | 25 ++++---- .../nbio/core/TestAmbiguityCompoundSet.java | 3 +- .../nbio/core/sequence/io/ABITracerTest.java | 60 ++++++++++--------- pom.xml | 52 +++++++--------- 4 files changed, 64 insertions(+), 76 deletions(-) diff --git a/biojava-core/pom.xml b/biojava-core/pom.xml index 4637ab6534..b61e45194a 100644 --- a/biojava-core/pom.xml +++ b/biojava-core/pom.xml @@ -42,20 +42,19 @@ junit junit - test - - org.junit.jupiter - junit-jupiter-api - - - org.junit.jupiter - junit-jupiter-engine - - org.junit.vintage - junit-vintage-engine - + org.junit.jupiter + junit-jupiter-engine + + + org.junit.jupiter + junit-jupiter-params + + + org.junit.vintage + junit-vintage-engine + org.slf4j @@ -76,5 +75,3 @@ - - diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java b/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java index 6951fbc4d4..9fad78d7b0 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java @@ -45,18 +45,17 @@ public class TestAmbiguityCompoundSet { @Test - @DisplayName("Convert DNA to RNA") public void testCompountSet() throws Exception { CompoundSet dnaSet = AmbiguityDNACompoundSet.getDNACompoundSet(); CompoundSet rnaSet = AmbiguityRNACompoundSet.getRNACompoundSet(); + DNASequence dna = new DNASequence("AGTCS", dnaSet); assertEquals("AGTCS", dna.toString()); RNASequence rna = dna.getRNASequence(); - rna = new RNASequence(dna.getSequenceAsString().replaceAll("T", "U"), AmbiguityRNACompoundSet.getRNACompoundSet()); //fails with missing compound S assertEquals("AGUCS", rna.toString()); diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java index 6d42ba48fc..dce9cc7b58 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java @@ -21,10 +21,11 @@ package org.biojava.nbio.core.sequence.io; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.*; +import org.junit.jupiter.params.provider.ValueSource; +import org.junit.jupiter.params.ParameterizedTest; import java.awt.image.BufferedImage; import java.io.File; @@ -32,35 +33,31 @@ import java.util.Arrays; import org.biojava.nbio.core.exceptions.CompoundNotFoundException; -import org.junit.*; /** * Test file 3730.ab1 is from https://github.com/biopython/biopython/blob/master/Tests/Abi/3730.ab1 * The test data for comparing the results from ABITrace.java for file 3730.ab1 is from https://github.com/biopython/biopython/blob/master/Tests/Abi/test_data */ public class ABITracerTest { + private String sequence = "GGGCGAGCKYYAYATTTTGGCAAGAATTGAGCTCTATGGCCACAACCATGGTGAGCAAGGGCGAGGAGGATAACATGGCCATCATCAAGGAGTTCATGCGCTTCAAGGTGCACATGGAGGGCTCCGTGAACGGCCACGAGTTCGAGATCGAGGGCGAGGGCGAGGGCCGCCCCTACGAGGGCACCCAGACCGCCAAGCTGAAGGTGACCAAGGGTGGCCCCCTGCCCTTCGCCTGGGACATCCTGTCCCCTCAGTTCATGTACGGCTCCAAGGCCTACGTGAAGCACCCCGCCGACATCCCCGACTACTTGAAGCTGTCCTTCCCCGAGGGCTTCAAGTGGGAGCGCGTGATGAACTTCGAGGACGGCGGCGTGGTGACCGTGACCCAGGACTCCTCCCTGCAGGACGGCGAGTTCATCTACAAGGTGAAGCTGCGCGGCACCAACTTCCCCTCCGACGGCCCCGTAATGCAGAAGAAGACCATGGGCTGGGAGGCCTCCTCCGAGCGGATGTACCCCGAGGACGGCGCCCTGAAGGGCGAGATCAAGCAGAGGCTGAAGCTGAAGGACGGCGGCCACTACGACGCTGAGGTCAAGACCACCTACAAGGCCAAGAAGCCCGTGCAGCTGCCCGGCGCCTACAACGTCAACATCAAGTTGGACATCACCTCCCACAACGAGGACTACACCATCGTGGAACAGTACGAACGCGCCGAGGGCCGCCACTCCACCGGCGGCATGGACGAGCTGTACAAGGGCGGCAGCGGCATGGTGAGCAAGGGCGAGGAGCTGTTCACCGGGGTGGTGCCCATCCTGGTCGAGCTGGACGGCGACGTAAACGGCCACAAGTTCAGCGTGTCCGGCGAGGGCGAGGGCGATGCCACCTACGGCAAGCTGACCCTGAAGTTCATCTGCACCACCGGCAAGCTGCCCGTGCCCTGGCCCACCCTCGTGACCACCCTGACCTACGGCGTGCAGTGCTTCAGCCGCTACCCCGACCACATGAAGCAGCACGACTTCTTCAAGTCCGCCATGCCCGAAGGCTACGTCCAGGAGCGCACCATCTTCTTCAAGGACGACGGCAACTACAARACCCGCGCCGAGGTGAARTTCGAGGGCGACACCCTGGTGAACCGCATCGAGCTGAAAGGGGCAYCGCACCTTTC"; private int[] qual = {20, 3, 4, 4, 4, 6, 4, 4, 0, 0, 0, 6, 0, 10, 20, 26, 22, 17, 21, 31, 29, 32, 28, 18, 23, 17, 19, 35, 36, 50, 39, 50, 50, 50, 50, 50, 25, 35, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 35, 39, 33, 20, 35, 31, 50, 50, 50, 50, 50, 50, 50, 50, 50, 31, 50, 35, 31, 23, 28, 31, 21, 43, 39, 35, 24, 30, 26, 35, 31, 50, 50, 50, 50, 50, 50, 50, 50, 50, 39, 31, 24, 39, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 31, 31, 43, 43, 50, 50, 50, 50, 50, 31, 31, 31, 31, 50, 50, 50, 50, 50, 50, 50, 50, 31, 31, 35, 50, 50, 50, 50, 31, 36, 55, 55, 55, 55, 36, 55, 55, 55, 55, 55, 36, 55, 55, 55, 55, 55, 36, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 40, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 36, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 40, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 43, 43, 50, 43, 43, 50, 43, 43, 50, 43, 43, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 43, 43, 50, 43, 43, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 28, 28, 35, 28, 28, 35, 28, 28, 35, 28, 28, 35, 28, 28, 35, 28, 21, 28, 35, 28, 28, 35, 35, 35, 35, 35, 37, 38, 21, 28, 35, 28, 28, 35, 35, 35, 35, 35, 35, 35, 36, 36, 21, 39, 35, 35, 35, 39, 35, 37, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 28, 28, 35, 35, 28, 28, 35, 35, 35, 36, 36, 22, 39, 35, 35, 35, 35, 35, 35, 37, 38, 28, 35, 21, 36, 36, 37, 35, 35, 20, 39, 39, 35, 35, 35, 35, 37, 38, 28, 35, 37, 34, 35, 24, 24, 27, 25, 20, 24, 37, 35, 27, 21, 20, 21, 27, 17, 20, 24, 32, 26, 20, 12, 20, 10, 20, 24, 25, 23, 20, 32, 24, 24, 23, 20, 24, 23, 18, 34, 34, 34, 22, 26, 24, 24, 18, 22, 22, 23, 25, 20, 12, 20, 24, 23, 24, 23, 22, 20, 20, 0, 20, 24, 23, 20, 8, 10, 4, 20, 20, 3, 7, 19, 20, 4, 4, 7, 7, 0, 7, 11, 18, 8, 3, 23, 23, 20, 11, 4, 20, 18, 12, 20, 20, 20, 4, 20, 4, 2, 3, 21, 21, 21, 21, 10, 15, 14, 15, 19, 2, 4, 3, 6, 11, 3, 4, 6, 21, 16, 20, 11, 1, 4, 12, 0, 15, 8, 1, 3, 3, 12, 1, 11, 20, 4}; private int[] base = {2, 13, 38, 51, 67, 78, 92, 118, 138, 162, 181, 191, 210, 222, 239, 253, 266, 280, 288, 304, 317, 333, 347, 359, 375, 386, 394, 406, 418, 433, 444, 457, 472, 482, 496, 506, 519, 529, 544, 557, 569, 579, 590, 601, 614, 626, 638, 649, 663, 673, 686, 706, 715, 731, 740, 753, 765, 777, 787, 799, 813, 826, 838, 854, 863, 876, 892, 901, 913, 929, 937, 948, 960, 970, 981, 993, 1004, 1017, 1034, 1045, 1056, 1068, 1080, 1091, 1103, 1115, 1126, 1138, 1148, 1160, 1177, 1187, 1199, 1211, 1222, 1232, 1243, 1254, 1268, 1279, 1294, 1307, 1319, 1330, 1341, 1352, 1362, 1374, 1388, 1398, 1411, 1422, 1433, 1444, 1456, 1466, 1479, 1497, 1506, 1519, 1531, 1543, 1556, 1567, 1578, 1589, 1604, 1614, 1630, 1641, 1651, 1662, 1675, 1688, 1700, 1711, 1721, 1732, 1748, 1758, 1772, 1784, 1795, 1806, 1820, 1830, 1844, 1855, 1866, 1877, 1892, 1902, 1914, 1926, 1939, 1950, 1965, 1974, 1986, 1999, 2011, 2023, 2037, 2047, 2059, 2072, 2084, 2096, 2107, 2120, 2132, 2144, 2156, 2169, 2180, 2191, 2202, 2217, 2227, 2239, 2251, 2264, 2275, 2286, 2297, 2309, 2321, 2332, 2347, 2358, 2369, 2381, 2394, 2406, 2417, 2429, 2439, 2452, 2465, 2476, 2490, 2501, 2512, 2524, 2536, 2546, 2560, 2570, 2581, 2593, 2605, 2616, 2628, 2640, 2653, 2664, 2676, 2688, 2700, 2712, 2723, 2735, 2748, 2759, 2772, 2784, 2795, 2808, 2820, 2831, 2842, 2854, 2866, 2878, 2888, 2901, 2913, 2927, 2936, 2947, 2958, 2970, 2982, 2994, 3005, 3019, 3030, 3041, 3053, 3064, 3077, 3088, 3099, 3110, 3123, 3135, 3146, 3157, 3168, 3179, 3192, 3203, 3214, 3226, 3238, 3251, 3263, 3275, 3286, 3297, 3308, 3320, 3331, 3344, 3356, 3368, 3380, 3391, 3402, 3415, 3426, 3440, 3451, 3462, 3474, 3485, 3496, 3508, 3520, 3532, 3543, 3556, 3569, 3580, 3593, 3604, 3615, 3626, 3638, 3650, 3661, 3673, 3684, 3698, 3709, 3721, 3732, 3744, 3756, 3767, 3779, 3792, 3803, 3814, 3827, 3838, 3850, 3862, 3873, 3885, 3897, 3909, 3920, 3932, 3943, 3955, 3966, 3980, 3990, 4002, 4014, 4026, 4038, 4050, 4061, 4072, 4083, 4095, 4107, 4119, 4131, 4143, 4156, 4167, 4179, 4191, 4203, 4215, 4227, 4238, 4252, 4262, 4274, 4287, 4298, 4310, 4321, 4333, 4345, 4356, 4370, 4381, 4393, 4406, 4417, 4428, 4440, 4453, 4464, 4477, 4489, 4500, 4513, 4524, 4536, 4548, 4560, 4573, 4583, 4595, 4607, 4620, 4631, 4645, 4655, 4667, 4679, 4690, 4702, 4714, 4728, 4739, 4750, 4762, 4774, 4786, 4798, 4810, 4821, 4833, 4845, 4857, 4869, 4880, 4892, 4905, 4916, 4927, 4940, 4952, 4963, 4977, 4988, 5000, 5012, 5023, 5034, 5045, 5057, 5069, 5081, 5093, 5104, 5115, 5127, 5139, 5151, 5163, 5176, 5188, 5199, 5211, 5223, 5235, 5247, 5259, 5272, 5283, 5296, 5308, 5320, 5331, 5343, 5354, 5366, 5378, 5390, 5402, 5414, 5426, 5438, 5450, 5462, 5474, 5486, 5497, 5510, 5521, 5532, 5544, 5557, 5569, 5581, 5592, 5604, 5617, 5629, 5641, 5652, 5663, 5676, 5687, 5699, 5712, 5724, 5735, 5748, 5760, 5771, 5784, 5794, 5806, 5817, 5829, 5841, 5853, 5866, 5879, 5891, 5903, 5916, 5928, 5941, 5952, 5964, 5976, 5988, 6000, 6012, 6024, 6036, 6048, 6060, 6072, 6085, 6096, 6109, 6121, 6133, 6146, 6157, 6168, 6180, 6192, 6203, 6215, 6227, 6239, 6251, 6265, 6276, 6289, 6302, 6313, 6325, 6337, 6349, 6361, 6374, 6386, 6398, 6410, 6422, 6436, 6448, 6459, 6471, 6483, 6495, 6507, 6520, 6532, 6545, 6555, 6567, 6579, 6591, 6603, 6615, 6627, 6640, 6652, 6664, 6676, 6688, 6700, 6713, 6726, 6738, 6749, 6761, 6774, 6786, 6799, 6811, 6823, 6835, 6848, 6859, 6871, 6883, 6895, 6907, 6920, 6933, 6945, 6956, 6968, 6980, 6992, 7005, 7016, 7030, 7042, 7053, 7066, 7079, 7091, 7104, 7115, 7128, 7140, 7152, 7163, 7175, 7187, 7200, 7212, 7224, 7235, 7248, 7260, 7272, 7285, 7297, 7309, 7321, 7333, 7345, 7358, 7370, 7382, 7394, 7406, 7419, 7431, 7443, 7455, 7468, 7480, 7492, 7505, 7517, 7530, 7542, 7554, 7566, 7578, 7591, 7603, 7615, 7628, 7640, 7653, 7666, 7677, 7690, 7702, 7714, 7727, 7738, 7750, 7762, 7775, 7786, 7799, 7812, 7823, 7836, 7848, 7859, 7871, 7884, 7896, 7909, 7921, 7933, 7946, 7958, 7971, 7984, 7996, 8007, 8019, 8032, 8044, 8056, 8069, 8081, 8094, 8107, 8119, 8131, 8143, 8155, 8167, 8179, 8192, 8205, 8218, 8230, 8244, 8255, 8267, 8279, 8291, 8303, 8315, 8328, 8340, 8353, 8366, 8378, 8392, 8404, 8417, 8431, 8443, 8455, 8467, 8479, 8492, 8504, 8516, 8529, 8543, 8555, 8567, 8580, 8593, 8606, 8619, 8632, 8644, 8658, 8670, 8683, 8695, 8708, 8721, 8733, 8746, 8759, 8771, 8783, 8795, 8808, 8821, 8833, 8845, 8858, 8871, 8885, 8898, 8910, 8923, 8936, 8949, 8960, 8973, 8986, 9000, 9012, 9025, 9038, 9051, 9064, 9076, 9089, 9102, 9114, 9126, 9139, 9151, 9164, 9177, 9191, 9204, 9217, 9230, 9243, 9255, 9268, 9281, 9294, 9307, 9320, 9333, 9345, 9358, 9371, 9384, 9398, 9412, 9424, 9437, 9450, 9462, 9475, 9488, 9501, 9514, 9528, 9542, 9554, 9567, 9581, 9593, 9606, 9619, 9632, 9645, 9658, 9671, 9682, 9695, 9708, 9721, 9735, 9749, 9762, 9776, 9789, 9802, 9815, 9828, 9842, 9855, 9867, 9880, 9893, 9906, 9920, 9933, 9947, 9960, 9974, 9987, 10000, 10014, 10027, 10040, 10054, 10067, 10081, 10095, 10107, 10120, 10134, 10148, 10161, 10175, 10188, 10201, 10214, 10228, 10241, 10254, 10267, 10280, 10294, 10309, 10322, 10335, 10348, 10362, 10374, 10387, 10401, 10415, 10428, 10441, 10455, 10469, 10482, 10497, 10510, 10523, 10537, 10551, 10565, 10579, 10593, 10606, 10621, 10634, 10647, 10661, 10675, 10689, 10704, 10719, 10732, 10746, 10760, 10774, 10788, 10802, 10815, 10829, 10843, 10856, 10871, 10884, 10898, 10913, 10927, 10940, 10955, 10970, 10984, 10999, 11013, 11027, 11042, 11056, 11071, 11086, 11100, 11114, 11128, 11142, 11158, 11171, 11186, 11200, 11213, 11228, 11241, 11255, 11270, 11284, 11299, 11314, 11328, 11342, 11356, 11370, 11385, 11399, 11413, 11429, 11445, 11460, 11474, 11489, 11503, 11518, 11533, 11549, 11563, 11577, 11592, 11607, 11621, 11637, 11651, 11665, 11680, 11694, 11708, 11725, 11740, 11754, 11768, 11784, 11798, 11813, 11828, 11843, 11858, 11874, 11888, 11904, 11920, 11933, 11948, 11964, 11979, 11993, 12009, 12024, 12041, 12058, 12071, 12087, 12102, 12117, 12132, 12148, 12165, 12179, 12195, 12210, 12226, 12241, 12256, 12273, 12288, 12304, 12320, 12335, 12350, 12365, 12382, 12398, 12414, 12430, 12446, 12462, 12478, 12495, 12511, 12525, 12541, 12556, 12575, 12591, 12605, 12622, 12638, 12653, 12671, 12686, 12705, 12721, 12739, 12756, 12772, 12788, 12806, 12822, 12839, 12855, 12873, 12890, 12908, 12923, 12941, 12960, 12975, 12992, 13009, 13024, 13040, 13059, 13076, 13092, 13109, 13128, 13145, 13161, 13179, 13194, 13216, 13233, 13249, 13266, 13287, 13303, 13322, 13337, 13357, 13375, 13392, 13410, 13424, 13446, 13465, 13480, 13499, 13517, 13533, 13559, 13575, 13595, 13612, 13632, 13650, 13670, 13687, 13706, 13726, 13744, 13765, 13783, 13803, 13822, 13841, 13860, 13879, 13897, 13917, 13936, 13960, 13979, 13996, 14019, 14040, 14057, 14077, 14102, 14122, 14141, 14163, 14184, 14202, 14225, 14244, 14265, 14287, 14312, 14336, 14356, 14375, 14393, 14420, 14438, 14465, 14483, 14500, 14536, 14555, 14575, 14604, 14619, 14648, 14668, 14691, 14725, 14748, 14770, 14788, 14818, 14840, 14862, 14888, 14921, 14939, 14969, 14996, 15022, 15051, 15075, 15098, 15130, 15149, 15167, 15218, 15237, 15276, 15297, 15333, 15356, 15379, 15418, 15447, 15481, 15508, 15530, 15574, 15599, 15643, 15680, 15697, 15743, 15759, 15775, 15813, 15845, 15877, 15911, 15931, 15968, 16014, 16049, 16077, 16088, 16138, 16149, 16185, 16200, 16241, 16280, 16296}; - public ABITracerTest() { - } + private ABITrace tracer = null; + //Test length of tracer for file 3730.ab1 + static final int EXPECTED_TRACE_LENGTH = 16302; - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { + @BeforeEach + void setUp() throws Exception { + URL resource = this.getClass().getResource("/3730.ab1"); + assertNotNull(resource); + tracer = new ABITrace(resource); } - @After - public void tearDown() { + @AfterEach + void tearDown() { } /** @@ -68,9 +65,6 @@ public void tearDown() { */ @Test public void testURL() throws Exception { - URL resource = this.getClass().getResource("/3730.ab1"); - assertNotNull(resource); - ABITrace tracer = new ABITrace(resource); assertNotNull(tracer); } @@ -78,7 +72,7 @@ public void testURL() throws Exception { * Test of Local file method, of class ABITracer. */ @Test - public void testLocal() throws Exception { + void testLocal() throws Exception { URL resource = this.getClass().getResource("/3730.ab1"); assertNotNull(resource); File file = new File(resource.toURI()); @@ -86,8 +80,7 @@ public void testLocal() throws Exception { ABITrace tracer = new ABITrace(file); assertNotNull(tracer); - //Test length of tracer for file 3730.ab1 - final int EXPECTED_TRACE_LENGTH = 16302; + assertEquals(EXPECTED_TRACE_LENGTH, tracer.getTraceLength()); //Test length of sequence for file 3730.ab1 assertEquals(1165, tracer.getSequenceLength()); @@ -102,9 +95,18 @@ public void testLocal() throws Exception { BufferedImage image = tracer.getImage(100,100); assertNotNull(image); - Assert.assertThrows(CompoundNotFoundException.class, ()->tracer.getTrace("D")); - for (String base: Arrays.asList(new String []{"A","T","C","G"})){ - assertEquals(EXPECTED_TRACE_LENGTH, tracer.getTrace(base).length); - } + + } + + @DisplayName("getTrace rejects invalid bases") + @Test + void testGetTraceThrowsCNFE() throws Exception { + assertThrows(CompoundNotFoundException.class, ()->tracer.getTrace("D")); + } + + @ParameterizedTest + @ValueSource(strings = {"A","T","C", "G" }) + void testGetTrace(String base) throws Exception {; + assertEquals(EXPECTED_TRACE_LENGTH, tracer.getTrace(base).length); } } diff --git a/pom.xml b/pom.xml index d5a7d30e65..3866c8753e 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,7 @@ 1.0.10 1.7.30 2.14.0 + 5.7.2 ciftools-java-jdk8 2.0.2 @@ -243,20 +244,8 @@ org.apache.maven.plugins maven-surefire-plugin 3.0.0-M5 - - - true - true - true - true - - - true - true - true - - - + + org.apache.maven.plugins maven-shade-plugin @@ -419,23 +408,24 @@ test - org.junit.vintage - junit-vintage-engine - 5.7.2 - test - - - org.junit.jupiter - junit-jupiter-api - 5.7.2 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.7.2 - test - + org.junit.vintage + junit-vintage-engine + ${junit-jupiter.version} + test + + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit-jupiter.version} + test + org.slf4j slf4j-api From 00bd3b2c610e60dded181e85a8781be588e7b991 Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Sun, 4 Jul 2021 10:43:38 +0100 Subject: [PATCH 277/769] formatting --- .../nbio/core/sequence/io/ABITracerTest.java | 159 +++++++++++++++--- 1 file changed, 131 insertions(+), 28 deletions(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java index dce9cc7b58..3024940a07 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java @@ -21,9 +21,8 @@ package org.biojava.nbio.core.sequence.io; - import static org.junit.jupiter.api.Assertions.*; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.*; import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.ParameterizedTest; @@ -35,31 +34,138 @@ import org.biojava.nbio.core.exceptions.CompoundNotFoundException; /** - * Test file 3730.ab1 is from https://github.com/biopython/biopython/blob/master/Tests/Abi/3730.ab1 - * The test data for comparing the results from ABITrace.java for file 3730.ab1 is from https://github.com/biopython/biopython/blob/master/Tests/Abi/test_data + * Test file 3730.ab1 is from https://github.com/biopython/biopython/blob/master/Tests/Abi/3730.ab1 The test data for + * comparing the results from ABITrace.java for file 3730.ab1 is from + * https://github.com/biopython/biopython/blob/master/Tests/Abi/test_data */ public class ABITracerTest { - private String sequence = "GGGCGAGCKYYAYATTTTGGCAAGAATTGAGCTCTATGGCCACAACCATGGTGAGCAAGGGCGAGGAGGATAACATGGCCATCATCAAGGAGTTCATGCGCTTCAAGGTGCACATGGAGGGCTCCGTGAACGGCCACGAGTTCGAGATCGAGGGCGAGGGCGAGGGCCGCCCCTACGAGGGCACCCAGACCGCCAAGCTGAAGGTGACCAAGGGTGGCCCCCTGCCCTTCGCCTGGGACATCCTGTCCCCTCAGTTCATGTACGGCTCCAAGGCCTACGTGAAGCACCCCGCCGACATCCCCGACTACTTGAAGCTGTCCTTCCCCGAGGGCTTCAAGTGGGAGCGCGTGATGAACTTCGAGGACGGCGGCGTGGTGACCGTGACCCAGGACTCCTCCCTGCAGGACGGCGAGTTCATCTACAAGGTGAAGCTGCGCGGCACCAACTTCCCCTCCGACGGCCCCGTAATGCAGAAGAAGACCATGGGCTGGGAGGCCTCCTCCGAGCGGATGTACCCCGAGGACGGCGCCCTGAAGGGCGAGATCAAGCAGAGGCTGAAGCTGAAGGACGGCGGCCACTACGACGCTGAGGTCAAGACCACCTACAAGGCCAAGAAGCCCGTGCAGCTGCCCGGCGCCTACAACGTCAACATCAAGTTGGACATCACCTCCCACAACGAGGACTACACCATCGTGGAACAGTACGAACGCGCCGAGGGCCGCCACTCCACCGGCGGCATGGACGAGCTGTACAAGGGCGGCAGCGGCATGGTGAGCAAGGGCGAGGAGCTGTTCACCGGGGTGGTGCCCATCCTGGTCGAGCTGGACGGCGACGTAAACGGCCACAAGTTCAGCGTGTCCGGCGAGGGCGAGGGCGATGCCACCTACGGCAAGCTGACCCTGAAGTTCATCTGCACCACCGGCAAGCTGCCCGTGCCCTGGCCCACCCTCGTGACCACCCTGACCTACGGCGTGCAGTGCTTCAGCCGCTACCCCGACCACATGAAGCAGCACGACTTCTTCAAGTCCGCCATGCCCGAAGGCTACGTCCAGGAGCGCACCATCTTCTTCAAGGACGACGGCAACTACAARACCCGCGCCGAGGTGAARTTCGAGGGCGACACCCTGGTGAACCGCATCGAGCTGAAAGGGGCAYCGCACCTTTC"; - private int[] qual = {20, 3, 4, 4, 4, 6, 4, 4, 0, 0, 0, 6, 0, 10, 20, 26, 22, 17, 21, 31, 29, 32, 28, 18, 23, 17, 19, 35, 36, 50, 39, 50, 50, 50, 50, 50, 25, 35, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 35, 39, 33, 20, 35, 31, 50, 50, 50, 50, 50, 50, 50, 50, 50, 31, 50, 35, 31, 23, 28, 31, 21, 43, 39, 35, 24, 30, 26, 35, 31, 50, 50, 50, 50, 50, 50, 50, 50, 50, 39, 31, 24, 39, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 31, 31, 43, 43, 50, 50, 50, 50, 50, 31, 31, 31, 31, 50, 50, 50, 50, 50, 50, 50, 50, 31, 31, 35, 50, 50, 50, 50, 31, 36, 55, 55, 55, 55, 36, 55, 55, 55, 55, 55, 36, 55, 55, 55, 55, 55, 36, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 40, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 36, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 40, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 43, 43, 50, 43, 43, 50, 43, 43, 50, 43, 43, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 43, 43, 50, 43, 43, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 28, 28, 35, 28, 28, 35, 28, 28, 35, 28, 28, 35, 28, 28, 35, 28, 21, 28, 35, 28, 28, 35, 35, 35, 35, 35, 37, 38, 21, 28, 35, 28, 28, 35, 35, 35, 35, 35, 35, 35, 36, 36, 21, 39, 35, 35, 35, 39, 35, 37, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 28, 28, 35, 35, 28, 28, 35, 35, 35, 36, 36, 22, 39, 35, 35, 35, 35, 35, 35, 37, 38, 28, 35, 21, 36, 36, 37, 35, 35, 20, 39, 39, 35, 35, 35, 35, 37, 38, 28, 35, 37, 34, 35, 24, 24, 27, 25, 20, 24, 37, 35, 27, 21, 20, 21, 27, 17, 20, 24, 32, 26, 20, 12, 20, 10, 20, 24, 25, 23, 20, 32, 24, 24, 23, 20, 24, 23, 18, 34, 34, 34, 22, 26, 24, 24, 18, 22, 22, 23, 25, 20, 12, 20, 24, 23, 24, 23, 22, 20, 20, 0, 20, 24, 23, 20, 8, 10, 4, 20, 20, 3, 7, 19, 20, 4, 4, 7, 7, 0, 7, 11, 18, 8, 3, 23, 23, 20, 11, 4, 20, 18, 12, 20, 20, 20, 4, 20, 4, 2, 3, 21, 21, 21, 21, 10, 15, 14, 15, 19, 2, 4, 3, 6, 11, 3, 4, 6, 21, 16, 20, 11, 1, 4, 12, 0, 15, 8, 1, 3, 3, 12, 1, 11, 20, 4}; - private int[] base = {2, 13, 38, 51, 67, 78, 92, 118, 138, 162, 181, 191, 210, 222, 239, 253, 266, 280, 288, 304, 317, 333, 347, 359, 375, 386, 394, 406, 418, 433, 444, 457, 472, 482, 496, 506, 519, 529, 544, 557, 569, 579, 590, 601, 614, 626, 638, 649, 663, 673, 686, 706, 715, 731, 740, 753, 765, 777, 787, 799, 813, 826, 838, 854, 863, 876, 892, 901, 913, 929, 937, 948, 960, 970, 981, 993, 1004, 1017, 1034, 1045, 1056, 1068, 1080, 1091, 1103, 1115, 1126, 1138, 1148, 1160, 1177, 1187, 1199, 1211, 1222, 1232, 1243, 1254, 1268, 1279, 1294, 1307, 1319, 1330, 1341, 1352, 1362, 1374, 1388, 1398, 1411, 1422, 1433, 1444, 1456, 1466, 1479, 1497, 1506, 1519, 1531, 1543, 1556, 1567, 1578, 1589, 1604, 1614, 1630, 1641, 1651, 1662, 1675, 1688, 1700, 1711, 1721, 1732, 1748, 1758, 1772, 1784, 1795, 1806, 1820, 1830, 1844, 1855, 1866, 1877, 1892, 1902, 1914, 1926, 1939, 1950, 1965, 1974, 1986, 1999, 2011, 2023, 2037, 2047, 2059, 2072, 2084, 2096, 2107, 2120, 2132, 2144, 2156, 2169, 2180, 2191, 2202, 2217, 2227, 2239, 2251, 2264, 2275, 2286, 2297, 2309, 2321, 2332, 2347, 2358, 2369, 2381, 2394, 2406, 2417, 2429, 2439, 2452, 2465, 2476, 2490, 2501, 2512, 2524, 2536, 2546, 2560, 2570, 2581, 2593, 2605, 2616, 2628, 2640, 2653, 2664, 2676, 2688, 2700, 2712, 2723, 2735, 2748, 2759, 2772, 2784, 2795, 2808, 2820, 2831, 2842, 2854, 2866, 2878, 2888, 2901, 2913, 2927, 2936, 2947, 2958, 2970, 2982, 2994, 3005, 3019, 3030, 3041, 3053, 3064, 3077, 3088, 3099, 3110, 3123, 3135, 3146, 3157, 3168, 3179, 3192, 3203, 3214, 3226, 3238, 3251, 3263, 3275, 3286, 3297, 3308, 3320, 3331, 3344, 3356, 3368, 3380, 3391, 3402, 3415, 3426, 3440, 3451, 3462, 3474, 3485, 3496, 3508, 3520, 3532, 3543, 3556, 3569, 3580, 3593, 3604, 3615, 3626, 3638, 3650, 3661, 3673, 3684, 3698, 3709, 3721, 3732, 3744, 3756, 3767, 3779, 3792, 3803, 3814, 3827, 3838, 3850, 3862, 3873, 3885, 3897, 3909, 3920, 3932, 3943, 3955, 3966, 3980, 3990, 4002, 4014, 4026, 4038, 4050, 4061, 4072, 4083, 4095, 4107, 4119, 4131, 4143, 4156, 4167, 4179, 4191, 4203, 4215, 4227, 4238, 4252, 4262, 4274, 4287, 4298, 4310, 4321, 4333, 4345, 4356, 4370, 4381, 4393, 4406, 4417, 4428, 4440, 4453, 4464, 4477, 4489, 4500, 4513, 4524, 4536, 4548, 4560, 4573, 4583, 4595, 4607, 4620, 4631, 4645, 4655, 4667, 4679, 4690, 4702, 4714, 4728, 4739, 4750, 4762, 4774, 4786, 4798, 4810, 4821, 4833, 4845, 4857, 4869, 4880, 4892, 4905, 4916, 4927, 4940, 4952, 4963, 4977, 4988, 5000, 5012, 5023, 5034, 5045, 5057, 5069, 5081, 5093, 5104, 5115, 5127, 5139, 5151, 5163, 5176, 5188, 5199, 5211, 5223, 5235, 5247, 5259, 5272, 5283, 5296, 5308, 5320, 5331, 5343, 5354, 5366, 5378, 5390, 5402, 5414, 5426, 5438, 5450, 5462, 5474, 5486, 5497, 5510, 5521, 5532, 5544, 5557, 5569, 5581, 5592, 5604, 5617, 5629, 5641, 5652, 5663, 5676, 5687, 5699, 5712, 5724, 5735, 5748, 5760, 5771, 5784, 5794, 5806, 5817, 5829, 5841, 5853, 5866, 5879, 5891, 5903, 5916, 5928, 5941, 5952, 5964, 5976, 5988, 6000, 6012, 6024, 6036, 6048, 6060, 6072, 6085, 6096, 6109, 6121, 6133, 6146, 6157, 6168, 6180, 6192, 6203, 6215, 6227, 6239, 6251, 6265, 6276, 6289, 6302, 6313, 6325, 6337, 6349, 6361, 6374, 6386, 6398, 6410, 6422, 6436, 6448, 6459, 6471, 6483, 6495, 6507, 6520, 6532, 6545, 6555, 6567, 6579, 6591, 6603, 6615, 6627, 6640, 6652, 6664, 6676, 6688, 6700, 6713, 6726, 6738, 6749, 6761, 6774, 6786, 6799, 6811, 6823, 6835, 6848, 6859, 6871, 6883, 6895, 6907, 6920, 6933, 6945, 6956, 6968, 6980, 6992, 7005, 7016, 7030, 7042, 7053, 7066, 7079, 7091, 7104, 7115, 7128, 7140, 7152, 7163, 7175, 7187, 7200, 7212, 7224, 7235, 7248, 7260, 7272, 7285, 7297, 7309, 7321, 7333, 7345, 7358, 7370, 7382, 7394, 7406, 7419, 7431, 7443, 7455, 7468, 7480, 7492, 7505, 7517, 7530, 7542, 7554, 7566, 7578, 7591, 7603, 7615, 7628, 7640, 7653, 7666, 7677, 7690, 7702, 7714, 7727, 7738, 7750, 7762, 7775, 7786, 7799, 7812, 7823, 7836, 7848, 7859, 7871, 7884, 7896, 7909, 7921, 7933, 7946, 7958, 7971, 7984, 7996, 8007, 8019, 8032, 8044, 8056, 8069, 8081, 8094, 8107, 8119, 8131, 8143, 8155, 8167, 8179, 8192, 8205, 8218, 8230, 8244, 8255, 8267, 8279, 8291, 8303, 8315, 8328, 8340, 8353, 8366, 8378, 8392, 8404, 8417, 8431, 8443, 8455, 8467, 8479, 8492, 8504, 8516, 8529, 8543, 8555, 8567, 8580, 8593, 8606, 8619, 8632, 8644, 8658, 8670, 8683, 8695, 8708, 8721, 8733, 8746, 8759, 8771, 8783, 8795, 8808, 8821, 8833, 8845, 8858, 8871, 8885, 8898, 8910, 8923, 8936, 8949, 8960, 8973, 8986, 9000, 9012, 9025, 9038, 9051, 9064, 9076, 9089, 9102, 9114, 9126, 9139, 9151, 9164, 9177, 9191, 9204, 9217, 9230, 9243, 9255, 9268, 9281, 9294, 9307, 9320, 9333, 9345, 9358, 9371, 9384, 9398, 9412, 9424, 9437, 9450, 9462, 9475, 9488, 9501, 9514, 9528, 9542, 9554, 9567, 9581, 9593, 9606, 9619, 9632, 9645, 9658, 9671, 9682, 9695, 9708, 9721, 9735, 9749, 9762, 9776, 9789, 9802, 9815, 9828, 9842, 9855, 9867, 9880, 9893, 9906, 9920, 9933, 9947, 9960, 9974, 9987, 10000, 10014, 10027, 10040, 10054, 10067, 10081, 10095, 10107, 10120, 10134, 10148, 10161, 10175, 10188, 10201, 10214, 10228, 10241, 10254, 10267, 10280, 10294, 10309, 10322, 10335, 10348, 10362, 10374, 10387, 10401, 10415, 10428, 10441, 10455, 10469, 10482, 10497, 10510, 10523, 10537, 10551, 10565, 10579, 10593, 10606, 10621, 10634, 10647, 10661, 10675, 10689, 10704, 10719, 10732, 10746, 10760, 10774, 10788, 10802, 10815, 10829, 10843, 10856, 10871, 10884, 10898, 10913, 10927, 10940, 10955, 10970, 10984, 10999, 11013, 11027, 11042, 11056, 11071, 11086, 11100, 11114, 11128, 11142, 11158, 11171, 11186, 11200, 11213, 11228, 11241, 11255, 11270, 11284, 11299, 11314, 11328, 11342, 11356, 11370, 11385, 11399, 11413, 11429, 11445, 11460, 11474, 11489, 11503, 11518, 11533, 11549, 11563, 11577, 11592, 11607, 11621, 11637, 11651, 11665, 11680, 11694, 11708, 11725, 11740, 11754, 11768, 11784, 11798, 11813, 11828, 11843, 11858, 11874, 11888, 11904, 11920, 11933, 11948, 11964, 11979, 11993, 12009, 12024, 12041, 12058, 12071, 12087, 12102, 12117, 12132, 12148, 12165, 12179, 12195, 12210, 12226, 12241, 12256, 12273, 12288, 12304, 12320, 12335, 12350, 12365, 12382, 12398, 12414, 12430, 12446, 12462, 12478, 12495, 12511, 12525, 12541, 12556, 12575, 12591, 12605, 12622, 12638, 12653, 12671, 12686, 12705, 12721, 12739, 12756, 12772, 12788, 12806, 12822, 12839, 12855, 12873, 12890, 12908, 12923, 12941, 12960, 12975, 12992, 13009, 13024, 13040, 13059, 13076, 13092, 13109, 13128, 13145, 13161, 13179, 13194, 13216, 13233, 13249, 13266, 13287, 13303, 13322, 13337, 13357, 13375, 13392, 13410, 13424, 13446, 13465, 13480, 13499, 13517, 13533, 13559, 13575, 13595, 13612, 13632, 13650, 13670, 13687, 13706, 13726, 13744, 13765, 13783, 13803, 13822, 13841, 13860, 13879, 13897, 13917, 13936, 13960, 13979, 13996, 14019, 14040, 14057, 14077, 14102, 14122, 14141, 14163, 14184, 14202, 14225, 14244, 14265, 14287, 14312, 14336, 14356, 14375, 14393, 14420, 14438, 14465, 14483, 14500, 14536, 14555, 14575, 14604, 14619, 14648, 14668, 14691, 14725, 14748, 14770, 14788, 14818, 14840, 14862, 14888, 14921, 14939, 14969, 14996, 15022, 15051, 15075, 15098, 15130, 15149, 15167, 15218, 15237, 15276, 15297, 15333, 15356, 15379, 15418, 15447, 15481, 15508, 15530, 15574, 15599, 15643, 15680, 15697, 15743, 15759, 15775, 15813, 15845, 15877, 15911, 15931, 15968, 16014, 16049, 16077, 16088, 16138, 16149, 16185, 16200, 16241, 16280, 16296}; + private int[] qual = { 20, 3, 4, 4, 4, 6, 4, 4, 0, 0, 0, 6, 0, 10, 20, 26, 22, 17, 21, 31, 29, 32, 28, 18, 23, 17, + 19, 35, 36, 50, 39, 50, 50, 50, 50, 50, 25, 35, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 35, 39, 33, 20, 35, + 31, 50, 50, 50, 50, 50, 50, 50, 50, 50, 31, 50, 35, 31, 23, 28, 31, 21, 43, 39, 35, 24, 30, 26, 35, 31, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 39, 31, 24, 39, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 31, 31, 43, 43, 50, 50, 50, 50, 50, 31, 31, 31, 31, 50, 50, 50, 50, 50, + 50, 50, 50, 31, 31, 35, 50, 50, 50, 50, 31, 36, 55, 55, 55, 55, 36, 55, 55, 55, 55, 55, 36, 55, 55, 55, 55, + 55, 36, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 40, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 36, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 40, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 43, 43, 50, 43, 43, 50, 43, 43, 50, 43, 43, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 43, 43, 50, 43, 43, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 28, 28, 35, 28, 28, 35, 28, 28, 35, 28, 28, 35, 28, 28, 35, 28, + 21, 28, 35, 28, 28, 35, 35, 35, 35, 35, 37, 38, 21, 28, 35, 28, 28, 35, 35, 35, 35, 35, 35, 35, 36, 36, 21, + 39, 35, 35, 35, 39, 35, 37, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 28, 28, 35, 35, 28, 28, 35, 35, + 35, 36, 36, 22, 39, 35, 35, 35, 35, 35, 35, 37, 38, 28, 35, 21, 36, 36, 37, 35, 35, 20, 39, 39, 35, 35, 35, + 35, 37, 38, 28, 35, 37, 34, 35, 24, 24, 27, 25, 20, 24, 37, 35, 27, 21, 20, 21, 27, 17, 20, 24, 32, 26, 20, + 12, 20, 10, 20, 24, 25, 23, 20, 32, 24, 24, 23, 20, 24, 23, 18, 34, 34, 34, 22, 26, 24, 24, 18, 22, 22, 23, + 25, 20, 12, 20, 24, 23, 24, 23, 22, 20, 20, 0, 20, 24, 23, 20, 8, 10, 4, 20, 20, 3, 7, 19, 20, 4, 4, 7, 7, + 0, 7, 11, 18, 8, 3, 23, 23, 20, 11, 4, 20, 18, 12, 20, 20, 20, 4, 20, 4, 2, 3, 21, 21, 21, 21, 10, 15, 14, + 15, 19, 2, 4, 3, 6, 11, 3, 4, 6, 21, 16, 20, 11, 1, 4, 12, 0, 15, 8, 1, 3, 3, 12, 1, 11, 20, 4 }; + private int[] base = { 2, 13, 38, 51, 67, 78, 92, 118, 138, 162, 181, 191, 210, 222, 239, 253, 266, 280, 288, 304, + 317, 333, 347, 359, 375, 386, 394, 406, 418, 433, 444, 457, 472, 482, 496, 506, 519, 529, 544, 557, 569, + 579, 590, 601, 614, 626, 638, 649, 663, 673, 686, 706, 715, 731, 740, 753, 765, 777, 787, 799, 813, 826, + 838, 854, 863, 876, 892, 901, 913, 929, 937, 948, 960, 970, 981, 993, 1004, 1017, 1034, 1045, 1056, 1068, + 1080, 1091, 1103, 1115, 1126, 1138, 1148, 1160, 1177, 1187, 1199, 1211, 1222, 1232, 1243, 1254, 1268, 1279, + 1294, 1307, 1319, 1330, 1341, 1352, 1362, 1374, 1388, 1398, 1411, 1422, 1433, 1444, 1456, 1466, 1479, 1497, + 1506, 1519, 1531, 1543, 1556, 1567, 1578, 1589, 1604, 1614, 1630, 1641, 1651, 1662, 1675, 1688, 1700, 1711, + 1721, 1732, 1748, 1758, 1772, 1784, 1795, 1806, 1820, 1830, 1844, 1855, 1866, 1877, 1892, 1902, 1914, 1926, + 1939, 1950, 1965, 1974, 1986, 1999, 2011, 2023, 2037, 2047, 2059, 2072, 2084, 2096, 2107, 2120, 2132, 2144, + 2156, 2169, 2180, 2191, 2202, 2217, 2227, 2239, 2251, 2264, 2275, 2286, 2297, 2309, 2321, 2332, 2347, 2358, + 2369, 2381, 2394, 2406, 2417, 2429, 2439, 2452, 2465, 2476, 2490, 2501, 2512, 2524, 2536, 2546, 2560, 2570, + 2581, 2593, 2605, 2616, 2628, 2640, 2653, 2664, 2676, 2688, 2700, 2712, 2723, 2735, 2748, 2759, 2772, 2784, + 2795, 2808, 2820, 2831, 2842, 2854, 2866, 2878, 2888, 2901, 2913, 2927, 2936, 2947, 2958, 2970, 2982, 2994, + 3005, 3019, 3030, 3041, 3053, 3064, 3077, 3088, 3099, 3110, 3123, 3135, 3146, 3157, 3168, 3179, 3192, 3203, + 3214, 3226, 3238, 3251, 3263, 3275, 3286, 3297, 3308, 3320, 3331, 3344, 3356, 3368, 3380, 3391, 3402, 3415, + 3426, 3440, 3451, 3462, 3474, 3485, 3496, 3508, 3520, 3532, 3543, 3556, 3569, 3580, 3593, 3604, 3615, 3626, + 3638, 3650, 3661, 3673, 3684, 3698, 3709, 3721, 3732, 3744, 3756, 3767, 3779, 3792, 3803, 3814, 3827, 3838, + 3850, 3862, 3873, 3885, 3897, 3909, 3920, 3932, 3943, 3955, 3966, 3980, 3990, 4002, 4014, 4026, 4038, 4050, + 4061, 4072, 4083, 4095, 4107, 4119, 4131, 4143, 4156, 4167, 4179, 4191, 4203, 4215, 4227, 4238, 4252, 4262, + 4274, 4287, 4298, 4310, 4321, 4333, 4345, 4356, 4370, 4381, 4393, 4406, 4417, 4428, 4440, 4453, 4464, 4477, + 4489, 4500, 4513, 4524, 4536, 4548, 4560, 4573, 4583, 4595, 4607, 4620, 4631, 4645, 4655, 4667, 4679, 4690, + 4702, 4714, 4728, 4739, 4750, 4762, 4774, 4786, 4798, 4810, 4821, 4833, 4845, 4857, 4869, 4880, 4892, 4905, + 4916, 4927, 4940, 4952, 4963, 4977, 4988, 5000, 5012, 5023, 5034, 5045, 5057, 5069, 5081, 5093, 5104, 5115, + 5127, 5139, 5151, 5163, 5176, 5188, 5199, 5211, 5223, 5235, 5247, 5259, 5272, 5283, 5296, 5308, 5320, 5331, + 5343, 5354, 5366, 5378, 5390, 5402, 5414, 5426, 5438, 5450, 5462, 5474, 5486, 5497, 5510, 5521, 5532, 5544, + 5557, 5569, 5581, 5592, 5604, 5617, 5629, 5641, 5652, 5663, 5676, 5687, 5699, 5712, 5724, 5735, 5748, 5760, + 5771, 5784, 5794, 5806, 5817, 5829, 5841, 5853, 5866, 5879, 5891, 5903, 5916, 5928, 5941, 5952, 5964, 5976, + 5988, 6000, 6012, 6024, 6036, 6048, 6060, 6072, 6085, 6096, 6109, 6121, 6133, 6146, 6157, 6168, 6180, 6192, + 6203, 6215, 6227, 6239, 6251, 6265, 6276, 6289, 6302, 6313, 6325, 6337, 6349, 6361, 6374, 6386, 6398, 6410, + 6422, 6436, 6448, 6459, 6471, 6483, 6495, 6507, 6520, 6532, 6545, 6555, 6567, 6579, 6591, 6603, 6615, 6627, + 6640, 6652, 6664, 6676, 6688, 6700, 6713, 6726, 6738, 6749, 6761, 6774, 6786, 6799, 6811, 6823, 6835, 6848, + 6859, 6871, 6883, 6895, 6907, 6920, 6933, 6945, 6956, 6968, 6980, 6992, 7005, 7016, 7030, 7042, 7053, 7066, + 7079, 7091, 7104, 7115, 7128, 7140, 7152, 7163, 7175, 7187, 7200, 7212, 7224, 7235, 7248, 7260, 7272, 7285, + 7297, 7309, 7321, 7333, 7345, 7358, 7370, 7382, 7394, 7406, 7419, 7431, 7443, 7455, 7468, 7480, 7492, 7505, + 7517, 7530, 7542, 7554, 7566, 7578, 7591, 7603, 7615, 7628, 7640, 7653, 7666, 7677, 7690, 7702, 7714, 7727, + 7738, 7750, 7762, 7775, 7786, 7799, 7812, 7823, 7836, 7848, 7859, 7871, 7884, 7896, 7909, 7921, 7933, 7946, + 7958, 7971, 7984, 7996, 8007, 8019, 8032, 8044, 8056, 8069, 8081, 8094, 8107, 8119, 8131, 8143, 8155, 8167, + 8179, 8192, 8205, 8218, 8230, 8244, 8255, 8267, 8279, 8291, 8303, 8315, 8328, 8340, 8353, 8366, 8378, 8392, + 8404, 8417, 8431, 8443, 8455, 8467, 8479, 8492, 8504, 8516, 8529, 8543, 8555, 8567, 8580, 8593, 8606, 8619, + 8632, 8644, 8658, 8670, 8683, 8695, 8708, 8721, 8733, 8746, 8759, 8771, 8783, 8795, 8808, 8821, 8833, 8845, + 8858, 8871, 8885, 8898, 8910, 8923, 8936, 8949, 8960, 8973, 8986, 9000, 9012, 9025, 9038, 9051, 9064, 9076, + 9089, 9102, 9114, 9126, 9139, 9151, 9164, 9177, 9191, 9204, 9217, 9230, 9243, 9255, 9268, 9281, 9294, 9307, + 9320, 9333, 9345, 9358, 9371, 9384, 9398, 9412, 9424, 9437, 9450, 9462, 9475, 9488, 9501, 9514, 9528, 9542, + 9554, 9567, 9581, 9593, 9606, 9619, 9632, 9645, 9658, 9671, 9682, 9695, 9708, 9721, 9735, 9749, 9762, 9776, + 9789, 9802, 9815, 9828, 9842, 9855, 9867, 9880, 9893, 9906, 9920, 9933, 9947, 9960, 9974, 9987, 10000, + 10014, 10027, 10040, 10054, 10067, 10081, 10095, 10107, 10120, 10134, 10148, 10161, 10175, 10188, 10201, + 10214, 10228, 10241, 10254, 10267, 10280, 10294, 10309, 10322, 10335, 10348, 10362, 10374, 10387, 10401, + 10415, 10428, 10441, 10455, 10469, 10482, 10497, 10510, 10523, 10537, 10551, 10565, 10579, 10593, 10606, + 10621, 10634, 10647, 10661, 10675, 10689, 10704, 10719, 10732, 10746, 10760, 10774, 10788, 10802, 10815, + 10829, 10843, 10856, 10871, 10884, 10898, 10913, 10927, 10940, 10955, 10970, 10984, 10999, 11013, 11027, + 11042, 11056, 11071, 11086, 11100, 11114, 11128, 11142, 11158, 11171, 11186, 11200, 11213, 11228, 11241, + 11255, 11270, 11284, 11299, 11314, 11328, 11342, 11356, 11370, 11385, 11399, 11413, 11429, 11445, 11460, + 11474, 11489, 11503, 11518, 11533, 11549, 11563, 11577, 11592, 11607, 11621, 11637, 11651, 11665, 11680, + 11694, 11708, 11725, 11740, 11754, 11768, 11784, 11798, 11813, 11828, 11843, 11858, 11874, 11888, 11904, + 11920, 11933, 11948, 11964, 11979, 11993, 12009, 12024, 12041, 12058, 12071, 12087, 12102, 12117, 12132, + 12148, 12165, 12179, 12195, 12210, 12226, 12241, 12256, 12273, 12288, 12304, 12320, 12335, 12350, 12365, + 12382, 12398, 12414, 12430, 12446, 12462, 12478, 12495, 12511, 12525, 12541, 12556, 12575, 12591, 12605, + 12622, 12638, 12653, 12671, 12686, 12705, 12721, 12739, 12756, 12772, 12788, 12806, 12822, 12839, 12855, + 12873, 12890, 12908, 12923, 12941, 12960, 12975, 12992, 13009, 13024, 13040, 13059, 13076, 13092, 13109, + 13128, 13145, 13161, 13179, 13194, 13216, 13233, 13249, 13266, 13287, 13303, 13322, 13337, 13357, 13375, + 13392, 13410, 13424, 13446, 13465, 13480, 13499, 13517, 13533, 13559, 13575, 13595, 13612, 13632, 13650, + 13670, 13687, 13706, 13726, 13744, 13765, 13783, 13803, 13822, 13841, 13860, 13879, 13897, 13917, 13936, + 13960, 13979, 13996, 14019, 14040, 14057, 14077, 14102, 14122, 14141, 14163, 14184, 14202, 14225, 14244, + 14265, 14287, 14312, 14336, 14356, 14375, 14393, 14420, 14438, 14465, 14483, 14500, 14536, 14555, 14575, + 14604, 14619, 14648, 14668, 14691, 14725, 14748, 14770, 14788, 14818, 14840, 14862, 14888, 14921, 14939, + 14969, 14996, 15022, 15051, 15075, 15098, 15130, 15149, 15167, 15218, 15237, 15276, 15297, 15333, 15356, + 15379, 15418, 15447, 15481, 15508, 15530, 15574, 15599, 15643, 15680, 15697, 15743, 15759, 15775, 15813, + 15845, 15877, 15911, 15931, 15968, 16014, 16049, 16077, 16088, 16138, 16149, 16185, 16200, 16241, 16280, + 16296 }; private ABITrace tracer = null; - //Test length of tracer for file 3730.ab1 + + // Test length of tracer for file 3730.ab1 static final int EXPECTED_TRACE_LENGTH = 16302; @BeforeEach - void setUp() throws Exception { + void setUp() throws Exception { URL resource = this.getClass().getResource("/3730.ab1"); assertNotNull(resource); tracer = new ABITrace(resource); } - @AfterEach - void tearDown() { - } - /** * Test of URL method, of class ABITracer. */ @@ -72,41 +178,38 @@ public void testURL() throws Exception { * Test of Local file method, of class ABITracer. */ @Test - void testLocal() throws Exception { + void testLocal() throws Exception { URL resource = this.getClass().getResource("/3730.ab1"); - assertNotNull(resource); File file = new File(resource.toURI()); assertNotNull(file); ABITrace tracer = new ABITrace(file); assertNotNull(tracer); - assertEquals(EXPECTED_TRACE_LENGTH, tracer.getTraceLength()); - //Test length of sequence for file 3730.ab1 + // Test length of sequence for file 3730.ab1 assertEquals(1165, tracer.getSequenceLength()); - //Test sequence of tracer for file 3730.ab1 + // Test sequence of tracer for file 3730.ab1 assertTrue(sequence.equals(tracer.getSequence().getSequenceAsString())); - //Test array that represents the quality of tracer for file 3730.ab1 + // Test array that represents the quality of tracer for file 3730.ab1 assertArrayEquals(qual, tracer.getQcalls()); - //Test array that represents the baseline of tracer for file 3730.ab1 + // Test array that represents the baseline of tracer for file 3730.ab1 assertArrayEquals(base, tracer.getBasecalls()); - //Test image of tracer for file 3730.ab1 - BufferedImage image = tracer.getImage(100,100); + // Test image of tracer for file 3730.ab1 + BufferedImage image = tracer.getImage(100, 100); assertNotNull(image); - - } @DisplayName("getTrace rejects invalid bases") @Test void testGetTraceThrowsCNFE() throws Exception { - assertThrows(CompoundNotFoundException.class, ()->tracer.getTrace("D")); + assertThrows(CompoundNotFoundException.class, () -> tracer.getTrace("D")); } - @ParameterizedTest - @ValueSource(strings = {"A","T","C", "G" }) - void testGetTrace(String base) throws Exception {; + @DisplayName("Traces are equal length for 4 nucleotides") + @ParameterizedTest(name="Base: {0}") + @ValueSource(strings = { "A", "T", "C", "G" }) + void testGetTrace(String base) throws Exception { assertEquals(EXPECTED_TRACE_LENGTH, tracer.getTrace(base).length); } } From 3669911f7f109833607be9b09691fa104e9197b2 Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Sun, 4 Jul 2021 10:56:56 +0100 Subject: [PATCH 278/769] more formatting --- .../nbio/core/TestAmbiguityCompoundSet.java | 6 ++---- .../nbio/core/sequence/io/ABITracerTest.java | 15 ++++++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java b/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java index 9fad78d7b0..714f418280 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/TestAmbiguityCompoundSet.java @@ -20,7 +20,8 @@ */ package org.biojava.nbio.core; -import org.biojava.nbio.core.exceptions.CompoundNotFoundException; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.biojava.nbio.core.sequence.DNASequence; import org.biojava.nbio.core.sequence.RNASequence; import org.biojava.nbio.core.sequence.compound.AmbiguityDNACompoundSet; @@ -31,9 +32,6 @@ import org.biojava.nbio.core.sequence.template.Sequence; import org.biojava.nbio.core.sequence.transcription.DNAToRNATranslator; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.DisplayName; - -import static org.junit.jupiter.api.Assertions.assertEquals; /** * A Test case for https://github.com/biojava/biojava/issues/344 diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java index 3024940a07..be87905e04 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/sequence/io/ABITracerTest.java @@ -21,17 +21,22 @@ package org.biojava.nbio.core.sequence.io; -import static org.junit.jupiter.api.Assertions.*; -import org.junit.jupiter.api.*; -import org.junit.jupiter.params.provider.ValueSource; -import org.junit.jupiter.params.ParameterizedTest; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.awt.image.BufferedImage; import java.io.File; import java.net.URL; -import java.util.Arrays; import org.biojava.nbio.core.exceptions.CompoundNotFoundException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; /** * Test file 3730.ab1 is from https://github.com/biopython/biopython/blob/master/Tests/Abi/3730.ab1 The test data for From 704bda6c582d049dab109586fe0949e7b8e63ab2 Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Sun, 4 Jul 2021 11:32:26 +0100 Subject: [PATCH 279/769] update junit3->junit4 test, remove doc references to ju3 --- .../nbio/structure/test/TestSECalignment.java | 16 +++++++++++----- .../test/align/ce/OptimalCECPMainTest.java | 8 +------- .../org/biojava/nbio/structure/ElementTest.java | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/TestSECalignment.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/TestSECalignment.java index 6a9516251b..b8ec8ed89c 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/TestSECalignment.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/TestSECalignment.java @@ -22,7 +22,14 @@ */ package org.biojava.nbio.structure.test; -import junit.framework.TestCase; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.InputStream; + +import org.biojava.nbio.core.util.StringManipulationHelper; import org.biojava.nbio.structure.Atom; import org.biojava.nbio.structure.align.StructureAlignment; import org.biojava.nbio.structure.align.StructureAlignmentFactory; @@ -33,9 +40,7 @@ import org.biojava.nbio.structure.align.xml.AFPChainXMLParser; import org.biojava.nbio.structure.test.align.fatcat.FlipAFPChainTest; import org.biojava.nbio.structure.test.util.StringManipulationTestsHelper; -import org.biojava.nbio.core.util.StringManipulationHelper; - -import java.io.InputStream; +import org.junit.Test; /** This test makes sure that the new representation of selenocysteins as SEC amino acids does not * affect the structure alignment results. @@ -43,8 +48,9 @@ * @author andreas * */ -public class TestSECalignment extends TestCase { +public class TestSECalignment { + @Test public void testOldSecOutput() throws Exception { String fileName = "/ce_1fdo.A_2iv2.X.out"; diff --git a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/align/ce/OptimalCECPMainTest.java b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/align/ce/OptimalCECPMainTest.java index bf7ee56be4..81eb35c9b9 100644 --- a/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/align/ce/OptimalCECPMainTest.java +++ b/biojava-integrationtest/src/test/java/org/biojava/nbio/structure/test/align/ce/OptimalCECPMainTest.java @@ -46,13 +46,7 @@ public class OptimalCECPMainTest { private AtomCache cache = new AtomCache(); - /* (non-Javadoc) - * @see junit.framework.TestCase#setUp() - */ - @Before - public void setUp() throws Exception { - } - + /** * Basic test that alignPermuted(..., 0) is equivalent to a normal CE alignment. * diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/ElementTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/ElementTest.java index 81ce22d087..7dd8cda993 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/ElementTest.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/ElementTest.java @@ -21,7 +21,7 @@ package org.biojava.nbio.structure; -import junit.framework.TestCase; + import org.junit.Assert; import org.junit.Test; From 3cc243e6660acc3d0ca98320d1863a58841c04ca Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Fri, 9 Jul 2021 18:34:48 +0100 Subject: [PATCH 280/769] example of new nested test, with bug in SequenceTools#permuteCyclic detected and fixed --- .../biojava/nbio/core/util/SequenceTools.java | 15 ++++ .../nbio/core/util/SequenceToolsTest.java | 74 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 biojava-core/src/test/java/org/biojava/nbio/core/util/SequenceToolsTest.java diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/util/SequenceTools.java b/biojava-core/src/main/java/org/biojava/nbio/core/util/SequenceTools.java index f23d4e7417..2dd32af6c9 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/util/SequenceTools.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/util/SequenceTools.java @@ -50,6 +50,21 @@ public static String permuteCyclic(String string, int n) { return String.valueOf(p); } + /** + * Improved implementation that is generally 10-100x faster, and fixes some edge-case bugs. + * @param string The string to permute + * @param n The number of characters to permute by; can be positive or negative; values greater than the length of the array are acceptable + * @return + */ + public static String permuteCyclic2(String string, int n) { + String toMutate = string + string; + n = n % string.length(); + if (n < 0) { + n = string.length() + n; + } + return toMutate.substring(n, n + string.length()); + } + /** * Cyclically permute {@code array} forward by {@code n} elements. * @param array The original result; will not be changed diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/util/SequenceToolsTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/util/SequenceToolsTest.java new file mode 100644 index 0000000000..819c40e9b0 --- /dev/null +++ b/biojava-core/src/test/java/org/biojava/nbio/core/util/SequenceToolsTest.java @@ -0,0 +1,74 @@ +package org.biojava.nbio.core.util; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Random; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class SequenceToolsTest { + + String randomDNA(int n) { + String[] nucs = new String[] { "A", "T", "C", "G" }; + Random r = new Random(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < n; i++) { + sb.append(nucs[r.nextInt(4)]); + } + return sb.toString(); + } + + @Nested + class PermuteCyclic { + + @ParameterizedTest + @CsvSource(value = { "ATCGT,1,TCGTA", "ATCGT,-1,TATCG", "ATCGT,0,ATCGT", "ATCGT,25,ATCGT","12345,1,23451" }) + void permuteCyclicBasic(String original, int n, String expected) { + assertEquals(expected, SequenceTools.permuteCyclic(original, n)); + } + + @ParameterizedTest + @CsvSource(value = { "ATCGT,CGTAT", "ATCGT,CGTAT" }) + @Disabled("fails with current implementation") + void permuteCycleIntMaxMin(String original, String expected) { + assertAll( + ()->assertEquals(expected, SequenceTools.permuteCyclic(original, Integer.MAX_VALUE)), + ()->assertEquals(expected, SequenceTools.permuteCyclic(original, Integer.MIN_VALUE)) + ); + } + + @ParameterizedTest + @CsvSource(value = { "ATCGT,CGTAT", "ATCGT,CGTAT" }) + @DisplayName("Edge case fixed") + void permuteCycleIntMaxMin2(String original, String expected) { + assertAll( + ()->assertEquals(expected, SequenceTools.permuteCyclic2(original, Integer.MAX_VALUE)), + ()->assertEquals(expected, SequenceTools.permuteCyclic2(original, Integer.MIN_VALUE)) + ); + } + + @Test + void permuteCyclicPerformance() { + String dna = randomDNA(10_000_000); + long start = System.currentTimeMillis(); + String rotated = SequenceTools.permuteCyclic(dna, 5_000_000); + long end = System.currentTimeMillis(); + System.err.println(end-start); + + long start2 = System.currentTimeMillis(); + String rotated2 = SequenceTools.permuteCyclic2(dna, 5_000_000); + long end2 = System.currentTimeMillis(); + System.err.println(end2-start2); + assertTrue((end-start)/(end2-start2) > 5); + } + + } + +} From 43fafd0a40a523422c1f8d16d7a2a0b504881a01 Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Sat, 10 Jul 2021 21:41:39 +0100 Subject: [PATCH 281/769] add tests for other SequenceToolsMethods --- .gitignore | 1 + .../biojava/nbio/core/util/SequenceTools.java | 18 ++++ .../nbio/core/util/SequenceToolsTest.java | 95 +++++++++++++++++++ 3 files changed, 114 insertions(+) diff --git a/.gitignore b/.gitignore index 4c968aac08..89345576ab 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .profile .settings .classpath +.factorypath .DS_Store .idea *.iml diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/util/SequenceTools.java b/biojava-core/src/main/java/org/biojava/nbio/core/util/SequenceTools.java index 2dd32af6c9..61f7e44135 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/util/SequenceTools.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/util/SequenceTools.java @@ -119,6 +119,23 @@ public static boolean isNucleotideSequence(String sequence) return true; } + /** + * Attempts to parse String as a DNA sequence first.
      + * If this fails it tries to parse as a ProteinSequence. + *
      + * This method does not attempt to create an RNASequence. + *

      + * Also, a sequence such as 'ATCGTA' which is both a + * peptide sequence and a DNA sequence, will always be returned + * as a DNA sequence. + *

      + *

      + * An empty string argument returns a ProteinSequence of length 0. + * A null argument throws a {@link NullPointerException} + * @param sequence + * @return Either a DNASequence or a ProteinSequence + * @throws CompoundNotFoundException + */ public Sequence getSequenceFromString(String sequence) throws CompoundNotFoundException { @@ -126,6 +143,7 @@ public Sequence getSequenceFromString(String sequence) throws CompoundNotFoun return new DNASequence(sequence); } else { return new ProteinSequence(sequence); + } } diff --git a/biojava-core/src/test/java/org/biojava/nbio/core/util/SequenceToolsTest.java b/biojava-core/src/test/java/org/biojava/nbio/core/util/SequenceToolsTest.java index 819c40e9b0..420e574c28 100644 --- a/biojava-core/src/test/java/org/biojava/nbio/core/util/SequenceToolsTest.java +++ b/biojava-core/src/test/java/org/biojava/nbio/core/util/SequenceToolsTest.java @@ -1,17 +1,25 @@ package org.biojava.nbio.core.util; +import static org.junit.Assert.assertThrows; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Random; +import org.biojava.nbio.core.exceptions.CompoundNotFoundException; +import org.biojava.nbio.core.sequence.ProteinSequence; +import org.biojava.nbio.core.sequence.template.Sequence; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.EmptySource; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.NullSource; class SequenceToolsTest { @@ -68,7 +76,94 @@ void permuteCyclicPerformance() { System.err.println(end2-start2); assertTrue((end-start)/(end2-start2) > 5); } + } + + @Nested + class PercentNucleotideContent { + + @ParameterizedTest + @NullAndEmptySource + @DisplayName("percent nucleotide sequence returns 0 for null "+ + "or empty string") + void nucleotideContentInvalidValues(String empty){ + assertEquals(0, SequenceTools.percentNucleotideSequence(empty)); + } + + @Test + void nucleotideContentTest(){ + assertEquals(100, SequenceTools.percentNucleotideSequence("ATCGCAA")); + assertEquals(100, SequenceTools.percentNucleotideSequence("UUACG")); + assertEquals(100, SequenceTools.percentNucleotideSequence(randomDNA(1_000_000))); + assertEquals(50, SequenceTools.percentNucleotideSequence("123CCG")); + assertEquals(66, SequenceTools.percentNucleotideSequence("12TTAC")); assertEquals(0, SequenceTools.percentNucleotideSequence(" HH")); + assertEquals(0, SequenceTools.percentNucleotideSequence("actg")); + } + + @Test + void isNucleotideSequence () { + assertTrue(SequenceTools.isNucleotideSequence("AACGAA")); + assertFalse(SequenceTools.isNucleotideSequence("aacgaa")); + assertFalse(SequenceTools.isNucleotideSequence(" HH")); + } + @ParameterizedTest + @NullAndEmptySource + @DisplayName("isNucleotide is false for null "+ + "or empty string") + void isnucleotideInvalidValues(String empty){ + assertFalse(SequenceTools.isNucleotideSequence(empty)); + } } + @Nested + @DisplayName("SequenceFromString") + class SequenceFromString{ + SequenceTools tools = new SequenceTools(); + @Test + void acceptsUpperCaseDNA() throws CompoundNotFoundException { + Sequencenuc = tools.getSequenceFromString("ATCG"); + assertEquals(4, nuc.getLength()); + } + + @Test + void acceptsLowerCaseDNA() throws CompoundNotFoundException { + Sequencenuc = tools.getSequenceFromString("atcg"); + assertEquals(4, nuc.getLength()); + } + + @Test + void rejectsRNA()throws CompoundNotFoundException { + assertThrows(CompoundNotFoundException.class, + ()->tools.getSequenceFromString("AUCG")); + } + + @Test + void acceptsSingleLetterProtein()throws CompoundNotFoundException { + Sequence protein = tools.getSequenceFromString("HYDESS"); + assertEquals(6, protein.getLength()); + } + + @Test + void interpets3LetterAACodeAsSingleLetter()throws CompoundNotFoundException { + Sequence protein = tools.getSequenceFromString("AlaGlySer"); + assertEquals(9, protein.getLength()); + } + + @EmptySource + @ParameterizedTest + @DisplayName("empty string return 0-length protein sequence") + void emptyString(String empty) throws CompoundNotFoundException{ + Sequence protein = tools.getSequenceFromString(empty); + assertEquals(0, protein.getLength()); + assertTrue(protein instanceof ProteinSequence); + } + + @NullSource + @ParameterizedTest + @DisplayName("null string throws NPE") + void nullString(String nullStr) throws CompoundNotFoundException{ + assertThrows(NullPointerException.class, + ()-> tools.getSequenceFromString(nullStr)); + } + } } From 190b55fc016fe78a9d0d11295e2fbe03d5e146c9 Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Wed, 21 Jul 2021 23:08:28 +0100 Subject: [PATCH 282/769] padleft/right tests --- .../core/util/StringManipulationHelper.java | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/util/StringManipulationHelper.java b/biojava-core/src/main/java/org/biojava/nbio/core/util/StringManipulationHelper.java index f8aef6b35e..ca7edcb3b2 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/util/StringManipulationHelper.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/util/StringManipulationHelper.java @@ -23,6 +23,19 @@ */ package org.biojava.nbio.core.util; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.AbstractCollection; +import java.util.Iterator; +import java.util.Scanner; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -31,14 +44,6 @@ import org.w3c.dom.Node; import org.xml.sax.SAXException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.*; -import java.util.AbstractCollection; -import java.util.Iterator; -import java.util.Scanner; - /** * A utility class for common {@link String} manipulation tasks. @@ -62,10 +67,6 @@ private StringManipulationHelper() { // to prevent instantiation } - - - - /** * @author andreas * @param stream @@ -174,14 +175,36 @@ public static boolean equalsToXml(String expected, String actual) { throw new UnsupportedOperationException("not yet implemented"); } + /** + * Adds padding to left of supplied string + * @param s The String to pad + * @param n an integer >= 1 + * @return The left-padded string. + * @throws IllegalArgumentException if n <= 0 + */ public static String padLeft(String s, int n) { + validatePadding(n); return String.format("%1$" + n + "s", s); } + /** + * Adds padding to right of supplied string + * @param s The String to pad + * @param n an integer >= 1 + * @return The right-padded string. + * @throws IllegalArgumentException if n <= 0 + */ public static String padRight(String s, int n) { + validatePadding(n); return String.format("%1$-" + n + "s", s); } + private static void validatePadding(int n) { + if (n <=0 ) { + throw new IllegalArgumentException("padding must be >= 1"); + } + } + public static String join(AbstractCollection s, String delimiter) { if (s == null || s.isEmpty()) return ""; Iterator iter = s.iterator(); From fda5184389db3e05b9d825e03ab0049b958af60a Mon Sep 17 00:00:00 2001 From: Richard Adams Date: Thu, 22 Jul 2021 09:12:01 +0100 Subject: [PATCH 283/769] tests and docs for convertStreamToString --- .../core/util/StringManipulationHelper.java | 22 +++-- .../util/StringManipulationHelperTest.java | 83 +++++++++++++++++++ 2 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 biojava-core/src/test/java/org/biojava/nbio/core/util/StringManipulationHelperTest.java diff --git a/biojava-core/src/main/java/org/biojava/nbio/core/util/StringManipulationHelper.java b/biojava-core/src/main/java/org/biojava/nbio/core/util/StringManipulationHelper.java index ca7edcb3b2..88f100b4d2 100644 --- a/biojava-core/src/main/java/org/biojava/nbio/core/util/StringManipulationHelper.java +++ b/biojava-core/src/main/java/org/biojava/nbio/core/util/StringManipulationHelper.java @@ -68,9 +68,18 @@ private StringManipulationHelper() { } /** + * Converts an InputStream of text to a String, closing the stream + * before returning. + *

      u!7VP<;8{Lc0lJHk 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 diff --git a/biojava-structure/src/test/resources/validation/3zoi-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3zoi-valdata.xml.gz deleted file mode 100644 index db9e4fcef113db57ece7eb89853f6626c4b5fea7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19978 zcmV(`K-0e;iwFo1<~dRT12cMWX)ShPY-C|{VJ>)WYyj1LYi}G!mgVQ2Um*xsU=|>& zET%#4h< z&vVZG>wo|2`s&&5^ZSR(+nX29h$;XtIJR4i}b70%bQvwndH(F{v$GFBzIZNX(y#vU z%l&+wf1qUZgZud}mpAk4`OV_P-Tm$7`}6A;&wqUN&G#?Q((lg~=Pz$AA8r@-w|9T$ zPdVwDAD`V`-(AfY^PBm@!;9xJ%tUzp?A6!rS65s8<9_~dd-Y|pdaR(jKmBlZ`$zhX zoJITm**CWzzPb2taeIG1zdCO|BhoL@SABPz9`OC;=j-zq&(%zc|IFX@GCf{ipZodm zm-*pOZ@yfAoZqLfd;aXl`7hV!7k^)`ik6_d8 zuWoNXy}bE+HUD;gdp%EU`r`Sw@7|nzul{lJ&8w65@67XOKi!|-JiI-7|Kj;izs{ds zo!@^>U-azumtRhA?=L@J-aNaTpa1qO{r^S!^$+KZMY{Cu&9h&=++5@*d3O2mEWH~4 zztcySfAZ`6^7F5Y^}padX3yTTr-OmM4zsr*l!-@!jFuhMONb)Mhhi|7AW#+ftnMEUgp!ihAq;KPYX zOC#`q|6lvL^o*BjyQTe-J{e?sediySuWo*NH^09~d*HahhHDk z%T0e3(^Ay`YW1I|KfeF*=hNFSi>u4DjxV13n2!YafwXPU;R8~Lji0z(;3s@q!1RIq ztNY7~59Js6YtrkyzDvvf_x32hU(D~)FRyQ}(xLfyx%l(s`u6jetCN4FPoICDpUgi! zoRo_`ocwWrxtOO@{`}d;FIT^PNVoNSK5-w@evUIAP3PyoEnlck*RI|WE~cKDbav9- zKYg8!!ly46>1WD1x%}DpmseNw`|oZ(U0%%7N3{?({i0`;P|-+4>)myMv-!^dk}dA{x1Z)|ML)g&^6~Ti z?U%b}Z_gLE*AL04CDWTW%GKf`{l$yt&(eSY{`vOe;>*&U=cT*&_53oKqLq|1z=@8{ReewL=-+p@Y-SRgN z7Z>?m1)Z1r;eKfd@?J>){Xgk@XU2%lPvQ^vBys&DI?PPWJLuQT7tc?nT$+Hphx8Ar z#qyP(XY2mW`R{2Pe1a$b`^z`wiOu?n7x1huw$CbkTtBOvxpaQgqyDeIeoXd#{W_oJ z#}qG~pFLmxmrRS7?tXs0bWke0h}(~=vykrgVex7H`*QQ=qmjP#RLz8IR`4&~C7f`B z*mhan@-bJ-8gxDj&8k|lJZ?R!O7@Xmuj*Y{)tIgQdR47nuWDLuIba9H!#%3h>t{7K zdC>M*U6}cH2g$sf`kwX8Ki`*Ub?pvXTwlW`3ch_@WkuOU#;ZLxkqWW0iPBrLJMJMn z!X8p)X3M%Jd#cv!YGQVZee3%2&C9Z`9@a9JwUi3Bj!9l(dqUTq5}P8@@`N@& zRr7>GbEo9x`?uu@L%+3^vOI8v&7+)dHqUvEE+6fluiEW%_Okg;wcJyyog~wW+EJtIKQjGkU{_DK0Ugj&jj)UvCbXD12C%N`=9j#Z_sU8M+oNvoz%TU z?UrBl;`!@ubJBTn`6>OyDu}&4|GcyeX}LaKJ}j2|O+Wo!@a?PCGcev9cvp z`<|TNaj{47@G9Bqa`K`n9zMN?FwnyX-FXQ4WPB zb~?UZ+|&cd7)JaM7Tm&17>>@h^-ioawP1-mv+|RxyQ7(Y&a*xs=?Br?=AJ z&) za9-($*XYyRT=)7k;8`-TvjT=tI{jwj1DnG=uZH4<2mvzhhMrakNZq@^JP`)8S!ug*(o%|pudnf#7EZJTkBAWlOCRS4Kd%E=vqxZco8 z%xt#!k3uUov%7Ar17>#tEK>xp=Zj_1feWs_eFH@}RkDriQ-iDRAY=}>+Fo)Y^LE9t zWyK>_ier1U1x6|9CVvcN3!NJ*%~~6_*+NRXP3d+WMWN+aX!-Sk_;rkDT(+dkGupOn zeQGpUrlZejdY;kYGx{OVI7&q%JtWlTtuLXXj@(0%iim0(JlBgm62CZbbQr(n5R$P_ zUzbDksy#Gsf5wWWhl)r#G!8>Wz0NXq?l^N<=GLVbA#}a;V(j+mECjz&5;KtAipCm` zYlC00YiH+x&MiWgWJ+-4T#0?PUiQFycF*^(euCZOipeDzEd;+F4X%p=PRk*KUnn4| zreEIr7}q|qW8L|W-@*e!uutRP5Oi_r(!et-6F4XHs%)>H%Yk{VFuB6IObSChx^xS5 z8FnN0T}k#_DJ__{zH+4$7D=wz^K(fS;W1`fm2g*E+Wge(sKjtzys@R~Ykm0~K@PoL z*>}69db@I0$39Yh%9L=`nYNR8YAhF>lM0n;(>rtq7MwxAy=~lpw(Te$-li8+oS!Yu z*13}$wrG-`z@nO(X`A1C$jZB(2RR$p*27EH7;oP#G(v2N3?#kKfvw9(LA@>u%{ zRx_}MZ;KHrE|7F`Ej@*5eOUYv^pgSvPriU-QWV@C7HzrxL)RACNvE1*9N6N(=qbd= zEN%&&-n{}-q;f#9#vW1FNKSeh<9}qOHP;kjTW?#=r{pRxq<^IA{UZ-Gn1DOisR1W- zlzvY-n_!J%$zKhdzmigcF8v-)8a_~@_Go;a9||EE)bL4f%!GQwhjpNR#jWC(t?*>e zuJdBOYtL>JkK$(1qP1<~L#qdS6pc9}*4jPR+O2%5yx7eIoJ!~}7`D4WpOI93bb>JgiKS_Ym;YI{-hKTuEP7f1Rqtm&qx~ z9S_JzDU`r6U7*b=&dgy7r6Gm7lYvx4A8yDo!=4M1#VADG_Iyus+TX@tFR!j{ z|6nY8395-VAOxa ze|nA9vqd=G^;F?W>&$8n;kXeBOUiE|CBeb;Kpb~n=uw)Jvg!OR7dnd8lo~$!fW9PY zabWkg5FM6&SUyp^nFbqD0kqm!E(aj}W>a!3+HZz-p|GVQpO)2eu>4nGYJP@lk1HqD zNK-8%=`hT)oS|jWxh}Z=ViPJ&UNh6X_Tt8QZzg3H<-M6$pq5T>bqD(1+T86f_GQMT zH0(_U{CD>C7TCXC(-RY8H9Zk*m2=QW>ZwN#-bkuvBS~LH3+!y+mi)~T3_vLLt7r;& zL`4o>^V2`Uml)l1{ymmhup^g&1dKZ=<=(Sb3i>$^KE%hO~i=p)eB{*dvpO9onyH2a?NHT7NHMjueA{n_%jbx*SbZH@haKyOy z0omwCMR|`Hq=FhvZi)-2D7Ue6X?rTx)`JJk|Jox^^{O7I#>j0-Oco?=OVe8!mTR-M zYnnR-AuK1kZOUg07u9$!W+8MiQ>q72^+aie{U+Uj{5Ct2!{bd|6Ctl`v}$qwr)jG) zXYloR03tALN`FW4dBi|c&_o!3fgB_1&Mv8axrl&dd)_qc4rp-T2`zC#ifN(@fCDN~ zaqu|@JuaGvMJ!PWg(afdmLsY1n>JgdRerE;q=gdIfQ)7g%a92G!0L!?g*Z5#)B&c! zmUbLLKlbmW7&)qX2^QayU=gftrz@`7y|gpacqB&&4I^*M(NrwjlK4qml0`H_7!_ch zE$9Kr(owpPA-&`}79|euKH4_J>U4HV-+>q<9hj{|0adO4hTfy0B`oMYnj=VHW!=hW z_+N|rHjWJ}u}*DEJ8rS)FFlY-R@T-yAOJ@$ZQWx4j!sth$lL(11x+YLL(76O2#>-R z0gt<$!%M)WPOvz{9@L(~x*<}d{mfbi6=kR!id|X9Bel0|v6B{|t%^&ksj5etPY}pw zUqGh2PSUs>T;kc2U7bKWo zTRLpli$$N^Dh=s$$9jN>(I|8`M>zEOf+g2cB<%)UC`p(dL$j7*P!-Fb@4*#=;ZR*p zHw5dl`Q0jE-Zifsi$Nb@ZvorQ_`wW%Tf{3CxVJ(C_^ZYSMDB7-d6-HfFK3~YUaSGI z1It$W_6>L?*T(DDi&IH*c{ofFg8(<=Fpbr5fy%v;h1y|R7!oPmyTVwa$vjuMf1=_= zAdnq|dU!7GAjJz;KxUHQu1LR9b_~dr31}g3hDJlE#a|RO0!wQln0;3Y>LlN`KuIg! zFpGh1A7{P)y2o0|m~w@ZMCewjNX^u)+2|NiRu;Jc{R;tzzT6%g7-qRPr0wg2J46wA z!C^x;qlk2rm1aT?V2`V46bKPRx2IMb!9}p7Xyi%+OExhQPcWqOlGSk;Aa5keKK9Ks z)MRsZP0dD$uY6PfS?^=jx&-N1*$NV1Iak}q*na5jV-}aXeSqbStp`|+6|H(VNVKY> zkL8fNrOTy`p;(5FPY85;3LGC3+7Oip*QN=NR3dymQ4lFd=D18-sYK|MW2>6-l-->u zH%b_(P$a@e2&!0_FB(P`1R#L`ssd$ChZ7f?E!Fk$1hNlrQEU_<(Dd3)%`CFu1N>%H z|7Im+?VEKvrpNT!B%+V3hfJFFGW4}UYl24qBpN0)Wey5F1S((0qF5HyxYt|TmBThp z0mLl@4@+=RUK`s{B1x);q>UCpuqMzYHE+&g4%m^*o2fjpL;K>O1i}RMKmGUvJaK7! zL{h0nAB|bL7aT<3m4-^SM(9dwz8_(b{1CF`kOLsA2S6SHM!fCFNG}88Y{a*x+A`1?R``@(%Ote#N0;$bwN$WxdI6=ilx~T#b^X|g+8Ng zhR~?SVmD%;t?1QcP#05pA}Opd+Ui6dvzY9TG>{m;wH~LTss(BAMexds)lmajp8X}&b}I>0m(f+F;DJ)rM1N|LCFl#dN1pi*jZCo^D@h>c?bolJv`y$r)V zR8%Z1(Z{DF8`d&DLrfBJD{ouZTVtoM#MiO2Pt@mHtg$?nL(-M5xvzycR?1h zGQ9zW-=oeVE#yqHf-Kf~M&FJQzL7e+3cOy5sMbf^nS$VZOuHtX-7u)LOPHwki2$L> z%|g9%&leO3&?!J?mkMA?oVw$PNqZ`7RXejKcJqZ}cq&;K8>yg#BBxG$mi9Fhp21|( zx-66%0$f)tp=ubeHWWark*W=8uuBrV2#OtZHb8AilLFBi@vD>XfBJ4%fkkB9fwH)w zz#@$0!T|yu4<$S8DHxL;XRvH$x*-(kPUWFfK@fVnYv+C>U^P)hUQJ7En_+@Ewpa)V z{R$vB+`^&=o8*zz+pKqrmzTY^N9&z}8NTjW4$Rx4Z3d{clJc;9>#ge= zaVCjZ2T91C!?Te@`w+k63m8GOvIit#520tjP}zeaLZhQF%uKTfmd_|vD4tx}I9PK& z5M@FzLXSvhPgIq#*jLDgzlO&Qe1c|~dzATpq9S^%wl^08kVW4m!rAfP(Z=rUV&tHBxEtXwq#rN*|%@d%V^G1ezoNq?|$s2P-69TTw!D0LL| zxLoyFuXPlVWU%Z6l4CRqrjOMYK#Q`OhWa#3p4{8ERdbMsxU?n0$2DNm<%xY~}hDDIrTOYu!9EKD@MiKMy=n9-GuE5yAW6~S+6H7Zepz4)! zv5t5-f`jTHAS}hDbWTfKEEkuUQa5REHbZ7t$g>Xg6yqeq>2aJ!>((94ltp`(L@$9q z)ef=QaRiL6zDB)k5;aO(Z*a(~bcV39nDap=*$P!VA0FY7gu4?4xbm?SMM3T+7e(7d zMzM(uojfXvB1?bMz@bHOEQzMKxCX-PT2upXzKSqN!P8c%cCC_5-z|fp^Hlf5$xIGVuiQPVDj>VC-e@*ymbQOcj1jH1;=B1c+QdXAJo z8_-EbR2T5G6bA0?fDXYp*?bm#hgKnQ6s31uBZN*@7DY>u0N({Ts{LhwWM5R7)pn|- zBDL;;@0!!=STilT1hs2#eH3sZ8GxW;nfNO~G^95F;4QwyHVf;-8@;WqjCp+;MH-ER z#ZZAq#=+EDDcV$soxn~p#(~|r+mta>y46rCW0>9J*->_vZai#@0&0;PY#7wpT!p0B z*<278n35OCWSE{z6W?GPEEN1i;7epA4w9lgFr7MvdaKBk@qr11hLj&&z5K{FFMIe~ z0>0N06WCG+kE^WdQ&0wutkAcl7o0^P5(-k5oC|B3I6eu>@EhiUZ?B<{wI8b*3hl^E zf;RqY4gD32?Ec`_5231+@cyX_)WfYt(VpENr!n>qxk`W*tCS~@;EvU^}F zhu~)()M1K4(Ce82yG}pO16SJX#L%EOY62QQR`yx`qM`fjIH;yH$ ztx8#Xa=o$wv??tlE4;BS^*7_>YcmZp`~I+#n%q)*zk+>f1KpkJzfMzds$6wy!p>9E z#2Eg=HHWR8xrb0GresH;?9D{!RRm3oAAOTXogYx{8A+T5=hB08mSQD`ItG(z1VZjN zRs^k^ps5x?JD$Q>ZCVtns8F48Rd^6rGok(mX1N^1F6XS)dtWik?O5Ke>aC^PqL1;f|bxgmt%A!VWIb{ITD!2TLe z@fa|z+tS>wjlp+?kB-Fj2E7Fj^e9#?pR`P+#GWZkw1*wksBk?I-XS^1wiW`CZkk1n zlLmYzG6JIXM*I@&|$^nI+v7WXx z#BG^KkWrI^tBQ(ABBAFIvFj%TI}L5is$%S^Dyn13*fZC+Whud!mea_=hB_Ooikif( z1HqX4xIK`C$cLbhPm!B8m6R!CS_Y1V!vP-99k-nU9&Ycsfum$hcIFDpEJCkLvw8+J zV^RePN+LBJ97XD&U7PYVk0_~HWGCI^G-x45?htXA?QM~I`lVH(i!*noX z^_vx2SLx#exl-QL5Cr5eHmwx(u1KDdQ2(MhYiEizO=%jlBWPr++r%YDwl|+hXp2D? zsc>3$Zu~Z(Z6>xuGpdBPMULl4+7EtaKzTHjL_+gQe5C)NW!;>6n6{;48yw{zasZNe zEE#7~OfHl1*u;s3M!Jm3yQBRU08Tv`;=)**;=g+JmO;rcG=d8y?X_PM5sql*%|^;~WpK4%<_B7%@);MGqq8X^zYhgC;e! z-LhvG+;-D#TEjcyNNUi66~@~Vs9=n%0u^>v03U0RbeppWUF>G$)|&9|q(zgs+{8Nc^ky+?AK+B4qszQ4>8YblR zHtO*OM>Akv+$bvcu}Oi3BrGCVE`*T zo|AH(jNNP>iBzCi&-dL~;YW}zS*!ZJyZ0GsbwT!<3|*JQ8D+-RR~P%qWax$!TwTAH z`G_({va-6#dhA*k8L8B5aO_)hH?4EmjsyDAO1CL}6I$tpXrIoOwYwBYP}$3q+K3jh z2EJ9Zz!FV=hQjx2e37vrhm4^wa@|Z0N5Ee*ki%ek+CtR8k`OyFE{sp0e0da|BlETF zK}R(ucdAtduMNuW8_pv_v}ekIFCjp10D$d^2^gi*rjSAI6_kNlNC0iLnKm`U!Wqtt zjo88*j=ArVCqV$NC6ihZ)Uk6FX`G}+FZ(K$*$TXL2Tf|MsJj&+?MWzkazGM1N+Cxr zXJxIQ*8y;IL&S}xoTk@bE9DU5?wH7=kA?>ZH`0dSS~K7n8dO9eP{BMy5AzJ!+8CvM zTj$ccv_2aliM}K9!W?ZPYm8jLGJzR`}=8QsTT}^de`wG3D&07YHfA3&s+A&CG*EZNl8sLDL zaT=1s;Tqu5k{MRe#0_X~^^h{oSnLO7(2JIl1ZB!fTAHXsp%Ok zY$-H?e%Fv?ti{Gu%>YA}-BO*!_SMBkaUohU6D+WLTcHt4rlAu}+MVkT<7fqXgil%z zK8KxsN!!@AWK?uSvqD4$HW|HRJ$!*=oR!%OZ-2(+_GGyoQDy|9GOO#ddueW00kV;X z6cqW;EOOEoH!M3-uoLtW5kh!xI^a2RTg&okfYCTxEi&xfnixyn9-W#h{3OkeZ=$t0 z2c0xBq>%`jV5w7CE)-i2W@JYv)-=a6#*oED_Hnbzdo!J5VB28icn6Z;*e#xxLxT~A z$sd-bshWf4#ONjuo5%9RfKIdlf;$!-Og*tH>hOJ%U!+@S!~l`AQMQjmjWY)vS1nmF z2)cbV9(Aa@YlJ{6JuQKN%rA%VD#Z4Xc#fynd8Kt(c9IKq$CvL@2DgMzwJOfmoc+$s zr%~K;3Z_~>MkqolV$X5!_cFwDBaiS%^q9m2pQ5OvG!qx26q;DwR9|LWiE?ni--=Sh8tr)Uc~GVru~ z@{Db=($z~QWJ26+!3^1LdW_w+($(r=aybmzWeF@Biq{&Vt%nGu>M?fPWOqMG^CaSY z#FQIj*@vkc(&mZpX`UEVj>JZl6HlgR7!iaJ0S9Xw%l@Gc40IHd_~6Koi0#!}irJb7 z4RcLRM|@Sa;3T#!zA;J%%u|Wd^*Wn6j-)3YF`ye;S2ig>YnVo@9)WZ?CY8XPlpMl6 z7)A0&rz{-Mt)}E6ipL8Q$sb>+EsJX+`Qsx*8ijt4@tLd^K#$@N!DnLYKfNuOH&+yY z^tuMp(@vzw;R!EXIl1*=#=XW>ri8x zd<-=-6-=!l?Bka!@^S2tkL{X#EN5X?MclDq)}ieFSm>}>LV04*>#u?`bMz4rc1c9$ni)j#d(nCNTJDm<6o(pgQOvQH z?beY3Ol&i^$BH?GZcniOJY8j*3QU$OBIuTuYHw!txcJ}^rAUJWg(6lekRJ5dqn9C} zCP9E7La=%n-Gj1TZ-5R*;ByV>o;=Bun)))L8P$R+8FzFB}0fvs42E zak3f)hYQcGEv*N}GJzS7o+{N(S+L(Cd8j8E;+gV4nAsKtOxtC%?v7;QJ334&AJ*#W!M7>eMD5$X2)7~40}(@5OoMJ@ z(N;!PJQcuSxlV7V6+_@FjI{h816nhvhexz#LJuhakMxi*sVlg)L~VytU?Si$L&RZ2 z;2Sf{?rBP=6hpMsylXuaJ6?%Y%a+Ho5?W&TBd`viISo&PvQOs`L>QKI$2J0DfzJfV zp+uW&z5ClwZ@yc$ds;9D%wR*Tw_sIMwk;S75&>bsnD@%yl)-h1g7vYTxV^1V9F>DJ zGYMh4vaoL@_ZmraS&5Po;kJdiiga7GAD}opiY3Yg=3;JRscAcQ(l)V0N+6%gBESzF zxLt2kDnhDOeE`?#0|e*;?7BlnSu)eepRZi9ENpDW05|%}m zE@~{NU^sLqOH}uaT!x@S;4x5qD!0{eq}=N;vC@Q4yQgwvFwm3&23myOG+YZwH7;<2HCwXJF)sUCjuF^rlbn(QP&Y2hO(3?6c*gs+)z9F{}JqOjZuOez&- zl_gzuwBexFxnDRc9SUX1+QKLzevDTq!a*GhSl-}(TvXadO=7Y~CDw&%CH5GwlB5y~ z!qypCVWED;P*F)GR*BM*>tkpd2prpqVY}K}MIuKD3Is&?(ygTpi0A)0KmI`1zn#&7 zu2@HEaqR+jCR~hy1|#F!Bj~rOz`c6{22)bhY!=LIrs4=$ZS8637D{4MN*V|{`P7i` zEtKr(O2H5u;Ys|dr=4~mfJHOUaui7sN6C^>bS72Xz9$ZrWth-W)vNQ33gc7~ zHN#Cq53ED*@R6P?$(}2zED7YQv76*6C&e3J2Og(HX+gsnxx&uxtf4!O7;@S(4wSq- zj4!r>$Nn_~#a1DB#JXR^5FGnQ!c=m!HB>7iYQRp_ zrj~rWo?0U5X0$N1qy_5KKiS>J7;n@|EX8d3gZY2wH zm6C6Iu&ZK;YTp)AiaOaHKah+dAqcKxN?qo1A4KgtEmu&!jxh0-yV7=}&5{e%9t9pl zacnH%v9B>%%%^oEg;e+bgGgl;TH8i*$+)z}1?9 zPHMCT2IfUYN(Qz|fV{{M@x(PVc4v}|ui`LSe87N2R@M^P(>?H=V`1chy_H^B8Ij_- zel;y)$TH9k-x*Qi#Xuptr)qO%Mhqh8z|mTE;tp+dsy27OBeU(XUxW{AC1=yNBn4Pf zB|%caQFZ3>QqzudTO!*4W+kOvRfv%2JxtF^YhGGp%igLrHG1vo9`&e^XkJL6Qxc$y zid$*wr&Sp!&|`RQM8hiwKu*RoTF?ZQG7>c1P>QWmx@xtEU>QBcL%Ur=w8MpIh^{p` zYs=>5ecDYBTT;+lJFsSV*_x4PEht;#z&>cUbN^3b9}4l4B<8xecOQn%tm%<)A+J%X znKD?Ra>W`4F1pMBcR(1fFNE^~SKy#F70Da0ZjJo*$rbKQ`bhaa8C`j#47OvbIvb(j zHjw6yT5DAsR#1F1%G0_UO=pjZX(J6%)WF8o1`tP%FU-8f4UdHxqB(&`4l?cAnE{pb zF;arOg<;48RMMU1G&X2Pph{T-qf20|5&p5$TnI3rOD0JS;DxMr$@IXqu6G)Vb!5}( zHI>Ehsu_hiqO5&-U4f`e30)>gIo$8A-wTht3s)H?$C zq6oVmW(Z`jRvKrlUU4TbD`ZvN{(wQEqvpdv-1Q*LKMvI+K4)iU)EK5!34%ff?hdao z)3K~2jlCBCjfPe9#1exBv5#>oGY=Y)D=PtLE_wALd}3YlSmH^@@J-@Lh76$_3vmI; zYe9j|j2x`8u5?{i$3ho}%yM2u~>nOE;uW8hYxaJa->}130x6fCH*S-EWKLJBL?eRLOFx8_2nA<&V5$hg6d) znYNWp8X^!7Q2yJvCnC}qO(tUn7zd&Uj{{K};IkfRrdqZ2sgzrZX~(6uj>_Z~WN}o$ z;b)niokxV30RcvO%JPUgFCS1w9|Hre6+jFS|0Z4J!!1NXYb1T4QoVp@l%5%;K4c(l z4FsKT|EMZqN)f=B0|_*CN)D}r={|iIq_L1xL52Y(+)?6nOEM#5n;Dj|K%)`UhOgad zL?VZfxGOpBkf6fQNFIr}=kksPD_len9;U>v6yc%qfiWI2V!)_}(J;~glNIHO1usQ?X5rApxB?l`r0-qdpQrFM{_+T@8Mw0&)Ka*=A$}Se2l6Sfa(Q zP2`byZ3^_>tZAdEXo{cMAkw^S&{RZOFzYAygxqaE99T`|Qm?6^;&kL1H`{ir4Rmd2 ze`r_6*GR9_f+GyToGAxn;~Q;T0(ZUO)W^EpPouOW$QBkBgwo8m(1;@z_WEPR2`QhooV8$_3jNMH(|<3G&eE5+LI`LO@@b?xL;jK*6T`oPXRh3 zX-4VSE$n@TioC02s#%S9*YhiJQT*(3>7>R*V@L zcAEC^lAQH;*r_gGq z@ExPRE(L|Mf}h(d8oSQS6`;QD+#(*Ok7sdm@T&N+LP$t1&7*xh+a}4KaL7aHhl~&Q zL&jr_f)XdB^Z=xE!>V$h5mLHs^IF_n0mu1}fL;wKf{YT6*k)wb+I<#%ESVzT!GaN% zBpa4@DH&TDv4dogJaBY5VAX6b&S0 zZ>$pSY>9Tww8x3`9G2@qiR085wh=`FJ=-Q`6pl%X7}#OY+B^rNYuV*VuhF&m`E-M% zz&k_r))>Q`74i@0PkIPjPQpuM-O2Z_e!`bn;97U&fPgo#2n&frhNX`(eaO#bNv>@{ zSe+VHpq!T5EJ^pUv)`T6y4OxcG;g|7&<`yM^(JEW#;TrI)vBI4E>?CVlV?>?jpWBE zQBt-ocr8b44cPJRN0yEyuc%9$=X9w7@c=cNHaX~bVG#&>KV-+6y+Z0odNI+}k+ALv zh8~r@70?7`222@xG@N$i+U%td^+Tr>D6VU=@z4faJ+$!%1kww>$TTxDm+NX^SfXQL z4J1!-gZ?~#r5o$CI^=($x(FVh_*~u2->SyZl+ z?Bo&f60jQVfUGRx)n+Do|Es0s8DG_uzyb{cZ{`-n(~N`26YPoscLwNXY~Dpf5ntL; z3!)6;keZDpnxME0w=<<-y}MxW-by#3ZF?@0fybR~l`P#+>1Ae!97G8L*h-3pyc4}l zUlK8t%k1a#86HTmm12EbZ3!Z7bZjm=UFv6DuJalb>IlpQ6Dr*}y?Y^d6f5B|?8#)? zHlkH=IK|Fa2aF@`ib`t^kwPAcbqi3w;M*v#3HXN9W_;<8Q3yYVc^>ml7oI9#ag7Bj zEaM_e$ucNu!s1E7f=3g3^u`X=Wf>sbkh~X}7iP=R)Qa`zTeWePle0w~7r8U&b__N_ z?voXF9zX?Gvg~QfCh$dx;Euvfpu0=Mw7@FXZ&~?@4dCI?xW`RnWrwg9RE@Pzv~`Xq zk(0e3{g}_GKujQtYdp+E^?bXMCM@JSEo|Fd; zxwW^IklXRS*3NZG)w?)pZ9}zQYIcRpj6(f)6whZso7`|#oRaMVG#_cflwdn>%M4c+ z9u{rI9yNQpD+6d0gp!$glzA#qLN;fNt)&p9&?dzskLdHBmaR>1D`iVp8ki(u2f_+* zo|a%B9C4nuHRn|r?%BFPqWcRZnw@z!L=Cov!rsFRjD^rOnw;o$i`)C*`iG&;tPJSO zvDz4ft5qA-8XFxuuf;;OF;=UMEh%&NSGpMwW2&un%?a6UrWaU2_DMUZW@o{u=v4;Drr>sua4&4Xx|_%h-- zvVwTD;t@&_0GArQI|fo-u>gW?HSw2|fg*Tb5G_3ds;Gld3MWrVV4@gyf*q~6gfbnF zR$NH)v>UiSk!XT#DhjK^91AisPk3#E^~e0!j&FydeLW>6s+wT-)XY?5cLjoN1%S$~ zV4#t>8LmW8K^3Z~6T_()A>skXS-M?n#%Av@3RouMfMgg7Uh;K*ijr#EX{46 zr9|r|u}$@I{p4R*KGDTAO3?zu@<4Gm-79E($g44}2G)ZLvt=#gQO`_g>9blWL-7UEy_BEipF4r3H{!1a=6P!~hI|!odSKMZRx>YAA<5+uGEMQz(CLh2wVs z{}%ra+FpjXGG(E<@MDWQHoG*X$!kN=OY+*p_9*`Tk(W7%G_GQ@(`$^!R18k54T|y3 zx5N2P6?;agEsMRjOo1&UTEm7rC3XK3!2hUfoqczaq*1!^DPj&FH7`xXSEqXnq$kg4-Qm%g415Nr%8O^qUbzWQ+U z#EtsPii^jNVk9O>3)O3qU<8;{rabY631HiVSLxMw5CkjXl{*UEuClubk}rfdlw~Ka zkutg#MN5`yEtjIFv|#!DQ;F^*PtnVo(PN*$HPUsUZXy4xe4k(abR%B~l+eLy)=9Q~N zf-MXBNWwGKL{P1meOq5NEa$uvodLmM*|n|8yWQ2?jFe3460F+*xP;*xXD!=&?@{QA6X!fOP1>T<0ZM~eJF6DE zCi}sTuHEFEgd$p;Dc2(-G|LGW$JH`X*g}vRg@ag}G=W}dS%ABD@J5mI=+T_|z%l^0 z)3(jzxrpW7H3Lv@(FYqezS^b42RmWVakIN-K4XobEupfP1pGc!FjC7Ru!`>#yT$~s z<%hr@M^bTw%)l1#d2%2OO$fKL6Ap@REOEDEC;HT0ZI59L&hHS;f=YhqYnicj zAqShamKl-0s!ik0NRp8>wKPi+M@y#amdvP7`Qqg0j{qSDfL5218|*u^8_lv1xlT|8 zinLg?0)U)^3a=alx3q_|X=Soq@?=U7i;Oi?NoF1*ybtF(u9ZLr-~FC8?FsJwfc~T? zC(4HJ(o?^dh}4y!4OUoA*-Z{9=^W6XOn>*Il-yTEos~O5UBxgwUQvBMgeaSNZTA}q z8mg6xoyP)?V>Tm#(;I4cD;PZ3Y^u@?BrH;Zw2&}9_-T8Ah~Ysmq1*CW4o8^%Ljb5+ zRn>-Yn0-Xftc-ik$RebgEWSfXHBf|iyTTPl$%svgNy=I)2>piRsI{t2;6Me`M{SiS zlIBx5F~XIJV5gd$i{3d&EfDtI-+p@Y-Et|~=pLgGfaxo-pZG<$vJ(Ltij|!W(2R{l zJX+bw3KKA~qEvR$4Y2I*ZA(abloS~%S1!b7`I|wjx?1x-2AOBrmm1l*216fzu` zYmbvfUAqO{VC^@pO1qsh{RF^KBthTsI;R`ZC|$>H6z;#`Z^f>jagV&QKmYjt$Ddb3$o0Q( zKHh)7yyN`d;D_&v$!&l7xZ2;Vf0Wghy2)79g%;p&TmM+%=ghRz zPrIBTSrG-lzWscCf(|pwkK!$$>%YgU)hDz0Ye+xvr0yXxAo4VHOlzm3oAqA1;!u$ZsNl`}z)~J~@-_csG@FPy0U zg)O;M+$bl}&wx>=cdw-E^CsfV_}ZI@)i)s@y@~MnO&FKVI`<~9i7yL)LLq>{`2hg= z{T|$h;agBYdT{gj!JTd<(bOMYDY6A+DWGf97SQuFiUHB{;0pHq`fl;(S66Azy`7)m zzq$N;e$xySsjP@zdgGy6;qi*t0U>%WERcxx+jnos62aae2yrRO-cTY`G!t{Qy9}sA zXH<$W9Ba3BH}y|0C(>gmrb{TMs_L0*UUye&F_aI6bqx3L=k@g|8BQYUrvivO=7o4z zKTi7O?Opom2fOo}^?i;?iU_qFepVhEiTYVtDk$}y6)2qrV2f+f_5yN!W(Xo-pG>pR zd^O(e>vyl=W<^6DT|>f(Z&5==qaNV?WNi9kz4wQiNq{tV2-WHk>*pGTVDJ55R01e% zsfHAG4{(2WSrY2MKQP<@wf2XM#yZ6PWqt^Ee?)5>Ac=$IGkXgYcJTeFW_Doj{b3zk z;3U8SPW~|G!?E{AW+{N&oE;DcAK?DrR-7CM!vbd~6ngDj$l*$|+{)8vtxG!Lg(!^6&< zZzGNdK5Ah(4>@kV&rh6~_AJJQDU#q7U&FiZwI*S1bN6YUb`Z|RZ&Y}(uC$kkp!9=C z-sU3yMUhRZ=tc*%bhVv3T%uGae~(`^N)F3Xdfr<1OQi%pO4VukR@w|*sX)$HyPzF` zo325pc%$SPBow~$-S|Cx%)uR&WQ^#>Nm93B_8qF5Dx(gtF-1t%IKiTqZu>>EIzAyO zV&+OK<-y}I=#N1I4fP8c-NMR$#m`)}6}|m&LWoPyqd$?p|6F{cSV(vW=kNtSd+gRc zS|oM@V%lV^LZT*{yHnqmu*e(DKb3@UORpi!1NT_16KWl;=8g=)voFf*_9BPBY~CLg zQ4QP(;g}9Ey`*KOC>lc$<7T5ubDGs&IK;tt24s7)PBS` z`x6_p48n}DobDATF$vrOf|C|AMmG=wQBAO^Y{$Mj=#Mc$(GU0hB%h|C}Pb{LI)?4+ehu z$9@2A9dbNt(yAk+<-Bw>j@F$20{)J~y@DTHzU3_+LaDL=aXpPx#6#?-NXI?oR?2YU z`yLw$DPTL9@KkwRs;V-R?by8gH+RtchYIs|-xD~SF%GFS&r4G034`aRI8mae5Glh6 z`8AEdyHDjmX|+asB)OO0KLWq2;9AswypDu)Ah|`3nKw@|QR3=1IM$@7dFPr`hmiyM zo+mDlGmgg2z(*0C;Zu9k5;BZ({T7P<9rAMxr`iZv#awXJ7hsH?q<9gxePuO-2j@-P^{8XsHK`V)p(!LMlQsJia@GfuY+8xAR3M3OASs<$i z)%uwpwyZcIec*9w*Gt8a#uV0(S{c-ldy=ykW(3=D^N}v=vDPq-s?$JLy@+NNfh!X? zc*z;LuaLCi9dh_6yhzl9wzKO~(EK+t8HqPRvZaxvc)eIPU?BJ0qoJlO*(q1xhgm`I zahM;#0aN7iQ|0M7nT~b;`bp5BkG>fQfo;|z?%I;IC|lALfIgJekuG7)Q@s(xNC-N< z%N=oQUo7IAG)NlNDXn6sv~OS@xJK0DdWP>m!aAyLHc;B^4ktms$bS&b3$fcA>r9PP@IAe=8YLrj>U=^457rzdj6gR@U8~MGPx75>J;(wWN@%TaE2~2IZOw{i^*7YN~ zvnh1_B=)y2No$AnsdfVLi8s{i?4)Cjl;&;! zHIP~DCZx7<%>5^sT_IRzo#G^SAa2a(HZ@SO#6axJ`19Iz_u^i@60 zXBpRQmh14*ifW?Se81rPOsWz)UUIut3~qLGLH!yK*F0pMSA1EXHoOOKQ;s6sE)-Q;NhZ zl#3?3dlfWT2Txg@Re1Fp>=N|xGP=G6jI%|lo{9S_BHYekbWb1LN;m4hpBX07--9W8 z{`d?nj}-OcDe>Z@17qb{OS=ZKYhL7tS5fK~QdBLgpme)o&^BSYlVt@Ly3)+PODb|^ zP9^*2w9rL9O9CcW(2Xug5AX)Ce=R*1IGxBj!5mJ%E2J|-1V{7{O(;z!`i;a9IKl8Lp^8cwex4xr^TbfK&YF+-haH&zw)K*U%n-2 zb3h_z#@#t2OXgbqq4nbgb5hj%+hbcow_E5`BFpK%zxG5_`xxQK z-kr{iiaSofJ+zNU(w>id<7Pg|Hmt`HnNxav;`5vIxNZNOrPW<)jlFaI8@L7ecX8Jt zpV3<-6g|tDMH-uj8P7)o*(lPw+Xd~E(Xx}M>Ge6~jZb;EeE@km-KZ>t7uwLPU0pS` zD6mZP=fmI$K2uFIRbj#+@r@@bFNr2}hkw8JB6h7@zPl|KJ5YhhC-xYxp;@k=`(6XH zw}T^95%)v-x(q&8-E9ujx3s$~bIrR+ugaf-^pQof6UMN zsw0~Bjrc{@!}K}l83^rfJwM@%?zWqn={C$Pci?r zj~hxX+3H6BX6=<0moBG4hM;Ubkz@R;;~sQ?e0S&7Dd6Oc^kL;|+@? z&&?`asRaRl%~4Q(q&b_Y%eKp7B+)%N_;Ta?^$l&)X^A+>J-YQq%5~X8)J(In%?#dU z=)Bg?{=A2I=N?X(UJX4B2jus#KZpBPDV(FFZk#mD4|(NRXyo#~78=%V^0(NhK1IU7 z=`t?P_4(vhrH_$-ovz6a3N{qM4xC7& zwRtUShuOv!p2o~w?ynPhLV6;O7-5HRx>HeW-ADr$4@S@2w3gCLYL!2hRQClpLFX(- zq}mzx9erzeeCov=j+Q>jHhs|;7V|FS*;Xs6+NWr3(9VNss^OUz;-$>Y^V$-zkWEZn z+NVd})=0zhCKppW+T5RFID0lq+DdCp564Ky`S~N8N<}vE$NYjZbHjH%ua{fper?Q8 zk=T58IJru+>X@}eraaIj1*Jh1yYg{?Z*#U1duuIg3JRXXom2UIpBB035uETO-JWF69!s68name$FUH)AOv*1TXFi z?htxjw6qg+2eqwNfmjz?7e#Zt<}PnT)^)Ka&u_UP-NrBU4OIL&IVC#TAG|U z!ha%|&^*qx(D32D^31?eGkQ9W=s|?jj_pscC9|77AK+4}1CKO#oI*p&zNIj2tLV)_ zN`$3dSPK3up}Sts&tA3bL( zM4p+U5cmu-!NQPJ2-*kMi-W1)E|xdRuMNm0IJ1r;ex!E5&mMhrE{I0$BJ2dqU@lKH zz*bF6)7f1@Ei4$NQX}h`+8nL0+!aFQqX+~+{dlv20F&xpqN+`doCKwmu2I#-ZiFjk zg&|;-s-d4{&vFz=;+5nKb}T%lm_I_Vw6V$SW9C$s;c2Zrww{U1U5r_Y7pVfK zJ>T0E5uE#}FG`3K5u=`zhr5?ClNVsbd-1(>K8P)ya_nWTSI|Wa(R=~5n!t*Qj+4Wq zlXGkpC!3Qra9Dk%dL$xeL40Z2gQ^~x9cybZPBMN!~?G{G*_3=TaW@*Qd`v83$B z&NlUspTAW@)?m-2>Xg(=DX12hO7`tMJRzBW!M7T_iVgXa#8x#I#u!t-$3``YtUTwB zbAX&7@=$y*-+#`u+$js#8BFh)&^`!G91EZ`DC28fy(<#(KO7${iz72EEysO#a>d7B zJ}M)2DYBSHQc^M5%pr~a)WYyi!DYi}D#vgPMHzd{hOxOV}O zQ~9dQT8!tymfh_J+;+q6nTzSg!k{HuO|&Em6m3t>uiwlfS$Tr43?-@T^n92eOCqcC z6_F=iC;sx^|Gc?A`8;3UFP67YPQ|o2J^Amy{^>7YzWnt3+2r%=dT}{h`#((B`A>TIZaY=e=H$QL&DZPe`TssWd47KW{_T^~W-8?NhmWiI z9DlKze_Y(oZ|1k__jjx1)oOP0;mhozt3yT#Sb?8&K|>gK<~v!43th4op@KQF@MC%2z&KFn8s z{Z3Eb&OhGFF8;n-6*INdrjcFv!~OdAyZQa=<@(~+`NePZ%kP$}XUp5mr?*$v^Y7=& zo4H@pC#UDH&Yr#b{`BPM)$I2E_4&Ier$7HXKe?W*uKWW|mLES(maE0p;`ZcjKKt#& z|Nq+m`KQ@>?O(aPJ^A?Q_9D#SWO0AePHp$U{8##q{5oG;{kq=$1kaeByk4H%FRpGE z9~T$1+x5xa{ruCVUwHri&1!^aUHTQjSkEt~eq>)3x8JR17n_Be{B}0^^=xwefBY7S zZu8eyVf}Qcw?E17qmuUY*VP~J5{$DqhtvuWO*G^m8p81C~4gUB44PWxp zU-%Q~kC2--#_!tfL%*5x$=!T);ZM=xdOm@J=1+zi|Io$t?Ecq#zunAyX@nxD-t@6X~(@6W!h7VEhe`_q#T zpRRvo>3UOF23qTuU|W{L*+~n7s6|arx-p-3+snnpJS>S3PWmS%mRR_+6aTokoL&GM_#<69F%|xg8!7&rJQyyl@7RZMGPXZH zW1mVL3>6Lr_l3QgsHu72^K^1LjQh_){r(68hD z?d-;X=KELw*!=X#t7s8sd4F-y>qy&$A6DVtveEs&{}pD|`W^Hm{g1zV@EUG6hm$bM z=E>>n)Baz=D?2}qoB6E2dUQB?%MaWA_piTSU(P@Gsz2!He+31sntlPsAA3GL_Dy`M zRC0K#=sNP$wtwnGPMdDCu7BQN*oPLoODuLXwbo@Ww)LwRPV}z}KbEcur|$0F|63?G z4J$eech7gT&;C?il0A71d*UYxpV`gW9-3+QJ4Y@$gwP1}T?g!IGMO-b|sD!pTWgDL6Vj;-$m zZkV*g^n_Bo>G|<>TZx(lyugc8_@}>g&z}u)Aew0#wrnE_jh;FkB}{mg+H7P&c`-gx z7Q!Yy_OuA?=NZ>l^eT0`ww9BIA6~tHwKan@+`!5@J*;eFWn5WdyT=?H7j`LYavlsu zNpIV5RyK3fdfKMv_Ua$+U~X-c^z|AA-Nf0oW;eTuztX+JP9L1}=kesc7*5XXU*gFT zQyWi?--Rw{)a}U$8oAl(W-E?7IJUsKF;f}OjcLPC>6dn*+WwYJEbUKk-@ww^-O`?4 zy`TSciAN`D(MAhcT#s3~#U0l6brj0y!_rD3l*%8a0GWrSmD{EDhr<=VpAKBwHlA8L zXuF9&3(V3|ZRd7Ndv}A%&NXpeO^1ip1J3lizIh?yseL{y?VA@euC3Y}&CS~SmDW;% z!rQIwBp7uZrikLvzjS~VCc+9CP6xmW(LdQ+!^iHLd;G3-{>(&B(G99*V%SUf-A}M* z-JoeEl584i8m&+mc6Y}gj48ayPlVkK!fv<|NgxHCk%Jjon2|Oan4*CG@*5Pl%UDof zlDqYY`jR58zI0-K#skN4>Z=PHbWD963$FvLeeBYP3u{IB5JU#HDE`adNMlWu4k_jH@txoDKsyu`@Ao76lZZDT9 zDW;%YR#Cd`#%a5Su-$N@1W?Z4ETVLY=dyz>Q+P*OoiU>lO4n^XAKN{H``>E;m8o^r zfXeSW;+O3b2U1BETkVPWPDQ;Sx)3a1uY;wPAnq=LE2CLu2rw?1*ogiGyvBIwg3b#O zU!&SwoeQo@^jvCqkH;qp-_s1Ly|IPwkWRZ1)vmnlzkN|3F6tlEFU-Z_ve$(DuWx2o z{kQyBFBkXgeo5McgBLR11~PyUP}<#gG|D~tp3!pTp7A%BIr26rV&W?zdV|v`_;qr% ziA=ahHF}yrX~Vbi=e0hzqU6Nx#^LJtwNUt@pYjq zTXz}OS#WMXdRDDhg%K*~0V;?Gob@lkWuammWG~W^?V%l~`ss^yir+L*@f$}Kzuo%l)Ui&NGDltvN8W>o z!3>xP!)bnc;4L0_Kw88dp=}0^Y>P}uLjcgBE2pMhoy4l4cAW;UXHNk4J1Q&y>bMyk^u98CxI< zjT;e#U}UOqnNMOipWQ+Y7fpE0n(%*r`U)0uFyV5f6 zcz+pz@_Gntt=H>xXiH)6C%|Gx<-dqW<(HUG@{#~4lt6#f36L@|p+tW>E$XILV$y>c zyjiTnodigWCwyB?M*@efKRXCans`sBM>_hIK(~{$9+P+D`6FG&LLl_OjK9iH1JRb-R1S}gusN=(+>WwjhRp*9AGydr0vFm z8K+q@jyUi%nsGK6G8Y+UTnS(uJf(ORBbI15SImzueugPUGj5%NWd;*Tlw%FKM5;xE zyCepwK1uz z)zOE3fa}l@g$aZAiaq( z@YW4x-^57Hb|<%;iIAS$c1bswl^K;FWo|niXNM7D{DoNUUnG#ZV_-wnGxJ6 zB5IO|T62u3>4fq)!b@MkMDW3sSj@!Ifl&B5}-Tl@b&HF|IG*iN5jy#F(b9Y|qK0XosM~nxwlW zD{Ks#?)DlBy@FC6bDvpa;`+01UBV~GM&^_6`USj#BpFSqJ`*IqOAKnvHLRTN9=|*P zUmNawv+AZ+bR$kdwe!zqWNE*~ENv*2qfS+^O}!imiAgr!;JKvBH$;gb<3JI$)Py9> zZ4sX09{r1okA8{jqKlLP3d&NUxL?Nw8hteG#4qI0poz>_p2VQy9$D9Pq|cCl4_5Z_X6G%zl-2vP*CTmIOsvV zCv7C1z%2x~o*PbRIG{OhuL4u^G6#*iY$;y_>5!FOA>J@)Z>ad$WS;FbIR z;&Q(Iyv@!3;@HudBM(tq9+z67r(IP}aLro|)yWy}p7qj798>w^AY{5q= z>o)>rLz5w;+CJB0mK9<)-BgC$@*TaFC1r(j0QdG=(wF#gjiy8DY;9$e5hGGmaAgB_Z1h03LfNdM>Qv~R0gtXLSZ~B4dA}AIwcJxhXJL*xSWE`0x>Jm zq6@2w6`MUf3FE@Tpp_jBTA`>rAP;MEg82o+!W%#>>|M+i5*{#fRvZzF7R7=V5Q~UT zL^JGOsK(HbNkC~d$=LIPp~p%Ih8+KLZe6bc!<=#nFNaG4Fs(8yNXL|UJ3!j~lzBIP za71@Z%6ux3T?7})SR#AK>^ZiMvjml>|LhR-Z&g(0ZFXGTx`cm-*s3{U@e<`pehLCF z+&Cc?L(>@{h9>tBVrZR{mrnE5xN-j>@!q4g5C9>Qs}iEsm{A`xfp!`7N7uC!^0mT2 z5Rj?Xaz~r^x7>KjImyDq*o{ybmvfPG091I!LV~vAATmkNcF{FS2!uLtB=1o~W~3OF z2>`SjPdS$CFvx@M+_-0wc*zF|4s**%4J{DNG#f0N02f{2kkK*#mlLfh5X`JL)&ikF z$~q+={GhTEio56trJ+Ae2OrOLEEW3eyHbpV{yLt(={<00?-2$F^Y}kk*tSqfU9>2 znWC9Sj=jAeCO6(X--c9Yp)p4=*0&#BaaRB;YeJz;p)zw+2vqI>DwFz-R1jaQ9BozP z)aXR63`@8}Pt5?8i5UP_C#A&BF$0RocteV)EVw3e{f`|1saRKwcZ(F&WL%KzGN%8q zWYlE0dc*I5?IKmsmAKA46o3kE2iY=$CHBXAQ#3IEy?1e9B~^oxCUWLiM$+15)b+yd z9c|asK=&$~9b}gr+^?rZIMHAsOXoF#0#9uiCx%@Bzumk(U5B-vjz8Bz8U+_rw> z;9x>2Esqrlx2OCOyb-jPHYIoM&MSBj zHx4mK6){MA1LiAkoQW4Mk&9p<3rNIdonCAqS!V#Sl6~+m(YsF)@ny^}l8)Bx4D8|^ z+h_-$ED}%d#Q2k2o&y&uAfPOvZQ^23@~Uluzc>4j4nh=i_(dbR1BajKvbn276U$Un z_ab@#gv=1o0zpSRm7rQ>8!vsw;d$Ovw$_9ldolLUh&>qoL-VG<1!B0|n&IE=)Ea~x4crUtEDgoT6>(Z<<5y}n+4;kGVv zWb84sB@1+$S}}dV(`ep3;AbO!3`IKokp!aAXJ4|Bq3Bbg$2x)8W0Sm!WWOV&JP=wa zwvQogL@SV_gLH)?j*gs0M`a*F2iZu9_|cgJ7YY$#yVP~!q!8;%SF*kW@imGWlzL8U6-vzd1e2;!BdHoBO;y?%`GBmKu&?ZST)Z; zOa+Y~An*hnUi4ICzo3b=joo`DlC28b+pk#of0vqEbij!|s!&CXbeJaBIzqCTOU$%^ zKwsAuVhcgYEC|M171F*29Rb)`(`yk%L(-j-<7kL9LKV1kCIiP7>5>9e-&O;T%`Pq! zk`yb0(kB5QD;^UW4yo9gH44IRy1H+`YwR}6w_Kv08*FEJM;xX$kv`nmqMXJp;h>0q zo504%H$$SniXGC5(alf>07xs)_zDOv=>ciAd};)B5bb6Z-6KL^W<;Z=793H~-D${- zDCP3fQ%Bfu2bY%!ysVG(c|i+k@Oi1@TbGw9;leJXE@~*r7S!%Zaf&=np?k9HatI%a z+$b=o-XItXaa490t$+@r$vcHata5mJOO&X2A&dyeM%XP3>*JwTnq-P`unLcq3d=T^ zg$pyDVl|E-MW$ZJq4BQV2;zpn=2(d+vAmiTH3|rt@idrpc`dWNn5l{aA`H8{hgiX~ zo3>p$Y6Xj(=Iz@NW_Modu*oIeF1P~o0XVS zB)|l9K*kX3lrwTDP#G+O^&JH&1X`kl-tAJNC|}``6!5QiU;IND;EObOL(XkMmN_@w zLC~z#R9TD3VjnHjvfYs!d;%k&?jEmzQ*%(l4HcuD{& zZj1egc(S1fS<=m3Qy@W#lH#=}j;-DKqXXS{d?S-yDlKm3}ovpX0SD;F?uV`c9mWb7rvWIl#vhRiSCX^gcikC&n zL_=p+(&IMf`CB$~Ad5@Xj-=~)<9)yl zUU4G#-o`MUiZ%7?z0wnuZS+&Q96y!B1coCkmO>|uCVe@Rnsu;O59S~vV?DBBsn%GF zfTIR8CjCW#h>vk%DIBsyJ*R(oLqwf z0Ns)bGYbK0!%c|-bS)CHeR#1;nMOY?C}x=(ouf!g1A@IvNEj^zmn_jryyf0SkL`K% z*fz+p?t<}+RR_E7^%Lv=z+9&9q5~S9-9x5I5@gfME_Y(7MdWQ?8vZAm5vdL5!ckojia3u zTd0iFg1fKw6kwa06Dfx?wQMn<_(Ywq*~Is~ZL$far-(bN&A_8YPF_dq6f(Cq zcBo2Y->?I22hs}7rYZoka90VCLgwUJz>=J6fnpTsg+?$6w)rOgw1S7_P>cUvj9mCZ zV^dYvceC1I2{mw>nq3!|GFV7VJE6v~Q0VB$^&Q9nL(Mj*<##`tMEZTfh3_)7%nS|>@ z=?t?o&CcqA%ROsK66;`HG&?<%;*lfX_K!Ix{G8Do^D0wv5y^VTH`WWll>jD1=tV6oPpC;|l&U5oaBe6nA2TIhM-$~K6gQh# zHLayiP!%1U<5yz!Bv7on$gIHPfW5^tDG@%nMz+LNB6S2n_eu%M$_Xytot*S&3;g4WT{AbZC#Mal-6h7?r!?8rrV$vJ z6fSYrnD!V76y}^dl71A=Dc|_?;B#uH&UNElEAAU6z`8yIFIK_EytpPGIav~4$G|2U zl_rP#qX63NriQd3i?NskieGIk;V0J$Mr9BOxSWE+B9dp2Tmq{pmCL96iVckRD8Imq zvtgjvwrO!KTfZOKb5o^CikO!xMS&tym+77Bh)RxFwdGtOG`ti0Ev1`_5XQQk z=7L3-r=T&su~EQ`$S-Shh{%HpR7XPdqtu;-3PohuQbpK> zEvcVsK%p>`qqP9BTTx1%*g@oi->uH6Y_X{aNmynn1oloP6v!mzcDOnzGC43jY!|V) z)ZFA~avJn1x*^9BJ24T@Q%>Zk%+?_-v;@K?utyrK^#)r6xWoj$N$8$Ch`P6|xx@4F2QsSxnB66<*?FKkG`wM$|Sv{D@#q1Zh?t+JaIeX@<)WM&U;MmNMl44W@a-t;2Q z>h%kF)wWmeKq}KT=>8SMs{}hKY|8XH;c4Dmz|h9lj{ASxW9ec=_jqaQ`g)sGXpHnp zYSAfgqZ)Qijxga^&;Py0THuB^B%`p2U8>k}sl5xHxHVIN$z)v;Wo$6QF*#^5#VRst zgT-!2Nk0|wE9T_2h$7_gU|<@=@{VOGc>5DhE@psEC_2MpUrRQxQfE7Z>5?6`$YiP9 zh%2~@MO5?>!rjB!iAt4xdZQP%n+FsVicPd4($?ZLtHU~>OCoN1al$O>AlxpN|CFG(k>kVdSO)^%Gz7Ls0j#VTgWk`lt>_o!G zNs0ehHjx?iE^!zMbFj`~MlIqUr@CXn(?(DPyQ z0>#Gh@RcXf!)czz`fyKRP#t3gklqw;atR^&$B)g*Vz#$`abHe0mI`{T0aiqJYLdh? z92vzX1yS7@yMHBF^NBAaG{3BZQrfA5sIVZ!z)aY5Pi-YoW$M~9Iz!xxG_-6YtPDrF zfxTle7)ha#VmuK8i`xX*x}08IMM9VoE_DG00h?vAw{_!%`$%Dk){b$NS|O7f_ZAej zV(a!vD`Y8RGcH;Lh9OK+1ZHx?uE6vh`T#p53SxOk_NEt;F=#yk?j8xRx3#?Q9i?4> zLN1$K$0cKLE&`?@N{Zd9Lhf%3TeX9hg$~R*!FIr-rYh}k2|l>5YK-gfu*pG9wz1bu z2Ric2-+q4e!>)pK1m;PR5U<0NUW?>igUi%G9+z$7>HE4L>E0ftdT>!~-_>D|uy9Ye z$gjZpekcZ!;~0cw9ef+()DBYtjB_KjBu(wzWG8C))8zT3wMm-J4RE@g<xl~pk z?-Fxz=*V(1LS&Oo11=Rwrv&|Qcs>-A}BB6`W&6+xR8ps!o zE(0+Q!~g}MRkuf_4AAO0qL(CElzpGrF|^q2=q6~EkNP78^-=K8Z{FnP#Bc1Ui#eVM zg$bzwlw5F+Wh27aehHPFigt^LGAyR9T30pFMJI5Q?)+i_pl5?LmGWpBkmyK$?tk#- zFpYR4;Ei~<2ZB4i+Zcj(yWN>PmLH@9MYZw9=2$LFpwi5C7{p#nJVo^(jdl-gfxGcv zjx}tQ$5s%O>4b>{b2@t7y@2L2vGyLF-8m)hCeng{@HyK`kp;1h25)cEE~fIcojz$~ zK@ZrQk^>`{B9?{ADflnK5GSyV)tCr?_|$hA!H<2Q)-AD|FmQtYAFbtBhu>W$rI35K zkcvHi&C$I9%Fw(jvRnhUk}O^%l>$-^$a=3*AnECMZKbS8+M-m)aE!EEoR9`Vb*xuQ zWi}BQX|u>yii8OjAY&x&V9PwHEXVLQy;BM2+;wn#P2^ub(EnjZ-D+8~43%_j zTa`dml=WCEbu*0K7NRe#+u%Ey6-bIkMw^@g@v$m>I%6AQMx{ zasd}%ArzbZ`-EeFGzCHqc59-*n4Ic|A|!;h23v;M7j8OWbkMB5v?tuL-95R+@k%(D zX{!h`4b*#?j;LiO8Ea1xl6;(pX8@Ei;5|-_zzZ5OJ&=-1QNKy0KBm0=Mjx8lc{F;PD4cOLgm!c6(L;* z3UAYrEC4Pem{@PIh0>ZjGE&*xq1|&0(k7v>gr0E4vSkL}ze2xcJAknD-9!+M0Bj#> z2m5q$R;!>)g)CwOWwONAgnv%Pc1r8?O@zjY$#T_{!I@%I_#WUJp~o|(XlCZ9WMl}J zIGqidohGd1Ty-QVq-bNA$PG0Tur3UDFU!#;3s8y)yUD^y?F)%6$I*&rQ1oKzT!ti( z!5#}gYYn!HaS2o|4*2eEe&%xfaCb@Q$u6ccC(o&jPK(}W6MIXV142o$6VqNODV^k$ zV>y)ZK4Yjwg9nf$5~M&h_F}qAk_=IQX-?@|37sa%$rO-E!*dRh-HRnERAVEr3h@TY z9GG1qQ04&zFrrEg`37tsO_=)XOjg}B7@8bTRi0qpW{kj_qw%?`0HDO1)> zNu~MmdU1C*`*1y<4Bf=~3G&@+ADkjb34OY0FJ8liExL`fF5#Sx z{dc}{PPfUpyDI0LZZ_RNMx4{;*k)An2vN9RT)lnw_Lq>T62dE+A8$Xbe(VPw765+v zE_SOQe*5Xh{~^q%9Z6i<-q*txJbQzzh0>Dl+)>L35uGK0_-GsRx>;UL*2~rXVtGr} z-oO1^oV^ie=i)!l&gFj&OYV_#nD@=%_Hyy@qd!%q|JlF2--Mu7{Xag>{Fpm2g?x2? zcEm1KEWDNO_b>MsUMBjauRYN4a{6OWZ|38?H1`gvnIjKV*wgjn@ zD0QurHKfi1u;yUB9F8_U`Q+>cJc1{mIRlMBrR)!ue)#YO)A;d+PZv3S>GbnHg3O*h zqQ>Fu+0nD7zB+s4==t^fbUj&I-S&(0`}`h^dQF;eoxdW75sAG>{0lv+O;$$aBj8b= z@BbKl)a5NkXm`Xc#tB{*4;Y{2#z(5SXwhGd_3IuO9%dMz3)|%Q zuL>-m+T@%k$A_lOUi#i2A&VoK{*C6wm*TT*b3z(LJV*CDu>n_|VEEwXy3*lr{Rq>c~eoZ5=Z_%9RM>A?pk;^k(Lkk1!vC zKUh=}54r6FlpG(qJph=vKL(eLc$!*v{qXu|A&oF6=2=2Kx@~z>YJ8-K7X1BLr4L2a zpEcb0$n^p1_ZW0=*!8B_^=lL3t8~37$-@JI*N1`YqpP#OvYk2(UJ1NDECvfJ=@+w! zz$C|q*9YMfthB#dcYSJnB=n)-`t5QO{fexgV8@5|heeKtO8VJsuZ7h3@cw9{d<4u> zWqfWE;7pDW?++-DmX+2oBnPnL!}|lPM{-#I%IN2g9bfAH$f_wXAitW&FG$?wpzc;y z($7k5GOLs0!~3I&`dQX9KUnik67!>}uKz?kZ521Zl=+dB(N|!6TlV18_z2|^j<1&c zz>klUUxoJv*heC#9<2<1w%q+eIEYk~U!g0F?}7VQ;r)SL>@1GpG6}Ps{1Or$bRSf* ze*^U>yT2wezDo96Xlu=`AKD)V@k=Fq70P6|@e%hG+`qDt{?prdMQVIW_f?(yEo8K@ z>xcIT@^ZA5@covyFf~4Gs%%mJiAwl+n~#1U|kx9b+e;XC?R`r;PN}V1?%JI>Mboc5=Gbn8kDsu zkdGWbnL_fx?k}N=0ZTQjYhwZVP<$k+CHDu?FjVqHC>~4Ff?RC*_XtnZA?w#|lID`* zBP~!ck*m)6^H`T3AIT?{WzOG$wgPAAx8(i+PkW{HlXgSkl^h@3AFcuYT**`7<%7j9 z7Ht_w#LS}>DS}VgL_JF)DVQl$$5vI^ZyPs0xIZi;+KNho&=a65| zjgKS(gZzp*_)4h_wM}w-SW+ipe=FHXYTI)pIX<{Qtd9CwR*IB``-8&=SdU^w+~2^* zUuk@7qOHaILsJUs8soEkA`LCt0P(Gq2P_^)G^6}x5Qxtqp(_*UW&=HrTps{WA0xhp zz(2WZHk%wDF+b2fR7pKMK2YIE9SJ5%J>vR3#MQZFc}b3sl*GgN%i_c@uzoF{=tD@q zfe)ybe0cR|Ie6em?J5?9RSTuCiRcc^4^=;uBHUi>@Ba8mA}|u!RWd&uf4w=pKbr2F z$Om`+2rZF8_g|$#60^s8vOhk&KhXWGD~-?bWs)7<9~#bIP6Nd<@ZNCnuS?Y-R=VFF z3V(E|@JANoY!UZ?;oOs?%>gocs7i$pZgW>B$A|Za27J)f(SLzRoE;zBA5MY$N>_59 zI=;}Q!%(~g`K^>_D?8pj-r@Zr>L-eZ`-9QXlx7tQHI%4?pWE%Vl^P%39|jWTZKd!` z!zStpTE>p{WhMM4`c{|e@sUCjIDcKeLL3JF2~x)ng*dhFi{kHJfpzQ->|gnqMApN? zA01=A2~x+7;e~qs1J1u8XdOE;YSqIpto)Mj2f8P#B|37cQi9g8gM6q;?n%jpX9O0q zJK;b+Dy71ysbub7K?~WzfAAQ5a2S4J^)o4C2O>!6I;O$1p}A%u+j*C3W{++)RK(fI zAC^Qem#Sn8`oqFi)e4cSN~sj9Rho5n3Q`rXKv`9CX8ZAJ?y|(Hcn9MPT}mn$gMu+u z1*wW}(AiY2DvC3<1gVNARe6<^ee-~_!pjJqiM6U`99vZ;uqxi_xPFh~ygKasan3q{ zRq@tFXPtOVFyOGN6t3z+kg9mnG^Nt`x;+B6{qbQ{3g&WEs!H}?sO99BRK-KycwYbH zBKp~KU`P^U26I&^$%kR9;ssX4Q)94_vC3Bs3Q`r1xhj=%ErjIpi%i`gwOEG~%gP`~ zReXyy{MA^8xLjL7tKzY$tQxD7;P4fxipN}^rjjvjH!Yo$<4fHiweY=uVEsri1@Mc% zSklIp*fX};XlxDayrW-Kdta3B#nKf)hiPFhWkHbId<|N-5;s^tq1-J-YV#GKyqvB; zWl$(TzIJ?k)k1cb&3F?kb&GYCP=I7J-UO}92Q6Hyda>a{60|lSTuSw-XE|;rfwlRV z(o>7uO7Yc|0&DXfq|8*SxM|pstialQ2QF8Y)gGvb%bG<|npCtPcR;oM<*1Vdsm%u~ zS3U-X9+L8Ar!9N_@cs~@jQk!lKFwxK3#`s}(D_nU3Yk0*(iT{q?;z#lQSy7(`f(|P zf>h^2b$PXlO+KYj=oB}Yt|K3zOAt3ctj;GPlS(OX4^VdtTAdFSL84N~=>aRvq*9Vi zwTcHe3WF8(&R|MtCHZYw>T^Lm&;x#Xj2H5-@p0@af>hK?;Ks3)_V)q%$fQz|Yo&xb zw&GQgiuxA3;FY|%Qn3~5f>hKadrG~EK90LvkcxWJUHRXlqF&I7dSrB{WS{dD^@3E? zkS}CMLo8@c}z<3LELW~VS=Cq_4UcsLZ4j@UbV#hK=)N8_lD!$ zf0kSym{D6Pqg$}89|S3=CwVs8(?moC8uS^f>NCgUJI9ICRF+6@D<@5sY-%7r}2b@D4iG5&frkZuhmP3+qdW;QL(ti&)UnD7~ z$JjzWHcievlBAqoV{E_D{U%wuB1y{WP5sz@pd(=S7w->&6#$ho*jrXUBq^uIa%)k| z`@-oLN!!AIgV={+>3}3Dr^mk1UA4ZnT!ou#5^TcKRIAY9DnKPEr#FcIDpgntZ&E3HG?c7VVZ_BQB`K%JzEzdV>HYXPd@pG^J<{#eyFWPjAm#L6zYTrA?pDjI)$HcJ zuiDuDaI$&S-F$U1zg;h`=l7>4{!jkr^)LW_2M)6WM2Yuf3aN6&$tJ@efRd4_@J>*K0iNy|Muf*J|BGz|JU)iaG!j5 zV#6nAH#2_Z`Jar7b$asIe`vA1ebP6P5Zgi_5Az!@@BqX{eIRD;cOOuH#`FN zaC|QQ_)T6;R`bhG7k&f$(w!yN(SPggF$#eV~L{h^d>1 z9f{ulOg_)97nidz-pv1hi|`I z&+qQxrT6Qws)01LO&pi2PuKKK{jVmg#qHIw*_&UHBeeO|dfC5c@3-`%Y<{=6x}`^0 zOoch|=v$4B>+<4)j;a^tv+&>5{G(r;8^2NSx8FG%BppS>-(U|e_3Yv|`kK4z+3hfN zc-p7i-)@&*Zbu(DzueP~@28!`k>#ofAdG;_Je;*IOpffo4f1zdVV{<_c~>Br=0oc z`K9aii=WZ^>*bfdU+o_BVfAi(Isbh2-SYi+7w^4)WYyj20YmXa8mM!}E%&!mxT;NrVuenXz_O^8 zneo`qwbuTR|NURrAD{ew`Q`TN=F?YC^1uJrzx~G_fBfZ}uQ$J6e7t&pahLwn z=IYb0H(#!I|NOuH?SK5o%TIS-{`us^i@%uRvu>-m;>rK~;qvb8mmpT9`|{o?N8 z`KPPfo4YSJpZ~f0RJ7e6zqq;n{PFVc^3&z*?N?8u+p6>*UVih#{?|hHFJCTiZ$AEZ zw|_08$A9|s$D2RCdTR96rN{fz&Ch>&_w&1(FJCS{UUZ)k+i3jLC*R(r7yRMs!}Y~i zPyN>T|Czt*d3wFPK3^_>zsfJa`SjcMFPC4^4?TVI{pGLM7w`VFUlqIcTOm};|KaxT zpPw&p-`?E4`}^g)e_X!*)6JK!Z$7<${^`TV%U72-*OzHczk2%i`O_yqe!2K``}V~T zUp@Wt@0U+LUVQnGKK$h7*Izd`U#>n}eR}fw^5P#)(*M6p|M@Q$cX#RMZazKv^|w#& z^3y-Lx_u(!){FlqeP;J}{(gD&;qQ0-zrmMmpS-gfTxrO03QJ}vjVyUX|6^k{!veR`9Z$2htFH?`ZIkXGyeTzyQ>@%2UCxUZi6e{LI; zd=|IT=x2WGjD5Dr$6@#Xv=h(7R!IH-4eop`K`sQQ0Ccj+W z{qx!N&4=GUKKrlq>5C7S&o1BJJ}WE%Woh5@pF2t-}4>&<*TPE zZezY6`?Eh^ef)U&<=ap1 zuijmzkNOZodY_3!PPRgo|2SIE&O}TsUfOi?^htM7f1f%UCLO){U&7ZhJ9}6ATT@5F z(mVDu(R9sB@&J1w{B>Az#}L{kF5;B5&E>FRqg9NrvQV_&eA6>vkuMZeQAkn?Ek{*>K5V z?3Uy9)5UfAFR$MGt^2p%l3kWDZSt4fcklA<1f}x7eA(ICD0ct+uk;Pc2$-ko+5g9X z{F3Zi|5i`(bBkoyp6>ohe)aT4da~=wi_S9JblGlx*=?-NXX5tm{pIiZn}tkv{a^X0 zNYO3HzmM1C&^m?Ft&{85Nhb4P(}zF*{pzcy8>#d*?Z)TZ^e@unYn@NPS5N+eQ zGRtJI^G|jQEz&V|dRS`Jtw#EpOj_)YxI+v?AJjlbjIcidK5IsA^?hW>X{a;5v< zIp(Ou;i#B&Cg7;3^1W{1S#hU3E4Du?zWZ!yb8lYBVuZggSLc;NV;{@i zN!~BI0LI?!?~dA9^Z5Q-O1L~~SnFW6wqI+>o~t)6|B7qvhP6hk?7(}6@D#kanCZP= zft8YFsrPTZU+QFQje({1`=!=f<@RoM7w7K2>Z_-(zs|w^)%zT*?*sblix0abE}g*l zSGRXN=d2g*(g~wcT`oj${U-UcN7`jGFttS_VpYP!#ss(pj@*I}9}=>f;3^@j%Gu2s z9eJPPuoALLF*xTOh}h``{r1gET+lECB4}V7Mj~KLwbW1VAH`RyKa0sK(6cD}vzRP~ zd{A^~MW{rFDwlzl?aCSfQ%q;CY>Ls@_;j1%EEgUA_?kGlSc?vw0y~6RL|Wuyqx%UX zBvMRd6~s!u1ou)i+XvR}yH^r6FojsdwQ{k#fqgJ?7Ezc?=d^_PP7R6RCf8Z!hG7!3 zKV8BwDPiA2oDqeslI_NAkR^rL)zbFf(sQPmX1j7oVZQt8k8i%+MQD93Ar|u?H6$`Y zyOSln=~;z$m4sJswc(EHtCBr@Qv#o@R%SS=I?znC_Wd3m0KaZZp%2H^k_hXojRU1sS`l_f#VFw;%8_3<>((-8Bg-Wi71CoukNJhi~Al4cFoAPZ-7c zavzjQF%jMeJyd**tX_xxZBUxthFrHDZiB5QVc+zDuN3s7&Xy!BvKQ%PaYsMFX%A3B zx2o!m9P8%jn)Tnii=zAQ_4V(yO9Qf%QhRN{9f@p{yCW&}t|2rl&yhnNg&ar^{>V!> zklBo#E;#%33vUr7;@X7ZV@MLTmRYId?%kZ<+FGYOR zTiVhtNU=8CTB0S-?BOb9K-@Kr1zx463m~O>{#~&PN)=b7g08x%urx}|m-*!7)qo{G zsY-oS+Q8L6{_>jGg-~upz`)H$a8*NVB1cGU3Ns2``p69;Bqh3***=R2JKtBzeiAb7 zKIk}6jOc3F(q>4&j|<0ifT&69YL8c+Rl!V}6w*S)%ncPtY2y)|q!efHE{bwqq*Rdd z`p~rZud$Lbyl#Y!wliE>L+h=?NoZGIQRwoDR>?WI#KK zlrYS2|I^bZD>1JO2Em*xL6`QV29QJV?iR*)Mm2zRc%Vd-4C+u^*6it_onJNG`L&P< z1Sl{ItxwkY%?K!8Y5bb4S=zi>>7tq;!rkA_Zmm7ryc*q9?EIqh@=#{U3GG7~BdTWS zv!_~`F|1(~lb~l`2ZeVaklTrzmc~cg7~{YvRZU9(0S3q zF+O}U;Pu6cJ5hJyVyR?u?{(3QnQzLhWb z^;Ma6@aPGJ!2rAXnG}5vpcC!bR^boWILJkv{n_>8>|)~p!41l@5T7dS@sKZ8O;PTHy)e0F@rCO0uqe}zoRSt{jj7C8i4+XrmG;9Hn zoR%S1xg(hww$-q%F2sz~Y?W*~V7<~}6Orwz(Og>(2?Rl8sq(r~LTx6<8By3OUOSy< z!1@KK@@cN4PMx+MdWiV48bVG1y>#nNS)o4WD5u=I9AyM?D#3-zLn5glKe}8nCJY0x=h66pOI&_xx1v822}+o*-z9nKcka1orTq zKJMYa{_pnit7QLi2k-ArSMWm+!G^yy_16fBl<KKs!E)c0VO30jhw+4 z`GQiZ$2whrtE7hwm0K6tLein)xg^1h@6al>;<;Mdzh9*wnj6OuWrR}VHjeAxk8VsA ze@IwNP~lG5HxunYCy4W*4V_C4eXtMM6;f5wOQZc&k|_`ObYn|BePdZ<1Wlz(iS|jR zisjIVrS%jWACEDIW)sDjr_i5Zn|nC_#`KFl1yTUwz)zU7Nhl7gO3tR2*9KRCKANp5 zwkXIFsIk|BcF|1 zE~BE^qm;OP$4B0uEGJ6*t=YCM^=YPH(%@wS94(Is3MFSm;%j7ADV>5QwTZ=p^W6)Y zU711~!@Whu3}FPSFqerur>K+}^08J_N^V9UUsIYQE2O+kyE<7xpIPk(*yT=_gjq@+ zZ%?*#61xSwkb0%?Kp7S{a;psB)rF`yp4>=Xdv#9$m`kRxIHVw;O2L+7My|f}QRL*J zqfZiI4v>8fr{EB|E43^EsxhU&`26F?n?E?OFolQm&^sy!!5saYxp*iEcqoY>swN?- z3y6>y>cqftJhD2`-{1o!>RbYSVC$Lyx9KV_RCFwdO>ixc8+83VBpk`b~ zS-p&kZ3Ip+jxu_o*biB$B@JfwJW^$gm{oA4ZNmadY%)j1Uba&l^0v^OzC+`%J2^eC!8>9cWN#c6 z#{jDkQccGdES0o@kjlfmwAE=w=RV1f8Q51v)% zs%JH9b$=dzHB?|WDzmm8M!D6rx;;>C)fwR7W4V(W$VReYiZj`iF?m$X$rgd334=#` zn0B%%w$hW}RuTSLCCoQlU%)^y6zr4c;W0GIFSVFaX#y+O(07rFZ2=z}605GMT+QOe zNh=fSceSb(K@Q#I8Q4{$Yr%Ii%v|t2N1lh0iHD_OWn;=7eD@kHngP2*yTb$3pS3%O zK!b{E(G)hmU~T)T?sHTIBG0MNV2IwSbOm>vY#S3}&_aWqEEYl*g1}(O()^FD{zp}- zLTwJnv`m+wfY1ovjGO3LrX<8J6G#W@_m%4(*e#7fR}q15=>o#x@Zjtuhu5JZ5VlmI z(*I!uS_QxDWZO7c{sfRjm*sVWTs_r?Rf4_LhfPI2@Db-lGY4==mOL$FXu)OKFUXcT zaVS3V(CX0kK?o}<=46rsk(G=AQ0Pa&ivT_0Yn5NUoNu{OOW#s9djW1qF2JNAl9Lk# z83}>dt~#W9yPO$Sa$%Ljb`RVU$RF3Js_Pu ztEMXIUo2;n`;X<~EQZ9KFrX<;D> z)l`So)G3UfbF4EXq1}FQzr&@4O-#{rG_Jmhg0mkp2-vZ1mMm+Qsu2#TsVNHckV9B1 z&R|9Z;K&8?FhC()D$8n<5s_zC%Fc)}1YW?18v8H+?x=O1;iol`=R@_%so)nbs;ye;Sf+|r`M8GTRyho-ED$B`T*1UUmSgtn4W24r^5^S~fn()C`$~o3Sf%^Q zVQe2zHDAgqTZJ?uup{k2N=$2xrATkAA9AblbS!Y;3dyi>2EJhpe2zz#6MW$tI2N8m zwXgg@ugKb0pWYMkE97WG5@J1zr5#Sw4DqWRX-XUirtW2u=aRVxqKshaAPWwuO;UGX z^qTHIOG>UokslN{6~=OQaw4Tx6DhUK60N3^Qg2L;13Zsrwk6FU4T!9)J~X}Hw3+Rz zlZhLCsNPf5j=?*5WzJLa(<_D@VS~%6xaRn(- z@+-9rXlIVNJn2zw4a);nhs97H=m2CPGvO)*Yv4JaY`GvQksL32d!*f@mrceP8Q}Z*sGEp3*oTBMQBv!+ZA7yUoyrSq|!x!PdUn zEgvhhO7Y6zbiWLcD?(?M?WvODl`nbhln%64U<$P5Ad?3>pCH&oKoX02`K!ba9%l+l zX-n%&vCRBY{4ih{?v1mV;1Oh$v14hIRg3ZVCHggJo(WGzBq@}F7OZJHy7;fQQMpQ_ zVwcNVtOGO#p&<((6)kvm6mn-`-G7p{Hu}%ZzkQgo0|$dRW5)tV58p->fcdC)4%*ln zxY_^>myR7%@aLC5!j^@h+Hs9qF9Zrtpy5i+Q14lT+z`82oP8)=Y)=4j|NERvN^S^s zQ8!coEORFh4*5KG;F}=P9iphtp!-v55DvyPnIhe8SV%mrK!k}3M2I+{4KVS!_4X(v z5`}7k5mZVPt2jmr`vLo&P%4ymXkX_RQd?Q5vZ1;Y{@E9mA|RI7d7z^$1r<4x^Ba)k zN3Hsd!9E$yAq91IVy1#W;mGw|%K=`m1fsI!x`s2#kIGick9s-weznFg>2nSB3hlYu zPh;m$p8$laRspJyVovpOojKqzkFJ{MQp>gsuv%gmB4 z!{zVjPE&r9Hbp{xC=Lee0^T-PQVz46SDG=1vucbkDT-rx-IUT5%B)gQ?Bmhe(yORk3K%56$rEXc`(P*3Quh%H*mLS+5q_+_PsaPMA7wWh zqndHpJrj=~9Xe-VPz`^Z<#5gkixfbTF1P~C^Xw5E-Ed4;(5E?){mvOyv4+idq-~ar zMQMYxa4TxFW64mHM0RszWPZ%43WKolD#Qs2=^Q zm1WGPXRC^bIcYE{7dUCjyquG|s3kRijVWN@+9#vC=W2J)V<8x;`&l31LCLkQC)Z2i z7i$!3_nN1LcQhC^eog}|*v68H5ma@AP}Jel@{+iR53QHAL#viI{nlt-xUEK#tu8^n z_VfGyv5;)MdxuwB@yy{7aycXoIQaYu&U~5Q~KSq$C=-k&4Aa&Co>i*jGpg$U-kuqL#Ab ziGaX4e2bhz*w>UVBSckn$#g}RLGV@Bv7$=LttHVm|ZZx~n z5tvH9e!7%=Pa&YA@?Z$ur#Sr1P{CeW;xVEw>=GBLypgJuGnJ~8IiN)|!>gzXuX0Z6 zai%lBed)*m(~%9pNhq{CPL6_i$P20Jg$f7E^ZlAYUgDRqw7(o5KPq^ zaY_?E`*7C8he+bh0J3H%r)n0=KAgrYYgtvQ(aSkBEtS+WWEMP50l93t@wBsA^;%4| z>WQ*AHtb|o|LmKhev4#<%((Bg3GW&A z40>N`7S^!tqvo*5rg;yJr( zn4c`O3{ksMpc3JE&@iz-Wuo}hpk1jzQ9g6+PM04UrzY|vRqZgSzE2QF9R?5tsM1VO)68_JgSA(eS_6S2@lAfrcpG0#~vU2#T&8sRJlqEntc|;lCO*Sy+-w9+NBM zqBs{$WtuGGhOLyYQtQct@#BkE_(P*IuG$7uohj}Lk>MzcQYk7~Pf9!C8!CXE7 zbWxRI&}w%z9tFyjPP!fZODwgE3}s@_nFQ#dJ7Vnq6;%PBt5OQeedtihex5(r)K@Js zszHs|E3Q}3T#BDtVMs~Cz0R4LaP$3oPGe8D%E`4WO!qU2aW zj1pkA1lx5#lmqB)YYG)qBNfzwaX1594)jQX#3L<;IT;q%PK&^D$mOv|Vo@g=*4bLt z3QsgZCu_i&gN{%zJ4D4|DbIN&2Dt|`NyizJIQo-C)* z$v){?PNfea6^|4v65V;Mh!v^X1AS-op?2pdRQgaGz_yL1L+x#b9S?_s=ICNIvQ+{b zi}j=I6%o+Hr1IasL6fTh4}!NG@s6nSVdD%k+CZ?M&XP_0yXs6`5<0FxSWGAWH)3yW5?_fbqw9Ti6 zw)g!upN1q}f}(-b+|-mLNrKvl zoFgf-%J?M}w;BvYSEm>Rt(cNJnZKkJXoZpaOB$p=P$5~V;|Ezx%gRh*JVmJbtv*q( z<5*Xmm)|M^CILkZLSfEqq-SL*C@e|=sh_YrBov_)q~u<(nq$X}U9#I9Q=lU5Xjmft z!3u6L)ubYxm09r^^a50A(*+?j%}T78m4IzJ1=iYI`#5d7jDEne!l2@;SX~j)Fwvza zNt)OmY10OZbv{0pgp!9m-n#-acC+VjYb{|%QAJq8q>0vi>AE#kHxORHBjxCsoYJ1XjUAI4IP^AhMl2;9N~W ztqVbZgcd?!Gl<^Ow;x@pXL`n_>zmbj#*v@kKJiOaoKK~9GVJ$%$u947t)#L7yi5ny zmY)DV+EzEQtuO>ZL^@vXgqVX&TA2{66N@khle?PyVvLnteE{WQ4a?-V7O+c2p?zam zA(@e3s_KvtC46GkXB3{+>D2-#Et82$D_n8;%IIZFzJg^o=pW*IQ6(S7XQQ(xhw8+c zO|WpJucrj4d07?%hYHkM7l7#9Xnd=KA_b8}$pQl$!I^Y__P3TD3aP8Q&@hF!VYPW3 z)*8%qiLs;wGR}`gjHq4sNgTcuGe%FX(be%}khca|CTqA#Gi~aa$)*lzXA)saF*g{Q z=d{F>)0#c#z0TA!hU$n6Lle)!z#z&7Q}+OzDt1B+ZAu%EKPKCV#qm9;LBde1iN^3dnY;|Gi&I>&WU>&gqtq#w-sr5zdTaWdXyGoREV9 z!(4pYQZuE+G?j6Yig|b>dC6qgz|1)Vb-WbD%|>M#Y%mcKO^L=_&A{2OQG<|#h8tka zg^fII9*YnLRFG-C*&yf{5=+ZUKO7Bu_AbBi0`!(28 zML-Bvvoh$TT`jGxYur-}Wjqa6RY^{M>+ql;3n(yR1^+wH*#qb}c8U|7SZd(YcoGto z-kKz7JO=6!%Kkhy_(=3g3IL*&74!+BLY8XQ)#g#29mO1GDLI%iq6J@#C0jVb@Fd6r zV)$9fx`Pcds#sT0c5Fa0ODlvD;?y|;Ujqfcq5`z!wv2Y#Os&&KVB%z$=7K3H1o&!6 zqe97vM#W;L>N>*u5i$h_+hAp6}5#%T^))nVoQ`que4OAzS4@z_U6pmtrwGc z0`ml`2xY?pb%ukWgI!v`UPptypw6O&3)qo1=7q>s)_vVQR?(yAf(Pty2T%pqY!)y& z`>J~OA?G2$ZOKxoW*i ztT8>bRY2x$*k%n4@l&tpm4g=2f>4Dd^FW%j6|x#RoWmFpyjrNtFI>4>l2u}$ML%0o zTVkcr0irUf?Ae$HO9_y`>~t#o#U06-g@@9J*9a{ff#h}_{~p5*?f(N4t9D$Dit4Hc zGmQ`y`AFC~2hh1tq!l*Oha+Oei1E`DD?!XD8fS*u=|M?3aVeFz0HE^7xuPHchCAv? zE0Bm9+R_jwD%2N+6hL6bX5a@6ny=%L5`%c+NI)c)5PNeOb?u|aeDJ8c zVv!UuR5`Ik!~7RdiBSg_Z9bX`)@w5ILKRaDp-_m&M$5_a&y0&^4*CMA)}07mMXL22RB=J>59Q~CFNwC*vj>%ES5HFagb~gCn#bu$ z*{v)IjP*qsRv!QuU^wrlfU!|vZ4Y2Y!p!AB%;^<{t+i8R6&~w&z zR6Nbd4jEI@fXc?II0nPY+s>GzAxH8&od(;+E^q&=)GvjpgHnjW>KzDT$k8mR_4US( z)*8b5P-R?Lu5K}Be7uUa<$XYRZT9jm@2-VX(y(9vO_>j7p#Xh9PNvNnhh1udRRQ?3 zh-A2>@s;fGWf6;}QA;j|bWw{a11a#MJN@2nZr5n|mQ#RjTMGMFM>r}DEXkd|*x-6* z&*0Mz2L~gf?cNN&SyfLA^NIwr@w8$-4BA*ccY2-WETyVl2Nq)wh=V;Xm{`!vwQP1x;$UBIL?Rj*1=!S#YqSbLGoM3ndRP)Q z-2PI4rY}HS3jdxIvCy*xDd*rObI_p()rl zFGlhx+#g_`l~I-AgkFwsU&o?DQOg51#<2&HT6ABK!dTKm?}Z$XaD4lJs<+}h)&6^_ z*qO;u1rP*}ZpeD`G_|>bfhWU`t3dj0XxigcM;-B40yNJZi#DazQEw(J8X>eG^ z=mn(tboKHOM^mr4@gs7kX87p<(`>A(qh{o6J3UqEr5MJc)az&0kk!N&OI`iqv(n1( zTZ=NGn6|k22rxe+;3V(@$-FYDApHx=Jw7g`mmxWnT1;p!gtVJ$O5M2$kloP z8?&`%peuvq4S+FuNpSugCWJsF{KR-1P#VCj%!MV>U)7WwH(Mu76(X^?Sic6R+W{F6 zrZgDCRq83B+n09vh|rCNDpDWR$Fr&!qO}+u>oU}1aWQ3`0qz=gxCLlhSq?!q$_K0c z^C<}kDIZA;j;Lb$00MuK10s&zHP+shZ^TJvD-ce!k zFvtlQbbQ5o)(1 z{mUFphjpO%NOo2*20}+JxS&{`P!QBpffRDza*OVSV4h6!Avqp8A=X!*69SWNVZN#j zbo#FB)Bm%IThgJ${zwr;&Igz|w4=CX$nw7X>yK}~-KFq{POdT!8B;SJRjG*HIy4N1 zSxrk@6Xcha-Ugy4)t?yC1MN=?zIbxpBGBwOSzCme~{h?1KCxyYqsrPkSp zB7o=J;Dy-4Vzdp2^9Rv8sspF}118O7xKVW}9aj;a;`J2j3AOY?!fN{V#+k$lVJk{L z6dh52Vr~l!72;Hh19Xi=go=`roV46TGYPD{5;zG*Cd*#!?B-B`Z(EJh_)6O<>(-GH z#}0NiY%ENvI?y3IR?LRJ5{TKbOu%^#eS`w-t+->2(hR?=WX10e;qe0kg^@$=ODTM- za0bId6M5L7ZSw#w?>c#zhXG1L7MG^Qd}YBXtDyq2r?5n$BsZ#RfgHD)Qn}D)AOPba zEJGzz1Ip))1D8>3cPz^1L;(g%L?o1O);lgH-!|5H_;--5xQNzYOKiS4~1D5&)|MSZqaly$V!~7gnVAo-Wr~-NTum77p z{2I-Tlv59W)5PIE@P?eWHsX}1ItW4#X%Q(OX%t%6`awD&6t$0yo3BzCkx)Qt2xv`( zm_Z$1M}sF!;084-LO?4fvEJv0Rt9D&O3h@WOchLg9oQ?Ey5)5g2tWha3lOe80@f7= zOaX?MX38d*8HZ>cy0V0_n&nu5tlRKr92LKfN*G~^^o7QLcT;-ExSY>Xy)wNJ$DFITsDz)^ZZ-45acl=2W z)8JPZU_PpD9YBv!mop_b7u=KV#fU-$CxTRAikqx^B;-P!-umFm#U+|mqzyuPPDF(D zS(B6eJmtUQ!j`OQByFHz#F$2Mj@Feb!a{z1|G8Dz^{WiAQ`-P;SO;PwnY!30Dy=qy zbwS=p0ev%nI&Pg%JFT`#2S)dk)|T2~IhxlJK_G+>l=K;xr!o>hCFQP7u-rb4TcL62Dxbjsk}@n$W5^mynKK@yFq-~|q%R)>%%;q?ewv_-T7HPXLMp~_dakrsn zFfwbAsrZmW@UD3|^hG9%AeeD!GXuuE62TfrB3KJNOZ|iRw7swHQU_~=3-msi>&XoxqCxS2^NU6M!0~D ztkml_a8OJ2>?e$>J;5bgA|0p)o@ZpGS!S@W9sG<<-UD?5!|*c`^^9I$O^tw**h4lo zJ=vk2AxC4(^9dRhm4**mchs&BPBo$ zL~@Sis#hvvYEaAb)4S=H!YbG3#cC+>N?RIgn**Z=NIP~XFHmYyNY1UHUl(QZ8gY~v zG7`}a;CviWxh&uHcV%?Tauso?8nTY>5IR?lMwmD%X?h;-q-*zI> z`;?R>`vF?h4yAdGo1;m#QhYZ`h^!JZ2{6@=m(sQ(B8@Ovv;4Sv49_N%Bs@YA zGl&@I400f%s{_2~<4R+C8)daLHuM5d#be3<-Wt6KoF~iLQo1>I~+n4hoxe!k~gs$g&dmL}7Esb*uM81a>fGSz9;9zOMtcQo{>FhgwVS z7|}AEs?XzE3uP5*7hfL`hnS)26lzKLCM!&yQK%kp0z=j*8H&V;gKyDDU76a35%?A$ zn!IM4>qk#u$P5P*b?QBe-U`dQt_d1~ocN&>;tJ6FAT$KFMDu__PG=xo4`2+Bu1Ys8-=pvro^UDS(iJU zzysKVrpgw405rg^;1)8Fr-c39K$DuK);@pp9G4S8#tQ8VG~C=Ad95{EU!FQr@L4_< zEUb;QrwQ+h!1v1@2K>B4fjm8L%-N)u8Xca&ONq0RrAWsI^t1vns}9Jt(WJ4Y$s}nM z7@$Ho)AN~zJ zkE}q=!LcmXnrb0;F;j1)3HOC9;cOvG7|B&NsqfbX3y&?2iSqpcvB$$GWjqzO18vpN zac(IHew9$bBO*iE0*{kUb15qg1@us3pa2DfLc{=2$dlG*`c1$myp+>^(-CDP@SFTV zh{Hf(>N9(wu;RV(EZ1hLt}UL^a3qU#v|O}TP{?E_{}G#Pu!jOIh2v+$u0@51JD>sX zrr5dnv|Ov}Ij)P7&!nt( zal~TNx(cJqqM~cA>fk&mt{X`hUAi>x@9rc8yrIkjvLg&H)&IJx>VurFWKj*twUjf} z{+we40FNe*`K|HTXC9&{TO@Htkc7VTEk=k0S^8O3eoyu?yHC2&Cv#z`@0lN%fHAyX ze$k;I;6$Nc@l6P94b$C^c$(y1evS^J`<>W z?@JWrE$1g`Emudl>BOv7_15w|_w0n+<7Up}p1j8XxEgM`Seh2E0rIc_d9Y@1)+Vql zS%UB|LrOfNa}bM4G?@HD_#8VPS0#)*hdCJ-2O-}qmWG68nS3-1GKHZ|fM$T7bf{rr z#qonOuo5N5fCw*7{3Q9i0cQiovi31}Ccd39cCu+^MA|QGrx5C>A6XI-Ty0 z++DMJENO5^n#GiHXzPewuk5&oKb`JQn}=U#P`#xiNrxtioOKGlFFJJz=J1qGr;17Q&2W9xv->%btxb3W5S&HkM55IlfTz&YI%+FU( z|9N=}8VU~A;w`r6Et;T+DlSA>QO)s>53#ue>DLl>_&P&1`-e>_12$lgHRI+4A18Re zy$_gtK83|d3g~XMeqM9Whw;Q{Fjb@HQT-hdV!)tpAVf!Kz4l_=cW!g4++jA0K!-5 zM(d|L^xNd~`TF|FIg)p$SUK{}iVFU|gZ@XBGYee(Ixi4ke8HkTl54VM9_DJ_E7#z!c#RjdsmJ`4&3qLB@@ybsgFhhdD; zC`LA&2=C#$f77*asDh4pgxN*;iK1`PaU&9#Ba4`x&Ljvn+ z)*$ZF_%OxZ50V364%uk^d`3rmur3tGJ??;;$CC8xb{YC#_=vcr; zF}&t-TuuB3+P_9Ip5wz8A{c-S6VYgYb;lc?d_MFa8vSoG|Hd{D3~9hX4kX$X=#zb6 z{Tl*0JYXDTqXtacU&+M>2K@&LR)j|PBX+>R$>&4=q0s*}vM=(${XqW_umaxb{OOK- zJNbOzKY~XY?fihx*Q|lc#s?Pt zM}+*cQ3Fuwt>*5pB{ejR4;r1n*s=L0pAY?qDDkP9Gmh>w_K&TBTdbjB2XGcT^d#{C zfBq)&k1WX42tX3K_{C!R3hOVvQH?$v*k4kQ*E`D+7KV17BQI_lA9*?9SbOuhN@`2=zpCjo9 zTo2o3dozK8dprXF0`JkPx@P$3z=8J&0G5=tQFTa;V6EflL+>FVJ8uQww0w2a5$}Q3 z@kZH^5zypK=CLaOWC(W=Wn!CP1O_`Tw?w5bQ$>w<@^KziM6$k(f!`OrJf%r|;toNq5=qjN1Kypm0-gMxL z8v$!qFb+?~HrF@qWUVG2k7&a|X|kDhjw7Ds`1#O#C`f*7qvD3zTFyF0^d1(9FRfZf zo~I{7l6-*o(9OtCEH^Mt(N7wc#u4{j(no)=ey&k+8ChtUB;0q6=dV$3 zL9oSpNx1J8p=*tbyM`tAO2U1|fdsDE`f2w3q5nYWOC$f0?4M)TkF?GaTHGjmQ*3xI z3HROL^EHEBNhW@g$bAn8P4tc8m)MC%PCg&{4}iuh+f3WQG4ZJ+Z`d<6ficXj0H=R^O2@n0+G9}f+al>QFd zAEA-9OJJ*OlF;83LKE9OpJ#i6QchK`8ueC{W0@%u+3x|5 zCv{CdAND?C2@gyo^?-~#<;)*diiPvn3VFqgr$}VKV{c2f5>M$=$floM{GwDzy0U+^=8Zz2ZDHxAA5p$_T{%b8hQG~ z^ue3Y=}CUJkI5U)#B9#KQg%Jn#BRkbW}1(Zjwgihw-I(FyLa~ausjCXGbI{@AD&Nd z2(ul>JDNuOYuN6Oq|A2kpRKx6hQ-E7!fZ!%pjON)!(uNaGTQ^TFI=Pcir~X@WVT0% z(tM59Pq5HnNto?;KUACb(|K$K_k5%|5Bu9neJt?t2Vu4&_O?}fMe*ecO|ZeL`Ti#V z8@c$LFxyc&wblMQ-aZp%yM6@bkYkxck}%s*IYYKtzsNrxA+}?9HD@B^X^tO9ERlrR zj>MNn)mf?7?wKUSc2w@Qjk*__r5;EmwueUuuX6Q{GcSbLj_cQ|`y=`EniAV#{aST@ z4!AcWnNGwt+ey!|_Ju%$!92TG*fa=!-0l1!;uj@VqZ4Bzf!<&Kk{fnoc$6 zi|iClMKtOp9k8WHlJ6F}@3b~c75Mc-nj>@yRjXDA50sUJBu_-n8kI^UOH+|Zk`Evf z(rSuE*aoiCfE;<`P-lc?qfm|0P?UrtPlg0E+g|p15RSY+5_O~JQ+%VJaO5pEsv7|% z;?{EK4@vR?fZDApozk-!7ZOSGAtKPYnT|Z$NT)1$)ERH{e45vhm&lTL2;^v`A;ync zkc1@<;el#p{|*2-kR=}?hA(a0Z(vzSl91$41VOYZWXJBWPCg!b4;=E*2nNXOQ%gdT z57-87b~#uS7EG^*kR9-{3h)wvq=D0qsLB>Z?XL8H-x1y)>M5_&uaR*j~+xdXO^cn$<8 zHY*!&1TIO~@z{a4Z5*%b=EzPy9(oRx)@vkv>R5WC3=_)0tr{pPs^{pdGEBjXn@MxA z@PI&)4zSFvl3v3Xun9LF*dMYLJIe6zT_neQ961}B3IDOKjgaHX?QPWmw0wUoOf*pP zy>0}b;iPk9m}I9kgGaGx5n;z;(W((UR30b_5q7-623fPg0c>Q7?08RvZQG3oWuK2E z9w=_nsOTs8(3G&_L;Iq$(tK4TPHC$&8jhFQwOr9ElA=}n;bd7Dojrf(KO~&LMuTS# zNdHM>$480q>1It2$KDT;d_d8!m2h@sg@F~aPHLmMSW8Q#s< z7bPa(zZqE5N;{0*U*bQor`l++TKc=p{Z(Q@+ObvXB@6Sj`-}cVLerzwXzolZ=bn$? zxA6Wp+Fw3@Q)Dtcu3w|d-vRA9McDCJyJ|-d<)oDrWyhoRX)}5dr@o;GJKo~pnP!7s zxTc^Y?08h)(9P(V9KKPJ+3?_hTh&fee#A+ODmkIf)ezt)*!>0n;c+f(EA=MFV!{+* z$D2o(9KbjAl_d2mEIv0{KhLU%DM{#uuzsxuuLj=#5_-ICA0J4^@*fl#4zCeZ(yaLr zIQvKF@u=?8sJ@%&`<(qF^mrT`+D^Qat8XYmj|Y5wD@>x|2X84tkB8<~27)%qKe+mu zQWNTqt?GXV1~)1-p{~+QU5b}RSCqbvt@B3pE5q`G6s50&eQq_nBE?s%{UiAYoWEA} zKVExW5&AlzH#e(~bNwwv=nQKjs(vNe{){5@b%FKgX7ziv{-O#0 z5Jw9&8(hZ5FJv$~@?TqVW&#UpS4dwc>Zft0{7XK-9r-JH(%8$t$g`1ukt{(^5qdnx zFUdxuchddi1|KUzk0(Yed?xEU8H$KOXC!&E)YUD-WV5KOXb{ zW}_D)yT7D9hOC1|_RnuEyME|DG~)VO$!~C@ixi>9BkiD({Kf%zh$8%Wgzq&vep%g& zb8pCxe~h`-8Q#EM4>I>1)Bi^D3@JQd%?qKlLwKp$aV9zJw?ayL&^Vl>QTxpE?Ri3J z_lRC@rar`)KSF6&=sp^yUy=`B=-hW?g*D=w@{^Aho%;^zn~lVg^YgLmM<(}Tc-1KU z3+(JMHOXmj1s~OXdx~({1^SO>?RidJPtm#W2>)qR9^=(n72&jFdr!2B4>tj^8uFKN%q=KGuM3!5GhPCL%#YgK+RtoXk|PCLRIRJ-yb+kPaRc9b`3#Y}Xp zda)vt-z5&8XcWKbtzqp8p_gEM)u{a~`0^TIwL|+%HX6>7;%81BSRt*Qw5J-W!{_!C zw|+=#$I0rg)Pd!p=Tmk2(o7yxvXW`aPp}hP*=K24`hg;o-wC|6(f-=BRowHD_B_r` zZ5BVX`3ExFeZcl;v-NZA^O5`m^7BUb!)+aVJ&5~&@VODXKg&LF-AAOh2ORv~Dt+@? z#f5)_+D_OxjnF>_%nNecgMjsOZT8o)qdyhpwnKHd-R;`z9aP@GTOVE z!Y^|FuGik(ulvLY{pf?be6YtNKMFv@vEz9aA=pEMT(_Ek7WoP!66{F_p_Qtk;X?pI zuqOoUMg#-3wVaP2;w9+b`^raSrJOG2Y^{a(O&NU#)%9_ghmxU z&nmYmGJYQCFSY8R>I3JGWI)*AXcxk>>xTekGM}uSzzA!fF$L0(AmAa`{ndnEkMlvgmqwv(T{3T7M&qI3NO1U?({bwzwgoPVj-;7^kk00sZV|dWUeFWb65q5oeg!ZI4 zuzct}aH3Ny^(@1}BQ;^ylkIJE{36?4({%VeByX*TBlGMmjqLh>>ItpHdo2t9(scN| zX>MNf`f<@8vg-p5e{ILE=aj)U9X=1yODp!P+DdkRN%0El35|+Zy!xzGlkl%b(X(JD zc4@+{NBDXxX?4FE ziC9ZB+a<3+{;c+5c ztBH2J_>LyzcNC{@C0-=>?2VA$@qV-u7v_4a8p-bg#RFQ22l4S@`5k-v&BAB4IYY?rWT;ppc9G}P4?=!d zD4suK{lcv0`?~&o=>aycH(xH_|Mo8ZCkyd3r2{=||u0KRALDWi!;niT0)Y z`seg`c(^Mc?5hq(2)qI(i_VD>fQWuoBmDfbc@naxV?LS`TOon=l{05P+=)p&aQAsT^D!k zm)dUKu+(bnrMAM(AYfKuD zQmV>P(q?~@e!2PdeteSN4kziw^Wpp?PZRsov$fd*@6V3t8r=Wd894Fy*EALbx9i;P zmsRJb+%K!)mi0fMzrkg-{j%QS4Mirg#Tz;!@j0Pml>l=Q<)Q>NSo2MavDEa-zIpjq zd|5ZVEHUTM7}-Nm{?&yMg0n|omt*t_ERr0Kl-$2@cc`S>v0nOPC6mkTj#b*Zn!_zV zKD)8H%azG|EIg6sbi1UBHQSX-cAMnwa3HniY}uLVluQ^BVY-n6Lu}IJ+dD6gB3K*}S?FSW?3~Fc5ex^5%_6C-kg8@Ypy1Pu(A=LeV?7sk9D9fDHY!`Y!&!QSvlexu^mX|i z(Q)JV;f?7!)Wh#Y(OZALG)9pp3{vvt?n#+Gfc=koA3OW6lNn+5^!vZyp6VeVAruKu zK}scNF_PQWm#VDxHwyN3Snd=8XtJ#?qi2Q-6pCrylW(VfDo3b&CjC;DpL$u2kccF5 zO^#h#_^ql=)b9N8Cv6h`;&U4|v3fl>6?EgpY_5j6>GF z5j$h~IQb!|S>+I^Pd>6?l5@jlIb_4vBwR*hhKKi^g;P7>`?``H=(4}T<@{>@wrmJH z^7%tLd@Tu*jMO(Vip}Ff=VipzFjf%9l)~7IZyLf_Q7l+AtOcuP-rqsyou^um%-iZ% z|E0YS&+>#vRjrI$noF)z35VK=v=WLZDO|L3D{wn7>Ag}Biq7rN&HipgrUVCD_}wd5 z+U(MLOKT!=44Ot0hYk4Gbqj8tCf{rOxYI3-Qs#BKjw|l%b#42=Gn5-{*&F_s*TkL; z>HqbHs1dk{C?%&l$CtcH;Gp(_$o}HR4xT)$HfE}c6Y{a`drJI&0 zker>Ju`8y!D|+d!tWo`xsvBjn+mtA>VclS8zt+gA@v`lAu$d$a{a;4F|B|@!~ z<_}fiaQs;=M_G4uqJ8-6JM6)*yteq({cM?q{gK_g=X?E;^tEp36)Sp#iQ9)xbzDb(X7apMYNBCaSW1tbrTt z-jJ?iT@|NjyCJqs0b?@p4@zF~_N9o+=t{M7^MF3$DxDGC2_)}5wtz|y>#=EPgie9P z&IsfVb`I)p6>q7x9*aM|gkDN;`7N!|D_^q(z$y_DVlX{RpGU2b8p@9U)i-=X*;4J; z`t{$)+YYJW9Z_*4Fn8#=OKX^P{u?M?za$A;3F37Iyxp@)hiWjRoO3XEvN$Yj>Y1Qi z>aW(>Hrat~_op-uP8v?B;s86NeJeTJD5Xbn2m<`Fk=Z%Sw6R2=fq6rw?W>g-bp|=H zf#vn3RfljWt+)d4^B=IQvqO`2w*sZHqr+Q)5uIcsy2F*qJpUA;0^8vM?{!)>IY4+| zv(6FswHp>TxG(4)iKUHSzsr21{LvN`YLU5-DsHTfd+sB|YSv1Y$?>O^L=S&S2uM5;Q1+N{t0F(pA&u#SD7r z0^{3iV4?~vWy~3>xym)N7$La=Cfi8Qg$$!xRFb6)sZ#+pL`33x=1lopCG0gj^kyF; zL4(Xh?l9A^m+=22D!dMxDtBy+M=8cB)y)>5=X zg^nP^q43Be$Z3fN*@z+HZX%{>j_m7NHT~Tr@4lul%YG`>)r|~rY59q#!QtK%9yx(K}JB zz;V_Rni$5;LmrTNLgt3-m)4EgKi$%r<=w`0kf|EHg^0k?n_u!WRbZ+`m1igciCL29 z>)0Kv^_N&ZM>-q|m)ad&w>wCN@R*zAD%-;fCt6hQs9s(;SqB{?p)BPTgppx>Dc%&U zATF(*SX#B9sXLuu?}SHd3AS5GQdlDi^8~YDiZRSpYStKH5@rfvj~rqoo)Cy);D{&3 z7N}Crv72dp&!w3|)RT!HQqz^NXeKIQXSJ(xj|m>?2m`w{u*?&>sU-=cnKgDF0%q27 zjsn*jE%K8tnTLkM1YlmmFhD48|Nun>Bn7p=jq8OL4Ri^gjRi@#YWC z`Ai}4i1$Gj6J^x*&cxda)M72lkhatCMGe zvTB_icm$__LhH^|-Ule_l9MbBLR77LqYvODXLQ}F?L1XTMT;{VrK%6S7{9OzKzBbk zpa)gk!7Sv)1QUQ$fUX(J7c?df0;~e*Oh`F1CY^%KDp%dMuoShhiqWO`RvQY?&^yk} zP@`*yO2g+!ybOk=P@fl$MZYb{{|VO|Vi>z1TADVz>32N|%fKEA-ttb+2@!Q>$SYYQ zVo<1HlC>vu00KtUEsA7|Ysj3Ntd*E*t;DiOD`2m^AnY~r$aUy}UK*mVQ7RzKpM6%h z=Mu2&Xj&_C-FGAQ)+(z)sc=5%ycH6r4nHD#i&Tp;!%>8Hp@m3};1R(%3GgO1G#~IY~_p z9nZB!P4WN=`FjvtCaozBRlDrhWk>;`&DiUH#1uOmEMC&4w^u=+pZiz^b zqyjIMm|LT#>PS?eEr<^*?#{m;OY1}}D!@4orA3l4%X37{*XhnjMJ!z57_kgW>Rz3k zuyDXgk#bO*k%#1hk1wHNsh_qKJZpN6_Tzr5qpSIGbK35O?M6RWx);mJk5lcK-1;-2 zvUWg4Jxxh9V_v1KlvI<|et7*+$BNn3eKGGLIFL~7XhgQRGo!GnZLP4m8ALE1Hv}rK zM(#71J%9&Xjb_D6pMU=fErbGBLv4gcP9kDF-nCwY2fHk{Ey* z0E<8y&|D3P7C0RiI1NfmgR_<#L~%-Xsvs1tuBB9V`L$mM(Jrx=>SPhxO#vno1yRv% zS8A!B@y1Jt3SecUTB2YiCo-R0$Bz;&NXbY1QZ4vZ&aF-NwO?w`u*i}evkxu_x^P$> zEU%q28g3;5NC3HeS8!HJa!st!J0g)?Kwzl_1eR{bc&b$xJrSARuC$Xj+Rmp$xEhb$ zL)xHfU0rmy90q+W^blBWvk&WjD zBxQ&@DN-9KQZGdmP1R%4Ju-K>fWVjOs4nQ8!yih{vGeT50p)8iE zkqVOuRq7{VfzDun;^M^IpL6Ialyo|v3SVXtl=7luZw^VP{Sa7xzWXdG6%XY>393hO zHMgVl=?s*Tl{D8JfY%=QR*QWUioeCB(@vRaWN{vszy| z{sbWeQ+!3lcAgGg&%a)dK~T?#UXyHHoIspgzR@=EOAKQuKn7iYDVgm>!)hjwskyOA zXkbNdQr0~8?uqB#@EN6F#AP9`yQamL3FBf5hpfV(WE zrTt*teeMW^P{X2bXl2QlM0rZ>pJ+V^6&}#I)Ra}c-!Zcs&a_T!;ZmRrU17k=D9NVf zG`1Mv3irnekqMOq^l2Xn^l8%#z(i!gaB0JN&XGlrb&F1XC!&M0@tOzCgtiiaW-4j} z)A((Cq ztYvJQg%1$+*!74Dy|F+1fn_&R2z#jOt0B*Z0OO3BA)eWCh+3XrHB?@0VYM1oQIl38 zLa9WMaVjB#9GC<(8WTB+=W*!a-3x?zm~~bSwn#eLSy%XL=6S7TRh8uUhr z!mekLaU{G9^#D zu&oEhDk}l^^{xdc<19#P~{E@E}?k;mMGUQFA^88hhd&eu@TuKu3a6%B}WQhAS7Sr;=leD={&LIgS6QW3Sbcs6InX`VeK(Q zdS`_g16LpDE#`sDIxR^f&Jk4KJvc9nHdke`vcVPPIjG^-s zmNZP{Q|Bc!q)Qh~Y6VSM!KUKWF;(XgkUR!E30ZIAK^8?5i{eRm1bSVXOQ7e>39pq? z(vdrZ5lX;R_vq$i*+9h>u4(HlmO2$7Yy=d#9Jjt6=I3w^{njg8DSK`nAiKPd&=3jZ z3}{+gz7v8q=2&C_?nYT6wh5|0qQz}zLX$0RT)Q}yTd6XLtYiyA0r|;?v@#gWdhftCUCeRy6pLW*D3>Y6($ zL5r!OiypK@$-LjppR84i2E4l-;oT(^e3mvw*DyoAqh5Q=7Ilj9qCo6X?&_qA($?;R)t{!Idt+8fI1zk$tr+Rqt3F zhUnTN70ENTV5km*!$|3Qu$3R$xUK3V=DNs&l~WbEII)OZ-?g6ON2SPe-Zk6BK zU@C?t%MC6$`BPU++HQth4S^(Ueb?PrbuCak-2zqTq!6Vg)We-9!Ys0z<2wr*qdWc0 z?g%(jj=)Ymx;p|cWoO4jmaqaYhniko22g)oMU` zk(xAPK=y*awMkEWnm41^6spChL)`R|K29LTL!IRrmLBp|*kS^hxe@A+jzva~Y?eVM z4S@a#fPQUfV1?H~EPB*(DG`Y@tVrVM9Z|b4Kwuhikb0c)j%!pRUAl(QiiLiNk+Y>q zv>Xz3tkV;Q20|9i5>x@i#`{Y=WUUdHYZ8=SMa`YOekFSWnOsUC9wmaN)Y5wKTA~V2 zZ!@;kQye?aiq=!)P+<5>_6e(PSo2rBS2uRva-kv62_Zd~hM*i#ApZ;Y%*Xcdr4#x5-lx)J##QU^}ZsSYOLhJb@D$ zaX1$eGjmhpu(JLM)i|KR>2bPH85yoQ_eUm&XgPskAv{#n$Lm#2$l-n7%PEdepn~|A zZL3YmnIk7o#A-|;m%<#^aM-rH9DP>;aYd2uN}$6gl_VSs=gG-qA>hYkQW=HdjjW|o zd1&)F6-Xu3Oa&OCJ0Qc21yWV&7I#z^5+gt|Qk|W+eXJan+&YrE7C9=kCy04}1c}aJl9D&R8Y7QyG z37ih-A)cd$eESCNv;w#U#!VBQcEQ%!4sNd`RElI9oT_cF+8S>7#T*{FtcMkGvFw#t zzlRTUsSz*~8C^KEpd*)^5$4a1A<*kLQ!Nisvqi}iIj(|sG$SV@)33ltsItAPs%krs zL-Kx2>Dq=`;#0^WN=|(grq$KSEF+TRSWk-?E4td~&sDQC3XB4Z*Jm?0sMkx+iVKe-BP`b#)baqdqo1Q%ze)p1V3O=& znQ39z?k#P?s{xa8zX@-U4j9WTYj)`8aXomOOn|KQ;2$83fU)576Qz6o1gkogS}T-& z(Ksdy3PE;X>Ye@YU;lT0_><{CDhgjSAQi4ywmTUQs1;~z-eI>?!Ohk<#?EsDietxC zS}W^7g~b|3jaBJTNz9`~jq@RdiV@=^)&|JOf<@vUsZD3Q88Q`ZI$a9{`f8UNRZcBr z0HQ`}?LTP7C0A2EIK`t?OMmojp~H@9BNi&XvG%j&qenk+`KTQaxRCcMGUrjd%QFMP zbrwAGMhUK*H8Pu}oCRnEsNG2cPSb?8lV1w~4P(w@}?W z%YCZ?0rJq&;q^9Y=S^27Yp{?;s+NjXqCB?smKnW4Ra$SG34{E4zBxV*DzH*$7=5Yo z#{=gO+irTOF^rkOvK&en5|!3Nu@hO2t9Odf&5Wz16ygk23L+$MfWHkOKxSEupwW#m zwHtv`NY${?X%jVDt9vDnz7e@GP}OqLOR>(YI6(^(BrAqod8acy2nrlRAnKx#sNs#%~-mJumelKPx#Z^`ZK1CkH7UKp+8QXmY0pag9y?-Frv-?7f9*6=Lsi$0 ztW6CSHL2KvRX4)&RYz>r@q@EIx>U+gQ#Gdj5j6);Mu*3KqRM*lczQV_v}M;hbY$4B zXjk$o&3651$Jvywzog(>Xpm5u`_R_BLIfU5pUz=4YPk0u1>h5E3=RuUL{LM{s7b6e z!vGis(twHxo7mANtf@6&2?1U~_sc~tV=nRVcQEVL$TF4Pcw0%B&GK6JItzdbR&MDOL2@XZgQQKK#KLZv( ze1s_rY$bZMovOB-L_CdH1;@Qp z(;=tIIDC@ui)RXQ41hi859#D8%74MQ9vS#nlWN^(q_e$gn$wXb#W5F5TZDS-GS8 z>#FFLe0khS2i1DztH}x*&OczZ=+gezT4W)J6GSWtCm(>(YLG1fHkvl8-A<&apmIf#GdM8MQ`;ilKjFaWlm!1k zKrV1WrQK@qXc9Wqo}IZk;|}`j9b{Q#Ga?)7M74yh&xslAff*bkg0=nZ(T2L~Vpm)c zid#rI!{KJW%*lhd*o~^&m&<&Sk&FeIs8!c zQIeFg;?^lVr#OOuRUewsCK@Z4MT_0u0jXsRc5!K&h)Nx0G*YbmlJ42_#|^{6X$1FH zPgqf3y)b)j0BIHZDHV#LH?G((rfXFSaxjm;saj^F`(pHwq(6LO8!Jz2w{~f9VvUrG zC@DK&<|#d2C*KuDJthU1xZ@xcF@w3Zj!Z71ZiFwWLlb9@)77q?xtqE@9_Ax1MLa8l zrHx%LZ*b2B&~}UI9n0^c>*) z8l_i9^pyl?pE?$jKx?nwOqdeXA|t^0$kK$zW6}HQvRu+Eg+NN8USjBuL$>9KOQMdH z{ah(JESjD>S>;U;GclJ#l~?!Wje~5V?_Q%?8MMTtuGrxNV`b;4{njc5c?(!f{;Uda z4Xma5*-qzSg+1hDo18EdOf@@vdt`=(q!(il998cKO2QsL7K0SjEa{?SyBqb$9Xmwp zu(_whhWZW6HJ>w}mSZ0s#(R5Nbl7a1uT}2rv)`P1S`Q=LLpT*O)YOej&*?lU*bdg! z7OskBYiX2!?F%@8@~@HkM`r3NKNny!i%9QwoZtF1juVRS3fD-&x?wSW3Af z=$2AHmrJ9tHFCRjUNGBnfSP2bOh&m~6&c~MI)jYojGBC;P7?@Kd(?)NME9S@@z2h}c^iJ+RN0KJ6x{ikaCpZ=86oto}F@tG8pvK_OW%>Y9tBv&@1b526F zPJ{^x4*tkp@3IshH}^Moqi zuBleiKOV$(EQs1f4L!O7q83$Y^{@MBR2la+IgVjzQ@;UFS_;sDQd~`sW_Y0pwGq^k zgI#jv4miuvL?$Ls0|AGC{e*IZkv=B^&R&ZY2u^o#* zj|wqMfIwF)araP$p3~532O&PF*k);CVu0tkrR<@VVs01~oCzgELp@m=ZZtBDxrd6% zeXVKqvVll`pN^fNQv@gLXTv>k{@ZL94qihm#UVx>=0wY!Ves84u>A=E?FG7Sb&2F^hK`Q?vzqzg%jsAgC!*~5u8 zC#_i;qv~}jo@hCzS_JW=h$+C)aKxImk>fAD!-|%GVTR zJVxW9?5h;qNT}mnx$VjUHCMh&(`9nVKum_FCjGxTq@6!UlwZ~RCT1xJV4X29u9JQ$ zNc{l08y6|ym=_};HNK+u)=R&R+AZxNMYr=p`G^>Jr2S1`Y)&Gytl7O zhJirgT$97TRk1h^RM#^xRtqWO4D>s2Di91z&I0*`PAg{*tu_L{Jv7-zekp=`46EFF zFb8v?nu9G?E?h@mRH2Gc0EJ`CQ!eP*nu)a~^hLahdHm?CoA{#K#J4}8_4ed~;B1Q` zcw>5o((*F+dF09g9jy1I5vW+?AW4;tm`Ifa`d6fr4{9ij;DD@O(@Oa(u5C$MM^ZCHKpk-Df*ol29b$azV;qzoDY)%KVDFdKbPshpk1j@T zVIfu%yniw|j5!~r00+kfA{t4=hvd*>G?EPyRUiK_q*|zVOTrmw-Ii&d$rOcRisS&= z-k89J`h-okYerY6phF)@#-Xo~QlEJIq%Vegl_%lVrg^%a5P2%rnn{McN{lvJQFBfG zaFvX6sn>?p@{au~=RxA=ihhRoYIW%drLse{Z`K zYr06&$;eW@K-&ee5@?di-N>qkat0h=lj^d;nsif79yMTBY^9jFKe zt`bT*2s>12bxsi(t4G0a97GWZaYNljL7=PYFvNYJn3mIx#;Sp)%B z89C&7pCegafEHGP;EUlzlz-8~i5@_)U!?|Wwz~Mi0C)t;USe7Tl_f=+)`W^s$ajtv zayfD?X-*=PtQRNcZ1Vdo;9AfqM+m?*#df}@L1Lh7MA73zRf`3q&QZD2Bart%*EDAU zJVG*@nIP<2c4`%^=}3^#AY?c^iUmZO#}9jM*7K1yofJol2@&G~8&QWva3zjqnIm#w&TT@av#W0P|XeD?k`%OkY+H|l=iV) z8s@BlL9ytE_f_m6A)OyYmV}hTP$q$w#?A<)SBmSPB9p;F11?zj+4DPgX>G0hN>od* z`>KxbzD|nnq*xUAltgsL^KiWd0u(aTN4#2~X7sXSt_DhH6 zyw4Jns7qgX9?L(2y;+R<5U7eg0#6>XGRtA3sOo# z@FVbCtYagzV@pZN@W4`+Qj&hK=;Ns5?o(P~DnGPQ%NZIg>FztKgY4&3Fo^QAQKghK zo?9SbVmQH>JCP(EswHn&$%P;Qs>pg*ZlyIG^7#3i=eT5u>o(ACh!8-lIO8_1 zVq|R>5bsNsx}Ztye024WFI_7Uk{;;;Q&;C`pcq|wWOG0zd`_xpYAWH$Y@Vb~^T44vgTSlYAGNx4tHD7l z!NZ&@6U*(kuIBAtsa}w66mAEoBdcoh`c*zgyN?R|sLZ9c5?L%(YQS}T;DDZ!uj8X| zw_*p6+s~OQLgSkwlvPYO+4g|=T*g42h`lA~l!e0H+8nC$RQm`p%}S2s;oTq)zqDks z5-Y687g-O|%?eeE z{PfwQM@grsS`uNnFvP07T=J}-Xi6AvsTAirJ-Y}E&pb#5@~gR`P(~Z`r;bKF@5pUV)7~` z-%(&0D7F}O?&Y^{5aXx|_hS-Ph7B4$yOIWx5cU!^lIru-A-A%GCkL9AGwAzrbpO4o z-Ty&6e{_Vuk$wGO6?oE0SVQFI8i;i~E8;^NJ34}`o)F#_5z#h!&J2fjW>$d2jVNlL z?6gLTEiwbrW<0S1i3#YJw0W#3FXe5(cM%}O!m7&CAkP$G2NL8V5RE9Y_(vPi5mA^x zzyLZmdy?x;6RI-CxSGE1M_o-jj~TQ5e9b9k+UHV@kadJ#MoCd&eX@pv#?PjZ__6i| z@mz$alNK|ip;j6q1~02nXxp(pCsIN+)#g41uRh{Al5>XGiWOdWlpBHkON#24y?y;H zIspUR2QMbBfR<$ z(?*Gy#YAP0Y5%Y(fX9|kz>H-Emg5A^m)3G81Ty)23Z4&npQ6&R?4kX7WbF)a&CTN8 z?Flv``O3h(ERJ?Zr5Vrg7)F|_+0oo%2i^Yj`g$||FnmY^;6CIV-FI%&2X8*72mjeD zW`v#Q5O-|MsdXcjWm;BmCfxH)5g+{wdiDvP&vzi+$;WdO7R%2_(oV5_p$oSr zpAW%jpgtq^^80H)U+hZDlaGg7BoDVXw0XQdR+YUSIE;f(#^)f|9{zlGkMf>)Ji_eX z!wLIbpvm&-T}5vC`OrfejL+IEpWHJ=C!Y^JB(~M|wc!@Wk9|ILYEHDj9_qmPGZWU& zHG00-RU9Xu51j|1Gi{p)GG)Am3tA+44+-~Uj-<^go=V510J@!nUGSx#{N=I~5T@O)u6%4_oRD3=x4(`}Yd+FdR;{e0*?Pz+3;hj~`$ zK2TkIR`Klw$8Rs7J^6g-K1f}(&HDMSML79*X5#qiHpegSAQjV(ht4Bn=Fuj!S6MEH zdp>j?2A{8uamnRe*1BNop#TwUEu$g=n{PPzeCR$vhp|% z!Zm6H2)+?z(S0av(>4n44?syQX{5mYXqEn|1NWD-;c@*Mg@10V*!9C&7?d|!rAO)c zB76SOe}MZ{veEM$Xmnd_q$o(=8l}JK{IThWBaL_r?;EY3-l^P9KOd$a8tzA{@HC}w zT>9aN|7af{cs{y!=spl<5t^0S`R60<1ES~HsQN7UKD;CD0~=Az%u8UeFKMNK{KFjX z$!W5q$TjjDW*->-H40zS`dQ9>I0EAm&9ARY_m?#<=spBghjgR;J%E!U3iOi>bN1QW`t!B2 zFIpT}KUBp8`Jh(SHDx=6xXI^3|KZ^LHNu%?C11{ec=R6*$J93p?+xD_^aKWss;7;* zN1BIGqo74V@iEgZzOr2W5=i=i@n56(AoKjW=R^M?QU0q7LE#A z&4n*}iI%zs}*2(9?{9`m*xD}0w$&V!Auqzy((#HR49(yX0#O{godmH~2*y5Tb9QKIC z-A3VQ=tkU5Js%;l%g}uJRAifjl91RnK3^mA61IX#&n1%BLxksR#RF3;bXO7*yTImo zv+#;5{z)XUhX~<)Xok&U%?ly1L;5BfQ5U3SH8Lb2u|xQryTYwxnwa!RN`k$D^Vf>U zsabG@BqVmg{;5XPfK0My?=ML|p!wDcnl0G!kVF=Hh~R!3(TKHXsYeo7?4Dqo8kIK; zpB@nwyF_qAqx913^f;!U5B-OF1nQ+@%WG0iiJ-JhY$ayRC|A?!fk9_MxzN-%LP|gVsqs1-){u zL|P2Hd?fimWMVVOrksCD*pL*#a}A$JGd@l1W0GEij~y0?+3gMdF^-2$F=uuG+HV7oo)bmjiJL2>j;Xou`=p-a|Jb#S}5z4c2 zlai3wF&2`I3bAqTwWgkr6vF6;={D|z1IbG}RR?QShzPv%B^371o`dMOjw?e@2773J zdGke)>d_GbJLxqQC6a!9RN!p1-rd1bD?`54P9*+{(+c&vA zO8}FEzaF59)2Ip|10Na?{yLT+8ZjU|--0Ln^?--3QI>D{9su&!1Gb>jgHLAB0+Z-u z9ZZ?%Wgan!_N*khbW>!MR#bDxgZL9I~`exTlrRQP}e(?&^tP7*jjPO0$NZfleT>I2V5+A)~qw-Y+$ToF>? ziIARTRKXRo^&(Gf9Bh49Iu-jg6(P3yycT|ig>8`ssK8 z;4(-*TIm)!RyI`4A6)#RD6t;)w~>EK{+GMI ziV*8zLS8Fo=>g`eBE))&!Yqx-2a;8dR)R1iK^44}Y^q@aO^Oif5!>BLR?ehl;hv8O zdqIBLYCLyf=YuLiWFawrZdA**TgBubicW{e^=stc9Lr2o$gB@2d)#X1qhW`3DZ;E* zct4s^tGM`75oSG5gH$77AbxtdBGchfSFT-p#8r0{A=YDf+Df<0vjboinGTP-MeTI6 zI7FBt#CpKfsaEFCv(z9Z-Gq5*1Q*ZYAG>}8PYmv(ReGsdJi8*qdV#IbW~%wT`NQ-B zQ8|s)FRQ+D;U6W|WBSpI_|NGUDKZ`&%P+0&hhxi=N=>!mWiwT4PS;S;@$g_@TH&!B zOXpF9STEa$&*}L%%%nnMy?>0MNphd{Og$f_9~#eJvzeZpaDt-DdX$ZBR34WspF$C4 zJr0d)B@AQ^>@WHcm@3hX`^wV=6=BvBUA|`Ra}IK^kXavqua)a=jrNyoFDN?G9nl+Y z;%CcO*9fy7G1;xE<2({hk&*5Sg$bHfH`wb-nDs~(Y?Qto@V*5Y9A5o>p z+tH?YVENiTA=cx}hE~D7;%m=@SZ`7Ez0K_n>_jm|c=gEEY9(qYS?G%*^V}h}SFNC7 za;v!53aRiRw9n0@XH{bqndeSai<*`0+1eFy;l0N7YZUvb1M5fFjG!6aY9eK1p>@g- z=v8~o_dJn^^B%~BC!({qQSRYcQA0%rx*OCiZ?t~;!2Ot*h$R|L9F>Bd$)N}rKEU%e znkfLdw=Ff1^3!UfQUbHQ1E^@6I!iASudTCbL<@mIU zkl___^_%5xY6yd`I@<6q+FP_yZQAmgnh|G4a!UHz? zb5l|(?KE*&_d!VP4#hUwY_C4h8FUk!57B5|x>9^)myp|D{lBH;8i1FQ{aKoPm*yN2)b4OffBiOFyachKjj<}{)^Njg-j z+EJ%@Z@)f&x%u$r;`(;CS^Ix^(tXwE%P;RPKiyq@yu5w-B>kuK?{`<1w_iQI_~rKI z<8ODDoANjMf82bzxx3ih{C4;8>hjC&voDt)FYc~>Cx3Id`?v3IzFa=zzUccOzW=Fw zQSEPj^Ww$N-~amM^0N9f{C}PGR@8 z!||3~-+WAe@XOWRKk1JBa`WkZ|3l9{|NZLO=i94i-(TL|{qytX?c1BXcYnWp_m9i> zf4cedb^4pnKYjRk`RelK`tt6}KcDR$;n_w0v*9aX59{xej^F0>=F8>#-`=GSNK5x@ zVja_`p8fjq>htG|U()yAUcJBE9ea4&tn^)d+5fuxa&__HlD=vB;Xhxc3-{&QPw%hZ zUEV(X@yo@h+qW-%c=pZ3-No}ySGPBJ>942PN)Pkp>fO)7qx|^C)u%VlF7EyL|GD~j zd-Lh*v{+Zy7k8K4-&4=Ny-82_!_|lM{QJLgk-r=sJQ=i&>Ss3{t5Z;+ei9KyFc1oefUIAS&Dq^6D9Tl-|_dnfA@}l%kI8C%m4f3^4Ih>*J&Mp z-hbxVa2fFwZ}-vx+|pdU`v?7*;!ohKe*5%~Pd9&js(#z$`;qmkU;STx`}mKa)BXEB zKlU%rvdv8Y^X1uKuJgbB>)FSv5BYP?vh}5(`N#ghrLFq(OZvim++N&VfBtxRclqh^ zHeK(|ygy6dm6m9C)zicO{PE_G(I53+^vjnY?%rSi{_IaTKmY07&*`#tMkoD+7cc%| z_Aj4q@vqkx@BVZDZ^K9be0lMSITru%@5S){$G`vaM?P(^?pL3Fz4>yz`{)1lZ~qst K$*$&zodf{Xaa@xC From 0837937148d1a601361299c4a150cee1789feeeb Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 23 Jul 2020 21:34:24 -0700 Subject: [PATCH 150/769] Removing demo using validation reports code --- .../java/demo/DemoShowValidationResults.java | 134 ------------------ 1 file changed, 134 deletions(-) delete mode 100644 biojava-structure-gui/src/main/java/demo/DemoShowValidationResults.java diff --git a/biojava-structure-gui/src/main/java/demo/DemoShowValidationResults.java b/biojava-structure-gui/src/main/java/demo/DemoShowValidationResults.java deleted file mode 100644 index 80001fd6bf..0000000000 --- a/biojava-structure-gui/src/main/java/demo/DemoShowValidationResults.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - * created at Sep 18, 2013 - * Author: ap3 - */ - -package demo; - -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.align.gui.jmol.StructureAlignmentJmol; -import org.biojava.nbio.structure.StructureIO; -import org.biojava.nbio.structure.validation.*; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Unmarshaller; -import java.io.InputStream; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.List; -import java.util.zip.GZIPInputStream; - -public class DemoShowValidationResults { - - public static void main(String[] args){ - //String pdbId ="3zjr"; - String pdbId ="3vtq"; - showPdbValidation(pdbId); - } - - private static void showPdbValidation(String pdbId) { - try { - JAXBContext ctx = JAXBContext.newInstance(new Class[] {WwPDBValidationInformation.class}); - - Unmarshaller um = ctx.createUnmarshaller(); - - InputStream inStream = new GZIPInputStream(DemoShowValidationResults.class.getResourceAsStream("/"+pdbId+"-valdata.xml.gz")); - - WwPDBValidationInformation validationReport = (WwPDBValidationInformation) um.unmarshal(inStream); - - Entry entry = validationReport.getEntry(); - - System.out.println(pdbId + " " + entry.getPDBRevisionNumber() + - "\t Rfree: " + entry.getDCCRfree() + - "\t Clashscore " + entry.getClashscore() + - "\t % Ramachandran outliers: " + entry.getPercentRamaOutliers() + - "\t % RSRC outliers: " + entry.getPercentRSRZOutliers() ); - - - StructureAlignmentJmol jmolPanel = new StructureAlignmentJmol(); - - Structure s = StructureIO.getStructure(pdbId); - - jmolPanel.setStructure(s); - - jmolPanel.evalString("select *; color grey ; cartoon off ; "); - - for (ModelledSubgroup subgroup: validationReport.getModelledSubgroup()) { - - List clashes = subgroup.getClash(); - - String chainId = subgroup.getChain(); - //String resname = subgroup.getResname(); - String iCode = subgroup.getIcode(); - BigInteger resnum = subgroup.getResnum(); - //String altcode = subgroup.getAltcode(); - - - String pos = resnum.toString() ; - if ( iCode !=null && iCode.length()>0 && (! iCode.equals(" "))) - pos +="^" + iCode; - pos +=":" + chainId; - - BigDecimal base = new BigDecimal(0.5); - - for (Clash clash : clashes){ - String clashatom = clash.getAtom(); - BigDecimal clashmag = clash.getClashmag(); - // pos1 icode A chain X should become: - // 1^A:X - // [MET]508:A.CA/1 #3918 - // insertion code: [ASP]1^A:A.CA/1 #2 - - String clashj = pos + "." + clashatom; - String jmols = " select " + clashj + "; color red; spacefill " + (base.add(clashmag)) + ";" ; - System.out.println(jmols + " " + clashmag); - jmolPanel.evalString(jmols); - } - - - for (AngleOutlier angleout : subgroup.getAngleOutlier()) { - String atom0 = angleout.getAtom0(); - String atom1 = angleout.getAtom1(); - String atom2 = angleout.getAtom2(); - - String anglej = "select " + pos + "." + atom0+"," +pos+"." + atom1 +"," + pos +"." + atom2+"; color wireframe blue; wireframe 0.5;"; - //System.out.println(anglej); - jmolPanel.evalString(anglej); - } - - for (BondOutlier bondout : subgroup.getBondOutlier()){ - String atom0 = bondout.getAtom0(); - String atom1 = bondout.getAtom1(); - String bondj = "select " + pos + "." + atom0+"," +pos+"." + atom1 +"; color wireframe green; wireframe 0.5;"; - jmolPanel.evalString(bondj); - - } - } - - - } catch (Exception e){ - e.printStackTrace(); - - } - - } - -} From a621a1c1142a987a1856afb2915d1fe0b6f6c928 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Thu, 23 Jul 2020 21:42:06 -0700 Subject: [PATCH 151/769] Updating changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 377e6fea62..3570f5834b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ BioJava 6.0.0 (future release) * Support for retrieving structure data with prefix "PDP:" (AtomCache, StructureIO) * RemoteScopInstallation consuming data provided by source.rcsb.org * The whole `org.biojava.nbio.structure.rcsb` package, a client for the now legacy RCSB PDB APIs (to be shutdown in Nov 2020) +* The whole `org.biojava.nbio.structure.validation` package BioJava 5.4.0 ============= From eb46527d0af581a3371ec1dd497f773d1b0fded8 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Fri, 31 Jul 2020 17:17:45 -0700 Subject: [PATCH 152/769] Removing another class for querying domains from legacy rcsb rest --- CHANGELOG.md | 3 +- .../structure/domain/PDBDomainProvider.java | 180 ------------------ 2 files changed, 2 insertions(+), 181 deletions(-) delete mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDBDomainProvider.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 3570f5834b..4c54d137b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,9 @@ BioJava 6.0.0 (future release) * PDP domain providers (depended on JFatCatClient) * Support for retrieving structure data with prefix "PDP:" (AtomCache, StructureIO) * RemoteScopInstallation consuming data provided by source.rcsb.org -* The whole `org.biojava.nbio.structure.rcsb` package, a client for the now legacy RCSB PDB APIs (to be shutdown in Nov 2020) +* The whole `org.biojava.nbio.structure.rcsb` package, a client for the legacy RCSB PDB APIs (to be shutdown in Nov 2020) * The whole `org.biojava.nbio.structure.validation` package +* The `org.biojava.nbio.structure.domain.PDBDomainProvider` class to pull domain definitions from legacy RCSB PDB APIs BioJava 5.4.0 ============= diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDBDomainProvider.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDBDomainProvider.java deleted file mode 100644 index adb7f2f6bf..0000000000 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/domain/PDBDomainProvider.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * BioJava development code - * - * This code may be freely distributed and modified under the - * terms of the GNU Lesser General Public Licence. This should - * be distributed with the code. If you do not have a copy, - * see: - * - * http://www.gnu.org/copyleft/lesser.html - * - * Copyright for this code is held jointly by the individual - * authors. These should be listed in @author doc comments. - * - * For more information on the BioJava project and its aims, - * or to join the biojava-l mailing list, visit the home page - * at: - * - * http://www.biojava.org/ - * - */ -package org.biojava.nbio.structure.domain; - -import org.biojava.nbio.structure.align.util.URLConnectionTools; -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import java.io.*; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.SortedSet; -import java.util.TreeSet; - - -/** - * Class to fetch domains through the RCSB's REST API. - * - * @author Spencer Bliven - * - */ -public class PDBDomainProvider implements DomainProvider{ - public static final String DEFAULT_PDB_HOST = "http://www.rcsb.org"; - public static final String DEFAULT_PDB_API_URL = DEFAULT_PDB_HOST + "/pdb/rest/"; - - private String base; - private int cutoff; - - /** - */ - public PDBDomainProvider() { - this(DEFAULT_PDB_API_URL,40); - } - /** - * @param base - * @param cutoff - */ - public PDBDomainProvider(String base, int cutoff) { - this.base = base; - this.cutoff = cutoff; - } - - - /** - * Gets a list of domain representatives for a given PDB ID. - */ - @Override - public SortedSet getDomainNames(String name) { - if ( name.length() < 4) - throw new IllegalArgumentException("Can't interpret IDs that are shorter than 4 residues!"); - - String url = String.format("%srepresentativeDomains?cluster=%s&structureId=%s", - base, cutoff, name); - return requestRepresentativeDomains(url); - } - /** - * Gets a list of all domain representatives - */ - @Override - public SortedSet getRepresentativeDomains() { - String url = base + "representativeDomains?cluster="+ cutoff; - return requestRepresentativeDomains(url); - } - - /** - * Handles fetching and parsing XML from representativeDomains requests - * @param url Eg "http://www.rcsb.org/pdb/rest/representativeDomains" - * @return The names of all domain representatives - */ - private SortedSet requestRepresentativeDomains(String url) { - try { - - //System.out.println(url); - - final SortedSet results = new TreeSet(); - DefaultHandler handler = new DefaultHandler() { - @Override - public void startElement(String uri, String localName,String qName, - Attributes attributes) throws SAXException { - - //System.out.println("Start Element :" + qName); - - if (qName.equalsIgnoreCase("representative")) { - String name = attributes.getValue("name"); - results.add(name); - } - } - }; - handleRestRequest(url,handler); - return results; - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } - return null; - } - /** - * Handles fetching and processing REST requests. The actual XML parsing is handled - * by the handler, which is also in charge of storing interesting data. - * @param url REST request - * @param handler SAX XML parser - * @throws SAXException - * @throws IOException - * @throws ParserConfigurationException - */ - private static void handleRestRequest(String url, DefaultHandler handler) throws SAXException, IOException, ParserConfigurationException { - // Fetch XML stream - URL u = new URL(url); - InputStream response = URLConnectionTools.getInputStream(u); - InputSource xml = new InputSource(response); - - // Parse XML - SAXParserFactory factory = SAXParserFactory.newInstance(); - SAXParser saxParser = factory.newSAXParser(); - saxParser.parse(xml, handler); - - } - - - //TODO Add methods to access http://www.rcsb.org/pdb/rest/representatives - - public static void main(String[] args){ - PDBDomainProvider dom = new PDBDomainProvider(); - String name; - name = "2CDG"; - - SortedSet domains = dom.getDomainNames(name); - - System.out.println("Domains for "+name+":"); - for(String s : domains) { - System.out.println(s); - } - - SortedSet reprs = dom.getRepresentativeDomains(); - System.out.format("%nFound %d clusters.%n",reprs.size()); - - try { - File outfile = new File("/Users/blivens/Downloads/representativeDomainsJava.xml"); - Writer out = new BufferedWriter(new FileWriter(outfile)); - - for(String repr : reprs) { - out.write(String.format(" %n", repr)); - } - out.close(); - } catch (IOException e) { - e.printStackTrace(); - } - - } - - -} From 99b0a0cb903bde1397392e3fbb859f29c7f357a4 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Tue, 4 Aug 2020 07:57:10 -0700 Subject: [PATCH 153/769] Trying to trigger travis build again --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c54d137b9..c2e4833414 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ BioJava 6.0.0 (future release) * PDP domain providers (depended on JFatCatClient) * Support for retrieving structure data with prefix "PDP:" (AtomCache, StructureIO) * RemoteScopInstallation consuming data provided by source.rcsb.org -* The whole `org.biojava.nbio.structure.rcsb` package, a client for the legacy RCSB PDB APIs (to be shutdown in Nov 2020) +* The whole `org.biojava.nbio.structure.rcsb` package, a client for the legacy RCSB PDB APIs (disappearing in Nov 2020) * The whole `org.biojava.nbio.structure.validation` package * The `org.biojava.nbio.structure.domain.PDBDomainProvider` class to pull domain definitions from legacy RCSB PDB APIs From 5c02fd797e7c372b1d88504657b81681738fe730 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sat, 8 Aug 2020 15:25:27 -0700 Subject: [PATCH 154/769] Fixed test broken after carbohydrate remediation --- .../src/test/java/org/biojava/nbio/structure/TestBond.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java index 1140a14738..d1b7b24122 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestBond.java @@ -68,7 +68,7 @@ public static void setUp() { public void testStructConnModels() throws IOException, StructureException { Structure s = StructureIO.getStructure("1cdr"); Group groupOne = s.getPolyChain("A",1).getGroupByPDB(new ResidueNumber("A", 18, ' ')); - Group groupTwo = s.getNonPolyChain("B",1).getGroupByPDB(new ResidueNumber("A", 78, ' ')); + Group groupTwo = s.getNonPolyChain("B",1).getGroupByPDB(new ResidueNumber("B", 1, ' ')); Atom atomOne = groupOne.getAtom("ND2"); Atom atomTwo = groupTwo.getAtom("C1"); assertTrue(areBonded(atomOne, atomTwo)); From 984295197677242b83fa3b6e3e36cb4a1edb6e23 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Mon, 10 Aug 2020 21:34:56 -0700 Subject: [PATCH 155/769] fix potentially unsafe access in ciftools v0.10.1 --- .../biojava/nbio/structure/io/cif/CifFileConsumerImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java index c6d232d52a..8820ef230a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java @@ -902,8 +902,10 @@ public void consumeStructConnType(StructConnType structConnType) { public void consumeStructKeywords(StructKeywords structKeywords) { StrColumn pdbxKeywords = structKeywords.getPdbxKeywords(); // TODO what is the correct format for these? - pdbHeader.setDescription(pdbxKeywords.values().collect(Collectors.joining(", "))); - pdbHeader.setClassification(pdbxKeywords.values().collect(Collectors.joining(", "))); + if (pdbxKeywords.isDefined()) { + pdbHeader.setDescription(pdbxKeywords.values().collect(Collectors.joining(", "))); + pdbHeader.setClassification(pdbxKeywords.values().collect(Collectors.joining(", "))); + } } @Override From b3221cfb59634a7ff060d07206aeab24ad91d573 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 11 Aug 2020 10:39:05 -0700 Subject: [PATCH 156/769] bump to Java 11 ciftools release --- biojava-structure/pom.xml | 2 +- .../biojava/nbio/structure/io/cif/CifFileConsumerImpl.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index 9dd47ccef7..a18a40f80d 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -21,7 +21,7 @@ org.rcsb ciftools-java - 0.10.1 + 2.0.2 org.rcsb diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java index 8820ef230a..7a8fae1e5d 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java @@ -903,8 +903,9 @@ public void consumeStructKeywords(StructKeywords structKeywords) { StrColumn pdbxKeywords = structKeywords.getPdbxKeywords(); // TODO what is the correct format for these? if (pdbxKeywords.isDefined()) { - pdbHeader.setDescription(pdbxKeywords.values().collect(Collectors.joining(", "))); - pdbHeader.setClassification(pdbxKeywords.values().collect(Collectors.joining(", "))); + String keywords = pdbxKeywords.values().collect(Collectors.joining(", ")); + pdbHeader.setDescription(keywords); + pdbHeader.setClassification(keywords); } } From e2b9e5a84b36073888d4afe2dd591ea9f2ab771d Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Tue, 11 Aug 2020 19:53:36 -0700 Subject: [PATCH 157/769] move to ciftools release that supports JDK 8 --- biojava-structure/pom.xml | 4 ++-- pom.xml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/biojava-structure/pom.xml b/biojava-structure/pom.xml index a18a40f80d..87b34d4dcb 100644 --- a/biojava-structure/pom.xml +++ b/biojava-structure/pom.xml @@ -20,8 +20,8 @@ org.rcsb - ciftools-java - 2.0.2 + ${ciftools.artifact} + ${ciftools.version} org.rcsb diff --git a/pom.xml b/pom.xml index 598cbe0a8b..274c482a7a 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,8 @@ 1.0.9 1.7.30 2.13.3 + ciftools-java-jdk8 + 2.0.2 scm:git:git://github.com/biojava/biojava.git From db3020600cd00c9dc153d4ee1db6a5118e2e7629 Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Wed, 12 Aug 2020 09:42:08 -0700 Subject: [PATCH 158/769] adapt TestMMCIFWriting for ciftools-based impl --- .../structure/io/cif/CifFileSupplierTest.java | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileSupplierTest.java diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileSupplierTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileSupplierTest.java new file mode 100644 index 0000000000..09b5017300 --- /dev/null +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileSupplierTest.java @@ -0,0 +1,192 @@ +package org.biojava.nbio.structure.io.cif; + +import org.biojava.nbio.structure.AminoAcidImpl; +import org.biojava.nbio.structure.Atom; +import org.biojava.nbio.structure.AtomImpl; +import org.biojava.nbio.structure.Chain; +import org.biojava.nbio.structure.ChainImpl; +import org.biojava.nbio.structure.Element; +import org.biojava.nbio.structure.EntityInfo; +import org.biojava.nbio.structure.Group; +import org.biojava.nbio.structure.ResidueNumber; +import org.biojava.nbio.structure.Structure; +import org.biojava.nbio.structure.StructureImpl; +import org.biojava.nbio.structure.StructureTools; +import org.biojava.nbio.structure.io.CifFileReader; +import org.biojava.nbio.structure.io.FileParsingParameters; +import org.junit.Test; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class CifFileSupplierTest { + @Test + public void test1SMT() throws IOException { + // an x-ray structure + testRoundTrip("1SMT"); + } + + @Test + public void test2N3J() throws IOException { + // an NMR structure (multimodel) with 2 chains + testRoundTrip("2N3J"); + } + + @Test + public void test1A2C() throws IOException { + // a structure with insertion codes + testRoundTrip("1A2C"); + } + + private static void testRoundTrip(String pdbId) throws IOException { + CifFileReader reader = new CifFileReader(); + FileParsingParameters fileParsingParams = new FileParsingParameters(); + fileParsingParams.setAlignSeqRes(true); + reader.setFileParsingParameters(fileParsingParams); + + Structure originalStruct = reader.getStructureById(pdbId); + + File outputFile = File.createTempFile("biojava_testing_", ".cif"); + outputFile.deleteOnExit(); + + FileWriter fw = new FileWriter(outputFile); + fw.write(originalStruct.toMMCIF()); + fw.close(); + + Structure readStruct = reader.getStructure(outputFile); + + assertNotNull(readStruct); + + assertEquals(originalStruct.getChains().size(), readStruct.getChains().size()); + + assertEquals(originalStruct.nrModels(), readStruct.nrModels()); + + for (int i=0; i l.startsWith("ATOM")).count(); + assertNotNull(mmcif); + assertEquals(4, atomLines); + } + + private static Structure createDummyStructure() { + Group g = new AminoAcidImpl(); + Atom a = getAtom(1, 1, 1, 1); + g.addAtom(a); + g.setResidueNumber(new ResidueNumber("A", 1, null)); + Group altLocG = new AminoAcidImpl(); + Atom a2 = getAtom(2, 2, 2, 2); + altLocG.addAtom(a2); + altLocG.setResidueNumber(new ResidueNumber("A", 1, null)); + + g.addAltLoc(altLocG); + + Chain c1 = new ChainImpl(); + c1.addGroup(g); + c1.setId("A"); + EntityInfo entityInfo = new EntityInfo(); + entityInfo.setMolId(1); + entityInfo.addChain(c1); + c1.setEntityInfo(entityInfo); + + Group gc2 = new AminoAcidImpl(); + Atom ac2 = getAtom(3, 3, 3, 3); + gc2.addAtom(ac2); + gc2.setResidueNumber(new ResidueNumber("A_1", 1, null)); + + Group altLocGc2 = new AminoAcidImpl(); + Atom ac22 = getAtom(4, 4, 4, 4); + altLocGc2.addAtom(ac22); + altLocGc2.setResidueNumber(new ResidueNumber("A_1", 1, null)); + + gc2.addAltLoc(altLocGc2); + + Chain c2 = new ChainImpl(); + c2.addGroup(gc2); + c2.setId("A_1"); + c2.setEntityInfo(entityInfo); + entityInfo.addChain(c2); + + Structure s = new StructureImpl(); + s.addChain(c1); + s.addChain(c2); + return s; + } + + private static Atom getAtom(int id, double x, double y, double z) { + Atom a = new AtomImpl(); + a.setX(x); + a.setY(y); + a.setZ(z); + a.setPDBserial(id); + a.setName("CA"); + a.setElement(Element.C); + return a; + } +} \ No newline at end of file From 937c37e86f3297338df33ad0d751a07a8d0b6d7e Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Wed, 12 Aug 2020 16:15:55 -0700 Subject: [PATCH 159/769] remove redundant test --- .../structure/io/cif/CifFileSupplierTest.java | 192 ------------------ 1 file changed, 192 deletions(-) delete mode 100644 biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileSupplierTest.java diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileSupplierTest.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileSupplierTest.java deleted file mode 100644 index 09b5017300..0000000000 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/io/cif/CifFileSupplierTest.java +++ /dev/null @@ -1,192 +0,0 @@ -package org.biojava.nbio.structure.io.cif; - -import org.biojava.nbio.structure.AminoAcidImpl; -import org.biojava.nbio.structure.Atom; -import org.biojava.nbio.structure.AtomImpl; -import org.biojava.nbio.structure.Chain; -import org.biojava.nbio.structure.ChainImpl; -import org.biojava.nbio.structure.Element; -import org.biojava.nbio.structure.EntityInfo; -import org.biojava.nbio.structure.Group; -import org.biojava.nbio.structure.ResidueNumber; -import org.biojava.nbio.structure.Structure; -import org.biojava.nbio.structure.StructureImpl; -import org.biojava.nbio.structure.StructureTools; -import org.biojava.nbio.structure.io.CifFileReader; -import org.biojava.nbio.structure.io.FileParsingParameters; -import org.junit.Test; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Arrays; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class CifFileSupplierTest { - @Test - public void test1SMT() throws IOException { - // an x-ray structure - testRoundTrip("1SMT"); - } - - @Test - public void test2N3J() throws IOException { - // an NMR structure (multimodel) with 2 chains - testRoundTrip("2N3J"); - } - - @Test - public void test1A2C() throws IOException { - // a structure with insertion codes - testRoundTrip("1A2C"); - } - - private static void testRoundTrip(String pdbId) throws IOException { - CifFileReader reader = new CifFileReader(); - FileParsingParameters fileParsingParams = new FileParsingParameters(); - fileParsingParams.setAlignSeqRes(true); - reader.setFileParsingParameters(fileParsingParams); - - Structure originalStruct = reader.getStructureById(pdbId); - - File outputFile = File.createTempFile("biojava_testing_", ".cif"); - outputFile.deleteOnExit(); - - FileWriter fw = new FileWriter(outputFile); - fw.write(originalStruct.toMMCIF()); - fw.close(); - - Structure readStruct = reader.getStructure(outputFile); - - assertNotNull(readStruct); - - assertEquals(originalStruct.getChains().size(), readStruct.getChains().size()); - - assertEquals(originalStruct.nrModels(), readStruct.nrModels()); - - for (int i=0; i l.startsWith("ATOM")).count(); - assertNotNull(mmcif); - assertEquals(4, atomLines); - } - - private static Structure createDummyStructure() { - Group g = new AminoAcidImpl(); - Atom a = getAtom(1, 1, 1, 1); - g.addAtom(a); - g.setResidueNumber(new ResidueNumber("A", 1, null)); - Group altLocG = new AminoAcidImpl(); - Atom a2 = getAtom(2, 2, 2, 2); - altLocG.addAtom(a2); - altLocG.setResidueNumber(new ResidueNumber("A", 1, null)); - - g.addAltLoc(altLocG); - - Chain c1 = new ChainImpl(); - c1.addGroup(g); - c1.setId("A"); - EntityInfo entityInfo = new EntityInfo(); - entityInfo.setMolId(1); - entityInfo.addChain(c1); - c1.setEntityInfo(entityInfo); - - Group gc2 = new AminoAcidImpl(); - Atom ac2 = getAtom(3, 3, 3, 3); - gc2.addAtom(ac2); - gc2.setResidueNumber(new ResidueNumber("A_1", 1, null)); - - Group altLocGc2 = new AminoAcidImpl(); - Atom ac22 = getAtom(4, 4, 4, 4); - altLocGc2.addAtom(ac22); - altLocGc2.setResidueNumber(new ResidueNumber("A_1", 1, null)); - - gc2.addAltLoc(altLocGc2); - - Chain c2 = new ChainImpl(); - c2.addGroup(gc2); - c2.setId("A_1"); - c2.setEntityInfo(entityInfo); - entityInfo.addChain(c2); - - Structure s = new StructureImpl(); - s.addChain(c1); - s.addChain(c2); - return s; - } - - private static Atom getAtom(int id, double x, double y, double z) { - Atom a = new AtomImpl(); - a.setX(x); - a.setY(y); - a.setZ(z); - a.setPDBserial(id); - a.setName("CA"); - a.setElement(Element.C); - return a; - } -} \ No newline at end of file From 35594ef4d63cf32cb9c3fe2ee79bd16ba8577462 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Martin Date: Wed, 16 Sep 2020 17:35:23 -0700 Subject: [PATCH 160/769] Add GFF3Reader overload that accepts Path The String-based functions are still here, and almost all the code is shared. The Path overload allows us to read files via NIO providers, such as e.g. the GCS NIO provider for reading files on Google Cloud Storage. --- .../nbio/genome/parsers/gff/GFF3Reader.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java b/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java index a0f5b573f8..e00fe42547 100644 --- a/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java +++ b/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java @@ -20,6 +20,9 @@ */ package org.biojava.nbio.genome.parsers.gff; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,11 +70,15 @@ public class GFF3Reader { */ public static FeatureList read(String filename, List indexes) throws IOException { - logger.info("Reading: {}", filename); + return read(Paths.get(filename), indexes); + } + + public static FeatureList read(Path path, List indexes) throws IOException { + logger.info("Reading: {}", path.toString()); FeatureList features = new FeatureList(); features.addIndexes(indexes); - BufferedReader br = new BufferedReader(new FileReader(filename)); + BufferedReader br = Files.newBufferedReader(path); String s; for (s = br.readLine(); null != s; s = br.readLine()) { @@ -103,6 +110,10 @@ public static FeatureList read(String filename) throws IOException { return read(filename,new ArrayList(0)); } + public static FeatureList read(Path path) throws IOException { + return read(path,new ArrayList(0)); + } + /** * create Feature from line of GFF file From ac475b70cc0e35140d789a0e7884afa70698ebd9 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Martin Date: Wed, 16 Sep 2020 17:39:02 -0700 Subject: [PATCH 161/769] Add Javadoc to the overload --- .../org/biojava/nbio/genome/parsers/gff/GFF3Reader.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java b/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java index e00fe42547..45cb1ed2c3 100644 --- a/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java +++ b/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java @@ -68,11 +68,17 @@ public class GFF3Reader { * @return A FeatureList. * @throws IOException Something went wrong -- check exception detail message. */ - public static FeatureList read(String filename, List indexes) throws IOException { return read(Paths.get(filename), indexes); } + /** + * Read a file into a FeatureList. Each line of the file becomes one Feature object. + * + * @param path The path to the GFF file. + * @return A FeatureList. + * @throws IOException Something went wrong -- check exception detail message. + */ public static FeatureList read(Path path, List indexes) throws IOException { logger.info("Reading: {}", path.toString()); From f8148e9953b07d53fdaabcfe5d5f3f7bebad292b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Martin Date: Wed, 16 Sep 2020 17:43:16 -0700 Subject: [PATCH 162/769] Remove unused import --- .../java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java | 1 - 1 file changed, 1 deletion(-) diff --git a/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java b/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java index 45cb1ed2c3..e1a5f03417 100644 --- a/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java +++ b/biojava-genome/src/main/java/org/biojava/nbio/genome/parsers/gff/GFF3Reader.java @@ -27,7 +27,6 @@ import org.slf4j.LoggerFactory; import java.io.BufferedReader; -import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; From 6c10910f7af7aeb96787c3d29350a789839e9943 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Oct 2020 17:34:02 +0000 Subject: [PATCH 163/769] Bump junit from 4.12 to 4.13.1 Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 274c482a7a..411aa6d1be 100644 --- a/pom.xml +++ b/pom.xml @@ -480,7 +480,7 @@ junit junit - 4.12 + 4.13.1 test From 62aebdcff6ab1c076b771efd4947aebc8ef76e95 Mon Sep 17 00:00:00 2001 From: Gerrit Grunwald Date: Wed, 14 Oct 2020 11:06:02 +0200 Subject: [PATCH 164/769] Added github actions After each push the build will be tested on Ubuntu 18.04, latest Mac OSX and Windows 2016 using JDK 11 --- .github/workflows/ci.yaml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/ci.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000000..b64e1fefb2 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,26 @@ +--- +name: Java CI + +on: [push] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-18.04, macOS-latest, windows-2016] + java: [11] + fail-fast: false + max-parallel: 4 + name: Test JDK ${{ matrix.java }}, ${{ matrix.os }} + + steps: + - uses: actions/checkout@v1 + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: Test with Maven + run: mvn test -B --file pom.xml + +... \ No newline at end of file From 14d8c20484eb5af69631693702db425e38f00aa0 Mon Sep 17 00:00:00 2001 From: Gerrit Grunwald Date: Mon, 19 Oct 2020 15:15:31 +0200 Subject: [PATCH 165/769] instead of running the tests check the packaging first --- .github/workflows/ci.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b64e1fefb2..55f99973dd 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -21,6 +21,7 @@ jobs: with: java-version: ${{ matrix.java }} - name: Test with Maven - run: mvn test -B --file pom.xml + #run: mvn test --batch-mode verify + run: mvn verify ... \ No newline at end of file From d58615d251c626bd3830ce23a72d3bb119cb6838 Mon Sep 17 00:00:00 2001 From: Gerrit Grunwald Date: Mon, 19 Oct 2020 15:42:26 +0200 Subject: [PATCH 166/769] Removed windows-2016 --- .github/workflows/ci.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 55f99973dd..80fcc2c29f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-18.04, macOS-latest, windows-2016] + os: [ubuntu-18.04, macOS-latest] java: [11] fail-fast: false max-parallel: 4 @@ -21,7 +21,6 @@ jobs: with: java-version: ${{ matrix.java }} - name: Test with Maven - #run: mvn test --batch-mode verify run: mvn verify ... \ No newline at end of file From 341f4d10365d8963aa83f5d2ec3612490dba0804 Mon Sep 17 00:00:00 2001 From: Shilpa Rani Date: Sun, 1 Nov 2020 20:55:14 -0600 Subject: [PATCH 167/769] Fixing the flakiness caused by testGetProteinSequenceForStructure --- .../org/biojava/nbio/structure/io/StructureSequenceMatcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureSequenceMatcher.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureSequenceMatcher.java index 3c884bbc2d..e3c70452a7 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureSequenceMatcher.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureSequenceMatcher.java @@ -119,7 +119,7 @@ public static ProteinSequence getProteinSequenceForStructure(Structure struct, M for(Chain chain : struct.getChains()) { List groups = chain.getAtomGroups(); - Map chainIndexPosition = new HashMap(); + Map chainIndexPosition = new LinkedHashMap(); int prevLen = seqStr.length(); // get the sequence for this chain From a6e15ce75dadb7511f6f962330f1d0fcd0d1886f Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Mon, 2 Nov 2020 16:35:47 -0800 Subject: [PATCH 168/769] Removing DSSPParser.fetch after RCSB deprecation --- .../src/main/java/demo/DemoLoadSecStruc.java | 8 ------ .../nbio/structure/io/mmtf/MmtfUtils.java | 8 +----- .../nbio/structure/secstruc/DSSPParser.java | 28 ------------------- .../structure/secstruc/TestDSSPParser.java | 10 ++----- 4 files changed, 3 insertions(+), 51 deletions(-) diff --git a/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java b/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java index 8684ba1257..6ab26831b2 100644 --- a/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java +++ b/biojava-structure/src/main/java/demo/DemoLoadSecStruc.java @@ -27,7 +27,6 @@ import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.io.FileParsingParameters; -import org.biojava.nbio.structure.secstruc.DSSPParser; import org.biojava.nbio.structure.secstruc.SecStrucCalc; import org.biojava.nbio.structure.secstruc.SecStrucInfo; import org.biojava.nbio.structure.secstruc.SecStrucTools; @@ -64,13 +63,6 @@ public static void main(String[] args) throws IOException, System.out.println("Author's assignment: "); printSecStruc(s); - // If the more detailed DSSP prediction is required call this - DSSPParser.fetch(pdbID, s, true); - - // Print the assignment residue by residue - System.out.println("DSSP assignment: "); - printSecStruc(s); - // finally use BioJava's built in DSSP-like secondary structure assigner SecStrucCalc secStrucCalc = new SecStrucCalc(); diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java index bbd34c9610..a571813995 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfUtils.java @@ -164,13 +164,7 @@ public static void calculateDsspSecondaryStructure(Structure bioJavaStruct) { ssp.calculate(bioJavaStruct, true); } catch(StructureException e) { - LOGGER.warn("Could not calculate secondary structure (error {}). Will try to get a DSSP file from the RCSB web server instead.", e.getMessage()); - - try { - DSSPParser.fetch(bioJavaStruct.getPDBCode(), bioJavaStruct, true); //download from PDB the DSSP result - } catch(Exception bige){ - LOGGER.warn("Could not get a DSSP file from RCSB web server. There will not be secondary structure assignment for this structure ({}). Error: {}", bioJavaStruct.getPDBCode(), bige.getMessage()); - } + LOGGER.warn("Could not calculate secondary structure (error {}). Secondary structure annotation will be missing.", e.getMessage()); } } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/secstruc/DSSPParser.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/secstruc/DSSPParser.java index 519aef812d..629dd66715 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/secstruc/DSSPParser.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/secstruc/DSSPParser.java @@ -28,10 +28,8 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; -import java.net.URL; import java.util.ArrayList; import java.util.List; -import java.util.zip.GZIPInputStream; import org.biojava.nbio.structure.Group; import org.biojava.nbio.structure.ResidueNumber; @@ -99,32 +97,6 @@ public static List parseFile(String dsspPath, return generalParse(reader, structure, assign); } - /** - * Fetch and parse the DSSP file of the specified pdb code - * from the PDB web server and return the secondary structure - * annotation as a List of {@link SecStrucState} objects. - * - * @param pdb path to the DSSP file to parse - * @param structure Structure object associated to the dssp - * @param assign assigns the SS to the structure if true - * @return a List of SS annotation objects - * @throws StructureException - * @throws IOException - */ - public static List fetch(String pdb, - Structure structure, boolean assign) - throws IOException, StructureException { - - URL url = new URL("http://files.rcsb.org/dssp/" + - pdb.toLowerCase().substring(1, 3) + "/" + - pdb.toLowerCase() + "/" + - pdb.toLowerCase() + ".dssp.gz"); - InputStream in = new GZIPInputStream(url.openStream()); - Reader read = new InputStreamReader(in); - BufferedReader reader = new BufferedReader(read); - return generalParse(reader, structure, assign); - } - /** * Parse a DSSP format String and return the secondary structure * annotation as a List of {@link SecStrucState} objects. diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/secstruc/TestDSSPParser.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/secstruc/TestDSSPParser.java index d79db697d7..57612fc8d6 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/secstruc/TestDSSPParser.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/secstruc/TestDSSPParser.java @@ -56,10 +56,7 @@ public void testDSSPParser() throws IOException, StructureException { List file = DSSPParser.parseInputStream(new GZIPInputStream( this.getClass().getResourceAsStream("/org/biojava/nbio/structure/secstruc/"+name+".dssp.gz")), s, false); - // Test fetching from PDB - List pdb = DSSPParser.fetch(name, s, false); - - // Test predicting, writting and parsing back + // Test predicting, writing and parsing back SecStrucCalc sec = new SecStrucCalc(); List pred = sec.calculate(s, false); @@ -68,13 +65,10 @@ public void testDSSPParser() throws IOException, StructureException { assertTrue( "SS assignment lengths do not match", - file.size() == pdb.size() - && pred.size() == parseBack.size() + pred.size() == parseBack.size() && pred.size() == file.size()); for (int i = 0; i < file.size(); i++) { - assertEquals("SS assignment position " + (i + 1) - + " does not match", file.get(i), pdb.get(i)); assertEquals("SS assignment position " + (i + 1) + " does not match", pred.get(i), parseBack.get(i)); assertEquals("SS assignment position " + (i + 1) From 7c888429f5eb0e76def176f87eeb4ac2c992c2cb Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Mon, 2 Nov 2020 16:39:29 -0800 Subject: [PATCH 169/769] Fixing potential bugs --- .../nbio/structure/secstruc/DSSPParser.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/secstruc/DSSPParser.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/secstruc/DSSPParser.java index 629dd66715..69e9cd6d67 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/secstruc/DSSPParser.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/secstruc/DSSPParser.java @@ -155,16 +155,16 @@ private static List generalParse(BufferedReader reader, //Parse the Bridge partners - TODO parallel or antiparallel? String bp = line.substring(25,29).trim(); - if (bp != "") { + if (!bp.equals("")) { BetaBridge bb = new BetaBridge( - index, Integer.valueOf(bp), BridgeType.parallel); + index, Integer.parseInt(bp), BridgeType.parallel); ss.addBridge(bb); } else logger.warn("Unable to parse beta Bridge for resn "+index); bp = line.substring(29,33).trim(); - if (bp != "") { + if (!bp.equals("")) { BetaBridge bb = new BetaBridge( - index, Integer.valueOf(bp), BridgeType.parallel); + index, Integer.parseInt(bp), BridgeType.parallel); ss.addBridge(bb); } else logger.warn("Unable to parse beta Bridge for resn "+index); @@ -175,7 +175,7 @@ private static List generalParse(BufferedReader reader, int b = a + 8; String val = line.substring(a,b).trim(); - if (val == "") { + if (val.equals("")) { logger.warn("Unable to parse energy for resn "+index); continue; } @@ -184,7 +184,7 @@ private static List generalParse(BufferedReader reader, int partner = Integer.parseInt(p[0]); if (partner != 0) partner += index; - double energy = Double.valueOf(p[1]) * 1000.0; + double energy = Double.parseDouble(p[1]) * 1000.0; switch(i){ case 0: @@ -208,15 +208,15 @@ private static List generalParse(BufferedReader reader, //Angle properties String val = line.substring(91,97).trim(); - if (val != "") ss.setKappa(Float.valueOf(val)); + if (!val.equals("")) ss.setKappa(Float.parseFloat(val)); else logger.warn("Unable to parse kappa for resn "+index); val = line.substring(103,109).trim(); - if (val != "") ss.setPhi(Float.valueOf(val)); + if (!val.equals("")) ss.setPhi(Float.parseFloat(val)); else logger.warn("Unable to parse phi for resn "+index); val = line.substring(109,116).trim(); - if (val != "") ss.setPsi(Float.valueOf(val)); + if (!val.equals("")) ss.setPsi(Float.parseFloat(val)); else logger.warn("Unable to parse psi for resn "+index); if (assign) parent.setProperty(Group.SEC_STRUC, ss); From b23e67bf8bc1a85347749594d261760a8b3fc0ac Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Mon, 2 Nov 2020 16:43:57 -0800 Subject: [PATCH 170/769] Updating changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2e4833414..00a530e652 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ BioJava 6.0.0 (future release) * The whole `org.biojava.nbio.structure.rcsb` package, a client for the legacy RCSB PDB APIs (disappearing in Nov 2020) * The whole `org.biojava.nbio.structure.validation` package * The `org.biojava.nbio.structure.domain.PDBDomainProvider` class to pull domain definitions from legacy RCSB PDB APIs +* Support for automatically fetching dssp files from RCSB (`org.biojava.nbio.structure.secstruc.DSSPParser.fetch()`) BioJava 5.4.0 ============= From 57c219b7e9a39ac09d7c32b1e8ea535649d362da Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Wed, 11 Nov 2020 09:33:58 -0800 Subject: [PATCH 171/769] Removing a test that now fails due to a deprecation in RCSB PDB --- .../TestDownloadChemCompProvider.java | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestDownloadChemCompProvider.java b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestDownloadChemCompProvider.java index bc2a8dcd41..2fc5ab2a66 100644 --- a/biojava-structure/src/test/java/org/biojava/nbio/structure/TestDownloadChemCompProvider.java +++ b/biojava-structure/src/test/java/org/biojava/nbio/structure/TestDownloadChemCompProvider.java @@ -21,7 +21,6 @@ package org.biojava.nbio.structure; import org.biojava.nbio.core.util.FlatFileCache; -import org.biojava.nbio.structure.io.LocalPDBDirectory; import org.biojava.nbio.structure.io.mmcif.DownloadChemCompProvider; import org.biojava.nbio.structure.io.mmcif.model.ChemComp; import org.junit.Test; @@ -47,39 +46,6 @@ public void testProtectedIDs(){ assertEquals(cc.getId(), id); } - @Test - public void testRedirectWorks() { - // since August 2017, RCSB is redirecting: - // http://rcsb.org/pdb/files/ligand/HEM.cif ----> http://files.org/ligands/HEM.cif - // see #703 - - File file = new File(DownloadChemCompProvider.getLocalFileName("HEM")); - file.delete(); - - DownloadChemCompProvider prov = new DownloadChemCompProvider(); - - DownloadChemCompProvider.serverBaseUrl = "http://www.rcsb.org/pdb/files/ligand/"; - - ChemComp cc = prov.getChemComp("HEM"); - - //System.out.println(file.toString()); - - assertTrue(file.exists()); - - // just in case the we did get garbage, let's clean up - file.delete(); - - // very important: we have a memory cache of files, we need to reset it not to pollute the cache for later tests - FlatFileCache.clear(); - - assertNotNull(cc); - - assertNotNull(cc.getName()); - - // reset to default URL or otherwise we could affect other tests - DownloadChemCompProvider.serverBaseUrl = DownloadChemCompProvider.DEFAULT_SERVER_URL; - } - @Test public void testWeDontCacheGarbage() { // see #703 From 9b2335e97da0789bd69ba3ea66022f838dda3fda Mon Sep 17 00:00:00 2001 From: Vidishab18 <71988063+Vidishab18@users.noreply.github.com> Date: Fri, 13 Nov 2020 17:44:18 -0800 Subject: [PATCH 172/769] Update StructureSequenceMatcher.java --- .../org/biojava/nbio/structure/io/StructureSequenceMatcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureSequenceMatcher.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureSequenceMatcher.java index e3c70452a7..3c884bbc2d 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureSequenceMatcher.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/StructureSequenceMatcher.java @@ -119,7 +119,7 @@ public static ProteinSequence getProteinSequenceForStructure(Structure struct, M for(Chain chain : struct.getChains()) { List groups = chain.getAtomGroups(); - Map chainIndexPosition = new LinkedHashMap(); + Map chainIndexPosition = new HashMap(); int prevLen = seqStr.length(); // get the sequence for this chain From 43f8dcdd80aab451c0b9ad86f8079aa9d3ee9646 Mon Sep 17 00:00:00 2001 From: Vidishab18 <71988063+Vidishab18@users.noreply.github.com> Date: Fri, 13 Nov 2020 17:45:12 -0800 Subject: [PATCH 173/769] Update MmtfStructureReader.java --- .../biojava/nbio/structure/io/mmtf/MmtfStructureReader.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java index 09d8ca58a8..fbdf9d3869 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java @@ -27,6 +27,7 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -105,7 +106,7 @@ public class MmtfStructureReader implements StructureAdapterInterface, Serializa private List chainList; /** All the chains as a list of maps */ - private List> chainMap; + private List> chainMap; private List transformList; @@ -178,7 +179,7 @@ public void setModelInfo(int inputModelNumber, int chainCount) { modelNumber = inputModelNumber; structure.addModel(new ArrayList(chainCount)); - chainMap.add(new HashMap<>()); + chainMap.add(new LinkedHashMap<>()); } /* (non-Javadoc) From 2cbb6c6813ef959dd4dc747478570cf2511da190 Mon Sep 17 00:00:00 2001 From: Vidishab18 <71988063+Vidishab18@users.noreply.github.com> Date: Fri, 13 Nov 2020 17:48:55 -0800 Subject: [PATCH 174/769] Update MmtfStructureReader.java --- .../org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java index fbdf9d3869..6385b92391 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/mmtf/MmtfStructureReader.java @@ -106,7 +106,7 @@ public class MmtfStructureReader implements StructureAdapterInterface, Serializa private List chainList; /** All the chains as a list of maps */ - private List> chainMap; + private List> chainMap; private List transformList; From e3bad37bd4bc39bdec3c70d1d76bc98acbec46bb Mon Sep 17 00:00:00 2001 From: JonStargaryen Date: Wed, 18 Nov 2020 15:10:30 -0800 Subject: [PATCH 175/769] detach mmcif.model.DatabasePdbrevRecord - replaced by DatabasePdbRevRecord --- .../nbio/structure/DatabasePdbRevRecord.java | 43 +++++++++++++++++++ .../org/biojava/nbio/structure/PDBHeader.java | 7 ++- .../structure/io/cif/CifFileConsumerImpl.java | 22 +++++----- 3 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePdbRevRecord.java diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePdbRevRecord.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePdbRevRecord.java new file mode 100644 index 0000000000..91ec85549f --- /dev/null +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/DatabasePdbRevRecord.java @@ -0,0 +1,43 @@ +package org.biojava.nbio.structure; + +import java.io.Serializable; + +public class DatabasePdbRevRecord implements Serializable { + private static final long serialVersionUID = -791924804009516791L; + private String rev_num; + private String type; + private String details; + + public String getRev_num() { + return rev_num; + } + + public void setRev_num(String rev_num) { + this.rev_num = rev_num; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + @Override + public String toString() { + return "DatabasePdbrevRecord{" + + "rev_num='" + rev_num + '\'' + + ", type='" + type + '\'' + + ", details='" + details + '\'' + + '}'; + } +} diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java index dbcc0f794c..1071c52c23 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBHeader.java @@ -20,7 +20,6 @@ */ package org.biojava.nbio.structure; -import org.biojava.nbio.structure.io.mmcif.model.DatabasePdbrevRecord; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,7 +76,7 @@ public class PDBHeader implements PDBRecord { private Map bioAssemblies ; - List revisionRecords; + List revisionRecords; public PDBHeader(){ @@ -663,11 +662,11 @@ public int getNrBioAssemblies() { return this.bioAssemblies.size(); } - public List getRevisionRecords() { + public List getRevisionRecords() { return revisionRecords; } - public void setRevisionRecords(List revisionRecords) { + public void setRevisionRecords(List revisionRecords) { this.revisionRecords = revisionRecords; } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java index 7a8fae1e5d..a3af75fc91 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifFileConsumerImpl.java @@ -7,6 +7,7 @@ import org.biojava.nbio.structure.Chain; import org.biojava.nbio.structure.ChainImpl; import org.biojava.nbio.structure.DBRef; +import org.biojava.nbio.structure.DatabasePdbRevRecord; import org.biojava.nbio.structure.Element; import org.biojava.nbio.structure.EntityInfo; import org.biojava.nbio.structure.EntityType; @@ -30,7 +31,6 @@ import org.biojava.nbio.structure.io.FileParsingParameters; import org.biojava.nbio.structure.io.SeqRes2AtomAligner; import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory; -import org.biojava.nbio.structure.io.mmcif.model.DatabasePdbrevRecord; import org.biojava.nbio.structure.quaternary.BioAssemblyInfo; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyBuilder; import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation; @@ -97,8 +97,6 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -// TODO detach the impl from the redundant mmCIF impl - /** * An implementation of a CifFileConsumer for BioJava. Will process the information provided by a CifFile instance and * use it to build up a {@link Structure} object. The implementation is for the most part really close to that in @@ -144,7 +142,7 @@ class CifFileConsumerImpl implements CifFileConsumer { private Map asymId2authorId; private Matrix4d parsedScaleMatrix; - private FileParsingParameters params; + private final FileParsingParameters params; public CifFileConsumerImpl(FileParsingParameters params) { this.params = params; @@ -624,7 +622,7 @@ public void consumeDatabasePDBrev(DatabasePDBRev databasePDBrev) { @Override public void consumeDatabasePDBrevRecord(DatabasePDBRevRecord databasePDBrevRecord) { - List revRecords = pdbHeader.getRevisionRecords(); + List revRecords = pdbHeader.getRevisionRecords(); if (revRecords == null) { revRecords = new ArrayList<>(); pdbHeader.setRevisionRecords(revRecords); @@ -633,10 +631,10 @@ public void consumeDatabasePDBrevRecord(DatabasePDBRevRecord databasePDBrevRecor revRecords.addAll(convert(databasePDBrevRecord)); } - private List convert(DatabasePDBRevRecord databasePDBrevRecord) { - List revRecords = new ArrayList<>(); + private List convert(DatabasePDBRevRecord databasePDBrevRecord) { + List revRecords = new ArrayList<>(); for (int rowIndex = 0; rowIndex < databasePDBrevRecord.getRowCount(); rowIndex++) { - DatabasePdbrevRecord revRecord = new DatabasePdbrevRecord(); + DatabasePdbRevRecord revRecord = new DatabasePdbRevRecord(); revRecord.setDetails(databasePDBrevRecord.getDetails().get(rowIndex)); revRecord.setRev_num(databasePDBrevRecord.getRevNum().getStringData(rowIndex)); revRecord.setType(databasePDBrevRecord.getType().get(rowIndex)); @@ -1297,14 +1295,14 @@ private void addEntity(int asymRowIndex, String entityId, String pdbxDescription } catch (NumberFormatException e) { logger.warn("Could not parse mol_id from string {}. Will use 0 for creating Entity", entityId); } - + int entityRowIndex = IntStream.range(0, entity.getRowCount()) .filter(i -> entity.getId().get(i).equals(entityId)) .findFirst() .orElse(-1); - + EntityInfo entityInfo = structure.getEntityById(eId); - + if (entityInfo == null) { entityInfo = new EntityInfo(); entityInfo.setMolId(eId); @@ -1320,7 +1318,7 @@ private void addEntity(int asymRowIndex, String entityId, String pdbxDescription } addAncilliaryEntityData(asymRowIndex, entityInfo); structure.addEntityInfo(entityInfo); - logger.debug("Adding Entity with entity id {} from _entity, with name: {}", eId, + logger.debug("Adding Entity with entity id {} from _entity, with name: {}", eId, entityInfo.getDescription()); } } From b4ecf191199c91e2fe2f2ec7c25144de30dbfdc7 Mon Sep 17 00:00:00 2001 From: Jose Duarte Date: Sun, 1 Nov 2020 13:35:04 -0800 Subject: [PATCH 176/769] WIP: start of pdbstatus rewrite --- .../org/biojava/nbio/structure/PDBStatus.java | 240 +++++++----------- 1 file changed, 85 insertions(+), 155 deletions(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java index dfb95eab8e..1fc54f9410 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/PDBStatus.java @@ -23,6 +23,8 @@ */ package org.biojava.nbio.structure; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; import org.biojava.nbio.structure.align.util.URLConnectionTools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,19 +45,22 @@ * Methods for getting the status of a PDB file (current, obsolete, etc) * and for accessing different versions of the structure. * - *

    fU1~5Y~PB8Z@LM6%uZ5mDf~?djS9^KVA3(-YPqLw8FR8l zh#$La14g_GFjofOrVbbIZHkM*Bu+UbAZ5&MTV$!WfQ;fCYDj5RzNU&TofFVVXN(y? zE}a^O)r*Epx{dd9djZZ2q~s)(<$n-FT?51n+l79US^a+A?$Dxgu*q3=JDZ5n73TiDLXh*#(jGdkj%ZKuh!33UE+Vj5syO5E)gdG#_TX8V?p$dAC5kNArY zsvq`LV#FrKX$+X4+Lt+7(Kxj_T9b(p3oK3I$m@jSk5{>+%YUoD0%&;xf+x!rbLoCF zF#?S-w&9B$N5v5e4ZGcnKxHzc*bV@dI&Qlp&ot!@MC`~jq;IT+SGvu1J@z14O-un} z`$%A6QrLKxfk?O!q$(xkgK!M9@IX?R%GYvd4oyA8@I04C7@kF!+VjJY#w>t{8`#{Y zW?lKQhvqm-f7HQK{i*f#O^|fA(;g3qg*cllKa=pJhNPprAg9BO&SS*@CB}Nb5TMAN zcv7V|Ly~a^*n?#eMJ&9T9Ok3#sWE{~lYGpIX?Zj^3DbkKWqdY16Ctg--5=m=*&OGe zQ}uJ?a(Lixsumn#8^qY}EMe!S#D-@&5X9Kl5Mu+T)*&d7U#VRIZ$=oMJ% zBBVyG7#)fxdWBF${cP<1J$DOWS5BQst% za8dQU7ii~G5`ncU35O?u6_T<=cxTumXz@t$ip;LmgE=87wcWn@GgM4$hMtKTG62Rp ztj$HezQ>Yn0e16f8L$%BD%)aHM0`iL1x4crpTDqCY{HbRLxXOMic+SwpxY8vl};s= zY;v|nE1atuE(3GtZ1O=*R*HweoKsyBY(gPT@hu*Gn{-@_iDR}K9>68GQbp2nmm*?{ zK47kOT9-m4Jd`9n-1pqyArw4~_9l4K7Q0OieFH zh7P11F9`b@^NzBj#px;wnDFQ_vIP*hM zUT`?IGi@V$O_Ne<>PHwIKr6A`m5J@cvvLliS~$>Kq>jA3BtWSb!PX;Qk`nstR zU4?Hz4>q~C0TUi?van4YXVGYpeM)%HB7@%RJe7S$N&<_9SE3{c!sRkd3L3&Box>z` zYR0pXg$zIt6uHTAjK>*wKrEyeRSQXg8p8Z&DKKrK{^F*4eb?I$Y>Ib*+Alt59kg_b zQ8+DKK311kRCs}`1535-YA8Nu9Sdd(X-I(BQTWFau^2aujrR_Cf^4~zP_;c!wMiB~ zPf+@Q14-ZR+3iwOvUjv*LzI$@VKlp@=ZWk5b+^>NbpwCd6nal z522v*3e=1fQJ6b|vO<*}G&ME45zAiZuCA4p!|~b zE;PSSR5!$lC=Pp2M9Ub@P3p;t)aq#qcB{yR&kF4o02BjV)l?E(5yKLgxM--6LET0R z_KTtQt6N{(>5l+sKLq1@GY#Dd3%>g5FUe3UVS-DVpz<{&A#MqHLh9^um zO-tMa7?x9Lk-Sc-JL{oYEHqTuKHz}n5!`csSIZ|}QEb@2Zm03QMOZT6_^WCrrd^@u z;O)z125#jC8)&}|GYb#w!(IIyKGq#~dsUdb67ez2VyO7^j)NrQt)SEr2)aDh(RhUD z%`0)A8yRx~O;QmV1mrv-ry`0?MW{;q;XyC39_#^%GE=!Z;m0CpB68p!RCA1?<`~1& zu2FJ~GMw@x#swRaU75V6S)icyq#|u0hslCq?}ObrfqAJ1{ku{Zz^j*sE`X!Q+~gl^ zm~(TS%5049%OX}$x^jAL!^zZuZAjomBg_gS)x#mcNCFR8i8SC9hpOB>e|8#PIP^q__DXMK^$Z8pEE~gpY|3fv84kHmWFc>b0uG1-TG!e~&{~8uqFjXY z$0Kxaktem((TbT$QAf+1TJGDTL=%vmU_yqom2Mx2Go-AUwEy6|a-a>X7U}j)*a-@= z882Il6(ocegD7p5v@W0?oo<=#x=ATY@6}IIhdJ^S*yN4WqQoF8R~98J=&(3;*kd_H zs>x4>y+%R~FAsFXI9%}wFsLALAam+ql8E53HaZYyfJ)dRa|l58p)LKMW#And&)c0O zENzkP*2yjLo7`nF%_yGT5i|fO)yy;!gD%}=;(G~ed1&DOZ#4!HLJgNm+KwHuL8l-N zCSPSjfkCDbb}b5j${0kZYGqupYBk1D?6ktBnSzvPnPv(G?ias+au{}wdB|yi?u@_q zDNxH%dlWodWW*<+PFTeco%tS5NbdhpweW09j?@_WlXkK!>Y~KT;h7pL;h8)&$5;_% z_i*nm5tYp$i{SZK#D}Nc?e>c$-xUYGB7r8fOcUCoE;l-Sg1-%rWi$^R8?Y{i!wksW z7u7O^dm8}4lSX0a$=06jx&MJ&)?AsR07Ow-YuxWaDY$3~e^U7hy+UR{4BZpHLkDo# zL+kJgz4nwZ54XOZ(zj<-^Nx6{ZiL~XzkA{;| z&5cq4Ak|JyB*}Sj^WW(atWCJEl`EGy zSwIDl&iX;w00Nq{bg^vWE*+6ZfFWgi;1X$491x<+qXQ)_q0(s*d*}8jvb>&fRy3Is z#@emF;%1RXha+L~nDdA;H!z{L8ij^O*n(4Lo3IuEP^B(Wo4XNNqbmkLZVXpdxzAXf zYA?1y{=&{@g0#a7ZD8vn1o+ESgl}#az#o|>wWI|xZ#)lUdy|K;0m>m27Ne!zxgZNY zCHGZEj;-TMIk7$NRM+n?cUor;JT-_ZQHipU7Q-HwsC6Pw%wlEwr$(C z+qd7}yw6|R*=r`rWUa|0E7$#rdcN`yLWw^|2Bmx?#jhH^L=n?rQRG3WI0@!$6|Se( z7g_F8n(*dKe83)JDG&$MxiIwjSQx{W$dW`&ttkvUE-;EmEdgIL!H{a{vY99lMC_pkdDCZqCjI!q_7 zt*VI*w%)|cAd}hQ0=ZmFonX3jL8UQeUA#i*i9N+s&uk~APOgt!%@4vGcm;Aa+d0P4 zVP29fvP-}I$tIO~2dC_Ra$~cc5b!W&LoLY0fXu%Ude-hC&1vN4F3cW;M4*Y`8Y36g z19wM;YnK?vEKA&SAGt8a&&qf!brG4`JdB-UVVj9l93LkD_h;mgaqOg`m)EAC!FI@6 zOJ;N&BG#CJ^ew=2Tnb@AhAX2QNNj;}7Ia(zFL)+#@Rs2^kkOyyN%`n~(#W_wedx?U z(u?-+lhfR1;4huodC3x5^WBSai}_u>_(3mr-hLF$kJdJ0CcvW;B@j$gY`-sxk>u(e zv9~N(s0b*PDG4NG@{*gG=0YVlgR>nMM|G-3UmnX>;;nV$8<2D`;-g;z;9f3#&xFE( zAIZrg&4{L?ftAQIPz>ZCPB>QEapL~e9BqncBB3-=@}G{!7uycnc>g#?I2d*ii9xa^ zfMAE5F9v;g!VG|dG!8vg99ujLRe2!g9T;#JZKa_(nf4b|J6(+YNQz(Nz7!TXVFE*> zg%;YA;rL<;t_Qx{!Y0mMzdN2&_1y{uKW!77lVND@z}#gD%{cxL>Xh_OESeNQbs(cm zv`fp)F8)iP#uWZKgJ@m_++rN zQOSZxtoW*b7O_+a+(ZqqpGjcN^_-dtFM8Bey*io$YBa1B96?sR*T$uFs=Pz-0Y`r` z!t0e=xI8*%Kh^^^>xP>o;SMDJ5N?nS)LWS=YlIUUAda*EngY;fOHdJ0-@}|H!W&T` z!8s1b`=#Ks@_|0>nE^GrBESy&UglggqmYFDa~+J9VxmoBoRps8XzO`O~+V~eZ3a7)vP=-XmX z(a0~%)>+Mf&0mgTCsZV|`vX3^^2b3_T7QF<=}=0m?N&o zBV67)sXO0QP5oEL)q=^3+zs*`Vil2!Q}Ld7J&Mkhcidl~YRz!9e@@_066@9_*b-9A zx>?vQ*2J9bJGkti69$u(m@;6ooH|EAV8{GDmr#V!B4a zq48v6y^BJ%lC&V`mOB&*se53-=je;sQMj1^%v9r3 zKD8~E-5qK!UUo5LHa|b>d$Y8L){_+YhdSP-i;u;Ut!#Fp|*OtH^C;LeH25L^E3W{>EdO45Mz?-5BRRuiO|EM zi;%J2$shZ8PvxVJF7I2CEA+SPU#74^h=r4s>owcfza3nNM~jP_7h3+1suvc~aslQy zhlP+^bI~V##-p2wp;z~UldP&sv6Phx>RDz$_3tQgGqMO&&m7uwwQCn18{$WAtpfz? zM7-CTSrr=5A%2IU{t*G8H7|!H!|w4DMS4vq%)yCW z$hJ}%TMy!Y@G(^^?8-)K3vjJy7d;QK4YyKfKW8|IK(f8&ujy zG(D2Ki{oD6#{Y}(mX!X8IJDPH~Q5mengzI^3 z;R!&}B6k$~ngwPWL=9mDBy3)T-ez{A8LmB&-UbKXfVr-3#_cj~DP+d1fX$TQWK&>@gD;^A+=^v(Z}2XH!y|>0XrxmG0>veun3bcL4ipJT zN_iP9>B!|1CFq##m9K~GP1ID40SJArb9UV=#d1-NYD}n>ReKBdEm9x*OdnX&hQ9S9 zljdZ*F#*~^u+Rfzof6k(#-KjVF!z^|t!S3xR@OEKU13AGf;b=#t6nnVwcrg*;%uuT zTw)O0jHeVq_S&@(c&v)1c*j@^DsZ!#>>fd5`@+nzOhpl$!E?H^p%AfLs&%#p*)UuN zkqGjw6@}6JfCKp*i%fl_9aI_Tk5Gb!1J~5$>=Be)GSlOMEW$ZlNMY0*(xueV7B#TT zl8#*)`)E`Ad7!mp2>+ll2+w76Un%Uxu}MF!E(z0^vn^oa>BA`j;BstHU2HQgXb9?6 z7yiy^kXbW&unsdu3^m8hDspD3U8_ly_Qlivr6&7|Zb=+}WjOuzUCtFczW+W@+F0}OY z;%A-_Nq^P!R`muJqCKBlQ_JPTa!FWNZFgxgc82A~kLk;VDf z)U^?8IR?iRB7={vNyVa_(9Zd~?c_SzbFK7H(c3-K(M4_Q)C1*7BrA_V$Js^&AA3vJK{ywgI&Vmk$ty}?S z!^>l~95G-{8!J^xt0eMW6-^ftxtj!V1TA(geUS&tX*^wT$|Dk;XN-3pfgSaL zxHD`+ad2r)&4XhycMoPyijXUaL9fKCxT4$;NOGCGr8JA2G4G^Ky;G8~G>IiLShdiX zF_uWphve4SV{}Mc*If_EU}*ks`{1NMm<)N=>u&$r|18=55-sZB*ZscjZzu3hC(Q5v z{&*N)UVhIKMMeL*(FyjM%lY~=`9RnvN9#QM3^LM9h`B!-JpZtNveS{mGQ?)|D#Z_v zpISI~Qo(U5PTpt`l}8!>b0svalj8mKxagGoI6lI$ZgBbWd>HoYU>y z{`C=-xqI8M6BbcV!}aCJ^yTPo&pBYgaB)w-v7GbM{`oAxS5H19d)t3C?d&=B!tm`z z(EZGKAy{kH;kU)gtDcloQ6TE_*jfwZ;bvpS`3pVAQnlal@V=gg?SI=#ldRgh9DJU4 z+}vw@t^I>(%u;ym%FN2EB5;$Zv>-9E1~3Quo^RHZxUOktI?~YXeMv7-&%RjL`5$_u z67p`ty+L{BB*(JchKq^0qzM`B&L*h7-!Ix8ck0{!V@_y|Paq)9Lg>VQB=fd4T*2v` zhTC)t*WouA;^m!{jnAWhKOZzW*^XD1&oh7HMDfE;kN?15dq3QxU#F~z5oBz2_6)Cc z-h*05K5Y%3^VOx|3lQ)oQEk*_$nB1S|9)|YJl=K}wc{DHzEdN&4Gk3Eg zY!52v>>hgg4IIo9I~iVpkF7eo38+_mCwqrnpTiq{>0DQxpxS_@JLFM z=~zAoV@rI0rUu)r7%CZi(;bC*lIYTJcl$pe`KYAj?6IDm{gP4N3Px6|YfUEav8AA)xSMiyn(VkTJ(sqk zo9-mFNR8p@{j*R76AGU_?rE~r^bh9~;g%k=;rokgH#a+W$8BVwb??7^#Ov$T#pbH& z2XY98tt);%04<^IV~^=`4S^7p=1_sWP5|sSgAHe+OdGfj(NB;&8}^x6HF;h(3T zs+fmVLGYroN2{P`)2mj39Tm?J!U`*_;XtLK*~r}2&&kZFvo~CCJwmgzU^Ad)SJvZ_ z{{Q*D@>8{C2?zwin1nMY0aPD>krT>Fi6HrN9P-7=vme|?NYFX|jAl_ysI8YX@YuS) zwT=DkN?)hG9P$NvNHGxibhz-|e)y*L)|L5?h~zT`fb51 zXZ1Nm3dO?Y6ym$R?=!S5;^M8wa$L}JMmR%b*W0SC%lQY^HBO&w3+6E*i?n&_3BakB z|6>sJ^j+J^-}SD%^=j7M=DsaEx~LcZuBiWxD%aDw*yd%+ZR3CFmV}!3x*Kodr|(WY z*+v~;$eVx8q99ZKIX*a{D)}#wDVF#0ACX4qqqn*Ma)0w^-n$Qp{E@+8=c6jZaF2a` zjsH$N>l6DQhRb#FzqdvHghVR4s^{OmYV8Kz&bj{jI@sXQ&?3n4^S65AKUR1(zXLdX z?FeK-c=o%5UxN~C)5Lchbn8SsEK}bm?e2jFeSuy?SjCfTfq(y~9K>&y9Uq=u$O12e z+y9!52&LB{zY|O-T3*BqyblNkEYcLZqP-0E0b(k2CojqLFTpGBgFmD%B=Ds{jKUnw z^UwHW70S0<`QOGzgD;}@VV^%=NSyDof!z=)J=Z_ouTI|1ucV=Og8IGcu@v$pN5sDh zM__sxLH%wr<)cQe;9C6b*s97JwjON3t%j$8}VNyaV&n2%f zJ-I#!GY4ecKbxy2zS1D|?CQb?sA_B<0i6`7w~8-=gD$4QyLEx{?jF z{|&d>6x}BUx%~XaN1`tZvG4c1CzXb?H`*5jQ!&?f<~NT1!D&w1;1SoxiE=#(0pyL> z`jKxDPY$OF+uGaupF*`#hKIf5(5%CY2(nkC@@$vA<oZ6E zjS%cMf-cm~w&XgaSy2^pK%lsNjVciHtX}s&*Qk~C5rW^3Z1V#P?QR0j6A8?}KDj0Y zSf$HZJ-3ryEH^%#lRiWmBgcM+bvLcPExmSGc^=Mm3wc&+kxx~j{OC{?tiQg*C~W}G zB3Dokftl{zQtaj7ZgZ~Ux{bGRAe{_YPE7@QZ56$K21^uf91KW%xF5|G;PSZ1APZl9 zIPVi+4t0m+#rr&j=a3QPK<7{I*rD2%e2B>Y`46Oj8xVe94psvyzY#@qdiUSYoxUKF zeHb8gzPid$e0Z}3o<3DyRy*G?uF7no7EB36G^|U$m`9gP!OjT4LSB_h-r_c)mb!Ak zF>8GO>nZdx_3-!<;Qm!XGxKskZXe#Jg@WW4QKJ0}av35S3_e=>) zsd!E$CP3~MA5|Z`_6DyKeay(eP)dDvkbG=*1*!qxhcB!CCj^87P3oQ&D_^`s)UU%c zW!|I{tTk0_{Br~r?K#~m0+Zf)l?*F0pC3UU{~*l~2A@9pPqp-CiG+&fe7U1)yz<{m zZH98E{Yzm8Jql3%5{7te5!~V;kxARz<>Jsmzx_Z@oQ!2N$Zp z&J@FfsTu@X*l>%V-e>5zZ8VBHzOv(&LD|wxZ$zbSKrbAdRPQar-^k9uq8xwo5_sRG zbK3-aPO4MdVvH8g!BjDPA0Nx*5uQEu9tc1_Lav$)^E2-jbL3bj2eZPuzkCvR)ecM)&CgYjK1@R?~i zqxo&V18~NPyiXhWv-zkbpSwigm#My3cm`h)E}|uzsb(wQMXpgzziW850^VYivlfby zNwAWC1__hCt8~eSl#LHwm@H(|Cw;fRmX`B*SApHe%^Z(hBxBk zZp#_cY4q@!M9GUTTxDA};pXj(4!e^f2F&!ZPa#kCfkf8bHWUBO2jpqAdg%9RpXZk8 z{I8jnIbrc^P0T#+v(#1RQuNHkBEqUCh$8>CBoK(H-*IXliRtI6(&&{7-9P^$YZ0|6 zO|BTFH>_F8s_~G$M<@9sFRH!kD#v+Kv|dM4Jq3=fg;^l=B2T5xsd?CmXO$|~q9uFz zu$eBvTrBV=MKr7>s6E;IWEwsXDtGv5{;4*EW@sdptmyPttB}7|*g~oN*=3>TL;PGf zq%3LG6XhWh_vW@oyw{vX%xIsT5zW(SLHG|8E~FJYYXra0HdUE*IoE=sJ-T8rHy&2f zC|;*Tmp>EdRF>^Esz6!cy3voWKm*8@ywkiG;#(U_P;J}XvQQk7Oko)7(6RYOPZJo`aHY zxS$mAtGejTSFxd}+1$GSvM~CWtdwr;7*#!X{w_)Z54t0Sx8>^Nm4XquG-GV0HARg5 z9X;*RWpL^}SoFu(VO#y-(C6Rx!v$|-+2_mk_K;5uO5nbbo6r51!t~eqrvQJ90F2hh zy(=St3wvR@d4IdTRctwsnvvX=9lhq-*QPpqxb6wxHNpsSV3Qc1W!GjuB3+j7bG72w z@N0I2d61wHXmzqEdM##+Y%L|b+yydfuwa(Id5gl)*Z8{n`e6{(vzE!;;gR9#6T$W# z!!d-x<#BkL;Om(MTb5B0cqq8y7UfEhAS)dAnfsy{@mucWbT#92+sLzd8eSxBIM%Yd zi#5t8y8dPlN){#OdE(sXnxeQJWxGN5T8^fa`})}8YTF5shpqd>kx6&^EyDYCQ|~^4 zJc#5b$!Mv?CO@xfGT(O1(D(O`1xwWqg*5B>O6HLj_<9WK7`Ee-Z60VuGLzhKkpn$9 zOsHTfH}f;Kr9aiuihgc4@|ss-RNwU#5g`<-p)*66xWqs z2su52HE8(bZt_AqhM1EGy8*=(CMTbqid}5VVthXu{vy9Wy5>rj6pgM3WaZmTH=MK5 zeW}Oq^L9Bk9zFDR)1(*r5dKX3bPuz28v0Tack$ku`5nzJo%QCzQ7h}%Joa_?b{ji+ z?XsiIUMo|W1C6OvAA9}5ttvBuv9z8Wg!z{tgkyVw6Ys08kqhNzTz;_^c z1&}~1a&pE!J#~-f{}{qMaq``&_MJk7j8n;XWnwBVBQ=x28T^*5$VZ0W#Qz3-R_S$kfZFnzaxJ7vUKGn#dtpaSxOp>@ zW31krb_*bO+dfNAa2es({nQ)$;+tsTWi3$ol~dt4pyMDf?EYl@eS@s)BCTlC?MW0G zhCn%Wc$XE8oc_4{c_ik&DNyvYOd7xyJH)`p60ye^P0r|tS>`D@wzOYJ5IvNtaX@0gvD#VDw>T!HQ zeRU8&p;>4}S-kXvYB#W*a!iC?M8sK38{^OIVVY94hhcXYF8<2N__dadVfn{$XBZa{ zmn(T~R|9#(bK#L-+Xj-E?&z$e%b%j#n6XkJZ_K1Rw1H7__FAXD5T!ZfGdP*i9*MRX zRAIZ(W%x!QjZX435v7Nj_tz4YbZuYj3O3YN*KCPlV6bS`EhoWIexv7QWm1q%H~q0? zDxS3HUzI>!8%?a+@Ft2UqU5pwPIja#>_QXx2LWg;A)S8h9NAW*xmwrlc*k$5pkYFz z_Qh&QY%<>3We?Gi=PSQAV6WNjWU%6yAotl0r)W5Vin8z>Q{$cFibT2ZnGM`tY1r%` z3MhOc0!(;%cz6UfV_1NK8V1w_1vXDUF9KG*zPh+~&yM31=ij^l8`6u{N^`Rk8|`>=&75rWN7aC)v8`<2g++wH0eZXQ_6GBJ)Lde6z8 zdR7|Zyj0Q91|aRnz7j_&yCs=m;aMb7xy{(ZJm6A0Wq}WJGdwIrtoN$%t18jzVN6K_ zXyruR7mi9Wm$<*zmjSBZ$*+3k@F*Q?41UH8sCsAq6_9y2X?~xZMr*KE zmsA^%tbYm>9`@Rv#M!=Mi>IT!D8xvpp+l}FX#%^Ho2lk!$FBAazj`)|g=Alaa!-e( zo08Lj!ANB~gzp}ew|*R=Wlf@li~yd2M!tTXSiweqwO@pfeq7D>-Y0~uZuw|K5{AMR z6g_{4ydee|Q?%BHrft{yp1M($+X>zMYI&4KZJ=OwtwmsCzF5}*XUcFvO`&{>_La`j zEpFZg*`hyjL&*(!xS}se4+`Zt2-t41k}DJwnsq4lZuVKC65=nA_p@LkJ&XCdgNFR> z35s#q%A-{;#g4?uFyQxPEc`Aq3@X!s`s9O5K@E2fO7HtUL{tgh07h#*m7BqRP-sP! z?BS3}Bvs#nzAYJ$?UPL9jV=8zD&{p>$QqHc})^LGiEv z)W_9htAT;()OsX${TjFu?^!zGg8+PQ=r|-|3o+Ty3wZb>!mt_(ETU#`nd@9>CEppc zlxLKDeCg*{8$tv@DZu$8xhHv4TC^BHV5d2h3E1}t?DU@UKtQlN(89cN0|YFh^Y}GE z6H+5)_en;OF-yturHN6+dC4O?AWwn@Ni-#iCSB-wQo6UOwoo(|m?eZEVuH8Kpjl2% zTnlV-Uy1#(1r05dm)-f;i0-O9Xt-N!X4CrCqLU+s`FurD8rwl?EOJd2zrn}&iYlH5 zaJOI!aE!^@TFQ%$q2aW688tv6hC?JS>x&s`@ywSP3yM&Gr8s6UMhWG#=c+AZ?%e6V)xZDQdD$JM%jV3c10doZM@Tu4nYu z@Jm}i2{L;u?(v>yX3A!Mb3Hics^zVgGwk^WlT~gcD?VGWl#n70zy^!`_k<|w##nIq zGy8f{LW4!0HDaNm4LX#+TpBu$x_Z>Ab${j4%*C>x3cV&?;0Rf3b3)yM-jf48rKMl(qT<<2*f!hNF^r zW_G_{A!2|i@as8fBxE7+K%uO_WgH1Neq;hl+4<_Ddsbf<>toPW+(i`r*uf^qJ|AUm z8e48zTb59I+`eW~V979<6Zgrd;BPcy@jQ+CA_>5R; zyt*2?WI=EYqPW22qc*k4srX`V0&I_s-PE*SbNJA*y0PjsCgW%FaLP?}mH1Ke#GWvd zZ1+mz;n5K@(X;k&A>!MA2$xbB<5MmL!3{j@#^IlSsJ2@l|lj+ zIu`ie6}Mc*2mj8vYv$1eAifD>C^jfsEsM4(S!)7**tWS`8sJ*}J&or`=RAx(NiznJ zOaz8OI$MwwU(Rr>!U)L|Q)^7jEQ((ZOl6AID~vvRmWrf5Skw>>LZe7QAyi{AYqx3A z4q;FF$Dy#=$?-i`MhcCH#{gPtWm&UX5tAd%hgq^P;!sL|ytwdnZ-03DyYe`e-m(2` z%n*#st|Zi2HPq>kRdBC4`P|RTz0s(Lj1EgKsJ7{1(C8&I6-}uK`sb7x&#Z?g16*@A zu^tkQ2=C+E=BOI!)L{J-h)<`*3vq)9g@MtYaVUkZs6TmC`p->Q|1y<09C6&f_-`bRhSf zf3X>#Vh>#^k7lHhQ`@zpdnbu8Wn#IXe}hCPgB5~wgqy)j>gar+u3N#L(k^;eg{lm8 zG3td%PWma{v4(RLK!!w{mn5j0r?}ctJ?Kd$<(jeJ(^fB4Zir@)VL?A8LYf)dJ-5)4HJmWDI$7u|s8FacyHQsDO6&)aP+7 z8eXCX^8NbE9U&M{*Bj(ui!oFKpm2)WR`MKsxB8a-!@~(2?r(csptW;{;-|xg^N%9K z$WHqcy@E8EQw9(rnx=cZjhr=q9S$7t`1F1#+2w=3_R!6XH=TlGkz_MNYSkkloPyuZ zzz92-r_$5HCjN<{c}(e+R0e}F(X%;m3w=5#U(F{6CP~CCb}OgSde9gSH96W@l>#z` zY&SHya?MYr9oxLviw-BOVJACQ=aE2kpoT8~)o1c+XCbCdl|~0hIT`$mpkiNshD?vh z*g!0eb*W*5)rM58j7-xvQbtQn0wE)WH+og5lgU434BgWyfzM(=-4Wzz#ARuQFMoqP zI-Lmx;-Sxe)+&-~*z1=G?9~(ufXceqh3;(jUu@S`s7Ggr< ztHk~$A)*s0-S4hlyO0RK%79v+47*z2Bdh}z={87R!Bc8CrHE!67g%HDyaa>khAa8| z5Vk{v7FxxfY#5n&7Q1LHGP!XWUW9x7NAHv}A1{(+U9rnQXjgJtwna~i9Y{ZKpn&SM zJPTYBx|H_WtjdrX+ta?eG~sa8dH5C+LFxls>I3qpdgIv2Z((C}@Mkib)o`v^iYn2M zwYE_n#erc+IJjN>AA5X|W3;tr+G8wqPo6?2b& z;y)s_mC_p7c2DKPT-KCylS6marj?Ww;-1%K6fGv4>{Z5QsxEuQ)TD$aCLd0tOYfA&~Ok5o98 z{z9j?o+2dkFjM^$M#Y?(vba9qPoX%3S;^W>TBkDvtcA47KuCL^zBK_15AgT5VMywj zdmY{H5A-!JruV@3v>-wm_K2`hV3Tx>_-aAfidh`--jQJ{eo=);oGBpOYuM4s>fYrp zYLGi??!$GXJkYW%ktnhEqp2-(Uo#@O!5uCj)Hx3$1X7dwBSC2qIN!)f48pLq5ztt3 z{O~oW!jBys{u}aOX<{uzn$7SBa zXj43z8Tmh}0<4sGl8jRm!G+mSOx#YwQtI6Ha{P~~!O!8~>_tsOt3qd$M%~r!40G|@XyS=9XB9y=2KYjP zlFI{gBc#HiBxyy{20)=|XMDpDL_`?tz)!glkqNBSX!r|Wc!8*)pcb2E=F)5B zI@qvzl&umFeHrzfkZhCU>|jgz&W2#Y$3M>8nX3&nGLUIt<<@?YW5*J(ilai=CjIkD zbjlv_aBL3@b5OKTVXim4enrA`B-FtWJlHQWO<>oL3)!1PcZ}f&XPI;x$yTfGBm~)& z7turEiFCgucIdCH()i~2oN+yG3+pw)kgjX3fl;P3zMJ1$;|dMEDD!qLur!S&id>W) zol7}s9C!5S-k3wWN+gS9_Q}pdcZLQ`CX-hb*i34&Y~Y(EEEdo zkTNP3`7((#9Hb0$qwMgi{PVjdV>?gDUya`|2n}^P*5em~3%(AEWso>Ow43+~R1|ci zLd6`ggT+rKFJ|nG;SF(X9yodbp+F7HK2mb` zEUgV;BBvQ*!UZfi@i^ffb77E|UJhm}iNiAdzg zYoIP>o{)PG!A$c_Q!AVSlC~hZ(vhbc;T!ov(Oo^9;xyn?BW2z#fvavDWguuKQ!n?C z9+OBueJRc}0c4f4{v+;8he-V8J_cRc98`3&BE`Q6Vko!Jjt_WFdJ( z#_fa|YPbL>C6wJaFFH0=q!TtrA86ViZurbN5@(I1!&O&D#r|M>b5`VE(X4Un2yvZ# zQYn?qEMyhj!x0+J#oU5!_lHv2WgR>j?;%i*c(-8No9_a$G@RclMZcm?ae{W?8z5Rm z4;W#B^ zf(TZ&ths!=!vN4zV<(I5Ng%=o)g+PmqrCZ5oF{Y|@u7iuIIsU?wcn7`AP^#m@QBQN z@`1^qUui>tL(fGpvv32g57Qp1wRz2M#WC?}uUKrE0i_Y=>q0eWj??GzEhpl#nL^$p zM4Egw3Gi&78pbYyFcYMUNn$6hQwhN#h(Z>8J{;Y7xQIw1C)@iqE-a|vu_&YlUvjA=;hpr%Ad%ax!~!Z(+Zsd=j<`Bg4WA3#?hEcO(^`%gAqR^= zHJ)L4eYFUv35Y^e6{T*XIOl`>4Qrya_!4-;^-xx5U_bbQHdcz+Hd$=&K}HK1FVNHu zRazkHwv}GPRVwI+--ND)vpXflS80^X6$kVt6b1(f2lQNhbwWB*AB};2GnRL_T4>1mg1?YwaTf#mH4=RZrmJLY)*VMof#S@bvrV zma0pKVMI`IO`4@(Ea*q*Z=TM&XYa=OsDifgi<_$0Cc^!1V@(m|>0ayw1C|0~g-(ji zdPToNThR9Cy}MYph5Coo_4%mxZCZ$eb;@16;B?)^rw!&;b0Ab-yo1{ryR@I-~tZ1+@0Z&nzN&$wtzh@e#IMd)G zukAeJu*jy8~|tdIdK>!Fhtm`^!U6G*Ax4 zt&VM8fJQNZ?g`nM%=1A}LeGT}!S%pFf#7eYRGd{%Ty=&Z%q?x7HW#;WN&*x4NhKBf z37_noe=aZk2irvUwAaE^+mtIEjtbsTe@MG5 zF#bBV;JHNcnv!`TgEiM#-9HLP_TWtssUum{Q6@-ZKQX#RA=%=HES6ReTO=H;UlsBY zO&s=Ve}-V!)D1?W5+qmyRucbhcnZawiZvBew)EV<{ULQhe~C2-rrFRoTS7t zc047JSvTiCn?V|p$38tX0uC?ryg#m{A(butHvSMHVr_8Y>RZ#7ko0(?6~{Qkg@PPG0KRBy3HK-z5I_>=T65Ps z846Me@Ta@*DC@dGW9TbWg-D_m5E$A01W8VQA?t&3<9f9OI5(myp5&uaz^7>?u$Zcj ze45!iZ^J>{o5V+$grU+)P>&3KvnKpX9xZfAqqAh|A_zmM#d$-d?s};NZZU}_A}nSV zfhA(i^zh-o@xfRX6zZJc6~o9kc+Z$Ol7C`eW}r>vG%qpa!`4IxE z6pbicF!@TXRrov9g!BYWE?{`T6?GE7qO?BLi3R%5w7MW@l>60eaUeKnkFhx716~{Y zjum)9C7|a(%oBj{2&~tgJw31PG)`WC=($c!apO~yZ;T@nd3QXIZz+#g1|3yx)8pPN zlXcmZ4%WmkPHQV`=&w}k8_+C*_`<~PdlW`;92NbLhKofnH#*~SUsLCUg`dMW$^e5r z?8Kjt{@bS7X;~6=jIf0EAw-1n*@#=1YIrrKC2w}-J=p@S?^YF5M2sD?{#enV&6@SF zIqPP@W2%#zAr=CEFX@}^_Il(sLU~bH?<@sYb0@w<#nqyUdvir%Z`RU8x3kl?T0OA*M>e-im@^C+YuCNu~vvez;N%9&~b7B*+{`$4%o$S{Ecdjbax`_!f;waX}1S%m$ItSy|C0 z%*e3QiwBNIFBRp4;VERG7XBt@_fP^db@F$B+-4#dGXVv=rX#K3o?cLd@gYq@w`Sn+ zvwsBrL`^lYd+&>>E|3UY32PvQI^x7}H4(4n=v%OTQjNyUhv%B7i=ntW1!=DQIOtfI zbT4t{md_Jl0SN|5`$bq}R*6;iLdnLK5WQ&uP3Ampl23eGMJuA&WBoV(7=adgFeGEU z(Jc-^l)>ZgY7>nf<&V`)DZA1DS4T>##0Qn;Oz`lAW3nqewwVI;s+7$+lqytUV1SNI zCtlF2fu>L(%f+??1P(o$Z|7J04su)mj_ZpK1h#)_egxtKGLiMf5 zs9DQUxnlHq_NXc?aHURG`gJjD_^X;e;cAh}l3&>5==*g#W7;Qk+xzS7^6j3&&~O;R zm5hGs-@(iD;LG&kVDA7#@&y4(dkWvYoh7K^4-?E*VQEK|AmywKG0o1;ZdHp+T3n@tlUlx^w@ZpPeTTH zlzQ)oOn-ins$@%NJt%B@^QvIeH$x5%ZXL3+$fW+S8)&dig5wn$Uqt zQ)7Bv@2fgp9$217)N{O^imX(S7M8?dq44rWYm7rqTuM${%l6OjORn_)Kw9-`W*yrH zwc3wtgtf1V;$a-mj;(1RDR)I_@4bDgmH3>igZe=@P^NvqE+7MG%+bD^q6KRXp$QvRNUy@`0Gx(~o88SVKW zm9=(`45st?56jZF{-lX2X+AvmG1JO?xB*$ z;(J7}M`ufUw?X@s0rpOlZdPZjMO)Rv&vz)dt0hQy(|uk$ynS~+r9TPVjX>ScGL9d! z&YWGaSC?+&u2;*-E*D@Wt`>a3y*oWE>NU8p{*|A6V%V#CRT~ynQ$MQ#WsiBOYP^R(HgniZ@bp>>P_4YWYJC=#;2eGq~JXtmpM}Bk;;%$y%RiArb?QsJW#fe zh*y~0tG7m#w{ZF=`*7?(aLO1N60>s~Vb43nV%5Piw&OtU)XxVBFdd_3dTzM$}t}1k?2uS5mnQE&@JsAdWh)6HE*Ln$VBm)OcN;yd$Am{ zrLfdpuow4>ce7g?=4E~*zgHXX>#0jl!=dcOSIPRPPIk_hS|^W(s|(t)<4Q-EBi8-C zT;dG9DWyGiwl6NHITW)liQq4~;Ck1eIM$8gy)rZ1gTc*TZw9*iC-D1V1`3&nfm>pm zj)K=S3zlY@7Fbb%=R9p8E&Xr!q8vHvgoCW{oo)QS&sh*#(lE`gKMYq&Ia!OK{8sq= zV`gC4=jAOQo9q2c(h>L}5CKk8gr-tqR0_VOjo!Zr2^U|fMWZ1LZcmwGY&^KF=-&U7T;I=#`3AniVVwbDeFz~V<&ipZ~ zPh7rUHq>|3c0P1Jd8KCZZivUxqB->EI76`US_H`)Un#)@klgdvN>|6;a zcqjO(#__wwRF~ur;ylHmvm2+r?L^!7LBl|alv-vn=L3*aj^{tIrZwXtPwqa{6Y=(q zkAB}bP2Zn*`=IP!2`2)y`ah3<-;eX!eg9cwATrgagJa7bhQG)E1)u_nk+S`uO17I6 zy5;8RZ$|A8|I0}Jo=@wzIIZ3H=;wf_YSb4FNIdppv16~G>-N*PrBH=WR-DE*e&L*; zmxdHCrHHt-AGhZd@Zvp_^-;aIk0Dn4Cge@eU1hs-3m5c?G*_S%%vV|8<)@0`w|TDy-Os3(Rl+mdQ2c%_ltAOKG22Youc(c`j2l;VNb2GwM{z2hiH64Q9Z^CayiJ_8`9D&|l zAMDQz|F;b8JMT>IuO_W+?pH1SAK@w|6qA3M_?=$X{=)ztY?-?S7Av~2-!EGp|C7S} zmxn%sg_=5AIYQsXziCKoWHwqLC<;cw9SJL9Ik>wlIsCf`RBMMUv)^#B3qRz zUjDbUD_T!=t>Lu}S^h)Mlbc{9YOgOh^t z47@Cj@b42le=vNbXl0ylBLpevEis(A}*Z%d=W7LwF;@hy|oc;Ke`( z_T_jFmt(}#uedzjw2(Edr+4IU;E{;4;7A@DFZfSL#{R&Ip$^0D>Ix%qxsh$|iC^QZ zrXgP>J7xR%S(Y;_?z6V`Q+ z&=8a`%WMb_o3-*k5GbzNp2=ziX#9laF0~R=`V@?fDZW~pd+3xfPadV{s!!?37@HKm zWPADie#HcuI346o;!WL$!VDG(<6%M}yB6SmLzscL9`jk|^hvJve1We2r+z%^<^w*Q z`7rR4y1N+G%5<~M0c-qD%Su}{h<%@{?tSWZBu@AWse;b!H&|OYrph0BQ!x0v zT*jiXRnNaCkn6C@oM)HyppLPU`Ld76Z=gjZu!)ey9#{;Pa z8caa%{0pc#iZEjd04HH*oipqVB>9$mmT|FX-V-Dbs^{Gji@#1eEhCQ$I)AS$Hh2Mw z7HdUc4iU@O*P7ES(l6E2US&Ci71&8UYwcv{5sUmc3MIhzTH(Pm0re-cauU{mRDLjA z5@6uZCS(NNanaRPDn77+@$(xD6~K*lKcp{N^8_A21<|`F&x$rq4&y(9iup5?&G`H3 zm`Q$CdKUie{!ZU78=Qf1t@sx+0^}PhQ7Pz36>QVmqj1c{7O9|LvOgj~Yn2n|jhEAlq`F{Z%1>^cigKKG1Tj%?FE`Fgh1t6o) ztJo;nVucVyVh-c`PHh@Ija3kt0+=Eht9+gO+rYj*^dA<;KB1HS(>uk*2PjkEJ)FNz zZC0awVZSfR6nLD0?Yp(Hb7U1kWC{kbf1QdI~jkAPtS7WX2n zgnQl}DW<@nA=|GQ&wyb<5-<$g)H;Ekf+dRzB2(ZVq0L3``7e1&rXc>aEj26H#3)YCH00u+7G$#$K$smZPfJSC} zC+3iu38l655lsPfmYtG8!6$=6Q-El~b*o%*ntDPJ%}(su@04ua1IAKK0kAKfDy!rD zW$y=S3V756>E(arZeZ6(k{S5EvJ=>3#<+`HAA(^6fbE8<{6+)~gEc4e$Txp#u(k%W zJ31pS*gydQ2Q>6J{h?mw){8PX%;XzRou|GAO#Fb&b}A$DCy#hGDC5aaFdg61BZ!)S z!7^hf&ZOH}F7hL40v0*Doz|yW&a{1iS^9u9q6H-AOL8B5DFy z1|2$O9*X7c3Zf<;vCP=5XND~^5;Xx-v(TNsujb3hL`^^;XR_1%Rr64r+WIgvLN%XW zoI0L!FNgpDs)hB++$>+_Ap!tM1L-uaVvI~VHDy5r0HEhcbn2Oj0ty_mMtb&feFwF~ zFJC|Z@%8=9w|(R`|BwHee$|%`Uw{4Z>Gt~Lhi}jRWBgC!|GvHc@a<2}-v9FL^T)s6 zemKv6hSg3hgwkoe*gO6 zL-8^Ee=R?S`O_}fBl~izy9sRZ~yiA>*e@2FX9NMmmfag ze7ODkue1FU&d6A%Gx&z(y?laUS!eOpomJlB_)}-Uf4u(k<^3yO_)f4Uss&GpUu+YfOkudl}&{PoYDe!Kql!?&|Pe;$|i?)r~$;q%{p zA0IRQLJ12W)3|eSAa^ep|Bv?{uYVhl(C1I*U#`D=_;~$kv61heUykqZAJ_Xq)Z-$4 z8DIPR+uJx5@568Zoqqb=?T0Vl;Gy4cVHnws?{`mVx`lS6IoqxUl^hf%>(;tyj zGyTzGGWPtZ{m*>2IGt|MOGvw|)3+VF1h4wV8)xJ1 z8{gaBgp51-`Qzt*F8=6@4!t}3ug^dK*RMa1mv}N}<6pSC`d-g(WV8;y-@O0zzvur& uhUhWJ?LYrdb}0Y(fByN;c#7d;Tz~rg^VggGzyE*#@BanvG*1BCNCW`y>I$v^ diff --git a/biojava-structure/src/test/resources/validation/3zjn-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3zjn-valdata.xml.gz deleted file mode 100644 index fc2f6526f3f46f3c0434cb04513a3264d4f690b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26368 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 WKQC{u*8l#?zyE(A3!(vHgaQEmp^`iR diff --git a/biojava-structure/src/test/resources/validation/3zjr-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3zjr-valdata.xml.gz deleted file mode 100644 index 8dba9bfd0258647f04f63679cb90cb0aac773801..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11047 zcmV+?E7;T@iwFo1<~dRT12cMRaxHdYY-C|{VJ>)WYyj1LZEqVnmi6bEUtt(nU>`uz z6yI4uX9l+8P8vv@M$+56-HQi-Vk?f&wq;04GCjY3NtKE`x5T1KiptS^NVi{9W|6$S zyf5dT`@=u}d4G5EWinq(XAjR#*{C=@`N!Y?`oq_+KR-Voei`3QZ^ldatKszF<7|Gv z`ugvG{mT!R56k(VCl?n#%kZooiBWO#pYJBi<=y1}ot`|uxOo5e*=aH2#rm6%^U1{j zK&*c-pM0D?OztNS%lD7-+3kFM|LpYb<&Uq=F5K_O%kkO6bTM1bXODmSrx;V!k1uBT zk9U*hMl8=NvJ^69= z{>SV0*R%P2ayPD?DMqFLyFbm`1m8_>@5j$h`G|}EbbpJTx#{`!nNPk<{p5!apYK0R z=5GB?Pu@;G-jA<;tye{jj2oPn{uhhopO2Hp)ogkFX>$F?BN>nU5b9R~PS|o&NG^a&kAG-?~3?GW+;(IGayzrw=EO zlkp!X?*B{o>z~KVr5kqkaPslDG5LJsR^PoqwIu$J-MD4HUQTXC?$y3dA71%ol18q-QpzVlTGbr4;6oVlf878W4{(pGT&2s95%}I-Ulo@k+ zGXAjIxXJKwGQV~bGrgM(L8!_RPk-k6ZoK%ka69Wh#Kg#^KehgH`1ak~--ol$%e$#t zNcTWd_ydu9!U^pdo)CP*wmdLf;sacaw0pq+YCgSwAAjM;b^Ce$=$8A}a1P%sCy(xz z_p>{9Vm?fle-7?vx1a9@|8!4}ZzqGv&0-J-T@1d?r^|^u;-@DcKHvTE-o4frf80Je z$yXy?@W#*osCLjv>*fo&dEsJ;Vr1N#JINoubO+()^R-`LrR?fwucvo+lle~%H`D8h zUlz^W<1MRPtWIakf)*ns;Fomq^hmp3R%iB0n`m%7D$^gr=}7BkBlW4gY~-G3OvMy! zFVZqSRgTQ*-@LkgJ-eB>1-*Iq`NQpe_WAMTYP_7?FPuhm3eXA4-SXOf;@Rnm`})i6 z?E3oiN|*a}z5XYn3@?|At{vP_*N{h2R$5sv|DUGMPKS0SRF4by zHFK)LOZV7cJwJ}WI5E9}4f*-)o46sS-jIvi_mh9l;--{Z#Z6(l-jtymhKXud#{T+g zF78EG-1Ra$-G1>rEHf{h@+j(sW@=ROxYTZei)yKdP8*8#7Lv_>F1qjj?%N~}w@spX zAXeLCwZCpwyR_2xZF}_M)o*c+EbNLDVON+aVOOM<+fO{>hnrv-CMZTmMmZECxt^h$ ztZbj+FTcHwQ!HySTzZKPilO?Zl0hw_VkkAdQ#*6tDHM42cjmV=yd!xB361+UMQ;f-@8;<++n z&$a7E?hMMETS^o3-|Fj5g6FM^gyfY1w4dQo@|e_#;29MuvOQ>pN}a2Lr|#Z(?{iaJbDj93xmgE8(WR-LZZL2El*FJAo@%u$5X zwH$KPO@#*C1QJrPa{GMyP$q7^l0`ktgB~6#o!e8YO=LowSQ8C2rt#JhmgQ`Lb7E=L z)<7@@7$e3&xjJ3Z7%)X`cbRf+3nYiR+B!-RM=88@rxK$Kg+HzPozPyyS2_2)-cIiT z*TNg^hHbK|g0+1=lqkDkMFgWAF*)>%5Oo!iZ=LgVhFFpPEXyJj#- zQSYYvnA+D2JfLF~w^NR|irT1HndsGZVOEqmljQ8x8B7`NePh9n!;NL7$r&PyQA5OQ?cg5mYsU3r0vl(|M=7z<1kU+K z#D`_Ud+<)|!wq_|s*LNWP(~Cl59q}fT&2BOwYSN9z%v<5W@p1|Fo}wICWRiU%zD3s zAPz5D&t$2=D&hwH4$;9s?L+Z8|J%kh=`M^Sn7YQ~WQ-_Y9{hwyRJ&hrONH|;qvkZxc;(sK@zo_5Je;S( zizNe@Tw6YC9m-Sj#pkSEKG}>hSy(=GM7E;#k)fzWqir#iB6qBbxyXa7vwUPk#wA1o z(Y52H*j&Fi>&3IpKmxeJ>Db=6=q|R6F+=Fb=*+0{`%Ap6w@f+fDBgRDMGxG0r$tUH z{R~?cytRAcoR*43wM5jgF2&O(2Eqw+ zl`3bmzxwSRY*KVmmdkq#UhAY(vQ>;IqYrjhB_U1FK_9fFmvm#(VuHav$x=$F-fjAv zfz7u21{iudky2Jx?E21?{-y|bZpJX8Co(u_I_T$kIWFXtC ztW3A*+N1(9AlV8PkTE$k5Mv!Lz|r7s!7Fz)_^9hz1F;yqa>__0WODVVsxxF7;>@Br zJGGpBv}p!~M}_mHl_))0rI-$Gu+jP^Z1{A) z*TIcuL{teqlX&eIkD_vxibq|%2#3_Rtvh!n zS27Y9@O8HNESzw$uf2M}6K)}I#$&idNw^SXEeSiq1iCKW`Hz;<5k zyYg56Cd(dU7|t~S&5G-;MK%+LF$@_K14|by32zD-y+F0nE`9UIHGA0dLB3=qr zu`Y{LHmv(GKN8c;2e~4qqm)rG@+|O%BwQr8SQr!m|BB#lnEg%x18pkYSI9kZP)=P> zno4^_Xf3f49RyKkOXO6WtT?rxzrUI#AW)vBde51Cyqi8gjz8Q@hKuRVWc_otoB6LWTWVtQ#E_Nw zTo9Q53IJKe{4cp`6KI*bI4*e|?k^j_)@aDH2rMTaK!~ldMj}aD*v=!s#KucUV_6sn zFr0!|+$Q>;TskVkxzObWMPktHQas`E)~2OtVj;v907m^_*;sOKCx-|3RY1LHZ$0AC zhdgjcUZ`zPqD8ct&g!UW6#L-%by@UsiQqj zSy#Z;B4zB_B-1gqC(}eTU`%LV)Jz|in~ww=G-ZO*oiF+#<<2@-s+;A`9P1D;tmYZb zG7iZu<<9O%TcZ=@&fL3@Nq3~red;d$yKNL`Zx40~(a&tH2$k|+Vm}fo$Kx&;Iqu)F zIIoN@REf!pYz~`v$tKv?_icGDa;R+=Zi;@UOH%flMFUf?&OreasiRPt8;A*z%v345 zP;vBOPdm2|l9-Y~64PdxfzX~dA(p=x`I0ba8s4lUUwg(u1aQ4D=3Z7YsD3Jg;<5W; z)_PfQSyocN7B3ytyvjxI>1s#d6!l&dXn2ExRaK;dj4}D4+8jsb{m+EE8Xj%9oU#6f zkJ#Q?yB8Njq94ULCaqXbZ4)2E$d;uSu=JLcsPLz)#zAXLkt&Nw=aEg)kw}n9Rvn-k zEAW!?zE-Acwiy+{Vy%7ip1qj!2F-aD@$Ss?s&+KzO(q+l!3F1d?J3jYmhVMc>`28x znxYl>U9C@(VT^@~o@1ocvII{AP`Ne}5rAmfyS}uS8VTq0Sv+nb63J{%y^uh&3FbRx zk`Z7P3gY{uvPU&`&oqPd5Y*GDP+}y9>G0^$!2Y7#dIG=ts0!7YL$?CZB$AU76}c=r zRNwT(MD)qsC@dns~1WuRhh*hj1U-?dDP>Z2Id(OTG?0exjZi4~!zWK?%uq82HhtW|{7r&3Q|)cjGhNg%QfAN1yBZCbav?r!h*MLhP!|0h5gbxbQ1S>7oO z$k}9f5kdh9rMT{OZ4zhC`&3g& zv3P1gK)i8%k|pk`1l*R$)>IRM=rRI(mP;Bbg=C^25iHxm%j?C)a5H9*C)ZJk^Fb$K zW0VotLiwqnwo}BAowo|RV7L0&VvedwX+Rn0>pI95Llr?IBnwP14c@i#yD{I8z@lcr z0+p3&5`!*Va4u+8DKsNZsxL|Kux$HHmMq_mne`@q6f6(5Z=GH*;asn_(It+xW-=#e zB%E6&;Wk(@K|7mt!S45Vt~g*KEfC#hQO)#R1>1d-TfdAUGEQ>Tyap1aI;+(rhK#@m zoTRAOT1{)xT1~C(^@l7#ZNJ;GlQ2*$qdxR1>r(^4}8pj)uTd3X3kX_HHht_NxAVRfo;+4E2s*rC?7MZ_CEGJuly zCVB58`{Yy-M9qDx5zzTL4+yhQWrY3HurH=7OGy-d)=S<)De*paOE2txs!DFIF9Qw6 z1<#T{(LQ|<9)))S6tc&psk<4wWQqH*q@*6n7>V)ewtBWIr$&h(RUrm8=8EV=xtx&$72K|Jb_P$>(=WI^h*HE0p5n<;sL0Ov@c7hZf@JH&$IHl)*Y zEMX41ua1DB4;z^PGa{)7FxfTce)tc;-PO$_4^rU*}s)ormOwf+kIQZKh{6xpu0 zlY?s-Q%OaR;XpUROV}pj2>M9|LJwsyWT14USjl4r384oof`hbt)VNJWOmK=AZS{o% zDYHG?8NIYv>Lmfe5nF0_Tt1#%KHA!^zyt)E+ysUcdWWT9DorXwc>sy)DT-nd)}+B4 z5+>WC`7KcmF{44kD7bzGUBxuaCzz8Rj%*7JO4DJ%YWgE+E(IPsZA6K*WhTeaO+0iK zTZ_|ZNE?=cs}9AMJ&{)zP_BcqpQ1B;6pOvU8@{mwyx?}<_)UaFZ9l1Pu$czR;2`Zg z`>AzM*hHv=Bp%CVcp6>UBN~m^(NM?C3k zw`2!}*Gs1!MT|M8GenG#qVtYQv> zA6E{;RC+XM48#+4t$3}#QHdmmXp^U8*Y4+m9o{reQ_#43b1wB1Lz9?sH(+x)S2`0Y zrZKeGyZe6Gh@nY1l(cSGXUVl_4tg!HSC<&>v_xWy5+#;_#Mbv?`e0nffqstzy^PKK zc!3cHXAhMcBMfjhbTYE~GV*veE9XHj%-;53(MPU?AsJUGz~#$U>yXNM7F&!{f(Q$i zIN_(#<#B#&+wl)NtU>{vnW#ojgFeL->z@WWVO5bdrGV+Zp`XOgw5LxI(mrAb6P zu3px8anW!kmDL7Ii}|Omr*n+?;}zjlBum#bBr62oykMQrN!ybhj`fjL==dfNfB}b28(2rRnOr64 zSq44Rmye{qYn#(!yEp;8%{aPwM#ip!yn8Pg22Il&{kSo@f-wbU^Z_f!l&^G2q?0Yn znO8ey%gS}qw*|!Ive9806~!L&w2N4Y#mZb`Q3~y@QM^9GMBLf z81?DhLx-%8!!77`bkIpqu zoO@A&ZV!UyD5Udxl3I+9$`nm|xM!LXlWzrMQ1Ugq*kx0OWQc-GKmQtR*2|St|!>?yA}#VAN5_UlS3bY zorxcydqFSK-3x~U$Ar2++%^7#xDSy){-!W`^ zz^v7#-yWwsj*DJ#wCO!!I$V7!OW)ME>tk_TgMbJdZjfRt@!gWo7V$-%eSm}Z&sg;| z`z+GcWjZP_ULcN5=p=7myt11e9iaBcBtyG3zGyq8XB#kSJB{dZkj8o32hjP%{#ILf z%4q^!AYKzV6dD&z7f$-V&{xnm5kbAI?2da85n$PdzM}onl}vzoLvwlCED3|UE|s)G zW7Fqm5g$A%_qAwx%72@Yh|y>bO-cmMK`d#)M+T2)BjJNI;e?2-Q#`sKadUihm?I+3aLP9R=q&5r!>x(Mcg=(m|uQcI9Qw2qRX8?VI}Vg*1g@6VDO~HZ&ZRL>nBE z2v-pZj7J3fE|bd76p;vE-TJr<`Y_vl%^0-!Rp54Ji6W`lUUADLWR;{0G)ttIVo2uS zMl-8|u;Q~AoG_icB3DGP8_jS~-iYfeyRh^eP`R~G#g-Z(G1+wF>&stow$V{1P)LF` z#`9&2-I;UYUA%-CC)R?lhQ~D7)i{J=}dcCTtZqALG`S2%c80!T}#g*So#8QaBt)t z$k^geee)vOFtbRysn7S`;pe^Xa4)eNXALmmZ8Sh-s&Z$GMsE}#R7vzk16cuOV&aLq z=@>_`O>D*Hwb$A&ukmOCg>xhpvZg#(I<7s>9xoc*R_U}Ru)T3f(R*no$B;yCqFXVo zc}&4oU-XEeAQqyl*`7@eBMnoG9Ho_T4JT8<5qHom;sB4r?9Hs(OWw=~ED$sr9O&-U z#T7_u4WzoKd9xzNz1A8Nl#K|cg7eOjamX0xZJc*)A<&x&3PMNZrZdeBuy4JXK%OxU zVtX>i}4ZmYe~!JFG;oHhXCA`vQ2k-52qzXuRRLe<6T^{l#s>1#(TZYn2k%!0e-ON13u$>#07Y%ce;t7Q+G!EPQVquR zNaU;VcL4jBc2xLq#>OB+r_Pdbx6lWnnUE_Epr?D01BpmmOyG-L(2e>_IykBu{t`pT z0z%V8K98`Aza-2^dUdtoFPV}4rh+eyR3)6R8o|U-bSU^@=@=~UE)3i8w`ov;GKzo- zYClo!%kj_$7T)O^1}w*%^1o+NRTK-aW5WFrYduONIVLq-qHFM}Lp=_wSgtqgapeBg zR=q5?9Px-_wAdsmi^yrLbp+eqw^r8B8Y>|>FlzKtSwl#)wT22hk#nmk21%R5RYr(; z1g+vvV~|*%4puLPDwNkq0W2}wC7>ZMAwSt*2IEM|g9~WH_bQTi1~K%QBJBJkmyvC_ zCP+ktxh8Vs5m2H@v9yK=oNhuzHi0aIQE3m^NYz&ELxOl@?*+XjVSKGGMRdwMT?IjcJw1q_N7H-3;uB=;-u`<;Y023look&&t zVT$(9F(~Qc@eoOoiwaVvXcIGR!-~E?i5MWDRh4yOI~*fJ@J~X@EdJ?8vMz4DfiOv$ zcxkF^c?`|EnD!2GWotaoriw>i2Am{sMpGesQX~tJ!=s{^c)@nZ=}cRAv7QDf*vN+26Y7czpncT@ZTMEJgUH=u4y zzjCb*Z1RQvhjUa?bZ8I%`W#2`%Xw5c(ZsAd}KaovOj;h6iV8f!oa+XcB z5=Yg>+((gKdrEn(WlD4}gZHw%QAZ1dP;<`?!N1f?S5lw;!K6T}W9`l#WMhxHmT(BC z7fLE85cEX{nu8;WP)d!xX_N(LpLdT?+LqF?0wA;{%^)QdMvYz;O)v@4-J~jz>IY4; zjuOAItgnDUp~X=FrQ8cV~gIK*LEO)JRjIF(|I&!B~D-p+-upG(o0J zR*;9-T`#0DeVF#rkbNql?QoW@hnn_fbcoR{f?KR4BvPt_Y2Qou&o?22@E>%*;8{!> z4gZzk36k(1vf%<96Z@WRhecIqwFvq;q+2NAuRm3lya4HF1R9k0gDLN3*kk>!|w|jkW1MMnrchlRq z@815t8d25XK75$JUg-fZ1n|Rm0fi{SPe0$gUo0v!u=Rizkh-pVSO#?Uy8uK zD(SUKdA_fMS-Cq0;(0UDR zdmFnqNO&Dk*G&(**zmA7<@n6BcpsvY>0OVAdettB59G$dP1XYtK)TM|WP$118x1(Bj-v`Z%PS$-VXng8AMr>vN7Zyx z-XhK`B+CNKj;$N36rHQYQ5zd8V6N@b)L~mavK$9JJ8$3Cwv*csrma&Io);*doC~+W z7wuDJaa1n9L72)_7l<&|=BN!}vM_2%go*Dosvuh8b#v67gvqV2rgJ^J=%$s! zy#f#W>Qpg*-v7QbMRb$cGHls4EM4Lb8*5;)ubZRl*7N#}M@NG=RR%}@OYFoc>ZTtr z2UnmZO5HjpYT;E_9LAK}^`X#YOb}pSv(|FW35#PEdUMR(13r5M*Mf7pYH6DCPHoaV zlGV!8<3Fjy7`&)jCTdr~9PE0=E z4X3vcE7|ySvIrGr)_Fs?7XNdJOTiH@5+QVjidX=*i>3?J@3%z6s&{3kLR`fV!kd>Q zga8|7fcSwu(fjeTYDwDqez=-C#yAA;5MVpN`#HI1GWUKM|11Fc(WRl>0p8CykvF;b z1LA3Gk%jGP){of=cF_8MglZ_B7NNUP^dDeQ6mR=GT*l<@C<`wC-2#`{i`v{NM41#q93$ax#pcsJ|R~07M-z zSq$cryYX`Rg?w^l#;igqgWMnTzIyyasZTz?xOo5e<9sqn4wL_FdX(HJw@)m5a(q9| zzj^mh#>F~4`7&80_x!f1vW|?=E&JzkJ{{jq=yv@wA3rRvF5V5EkC)@Khv{Orbie&` z;K!Ixuiu9k_~q;L;niTg@$>(l-YsSi=aa>9dOu!H22QqKPn}TDe|or?UQZT-pJwje z-c4`s$Mt8&ewgYHa(Ht#vO`wrGWqgf#&^>jx2m&;;p6miayNZwOyuY1=fnBr%XF3E zbT9E?G9QeW%gO!Ya&q%)c>3LP^0`ED+j@Hj)sHYB zxc*Ti=eqtWNed1zNJN%{sgsovm3pt6>udT}E0G@f|IQ~L-Rj)Cje5U+W)S2Z1tlh0 znp3`WKlm_R{z*q5(|i0h9Xu|kgST$u|9qS*u4c>YPm}9ECO1FM=I8E{XMT<^CbRp= za_+>*i|T;R8_s%K<`L5}@JDRWa^BoigGALFOjbl>G@b0^rlG&mhyTOpyFcE$6Zpli z>W6{Xn(jaIK~UKKyMGPVVZ?#gzx0_u1|&|nI&K%U`^USSV0ZW$}J<34b4@v~gd-0jcD`|+eWdGjj@l_*+!{ hKm6_MSAV$R1Wq45&gS>4umAqn{{xpec_oD+0RW6Fe;EJ( diff --git a/biojava-structure/src/test/resources/validation/3zjs-valdata.xml.gz b/biojava-structure/src/test/resources/validation/3zjs-valdata.xml.gz deleted file mode 100644 index ba1fdb5e779db6bad7490f380113eca705162eee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19225 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