001/* 002 * PDB web 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 * 015 * Created on Jul 28, 2009 016 * Created by ap3 017 * 018 */ 019 020package org.biojava.nbio.structure.align.gui; 021 022import org.biojava.nbio.structure.Atom; 023import org.biojava.nbio.structure.StructureException; 024import org.biojava.nbio.structure.align.StructureAlignmentFactory; 025import org.biojava.nbio.structure.align.ce.CeCPMain; 026import org.biojava.nbio.structure.align.ce.CeMain; 027import org.biojava.nbio.structure.align.ce.CeParameters; 028import org.biojava.nbio.structure.align.helper.JointFragments; 029import org.biojava.nbio.structure.align.model.AFP; 030import org.biojava.nbio.structure.align.model.AFPChain; 031import org.biojava.nbio.structure.align.pairwise.AlternativeAlignment; 032import org.biojava.nbio.structure.align.util.AtomCache; 033import org.biojava.nbio.structure.gui.ScaleableMatrixPanel; 034import org.biojava.nbio.structure.jama.Matrix; 035 036import javax.swing.*; 037import java.awt.event.WindowAdapter; 038import java.awt.event.WindowEvent; 039import java.io.IOException; 040import java.util.ArrayList; 041import java.util.List; 042 043/** 044 * Displays the dot plot trace for an alignment. 045 * 046 * This class adapts ScaleableMatrixPanel, which uses code from org.biojava.nbio.structure.align.pairwise, 047 * with more BioJava-friendly methods based off AFPChains. 048 * 049 * @author Spencer Bliven 050 * 051 */ 052public class DotPlotPanel extends ScaleableMatrixPanel { 053 054 private static final long serialVersionUID = -7641953255857483895L; 055 056 /** 057 * 058 * @param alignment The alignment to plot 059 * @param background [Optional]A matrix of 'background colors' over which to draw the alignment. 060 * 061 * Originally designed as a matrix of RMSD values between AFPs, so it is colorized 062 * accordingly from red (0) to black (>10). 063 * 064 * If this set to null, the background is set to black. 065 */ 066 public DotPlotPanel(AFPChain alignment ){ 067 super(); 068 069 final double defaultBackground = 100.; 070 071 // Convert the AFPChain alignment into the MatrixPanel format 072 AlternativeAlignment[] aligns = new AlternativeAlignment[alignment.getBlockNum()]; 073 int alignNumber = 0; 074 075 //One alternative alignment for each block 076 int[][][] optAln = alignment.getOptAln(); // [block #][{0,1} chain index][pos] 077 078 for(;alignNumber < optAln.length;alignNumber++) { 079 List<int[]> alignPairs = new ArrayList<int[]>(); 080 for(int pos = 0; pos<optAln[alignNumber][0].length; pos++ ) { 081 alignPairs.add( new int[] { 082 optAln[alignNumber][0][pos], 083 optAln[alignNumber][1][pos] } 084 ); 085 } 086 JointFragments frag = new JointFragments(); 087 frag.setIdxlist(alignPairs); 088 aligns[alignNumber] = new AlternativeAlignment(); 089 aligns[alignNumber].apairs_from_idxlst(frag); 090 091 } 092 093 /* TODO After the AFPSet is fixed in CeMain#filterDuplicateAFPs, maybe include this again 094 //add alignment for the AFPs 095 List<AFP> afps = alignment.getAfpSet(); 096 List<int[]> alignPairs = new ArrayList<int[]>(); 097 for(AFP afp : afps) { 098 int start1 = afp.getP1(); 099 int start2 = afp.getP2(); 100 for(int i=0;i<afp.getFragLen();i++) { 101 alignPairs.add( new int[] { start1+i, start2+i } ); 102 } 103 } 104 JointFragments frag = new JointFragments(); 105 frag.setIdxlist(alignPairs); 106 aligns[alignNumber] = new AlternativeAlignment(); 107 aligns[alignNumber].apairs_from_idxlst(frag); 108 */ 109 110 111 /* AFP boxes are unnecessary. 112 // Calculate FragmentPairs based on alignment. 113 // These are displayed as a small box around the start of each alignment. 114 FragmentPair[] pairs = new FragmentPair[afps.size()]; 115 for(int i=0;i<pairs.length;i++) { 116 AFP afp = afps.get(i); 117 pairs[i] = new FragmentPair(afp.getFragLen(), afp.getP1(), afp.getP2()); 118 pairs[i].setRms(afp.getRmsd()); 119 } 120 121 this.setFragmentPairs(pairs); 122 */ 123 124 125 // Now the alignments have been build; add it 126 this.setAlternativeAligs(aligns); 127 this.setSelectedAlignmentPos(0); //color white, not red 128 129 Matrix background = alignment.getDistanceMatrix(); 130 //Fill with default black background if none given 131 if(background == null) { 132 background = new Matrix(alignment.getCa1Length(),alignment.getCa2Length()); 133 for(int i=0;i<background.getRowDimension();i++) 134 for(int j=0;j<background.getColumnDimension(); j++) { 135 background.set(i, j, defaultBackground); 136 } 137 } 138 139 // Set parameters 140 this.setMatrix(background); 141 } 142 143 /** 144 * Helper function to create and display a JFrame with a single DotPlotPanel 145 * 146 * @param afpChain 147 * @param background 148 */ 149 private static JFrame showDotPlotJFrame(AFPChain afpChain ) { 150 151 DotPlotPanel dotplot = new DotPlotPanel(afpChain); 152 153 //Create JFrame 154 155 String title = String.format("Dot plot of %s vs. %s", afpChain.getName1(),afpChain.getName2()); 156 157 // Create window 158 JFrame frame = new JFrame(title); 159 frame.addWindowListener(new WindowAdapter(){ 160 @Override 161 public void windowClosing(WindowEvent e){ 162 JFrame f = (JFrame) e.getSource(); 163 f.setVisible(false); 164 f.dispose(); 165 } 166 }); 167 168 169 frame.getContentPane().add(dotplot); 170 171 frame.pack(); 172 frame.setVisible(true); 173 174 return frame; 175 } 176 177 public static void main(String[] args) { 178 179// String name2= "1k5j.A"; //16-68,73-119 180// String name1= "1lrh.A"; //80-127,37-79 181 182 String name1= "1iu9.A"; 183 String name2= "1h0r.A"; 184 185 // Hard case 186// String name1= "1uiz.A"; 187// String name2= "1xxa.C"; 188 189 AtomCache cache = new AtomCache(); 190 191 192 try { 193 CeMain ceA = (CeMain) StructureAlignmentFactory.getAlgorithm(CeMain.algorithmName); 194 195 CeParameters params = (CeParameters) ceA.getParameters(); 196 params.setMaxGapSize(0); 197 198 Atom[] ca1 = cache.getAtoms(name1); 199 Atom[] ca2 = cache.getAtoms(name2); 200 201 // Create initial alignment 202 AFPChain afpChain = ceA.align(ca1,ca2); 203 afpChain.setName1(name1); 204 afpChain.setName2(name2); 205 for ( AFP afpI : afpChain.getAfpSet()){ 206 System.out.println(afpI); 207 } 208 209 /* 210 // Get background distances 211 CECalculator calculator = ceA.getCECalculator(); 212 int winSize = params.getWinSize(); 213 int winSizeComb1 = (winSize-1)*(winSize-2)/2; 214 double[][] m = calculator.initSumOfDistances(ca1.length, ca2.length, params.getWinSize(), winSizeComb1, ca1, ca2); 215 //double[][] m = calculator.getMatMatrix(); 216 Matrix mat = new Matrix(m); 217 218 //Find range 219 double min = mat.get(0, 0); 220 double max = min; 221 for(int r=0;r<mat.getRowDimension();r++) { 222 for(int c=0;c<mat.getColumnDimension();c++) { 223 double y = mat.get(r,c); 224 if(y<min) 225 min = y; 226 if(y>max) 227 max = y; 228 } 229 } 230 System.out.format("[%f, %f]\n", min, max); 231 */ 232 233 //afpChain.setDistanceMatrix(mat); 234 showDotPlotJFrame(afpChain); 235 236 //StructureAlignmentJmol jmol = new StructureAlignmentJmol(afpChain, ca1, ca2); 237// jmol.setStructure(cache.getStructure(name1)); 238 239 240 ////////////////////////// 241 // Now make it circular 242 ceA = (CeMain) StructureAlignmentFactory.getAlgorithm(CeCPMain.algorithmName); 243 244 System.out.format("Aligning %s[%d] with %s[%d] with CPs\n",name1,ca1.length,name2,ca2.length); 245 afpChain = ceA.align(ca1,ca2); 246 afpChain.setName1(name1); 247 afpChain.setName2(name2+"-"+name2); 248 for ( AFP afpI : afpChain.getAfpSet()){ 249 System.out.println(afpI); 250 } 251 252 /*/ Reuse mat from the non-cp case, for simplicity 253 254 // Get background distances 255 Atom[] ca2clone = new Atom[ca2.length*2]; 256 int pos = 0; 257 for (Atom a : ca2){ 258 Group g = (Group)a.getParent().clone(); // works because each group has only a CA atom 259 260 ca2clone[pos] = g.getAtom(StructureTools.caAtomName); 261 262 pos++; 263 } 264 for (Atom a : ca2){ 265 Group g = (Group)a.getParent().clone(); 266 267 ca2clone[pos] = g.getAtom(StructureTools.caAtomName); 268 269 pos++; 270 } 271 m = calculator.initSumOfDistances(ca1.length, ca2clone.length, params.getWinSize(), winSizeComb1, ca1, ca2clone); 272 //m = calculator.getMatMatrix(); 273 mat = new Matrix(m);/*ca2.length,ca1.length); 274 for(int i=0;i<ca2.length;i++) 275 for(int j=0;j<ca1.length;j++) { 276 mat.set(i, j, m[i][j]); 277 } 278 */ 279 280 showDotPlotJFrame(afpChain); 281 282 283 } catch (StructureException e) { 284 e.printStackTrace(); 285 } catch (IOException e) { 286 e.printStackTrace(); 287 } 288 289 } 290} 291