Skip to content

Commit 03da5f5

Browse files
committed
Show ligands in the MultipleAlignment display
1 parent 1ee85f7 commit 03da5f5

File tree

4 files changed

+177
-124
lines changed

4 files changed

+177
-124
lines changed

biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/DisplayAFP.java

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ private static final int getUngappedFatCatPos(AFPChain afpChain, int chainNr, in
420420
* @return a list of Chains that is built up from the Atoms in the ca array
421421
* @throws StructureException
422422
*/
423-
private static final List<Chain> getAlignedModel(Atom[] ca){
423+
static final List<Chain> getAlignedModel(Atom[] ca){
424424

425425
List<Chain> model = new ArrayList<Chain>();
426426
for ( Atom a: ca){
@@ -473,30 +473,16 @@ public static final Structure getAlignedStructure(Atom[] ca1, Atom[] ca2) throws
473473
474474
return s;*/
475475

476-
return getAlignedStructure(Arrays.asList(ca1,ca2));
477-
}
478-
479-
/** Get an artifical Structure containing all the chains (Multiple Alignment generalization)
480-
* Does NOT rotate anything
481-
* @param ca1
482-
* @param ca2
483-
* @return a structure object containing two models, one for each set of Atoms.
484-
* @throws StructureException
485-
*/
486-
public static final Structure getAlignedStructure(List<Atom[]> atomArrays) throws StructureException{
487-
488476
Structure s = new StructureImpl();
489477

490-
for (int i=0; i<atomArrays.size(); i++){
491-
List<Chain>model = getAlignedModel(atomArrays.get(i));
492-
s.addModel(model);
493-
}
478+
List<Chain>model1 = getAlignedModel(ca1);
479+
s.addModel(model1);
480+
List<Chain> model2 = getAlignedModel(ca2);
481+
s.addModel(model2);
494482

495483
return s;
496484
}
497485

498-
499-
500486
/**
501487
* Returns the first atom for each group
502488
* @param ca

biojava-structure-gui/src/main/java/org/biojava/nbio/structure/align/gui/MultipleAlignmentDisplay.java

Lines changed: 147 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.awt.Dimension;
44
import java.util.ArrayList;
5+
import java.util.Arrays;
6+
import java.util.Collections;
57
import java.util.List;
68

79
import javax.swing.Box;
@@ -12,8 +14,11 @@
1214

1315
import org.biojava.nbio.structure.Atom;
1416
import org.biojava.nbio.structure.Calc;
17+
import org.biojava.nbio.structure.Chain;
18+
import org.biojava.nbio.structure.Group;
1519
import org.biojava.nbio.structure.Structure;
1620
import org.biojava.nbio.structure.StructureException;
21+
import org.biojava.nbio.structure.StructureImpl;
1722
import org.biojava.nbio.structure.StructureTools;
1823
import org.biojava.nbio.structure.align.gui.aligpanel.MultipleAligPanel;
1924
import org.biojava.nbio.structure.align.gui.aligpanel.MultipleStatusDisplay;
@@ -24,42 +29,49 @@
2429
import org.biojava.nbio.structure.align.multiple.MultipleAlignment;
2530
import org.biojava.nbio.structure.align.multiple.MultipleSuperimposer;
2631
import org.biojava.nbio.structure.align.multiple.ReferenceSuperimposer;
27-
import org.jcolorbrewer.ColorBrewer;
2832
import org.slf4j.Logger;
2933
import org.slf4j.LoggerFactory;
3034

3135
/**
32-
* Utility Class that provides methods for the visualization of {@link MultipleAlignment}s.
36+
* Utility Class that provides helper methods for the visualization of
37+
* {@link MultipleAlignment}s.
3338
* <p>
34-
* Currently supported: Alignment Panel Display, select aligned residues by PDB code,
35-
* JmolPanel display.
39+
* Currently supported: Alignment Panel Display, select aligned
40+
* residues in Jmol by their PDB name, show a text Frame for any sequence
41+
* alignment format, basic Jmol display from a MultipleAlignment, generate
42+
* an artificial PDB structure with a new model for every aligned structure.
3643
*
3744
* @author Aleix Lafita
3845
*
3946
*/
4047
public class MultipleAlignmentDisplay {
41-
42-
private static final Logger logger = LoggerFactory.getLogger(MultipleAlignmentDisplay.class);
48+
49+
private static final Logger logger =
50+
LoggerFactory.getLogger(MultipleAlignmentDisplay.class);
4351

4452
/**
45-
* Utility method used in the {@link MultipleAlignmentJmol} panel, when the aligned residues of a
46-
* structure in the alignment have to be selected for formatting (coloring and style).
53+
* Utility method used in the {@link MultipleAlignmentJmol} Frame,
54+
* when the aligned residues of a structure in the alignment have
55+
* to be selected for formatting them (coloring and style).
4756
*
4857
* @param structNum the structure index (row) of the alignment
49-
* @param multAln the MultipleAlignment that contains the equivalent positions
50-
* @param ca the atom array of the structure specified (corresponding to the structure index)
51-
* @return List of pdb Strings corresponding to the aligned positions of the molecule.
58+
* @param multAln the MultipleAlignment that contains the equivalent
59+
* positions
60+
* @param ca the atom array of the structure specified
61+
* (corresponding to the structure index)
62+
* @return List of pdb Strings corresponding to the aligned positions
63+
* of the structure.
5264
*/
53-
public static final List<String> getPDBresnum(int structNum, MultipleAlignment multAln, Atom[] ca){
54-
65+
public static final List<String> getPDBresnum(int structNum,
66+
MultipleAlignment multAln, Atom[] ca){
67+
5568
List<String> lst = new ArrayList<String>();
5669

57-
//Loop through all the Blocks in the alignment
5870
for(Block block : multAln.getBlocks() ) {
59-
//Loop though all the residues in the Block
71+
6072
for (int i=0; i<block.length(); i++){
6173
Integer pos = block.getAlignRes().get(structNum).get(i);
62-
if (pos==null) continue; //It means a GAP
74+
if (pos==null) continue; //gap
6375
else if (pos < ca.length) {
6476
String pdbInfo = JmolTools.getPdbInfo(ca[pos]);
6577
lst.add(pdbInfo);
@@ -68,26 +80,31 @@ else if (pos < ca.length) {
6880
}
6981
return lst;
7082
}
71-
83+
7284
/**
73-
* Creates a new Frame with the MultipleAlignment Sequence Panel. The panel can communicate with
74-
* the Jmol 3D visualization by selecting the aligned residues of all structures.
85+
* Creates a new Frame with the MultipleAlignment Sequence Panel.
86+
* The panel can communicate with the Jmol 3D visualization by
87+
* selecting the aligned residues of every structure.
7588
*
7689
* @param multAln
7790
* @param jmol
7891
* @param colors
7992
* @throws StructureException
8093
*/
81-
public static void showMultipleAligmentPanel(MultipleAlignment multAln, AbstractAlignmentJmol jmol) throws StructureException {
82-
94+
public static void showMultipleAligmentPanel(MultipleAlignment multAln,
95+
AbstractAlignmentJmol jmol) throws StructureException {
96+
8397
MultipleAligPanel me = new MultipleAligPanel(multAln, jmol);
8498
JFrame frame = new JFrame();
8599

86100
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
87101
frame.setTitle(jmol.getTitle());
88-
me.setPreferredSize(new Dimension(me.getCoordManager().getPreferredWidth() , me.getCoordManager().getPreferredHeight()));
102+
me.setPreferredSize(new Dimension(
103+
me.getCoordManager().getPreferredWidth() ,
104+
me.getCoordManager().getPreferredHeight()));
89105

90-
JMenuBar menu = MenuCreator.getAlignmentPanelMenu(frame,me,null, multAln);
106+
JMenuBar menu = MenuCreator.getAlignmentPanelMenu(
107+
frame,me,null, multAln);
91108
frame.setJMenuBar(menu);
92109

93110
JScrollPane scroll = new JScrollPane(me);
@@ -103,29 +120,33 @@ public static void showMultipleAligmentPanel(MultipleAlignment multAln, Abstract
103120

104121
frame.pack();
105122
frame.setVisible(true);
106-
//make sure they get cleaned up correctly:
123+
107124
frame.addWindowListener(me);
108125
frame.addWindowListener(status);
109126
}
110-
127+
111128
/**
112-
* Creates a new Frame with the String output representation of the {@link MultipleAlignment}.
129+
* Creates a new Frame with the String output representation of the
130+
* {@link MultipleAlignment}.
113131
*
114132
* @param multAln
115133
* @param result String output
116134
*/
117-
public static void showAlignmentImage(MultipleAlignment multAln, String result) {
135+
public static void showAlignmentImage(MultipleAlignment multAln,
136+
String result) {
118137

119138
JFrame frame = new JFrame();
120139

121-
String title = multAln.getEnsemble().getAlgorithmName() + " V."+multAln.getEnsemble().getVersion();
140+
String title = multAln.getEnsemble().getAlgorithmName() +
141+
" V."+multAln.getEnsemble().getVersion();
122142
frame.setTitle(title);
123143
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
124144

125145
AlignmentTextPanel txtPanel = new AlignmentTextPanel();
126146
txtPanel.setText(result);
127147

128-
JMenuBar menu = MenuCreator.getAlignmentTextMenu(frame,txtPanel,null,multAln);
148+
JMenuBar menu = MenuCreator.getAlignmentTextMenu(
149+
frame,txtPanel,null,multAln);
129150

130151
frame.setJMenuBar(menu);
131152
JScrollPane js = new JScrollPane();
@@ -136,61 +157,101 @@ public static void showAlignmentImage(MultipleAlignment multAln, String result)
136157
frame.pack();
137158
frame.setVisible(true);
138159
}
139-
140-
/**
141-
* Display a MultipleAlignment with a JmolPanel. New structures are downloaded if they were
142-
* not cached in the alignment and they are entirely transformed here with the cached
143-
* superposition information.
144-
*
145-
* @param multAln
146-
* @return MultipleAlignmentJmol instance
147-
* @throws StructureException
148-
*/
149-
public static MultipleAlignmentJmol display(MultipleAlignment multAln) throws StructureException {
150-
151-
int size = multAln.size();
152-
153-
List<Atom[]> atomArrays = multAln.getEnsemble().getAtomArrays();
154-
for (int i=0; i<size; i++){
155-
if (atomArrays.get(i).length < 1)
156-
throw new StructureException("Length of atoms arrays is too short! " + atomArrays.get(i).length);
157-
}
158-
159-
List<Atom[]> rotatedAtoms = new ArrayList<Atom[]>();
160-
161-
List<Matrix4d> transformations = multAln.getTransformations();
162-
//TODO implement BlockSet superposition of the structure, now using the transformation of first Block Only
163-
if (multAln.getBlockSets().size() > 1) transformations = multAln.getBlockSets().get(0).getTransformations();
164-
165-
if(transformations == null) {
166-
logger.error("Alignment Transformations are not calculated. Superimposing to first structure as reference.");
167-
168-
multAln = multAln.clone();
169-
MultipleSuperimposer imposer = new ReferenceSuperimposer();
170-
imposer.superimpose(multAln);
171-
transformations = multAln.getTransformations();
172-
173-
//TODO implement BlockSet superposition of the structure, now using the transformation of first Block Only
174-
if (multAln.getBlockSets().size() > 1) transformations = multAln.getBlockSets().get(0).getTransformations();
175-
176-
assert(transformations != null);
177-
}
178-
179-
//Rotate the atom coordinates of all the structures
180-
for (int i=0; i<size; i++){
181-
//TODO handle BlockSet-level transformations for flexible alignments.
182-
// In general, make sure this method has the same behavior as the other display. -SB 2015-06
183-
184-
//Assume all atoms are from the same structure
185-
Structure displayS = atomArrays.get(i)[0].getGroup().getChain().getParent().clone();
186-
Atom[] rotCA = StructureTools.getRepresentativeAtomArray(displayS);
187-
//Rotate the structure to ensure a full rotation in the display
188-
Calc.transform(rotCA[0].getGroup().getChain().getParent(), transformations.get(i));
189-
rotatedAtoms.add(rotCA);
190-
}
191-
192-
MultipleAlignmentJmol jmol = new MultipleAlignmentJmol(multAln, rotatedAtoms);
193-
jmol.setTitle(jmol.getStructure().getPDBHeader().getTitle());
194-
return jmol;
195-
}
160+
161+
/**
162+
* Display a MultipleAlignment with a JmolPanel.
163+
* New structures are downloaded if they were
164+
* not cached in the alignment and they are entirely
165+
* transformed here with the superposition information
166+
* in the Multiple Alignment.
167+
*
168+
* @param multAln
169+
* @return MultipleAlignmentJmol instance
170+
* @throws StructureException
171+
*/
172+
public static MultipleAlignmentJmol display(MultipleAlignment multAln)
173+
throws StructureException {
174+
175+
int size = multAln.size();
176+
177+
List<Atom[]> atomArrays = multAln.getEnsemble().getAtomArrays();
178+
for (int i=0; i<size; i++){
179+
if (atomArrays.get(i).length < 1)
180+
throw new StructureException(
181+
"Length of atoms arrays is too short! Size: "
182+
+ atomArrays.get(i).length);
183+
}
184+
185+
List<Atom[]> rotatedAtoms = new ArrayList<Atom[]>();
186+
187+
List<Matrix4d> transforms = multAln.getTransformations();
188+
//TODO implement independent BlockSet superposition of the structure
189+
if (multAln.getBlockSets().size() > 1) {
190+
transforms = multAln.getBlockSets().get(0).getTransformations();
191+
}
192+
193+
if(transforms == null) {
194+
195+
logger.error("Alignment Transformations are not calculated. "
196+
+ "Superimposing to first structure as reference.");
197+
198+
multAln = multAln.clone();
199+
MultipleSuperimposer imposer = new ReferenceSuperimposer();
200+
imposer.superimpose(multAln);
201+
transforms = multAln.getTransformations();
202+
203+
if (multAln.getBlockSets().size() > 1) {
204+
transforms = multAln.getBlockSets().get(0).getTransformations();
205+
}
206+
assert(transforms != null);
207+
}
208+
209+
//Rotate the atom coordinates of all the structures
210+
for (int i=0; i<size; i++){
211+
//TODO handle BlockSet-level transformations
212+
//make sure this method has the same behavior as the other display.
213+
//-SB 2015-06
214+
215+
//Assume all atoms are from the same structure
216+
Structure displayS = atomArrays.get(i)[0].getGroup().
217+
getChain().getParent().clone();
218+
//Get all the atoms and include ligands and hetatoms
219+
Atom[] rotCA = StructureTools.getRepresentativeAtomArray(displayS);
220+
List<Group> hetatms = StructureTools.getUnalignedGroups(rotCA);
221+
for (Group g:hetatms){
222+
rotCA = Arrays.copyOf(rotCA, rotCA.length + 1);
223+
rotCA[rotCA.length - 1] = g.getAtom(0);
224+
}
225+
226+
//Transform the structure to ensure a full rotation in the display
227+
Calc.transform(displayS, transforms.get(i));
228+
rotatedAtoms.add(rotCA);
229+
}
230+
231+
MultipleAlignmentJmol jmol = new MultipleAlignmentJmol(multAln, rotatedAtoms);
232+
jmol.setTitle(jmol.getStructure().getPDBHeader().getTitle());
233+
return jmol;
234+
}
235+
236+
/**
237+
* Get an artifical Structure containing a different model for every
238+
* input structure, so that the alignment result can be viewed in Jmol.
239+
* The Atoms have to be rotated beforehand.
240+
*
241+
* @param atomArrays an array of Atoms for every aligned structure
242+
* @return a structure object containing a set of models,
243+
* one for each input array of Atoms.
244+
* @throws StructureException
245+
*/
246+
public static final Structure getAlignedStructure(List<Atom[]> atomArrays)
247+
throws StructureException {
248+
249+
Structure s = new StructureImpl();
250+
for (int i=0; i<atomArrays.size(); i++){
251+
List<Chain> model = DisplayAFP.getAlignedModel(atomArrays.get(i));
252+
s.addModel(model);
253+
}
254+
return s;
255+
}
256+
196257
}

0 commit comments

Comments
 (0)