/* * PDB web development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * * Created on Jul 28, 2009 * Created by ap3 * */ package org.biojava.nbio.structure.align.gui; import org.biojava.nbio.structure.Atom; import org.biojava.nbio.structure.StructureException; import org.biojava.nbio.structure.align.StructureAlignmentFactory; import org.biojava.nbio.structure.align.ce.CeCPMain; import org.biojava.nbio.structure.align.ce.CeMain; import org.biojava.nbio.structure.align.ce.CeParameters; import org.biojava.nbio.structure.align.helper.JointFragments; import org.biojava.nbio.structure.align.model.AFP; import org.biojava.nbio.structure.align.model.AFPChain; import org.biojava.nbio.structure.align.pairwise.AlternativeAlignment; import org.biojava.nbio.structure.align.util.AtomCache; import org.biojava.nbio.structure.gui.ScaleableMatrixPanel; import org.biojava.nbio.structure.jama.Matrix; import javax.swing.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Displays the dot plot trace for an alignment. * * This class adapts ScaleableMatrixPanel, which uses code from org.biojava.nbio.structure.align.pairwise, * with more BioJava-friendly methods based off AFPChains. * * @author Spencer Bliven * */ public class DotPlotPanel extends ScaleableMatrixPanel { private static final long serialVersionUID = -7641953255857483895L; /** * * @param alignment The alignment to plot * @param background [Optional]A matrix of 'background colors' over which to draw the alignment. * * Originally designed as a matrix of RMSD values between AFPs, so it is colorized * accordingly from red (0) to black (>10). * * If this set to null, the background is set to black. */ public DotPlotPanel(AFPChain alignment ){ super(); final double defaultBackground = 100.; // Convert the AFPChain alignment into the MatrixPanel format AlternativeAlignment[] aligns = new AlternativeAlignment[alignment.getBlockNum()]; int alignNumber = 0; //One alternative alignment for each block int[][][] optAln = alignment.getOptAln(); // [block #][{0,1} chain index][pos] for(;alignNumber < optAln.length;alignNumber++) { List<int[]> alignPairs = new ArrayList<int[]>(); for(int pos = 0; pos<optAln[alignNumber][0].length; pos++ ) { alignPairs.add( new int[] { optAln[alignNumber][0][pos], optAln[alignNumber][1][pos] } ); } JointFragments frag = new JointFragments(); frag.setIdxlist(alignPairs); aligns[alignNumber] = new AlternativeAlignment(); aligns[alignNumber].apairs_from_idxlst(frag); } /* TODO After the AFPSet is fixed in CeMain#filterDuplicateAFPs, maybe include this again //add alignment for the AFPs List<AFP> afps = alignment.getAfpSet(); List<int[]> alignPairs = new ArrayList<int[]>(); for(AFP afp : afps) { int start1 = afp.getP1(); int start2 = afp.getP2(); for(int i=0;i<afp.getFragLen();i++) { alignPairs.add( new int[] { start1+i, start2+i } ); } } JointFragments frag = new JointFragments(); frag.setIdxlist(alignPairs); aligns[alignNumber] = new AlternativeAlignment(); aligns[alignNumber].apairs_from_idxlst(frag); */ /* AFP boxes are unnecessary. // Calculate FragmentPairs based on alignment. // These are displayed as a small box around the start of each alignment. FragmentPair[] pairs = new FragmentPair[afps.size()]; for(int i=0;i<pairs.length;i++) { AFP afp = afps.get(i); pairs[i] = new FragmentPair(afp.getFragLen(), afp.getP1(), afp.getP2()); pairs[i].setRms(afp.getRmsd()); } this.setFragmentPairs(pairs); */ // Now the alignments have been build; add it this.setAlternativeAligs(aligns); this.setSelectedAlignmentPos(0); //color white, not red Matrix background = alignment.getDistanceMatrix(); //Fill with default black background if none given if(background == null) { background = new Matrix(alignment.getCa1Length(),alignment.getCa2Length()); for(int i=0;i<background.getRowDimension();i++) for(int j=0;j<background.getColumnDimension(); j++) { background.set(i, j, defaultBackground); } } // Set parameters this.setMatrix(background); } /** * Helper function to create and display a JFrame with a single DotPlotPanel * * @param afpChain * @param background */ private static JFrame showDotPlotJFrame(AFPChain afpChain ) { DotPlotPanel dotplot = new DotPlotPanel(afpChain); //Create JFrame String title = String.format("Dot plot of %s vs. %s", afpChain.getName1(),afpChain.getName2()); // Create window JFrame frame = new JFrame(title); frame.addWindowListener(new WindowAdapter(){ @Override public void windowClosing(WindowEvent e){ JFrame f = (JFrame) e.getSource(); f.setVisible(false); f.dispose(); } }); frame.getContentPane().add(dotplot); frame.pack(); frame.setVisible(true); return frame; } public static void main(String[] args) { // String name2= "1k5j.A"; //16-68,73-119 // String name1= "1lrh.A"; //80-127,37-79 String name1= "1iu9.A"; String name2= "1h0r.A"; // Hard case // String name1= "1uiz.A"; // String name2= "1xxa.C"; AtomCache cache = new AtomCache(); try { CeMain ceA = (CeMain) StructureAlignmentFactory.getAlgorithm(CeMain.algorithmName); CeParameters params = (CeParameters) ceA.getParameters(); params.setMaxGapSize(0); Atom[] ca1 = cache.getAtoms(name1); Atom[] ca2 = cache.getAtoms(name2); // Create initial alignment AFPChain afpChain = ceA.align(ca1,ca2); afpChain.setName1(name1); afpChain.setName2(name2); for ( AFP afpI : afpChain.getAfpSet()){ System.out.println(afpI); } /* // Get background distances CECalculator calculator = ceA.getCECalculator(); int winSize = params.getWinSize(); int winSizeComb1 = (winSize-1)*(winSize-2)/2; double[][] m = calculator.initSumOfDistances(ca1.length, ca2.length, params.getWinSize(), winSizeComb1, ca1, ca2); //double[][] m = calculator.getMatMatrix(); Matrix mat = new Matrix(m); //Find range double min = mat.get(0, 0); double max = min; for(int r=0;r<mat.getRowDimension();r++) { for(int c=0;c<mat.getColumnDimension();c++) { double y = mat.get(r,c); if(y<min) min = y; if(y>max) max = y; } } System.out.format("[%f, %f]\n", min, max); */ //afpChain.setDistanceMatrix(mat); showDotPlotJFrame(afpChain); //StructureAlignmentJmol jmol = new StructureAlignmentJmol(afpChain, ca1, ca2); // jmol.setStructure(cache.getStructure(name1)); ////////////////////////// // Now make it circular ceA = (CeMain) StructureAlignmentFactory.getAlgorithm(CeCPMain.algorithmName); System.out.format("Aligning %s[%d] with %s[%d] with CPs\n",name1,ca1.length,name2,ca2.length); afpChain = ceA.align(ca1,ca2); afpChain.setName1(name1); afpChain.setName2(name2+"-"+name2); for ( AFP afpI : afpChain.getAfpSet()){ System.out.println(afpI); } /*/ Reuse mat from the non-cp case, for simplicity // Get background distances Atom[] ca2clone = new Atom[ca2.length*2]; int pos = 0; for (Atom a : ca2){ Group g = (Group)a.getParent().clone(); // works because each group has only a CA atom ca2clone[pos] = g.getAtom(StructureTools.caAtomName); pos++; } for (Atom a : ca2){ Group g = (Group)a.getParent().clone(); ca2clone[pos] = g.getAtom(StructureTools.caAtomName); pos++; } m = calculator.initSumOfDistances(ca1.length, ca2clone.length, params.getWinSize(), winSizeComb1, ca1, ca2clone); //m = calculator.getMatMatrix(); mat = new Matrix(m);/*ca2.length,ca1.length); for(int i=0;i<ca2.length;i++) for(int j=0;j<ca1.length;j++) { mat.set(i, j, m[i][j]); } */ showDotPlotJFrame(afpChain); } catch (StructureException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }