22
33import java .awt .Dimension ;
44import java .util .ArrayList ;
5+ import java .util .Arrays ;
6+ import java .util .Collections ;
57import java .util .List ;
68
79import javax .swing .Box ;
1214
1315import org .biojava .nbio .structure .Atom ;
1416import org .biojava .nbio .structure .Calc ;
17+ import org .biojava .nbio .structure .Chain ;
18+ import org .biojava .nbio .structure .Group ;
1519import org .biojava .nbio .structure .Structure ;
1620import org .biojava .nbio .structure .StructureException ;
21+ import org .biojava .nbio .structure .StructureImpl ;
1722import org .biojava .nbio .structure .StructureTools ;
1823import org .biojava .nbio .structure .align .gui .aligpanel .MultipleAligPanel ;
1924import org .biojava .nbio .structure .align .gui .aligpanel .MultipleStatusDisplay ;
2429import org .biojava .nbio .structure .align .multiple .MultipleAlignment ;
2530import org .biojava .nbio .structure .align .multiple .MultipleSuperimposer ;
2631import org .biojava .nbio .structure .align .multiple .ReferenceSuperimposer ;
27- import org .jcolorbrewer .ColorBrewer ;
2832import org .slf4j .Logger ;
2933import 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 */
4047public 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