Clover icon

Coverage Report

  1. Project Clover database Wed Jan 7 2026 02:39:37 GMT
  2. Package jalview.analysis

File AlignSeq.java

 

Coverage histogram

../../img/srcFileCovDistChart7.png
30% of files have more coverage

Code metrics

222
516
46
1
1,553
1,026
180
0.35
11.22
46
3.91

Classes

Class Line # Actions
AlignSeq 54 516 180
0.663265366.3%
 

Contributing tests

This file is covered by 444 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.analysis;
22   
23    import jalview.analysis.scoremodels.PIDModel;
24    import jalview.analysis.scoremodels.ScoreMatrix;
25    import jalview.analysis.scoremodels.ScoreModels;
26    import jalview.analysis.scoremodels.SimilarityParams;
27    import jalview.api.analysis.SimilarityParamsI;
28    import jalview.datamodel.AlignmentAnnotation;
29    import jalview.datamodel.AlignmentI;
30    import jalview.datamodel.Mapping;
31    import jalview.datamodel.Sequence;
32    import jalview.datamodel.SequenceI;
33    import jalview.math.MiscMath;
34    import jalview.util.Comparison;
35    import jalview.util.Format;
36    import jalview.util.MapList;
37    import jalview.util.MessageManager;
38   
39    import java.awt.Color;
40    import java.awt.Graphics;
41    import java.io.PrintStream;
42    import java.lang.IllegalArgumentException;
43    import java.util.ArrayList;
44    import java.util.Arrays;
45    import java.util.HashMap;
46    import java.util.List;
47    import java.util.StringTokenizer;
48    import java.util.Locale;
49   
50    /**
51    * @author $author$
52    * @version $Revision$
53    */
 
54    public class AlignSeq
55    {
56    private static final int MAX_NAME_LENGTH = 30;
57   
58    private static final int DEFAULT_OPENCOST = 120;
59   
60    private static final int DEFAULT_EXTENDCOST = 20;
61   
62    private int GAP_OPEN_COST = DEFAULT_OPENCOST;
63   
64    private int GAP_EXTEND_COST = DEFAULT_EXTENDCOST;
65   
66    private static final int GAP_INDEX = -1;
67   
68    public static final String PEP = "pep";
69   
70    public static final String DNA = "dna";
71   
72    private static final String NEWLINE = System.lineSeparator();
73   
74    float[][] score;
75   
76    float alignmentScore;
77   
78    float[][] E;
79   
80    float[][] F;
81   
82    int[][] traceback; // todo is this actually used?
83   
84    int[] seq1;
85   
86    int[] seq2;
87   
88    SequenceI s1;
89   
90    SequenceI s2;
91   
92    public String s1str;
93   
94    public String s2str;
95   
96    int maxi;
97   
98    int maxj;
99   
100    int[] aseq1;
101   
102    int[] aseq2;
103   
104    /*
105    * matches in alignment
106    */
107    int match=-1;
108   
109    public String astr1 = "";
110   
111    public String astr2 = "";
112   
113    public String indelfreeAstr1 = "";
114   
115    public String indelfreeAstr2 = "";
116   
117    /** DOCUMENT ME!! */
118    public int seq1start;
119   
120    /** DOCUMENT ME!! */
121    public int seq1end;
122   
123    /** DOCUMENT ME!! */
124    public int seq2start;
125   
126    public int seq2end;
127   
128    int count;
129   
130    public float maxscore;
131   
132    public float meanScore; // needed for PaSiMap
133   
134    public int hypotheticMaxScore; // needed for PaSiMap
135   
136    int prev = 0;
137   
138    StringBuffer output = new StringBuffer();
139   
140    String type; // AlignSeq.PEP or AlignSeq.DNA
141   
142    private ScoreMatrix scoreMatrix;
143   
144    /**
145    * Creates a new AlignSeq object.
146    *
147    * @param s1
148    * first sequence for alignment
149    * @param s2
150    * second sequence for alignment
151    * @param type
152    * molecule type, either AlignSeq.PEP or AlignSeq.DNA
153    */
 
154  0 toggle public AlignSeq(int opencost, int extcost)
155    {
156  0 GAP_OPEN_COST = opencost;
157  0 GAP_EXTEND_COST = extcost;
158    }
159   
 
160  281 toggle public AlignSeq(SequenceI s1, SequenceI s2, String type)
161    {
162  281 seqInit(s1, s1.getSequenceAsString(), s2, s2.getSequenceAsString(),
163    type);
164    }
165   
166    /**
167    * Creates a new AlignSeq object.
168    *
169    * @param s1,string1
170    * s1 reference sequence for string1
171    * @param s2,string2
172    * s2 reference sequence for string2
173    * @param type
174    * molecule type, either AlignSeq.PEP or AlignSeq.DNA
175    */
 
176  2 toggle public AlignSeq(SequenceI s1, String string1, SequenceI s2,
177    String string2, String type)
178    {
179  2 seqInit(s1, string1.toUpperCase(Locale.ROOT), s2,
180    string2.toUpperCase(Locale.ROOT), type);
181    }
182   
 
183  279 toggle public AlignSeq(SequenceI s1, SequenceI s2, String type, int opencost,
184    int extcost)
185    {
186  279 this(s1, s2, type);
187  279 GAP_OPEN_COST = opencost;
188  279 GAP_EXTEND_COST = extcost;
189    }
190   
 
191  2 toggle public AlignSeq(SequenceI s12, String string1, SequenceI s22,
192    String string2, String type2, int defaultOpencost,
193    int defaultExtendcost)
194    {
195  2 this(s12, string1, s22, string2, type2);
196  2 GAP_OPEN_COST = defaultOpencost;
197  2 GAP_EXTEND_COST = defaultExtendcost;
198    }
199   
200    /**
201    * DOCUMENT ME!
202    *
203    * @return DOCUMENT ME!
204    */
 
205  32 toggle public float getMaxScore()
206    {
207  32 return maxscore;
208    }
209   
210    /**
211    * returns the overall score of the alignment
212    *
213    * @return
214    */
 
215  2 toggle public float getAlignmentScore()
216    {
217  2 return alignmentScore;
218    }
219   
220    /**
221    * DOCUMENT ME!
222    *
223    * @return DOCUMENT ME!
224    */
 
225  755 toggle public int getSeq2Start()
226    {
227  755 return seq2start;
228    }
229   
230    /**
231    * DOCUMENT ME!
232    *
233    * @return DOCUMENT ME!
234    */
 
235  244 toggle public int getSeq2End()
236    {
237  244 return seq2end;
238    }
239   
240    /**
241    * DOCUMENT ME!
242    *
243    * @return DOCUMENT ME!
244    */
 
245  755 toggle public int getSeq1Start()
246    {
247  755 return seq1start;
248    }
249   
250    /**
251    * DOCUMENT ME!
252    *
253    * @return DOCUMENT ME!
254    */
 
255  244 toggle public int getSeq1End()
256    {
257  244 return seq1end;
258    }
259   
260    /**
261    * DOCUMENT ME!
262    *
263    * @return DOCUMENT ME!
264    */
 
265  4 toggle public String getOutput()
266    {
267  4 return output.toString();
268    }
269   
270    /**
271    * DOCUMENT ME!
272    *
273    * @return DOCUMENT ME!
274    */
 
275  253 toggle public String getAStr1()
276    {
277  253 return astr1;
278    }
279   
280    /**
281    * DOCUMENT ME!
282    *
283    * @return DOCUMENT ME!
284    */
 
285  252 toggle public String getAStr2()
286    {
287  252 return astr2;
288    }
289   
290    /**
291    * DOCUMENT ME!
292    *
293    * @return DOCUMENT ME!
294    */
 
295  2 toggle public int[] getASeq1()
296    {
297  2 return aseq1;
298    }
299   
300    /**
301    * DOCUMENT ME!
302    *
303    * @return DOCUMENT ME!
304    */
 
305  0 toggle public int[] getASeq2()
306    {
307  0 return aseq2;
308    }
309   
310    /**
311    *
312    * @return aligned instance of Seq 1
313    */
 
314  243 toggle public SequenceI getAlignedSeq1()
315    {
316  243 SequenceI alSeq1 = new Sequence(s1.getName(), getAStr1());
317  243 alSeq1.setStart(s1.getStart() + getSeq1Start() - 1);
318  243 alSeq1.setEnd(s1.getStart() + getSeq1End() - 1);
319  243 alSeq1.setDatasetSequence(
320  243 s1.getDatasetSequence() == null ? s1 : s1.getDatasetSequence());
321  243 return alSeq1;
322    }
323   
324    /**
325    *
326    * @return aligned instance of Seq 2
327    */
 
328  243 toggle public SequenceI getAlignedSeq2()
329    {
330  243 SequenceI alSeq2 = new Sequence(s2.getName(), getAStr2());
331  243 alSeq2.setStart(s2.getStart() + getSeq2Start() - 1);
332  243 alSeq2.setEnd(s2.getStart() + getSeq2End() - 1);
333  243 alSeq2.setDatasetSequence(
334  243 s2.getDatasetSequence() == null ? s2 : s2.getDatasetSequence());
335  243 return alSeq2;
336    }
337    /**
338    * fraction of seq2 matched in the alignment
339    *
340    * @return NaN or [0..1]
341    */
 
342  191 toggle public double getS2Coverage()
343    {
344  191 if (match >= 0)
345    {
346  191 return ((double) match) / ((double) s2.getEnd() - s2.getStart() + 1);
347    }
348  0 return Double.NaN;
349    }
350   
351    /**
352    * fraction of seq1 matched in the alignment
353    *
354    * @return NaN or [0..1]
355    */
 
356  238 toggle public double getS1Coverage()
357    {
358  238 if (match >= 0)
359    {
360  238 return ((double) match) / ((double) s1.getEnd() - s1.getStart() + 1);
361    }
362  0 return Double.NaN;
363    }
364   
365    /**
366    * Construct score matrix for sequences with standard DNA or PEPTIDE matrix
367    *
368    * @param s1
369    * - sequence 1
370    * @param string1
371    * - string to use for s1
372    * @param s2
373    * - sequence 2
374    * @param string2
375    * - string to use for s2
376    * @param type
377    * DNA or PEPTIDE
378    */
 
379  283 toggle public void seqInit(SequenceI s1, String string1, SequenceI s2,
380    String string2, String type)
381    {
382  283 seqInit(s1, string1, s2, string2, type, GAP_OPEN_COST, GAP_EXTEND_COST);
383    }
384   
 
385  283 toggle public void seqInit(SequenceI s1, String string1, SequenceI s2,
386    String string2, String type, int opening, int extension)
387    {
388  283 GAP_OPEN_COST = opening;
389  283 GAP_EXTEND_COST = extension;
390  283 this.s1 = s1;
391  283 this.s2 = s2;
392  283 setDefaultParams(type);
393  283 seqInit(string1, string2);
394    }
395   
396    /**
397    * construct score matrix for string1 and string2 (after removing any existing
398    * gaps
399    *
400    * @param string1
401    * @param string2
402    */
 
403  283 toggle private void seqInit(String string1, String string2)
404    {
405  283 s1str = extractGaps(jalview.util.Comparison.GapChars, string1);
406  283 s2str = extractGaps(jalview.util.Comparison.GapChars, string2);
407   
408  283 if (s1str.length() == 0 || s2str.length() == 0)
409    {
410  0 output.append(
411  0 "ALL GAPS: " + (s1str.length() == 0 ? s1.getName() : " ")
412  0 + (s2str.length() == 0 ? s2.getName() : ""));
413  0 return;
414    }
415   
416  283 score = new float[s1str.length()][s2str.length()];
417   
418  283 E = new float[s1str.length()][s2str.length()];
419   
420  283 F = new float[s1str.length()][s2str.length()];
421  283 traceback = new int[s1str.length()][s2str.length()];
422   
423  283 seq1 = indexEncode(s1str);
424   
425  283 seq2 = indexEncode(s2str);
426    }
427   
 
428  283 toggle private void setDefaultParams(String moleculeType)
429    {
430  283 if (!PEP.equals(moleculeType) && !DNA.equals(moleculeType))
431    {
432  0 output.append("Wrong type = dna or pep only");
433  0 throw new Error(MessageManager
434    .formatMessage("error.unknown_type_dna_or_pep", new String[]
435    { moleculeType }));
436    }
437   
438  283 type = moleculeType;
439  283 scoreMatrix = ScoreModels.getInstance()
440    .getDefaultModel(PEP.equals(type));
441    }
442   
443    /**
444    * DOCUMENT ME!
445    */
 
446  281 toggle public void traceAlignment()
447    {
448    // Find the maximum score along the rhs or bottom row
449  281 float max = -Float.MAX_VALUE;
450   
451  34380 for (int i = 0; i < seq1.length; i++)
452    {
453  34099 if (score[i][seq2.length - 1] > max)
454    {
455  21833 max = score[i][seq2.length - 1];
456  21833 maxi = i;
457  21833 maxj = seq2.length - 1;
458    }
459    }
460   
461  32996 for (int j = 0; j < seq2.length; j++)
462    {
463  32715 if (score[seq1.length - 1][j] > max)
464    {
465  15 max = score[seq1.length - 1][j];
466  15 maxi = seq1.length - 1;
467  15 maxj = j;
468    }
469    }
470   
471  281 int i = maxi;
472  281 int j = maxj;
473  281 int trace;
474  281 maxscore = score[i][j] / 10f;
475   
476  281 seq1end = maxi + 1;
477  281 seq2end = maxj + 1;
478   
479  281 aseq1 = new int[seq1.length + seq2.length];
480  281 aseq2 = new int[seq1.length + seq2.length];
481  281 match = 0;
482  281 StringBuilder sb1 = new StringBuilder(aseq1.length);
483  281 StringBuilder sb2 = new StringBuilder(aseq2.length);
484   
485  281 count = (seq1.length + seq2.length) - 1;
486   
487  30005 while (i > 0 && j > 0)
488    {
489  29724 aseq1[count] = seq1[i];
490  29724 sb1.append(s1str.charAt(i));
491  29724 aseq2[count] = seq2[j];
492  29724 sb2.append(s2str.charAt(j));
493  29724 trace = findTrace(i, j);
494   
495  29724 if (trace == 0)
496    {
497  29700 match++;
498  29700 i--;
499  29700 j--;
500    }
501  24 else if (trace == 1)
502    {
503  0 j--;
504  0 aseq1[count] = GAP_INDEX;
505  0 sb1.replace(sb1.length() - 1, sb1.length(), "-");
506    }
507  24 else if (trace == -1)
508    {
509  24 i--;
510  24 aseq2[count] = GAP_INDEX;
511  24 sb2.replace(sb2.length() - 1, sb2.length(), "-");
512    }
513   
514  29724 count--;
515    }
516   
517  281 seq1start = i + 1;
518  281 seq2start = j + 1;
519   
520  281 if (aseq1[count] != GAP_INDEX)
521    {
522  281 aseq1[count] = seq1[i];
523  281 sb1.append(s1str.charAt(i));
524    }
525   
526  281 if (aseq2[count] != GAP_INDEX)
527    {
528  281 aseq2[count] = seq2[j];
529  281 sb2.append(s2str.charAt(j));
530  281 if (aseq1[count] != GAP_INDEX)
531    {
532  281 match++;
533    }
534    }
535   
536    /*
537    * we built the character strings backwards, so now
538    * reverse them to convert to sequence strings
539    */
540  281 astr1 = sb1.reverse().toString();
541  281 astr2 = sb2.reverse().toString();
542    }
543   
544    /**
545    * DOCUMENT ME!
546    */
 
547  0 toggle public void traceAlignmentWithEndGaps()
548    {
549    // Find the maximum score along the rhs or bottom row
550  0 float max = -Float.MAX_VALUE;
551   
552  0 for (int i = 0; i < seq1.length; i++)
553    {
554  0 if (score[i][seq2.length - 1] > max)
555    {
556  0 max = score[i][seq2.length - 1];
557  0 maxi = i;
558  0 maxj = seq2.length - 1;
559    }
560    }
561   
562  0 for (int j = 0; j < seq2.length; j++)
563    {
564  0 if (score[seq1.length - 1][j] > max)
565    {
566  0 max = score[seq1.length - 1][j];
567  0 maxi = seq1.length - 1;
568  0 maxj = j;
569    }
570    }
571   
572  0 int i = maxi;
573  0 int j = maxj;
574  0 int trace;
575  0 maxscore = score[i][j] / 10f;
576   
577    // prepare trailing gaps
578  0 while ((i < seq1.length - 1) || (j < seq2.length - 1))
579    {
580  0 i++;
581  0 j++;
582    }
583  0 seq1end = i + 1;
584  0 seq2end = j + 1;
585   
586  0 aseq1 = new int[seq1.length + seq2.length];
587  0 aseq2 = new int[seq1.length + seq2.length];
588   
589  0 StringBuilder sb1 = new StringBuilder(aseq1.length);
590  0 StringBuilder sb2 = new StringBuilder(aseq2.length);
591   
592  0 count = (seq1.length + seq2.length) - 1;
593   
594    // get trailing gaps
595  0 while ((i >= seq1.length) || (j >= seq2.length))
596    {
597  0 if (i >= seq1.length)
598    {
599  0 aseq1[count] = GAP_INDEX;
600  0 sb1.append("-");
601  0 aseq2[count] = seq2[j];
602  0 sb2.append(s2str.charAt(j));
603    }
604  0 else if (j >= seq2.length)
605    {
606  0 aseq1[count] = seq1[i];
607  0 sb1.append(s1str.charAt(i));
608  0 aseq2[count] = GAP_INDEX;
609  0 sb2.append("-");
610    }
611  0 i--;
612  0 j--;
613    }
614   
615  0 while (i > 0 && j > 0)
616    {
617  0 aseq1[count] = seq1[i];
618  0 sb1.append(s1str.charAt(i));
619  0 aseq2[count] = seq2[j];
620  0 sb2.append(s2str.charAt(j));
621   
622  0 trace = findTrace(i, j);
623   
624  0 if (trace == 0)
625    {
626  0 i--;
627  0 j--;
628    }
629  0 else if (trace == 1)
630    {
631  0 j--;
632  0 aseq1[count] = GAP_INDEX;
633  0 sb1.replace(sb1.length() - 1, sb1.length(), "-");
634    }
635  0 else if (trace == -1)
636    {
637  0 i--;
638  0 aseq2[count] = GAP_INDEX;
639  0 sb2.replace(sb2.length() - 1, sb2.length(), "-");
640    }
641   
642  0 count--;
643    }
644   
645  0 seq1start = i + 1;
646  0 seq2start = j + 1;
647   
648  0 aseq1[count] = seq1[i];
649  0 sb1.append(s1str.charAt(i));
650  0 aseq2[count] = seq2[j];
651  0 sb2.append(s2str.charAt(j));
652   
653    // get initial gaps
654  0 while (j > 0 || i > 0)
655    {
656  0 if (j > 0)
657    {
658  0 j--;
659  0 sb1.append("-");
660  0 sb2.append(s2str.charAt(j));
661    }
662  0 else if (i > 0)
663    {
664  0 i--;
665  0 sb1.append(s1str.charAt(i));
666  0 sb2.append("-");
667    }
668    }
669    /*
670    * we built the character strings backwards, so now
671    * reverse them to convert to sequence strings
672    */
673  0 astr1 = sb1.reverse().toString();
674  0 astr2 = sb2.reverse().toString();
675    }
676   
677    /**
678    * DOCUMENT ME!
679    */
 
680  241 toggle public void printAlignment(PrintStream os)
681    {
682    // TODO: Use original sequence characters rather than re-translated
683    // characters in output
684    // Find the biggest id length for formatting purposes
685  241 String s1id = getAlignedSeq1().getDisplayId(true);
686  241 String s2id = getAlignedSeq2().getDisplayId(true);
687  241 int nameLength = Math.max(s1id.length(), s2id.length());
688  241 if (nameLength > MAX_NAME_LENGTH)
689    {
690  27 int truncateBy = nameLength - MAX_NAME_LENGTH;
691  27 nameLength = MAX_NAME_LENGTH;
692    // JAL-527 - truncate the sequence ids
693  27 if (s1id.length() > nameLength)
694    {
695  0 int slashPos = s1id.lastIndexOf('/');
696  0 s1id = s1id.substring(0, slashPos - truncateBy)
697    + s1id.substring(slashPos);
698    }
699  27 if (s2id.length() > nameLength)
700    {
701  27 int slashPos = s2id.lastIndexOf('/');
702  27 s2id = s2id.substring(0, slashPos - truncateBy)
703    + s2id.substring(slashPos);
704    }
705    }
706  241 int len = 72 - nameLength - 1;
707  241 int nochunks = ((aseq1.length - count) / len)
708  241 + ((aseq1.length - count) % len > 0 ? 1 : 0);
709  241 float pid = 0f;
710   
711  241 output.append("Score = ").append(score[maxi][maxj]).append(NEWLINE);
712  241 output.append("Length of alignment = ")
713    .append(String.valueOf(aseq1.length - count)).append(NEWLINE);
714  241 output.append("Sequence ");
715  241 Format nameFormat = new Format("%" + nameLength + "s");
716  241 output.append(nameFormat.form(s1id));
717  241 output.append(" (Sequence length = ")
718    .append(String.valueOf(s1str.length())).append(")")
719    .append(NEWLINE);
720  241 output.append("Sequence ");
721  241 output.append(nameFormat.form(s2id));
722  241 output.append(" (Sequence length = ")
723    .append(String.valueOf(s2str.length())).append(")")
724    .append(NEWLINE).append(NEWLINE);
725   
726  241 ScoreMatrix pam250 = ScoreModels.getInstance().getPam250();
727   
728  820 for (int j = 0; j < nochunks; j++)
729    {
730    // Print the first aligned sequence
731  579 output.append(nameFormat.form(s1id)).append(" ");
732   
733  30244 for (int i = 0; i < len; i++)
734    {
735  29665 if ((i + (j * len)) < astr1.length())
736    {
737  24555 output.append(astr1.charAt(i + (j * len)));
738    }
739    }
740   
741  579 output.append(NEWLINE);
742  579 output.append(nameFormat.form(" ")).append(" ");
743   
744    /*
745    * Print out the match symbols:
746    * | for exact match (ignoring case)
747    * . if PAM250 score is positive
748    * else a space
749    */
750  30244 for (int i = 0; i < len; i++)
751    {
752  29665 if ((i + (j * len)) < astr1.length())
753    {
754  24555 char c1 = astr1.charAt(i + (j * len));
755  24555 char c2 = astr2.charAt(i + (j * len));
756  24555 boolean sameChar = Comparison.isSameResidue(c1, c2, false);
757  24555 if (sameChar && !Comparison.isGap(c1))
758    {
759  24501 pid++;
760  24501 output.append("|");
761    }
762  54 else if (PEP.equals(type))
763    {
764  54 if (pam250.getPairwiseScore(c1, c2) > 0)
765    {
766  2 output.append(".");
767    }
768    else
769    {
770  52 output.append(" ");
771    }
772    }
773    else
774    {
775  0 output.append(" ");
776    }
777    }
778    }
779   
780    // Now print the second aligned sequence
781  579 output = output.append(NEWLINE);
782  579 output = output.append(nameFormat.form(s2id)).append(" ");
783   
784  30244 for (int i = 0; i < len; i++)
785    {
786  29665 if ((i + (j * len)) < astr2.length())
787    {
788  24555 output.append(astr2.charAt(i + (j * len)));
789    }
790    }
791   
792  579 output.append(NEWLINE).append(NEWLINE);
793    }
794   
795  241 pid = pid / (aseq1.length - count) * 100;
796  241 output.append(new Format("Percentage ID = %3.2f\n").form(pid));
797  241 output.append(NEWLINE);
798  241 try
799    {
800  241 os.print(output.toString());
801    } catch (Exception ex)
802    {
803    }
804    }
805   
806    /**
807    * DOCUMENT ME!
808    *
809    * @param i
810    * DOCUMENT ME!
811    * @param j
812    * DOCUMENT ME!
813    *
814    * @return DOCUMENT ME!
815    */
 
816  5232130 toggle public int findTrace(int i, int j)
817    {
818  5232130 int t = 0;
819  5232130 float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(i),
820    s2str.charAt(j));
821  5232130 float max = score[i - 1][j - 1] + (pairwiseScore * 10);
822   
823  5232130 if (F[i][j] > max)
824    {
825  1746010 max = F[i][j];
826  1746010 t = -1;
827    }
828  3486120 else if (F[i][j] == max)
829    {
830  190535 if (prev == -1)
831    {
832  118996 max = F[i][j];
833  118996 t = -1;
834    }
835    }
836   
837  5232130 if (E[i][j] >= max)
838    {
839  1900611 max = E[i][j];
840  1900611 t = 1;
841    }
842  3331519 else if (E[i][j] == max)
843    {
844  0 if (prev == 1)
845    {
846  0 max = E[i][j];
847  0 t = 1;
848    }
849    }
850   
851  5232130 prev = t;
852   
853  5232130 return t;
854    }
855   
856    /**
857    * DOCUMENT ME!
858    */
 
