From 96def7e7b87cf621dde0a40889f42a7129b10727 Mon Sep 17 00:00:00 2001 From: Amr ALHOSSARY Date: Sun, 28 Nov 2021 04:02:50 +0800 Subject: [PATCH 1/5] Parsing REMARK 2 and REMARK 3 (new format) Apparently it affects only cryo-EM entries. --- .../nbio/structure/io/PDBFileParser.java | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) 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 c3dcc330e0..db6669cc75 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 @@ -1351,7 +1351,7 @@ private void pdb_REMARK_Handler(String line) { if (line.startsWith("REMARK 800")) { pdb_REMARK_800_Handler(line); - } else if ( line.startsWith("REMARK 350")){ + } else if ( line.startsWith("REMARK 350")){ if ( params.isParseBioAssembly()) { @@ -1361,6 +1361,10 @@ private void pdb_REMARK_Handler(String line) { bioAssemblyParser.pdb_REMARK_350_Handler(line); } + } else if (line.startsWith("REMARK 2")) { + //REMARK 2 RESOLUTION. + Pattern pR = Pattern.compile("^REMARK 2 RESOLUTION.\\s+(\\d+\\.\\d+)\\s+ANGSTROMS\\..*"); + handleResolutionLine(line, pR); // REMARK 3 (for R free) // note: if more than 1 value present (occurring in hybrid experimental technique entries, e.g. 3ins, 4n9m) @@ -1396,21 +1400,29 @@ private void pdb_REMARK_Handler(String line) { // then last one encountered will be taken } else if (line.startsWith("REMARK 3 RESOLUTION RANGE HIGH")){ Pattern pR = Pattern.compile("^REMARK 3 RESOLUTION RANGE HIGH \\(ANGSTROMS\\) :\\s+(\\d+\\.\\d+).*"); - Matcher mR = pR.matcher(line); - if (mR.matches()) { - try { - float res = Float.parseFloat(mR.group(1)); - if (pdbHeader.getResolution()!=PDBHeader.DEFAULT_RESOLUTION) { - logger.warn("More than 1 resolution value present, will use last one {} and discard previous {} " - ,mR.group(1), String.format("%4.2f",pdbHeader.getResolution())); - } - pdbHeader.setResolution(res); - } catch (NumberFormatException e) { - logger.info("Could not parse resolution '{}', ignoring it",mR.group(1)); + handleResolutionLine(line, pR); + } else if (line.startsWith("REMARK 3 EFFECTIVE RESOLUTION")){ + Pattern pR = Pattern.compile("^REMARK 3 EFFECTIVE RESOLUTION \\(ANGSTROMS\\)\\s+:\\s+(\\d+\\.\\d+).*"); + handleResolutionLine(line, pR); + } + } + + public void handleResolutionLine(String line, Pattern pR) { + Matcher mR = pR.matcher(line); + if (mR.matches()) { + final String resString = mR.group(1); + try { + float res = Float.parseFloat(resString); + final float resInHeader = pdbHeader.getResolution(); + if (resInHeader!=PDBHeader.DEFAULT_RESOLUTION && resInHeader != res) { + logger.warn("More than 1 resolution value present, will use last one {} and discard previous {} " + ,resString, String.format("%4.2f",resInHeader)); } + pdbHeader.setResolution(res); + } catch (NumberFormatException e) { + logger.info("Could not parse resolution '{}', ignoring it",resString); } } - } From c16c2a86a7431c112ea2d327193f6dd544ce665e Mon Sep 17 00:00:00 2001 From: Amr ALHOSSARY Date: Fri, 3 Dec 2021 05:28:39 +0800 Subject: [PATCH 2/5] Parsing EM resolution in mmCif parser --- .../structure/io/cif/CifStructureConsumer.java | 9 ++++++++- .../io/cif/CifStructureConsumerImpl.java | 16 ++++++++++++++++ .../structure/io/cif/CifStructureConverter.java | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumer.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumer.java index c6c5318217..8472bc8056 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumer.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumer.java @@ -10,6 +10,7 @@ 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.Em3dReconstruction; import org.rcsb.cif.schema.mm.Entity; import org.rcsb.cif.schema.mm.EntityPoly; import org.rcsb.cif.schema.mm.EntityPolySeq; @@ -107,7 +108,13 @@ public interface CifStructureConsumer extends CifFileConsumer { */ void consumeDatabasePDBRevRecord(DatabasePDBRevRecord databasePDBrevRecord); - /** + /** + * Consume Electron Microscopy 3D reconstruction data + * @param em3dReconstruction + */ + void consumeEm3dReconstruction(Em3dReconstruction em3dReconstruction); + + /** * Consume a particular Cif category. * @param entity data */ diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java index eb56b9a59a..0cdf8bbb1a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java @@ -69,6 +69,7 @@ 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.Em3dReconstruction; import org.rcsb.cif.schema.mm.Entity; import org.rcsb.cif.schema.mm.EntityPoly; import org.rcsb.cif.schema.mm.EntityPolySeq; @@ -128,6 +129,7 @@ public class CifStructureConsumerImpl implements CifStructureConsumer { private List currentModel; private PDBHeader pdbHeader; private String currentNmrModelNumber; + private Em3dReconstruction em3dReconstruction; private List entityChains; private Entity entity; @@ -644,6 +646,16 @@ public void consumeDatabasePDBRevRecord(DatabasePDBRevRecord databasePDBrevRecor revRecords.add(new org.biojava.nbio.structure.DatabasePDBRevRecord(databasePDBrevRecord, i)); } } + + @Override + public void consumeEm3dReconstruction(Em3dReconstruction em3dReconstruction) { + this.em3dReconstruction = em3dReconstruction; + + for (int rowIndex = 0; rowIndex < em3dReconstruction.getRowCount(); rowIndex++) { + pdbHeader.setResolution((float) em3dReconstruction.getResolution().get(rowIndex)); //can it have more than 1 value? + } + //TODO other fields (maybe RFree)? + } @Override public void consumeEntity(Entity entity) { @@ -831,6 +843,10 @@ public void consumePdbxStructOperList(PdbxStructOperList pdbxStructOperList) { public void consumeRefine(Refine refine) { for (int rowIndex = 0; rowIndex < refine.getRowCount(); rowIndex++) { // RESOLUTION + ValueKind valueKind = refine.getLsDResHigh().getValueKind(rowIndex); + if (ValueKind.NOT_PRESENT.equals(valueKind)) { + continue; + } // 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 diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConverter.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConverter.java index 1351223982..4f3a1f403a 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConverter.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConverter.java @@ -118,6 +118,7 @@ public static Structure fromCifFile(CifFile cifFile, FileParsingParameters param consumer.consumeDatabasePDBRemark(cifBlock.getDatabasePDBRemark()); consumer.consumeDatabasePDBRev(cifBlock.getDatabasePDBRev()); consumer.consumeDatabasePDBRevRecord(cifBlock.getDatabasePDBRevRecord()); + consumer.consumeEm3dReconstruction(cifBlock.getEm3dReconstruction()); consumer.consumeEntity(cifBlock.getEntity()); consumer.consumeEntityPoly(cifBlock.getEntityPoly()); consumer.consumeEntitySrcGen(cifBlock.getEntitySrcGen()); From 0dea8f5beef88d53e461a0ce9134d6e284ed8855 Mon Sep 17 00:00:00 2001 From: Amr ALHOSSARY Date: Tue, 7 Dec 2021 02:29:00 +0800 Subject: [PATCH 3/5] Safer condition the safer condition covers both UNKNOWN and NOT_PRESENT values --- .../biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java index 0cdf8bbb1a..4f1a40fab5 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java @@ -844,7 +844,7 @@ public void consumeRefine(Refine refine) { for (int rowIndex = 0; rowIndex < refine.getRowCount(); rowIndex++) { // RESOLUTION ValueKind valueKind = refine.getLsDResHigh().getValueKind(rowIndex); - if (ValueKind.NOT_PRESENT.equals(valueKind)) { + if (! ValueKind.PRESENT.equals(valueKind)) { continue; } // in very rare cases (for instance hybrid methods x-ray + neutron diffraction, e.g. 3ins, 4n9m) From 73343ef4c90d7985d38b75ddb4da61493a237687 Mon Sep 17 00:00:00 2001 From: Amr ALHOSSARY Date: Tue, 7 Dec 2021 08:02:15 +0800 Subject: [PATCH 4/5] Resolution defaults to 99 if no value is available. --- .../java/org/biojava/nbio/structure/PDBHeader.java | 10 ++++++++++ .../structure/io/cif/CifStructureConsumerImpl.java | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) 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 ea0f36115c..44fe2b0592 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 @@ -580,6 +580,16 @@ public void setCrystallographicInfo(PDBCrystallographicInfo crystallographicInfo this.crystallographicInfo = crystallographicInfo; } + /** + * Returns the resolution (or effective resolution) of the experiment. This is + * related to _refine.ls_d_res_high (DIFFRACTION) or + * _em_3d_reconstruction.resolution (ELECTRON MICROSCOPY) for mmCif + * format, or to REMARK 2 or REMARK 3 for PDB legacy + * format. If more than one value is available (in rare cases), the last one is + * reported. If no value is available, it defaults to 99. + * + * @return The reported experiment resolution, 99 if no value is available. + */ public float getResolution() { return resolution; } diff --git a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java index 4f1a40fab5..debadc4c08 100644 --- a/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java +++ b/biojava-structure/src/main/java/org/biojava/nbio/structure/io/cif/CifStructureConsumerImpl.java @@ -651,8 +651,10 @@ public void consumeDatabasePDBRevRecord(DatabasePDBRevRecord databasePDBrevRecor public void consumeEm3dReconstruction(Em3dReconstruction em3dReconstruction) { this.em3dReconstruction = em3dReconstruction; - for (int rowIndex = 0; rowIndex < em3dReconstruction.getRowCount(); rowIndex++) { - pdbHeader.setResolution((float) em3dReconstruction.getResolution().get(rowIndex)); //can it have more than 1 value? + for (int rowIndex = 0; rowIndex < em3dReconstruction.getRowCount(); rowIndex++) { //can it have more than 1 value? + final FloatColumn resolution = em3dReconstruction.getResolution(); + if (ValueKind.PRESENT.equals(resolution.getValueKind(rowIndex))) + pdbHeader.setResolution((float) resolution.get(rowIndex)); } //TODO other fields (maybe RFree)? } From f04916ad4e47ca9e6898b8c0b81844916c7a039a Mon Sep 17 00:00:00 2001 From: Amr ALHOSSARY Date: Thu, 9 Dec 2021 07:14:37 +0800 Subject: [PATCH 5/5] Referring to DEFAULT_RESOLUTION instead of 99 --- .../src/main/java/org/biojava/nbio/structure/PDBHeader.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 44fe2b0592..a948e3281a 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 @@ -586,9 +586,11 @@ public void setCrystallographicInfo(PDBCrystallographicInfo crystallographicInfo * _em_3d_reconstruction.resolution (ELECTRON MICROSCOPY) for mmCif * format, or to REMARK 2 or REMARK 3 for PDB legacy * format. If more than one value is available (in rare cases), the last one is - * reported. If no value is available, it defaults to 99. + * reported. If no value is available, it defaults to + * {@link #DEFAULT_RESOLUTION} ({@value #DEFAULT_RESOLUTION}). * - * @return The reported experiment resolution, 99 if no value is available. + * @return The reported experiment resolution, {@link #DEFAULT_RESOLUTION} + * ({@value #DEFAULT_RESOLUTION}) if no value is available. */ public float getResolution() { return resolution;