001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.nbio.structure.align.multiple.util; 022 023import org.biojava.nbio.structure.*; 024import org.biojava.nbio.structure.align.multiple.MultipleAlignment; 025import org.slf4j.Logger; 026import org.slf4j.LoggerFactory; 027 028import javax.vecmath.Matrix4d; 029 030import java.util.ArrayList; 031import java.util.Arrays; 032import java.util.List; 033 034/** 035 * Utility functions to generalize the visualization of MultipleAlignments in 036 * molecular viewers. The methods return different types of selectors for the 037 * aligned residues in the alignment. 038 * 039 * @author Andreas Prlic 040 * @author Aleix Lafita 041 * @author Spencer Bliven 042 * @since 4.2.0 043 * 044 */ 045public class MultipleAlignmentDisplay { 046 047 private static final Logger logger = LoggerFactory 048 .getLogger(MultipleAlignmentDisplay.class); 049 050 /** 051 * New structures are downloaded if they were not cached in the alignment 052 * and they are entirely transformed here with the superposition information 053 * in the Multiple Alignment. 054 * 055 * @param multAln 056 * @return list of transformed AtomArrays 057 * @throws StructureException 058 */ 059 public static List<Atom[]> getRotatedAtoms(MultipleAlignment multAln) 060 throws StructureException { 061 062 int size = multAln.size(); 063 064 List<Atom[]> atomArrays = multAln.getAtomArrays(); 065 for (int i = 0; i < size; i++) { 066 if (atomArrays.get(i).length < 1) 067 throw new StructureException( 068 "Length of atoms arrays is too short! Size: " 069 + atomArrays.get(i).length); 070 } 071 072 List<Atom[]> rotatedAtoms = new ArrayList<Atom[]>(); 073 074 // TODO implement independent BlockSet superposition of the structure 075 List<Matrix4d> transf = multAln.getBlockSet(0).getTransformations(); 076 077 if (transf == null) { 078 079 logger.error("Alignment Transformations are not calculated. " 080 + "Superimposing to first structure as reference."); 081 082 multAln = multAln.clone(); 083 MultipleSuperimposer imposer = new ReferenceSuperimposer(); 084 imposer.superimpose(multAln); 085 transf = multAln.getBlockSet(0).getTransformations(); 086 assert (transf != null); 087 } 088 089 // Rotate the atom coordinates of all the structures 090 for (int i = 0; i < size; i++) { 091 // TODO handle BlockSet-level transformations 092 // make sure this method has the same behavior as the other display. 093 // -SB 2015-06 094 095 // Assume all atoms are from the same structure 096 Structure displayS = atomArrays.get(i)[0].getGroup().getChain() 097 .getStructure().clone(); 098 099 // Get all the atoms and include ligands and hetatoms 100 Atom[] rotCA = StructureTools.getRepresentativeAtomArray(displayS); 101 List<Group> hetatms = StructureTools.getUnalignedGroups(rotCA); 102 int index = rotCA.length; 103 rotCA = Arrays.copyOf(rotCA, rotCA.length + hetatms.size()); 104 for (Group g : hetatms) { 105 rotCA[index] = g.getAtom(0); 106 index++; 107 } 108 109 // Transform the structure to ensure a full rotation in the display 110 Calc.transform(displayS, transf.get(i)); 111 rotatedAtoms.add(rotCA); 112 } 113 114 return rotatedAtoms; 115 } 116}