859  281 toggle public void calcScoreMatrix()
860    {
861  281 int n = seq1.length;
862  281 int m = seq2.length;
863  281 final int GAP_EX_COST = GAP_EXTEND_COST;
864  281 final int GAP_OP_COST = GAP_OPEN_COST;
865    // top left hand element
866  281 score[0][0] = scoreMatrix.getPairwiseScore(s1str.charAt(0),
867    s2str.charAt(0)) * 10;
868  281 E[0][0] = -GAP_EX_COST;
869  281 F[0][0] = 0;
870   
871    // Calculate the top row first
872  32715 for (int j = 1; j < m; j++)
873    {
874    // What should these values be? 0 maybe
875  32434 E[0][j] = max(score[0][j - 1] - GAP_OP_COST,
876    E[0][j - 1] - GAP_EX_COST);
877  32434 F[0][j] = -GAP_EX_COST;
878   
879  32434 float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(0),
880    s2str.charAt(j));
881  32434 score[0][j] = max(pairwiseScore * 10, -GAP_OP_COST, -GAP_EX_COST);
882   
883  32434 traceback[0][j] = 1;
884    }
885   
886    // Now do the left hand column
887  34099 for (int i = 1; i < n; i++)
888    {
889  33818 E[i][0] = -GAP_OP_COST;
890  33818 F[i][0] = max(score[i - 1][0] - GAP_OP_COST,
891    F[i - 1][0] - GAP_EX_COST);
892   
893  33818 float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(i),
894    s2str.charAt(0));
895  33818 score[i][0] = max(pairwiseScore * 10, E[i][0], F[i][0]);
896  33818 traceback[i][0] = -1;
897    }
898   
899    // Now do all the other rows
900  34099 for (int i = 1; i < n; i++)
901    {
902  5236224 for (int j = 1; j < m; j++)
903    {
904  5202406 E[i][j] = max(score[i][j - 1] - GAP_OP_COST,
905    E[i][j - 1] - GAP_EX_COST);
906  5202406 F[i][j] = max(score[i - 1][j] - GAP_OP_COST,
907    F[i - 1][j] - GAP_EX_COST);
908   
909  5202406 float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(i),
910    s2str.charAt(j));
911  5202406 score[i][j] = max(score[i - 1][j - 1] + (pairwiseScore * 10),
912    E[i][j], F[i][j]);
913  5202406 traceback[i][j] = findTrace(i, j);
914    }
915    }
916    }
917   
918    /**
919    * Returns the given sequence with all of the given gap characters removed.
920    *
921    * @param gapChars
922    * a string of characters to be treated as gaps
923    * @param seq
924    * the input sequence
925    *
926    * @return
927    */
 
