added help and documentation for annotation editing.
[jalview.git] / src / jalview / analysis / AlignSeq.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 package jalview.analysis;\r
20 \r
21 import jalview.datamodel.SequenceI;\r
22 \r
23 import jalview.schemes.*;\r
24 \r
25 import jalview.util.*;\r
26 \r
27 import java.awt.*;\r
28 \r
29 import java.util.*;\r
30 \r
31 \r
32 /**\r
33  *\r
34  *\r
35  * @author $author$\r
36  * @version $Revision$\r
37  */\r
38 public class AlignSeq\r
39 {\r
40     /** DOCUMENT ME!! */\r
41     public static java.util.Hashtable dnaHash = new java.util.Hashtable();\r
42 \r
43     static\r
44     {\r
45         dnaHash.put("C", new Integer(0));\r
46         dnaHash.put("T", new Integer(1));\r
47         dnaHash.put("A", new Integer(2));\r
48         dnaHash.put("G", new Integer(3));\r
49         dnaHash.put("-", new Integer(4));\r
50     }\r
51 \r
52     static String[] dna = { "C", "T", "A", "G", "-" };\r
53     static String[] pep =\r
54     {\r
55         "A", "R", "N", "D", "C", "Q", "E", "G", "H", "I", "L", "K", "M", "F",\r
56         "P", "S", "T", "W", "Y", "V", "B", "Z", "X", "-"\r
57     };\r
58     int[][] score;\r
59     int[][] E;\r
60     int[][] F;\r
61     int[][] traceback;\r
62     int[] seq1;\r
63     int[] seq2;\r
64     SequenceI s1;\r
65     SequenceI s2;\r
66     String s1str;\r
67     String s2str;\r
68     int maxi;\r
69     int maxj;\r
70     int[] aseq1;\r
71     int[] aseq2;\r
72     String astr1 = "";\r
73     String astr2 = "";\r
74 \r
75     /** DOCUMENT ME!! */\r
76     public int seq1start;\r
77 \r
78     /** DOCUMENT ME!! */\r
79     public int seq1end;\r
80 \r
81     /** DOCUMENT ME!! */\r
82     public int seq2start;\r
83 \r
84     /** DOCUMENT ME!! */\r
85     public int seq2end;\r
86     int count;\r
87 \r
88     /** DOCUMENT ME!! */\r
89     public int maxscore;\r
90     float pid;\r
91     int prev = 0;\r
92     int gapOpen = 120;\r
93     int gapExtend = 20;\r
94     int[][] lookup = ResidueProperties.getBLOSUM62();\r
95     String[] intToStr = pep;\r
96     int defInt = 23;\r
97     String output = "";\r
98     String type;\r
99     Runtime rt;\r
100 \r
101 \r
102     /**\r
103      * Creates a new AlignSeq object.\r
104      *\r
105      * @param s1 DOCUMENT ME!\r
106      * @param s2 DOCUMENT ME!\r
107      * @param type DOCUMENT ME!\r
108      */\r
109     public AlignSeq(SequenceI s1, SequenceI s2, String type)\r
110     {\r
111         rt = Runtime.getRuntime();\r
112         SeqInit(s1, s2, type);\r
113     }\r
114 \r
115     /**\r
116      * DOCUMENT ME!\r
117      *\r
118      * @return DOCUMENT ME!\r
119      */\r
120     public int getMaxScore()\r
121     {\r
122         return maxscore;\r
123     }\r
124 \r
125     /**\r
126      * DOCUMENT ME!\r
127      *\r
128      * @return DOCUMENT ME!\r
129      */\r
130     public int getSeq2Start()\r
131     {\r
132         return seq2start;\r
133     }\r
134 \r
135     /**\r
136      * DOCUMENT ME!\r
137      *\r
138      * @return DOCUMENT ME!\r
139      */\r
140     public int getSeq2End()\r
141     {\r
142         return seq2end;\r
143     }\r
144 \r
145     /**\r
146      * DOCUMENT ME!\r
147      *\r
148      * @return DOCUMENT ME!\r
149      */\r
150     public int getSeq1Start()\r
151     {\r
152         return seq1start;\r
153     }\r
154 \r
155     /**\r
156      * DOCUMENT ME!\r
157      *\r
158      * @return DOCUMENT ME!\r
159      */\r
160     public int getSeq1End()\r
161     {\r
162         return seq1end;\r
163     }\r
164 \r
165     /**\r
166      * DOCUMENT ME!\r
167      *\r
168      * @return DOCUMENT ME!\r
169      */\r
170     public String getOutput()\r
171     {\r
172         return output;\r
173     }\r
174 \r
175     /**\r
176      * DOCUMENT ME!\r
177      *\r
178      * @return DOCUMENT ME!\r
179      */\r
180     public String getAStr1()\r
181     {\r
182         return astr1;\r
183     }\r
184 \r
185     /**\r
186      * DOCUMENT ME!\r
187      *\r
188      * @return DOCUMENT ME!\r
189      */\r
190     public String getAStr2()\r
191     {\r
192         return astr2;\r
193     }\r
194 \r
195     /**\r
196      * DOCUMENT ME!\r
197      *\r
198      * @return DOCUMENT ME!\r
199      */\r
200     public int[] getASeq1()\r
201     {\r
202         return aseq1;\r
203     }\r
204 \r
205     /**\r
206      * DOCUMENT ME!\r
207      *\r
208      * @return DOCUMENT ME!\r
209      */\r
210     public int[] getASeq2()\r
211     {\r
212         return aseq2;\r
213     }\r
214 \r
215     /**\r
216      * DOCUMENT ME!\r
217      *\r
218      * @return DOCUMENT ME!\r
219      */\r
220     public SequenceI getS1()\r
221     {\r
222         return s1;\r
223     }\r
224 \r
225     /**\r
226      * DOCUMENT ME!\r
227      *\r
228      * @return DOCUMENT ME!\r
229      */\r
230     public SequenceI getS2()\r
231     {\r
232         return s2;\r
233     }\r
234 \r
235     /**\r
236      * DOCUMENT ME!\r
237      *\r
238      * @param s1 DOCUMENT ME!\r
239      * @param s2 DOCUMENT ME!\r
240      * @param type DOCUMENT ME!\r
241      */\r
242     public void SeqInit(SequenceI s1, SequenceI s2, String type)\r
243     {\r
244         s1str = extractGaps(jalview.util.Comparison.GapChars, s1.getSequence());\r
245         s2str = extractGaps(jalview.util.Comparison.GapChars, s2.getSequence());\r
246 \r
247         this.s1 = s1;\r
248         this.s2 = s2;\r
249 \r
250         this.type = type;\r
251 \r
252         if (type.equals("pep"))\r
253         {\r
254             lookup = ResidueProperties.getBLOSUM62();\r
255             intToStr = pep;\r
256             defInt = 23;\r
257         }\r
258         else if (type.equals("dna"))\r
259         {\r
260             lookup = ResidueProperties.getDNA();\r
261             intToStr = dna;\r
262             defInt = 4;\r
263         }\r
264         else\r
265         {\r
266             output = output + ("Wrong type = dna or pep only");\r
267             System.exit(0);\r
268         }\r
269 \r
270         //System.out.println("lookuip " + rt.freeMemory() + " "+  rt.totalMemory());\r
271         seq1 = new int[s1str.length()];\r
272 \r
273         //System.out.println("seq1 " + rt.freeMemory() +" "  + rt.totalMemory());\r
274         seq2 = new int[s2str.length()];\r
275 \r
276         //System.out.println("seq2 " + rt.freeMemory() + " " + rt.totalMemory());\r
277         score = new int[s1str.length()][s2str.length()];\r
278 \r
279         //System.out.println("score " + rt.freeMemory() + " " + rt.totalMemory());\r
280         E = new int[s1str.length()][s2str.length()];\r
281 \r
282         //System.out.println("E " + rt.freeMemory() + " " + rt.totalMemory());\r
283         F = new int[s1str.length()][s2str.length()];\r
284         traceback = new int[s1str.length()][s2str.length()];\r
285 \r
286         //System.out.println("F " + rt.freeMemory() + " " + rt.totalMemory());\r
287         seq1 = stringToInt(s1str, type);\r
288 \r
289         //System.out.println("seq1 " + rt.freeMemory() + " " + rt.totalMemory());\r
290         seq2 = stringToInt(s2str, type);\r
291 \r
292         //System.out.println("Seq2 " + rt.freeMemory() + " " + rt.totalMemory());\r
293         //   long tstart = System.currentTimeMillis();\r
294         //    calcScoreMatrix();\r
295         //long tend = System.currentTimeMillis();\r
296         //System.out.println("Time take to calculate score matrix = " + (tend-tstart) + " ms");\r
297         //   printScoreMatrix(score);\r
298         //System.out.println();\r
299         //printScoreMatrix(traceback);\r
300         //System.out.println();\r
301         //  printScoreMatrix(E);\r
302         //System.out.println();\r
303         ///printScoreMatrix(F);\r
304         //System.out.println();\r
305         // tstart = System.currentTimeMillis();\r
306         //traceAlignment();\r
307         //tend = System.currentTimeMillis();\r
308         //System.out.println("Time take to traceback alignment = " + (tend-tstart) + " ms");\r
309     }\r
310 \r
311     /**\r
312      * DOCUMENT ME!\r
313      */\r
314     public void traceAlignment()\r
315     {\r
316         // Find the maximum score along the rhs or bottom row\r
317         int max = -9999;\r
318 \r
319         for (int i = 0; i < seq1.length; i++)\r
320         {\r
321             if (score[i][seq2.length - 1] > max)\r
322             {\r
323                 max = score[i][seq2.length - 1];\r
324                 maxi = i;\r
325                 maxj = seq2.length - 1;\r
326             }\r
327         }\r
328 \r
329         for (int j = 0; j < seq2.length; j++)\r
330         {\r
331             if (score[seq1.length - 1][j] > max)\r
332             {\r
333                 max = score[seq1.length - 1][j];\r
334                 maxi = seq1.length - 1;\r
335                 maxj = j;\r
336             }\r
337         }\r
338 \r
339         //  System.out.println(maxi + " " + maxj + " " + score[maxi][maxj]);\r
340         int i = maxi;\r
341         int j = maxj;\r
342         int trace;\r
343         maxscore = score[i][j] / 10;\r
344 \r
345         seq1end = maxi + 1;\r
346         seq2end = maxj + 1;\r
347 \r
348         aseq1 = new int[seq1.length + seq2.length];\r
349         aseq2 = new int[seq1.length + seq2.length];\r
350 \r
351         count = (seq1.length + seq2.length) - 1;\r
352 \r
353         while ((i > 0) && (j > 0))\r
354         {\r
355             if ((aseq1[count] != defInt) && (i >= 0))\r
356             {\r
357                 aseq1[count] = seq1[i];\r
358                 astr1 = intToStr[seq1[i]] + astr1;\r
359             }\r
360 \r
361             if ((aseq2[count] != defInt) && (j > 0))\r
362             {\r
363                 aseq2[count] = seq2[j];\r
364                 astr2 = intToStr[seq2[j]] + astr2;\r
365             }\r
366 \r
367             trace = findTrace(i, j);\r
368 \r
369             if (trace == 0)\r
370             {\r
371                 i--;\r
372                 j--;\r
373             }\r
374             else if (trace == 1)\r
375             {\r
376                 j--;\r
377                 aseq1[count] = defInt;\r
378                 astr1 = "-" + astr1.substring(1);\r
379             }\r
380             else if (trace == -1)\r
381             {\r
382                 i--;\r
383                 aseq2[count] = defInt;\r
384                 astr2 = "-" + astr2.substring(1);\r
385             }\r
386 \r
387             count--;\r
388         }\r
389 \r
390         seq1start = i + 1;\r
391         seq2start = j + 1;\r
392 \r
393         if (aseq1[count] != defInt)\r
394         {\r
395             aseq1[count] = seq1[i];\r
396             astr1 = intToStr[seq1[i]] + astr1;\r
397         }\r
398 \r
399         if (aseq2[count] != defInt)\r
400         {\r
401             aseq2[count] = seq2[j];\r
402             astr2 = intToStr[seq2[j]] + astr2;\r
403         }\r
404     }\r
405 \r
406     /**\r
407      * DOCUMENT ME!\r
408      */\r
409     public void printAlignment()\r
410     {\r
411         // Find the biggest id length for formatting purposes\r
412         int maxid = s1.getName().length();\r
413 \r
414         if (s2.getName().length() > maxid)\r
415         {\r
416             maxid = s2.getName().length();\r
417         }\r
418 \r
419         int len = 72 - maxid - 1;\r
420         int nochunks = ((aseq1.length - count) / len) + 1;\r
421         pid = 0;\r
422 \r
423         output = output + ("Score = " + score[maxi][maxj] + "\n");\r
424         output = output +\r
425             ("Length of alignment = " + (aseq1.length - count) + "\n");\r
426         output = output + ("Sequence ");\r
427         output = output + (new Format("%" + maxid + "s").form(s1.getName()));\r
428         output = output +\r
429             (" :  " + seq1start + " - " + seq1end + " (Sequence length = " +\r
430             s1str.length() + ")\n");\r
431         output = output + ("Sequence ");\r
432         output = output + (new Format("%" + maxid + "s").form(s2.getName()));\r
433         output = output +\r
434             (" :  " + seq2start + " - " + seq2end + " (Sequence length = " +\r
435             s2str.length() + ")\n\n");\r
436 \r
437         for (int j = 0; j < nochunks; j++)\r
438         {\r
439             // Print the first aligned sequence\r
440             output = output +\r
441                 (new Format("%" + (maxid) + "s").form(s1.getName()) + " ");\r
442 \r
443             for (int i = 0; i < len; i++)\r
444             {\r
445                 if ((count + i + (j * len)) < aseq1.length)\r
446                 {\r
447                     output = output +\r
448                         (new Format("%s").form(intToStr[aseq1[count + i +\r
449                             (j * len)]]));\r
450                 }\r
451             }\r
452 \r
453             output = output + ("\n");\r
454             output = output +\r
455                 (new Format("%" + (maxid) + "s").form(" ") + " ");\r
456 \r
457             // Print out the matching chars\r
458             for (int i = 0; i < len; i++)\r
459             {\r
460                 if ((count + i + (j * len)) < aseq1.length)\r
461                 {\r
462                     if (intToStr[aseq1[count + i + (j * len)]].equals(\r
463                                 intToStr[aseq2[count + i + (j * len)]]) &&\r
464                             !intToStr[aseq1[count + i + (j * len)]].equals("-"))\r
465                     {\r
466                         pid++;\r
467                         output = output + ("|");\r
468                     }\r
469                     else if (type.equals("pep"))\r
470                     {\r
471                         if (ResidueProperties.getPAM250(\r
472                                     intToStr[aseq1[count + i + (j * len)]],\r
473                                     intToStr[aseq2[count + i + (j * len)]]) > 0)\r
474                         {\r
475                             output = output + (".");\r
476                         }\r
477                         else\r
478                         {\r
479                             output = output + (" ");\r
480                         }\r
481                     }\r
482                     else\r
483                     {\r
484                         output = output + (" ");\r
485                     }\r
486                 }\r
487             }\r
488 \r
489             // Now print the second aligned sequence\r
490             output = output + ("\n");\r
491             output = output +\r
492                 (new Format("%" + (maxid) + "s").form(s2.getName()) + " ");\r
493 \r
494             for (int i = 0; i < len; i++)\r
495             {\r
496                 if ((count + i + (j * len)) < aseq1.length)\r
497                 {\r
498                     output = output +\r
499                         (new Format("%s").form(intToStr[aseq2[count + i +\r
500                             (j * len)]]));\r
501                 }\r
502             }\r
503 \r
504             output = output + ("\n\n");\r
505         }\r
506 \r
507         pid = pid / (float) (aseq1.length - count) * 100;\r
508         output = output + (new Format("Percentage ID = %2.2f\n\n").form(pid));\r
509     }\r
510 \r
511     /**\r
512      * DOCUMENT ME!\r
513      *\r
514      * @param mat DOCUMENT ME!\r
515      */\r
516     public void printScoreMatrix(int[][] mat)\r
517     {\r
518         int n = seq1.length;\r
519         int m = seq2.length;\r
520 \r
521         for (int i = 0; i < n; i++)\r
522         {\r
523             // Print the top sequence\r
524             if (i == 0)\r
525             {\r
526                 Format.print(System.out, "%8s", s2str.substring(0, 1));\r
527 \r
528                 for (int jj = 1; jj < m; jj++)\r
529                 {\r
530                     Format.print(System.out, "%5s", s2str.substring(jj, jj + 1));\r
531                 }\r
532 \r
533                 System.out.println();\r
534             }\r
535 \r
536             for (int j = 0; j < m; j++)\r
537             {\r
538                 if (j == 0)\r
539                 {\r
540                     Format.print(System.out, "%3s", s1str.substring(i, i + 1));\r
541                 }\r
542 \r
543                 Format.print(System.out, "%3d ", mat[i][j] / 10);\r
544             }\r
545 \r
546             System.out.println();\r
547         }\r
548     }\r
549 \r
550     /**\r
551      * DOCUMENT ME!\r
552      *\r
553      * @param i DOCUMENT ME!\r
554      * @param j DOCUMENT ME!\r
555      *\r
556      * @return DOCUMENT ME!\r
557      */\r
558     public int findTrace(int i, int j)\r
559     {\r
560         int t = 0;\r
561         int max = score[i - 1][j - 1] + (lookup[seq1[i]][seq2[j]] * 10);\r
562 \r
563         if (F[i][j] > max)\r
564         {\r
565             max = F[i][j];\r
566             t = -1;\r
567         }\r
568         else if (F[i][j] == max)\r
569         {\r
570             if (prev == -1)\r
571             {\r
572                 max = F[i][j];\r
573                 t = -1;\r
574             }\r
575         }\r
576 \r
577         if (E[i][j] >= max)\r
578         {\r
579             max = E[i][j];\r
580             t = 1;\r
581         }\r
582         else if (E[i][j] == max)\r
583         {\r
584             if (prev == 1)\r
585             {\r
586                 max = E[i][j];\r
587                 t = 1;\r
588             }\r
589         }\r
590 \r
591         prev = t;\r
592 \r
593         return t;\r
594     }\r
595 \r
596     /**\r
597      * DOCUMENT ME!\r
598      */\r
599     public void calcScoreMatrix()\r
600     {\r
601         int n = seq1.length;\r
602         int m = seq2.length;\r
603 \r
604         // top left hand element\r
605         score[0][0] = lookup[seq1[0]][seq2[0]] * 10;\r
606         E[0][0] = -gapExtend;\r
607         F[0][0] = 0;\r
608 \r
609         // Calculate the top row first\r
610         for (int j = 1; j < m; j++)\r
611         {\r
612             // What should these values be? 0 maybe\r
613             E[0][j] = max(score[0][j - 1] - gapOpen, E[0][j - 1] - gapExtend);\r
614             F[0][j] = -gapExtend;\r
615 \r
616             score[0][j] = max(lookup[seq1[0]][seq2[j]] * 10, -gapOpen,\r
617                     -gapExtend);\r
618 \r
619             traceback[0][j] = 1;\r
620         }\r
621 \r
622         // Now do the left hand column\r
623         for (int i = 1; i < n; i++)\r
624         {\r
625             E[i][0] = -gapOpen;\r
626             F[i][0] = max(score[i - 1][0] - gapOpen, F[i - 1][0] - gapExtend);\r
627 \r
628             score[i][0] = max(lookup[seq1[i]][seq2[0]] * 10, E[i][0], F[i][0]);\r
629             traceback[i][0] = -1;\r
630         }\r
631 \r
632         // Now do all the other rows\r
633         for (int i = 1; i < n; i++)\r
634         {\r
635             for (int j = 1; j < m; j++)\r
636             {\r
637                 E[i][j] = max(score[i][j - 1] - gapOpen, E[i][j - 1] -\r
638                         gapExtend);\r
639                 F[i][j] = max(score[i - 1][j] - gapOpen, F[i - 1][j] -\r
640                         gapExtend);\r
641 \r
642                 score[i][j] = max(score[i - 1][j - 1] +\r
643                         (lookup[seq1[i]][seq2[j]] * 10), E[i][j], F[i][j]);\r
644                 traceback[i][j] = findTrace(i, j);\r
645             }\r
646         }\r
647     }\r
648 \r
649 \r
650 \r
651     /**\r
652      * DOCUMENT ME!\r
653      *\r
654      * @param gapChar DOCUMENT ME!\r
655      * @param seq DOCUMENT ME!\r
656      *\r
657      * @return DOCUMENT ME!\r
658      */\r
659     public static String extractGaps(String gapChar, String seq)\r
660     {\r
661         StringTokenizer str = new StringTokenizer(seq, gapChar);\r
662         String newString = "";\r
663 \r
664         while (str.hasMoreTokens())\r
665         {\r
666             newString = newString + str.nextToken();\r
667         }\r
668 \r
669         return newString;\r
670     }\r
671 \r
672     /**\r
673      * DOCUMENT ME!\r
674      *\r
675      * @param i1 DOCUMENT ME!\r
676      * @param i2 DOCUMENT ME!\r
677      * @param i3 DOCUMENT ME!\r
678      *\r
679      * @return DOCUMENT ME!\r
680      */\r
681     public int max(int i1, int i2, int i3)\r
682     {\r
683         int max = i1;\r
684 \r
685         if (i2 > i1)\r
686         {\r
687             max = i2;\r
688         }\r
689 \r
690         if (i3 > max)\r
691         {\r
692             max = i3;\r
693         }\r
694 \r
695         return max;\r
696     }\r
697 \r
698     /**\r
699      * DOCUMENT ME!\r
700      *\r
701      * @param i1 DOCUMENT ME!\r
702      * @param i2 DOCUMENT ME!\r
703      *\r
704      * @return DOCUMENT ME!\r
705      */\r
706     public int max(int i1, int i2)\r
707     {\r
708         int max = i1;\r
709 \r
710         if (i2 > i1)\r
711         {\r
712             max = i2;\r
713         }\r
714 \r
715         return max;\r
716     }\r
717 \r
718     /**\r
719      * DOCUMENT ME!\r
720      *\r
721      * @param s DOCUMENT ME!\r
722      * @param type DOCUMENT ME!\r
723      *\r
724      * @return DOCUMENT ME!\r
725      */\r
726     public int[] stringToInt(String s, String type)\r
727     {\r
728         int[] seq1 = new int[s.length()];\r
729 \r
730         for (int i = 0; i < s.length(); i++)\r
731         {\r
732             String ss = s.substring(i, i + 1).toUpperCase();\r
733 \r
734             try\r
735             {\r
736                 if (type.equals("pep"))\r
737                 {\r
738                     seq1[i] = ((Integer) ResidueProperties.aaHash.get(ss)).intValue();\r
739                 }\r
740                 else if (type.equals("dna"))\r
741                 {\r
742                     seq1[i] = ((Integer) dnaHash.get(ss)).intValue();\r
743                 }\r
744 \r
745                 if (seq1[i] > 23)\r
746                 {\r
747                     seq1[i] = 23;\r
748                 }\r
749             }\r
750             catch (Exception e)\r
751             {\r
752                 if (type.equals("dna"))\r
753                 {\r
754                     seq1[i] = 4;\r
755                 }\r
756                 else\r
757                 {\r
758                     seq1[i] = 23;\r
759                 }\r
760             }\r
761         }\r
762 \r
763         return seq1;\r
764     }\r
765 \r
766     /**\r
767      * DOCUMENT ME!\r
768      *\r
769      * @param g DOCUMENT ME!\r
770      * @param mat DOCUMENT ME!\r
771      * @param n DOCUMENT ME!\r
772      * @param m DOCUMENT ME!\r
773      * @param psize DOCUMENT ME!\r
774      */\r
775     public static void displayMatrix(Graphics g, int[][] mat, int n, int m,\r
776         int psize)\r
777     {\r
778         int max = -1000;\r
779         int min = 1000;\r
780 \r
781         for (int i = 0; i < n; i++)\r
782         {\r
783             for (int j = 0; j < m; j++)\r
784             {\r
785                 if (mat[i][j] >= max)\r
786                 {\r
787                     max = mat[i][j];\r
788                 }\r
789 \r
790                 if (mat[i][j] <= min)\r
791                 {\r
792                     min = mat[i][j];\r
793                 }\r
794             }\r
795         }\r
796 \r
797         System.out.println(max + " " + min);\r
798 \r
799         for (int i = 0; i < n; i++)\r
800         {\r
801             for (int j = 0; j < m; j++)\r
802             {\r
803                 int x = psize * i;\r
804                 int y = psize * j;\r
805 \r
806                 //      System.out.println(mat[i][j]);\r
807                 float score = (float) (mat[i][j] - min) / (float) (max - min);\r
808                 g.setColor(new Color(score, 0, 0));\r
809                 g.fillRect(x, y, psize, psize);\r
810 \r
811                 //      System.out.println(x + " " + y + " " + score);\r
812             }\r
813         }\r
814     }\r
815 }\r