Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,27 @@ protected CifFile getInternal(Structure structure, List<WrappedAtom> wrappedAtom
// entity information
List<EntityInfo> entityInfos = structure.getEntityInfos();

PdbId pdbId = structure.getPdbId();

MmCifBlockBuilder blockBuilder = CifBuilder.enterFile(StandardSchemata.MMCIF)
.enterBlock(structure.getPdbId() == null? "" : structure.getPdbId().getId());
.enterBlock(pdbId == null? "" : pdbId.getId());

if (pdbId != null) {
// The block header alone does not carry the identifier for consumers: readers pick it up from
// _entry.id (e.g. Jmol) or from _struct.entry_id (BioJava's own CifStructureConsumerImpl).
// Both are written so that the identifier survives a write-then-read round trip either way.
blockBuilder.enterEntry()
.enterId()
.add(pdbId.getId())
.leaveColumn()
.leaveCategory();

blockBuilder.enterStruct()
.enterEntryId()
.add(pdbId.getId())
.leaveColumn()
.leaveCategory();
}

blockBuilder.enterStructKeywords().enterText()
.add(String.join(", ", structure.getPDBHeader().getKeywords()))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.biojava.nbio.structure.io.cif;

import org.biojava.nbio.structure.PdbId;
import org.biojava.nbio.structure.Structure;
import org.biojava.nbio.structure.io.FileParsingParameters;
import org.biojava.nbio.structure.io.PDBFileParser;
Expand Down Expand Up @@ -41,4 +42,43 @@ public void shouldReadRawPdbOutputtingCifWithEntity() throws IOException {
}

}

/**
* The identifier must be written as a data item and not only as the name of the data block: consumers read it
* from _entry.id or from _struct.entry_id, so writing the block header alone loses it. See issue #1143.
*/
@Test
public void shouldWriteEntryIdAndSurviveRoundTrip() throws IOException {
Structure s;
try (InputStream inStream = new GZIPInputStream(this.getClass().getResourceAsStream("/4hhb.cif.gz"))) {
s = CifStructureConverter.fromInputStream(inStream);
}
assertEquals(new PdbId("4HHB"), s.getPdbId());

String cifText = CifStructureConverter.toText(s);
assertTrue("_entry.id must be written", cifText.contains("_entry.id"));
assertTrue("_struct.entry_id must be written", cifText.contains("_struct.entry_id"));

Structure readStruct = CifStructureConverter.fromInputStream(
new ByteArrayInputStream(cifText.getBytes()));

assertEquals(s.getPdbId(), readStruct.getPdbId());
assertEquals(s.getPdbId(), readStruct.getPDBHeader().getPdbId());
}

/**
* Structures without an identifier must not gain empty entry categories.
*/
@Test
public void shouldNotWriteEntryIdWhenPdbIdIsAbsent() throws IOException {
Structure s;
try (InputStream inStream = new GZIPInputStream(this.getClass().getResourceAsStream("/4hhb.cif.gz"))) {
s = CifStructureConverter.fromInputStream(inStream);
}
s.setPdbId(null);

String cifText = CifStructureConverter.toText(s);
assertFalse(cifText.contains("_entry.id"));
assertFalse(cifText.contains("_struct.entry_id"));
}
}
Loading