928  8671 toggle public static String extractGaps(String gapChars, String seq)
929    {
930  8671 if (gapChars == null || seq == null)
931    {
932  6 return null;
933    }
934  8665 StringTokenizer str = new StringTokenizer(seq, gapChars);
935  8665 StringBuilder newString = new StringBuilder(seq.length());
936   
937  50943 while (str.hasMoreTokens())
938    {
939  42278 newString.append(str.nextToken());
940    }
941   
942  8665 return newString.toString();
943    }
944   
945    /**
946    * DOCUMENT ME!
947    *
948    * @param f1
949    * DOCUMENT ME!
950    * @param f2
951    * DOCUMENT ME!
952    * @param f3
953    * DOCUMENT ME!
954    *
955    * @return DOCUMENT ME!
956    */
 
957  5268658 toggle private static float max(float f1, float f2, float f3)
958    {
959  5268658 float max = f1;
960   
961  5268658 if (f2 > f1)
962    {
963  1740100 max = f2;
964    }
965   
966  5268658 if (f3 > max)
967    {
968  1734649 max = f3;
969    }
970   
971  5268658 return max;
972    }
973   
974    /**
975    * DOCUMENT ME!
976    *
977    * @param f1
978    * DOCUMENT ME!
979    * @param f2
980    * DOCUMENT ME!
981    *
982    * @return DOCUMENT ME!
983    */
 
984  10471064 toggle private static float max(float f1, float f2)
985    {
986  10471064 float max = f1;
987   
988  10471064 if (f2 > f1)
989    {
990  5521065 max = f2;
991    }
992   
993  10471064 return max;
994    }
995   
996    /**
997    * Converts the character string to an array of integers which are the
998    * corresponding indices to the characters in the score matrix
999    *
1000    * @param s
1001    *
1002    * @return
1003    */
 
1004  568 toggle int[] indexEncode(String s)
1005    {
1006  568 int[] encoded = new int[s.length()];
1007   
1008  67435 for (int i = 0; i < s.length(); i++)
1009    {
1010  66867 char c = s.charAt(i);
1011  66867 encoded[i] = scoreMatrix.getMatrixIndex(c);
1012    }
1013   
1014  568 return encoded;
1015    }
1016   
1017    /**
1018    * DOCUMENT ME!
1019    *
1020    * @param g
1021    * DOCUMENT ME!
1022    * @param mat
1023    * DOCUMENT ME!
1024    * @param n
1025    * DOCUMENT ME!
1026    * @param m
1027    * DOCUMENT ME!
1028    * @param psize
1029    * DOCUMENT ME!
1030    */
 
1031  0 toggle public static void displayMatrix(Graphics g, int[][] mat, int n, int m,
1032    int psize)
1033    {
1034    // TODO method doesn't seem to be referenced anywhere delete??
1035  0 int max = -1000;
1036  0 int min = 1000;
1037   
1038  0 for (int i = 0; i < n; i++)
1039    {
1040  0 for (int j = 0; j < m; j++)
1041    {
1042  0 if (mat[i][j] >= max)
1043    {
1044  0 max = mat[i][j];
1045    }
1046   
1047  0 if (mat[i][j] <= min)
1048    {
1049  0 min = mat[i][j];
1050    }
1051    }
1052    }
1053   
1054  0 jalview.bin.Console.outPrintln(max + " " + min);
1055   
1056  0 for (int i = 0; i < n; i++)
1057    {
1058  0 for (int j = 0; j < m; j++)
1059    {
1060  0 int x = psize * i;
1061  0 int y = psize * j;
1062   
1063    // jalview.bin.Console.outPrintln(mat[i][j]);
1064  0 float score = (float) (mat[i][j] - min) / (float) (max - min);
1065  0 g.setColor(new Color(score, 0, 0));
1066  0 g.fillRect(x, y, psize, psize);
1067   
1068    // jalview.bin.Console.outPrintln(x + " " + y + " " + score);
1069    }
1070    }
1071    }
1072   
1073    /**
1074    * Compute a globally optimal needleman and wunsch alignment between two
1075    * sequences
1076    *
1077    * @param s1
1078    * @param s2
1079    * @param type
1080    * AlignSeq.DNA or AlignSeq.PEP
1081    */
 
1082  279 toggle public static AlignSeq doGlobalNWAlignment(SequenceI s1, SequenceI s2,
1083    String type)
1084    {
1085  279 return doGlobalNWAlignment(s1, s2, type, DEFAULT_OPENCOST,
1086    DEFAULT_EXTENDCOST);
1087    }
1088   
 
1089  279 toggle public static AlignSeq doGlobalNWAlignment(SequenceI s1, SequenceI s2,
1090    String type, int opencost, int extcost)
1091    {
1092   
1093  279 AlignSeq as = new AlignSeq(s1, s2, type, opencost, extcost);
1094   
1095  279 as.calcScoreMatrix();
1096  279 as.traceAlignment();
1097  279 return as;
1098    }
1099   
1100    /**
1101    *
1102    * @return mapping from positions in S1 to corresponding positions in S2
1103    */
 
1104  272 toggle public jalview.datamodel.Mapping getMappingFromS1(boolean allowmismatch)
1105    {
1106  272 ArrayList<Integer> as1 = new ArrayList<Integer>(),
1107    as2 = new ArrayList<Integer>();
1108  272 int pdbpos = s2.getStart() + getSeq2Start() - 2;
1109  272 int alignpos = s1.getStart() + getSeq1Start() - 2;
1110  272 int lp2 = pdbpos - 3, lp1 = alignpos - 3,last_i;
1111  272 boolean lastmatch = false;
1112    // and now trace the alignment onto the atom set.
1113  31880 for (int i = 0; i < astr1.length(); i++)
1114    {
1115  31608 char c1 = astr1.charAt(i), c2 = astr2.charAt(i);
1116  31608 if (c1 != '-')
1117    {
1118  31608 alignpos++;
1119    }
1120   
1121  31608 if (c2 != '-')
1122    {
1123  31584 pdbpos++;
1124    }
1125  31608 boolean isMatch = (allowmismatch || (c1 == c2) || (Math.abs(c2 - c1) == ('a' - 'A')));
1126    // ignore case differences
1127  31608 if ((c1!='-' && c2!='-')
1128    && isMatch)
1129    {
1130    // extend mapping interval
1131  31511 if (!lastmatch || (lp1 + 1 != alignpos || lp2 + 1 != pdbpos))
1132    {
1133  343 as1.add(Integer.valueOf(alignpos));
1134  343 as2.add(Integer.valueOf(pdbpos));
1135    }
1136  31511 lastmatch = true;
1137  31511 last_i=i;
1138  31511 lp1 = alignpos;
1139  31511 lp2 = pdbpos;
1140    } else {
1141    // extend mapping interval
1142  97 if (lastmatch)
1143    {
1144  71 as1.add(Integer.valueOf(lp1));
1145  71 as2.add(Integer.valueOf(lp2));
1146    }
1147  97 lastmatch = false;
1148    }
1149    }
1150    // construct range pairs
1151   
1152  272 if (lastmatch)
1153    {
1154    // add the final matching positions
1155   
1156    // whilst making sure each of as1 and as2
1157    // have an even number of elements
1158   
1159  272 do
1160    {
1161  272 as1.add(lp1);
1162  272 } while (as1.size() % 2 == 1);
1163  272 do
1164    {
1165  272 as2.add(lp2);
1166  272 } while (as2.size() % 2 == 1);
1167   
1168    }
1169  272 int[] mapseq1 = new int[as1.size()],
1170    mapseq2 = new int[as2.size()];
1171  272 int i = 0;
1172  272 for (Integer ip : as1)
1173    {
1174  686 mapseq1[i++] = ip;
1175    }
1176  272 ;
1177  272 i = 0;
1178  272 for (Integer ip : as2)
1179    {
1180  686 mapseq2[i++] = ip;
1181    }
1182  272 ;
1183  272 MapList map = new MapList(mapseq1, mapseq2, 1, 1);
1184   
1185  272 jalview.datamodel.Mapping mapping = new Mapping(map);
1186  272 mapping.setTo(s2);
1187  272 return mapping;
1188    }
1189   
1190    /**
1191    * matches ochains against al and populates seqs with the best match between
1192    * each ochain and the set in al
1193    *
1194    * @param ochains
1195    * @param al
1196    * @param dnaOrProtein
1197    * @param removeOldAnnots
1198    * when true, old annotation is cleared before new annotation
1199    * transferred
1200    * @return List<List<SequenceI> originals, List<SequenceI> replacement,
1201    * List<AlignSeq> alignment between each>
1202    */
 
