
org.biojava.nbio.structure.io.mmtf.MmtfStructureWriter Maven / Gradle / Ivy
/*
* 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.mmtf;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.biojava.nbio.structure.Atom;
import org.biojava.nbio.structure.Bond;
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.PDBCrystallographicInfo;
import org.biojava.nbio.structure.PDBHeader;
import org.biojava.nbio.structure.Structure;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 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 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
* structure and calls all the set functions.
* @param structure the input {@link Structure} to write
* @param dataTransferInterface the generic interface that
* implements all the set methods.
*/
public MmtfStructureWriter(Structure structure, StructureAdapterInterface dataTransferInterface) {
this.mmtfDecoderInterface = dataTransferInterface;
// Reset structure to consider altloc groups with the same residue number but different group names as seperate groups
MmtfUtils.fixMicroheterogenity(structure);
// Get the chain name to index map
MmtfSummaryDataBean mmtfSummaryDataBean = MmtfUtils.getStructureInfo(structure);
Map chainIdToIndexMap = mmtfSummaryDataBean.getChainIdToIndexMap();
List allAtoms = mmtfSummaryDataBean.getAllAtoms();
int numBonds = mmtfSummaryDataBean.getNumBonds();
List allChains = mmtfSummaryDataBean.getAllChains();
mmtfDecoderInterface.initStructure(numBonds, allAtoms.size(), MmtfUtils.getNumGroups(structure), allChains.size(), structure.nrModels(), structure.getPDBCode());
// Generate the secondary structure
MmtfUtils.calculateDsspSecondaryStructure(structure);
// Get the header and the xtal info.
PDBHeader pdbHeader = structure.getPDBHeader();
PDBCrystallographicInfo xtalInfo = pdbHeader.getCrystallographicInfo();
mmtfDecoderInterface.setHeaderInfo(pdbHeader.getRfree(), pdbHeader.getRwork(), pdbHeader.getResolution(), pdbHeader.getTitle(), MmtfUtils.dateToIsoString(pdbHeader.getDepDate()),
MmtfUtils.dateToIsoString(pdbHeader.getRelDate()), MmtfUtils.techniquesToStringArray(pdbHeader.getExperimentalTechniques()));
mmtfDecoderInterface.setXtalInfo(MmtfUtils.getSpaceGroupAsString(xtalInfo.getSpaceGroup()), MmtfUtils.getUnitCellAsArray(xtalInfo), MmtfUtils.getNcsAsArray(xtalInfo.getNcsOperators()));
// Store the bioassembly data
storeBioassemblyInformation(chainIdToIndexMap, pdbHeader.getBioAssemblies());
// Store the entity data
storeEntityInformation(allChains, structure.getEntityInfos());
// Now loop through the data structure
for (int modelIndex=0; modelIndex modelChains = structure.getChains(modelIndex);
// Set this model
mmtfDecoderInterface.setModelInfo(modelIndex, modelChains.size());
for(int chainInModelIndex=0; chainInModelIndex groups = chain.getAtomGroups();
List sequenceGroups = chain.getSeqResGroups();
mmtfDecoderInterface.setChainInfo(chain.getId(), chain.getName(), groups.size());
for(int groupInChainIndex=0; groupInChainIndex atomsInGroup = MmtfUtils.getAtomsForGroup(group);
ChemComp chemComp = group.getChemComp();
Character insCode = group.getResidueNumber().getInsCode();
if(insCode==null || insCode.equals(' ')){
insCode=MmtfStructure.UNAVAILABLE_CHAR_VALUE;
}
char singleLetterCode = 'X';
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,
sequenceGroups.indexOf(group), MmtfUtils.getSecStructType(group));
for (Atom atom : atomsInGroup){
char altLoc = MmtfStructure.UNAVAILABLE_CHAR_VALUE;
if(atom.getAltLoc()!=null){
if(atom.getAltLoc().charValue()!=' '){
altLoc=atom.getAltLoc().charValue();
}
}
mmtfDecoderInterface.setAtomInfo(atom.getName(), atom.getPDBserial(), altLoc, (float) atom.getX(),
(float) atom.getY(), (float) atom.getZ(), atom.getOccupancy(),
atom.getTempFactor(), atom.getElement().toString(), atom.getCharge());
addBonds(atom, atomsInGroup, allAtoms);
}
}
}
}
mmtfDecoderInterface.finalizeStructure();
}
/**
* Add the bonds for a given atom.
* @param atom the atom for which bonds are to be formed
* @param atomsInGroup the list of atoms in the group
* @param allAtoms the list of atoms in the whole structure
*/
private void addBonds(Atom atom, List atomsInGroup, List allAtoms) {
if(atom.getBonds()==null){
return;
}
for(Bond bond : atom.getBonds()) {
// Now set the bonding information.
Atom other = bond.getOther(atom);
// If both atoms are in the group
if (atomsInGroup.indexOf(other)!=-1){
Integer firstBondIndex = atomsInGroup.indexOf(atom);
Integer secondBondIndex = atomsInGroup.indexOf(other);
// Don't add the same bond twice
if(firstBondIndex>secondBondIndex){
int bondOrder = bond.getBondOrder();
mmtfDecoderInterface.setGroupBond(firstBondIndex, secondBondIndex, bondOrder);
}
}
// Otherwise it's an inter group bond - so add it here
else {
Integer firstBondIndex = allAtoms.indexOf(atom);
Integer secondBondIndex = allAtoms.indexOf(other);
if(firstBondIndex>secondBondIndex){
// Don't add the same bond twice
int bondOrder = bond.getBondOrder();
mmtfDecoderInterface.setInterGroupBond(firstBondIndex, secondBondIndex, bondOrder);
}
}
}
}
/**
* Store the entity information for a given structure.
* @param allChains a list of all the chains in a structure
* @param entityInfos a list of the entity information
*/
private void storeEntityInformation(List allChains, List entityInfos) {
for (EntityInfo entityInfo : entityInfos) {
String description = entityInfo.getDescription();
String type;
if (entityInfo.getType()==null){
type = null;
}
else{
type = entityInfo.getType().getEntityType();
}
List entityChains = entityInfo.getChains();
if (entityChains.isEmpty()){
// Error mapping chain to entity
logger.error("ERROR MAPPING CHAIN TO ENTITY: "+description);
mmtfDecoderInterface.setEntityInfo(new int[0], "", description, type);
}
else{
int[] chainIndices = new int[entityChains.size()];
for (int i=0; i chainIdToIndexMap, Map inputBioAss) {
int bioAssemblyIndex = 0;
for (Entry entry : inputBioAss.entrySet()) {
Map transformMap = MmtfUtils.getTransformMap(entry.getValue(), chainIdToIndexMap);
for(Entry transformEntry : transformMap.entrySet()) {
mmtfDecoderInterface.setBioAssemblyTrans(bioAssemblyIndex, transformEntry.getValue(), transformEntry.getKey(), entry.getKey().toString());
}
bioAssemblyIndex++;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy