Skip to content

Commit c04eb88

Browse files
committed
Merge pull request biojava#318 from sbliven/master
Output MultipleAlignment objects as an I-TASSER restraint file
2 parents 9f57459 + 7ecb81e commit c04eb88

1 file changed

Lines changed: 88 additions & 1 deletion

File tree

biojava-structure/src/main/java/org/biojava/nbio/structure/align/multiple/util/MultipleAlignmentTools.java

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.biojava.nbio.structure.Atom;
1414
import org.biojava.nbio.structure.Calc;
1515
import org.biojava.nbio.structure.StructureTools;
16+
import org.biojava.nbio.structure.align.client.StructureName;
1617
import org.biojava.nbio.structure.align.multiple.Block;
1718
import org.biojava.nbio.structure.align.multiple.BlockSet;
1819
import org.biojava.nbio.structure.align.multiple.MultipleAlignment;
@@ -669,7 +670,93 @@ public static List<Integer> getCorePositions(Block block){
669670
}
670671
return corePositions;
671672
}
672-
673+
674+
/**
675+
* Outputs a pairwise alignment in I-TASSER's 3D Format for target-template
676+
* alignment.
677+
* http://zhanglab.ccmb.med.umich.edu/I-TASSER/option4.html
678+
*
679+
* <p>The format is closely related to a standard PDB file, but contains only
680+
* CA atoms and adds two columns for specifying the alignment:
681+
*
682+
* <pre>
683+
ATOM 2001 CA MET 1 41.116 -30.727 6.866 129 THR
684+
ATOM 2002 CA ALA 2 39.261 -27.408 6.496 130 ARG
685+
ATOM 2003 CA ALA 3 35.665 -27.370 7.726 131 THR
686+
ATOM 2004 CA ARG 4 32.662 -25.111 7.172 132 ARG
687+
ATOM 2005 CA GLY 5 29.121 -25.194 8.602 133 ARG
688+
689+
Column 1 -30: Atom & Residue records of query sequence.
690+
Column 31-54: Coordinates of atoms in query copied from corresponding atoms in template.
691+
Column 55-59: Corresponding residue number in template based on alignment
692+
Column 60-64: Corresponding residue name in template
693+
</pre>
694+
*
695+
* <p>Note that the output is a pairwise alignment. Other rows in the
696+
* MultipleAlignment will be ignored.
697+
*
698+
* <p>This method supports topology-independent alignments. The output will
699+
* have sequence order matching the query, but include atoms from the
700+
* template.
701+
*
702+
* @param alignment A <em>full</em> multiple alignment between proteins
703+
* @param queryIndex index of the query within the multiple alignment
704+
* @param templateIndex index of the template within the multiple alignment
705+
* @return The file contents as a string
706+
*/
707+
public static String to3DFormat(MultipleAlignment alignment, int queryIndex, int templateIndex) {
708+
List<Atom[]> atomArrays = alignment.getEnsemble().getAtomArrays();
709+
Atom[] queryAtoms = atomArrays.get(queryIndex);
710+
Atom[] templateAtoms = atomArrays.get(templateIndex);
711+
712+
List<Block> blocks = alignment.getBlocks();
713+
sortBlocks(blocks, queryIndex);
714+
715+
StringBuilder str = new StringBuilder();
716+
717+
// Gather info about the template structure
718+
String tNameStr = alignment.getEnsemble().getStructureNames().get(templateIndex);
719+
StructureName tName = new StructureName(tNameStr);
720+
String tPdbId = tName.getPdbId();
721+
String tChain = tName.getChainId();
722+
723+
if(tChain == null ) {
724+
// Use the chain of the first template block
725+
for(Integer i : blocks.get(0).getAlignRes().get(templateIndex)) {
726+
if(i!=null) {
727+
tChain = templateAtoms[ i ].getGroup().getChainId();
728+
break;
729+
}
730+
}
731+
}
732+
str.append(String.format("REMARK Template name:%s:%s\n",tPdbId,tChain));
733+
for(Block block : blocks) {
734+
List<Integer> qAlign = block.getAlignRes().get(queryIndex);
735+
List<Integer> tAlign = block.getAlignRes().get(templateIndex);
736+
for(int i=0;i<block.length();i++) {
737+
Integer qRes = qAlign.get(i);
738+
Integer tRes = tAlign.get(i);
739+
740+
// skip gaps
741+
if(qRes == null || tRes == null)
742+
continue;
743+
744+
// Get PDB-format ATOM records
745+
String qPDB = queryAtoms[qRes].toPDB();
746+
String tPDB = templateAtoms[tRes].toPDB();
747+
748+
// merge the two records into 3D format
749+
str.append(qPDB.substring(0,30)); // up through coordinates
750+
str.append(tPDB.substring(30, 54)); // coordinates
751+
str.append(tPDB.substring(22, 27)); // residue number
752+
str.append(' ');
753+
str.append(tPDB.substring(17, 20));
754+
str.append('\n');
755+
}
756+
}
757+
return str.toString();
758+
}
759+
673760
/**
674761
* Sort blocks so that the specified row is in sequential order.
675762
* The sort happens in place.

0 commit comments

Comments
 (0)