1 static char const rcsid[] = "$Id: posit.c,v 6.88 2011/10/25 14:33:16 boratyng Exp $";
2
3 /* $Id: posit.c,v 6.88 2011/10/25 14:33:16 boratyng Exp $
4 * ===========================================================================
5 *
6 * PUBLIC DOMAIN NOTICE
7 * National Center for Biotechnology Information
8 *
9 * This software/database is a "United States Government Work" under the
10 * terms of the United States Copyright Act. It was written as part of
11 * the author's official duties as a United States Government employee and
12 * thus cannot be copyrighted. This software/database is freely available
13 * to the public for use. The National Library of Medicine and the U.S.
14 * Government have not placed any restriction on its use or reproduction.
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * Please cite the author in any work or product based on this material.
25 *
26 * ===========================================================================
27 *
28
29 File name: posit.c
30
31 Author: Alejandro Schaffer
32
33 Contents: utilities for position-based BLAST.
34
35 $Revision: 6.88 $
36 *****************************************************************************
37
38 * $Log: posit.c,v $
39 * Revision 6.88 2011/10/25 14:33:16 boratyng
40 * Fix for printing gapless column weights relative to pseudocounts in ascii pssm output JIRA SB-589
41 *
42 * Revision 6.87 2008/10/03 18:09:17 madden
43 * Change a few constants for pseudo counts (from A. Schaffer)
44 *
45 * Revision 6.86 2008/07/22 19:45:32 kans
46 * removed unused variables
47 *
48 * Revision 6.85 2008/03/31 16:21:58 kans
49 * CodeWarrior requred a cast to Blast_GetMatrixBackgroundFreq result
50 *
51 * Revision 6.84 2008/03/31 13:36:10 madden
52 * Implemented a new method to compute effective observations.
53 * Implemented a new entropy-based method to compute column-specific pseudocounts.
54 *
55 * Revision 6.83 2007/05/07 13:30:54 kans
56 * added casts for Seq-data.gap (SeqDataPtr, SeqGapPtr, ByteStorePtr)
57 *
58 * Revision 6.82 2007/03/12 16:21:35 papadopo
59 * From Kristoffer Osowski: fix a buffer overflow caused by incorrect computation of number of sequences for psiblast
60 *
61 * Revision 6.81 2007/01/22 19:20:55 camacho
62 * From Alejandro Schaffer:
63 * In posPurgeMatches, when in command-line mode, added a warning for the
64 * situation in which only the query is used to construct the PSSM.
65 *
66 * Revision 6.80 2006/09/28 12:45:39 madden
67 * Use more accurrate, symmetric, frequency data for the PAM matrices.
68 * Make the frequency ratios for the X character in BLOSUM90 the
69 * same consistent with the other BLOSUM matrices.
70 * [from Mike Gertz]
71 *
72 * Revision 6.79 2006/09/25 19:27:39 madden
73 * - Include blastkar.h in posit.c to get the declarations of
74 * BlastScoreFreqNew and BlastScoreFreqDestruct
75 * - Change %lf in printf statements to %f: %lf is equivalent to %f,
76 * but is not ANSI C, so was causing warnings.
77 * - Copied the correct, 28-character frequency ratios from
78 * algo/blast/core/matrix_freq_ratios.c.
79 * [from Mike Gertz]
80 *
81 * Revision 6.78 2006/08/01 16:52:07 camacho
82 * Fix comments
83 *
84 * Revision 6.77 2006/06/30 18:44:40 camacho
85 * Add support for O and J to getRes, ResToInt
86 *
87 * Revision 6.76 2005/08/30 18:21:02 coulouri
88 * From Mike Gertz:
89 * In posFreqsToMatrix while setting posSearch->posPrivateMatrix, check
90 * whether the frequency ratio is zero before taking the log. If it is
91 * zero, set the score to BLAST_SCORE_MIN. Do not test whether the
92 * original matrix has a score of BLAST_SCORE_MIN.
93 *
94 * Revision 6.75 2005/08/05 12:05:13 coulouri
95 * From Mike Gertz:
96 * - Changed the freq ratio of a (*,-) or (-,*) match for all matrices to
97 * be zero. The effect of this change is that these substitutions get
98 * assigned a score of BLAST_SCORE_MIN when composition-based statistics
99 * is used in any mode.
100 *
101 * Revision 6.74 2005/07/28 14:57:10 coulouri
102 * remove dead code
103 *
104 * Revision 6.73 2005/06/08 12:26:29 camacho
105 * Change posReadPosFreqsScoremat to accept other encodings of Bioseq data in ASN.1 PSSM
106 *
107 * Revision 6.72 2004/10/12 15:06:57 papadopo
108 * 1. Modify residue frequency IO to comply with new scoremat spec
109 * 2. Remove check that residue frequencies read from scoremat are <= 1.0
110 * 3. Pass gap open and gap extend penalties into BposComputation and
111 * CposComputation, so that scoremats can contain them
112 *
113 * Revision 6.71 2004/08/23 17:09:22 papadopo
114 * From Michael Gertz: move static arrays out of header and into the one file that needs them
115 *
116 * Revision 6.70 2004/08/05 17:30:53 camacho
117 * Remove initialization of identifier as it is no longer required
118 *
119 * Revision 6.69 2004/07/24 18:56:01 camacho
120 * Fix in posDemographics when GetSequenceWithDenseSeg cannot find sequence data
121 *
122 * Revision 6.68 2004/07/19 17:13:13 papadopo
123 * add capability to perform input and output of residue frequencies in scoremat form; also call PSIMatrixFrequencyRatiosNew before restarting from checkpoint
124 *
125 * Revision 6.67 2004/07/13 13:54:15 camacho
126 * Fix memory leak
127 *
128 * Revision 6.66 2004/06/25 21:54:51 dondosha
129 * Choose ideal values for lambda and K correctly for ungapped search
130 *
131 * Revision 6.65 2004/06/23 14:53:29 camacho
132 * Copy renamed versions of SFreqRatios and its *{New,Free} functions to avoid
133 * dependency ncbitool -> blast
134 *
135 * Revision 6.64 2004/06/22 14:16:46 camacho
136 * Changed signature of posFreqsToMatrix, added use of SFreqRatios structure from
137 * algo/blast/core/ to obtain underlying matrices' frequency ratios.
138 * This change results in using the frequency ratios to provide the scores
139 * for the PSSM in columns where all residue frequencies are 0. Previously the
140 * standard scoring matrix were used.
141 *
142 * Revision 6.63 2004/06/08 14:03:48 camacho
143 * Alejandro Schaffer's fix to spread out gap costs in posDemographics.
144 *
145 * Revision 6.62 2004/05/14 12:13:09 camacho
146 * Made posDemographics non-static for testing purposes.
147 *
148 * Revision 6.61 2003/08/04 20:43:55 dondosha
149 * Test for selenocysteines when comparing checkpoint sequences with query
150 *
151 * Revision 6.60 2003/05/30 17:25:37 coulouri
152 * add rcsid
153 *
154 * Revision 6.59 2003/05/13 16:02:53 coulouri
155 * make ErrPostEx(SEV_FATAL, ...) exit with nonzero status
156 *
157 * Revision 6.58 2001/12/11 14:48:54 madden
158 * Fix for ABW (reset Xcount to zero in some cases)
159 *
160 * Revision 6.57 2001/08/29 19:04:48 madden
161 * added parameter posComputationCalled to outputPosComputation, extra printing added in revision 6.54 is suppressed if posComputationCalled is FALSE
162 *
163 * Revision 6.56 2001/08/06 18:09:13 madden
164 * Corrected handling of X in posCancel by adding usage of Xcount
165 *
166 * Revision 6.55 2001/04/09 13:00:09 madden
167 * Fixed error in posComputeExtents; adjustment of interval sizes when the query contained an X had been asymmetric.
168 *
169 * Revision 6.54 2001/04/03 19:38:24 madden
170 * Changed IDENTITY_PERCENTAGE to 0.94, Added to output of -Q option in outputPosMatrix
171 *
172 * Revision 6.53 2001/02/16 16:11:50 dondosha
173 * In WposComputation, compute posMatrix from posFreqs if seqalign argument is NULL
174 *
175 * Revision 6.52 2001/01/03 01:49:38 bauer
176 * Changed from static to "LIBCALL":
177 * posAllocateMemory
178 * posPurgeMatches
179 * posCancel
180 * posComputeExtents
181 * posComputeSequenceWeights
182 * posCheckWeights
183 * posComputePseudoFreqs
184 * posScaling
185 *
186 * Revision 6.51 2000/11/24 22:07:51 shavirin
187 * Fixed some memory leaks.
188 *
189 * Revision 6.50 2000/11/20 14:35:51 madden
190 * Changed FileOpen mode for byte-encoded checkpoint files from "r" to "rb" or from "w" to "wb" to solve a problem on Windows NT.
191 *
192 * Revision 6.49 2000/11/13 14:00:39 madden
193 * Added frequency ratios for * in all standard matrices
194 *
195 * Revision 6.48 2000/11/09 14:27:52 madden
196 * psi-blast fixes for star character
197 *
198 * Revision 6.47 2000/11/01 16:25:57 madden
199 * Changes from Futamura for psitblastn
200 *
201 * Revision 6.46 2000/10/24 16:28:29 madden
202 * Changed IDENTITY_RATIO for putging near-identical matches from 0.98 to 0.95
203 *
204 * Revision 6.45 2000/10/10 21:46:04 shavirin
205 * Added support for BLOSUM50, BLOSUM90, PAM250 with -t T
206 *
207 * Revision 6.44 2000/08/18 21:28:37 madden
208 * support for BLOSUM62_20A and BLOSUM62_20B
209 *
210 * Revision 6.43 2000/07/31 16:41:01 shavirin
211 * Reduced POSIT_SCALE_FACTOR from 1000 to 200 to avoid overflow
212 * with BLOSUM80; moved declaration os POSIT_SCALE_FACTOR to posit.h
213 *
214 * Revision 6.42 2000/07/26 13:11:19 shavirin
215 * Added magical "LIBCALL" to pacify Windows build function allocatePosFreqs()
216 *
217 * Revision 6.41 2000/07/25 18:12:04 shavirin
218 * WARNING: This is no-turning-back changed related to S&W Blast from
219 * Alejandro Schaffer
220 *
221 * Revision 6.40 2000/05/01 12:48:33 madden
222 * changed rules for gaps in processing alignments with -B
223 *
224 * Revision 6.39 2000/03/02 21:47:07 shavirin
225 * Added missing variable for POSIT_DEBUG case
226 *
227 * Revision 6.38 1999/12/16 19:18:00 egorov
228 * Code cleanup
229 *
230 * Revision 6.37 1999/11/16 21:33:46 shavirin
231 * Fixed bug involved posSearch->posResultSequences structure.
232 *
233 * Revision 6.36 1999/11/16 17:30:41 shavirin
234 * Added copying use_best_align parameter in copySearchItems.
235 *
236 * Revision 6.35 1999/11/15 22:21:09 shavirin
237 * Removed nested comments in log space.
238 *
239 * Revision 6.34 1999/11/15 21:48:31 shavirin
240 * Added possibility to take into account best alignments of all
241 * alignments (even with e-thresh value larger than threshhold)
242 *
243 * Revision 6.33 1999/10/21 16:15:04 shavirin
244 * Removed unused array and all references to array threshSequences
245 *
246 * Revision 6.32 1999/09/30 14:15:29 shavirin
247 * Fixed bug in the function findThreshSequences().
248 *
249 * Revision 6.31 1999/09/23 20:58:37 shavirin
250 * Fixed some memory leaks.
251 *
252 * Revision 6.27 1999/09/03 17:24:38 madden
253 * Eliminated use of posMaxThresh field in posSearchItems. Recoded findThreshSequences completely and changed CposComputation so as not to use search->result_struct and thereby eliminate the hidden assumption that search->result_struct and listOfSeqAligns have the matches listed in the same order
254 *
255 * Revision 6.26 1999/08/04 13:27:10 madden
256 * Added -B option
257 *
258 * Revision 6.25 1999/04/05 14:45:40 madden
259 * Fixed format mismatches
260 *
261 * Revision 6.24 1999/03/21 19:41:51 madden
262 * Added 3rd argument matrixfp to outputPosMatrix, Took some of the code in outputPosMatrix outside the #ifdef POSIT_DEBUG for use with -Q option
263 *
264 * Revision 6.23 1999/01/26 18:27:58 madden
265 * Made functions public for AS
266 *
267 * Revision 6.22 1998/12/09 18:51:51 madden
268 * fixed counting bug in posCancel
269 *
270 * Revision 6.21 1998/09/28 12:31:31 madden
271 * Used BlastConstructErrorMessage
272 *
273 * Revision 6.20 1998/09/09 21:18:33 madden
274 * AS fixed warnings
275 *
276 * Revision 6.19 1998/09/09 16:09:20 madden
277 * Changes for PHI-BLAST
278 *
279 * Revision 6.18 1998/08/26 18:07:00 kans
280 * fixed -v -fd warnings (AS)
281 *
282 * Revision 6.17 1998/06/18 18:20:22 madden
283 * Fixed typo in posConvergenceTest
284 *
285 * Revision 6.16 1998/06/14 19:43:02 madden
286 * Added function posFreqsToInformation
287 *
288 * Revision 6.15 1998/06/12 20:38:48 madden
289 * Fix for no hits to build model situation
290 *
291 * Revision 6.14 1998/06/09 19:38:16 madden
292 * Changes rounddown to posit_rounddown to avoid conflict
293 *
294 * Revision 6.13 1998/04/24 19:29:30 madden
295 * Moved rescaling code to blastool.c
296 *
297 * Revision 6.12 1998/03/25 22:36:17 egorov
298 * Change type of posRepeatSequences
299 *
300 * Revision 6.11 1998/03/23 18:32:30 madden
301 * Fix for zero/zero problem
302 *
303 * Revision 6.10 1998/02/06 18:34:17 madden
304 * Added check that residue was not masked in posReadCheckpoint
305 *
306 * Revision 6.9 1998/02/03 15:57:28 madden
307 * Cpos arg in posComputePseudoFreqs set to FALSE for WposComputation call
308 *
309 * Revision 6.8 1998/01/02 22:19:46 madden
310 * Replaced printf by ErrPostEx of SEV_WARNING
311 *
312 * Revision 6.7 1997/12/23 21:07:06 madden
313 * Changes for checkpointing
314 *
315 * Revision 6.6 1997/12/12 22:14:35 kans
316 * changed round to rounddown to avoid CodeWarrior 68K collision
317 *
318 * Revision 6.5 1997/11/19 15:29:31 madden
319 * Changed OS_UNIX ifdef to POSIT_DEBUG
320 *
321 * Revision 6.4 1997/09/08 13:33:29 madden
322 * Added posEpsilon2 to check for small numbers
323 *
324 * Revision 6.3 1997/09/05 22:29:13 madden
325 * Check for zero denominator and replace log(2) by NCBIMATH_LN2
326 *
327 * Revision 6.2 1997/09/02 22:23:01 madden
328 * Removed redundant calls to updateLambdaK
329 *
330 * Revision 6.1 1997/08/27 21:18:18 madden
331 * Fixed problem with deleted matrix
332 *
333 * Revision 6.0 1997/08/25 18:53:48 madden
334 * Revision changed to 6.0
335 *
336 * Revision 1.22 1997/08/20 21:35:01 madden
337 * ALL_ROUNDS replaced by Boolean
338 *
339 * Revision 1.21 1997/08/11 15:45:24 madden
340 * eliminated obsolete fields
341 *
342 * Revision 1.20 1997/07/28 18:35:06 madden
343 * Removed and ifdefed printf
344 *
345 * Revision 1.19 1997/06/27 19:14:01 madden
346 * Fixed two bugs in posComputeSequenceWeights for the special case where all participating sequences are identical in a block
347 *
348 * Revision 1.17 1997/06/23 14:42:46 madden
349 * Made posComputeSequenceWeights faster by catching the special case where the set of participating sequences does not change from one column to the next.
350 *
351 * Revision 1.16 1997/05/29 20:35:47 madden
352 * Eliminate duplicate sequences and alignments that are 98 perc. identical and ignore columns with all identical sequence weights.
353 *
354 * Revision 1.15 1997/05/27 20:26:09 madden
355 * Fixed problem with matrix
356 *
357 * Revision 1.14 1997/05/23 20:52:50 madden
358 * Fixed bug in setting of matrix for psi-blast
359 *
360 * Revision 1.13 1997/05/22 21:25:28 madden
361 * fixed memory leaks
362 *
363 * Revision 1.12 1997/05/16 20:56:35 madden
364 * replace hard coded numbers by defines
365 *
366 * Revision 1.11 1997/05/16 20:09:42 madden
367 * Fixes for statistical problems
368 *
369 * Revision 1.10 1997/05/07 21:00:03 madden
370 * Call to SeqId2OrdinalId replaces call to readdb_gi2seq
371 *
372 * Revision 1.9 1997/05/01 15:53:25 madden
373 * Addition of extra KarlinBlk's for psi-blast
374 *
375 * Revision 1.8 1997/04/23 13:31:20 madden
376 * Changed diagnostic output.
377 *
378 * Revision 1.7 1997/04/22 16:36:49 madden
379 * Changes for use of psi-blast with www.
380 *
381 * Revision 1.6 1997/04/10 19:25:53 madden
382 * Added casts, COMMAND_LINE replaced by ALL_ROUNDS.
383 *
384 * Revision 1.5 1997/04/09 20:01:53 madden
385 * Functions CposComputation and WposComputation replace posComputations.
386 *
387 * Revision 1.4 1997/04/04 20:44:55 madden
388 * Changed posComputation to return Int4Ptr *.
389 *
390 * Revision 1.3 1997/03/27 22:30:51 madden
391 * Fix for Array Bounds Read.
392 *
393 * Revision 1.2 1997/03/11 14:38:40 madden
394 * Fixes for GI's instead of ordinal numbers.
395 *
396 * Revision 1.1 1997/02/13 15:22:13 madden
397 * Initial revision
398 *
399 */
400
401
402 #include <ncbi.h>
403 #include <blastpri.h>
404 #include <objcode.h>
405 #include <objseq.h>
406 #include <objsset.h>
407 #include <objscoremat.h>
408 #include <sequtil.h>
409 #include <posit.h>
410 #include <txalign.h>
411 #include <blastkar.h>
412
413 #include <algo/blast/composition_adjustment/nlm_linear_algebra.h>
414 #include <algo/blast/composition_adjustment/matrix_frequency_data.h>
415 #include <algo/blast/composition_adjustment/composition_adjustment.h>
416 #include <algo/blast/composition_adjustment/compo_heap.h>
417 #include <algo/blast/composition_adjustment/smith_waterman.h>
418 #include <algo/blast/composition_adjustment/redo_alignment.h>
419 #include <algo/blast/composition_adjustment/unified_pvalues.h>
420
421 /*small constants to test against 0*/
422 #define posEpsilon 0.0001
423 #define posEpsilon2 0.0000001
424 /*Representation of a gap in a motif*/
425 #define GAP_CHAR 0
426 /*Used inside a seqAlign to reprsent the presence of a gap*/
427 #define GAP_HERE (-1)
428 /*Used to check that diagnostics printing routine will work*/
429 #define EFFECTIVE_ALPHABET 20
430
431 #define POSIT_PERCENT 0.05
432 #define POSIT_NUM_ITERATIONS 10
433
434
435 #define POS_RESTING 0
436 #define POS_COUNTING 1
437
438 #define IDENTITY_RATIO 0.94
439
440
441 /*Allocate memory for data structures inside posSearch used in
442 * position-specific caculations
443 * posSearch -- to be filled in
444 * alphabetSize -- number of distinct characters used in the sequences
445 * querySize -- number of characters in the query sequence
446 * numSequences -- number of matching sequences potentially in the model */
posAllocateMemory(posSearchItems * posSearch,Int4 alphabetSize,Int4 querySize,Int4 numSequences)447 void LIBCALL posAllocateMemory(posSearchItems * posSearch,
448 Int4 alphabetSize, Int4 querySize, Int4 numSequences)
449 {
450 Int4 i, j; /*loop indices*/
451
452 posSearch->posCount = (Int4 *) MemNew(querySize * sizeof(Int4));
453 if (NULL == posSearch->posCount)
454 exit(EXIT_FAILURE);
455 for(i = 0; i < querySize; i++)
456 posSearch->posCount[i] = 0;
457
458 posSearch->posC = (Int4 **) MemNew((querySize + 1) * sizeof(Int4 *));
459 if (NULL == posSearch->posC)
460 exit(EXIT_FAILURE);
461 for(i = 0; i <= querySize; i++) {
462 posSearch->posC[i] = (Int4 *) MemNew(alphabetSize * sizeof(Int4));
463 if (NULL == posSearch->posC[i])
464 exit(EXIT_FAILURE);
465 for(j = 0; j < alphabetSize; j++)
466 posSearch->posC[i][j] = 0;
467
468 }
469 posSearch->posDistinctDistrib = (Int4 **) MemNew((querySize + 1) * sizeof(Int4* ));
470 for (i = 0; i <=querySize; i++) {
471 posSearch->posDistinctDistrib[i] = (Int4 *) MemNew((EFFECTIVE_ALPHABET + 1) * sizeof(Int4));
472 for(j = 0; j <=EFFECTIVE_ALPHABET; j++)
473 posSearch->posDistinctDistrib[i][j] = 0;
474 }
475 posSearch->posNumParticipating = (Int4 *) MemNew((querySize + 1) * sizeof(Int4 ));
476 posSearch->posGaplessColumnWeights = (Nlm_FloatHi *) MemNew((querySize + 1) * sizeof(Nlm_FloatHi));
477 if (NULL == posSearch->posGaplessColumnWeights)
478 exit(EXIT_FAILURE);
479 posSearch->pseudoWeights = (Nlm_FloatHi *) MemNew((querySize + 1) * sizeof(Nlm_FloatHi));
480 if (NULL == posSearch->pseudoWeights)
481 exit(EXIT_FAILURE);
482 posSearch->posMatchWeights = (Nlm_FloatHi **) MemNew((querySize+1) * sizeof(Nlm_FloatHi *));
483 if (NULL == posSearch->posMatchWeights)
484 exit(EXIT_FAILURE);
485 for (i = 0; i <= querySize ; i++) {
486 posSearch->posMatchWeights[i] = (Nlm_FloatHi *) MemNew(alphabetSize * sizeof(Nlm_FloatHi));
487 if (NULL == posSearch->posMatchWeights[i])
488 exit(EXIT_FAILURE);
489 for(j = 0; j < alphabetSize; j++)
490 posSearch->posMatchWeights[i][j] = 0.0;
491 }
492
493 posSearch->posMatrix = (BLAST_Score **) MemNew((querySize + 1) * sizeof(BLAST_Score *));
494 posSearch->posPrivateMatrix = (BLAST_Score **) MemNew((querySize + 1) * sizeof(BLAST_Score *));
495 if (NULL == posSearch->posMatrix)
496 exit(EXIT_FAILURE);
497 for(i = 0; i <= querySize; i++) {
498 posSearch->posMatrix[i] = (BLAST_Score *) MemNew(alphabetSize * sizeof(BLAST_Score));
499 posSearch->posPrivateMatrix[i] = (BLAST_Score *) MemNew(alphabetSize * sizeof(BLAST_Score));
500 if (NULL == posSearch->posMatrix[i])
501 exit(EXIT_FAILURE);
502 for(j = 0; j < alphabetSize; j++)
503 posSearch->posMatrix[i][j] = 0;
504
505 }
506
507 posSearch->posSigma = (Nlm_FloatHi *) MemNew((querySize) * sizeof(Nlm_FloatHi));
508 if (NULL == posSearch->posSigma)
509 exit(EXIT_FAILURE);
510 for(i = 0; i < querySize; i++) {
511 posSearch->posSigma[i] = 0.0;
512 }
513
514 posSearch->posIntervalSizes = (Int4 *) MemNew((querySize) * sizeof(Int4));
515 if (NULL == posSearch->posIntervalSizes)
516 exit(EXIT_FAILURE);
517 for(i=0; i < querySize; i++)
518 posSearch->posIntervalSizes[i] = 0;
519
520 posSearch->posDescMatrixLength = numSequences;
521 posSearch->posDescMatrix = (posDesc **) MemNew((numSequences + 1) * sizeof(posDesc *));
522 if (NULL == posSearch->posDescMatrix)
523 exit(EXIT_FAILURE);
524 for (i = 0; i <= numSequences; i++) {
525 posSearch->posDescMatrix[i] = (posDesc *) MemNew(querySize * sizeof(posDesc));
526 if (NULL == posSearch->posDescMatrix[i])
527 exit(EXIT_FAILURE);
528 for(j = 0; j < querySize; j++) {
529 posSearch->posDescMatrix[i][j].letter = UNUSED;
530 posSearch->posDescMatrix[i][j].used = FALSE;
531 posSearch->posDescMatrix[i][j].e_value = 1.0;
532 posSearch->posDescMatrix[i][j].leftExtent = -1;
533 posSearch->posDescMatrix[i][j].rightExtent = querySize;
534 }
535 }
536 posSearch->posExtents = (posDesc *) MemNew(querySize * sizeof(posDesc));
537 if (NULL == posSearch->posExtents)
538 exit(EXIT_FAILURE);
539 for(j = 0; j < querySize; j++) {
540 posSearch->posExtents[j].used = FALSE;
541 posSearch->posExtents[j].leftExtent = -1;
542 posSearch->posExtents[j].rightExtent = querySize;
543 }
544 posSearch->posA = (Nlm_FloatHi *) MemNew((numSequences+ 1) * sizeof(Nlm_FloatHi));
545 if (NULL == posSearch->posA)
546 exit(EXIT_FAILURE);
547 posSearch->posRowSigma = (Nlm_FloatHi *) MemNew((numSequences + 1) * sizeof(Nlm_FloatHi));
548 if (NULL == posSearch->posRowSigma)
549 exit(EXIT_FAILURE);
550
551 /* populated in posComputePseudoFreqs or on demand */
552 posSearch->stdFreqRatios = NULL;
553 }
554
freePosFreqs(Nlm_FloatHi ** posFreqs,Int4 length)555 static void freePosFreqs(Nlm_FloatHi ** posFreqs, Int4 length)
556 {
557 Int4 i;
558
559 for (i = 0; i <= length; i++)
560 MemFree(posFreqs[i]);
561 MemFree(posFreqs);
562 }
563
564 /*Deallocate memory allocated in posReadCheckpoint
565 * posSearch -- pointer to record used in building the position-specific model
566 * querySize -- number of characters in the query sequence
567 */
posCheckpointFreeMemory(posSearchItems * posSearch,Int4 querySize)568 void LIBCALL posCheckpointFreeMemory(posSearchItems *posSearch, Int4 querySize)
569 {
570 Int4 i; /*loop index*/
571
572 freePosFreqs(posSearch->posFreqs, querySize);
573 for(i = 0; i <= querySize; i++){
574 MemFree(posSearch->posMatrix[i]);
575 MemFree(posSearch->posPrivateMatrix[i]);
576 }
577 MemFree(posSearch->posMatrix);
578 MemFree(posSearch->posPrivateMatrix);
579 }
580
581 /*Deallocate memory allocated in posAllocateMemory
582 * posSearch -- pointer to record used in building the position-specific model
583 * querySize -- number of characters in the query sequence
584 */
posFreeMemory(posSearchItems * posSearch,Int4 querySize)585 static void posFreeMemory(posSearchItems *posSearch, Int4 querySize)
586 {
587 Int4 i; /*loop index*/
588
589 MemFree(posSearch->posCount);
590 MemFree(posSearch->posExtents);
591 MemFree(posSearch->posSigma);
592
593 for(i = 0; i <= querySize; i++){
594 MemFree(posSearch->posC[i]);
595 MemFree(posSearch->posMatrix[i]);
596 MemFree(posSearch->posPrivateMatrix[i]);
597 MemFree(posSearch->posMatchWeights[i]);
598 MemFree(posSearch->posDistinctDistrib[i]);
599 }
600
601 MemFree(posSearch->posC);
602 MemFree(posSearch->posDistinctDistrib);
603 MemFree(posSearch->posNumParticipating);
604
605 for(i = 0; i <= posSearch->posDescMatrixLength; i++)
606 MemFree(posSearch->posDescMatrix[i]);
607
608 MemFree(posSearch->posMatrix);
609 MemFree(posSearch->posPrivateMatrix);
610 MemFree(posSearch->posDescMatrix);
611 MemFree(posSearch->posGaplessColumnWeights);
612 MemFree(posSearch->pseudoWeights);
613 MemFree(posSearch->posMatchWeights);
614 MemFree(posSearch->posA);
615 MemFree(posSearch->posRowSigma);
616 MemFree(posSearch->posIntervalSizes);
617 MemFree(posSearch->posUseSequences);
618 posSearch->stdFreqRatios = PSIMatrixFrequencyRatiosFree(posSearch->stdFreqRatios);
619 freePosFreqs(posSearch->posFreqs,querySize);
620 }
621
622 /*Cleanup position-specific data structures after one pass*/
posCleanup(posSearchItems * posSearch,compactSearchItems * compactSearch)623 void LIBCALL posCleanup(posSearchItems *posSearch, compactSearchItems * compactSearch)
624 {
625 posFreeMemory(posSearch, compactSearch->qlength);
626 }
627
628
629 /*extract the e-value that applies to an entire dense
630 diagonal alignment from its ScorePtr, based on similar
631 code from Tom Madden*/
632
getEvalueFromSeqAlign(SeqAlignPtr thisSeqAlign)633 static Nlm_FloatHi getEvalueFromSeqAlign(SeqAlignPtr thisSeqAlign)
634 {
635 ScorePtr thisScorePtr;
636
637 thisScorePtr = thisSeqAlign->score;
638 while ((thisScorePtr != NULL) &&
639 (StringICmp(thisScorePtr->id->str, "e_value") != 0) &&
640 (StringICmp(thisScorePtr->id->str, "sum_e") != 0))
641 thisScorePtr = thisScorePtr->next;
642 if(NULL == thisScorePtr)
643 return(10.0);
644 else
645 return((Nlm_FloatHi) (thisScorePtr->value.realvalue));
646 }
647
648 /*Find the lowest e-value among all seqAligns for the sequence represented by
649 curSeqAlign*/
minEvalueForSequence(SeqAlignPtr curSeqAlign,SeqAlignPtr listOfSeqAligns)650 static Nlm_FloatHi minEvalueForSequence(SeqAlignPtr curSeqAlign, SeqAlignPtr listOfSeqAligns)
651 {
652 SeqAlignPtr testSeqAlign; /*Index into listOfSeqALigns*/
653 DenseSegPtr curSegs, testSegs; /*Used to extract ids from curSeqAlign, testSeqAlign*/
654 SeqIdPtr curId, testId; /*Ids of target sequences in testSeqAlign*/
655 Nlm_FloatHi returnValue; /*stores current best e-value*/
656 Nlm_FloatHi testEvalue; /*temporary e-value for one seqAlign*/
657 Boolean seen; /*have we seen a seqAlign matching the sequence yet*/
658
659 returnValue = getEvalueFromSeqAlign(curSeqAlign);
660 curSegs = (DenseSegPtr) curSeqAlign->segs;
661 curId = curSegs->ids->next;
662 seen = FALSE;
663
664 testSeqAlign = listOfSeqAligns;
665 while (NULL != testSeqAlign) {
666 testSegs = (DenseSegPtr) testSeqAlign->segs;
667
668 if(testSegs->ids == NULL)
669 break;
670
671 testId = testSegs->ids->next;
672 if (SeqIdMatch(curId, testId)) {
673 seen = TRUE;
674 if ((testEvalue = getEvalueFromSeqAlign(testSeqAlign)) < returnValue)
675 returnValue = testEvalue;
676 }
677 else
678 /*if we have already seen a match and this one doesn't match,
679 then stop looking*/
680 if (seen)
681 break;
682 testSeqAlign = testSeqAlign->next;
683 }
684 return(returnValue);
685 }
686
687
688 /*Count the number of seqAligns in a list (returned) and count the number of
689 distinct target sequences represented (passed back in numSequences);
690 if useThreshold is TRUE, only those sequences with e-values below the threshold are counted.
691 Important assumption: All SeqAligns with the same target sequence
692 are consecutive in the list*/
countSeqAligns(SeqAlignPtr listOfSeqAligns,Int4 * numSequences,Boolean useThreshold,Nlm_FloatHi threshold)693 static Int4 countSeqAligns(SeqAlignPtr listOfSeqAligns, Int4 * numSequences, Boolean useThreshold, Nlm_FloatHi threshold)
694 {
695 SeqAlignPtr curSeqAlign, prevSeqAlign;
696 Int4 seqAlignCounter;
697 DenseSegPtr curSegs;
698 SeqIdPtr curId, prevId; /*Ids of target sequences in current and previous
699 SeqAlign*/
700
701 seqAlignCounter = 0;
702 *numSequences = 0;
703 curSeqAlign = listOfSeqAligns;
704 prevSeqAlign = NULL;
705 while (NULL != curSeqAlign) {
706 curSegs = (DenseSegPtr) curSeqAlign->segs;
707 if(curSegs->ids == NULL)
708 break;
709 curId = curSegs->ids->next;
710 seqAlignCounter++;
711 if ((NULL == prevSeqAlign) || (!(SeqIdMatch(curId, prevId))))
712 if (!useThreshold || (threshold > minEvalueForSequence(curSeqAlign, listOfSeqAligns)))
713 (*numSequences)++;
714 prevSeqAlign = curSeqAlign;
715 prevId = curId;
716 curSeqAlign = curSeqAlign->next;
717 }
718 return(seqAlignCounter);
719 }
720
721 /*Find which sequences that match in the i-th pass have an e-value below
722 the specified threshold. These sequences will be used to make the
723 score matrix for the next pass*/
findThreshSequences(posSearchItems * posSearch,BlastSearchBlkPtr search,SeqAlignPtr listOfSeqAligns,Int4 numalign,Int4 numseq)724 static void findThreshSequences(posSearchItems *posSearch, BlastSearchBlkPtr search, SeqAlignPtr listOfSeqAligns, Int4 numalign, Int4 numseq)
725 {
726
727 Int4 alignIndex; /* indices for sequences and alignments*/
728 SeqAlignPtr curSeqAlign, prevSeqAlign; /* pointers into list of seqAligns*/
729 DenseSegPtr curSegs; /*Item in list of seqAligns*/
730 SeqIdPtr thisId, prevId; /*Ids of target sequences in current and previous
731 SeqAlign*/
732 Nlm_FloatHi thisEvalue; /*Best E-value for current sequence*/
733 Int4 ordinalNumber; /*index of sequence within database*/
734
735 /*Allocate boolean array to store values*/
736 posSearch->posResultSequences = (Int4 *) MemNew(numseq * sizeof(Int4));
737 posSearch->posResultsCounter = 0;
738
739 curSeqAlign = listOfSeqAligns;
740 prevSeqAlign = NULL;
741 for(alignIndex = 0; alignIndex < numalign; alignIndex++) {
742 curSegs = (DenseSegPtr) curSeqAlign->segs;
743 thisId = curSegs->ids->next;
744 if ((NULL == prevSeqAlign) || (!(SeqIdMatch(thisId, prevId)))) {
745 thisEvalue = minEvalueForSequence(curSeqAlign, curSeqAlign);
746 thisId = curSegs->ids->next; /*id of target sequence is second*/
747 /*Get ordinal ids of sequences in result*/
748 ordinalNumber = SeqId2OrdinalId(search->rdfp, thisId);
749 if(thisEvalue < (search->pbp->ethresh)) {
750 posSearch->posResultSequences[posSearch->posResultsCounter] =
751 ordinalNumber;
752 posSearch->posResultsCounter++;
753 }
754 }
755 prevSeqAlign = curSeqAlign;
756 prevId = thisId;
757 curSeqAlign = curSeqAlign->next;
758 }
759 }
760
761
762
763 /* Determines if the search has converged from round to round.
764 * Checks whether every new sequence found is in posSearch->posResultSequences.
765 * Also sets up posSearch->posRepeatSequences, a boolean array that
766 * indicates whether the sequence represented by the i-th new seqAlign is a repeat.
767 * This is used in printing the sequences where they are
768 * subdivided into two categories: sequences that were found previously
769 * and new sequences.
770 * posSearch is the data structure representing the parameters of the position-specific part
771 * search represents the overall BLAST search
772 * listOfSeqAligns is one representation of the results of the current round.
773 * If thissPassNum is 1, then it checks only to see that some sequence
774 * distinct from the query was found */
posConvergenceTest(posSearchItems * posSearch,BlastSearchBlkPtr search,SeqAlignPtr listOfSeqAligns,Int4 thisPassNum)775 void LIBCALL posConvergenceTest(posSearchItems *posSearch, BlastSearchBlkPtr search, SeqAlignPtr listOfSeqAligns, Int4 thisPassNum)
776 {
777 Int4 numseq; /*Number of sequences found*/
778 Int4 numalign; /* Number of items in listOfSeqAligns*/
779 Int4 oldSeqIndex; /*Ordinal number of a sequence in old results (previous round)*/
780 Int4 alignIndex; /*index into the list of seqAligns*/
781 Boolean found; /*Have we found the new sequence on the old list?*/
782 SeqAlignPtr curSeqAlign, prevSeqAlign, startAlign; /* pointers into list of seqAligns*/
783 DenseSegPtr curSegs; /*Item in list of seqAligns*/
784 SeqIdPtr thisId, prevId; /*Ids of target sequences in current and previous
785 SeqAlign*/
786 Int4 ordinalNumber; /*Ordinal number of a sequence in the database*/
787 Nlm_FloatHi thisEvalue; /*lowest evalue from all seqAligns for a sequence*/
788 Int4 queryOffset, subjectOffset, retrievalOffset; /*offsets needed
789 to make a match align*/
790 Int4 qplace, splace; /*index into query string and matching string*/
791 Uint1Ptr q,s; /*Pointers into query and matching string*/
792 Int4 queryLength; /*length of query*/
793 Int4 matchLength; /* length of match*/
794 Int4 subjectLength; /* length of a matching string*/
795 Int4 c; /*index into a string*/
796 Int4 numsegs; /*number of segments in an alignment*/
797 Int4 startQ,startS; /*Indices into array of starting positions*/
798
799
800 numalign = countSeqAligns(listOfSeqAligns, &numseq, FALSE, 0.0);
801 search->posConverged = TRUE;
802 curSeqAlign = listOfSeqAligns;
803 if (thisPassNum > 1) {
804 posSearch->posRepeatSequences = (Int2Ptr) MemNew(numalign * sizeof(Int2));
805 prevSeqAlign = NULL;
806 for(alignIndex = 0; alignIndex < numalign; alignIndex++) {
807 posSearch->posRepeatSequences[alignIndex] = (Int2) 0;
808 curSegs = (DenseSegPtr) curSeqAlign->segs;
809 thisId = curSegs->ids->next;
810 if ((NULL == prevSeqAlign) || (!(SeqIdMatch(thisId, prevId)))) {
811 startAlign = curSeqAlign;
812 thisEvalue = minEvalueForSequence(curSeqAlign, startAlign);
813 if (thisEvalue < search->pbp->ethresh) {
814 /*Extract the ordinal number from the SeqAlign*/
815 curSegs = (DenseSegPtr) curSeqAlign->segs;
816 thisId = curSegs->ids->next; /*id of target sequence is second*/
817 /*Get ordinal ids of sequences in result*/
818 ordinalNumber = SeqId2OrdinalId(search->rdfp, thisId);
819 found = FALSE;
820 for(oldSeqIndex = 0; oldSeqIndex < posSearch->posResultsCounter; oldSeqIndex++)
821 if(ordinalNumber == posSearch->posResultSequences[oldSeqIndex]) {
822 posSearch->posRepeatSequences[alignIndex] = SEQ_ALIGN_MARK_REPEAT;
823 found = TRUE;
824 break;
825 }
826 if (!found)
827 search->posConverged = FALSE;
828 }
829 }
830 else /*both alignments come from the same sequence*/
831 posSearch->posRepeatSequences[alignIndex] = posSearch->posRepeatSequences[alignIndex - 1];
832 prevSeqAlign = curSeqAlign;
833 prevId = thisId;
834 curSeqAlign = curSeqAlign->next;
835 }
836 MemFree(posSearch->posResultSequences);
837 }
838 else {
839 q = search->context[0].query->sequence;
840 queryLength = search->context[0].query->length;
841 prevSeqAlign = NULL;
842 while (curSeqAlign != NULL) {
843 curSegs = (DenseSegPtr) curSeqAlign->segs;
844 s = GetSequenceWithDenseSeg(curSegs, FALSE, &retrievalOffset, &subjectLength);
845 numsegs = curSegs->numseg;
846 thisId = curSegs->ids->next;
847 if ((NULL == prevSeqAlign) || (!(SeqIdMatch(thisId, prevId)))) {
848 startAlign = curSeqAlign;
849 thisEvalue = minEvalueForSequence(curSeqAlign, startAlign);
850 if (thisEvalue < search->pbp->ethresh) {
851 if (numsegs > 1) {
852 search->posConverged = FALSE;
853 return;
854 }
855 startQ = 0;
856 startS = 1;
857 queryOffset = curSegs->starts[startQ];
858 if (curSegs->starts[startS] != GAP_HERE)
859 subjectOffset = curSegs->starts[startS] - retrievalOffset;
860 else
861 subjectOffset = GAP_HERE;
862 matchLength = curSegs->lens[0];
863 if ((queryOffset != 0) || (subjectOffset != 0) ||
864 (matchLength != queryLength) || (matchLength != subjectLength)) {
865 search->posConverged = FALSE;
866 return;
867 }
868 for (c = 0, qplace = queryOffset, splace = subjectOffset;
869 c < matchLength; c++, qplace++, splace++)
870 if (s[splace] != q[qplace]) {
871 search->posConverged = FALSE;
872 return;
873 }
874 }
875 }
876 prevSeqAlign = curSeqAlign;
877 prevId = thisId;
878 curSeqAlign = curSeqAlign->next;
879 }
880 }
881 }
882
883
884 /*Eliminate the matches from sequence second starting at position
885 matchStart and extending for intervalLength characters */
posCancel(posSearchItems * posSearch,compactSearchItems * compactSearch,Int4 first,Int4 second,Int4 matchStart,Int4 intervalLength)886 void LIBCALL posCancel(posSearchItems *posSearch, compactSearchItems * compactSearch, Int4 first, Int4 second, Int4 matchStart, Int4 intervalLength)
887 {
888 Int4 c, i;
889 Boolean stillNeeded;
890
891 for(c = matchStart, i = 0; i < intervalLength; i++, c++) {
892 posSearch->posDescMatrix[second][c].used = FALSE;
893 posSearch->posDescMatrix[second][c].letter = 0;
894 }
895 stillNeeded = FALSE;
896 for (c = 0; c < compactSearch->qlength; c++)
897 if (posSearch->posDescMatrix[second][c].used) {
898 stillNeeded = TRUE;
899 break;
900 }
901 if (!stillNeeded)
902 posSearch->posUseSequences[second] = FALSE;
903 }
904
905 /*Eliminate sequences that are identical to the query and partial alignments
906 that are identical in two matching sequences
907 Modified by Natsuhiko Futamura to change order in which
908 pairs of sequences are compared*/
posPurgeMatches(posSearchItems * posSearch,compactSearchItems * compactSearch,ValNodePtr * error_return)909 void LIBCALL posPurgeMatches(posSearchItems *posSearch, compactSearchItems * compactSearch, ValNodePtr * error_return)
910 {
911 Int4 i, j; /*index over sequences*/
912 Int4 k; /*difference between pair of sequence indices*/
913 Boolean matchesQuery; /*Is a matching sequence identical to the query?*/
914 Int4 c; /*index over demographics of matching sequence*/
915 Int4 state; /*state of checking for a match*/
916 Int4 intervalLength, matchStart; /*Length and start of a matching region*/
917 Int4 matchNumber; /*number of characters matching*/
918 Int4 Xcount; /*number of X's in interval*/
919 Int4 numSequencesInUse; /*number of sequences left in use*/
920
921 posSearch->posUseSequences = (Boolean *) MemNew((posSearch->posNumSequences + 1) * sizeof(Boolean));
922 if (NULL == posSearch->posUseSequences)
923 exit(EXIT_FAILURE);
924 for(i = 0; i <= posSearch->posNumSequences; i++)
925 posSearch->posUseSequences[i] = TRUE;
926 for(i = 1; i <= posSearch->posNumSequences; i++) {
927 matchesQuery = TRUE;
928 for (c = 0; c < compactSearch->qlength; c++) {
929 if ((!posSearch->posDescMatrix[i][c].used) ||
930 (posSearch->posDescMatrix[i][c].letter !=
931 posSearch->posDescMatrix[0][c].letter)) {
932 matchesQuery = FALSE;
933 break;
934 }
935 }
936 if (matchesQuery) {
937 posSearch->posUseSequences[i] = FALSE;
938 }
939 }
940 for(j = 1; j <= posSearch->posNumSequences; j++) {
941 if (!posSearch->posUseSequences[j])
942 continue;
943 state = POS_COUNTING;
944 c = 0;
945 matchStart = 0;
946 intervalLength = 0;
947 Xcount = 0;
948 matchNumber = 0;
949 while (c < compactSearch->qlength) {
950 if (posSearch->posDescMatrix[j][c].used) {
951 if ((posSearch->posDescMatrix[0][c].letter != Xchar) &&
952 (posSearch->posDescMatrix[j][c].letter != Xchar)) {
953 if (state == POS_RESTING) {
954 matchStart = c;
955 intervalLength = 1;
956 state = POS_COUNTING;
957 matchNumber = 0;
958 }
959 else
960 intervalLength++;
961 if (posSearch->posDescMatrix[j][c].used &&
962 (posSearch->posDescMatrix[0][c].letter == posSearch->posDescMatrix[j][c].letter))
963 matchNumber++;
964 }
965 else {
966 if (POS_COUNTING == state)
967 Xcount++;
968 }
969 }
970 else {
971 if (state == POS_COUNTING) {
972 if ((intervalLength > 0) && (matchNumber == intervalLength))
973 posCancel(posSearch,compactSearch,0,j,matchStart,intervalLength+Xcount);
974 state = POS_RESTING;
975 Xcount = 0;
976 }
977 }
978 c++;
979 }
980 if (state == POS_COUNTING) /*at end of sequence i*/
981 if ((intervalLength > 0) && (matchNumber == intervalLength))
982 posCancel(posSearch,compactSearch,0,j,matchStart,intervalLength+Xcount);
983 }
984
985 for (k=1; k <= posSearch->posNumSequences -1; k++){
986 for (i = 1; (i+k) <= posSearch->posNumSequences; i++) {
987 if (!posSearch->posUseSequences[i])
988 continue;
989 j = i+k;
990 if (!posSearch->posUseSequences[j])
991 continue;
992
993 state = POS_COUNTING;
994 c = 0;
995 matchStart = 0;
996 intervalLength = 0;
997 Xcount = 0;
998 matchNumber = 0;
999 while (c < compactSearch->qlength) {
1000 if (posSearch->posDescMatrix[i][c].used ||
1001 posSearch->posDescMatrix[j][c].used) {
1002 if ((posSearch->posDescMatrix[i][c].letter != Xchar) &&
1003 (posSearch->posDescMatrix[j][c].letter != Xchar)) {
1004 if (state == POS_RESTING) {
1005 matchStart = c;
1006 intervalLength = 1;
1007 state = POS_COUNTING;
1008 matchNumber = 0;
1009 }
1010 else
1011 intervalLength++;
1012 if (posSearch->posDescMatrix[i][c].used &&
1013 posSearch->posDescMatrix[j][c].used &&
1014 (posSearch->posDescMatrix[i][c].letter == posSearch->posDescMatrix[j][c].letter))
1015 matchNumber++;
1016 }
1017 else {
1018 if (POS_COUNTING == state)
1019 Xcount++;
1020 }
1021 }
1022 else {
1023 if (state == POS_COUNTING) {
1024 if ((intervalLength > 0) && ((((Nlm_FloatHi) matchNumber)/intervalLength) >= IDENTITY_RATIO))
1025 posCancel(posSearch,compactSearch,i,j,matchStart,intervalLength+Xcount);
1026 state = POS_RESTING;
1027 Xcount = 0;
1028 }
1029 }
1030 c++;
1031 }
1032 if (state == POS_COUNTING) /*at end of sequence i*/
1033 if ((intervalLength > 0) && ((((Nlm_FloatHi) matchNumber)/intervalLength) >= IDENTITY_RATIO))
1034 posCancel(posSearch,compactSearch,i,j,matchStart,intervalLength+Xcount);
1035 }
1036 }
1037 if (error_return) {
1038 numSequencesInUse = 0;
1039 for(i = 0; i <= posSearch->posNumSequences; i++)
1040 if(posSearch->posUseSequences[i])
1041 numSequencesInUse++;
1042 if (numSequencesInUse < 2)
1043 BlastConstructErrorMessage("posPurgeMatches", "Due to purging near identical sequences, only the query is used to construct the position-specific score matrix\n", 1, error_return);
1044 }
1045 }
1046
countNumSeq(posSearchItems * posSearch,compactSearchItems * compactSearch,SeqAlignPtr listOfSeqAligns,Int4 * prevNumSeq)1047 static void countNumSeq(posSearchItems *posSearch,
1048 compactSearchItems * compactSearch,
1049 SeqAlignPtr listOfSeqAligns, Int4 *prevNumSeq)
1050 {
1051 Uint1Ptr s; /* pointer into a matching string */
1052 Int4 subjectLength; /* length of subject */
1053 Int4 retrievalOffset; /* retrieval offset */
1054 SeqAlignPtr curSeqAlign, prevSeqAlign; /* pointers into listOfSeqAligns */
1055 DenseSegPtr curSegs, prevSegs; /* used to extract alignments from curSeqAlign */
1056 SeqIdPtr curId, prevId; /* Used to compare sequences that come from different SeqAligns */
1057 Nlm_FloatHi thisEvalue; /* evalue of current partial alignment */
1058 Int4 newNumSeq; /* numseq computed in another way */
1059 Boolean is_new_id = FALSE;
1060
1061 newNumSeq = 0;
1062 /*use only those sequences below e-value threshold*/
1063 curSeqAlign = listOfSeqAligns;
1064 prevSeqAlign = NULL;
1065 for (curSeqAlign = listOfSeqAligns; curSeqAlign != NULL;
1066 curSeqAlign = curSeqAlign->next) {
1067 is_new_id = FALSE;
1068 thisEvalue = getEvalueFromSeqAlign(curSeqAlign);
1069 curSegs = (DenseSegPtr) curSeqAlign->segs;
1070 if (NULL != prevSeqAlign) {
1071 prevSegs = (DenseSegPtr) prevSeqAlign->segs;
1072 if(curSegs->ids == NULL)
1073 break;
1074 curId = curSegs->ids->next;
1075 prevId = prevSegs->ids->next;
1076
1077 if (!(SeqIdMatch(curId, prevId)))
1078 is_new_id = TRUE;
1079 }
1080 if (!(compactSearch->use_best_align && is_new_id)) {
1081 if (thisEvalue >= compactSearch->ethresh)
1082 continue;
1083 }
1084 if (is_new_id == TRUE)
1085 newNumSeq++;
1086 s = GetSequenceWithDenseSeg(curSegs, FALSE, &retrievalOffset, &subjectLength);
1087 SeqMgrFreeCache();
1088 if (s == NULL)
1089 continue;
1090 s = MemFree(s);
1091 prevSeqAlign = curSeqAlign;
1092 }
1093 newNumSeq++;
1094 /* numseq gets the highest number computed by both methods */
1095 if (newNumSeq > *prevNumSeq)
1096 *prevNumSeq = newNumSeq;
1097 }
1098
1099 /*Compute general information about the sequences that matched on the
1100 i-th pass such as how many matched at each query position and what letter
1101 matched*/
posDemographics(posSearchItems * posSearch,compactSearchItems * compactSearch,SeqAlignPtr listOfSeqAligns)1102 void LIBCALL posDemographics(posSearchItems *posSearch,
1103 compactSearchItems * compactSearch,
1104 SeqAlignPtr listOfSeqAligns)
1105 {
1106 Uint1Ptr q; /*pointers into query */
1107 Uint1Ptr s; /*pointer into a matching string */
1108 Int4 length, subjectLength; /*length of query and subject*/
1109 Int4 c; /*index into a string*/
1110 Int4 numseq, numSeqAligns; /*number of matching sequences and SeqAligns*/
1111 Int4 seqIndex; /*index for the array of matching sequences*/
1112 Int4 matchLength; /*length of a match*/
1113 Int4 queryOffset, subjectOffset, retrievalOffset; /*offsets needed to make a match align*/
1114 Int4 qplace, splace; /*index into query string and matching string*/
1115 SeqAlignPtr curSeqAlign, prevSeqAlign; /*pointers into listOfSeqAligns*/
1116 DenseSegPtr curSegs, prevSegs; /*used to extract alignments from curSeqAlign*/
1117 SeqIdPtr curId, prevId; /*Used to compare sequences that come from different SeqAligns*/
1118 Int4 startQ, startS; /*Indices into array of starting positions*/
1119 Int4 numsegs; /*Number of pieces in the gapped alignment*/
1120 Int4 segIndex; /*Index for which piece we are at*/
1121 Nlm_FloatHi thisEvalue; /*evalue of current partial alignment*/
1122 Boolean is_new_id = FALSE;
1123
1124 q = compactSearch->query;
1125 length = compactSearch->qlength;
1126 for(c = 0; c < length; c++) {
1127 posSearch->posDescMatrix[0][c].letter = (Int1) q[c];
1128 posSearch->posDescMatrix[0][c].used = TRUE;
1129 posSearch->posDescMatrix[0][c].leftExtent = 0;
1130 posSearch->posDescMatrix[0][c].rightExtent = length;
1131 posSearch->posDescMatrix[0][c].e_value = compactSearch->ethresh/2;
1132 posSearch->posC[c][q[c]]++;
1133 posSearch->posCount[c]++;
1134 }
1135
1136 numSeqAligns = countSeqAligns(listOfSeqAligns, &numseq,
1137 !compactSearch->use_best_align,
1138 compactSearch->ethresh);
1139
1140 posSearch->posNumSequences = numseq;
1141 /*use only those sequences below e-value threshold*/
1142 seqIndex = 0;
1143 curSeqAlign = listOfSeqAligns;
1144 prevSeqAlign = NULL;
1145 for(curSeqAlign = listOfSeqAligns; curSeqAlign != NULL;
1146 curSeqAlign = curSeqAlign->next) {
1147 is_new_id = FALSE;
1148
1149 thisEvalue = getEvalueFromSeqAlign(curSeqAlign);
1150
1151 curSegs = (DenseSegPtr) curSeqAlign->segs;
1152 if (NULL != prevSeqAlign) {
1153 prevSegs = (DenseSegPtr) prevSeqAlign->segs;
1154
1155 if(curSegs->ids == NULL)
1156 break;
1157
1158 curId = curSegs->ids->next;
1159 prevId = prevSegs->ids->next;
1160 if (!(SeqIdMatch(curId, prevId)))
1161 is_new_id = TRUE;
1162 }
1163
1164 if(!(compactSearch->use_best_align && is_new_id)) {
1165 if (thisEvalue >= compactSearch->ethresh)
1166 continue;
1167 }
1168
1169 if(is_new_id == TRUE)
1170 seqIndex++;
1171
1172 s = GetSequenceWithDenseSeg(curSegs, FALSE, &retrievalOffset, &subjectLength);
1173 if (s == NULL) {
1174 /* Kludge: set all of this sequence's residues to those of the query
1175 * so that it can be purged in posPurgeMatches */
1176 for (c = 0; c < length; c++) {
1177 posSearch->posDescMatrix[seqIndex+1][c].letter = (Int1) q[c];
1178 posSearch->posDescMatrix[seqIndex+1][c].used = TRUE;
1179 posSearch->posDescMatrix[seqIndex+1][c].e_value =
1180 compactSearch->ethresh/2;
1181 }
1182 continue;
1183 }
1184 startQ = 0;
1185 startS = 1;
1186 numsegs = curSegs->numseg;
1187 for(segIndex = 0; segIndex < numsegs; segIndex++) {
1188 queryOffset = curSegs->starts[startQ];
1189 if (curSegs->starts[startS] != GAP_HERE) /*XX*/
1190 subjectOffset = curSegs->starts[startS] - retrievalOffset;
1191 else
1192 subjectOffset = GAP_HERE;
1193 matchLength = curSegs->lens[segIndex];
1194 if ((GAP_HERE ) == queryOffset) {
1195 ; /*do nothing, gap in query*/
1196 }
1197 else
1198 if ((GAP_HERE) == subjectOffset) { /*XX*/
1199 for(c = 0, qplace = queryOffset;
1200 c < matchLength; c++, qplace++) {
1201 /*Keep the following test if spreading out gap costs,
1202 so that in that case a lower E-value non-gap trumps
1203 a higher E-value gap; if not spreading out gap costs
1204 then comment out the test, so that a higher E-value
1205 gap trumps a lower E-value letter*/
1206 if (!posSearch->posDescMatrix[seqIndex+1][qplace].used)
1207 {
1208 posSearch->posDescMatrix[seqIndex + 1][qplace].used = TRUE;
1209 posSearch->posDescMatrix[seqIndex + 1][qplace].letter = GAP_CHAR;
1210 posSearch->posDescMatrix[seqIndex + 1][qplace].e_value = 1.0;
1211 }
1212 }
1213 }
1214 else { /*no gap*/
1215 for(c = 0, qplace = queryOffset, splace = subjectOffset;
1216 c < matchLength; c++, qplace++, splace++) {
1217 if (!posSearch->posDescMatrix[seqIndex+1][qplace].used)
1218 {
1219 posSearch->posDescMatrix[seqIndex+1][qplace].letter = (Int1) s[splace];
1220 posSearch->posDescMatrix[seqIndex+1][qplace].used = TRUE;
1221 posSearch->posDescMatrix[seqIndex+1][qplace].e_value =
1222 thisEvalue;
1223 }
1224 }
1225 }
1226 startQ += 2;
1227 startS += 2;
1228 }
1229 prevSeqAlign = curSeqAlign;
1230 s = MemFree(s);
1231 } /*closes the for loop over seqAligns*/
1232 }
1233
posComputeExtents(posSearchItems * posSearch,compactSearchItems * compactSearch)1234 void LIBCALL posComputeExtents(posSearchItems *posSearch, compactSearchItems * compactSearch)
1235 {
1236 Int4 seqIndex; /*index of sequence*/
1237 Int4 length; /*length of query*/
1238 Int4 qplace, qplace2; /*place in query*/
1239 Int4 numseq; /*number of sequences including query*/
1240 Uint1Ptr q; /*pointers into query */
1241
1242 length = compactSearch->qlength;
1243 numseq = posSearch->posNumSequences;
1244 q = compactSearch->query;
1245 for(seqIndex = 0; seqIndex < numseq; seqIndex++) {
1246 if (!posSearch->posUseSequences[seqIndex+1])
1247 continue; /*XX*/
1248 if ((posSearch->posDescMatrix[seqIndex+1][0].used)
1249 && (posSearch->posDescMatrix[seqIndex+1][0].letter != GAP_CHAR))
1250 posSearch->posDescMatrix[seqIndex+1][0].leftExtent = 0;
1251 for(qplace = 1; qplace < length; qplace++)
1252 if(posSearch->posDescMatrix[seqIndex+1][qplace].used) {
1253 if(posSearch->posDescMatrix[seqIndex+1][qplace-1].used)
1254 posSearch->posDescMatrix[seqIndex+1][qplace].leftExtent =
1255 posSearch->posDescMatrix[seqIndex+1][qplace -1].leftExtent;
1256 else
1257 posSearch->posDescMatrix[seqIndex+1][qplace].leftExtent = qplace;
1258 }
1259 if ((posSearch->posDescMatrix[seqIndex+1][length-1].used)
1260 && (posSearch->posDescMatrix[seqIndex+1][length-1].letter != GAP_CHAR))
1261 posSearch->posDescMatrix[seqIndex+1][length-1].rightExtent = length -1;
1262 for(qplace = length -2; qplace >= 0; qplace--)
1263 if(posSearch->posDescMatrix[seqIndex+1][qplace].used) {
1264 if(posSearch->posDescMatrix[seqIndex+1][qplace+1].used)
1265 posSearch->posDescMatrix[seqIndex+1][qplace].rightExtent =
1266 posSearch->posDescMatrix[seqIndex+1][qplace + 1].rightExtent;
1267 else
1268 posSearch->posDescMatrix[seqIndex+1][qplace].rightExtent = qplace;
1269 }
1270 for(qplace = 0; qplace < length; qplace++)
1271 if (posSearch->posDescMatrix[seqIndex+1][qplace].used) {
1272 /* comment next if out to spread gap costs*/
1273 /* if (posSearch->posDescMatrix[seqIndex+1][qplace].letter != GAP_CHAR) { */
1274 posSearch->posExtents[qplace].leftExtent = MAX(posSearch->posExtents[qplace].leftExtent,
1275 posSearch->posDescMatrix[seqIndex+1][qplace].leftExtent);
1276 posSearch->posExtents[qplace].rightExtent = MIN(posSearch->posExtents[qplace].rightExtent,
1277 posSearch->posDescMatrix[seqIndex+1][qplace].rightExtent);
1278
1279 }
1280 /*}*/ /*comment this out if we want to spread gap costs out */
1281
1282 for(qplace = 0; qplace < length; qplace++)
1283 /*used to check qplace for GAP_CHAR here*/ /*XX*/
1284 if (posSearch->posDescMatrix[seqIndex+1][qplace].used) {
1285 posSearch->posC[qplace][posSearch->posDescMatrix[seqIndex+1][qplace].letter]++;
1286 posSearch->posCount[qplace]++; /*Add to number of matches in this query position*/
1287 }
1288 }
1289 for(qplace = 0; qplace < length; qplace++)
1290 posSearch->posIntervalSizes[qplace] = posSearch->posExtents[qplace].rightExtent -
1291 posSearch->posExtents[qplace].leftExtent + 1;
1292 for(qplace =0; qplace < length; qplace++) {
1293 if(Xchar == q[qplace]) {
1294 posSearch->posIntervalSizes[qplace] = 0;
1295 for(qplace2 = 0; qplace2 <qplace; qplace2++) {
1296 if((Xchar != q[qplace2]) && (posSearch->posExtents[qplace2].rightExtent >= qplace))
1297 posSearch->posIntervalSizes[qplace2]--;
1298 }
1299 for(qplace2 = length-1; qplace2 > qplace; qplace2--) {
1300 if((Xchar != q[qplace2]) && (posSearch->posExtents[qplace2].leftExtent <= qplace))
1301 posSearch->posIntervalSizes[qplace2]--;
1302 }
1303 }
1304 }
1305 }
1306
1307 /*Compute weight of each sequence and letter in each position*/
posComputeSequenceWeights(posSearchItems * posSearch,compactSearchItems * compactSearch,Nlm_FloatHi weightExponent)1308 void LIBCALL posComputeSequenceWeights(posSearchItems *posSearch, compactSearchItems * compactSearch, Nlm_FloatHi weightExponent)
1309 {
1310 Int4 length; /*length of query*/
1311 Int4 numseq, seqIndex; /*number of matches, index for them*/
1312 Int4 i; /*index over a multi-alignment block*/
1313 Int4 qplace; /*index into query*/
1314 Nlm_FloatHi Sigma; /*Number of different characters occurring in matches within
1315 a multi-alignment block, excluding identical columns*/
1316 Nlm_FloatHi intervalSigma; /*Same as Sigma but includes identical columns*/
1317 Int4 alphabetSize; /*number of characters in alphabet*/
1318 Int4 *participatingSequences; /*array of participating sequences at a position*/
1319 Int4 *oldParticipatingSequences; /*array of participating sequences at a position*/
1320 Int4 posLocalVariety; /*number of different characters at a position*/
1321 Int4 posLocalStandardLet; /*posLocalVariety, not counting X or gap*/
1322 Int4 *posLocalC; /*counts of how many of each letter in this column*/
1323 Int4 c;
1324 Int4 thisSeq;
1325 Int4 numParticipating; /*number of sequences in this alignment block*/
1326 Int4 oldNumParticipating; /*number of sequences in this alignment block*/
1327 Boolean newSequenceSet;
1328 Int4 p; /*index on sequences*/
1329 Nlm_FloatHi weightSum; /*Sum of intermediate sequence weights in a column
1330 used to normalize the weights, so they sum to 1*/
1331
1332 alphabetSize = compactSearch->alphabetSize;
1333 length = compactSearch->qlength;
1334 numseq = posSearch->posNumSequences;
1335 participatingSequences = (Int4 *) MemNew((numseq+1) * sizeof(Int4));
1336 if (NULL == participatingSequences)
1337 exit(EXIT_FAILURE);
1338 oldParticipatingSequences = (Int4 *) MemNew((numseq+1) * sizeof(Int4));
1339 if (NULL == oldParticipatingSequences)
1340 exit(EXIT_FAILURE);
1341 posLocalC = (Int4 *) MemNew(alphabetSize * sizeof(Int4));
1342 if (NULL == posLocalC)
1343 exit(EXIT_FAILURE);
1344 for (qplace = 0; qplace < length; qplace++) {
1345 posSearch->posSigma[qplace] = 0.0;
1346 }
1347 numParticipating = 0;
1348 for(qplace = 0; qplace < length; qplace++) {
1349 posSearch->posGaplessColumnWeights[qplace] = 0.0;
1350 if ((posSearch->posCount[qplace] > 1) && (posSearch->posIntervalSizes[qplace] > 0)) {
1351 oldNumParticipating = numParticipating;
1352 for(p =0; p < numParticipating; p++)
1353 oldParticipatingSequences[p] = participatingSequences[p];
1354 numParticipating = 0;
1355 for (seqIndex = 0; seqIndex <= numseq; seqIndex++) {
1356 if (!posSearch->posUseSequences[seqIndex])
1357 continue;
1358 /* if ((posSearch->posDescMatrix[seqIndex][qplace].used) &&
1359 (posSearch->posDescMatrix[seqIndex][qplace].letter != GAP_CHAR)) {
1360 */
1361 /*change to this if we want to spread gap costs*/
1362 if (posSearch->posDescMatrix[seqIndex][qplace].used) {
1363 participatingSequences[numParticipating] = seqIndex;
1364 numParticipating++;
1365 }
1366 }
1367 newSequenceSet = TRUE;
1368 if (numParticipating == oldNumParticipating) {
1369 for(p = 0; p < numParticipating; p++)
1370 if (oldParticipatingSequences[p] != participatingSequences[p])
1371 break;
1372 if (p == numParticipating)
1373 newSequenceSet = FALSE;
1374 }
1375
1376 if (newSequenceSet) {
1377 Sigma = 0;
1378 intervalSigma = 0;
1379 for (seqIndex = 0; seqIndex <= numseq; seqIndex++) {
1380 if (!posSearch->posUseSequences[seqIndex])
1381 continue;
1382 posSearch->posRowSigma[seqIndex] = 0.0;
1383 posSearch->posA[seqIndex] = 0.0;
1384 }
1385 for (i = posSearch->posExtents[qplace].leftExtent;
1386 i <= posSearch->posExtents[qplace].rightExtent; i++) {
1387 posLocalVariety = 0;
1388 posLocalStandardLet = 0;
1389 for(c = 0; c < alphabetSize; c++)
1390 posLocalC[c] = 0;
1391 for(seqIndex = 0; seqIndex < numParticipating; seqIndex++) {
1392 thisSeq = participatingSequences[seqIndex];
1393 /*used to check for GAP here*/ /*XX*/
1394 if (0 == posLocalC[posSearch->posDescMatrix[thisSeq][i].letter]) {
1395 /*letter (not a gap) not seen before in this query pos.*/
1396 posLocalVariety++;
1397 if ((GAP_CHAR != posSearch->posDescMatrix[thisSeq][i].letter) &&
1398 (Xchar != posSearch->posDescMatrix[thisSeq][i].letter))
1399 posLocalStandardLet++;
1400 }
1401 posLocalC[posSearch->posDescMatrix[thisSeq][i].letter]++;
1402 }
1403 intervalSigma += posLocalVariety;
1404 posLocalStandardLet = MIN(posLocalStandardLet,EFFECTIVE_ALPHABET);
1405 posSearch->posDistinctDistrib[qplace][posLocalStandardLet]++;
1406 if (posLocalVariety > 1) {
1407 Sigma += posLocalVariety;
1408 }
1409 for(seqIndex = 0; seqIndex < numParticipating; seqIndex++) {
1410 thisSeq = participatingSequences[seqIndex];
1411 /*used to check for gap here*/
1412 posSearch->posRowSigma[thisSeq] +=
1413 ( 1.0 /
1414 (((Nlm_FloatHi) posLocalC[posSearch->posDescMatrix[thisSeq][i].letter])
1415 * posLocalVariety));
1416 }
1417 }
1418 }
1419 else {
1420 for (i = 0; i <= EFFECTIVE_ALPHABET; i++) {
1421 posSearch->posDistinctDistrib[qplace][i] = posSearch->posDistinctDistrib[qplace - 1][i];
1422 }
1423 }
1424 if (Sigma > 0) {
1425 weightSum = 0;
1426 for (seqIndex = 0; seqIndex < numParticipating; seqIndex++) {
1427 thisSeq = participatingSequences[seqIndex];
1428 posSearch->posA[thisSeq] = posSearch->posRowSigma[thisSeq]/
1429 (posSearch->posExtents[qplace].rightExtent -
1430 posSearch->posExtents[qplace].leftExtent +1);
1431 /*spread gap weight here*/
1432 posSearch->posA[thisSeq] = pow(posSearch->posA[thisSeq],
1433 weightExponent);
1434 weightSum += posSearch->posA[thisSeq];
1435 }
1436 for (seqIndex = 0; seqIndex < numParticipating; seqIndex++) {
1437 thisSeq = participatingSequences[seqIndex];
1438 posSearch->posA[thisSeq] = posSearch->posA[thisSeq]/weightSum;
1439 }
1440 }
1441 else {
1442 for (seqIndex = 0; seqIndex < numParticipating; seqIndex++) {
1443 thisSeq = participatingSequences[seqIndex];
1444 posSearch->posA[thisSeq] = ((Nlm_FloatHi) 1 / (Nlm_FloatHi) numParticipating);
1445 }
1446 }
1447 posSearch->posSigma[qplace] = intervalSigma;
1448 for (seqIndex = 0; seqIndex < numParticipating; seqIndex++) {
1449 thisSeq = participatingSequences[seqIndex];
1450 posSearch->posMatchWeights[qplace][posSearch->posDescMatrix[thisSeq][qplace].letter] += posSearch->posA[thisSeq];
1451 if(posSearch->posDescMatrix[thisSeq][qplace].letter)
1452 posSearch->posGaplessColumnWeights[qplace] += posSearch->posA[thisSeq];
1453 }
1454 posSearch->posNumParticipating[qplace] = numParticipating;
1455 }
1456 }
1457 MemFree(participatingSequences);
1458 MemFree(oldParticipatingSequences);
1459 MemFree(posLocalC);
1460 }
1461
countsFunction(Nlm_FloatHi Sigma,Int4 intervalLength)1462 static Nlm_FloatHi countsFunction(Nlm_FloatHi Sigma, Int4 intervalLength)
1463 {
1464 return(Sigma / intervalLength - 1);
1465 }
1466
1467 #define MAX_IND_OBSERVATIONS 400
1468
1469
1470 /*initialize the expected number of observations
1471 use background probabilities for this matrix
1472 Calculate exp. # of distinct aa's as a function of independent trials
1473 */
initializeExpNumObservations(double * expno,double * backgroundProbabilities)1474 static void initializeExpNumObservations(double *expno,
1475 double *backgroundProbabilities)
1476
1477 {
1478 int j,k ; /*loop indices*/
1479 double weighted_sum; /*20 - this is how many distinct
1480 amino acids are expected*/
1481
1482 expno[0] = 0;
1483 for (j=1;j<MAX_IND_OBSERVATIONS;++j) {
1484 weighted_sum = 0;
1485 for (k=0;k<EFFECTIVE_ALPHABET;++k)
1486 weighted_sum += exp(j*log(1.0-backgroundProbabilities[k]));
1487 expno[j] = EFFECTIVE_ALPHABET-weighted_sum;
1488 }
1489 }
1490
1491
1492 /*A method to estimate the effetive number of observations
1493 in the interval for the specified columnNumber */
1494
effectiveObservations(posSearchItems * posSearch,Int4 columnNumber,Int4 queryLength,double * expno)1495 static Nlm_FloatHi effectiveObservations(posSearchItems *posSearch,
1496 Int4 columnNumber, Int4 queryLength,
1497 double *expno)
1498 {
1499 int i,k; /*loop indices*/
1500 double indep; /*number of independent observations to return*/
1501 int halfNumColumns; /*half the number of columns in the interval, rounded
1502 down*/
1503 int totalDistinctCounts; /*total number of distinct letters in columns
1504 used*/
1505 double aveDistinctAA; /*average number of distinct letters in columns used*/
1506 int columnsAccountedFor; /*how many of the columns had their
1507 distinct count totaled so far*/
1508
1509
1510 if (posSearch->posExtents[columnNumber].leftExtent < 0)
1511 return(0);
1512 if (posSearch->posExtents[columnNumber].rightExtent >= queryLength)
1513 return(0);
1514
1515 /* Calculate the average number of distinct amino acids in the half of the
1516 columns within the block in question with the most distinct amino acids;
1517 +2 in the parentheses is for rounding up.*/
1518
1519 halfNumColumns = MAX(1,(posSearch->posExtents[columnNumber].rightExtent -
1520 posSearch->posExtents[columnNumber].leftExtent+2)/2);
1521 k = EFFECTIVE_ALPHABET;
1522 columnsAccountedFor = 0;
1523 totalDistinctCounts = 0;
1524 while (columnsAccountedFor < halfNumColumns) {
1525 totalDistinctCounts += (posSearch->posDistinctDistrib[columnNumber][k] *k);
1526 columnsAccountedFor += posSearch->posDistinctDistrib[columnNumber][k];
1527 if (columnsAccountedFor > halfNumColumns) {
1528 totalDistinctCounts -=
1529 ((columnsAccountedFor - halfNumColumns) * k);
1530 columnsAccountedFor = halfNumColumns;
1531 }
1532 k--;
1533 }
1534 aveDistinctAA = ((double) totalDistinctCounts)/
1535 ((double) columnsAccountedFor);
1536
1537 /* Then use the following code to calculate the number of
1538 independent observations corresponding to
1539 aveDistinctAA.
1540 */
1541
1542 for (i=1;i<MAX_IND_OBSERVATIONS && expno[i]<=aveDistinctAA;++i);
1543 indep = (i==MAX_IND_OBSERVATIONS) ? i :
1544 i-(expno[i]-aveDistinctAA)/(expno[i]-expno[i-1]);
1545 indep = MIN(indep, posSearch->posNumParticipating[columnNumber]);
1546 indep = MAX(0,indep - 1);
1547 return(indep);
1548 }
1549
posit_rounddown(Nlm_FloatHi value)1550 static Nlm_FloatHi posit_rounddown(Nlm_FloatHi value)
1551 {
1552 return (Nlm_FloatHi) Nlm_Nint(value);
1553 }
1554
1555 /*check that weights add to 1 in each column */
posCheckWeights(posSearchItems * posSearch,compactSearchItems * compactSearch)1556 void LIBCALL posCheckWeights(posSearchItems *posSearch, compactSearchItems * compactSearch)
1557 {
1558 Uint1Ptr q; /*pointer to query*/
1559 Int4 length, alphabetSize; /*length of query and number of characters in alphabet*/
1560 Int4 a, c; /*loop indices*/
1561 Nlm_FloatHi runningSum; /*partial total for a column*/
1562
1563
1564 length = compactSearch->qlength;
1565 alphabetSize = compactSearch->alphabetSize;
1566
1567 q = compactSearch->query;
1568 for(c = 0; c < length; c++) {
1569 if ((posSearch->posCount[c] > 1) && (q[c] != Xchar)) {
1570 runningSum = 0;
1571 /* if (posSearch->posMatchWeights[c][0] > 0.0)
1572 printf("Stop here %d ", c); */
1573 for(a = 0; a < alphabetSize; a++)
1574 runningSum += posSearch->posMatchWeights[c][a];
1575 if((runningSum < 0.99) || (runningSum > 1.01))
1576 ErrPostEx(SEV_ERROR, 0, 0, "\nERROR IN WEIGHTS, column %d, value %lf\n",c, runningSum);
1577 /* spread out gap weight here*/
1578 for(a = 1; a < alphabetSize; a++)
1579 if (compactSearch->standardProb[a] > posEpsilon)
1580 posSearch->posMatchWeights[c][a] = posSearch->posMatchWeights[c][a] +
1581 (posSearch->posMatchWeights[c][0] * compactSearch->standardProb[a]);
1582 posSearch->posMatchWeights[c][0] = 0.0;
1583 runningSum = 0;
1584 for(a = 0; a < alphabetSize; a++)
1585 runningSum += posSearch->posMatchWeights[c][a];
1586 if((runningSum < 0.99) || (runningSum > 1.01))
1587 ErrPostEx(SEV_ERROR, 0, 0, "\nERROR IN WEIGHTS, column %d, value %lf\n",c, runningSum);
1588 }
1589 }
1590 }
1591
1592 /*Fill in information content per position from pseudo-count frequencies*/
posFreqsToInformation(posSearchItems * posSearch,compactSearchItems * compactSearch)1593 static void posFreqsToInformation(posSearchItems * posSearch, compactSearchItems * compactSearch)
1594 {
1595 Int4 length; /*length of the query*/
1596 Int4 c; /*loop index*/
1597 Int4 a, alphabetSize; /*loop index and size of alphabet*/
1598 Nlm_FloatHi qOverPEstimate; /*intermediate term*/
1599 Nlm_FloatHi infoSum; /*information content sum for this position*/
1600
1601 length = compactSearch->qlength;
1602 alphabetSize = compactSearch->alphabetSize;
1603 for (c = 0; c < length; c++) {
1604 infoSum = 0;
1605 for(a = 0; a < alphabetSize; a++) {
1606 if (compactSearch->standardProb[a] > posEpsilon) {
1607 qOverPEstimate = posSearch->posFreqs[c][a] / compactSearch->standardProb[a];
1608 if (qOverPEstimate > posEpsilon)
1609 infoSum += posSearch->posFreqs[c][a] * log(qOverPEstimate)/
1610 NCBIMATH_LN2;
1611 }
1612 }
1613 posSearch->posInformation[c] = infoSum;
1614 }
1615 }
1616
1617 /*Convert pseudo-count frequencies to a score matrix, where standard
1618 matrix is represented by its frequencies */
posFreqsToMatrix(posSearchItems * posSearch,compactSearchItems * compactSearch)1619 void LIBCALL posFreqsToMatrix(posSearchItems *posSearch,
1620 compactSearchItems *compactSearch)
1621 {
1622 Uint1Ptr q; /*pointer to the query*/
1623 Int4 length; /*length of the query*/
1624 Int4 c; /*loop index*/
1625 Int4 a, alphabetSize; /*loop index and size of alphabet*/
1626 Nlm_FloatHi lambda; /*Karlin-Altschul parameter*/
1627 Nlm_FloatHi qOverPEstimate, value; /*intermediate terms*/
1628 Boolean allZeros; /*are all frequencies in a column 0?*/
1629 Nlm_FloatHi intermediateValue; /*intermediate value*/
1630
1631 q = compactSearch->query;
1632 length = compactSearch->qlength;
1633
1634 alphabetSize = compactSearch->alphabetSize;
1635 lambda = compactSearch->lambda_ideal;
1636
1637
1638 for(c = 0; c < length; c++) {
1639 allZeros = TRUE;
1640 for(a = 0; a < alphabetSize; a++) {
1641 /*Division compensates for multiplication in posComputePsedoFreqs*/
1642 if (compactSearch->standardProb[a] > posEpsilon)
1643 qOverPEstimate = posSearch->posFreqs[c][a]/compactSearch->standardProb[a];
1644 else
1645 qOverPEstimate = 0.0;
1646 if (qOverPEstimate != 0.0)
1647 allZeros = FALSE;
1648 if (0.0 == qOverPEstimate || (compactSearch->standardProb[a] < posEpsilon))
1649 posSearch->posPrivateMatrix[c][a] = BLAST_SCORE_MIN;
1650 else {
1651 value = log(qOverPEstimate)/lambda;
1652 posSearch->posPrivateMatrix[c][a] = (BLAST_Score) posit_rounddown(POSIT_SCALE_FACTOR*value);
1653
1654 }
1655 if (((Xchar == a) || (StarChar == a)) && (compactSearch->matrix[q[c]][Xchar] != BLAST_SCORE_MIN))
1656 posSearch->posPrivateMatrix[c][a] =
1657 compactSearch->matrix[q[c]][a] * POSIT_SCALE_FACTOR;
1658 }
1659 if (allZeros) {
1660 if ( !posSearch->stdFreqRatios ) {
1661 ErrPostEx(SEV_FATAL, 1, 0, "Frequency ratios for %s scoring matrix are not available\n", compactSearch->standardMatrixName);
1662 return;
1663 }
1664
1665 for(a = 0; a < alphabetSize; a++) {
1666 posSearch->posMatrix[c][a] = compactSearch->matrix[q[c]][a];
1667 if (posSearch->stdFreqRatios->data[q[c]][a] == 0.0) {
1668 posSearch->posPrivateMatrix[c][a] = BLAST_SCORE_MIN;
1669 } else {
1670 intermediateValue = POSIT_SCALE_FACTOR *
1671 posSearch->stdFreqRatios->bit_scale_factor *
1672 log(posSearch->stdFreqRatios->data[q[c]][a])/NCBIMATH_LN2;
1673 posSearch->posPrivateMatrix[c][a] = Nlm_Nint(intermediateValue);
1674 }
1675 }
1676 }
1677 }
1678 for(a = 0; a < alphabetSize; a++) {
1679 posSearch->posPrivateMatrix[length][a] = posSearch->posPrivateMatrix[length][a] = BLAST_SCORE_MIN;
1680 }
1681 }
1682
1683 /*copy position specific frequency matrix of diminesions qlength * alphabetSize*/
copyPosFreqs(Nlm_FloatHi ** posFreqsFrom,Nlm_FloatHi ** posFreqsTo,Int4 qlength,Int4 alphabetSize)1684 void LIBCALL copyPosFreqs(Nlm_FloatHi **posFreqsFrom, Nlm_FloatHi **posFreqsTo, Int4 qlength, Int4 alphabetSize)
1685 {
1686 Int4 c, i; /*loop indices*/
1687
1688 for (i = 0; i < qlength; i++)
1689 for (c = 0; c < alphabetSize; c++)
1690 posFreqsTo[i][c] = posFreqsFrom[i][c];
1691 }
1692
allocatePosFreqs(Int4 length,Int4 alphabetSize)1693 Nlm_FloatHi ** LIBCALL allocatePosFreqs(Int4 length, Int4 alphabetSize)
1694 {
1695 Int4 c, i; /*loop indices*/
1696 Nlm_FloatHi ** returnArray;
1697
1698 returnArray = (Nlm_FloatHi **) MemNew((length + 1) * sizeof(Nlm_FloatHi *));
1699 if (NULL == returnArray)
1700 exit(EXIT_FAILURE);
1701 for(i = 0; i <= length; i++) {
1702 returnArray[i] = (Nlm_FloatHi *) MemNew(alphabetSize * sizeof(Nlm_FloatHi));
1703 if (NULL == returnArray[i])
1704 exit(EXIT_FAILURE);
1705 for(c = 0; c < alphabetSize; c++)
1706 returnArray[i][c] = 0.0;
1707 }
1708 return(returnArray);
1709 }
1710
1711 /*The following constants are used in
1712 posComputePseudoFreqs and columnSpecificPseudocounts */
1713 #define PSEUDO_MULTIPLIER 500
1714 #define PSEUDO_SMALL_INITIAL 5.5 /*small number of pseudocounts to
1715 avoid 0 probabilities in entropy-based
1716 method*/
1717 #define PSEUDO_NUMERATOR 0.0457 /*numerator of entropy-based method*/
1718 #define PSEUDO_EXPONENT 0.8 /*exponent of denominator*/
1719 #define PSEUDO_MAX 1000000 /*effective infinity*/
1720 #define ZERO_OBS_PSEUDO 30 /*arbitrary constant to use for columns with
1721 zero observations in actual data*/
1722
fillColumnProbabilities(double * probabilities,posSearchItems * posSearch,Int4 columnNumber)1723 static void fillColumnProbabilities(double *probabilities,
1724 posSearchItems *posSearch,
1725 Int4 columnNumber)
1726 {
1727 Int4 charOrder[EFFECTIVE_ALPHABET]; /*standard order of letters according to S. Altschul*/
1728 Int4 c; /*loop index*/
1729
1730 charOrder[0] = 1; /*A*/
1731 charOrder[1] = 16; /*R*/
1732 charOrder[2] = 13; /*N*/
1733 charOrder[3] = 4; /*D*/
1734 charOrder[4] = 3; /*C*/
1735 charOrder[5] = 15; /*Q*/
1736 charOrder[6] = 5; /*E*/
1737 charOrder[7] = 7; /*G*/
1738 charOrder[8] = 8; /*H*/
1739 charOrder[9] = 9; /*I*/
1740 charOrder[10] = 11; /*L*/
1741 charOrder[11] = 10; /*K*/
1742 charOrder[12] = 12; /*M*/
1743 charOrder[13] = 6; /*F*/
1744 charOrder[14] = 14; /*P*/
1745 charOrder[15] = 17; /*S*/
1746 charOrder[16] = 18; /*T*/
1747 charOrder[17] = 20; /*W*/
1748 charOrder[18] = 22; /*Y*/
1749 charOrder[19] = 19; /*V*/
1750
1751 for(c = 0; c < EFFECTIVE_ALPHABET; c++)
1752 probabilities[c] = posSearch->posMatchWeights[columnNumber][charOrder[c]];
1753 }
1754
1755 /*adjust the probabilities by assigning observations weight
1756 to initialProbabilities and standardWeight to standardProbabilities*/
adjustColumnProbabilities(double * initialProbabilities,double * probabilitiesToReturn,double standardWeight,double * standardProbabilities,double observations)1757 static void adjustColumnProbabilities(double *initialProbabilities,
1758 double *probabilitiesToReturn,
1759 double standardWeight,
1760 double *standardProbabilities,
1761 double observations)
1762 {
1763 double intermediateSums[EFFECTIVE_ALPHABET]; /*weighted sums for each letter*/
1764 double overallSum; /*overall sum of weightedSums*/
1765 Int4 c; /*loop index*/
1766
1767 overallSum = 0.0;
1768 for(c = 0; c < EFFECTIVE_ALPHABET; c++) {
1769 intermediateSums[c] =
1770 (initialProbabilities[c] * observations) +
1771 (standardProbabilities[c] * standardWeight);
1772 overallSum += intermediateSums[c];
1773 }
1774 for(c = 0; c < EFFECTIVE_ALPHABET; c++)
1775 probabilitiesToReturn[c] = intermediateSums[c]/overallSum;
1776 }
1777
1778 /*compute relative entropy of first distribution to second distribution*/
1779
computeRelativeEntropy(double * newDistribution,double * backgroundProbabilities)1780 static double computeRelativeEntropy(double *newDistribution,
1781 double *backgroundProbabilities)
1782 {
1783 Int4 c; /*loop index*/
1784 double returnValue; /*value to return*/
1785
1786
1787 returnValue = 0;
1788 for(c = 0; c < EFFECTIVE_ALPHABET; c++) {
1789 if (newDistribution[c] > posEpsilon)
1790 returnValue += (newDistribution[c] *
1791 log (newDistribution[c]/backgroundProbabilities[c]));
1792 }
1793 if (returnValue < posEpsilon)
1794 returnValue = posEpsilon;
1795 return(returnValue);
1796 }
1797
1798
columnSpecificPseudocounts(posSearchItems * posSearch,compactSearchItems * compactSearch,Int4 columnNumber,double * backgroundProbabilities,double observations)1799 static double columnSpecificPseudocounts(posSearchItems *posSearch,
1800 compactSearchItems *compactSearch,
1801 Int4 columnNumber,
1802 double *backgroundProbabilities,
1803 double observations)
1804 {
1805 double columnProbabilitiesInitial[EFFECTIVE_ALPHABET];
1806 double columnProbabilitiesAdjusted[EFFECTIVE_ALPHABET];
1807 double relativeEntropy; /*relative entropy of this column to background probs.*/
1808 double alpha; /*intermediate term*/
1809 double pseudoDenominator; /*intermediate term*/
1810 double returnValue;
1811
1812 fillColumnProbabilities(&(columnProbabilitiesInitial[0]), posSearch, columnNumber);
1813 adjustColumnProbabilities(&(columnProbabilitiesInitial[0]),
1814 &(columnProbabilitiesAdjusted[0]),
1815 compactSearch->standardProbWeight,
1816 backgroundProbabilities, observations);
1817 relativeEntropy = computeRelativeEntropy(&(columnProbabilitiesAdjusted[0]),
1818 backgroundProbabilities);
1819 pseudoDenominator = pow(relativeEntropy, compactSearch->HmethodDenominator);
1820 alpha = compactSearch->HmethodNumerator/pseudoDenominator;
1821 if (alpha < (1.0 - posEpsilon))
1822 returnValue = PSEUDO_MULTIPLIER * alpha/ (1- alpha);
1823 else
1824 returnValue = PSEUDO_MAX;
1825 /*extraOutputFile = fopen("Pseudocounts.txt","a");
1826 fprintf(extraOutputFile,"%s\t%5d\t%3.6lf\t%3.6lf\t%3.6lf\t%3.6lf",compactSearch->queryFileName,columnNumber+1,observations+1,relativeEntropy,alpha,returnValue);
1827 fprintf(extraOutputFile,"\n");
1828 fclose(extraOutputFile);*/
1829
1830 return(returnValue);
1831 }
1832
1833
posComputePseudoFreqs(posSearchItems * posSearch,compactSearchItems * compactSearch,Boolean Cpos)1834 Nlm_FloatHi ** LIBCALL posComputePseudoFreqs(posSearchItems *posSearch, compactSearchItems * compactSearch, Boolean Cpos)
1835 {
1836 Uint1Ptr q; /*pointer to the query*/
1837 Int4 length; /*length of the query*/
1838 Int4 c; /*loop index*/
1839 Int4 a, aSub, alphabetSize; /*loop indices and size of alphabet*/
1840 Nlm_FloatHi lambda; /*Karlin-Altschul parameter*/
1841 Nlm_FloatHi pseudo, numerator, denominator, qOverPEstimate; /*intermediate terms*/
1842 Nlm_FloatHi infoSum; /*sum used for information content*/
1843 Nlm_FloatHi **posFreqs; /*store frequencies*/
1844 double observations; /*estimated number of independent observations*/
1845 double expno[MAX_IND_OBSERVATIONS+1]; /*table of expectations*/
1846 double pseudoWeight; /*multiplier for pseudocounts term*/
1847 double *backgroundProbabilities; /*background probabilities for matrix*/
1848 double columnCounts; /*column-specific pseudocounts*/
1849
1850 q = compactSearch->query;
1851 length = compactSearch->qlength;
1852
1853 alphabetSize = compactSearch->alphabetSize;
1854 lambda = compactSearch->lambda_ideal;
1855 posFreqs = allocatePosFreqs(length, alphabetSize);
1856 backgroundProbabilities = (double *) Blast_GetMatrixBackgroundFreq(compactSearch->standardMatrixName);
1857 if (!posSearch->stdFreqRatios) {
1858 posSearch->stdFreqRatios =
1859 PSIMatrixFrequencyRatiosNew(compactSearch->standardMatrixName);
1860 }
1861
1862 initializeExpNumObservations(&(expno[0]), backgroundProbabilities);
1863 compactSearch->standardProbWeight = PSEUDO_SMALL_INITIAL;
1864 compactSearch->HmethodDenominator = PSEUDO_EXPONENT;
1865 compactSearch->HmethodNumerator = PSEUDO_NUMERATOR;
1866
1867 for(c = 0; c < length; c++) {
1868 if (Xchar != q[c]) {
1869 infoSum = 0;
1870 observations = effectiveObservations(posSearch,c,
1871 compactSearch->qlength,
1872 &(expno[0]));
1873 /* observations = countsFunction(posSearch->posSigma[c],
1874 posSearch->posIntervalSizes[c]);*/
1875 if (0 == compactSearch->pseudoCountConst)
1876 columnCounts = columnSpecificPseudocounts(posSearch,compactSearch, c, backgroundProbabilities, observations);
1877 else
1878 columnCounts = compactSearch->pseudoCountConst;
1879 if (columnCounts >= PSEUDO_MAX) {
1880 pseudoWeight = ZERO_OBS_PSEUDO;
1881 observations = 0;
1882 }
1883 else {
1884 pseudoWeight = columnCounts;
1885 }
1886 posSearch->pseudoWeights[c] = pseudoWeight;
1887 for(a = 0; a < alphabetSize; a++) {
1888 if (compactSearch->standardProb[a] > posEpsilon) {
1889 pseudo = 0;
1890 /*changed to matrix specific ratios here May 2000*/
1891 for (aSub = 0; aSub < alphabetSize; aSub++)
1892 if(compactSearch->matrix[a][aSub] != BLAST_SCORE_MIN)
1893 pseudo += (posSearch->posMatchWeights[c][aSub] *
1894 posSearch->stdFreqRatios->data[a][aSub]);
1895 pseudo *= pseudoWeight;
1896 numerator = pseudo +
1897 (observations * posSearch->posMatchWeights[c][a]/
1898 compactSearch->standardProb[a]);
1899 denominator = observations + pseudoWeight;
1900 qOverPEstimate = numerator / denominator;
1901 /*Note artificial multiplication by standard probability to
1902 normalize*/
1903 posFreqs[c][a] = qOverPEstimate * compactSearch->standardProb[a];
1904 if (0.0 != qOverPEstimate && (compactSearch->standardProb[a] > posEpsilon))
1905 infoSum += qOverPEstimate * compactSearch->standardProb[a] * log(qOverPEstimate)/ NCBIMATH_LN2;
1906 }
1907 else
1908 posFreqs[c][a] = 0.0;
1909 }
1910 if (Cpos)
1911 posSearch->posInformation[c] = infoSum;
1912 }
1913 else
1914 for(a = 0; a < alphabetSize; a++) {
1915 posFreqs[c][a] = 0;
1916 }
1917 }
1918 return(posFreqs);
1919 }
1920
posScaling(posSearchItems * posSearch,compactSearchItems * compactSearch)1921 void LIBCALL posScaling(posSearchItems *posSearch, compactSearchItems * compactSearch)
1922 {
1923 BlastMatrixRescalePtr matrix_rescale;
1924
1925 matrix_rescale = BlastMatrixRescaleNew(compactSearch->alphabetSize,
1926 compactSearch->qlength,
1927 compactSearch->query,
1928 compactSearch->standardProb,
1929 posSearch->posMatrix,
1930 posSearch->posPrivateMatrix,
1931 compactSearch->kbp_std,
1932 compactSearch->kbp_psi,
1933 compactSearch->kbp_gap_std,
1934 compactSearch->kbp_gap_psi,
1935 compactSearch->lambda_ideal,
1936 compactSearch->K_ideal);
1937
1938 BlastScaleMatrix(matrix_rescale, TRUE);
1939
1940 matrix_rescale = BlastMatrixRescaleDestruct(matrix_rescale);
1941
1942 return;
1943 }
1944
1945
CposComputation(posSearchItems * posSearch,BlastSearchBlkPtr search,compactSearchItems * compactSearch,SeqAlignPtr listOfSeqAligns,Char * ckptFileName,Boolean patternSearchStart,Int4 scorematOutput,Bioseq * query_bsp,Int4 gap_open,Int4 gap_extend,ValNodePtr * error_return,Nlm_FloatHi weightExponent)1946 Int4Ptr * LIBCALL CposComputation(posSearchItems *posSearch, BlastSearchBlkPtr search, compactSearchItems * compactSearch, SeqAlignPtr listOfSeqAligns, Char *ckptFileName, Boolean patternSearchStart, Int4 scorematOutput, Bioseq *query_bsp, Int4 gap_open, Int4 gap_extend, ValNodePtr * error_return, Nlm_FloatHi weightExponent)
1947 {
1948 Int4 numalign, numseq; /*number of alignments and matches in previous round*/
1949
1950 search->posConverged = FALSE;
1951 /* if (patternSearchStart)
1952 posAllocateMemory(posSearch, compactSearch->alphabetSize, compactSearch->qlength, posSearch->posNumSequences);
1953 else {
1954 */
1955 numalign = countSeqAligns(listOfSeqAligns, &numseq, FALSE, 0.0);
1956 countNumSeq(posSearch, compactSearch, listOfSeqAligns, &numseq);
1957 posAllocateMemory(posSearch, compactSearch->alphabetSize, compactSearch->qlength, numseq);
1958
1959 if (!patternSearchStart)
1960 findThreshSequences(posSearch, search, listOfSeqAligns, numalign, numseq);
1961 posDemographics(posSearch, compactSearch, listOfSeqAligns);
1962 posPurgeMatches(posSearch, compactSearch, error_return);
1963 posComputeExtents(posSearch, compactSearch);
1964 posComputeSequenceWeights(posSearch, compactSearch, weightExponent);
1965 posCheckWeights(posSearch, compactSearch);
1966 posSearch->posFreqs = posComputePseudoFreqs(posSearch, compactSearch, TRUE);
1967 if (NULL == search->sbp->posFreqs)
1968 search->sbp->posFreqs = allocatePosFreqs(compactSearch->qlength, compactSearch->alphabetSize);
1969 copyPosFreqs(posSearch->posFreqs,search->sbp->posFreqs, compactSearch->qlength, compactSearch->alphabetSize);
1970 if (NULL != ckptFileName) {
1971 if (scorematOutput == NO_SCOREMAT_IO)
1972 posTakeCheckpoint(posSearch, compactSearch, ckptFileName, error_return);
1973 else
1974 posTakeScoremat(posSearch, compactSearch, ckptFileName,
1975 scorematOutput, query_bsp, gap_open,
1976 gap_extend, error_return);
1977 }
1978 posFreqsToMatrix(posSearch,compactSearch);
1979 posScaling(posSearch, compactSearch);
1980 return posSearch->posMatrix;
1981 }
1982
1983 /* Top-level routine to compute position-specific matrix, when used through
1984 the Web, one round at a time*/
WposComputation(compactSearchItems * compactSearch,SeqAlignPtr listOfSeqAligns,Nlm_FloatHi ** posFreqs)1985 Int4Ptr * LIBCALL WposComputation(compactSearchItems * compactSearch, SeqAlignPtr listOfSeqAligns, Nlm_FloatHi ** posFreqs)
1986 {
1987 posSearchItems *posSearch;
1988 Int4 i, numSeqAligns, numseq, qlength;
1989 Int2 alphabetSize;
1990 Int4Ptr *posMatrix;
1991
1992 /* Why isn't posAllocateMemory() called? */
1993 posSearch = (posSearchItems *) MemNew(1 * sizeof(posSearchItems));
1994 qlength = compactSearch->qlength;
1995 alphabetSize = compactSearch->alphabetSize;
1996
1997 if (listOfSeqAligns != NULL) {
1998 numSeqAligns = countSeqAligns(listOfSeqAligns, &numseq, FALSE, 0.0);
1999 countNumSeq(posSearch, compactSearch, listOfSeqAligns, &numseq);
2000 posAllocateMemory(posSearch, alphabetSize,
2001 qlength, numseq);
2002 posDemographics(posSearch, compactSearch, listOfSeqAligns);
2003 posPurgeMatches(posSearch, compactSearch, NULL);
2004 posComputeExtents(posSearch, compactSearch);
2005 posComputeSequenceWeights(posSearch, compactSearch, 1.0);
2006 posCheckWeights(posSearch, compactSearch);
2007 posSearch->posFreqs = posComputePseudoFreqs(posSearch, compactSearch,
2008 FALSE);
2009 copyPosFreqs(posSearch->posFreqs,posFreqs, qlength, alphabetSize);
2010 } else {
2011 /* Assume that posFreqs are already filled, use them to calculate
2012 posMatrix.
2013 If listOfSeqAligns is NULL as a result of search, all frequencies are
2014 0 anyway, so there is no need to compute them. However if it is
2015 deliberately passed as NULL before search, this means that posFreqs
2016 are passed as input from PSSM.
2017 */
2018 posSearch->posFreqs = posFreqs;
2019 ASSERT(compactSearch->standardMatrixName);
2020 posSearch->stdFreqRatios =
2021 PSIMatrixFrequencyRatiosNew(compactSearch->standardMatrixName);
2022 posSearch->posMatrix = (BLAST_Score **) MemNew((qlength + 1) * sizeof(BLAST_Score *));
2023 posSearch->posPrivateMatrix = (BLAST_Score **) MemNew((qlength + 1) * sizeof(BLAST_Score *));
2024 for(i = 0; i <= qlength; i++) {
2025 posSearch->posMatrix[i] = (BLAST_Score *) MemNew(alphabetSize * sizeof(BLAST_Score));
2026 posSearch->posPrivateMatrix[i] = (BLAST_Score *) MemNew(alphabetSize * sizeof(BLAST_Score));
2027 }
2028 }
2029 posFreqsToMatrix(posSearch,compactSearch);
2030 posScaling(posSearch, compactSearch);
2031 posMatrix = posSearch->posMatrix;
2032
2033 /* Why isn't posFreeMemory() called? */
2034 if (listOfSeqAligns != NULL) {
2035 for(i = 0; i <= qlength ; i++) {
2036 MemFree(posSearch->posFreqs[i]);
2037 MemFree(posSearch->posMatchWeights[i]);
2038 MemFree(posSearch->posC[i]);
2039 }
2040
2041 MemFree(posSearch->posFreqs);
2042 MemFree(posSearch->posMatchWeights);
2043 MemFree(posSearch->posC);
2044 MemFree(posSearch->posA);
2045 MemFree(posSearch->posExtents);
2046 MemFree(posSearch->posSigma);
2047 MemFree(posSearch->posRowSigma);
2048 MemFree(posSearch->posIntervalSizes);
2049 MemFree(posSearch->posCount);
2050
2051 for(i = 0; i <= posSearch->posDescMatrixLength; i++) {
2052 MemFree(posSearch->posDescMatrix[i]);
2053 }
2054 MemFree(posSearch->posDescMatrix);
2055 }
2056
2057 for(i = 0; i <= qlength ; i++)
2058 MemFree(posSearch->posPrivateMatrix[i]);
2059 MemFree(posSearch->posPrivateMatrix);
2060 posSearch->stdFreqRatios = PSIMatrixFrequencyRatiosFree(posSearch->stdFreqRatios);
2061 MemFree(posSearch);
2062
2063 return posMatrix;
2064 }
2065
2066
getRes(Char input)2067 static Char getRes(Char input)
2068 {
2069 switch(input)
2070 {
2071 case 0:
2072 return('-');
2073 case 1:
2074 return('A');
2075 case 2:
2076 return('B');
2077 case 3:
2078 return('C');
2079 case 4:
2080 return('D');
2081 case 5:
2082 return('E');
2083 case 6:
2084 return('F');
2085 case 7:
2086 return('G');
2087 case 8:
2088 return('H');
2089 case 9:
2090 return('I');
2091 case 10:
2092 return('K');
2093 case 11:
2094 return('L');
2095 case 12:
2096 return('M');
2097 case 13:
2098 return('N');
2099 case 14:
2100 return('P');
2101 case 15:
2102 return('Q');
2103 case 16:
2104 return('R');
2105 case 17:
2106 return('S');
2107 case 18:
2108 return('T');
2109 case 19:
2110 return('V');
2111 case 20:
2112 return('W');
2113 case 21:
2114 return('X');
2115 case 22:
2116 return('Y');
2117 case 23:
2118 return('Z');
2119 case 24:
2120 return('U');
2121 case 25:
2122 return('*');
2123 case 26:
2124 return('O');
2125 case 27:
2126 return('J');
2127 default:
2128 return('?');
2129 }
2130 }
ResToInt(Char input)2131 Uint1 LIBCALL ResToInt(Char input)
2132 {
2133 switch(input)
2134 {
2135 case '-':
2136 return(0);
2137 case 'A':
2138 return(1);
2139 case 'B':
2140 return(2);
2141 case 'C':
2142 return(3);
2143 case 'D':
2144 return(4);
2145 case 'E':
2146 return(5);
2147 case 'F':
2148 return(6);
2149 case 'G':
2150 return(7);
2151 case 'H':
2152 return(8);
2153 case 'I':
2154 return(9);
2155 case 'K':
2156 return(10);
2157 case 'L':
2158 return(11);
2159 case 'M':
2160 return(12);
2161 case 'N':
2162 return(13);
2163 case 'P':
2164 return(14);
2165 case 'Q':
2166 return(15);
2167 case 'R':
2168 return(16);
2169 case 'S':
2170 return(17);
2171 case 'T':
2172 return(18);
2173 case 'V':
2174 return(19);
2175 case 'W':
2176 return(20);
2177 case 'X':
2178 return(21);
2179 case 'Y':
2180 return(22);
2181 case 'Z':
2182 return(23);
2183 case 'U':
2184 return(24);
2185 case '*':
2186 return(25);
2187 case 'O':
2188 return(26);
2189 case 'J':
2190 return(27);
2191 default:
2192 return(-1);
2193 }
2194 }
2195
2196
2197 /*Print out the position-specific matrix*/
outputPosMatrix(posSearchItems * posSearch,compactSearchItems * compactSearch,FILE * matrixfp,Boolean posComputationCalled)2198 void LIBCALL outputPosMatrix(posSearchItems *posSearch, compactSearchItems *compactSearch, FILE *matrixfp, Boolean posComputationCalled)
2199 {
2200 Uint1Ptr q; /*query sequence*/
2201 Int4 i; /*loop indices*/
2202 Int4 c; /*index over alphabet*/
2203 Int4 length; /*length of query*/
2204 Int4 charOrder[EFFECTIVE_ALPHABET]; /*standard order of letters according to S. Altschul*/
2205
2206 if (compactSearch->alphabetSize != PROTEIN_ALPHABET){
2207 ErrPostEx(SEV_ERROR, 0, 0, "\nCannot print diagnostic information because alphabet size is not %ld", (long) compactSearch->alphabetSize);
2208 return;
2209 }
2210
2211 charOrder[0] = 1; /*A*/
2212 charOrder[1] = 16; /*R*/
2213 charOrder[2] = 13; /*N*/
2214 charOrder[3] = 4; /*D*/
2215 charOrder[4] = 3; /*C*/
2216 charOrder[5] = 15; /*Q*/
2217 charOrder[6] = 5; /*E*/
2218 charOrder[7] = 7; /*G*/
2219 charOrder[8] = 8; /*H*/
2220 charOrder[9] = 9; /*I*/
2221 charOrder[10] = 11; /*L*/
2222 charOrder[11] = 10; /*K*/
2223 charOrder[12] = 12; /*M*/
2224 charOrder[13] = 6; /*F*/
2225 charOrder[14] = 14; /*P*/
2226 charOrder[15] = 17; /*S*/
2227 charOrder[16] = 18; /*T*/
2228 charOrder[17] = 20; /*W*/
2229 charOrder[18] = 22; /*Y*/
2230 charOrder[19] = 19; /*V*/
2231
2232 q = compactSearch->query;
2233 length = compactSearch->qlength;
2234
2235 /* Used ifdef until final decision is made on output. */
2236
2237 #ifdef POSIT_DEBUG
2238 printf("\nCharacter Frequencies by positon\n");
2239 printf(" ");
2240 for (c = 0; c< EFFECTIVE_ALPHABET; c++)
2241 printf(" %c",getRes((Char) charOrder[c]));
2242 for(i=0; i < length; i++) {
2243 printf("\n%5d %c ", i + 1, getRes(q[i]));
2244 for (c = 0; c < EFFECTIVE_ALPHABET; c++)
2245 printf("%2d ", posSearch->posC[i][charOrder[c]]);
2246 }
2247 printf("\n\n");
2248 printf("\nposition counts used. multiplied by 10 and rounded and");
2249 printf("\nposition character weights used, multiplied by 10 and rounded\n");
2250 printf(" Counts");
2251 for (c = 0; c< EFFECTIVE_ALPHABET; c++)
2252 printf(" %c",getRes((Char) charOrder[c]));
2253 printf(" Extent ");
2254 for(i=0; i < length; i++) {
2255 printf("\n%5d %c ", i + 1, getRes(q[i]));
2256 if ((posSearch->posCount[i] > 1) && (Xchar != q[i]))
2257 printf("%4d ", (Int4) posit_rounddown(10 * countsFunction
2258 (posSearch->posSigma[i],posSearch->posIntervalSizes[i])));
2259 else
2260 printf(" ");
2261 for (c = 0; c< EFFECTIVE_ALPHABET; c++)
2262 if((posSearch->posMatrix[i][charOrder[c]] == BLAST_SCORE_MIN) ||
2263 (0.0 == posSearch->posMatchWeights[i][charOrder[c]]))
2264 printf(" - ");
2265 else
2266 printf("%2d ", (Int4) posit_rounddown(10 * posSearch->posMatchWeights[i][charOrder[c]]));
2267 printf(" %4d",posSearch->posExtents[i].rightExtent - posSearch->posExtents[i].leftExtent +1);
2268 }
2269 printf("\n\n");
2270 #endif
2271 if (NULL != matrixfp) {
2272 if (posComputationCalled) {
2273 fprintf(matrixfp,"\nLast position-specific scoring matrix computed, weighted observed percentages rounded down, information per position, and relative weight of gapless real matches to pseudocounts\n");
2274 }
2275 else {
2276 fprintf(matrixfp,"\nLast position-specific scoring matrix computed\n");
2277 }
2278 fprintf(matrixfp," ");
2279 for (c = 0; c< EFFECTIVE_ALPHABET; c++)
2280 fprintf(matrixfp," %c",getRes((Char) charOrder[c]));
2281 if (posComputationCalled) {
2282 for (c = 0; c< EFFECTIVE_ALPHABET; c++)
2283 fprintf(matrixfp," %c",getRes((Char) charOrder[c]));
2284 }
2285 for(i=0; i < length; i++) {
2286 fprintf(matrixfp,"\n%5ld %c ", (long) (i + 1), getRes(q[i]));
2287 /*fprintf(matrixfp,"\n ");*/
2288 for (c = 0; c < EFFECTIVE_ALPHABET; c++)
2289 if(posSearch->posMatrix[i][charOrder[c]] == BLAST_SCORE_MIN)
2290 fprintf(matrixfp,"-I ");
2291 else
2292 fprintf(matrixfp,"%2ld ", (long) posSearch->posMatrix[i][charOrder[c]]);
2293 if (posComputationCalled) {
2294 for (c = 0; c < EFFECTIVE_ALPHABET; c++)
2295 if(posSearch->posMatrix[i][charOrder[c]] != BLAST_SCORE_MIN)
2296 fprintf(matrixfp, "%4d", (Int4) posit_rounddown(100 * posSearch->posMatchWeights[i][charOrder[c]]));
2297 fprintf(matrixfp," %5.2f", posSearch->posInformation[i]);
2298 if ((posSearch->posCount[i] > 1) && (Xchar != q[i]))
2299 fprintf(matrixfp," %.2f", countsFunction(posSearch->posSigma[i],
2300 posSearch->posIntervalSizes[i]) *
2301 posSearch->posGaplessColumnWeights[i]/
2302 posSearch->pseudoWeights[i]);
2303 else
2304 fprintf(matrixfp," 0.00");
2305 }
2306 }
2307 fprintf(matrixfp,"\n\n");
2308 fprintf(matrixfp," K Lambda\n");
2309 fprintf(matrixfp,"Standard Ungapped %6.4f %6.4f\n",compactSearch->kbp_std[0]->K,compactSearch->kbp_std[0]->Lambda);
2310 fprintf(matrixfp,"Standard Gapped %6.4f %6.4f\n",compactSearch->kbp_gap_std[0]->K,compactSearch->kbp_gap_std[0]->Lambda);
2311 fprintf(matrixfp,"PSI Ungapped %6.4f %6.4f\n",compactSearch->kbp_psi[0]->K,compactSearch->kbp_psi[0]->Lambda);
2312 fprintf(matrixfp,"PSI Gapped %6.4f %6.4f\n",compactSearch->kbp_gap_psi[0]->K,compactSearch->kbp_gap_psi[0]->Lambda);
2313 }
2314 }
2315
2316
posPrintInformation(posSearchItems * posSearch,BlastSearchBlkPtr search,Int4 passNum)2317 void LIBCALL posPrintInformation(posSearchItems *posSearch, BlastSearchBlkPtr search, Int4 passNum)
2318 {
2319 Int4 querySize;
2320
2321 querySize = search->context[0].query->length;
2322
2323 /* Used ifdef until final decision is made on output. */
2324 #ifdef POSIT_DEBUG
2325 {{
2326 Int4 c;
2327
2328 printf("\nInformation content by position for pass %d\n", passNum);
2329 for(c = 0; c < querySize; c++)
2330 printf(" %5d", c);
2331 printf("\n");
2332 for(c = 0; c < querySize; c++)
2333 printf(" %5.2lf", posSearch->posInformation[c]);
2334 printf("\n");
2335 }}
2336 #endif
2337 }
2338
posInitializeInformation(posSearchItems * posSearch,BlastSearchBlkPtr search)2339 void LIBCALL posInitializeInformation(posSearchItems *posSearch, BlastSearchBlkPtr search)
2340 {
2341 Uint1Ptr query;
2342 Int4 querySize;
2343 Int4 c, a, alphabetSize;
2344 BLAST_ScoreBlkPtr sbp;
2345 BLAST_ResFreqPtr stdrfp; /*standard frequencies*/
2346 Nlm_FloatHi lambda;
2347 Nlm_FloatHi term1, term2, term3, term4;
2348 Nlm_FloatHi infoSum;
2349
2350 querySize = search->context[0].query->length;
2351 query = search->context[0].query->sequence;
2352 posSearch->posInformation = (Nlm_FloatHi *) MemNew(querySize * sizeof(Nlm_FloatHi));
2353 if (NULL == posSearch->posInformation)
2354 exit(EXIT_FAILURE);
2355 for(c = 0; c < querySize; c++)
2356 posSearch->posInformation[c] = 0.0;
2357 alphabetSize = search->sbp->alphabet_size;
2358 /*Compute standard frequencies as in BlastScoreBlkFill in blastkar.c*/
2359 sbp = search->sbp;
2360 stdrfp = BlastResFreqNew(sbp);
2361 BlastResFreqStdComp(sbp,stdrfp);
2362 lambda = search->sbp->kbp[0]->Lambda;
2363 for(c = 0; c < querySize; c++) {
2364 infoSum = 0;
2365 for(a = 0; a < alphabetSize; a++)
2366 if (stdrfp->prob[a] > posEpsilon) {
2367 term1 = search->sbp->matrix[query[c]][a];
2368 term2 = term1 * lambda;
2369 term3 = exp(term2);
2370 term4 = stdrfp->prob[a] * term3;
2371 infoSum += term4 * log(term4/stdrfp->prob[a])/NCBIMATH_LN2;
2372 }
2373 posSearch->posInformation[c] = infoSum;
2374 }
2375 BlastResFreqFree(stdrfp);
2376 }
2377
2378 /*
2379 Is this function used?
2380 */
2381
posFreeInformation(posSearchItems * posSearch)2382 void LIBCALL posFreeInformation(posSearchItems *posSearch)
2383 {
2384 MemFree(posSearch->posInformation);
2385 }
2386
2387 /*Copy a few fields from the lasrge record search into the small record
2388 compactSearch, so that a small amount of information
2389 is passed into posit.c*/
copySearchItems(compactSearchItems * compactSearch,BlastSearchBlkPtr search,char * matrixName)2390 void LIBCALL copySearchItems(compactSearchItems * compactSearch, BlastSearchBlkPtr search, char * matrixName)
2391 {
2392 BLAST_ResFreqPtr stdrfp; /* gets standard frequencies in prob field */
2393 Int4 a; /*index over characters*/
2394
2395 compactSearch->query = search->context[0].query->sequence;
2396 compactSearch->qlength = search->context[0].query->length;
2397 compactSearch->gapped_calculation = search->pbp->gapped_calculation;
2398 compactSearch->alphabetSize = search->sbp->alphabet_size;
2399 compactSearch->pseudoCountConst = search->pbp->pseudoCountConst;
2400 compactSearch->ethresh = search->pbp->ethresh;
2401 compactSearch->lambda = search->sbp->kbp[0]->Lambda;
2402 compactSearch->matrix = search->sbp->matrix;
2403 compactSearch->kbp_psi = search->sbp->kbp_psi;
2404 compactSearch->kbp_gap_psi = search->sbp->kbp_gap_psi;
2405 compactSearch->kbp_std = search->sbp->kbp_std;
2406 compactSearch->kbp_gap_std = search->sbp->kbp_gap_std;
2407 if (search->pbp->gapped_calculation) {
2408 compactSearch->lambda_ideal = search->sbp->kbp_ideal->Lambda;
2409 compactSearch->K_ideal = search->sbp->kbp_ideal->K;
2410 }
2411 else {
2412 compactSearch->lambda_ideal = search->sbp->kbp[0] ->Lambda;
2413 compactSearch->K_ideal = search->sbp->kbp[0]->K;
2414 }
2415 compactSearch->use_best_align = search->pbp->use_best_align;
2416
2417 stdrfp = BlastResFreqNew(search->sbp);
2418 BlastResFreqStdComp(search->sbp,stdrfp);
2419 compactSearch->standardProb = MemNew(compactSearch->alphabetSize * sizeof(Nlm_FloatHi));
2420 if (NULL == compactSearch->standardProb)
2421 exit(EXIT_FAILURE);
2422 for(a = 0; a < compactSearch->alphabetSize; a++)
2423 compactSearch->standardProb[a] = stdrfp->prob[a];
2424 stdrfp = BlastResFreqDestruct(stdrfp);
2425 strcpy(compactSearch->standardMatrixName,matrixName);
2426 }
2427
2428 /*allocate memory for a record of type compactSearchItems*/
compactSearchNew(compactSearchItems * compactSearch)2429 compactSearchItems * LIBCALL compactSearchNew(compactSearchItems * compactSearch)
2430 {
2431 compactSearch = MemNew(1 * sizeof(compactSearchItems));
2432 if (NULL == compactSearch)
2433 exit(EXIT_FAILURE);
2434 return(compactSearch);
2435 }
2436
2437 /*De-allocate memory for a record of type compactSearchItems*/
compactSearchDestruct(compactSearchItems * compactSearch)2438 void LIBCALL compactSearchDestruct(compactSearchItems * compactSearch)
2439 {
2440
2441 MemFree(compactSearch->standardProb);
2442 MemFree(compactSearch);
2443 }
2444
2445 /*Some of the following checkpointing code is taken and adapted from
2446 code written by K. Shriram for FASTLINK.
2447 Reference:
2448 A. A. Schaffer, S. K. Gupta, K. Shriram, and R. W. Cottingham, Jr.
2449 Avoiding Recomputation in Linkage Analysis,
2450 Human Heredity 44(1994), pp. 225-237. */
2451
2452
2453 #define putCkptNlm_FloatHi(d, ckptFile) (putCkptNumber(&(d),sizeof(Nlm_FloatHi),ckptFile))
2454 #define putCkptInt4(i, ckptFile) (putCkptNumber(&(i),sizeof(Int4),ckptFile))
2455 #define putCkptChar(c, ckptFile) (putCkptNumber(&(c),sizeof(Char),ckptFile))
2456
2457 /* General routine for putting the internal representation of a number. */
2458
putCkptNumber(void * numberPtr,Int4 numberSize,FILE * ckptFile)2459 static void putCkptNumber(void * numberPtr, Int4 numberSize, FILE * ckptFile )
2460 {
2461 FileWrite(numberPtr,numberSize,1,ckptFile) ;
2462 }
2463
2464 /*Code to put a vector of frequencies; put only the interesting
2465 entries*/
putFreqVector(Nlm_FloatHi * theVector,Int4 length,FILE * ckptFile)2466 static void putFreqVector(Nlm_FloatHi * theVector, Int4 length, FILE * ckptFile)
2467 {
2468 int vectorRef;
2469 Int4 charOrder[EFFECTIVE_ALPHABET]; /*standard order of letters according to S. Altschul*/
2470
2471
2472 charOrder[0] = 1; /*A*/
2473 charOrder[1] = 16; /*R*/
2474 charOrder[2] = 13; /*N*/
2475 charOrder[3] = 4; /*D*/
2476 charOrder[4] = 3; /*C*/
2477 charOrder[5] = 15; /*Q*/
2478 charOrder[6] = 5; /*E*/
2479 charOrder[7] = 7; /*G*/
2480 charOrder[8] = 8; /*H*/
2481 charOrder[9] = 9; /*I*/
2482 charOrder[10] = 11; /*L*/
2483 charOrder[11] = 10; /*K*/
2484 charOrder[12] = 12; /*M*/
2485 charOrder[13] = 6; /*F*/
2486 charOrder[14] = 14; /*P*/
2487 charOrder[15] = 17; /*S*/
2488 charOrder[16] = 18; /*T*/
2489 charOrder[17] = 20; /*W*/
2490 charOrder[18] = 22; /*Y*/
2491 charOrder[19] = 19; /*V*/
2492
2493
2494 for(vectorRef = 0; vectorRef < EFFECTIVE_ALPHABET; vectorRef++)
2495 putCkptNlm_FloatHi(theVector[charOrder[vectorRef]],ckptFile);
2496 }
2497
2498
2499 /* Code to put a matrix, vector-by-vector. */
putCkptFreqMatrix(Nlm_FloatHi ** theMatrix,Int4 length,Int4 width,FILE * ckptFile)2500 static void putCkptFreqMatrix (Nlm_FloatHi **theMatrix, Int4 length, Int4 width, FILE * ckptFile)
2501 {
2502 int matrixRef; /*loop index*/
2503
2504 for (matrixRef = 0; matrixRef < length ; matrixRef++ )
2505 putFreqVector(theMatrix[matrixRef], width, ckptFile);
2506 }
2507
2508
2509 /* General routine for getting the internal representation of a number. */
2510
getCkptNumber(void * numberPtr,Int4 numberSize,FILE * ckptFile)2511 void LIBCALL getCkptNumber(void * numberPtr, Int4 numberSize, FILE * ckptFile )
2512 {
2513 FileRead(numberPtr,numberSize,1,ckptFile) ;
2514 }
2515
getFreqVector(Nlm_FloatHi * theVector,Int4 length,FILE * ckptFile)2516 static void getFreqVector (Nlm_FloatHi * theVector, Int4 length, FILE * ckptFile)
2517 {
2518 int vectorRef ;
2519
2520 Int4 charOrder[EFFECTIVE_ALPHABET]; /*standard order of letters according to S. Altschul*/
2521
2522
2523 charOrder[0] = 1; /*A*/
2524 charOrder[1] = 16; /*R*/
2525 charOrder[2] = 13; /*N*/
2526 charOrder[3] = 4; /*D*/
2527 charOrder[4] = 3; /*C*/
2528 charOrder[5] = 15; /*Q*/
2529 charOrder[6] = 5; /*E*/
2530 charOrder[7] = 7; /*G*/
2531 charOrder[8] = 8; /*H*/
2532 charOrder[9] = 9; /*I*/
2533 charOrder[10] = 11; /*L*/
2534 charOrder[11] = 10; /*K*/
2535 charOrder[12] = 12; /*M*/
2536 charOrder[13] = 6; /*F*/
2537 charOrder[14] = 14; /*P*/
2538 charOrder[15] = 17; /*S*/
2539 charOrder[16] = 18; /*T*/
2540 charOrder[17] = 20; /*W*/
2541 charOrder[18] = 22; /*Y*/
2542 charOrder[19] = 19; /*V*/
2543
2544 for(vectorRef = 0; vectorRef < length; vectorRef++)
2545 theVector[vectorRef] = 0;
2546 for(vectorRef = 0; vectorRef < EFFECTIVE_ALPHABET; vectorRef++)
2547 getCkptNlm_FloatHi(theVector[charOrder[vectorRef]],ckptFile) ;
2548 }
2549
2550 /* Code to frequency matrix, vector-by-vector. */
2551
getCkptFreqMatrix(Nlm_FloatHi ** theMatrix,Int4 length,Int4 width,FILE * ckptFile)2552 void LIBCALL getCkptFreqMatrix (Nlm_FloatHi ** theMatrix, Int4 length, Int4 width, FILE * ckptFile)
2553 {
2554 Int4 matrixRef; /*loop index*/
2555
2556 for (matrixRef = 0; matrixRef < length ; matrixRef++ )
2557 getFreqVector(theMatrix[matrixRef], width, ckptFile);
2558 }
2559
2560 /*Take a checkpoint at the end of the current PSI-BLAST round, stores
2561 query length, query, and position-specific target frequencies.
2562 Returns TRUE if checkpoint was sucessful and FALSE otherwise. */
posTakeCheckpoint(posSearchItems * posSearch,compactSearchItems * compactSearch,CharPtr fileName,ValNodePtr * error_return)2563 Boolean LIBCALL posTakeCheckpoint(posSearchItems * posSearch, compactSearchItems * compactSearch, CharPtr fileName, ValNodePtr *error_return)
2564 {
2565 FILE * checkFile; /*file in which to take the checkpoint*/
2566 Int4 length; /*length of query sequence, and an index for it*/
2567 Int4 i; /*indices to position and alphabet */
2568 Char localChar; /*temporary character*/
2569
2570 checkFile = FileOpen(fileName, "wb");
2571 if (NULL == checkFile) {
2572 BlastConstructErrorMessage("posTakeCheckpoint", "Could not open checkpoint file", 1, error_return);
2573 return(FALSE);
2574 }
2575 length = compactSearch->qlength;
2576 putCkptInt4(length, checkFile);
2577 for(i = 0; i < length; i++) {
2578 localChar = getRes(compactSearch->query[i]);
2579 putCkptChar(localChar, checkFile);
2580 }
2581 putCkptFreqMatrix(posSearch->posFreqs,length,compactSearch->alphabetSize, checkFile);
2582 FileClose(checkFile);
2583 return(TRUE);
2584 }
2585
2586 /* Like posTakeCheckpoint, posTakeScoremat will emit the position
2587 frequencies that have been generated. Unlike that routine, the
2588 file to be written is an ASN.1 encoded PssmWithParameters object. */
2589
posTakeScoremat(posSearchItems * posSearch,compactSearchItems * compactSearch,CharPtr filename,Int4 scorematOutput,Bioseq * query_bsp,Int4 gap_open,Int4 gap_extend,ValNodePtr * error_return)2590 Boolean LIBCALL posTakeScoremat(posSearchItems *posSearch,
2591 compactSearchItems *compactSearch,
2592 CharPtr filename, Int4 scorematOutput,
2593 Bioseq *query_bsp, Int4 gap_open,
2594 Int4 gap_extend, ValNodePtr *error_return)
2595 {
2596 AsnIoPtr outfile = NULL;
2597 PssmWithParametersPtr scoremat = NULL;
2598 PssmIntermediateDataPtr freqs = NULL;
2599 PssmParametersPtr params = NULL;
2600 FormatRpsDbParametersPtr rpsparams = NULL;
2601 PssmPtr pssm = NULL;
2602 Int4 i, j;
2603 Boolean status = FALSE;
2604
2605 scoremat = PssmWithParametersNew();
2606 if (scoremat == NULL) {
2607 BlastConstructErrorMessage("posTakeScoremat",
2608 "Could not allocate PssmWithParameters", 1, error_return);
2609 goto bail_out;
2610 }
2611
2612 /* Add information about the underlying score matrix.
2613 Note that blastpgp will ignore this information */
2614
2615 params = scoremat->params = PssmParametersNew();
2616 if (params == NULL) {
2617 BlastConstructErrorMessage("posTakeScoremat",
2618 "Could not allocate PssmParameters", 1, error_return);
2619 goto bail_out;
2620 }
2621 rpsparams = params->rpsdbparams = FormatRpsDbParametersNew();
2622 if (params == NULL) {
2623 BlastConstructErrorMessage("posTakeScoremat",
2624 "Could not allocate RpsDbParameters", 1, error_return);
2625 goto bail_out;
2626 }
2627 rpsparams->matrixName = strdup(compactSearch->standardMatrixName);
2628 rpsparams->gapOpen = gap_open;
2629 rpsparams->gapExtend = gap_extend;
2630
2631 /* Build up the objects describing the frequency ratios */
2632
2633 pssm = scoremat->pssm = PssmNew();
2634 if (pssm == NULL) {
2635 BlastConstructErrorMessage("posTakeScoremat",
2636 "Could not allocate PSSM object", 1, error_return);
2637 goto bail_out;
2638 }
2639 freqs = pssm->intermediateData = PssmIntermediateDataNew();
2640 if (freqs == NULL) {
2641 BlastConstructErrorMessage("posTakeScoremat",
2642 "Could not allocate PssmIntermediateData", 1, error_return);
2643 goto bail_out;
2644 }
2645
2646 pssm->isProtein = TRUE;
2647 pssm->numRows = compactSearch->alphabetSize;
2648 pssm->numColumns = compactSearch->qlength;
2649
2650 for (i = 0; i < pssm->numColumns; i++) {
2651 for (j = 0; j < pssm->numRows; j++) {
2652 ValNodeAddFloat(&freqs->freqRatios, 0, posSearch->posFreqs[i][j]);
2653 }
2654 }
2655
2656 /* Do not make a copy of the query bioseq; use it directly.
2657 The '1' below indicates a single bioseq (not a bioseq-set) */
2658
2659 ValNodeAddPointer(&pssm->query, 1, query_bsp);
2660 if (pssm->query == NULL) {
2661 BlastConstructErrorMessage("posTakeScoremat",
2662 "Could not attach bioseq to scoremat", 1, error_return);
2663 goto bail_out;
2664 }
2665
2666 if (scorematOutput == ASCII_SCOREMAT)
2667 outfile = AsnIoOpen(filename, "w");
2668 else
2669 outfile = AsnIoOpen(filename, "wb");
2670
2671 if (outfile == NULL) {
2672 ErrPostEx(SEV_FATAL, 1, 0, "Unable to open matrix output file %s\n",
2673 filename);
2674 goto bail_out;
2675 }
2676
2677 PssmWithParametersAsnWrite(scoremat, outfile, NULL);
2678 status = TRUE;
2679
2680 bail_out:
2681 AsnIoClose(outfile);
2682
2683 /* explicitly free the ValNode pointing to the query bioseq.
2684 This will prevent the ScoreMatrix freeing routine
2685 from also freeing the query bioseq, which we did not
2686 allocate */
2687
2688 pssm->query = ValNodeFree(pssm->query);
2689
2690 /* free everything else */
2691
2692 scoremat = PssmWithParametersFree(scoremat);
2693 return status;
2694 }
2695
posReadPosFreqsScoremat(posSearchItems * posSearch,compactSearchItems * compactSearch,CharPtr fileName,Int4 scorematInput,ValNodePtr * error_return)2696 static Boolean LIBCALL posReadPosFreqsScoremat(posSearchItems * posSearch, compactSearchItems * compactSearch, CharPtr fileName, Int4 scorematInput, ValNodePtr * error_return)
2697 {
2698 AsnIoPtr infile = NULL;
2699 PssmWithParametersPtr scoremat = NULL;
2700 PssmPtr pssm = NULL;
2701 PssmIntermediateDataPtr freqs = NULL;
2702 Int4 i, j, c;
2703 ValNodePtr freq_list;
2704 Bioseq *bsp;
2705
2706 if (scorematInput == ASCII_SCOREMAT)
2707 infile = AsnIoOpen(fileName, "r");
2708 else
2709 infile = AsnIoOpen(fileName, "rb");
2710
2711 if (infile == NULL) {
2712 ErrPostEx(SEV_WARNING, 0, 0,"Could not open scoremat file\n");
2713 return FALSE;
2714 }
2715
2716 scoremat = PssmWithParametersAsnRead(infile, NULL);
2717 AsnIoClose(infile);
2718 if (scoremat == NULL) {
2719 ErrPostEx(SEV_WARNING, 0, 0, "Could not read scoremat from input file\n");
2720 return FALSE;
2721 }
2722 pssm = scoremat->pssm;
2723 if (pssm == NULL) {
2724 ErrPostEx(SEV_WARNING, 0, 0,"Scoremat is empty\n");
2725 PssmWithParametersFree(scoremat);
2726 return FALSE;
2727 }
2728 freqs = pssm->intermediateData;
2729 if (freqs == NULL) {
2730 ErrPostEx(SEV_WARNING, 0, 0,"Scoremat doesn't contain intermediate data\n");
2731 PssmWithParametersFree(scoremat);
2732 return FALSE;
2733 }
2734 if (freqs->freqRatios == NULL) {
2735 ErrPostEx(SEV_WARNING, 0, 0,
2736 "Scoremat does not contain frequency ratios\n");
2737 PssmWithParametersFree(scoremat);
2738 return FALSE;
2739 }
2740 if (pssm->numRows != compactSearch->alphabetSize) {
2741 ErrPostEx(SEV_WARNING, 0, 0, "Wrong alphabet size of %d in "
2742 "input scoremat\n", pssm->numRows);
2743 PssmWithParametersFree(scoremat);
2744 return FALSE;
2745 }
2746 if (!pssm->query || !pssm->query->data.ptrvalue) {
2747 ErrPostEx(SEV_WARNING, 0, 0, "Missing sequence data in input scoremat\n");
2748 PssmWithParametersFree(scoremat);
2749 return FALSE;
2750 }
2751 bsp = (Bioseq *)(pssm->query->data.ptrvalue);
2752 if (pssm->numColumns != bsp->length) {
2753 ErrPostEx(SEV_WARNING, 0, 0, "Different sequence lengths "
2754 "(%d and %d) in input scoremat\n", pssm->numColumns, bsp->length);
2755 PssmWithParametersFree(scoremat);
2756 return FALSE;
2757 }
2758 if (pssm->numColumns != compactSearch->qlength) {
2759 ErrPostEx(SEV_WARNING, 0, 0, "Scoremat sequence length "
2760 "(%d) does not match query length (%d)\n",
2761 pssm->numColumns, compactSearch->qlength);
2762 PssmWithParametersFree(scoremat);
2763 return FALSE;
2764 }
2765 if (!bsp->seq_data || !ISA_aa(bsp->mol)) {
2766 ErrPostEx(SEV_WARNING, 0, 0,
2767 "Sequence within checkpoint file has no data or is not protein\n");
2768 PssmWithParametersFree(scoremat);
2769 return FALSE;
2770 }
2771 if (bsp->seq_data_type == Seq_code_gap) {
2772 ErrPostEx(SEV_WARNING, 0, 0,
2773 "Seq_code_gap passed to posReadPosFreqsScoremat\n");
2774 PssmWithParametersFree(scoremat);
2775 return FALSE;
2776 }
2777 BSSeek((ByteStorePtr) bsp->seq_data, 0, SEEK_SET);
2778
2779 /* Convert sequence data into Seq_code_ncbistdaa */
2780 if (bsp->seq_data_type != Seq_code_ncbistdaa) {
2781
2782 ByteStore* new_byte_store = BSConvertSeq((ByteStorePtr) bsp->seq_data,
2783 Seq_code_ncbistdaa,
2784 bsp->seq_data_type,
2785 bsp->length);
2786
2787 if ( !new_byte_store ) {
2788 ErrPostEx(SEV_FATAL, 1, 0, "Failed to convert Bioseq in ASN.1 PSSM "
2789 "to Seq_code_ncbistdaa");
2790 }
2791
2792 bsp->seq_data = (SeqDataPtr) new_byte_store;
2793 bsp->seq_data_type = Seq_code_ncbistdaa;
2794 BSSeek((ByteStorePtr) bsp->seq_data, 0, SEEK_SET);
2795
2796 }
2797
2798 /* verify the input query is the same as the sequence
2799 within the checkpoint file */
2800
2801 for (i = 0; i < compactSearch->qlength; i++) {
2802 c = BSGetByte((ByteStorePtr) bsp->seq_data);
2803 if (c == EOF) {
2804 ErrPostEx(SEV_WARNING, 0, 0, "Premature end of sequence data\n");
2805 PssmWithParametersFree(scoremat);
2806 return FALSE;
2807 }
2808 if (c != compactSearch->query[i]) {
2809 if (compactSearch->query[i] == Xchar) {
2810 ErrPostEx(SEV_WARNING, 0, 0,
2811 "Query sequence contains '%c' at position %d; "
2812 "if filtering was used, rerun the search with "
2813 "filtering turned off ('-F F')\n", getRes(Xchar), i);
2814 }
2815 else {
2816 ErrPostEx(SEV_WARNING, 0, 0,
2817 "Query sequence contains '%c' at position %d, "
2818 "while sequence withing checkpoint file contains "
2819 "'%c' at this position\n",
2820 getRes(compactSearch->query[i]), i, getRes(c));
2821 }
2822 PssmWithParametersFree(scoremat);
2823 return FALSE;
2824 }
2825 }
2826
2827 /* Read in the frequency ratios, verify they fall
2828 in the correct range, and verify that the linked list
2829 of residue frequencies is exactly as long as it should be */
2830
2831 freq_list = freqs->freqRatios;
2832 if (pssm->byRow == FALSE) {
2833 for (i = 0; i < pssm->numColumns; i++) {
2834 for (j = 0; j < pssm->numRows; j++) {
2835 if (freq_list == NULL)
2836 break;
2837 posSearch->posFreqs[i][j] = freq_list->data.realvalue;
2838
2839 if (posSearch->posFreqs[i][j] < 0.0) {
2840 ErrPostEx(SEV_WARNING, 0, 0, "position frequency (%d,%d) "
2841 "out of bounds\n", i, j);
2842 PssmWithParametersFree(scoremat);
2843 return FALSE;
2844 }
2845
2846 freq_list = freq_list->next;
2847 }
2848 if (j < pssm->numRows)
2849 break;
2850 }
2851 }
2852 else {
2853 for (j = 0; j < pssm->numRows; j++) {
2854 for (i = 0; i < pssm->numColumns; i++) {
2855 if (freq_list == NULL)
2856 break;
2857 posSearch->posFreqs[i][j] = freq_list->data.realvalue;
2858
2859 if (posSearch->posFreqs[i][j] < 0.0) {
2860 ErrPostEx(SEV_WARNING, 0, 0, "position frequency (%d,%d) "
2861 "out of bounds\n", i, j);
2862 PssmWithParametersFree(scoremat);
2863 return FALSE;
2864 }
2865
2866 freq_list = freq_list->next;
2867 }
2868 if (i < pssm->numColumns)
2869 break;
2870 }
2871 }
2872
2873 if (i < pssm->numColumns || j < pssm->numRows) {
2874 ErrPostEx(SEV_WARNING, 0, 0, "Not enough frequency "
2875 "ratios in input scoremat\n");
2876 PssmWithParametersFree(scoremat);
2877 return FALSE;
2878 }
2879 if (freq_list != NULL) {
2880 ErrPostEx(SEV_WARNING, 0, 0, "Too many frequency "
2881 "ratios in input scoremat\n");
2882 PssmWithParametersFree(scoremat);
2883 return FALSE;
2884 }
2885 PssmWithParametersFree(scoremat);
2886 return TRUE;
2887 }
2888
posReadPosFreqsStandard(posSearchItems * posSearch,compactSearchItems * compactSearch,CharPtr fileName,ValNodePtr * error_return)2889 static Boolean posReadPosFreqsStandard(posSearchItems * posSearch, compactSearchItems * compactSearch, CharPtr fileName, ValNodePtr * error_return)
2890 {
2891 FILE * checkFile; /*file in which to take the checkpoint*/
2892 Int4 length1, length2, c; /*length of query sequence, and an index for it*/
2893 Char nextRes; /*next residue in stored copy of the query sequence*/
2894 Uint1Ptr oldQuery; /*array to hold the query sequence*/
2895
2896 length1 = compactSearch->qlength;
2897
2898 checkFile = FileOpen(fileName, "rb");
2899 if (NULL == checkFile) {
2900 BlastConstructErrorMessage("posReadPosFreqsStandard", "Could not open checkpoint file\n", 1, error_return);
2901 return(FALSE);
2902 }
2903 getCkptInt4(length2,checkFile);
2904 if (length1 != length2) {
2905 ErrPostEx(SEV_WARNING, 0, 0, "Invalid usage of checkpoint recovery; old query has length %ld, new query has length %ld", (long) length2, (long) length1);
2906 BlastConstructErrorMessage("posReadPosFreqsStandard", "Failed to recover data\n", 1, error_return);
2907 FileClose(checkFile);
2908 return(FALSE);
2909 }
2910 oldQuery = (Uint1Ptr) MemNew(length1 * sizeof(Uint1));
2911 if (NULL == oldQuery) {
2912 BlastConstructErrorMessage("posReadPosFreqsStandard", "Failed to reconstruct previous query\n", 1, error_return);
2913 BlastConstructErrorMessage("posReadPosFreqsStandard", "Failed to recover data\n", 1, error_return);
2914 FileClose(checkFile);
2915 return(FALSE);
2916 }
2917 for(c = 0; c < length1; c++) {
2918 getCkptChar(nextRes, checkFile);
2919 oldQuery[c] = ResToInt(nextRes);
2920
2921
2922 if ((oldQuery[c] != compactSearch->query[c]) && (oldQuery[c] != Xchar)) {
2923 /* Error massage Added by Natsuhiko */
2924 if (compactSearch->query[c] == Xchar) {
2925 ErrPostEx(SEV_WARNING, 0, 0, "\nStored query has a %c at position %ld, while new query has a %c there.\n%c appears in query sequence: The query could be filtered. Run with \"-F F\" option to turn the filter off.",getRes(oldQuery[c]), (long) c, getRes(compactSearch->query[c]),
2926 getRes(compactSearch->query[c]));
2927 }
2928 else{
2929 ErrPostEx(SEV_WARNING, 0, 0, "Stored query has a %c at position %ld, while new query has a %c there",getRes(oldQuery[c]), (long) c, getRes(compactSearch->query[c]));
2930 }
2931
2932 BlastConstructErrorMessage("posReadPosFreqsStandard", "Failed to recover data\n", 1, error_return);
2933 MemFree(oldQuery);
2934 FileClose(checkFile);
2935 return(FALSE);
2936 }
2937 if ((oldQuery[c] != compactSearch->query[c]) && (Xchar==oldQuery[c])) {
2938 ErrPostEx(SEV_WARNING, 0, 0, "Stored query has a %c at position %ld, while new query has a %c there\n%c appears in the stored query: The stored query may be filtered. Run blastpgp with \"-F F\" option to turn the filter off",getRes(oldQuery[c]), (long) c,
2939 getRes(compactSearch->query[c]), getRes(oldQuery[c])); }
2940
2941 }
2942 getCkptFreqMatrix(posSearch->posFreqs,length1,compactSearch->alphabetSize,checkFile);
2943 MemFree(oldQuery);
2944 FileClose(checkFile);
2945 return(TRUE);
2946 }
2947
2948 /*Read a checkpoint from the end of a previous PSI-BLAST round, get
2949 query length, query, and position-specific target frequencies.
2950 Returns TRUE if checkpoint was read sucessfully and FALSE otherwise. */
posReadCheckpoint(posSearchItems * posSearch,compactSearchItems * compactSearch,CharPtr fileName,Int4 scorematInput,ValNodePtr * error_return)2951 Boolean LIBCALL posReadCheckpoint(posSearchItems * posSearch, compactSearchItems * compactSearch, CharPtr fileName, Int4 scorematInput, ValNodePtr * error_return)
2952 {
2953 Int4 length1; /*length of query sequence*/
2954 Int4 i,j; /*indices for position and character in alphabet*/
2955 Boolean FreqsRead;
2956
2957 BlastConstructErrorMessage("posReadCheckpoint", "Attempting to recover data from previous checkpoint\n", 1, error_return);
2958 length1 = compactSearch->qlength;
2959
2960 /* allocate memory for the PSSMs and position frequency matrix */
2961
2962 posSearch->posMatrix = (BLAST_Score **) MemNew((length1 + 1) * sizeof(BLAST_Score *));
2963 posSearch->posPrivateMatrix = (BLAST_Score **) MemNew((length1 + 1) * sizeof(BLAST_Score *));
2964 posSearch->posFreqs = (Nlm_FloatHi **) MemNew((length1 + 1) * sizeof(Nlm_FloatHi *));
2965 ASSERT(compactSearch->standardMatrixName);
2966 posSearch->stdFreqRatios =
2967 PSIMatrixFrequencyRatiosNew(compactSearch->standardMatrixName);
2968 if ((NULL == posSearch->posMatrix) || (NULL == posSearch->posPrivateMatrix) || (NULL == posSearch->posFreqs)) {
2969
2970 BlastConstructErrorMessage("posReadCheckpoint", "Failed to allocate position-specific score matrix", 1, error_return);
2971 BlastConstructErrorMessage("posReadCheckpoint", "Failed to recover data\n", 1, error_return);
2972 return(FALSE);
2973 }
2974 for(i = 0; i <= length1; i++) {
2975 posSearch->posMatrix[i] = (BLAST_Score *) MemNew(compactSearch->alphabetSize * sizeof(BLAST_Score));
2976 posSearch->posPrivateMatrix[i] = (BLAST_Score *) MemNew(compactSearch->alphabetSize * sizeof(BLAST_Score));
2977 posSearch->posFreqs[i] = (Nlm_FloatHi *) MemNew(compactSearch->alphabetSize * sizeof(Nlm_FloatHi));
2978
2979 if ((NULL == posSearch->posMatrix[i]) || (NULL == posSearch->posPrivateMatrix[i]) || (NULL == posSearch->posFreqs[i])) {
2980 BlastConstructErrorMessage("posReadCheckpoint", "Failed to allocate position-specific score matrix", 1, error_return);
2981 BlastConstructErrorMessage("posReadCheckpoint", "Failed to recover data\n", 1, error_return);
2982 return(FALSE);
2983 }
2984 for(j = 0; j < compactSearch->alphabetSize; j++) {
2985 posSearch->posFreqs[i][j] = 0.0;
2986 }
2987 }
2988
2989 if (scorematInput == NO_SCOREMAT_IO) {
2990 FreqsRead = posReadPosFreqsStandard(posSearch, compactSearch,
2991 fileName, error_return);
2992 }
2993 else {
2994 FreqsRead = posReadPosFreqsScoremat(posSearch, compactSearch,
2995 fileName, scorematInput, error_return);
2996 }
2997 if (FreqsRead != TRUE) {
2998 BlastConstructErrorMessage("posReadCheckpoint", "Data recovery failed\n",
2999 1, error_return);
3000 return(FALSE);
3001 }
3002 posFreqsToInformation(posSearch,compactSearch);
3003 posFreqsToMatrix(posSearch,compactSearch);
3004 posScaling(posSearch, compactSearch);
3005 BlastConstructErrorMessage("posReadCheckpoint", "Data recovered successfully\n", 1, error_return);
3006 return(TRUE);
3007 }
3008
3009 /* Two routines taken from */
3010 /* "p2c" Copyright (C) 1989, 1990, 1991 Free Software Foundation.
3011 * By Dave Gillespie, daveg@csvax.cs.caltech.edu. Version --VERSION--.
3012 * This file may be copied, modified, etc. in any way. It is not restricted
3013 * by the licence agreement accompanying p2c itself.
3014 */
3015
3016
3017 /* Check if at end of file, using Pascal "eof" semantics. End-of-file for
3018 stdin is broken; remove the special case for it to be broken in a
3019 different way. */
3020
P_eof(FILE * f)3021 static Int4 P_eof(FILE *f)
3022 {
3023 register Int4 ch;
3024
3025 if (feof(f))
3026 return 1;
3027 if (f == stdin)
3028 return 0; /* not safe to look-ahead on the keyboard! */
3029 ch = getc(f);
3030 if (ch == EOF)
3031 return 1;
3032 ungetc(ch, f);
3033 return 0;
3034 }
3035
isBlankChar(Char thisChar)3036 static Boolean isBlankChar(Char thisChar)
3037 {
3038 return((thisChar == ' ') || (thisChar == '\t') || (thisChar == '\n') ||
3039 (thisChar == '\t'));
3040 }
3041
3042
3043 /*preprocess alignment checkpoint file to find number of sequences and
3044 number of blocks. Return number of blocks as return value
3045 and number of sequences through a reference parameter*/
posFindAlignmentDimensions(char * fileName,Int4 * numSeqs,ValNodePtr * error_return)3046 static Int4 posFindAlignmentDimensions(char * fileName, Int4 *numSeqs, ValNodePtr * error_return)
3047 {
3048 FILE *checkFile; /*checkpoint file*/
3049 Char nextLine[ALIGN_LINE_LENGTH]; /*line read in*/
3050 Boolean foundBlankLine; /*have we found a blank line yet*/
3051 Int4 numBlocks; /*number of blocks to be returned*/
3052 Int4 testCountSeqs; /*counts number of sequences in each block
3053 to ensure that each block has the same
3054 number of sequences*/
3055
3056 BlastConstructErrorMessage("posFindAlignmentDimensions", "Attempting to recover data from multiple alignment file\n", 1, error_return);
3057 checkFile = FileOpen(fileName, "rb");
3058 if (NULL == checkFile) {
3059 ErrPostEx(SEV_WARNING, 0, 0, "\nCould not open alignment checkpoint file");
3060 BlastConstructErrorMessage("posFindAlignmentDimensions", "Could not open alignment checkpoint file\n", 1, error_return);
3061 return(0);
3062 }
3063 do {
3064 fgets(nextLine, ALIGN_LINE_LENGTH,checkFile);
3065 } while (isBlankChar(nextLine[0]));
3066 foundBlankLine = FALSE;
3067 *numSeqs = 1;
3068 numBlocks = 0;
3069 while (!P_eof(checkFile) && (!foundBlankLine)) {
3070 fgets(nextLine, ALIGN_LINE_LENGTH,checkFile);
3071 if (!(isBlankChar(nextLine[0])))
3072 (*numSeqs)++;
3073 else
3074 foundBlankLine = TRUE;
3075 }
3076 numBlocks = 1;
3077 while(!P_eof(checkFile)) {
3078 do {
3079 fgets(nextLine, ALIGN_LINE_LENGTH,checkFile);
3080 } while((!P_eof(checkFile)) && (isBlankChar(nextLine[0])));
3081 if (!P_eof(checkFile)) {
3082 numBlocks++;
3083 testCountSeqs = 0;
3084 }
3085 do {
3086 fgets(nextLine, ALIGN_LINE_LENGTH,checkFile);
3087 testCountSeqs++;
3088 } while((!P_eof(checkFile)) && !(isBlankChar(nextLine[0])));
3089 if (!(isBlankChar(nextLine[0])))
3090 testCountSeqs++;
3091 if (testCountSeqs != (*numSeqs)) {
3092 ErrPostEx(SEV_WARNING, 0, 0, "\nInconsistent number of sequences across alignment blocks, first block has %d while block %d has %d sequences",(*numSeqs), numBlocks, testCountSeqs);
3093 BlastConstructErrorMessage("posFindAlignmentDimensions", "Could not read alignment due to different number of sequences in different blocks\n", 1, error_return);
3094 FileClose(checkFile);
3095 return(0);
3096 }
3097 }
3098
3099 FileClose(checkFile);
3100 return(numBlocks);
3101 }
3102
3103 /*Is thisChar possibly part of an alignment?*/
isProteinChar(Char thisChar)3104 static Boolean isProteinChar(Char thisChar)
3105 {
3106
3107 return(((thisChar >= 'A') && (thisChar <= 'Z')) ||
3108 ((thisChar >= 'a') && (thisChar <= 'z')) ||
3109 ('-' == thisChar));
3110 }
3111
3112
3113 /*preprocess alignment checkpoint file to find the
3114 start column and end column of each alignment block.
3115 As a consequece the length of
3116 the alignment can be computed and it is returned*/
posPreprocessAlignment(char * fileName,Int4 numSeqs,Int4 numBlocks,Int4 * numCols,ValNodePtr * error_return)3117 static Int4 posPreprocessAlignment(char * fileName, Int4 numSeqs, Int4 numBlocks, Int4 * numCols, ValNodePtr * error_return)
3118 {
3119 FILE *checkFile; /*checkpoint file*/
3120 char nextLine[ALIGN_LINE_LENGTH]; /*line read in*/
3121 Int4 alignLength; /*number of columns in alignment, to be returned*/
3122 Int4 charIndex; /*index over characters in a row*/
3123 Int4 blockIndex; /*index for the blocks in the alignment file*/
3124 Int4 seqIndex;
3125
3126 checkFile = FileOpen(fileName, "rb");
3127 if (NULL == checkFile) {
3128 ErrPostEx(SEV_WARNING, 0, 0, "\nCould not open alignment checkpoint file");
3129 BlastConstructErrorMessage("posPreprocessAlignment", "Could not open alignment checkpoint file\n", 1, error_return);
3130 return(0);
3131 }
3132
3133 blockIndex = 0;
3134 alignLength= 0;
3135 while (!P_eof(checkFile)) {
3136 do {
3137 fgets(nextLine, ALIGN_LINE_LENGTH,checkFile);
3138 } while (isBlankChar(nextLine[0])); /*line belongs to query*/
3139 charIndex = 0;
3140 while(!(isBlankChar(nextLine[charIndex])))
3141 charIndex++;
3142 while(isBlankChar(nextLine[charIndex]))
3143 charIndex++;
3144 numCols[blockIndex] = 0;
3145 while (isProteinChar(nextLine[charIndex])){
3146 alignLength++;
3147 charIndex++;
3148 numCols[blockIndex]++;
3149 }
3150 /*skip over other sequences*/
3151 for (seqIndex = 0; seqIndex < numSeqs; seqIndex++)
3152 fgets(nextLine, ALIGN_LINE_LENGTH,checkFile);
3153 blockIndex++;
3154 }
3155 FileClose(checkFile);
3156 return(alignLength);
3157 }
3158
3159 /*Find the index of the sequence in the multiple alignment that
3160 matches the query sequence; if non match return -1*/
findQuery(posDesc ** alignArray,compactSearchItems * compactSearch,Int4 numSeqs,Int4 alignLength)3161 static Int4 findQuery(posDesc ** alignArray, compactSearchItems * compactSearch, Int4 numSeqs, Int4 alignLength)
3162 {
3163 Uint1Ptr query; /*query sequence*/
3164 Int4 qlength; /*length of query sequence*/
3165 Int4 seqIndex; /*index over sequences*/
3166 Int4 i; /*index within a sequence*/
3167 Int4 queryIndex; /*index within query*/
3168 Char thisRes;
3169
3170 query = compactSearch->query;
3171 qlength = compactSearch->qlength;
3172 for(seqIndex = 0; seqIndex < numSeqs; seqIndex++) {
3173 i = 0;
3174 queryIndex = 0;
3175 while ((queryIndex < qlength) && (i < alignLength)) {
3176 if ('-' == alignArray[seqIndex][i].letter)
3177 i++;
3178 else {
3179 /*Need to keep lower-case letters*/
3180 thisRes = getRes(query[queryIndex]);
3181 /* Selenocysteines are replaced by X's in query; test for this
3182 possibility */
3183 if ((alignArray[seqIndex][i].letter == 'U' ||
3184 alignArray[seqIndex][i].letter == 'u') &&
3185 thisRes == 'X')
3186 thisRes = alignArray[seqIndex][i].letter;
3187
3188 if ((thisRes != (alignArray[seqIndex][i].letter + 'A' - 'a')) &&
3189 (thisRes != alignArray[seqIndex][i].letter))
3190 /*character mismatch*/
3191 break;
3192 else {
3193 queryIndex++;
3194 i++;
3195 }
3196 }
3197 }
3198 if (queryIndex == qlength) {
3199 while (i < alignLength) {
3200 /*chew up gaps at end of alignment sequence*/
3201 if ('-' != alignArray[seqIndex][i].letter)
3202 break;
3203 i++;
3204 }
3205 /*found a match! */
3206 return(seqIndex);
3207 }
3208 else
3209 /*alignment string is prefix of query*/
3210 continue;
3211 }
3212 return (-1);
3213
3214 }
3215
3216
posReadAlignment(compactSearchItems * compactSearch,char * fileName,Int4 numSeqs,Int4 numBlocks,Int4 alignLength,Int4 * numCols,ValNodePtr * error_return)3217 static posDesc** posReadAlignment(compactSearchItems *compactSearch, char * fileName, Int4 numSeqs, Int4 numBlocks, Int4 alignLength, Int4 * numCols,
3218 ValNodePtr * error_return)
3219 {
3220 FILE *checkFile; /*checkpoint file to read*/
3221 Char nextline[ALIGN_LINE_LENGTH];
3222 Int4 blockIndex;
3223 Int4 linePos; /* moving index for a line*/
3224 Int4 alignPos; /*placeholder for position alignment*/
3225 Int4 base; /*base for this block*/
3226 posDesc **returnArray; /*array of sequences to retunr*/
3227 Int4 i,j; /*loop indices*/
3228 Int4 temp; /*temporary character for swapping sequences*/
3229 Int4 queryIndex; /*which sequnec in the alignment is the query*/
3230
3231 checkFile = FileOpen(fileName, "rb");
3232 if (NULL == checkFile) {
3233 BlastConstructErrorMessage("posReadAlignment", "Could not open alignment checkpoint file\n", 1, error_return);
3234 ErrPostEx(SEV_WARNING, 0, 0, "\nCould not open alignment checkpoint file");
3235 }
3236 returnArray = (posDesc**) MemNew(numSeqs * sizeof(posDesc *));
3237 if (NULL == returnArray)
3238 exit(EXIT_FAILURE);
3239 for (i = 0; i < numSeqs; i++) {
3240 returnArray[i] = (posDesc *) MemNew(alignLength * sizeof(posDesc));
3241 if (NULL == returnArray[i])
3242 exit(EXIT_FAILURE);
3243 for(j = 0; j < alignLength; j++) {
3244 returnArray[i][j].letter = UNUSED;
3245 returnArray[i][j].used = FALSE;
3246 }
3247 }
3248 alignPos = 0;
3249 base = 0;
3250 for(blockIndex = 0; blockIndex < numBlocks; blockIndex++){
3251 for(i = 0; i < numSeqs; i++) {
3252 do {
3253 fgets(nextline, ALIGN_LINE_LENGTH,checkFile);
3254 } while(isBlankChar(nextline[0]));
3255 linePos = 0;
3256 while(!isBlankChar(nextline[linePos]))
3257 linePos++;
3258 while(isBlankChar(nextline[linePos]))
3259 linePos++;
3260 alignPos = base;
3261 while (alignPos < (base + numCols[blockIndex])) {
3262 if (!isProteinChar(nextline[linePos])) {
3263 BlastConstructErrorMessage("posReadAlignment", "Invalid character or wrong number of characters in a sequence\n", 1, error_return);
3264 ErrPostEx(SEV_WARNING, 0, 0, "\nInvalid character or wrong number of characters in sequence index %d\n", i+1);
3265 }
3266 returnArray[i][alignPos].letter = nextline[linePos];
3267 returnArray[i][alignPos].used = TRUE;
3268 alignPos++;
3269 linePos++;
3270 }
3271 }
3272 base += numCols[blockIndex];
3273 }
3274 FileClose(checkFile);
3275 queryIndex = findQuery(returnArray, compactSearch, numSeqs, alignLength);
3276 if (-1 == queryIndex) {
3277 BlastConstructErrorMessage("posReadAlignment", "None of the alignment sequences equals the query sequence\n", 1, error_return);
3278 ErrPostEx(SEV_WARNING, 0, 0, "\nNone of the alignment sequences equals the query sequence");
3279 BlastConstructErrorMessage("posReadAlignment", "Cannot recover alignment checkpoint\n", 1, error_return);
3280 ErrPostEx(SEV_WARNING, 0, 0, "\nCannot recover alignment checkpoint");
3281 exit(EXIT_FAILURE);
3282 }
3283 else {
3284 if (queryIndex > 0) {
3285 /*swap query with first sequence in alignment*/
3286 for (alignPos = 0; alignPos < alignLength; alignPos++) {
3287 temp = returnArray[0][alignPos].letter;
3288 returnArray[0][alignPos].letter = returnArray[queryIndex][alignPos].letter;
3289 returnArray[queryIndex][alignPos].letter = temp;
3290 }
3291 }
3292 }
3293 return(returnArray);
3294 }
3295
posProcessAlignment(posSearchItems * posSearch,compactSearchItems * compactSearch,char * fileName,Int4 numSeqs,Int4 numBlocks,Int4 alignLength,Int4 * numCols,ValNodePtr * error_return)3296 static void posProcessAlignment(posSearchItems *posSearch, compactSearchItems *compactSearch, char * fileName, Int4 numSeqs, Int4 numBlocks, Int4 alignLength, Int4 * numCols, ValNodePtr * error_return)
3297 {
3298 Int4 queryPos, alignPos, linePos; /*placeholder for position in query and
3299 alignment*/
3300 Int4 *queryDesc; /*position correspondence between alignment and query*/
3301 Int4 seqIndex; /*counter for sequences*/
3302 posDesc ** alignArray;
3303 Int4 queryLength; /*length of query sequence*/
3304
3305 alignArray = posReadAlignment(compactSearch, fileName, numSeqs, numBlocks, alignLength, numCols, error_return);
3306 queryDesc = (Int4 *) MemNew(alignLength * sizeof(Int4));
3307 if (NULL == queryDesc)
3308 exit(EXIT_FAILURE);
3309 for(alignPos = 0; alignPos < alignLength; alignPos++)
3310 queryDesc[alignPos] = GAP_HERE;
3311 alignPos = 0;
3312 queryPos = 0;
3313 for(linePos = 0; linePos < alignLength; linePos++) {
3314 if (alignArray[0][linePos].letter == '-')
3315 queryDesc[alignPos] = GAP_HERE;
3316 else {
3317 queryDesc[alignPos] = queryPos;
3318 if ((alignArray[0][linePos].letter >= 'A' ) && (alignArray[0][linePos].letter <= 'Z')) {
3319 posSearch->posDescMatrix[0][queryPos].letter = ResToInt(alignArray[0][linePos].letter);
3320 posSearch->posDescMatrix[0][queryPos].used = TRUE;
3321 posSearch->posDescMatrix[0][queryPos].e_value = compactSearch->ethresh/2;
3322 posSearch->posDescMatrix[0][queryPos].leftExtent = 0;
3323 posSearch->posDescMatrix[0][queryPos].rightExtent = compactSearch->qlength - 1;
3324 posSearch->posC[queryPos][ResToInt(alignArray[0][linePos].letter)]++;
3325 posSearch->posCount[queryPos]++;
3326 }
3327 else {
3328 posSearch->posDescMatrix[0][queryPos].used = FALSE;
3329 posSearch->posDescMatrix[0][queryPos].letter = ResToInt(alignArray[0][linePos].letter + 'A' - 'a');
3330 }
3331 queryPos++;
3332 }
3333 alignPos++;
3334 }
3335 queryLength = queryPos;
3336 for(seqIndex = 1; seqIndex < numSeqs; seqIndex++) {
3337 for(linePos = 0; linePos < alignLength; linePos++) {
3338 if (queryDesc[linePos] != GAP_HERE) {
3339 if (!(posSearch->posDescMatrix[0][queryDesc[linePos]].used)) {
3340 /*mark column as not participating*/
3341 posSearch->posDescMatrix[seqIndex][queryDesc[linePos]].used = FALSE;
3342 }
3343 else {
3344 posSearch->posDescMatrix[seqIndex][queryDesc[linePos]].letter = ResToInt(alignArray[seqIndex][linePos].letter);
3345 posSearch->posDescMatrix[seqIndex][queryDesc[linePos]].used = TRUE;
3346 posSearch->posDescMatrix[seqIndex][queryDesc[linePos]].e_value = compactSearch->ethresh/2;
3347 posSearch->posDescMatrix[seqIndex][queryDesc[linePos]].leftExtent = 0;
3348 posSearch->posDescMatrix[seqIndex][queryDesc[linePos]].rightExtent = compactSearch->qlength;
3349 }
3350 }
3351 }
3352 }
3353 /*make terminal gaps unused*/
3354 for(seqIndex = 1; seqIndex < numSeqs; seqIndex++) {
3355 linePos = 0;
3356 while((linePos < queryLength) && (posSearch->posDescMatrix[seqIndex][linePos].letter == GAP_CHAR)) {
3357 posSearch->posDescMatrix[seqIndex][linePos].used = FALSE;
3358 linePos++;
3359 }
3360 linePos = queryLength - 1;
3361 while((linePos >= 0) && (posSearch->posDescMatrix[seqIndex][linePos].letter == GAP_CHAR)) {
3362 posSearch->posDescMatrix[seqIndex][linePos].used = FALSE;
3363 linePos--;
3364 }
3365 }
3366 BlastConstructErrorMessage("posProcessAlignment", "Alignment recovered successfully\n", 1, error_return);
3367 }
3368
3369
3370 /* Top-level routine to compute position-specific matrix, when used for
3371 one round to recover from a multiple alignment checkpoint. */
BposComputation(posSearchItems * posSearch,BlastSearchBlkPtr search,compactSearchItems * compactSearch,Char * ckptFileName,Char * takeCkptFileName,Int4 scorematOutput,Bioseq * query_bsp,Int4 gap_open,Int4 gap_extend,ValNodePtr * error_return)3372 Int4Ptr * LIBCALL BposComputation(posSearchItems *posSearch, BlastSearchBlkPtr
3373 search, compactSearchItems * compactSearch, Char *ckptFileName,
3374 Char *takeCkptFileName, Int4 scorematOutput, Bioseq *query_bsp,
3375 Int4 gap_open, Int4 gap_extend, ValNodePtr * error_return)
3376 {
3377 Int4 numSeqs, numBlocks, alignLength; /*number of sequences, number of pieces
3378 of alignment, total length of the alignment*/
3379 Int4 *numCols; /*number of columns within each block*/
3380
3381 search->posConverged = FALSE;
3382
3383 numBlocks = posFindAlignmentDimensions(ckptFileName, &numSeqs, error_return);
3384 if (0 == numBlocks) {
3385 ErrPostEx(SEV_WARNING, 0, 0, "\nCould not recover block structure from checkpoint");
3386 BlastConstructErrorMessage("BposComputation", "Cannot recover alignment checkpoint\n", 1, error_return);
3387 return(NULL);
3388 }
3389 numCols = (Int4 *) MemNew(numBlocks * sizeof(Int4));
3390 if (NULL == numCols)
3391 exit(EXIT_FAILURE);
3392 alignLength = posPreprocessAlignment(ckptFileName, numSeqs, numBlocks, numCols, error_return);
3393 if (0 == alignLength) {
3394 ErrPostEx(SEV_WARNING, 0, 0, "\nCould not recover alignment structure from checkpoint");
3395 BlastConstructErrorMessage("BposComputation", "Cannot recover alignment checkpoint\n", 1, error_return);
3396 return(NULL);
3397 }
3398 posAllocateMemory(posSearch, compactSearch->alphabetSize, compactSearch->qlength, numSeqs);
3399 posProcessAlignment(posSearch, compactSearch, ckptFileName, numSeqs, numBlocks, alignLength, numCols, error_return);
3400 MemFree(numCols);
3401 posSearch->posNumSequences = numSeqs;
3402 posPurgeMatches(posSearch, compactSearch, error_return);
3403 posComputeExtents(posSearch, compactSearch);
3404 posComputeSequenceWeights(posSearch, compactSearch, 1.0);
3405 posCheckWeights(posSearch, compactSearch);
3406 posSearch->posFreqs = posComputePseudoFreqs(posSearch, compactSearch, TRUE);
3407 if (NULL == search->sbp->posFreqs)
3408 search->sbp->posFreqs = allocatePosFreqs(compactSearch->qlength, compactSearch->alphabetSize);
3409 copyPosFreqs(posSearch->posFreqs,search->sbp->posFreqs, compactSearch->qlength, compactSearch->alphabetSize);
3410 if (NULL != takeCkptFileName) {
3411 if (scorematOutput == NO_SCOREMAT_IO)
3412 posTakeCheckpoint(posSearch, compactSearch, takeCkptFileName, error_return);
3413 else
3414 posTakeScoremat(posSearch, compactSearch, takeCkptFileName, scorematOutput, query_bsp, gap_open, gap_extend, error_return);
3415 }
3416 posFreqsToMatrix(posSearch,compactSearch);
3417 posScaling(posSearch, compactSearch);
3418 return posSearch->posMatrix;
3419 }
3420
3421 /****************************************************************************/
3422 /* PLEASE NOTE: The following structure and the PSIMatrixFrequencyRatios*
3423 * functions have been copied and renamed from
3424 * algo/blast/core/matrix_freq_ratios.[hc] to eliminate a dependency from the
3425 * ncbitool library to the blast library.
3426 */
3427 #ifndef BLOSUM62_20A_SCALE_MULTIPLIER
3428 #define BLOSUM62_20A_SCALE_MULTIPLIER 0.9666
3429 #endif
3430
3431 #ifndef BLOSUM62_20B_SCALE_MULTIPLIER
3432 #define BLOSUM62_20B_SCALE_MULTIPLIER 0.9344
3433 #endif
3434
3435 /* posit.c has static frequency data for the 28 character alphabet,
3436 * which may be different from PROTEIN_ALPHABET */
3437
3438 #define POSITAA_SIZE 28
3439
3440 /** Underlying frequency ratios for BLOSUM45 */
3441 static const double BLOSUM45_FREQRATIOS[POSITAA_SIZE][POSITAA_SIZE] =
3442 {{0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3443 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3444 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3445 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3446 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3447 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3448 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00},
3449 {0.00000000e+00, 2.95043377e+00, 7.34701741e-01, 8.00397827e-01,
3450 6.88936672e-01, 8.25164920e-01, 5.87357723e-01, 1.08031132e+00,
3451 6.54086288e-01, 7.46806187e-01, 7.86209397e-01, 7.12370041e-01,
3452 8.21348665e-01, 7.89043130e-01, 7.08569419e-01, 8.66678731e-01,
3453 6.99695540e-01, 1.30031418e+00, 1.00058530e+00, 1.00992663e+00,
3454 5.65442334e-01, 7.50000000e-01, 6.38727873e-01, 8.41025176e-01,
3455 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 7.26064996e-01},
3456 {0.00000000e+00, 7.34701741e-01, 3.25946658e+00, 6.00232275e-01,
3457 3.59386786e+00, 1.30000108e+00, 4.95670856e-01, 8.85913772e-01,
3458 1.08769141e+00, 4.96979579e-01, 1.02264352e+00, 4.72210752e-01,
3459 5.80058073e-01, 2.86239890e+00, 6.85801186e-01, 9.91862879e-01,
3460 8.29088221e-01, 1.05297301e+00, 9.85207016e-01, 5.20111147e-01,
3461 3.80841719e-01, 7.50000000e-01, 6.27051284e-01, 1.18227759e+00,
3462 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 4.82061098e-01},
3463 {0.00000000e+00, 8.00397827e-01, 6.00232275e-01, 1.70900872e+01,
3464 5.32858023e-01, 5.45353890e-01, 6.01657157e-01, 5.56827599e-01,
3465 4.90637659e-01, 5.42801532e-01, 5.46735291e-01, 6.72663401e-01,
3466 6.03730225e-01, 6.80232381e-01, 4.11520916e-01, 4.86216592e-01,
3467 4.71814444e-01, 7.96941950e-01, 8.21766666e-01, 7.14771712e-01,
3468 3.33596922e-01, 7.50000000e-01, 4.88896599e-01, 5.22760621e-01,
3469 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 6.21018471e-01},
3470 {0.00000000e+00, 6.88936672e-01, 3.59386786e+00, 5.32858023e-01,
3471 5.35580571e+00, 1.64256912e+00, 4.31018420e-01, 7.40433725e-01,
3472 9.76205497e-01, 4.40334375e-01, 9.41681214e-01, 4.62523949e-01,
3473 4.94422549e-01, 1.50174498e+00, 7.24041930e-01, 9.57667486e-01,
3474 7.71179788e-01, 9.29413105e-01, 8.76125496e-01, 4.93585385e-01,
3475 3.73386452e-01, 7.50000000e-01, 6.44927232e-01, 1.38090402e+00,
3476 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 4.53699350e-01},
3477 {0.00000000e+00, 8.25164920e-01, 1.30000108e+00, 5.45353890e-01,
3478 1.64256912e+00, 3.87327599e+00, 4.97795679e-01, 5.76408577e-01,
3479 9.61718230e-01, 4.85270933e-01, 1.27686825e+00, 5.70784073e-01,
3480 6.14865688e-01, 8.93236200e-01, 9.10746443e-01, 1.53097375e+00,
3481 1.01074883e+00, 9.12113764e-01, 8.32873235e-01, 5.55160304e-01,
3482 5.19337483e-01, 7.50000000e-01, 6.16552718e-01, 2.97840479e+00,
3483 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.36776244e-01},
3484 {0.00000000e+00, 5.87357723e-01, 4.95670856e-01, 6.01657157e-01,
3485 4.31018420e-01, 4.97795679e-01, 5.74817622e+00, 4.80346092e-01,
3486 6.79103477e-01, 1.06375667e+00, 5.29188869e-01, 1.30295859e+00,
3487 1.06255416e+00, 5.72439082e-01, 4.51176385e-01, 4.43558969e-01,
3488 5.89537777e-01, 6.09495403e-01, 7.16103747e-01, 9.52475503e-01,
3489 1.35493791e+00, 7.50000000e-01, 2.18456832e+00, 4.77074668e-01,
3490 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 1.20783008e+00},
3491 {0.00000000e+00, 1.08031132e+00, 8.85913772e-01, 5.56827599e-01,
3492 7.40433725e-01, 5.76408577e-01, 4.80346092e-01, 5.07068525e+00,
3493 6.62087167e-01, 4.16341047e-01, 6.77879412e-01, 4.50091586e-01,
3494 5.84692214e-01, 1.05865660e+00, 7.02165561e-01, 6.87007231e-01,
3495 5.70228460e-01, 1.05800656e+00, 6.92819008e-01, 4.79214700e-01,
3496 5.91296285e-01, 7.50000000e-01, 5.49197180e-01, 6.18662539e-01,
3497 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 4.36669292e-01},
3498 {0.00000000e+00, 6.54086288e-01, 1.08769141e+00, 4.90637659e-01,
3499 9.76205497e-01, 9.61718230e-01, 6.79103477e-01, 6.62087167e-01,
3500 9.51252809e+00, 4.53313059e-01, 8.90272071e-01, 6.69868446e-01,
3501 9.18088604e-01, 1.22006964e+00, 6.61223470e-01, 1.15049417e+00,
3502 9.73045615e-01, 8.54331847e-01, 7.06245757e-01, 4.56693295e-01,
3503 4.51816356e-01, 7.50000000e-01, 1.47204221e+00, 1.03383965e+00,
3504 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.83746261e-01},
3505 {0.00000000e+00, 7.46806187e-01, 4.96979579e-01, 5.42801532e-01,
3506 4.40334375e-01, 4.85270933e-01, 1.06375667e+00, 4.16341047e-01,
3507 4.53313059e-01, 3.23256769e+00, 5.32316397e-01, 1.59618413e+00,
3508 1.45527106e+00, 5.64240025e-01, 6.09639867e-01, 5.77938325e-01,
3509 4.88387978e-01, 6.18410187e-01, 8.47505386e-01, 2.17596400e+00,
3510 5.64907506e-01, 7.50000000e-01, 9.06458192e-01, 5.20674297e-01,
3511 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 2.24695958e+00},
3512 {0.00000000e+00, 7.86209397e-01, 1.02264352e+00, 5.46735291e-01,
3513 9.41681214e-01, 1.27686825e+00, 5.29188869e-01, 6.77879412e-01,
3514 8.90272071e-01, 5.32316397e-01, 3.32707189e+00, 5.53563636e-01,
3515 7.37955763e-01, 1.11877807e+00, 7.81202774e-01, 1.33004839e+00,
3516 1.94261316e+00, 8.89937552e-01, 8.84562104e-01, 5.91651856e-01,
3517 5.61572955e-01, 7.50000000e-01, 7.37107274e-01, 1.29718560e+00,
3518 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.45113795e-01},
3519 {0.00000000e+00, 7.12370041e-01, 4.72210752e-01, 6.72663401e-01,
3520 4.62523949e-01, 5.70784073e-01, 1.30295859e+00, 4.50091586e-01,
3521 6.69868446e-01, 1.59618413e+00, 5.53563636e-01, 2.99708655e+00,
3522 1.73144954e+00, 4.83712850e-01, 4.77913692e-01, 6.42028706e-01,
3523 6.01135200e-01, 5.55659969e-01, 7.80723755e-01, 1.33363845e+00,
3524 6.70858407e-01, 7.50000000e-01, 9.65090110e-01, 5.98002922e-01,
3525 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 2.43995990e+00},
3526 {0.00000000e+00, 8.21348665e-01, 5.80058073e-01, 6.03730225e-01,
3527 4.94422549e-01, 6.14865688e-01, 1.06255416e+00, 5.84692214e-01,
3528 9.18088604e-01, 1.45527106e+00, 7.37955763e-01, 1.73144954e+00,
3529 4.11411354e+00, 6.81741591e-01, 6.43682874e-01, 9.40467390e-01,
3530 7.75906233e-01, 6.60370266e-01, 8.60449567e-01, 1.23582796e+00,
3531 6.34345311e-01, 7.50000000e-01, 1.02316322e+00, 7.39261071e-01,
3532 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 1.62161577e+00},
3533 {0.00000000e+00, 7.89043130e-01, 2.86239890e+00, 6.80232381e-01,
3534 1.50174498e+00, 8.93236200e-01, 5.72439082e-01, 1.05865660e+00,
3535 1.22006964e+00, 5.64240025e-01, 1.11877807e+00, 4.83712850e-01,
3536 6.81741591e-01, 4.47803773e+00, 6.40394172e-01, 1.03246645e+00,
3537 8.97848625e-01, 1.19968790e+00, 1.11473028e+00, 5.51607804e-01,
3538 3.89694095e-01, 7.50000000e-01, 6.05825405e-01, 9.46428796e-01,
3539 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.15737804e-01},
3540 {0.00000000e+00, 7.08569419e-01, 6.85801186e-01, 4.11520916e-01,
3541 7.24041930e-01, 9.10746443e-01, 4.51176385e-01, 7.02165561e-01,
3542 6.61223470e-01, 6.09639867e-01, 7.81202774e-01, 4.77913692e-01,
3543 6.43682874e-01, 6.40394172e-01, 8.81911509e+00, 7.15515810e-01,
3544 5.81631739e-01, 7.49733904e-01, 8.56242933e-01, 5.40037335e-01,
3545 5.25005050e-01, 7.50000000e-01, 4.78832406e-01, 8.36159027e-01,
3546 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.30300041e-01},
3547 {0.00000000e+00, 8.66678731e-01, 9.91862879e-01, 4.86216592e-01,
3548 9.57667486e-01, 1.53097375e+00, 4.43558969e-01, 6.87007231e-01,
3549 1.15049417e+00, 5.77938325e-01, 1.33004839e+00, 6.42028706e-01,
3550 9.40467390e-01, 1.03246645e+00, 7.15515810e-01, 4.40728842e+00,
3551 1.32912854e+00, 1.09183956e+00, 7.80601862e-01, 5.47266398e-01,
3552 6.45177884e-01, 7.50000000e-01, 8.29182983e-01, 2.62986317e+00,
3553 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 6.16540522e-01},
3554 {0.00000000e+00, 6.99695540e-01, 8.29088221e-01, 4.71814444e-01,
3555 7.71179788e-01, 1.01074883e+00, 5.89537777e-01, 5.70228460e-01,
3556 9.73045615e-01, 4.88387978e-01, 1.94261316e+00, 6.01135200e-01,
3557 7.75906233e-01, 8.97848625e-01, 5.81631739e-01, 1.32912854e+00,
3558 4.74702063e+00, 7.99048209e-01, 7.15164318e-01, 5.77699501e-01,
3559 5.80165842e-01, 7.50000000e-01, 8.07446927e-01, 1.13238507e+00,
3560 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.56296615e-01},
3561 {0.00000000e+00, 1.30031418e+00, 1.05297301e+00, 7.96941950e-01,
3562 9.29413105e-01, 9.12113764e-01, 6.09495403e-01, 1.05800656e+00,
3563 8.54331847e-01, 6.18410187e-01, 8.89937552e-01, 5.55659969e-01,
3564 6.60370266e-01, 1.19968790e+00, 7.49733904e-01, 1.09183956e+00,
3565 7.99048209e-01, 2.78188630e+00, 1.47248598e+00, 7.27836330e-01,
3566 4.28363793e-01, 7.50000000e-01, 7.05878947e-01, 9.80777594e-01,
3567 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.80615182e-01},
3568 {0.00000000e+00, 1.00058530e+00, 9.85207016e-01, 8.21766666e-01,
3569 8.76125496e-01, 8.32873235e-01, 7.16103747e-01, 6.92819008e-01,
3570 7.06245757e-01, 8.47505386e-01, 8.84562104e-01, 7.80723755e-01,
3571 8.60449567e-01, 1.11473028e+00, 8.56242933e-01, 7.80601862e-01,
3572 7.15164318e-01, 1.47248598e+00, 3.13871529e+00, 1.04019697e+00,
3573 4.54128072e-01, 7.50000000e-01, 7.43457494e-01, 8.12903077e-01,
3574 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 8.07282226e-01},
3575 {0.00000000e+00, 1.00992663e+00, 5.20111147e-01, 7.14771712e-01,
3576 4.93585385e-01, 5.55160304e-01, 9.52475503e-01, 4.79214700e-01,
3577 4.56693295e-01, 2.17596400e+00, 5.91651856e-01, 1.33363845e+00,
3578 1.23582796e+00, 5.51607804e-01, 5.40037335e-01, 5.47266398e-01,
3579 5.77699501e-01, 7.27836330e-01, 1.04019697e+00, 2.87075890e+00,
3580 4.73320057e-01, 7.50000000e-01, 8.09252575e-01, 5.52144455e-01,
3581 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 1.66862396e+00},
3582 {0.00000000e+00, 5.65442334e-01, 3.80841719e-01, 3.33596922e-01,
3583 3.73386452e-01, 5.19337483e-01, 1.35493791e+00, 5.91296285e-01,
3584 4.51816356e-01, 5.64907506e-01, 5.61572955e-01, 6.70858407e-01,
3585 6.34345311e-01, 3.89694095e-01, 5.25005050e-01, 6.45177884e-01,
3586 5.80165842e-01, 4.28363793e-01, 4.54128072e-01, 4.73320057e-01,
3587 2.97023509e+01, 7.50000000e-01, 1.80096028e+00, 5.67414520e-01,
3588 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 6.28722660e-01},
3589 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3590 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3591 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3592 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3593 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3594 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3595 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 7.50000000e-01},
3596 {0.00000000e+00, 6.38727873e-01, 6.27051284e-01, 4.88896599e-01,
3597 6.44927232e-01, 6.16552718e-01, 2.18456832e+00, 5.49197180e-01,
3598 1.47204221e+00, 9.06458192e-01, 7.37107274e-01, 9.65090110e-01,
3599 1.02316322e+00, 6.05825405e-01, 4.78832406e-01, 8.29182983e-01,
3600 8.07446927e-01, 7.05878947e-01, 7.43457494e-01, 8.09252575e-01,
3601 1.80096028e+00, 7.50000000e-01, 5.75351902e+00, 6.97787623e-01,
3602 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 9.41772708e-01},
3603 {0.00000000e+00, 8.41025176e-01, 1.18227759e+00, 5.22760621e-01,
3604 1.38090402e+00, 2.97840479e+00, 4.77074668e-01, 6.18662539e-01,
3605 1.03383965e+00, 5.20674297e-01, 1.29718560e+00, 5.98002922e-01,
3606 7.39261071e-01, 9.46428796e-01, 8.36159027e-01, 2.62986317e+00,
3607 1.13238507e+00, 9.80777594e-01, 8.12903077e-01, 5.52144455e-01,
3608 5.67414520e-01, 7.50000000e-01, 6.97787623e-01, 2.84524527e+00,
3609 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.67250003e-01},
3610 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3611 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3612 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3613 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3614 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3615 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3616 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 7.50000000e-01},
3617 {0.00000000e+00, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3618 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3619 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3620 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3621 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3622 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3623 2.90000000e-01, 1.33300000e+00, 2.90000000e-01, 2.90000000e-01},
3624 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3625 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3626 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3627 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3628 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3629 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3630 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 7.50000000e-01},
3631 {0.00000000e+00, 7.26064996e-01, 4.82061098e-01, 6.21018471e-01,
3632 4.53699350e-01, 5.36776244e-01, 1.20783008e+00, 4.36669292e-01,
3633 5.83746261e-01, 2.24695958e+00, 5.45113795e-01, 2.43995990e+00,
3634 1.62161577e+00, 5.15737804e-01, 5.30300041e-01, 6.16540522e-01,
3635 5.56296615e-01, 5.80615182e-01, 8.07282226e-01, 1.66862396e+00,
3636 6.28722660e-01, 7.50000000e-01, 9.41772708e-01, 5.67250003e-01,
3637 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 2.36320536e+00}};
3638
3639
3640 /** Underlying frequency ratios for BLOSUM50 */
3641 static const double BLOSUM50_FREQRATIOS[POSITAA_SIZE][POSITAA_SIZE] =
3642 {{0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3643 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3644 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3645 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3646 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3647 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3648 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00},
3649 {0.00000000e+00, 3.27354473e+00, 6.87168642e-01, 8.87624875e-01,
3650 6.59704230e-01, 7.97359654e-01, 5.46298170e-01, 1.10130683e+00,
3651 6.41220589e-01, 7.15157692e-01, 7.47622201e-01, 6.56954186e-01,
3652 8.53472686e-01, 7.19514908e-01, 7.14770771e-01, 8.19913708e-01,
3653 6.68351460e-01, 1.36359270e+00, 9.67331593e-01, 9.81625416e-01,
3654 4.63560176e-01, 7.50000000e-01, 5.96400452e-01, 8.05980349e-01,
3655 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 6.80310043e-01},
3656 {0.00000000e+00, 6.87168642e-01, 3.67565906e+00, 5.07294595e-01,
3657 4.02052534e+00, 1.31892999e+00, 3.83849184e-01, 8.47577177e-01,
3658 1.11810068e+00, 4.07212168e-01, 9.68440788e-01, 3.91166888e-01,
3659 5.16058658e-01, 3.26949213e+00, 6.61247189e-01, 9.98204754e-01,
3660 7.59007679e-01, 1.06055276e+00, 9.55438618e-01, 4.46192804e-01,
3661 3.38571955e-01, 7.50000000e-01, 5.55905269e-01, 1.19634119e+00,
3662 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 3.97605526e-01},
3663 {0.00000000e+00, 8.87624875e-01, 5.07294595e-01, 1.82308935e+01,
3664 4.27724382e-01, 4.56030174e-01, 5.64985221e-01, 5.24350848e-01,
3665 5.17412429e-01, 5.87186086e-01, 4.59864212e-01, 6.50074165e-01,
3666 6.80946766e-01, 6.01008569e-01, 4.03060607e-01, 4.81296027e-01,
3667 4.27834290e-01, 8.29850973e-01, 8.17890869e-01, 8.08665030e-01,
3668 3.12131245e-01, 7.50000000e-01, 5.38704705e-01, 4.65687383e-01,
3669 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 6.24838486e-01},
3670 {0.00000000e+00, 6.59704230e-01, 4.02052534e+00, 4.27724382e-01,
3671 6.11147890e+00, 1.65784569e+00, 3.37276799e-01, 7.44468416e-01,
3672 8.83789762e-01, 3.70146565e-01, 8.90348134e-01, 3.72923686e-01,
3673 4.35009775e-01, 1.55790069e+00, 7.09628659e-01, 9.66997497e-01,
3674 6.78533894e-01, 9.21480865e-01, 8.25179634e-01, 4.31712984e-01,
3675 3.07050170e-01, 7.50000000e-01, 5.04473723e-01, 1.39378711e+00,
3676 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 3.71809285e-01},
3677 {0.00000000e+00, 7.97359654e-01, 1.31892999e+00, 4.56030174e-01,
3678 1.65784569e+00, 4.43735647e+00, 4.56055858e-01, 5.39909105e-01,
3679 9.11487897e-01, 4.15558851e-01, 1.33108575e+00, 4.78428941e-01,
3680 6.05096970e-01, 9.19771370e-01, 8.38805682e-01, 1.67134451e+00,
3681 9.76357610e-01, 8.82100970e-01, 8.19031320e-01, 4.79075838e-01,
3682 5.48039829e-01, 7.50000000e-01, 6.51686488e-01, 3.38012103e+00,
3683 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 4.53200481e-01},
3684 {0.00000000e+00, 5.46298170e-01, 3.83849184e-01, 5.64985221e-01,
3685 3.37276799e-01, 4.56055858e-01, 6.63625360e+00, 4.13949535e-01,
3686 7.54714659e-01, 9.89742646e-01, 4.44979578e-01, 1.26171801e+00,
3687 1.05158910e+00, 4.38699901e-01, 3.75736079e-01, 4.16967765e-01,
3688 4.61789222e-01, 5.52981315e-01, 5.70349305e-01, 8.59643167e-01,
3689 1.34807169e+00, 7.50000000e-01, 2.42442622e+00, 4.41115461e-01,
3690 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 1.15257995e+00},
3691 {0.00000000e+00, 1.10130683e+00, 8.47577177e-01, 5.24350848e-01,
3692 7.44468416e-01, 5.39909105e-01, 4.13949535e-01, 5.79218671e+00,
3693 6.01271290e-01, 3.70370366e-01, 6.54870319e-01, 3.76903001e-01,
3694 5.19438610e-01, 9.69013722e-01, 6.20168128e-01, 6.41416113e-01,
3695 5.16985831e-01, 9.99248542e-01, 6.36269018e-01, 4.02720033e-01,
3696 5.04888636e-01, 7.50000000e-01, 4.67274430e-01, 5.78707493e-01,
3697 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 3.74281590e-01},
3698 {0.00000000e+00, 6.41220589e-01, 1.11810068e+00, 5.17412429e-01,
3699 8.83789762e-01, 9.11487897e-01, 7.54714659e-01, 6.01271290e-01,
3700 1.04489376e+01, 4.11545408e-01, 9.45545516e-01, 5.47445792e-01,
3701 7.60124356e-01, 1.39406083e+00, 5.81906417e-01, 1.20911332e+00,
3702 9.81604707e-01, 8.22540644e-01, 6.52641826e-01, 4.13620259e-01,
3703 4.75002356e-01, 7.50000000e-01, 1.57000854e+00, 1.02524740e+00,
3704 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 4.92911793e-01},
3705 {0.00000000e+00, 7.15157692e-01, 4.07212168e-01, 5.87186086e-01,
3706 3.70146565e-01, 4.15558851e-01, 9.89742646e-01, 3.70370366e-01,
3707 4.11545408e-01, 3.41093885e+00, 4.68297844e-01, 1.69677965e+00,
3708 1.43810563e+00, 4.50866254e-01, 5.11210841e-01, 5.02656404e-01,
3709 4.35318230e-01, 5.45643330e-01, 8.60722536e-01, 2.31272269e+00,
3710 5.22495607e-01, 7.50000000e-01, 8.26095669e-01, 4.48849604e-01,
3711 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 2.38463611e+00},
3712 {0.00000000e+00, 7.47622201e-01, 9.68440788e-01, 4.59864212e-01,
3713 8.90348134e-01, 1.33108575e+00, 4.44979578e-01, 6.54870319e-01,
3714 9.45545516e-01, 4.68297844e-01, 3.88090096e+00, 4.79194854e-01,
3715 6.85231759e-01, 1.06041456e+00, 7.63679086e-01, 1.41855717e+00,
3716 2.06468049e+00, 8.92977250e-01, 8.44796364e-01, 5.22802406e-01,
3717 4.61593643e-01, 7.50000000e-01, 6.67754286e-01, 1.36451940e+00,
3718 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 4.74822110e-01},
3719 {0.00000000e+00, 6.56954186e-01, 3.91166888e-01, 6.50074165e-01,
3720 3.72923686e-01, 4.78428941e-01, 1.26171801e+00, 3.76903001e-01,
3721 5.47445792e-01, 1.69677965e+00, 4.79194854e-01, 3.32815910e+00,
3722 1.78991633e+00, 4.12652855e-01, 4.43674459e-01, 5.62937315e-01,
3723 5.54029894e-01, 5.10605044e-01, 7.59171671e-01, 1.32427289e+00,
3724 6.01518374e-01, 7.50000000e-01, 8.58373419e-01, 5.10730048e-01,
3725 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 2.67352044e+00},
3726 {0.00000000e+00, 8.53472686e-01, 5.16058658e-01, 6.80946766e-01,
3727 4.35009775e-01, 6.05096970e-01, 1.05158910e+00, 5.19438610e-01,
3728 7.60124356e-01, 1.43810563e+00, 6.85231759e-01, 1.78991633e+00,
3729 4.81561797e+00, 6.11514139e-01, 5.44813932e-01, 9.59915799e-01,
3730 6.78015272e-01, 6.82291911e-01, 8.82308943e-01, 1.21329921e+00,
3731 7.61522900e-01, 7.50000000e-01, 9.17831903e-01, 7.40717150e-01,
3732 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 1.64874201e+00},
3733 {0.00000000e+00, 7.19514908e-01, 3.26949213e+00, 6.01008569e-01,
3734 1.55790069e+00, 9.19771370e-01, 4.38699901e-01, 9.69013722e-01,
3735 1.39406083e+00, 4.50866254e-01, 1.06041456e+00, 4.12652855e-01,
3736 6.11514139e-01, 5.28532229e+00, 6.04265819e-01, 1.03495916e+00,
3737 8.53785837e-01, 1.22434496e+00, 1.10885139e+00, 4.63246441e-01,
3738 3.75696800e-01, 7.50000000e-01, 6.16478872e-01, 9.63798879e-01,
3739 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 4.27987098e-01},
3740 {0.00000000e+00, 7.14770771e-01, 6.61247189e-01, 4.03060607e-01,
3741 7.09628659e-01, 8.38805682e-01, 3.75736079e-01, 6.20168128e-01,
3742 5.81906417e-01, 5.11210841e-01, 7.63679086e-01, 4.43674459e-01,
3743 5.44813932e-01, 6.04265819e-01, 1.02035160e+01, 7.50499600e-01,
3744 5.18638945e-01, 7.59438841e-01, 7.48565360e-01, 5.24438149e-01,
3745 4.20092966e-01, 7.50000000e-01, 4.68173126e-01, 8.05053001e-01,
3746 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 4.70775405e-01},
3747 {0.00000000e+00, 8.19913708e-01, 9.98204754e-01, 4.81296027e-01,
3748 9.66997497e-01, 1.67134451e+00, 4.16967765e-01, 6.41416113e-01,
3749 1.20911332e+00, 5.02656404e-01, 1.41855717e+00, 5.62937315e-01,
3750 9.59915799e-01, 1.03495916e+00, 7.50499600e-01, 4.69722165e+00,
3751 1.35733364e+00, 1.06872445e+00, 8.10316946e-01, 5.57384267e-01,
3752 7.14705591e-01, 7.50000000e-01, 7.42076535e-01, 2.82790659e+00,
3753 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.38747839e-01},
3754 {0.00000000e+00, 6.68351460e-01, 7.59007679e-01, 4.27834290e-01,
3755 6.78533894e-01, 9.76357610e-01, 4.61789222e-01, 5.16985831e-01,
3756 9.81604707e-01, 4.35318230e-01, 2.06468049e+00, 5.54029894e-01,
3757 6.78015272e-01, 8.53785837e-01, 5.18638945e-01, 1.35733364e+00,
3758 5.37787401e+00, 8.04499038e-01, 7.36510915e-01, 5.12488758e-01,
3759 5.28823677e-01, 7.50000000e-01, 7.27125062e-01, 1.12197569e+00,
3760 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.06393371e-01},
3761 {0.00000000e+00, 1.36359270e+00, 1.06055276e+00, 8.29850973e-01,
3762 9.21480865e-01, 8.82100970e-01, 5.52981315e-01, 9.99248542e-01,
3763 8.22540644e-01, 5.45643330e-01, 8.92977250e-01, 5.10605044e-01,
3764 6.82291911e-01, 1.22434496e+00, 7.59438841e-01, 1.06872445e+00,
3765 8.04499038e-01, 3.14298812e+00, 1.49727124e+00, 6.78664919e-01,
3766 3.92328021e-01, 7.50000000e-01, 6.51019697e-01, 9.53432893e-01,
3767 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.24665180e-01},
3768 {0.00000000e+00, 9.67331593e-01, 9.55438618e-01, 8.17890869e-01,
3769 8.25179634e-01, 8.19031320e-01, 5.70349305e-01, 6.36269018e-01,
3770 6.52641826e-01, 8.60722536e-01, 8.44796364e-01, 7.59171671e-01,
3771 8.82308943e-01, 1.10885139e+00, 7.48565360e-01, 8.10316946e-01,
3772 7.36510915e-01, 1.49727124e+00, 3.55307500e+00, 1.05992520e+00,
3773 5.02669810e-01, 7.50000000e-01, 6.90730891e-01, 8.15700480e-01,
3774 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 7.99921922e-01},
3775 {0.00000000e+00, 9.81625416e-01, 4.46192804e-01, 8.08665030e-01,
3776 4.31712984e-01, 4.79075838e-01, 8.59643167e-01, 4.02720033e-01,
3777 4.13620259e-01, 2.31272269e+00, 5.22802406e-01, 1.32427289e+00,
3778 1.21329921e+00, 4.63246441e-01, 5.24438149e-01, 5.57384267e-01,
3779 5.12488758e-01, 6.78664919e-01, 1.05992520e+00, 3.11745700e+00,
3780 4.84839541e-01, 7.50000000e-01, 7.27350506e-01, 5.09007179e-01,
3781 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 1.72091725e+00},
3782 {0.00000000e+00, 4.63560176e-01, 3.38571955e-01, 3.12131245e-01,
3783 3.07050170e-01, 5.48039829e-01, 1.34807169e+00, 5.04888636e-01,
3784 4.75002356e-01, 5.22495607e-01, 4.61593643e-01, 6.01518374e-01,
3785 7.61522900e-01, 3.75696800e-01, 4.20092966e-01, 7.14705591e-01,
3786 5.28823677e-01, 3.92328021e-01, 5.02669810e-01, 4.84839541e-01,
3787 3.13609332e+01, 7.50000000e-01, 1.76515899e+00, 6.11743441e-01,
3788 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 5.69808181e-01},
3789 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3790 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3791 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3792 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3793 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3794 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3795 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 7.50000000e-01},
3796 {0.00000000e+00, 5.96400452e-01, 5.55905269e-01, 5.38704705e-01,
3797 5.04473723e-01, 6.51686488e-01, 2.42442622e+00, 4.67274430e-01,
3798 1.57000854e+00, 8.26095669e-01, 6.67754286e-01, 8.58373419e-01,
3799 9.17831903e-01, 6.16478872e-01, 4.68173126e-01, 7.42076535e-01,
3800 7.27125062e-01, 6.51019697e-01, 6.90730891e-01, 7.27350506e-01,
3801 1.76515899e+00, 7.50000000e-01, 6.89283261e+00, 6.86235710e-01,
3802 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 8.45421029e-01},
3803 {0.00000000e+00, 8.05980349e-01, 1.19634119e+00, 4.65687383e-01,
3804 1.39378711e+00, 3.38012103e+00, 4.41115461e-01, 5.78707493e-01,
3805 1.02524740e+00, 4.48849604e-01, 1.36451940e+00, 5.10730048e-01,
3806 7.40717150e-01, 9.63798879e-01, 8.05053001e-01, 2.82790659e+00,
3807 1.12197569e+00, 9.53432893e-01, 8.15700480e-01, 5.09007179e-01,
3808 6.11743441e-01, 7.50000000e-01, 6.86235710e-01, 3.16905156e+00,
3809 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 4.85898712e-01},
3810 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3811 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3812 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3813 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3814 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3815 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3816 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 7.50000000e-01},
3817 {0.00000000e+00, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3818 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3819 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3820 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3821 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3822 2.90000000e-01, 2.90000000e-01, 2.90000000e-01, 2.90000000e-01,
3823 2.90000000e-01, 1.33300000e+00, 2.90000000e-01, 2.90000000e-01},
3824 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3825 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3826 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3827 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3828 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3829 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3830 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 7.50000000e-01},
3831 {0.00000000e+00, 6.80310043e-01, 3.97605526e-01, 6.24838486e-01,
3832 3.71809285e-01, 4.53200481e-01, 1.15257995e+00, 3.74281590e-01,
3833 4.92911793e-01, 2.38463611e+00, 4.74822110e-01, 2.67352044e+00,
3834 1.64874201e+00, 4.27987098e-01, 4.70775405e-01, 5.38747839e-01,
3835 5.06393371e-01, 5.24665180e-01, 7.99921922e-01, 1.72091725e+00,
3836 5.69808181e-01, 7.50000000e-01, 8.45421029e-01, 4.85898712e-01,
3837 7.50000000e-01, 2.90000000e-01, 7.50000000e-01, 2.55759716e+00}};
3838
3839
3840 /** Underlying frequency ratios for BLOSUM62 */
3841 static const double BLOSUM62_FREQRATIOS[POSITAA_SIZE][POSITAA_SIZE] =
3842 {{0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3843 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3844 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3845 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3846 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3847 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
3848 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00},
3849 {0.00000000e+00, 3.90294070e+00, 5.64459671e-01, 8.67987664e-01,
3850 5.44605275e-01, 7.41264113e-01, 4.64893827e-01, 1.05686961e+00,
3851 5.69364849e-01, 6.32481035e-01, 7.75390239e-01, 6.01945975e-01,
3852 7.23150342e-01, 5.88307640e-01, 7.54121369e-01, 7.56803943e-01,
3853 6.12698600e-01, 1.47210399e+00, 9.84401956e-01, 9.36458396e-01,
3854 4.16548781e-01, 7.50000000e-01, 5.42611869e-01, 7.47274948e-01,
3855 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 6.14377313e-01},
3856 {0.00000000e+00, 5.64459671e-01, 4.43758048e+00, 3.45226274e-01,
3857 4.74290926e+00, 1.33503378e+00, 3.24101420e-01, 7.38524318e-01,
3858 9.25449581e-01, 3.33981361e-01, 8.54849426e-01, 2.97257620e-01,
3859 4.04640322e-01, 4.07083696e+00, 5.53838329e-01, 9.44103648e-01,
3860 7.02873767e-01, 1.05798620e+00, 8.26250098e-01, 3.51280513e-01,
3861 2.52855433e-01, 7.50000000e-01, 4.09444638e-01, 1.18382127e+00,
3862 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 3.12208474e-01},
3863 {0.00000000e+00, 8.67987664e-01, 3.45226274e-01, 1.95765857e+01,
3864 3.01454345e-01, 2.85934574e-01, 4.38990118e-01, 4.20387870e-01,
3865 3.55049505e-01, 6.53458801e-01, 3.49128465e-01, 6.42275633e-01,
3866 6.11354340e-01, 3.97802620e-01, 3.79562691e-01, 3.65781531e-01,
3867 3.08939296e-01, 7.38415701e-01, 7.40551692e-01, 7.55844055e-01,
3868 4.49983903e-01, 7.50000000e-01, 4.34203398e-01, 3.16819526e-01,
3869 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 6.46828489e-01},
3870 {0.00000000e+00, 5.44605275e-01, 4.74290926e+00, 3.01454345e-01,
3871 7.39792738e+00, 1.68781075e+00, 2.98969081e-01, 6.34301019e-01,
3872 6.78558839e-01, 3.39015407e-01, 7.84090406e-01, 2.86613046e-01,
3873 3.46454634e-01, 1.55385281e+00, 5.98716826e-01, 8.97081129e-01,
3874 5.73200024e-01, 9.13504624e-01, 6.94789868e-01, 3.36500142e-01,
3875 2.32102315e-01, 7.50000000e-01, 3.45683565e-01, 1.38195506e+00,
3876 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 3.07946931e-01},
3877 {0.00000000e+00, 7.41264113e-01, 1.33503378e+00, 2.85934574e-01,
3878 1.68781075e+00, 5.46952608e+00, 3.30743991e-01, 4.81267655e-01,
3879 9.60040718e-01, 3.30522558e-01, 1.30827885e+00, 3.72873704e-01,
3880 5.00342289e-01, 9.11298183e-01, 6.79202587e-01, 1.90173784e+00,
3881 9.60797602e-01, 9.50357185e-01, 7.41425610e-01, 4.28943130e-01,
3882 3.74300212e-01, 7.50000000e-01, 4.96467354e-01, 4.08949895e+00,
3883 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 3.55631838e-01},
3884 {0.00000000e+00, 4.64893827e-01, 3.24101420e-01, 4.38990118e-01,
3885 2.98969081e-01, 3.30743991e-01, 8.12879702e+00, 3.40640908e-01,
3886 6.51990521e-01, 9.45769883e-01, 3.44043119e-01, 1.15459749e+00,
3887 1.00437163e+00, 3.54288952e-01, 2.87444758e-01, 3.33972402e-01,
3888 3.80726330e-01, 4.39973597e-01, 4.81693683e-01, 7.45089738e-01,
3889 1.37437942e+00, 7.50000000e-01, 2.76938063e+00, 3.31992746e-01,
3890 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 1.06958025e+00},
3891 {0.00000000e+00, 1.05686961e+00, 7.38524318e-01, 4.20387870e-01,
3892 6.34301019e-01, 4.81267655e-01, 3.40640908e-01, 6.87630691e+00,
3893 4.92966576e-01, 2.75009722e-01, 5.88871736e-01, 2.84504012e-01,
3894 3.95486600e-01, 8.63711406e-01, 4.77385507e-01, 5.38649627e-01,
3895 4.49983999e-01, 9.03596525e-01, 5.79271582e-01, 3.36954912e-01,
3896 4.21690355e-01, 7.50000000e-01, 3.48714366e-01, 5.03463109e-01,
3897 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 2.80638726e-01},
3898 {0.00000000e+00, 5.69364849e-01, 9.25449581e-01, 3.55049505e-01,
3899 6.78558839e-01, 9.60040718e-01, 6.51990521e-01, 4.92966576e-01,
3900 1.35059997e+01, 3.26288125e-01, 7.78887490e-01, 3.80675486e-01,
3901 5.84132623e-01, 1.22200067e+00, 4.72879831e-01, 1.16798104e+00,
3902 9.17048021e-01, 7.36731740e-01, 5.57503254e-01, 3.39447442e-01,
3903 4.44088955e-01, 7.50000000e-01, 1.79790413e+00, 1.04047242e+00,
3904 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 3.58533474e-01},
3905 {0.00000000e+00, 6.32481035e-01, 3.33981361e-01, 6.53458801e-01,
3906 3.39015407e-01, 3.30522558e-01, 9.45769883e-01, 2.75009722e-01,
3907 3.26288125e-01, 3.99792994e+00, 3.96372934e-01, 1.69443475e+00,
3908 1.47774450e+00, 3.27934752e-01, 3.84662860e-01, 3.82937802e-01,
3909 3.54751311e-01, 4.43163582e-01, 7.79816110e-01, 2.41751209e+00,
3910 4.08874390e-01, 7.50000000e-01, 6.30388931e-01, 3.50796872e-01,
3911 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 2.63222650e+00},
3912 {0.00000000e+00, 7.75390239e-01, 8.54849426e-01, 3.49128465e-01,
3913 7.84090406e-01, 1.30827885e+00, 3.44043119e-01, 5.88871736e-01,
3914 7.78887490e-01, 3.96372934e-01, 4.76433717e+00, 4.28270363e-01,
3915 6.25302816e-01, 9.39841129e-01, 7.03774479e-01, 1.55432308e+00,
3916 2.07680867e+00, 9.31919141e-01, 7.92905803e-01, 4.56542720e-01,
3917 3.58930071e-01, 7.50000000e-01, 5.32179333e-01, 1.40344922e+00,
3918 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 4.15284382e-01},
3919 {0.00000000e+00, 6.01945975e-01, 2.97257620e-01, 6.42275633e-01,
3920 2.86613046e-01, 3.72873704e-01, 1.15459749e+00, 2.84504012e-01,
3921 3.80675486e-01, 1.69443475e+00, 4.28270363e-01, 3.79662137e+00,
3922 1.99429557e+00, 3.10043276e-01, 3.71121724e-01, 4.77325586e-01,
3923 4.73919278e-01, 4.28893743e-01, 6.60328975e-01, 1.31423573e+00,
3924 5.68037074e-01, 7.50000000e-01, 6.92059423e-01, 4.13275887e-01,
3925 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 2.94078574e+00},
3926 {0.00000000e+00, 7.23150342e-01, 4.04640322e-01, 6.11354340e-01,
3927 3.46454634e-01, 5.00342289e-01, 1.00437163e+00, 3.95486600e-01,
3928 5.84132623e-01, 1.47774450e+00, 6.25302816e-01, 1.99429557e+00,
3929 6.48145121e+00, 4.74529655e-01, 4.23898024e-01, 8.64250293e-01,
3930 6.22623369e-01, 5.98558924e-01, 7.93801616e-01, 1.26893679e+00,
3931 6.10296214e-01, 7.50000000e-01, 7.08364628e-01, 6.41102583e-01,
3932 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 1.78399892e+00},
3933 {0.00000000e+00, 5.88307640e-01, 4.07083696e+00, 3.97802620e-01,
3934 1.55385281e+00, 9.11298183e-01, 3.54288952e-01, 8.63711406e-01,
3935 1.22200067e+00, 3.27934752e-01, 9.39841129e-01, 3.10043276e-01,
3936 4.74529655e-01, 7.09409488e+00, 4.99932836e-01, 1.00058442e+00,
3937 8.58630478e-01, 1.23152924e+00, 9.84152635e-01, 3.69033853e-01,
3938 2.77782896e-01, 7.50000000e-01, 4.86030806e-01, 9.45834265e-01,
3939 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 3.17327197e-01},
3940 {0.00000000e+00, 7.54121369e-01, 5.53838329e-01, 3.79562691e-01,
3941 5.98716826e-01, 6.79202587e-01, 2.87444758e-01, 4.77385507e-01,
3942 4.72879831e-01, 3.84662860e-01, 7.03774479e-01, 3.71121724e-01,
3943 4.23898024e-01, 4.99932836e-01, 1.28375437e+01, 6.41280589e-01,
3944 4.81534905e-01, 7.55503259e-01, 6.88897122e-01, 4.43082984e-01,
3945 2.81833164e-01, 7.50000000e-01, 3.63521119e-01, 6.64534287e-01,
3946 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 3.76634549e-01},
3947 {0.00000000e+00, 7.56803943e-01, 9.44103648e-01, 3.65781531e-01,
3948 8.97081129e-01, 1.90173784e+00, 3.33972402e-01, 5.38649627e-01,
3949 1.16798104e+00, 3.82937802e-01, 1.55432308e+00, 4.77325586e-01,
3950 8.64250293e-01, 1.00058442e+00, 6.41280589e-01, 6.24442175e+00,
3951 1.40579606e+00, 9.65555228e-01, 7.91320741e-01, 4.66777931e-01,
3952 5.09360272e-01, 7.50000000e-01, 6.11094097e-01, 3.58149606e+00,
3953 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 4.38898727e-01},
3954 {0.00000000e+00, 6.12698600e-01, 7.02873767e-01, 3.08939296e-01,
3955 5.73200024e-01, 9.60797602e-01, 3.80726330e-01, 4.49983999e-01,
3956 9.17048021e-01, 3.54751311e-01, 2.07680867e+00, 4.73919278e-01,
3957 6.22623369e-01, 8.58630478e-01, 4.81534905e-01, 1.40579606e+00,
3958 6.66557707e+00, 7.67165633e-01, 6.77754679e-01, 4.20072316e-01,
3959 3.95102106e-01, 7.50000000e-01, 5.55965425e-01, 1.13292384e+00,
3960 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 4.25403989e-01},
3961 {0.00000000e+00, 1.47210399e+00, 1.05798620e+00, 7.38415701e-01,
3962 9.13504624e-01, 9.50357185e-01, 4.39973597e-01, 9.03596525e-01,
3963 7.36731740e-01, 4.43163582e-01, 9.31919141e-01, 4.28893743e-01,
3964 5.98558924e-01, 1.23152924e+00, 7.55503259e-01, 9.65555228e-01,
3965 7.67165633e-01, 3.84284741e+00, 1.61392097e+00, 5.65223766e-01,
3966 3.85303035e-01, 7.50000000e-01, 5.57520051e-01, 9.56235816e-01,
3967 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 4.34703235e-01},
3968 {0.00000000e+00, 9.84401956e-01, 8.26250098e-01, 7.40551692e-01,
3969 6.94789868e-01, 7.41425610e-01, 4.81693683e-01, 5.79271582e-01,
3970 5.57503254e-01, 7.79816110e-01, 7.92905803e-01, 6.60328975e-01,
3971 7.93801616e-01, 9.84152635e-01, 6.88897122e-01, 7.91320741e-01,
3972 6.77754679e-01, 1.61392097e+00, 4.83210516e+00, 9.80943005e-01,
3973 4.30934144e-01, 7.50000000e-01, 5.73156574e-01, 7.60725140e-01,
3974 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 7.08974203e-01},
3975 {0.00000000e+00, 9.36458396e-01, 3.51280513e-01, 7.55844055e-01,
3976 3.36500142e-01, 4.28943130e-01, 7.45089738e-01, 3.36954912e-01,
3977 3.39447442e-01, 2.41751209e+00, 4.56542720e-01, 1.31423573e+00,
3978 1.26893679e+00, 3.69033853e-01, 4.43082984e-01, 4.66777931e-01,
3979 4.20072316e-01, 5.65223766e-01, 9.80943005e-01, 3.69215640e+00,
3980 3.74456332e-01, 7.50000000e-01, 6.58038693e-01, 4.43577702e-01,
3981 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 1.76339815e+00},
3982 {0.00000000e+00, 4.16548781e-01, 2.52855433e-01, 4.49983903e-01,
3983 2.32102315e-01, 3.74300212e-01, 1.37437942e+00, 4.21690355e-01,
3984 4.44088955e-01, 4.08874390e-01, 3.58930071e-01, 5.68037074e-01,
3985 6.10296214e-01, 2.77782896e-01, 2.81833164e-01, 5.09360272e-01,
3986 3.95102106e-01, 3.85303035e-01, 4.30934144e-01, 3.74456332e-01,
3987 3.81077833e+01, 7.50000000e-01, 2.10980812e+00, 4.26541694e-01,
3988 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 5.03239261e-01},
3989 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3990 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3991 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3992 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3993 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3994 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
3995 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 7.50000000e-01},
3996 {0.00000000e+00, 5.42611869e-01, 4.09444638e-01, 4.34203398e-01,
3997 3.45683565e-01, 4.96467354e-01, 2.76938063e+00, 3.48714366e-01,
3998 1.79790413e+00, 6.30388931e-01, 5.32179333e-01, 6.92059423e-01,
3999 7.08364628e-01, 4.86030806e-01, 3.63521119e-01, 6.11094097e-01,
4000 5.55965425e-01, 5.57520051e-01, 5.73156574e-01, 6.58038693e-01,
4001 2.10980812e+00, 7.50000000e-01, 9.83220341e+00, 5.40805192e-01,
4002 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 6.66952325e-01},
4003 {0.00000000e+00, 7.47274948e-01, 1.18382127e+00, 3.16819526e-01,
4004 1.38195506e+00, 4.08949895e+00, 3.31992746e-01, 5.03463109e-01,
4005 1.04047242e+00, 3.50796872e-01, 1.40344922e+00, 4.13275887e-01,
4006 6.41102583e-01, 9.45834265e-01, 6.64534287e-01, 3.58149606e+00,
4007 1.13292384e+00, 9.56235816e-01, 7.60725140e-01, 4.43577702e-01,
4008 4.26541694e-01, 7.50000000e-01, 5.40805192e-01, 3.89300249e+00,
4009 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 3.87839626e-01},
4010 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4011 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4012 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4013 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4014 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4015 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4016 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 7.50000000e-01},
4017 {0.00000000e+00, 2.50000000e-01, 2.50000000e-01, 2.50000000e-01,
4018 2.50000000e-01, 2.50000000e-01, 2.50000000e-01, 2.50000000e-01,
4019 2.50000000e-01, 2.50000000e-01, 2.50000000e-01, 2.50000000e-01,
4020 2.50000000e-01, 2.50000000e-01, 2.50000000e-01, 2.50000000e-01,
4021 2.50000000e-01, 2.50000000e-01, 2.50000000e-01, 2.50000000e-01,
4022 2.50000000e-01, 2.50000000e-01, 2.50000000e-01, 2.50000000e-01,
4023 2.50000000e-01, 1.33300000e+00, 2.50000000e-01, 2.50000000e-01},
4024 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4025 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4026 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4027 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4028 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4029 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4030 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 7.50000000e-01},
4031 {0.00000000e+00, 6.14377313e-01, 3.12208474e-01, 6.46828489e-01,
4032 3.07946931e-01, 3.55631838e-01, 1.06958025e+00, 2.80638726e-01,
4033 3.58533474e-01, 2.63222650e+00, 4.15284382e-01, 2.94078574e+00,
4034 1.78399892e+00, 3.17327197e-01, 3.76634549e-01, 4.38898727e-01,
4035 4.25403989e-01, 4.34703235e-01, 7.08974203e-01, 1.76339815e+00,
4036 5.03239261e-01, 7.50000000e-01, 6.66952325e-01, 3.87839626e-01,
4037 7.50000000e-01, 2.50000000e-01, 7.50000000e-01, 2.81516607e+00}};
4038
4039
4040 /** Underlying frequency ratios for BLOSUM80 */
4041 static const double BLOSUM80_FREQRATIOS[POSITAA_SIZE][POSITAA_SIZE] =
4042 {{0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4043 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4044 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4045 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4046 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4047 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4048 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00},
4049 {0.00000000e+00, 4.77313697e+00, 4.77250219e-01, 7.31790935e-01,
4050 4.50905428e-01, 7.03141318e-01, 3.96805472e-01, 9.57108118e-01,
4051 5.14428496e-01, 5.43302985e-01, 7.22895459e-01, 5.04576848e-01,
4052 6.25509899e-01, 5.10109254e-01, 7.71095354e-01, 6.95763501e-01,
4053 5.55324683e-01, 1.53463504e+00, 9.79634362e-01, 8.65874830e-01,
4054 3.09281009e-01, 7.50000000e-01, 4.36234494e-01, 7.00327585e-01,
4055 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 5.20181427e-01},
4056 {0.00000000e+00, 4.77250219e-01, 5.36249708e+00, 2.52383415e-01,
4057 5.75921529e+00, 1.26868736e+00, 2.51452613e-01, 6.38679494e-01,
4058 8.30167261e-01, 2.33516284e-01, 7.93249084e-01, 2.20539708e-01,
4059 3.09639510e-01, 4.86768283e+00, 4.28138134e-01, 8.50001386e-01,
4060 6.08526572e-01, 9.48166786e-01, 7.43109762e-01, 2.67977796e-01,
4061 1.78830543e-01, 7.50000000e-01, 3.07187296e-01, 1.10900996e+00,
4062 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 2.25768580e-01},
4063 {0.00000000e+00, 7.31790935e-01, 2.52383415e-01, 2.07020176e+01,
4064 2.13899571e-01, 1.79625278e-01, 3.94756499e-01, 2.72055621e-01,
4065 2.21322329e-01, 5.81174860e-01, 2.41148280e-01, 4.92657548e-01,
4066 4.99414247e-01, 3.00383113e-01, 2.69170214e-01, 2.95117493e-01,
4067 2.32476995e-01, 5.76114817e-01, 6.01733396e-01, 6.34451252e-01,
4068 3.02232769e-01, 7.50000000e-01, 3.07930831e-01, 2.23671408e-01,
4069 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 5.28325329e-01},
4070 {0.00000000e+00, 4.50905428e-01, 5.75921529e+00, 2.13899571e-01,
4071 9.10634223e+00, 1.63552603e+00, 2.34434106e-01, 5.40654444e-01,
4072 5.94384672e-01, 2.14047157e-01, 6.76875328e-01, 1.97166761e-01,
4073 2.51946380e-01, 1.58444827e+00, 4.52407652e-01, 7.63275386e-01,
4074 4.76639455e-01, 7.74041684e-01, 6.10882957e-01, 2.44693975e-01,
4075 1.44774364e-01, 7.50000000e-01, 2.45193294e-01, 1.30286928e+00,
4076 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 2.03968665e-01},
4077 {0.00000000e+00, 7.03141318e-01, 1.26868736e+00, 1.79625278e-01,
4078 1.63552603e+00, 6.99475019e+00, 2.48970812e-01, 3.99359878e-01,
4079 9.01259830e-01, 2.64258683e-01, 1.19492933e+00, 2.75527698e-01,
4080 4.28576433e-01, 8.11140936e-01, 5.81414067e-01, 1.90643780e+00,
4081 8.31863127e-01, 8.45039731e-01, 6.85529376e-01, 3.69379335e-01,
4082 2.40807712e-01, 7.50000000e-01, 3.32874109e-01, 5.05418243e+00,
4083 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 2.70986883e-01},
4084 {0.00000000e+00, 3.96805472e-01, 2.51452613e-01, 3.94756499e-01,
4085 2.34434106e-01, 2.48970812e-01, 9.48547379e+00, 2.48796540e-01,
4086 5.71854758e-01, 8.40573731e-01, 2.82718808e-01, 1.11429351e+00,
4087 8.93330223e-01, 2.72679266e-01, 2.37160811e-01, 2.85158291e-01,
4088 2.87269045e-01, 3.69100895e-01, 4.45199900e-01, 6.48888163e-01,
4089 1.08939386e+00, 7.50000000e-01, 2.78024963e+00, 2.62771902e-01,
4090 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 1.00399896e+00},
4091 {0.00000000e+00, 9.57108118e-01, 6.38679494e-01, 2.72055621e-01,
4092 5.40654444e-01, 3.99359878e-01, 2.48796540e-01, 7.88244144e+00,
4093 3.87151686e-01, 1.84455102e-01, 4.83435068e-01, 2.10542976e-01,
4094 2.86067872e-01, 7.60943081e-01, 3.47300820e-01, 4.24585221e-01,
4095 3.77442786e-01, 7.84315177e-01, 4.92238430e-01, 2.50954947e-01,
4096 2.64396616e-01, 7.50000000e-01, 2.29516029e-01, 4.08980256e-01,
4097 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 2.00030947e-01},
4098 {0.00000000e+00, 5.14428496e-01, 8.30167261e-01, 2.21322329e-01,
4099 5.94384672e-01, 9.01259830e-01, 5.71854758e-01, 3.87151686e-01,
4100 1.60694674e+01, 2.57933576e-01, 7.40110055e-01, 3.14299881e-01,
4101 4.32076355e-01, 1.12425153e+00, 4.19656882e-01, 1.31555625e+00,
4102 9.25536475e-01, 6.61407005e-01, 5.39570743e-01, 2.88933760e-01,
4103 3.90225420e-01, 7.50000000e-01, 1.81930455e+00, 1.05926315e+00,
4104 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 2.91587251e-01},
4105 {0.00000000e+00, 5.43302985e-01, 2.33516284e-01, 5.81174860e-01,
4106 2.14047157e-01, 2.64258683e-01, 8.40573731e-01, 1.84455102e-01,
4107 2.57933576e-01, 4.86762150e+00, 3.13345237e-01, 1.66499837e+00,
4108 1.51247384e+00, 2.57799519e-01, 2.85790430e-01, 3.09071252e-01,
4109 2.99348100e-01, 3.78995471e-01, 7.00511896e-01, 2.49584558e+00,
4110 3.43150987e-01, 7.50000000e-01, 5.39308441e-01, 2.81349188e-01,
4111 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 2.95548558e+00},
4112 {0.00000000e+00, 7.22895459e-01, 7.93249084e-01, 2.41148280e-01,
4113 6.76875328e-01, 1.19492933e+00, 2.82718808e-01, 4.83435068e-01,
4114 7.40110055e-01, 3.13345237e-01, 6.32564527e+00, 3.56851811e-01,
4115 5.34403407e-01, 9.38398440e-01, 5.96694133e-01, 1.52403165e+00,
4116 2.19214139e+00, 8.20193974e-01, 7.35729790e-01, 3.70194033e-01,
4117 2.41427653e-01, 7.50000000e-01, 4.08501941e-01, 1.32044155e+00,
4118 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 3.39320970e-01},
4119 {0.00000000e+00, 5.04576848e-01, 2.20539708e-01, 4.92657548e-01,
4120 1.97166761e-01, 2.75527698e-01, 1.11429351e+00, 2.10542976e-01,
4121 3.14299881e-01, 1.66499837e+00, 3.56851811e-01, 4.46305621e+00,
4122 2.12274889e+00, 2.49692056e-01, 3.03099202e-01, 4.06904090e-01,
4123 3.62830591e-01, 3.68478686e-01, 5.60836408e-01, 1.22050154e+00,
4124 4.38789464e-01, 7.50000000e-01, 5.80503535e-01, 3.25631695e-01,
4125 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 3.33558735e+00},
4126 {0.00000000e+00, 6.25509899e-01, 3.09639510e-01, 4.99414247e-01,
4127 2.51946380e-01, 4.28576433e-01, 8.93330223e-01, 2.86067872e-01,
4128 4.32076355e-01, 1.51247384e+00, 5.34403407e-01, 2.12274889e+00,
4129 8.88346290e+00, 3.81598352e-01, 3.61925345e-01, 8.86557630e-01,
4130 5.05866341e-01, 4.98438721e-01, 7.57959723e-01, 1.22414515e+00,
4131 5.60653516e-01, 7.50000000e-01, 5.49937808e-01, 6.03240148e-01,
4132 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 1.87684042e+00},
4133 {0.00000000e+00, 5.10109254e-01, 4.86768283e+00, 3.00383113e-01,
4134 1.58444827e+00, 8.11140936e-01, 2.72679266e-01, 7.60943081e-01,
4135 1.12425153e+00, 2.57799519e-01, 9.38398440e-01, 2.49692056e-01,
4136 3.81598352e-01, 8.96275887e+00, 3.97867522e-01, 9.58172021e-01,
4137 7.73025258e-01, 1.16534759e+00, 9.08032132e-01, 2.97018980e-01,
4138 2.21307752e-01, 7.50000000e-01, 3.84510481e-01, 8.67215281e-01,
4139 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 2.52958933e-01},
4140 {0.00000000e+00, 7.71095354e-01, 4.28138134e-01, 2.69170214e-01,
4141 4.52407652e-01, 5.81414067e-01, 2.37160811e-01, 3.47300820e-01,
4142 4.19656882e-01, 2.85790430e-01, 5.96694133e-01, 3.03099202e-01,
4143 3.61925345e-01, 3.97867522e-01, 1.51545798e+01, 5.37994539e-01,
4144 4.45589871e-01, 6.51704179e-01, 5.60357280e-01, 3.70233083e-01,
4145 1.78033069e-01, 7.50000000e-01, 2.57545983e-01, 5.64854837e-01,
4146 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 2.96124685e-01},
4147 {0.00000000e+00, 6.95763501e-01, 8.50001386e-01, 2.95117493e-01,
4148 7.63275386e-01, 1.90643780e+00, 2.85158291e-01, 4.24585221e-01,
4149 1.31555625e+00, 3.09071252e-01, 1.52403165e+00, 4.06904090e-01,
4150 8.86557630e-01, 9.58172021e-01, 5.37994539e-01, 8.33990474e+00,
4151 1.39424540e+00, 8.58988713e-01, 7.24369298e-01, 4.10943414e-01,
4152 4.07901262e-01, 7.50000000e-01, 4.61857147e-01, 4.36001721e+00,
4153 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 3.67482647e-01},
4154 {0.00000000e+00, 5.55324683e-01, 6.08526572e-01, 2.32476995e-01,
4155 4.76639455e-01, 8.31863127e-01, 2.87269045e-01, 3.77442786e-01,
4156 9.25536475e-01, 2.99348100e-01, 2.19214139e+00, 3.62830591e-01,
4157 5.05866341e-01, 7.73025258e-01, 4.45589871e-01, 1.39424540e+00,
4158 8.24459589e+00, 6.94509540e-01, 5.98385216e-01, 3.53719047e-01,
4159 2.94245493e-01, 7.50000000e-01, 4.17775411e-01, 1.04634306e+00,
4160 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 3.37250515e-01},
4161 {0.00000000e+00, 1.53463504e+00, 9.48166786e-01, 5.76114817e-01,
4162 7.74041684e-01, 8.45039731e-01, 3.69100895e-01, 7.84315177e-01,
4163 6.61407005e-01, 3.78995471e-01, 8.20193974e-01, 3.68478686e-01,
4164 4.98438721e-01, 1.16534759e+00, 6.51704179e-01, 8.58988713e-01,
4165 6.94509540e-01, 5.10577131e+00, 1.66260189e+00, 4.93679246e-01,
4166 2.70773669e-01, 7.50000000e-01, 4.62005069e-01, 8.50359559e-01,
4167 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 3.72716393e-01},
4168 {0.00000000e+00, 9.79634362e-01, 7.43109762e-01, 6.01733396e-01,
4169 6.10882957e-01, 6.85529376e-01, 4.45199900e-01, 4.92238430e-01,
4170 5.39570743e-01, 7.00511896e-01, 7.35729790e-01, 5.60836408e-01,
4171 7.57959723e-01, 9.08032132e-01, 5.60357280e-01, 7.24369298e-01,
4172 5.98385216e-01, 1.66260189e+00, 6.20547751e+00, 8.91492247e-01,
4173 2.85084781e-01, 7.50000000e-01, 4.74451641e-01, 7.00342047e-01,
4174 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 6.17118219e-01},
4175 {0.00000000e+00, 8.65874830e-01, 2.67977796e-01, 6.34451252e-01,
4176 2.44693975e-01, 3.69379335e-01, 6.48888163e-01, 2.50954947e-01,
4177 2.88933760e-01, 2.49584558e+00, 3.70194033e-01, 1.22050154e+00,
4178 1.22414515e+00, 2.97018980e-01, 3.70233083e-01, 4.10943414e-01,
4179 3.53719047e-01, 4.93679246e-01, 8.91492247e-01, 4.58356287e+00,
4180 3.42175943e-01, 7.50000000e-01, 4.89223745e-01, 3.85230939e-01,
4181 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 1.73439753e+00},
4182 {0.00000000e+00, 3.09281009e-01, 1.78830543e-01, 3.02232769e-01,
4183 1.44774364e-01, 2.40807712e-01, 1.08939386e+00, 2.64396616e-01,
4184 3.90225420e-01, 3.43150987e-01, 2.41427653e-01, 4.38789464e-01,
4185 5.60653516e-01, 2.21307752e-01, 1.78033069e-01, 4.07901262e-01,
4186 2.94245493e-01, 2.70773669e-01, 2.85084781e-01, 3.42175943e-01,
4187 4.15522183e+01, 7.50000000e-01, 2.03605072e+00, 3.04533429e-01,
4188 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 4.00252232e-01},
4189 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4190 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4191 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4192 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4193 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4194 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4195 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 7.50000000e-01},
4196 {0.00000000e+00, 4.36234494e-01, 3.07187296e-01, 3.07930831e-01,
4197 2.45193294e-01, 3.32874109e-01, 2.78024963e+00, 2.29516029e-01,
4198 1.81930455e+00, 5.39308441e-01, 4.08501941e-01, 5.80503535e-01,
4199 5.49937808e-01, 3.84510481e-01, 2.57545983e-01, 4.61857147e-01,
4200 4.17775411e-01, 4.62005069e-01, 4.74451641e-01, 4.89223745e-01,
4201 2.03605072e+00, 7.50000000e-01, 1.21940332e+01, 3.82065335e-01,
4202 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 5.63904098e-01},
4203 {0.00000000e+00, 7.00327585e-01, 1.10900996e+00, 2.23671408e-01,
4204 1.30286928e+00, 5.05418243e+00, 2.62771902e-01, 4.08980256e-01,
4205 1.05926315e+00, 2.81349188e-01, 1.32044155e+00, 3.25631695e-01,
4206 6.03240148e-01, 8.67215281e-01, 5.64854837e-01, 4.36001721e+00,
4207 1.04634306e+00, 8.50359559e-01, 7.00342047e-01, 3.85230939e-01,
4208 3.04533429e-01, 7.50000000e-01, 3.82065335e-01, 4.78944345e+00,
4209 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 3.07788194e-01},
4210 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4211 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4212 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4213 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4214 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4215 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4216 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 7.50000000e-01},
4217 {0.00000000e+00, 1.40000000e-01, 1.40000000e-01, 1.40000000e-01,
4218 1.40000000e-01, 1.40000000e-01, 1.40000000e-01, 1.40000000e-01,
4219 1.40000000e-01, 1.40000000e-01, 1.40000000e-01, 1.40000000e-01,
4220 1.40000000e-01, 1.40000000e-01, 1.40000000e-01, 1.40000000e-01,
4221 1.40000000e-01, 1.40000000e-01, 1.40000000e-01, 1.40000000e-01,
4222 1.40000000e-01, 1.40000000e-01, 1.40000000e-01, 1.40000000e-01,
4223 1.40000000e-01, 1.33300000e+00, 1.40000000e-01, 1.40000000e-01},
4224 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4225 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4226 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4227 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4228 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4229 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4230 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 7.50000000e-01},
4231 {0.00000000e+00, 5.20181427e-01, 2.25768580e-01, 5.28325329e-01,
4232 2.03968665e-01, 2.70986883e-01, 1.00399896e+00, 2.00030947e-01,
4233 2.91587251e-01, 2.95548558e+00, 3.39320970e-01, 3.33558735e+00,
4234 1.87684042e+00, 2.52958933e-01, 2.96124685e-01, 3.67482647e-01,
4235 3.37250515e-01, 3.72716393e-01, 6.17118219e-01, 1.73439753e+00,
4236 4.00252232e-01, 7.50000000e-01, 5.63904098e-01, 3.07788194e-01,
4237 7.50000000e-01, 1.40000000e-01, 7.50000000e-01, 3.18242650e+00}};
4238
4239
4240 /** Underlying frequency ratios for BLOSUM90 */
4241 static const double BLOSUM90_FREQRATIOS[POSITAA_SIZE][POSITAA_SIZE] =
4242 {{0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4243 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4244 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4245 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4246 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4247 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4248 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00},
4249 {0.00000000e+00, 5.49812903e+00, 4.38682591e-01, 6.69393543e-01,
4250 4.10593787e-01, 6.67362415e-01, 3.46907686e-01, 8.55253386e-01,
4251 4.61993747e-01, 4.75838329e-01, 6.64089300e-01, 4.46304927e-01,
4252 5.48948177e-01, 4.75350260e-01, 7.12075051e-01, 6.37043670e-01,
4253 5.31189855e-01, 1.45279278e+00, 9.34706358e-01, 7.93712275e-01,
4254 2.83637106e-01, 7.50000000e-01, 3.70274337e-01, 6.55892238e-01,
4255 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 4.58271706e-01},
4256 {0.00000000e+00, 4.38682591e-01, 5.85593083e+00, 2.24322103e-01,
4257 6.24911512e+00, 1.23816514e+00, 2.14608760e-01, 5.64122407e-01,
4258 7.82997018e-01, 1.96621553e-01, 7.38810616e-01, 1.94127812e-01,
4259 2.69937418e-01, 5.34266045e+00, 3.78549747e-01, 7.81147613e-01,
4260 5.45762328e-01, 8.70271567e-01, 6.66528685e-01, 2.28904046e-01,
4261 1.42810925e-01, 7.50000000e-01, 2.77062678e-01, 1.06526643e+00,
4262 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 1.95138263e-01},
4263 {0.00000000e+00, 6.69393543e-01, 2.24322103e-01, 2.16370056e+01,
4264 1.76054992e-01, 1.47039970e-01, 3.92579579e-01, 2.18182122e-01,
4265 1.93552170e-01, 5.20896357e-01, 2.15679622e-01, 4.25126435e-01,
4266 4.27104871e-01, 2.87330927e-01, 2.30151009e-01, 2.42068607e-01,
4267 2.06242089e-01, 5.23756471e-01, 5.48342086e-01, 5.88014943e-01,
4268 2.50594014e-01, 7.50000000e-01, 2.92512133e-01, 1.82991170e-01,
4269 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 4.63931905e-01},
4270 {0.00000000e+00, 4.10593787e-01, 6.24911512e+00, 1.76054992e-01,
4271 9.87094836e+00, 1.61092322e+00, 1.97472144e-01, 4.84699282e-01,
4272 5.46208942e-01, 1.71646922e-01, 6.20942905e-01, 1.71021465e-01,
4273 2.15937410e-01, 1.52110375e+00, 3.99848977e-01, 6.86343892e-01,
4274 4.17577647e-01, 6.96691332e-01, 5.29001708e-01, 2.06199101e-01,
4275 1.15609648e-01, 7.50000000e-01, 2.13739536e-01, 1.26113669e+00,
4276 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 1.71274897e-01},
4277 {0.00000000e+00, 6.67362415e-01, 1.23816514e+00, 1.47039970e-01,
4278 1.61092322e+00, 7.91072600e+00, 2.04920324e-01, 3.47008914e-01,
4279 7.72534981e-01, 2.37473636e-01, 1.07737256e+00, 2.37238651e-01,
4280 3.61519510e-01, 7.51559518e-01, 5.28989676e-01, 1.83144568e+00,
4281 7.31811567e-01, 7.59912485e-01, 6.13331345e-01, 3.33942314e-01,
4282 2.02669731e-01, 7.50000000e-01, 2.73296982e-01, 5.61081481e+00,
4283 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 2.37333866e-01},
4284 {0.00000000e+00, 3.46907686e-01, 2.14608760e-01, 3.92579579e-01,
4285 1.97472144e-01, 2.04920324e-01, 1.05190688e+01, 1.97046381e-01,
4286 5.10867985e-01, 7.73236776e-01, 2.73932585e-01, 1.05058955e+00,
4287 8.11125795e-01, 2.36979230e-01, 2.12448013e-01, 2.80742738e-01,
4288 2.62210098e-01, 3.33306129e-01, 3.90547453e-01, 5.77272331e-01,
4289 9.82154073e-01, 7.50000000e-01, 2.77172979e+00, 2.33605433e-01,
4290 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 9.38207661e-01},
4291 {0.00000000e+00, 8.55253386e-01, 5.64122407e-01, 2.18182122e-01,
4292 4.84699282e-01, 3.47008914e-01, 1.97046381e-01, 8.29576319e+00,
4293 3.35169505e-01, 1.51428808e-01, 4.27685370e-01, 1.83265898e-01,
4294 2.37360208e-01, 6.67802895e-01, 2.98989408e-01, 3.80871171e-01,
4295 3.28608745e-01, 7.00460225e-01, 4.00474342e-01, 2.02269779e-01,
4296 2.34021877e-01, 7.50000000e-01, 1.88904853e-01, 3.59819671e-01,
4297 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 1.70365676e-01},
4298 {0.00000000e+00, 4.61993747e-01, 7.82997018e-01, 1.93552170e-01,
4299 5.46208942e-01, 7.72534981e-01, 5.10867985e-01, 3.35169505e-01,
4300 1.85636930e+01, 2.32236241e-01, 6.80230209e-01, 2.89296785e-01,
4301 4.06641319e-01, 1.09210477e+00, 3.99528365e-01, 1.24778653e+00,
4302 8.70382542e-01, 5.94270003e-01, 4.71855284e-01, 2.49881715e-01,
4303 3.84396440e-01, 7.50000000e-01, 1.62620965e+00, 9.52331980e-01,
4304 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 2.66176152e-01},
4305 {0.00000000e+00, 4.75838329e-01, 1.96621553e-01, 5.20896357e-01,
4306 1.71646922e-01, 2.37473636e-01, 7.73236776e-01, 1.51428808e-01,
4307 2.32236241e-01, 5.62471003e+00, 2.84042165e-01, 1.59032509e+00,
4308 1.47982983e+00, 2.29223921e-01, 2.60766373e-01, 2.80218761e-01,
4309 2.69951432e-01, 3.32350183e-01, 6.20404233e-01, 2.47466358e+00,
4310 2.84494454e-01, 7.50000000e-01, 4.78737209e-01, 2.53644956e-01,
4311 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 3.22503669e+00},
4312 {0.00000000e+00, 6.64089300e-01, 7.38810616e-01, 2.15679622e-01,
4313 6.20942905e-01, 1.07737256e+00, 2.73932585e-01, 4.27685370e-01,
4314 6.80230209e-01, 2.84042165e-01, 7.40971353e+00, 3.18645229e-01,
4315 5.03980900e-01, 8.92677413e-01, 5.54085013e-01, 1.48494120e+00,
4316 2.15988586e+00, 7.31921781e-01, 6.80549543e-01, 3.28415139e-01,
4317 1.74946435e-01, 7.50000000e-01, 3.46172886e-01, 1.23156378e+00,
4318 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 3.04624249e-01},
4319 {0.00000000e+00, 4.46304927e-01, 1.94127812e-01, 4.25126435e-01,
4320 1.71021465e-01, 2.37238651e-01, 1.05058955e+00, 1.83265898e-01,
4321 2.89296785e-01, 1.59032509e+00, 3.18645229e-01, 5.03145573e+00,
4322 2.07702392e+00, 2.24291285e-01, 2.72188366e-01, 3.74709469e-01,
4323 3.26170372e-01, 3.38914311e-01, 5.07385737e-01, 1.13293282e+00,
4324 3.72830750e-01, 7.50000000e-01, 5.08794972e-01, 2.89246563e-01,
4325 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 3.63712766e+00},
4326 {0.00000000e+00, 5.48948177e-01, 2.69937418e-01, 4.27104871e-01,
4327 2.15937410e-01, 3.61519510e-01, 8.11125795e-01, 2.37360208e-01,
4328 4.06641319e-01, 1.47982983e+00, 5.03980900e-01, 2.07702392e+00,
4329 1.13394084e+01, 3.40430076e-01, 3.16108504e-01, 8.49621832e-01,
4330 4.63059321e-01, 4.39100157e-01, 6.79030953e-01, 1.13727027e+00,
4331 4.92730381e-01, 7.50000000e-01, 4.80316866e-01, 5.46178209e-01,
4332 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 1.83504401e+00},
4333 {0.00000000e+00, 4.75350260e-01, 5.34266045e+00, 2.87330927e-01,
4334 1.52110375e+00, 7.51559518e-01, 2.36979230e-01, 6.67802895e-01,
4335 1.09210477e+00, 2.29223921e-01, 8.92677413e-01, 2.24291285e-01,
4336 3.40430076e-01, 1.03313947e+01, 3.50745318e-01, 9.04906229e-01,
4337 7.13097098e-01, 1.09686657e+00, 8.46059068e-01, 2.58543521e-01,
4338 1.78320001e-01, 7.50000000e-01, 3.59725936e-01, 8.09573592e-01,
4339 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 2.26289963e-01},
4340 {0.00000000e+00, 7.12075051e-01, 3.78549747e-01, 2.30151009e-01,
4341 3.99848977e-01, 5.28989676e-01, 2.12448013e-01, 2.98989408e-01,
4342 3.99528365e-01, 2.60766373e-01, 5.54085013e-01, 2.72188366e-01,
4343 3.16108504e-01, 3.50745318e-01, 1.60877707e+01, 4.86643270e-01,
4344 4.09306303e-01, 5.93677872e-01, 4.80576271e-01, 3.23032809e-01,
4345 1.74477792e-01, 7.50000000e-01, 2.13074361e-01, 5.12969199e-01,
4346 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 2.67560235e-01},
4347 {0.00000000e+00, 6.37043670e-01, 7.81147613e-01, 2.42068607e-01,
4348 6.86343892e-01, 1.83144568e+00, 2.80742738e-01, 3.80871171e-01,
4349 1.24778653e+00, 2.80218761e-01, 1.48494120e+00, 3.74709469e-01,
4350 8.49621832e-01, 9.04906229e-01, 4.86643270e-01, 9.98642121e+00,
4351 1.25897253e+00, 7.86784913e-01, 6.71486014e-01, 3.48766905e-01,
4352 3.51106744e-01, 7.50000000e-01, 4.01714365e-01, 4.91663315e+00,
4353 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 3.36422330e-01},
4354 {0.00000000e+00, 5.31189855e-01, 5.45762328e-01, 2.06242089e-01,
4355 4.17577647e-01, 7.31811567e-01, 2.62210098e-01, 3.28608745e-01,
4356 8.70382542e-01, 2.69951432e-01, 2.15988586e+00, 3.26170372e-01,
4357 4.63059321e-01, 7.13097098e-01, 4.09306303e-01, 1.25897253e+00,
4358 9.45518393e+00, 6.27094667e-01, 5.25362150e-01, 3.16415957e-01,
4359 2.48889195e-01, 7.50000000e-01, 3.62347797e-01, 9.31246918e-01,
4360 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 3.03390753e-01},
4361 {0.00000000e+00, 1.45279278e+00, 8.70271567e-01, 5.23756471e-01,
4362 6.96691332e-01, 7.59912485e-01, 3.33306129e-01, 7.00460225e-01,
4363 5.94270003e-01, 3.32350183e-01, 7.31921781e-01, 3.38914311e-01,
4364 4.39100157e-01, 1.09686657e+00, 5.93677872e-01, 7.86784913e-01,
4365 6.27094667e-01, 5.99164849e+00, 1.62868240e+00, 4.49399804e-01,
4366 2.30316670e-01, 7.50000000e-01, 4.11583504e-01, 7.70078852e-01,
4367 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 3.36254561e-01},
4368 {0.00000000e+00, 9.34706358e-01, 6.66528685e-01, 5.48342086e-01,
4369 5.29001708e-01, 6.13331345e-01, 3.90547453e-01, 4.00474342e-01,
4370 4.71855284e-01, 6.20404233e-01, 6.80549543e-01, 5.07385737e-01,
4371 6.79030953e-01, 8.46059068e-01, 4.80576271e-01, 6.71486014e-01,
4372 5.25362150e-01, 1.62868240e+00, 7.25868130e+00, 8.04058132e-01,
4373 2.27083637e-01, 7.50000000e-01, 4.20544390e-01, 6.35332398e-01,
4374 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 5.53180238e-01},
4375 {0.00000000e+00, 7.93712275e-01, 2.28904046e-01, 5.88014943e-01,
4376 2.06199101e-01, 3.33942314e-01, 5.77272331e-01, 2.02269779e-01,
4377 2.49881715e-01, 2.47466358e+00, 3.28415139e-01, 1.13293282e+00,
4378 1.13727027e+00, 2.58543521e-01, 3.23032809e-01, 3.48766905e-01,
4379 3.16415957e-01, 4.49399804e-01, 8.04058132e-01, 5.31607752e+00,
4380 2.99756311e-01, 7.50000000e-01, 4.04621372e-01, 3.39550748e-01,
4381 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 1.67659508e+00},
4382 {0.00000000e+00, 2.83637106e-01, 1.42810925e-01, 2.50594014e-01,
4383 1.15609648e-01, 2.02669731e-01, 9.82154073e-01, 2.34021877e-01,
4384 3.84396440e-01, 2.84494454e-01, 1.74946435e-01, 3.72830750e-01,
4385 4.92730381e-01, 1.78320001e-01, 1.74477792e-01, 3.51106744e-01,
4386 2.48889195e-01, 2.30316670e-01, 2.27083637e-01, 2.99756311e-01,
4387 4.26750567e+01, 7.50000000e-01, 1.77446682e+00, 2.58826370e-01,
4388 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 3.37037347e-01},
4389 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4390 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4391 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4392 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4393 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4394 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4395 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 7.50000000e-01},
4396 {0.00000000e+00, 3.70274337e-01, 2.77062678e-01, 2.92512133e-01,
4397 2.13739536e-01, 2.73296982e-01, 2.77172979e+00, 1.88904853e-01,
4398 1.62620965e+00, 4.78737209e-01, 3.46172886e-01, 5.08794972e-01,
4399 4.80316866e-01, 3.59725936e-01, 2.13074361e-01, 4.01714365e-01,
4400 3.62347797e-01, 4.11583504e-01, 4.20544390e-01, 4.04621372e-01,
4401 1.77446682e+00, 7.50000000e-01, 1.36090374e+01, 3.21879801e-01,
4402 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 4.96615724e-01},
4403 {0.00000000e+00, 6.55892238e-01, 1.06526643e+00, 1.82991170e-01,
4404 1.26113669e+00, 5.61081481e+00, 2.33605433e-01, 3.59819671e-01,
4405 9.52331980e-01, 2.53644956e-01, 1.23156378e+00, 2.89246563e-01,
4406 5.46178209e-01, 8.09573592e-01, 5.12969199e-01, 4.91663315e+00,
4407 9.31246918e-01, 7.70078852e-01, 6.35332398e-01, 3.39550748e-01,
4408 2.58826370e-01, 7.50000000e-01, 3.21879801e-01, 5.34819225e+00,
4409 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 2.74820979e-01},
4410 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4411 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4412 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4413 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4414 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4415 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4416 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 7.50000000e-01},
4417 {0.00000000e+00, 1.20000000e-01, 1.20000000e-01, 1.20000000e-01,
4418 1.20000000e-01, 1.20000000e-01, 1.20000000e-01, 1.20000000e-01,
4419 1.20000000e-01, 1.20000000e-01, 1.20000000e-01, 1.20000000e-01,
4420 1.20000000e-01, 1.20000000e-01, 1.20000000e-01, 1.20000000e-01,
4421 1.20000000e-01, 1.20000000e-01, 1.20000000e-01, 1.20000000e-01,
4422 1.20000000e-01, 1.20000000e-01, 1.20000000e-01, 1.20000000e-01,
4423 1.20000000e-01, 1.33300000e+00, 1.20000000e-01, 1.20000000e-01},
4424 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4425 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4426 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4427 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4428 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4429 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4430 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 7.50000000e-01},
4431 {0.00000000e+00, 4.58271706e-01, 1.95138263e-01, 4.63931905e-01,
4432 1.71274897e-01, 2.37333866e-01, 9.38207661e-01, 1.70365676e-01,
4433 2.66176152e-01, 3.22503669e+00, 3.04624249e-01, 3.63712766e+00,
4434 1.83504401e+00, 2.26289963e-01, 2.67560235e-01, 3.36422330e-01,
4435 3.03390753e-01, 3.36254561e-01, 5.53180238e-01, 1.67659508e+00,
4436 3.37037347e-01, 7.50000000e-01, 4.96615724e-01, 2.74820979e-01,
4437 7.50000000e-01, 1.20000000e-01, 7.50000000e-01, 3.47015056e+00}};
4438
4439
4440 /** Underlying frequency ratios for PAM30 */
4441 static const double PAM30_FREQRATIOS[POSITAA_SIZE][POSITAA_SIZE] =
4442 {{0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4443 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4444 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4445 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4446 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4447 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4448 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00},
4449 {0.00000000e+00, 7.78912912e+00, 3.02026381e-01, 1.07971742e-01,
4450 3.16807704e-01, 4.53014491e-01, 5.67768414e-02, 5.75744366e-01,
4451 8.33329143e-02, 1.98631007e-01, 9.54324770e-02, 1.15281887e-01,
4452 1.89338526e-01, 2.84890839e-01, 5.93402017e-01, 2.35344432e-01,
4453 9.10275603e-02, 8.75340369e-01, 8.27084092e-01, 4.77504036e-01,
4454 9.76867708e-03, 7.50000000e-01, 6.99222384e-02, 3.58158006e-01,
4455 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 1.40431646e-01},
4456 {0.00000000e+00, 3.02026381e-01, 8.11766307e+00, 1.52757717e-02,
4457 8.45582330e+00, 1.47233532e+00, 2.69459344e-02, 3.37867839e-01,
4458 6.63755159e-01, 1.25827363e-01, 4.40914175e-01, 4.89221062e-02,
4459 3.39137767e-02, 7.72564409e+00, 1.02509984e-01, 3.67813095e-01,
4460 8.23817770e-02, 6.03773710e-01, 3.53305100e-01, 6.71234492e-02,
4461 3.23783774e-02, 7.50000000e-01, 1.13742904e-01, 9.91005473e-01,
4462 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 7.21274943e-02},
4463 {0.00000000e+00, 1.07971742e-01, 1.52757717e-02, 2.75882699e+01,
4464 7.71413760e-03, 7.86819951e-03, 1.16056875e-02, 4.15734061e-02,
4465 7.76695875e-02, 1.19064797e-01, 7.78302876e-03, 6.02160155e-03,
4466 9.46008155e-03, 2.40417467e-02, 6.32617140e-02, 8.13944094e-03,
4467 6.80179741e-02, 3.79110970e-01, 6.77518036e-02, 1.32369559e-01,
4468 4.67559620e-03, 7.50000000e-01, 2.57579768e-01, 7.98640138e-03,
4469 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 4.01312493e-02},
4470 {0.00000000e+00, 3.16807704e-01, 8.45582330e+00, 7.71413760e-03,
4471 1.42349183e+01, 2.34246282e+00, 6.53544516e-03, 3.26331184e-01,
4472 2.71287596e-01, 7.98669838e-02, 2.19798242e-01, 1.38483017e-02,
4473 2.29035955e-02, 1.75629226e+00, 6.80928461e-02, 4.27289142e-01,
4474 2.95026156e-02, 2.86012439e-01, 1.99709663e-01, 6.47860871e-02,
4475 5.42804139e-03, 7.50000000e-01, 1.97046510e-02, 1.50786644e+00,
4476 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 3.37687752e-02},
4477 {0.00000000e+00, 4.53014491e-01, 1.47233532e+00, 7.86819951e-03,
4478 2.34246282e+00, 1.36624533e+01, 7.86638136e-03, 2.31589040e-01,
4479 1.81505594e-01, 1.49736909e-01, 2.26119978e-01, 4.27891596e-02,
4480 9.24578171e-02, 4.63622671e-01, 1.53529752e-01, 1.50713628e+00,
4481 4.28627549e-02, 2.25474962e-01, 1.30340902e-01, 1.09854687e-01,
4482 3.23568839e-03, 7.50000000e-01, 5.65446816e-02, 8.36539662e+00,
4483 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 7.50595678e-02},
4484 {0.00000000e+00, 5.67768414e-02, 2.69459344e-02, 1.16056875e-02,
4485 6.53544516e-03, 7.86638136e-03, 2.14068164e+01, 4.44753676e-02,
4486 1.31584637e-01, 4.73011553e-01, 8.55473177e-03, 4.15676862e-01,
4487 2.49857403e-01, 5.06072009e-02, 3.56716332e-02, 1.12390799e-02,
4488 4.18628794e-02, 1.13897780e-01, 5.14073961e-02, 6.66400959e-02,
4489 2.13219283e-01, 7.50000000e-01, 1.78617980e+00, 9.33613946e-03,
4490 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 4.32977029e-01},
4491 {0.00000000e+00, 5.75744366e-01, 3.37867839e-01, 4.15734061e-02,
4492 3.26331184e-01, 2.31589040e-01, 4.44753676e-02, 9.31368857e+00,
4493 4.78871557e-02, 2.41395424e-02, 8.59403011e-02, 2.78096704e-02,
4494 5.67940501e-02, 3.51241937e-01, 1.21951553e-01, 9.44408638e-02,
4495 3.97493058e-02, 5.52895766e-01, 1.35075690e-01, 1.48994667e-01,
4496 5.68401675e-03, 7.50000000e-01, 9.25861867e-03, 1.71822465e-01,
4497 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 2.67022462e-02},
4498 {0.00000000e+00, 8.33329143e-02, 6.63755159e-01, 7.76695875e-02,
4499 2.71287596e-01, 1.81505594e-01, 1.31584637e-01, 4.78871557e-02,
4500 2.29276353e+01, 4.36863126e-02, 1.19631443e-01, 1.23251186e-01,
4501 2.78547216e-02, 1.11873100e+00, 2.47982049e-01, 1.35964891e+00,
4502 5.86952720e-01, 1.31501535e-01, 8.61653901e-02, 1.14978024e-01,
4503 8.12035191e-02, 7.50000000e-01, 3.23746871e-01, 6.94918113e-01,
4504 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 9.92432853e-02},
4505 {0.00000000e+00, 1.98631007e-01, 1.25827363e-01, 1.19064797e-01,
4506 7.98669838e-02, 1.49736909e-01, 4.73011553e-01, 2.41395424e-02,
4507 4.36863126e-02, 1.86346064e+01, 1.27210180e-01, 6.43409762e-01,
4508 7.92524183e-01, 1.79107849e-01, 5.32543187e-02, 7.03383168e-02,
4509 1.58533228e-01, 9.68805230e-02, 4.44355269e-01, 1.93788392e+00,
4510 9.23811792e-03, 7.50000000e-01, 1.18573178e-01, 1.15136508e-01,
4511 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 6.07207247e+00},
4512 {0.00000000e+00, 9.54324770e-02, 4.40914175e-01, 7.78302876e-03,
4513 2.19798242e-01, 2.26119978e-01, 8.55473177e-03, 8.59403011e-02,
4514 1.19631443e-01, 1.27210180e-01, 9.98780825e+00, 6.07412260e-02,
4515 5.62560724e-01, 6.97247226e-01, 1.06485246e-01, 3.84266618e-01,
4516 1.11121735e+00, 2.59857530e-01, 3.36316040e-01, 4.62631009e-02,
4517 1.75142268e-02, 7.50000000e-01, 4.16645387e-02, 2.95037286e-01,
4518 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 8.07975645e-02},
4519 {0.00000000e+00, 1.15281887e-01, 4.89221062e-02, 6.02160155e-03,
4520 1.38483017e-02, 4.27891596e-02, 4.15676862e-01, 2.78096704e-02,
4521 1.23251186e-01, 6.43409762e-01, 6.07412260e-02, 1.00194105e+01,
4522 1.24218990e+00, 8.95821132e-02, 9.04970355e-02, 1.84988987e-01,
4523 5.31753716e-02, 5.83025512e-02, 1.02884887e-01, 4.62744892e-01,
4524 1.27405990e-01, 7.50000000e-01, 9.50388211e-02, 1.04757148e-01,
4525 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 7.19029657e+00},
4526 {0.00000000e+00, 1.89338526e-01, 3.39137767e-02, 9.46008155e-03,
4527 2.29035955e-02, 9.24578171e-02, 2.49857403e-01, 5.67940501e-02,
4528 2.78547216e-02, 7.92524183e-01, 5.62560724e-01, 1.24218990e+00,
4529 4.65953079e+01, 4.66775487e-02, 6.48026667e-02, 2.71732304e-01,
4530 2.43002286e-01, 1.60899996e-01, 2.62669188e-01, 6.30878126e-01,
4531 1.29243603e-02, 7.50000000e-01, 2.12719960e-02, 1.70582240e-01,
4532 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 1.10650779e+00},
4533 {0.00000000e+00, 2.84890839e-01, 7.72564409e+00, 2.40417467e-02,
4534 1.75629226e+00, 4.63622671e-01, 5.06072009e-02, 3.51241937e-01,
4535 1.11873100e+00, 1.79107849e-01, 6.97247226e-01, 8.95821132e-02,
4536 4.66775487e-02, 1.46457342e+01, 1.42408737e-01, 2.98864303e-01,
4537 1.43682999e-01, 9.72144796e-01, 5.31363673e-01, 6.98330827e-02,
4538 6.36210916e-02, 7.50000000e-01, 2.22758622e-01, 3.91824098e-01,
4539 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 1.16595604e-01},
4540 {0.00000000e+00, 5.93402017e-01, 1.02509984e-01, 6.32617140e-02,
4541 6.80928461e-02, 1.53529752e-01, 3.56716332e-02, 1.21951553e-01,
4542 2.47982049e-01, 5.32543187e-02, 1.06485246e-01, 9.04970355e-02,
4543 6.48026667e-02, 1.42408737e-01, 1.58088136e+01, 3.76066261e-01,
4544 2.69813309e-01, 5.70573606e-01, 2.40194503e-01, 1.40453450e-01,
4545 9.02230244e-03, 7.50000000e-01, 9.80486654e-03, 2.50506944e-01,
4546 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 7.92594202e-02},
4547 {0.00000000e+00, 2.35344432e-01, 3.67813095e-01, 8.13944094e-03,
4548 4.27289142e-01, 1.50713628e+00, 1.12390799e-02, 9.44408638e-02,
4549 1.35964891e+00, 7.03383168e-02, 3.84266618e-01, 1.84988987e-01,
4550 2.71732304e-01, 2.98864303e-01, 3.76066261e-01, 1.81380436e+01,
4551 5.84920778e-01, 1.67743101e-01, 1.50331260e-01, 1.02742037e-01,
4552 1.20726953e-02, 7.50000000e-01, 1.69239569e-02, 8.75457039e+00,
4553 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 1.50394300e-01},
4554 {0.00000000e+00, 9.10275603e-02, 8.23817770e-02, 6.80179741e-02,
4555 2.95026156e-02, 4.28627549e-02, 4.18628794e-02, 3.97493058e-02,
4556 5.86952720e-01, 1.58533228e-01, 1.11121735e+00, 5.31753716e-02,
4557 2.43002286e-01, 1.43682999e-01, 2.69813309e-01, 5.84920778e-01,
4558 1.89240175e+01, 3.54610075e-01, 1.06409795e-01, 7.42726505e-02,
4559 5.17051285e-01, 7.50000000e-01, 3.01584225e-02, 2.79081365e-01,
4560 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 8.49660454e-02},
4561 {0.00000000e+00, 8.75340369e-01, 6.03773710e-01, 3.79110970e-01,
4562 2.86012439e-01, 2.25474962e-01, 1.13897780e-01, 5.52895766e-01,
4563 1.31501535e-01, 9.68805230e-02, 2.59857530e-01, 5.83025512e-02,
4564 1.60899996e-01, 9.72144796e-01, 5.70573606e-01, 1.67743101e-01,
4565 3.54610075e-01, 9.02800848e+00, 1.14463515e+00, 1.17807053e-01,
4566 1.79210510e-01, 7.50000000e-01, 9.65415148e-02, 2.00316511e-01,
4567 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 6.99430663e-02},
4568 {0.00000000e+00, 8.27084092e-01, 3.53305100e-01, 6.77518036e-02,
4569 1.99709663e-01, 1.30340902e-01, 5.14073961e-02, 1.35075690e-01,
4570 8.61653901e-02, 4.44355269e-01, 3.36316040e-01, 1.02884887e-01,
4571 2.62669188e-01, 5.31363673e-01, 2.40194503e-01, 1.50331260e-01,
4572 1.06409795e-01, 1.14463515e+00, 1.16950751e+01, 3.90871695e-01,
4573 1.25703039e-02, 7.50000000e-01, 1.11995399e-01, 1.39052321e-01,
4574 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 2.05920141e-01},
4575 {0.00000000e+00, 4.77504036e-01, 6.71234492e-02, 1.32369559e-01,
4576 6.47860871e-02, 1.09854687e-01, 6.66400959e-02, 1.48994667e-01,
4577 1.14978024e-01, 1.93788392e+00, 4.62631009e-02, 4.62744892e-01,
4578 6.30878126e-01, 6.98330827e-02, 1.40453450e-01, 1.02742037e-01,
4579 7.42726505e-02, 1.17807053e-01, 3.90871695e-01, 1.16090589e+01,
4580 5.05672115e-03, 7.50000000e-01, 8.04763342e-02, 1.06755129e-01,
4581 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 9.07853260e-01},
4582 {0.00000000e+00, 9.76867708e-03, 3.23783774e-02, 4.67559620e-03,
4583 5.42804139e-03, 3.23568839e-03, 2.13219283e-01, 5.68401675e-03,
4584 8.12035191e-02, 9.23811792e-03, 1.75142268e-02, 1.27405990e-01,
4585 1.29243603e-02, 6.36210916e-02, 9.02230244e-03, 1.20726953e-02,
4586 5.17051285e-01, 1.79210510e-01, 1.25703039e-02, 5.05672115e-03,
4587 8.86903633e+01, 7.50000000e-01, 1.73378233e-01, 7.08668846e-03,
4588 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 9.17500230e-02},
4589 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4590 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4591 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4592 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4593 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4594 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4595 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 7.50000000e-01},
4596 {0.00000000e+00, 6.99222384e-02, 1.13742904e-01, 2.57579768e-01,
4597 1.97046510e-02, 5.65446816e-02, 1.78617980e+00, 9.25861867e-03,
4598 3.23746871e-01, 1.18573178e-01, 4.16645387e-02, 9.50388211e-02,
4599 2.12719960e-02, 2.22758622e-01, 9.80486654e-03, 1.69239569e-02,
4600 3.01584225e-02, 9.65415148e-02, 1.11995399e-01, 8.04763342e-02,
4601 1.73378233e-01, 7.50000000e-01, 2.84454162e+01, 3.92787209e-02,
4602 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 1.02140077e-01},
4603 {0.00000000e+00, 3.58158006e-01, 9.91005473e-01, 7.98640138e-03,
4604 1.50786644e+00, 8.36539662e+00, 9.33613946e-03, 1.71822465e-01,
4605 6.94918113e-01, 1.15136508e-01, 2.95037286e-01, 1.04757148e-01,
4606 1.70582240e-01, 3.91824098e-01, 2.50506944e-01, 8.75457039e+00,
4607 2.79081365e-01, 2.00316511e-01, 1.39052321e-01, 1.06755129e-01,
4608 7.08668846e-03, 7.50000000e-01, 3.92787209e-02, 8.53499117e+00,
4609 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 1.07889016e-01},
4610 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4611 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4612 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4613 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4614 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4615 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4616 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 7.50000000e-01},
4617 {0.00000000e+00, 3.00000000e-03, 3.00000000e-03, 3.00000000e-03,
4618 3.00000000e-03, 3.00000000e-03, 3.00000000e-03, 3.00000000e-03,
4619 3.00000000e-03, 3.00000000e-03, 3.00000000e-03, 3.00000000e-03,
4620 3.00000000e-03, 3.00000000e-03, 3.00000000e-03, 3.00000000e-03,
4621 3.00000000e-03, 3.00000000e-03, 3.00000000e-03, 3.00000000e-03,
4622 3.00000000e-03, 3.00000000e-03, 3.00000000e-03, 3.00000000e-03,
4623 3.00000000e-03, 1.33300000e+00, 3.00000000e-03, 3.00000000e-03},
4624 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4625 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4626 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4627 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4628 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4629 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4630 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 7.50000000e-01},
4631 {0.00000000e+00, 1.40431646e-01, 7.21274943e-02, 4.01312493e-02,
4632 3.37687752e-02, 7.50595678e-02, 4.32977029e-01, 2.67022462e-02,
4633 9.92432853e-02, 6.07207247e+00, 8.07975645e-02, 7.19029657e+00,
4634 1.10650779e+00, 1.16595604e-01, 7.92594202e-02, 1.50394300e-01,
4635 8.49660454e-02, 6.99430663e-02, 2.05920141e-01, 9.07853260e-01,
4636 9.17500230e-02, 7.50000000e-01, 1.02140077e-01, 1.07889016e-01,
4637 7.50000000e-01, 3.00000000e-03, 7.50000000e-01, 6.85288369e+00}};
4638
4639
4640 /** Underlying frequency ratios for PAM70 */
4641 static const double PAM70_FREQRATIOS[POSITAA_SIZE][POSITAA_SIZE] =
4642 {{0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4643 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4644 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4645 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4646 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4647 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4648 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00},
4649 {0.00000000e+00, 4.89972946e+00, 6.04638890e-01, 2.42067963e-01,
4650 6.18433760e-01, 7.71213936e-01, 1.34833512e-01, 1.01498720e+00,
4651 2.21390981e-01, 4.34566961e-01, 2.49319770e-01, 2.49736666e-01,
4652 3.75829845e-01, 5.88646912e-01, 1.03045017e+00, 4.65602795e-01,
4653 2.26934456e-01, 1.34964157e+00, 1.32707297e+00, 8.08640731e-01,
4654 4.32618091e-02, 7.50000000e-01, 1.54222102e-01, 6.38034395e-01,
4655 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 3.05507349e-01},
4656 {0.00000000e+00, 6.04638890e-01, 5.42142610e+00, 6.60540784e-02,
4657 5.88929014e+00, 2.24885858e+00, 7.88958522e-02, 6.48829213e-01,
4658 1.09845328e+00, 2.52789787e-01, 7.77906911e-01, 1.19715714e-01,
4659 1.39730820e-01, 4.87904539e+00, 2.73736473e-01, 7.90138593e-01,
4660 2.53425041e-01, 9.54703234e-01, 6.53688648e-01, 1.85063408e-01,
4661 7.80441148e-02, 7.50000000e-01, 2.23329473e-01, 1.61317606e+00,
4662 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.59869478e-01},
4663 {0.00000000e+00, 2.42067963e-01, 6.60540784e-02, 2.48333286e+01,
4664 3.97130183e-02, 3.87120726e-02, 5.48382532e-02, 1.15679023e-01,
4665 1.64834856e-01, 2.46442788e-01, 3.83065039e-02, 3.01944614e-02,
4666 4.42379868e-02, 9.65904773e-02, 1.58823055e-01, 3.93861754e-02,
4667 1.51302811e-01, 6.65193229e-01, 1.86417892e-01, 2.74442219e-01,
4668 2.22251459e-02, 7.50000000e-01, 5.23320532e-01, 3.90058338e-02,
4669 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 9.54452197e-02},
4670 {0.00000000e+00, 6.18433760e-01, 5.88929014e+00, 3.97130183e-02,
4671 8.89965209e+00, 3.35659301e+00, 3.36340414e-02, 6.39387415e-01,
4672 5.99746161e-01, 1.93031482e-01, 4.83846284e-01, 6.35580693e-02,
4673 1.03502951e-01, 2.39946804e+00, 2.12686642e-01, 9.22524100e-01,
4674 1.38560979e-01, 5.99713481e-01, 4.42110174e-01, 1.72922381e-01,
4675 2.64171458e-02, 7.50000000e-01, 7.98817496e-02, 2.29587193e+00,
4676 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.02625370e-01},
4677 {0.00000000e+00, 7.71213936e-01, 2.24885858e+00, 3.87120726e-02,
4678 3.35659301e+00, 8.65385421e+00, 3.82398528e-02, 4.91841782e-01,
4679 4.80150693e-01, 2.83623924e-01, 4.66181910e-01, 1.17487568e-01,
4680 2.12426533e-01, 9.64695360e-01, 3.47480663e-01, 2.25815498e+00,
4681 1.78914910e-01, 4.78627630e-01, 3.38114944e-01, 2.46972907e-01,
4682 1.89756038e-02, 7.50000000e-01, 1.19141830e-01, 5.86672974e+00,
4683 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.67617543e-01},
4684 {0.00000000e+00, 1.34833512e-01, 7.88958522e-02, 5.48382532e-02,
4685 3.36340414e-02, 3.82398528e-02, 1.74546228e+01, 1.00136016e-01,
4686 2.76577280e-01, 8.45971180e-01, 4.12894272e-02, 8.23804865e-01,
4687 5.08442478e-01, 1.31366508e-01, 8.91727264e-02, 5.25046736e-02,
4688 9.93639027e-02, 2.15603624e-01, 1.37600314e-01, 2.07856659e-01,
4689 4.52242030e-01, 7.50000000e-01, 3.37849562e+00, 4.44561913e-02,
4690 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 8.30493328e-01},
4691 {0.00000000e+00, 1.01498720e+00, 6.48829213e-01, 1.15679023e-01,
4692 6.39387415e-01, 4.91841782e-01, 1.00136016e-01, 7.30864335e+00,
4693 1.45138751e-01, 1.07004308e-01, 2.09861286e-01, 8.09786598e-02,
4694 1.44276056e-01, 6.59774806e-01, 3.08399509e-01, 2.37177521e-01,
4695 1.22086776e-01, 9.64187863e-01, 3.70424893e-01, 3.12986176e-01,
4696 2.68996967e-02, 7.50000000e-01, 4.37757319e-02, 3.80863925e-01,
4697 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 8.88316375e-02},
4698 {0.00000000e+00, 2.21390981e-01, 1.09845328e+00, 1.64834856e-01,
4699 5.99746161e-01, 4.80150693e-01, 2.76577280e-01, 1.45138751e-01,
4700 1.64223829e+01, 1.39752446e-01, 3.35085062e-01, 2.59072609e-01,
4701 1.22395235e-01, 1.67658945e+00, 4.92867985e-01, 2.18832010e+00,
4702 1.05779530e+00, 3.26721114e-01, 2.30266854e-01, 2.33270842e-01,
4703 1.86063506e-01, 7.50000000e-01, 6.11386658e-01, 1.22453853e+00,
4704 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 2.23068949e-01},
4705 {0.00000000e+00, 4.34566961e-01, 2.52789787e-01, 2.46442788e-01,
4706 1.93031482e-01, 2.83623924e-01, 8.45971180e-01, 1.07004308e-01,
4707 1.39752446e-01, 1.17505537e+01, 2.66278255e-01, 1.19239531e+00,
4708 1.36908981e+00, 3.22065793e-01, 1.59577365e-01, 1.89299534e-01,
4709 3.01479599e-01, 2.53646367e-01, 7.61111058e-01, 3.00374358e+00,
4710 4.36969076e-02, 7.50000000e-01, 2.80489781e-01, 2.42519143e-01,
4711 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 4.37821344e+00},
4712 {0.00000000e+00, 2.49319770e-01, 7.77906911e-01, 3.83065039e-02,
4713 4.83846284e-01, 4.66181910e-01, 4.12894272e-02, 2.09861286e-01,
4714 3.35085062e-01, 2.66278255e-01, 7.61026217e+00, 1.52754534e-01,
4715 9.47937549e-01, 1.11880255e+00, 2.56118662e-01, 7.21669881e-01,
4716 1.93666556e+00, 5.20459614e-01, 6.20196625e-01, 1.38845936e-01,
4717 7.91911207e-02, 7.50000000e-01, 1.00771644e-01, 5.77518724e-01,
4718 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.87009175e-01},
4719 {0.00000000e+00, 2.49736666e-01, 1.19715714e-01, 3.01944614e-02,
4720 6.35580693e-02, 1.17487568e-01, 8.23804865e-01, 8.09786598e-02,
4721 2.59072609e-01, 1.19239531e+00, 1.52754534e-01, 8.22843955e+00,
4722 2.12939550e+00, 1.84817584e-01, 1.98778178e-01, 3.50784854e-01,
4723 1.37359422e-01, 1.48574310e-01, 2.40326213e-01, 9.08401895e-01,
4724 2.67168548e-01, 7.50000000e-01, 2.38980900e-01, 2.19154102e-01,
4725 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 6.10538395e+00},
4726 {0.00000000e+00, 3.75829845e-01, 1.39730820e-01, 4.42379868e-02,
4727 1.03502951e-01, 2.12426533e-01, 5.08442478e-01, 1.44276056e-01,
4728 1.22395235e-01, 1.36908981e+00, 9.47937549e-01, 2.12939550e+00,
4729 2.85861616e+01, 1.81728699e-01, 1.75926195e-01, 4.86044449e-01,
4730 4.88080973e-01, 3.18976045e-01, 4.97701201e-01, 1.13284160e+00,
4731 5.97810639e-02, 7.50000000e-01, 9.73038916e-02, 3.31664034e-01,
4732 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.89998090e+00},
4733 {0.00000000e+00, 5.88646912e-01, 4.87904539e+00, 9.65904773e-02,
4734 2.39946804e+00, 9.64695360e-01, 1.31366508e-01, 6.59774806e-01,
4735 1.67658945e+00, 3.22065793e-01, 1.11880255e+00, 1.84817584e-01,
4736 1.81728699e-01, 7.75354485e+00, 3.44509706e-01, 6.36668056e-01,
4737 3.86583495e-01, 1.36623218e+00, 8.98965212e-01, 1.99138136e-01,
4738 1.37893708e-01, 7.50000000e-01, 3.89624106e-01, 8.21747280e-01,
4739 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 2.26230851e-01},
4740 {0.00000000e+00, 1.03045017e+00, 2.73736473e-01, 1.58823055e-01,
4741 2.12686642e-01, 3.47480663e-01, 8.91727264e-02, 3.08399509e-01,
4742 4.92867985e-01, 1.59577365e-01, 2.56118662e-01, 1.98778178e-01,
4743 1.75926195e-01, 3.44509706e-01, 1.18714088e+01, 6.84263791e-01,
4744 5.26778639e-01, 9.79291808e-01, 5.30644206e-01, 3.07279290e-01,
4745 4.18182164e-02, 7.50000000e-01, 4.66910129e-02, 4.94244365e-01,
4746 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.86949727e-01},
4747 {0.00000000e+00, 4.65602795e-01, 7.90138593e-01, 3.93861754e-02,
4748 9.22524100e-01, 2.25815498e+00, 5.25046736e-02, 2.37177521e-01,
4749 2.18832010e+00, 1.89299534e-01, 7.21669881e-01, 3.50784854e-01,
4750 4.86044449e-01, 6.36668056e-01, 6.84263791e-01, 1.14706864e+01,
4751 1.02361055e+00, 3.73519396e-01, 3.29322200e-01, 2.32053434e-01,
4752 5.49721446e-02, 7.50000000e-01, 7.38645866e-02, 6.27280154e+00,
4753 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 3.02058283e-01},
4754 {0.00000000e+00, 2.26934456e-01, 2.53425041e-01, 1.51302811e-01,
4755 1.38560979e-01, 1.78914910e-01, 9.93639027e-02, 1.22086776e-01,
4756 1.05779530e+00, 3.01479599e-01, 1.93666556e+00, 1.37359422e-01,
4757 4.88080973e-01, 3.86583495e-01, 5.26778639e-01, 1.02361055e+00,
4758 1.36584013e+01, 6.10010848e-01, 2.83658630e-01, 1.75829089e-01,
4759 9.90780192e-01, 7.50000000e-01, 8.59463892e-02, 5.47017256e-01,
4760 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.86881035e-01},
4761 {0.00000000e+00, 1.34964157e+00, 9.54703234e-01, 6.65193229e-01,
4762 5.99713481e-01, 4.78627630e-01, 2.15603624e-01, 9.64187863e-01,
4763 3.26721114e-01, 2.53646367e-01, 5.20459614e-01, 1.48574310e-01,
4764 3.18976045e-01, 1.36623218e+00, 9.79291808e-01, 3.73519396e-01,
4765 6.10010848e-01, 5.20445832e+00, 1.69490837e+00, 3.03324606e-01,
4766 3.23868004e-01, 7.50000000e-01, 2.08076540e-01, 4.32823454e-01,
4767 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.80278747e-01},
4768 {0.00000000e+00, 1.32707297e+00, 6.53688648e-01, 1.86417892e-01,
4769 4.42110174e-01, 3.38114944e-01, 1.37600314e-01, 3.70424893e-01,
4770 2.30266854e-01, 7.61111058e-01, 6.20196625e-01, 2.40326213e-01,
4771 4.97701201e-01, 8.98965212e-01, 5.30644206e-01, 3.29322200e-01,
4772 2.83658630e-01, 1.69490837e+00, 7.33707214e+00, 7.18561720e-01,
4773 5.45397612e-02, 7.50000000e-01, 2.27833757e-01, 3.34283233e-01,
4774 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 3.97467804e-01},
4775 {0.00000000e+00, 8.08640731e-01, 1.85063408e-01, 2.74442219e-01,
4776 1.72922381e-01, 2.46972907e-01, 2.07856659e-01, 3.12986176e-01,
4777 2.33270842e-01, 3.00374358e+00, 1.38845936e-01, 9.08401895e-01,
4778 1.13284160e+00, 1.99138136e-01, 3.07279290e-01, 2.32053434e-01,
4779 1.75829089e-01, 3.03324606e-01, 7.18561720e-01, 8.21110545e+00,
4780 2.66588959e-02, 7.50000000e-01, 1.80843519e-01, 2.40471284e-01,
4781 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.54065018e+00},
4782 {0.00000000e+00, 4.32618091e-02, 7.80441148e-02, 2.22251459e-02,
4783 2.64171458e-02, 1.89756038e-02, 4.52242030e-01, 2.68996967e-02,
4784 1.86063506e-01, 4.36969076e-02, 7.91911207e-02, 2.67168548e-01,
4785 5.97810639e-02, 1.37893708e-01, 4.18182164e-02, 5.49721446e-02,
4786 9.90780192e-01, 3.23868004e-01, 5.45397612e-02, 2.66588959e-02,
4787 8.06167129e+01, 7.50000000e-01, 3.76692625e-01, 3.46622138e-02,
4788 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 1.99738227e-01},
4789 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4790 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4791 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4792 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4793 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4794 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4795 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 7.50000000e-01},
4796 {0.00000000e+00, 1.54222102e-01, 2.23329473e-01, 5.23320532e-01,
4797 7.98817496e-02, 1.19141830e-01, 3.37849562e+00, 4.37757319e-02,
4798 6.11386658e-01, 2.80489781e-01, 1.00771644e-01, 2.38980900e-01,
4799 9.73038916e-02, 3.89624106e-01, 4.66910129e-02, 7.38645866e-02,
4800 8.59463892e-02, 2.08076540e-01, 2.27833757e-01, 1.80843519e-01,
4801 3.76692625e-01, 7.50000000e-01, 2.31438270e+01, 9.94108657e-02,
4802 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 2.51505787e-01},
4803 {0.00000000e+00, 6.38034395e-01, 1.61317606e+00, 3.90058338e-02,
4804 2.29587193e+00, 5.86672974e+00, 4.44561913e-02, 3.80863925e-01,
4805 1.22453853e+00, 2.42519143e-01, 5.77518724e-01, 2.19154102e-01,
4806 3.31664034e-01, 8.21747280e-01, 4.94244365e-01, 6.27280154e+00,
4807 5.47017256e-01, 4.32823454e-01, 3.34283233e-01, 2.40471284e-01,
4808 3.46622138e-02, 7.50000000e-01, 9.94108657e-02, 6.04368813e+00,
4809 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 2.26204268e-01},
4810 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4811 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4812 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4813 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4814 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4815 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4816 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 7.50000000e-01},
4817 {0.00000000e+00, 2.00000000e-02, 2.00000000e-02, 2.00000000e-02,
4818 2.00000000e-02, 2.00000000e-02, 2.00000000e-02, 2.00000000e-02,
4819 2.00000000e-02, 2.00000000e-02, 2.00000000e-02, 2.00000000e-02,
4820 2.00000000e-02, 2.00000000e-02, 2.00000000e-02, 2.00000000e-02,
4821 2.00000000e-02, 2.00000000e-02, 2.00000000e-02, 2.00000000e-02,
4822 2.00000000e-02, 2.00000000e-02, 2.00000000e-02, 2.00000000e-02,
4823 2.00000000e-02, 1.33300000e+00, 2.00000000e-02, 2.00000000e-02},
4824 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4825 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4826 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4827 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4828 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4829 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4830 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 7.50000000e-01},
4831 {0.00000000e+00, 3.05507349e-01, 1.59869478e-01, 9.54452197e-02,
4832 1.02625370e-01, 1.67617543e-01, 8.30493328e-01, 8.88316375e-02,
4833 2.23068949e-01, 4.37821344e+00, 1.87009175e-01, 6.10538395e+00,
4834 1.89998090e+00, 2.26230851e-01, 1.86949727e-01, 3.02058283e-01,
4835 1.86881035e-01, 1.80278747e-01, 3.97467804e-01, 1.54065018e+00,
4836 1.99738227e-01, 7.50000000e-01, 2.51505787e-01, 2.26204268e-01,
4837 7.50000000e-01, 2.00000000e-02, 7.50000000e-01, 5.58422761e+00}};
4838
4839
4840 /** Underlying frequency ratios for PAM250 */
4841 static const double PAM250_FREQRATIOS[POSITAA_SIZE][POSITAA_SIZE] =
4842 {{0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4843 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4844 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4845 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4846 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4847 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4848 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00},
4849 {0.00000000e+00, 1.51578006e+00, 1.05606466e+00, 6.26687137e-01,
4850 1.07002228e+00, 1.07474947e+00, 4.46290560e-01, 1.33923306e+00,
4851 7.32178470e-01, 8.88728816e-01, 7.66227814e-01, 6.46341735e-01,
4852 7.70359541e-01, 1.03988401e+00, 1.29408826e+00, 9.03456780e-01,
4853 7.00798809e-01, 1.28966428e+00, 1.31725380e+00, 1.04499203e+00,
4854 2.63609841e-01, 7.50000000e-01, 4.49686798e-01, 1.00010336e+00,
4855 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 7.19479599e-01},
4856 {0.00000000e+00, 1.05606466e+00, 1.84257846e+00, 3.65113184e-01,
4857 2.05195422e+00, 1.82470118e+00, 3.54071966e-01, 1.11918465e+00,
4858 1.29683470e+00, 6.16970770e-01, 1.13010166e+00, 4.52559218e-01,
4859 6.04775077e-01, 1.59985542e+00, 8.46142888e-01, 1.33890747e+00,
4860 8.61808201e-01, 1.11706882e+00, 1.03197349e+00, 6.37811920e-01,
4861 2.96793416e-01, 7.50000000e-01, 4.85608019e-01, 1.61300149e+00,
4862 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 5.02168751e-01},
4863 {0.00000000e+00, 6.26687137e-01, 3.65113184e-01, 1.56285624e+01,
4864 3.06772262e-01, 2.94964746e-01, 3.70976416e-01, 4.59297624e-01,
4865 4.51836855e-01, 5.87603719e-01, 2.86099293e-01, 2.47791243e-01,
4866 2.99408166e-01, 4.32746060e-01, 5.27421501e-01, 2.89534285e-01,
4867 4.30504374e-01, 9.89678273e-01, 6.01385571e-01, 6.38902701e-01,
4868 1.68818010e-01, 7.50000000e-01, 1.07830459e+00, 2.92598254e-01,
4869 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 3.50326241e-01},
4870 {0.00000000e+00, 1.07002228e+00, 2.05195422e+00, 3.06772262e-01,
4871 2.43292288e+00, 2.19715052e+00, 2.73911818e-01, 1.14726861e+00,
4872 1.17343465e+00, 5.79909835e-01, 1.01987501e+00, 3.98183329e-01,
4873 5.48083233e-01, 1.61030872e+00, 8.05577240e-01, 1.46152937e+00,
4874 7.42874842e-01, 1.06886174e+00, 9.67471640e-01, 6.11601820e-01,
4875 2.12712296e-01, 7.50000000e-01, 3.69025897e-01, 1.87658077e+00,
4876 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 4.53017475e-01},
4877 {0.00000000e+00, 1.07474947e+00, 1.82470118e+00, 2.94964746e-01,
4878 2.19715052e+00, 2.41404373e+00, 2.87098831e-01, 1.04389169e+00,
4879 1.16525001e+00, 6.26339428e-01, 9.87756703e-01, 4.63568053e-01,
4880 6.13603630e-01, 1.39293185e+00, 8.79669521e-01, 1.77158803e+00,
4881 7.82149443e-01, 9.98597151e-01, 9.13853001e-01, 6.60440693e-01,
4882 2.00637717e-01, 7.50000000e-01, 3.71943861e-01, 2.13407372e+00,
4883 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 5.12682678e-01},
4884 {0.00000000e+00, 4.46290560e-01, 3.54071966e-01, 3.70976416e-01,
4885 2.73911818e-01, 2.87098831e-01, 8.02764197e+00, 3.32339414e-01,
4886 6.59545216e-01, 1.26203255e+00, 2.98137999e-01, 1.51752623e+00,
4887 1.04274830e+00, 4.46999215e-01, 3.50828021e-01, 3.43119584e-01,
4888 3.58749728e-01, 4.78353203e-01, 4.88459165e-01, 7.66309017e-01,
4889 1.07668873e+00, 7.50000000e-01, 4.97590308e+00, 3.11511613e-01,
4890 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 1.44043358e+00},
4891 {0.00000000e+00, 1.33923306e+00, 1.11918465e+00, 4.59297624e-01,
4892 1.14726861e+00, 1.04389169e+00, 3.32339414e-01, 2.99056680e+00,
4893 6.15552047e-01, 5.57103314e-01, 6.78509416e-01, 3.94686522e-01,
4894 5.25369171e-01, 1.08662777e+00, 8.94077901e-01, 7.57447784e-01,
4895 5.54986868e-01, 1.27845679e+00, 9.98770702e-01, 7.34634729e-01,
4896 2.00363838e-01, 7.50000000e-01, 2.99613619e-01, 9.19064864e-01,
4897 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 4.43694156e-01},
4898 {0.00000000e+00, 7.32178470e-01, 1.29683470e+00, 4.51836855e-01,
4899 1.17343465e+00, 1.16525001e+00, 6.59545216e-01, 6.15552047e-01,
4900 4.47513035e+00, 5.70614299e-01, 9.90160946e-01, 6.20055020e-01,
4901 6.09441413e-01, 1.43988866e+00, 9.46471632e-01, 1.96194975e+00,
4902 1.43036819e+00, 8.30226277e-01, 7.40733381e-01, 5.96692220e-01,
4903 5.44285116e-01, 7.50000000e-01, 9.78877039e-01, 1.51243666e+00,
4904 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 6.05136779e-01},
4905 {0.00000000e+00, 8.88728816e-01, 6.16970770e-01, 5.87603719e-01,
4906 5.79909835e-01, 6.26339428e-01, 1.26203255e+00, 5.57103314e-01,
4907 5.70614299e-01, 2.83022396e+00, 6.40800116e-01, 1.74919442e+00,
4908 1.64986005e+00, 6.59934398e-01, 6.27243837e-01, 6.25316723e-01,
4909 6.29014923e-01, 7.22513707e-01, 1.01665478e+00, 2.33821719e+00,
4910 3.02670201e-01, 7.50000000e-01, 7.99863687e-01, 6.25893752e-01,
4911 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 2.07538421e+00},
4912 {0.00000000e+00, 7.66227814e-01, 1.13010166e+00, 2.86099293e-01,
4913 1.01987501e+00, 9.87756703e-01, 2.98137999e-01, 6.78509416e-01,
4914 9.90160946e-01, 6.40800116e-01, 2.92620120e+00, 5.18814877e-01,
4915 1.09961986e+00, 1.25788411e+00, 7.70516817e-01, 1.18387275e+00,
4916 2.18168472e+00, 9.61645918e-01, 9.95647751e-01, 5.70096500e-01,
4917 4.50323287e-01, 7.50000000e-01, 3.59829368e-01, 1.07322036e+00,
4918 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 5.55622697e-01},
4919 {0.00000000e+00, 6.46341735e-01, 4.52559218e-01, 2.47791243e-01,
4920 3.98183329e-01, 4.63568053e-01, 1.51752623e+00, 3.94686522e-01,
4921 6.20055020e-01, 1.74919442e+00, 5.18814877e-01, 3.92994485e+00,
4922 2.33771776e+00, 5.15595552e-01, 5.56038228e-01, 6.65507525e-01,
4923 5.01008003e-01, 5.24107036e-01, 6.77040993e-01, 1.53178711e+00,
4924 6.46886104e-01, 7.50000000e-01, 8.14904569e-01, 5.51569446e-01,
4925 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 3.27192533e+00},
4926 {0.00000000e+00, 7.70359541e-01, 6.04775077e-01, 2.99408166e-01,
4927 5.48083233e-01, 6.13603630e-01, 1.04274830e+00, 5.25369171e-01,
4928 6.09441413e-01, 1.64986005e+00, 1.09961986e+00, 2.33771776e+00,
4929 4.40351686e+00, 6.70496227e-01, 6.21012433e-01, 7.95710012e-01,
4930 9.04471250e-01, 6.98581457e-01, 8.73067477e-01, 1.51039751e+00,
4931 3.74941590e-01, 7.50000000e-01, 5.67675865e-01, 6.92962139e-01,
4932 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 2.13016362e+00},
4933 {0.00000000e+00, 1.03988401e+00, 1.59985542e+00, 4.32746060e-01,
4934 1.61030872e+00, 1.39293185e+00, 4.46999215e-01, 1.08662777e+00,
4935 1.43988866e+00, 6.59934398e-01, 1.25788411e+00, 5.15595552e-01,
4936 6.70496227e-01, 1.58773724e+00, 8.93169424e-01, 1.19675558e+00,
4937 9.99684066e-01, 1.17295383e+00, 1.10674855e+00, 6.68196499e-01,
4938 3.94266130e-01, 7.50000000e-01, 6.20758168e-01, 1.30744195e+00,
4939 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 5.59148347e-01},
4940 {0.00000000e+00, 1.29408826e+00, 8.46142888e-01, 5.27421501e-01,
4941 8.05577240e-01, 8.79669521e-01, 3.50828021e-01, 8.94077901e-01,
4942 9.46471632e-01, 6.27243837e-01, 7.70516817e-01, 5.56038228e-01,
4943 6.21012433e-01, 8.93169424e-01, 3.84141803e+00, 1.05550534e+00,
4944 9.60208581e-01, 1.24349521e+00, 1.07552180e+00, 7.58279920e-01,
4945 2.75343404e-01, 7.50000000e-01, 3.20901839e-01, 9.56295438e-01,
4946 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 5.77523805e-01},
4947 {0.00000000e+00, 9.03456780e-01, 1.33890747e+00, 2.89534285e-01,
4948 1.46152937e+00, 1.77158803e+00, 3.43119584e-01, 7.57447784e-01,
4949 1.96194975e+00, 6.25316723e-01, 1.18387275e+00, 6.65507525e-01,
4950 7.95710012e-01, 1.19675558e+00, 1.05550534e+00, 2.54088209e+00,
4951 1.33504131e+00, 8.89983529e-01, 8.32948914e-01, 6.49448913e-01,
4952 3.35176014e-01, 7.50000000e-01, 3.94549334e-01, 2.10683180e+00,
4953 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 6.53380354e-01},
4954 {0.00000000e+00, 7.00798809e-01, 8.61808201e-01, 4.30504374e-01,
4955 7.42874842e-01, 7.82149443e-01, 3.58749728e-01, 5.54986868e-01,
4956 1.43036819e+00, 6.29014923e-01, 2.18168472e+00, 5.01008003e-01,
4957 9.04471250e-01, 9.99684066e-01, 9.60208581e-01, 1.33504131e+00,
4958 4.07760419e+00, 9.28286966e-01, 8.20208528e-01, 5.61449723e-01,
4959 1.65111328e+00, 7.50000000e-01, 3.78768704e-01, 1.02308924e+00,
4960 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 5.39632804e-01},
4961 {0.00000000e+00, 1.28966428e+00, 1.11706882e+00, 9.89678273e-01,
4962 1.06886174e+00, 9.98597151e-01, 4.78353203e-01, 1.27845679e+00,
4963 8.30226277e-01, 7.22513707e-01, 9.61645918e-01, 5.24107036e-01,
4964 6.98581457e-01, 1.17295383e+00, 1.24349521e+00, 8.89983529e-01,
4965 9.28286966e-01, 1.44062735e+00, 1.36207698e+00, 7.99071364e-01,
4966 5.65535441e-01, 7.50000000e-01, 5.19882078e-01, 9.51265394e-01,
4967 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 5.83974254e-01},
4968 {0.00000000e+00, 1.31725380e+00, 1.03197349e+00, 6.01385571e-01,
4969 9.67471640e-01, 9.13853001e-01, 4.88459165e-01, 9.98770702e-01,
4970 7.40733381e-01, 1.01665478e+00, 9.95647751e-01, 6.77040993e-01,
4971 8.73067477e-01, 1.10674855e+00, 1.07552180e+00, 8.32948914e-01,
4972 8.20208528e-01, 1.36207698e+00, 1.80640078e+00, 1.06764169e+00,
4973 3.05841935e-01, 7.50000000e-01, 5.30232118e-01, 8.78596534e-01,
4974 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 7.79516037e-01},
4975 {0.00000000e+00, 1.04499203e+00, 6.37811920e-01, 6.38902701e-01,
4976 6.11601820e-01, 6.60440693e-01, 7.66309017e-01, 7.34634729e-01,
4977 5.96692220e-01, 2.33821719e+00, 5.70096500e-01, 1.53178711e+00,
4978 1.51039751e+00, 6.68196499e-01, 7.58279920e-01, 6.49448913e-01,
4979 5.61449723e-01, 7.99071364e-01, 1.06764169e+00, 2.69825619e+00,
4980 2.36794202e-01, 7.50000000e-01, 5.65836205e-01, 6.55650683e-01,
4981 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 1.77511928e+00},
4982 {0.00000000e+00, 2.63609841e-01, 2.96793416e-01, 1.68818010e-01,
4983 2.12712296e-01, 2.00637717e-01, 1.07668873e+00, 2.00363838e-01,
4984 5.44285116e-01, 3.02670201e-01, 4.50323287e-01, 6.46886104e-01,
4985 3.74941590e-01, 3.94266130e-01, 2.75343404e-01, 3.35176014e-01,
4986 1.65111328e+00, 5.65535441e-01, 3.05841935e-01, 2.36794202e-01,
4987 5.26606678e+01, 7.50000000e-01, 9.69642510e-01, 2.59266956e-01,
4988 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 5.43022417e-01},
4989 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4990 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4991 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4992 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4993 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4994 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
4995 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 7.50000000e-01},
4996 {0.00000000e+00, 4.49686798e-01, 4.85608019e-01, 1.07830459e+00,
4997 3.69025897e-01, 3.71943861e-01, 4.97590308e+00, 2.99613619e-01,
4998 9.78877039e-01, 7.99863687e-01, 3.59829368e-01, 8.14904569e-01,
4999 5.67675865e-01, 6.20758168e-01, 3.20901839e-01, 3.94549334e-01,
5000 3.78768704e-01, 5.19882078e-01, 5.30232118e-01, 5.65836205e-01,
5001 9.69642510e-01, 7.50000000e-01, 1.03387565e+01, 3.81794898e-01,
5002 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 8.10366134e-01},
5003 {0.00000000e+00, 1.00010336e+00, 1.61300149e+00, 2.92598254e-01,
5004 1.87658077e+00, 2.13407372e+00, 3.11511613e-01, 9.19064864e-01,
5005 1.51243666e+00, 6.25893752e-01, 1.07322036e+00, 5.51569446e-01,
5006 6.92962139e-01, 1.30744195e+00, 9.56295438e-01, 2.10683180e+00,
5007 1.02308924e+00, 9.51265394e-01, 8.78596534e-01, 6.55650683e-01,
5008 2.59266956e-01, 7.50000000e-01, 3.81794898e-01, 2.12220220e+00,
5009 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 5.73996058e-01},
5010 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5011 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5012 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5013 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5014 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5015 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5016 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 7.50000000e-01},
5017 {0.00000000e+00, 1.70000000e-01, 1.70000000e-01, 1.70000000e-01,
5018 1.70000000e-01, 1.70000000e-01, 1.70000000e-01, 1.70000000e-01,
5019 1.70000000e-01, 1.70000000e-01, 1.70000000e-01, 1.70000000e-01,
5020 1.70000000e-01, 1.70000000e-01, 1.70000000e-01, 1.70000000e-01,
5021 1.70000000e-01, 1.70000000e-01, 1.70000000e-01, 1.70000000e-01,
5022 1.70000000e-01, 1.70000000e-01, 1.70000000e-01, 1.70000000e-01,
5023 1.70000000e-01, 1.33300000e+00, 1.70000000e-01, 1.70000000e-01},
5024 {0.00000000e+00, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5025 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5026 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5027 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5028 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5029 7.50000000e-01, 7.50000000e-01, 7.50000000e-01, 7.50000000e-01,
5030 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 7.50000000e-01},
5031 {0.00000000e+00, 7.19479599e-01, 5.02168751e-01, 3.50326241e-01,
5032 4.53017475e-01, 5.12682678e-01, 1.44043358e+00, 4.43694156e-01,
5033 6.05136779e-01, 2.07538421e+00, 5.55622697e-01, 3.27192533e+00,
5034 2.13016362e+00, 5.59148347e-01, 5.77523805e-01, 6.53380354e-01,
5035 5.39632804e-01, 5.83974254e-01, 7.79516037e-01, 1.77511928e+00,
5036 5.43022417e-01, 7.50000000e-01, 8.10366134e-01, 5.73996058e-01,
5037 7.50000000e-01, 1.70000000e-01, 7.50000000e-01, 2.91088108e+00}};
5038
5039
5040 FreqRatios*
PSIMatrixFrequencyRatiosNew(const char * matrix_name)5041 PSIMatrixFrequencyRatiosNew(const char* matrix_name)
5042 {
5043 unsigned int i, j; /* loop indices */
5044 FreqRatios* retval = NULL; /* the return value */
5045
5046 ASSERT(matrix_name);
5047
5048 retval = (FreqRatios*) Malloc(sizeof(FreqRatios));
5049 if ( !retval ) {
5050 return NULL;
5051 }
5052
5053 retval->data = (double**) Malloc(sizeof(double*)*PROTEIN_ALPHABET);
5054 if ( !retval->data ) {
5055 return PSIMatrixFrequencyRatiosFree(retval);
5056 }
5057
5058 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5059 retval->data[i] = (double*) Malloc(sizeof(double)*PROTEIN_ALPHABET);
5060 if ( !retval->data[i] ) {
5061 for (j = 0; j < i; j++) {
5062 retval->data[j] = MemFree(retval->data[j]);
5063 }
5064 return PSIMatrixFrequencyRatiosFree(retval);
5065 }
5066 }
5067
5068 if ( !strcmp(matrix_name, "BLOSUM62") ||
5069 !strcmp(matrix_name, "BLOSUM62_20")) {
5070 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5071 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5072 retval->data[i][j] = BLOSUM62_FREQRATIOS[i][j];
5073 }
5074 }
5075 retval->bit_scale_factor = 2;
5076 } else if ( !strcmp(matrix_name, "BLOSUM62_20A")) {
5077 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5078 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5079 retval->data[i][j] =
5080 BLOSUM62_20A_SCALE_MULTIPLIER * BLOSUM62_FREQRATIOS[i][j];
5081 }
5082 }
5083 retval->bit_scale_factor = 2;
5084 } else if ( !strcmp(matrix_name, "BLOSUM62_20B")) {
5085 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5086 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5087 retval->data[i][j] =
5088 BLOSUM62_20B_SCALE_MULTIPLIER * BLOSUM62_FREQRATIOS[i][j];
5089 }
5090 }
5091 retval->bit_scale_factor = 2;
5092 } else if ( !strcmp(matrix_name, "BLOSUM45") ) {
5093 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5094 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5095 retval->data[i][j] = BLOSUM45_FREQRATIOS[i][j];
5096 }
5097 }
5098 retval->bit_scale_factor = 3;
5099 } else if ( !strcmp(matrix_name, "BLOSUM80") ) {
5100 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5101 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5102 retval->data[i][j] = BLOSUM80_FREQRATIOS[i][j];
5103 }
5104 }
5105 retval->bit_scale_factor = 2;
5106 } else if ( !strcmp(matrix_name, "BLOSUM50") ) {
5107 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5108 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5109 retval->data[i][j] = BLOSUM50_FREQRATIOS[i][j];
5110 }
5111 }
5112 retval->bit_scale_factor = 2;
5113 } else if ( !strcmp(matrix_name, "BLOSUM90") ) {
5114 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5115 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5116 retval->data[i][j] = BLOSUM90_FREQRATIOS[i][j];
5117 }
5118 }
5119 retval->bit_scale_factor = 2;
5120 } else if ( !strcmp(matrix_name, "PAM30") ) {
5121 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5122 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5123 retval->data[i][j] = PAM30_FREQRATIOS[i][j];
5124 }
5125 }
5126 retval->bit_scale_factor = 2;
5127 } else if ( !strcmp(matrix_name, "PAM70") ) {
5128 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5129 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5130 retval->data[i][j] = PAM70_FREQRATIOS[i][j];
5131 }
5132 }
5133 retval->bit_scale_factor = 2;
5134 } else if ( !strcmp(matrix_name, "PAM250") ) {
5135 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5136 for (j = 0; j < PROTEIN_ALPHABET; j++) {
5137 retval->data[i][j] = PAM250_FREQRATIOS[i][j];
5138 }
5139 }
5140 retval->bit_scale_factor = 2;
5141 } else {
5142 retval = PSIMatrixFrequencyRatiosFree(retval);
5143 }
5144
5145 return retval;
5146 }
5147
5148 FreqRatios*
PSIMatrixFrequencyRatiosFree(FreqRatios * freq_ratios)5149 PSIMatrixFrequencyRatiosFree(FreqRatios* freq_ratios)
5150 {
5151 if ( !freq_ratios )
5152 return NULL;
5153
5154 if (freq_ratios->data) {
5155 Uint4 i;
5156 for (i = 0; i < PROTEIN_ALPHABET; i++) {
5157 freq_ratios->data[i] = MemFree(freq_ratios->data[i]);
5158 }
5159 freq_ratios->data = MemFree(freq_ratios->data);
5160 }
5161
5162 freq_ratios = MemFree(freq_ratios);
5163 return NULL;
5164 }
5165
5166 /* END of copied code */
5167 /****************************************************************************/
5168