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..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
@@ -580,6 +580,18 @@ 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
+ * {@link #DEFAULT_RESOLUTION} ({@value #DEFAULT_RESOLUTION}).
+ *
+ * @return The reported experiment resolution, {@link #DEFAULT_RESOLUTION}
+ * ({@value #DEFAULT_RESOLUTION}) if no value is available.
+ */
public float getResolution() {
return resolution;
}
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);
}
}
-
}
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..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
@@ -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,18 @@ 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++) { //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)?
+ }
@Override
public void consumeEntity(Entity entity) {
@@ -831,6 +845,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.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());