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