NCBI C Toolkit Cross Reference

C/cn3d/seqcons.c


  1 /*   $Id: seqcons.c,v 6.23 2000/05/05 13:28:59 thiessen Exp $
  2 * ===========================================================================
  3 *
  4 *                            PUBLIC DOMAIN NOTICE
  5 *            National Center for Biotechnology Information (NCBI)
  6 *
  7 *  This software/database is a "United States Government Work" under the
  8 *  terms of the United States Copyright Act.  It was written as part of
  9 *  the author's official duties as a United States Government employee and
 10 *  thus cannot be copyrighted.  This software/database is freely available
 11 *  to the public for use. The National Library of Medicine and the U.S.
 12 *  Government do not place any restriction on its use or reproduction.
 13 *  We would, however, appreciate having the NCBI and the author cited in
 14 *  any work or product based on this material
 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 * ===========================================================================
 25 *
 26 * File Name:  $Id: seqcons.c,v 6.23 2000/05/05 13:28:59 thiessen Exp $
 27 *
 28 * Authors:  Paul Thiessen
 29 *
 30 * Version Creation Date: 2/10/2000
 31 *
 32 * File Description: to calculate colors for columns to visualize
 33 *                   sequence conservation
 34 *
 35 * Modifications:
 36 * --------------------------------------------------------------------------
 37 * $Log: seqcons.c,v $
 38 * Revision 6.23  2000/05/05 13:28:59  thiessen
 39 * fix to handle updated profiler
 40 *
 41 * Revision 6.22  2000/04/27 13:36:19  thiessen
 42 * change algorithm GUI names
 43 *
 44 * Revision 6.21  2000/04/11 17:14:20  thiessen
 45 * remove warning for zero-length alignment
 46 *
 47 * Revision 6.20  2000/04/06 19:03:20  thiessen
 48 * new BLOSUM62 conservation coloring
 49 *
 50 * Revision 6.19  2000/04/06 14:49:46  thiessen
 51 * minor optimizations
 52 *
 53 * Revision 6.18  2000/04/04 15:50:45  thiessen
 54 * fix coloring when aligned gaps present
 55 *
 56 * Revision 6.17  2000/03/21 14:16:11  thiessen
 57 * improved color ramp for variety scheme
 58 *
 59 * Revision 6.16  2000/03/17 22:49:00  thiessen
 60 * fix for multi-chain / multi-model features ; added feature-move ; misc bug fixes
 61 *
 62 * Revision 6.15  2000/03/16 20:31:45  thiessen
 63 * fixes to color; new color-by-variety algorithm
 64 *
 65 * Revision 6.14  2000/03/14 18:03:14  thiessen
 66 * add target row to MMD; remove rowmgr
 67 *
 68 * Revision 6.13  2000/03/03 20:05:17  thiessen
 69 * removal of palette-building pass if in 24-bit color
 70 *
 71 * Revision 6.12  2000/03/03 14:22:29  thiessen
 72 * moved back into ncbicn3d
 73 *
 74 * Revision 1.1  2000/03/02 21:20:41  thiessen
 75 * many improvements, moved into object library
 76 *
 77 * Revision 6.10  2000/02/25 02:53:15  thiessen
 78 * check AlignMgr rather than bAligned flag to see if a residue is aligned
 79 *
 80 * Revision 6.9  2000/02/23 18:56:30  thiessen
 81 * move to 1-based row numbers
 82 *
 83 * Revision 6.8  2000/02/19 21:25:58  thiessen
 84 * split of cn3dmodl into cn3dmodl and cn3dstyl
 85 *
 86 * Revision 6.7  2000/02/17 15:41:11  thiessen
 87 * added CSC algorithm selection submenu
 88 *
 89 * Revision 6.6  2000/02/16 21:25:31  thiessen
 90 * new row manager module; made Cn3D use row-wise color storage for aligned strucs
 91 *
 92 * Revision 6.5  2000/02/16 14:02:00  thiessen
 93 * further progress on seqcons module
 94 *
 95 * Revision 6.4  2000/02/14 21:22:00  kans
 96 * include seqcons.h after other includes, to pick up SeqAlign, SeqId, etc., otherwise types undefined at first use
 97 *
 98 * Revision 6.3  2000/02/14 20:04:23  thiessen
 99 * another fix for solvent; more filling in of seqcons
100 *
101 * Revision 6.2  2000/02/14 12:32:31  thiessen
102 * fix solvent identification; progress on seqcons module
103 *
104 * Revision 6.1  2000/02/11 01:12:35  thiessen
105 * new module for sequence conservation coloring
106 *
107 *
108 *
109 * ==========================================================================
110 */
111 
112 #include <vibrant.h>
113 #include <objseq.h>
114 #include <mmdbapi.h>
115 #include <alignmgr.h>
116 #include <actutils.h>
117 #include <seqcons.h>
118 #include <seqmgr.h>
119 #include <viewmgr.h>
120 
121 
122 #define MESSAGE_TYPE MSG_POST
123 
124 #define ERR_RETURN(msg) do { \
125     Message(MESSAGE_TYPE, "Color-by-conservation module error: %s", (msg)); \
126     return; \
127 } while (0)
128 
129 #define ERR_RETURN_VAL(msg, val) do { \
130     Message(MESSAGE_TYPE, "Color-by-conservation module error: %s", (msg)); \
131     return (val); \
132 } while (0)
133 
134 
135 /**** data structures to hold column colors ****/
136 
137 static Nlm_UcharPtr CSC_CurrentColors = NULL;
138 static Nlm_Int4 CSC_CurrentNColumns = 0;
139 
140 static int CSC_CurrentProfileRows;
141 
142 
143 /**** data structures to hold row/SeqId index ****/
144 
145 static SeqAlignPtr CSC_CurrentSeqAlign = NULL;
146 static ACTProfilePtr CSC_CurrentProfile = NULL;
147 
148 
149 /**** functions to access color data ****/
150 
151 static Nlm_Int4 CSC_GetColumnColorByRowAndAlignLoc(Nlm_Int4 row, Nlm_Int4 alignLoc)
152 {
153     if (alignLoc < 0 || alignLoc >= CSC_CurrentNColumns)
154         ERR_RETURN_VAL("alignLoc out of range", CSC_COLOR_ERROR);
155     else
156         return ((CSC_CurrentColors[3*alignLoc] << 16) +
157                 (CSC_CurrentColors[3*alignLoc+1] << 8) +
158                  CSC_CurrentColors[3*alignLoc+2]);
159 }
160 
161 Nlm_Int4 CSC_GetColumnColorByRow(Nlm_Int4 row, Nlm_Int4 seqLoc)
162 {
163     Nlm_Int4 alignLoc = -1;
164 
165     if (row <= 0)
166         return CSC_COLOR_ERROR;
167     
168     /* determine alignment location (column) from bioseq location */
169     alignLoc = AlnMgrMapBioseqToSeqAlign(CSC_CurrentSeqAlign, seqLoc, row, NULL);
170 
171     /* then return the appropriate column color */
172     if (alignLoc < 0)
173         ERR_RETURN_VAL("can't map seqLoc to alignLoc", CSC_COLOR_ERROR);
174     if (alignLoc >= CSC_CurrentNColumns) {
175 #ifdef _DEBUG
176         Message(MSG_POST,"row %i, seqloc %i, alignloc %i, align len %i",
177             row, seqLoc, alignLoc, CSC_CurrentNColumns);
178 #endif
179         ERR_RETURN_VAL("alignLoc out of range", CSC_COLOR_ERROR);
180     }
181 
182     return CSC_GetColumnColorByRowAndAlignLoc(row, alignLoc);
183 }
184 
185 
186 /**** functions for various algorithms to assign colors based on profile ****/
187 
188 typedef void (*CSC_AlgorithmFunc)(void); /* must all be of this type */
189 
190 static Nlm_Uint1 CSC_FullIdentityColor[3] = { 255, 25, 25 },
191                  CSC_ZeroIdentityColor[3] = { 100, 100, 255 };
192 
193 
194 /* ramp depending on how many different residue types are present */
195 static void CSC_Algorithm_ShowVariety(void)
196 {
197     static int *variety = NULL, vSize = -1;
198     ACTProfilePtr app;
199     int c, pr, offset, maxResTypes = 1, nResTypes, nRows, i = 0;
200     Nlm_Int4 foundFlags, typeBit;
201     double scale;
202     FloatHi freqSum;
203 
204     /* static cache for color varieties */
205     if (vSize != CSC_CurrentNColumns) {
206         if (variety) MemFree(variety);
207         variety = (int *) MemNew(CSC_CurrentNColumns * sizeof(int));
208         if (!variety) return;
209         vSize = CSC_CurrentNColumns;
210     }
211 
212     nRows = AlnMgrGetNumRows(CSC_CurrentSeqAlign);
213 
214     /* first determine column variation and max */
215     for (app = CSC_CurrentProfile; app; app = app->next) {
216         for (c = 0; c < app->len; c++) {
217             foundFlags = nResTypes = 0;
218             freqSum = 0.0;
219             for (pr = 1; pr < CSC_CurrentProfileRows; pr++) {
220                 if (((int) (app->freq[pr][c] + 0.001)) > 0) {
221                     freqSum += app->freq[pr][c];
222                     typeBit = ((Nlm_Int4) 1) << pr;
223                     if (!(foundFlags & typeBit)) {
224                         nResTypes++;
225                         foundFlags |= typeBit;
226                     }
227                 }
228             }
229             /* each gap counts as an additional variety */
230             nResTypes += nRows - app->numseq;
231             nResTypes += app->numseq - ((int) (freqSum + 0.001));
232 
233             variety[i++] = nResTypes;
234             if (nResTypes > maxResTypes)
235                 maxResTypes = nResTypes;
236         }
237     }
238 
239     /* then color according to variety in each column, normalized by max variety */
240     for (i = 0; i < CSC_CurrentNColumns; i++) {
241         nResTypes = variety[i];
242         if (maxResTypes == 1)
243             scale = 0.0;
244         else
245             /* scale [1..maxResTypes] onto [0..1] */
246             scale = 1.0 * (nResTypes - 1) / (maxResTypes - 1);
247 
248         offset = 3 * i;
249         CSC_CurrentColors[offset] = (Nlm_Uint1)
250             (scale * (CSC_ZeroIdentityColor[0] - CSC_FullIdentityColor[0])
251                 + CSC_FullIdentityColor[0]);
252         CSC_CurrentColors[offset+1] = (Nlm_Uint1)
253             (scale * (CSC_ZeroIdentityColor[1] - CSC_FullIdentityColor[1])
254                 + CSC_FullIdentityColor[1]);
255         CSC_CurrentColors[offset+2] = (Nlm_Uint1)
256             (scale * (CSC_ZeroIdentityColor[2] - CSC_FullIdentityColor[2])
257                 + CSC_FullIdentityColor[2]);
258     }
259 }
260 
261 /* stuff for BLOSUM coloring */
262 #define CSC_BLOSUMSIZE 24
263 static const char CSC_Blosum62Fields[CSC_BLOSUMSIZE] =
264    { 'A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I', 'L', 'K', 'M', 
265      'F', 'P', 'S', 'T', 'W', 'Y', 'V', 'B', 'Z', 'X', '*' };
266 static const Nlm_Int1 CSC_Blosum62Matrix[CSC_BLOSUMSIZE][CSC_BLOSUMSIZE] = {
267 /*       A,  R,  N,  D,  C,  Q,  E,  G,  H,  I,  L,  K,  M,  F,  P,  S,  T,  W,  Y,  V,  B,  Z,  X,  * */
268 /*A*/ {  4, -1, -2, -2,  0, -1, -1,  0, -2, -1, -1, -1, -1, -2, -1,  1,  0, -3, -2,  0, -2, -1,  0, -4 },
269 /*R*/ { -1,  5,  0, -2, -3,  1,  0, -2,  0, -3, -2,  2, -1, -3, -2, -1, -1, -3, -2, -3, -1,  0, -1, -4 },
270 /*N*/ { -2,  0,  6,  1, -3,  0,  0,  0,  1, -3, -3,  0, -2, -3, -2,  1,  0, -4, -2, -3,  3,  0, -1, -4 },
271 /*D*/ { -2, -2,  1,  6, -3,  0,  2, -1, -1, -3, -4, -1, -3, -3, -1,  0, -1, -4, -3, -3,  4,  1, -1, -4 },
272 /*C*/ {  0, -3, -3, -3,  9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1, -2, -2, -1, -3, -3, -2, -4 },
273 /*Q*/ { -1,  1,  0,  0, -3,  5,  2, -2,  0, -3, -2,  1,  0, -3, -1,  0, -1, -2, -1, -2,  0,  3, -1, -4 },
274 /*E*/ { -1,  0,  0,  2, -4,  2,  5, -2,  0, -3, -3,  1, -2, -3, -1,  0, -1, -3, -2, -2,  1,  4, -1, -4 },
275 /*G*/ {  0, -2,  0, -1, -3, -2, -2,  6, -2, -4, -4, -2, -3, -3, -2,  0, -2, -2, -3, -3, -1, -2, -1, -4 },
276 /*H*/ { -2,  0,  1, -1, -3,  0,  0, -2,  8, -3, -3, -1, -2, -1, -2, -1, -2, -2,  2, -3,  0,  0, -1, -4 },
277 /*I*/ { -1, -3, -3, -3, -1, -3, -3, -4, -3,  4,  2, -3,  1,  0, -3, -2, -1, -3, -1,  3, -3, -3, -1, -4 },
278 /*L*/ { -1, -2, -3, -4, -1, -2, -3, -4, -3,  2,  4, -2,  2,  0, -3, -2, -1, -2, -1,  1, -4, -3, -1, -4 },
279 /*K*/ { -1,  2,  0, -1, -3,  1,  1, -2, -1, -3, -2,  5, -1, -3, -1,  0, -1, -3, -2, -2,  0,  1, -1, -4 },
280 /*M*/ { -1, -1, -2, -3, -1,  0, -2, -3, -2,  1,  2, -1,  5,  0, -2, -1, -1, -1, -1,  1, -3, -1, -1, -4 },
281 /*F*/ { -2, -3, -3, -3, -2, -3, -3, -3, -1,  0,  0, -3,  0,  6, -4, -2, -2,  1,  3, -1, -3, -3, -1, -4 },
282 /*P*/ { -1, -2, -2, -1, -3, -1, -1, -2, -2, -3, -3, -1, -2, -4,  7, -1, -1, -4, -3, -2, -2, -1, -2, -4 },
283 /*S*/ {  1, -1,  1,  0, -1,  0,  0,  0, -1, -2, -2,  0, -1, -2, -1,  4,  1, -3, -2, -2,  0,  0,  0, -4 },
284 /*T*/ {  0, -1,  0, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1, -2, -1,  1,  5, -2, -2,  0, -1, -1,  0, -4 },
285 /*W*/ { -3, -3, -4, -4, -2, -2, -3, -2, -2, -3, -2, -3, -1,  1, -4, -3, -2, 11,  2, -3, -4, -3, -2, -4 },
286 /*Y*/ { -2, -2, -2, -3, -2, -1, -2, -3,  2, -1, -1, -2, -1,  3, -3, -2, -2,  2,  7, -1, -3, -2, -1, -4 },
287 /*V*/ {  0, -3, -3, -3, -1, -2, -2, -3, -3,  3,  1, -2,  1, -1, -2, -2,  0, -3, -1,  4, -3, -2, -1, -4 },
288 /*B*/ { -2, -1,  3,  4, -3,  0,  1, -1,  0, -3, -4,  0, -3, -3, -2,  0, -1, -4, -3, -3,  4,  1, -1, -4 },
289 /*Z*/ { -1,  0,  0,  1, -3,  3,  4, -2,  0, -3, -3,  1, -1, -3, -1,  0, -1, -3, -2, -2,  1,  4, -1, -4 },
290 /*X*/ {  0, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2,  0,  0, -2, -1, -1, -1, -1, -1, -4 },
291 /***/ { -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,  1 }
292 };
293 
294 /* returns BLOSUM score, based values for an aa according to NCBIstdaa */
295 static Nlm_Int1 CSC_GetBlosumScore(int value1, int value2)
296 {
297     int index1, index2, i, value, index;
298 
299     for (i = 0; i < 2; i++) {
300         value = (i==0) ? value1 : value2;
301         switch (value) { /* map NCBIstdaa "value" onto index in BLOSUM matrix */
302             case 1: index = 0; break;
303             case 2: index = 20; break;
304             case 3: case 24: index = 4; break;
305             case 4: index = 3; break;
306             case 5: index = 6; break;
307             case 6: index = 13; break;
308             case 7: index = 7; break;
309             case 8: index = 8; break;
310             case 9: index = 9; break;
311             case 10: index = 11; break;
312             case 11: index = 10; break;
313             case 12: index = 12; break;
314             case 13: index = 2; break;
315             case 14: index = 14; break;
316             case 15: index = 5; break;
317             case 16: index = 1; break;
318             case 17: index = 15; break;
319             case 18: index = 16; break;
320             case 19: index = 19; break;
321             case 20: index = 17; break;
322             case 21: index = 22; break;
323             case 22: index = 18; break;
324             case 23: index = 21; break;
325             default: index = -1; break;
326         }
327         if (i==0) index1 = index; else index2 = index;
328     }
329     if (index1 < 0 || index2 < 0)
330         return -4;
331     else
332         return CSC_Blosum62Matrix[index1][index2];
333 }
334 
335 /* ramp depending on sum of pairwise BLOSUM scores */
336 static void CSC_Algorithm_ByBlosum62(void)
337 {
338     static int *score = NULL, vSize = -1;
339     ACTProfilePtr app;
340     int c, pr1, pr2, offset, maxScore, minScore, nRows, i = 0, sum, nGaps;
341     double scale;
342     FloatHi freqSum;
343 
344     if (CSC_CurrentProfile->nuc) {
345         Message(MSG_POST, "Can't do BLOSUM coloring on nucleotides!\nWill do \"Variety\" coloring instead.");
346         CSC_Algorithm_ShowVariety();
347         return;
348     }
349 
350     /* static cache for score totals */
351     if (vSize != CSC_CurrentNColumns) {
352         if (score) MemFree(score);
353         score = (int *) MemNew(CSC_CurrentNColumns * sizeof(int));
354         if (!score) return;
355         vSize = CSC_CurrentNColumns;
356     }
357 
358     nRows = AlnMgrGetNumRows(CSC_CurrentSeqAlign);
359 
360     /* first determine column sums, min and max */
361     for (app = CSC_CurrentProfile; app; app = app->next) {
362         for (c = 0; c < app->len; c++) {
363             sum = 0;
364             freqSum = 0.0;
365             
366             /* count all "identity" pair scores */
367             for (pr1 = 1; pr1 < 26; pr1++) {
368                 sum += ((int) (app->freq[pr1][c] * (app->freq[pr1][c] - 1) / 2 + 0.001))
369                     * CSC_GetBlosumScore(pr1, pr1);
370                 freqSum += app->freq[pr1][c];
371             }
372 
373             /* then count all non-identical pairs */
374             for (pr1 = 1; pr1 < 26 - 1; pr1++) {
375                 for (pr2 = pr1 + 1; pr2 < 26; pr2++) {
376                     sum += ((int) (app->freq[pr1][c] * app->freq[pr2][c] + 0.001))
377                         * CSC_GetBlosumScore(pr1, pr2);
378                 }
379             }
380 
381             /* then count all pairs with (and amongst) gaps */
382             nGaps = nRows - app->numseq;
383             nGaps += app->numseq - ((int) (freqSum + 0.001));
384             sum += (nGaps * (nGaps - 1) / 2 + nGaps * (nRows - nGaps))
385                 * CSC_GetBlosumScore(-1, -1);
386 
387             score[i] = sum;
388             if (i == 0 || score[i] > maxScore)
389                 maxScore = score[i];
390             if (i == 0 || score[i] < minScore)
391                 minScore = score[i];
392             i++;
393         }
394     }
395 
396     /* then color according to score in each column, normalized by max score */
397     for (i = 0; i < CSC_CurrentNColumns; i++) {
398         if (minScore == maxScore)
399             scale = 0.0;
400         else
401             /* scale [minScore..maxScore] onto [1..0] */
402             scale = 1.0 - 1.0 * (score[i] - minScore) / (maxScore - minScore);
403 
404         offset = 3 * i;
405         CSC_CurrentColors[offset] = (Nlm_Uint1)
406             (scale * (CSC_ZeroIdentityColor[0] - CSC_FullIdentityColor[0])
407                 + CSC_FullIdentityColor[0]);
408         CSC_CurrentColors[offset+1] = (Nlm_Uint1)
409             (scale * (CSC_ZeroIdentityColor[1] - CSC_FullIdentityColor[1])
410                 + CSC_FullIdentityColor[1]);
411         CSC_CurrentColors[offset+2] = (Nlm_Uint1)
412             (scale * (CSC_ZeroIdentityColor[2] - CSC_FullIdentityColor[2])
413                 + CSC_FullIdentityColor[2]);
414     }
415 }
416 
417 /* simply one of two colors, for 100% column identity or not */
418 static void CSC_Algorithm_ShowIdentity(void)
419 {
420     ACTProfilePtr app = CSC_CurrentProfile;
421     int c, pr, offset = 0;
422     int nRows = AlnMgrGetNumRows(CSC_CurrentSeqAlign);
423     
424     for (; app; app = app->next) {
425         for (c = 0; c < app->len; offset += 3, c++) {
426             for (pr = 1; pr < CSC_CurrentProfileRows; pr++) {
427                 if (((int) (app->freq[pr][c] + 0.001)) == 0) continue;
428                 else if (((int) (app->freq[pr][c] + 0.001)) == nRows) {
429                     CSC_CurrentColors[offset] = CSC_FullIdentityColor[0];
430                     CSC_CurrentColors[offset+1] = CSC_FullIdentityColor[1];
431                     CSC_CurrentColors[offset+2] = CSC_FullIdentityColor[2];
432                 } else {
433                     CSC_CurrentColors[offset] = CSC_ZeroIdentityColor[0];
434                     CSC_CurrentColors[offset+1] = CSC_ZeroIdentityColor[1];
435                     CSC_CurrentColors[offset+2] = CSC_ZeroIdentityColor[2];
436                 }
437                 break;
438             }
439         }
440     }
441 }
442 
443 /* simply color all aligned residues a single color */
444 static void CSC_Algorithm_ShowAligned(void)
445 {
446     int c, offset = 0;
447 
448     for (c = 0; c < CSC_CurrentNColumns; c++) {
449         CSC_CurrentColors[offset] = CSC_FullIdentityColor[0];
450         CSC_CurrentColors[offset+1] = CSC_FullIdentityColor[1];
451         CSC_CurrentColors[offset+2] = CSC_FullIdentityColor[2];
452         offset += 3;
453     }
454 }
455 
456 
457 /**** to manage which algorithm is used ****/
458 
459 typedef struct _CSC_AlgorithmFuncListItem {
460     Nlm_Int2 type;
461     Nlm_CharPtr name;
462     CSC_AlgorithmFunc function;
463 } CSC_AlgorithmFuncListItem;
464 
465 /* must be in the same order as the enum in seqcons.h */
466 static CSC_AlgorithmFuncListItem CSC_AlgorithmFuncList[] = {
467     { CSC_BYVARIETY, "Variety", CSC_Algorithm_ShowVariety },
468     { CSC_BYBLOSUM62, "Weighted Variety", CSC_Algorithm_ByBlosum62 },
469     { CSC_SHOWIDENTITY, "Identity", CSC_Algorithm_ShowIdentity },
470     { CSC_SHOWALIGNED, "Aligned", CSC_Algorithm_ShowAligned }
471 };
472 
473 static Nlm_Int2 CSC_CurrentAlgorithm = -1;
474 
475 const Nlm_Char * CSC_GetAlgorithmName(Nlm_Int2 which)
476 {
477     if (which >= 0 && which < CSC_NUMALGORITHMS)
478         return CSC_AlgorithmFuncList[which].name;
479     ERR_RETURN_VAL("invalid algorithm identity", NULL);
480 }
481 
482 
483 /**** functions to calculate and access column colors ****/
484 
485 /* calculate and store column colors for an alignment */
486 Nlm_Boolean CSC_CalculateColumnColors(SeqAlignPtr salp, Nlm_Int2 useAlgorithm)
487 {
488     ACTProfilePtr app;
489     int len;
490     
491     /* if passed a null pointer, then clear the current stores */
492     if (!salp) {
493         if (CSC_CurrentColors) MemFree(CSC_CurrentColors);
494         if (CSC_CurrentProfile) ACT_ProfileSetFree(CSC_CurrentProfile);
495         CSC_CurrentColors = NULL;
496         CSC_CurrentSeqAlign = NULL;
497         CSC_CurrentProfile = NULL;
498         CSC_CurrentNColumns = 0;
499         CSC_CurrentAlgorithm = -1;
500         return FALSE;
501     }
502 
503     CSC_CurrentAlgorithm = useAlgorithm;
504     CSC_CurrentSeqAlign = salp;
505 
506     /* calculate and save alignment profile */
507     if (!AlnMgrIndexSeqAlign(salp))
508         ERR_RETURN_VAL("problem indexing SeqAlign", FALSE);
509     if (AlnMgrGetAlnLength(salp, FALSE) <= 0)
510         return TRUE;
511     if (!(app = ACT_MakeProfileFromSA(salp)))
512         ERR_RETURN_VAL("problem generating sequence profile", FALSE);
513     if (CSC_CurrentProfile) ACT_ProfileSetFree(CSC_CurrentProfile);
514     CSC_CurrentProfile = app;
515 
516     /* allocate/free new color storage as necessary */
517     for (len = 0, app = CSC_CurrentProfile; app; app = app->next) len += app->len;
518     if (len != AlnMgrGetAlnLength(salp, FALSE)) /* sanity check */
519         ERR_RETURN_VAL("length mismatch between alignment and profile", FALSE);
520     if (len != CSC_CurrentNColumns) {
521         if (CSC_CurrentColors)
522             MemFree(CSC_CurrentColors);
523         CSC_CurrentColors = (Nlm_Uchar *) MemNew(3 * len * sizeof(Nlm_Uchar));
524         if (!CSC_CurrentColors)
525             ERR_RETURN_VAL("out of memory", FALSE);
526         CSC_CurrentNColumns = len;
527     }
528 
529     /* do the appropriate calculation */
530     CSC_CurrentProfileRows = CSC_CurrentProfile->nuc ? 5 : 25;
531     (*CSC_AlgorithmFuncList[CSC_CurrentAlgorithm].function)();
532 
533     return TRUE;
534 }
535 
536 
537 /* determine whether a (view) row has a structure */
538 static Nlm_Boolean CSC_DoesRowHaveStructure(Nlm_Int4 row, PMSD pmsd)
539 {
540     PDNMM pdnmm;
541     PDNMS pdnms;
542 
543     /* convert viewed row that's passed into target row to search MMD's*/
544     row = ViewMgr_VRow2TRow(CSC_CurrentSeqAlign, row);
545 
546     /* check master */
547     pdnmm = pmsd->pdnmmHead;
548     while (pdnmm) {
549         if (((PMMD) pdnmm->data.ptrvalue)->iTargetRow == row)
550             return TRUE;
551         pdnmm = pdnmm->next;
552     }
553 
554     /* go through the slave structures */
555     pdnms = pmsd->pdnmsSlaves;
556     while (pdnms) {
557         pdnmm = ((PMSD) pdnms->data.ptrvalue)->pdnmmHead;
558         while (pdnmm) {
559             if (((PMMD) pdnmm->data.ptrvalue)->iTargetRow == row)
560                 return TRUE;
561             pdnmm = pdnmm->next;
562         }
563         pdnms = pdnms->next;
564     }
565 
566     return FALSE;
567 }
568 
569 /* color a row */
570 void CSC_SetDDVRowCells(Nlm_Int4 row, Nlm_Boolean applyColumnColor, 
571                         Nlm_Uint1 *unalignedColor, DDV_ColorGlobal *pDDVCG)
572 {
573     BioseqPtr bsp;
574     int seqLoc;
575     DDV_ColorCell *pColorCell;
576     Nlm_Int4 alignLoc, residueColorInt;
577     Nlm_Uint1 residueColor[3];
578 
579     if (row <= 0 || !pDDVCG || !CSC_CurrentSeqAlign)
580         return;
581 
582     bsp = BioseqLockById(AlnMgrGetNthSeqIdPtr(CSC_CurrentSeqAlign, row));
583     if (!bsp) return;
584 
585     for (seqLoc = 0; seqLoc < bsp->length; seqLoc++) {
586 
587         pColorCell = DDV_GetColor(pDDVCG, NULL, row, seqLoc);
588         if (pColorCell == NULL) return;
589 
590         alignLoc = AlnMgrMapBioseqToSeqAlign(CSC_CurrentSeqAlign, seqLoc, row, NULL);
591         if (alignLoc >= 0 && applyColumnColor) {
592             residueColorInt = CSC_GetColumnColorByRow(row, seqLoc);
593             residueColor[0] = (residueColorInt >> 16) & 0xFF;
594             residueColor[1] = (residueColorInt >> 8) & 0xFF;
595             residueColor[2] = residueColorInt & 0xFF;
596             DDV_SetColorInCell(pColorCell, residueColor);
597         } else {
598             DDV_SetColorInCell(pColorCell, unalignedColor);
599         }
600 
601         DDV_RequestColor(&(pDDVCG->Palette), pColorCell);
602         pColorCell->LowerCase = (alignLoc < 0);
603         DDV_SetColor(pDDVCG, NULL, row, seqLoc, pColorCell);
604     }
605 
606     BioseqUnlock(bsp);
607 }
608 
609 /* color non-structure rows */
610 void CSC_SetNonStructureDDVRowCells(PMSD pmsd, Nlm_Boolean applyColumnColor, 
611                                     Nlm_Uint1 *unalignedColor, DDV_ColorGlobal *pDDVCG)
612 {
613     int row, nRows;
614 
615     if (!pmsd || !pDDVCG || !CSC_CurrentSeqAlign)
616         return;
617 
618     nRows = AlnMgrGetNumRows(CSC_CurrentSeqAlign);
619     for (row = 1; row <= nRows; row++) {
620         if (!CSC_DoesRowHaveStructure(row, pmsd))
621             CSC_SetDDVRowCells(row, applyColumnColor, unalignedColor, pDDVCG);
622     }
623 }
624 
625 /* do all rows */
626 void CSC_SetAllDDVRowCells(Nlm_Boolean applyColumnColor, Nlm_Uint1 *unalignedColor,
627                            DDV_ColorGlobal *pDDVCG)
628 {
629     int row, nRows;
630 
631     if (!pDDVCG || !CSC_CurrentSeqAlign)
632         return;
633 
634     nRows = AlnMgrGetNumRows(CSC_CurrentSeqAlign);
635     for (row = 1; row <= nRows; row++)
636         CSC_SetDDVRowCells(row, applyColumnColor, unalignedColor, pDDVCG);
637 }
638 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.