1203  5 toggle public static List<List<? extends Object>> replaceMatchingSeqsWith(
1204    List<SequenceI> seqs, List<AlignmentAnnotation> annotations,
1205    List<SequenceI> ochains, AlignmentI al, String dnaOrProtein,
1206    boolean removeOldAnnots)
1207    {
1208  5 List<SequenceI> orig = new ArrayList<SequenceI>(),
1209    repl = new ArrayList<SequenceI>();
1210  5 List<AlignSeq> aligs = new ArrayList<AlignSeq>();
1211  5 if (al != null && al.getHeight() > 0)
1212    {
1213  5 ArrayList<SequenceI> matches = new ArrayList<SequenceI>();
1214  5 ArrayList<AlignSeq> aligns = new ArrayList<AlignSeq>();
1215   
1216  5 for (SequenceI sq : ochains)
1217    {
1218  14 SequenceI bestm = null;
1219  14 AlignSeq bestaseq = null;
1220  14 float bestscore = 0;
1221  14 for (SequenceI msq : al.getSequences())
1222    {
1223  30 AlignSeq aseq = doGlobalNWAlignment(msq, sq, dnaOrProtein);
1224  30 if (bestm == null || aseq.getMaxScore() > bestscore)
1225    {
1226  14 bestscore = aseq.getMaxScore();
1227  14 bestaseq = aseq;
1228  14 bestm = msq;
1229    }
1230    }
1231    // jalview.bin.Console.outPrintln("Best Score for " + (matches.size() +
1232    // 1) + " :"
1233    // + bestscore);
1234  14 matches.add(bestm);
1235  14 aligns.add(bestaseq);
1236  14 al.deleteSequence(bestm);
1237    }
1238  19 for (int p = 0, pSize = seqs.size(); p < pSize; p++)
1239    {
1240  14 SequenceI sq, sp = seqs.get(p);
1241  14 int q;
1242  ? if ((q = ochains.indexOf(sp)) > -1)
1243    {
1244  14 seqs.set(p, sq = matches.get(q));
1245  14 orig.add(sp);
1246  14 repl.add(sq);
1247  14 sq.setName(sp.getName());
1248  14 sq.setDescription(sp.getDescription());
1249  14 Mapping sp2sq;
1250  14 sq.transferAnnotation(sp,
1251    sp2sq = aligns.get(q).getMappingFromS1(false));
1252  14 aligs.add(aligns.get(q));
1253  14 int inspos = -1;
1254  46 for (int ap = 0; ap < annotations.size();)
1255    {
1256  32 if (annotations.get(ap).sequenceRef == sp)
1257    {
1258  4 if (inspos == -1)
1259    {
1260  4 inspos = ap;
1261    }
1262  4 if (removeOldAnnots)
1263    {
1264  0 annotations.remove(ap);
1265    }
1266    else
1267    {
1268  4 AlignmentAnnotation alan = annotations.remove(ap);
1269  4 alan.liftOver(sq, sp2sq);
1270  4 alan.setSequenceRef(sq);
1271  4 sq.addAlignmentAnnotation(alan);
1272    }
1273    }
1274    else
1275    {
1276  28 ap++;
1277    }
1278    }
1279  14 if (sq.getAnnotation() != null && sq.getAnnotation().length > 0)
1280    {
1281  14 annotations.addAll(inspos == -1 ? annotations.size() : inspos,
1282    Arrays.asList(sq.getAnnotation()));
1283    }
1284    }
1285    }
1286    }
1287  5 return Arrays.asList(orig, repl, aligs);
1288    }
1289   
1290    /**
1291    * compute the PID vector used by the redundancy filter.
1292    *
1293    * @param originalSequences
1294    * - sequences in alignment that are to filtered
1295    * @param omitHidden
1296    * - null or strings to be analysed (typically, visible portion of
1297    * each sequence in alignment)
1298    * @param start
1299    * - first column in window for calculation
1300    * @param end
1301    * - last column in window for calculation
1302    * @param ungapped
1303    * - if true then use ungapped sequence to compute PID
1304    * @return vector containing maximum PID for i-th sequence and any sequences
1305    * longer than that seuqence
1306    */
 
1307  0 toggle public static float[] computeRedundancyMatrix(
1308    SequenceI[] originalSequences, String[] omitHidden, int start,
1309    int end, boolean ungapped)
1310    {
1311  0 int height = originalSequences.length;
1312  0 float[] redundancy = new float[height];
1313  0 int[] lngth = new int[height];
1314  0 for (int i = 0; i < height; i++)
1315    {
1316  0 redundancy[i] = 0f;
1317  0 lngth[i] = -1;
1318    }
1319   
1320    // long start = System.currentTimeMillis();
1321   
1322  0 SimilarityParams pidParams = new SimilarityParams(true, true, true,
1323    true);
1324  0 float pid;
1325  0 String seqi, seqj;
1326  0 for (int i = 0; i < height; i++)
1327    {
1328   
1329  0 for (int j = 0; j < i; j++)
1330    {
1331  0 if (i == j)
1332    {
1333  0 continue;
1334    }
1335   
1336  0 if (omitHidden == null)
1337    {
1338  0 seqi = originalSequences[i].getSequenceAsString(start, end);
1339  0 seqj = originalSequences[j].getSequenceAsString(start, end);
1340    }
1341    else
1342    {
1343  0 seqi = omitHidden[i];
1344  0 seqj = omitHidden[j];
1345    }
1346  0 if (lngth[i] == -1)
1347    {
1348  0 String ug = AlignSeq.extractGaps(Comparison.GapChars, seqi);
1349  0 lngth[i] = ug.length();
1350  0 if (ungapped)
1351    {
1352  0 seqi = ug;
1353    }
1354    }
1355  0 if (lngth[j] == -1)
1356    {
1357  0 String ug = AlignSeq.extractGaps(Comparison.GapChars, seqj);
1358  0 lngth[j] = ug.length();
1359  0 if (ungapped)
1360    {
1361  0 seqj = ug;
1362    }
1363    }
1364  0 pid = (float) PIDModel.computePID(seqi, seqj, pidParams);
1365   
1366    // use real sequence length rather than string length
1367  0 if (lngth[j] < lngth[i])
1368    {
1369  0 redundancy[j] = Math.max(pid, redundancy[j]);
1370    }
1371    else
1372    {
1373  0 redundancy[i] = Math.max(pid, redundancy[i]);
1374    }
1375   
1376    }
1377    }
1378  0 return redundancy;
1379    }
1380   
1381    /**
1382    * calculate the mean score of the alignment mean score is equal to the score
1383    * of an alignmenet of two sequences with randomly shuffled AA sequence
1384    * composited of the same AA as the two original sequences
1385    *
1386    */
 
