
org.biojava.nbio.structure.quaternary.BiologicalAssemblyBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of biojava-structure Show documentation
Show all versions of biojava-structure Show documentation
The protein structure modules of BioJava.
/*
* 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.quaternary;
import org.biojava.nbio.structure.Atom;
import org.biojava.nbio.structure.Chain;
import org.biojava.nbio.structure.Group;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* Reconstructs the quaternary structure of a protein from an asymmetric unit
*
* @author Peter Rose
* @author Andreas Prlic
*
*/
public class BiologicalAssemblyBuilder {
private static final Logger logger = LoggerFactory.getLogger(BiologicalAssemblyBuilder.class);
private OperatorResolver operatorResolver;
private List psags;
private List modelTransformations;
private List modelIndex = new ArrayList();
public BiologicalAssemblyBuilder(){
init();
}
public Structure rebuildQuaternaryStructure(Structure asymUnit, List transformations){
// ensure that new chains are build in the same order as they appear in the asymmetric unit
orderTransformationsByChainId(asymUnit, transformations);
Structure s = asymUnit.clone();
// this resets all models (not only the first one): this is important for NMR (multi-model)
// structures, otherwise we could not add new models below
s.resetModels();
for (BiologicalAssemblyTransformation transformation : transformations){
// note: for NMR structures (or any multi-model) we use the first model only and throw away the rest
for (Chain c : asymUnit.getChains()){
String intChainID = c.getInternalChainID();
if (intChainID == null) {
logger.info("No internal chain ID found while building bioassembly, using chain ID instead: " + c.getChainID());
intChainID = c.getChainID();
}
if (transformation.getChainId().equals(intChainID)){
Chain chain = (Chain)c.clone();
for (Group g : chain.getAtomGroups()) {
for (Atom a: g.getAtoms()) {
transformation.transformPoint(a.getCoords());
}
}
String transformId = transformation.getId();
addChainAndModel(s, chain, transformId);
}
}
}
s.setBiologicalAssembly(true);
return s;
}
/**
* Orders model transformations by chain ids in the same order as in the asymmetric unit
* @param asymUnit
* @param transformations
*/
private void orderTransformationsByChainId(Structure asymUnit, List transformations) {
final List chainIds = getChainIds(asymUnit);
Collections.sort(transformations, new Comparator() {
@Override
public int compare(BiologicalAssemblyTransformation t1, BiologicalAssemblyTransformation t2) {
// set sort order only if the two ids are identical
if (t1.getId().equals(t2.getId())) {
return chainIds.indexOf(t1.getChainId()) - chainIds.indexOf(t2.getChainId());
}
return 0;
}
});
}
/**
* Returns a list of chain ids in the order they are specified in the ATOM
* records in the asymmetric unit
* @param asymUnit
* @return
*/
private List getChainIds(Structure asymUnit) {
List chainIds = new ArrayList();
for ( Chain c : asymUnit.getChains()){
String intChainID = c.getInternalChainID();
if ( intChainID == null) {
//System.err.println("no internal chain ID found, using " + c.getChainID() + " ( while looking for " + max.ndbChainId+")");
intChainID = c.getChainID();
}
chainIds.add(intChainID);
}
return chainIds;
}
private void addChainAndModel(Structure s, Chain newChain, String modelId) {
if ( modelIndex.size() == 0)
modelIndex.add("PLACEHOLDER FOR ASYM UNIT");
int modelCount = modelIndex.indexOf(modelId);
if ( modelCount == -1) {
modelIndex.add(modelId);
modelCount = modelIndex.indexOf(modelId);
}
if (modelCount == 0) {
s.addChain(newChain);
} else if (modelCount > s.nrModels()) {
List newModel = new ArrayList();
newModel.add(newChain);
s.addModel(newModel);
} else {
s.addChain(newChain, modelCount-1);
}
}
/**
* Returns a list of transformation matrices for the generation of a macromolecular
* assembly for the specified assembly Id.
*
* @param assemblyId Id of the macromolecular assembly to be generated
* @return list of transformation matrices to generate macromolecular assembly
*/
public ArrayList getBioUnitTransformationList(PdbxStructAssembly psa, List psags, List operators) {
//System.out.println("Rebuilding " + psa.getDetails() + " | " + psa.getOligomeric_details() + " | " + psa.getOligomeric_count());
//System.out.println(psag);
init();
this.psags = psags;
//psa.getId();
for (PdbxStructOperList oper: operators){
BiologicalAssemblyTransformation transform = new BiologicalAssemblyTransformation();
transform.setId(oper.getId());
transform.setRotationMatrix(oper.getMatrix().getArray());
transform.setTranslation(oper.getVector());
// transform.setTransformationMatrix(oper.getMatrix(), oper.getVector());
modelTransformations.add(transform);
}
ArrayList transformations = getBioUnitTransformationsListUnaryOperators(psa.getId());
transformations.addAll(getBioUnitTransformationsListBinaryOperators(psa.getId()));
transformations.trimToSize();
return transformations;
}
private ArrayList getBioUnitTransformationsListBinaryOperators(String assemblyId) {
ArrayList transformations = new ArrayList();
List> operators = operatorResolver.getBinaryOperators();
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) {
int modelNumber = 1;
for (OrderedPair operator : operators) {
BiologicalAssemblyTransformation original1 = getModelTransformationMatrix(operator.getElement1());
BiologicalAssemblyTransformation original2 = getModelTransformationMatrix(operator.getElement2());
// ModelTransformationMatrix transform = ModelTransformationMatrix.multiply4square_x_4square2(original1, original2);
BiologicalAssemblyTransformation transform = BiologicalAssemblyTransformation.combine(original1, original2);
transform.setChainId(chainId);
// transform.setId(original1.getId() + "x" + original2.getId());
transform.setId(String.valueOf(modelNumber));
transformations.add(transform);
modelNumber++;
}
}
}
}
return transformations;
}
private BiologicalAssemblyTransformation getModelTransformationMatrix(String operator) {
for (BiologicalAssemblyTransformation transform: modelTransformations) {
if (transform.getId().equals(operator)) {
return transform;
}
}
logger.error("Could not find modelTransformationmatrix for " + operator);
return new BiologicalAssemblyTransformation();
}
private ArrayList getBioUnitTransformationsListUnaryOperators(String assemblyId) {
ArrayList transformations = new ArrayList();
for ( PdbxStructAssemblyGen psag : psags){
if ( psag.getAssembly_id().equals(assemblyId)) {
operatorResolver.parseOperatorExpressionString(psag.getOper_expression());
List operators = operatorResolver.getUnaryOperators();
ListasymIds= Arrays.asList(psag.getAsym_id_list().split(","));
// apply unary operators to the specified chains
for (String chainId : asymIds) {
for (String operator : operators) {
BiologicalAssemblyTransformation original = getModelTransformationMatrix(operator);
BiologicalAssemblyTransformation transform = new BiologicalAssemblyTransformation(original);
transform.setChainId(chainId);
transform.setId(operator);
transformations.add(transform);
}
}
}
}
return transformations;
}
private void init(){
operatorResolver= new OperatorResolver();
modelTransformations = new ArrayList(1);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy