package fr.orsay.lri.varna.models.rna; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.GeneralPath; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.Random; import java.util.Stack; import java.util.Vector; import fr.orsay.lri.varna.VARNAPanel; public class VARNASecDraw { public static VARNAPanel _vp = null; public abstract class Portion { public abstract ArrayList getBaseList(); public abstract int getNumBases(); public abstract GeneralPath getOutline(RNA r); }; public class UnpairedPortion extends Portion { int _pos; int _len; public UnpairedPortion(int pos, int len) { _len = len; _pos = pos; } @Override public ArrayList getBaseList() { // TODO Auto-generated method stub return null; } public String toString() { return "U["+_pos+","+(_pos+_len-1)+"]"; } public int getNumBases() { return _len; } public GeneralPath getOutline(RNA r) { GeneralPath gp = new GeneralPath(); ArrayList l = r.get_listeBases(); Point2D.Double p0 = l.get(_pos).getCoords(); gp.moveTo((float)p0.x, (float)p0.y); for (int i=1;i<_len;i++) { Point2D.Double p = l.get(_pos+i).getCoords(); gp.lineTo((float)p.x, (float)p.y); } return gp; } }; public class PairedPortion extends Portion { int _pos1; int _pos2; int _len; RNATree _r; public PairedPortion(int pos1,int pos2, int len, RNATree r) { _pos1 = pos1; _pos2 = pos2; _len = len; _r =r; } @Override public ArrayList getBaseList() { // TODO Auto-generated method stub return null; } public String toString() { return "H["+_pos1+","+(_pos1+_len-1)+"]["+(_pos2-_len+1)+","+(_pos2)+"]\n"+_r.toString(); } @Override public int getNumBases() { return 2*_len; } public GeneralPath getLocalOutline(RNA r) { GeneralPath gp = new GeneralPath(); if (_len>0) { ArrayList l = r.get_listeBases(); Point2D.Double p1 = l.get(_pos1).getCoords(); Point2D.Double p2 = l.get(_pos1+_len-1).getCoords(); Point2D.Double p3 = l.get(_pos2-_len+1).getCoords(); Point2D.Double p4 = l.get(_pos2).getCoords(); gp.moveTo((float)p1.x, (float)p1.y); gp.lineTo((float)p2.x, (float)p2.y); gp.lineTo((float)p3.x, (float)p3.y); gp.lineTo((float)p4.x, (float)p4.y); } return gp; } public GeneralPath getOutline(RNA r) { return getOutline(r,false); } public GeneralPath getOutline(RNA r, boolean local) { ArrayList l = r.get_listeBases(); Point2D.Double p1 = l.get(_pos1).getCoords(); Point2D.Double p2 = l.get(_pos1+_len-1).getCoords(); Point2D.Double p3 = l.get(_pos2-_len+1).getCoords(); Point2D.Double p4 = l.get(_pos2).getCoords(); GeneralPath gp = new GeneralPath(); gp.moveTo((float)p1.x, (float)p1.y); gp.lineTo((float)p2.x, (float)p2.y); if (!local) gp.append(_r.getOutline(r), true); gp.lineTo((float)p3.x, (float)p3.y); gp.lineTo((float)p4.x, (float)p4.y); return gp; } }; public int _depth = 0; public class RNATree { ArrayList _portions = new ArrayList(); int _numPairedPortions=0; public RNATree() { } public void addPortion(Portion p) { _portions.add(p); if (p instanceof PairedPortion) { _numPairedPortions++; } } public int getNumPortions() { return _portions.size(); } public Portion getPortion(int i) { return _portions.get(i); } public String toString() { String result = ""; _depth++; for (int i=0;i<_portions.size();i++ ) { result += String.format("%1$#" + _depth + "s", ' '); result += _portions.get(i).toString(); if (i<_portions.size()-1) result += "\n"; } _depth--; return result; } public GeneralPath getOutline(RNA r) { GeneralPath result = new GeneralPath(); for (int i=0;i<_portions.size();i++) { result.append(_portions.get(i).getOutline(r),true); } return result; } }; private void buildTree(int i, int j, RNATree parent, RNA r) { //LinkedList s = new LinkedList(); //s.add(new BuildTreeArgs(xi, xj, xparent,xr)); //while(s.size()!=0) //{ //BuildTreeArgs a = s.removeLast(); if (i >= j) { parent.addPortion(new UnpairedPortion(i,j-i+1)); } // BasePaired if (r.get_listeBases().get(i).getElementStructure() == j) { int i1 = i; int j1 = j; boolean over = false; while( (i+1=0)&& (i+1<=j-1) && !over) { if (r.get_listeBases().get(i).getElementStructure() != j) { over = true; } else { i++;j--; } } int i2 = i; int j2 = j; RNATree t = new RNATree(); if (i0) { parent.addPortion(new UnpairedPortion(start,len)); } buildTree(k, l, parent, r); k = l + 1; start = k; len = 0; } else { len++; k++; } } if (len>0) { parent.addPortion(new UnpairedPortion(start,len)); } } } /* public void drawTree(double x0, double y0, RNATree t, double dir, RNA r, double straightness) { boolean collision = true; double x=x0; double y=y0; double multRadius = 1.0; double initCirc = r.BASE_PAIR_DISTANCE+r.LOOP_DISTANCE; for (int i=0;i shapes = new ArrayList(); for (int i=0;i0) { collision = false; for (int i=0;(i=0) && !stop) { if (p[i]==prev-1) { prev = p[i]; i--; } else { stop = true; } } if (i<0) throw new Exception("No more placement available"); p[i]++; i++; while(i shapes = new ArrayList(); int curH = 0; for (int i=0;i0) { collision = false; for (int i=0;(i _children = new ArrayList(); ArrayList _indices = new ArrayList(); PairedPortion _p; RNA _r; HelixEmbedding _parent; public HelixEmbedding(Point2D.Double support, PairedPortion p, RNA r, HelixEmbedding parent) { _support = support; _clip = p.getLocalOutline(r); _p = p; _r = r; _parent = parent; } public void addHelixEmbedding(HelixEmbedding h, int index) { _children.add(h); _indices.add(index); } public GeneralPath getShape() { return _clip; } public int chooseNextMove() { int i = _parent._children.indexOf(this); int min; int max; if (_parent._children.size() mbl = _r.get_listeBases(); if (_p._len>0) { PathIterator pi = _clip.getPathIterator(AffineTransform.getRotateInstance(0.0)); ArrayList p = new ArrayList(); while(!pi.isDone()) { double[] args = new double[6]; int type= pi.currentSegment(args); if ((type == PathIterator.SEG_MOVETO) || (type == PathIterator.SEG_LINETO)) { Point2D.Double np = new Point2D.Double(args[0],args[1]); p.add(np); System.out.println(Arrays.toString(args)); } pi.next(); } if (p.size()<4) { return; } Point2D.Double startLeft = p.get(0); Point2D.Double endLeft = p.get(1); Point2D.Double endRight = p.get(2); Point2D.Double startRight = p.get(3); double d = startLeft.distance(endLeft); double vx = endLeft.x-startLeft.x; double vy = endLeft.y-startLeft.y; double interval = 0.0; if (_p._len>1) { vx/=d; vy/=d; interval = d/((double)_p._len-1); System.out.println("DELTA: "+interval+" "+_r.LOOP_DISTANCE); } for (int n=0;n<_p._len;n++) { int i = _p._pos1 + n; int j = _p._pos2 - n; ModeleBase mbLeft = mbl.get(i); mbLeft.setCoords(new Point2D.Double(startLeft.x+n*vx*interval, startLeft.y+n*vy*interval)); ModeleBase mbRight = mbl.get(j); mbRight.setCoords(new Point2D.Double(startRight.x+n*vx*interval, startRight.y+n*vy*interval)); } } for (int i=0;i<_children.size();i++) { _children.get(i).reflectCoordinates(); } if (_children.size()>0) { Point2D.Double center = _children.get(0)._support; for (int i=0;i<_p._r.getNumPortions();i++) { Portion p = _p._r.getPortion(i); if (p instanceof UnpairedPortion) { UnpairedPortion up = (UnpairedPortion) p; for (int j=0;j mbl, RNA r) { if ((_children.size()==0)&&(_p._r.getNumPortions()==1)) { Portion p = _p._r.getPortion(0); if (p instanceof UnpairedPortion) { UnpairedPortion up = (UnpairedPortion) p; double rad = determineRadius(1,up.getNumBases(),_r); int a = _p._pos1+_p._len-1; int b = _p._pos2-(_p._len-1); ModeleBase mbLeft = mbl.get(a); ModeleBase mbRight = mbl.get(b); Point2D.Double pl = mbLeft.getCoords(); Point2D.Double pr = mbRight.getCoords(); Point2D.Double pm = new Point2D.Double((pl.x+pr.x)/2.0,(pl.y+pr.y)/2.0); double vx = (pl.x-pr.x)/pl.distance(pr); double vy = (pl.y-pr.y)/pl.distance(pr); double vnx = -vy, vny = vx; Point2D.Double pc = new Point2D.Double(pm.x+rad*vnx,pm.y+rad*vny); double circ = r.LOOP_DISTANCE*(1.0+up.getNumBases())+r.BASE_PAIR_DISTANCE; double incrLoop = Math.PI*2.0*r.LOOP_DISTANCE/circ; double angle = Math.PI*2.0*r.BASE_PAIR_DISTANCE/(2.0*circ); for (int j=0;j all) throws Exception { double x=x0; double y=y0; int numHelices = 0; int numUBases = 0; double totCirc = r.BASE_PAIR_DISTANCE+r.LOOP_DISTANCE; for (int i=0;i all = new ArrayList(); HelixEmbedding root = null; try { root = new HelixEmbedding(new Point2D.Double(0.0,0.0),new PairedPortion(0,0,0,t),r,null); predrawTree(0,0,t,0.0,r,root,all); int steps=1000; double prevbadness = Double.MAX_VALUE; while((steps>0)&&(prevbadness>0)) { // Generating new structure HelixEmbedding chosen = all.get(_rnd.nextInt(all.size())); int delta = chosen.chooseNextMove(); // Draw current if (_vp!=null) { GeneralPath p = new GeneralPath(); for (int i=0;i0) { chosen.cancelMove(delta); } else { prevbadness = badness; } System.out.println(badness); steps--; } if (root!=null) { root.reflectCoordinates(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return t; }; }