NCBI C Toolkit Cross Reference

C/desktop/dotmatrx.c


  1 /* ===========================================================================
  2 *
  3 *                            PUBLIC DOMAIN NOTICE
  4 *               National Center for Biotechnology Information
  5 *
  6 *  This software/database is a "United States Government Work" under the
  7 *  terms of the United States Copyright Act.  It was written as part of
  8 *  the author's official duties as a United States Government employee and
  9 *  thus cannot be copyrighted.  This software/database is freely available
 10 *  to the public for use. The National Library of Medicine and the U.S.
 11 *  Government have not placed any restriction on its use or reproduction.
 12 *
 13 *  Although all reasonable efforts have been taken to ensure the accuracy
 14 *  and reliability of the software and data, the NLM and the U.S.
 15 *  Government do not and cannot warrant the performance or results that
 16 *  may be obtained by using this software or data. The NLM and the U.S.
 17 *  Government disclaim all warranties, express or implied, including
 18 *  warranties of performance, merchantability or fitness for any particular
 19 *  purpose.
 20 *
 21 *  Please cite the author in any work or product based on this material.
 22 *
 23 * ===========================================================================*/
 24 
 25 /*****************************************************************************
 26 
 27 File name: dotmatrx.c
 28 
 29 Author: Tom Madden
 30 
 31 *****************************************************************************/
 32 #include <dotmatrx.h>
 33 #include <objmgr.h>
 34 #include <dlogutil.h>
 35 #include <vibrant.h>
 36 #include <picture.h>
 37 #include <viewer.h>
 38 #include <objseq.h>
 39 #include <objsset.h>
 40 #include <salsap.h>
 41 #include <blast.h>
 42 #include <salpedit.h>
 43 
 44 typedef struct dotmatrixform {
 45   FEATURE_FORM_BLOCK
 46   PopuP        scale;
 47   GrouP        showLabels;
 48   VieweR       vwr;
 49   SegmenT      pict;
 50   DotMatrixAlignmentPtr dmap;
 51   int (LIBCALLBACK *user_callback)PROTO((SeqAlignPtr seqalign));
 52   Boolean      scaleNotCalculated;
 53 } DotMatForm, PNTR DotMatFormPtr;
 54 
 55 #define MAXZOOMSCALEVAL 22
 56 
 57 static Int4  zoomScaleVal [MAXZOOMSCALEVAL] = {
 58   1L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 20L,
 59   30L, 40L, 50L, 60L, 70L, 80L, 90L, 100L, 200L, 500L
 60 };
 61 
 62 
 63 static Boolean DeselectSegment (SegmenT seg, PrimitivE prim, Uint2 segID,
 64                                 Uint2 primID, Uint2 primCt, VoidPtr userdata)
 65 
 66 {
 67   DotMatFormPtr  dfp;
 68 
 69   dfp = (DotMatFormPtr) userdata;
 70   if (dfp == NULL) 
 71         return FALSE;
 72   HighlightSegment (dfp->vwr, seg, PLAIN_SEGMENT);
 73   return TRUE;
 74 }
 75 
 76 static SeqAlignPtr FindSeqAlign(DotMatFormPtr dfp, Int4 segID)
 77 
 78 {
 79         DenseDiagPtr ddp, ddp_new;
 80         DotMatrixAlignmentPtr dmap;
 81         SeqAlignPtr seqalign, new_seqalign=NULL;
 82         Int4 index=0;
 83 
 84         dmap = dfp->dmap;
 85         while (dmap)
 86         {
 87                 if (dmap->sap->segtype == 2)
 88                 {
 89                         seqalign = dmap->sap;
 90                 }
 91                 else
 92                 {       /* discontinuous */
 93                         seqalign = dmap->sap->segs;
 94                 }
 95                 
 96                 while (seqalign != NULL) 
 97                 {
 98                         index++;
 99                         if (index == segID)
100                         {
101                                 break;
102                         }
103                         seqalign = seqalign->next;
104                 }
105                 
106                 if (seqalign)
107                 {
108                         if (seqalign->segtype == 1)
109                         {
110                                 new_seqalign = SeqAlignNew();
111                                 new_seqalign->type = 2;
112                                 new_seqalign->segtype = 1;
113                                 ddp = seqalign->segs;
114                                 new_seqalign->segs = ddp_new = DenseDiagDup(ddp);       
115                                 while (ddp->next)
116                                 {
117                                         ddp_new->next = DenseDiagDup(ddp->next);
118                                         ddp = ddp->next;
119                                         ddp_new = ddp_new->next;
120                                 }
121                         }
122                         else if (seqalign->segtype == 2)
123                         {
124                                 new_seqalign = SeqAlignDup(seqalign);
125                         }
126                 }
127                 dmap = dmap->next;
128         }
129 
130         return new_seqalign;
131 }
132 
133 static void ClickDotMatrix (VieweR vwr, SegmenT seg, PoinT pt)
134 
135 {
136   DotMatFormPtr  dfp;
137   Int1           highlight;
138   SegmenT        new_seg;
139   PrimitivE      prim;
140   SeqAlignPtr    seqalign;
141   Uint2          primCT;
142   Uint2          primID;
143   Uint2          segID;
144 
145         dfp = (DotMatFormPtr) GetObjectExtra (vwr);
146         new_seg = FindSegment (vwr, pt, &segID, &primID, &primCT);
147         if (new_seg == NULL) 
148         {
149                 ExploreSegment(seg, (Pointer) dfp, DeselectSegment);
150         } 
151         else 
152         {
153                 prim = GetPrimitive (new_seg, primCT);
154                 GetPrimDrawAttribute (prim, NULL, NULL, NULL, NULL, NULL, &highlight);
155                 if (highlight != PLAIN_SEGMENT) 
156                 {
157                         HighlightSegment (vwr, new_seg, PLAIN_SEGMENT);
158                 } 
159                 else 
160                 {
161                         HighlightSegment (vwr, new_seg, FILL_CONTENTS);
162                         seqalign = FindSeqAlign(dfp, segID);
163                         if (dblClick && dfp->user_callback)
164                                 dfp->user_callback(seqalign);
165                 }
166         }
167 }
168 static SegmenT 
169 CreateDotMatrixPic (DotMatrixAlignmentPtr dmap, Boolean showLabels)
170 
171 {
172   Char          buffer [50];
173   DenseDiagPtr  ddp;
174   DenseSegPtr   dsp;
175   SeqAlignPtr   sap;
176   Int4          index, index1;
177   SegmenT       seg;
178   Int4          x;
179   Int4          y;
180   SegmenT               pict;
181 
182   if (dmap == NULL || dmap->sap == NULL) 
183         return NULL;
184   pict = CreatePicture ();
185 
186   while (dmap)
187   {
188           sap = dmap->sap;
189           if (sap == NULL)
190                 break;
191           if (sap->segtype != 2)
192           {     /* discontinuous */
193                 sap = sap->segs;
194           }
195           index = 0;
196           while (sap != NULL) 
197           {
198             seg = CreateSegment (pict, index + 1, 0);
199         
200             AddAttribute (seg, COLOR_ATT, dmap->color, 0, 0, 0, 0);
201         
202             if (sap->segtype == 1)
203             {
204                 ddp = sap->segs;
205                 while (ddp != NULL) 
206                 {
207                         AddLine (seg, ddp->starts [0], ddp->starts [1], ddp->starts [0] + ddp->len, ddp->starts [1] + ddp->len, FALSE, 0);
208                 
209                         if (showLabels) 
210                         {
211                                 x = ddp->starts [0];
212                                 y = ddp->starts [1];
213                                 sprintf (buffer, "(%ld, %ld)", (long) x + 1, (long) y + 1);
214                                 AddLabel (seg, x, y, buffer, SMALL_TEXT, 0, LOWER_RIGHT, 0);
215         
216                                 x = ddp->starts [0] + ddp->len;
217                                 y = ddp->starts [1] + ddp->len;
218                                 sprintf (buffer, "(%ld, %ld)", (long) x, (long) y);
219                                 AddLabel (seg, x, y, buffer, SMALL_TEXT, 0, UPPER_RIGHT, 0);
220                         }
221         
222                         ddp = ddp->next;
223                 }
224             }
225             else if (sap->segtype == 2)
226             {
227                 dsp = sap->segs;
228                 for (index1=0; index1<dsp->numseg; index1++)
229                 {
230                         if (dsp->starts[2*index1] != -1 && dsp->starts[2*index1+1] != -1)
231                         {
232                                 AddLine (seg, dsp->starts[2*index1], dsp->starts[2*index1+1], dsp->starts[2*index1] + dsp->lens[index1], dsp->starts[2*index1+1] + dsp->lens[index1], FALSE, 0);
233                                 if (showLabels) 
234                                 {
235                                         x = dsp->starts[2*index1];
236                                         y = dsp->starts[2*index1+1];
237                                         sprintf (buffer, "(%ld, %ld)", (long) x + 1, (long) y + 1);
238                                         AddLabel (seg, x, y, buffer, SMALL_TEXT, 0, LOWER_RIGHT, 0);
239                                         x = dsp->starts[2*index1] + dsp->lens[index1];
240                                         y = dsp->starts[2*index1+1] + dsp->lens[index1];
241                                         sprintf (buffer, "(%ld, %ld)", (long) x + 1, (long) y + 1);
242                                         AddLabel (seg, x, y, buffer, SMALL_TEXT, 0, UPPER_RIGHT, 0);
243                                 }
244                         }
245                 }
246             }
247             index++;
248             sap = sap->next;
249         }
250         dmap = dmap->next;
251   }
252   return pict;
253 }
254 
255 static void MakeDotMatrixPicture (DotMatFormPtr dfp)
256 
257 {
258   Boolean       showLabels;
259 
260   if (dfp == NULL || dfp->dmap == NULL) 
261         return;
262 
263   showLabels = (Boolean) (GetValue (dfp->showLabels) == 1);
264   dfp->pict = CreateDotMatrixPic (dfp->dmap, showLabels);
265 
266 }
267 static void RepopulateDotMatrixViewer (DotMatFormPtr dfp)
268 
269 {
270   Int2  index;
271   Int4  scaleX;
272   Int4  scaleY;
273   Char  str [16];
274 
275   if (dfp == NULL) 
276         return;
277 
278   Reset (dfp->vwr);
279   dfp->pict = DeletePicture (dfp->pict);
280   Update ();
281   MakeDotMatrixPicture (dfp);
282   if (dfp->scaleNotCalculated) 
283   {
284     SafeHide (dfp->scale);
285     Reset (dfp->scale);
286     for (index=1; index<=20; index++) 
287     {
288       sprintf (str, "%ld", (long) (zoomScaleVal [index]));
289       PopupItem (dfp->scale, str);
290     }
291     SetValue (dfp->scale, 5);
292     dfp->scaleNotCalculated = FALSE;
293   }
294   SafeShow (dfp->scale);
295   index = GetValue (dfp->scale);
296   if (index < MAXZOOMSCALEVAL && index > 0) 
297   {
298     scaleX = zoomScaleVal [index];
299   } 
300   else 
301   {
302     scaleX = 1;
303   }
304   scaleY = scaleX;
305   AttachPicture (dfp->vwr, dfp->pict, INT4_MIN, INT4_MAX, UPPER_LEFT, scaleX, scaleY, NULL);
306   SetViewerProcs (dfp->vwr, ClickDotMatrix, NULL, NULL, NULL);
307   Update ();
308 }
309 
310 static void ChangeScale (PopuP p)
311 
312 {
313   DotMatFormPtr  dfp;
314 
315   dfp = (DotMatFormPtr) GetObjectExtra (p);
316   if (dfp != NULL) 
317   {
318     RepopulateDotMatrixViewer (dfp);
319   }
320 }
321 
322 static void ChangeLabels (GrouP g)
323 
324 {
325   DotMatFormPtr  dfp;
326 
327   dfp = (DotMatFormPtr) GetObjectExtra (g);
328   if (dfp != NULL) 
329   {
330     RepopulateDotMatrixViewer (dfp);
331   }
332 }
333 
334 static void ResizeDotMatrixForm (WindoW w)
335 
336 {
337   DotMatFormPtr  dfp;
338   Int2           height;
339   RecT           r;
340   RecT           s;
341   Int2           width;
342 
343   dfp = (DotMatFormPtr) GetObjectExtra (w);
344   if (dfp != NULL) 
345   {
346     ObjectRect (w, &r);
347     width = r.right - r.left;
348     height = r.bottom - r.top;
349     if (dfp->vwr != NULL) 
350     {
351       GetPosition (dfp->vwr, &s);
352       s.right = width - s.left;
353       s.bottom = height - s.left;
354       SetPosition (dfp->vwr, &s);
355       AdjustPrnt (dfp->vwr, &s, FALSE);
356       if (Visible (dfp->vwr) && AllParentsVisible (dfp->vwr)) 
357       {
358                 ViewerWasResized (dfp->vwr);
359       }
360     }
361     Update ();
362   }
363 }
364 
365 static void CleanupDotMatrixForm (GraphiC g, VoidPtr data)
366 
367 {
368   DotMatFormPtr  dfp;
369   DotMatrixAlignmentPtr dmap;
370 
371   dfp = (DotMatFormPtr) data;
372   if (dfp != NULL) 
373   {
374     dfp->pict = DeletePicture (dfp->pict);
375     dmap = dfp->dmap;
376     while (dmap)
377     {
378         dmap->sap = SeqAlignFree (dmap->sap);
379         dmap = dmap->next;
380     }
381   }
382   StdCleanupFormProc (g, data);
383 }
384 
385 static void HideDotMatrix (ButtoN i)
386 
387 {
388         WindoW w;
389 
390         w = (WindoW)ParentWindow (i);
391         Remove(w);
392         
393 }
394 
395 DotMatrixAlignmentPtr LIBCALL
396 DotMatrixAlignmentNew (SeqAlignPtr sap, Uint1Ptr color, DotMatrixAlignmentPtr PNTR oldp)
397 
398 {
399         DotMatrixAlignmentPtr new, old;
400 
401         new = MemNew(sizeof(DotMatrixAlignment));
402 
403         if (new == NULL || oldp == NULL)
404                 return NULL;
405 
406         new->sap = sap;
407         new->color = color;
408 
409         if (*oldp)
410         {
411                 old = *oldp;
412                 while (old->next)
413                         old = old->next;
414 
415                 old->next = new;
416         }
417         else
418         {
419                 *oldp = new;
420         }
421         return new;
422 }
423 
424 #define BLAST_DOTMATRIX_EXTENT 600      /* Size of screen. */
425 
426 ForM LIBCALL CreateDotMatrixForm (SeqAlignPtr sap, int (LIBCALLBACK *callback)PROTO((SeqAlignPtr seqalign)))
427 
428 {
429         DotMatrixAlignmentPtr dmap, tmp;
430 
431         tmp = NULL;
432         dmap = DotMatrixAlignmentNew(sap, NULL, &tmp);
433         return CreateDotMatrixFormEx(dmap, callback);
434 }
435 
436 ForM LIBCALL CreateDotMatrixFormEx (DotMatrixAlignmentPtr dmap, int (LIBCALLBACK *callback)PROTO((SeqAlignPtr seqalign)))
437 
438 {
439   DotMatFormPtr  dfp;
440   GrouP          g;
441   PrompT         p1;
442   PrompT         p2;
443   GrouP          s, x;
444   WindoW         w;
445 
446   w = NULL;
447   dfp = (DotMatFormPtr) MemNew (sizeof (DotMatForm));
448   if (dfp != NULL) 
449   {
450     dfp->dmap = dmap;
451     dfp->user_callback = callback;
452 
453     w = DocumentWindow (-40, -33, -10, -10, "Dot Matrix Display",
454                         StdCloseWindowProc, ResizeDotMatrixForm);
455     SetObjectExtra (w, dfp, CleanupDotMatrixForm);
456     dfp->form = (ForM) w;
457 
458     x = HiddenGroup (w, 0, 1, NULL);
459     StaticPrompt (x, "Dot Matrix showing the BLAST hits between 2 sequences", 0, 0, programFont, 'l');
460 
461     s = HiddenGroup (w, 5, 0, NULL);
462     SetGroupSpacing (s, 7, 2);
463 
464     p1 = StaticPrompt (s, "Labels", 0, 0, programFont, 'l');
465     dfp->showLabels = HiddenGroup (s, 3, 0, ChangeLabels);
466     SetObjectExtra (dfp->showLabels, dfp, NULL);
467     RadioButton (dfp->showLabels, "Show");
468     RadioButton (dfp->showLabels, "Hide");
469     SetValue (dfp->showLabels, TRUE);
470 
471     p2 = StaticPrompt (s, "Scale", 0, popupMenuHeight, programFont, 'l');
472     dfp->scale = PopupList (s, TRUE, ChangeScale);
473     SetObjectExtra (dfp->scale, dfp, NULL);
474 
475     AlignObjects (ALIGN_MIDDLE, (HANDLE) p1, (HANDLE) dfp->showLabels, (HANDLE) p2, (HANDLE) dfp->scale, NULL);
476 
477     x = HiddenGroup (w, 0, 2, NULL);
478     StaticPrompt (x, "Decrease scale to zoom in", 0, 0, programFont, 'l');
479     StaticPrompt (x, "Click on diagonals to launch the alignment editor", 0, 0, programFont, 'l');
480 
481     g = HiddenGroup (w, 2, 0, NULL);
482     dfp->vwr = CreateViewer (g, BLAST_DOTMATRIX_EXTENT, BLAST_DOTMATRIX_EXTENT, TRUE, TRUE);
483     SetObjectExtra (dfp->vwr, dfp, NULL);
484     dfp->pict = NULL;
485     dfp->scaleNotCalculated = TRUE;
486 
487     PushButton (w, "Dismiss", HideDotMatrix );
488 
489     RealizeWindow (w);
490     RepopulateDotMatrixViewer (dfp);
491   }
492   return (ForM) w;
493 }
494 
495 Int2 LIBCALL DotMatrixSearch(SeqIdPtr sip1, SeqIdPtr sip2, int (LIBCALLBACK *callback)PROTO((SeqAlignPtr seqalign)))
496 
497 {
498         BioseqPtr query_bsp, subject_bsp;
499         BLAST_OptionsBlkPtr options;
500         Boolean is_na;
501         SeqAlignPtr seqalign;
502         WindoW  window;
503 
504 
505         query_bsp = BioseqLockById(sip1);
506         subject_bsp = BioseqLockById(sip2);
507         if (query_bsp == NULL || subject_bsp == NULL)
508         {
509                 ErrPostEx(SEV_WARNING, 0, 0, "Unable to obtain sequences");
510                 return 1;
511         }
512 
513         if (ISA_na(query_bsp->mol) != ISA_na(subject_bsp->mol))
514         {
515                 ErrPostEx(SEV_WARNING, 0, 0, "Sequences are of different types");
516                 return 1;
517         }
518 
519         is_na = ISA_na(query_bsp->mol);
520 
521         options = BLASTOptionNew((is_na == TRUE) ? "blastn":"blastp", TRUE);
522 
523         seqalign = BlastTwoSequences(query_bsp, subject_bsp, NULL, options);
524 
525         if (seqalign == NULL)
526         {
527                 ErrPostEx(SEV_WARNING, 0, 0, "No hits found");
528                 return 0;
529         }
530 
531         window = (WindoW) CreateDotMatrixForm(seqalign, callback);
532 
533         Show(window);
534 
535         BioseqUnlockById(sip1);
536         BioseqUnlockById(sip2);
537 
538         return 0;
539 }
540 
541 Int2 LIBCALLBACK DotMatrixGenFunc (Pointer data)
542 
543 {
544   OMProcControlPtr  ompcp;
545   SeqAlignPtr       sap;
546   WindoW            w;
547 
548   ompcp = (OMProcControlPtr) data;
549   if (ompcp == NULL || ompcp->proc == NULL) 
550         return OM_MSG_RET_ERROR;
551 
552   sap = NULL;
553   switch (ompcp->input_itemtype) 
554   {
555     case OBJ_SEQALIGN :
556       sap = (SeqAlignPtr) ompcp->input_data;
557       break;
558     case 0 :
559       return OM_MSG_RET_ERROR;
560     default :
561       return OM_MSG_RET_ERROR;
562   }
563   w = (WindoW) CreateDotMatrixForm (sap, NULL);
564   Show (w);
565   Select (w);
566   return OM_MSG_RET_DONE;
567 }
568 

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.