001/*
002 *                    BioJava 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 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.nbio.structure.align.gui.aligpanel;
022
023import java.awt.*;
024
025/**
026 * Generalization of the Coodinate Manager to include an arbitrary number of
027 * sequences (lines) for MultipleAlignment visualization.
028 *
029 * @author Aleix Lafita
030 *
031 */
032public class MultipleAlignmentCoordManager {
033
034        private int alignmentLength;            //number of aligned residues
035        private int alignmentSize;                      //number of strucures aligned
036
037        /**
038         * Constructor.
039         * @param size number of structures/sequences aligned (rows).
040         * @param length number of aligned residues (columns)
041         */
042        public MultipleAlignmentCoordManager(int size, int length){
043                alignmentLength = length;
044                alignmentSize = size;
045                DEFAULT_Y_STEP = 30*size;
046        }
047
048        /**
049         * Space on the right side between sequence and legend.
050         */
051        public static final int DEFAULT_RIGHT_SPACER = 10;
052
053        /**
054         * Number of chars per line
055         */
056        public static final int DEFAULT_LINE_LENGTH = 70;
057
058        /**
059         * Size of space between rows.
060         * Depends on the number of structures aligned.
061         */
062        public final int DEFAULT_Y_STEP;
063
064        /**
065         * Size per character
066         */
067        public static final int DEFAULT_CHAR_SIZE = 12;
068
069        /**
070         * Separation between sequences in the alignment
071         */
072        public static final int DEFAULT_LINE_SEPARATION = 20;
073
074        /**
075         * Left boundary
076         */
077        public static final int DEFAULT_X_SPACE = 20;
078
079        /**
080         * Top boundary
081         */
082        public static final int DEFAULT_Y_SPACE = 40;
083
084        /**
085         * Position at which the alignment summary is printed
086         */
087        public static final int SUMMARY_POS = 20;
088
089        private static final int DEFAULT_LEGEND_SIZE = 50;
090
091        public int getSummaryPos(){
092                return SUMMARY_POS;
093        }
094
095        /**
096         * X coordinate size
097         *
098         * @return the preferred width
099         */
100        public int getPreferredWidth(){
101                return alignmentSize* DEFAULT_X_SPACE + DEFAULT_LINE_LENGTH *
102                                DEFAULT_CHAR_SIZE + DEFAULT_LEGEND_SIZE +
103                                DEFAULT_RIGHT_SPACER + DEFAULT_LEGEND_SIZE;
104        }
105
106        /**
107         * Y coordinate size
108         *
109         * @return the preferred height
110         */
111        public int getPreferredHeight(){
112                return alignmentSize* DEFAULT_Y_SPACE +
113                                (alignmentLength / DEFAULT_LINE_LENGTH) *
114                                DEFAULT_Y_STEP + DEFAULT_LINE_SEPARATION;
115        }
116
117        /**
118         * Convert from an X position in the JPanel to the position
119         * in the sequence alignment.
120         *
121         * @param aligSeq sequence number
122         * @param p point on panel
123         * @return the sequence position for a point on the Panel
124         */
125        public int getSeqPos(int aligSeq, Point p) {
126
127                int x = p.x - DEFAULT_X_SPACE - DEFAULT_LEGEND_SIZE;
128                int y = p.y - DEFAULT_Y_SPACE ;
129
130                y -=  (DEFAULT_LINE_SEPARATION * aligSeq) - DEFAULT_CHAR_SIZE;
131
132                int lineNr = y / DEFAULT_Y_STEP;
133                int linePos = x / DEFAULT_CHAR_SIZE;
134                return lineNr * DEFAULT_LINE_LENGTH + linePos ;
135
136        }
137
138        /**
139         * Get the X position on the Panel of a particular sequence position.
140         *
141         * @param structure index of the structure for the sequence position.
142         * @param pos sequence position, the aligned position index
143         * @return the point on a panel for a sequence position
144         */
145        public Point getPanelPos(int structure, int pos) {
146                Point p = new Point();
147
148                int lineNr = pos / DEFAULT_LINE_LENGTH;
149                int linePos = pos % DEFAULT_LINE_LENGTH;
150
151                int x = linePos * DEFAULT_CHAR_SIZE + DEFAULT_X_SPACE +
152                                DEFAULT_LEGEND_SIZE;
153                int y = lineNr * DEFAULT_Y_STEP + DEFAULT_Y_SPACE;
154
155                y += DEFAULT_LINE_SEPARATION * structure;
156
157                p.setLocation(x, y);
158                return p;
159        }
160
161        /**
162         * Returns the index of the structure, for a given point in the Panel.
163         * Returns -1 if not over a position in the sequence alignment.
164         * @param point x and y coordinates in the panel
165         * @return which structure a point on the panel corresponds to
166         */
167        public int getAligSeq(Point point) {
168
169                for (int pos=0; pos<alignmentSize; pos++){
170                        int i = getSeqPos(pos, point);
171                        Point t = getPanelPos(pos,i);
172
173                        if ( Math.abs(t.x - point.x) <= DEFAULT_CHAR_SIZE &&
174                                        Math.abs(t.y-point.y) < DEFAULT_CHAR_SIZE ) return pos;
175                }
176                return -1;
177        }
178
179        /**
180         * Provide the coordinates for where to draw the legend for
181         * line X given the structure index.
182         *
183         * @param lineNr line of the Panel
184         * @param structure the structure index
185         * @return get the point where to draw the legend
186         */
187        public Point getLegendPosition(int lineNr, int structure) {
188
189                int x = DEFAULT_X_SPACE ;
190                int y = lineNr * DEFAULT_Y_STEP + DEFAULT_Y_SPACE;
191                y += structure * DEFAULT_LINE_SEPARATION;
192
193                Point p = new Point(x,y);
194                return p;
195        }
196
197        public Point getEndLegendPosition(int lineNr, int structure) {
198
199                int x = DEFAULT_LINE_LENGTH * DEFAULT_CHAR_SIZE + DEFAULT_X_SPACE + DEFAULT_LEGEND_SIZE + DEFAULT_RIGHT_SPACER;
200                int y = lineNr * DEFAULT_Y_STEP + DEFAULT_Y_SPACE;
201                y += structure * DEFAULT_LINE_SEPARATION;
202
203                Point p = new Point(x,y);
204                return p;
205        }
206
207}