Use stringbuffer, not string+
[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     StringBuffer output = new StringBuffer();\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.toString();\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.append("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(java.io.PrintStream os)\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.append("Score = " + score[maxi][maxj] + "\n");\r
424         output.append("Length of alignment = " + (aseq1.length - count) + "\n");\r
425         output.append("Sequence ");\r
426         output.append(new Format("%" + maxid + "s").form(s1.getName()));\r
427         output.append(" :  " + seq1start + " - " + seq1end + " (Sequence length = " +\r
428             s1str.length() + ")\n");\r
429         output .append("Sequence ");\r
430         output.append(new Format("%" + maxid + "s").form(s2.getName()));\r
431         output .append(" :  " + seq2start + " - " + seq2end + " (Sequence length = " +\r
432             s2str.length() + ")\n\n");\r
433 \r
434         for (int j = 0; j < nochunks; j++)\r
435         {\r
436             // Print the first aligned sequence\r
437             output.append(new Format("%" + (maxid) + "s").form(s1.getName()) + " ");\r
438 \r
439             for (int i = 0; i < len; i++)\r
440             {\r
441                 if ((count + i + (j * len)) < aseq1.length)\r
442                 {\r
443                     output.append(new Format("%s").form(intToStr[aseq1[count + i +\r
444                             (j * len)]]));\r
445                 }\r
446             }\r
447 \r
448             output.append("\n");\r
449             output.append(new Format("%" + (maxid) + "s").form(" ") + " ");\r
450 \r
451             // Print out the matching chars\r
452             for (int i = 0; i < len; i++)\r
453             {\r
454                 if ((count + i + (j * len)) < aseq1.length)\r
455                 {\r
456                     if (intToStr[aseq1[count + i + (j * len)]].equals(\r
457                                 intToStr[aseq2[count + i + (j * len)]]) &&\r
458                             !intToStr[aseq1[count + i + (j * len)]].equals("-"))\r
459                     {\r
460                         pid++;\r
461                         output.append("|");\r
462                     }\r
463                     else if (type.equals("pep"))\r
464                     {\r
465                         if (ResidueProperties.getPAM250(\r
466                                     intToStr[aseq1[count + i + (j * len)]],\r
467                                     intToStr[aseq2[count + i + (j * len)]]) > 0)\r
468                         {\r
469                             output.append(".");\r
470                         }\r
471                         else\r
472                         {\r
473                             output.append(" ");\r
474                         }\r
475                     }\r
476                     else\r
477                     {\r
478                         output.append(" ");\r
479                     }\r
480                 }\r
481             }\r
482 \r
483             // Now print the second aligned sequence\r
484             output = output.append("\n");\r
485             output = output.append(new Format("%" + (maxid) + "s").form(s2.getName()) + " ");\r
486 \r
487             for (int i = 0; i < len; i++)\r
488             {\r
489                 if ((count + i + (j * len)) < aseq1.length)\r
490                 {\r
491                     output .append(new Format("%s").form(intToStr[aseq2[count + i +\r
492                             (j * len)]]));\r
493                 }\r
494             }\r
495 \r
496             output = output .append("\n\n");\r
497         }\r
498 \r
499         pid = pid / (float) (aseq1.length - count) * 100;\r
500         output = output.append(new Format("Percentage ID = %2.2f\n\n").form(pid));\r
501 \r
502         try{\r
503           os.println(output.toString());\r
504         }catch(Exception ex){}\r
505     }\r
506 \r
507     /**\r
508      * DOCUMENT ME!\r
509      *\r
510      * @param mat DOCUMENT ME!\r
511      */\r
512     public void printScoreMatrix(int[][] mat)\r
513     {\r
514         int n = seq1.length;\r
515         int m = seq2.length;\r
516 \r
517         for (int i = 0; i < n; i++)\r
518         {\r
519             // Print the top sequence\r
520             if (i == 0)\r
521             {\r
522                 Format.print(System.out, "%8s", s2str.substring(0, 1));\r
523 \r
524                 for (int jj = 1; jj < m; jj++)\r
525                 {\r
526                     Format.print(System.out, "%5s", s2str.substring(jj, jj + 1));\r
527                 }\r
528 \r
529                 System.out.println();\r
530             }\r
531 \r
532             for (int j = 0; j < m; j++)\r
533             {\r
534                 if (j == 0)\r
535                 {\r
536                     Format.print(System.out, "%3s", s1str.substring(i, i + 1));\r
537                 }\r
538 \r
539                 Format.print(System.out, "%3d ", mat[i][j] / 10);\r
540             }\r
541 \r
542             System.out.println();\r
543         }\r
544     }\r
545 \r
546     /**\r
547      * DOCUMENT ME!\r
548      *\r
549      * @param i DOCUMENT ME!\r
550      * @param j DOCUMENT ME!\r
551      *\r
552      * @return DOCUMENT ME!\r
553      */\r
554     public int findTrace(int i, int j)\r
555     {\r
556         int t = 0;\r
557         int max = score[i - 1][j - 1] + (lookup[seq1[i]][seq2[j]] * 10);\r
558 \r
559         if (F[i][j] > max)\r
560         {\r
561             max = F[i][j];\r
562             t = -1;\r
563         }\r
564         else if (F[i][j] == max)\r
565         {\r
566             if (prev == -1)\r
567             {\r
568                 max = F[i][j];\r
569                 t = -1;\r
570             }\r
571         }\r
572 \r
573         if (E[i][j] >= max)\r
574         {\r
575             max = E[i][j];\r
576             t = 1;\r
577         }\r
578         else if (E[i][j] == max)\r
579         {\r
580             if (prev == 1)\r
581             {\r
582                 max = E[i][j];\r
583                 t = 1;\r
584             }\r
585         }\r
586 \r
587         prev = t;\r
588 \r
589         return t;\r
590     }\r
591 \r
592     /**\r
593      * DOCUMENT ME!\r
594      */\r
595     public void calcScoreMatrix()\r
596     {\r
597         int n = seq1.length;\r
598         int m = seq2.length;\r
599 \r
600         // top left hand element\r
601         score[0][0] = lookup[seq1[0]][seq2[0]] * 10;\r
602         E[0][0] = -gapExtend;\r
603         F[0][0] = 0;\r
604 \r
605         // Calculate the top row first\r
606         for (int j = 1; j < m; j++)\r
607         {\r
608             // What should these values be? 0 maybe\r
609             E[0][j] = max(score[0][j - 1] - gapOpen, E[0][j - 1] - gapExtend);\r
610             F[0][j] = -gapExtend;\r
611 \r
612             score[0][j] = max(lookup[seq1[0]][seq2[j]] * 10, -gapOpen,\r
613                     -gapExtend);\r
614 \r
615             traceback[0][j] = 1;\r
616         }\r
617 \r
618         // Now do the left hand column\r
619         for (int i = 1; i < n; i++)\r
620         {\r
621             E[i][0] = -gapOpen;\r
622             F[i][0] = max(score[i - 1][0] - gapOpen, F[i - 1][0] - gapExtend);\r
623 \r
624             score[i][0] = max(lookup[seq1[i]][seq2[0]] * 10, E[i][0], F[i][0]);\r
625             traceback[i][0] = -1;\r
626         }\r
627 \r
628         // Now do all the other rows\r
629         for (int i = 1; i < n; i++)\r
630         {\r
631             for (int j = 1; j < m; j++)\r
632             {\r
633                 E[i][j] = max(score[i][j - 1] - gapOpen, E[i][j - 1] -\r
634                         gapExtend);\r
635                 F[i][j] = max(score[i - 1][j] - gapOpen, F[i - 1][j] -\r
636                         gapExtend);\r
637 \r
638                 score[i][j] = max(score[i - 1][j - 1] +\r
639                         (lookup[seq1[i]][seq2[j]] * 10), E[i][j], F[i][j]);\r
640                 traceback[i][j] = findTrace(i, j);\r
641             }\r
642         }\r
643     }\r
644 \r
645 \r
646 \r
647     /**\r
648      * DOCUMENT ME!\r
649      *\r
650      * @param gapChar DOCUMENT ME!\r
651      * @param seq DOCUMENT ME!\r
652      *\r
653      * @return DOCUMENT ME!\r
654      */\r
655     public static String extractGaps(String gapChar, String seq)\r
656     {\r
657         StringTokenizer str = new StringTokenizer(seq, gapChar);\r
658         StringBuffer newString = new StringBuffer();\r
659 \r
660         while (str.hasMoreTokens())\r
661         {\r
662             newString.append( str.nextToken() );\r
663         }\r
664 \r
665         return newString.toString();\r
666     }\r
667 \r
668     /**\r
669      * DOCUMENT ME!\r
670      *\r
671      * @param i1 DOCUMENT ME!\r
672      * @param i2 DOCUMENT ME!\r
673      * @param i3 DOCUMENT ME!\r
674      *\r
675      * @return DOCUMENT ME!\r
676      */\r
677     public int max(int i1, int i2, int i3)\r
678     {\r
679         int max = i1;\r
680 \r
681         if (i2 > i1)\r
682         {\r
683             max = i2;\r
684         }\r
685 \r
686         if (i3 > max)\r
687         {\r
688             max = i3;\r
689         }\r
690 \r
691         return max;\r
692     }\r
693 \r
694     /**\r
695      * DOCUMENT ME!\r
696      *\r
697      * @param i1 DOCUMENT ME!\r
698      * @param i2 DOCUMENT ME!\r
699      *\r
700      * @return DOCUMENT ME!\r
701      */\r
702     public int max(int i1, int i2)\r
703     {\r
704         int max = i1;\r
705 \r
706         if (i2 > i1)\r
707         {\r
708             max = i2;\r
709         }\r
710 \r
711         return max;\r
712     }\r
713 \r
714     /**\r
715      * DOCUMENT ME!\r
716      *\r
717      * @param s DOCUMENT ME!\r
718      * @param type DOCUMENT ME!\r
719      *\r
720      * @return DOCUMENT ME!\r
721      */\r
722     public int[] stringToInt(String s, String type)\r
723     {\r
724         int[] seq1 = new int[s.length()];\r
725 \r
726         for (int i = 0; i < s.length(); i++)\r
727         {\r
728             String ss = s.substring(i, i + 1).toUpperCase();\r
729 \r
730             try\r
731             {\r
732                 if (type.equals("pep"))\r
733                 {\r
734                     seq1[i] = ((Integer) ResidueProperties.aaHash.get(ss)).intValue();\r
735                 }\r
736                 else if (type.equals("dna"))\r
737                 {\r
738                     seq1[i] = ((Integer) dnaHash.get(ss)).intValue();\r
739                 }\r
740 \r
741                 if (seq1[i] > 23)\r
742                 {\r
743                     seq1[i] = 23;\r
744                 }\r
745             }\r
746             catch (Exception e)\r
747             {\r
748                 if (type.equals("dna"))\r
749                 {\r
750                     seq1[i] = 4;\r
751                 }\r
752                 else\r
753                 {\r
754                     seq1[i] = 23;\r
755                 }\r
756             }\r
757         }\r
758 \r
759         return seq1;\r
760     }\r
761 \r
762     /**\r
763      * DOCUMENT ME!\r
764      *\r
765      * @param g DOCUMENT ME!\r
766      * @param mat DOCUMENT ME!\r
767      * @param n DOCUMENT ME!\r
768      * @param m DOCUMENT ME!\r
769      * @param psize DOCUMENT ME!\r
770      */\r
771     public static void displayMatrix(Graphics g, int[][] mat, int n, int m,\r
772         int psize)\r
773     {\r
774         int max = -1000;\r
775         int min = 1000;\r
776 \r
777         for (int i = 0; i < n; i++)\r
778         {\r
779             for (int j = 0; j < m; j++)\r
780             {\r
781                 if (mat[i][j] >= max)\r
782                 {\r
783                     max = mat[i][j];\r
784                 }\r
785 \r
786                 if (mat[i][j] <= min)\r
787                 {\r
788                     min = mat[i][j];\r
789                 }\r
790             }\r
791         }\r
792 \r
793         System.out.println(max + " " + min);\r
794 \r
795         for (int i = 0; i < n; i++)\r
796         {\r
797             for (int j = 0; j < m; j++)\r
798             {\r
799                 int x = psize * i;\r
800                 int y = psize * j;\r
801 \r
802                 //      System.out.println(mat[i][j]);\r
803                 float score = (float) (mat[i][j] - min) / (float) (max - min);\r
804                 g.setColor(new Color(score, 0, 0));\r
805                 g.fillRect(x, y, psize, psize);\r
806 \r
807                 //      System.out.println(x + " " + y + " " + score);\r
808             }\r
809         }\r
810     }\r
811 }\r