1387  2 toggle public void meanScore()
1388    {
1389  2 int length = indelfreeAstr1.length(); // both have the same length
1390    // create HashMap for counting residues in each sequence
1391  2 HashMap<Character, Integer> seq1ResCount = new HashMap<Character, Integer>();
1392  2 HashMap<Character, Integer> seq2ResCount = new HashMap<Character, Integer>();
1393   
1394    // for both sequences (String indelfreeAstr1 or 2) create a key for the
1395    // residue and add 1 each time its encountered
1396  2 for (char residue : indelfreeAstr1.toCharArray())
1397    {
1398  8 seq1ResCount.putIfAbsent(residue, 0);
1399  8 seq1ResCount.replace(residue, seq1ResCount.get(residue) + 1);
1400    }
1401  2 for (char residue : indelfreeAstr2.toCharArray())
1402    {
1403  8 seq2ResCount.putIfAbsent(residue, 0);
1404  8 seq2ResCount.replace(residue, seq2ResCount.get(residue) + 1);
1405    }
1406   
1407    // meanscore = for each residue pair get the number of appearance and add
1408    // (countA * countB * pairwiseScore(AB))
1409    // divide the meanscore by the sequence length afterwards
1410  2 float _meanscore = 0;
1411  2 for (char resA : seq1ResCount.keySet())
1412    {
1413  8 for (char resB : seq2ResCount.keySet())
1414    {
1415  32 int countA = seq1ResCount.get(resA);
1416  32 int countB = seq2ResCount.get(resB);
1417   
1418  32 float scoreAB = scoreMatrix.getPairwiseScore(resA, resB);
1419   
1420  32 _meanscore += countA * countB * scoreAB;
1421    }
1422    }
1423  2 _meanscore /= length;
1424  2 this.meanScore = _meanscore;
1425    }
1426   
 
1427  0 toggle public float getMeanScore()
1428    {
1429  0 return this.meanScore;
1430    }
1431   
1432    /**
1433    * calculate the hypothetic max score using the self-alignment of the
1434    * sequences
1435    */
 
1436  2 toggle public void hypotheticMaxScore()
1437    {
1438  2 int _hmsA = 0;
1439  2 int _hmsB = 0;
1440  2 for (char residue : indelfreeAstr1.toCharArray())
1441    {
1442  8 _hmsA += scoreMatrix.getPairwiseScore(residue, residue);
1443    }
1444  2 for (char residue : indelfreeAstr2.toCharArray())
1445    {
1446  8 _hmsB += scoreMatrix.getPairwiseScore(residue, residue);
1447    }
1448  2 this.hypotheticMaxScore = (_hmsA < _hmsB) ? _hmsA : _hmsB; // take the lower
1449    // self alignment
1450   
1451    }
1452   
 
1453  0 toggle public int getHypotheticMaxScore()
1454    {
1455  0 return this.hypotheticMaxScore;
1456    }
1457   
1458    /**
1459    * create strings based of astr1 and astr2 but without gaps
1460    */
 
1461  2 toggle public void getIndelfreeAstr()
1462    {
1463  2 int n = astr1.length(); // both have the same length
1464  10 for (int i = 0; i < n; i++)
1465    {
1466  8 if (Character.isLetter(astr1.charAt(i))
1467    && Character.isLetter(astr2.charAt(i))) // if both sequences dont
1468    // have a gap -> add to
1469    // indelfreeAstr
1470    {
1471  8 this.indelfreeAstr1 += astr1.charAt(i);
1472  8 this.indelfreeAstr2 += astr2.charAt(i);
1473    }
1474    }
1475    }
1476   
1477    /**
1478    * calculates the overall score of the alignment preprescore = sum of all
1479    * scores - all penalties if preprescore < 1 ~ alignmentScore = Float.NaN >
1480    * alignmentScore = ((preprescore - meanScore) / (hypotheticMaxScore -
1481    * meanScore)) * coverage
1482    */
 
1483  2 toggle public void scoreAlignment()
1484    {
1485   
1486  2 getIndelfreeAstr();
1487  2 meanScore();
1488  2 hypotheticMaxScore();
1489    // cannot calculate score because denominator would be zero
1490  2 if (this.hypotheticMaxScore == this.meanScore)
1491    {
1492  0 this.alignmentScore = Float.NaN;
1493  0 return;
1494    }
1495  2 int n = indelfreeAstr1.length();
1496   
1497  2 float score = 0;
1498  2 boolean aGapOpen = false;
1499  2 boolean bGapOpen = false;
1500  10 for (int i = 0; i < n; i++)
1501    {
1502  8 char char1 = indelfreeAstr1.charAt(i);
1503  8 char char2 = indelfreeAstr2.charAt(i);
1504  8 boolean aIsLetter = Character.isLetter(char1);
1505  8 boolean bIsLetter = Character.isLetter(char2);
1506  8 if (aIsLetter && bIsLetter) // if pair -> get score
1507    {
1508  8 score += scoreMatrix.getPairwiseScore(char1, char2);
1509    }
1510  0 else if (!aIsLetter && !bIsLetter)
1511    { // both are gap -> skip
1512    }
1513  0 else if ((!aIsLetter && aGapOpen) || (!bIsLetter && bGapOpen))
1514    { // one side gapopen -> score - gap_extend
1515  0 score -= GAP_EXTEND_COST;
1516    }
1517    else
1518    { // no gap open -> score - gap_open
1519  0 score -= GAP_OPEN_COST;
1520    }
1521    // adjust GapOpen status in both sequences
1522  8 aGapOpen = (!aIsLetter) ? true : false;
1523  8 bGapOpen = (!bIsLetter) ? true : false;
1524    }
1525   
1526  2 float preprescore = score; // if this score < 1 --> alignment score =
1527    // Float.NaN
1528  2 score = (score - this.meanScore)
1529    / (this.hypotheticMaxScore - this.meanScore);
1530  2 int[] _max = MiscMath
1531    .findMax(new int[]
1532    { astr1.replace("-", "").length(),
1533    astr2.replace("-", "").length() }); // {index of max, max}
1534  2 float coverage = (float) n / (float) _max[1]; // indelfreeAstr length /
1535    // longest sequence length
1536  2 float prescore = score; // only debug
1537  2 score *= coverage;
1538   
1539    // System.out.println(String.format("prepre-score: %f, pre-score: %f,
1540    // longlength: %d\nscore: %1.16f, mean: %f, max: %d", preprescore, prescore,
1541    // _max[1], score, this.meanScore, this.hypotheticMaxScore));
1542  2 float minScore = 0f;
1543  2 this.alignmentScore = (score <= minScore) ? Float.NaN : score;
1544    }
1545   
 
1546  0 toggle public void setScoreMatrix(ScoreMatrix sm)
1547    {
1548  0 if (sm != null)
1549    {
1550  0 scoreMatrix = sm;
1551    }
1552    }
1553    }