/* File: pairmapdisp.c * Written by Jo Dicks (jld@bioch.ox.ac.uk) * ------------------------------------------------------------------- * Acedb is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt * ------------------------------------------------------------------- * This file is part of the ACeDB comparative mapping package, * written by Jo Dicks and Michelle Kirby * The original ACeDB system was written by : * Richard Durbin (MRC LMB, UK) rd@mrc-lmba.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * Copyright (C) J Thierry-Mieg and R Durbin, 1991 * * Description: to display single cells of Oxford Grids in detail * Exported functions: pairMapCreate() only * HISTORY: * Last edited: May 6 13:38 2003 (edgrif) * - change NULL's to 0's to please MS Visual C++ compiler * * Dec 2 10:19 1996 (srk) * Created: December 1993 * New models : May 1995 *------------------------------------------------------------------- */ /* $Id: pairmapdisp.c,v 1.14 2003/05/06 13:14:03 edgrif Exp $ */ #include "acedb.h" #include "display.h" #include "lex.h" #include "bs.h" #include "query.h" #include "session.h" #include "oxgrid.h" #include "pmap.h" #include "keysetdisp.h" #include "whooks/systags.h" #include "whooks/classes.h" #include "whooks/sysclass.h" #include "whooks/tags.h" BOOL pairMapDisplay (void) ; int pairMapConvert (OX ox) ; static void pairMapPick (int box, double x_unused, double y_unused, int modifier_unused) ; static void pairMapSelect (OX ox, int box) ; static void pairMapFollow (OX ox) ; static void pairMapDraw (void) ; static void pairMapDestroy (void) ; static void drawyChromosome (OX ox, float xlen) ; static void drawxChromosome (OX ox, float ylen) ; static void drawShade (OX ox) ; static void drawSegs (OX ox) ; static void pairMapFlip (void) ; /* static void pairMapShowAll (void) ; */ static void toggleChroms (void) ; static void toggleBars (void) ; static void toggleShade (void) ; static void drawyScale (void) ; static void drawxScale (void) ; static void noChroms (void) ; static void pairClear (void) ; static void pairLightAll (void) ; static void pairLight (void) ; static void pairUnLight (void) ; static void pairHide (void) ; static void pairHideLight (void) ; static void pairUnHide (void) ; static void pairExport (void) ; static void pairLightHom (void) ; static void pairUnLightHom (void) ; static void pairFindHom (char *string) ; static void pairFindLoc (char *string) ; static int pairhomolCompletion (char *cp, int len) ; static int pairlocusCompletion (char *cp, int len) ; static void pairZoomIn (void) ; static void pairZoomOut (void) ; enum BoxNames { BACKGROUND=0, CHROM_BOX, BARS_BOX, FLIP_BOX, HIDE_BOX, SHADE_BOX, FINDHOM_BOX, FINDHOM2_BOX, FINDLOC_BOX, FINDLOC2_BOX, ZOOM_IN, ZOOM_OUT, MESS_BOX, MIN_BOX } ; /* MIN_BOX must be last */ static MENUOPT pairMapMenu[] = { {graphDestroy, "Quit"}, {help, "Help"}, {graphPrint, "Print"}, {displayPreserve, "Preserve"}, {0, 0} } ; static MENUOPT HighlightMenu[] = { {pairClear, "Clear and show all"}, {pairLightAll, "Highlight all"}, {pairLightHom, "Highlight homology"}, {pairUnLightHom, "Unhighlight homology"}, {pairLight, "Highlight selected keyset"}, {pairUnLight,"Unhighlight selected keyset"}, {pairHide, "Restrict to keyset"}, {pairHideLight, "Hide highlit items"}, {pairUnHide, "Unhide hidden items"}, {pairExport, "Export highlit keyset"}, {0, 0} } ; static float xOff, yOff ; /*********************************/ void pairMapCreate (void) { int box ; BOX *bx ; OXGET ("pairMapCreate") ; /* Find out if the user has selected a cell to look at */ if (!(ox->gridBox)) {messout ("You have not selected a cell") ; return ;} else {box = ox->gridBox ; if (box >= ox->mlb + ox->map_labels) {bx = arrayp (ox->boxes, (box - ox->mlb + 1), BOX) ; ox->c1 = bx->map1 ; ox->c2 = bx->map2 ; if (!pairMapDisplay ()) return ; } } } BOOL pairMapDisplay (void) { int h ; OXGET ("pairMapDisplay") ; ox->c1min = 0 ; ox->c1max = 0 ; ox->c2min = 0 ; ox->c2max = 0 ; /* Set up the display as per usual */ /* If no points in the cell have an x AND a y position then give up */ h = pairMapConvert (ox) ; if (!(h > 0)) {messout ("Not enough data to draw a PairMap") ; return FALSE ;} if (graphExists (ox->pairGraph)) {graphActivate (ox->pairGraph) ; graphPop() ;} else {if (!displayCreate ("PAIRMAP")) return FALSE ; ox->pairGraph = graphActive () ; graphAssociate (&OX_MAGIC,ox) ; graphRegister (DESTROY, pairMapDestroy) ; graphRegister (MESSAGE_DESTROY, displayUnBlock) ; graphRegister (PICK, (GraphFunc) pairMapPick) ; graphMenu (pairMapMenu) ; } pairMapDraw () ; return TRUE ; } /***********************************************************/ /***************** Registered routines *********************/ /*************************************************/ /************* conversion and drawing ************/ static void pairMapDestroy (void) { OXGET ("pairMapDestroy") ; arrayDestroy (ox->points) ; arrayDestroy (ox->c1segs) ; arrayDestroy (ox->c2segs) ; ox->c1 = 0 ; ox->c2 = 0 ; ox->s3 = 0 ; ox->s4 = 0 ; } int pairMapConvert (OX ox) { KEY band, col, key ; KEY map1, map2 ; float x1, x2, xmin = 0, xmax = 0 ; float ymin = 0, ymax = 0 ; float min1 = 0, max1 = 0 ; float min2 = 0, max2 = 0 ; float f1, f2, f3, f4 ; int h, i, box ; OBJ yChrom, yBand, xChrom, xBand ; OBJ loc1, loc2 ; SEG *tseg ; CHROMS *c1seg ; CHROMS *c2seg ; HOMOL *seg ; char *sym ; Array bands ; static BSMARK mark1 = 0 ; static BSMARK mark2 = 0 ; /* Initialise the flags */ ox->flag |= FLAG_PAIR_CHROMS ; ox->flag |= FLAG_SEGS ; ox->flag |= FLAG_YCEN ; ox->flag |= FLAG_XCEN ; ox->flag |= FLAG_BARS ; ox->flag |= FLAG_SHADE ; ox->pairwide = 60 ; ox->pairhigh = 40 ; /* Check we can make the Map objects and if we can display the Maps */ if (!(xChrom = bsCreate (ox->c1))) { return 0 ;} if(bsFindTag (xChrom, _Non_graphic)) { ox->flag |= ~FLAG_PAIR_CHROMS ;} bsDestroy (xChrom) ; if (!(yChrom = bsCreate (ox->c2))) { return 0 ;} if(bsFindTag (yChrom, _Non_graphic)) {ox->flag |= ~FLAG_PAIR_CHROMS ;} bsDestroy (yChrom) ; /* Get band data on the first chromosome, if there is any */ i = 0 ; bands = arrayCreate (8, BSunit) ; ox->c2segs = arrayCreate (128, CHROMS) ; ox->c1segs = arrayCreate (128, CHROMS) ; ox->points = arrayCreate (8, HOMOL) ; if ((xChrom = bsCreate (ox->c1))) {if (bsFindTag (xChrom, _Chrom_Band) && bsFlatten (xChrom, 1 , bands)) {for (i = 0 ; i < arrayMax (bands) ; i++ ) {band = array (bands, i, BSunit).k ; xBand = bsCreate (band) ; if (bsFindTag (xBand, _Map) && bsGetKey (xBand, _bsRight, &key)) if (bsPushObj (xBand)) if (bsGetData (xBand, _Left, _Float, &x1) && bsGetData (xBand, _Right, _Float, &x2)) {c1seg = arrayp (ox->c1segs, i, CHROMS) ; c1seg->key = band ; c1seg->x = 0.5*(x1 + x2) ; c1seg->dx = x2 - x1 ; c1seg->flag = 0 ; ox->flag |= FLAG_XBANDS ;} bsDestroy (xBand) ; if (x1 < xmin) xmin = x1 ; if (x2 > xmax) xmax = x2 ; } for (i = 0 ; i < arrayMax (bands) ; i++ ) {band = array (bands, i, BSunit).k ; xBand = bsCreate (band) ; c1seg = arrayp (ox->c1segs, i, CHROMS) ; if (bsFindTag (xBand, _Centromere)) {c1seg->flag |= FLAG_CENTROMERE ; ox->flag ^= FLAG_XCEN ;} if (bsFindTag (xBand, _Dark)) c1seg->flag |= FLAG_DARK_BAND ; if (bsFindTag (xBand, _NOR)) c1seg->flag |= FLAG_NOR ; if (bsFindTag (xBand, _Colour) && bsGetKey (xBand, _bsRight, &col)) c1seg->flag |= ((col - _WHITE) & 15 ) << 28 ; if (bsFindTag (xBand, _Symbol)) {bsGetData (xBand, _bsRight, _Text, &sym) ; c1seg->sym = sym ; c1seg->flag |= FLAG_SYM ;} bsDestroy (xBand) ; } ox->c1min = xmin ; ox->c1max = xmax ; bsDestroy (xChrom) ; } } /* Get band data on the second chromosome, if there is any */ i = 0 ; if ((yChrom = bsCreate (ox->c2))) {if (bsFindTag (yChrom, _Chrom_Band) && bsFlatten (yChrom, 1 , bands)) {for (i = 0 ; i < arrayMax (bands) ; i++ ) {band = array (bands, i, BSunit).k ; yBand = bsCreate (band) ; if (bsFindTag (yBand, _Map) && bsGetKey (yBand, _bsRight, &key)) if (bsPushObj (yBand)) if (bsGetData (yBand, _Left, _Float, &x1) && bsGetData (yBand, _Right, _Float, &x2)) {c2seg = arrayp (ox->c2segs, i, CHROMS) ; c2seg->key = band ; c2seg->x = 0.5*(x1+ x2) ; c2seg->dx = x2 - x1 ; c2seg->flag = 0 ; ox->flag |= FLAG_YBANDS ;} bsDestroy (yBand) ; if (x1 < ymin) ymin = x1 ; if (x2 > ymax) ymax = x2 ; } for (i = 0 ; i < arrayMax (bands) ; i++ ) {band = array (bands, i, BSunit).k ; yBand = bsCreate (band) ; c2seg = arrayp (ox->c2segs, i, CHROMS) ; if (bsFindTag (yBand, _Centromere)) {c2seg->flag |= FLAG_CENTROMERE ; ox->flag ^= FLAG_YCEN ;} if (bsFindTag (yBand, _Dark)) c2seg->flag |= FLAG_DARK_BAND ; if (bsFindTag (yBand, _NOR)) c2seg->flag |= FLAG_NOR ; if (bsFindTag (yBand, _Colour) && bsGetKey (yBand, _bsRight, &col)) c2seg->flag |= ((col - _WHITE) & 15 ) << 28; if (bsFindTag (yBand, _Symbol)) {bsGetData (yBand, _bsRight, _Text, &sym) ; c2seg->sym = sym ; c2seg->flag |= FLAG_SYM ;} bsDestroy (yBand) ; } ox->c2min = ymin ; ox->c2max = ymax ; bsDestroy (yChrom) ; } } /* Get homology data, Oxford Grid data plus positions on the two chromosomes */ i = 0 ; h = 0 ; box = ox->gridBox ; for (i = 0 ; i < arrayMax (ox->segs) ; i++ ) {tseg = arrayp (ox->segs, i, SEG) ; if (tseg->box == box) {seg = arrayp (ox->points, h, HOMOL) ; seg->hom = tseg->key ; seg->key1 = tseg->gene1 ; seg->key2 = tseg->gene2 ; seg->map1 = tseg->map1 ; seg->map2 = tseg->map2 ; seg->flag = 0 ; if (tseg->flag & FLAG_HIDE) seg->flag |= FLAG_HOMHIDE ; seg->x1 = 0 ; seg->dx1 = 0 ; seg->x2 = 0 ; seg->dx2 = 0 ; if ((loc1 = bsCreate (seg->key1))) {if (bsGetKey (loc1, _Map, &map1)) do {mark1 = bsMark (loc1, mark1) ; if (chkSpecies (map1, seg->map1)) {if (bsPushObj (loc1) &&bsGetData (loc1, _Position, _Float, &f1)) {seg->x1 = f1 ; seg->flag |= FLAG_XPOS ; if (bsPushObj (loc1) && bsGetData (loc1, _Error, _Float, &f2)) seg->dx1 = f2 ; else seg->dx1 = 0 ; if ((seg->x1-seg->dx1) < min1) min1 = (seg->x1-seg->dx1) ; if ((seg->x1+seg->dx1) > max1) max1 = (seg->x1+seg->dx1) ; } } }while (bsGoto (loc1, mark1), bsGetKey (loc1, _bsDown, &map1)) ; bsDestroy (loc1) ; } if ((loc2 = bsCreate (seg->key2))) {if (bsGetKey (loc2, _Map, &map2)) do {mark2 = bsMark (loc2, mark2) ; if (chkSpecies (map2, seg->map2)) {if (bsPushObj (loc2) &&bsGetData (loc2, _Position, _Float, &f3)) {seg->x2 = f3 ; seg->flag |= FLAG_YPOS ; if (bsPushObj (loc2) && bsGetData (loc2, _Error, _Float, &f4)) seg->dx2 = f4 ; else seg->dx2 = 0 ; if ((seg->x2-seg->dx2) < min2) min2 = (seg->x2-seg->dx2) ; if ((seg->x2+seg->dx2) > max2) max2 = (seg->x2+seg->dx2) ; } } }while (bsGoto (loc2, mark2), bsGetKey (loc2, _bsDown, &map2)) ; bsDestroy (loc2) ; } if (seg->flag & FLAG_XPOS && seg->flag & FLAG_YPOS) h++ ; } } if (!(ox->flag & FLAG_XBANDS && ox->flag & FLAG_YBANDS)) {ox->c1min = min1-5 ; ox->c1max = max1+5 ; ox->c2min = min2-5 ; ox->c2max = max2+5 ; } arrayDestroy (bands) ; return h ; } /***************************************/ static void pairMapDraw (void) { int box, i, xmax, ymax ; float xl, yl, xlen = 0, ylen = 0 ; CHROMS *c1seg, *c2seg ; OXGET ("pairMapDraw") ; /* Draw all the nice buttons, some toggle, some don't */ graphClear () ; if (ox->flag & FLAG_XBANDS && ox->flag & FLAG_YBANDS) {if (ox->flag & FLAG_PAIR_CHROMS) {if (graphButton ("Hide Chromosomes", toggleChroms, 2, 3) != CHROM_BOX) messcrash ("box screwup at %d in pairMapDraw", CHROM_BOX) ;} else {if (graphButton ("Draw Chromosomes", toggleChroms, 2, 3) != CHROM_BOX) messcrash ("box screwup at %d in pairMapDraw", CHROM_BOX) ;} } else {if (graphButton ("Draw Chromosomes", noChroms, 2, 3) != CHROM_BOX) messcrash ("box screwup at %d in pairMapDraw", CHROM_BOX) ;} if (ox->flag & FLAG_BARS) {if (graphButton ("Hide Error Bars", toggleBars, 20, 3) != BARS_BOX) messcrash ("box screwup at %d in pairMapDraw", BARS_BOX) ;} else {if (graphButton ("Draw Error Bars", toggleBars, 20, 3) != BARS_BOX) messcrash ("box screwup at %d in pairMapDraw", BARS_BOX) ;} if (graphButton ("Flip", pairMapFlip, 37, 3) != FLIP_BOX) messcrash ("box screwup at %d in pairMapDraw", FLIP_BOX) ; if (graphButton ("Highlight...", pairClear, 43, 3) != HIDE_BOX) messcrash ("box screwup at %d in pairMapDraw", HIDE_BOX) ; graphBoxMenu (HIDE_BOX, HighlightMenu) ; if (ox->flag & FLAG_SHADE) {if (graphButton (" Shade ", toggleShade, 57, 3) != SHADE_BOX) messcrash ("box screwup at %d in pairMapDraw", SHADE_BOX) ;} else {if (graphButton ("Unshade", toggleShade, 57, 3) != SHADE_BOX) messcrash ("box screwup at %d in pairMapDraw", SHADE_BOX) ;} graphText ("Find homology :", 2, 5) ; *ox->pairhom = 0 ; if (graphCompScrollEntry (pairhomolCompletion, ox->pairhom, 20, 20, 18, 5, pairFindHom) != FINDHOM_BOX) messcrash ("box screwup at %d in pairMapDraw", FINDHOM_BOX) ; graphEntryDisable () ; graphText ("Find locus :", 43, 5) ; *ox->findloc = 0 ; if (graphCompScrollEntry (pairlocusCompletion, ox->pairloc, 20, 20, 56, 5, pairFindLoc) != FINDLOC_BOX) messcrash ("box screwup at %d in pairMapDraw", FINDLOC_BOX) ; graphEntryDisable () ; if (graphButton ("Zoom in", pairZoomIn, 66, 3) != ZOOM_IN) messcrash ("box screwup at %d in pairMapDraw", ZOOM_IN) ; if (graphButton ("Zoom out", pairZoomOut, 75, 3) != ZOOM_OUT) messcrash ("box screwup at %d in pairMapDraw", ZOOM_OUT) ; /* Draw the header box to name a selected homology on screen */ ox->messageBox = MESS_BOX ; *ox->messageText = 0 ; ox->messageBox = graphBoxStart () ; graphTextPtr (ox->messageText, 2, 7, 80) ; graphBoxEnd () ; graphBoxDraw (ox->messageBox, BLACK, LIGHTBLUE) ; /* Now draw the titles */ xOff = 0 ; yOff = 0 ; graphText (messprintf ("PairMap for map %s and map %s", name (ox->c1), name (ox->c2)), 2, 1); graphLine (0, 9, 100, 9) ; xOff += 2 + strlen (name (ox->c2)) ; yOff += 10 ; /* If we have bands for both chromsomes we shall draw them, otherwise scales */ if (ox->flag & FLAG_XBANDS && ox->flag & FLAG_YBANDS) {for (i = 0 ; i < arrayMax (ox->c2segs) ; i++) {c2seg = arrayp (ox->c2segs, i, CHROMS) ; xl = strlen (name (c2seg->key)) ; if (xl > xlen) xlen = xl ; } xOff += 8 + xlen ; for (i = 0 ; i < arrayMax (ox->c1segs) ; i++) {c1seg = arrayp (ox->c1segs, i, CHROMS) ; yl = strlen (name (c1seg->key)) ; if (yl > ylen) ylen = yl ; } ylen *= 0.65 ; yOff += 5 + ylen ; } else {xOff += 10 ; yOff += 5 ; } xmax = arrayMax (ox->c1segs) ; ymax = arrayMax (ox->c2segs) ; box = MIN_BOX ; if (box != graphBoxStart ()) messcrash ("minLiveBox wrong in pairMapDraw () box %d", box) ; graphTextFormat (BOLD) ; graphText (name (ox->c1), xOff + (ox->pairwide)/2, 10) ; graphBoxEnd () ; graphBoxDraw (box, BLACK, WHITE) ; box++ ; if (box != graphBoxStart ()) messcrash ("minLiveBox wrong in pairMapDraw () box %d", box) ; graphTextFormat (BOLD) ; graphText (name (ox->c2), 2, yOff + (ox->pairhigh)/2) ; graphBoxEnd () ; graphBoxDraw (box, BLACK, WHITE) ; graphTextFormat(PLAIN_FORMAT); if (ox->flag & FLAG_XBANDS && ox->flag & FLAG_YBANDS) {if (ox->flag & FLAG_PAIR_CHROMS) {ox->pair_labels = 2 + xmax + ymax ; drawyChromosome (ox, xlen) ; drawxChromosome (ox, ylen) ; } else {ox->pair_labels = 2 ; drawyScale () ; drawxScale () ; } } else {ox->pair_labels = 2 ; drawyScale () ; drawxScale () ; } if (!(ox->flag & FLAG_SHADE)) drawShade (ox) ; /* And draw the box */ graphLine (xOff, yOff, xOff+ox->pairwide, yOff) ; graphLine (xOff+ox->pairwide, yOff, xOff+ox->pairwide, yOff+ox->pairhigh) ; graphLine (xOff+ox->pairwide, yOff+ox->pairhigh, xOff, yOff+ox->pairhigh) ; graphLine (xOff, yOff+ox->pairhigh, xOff, yOff) ; drawSegs (ox) ; ox->pairBox = 0 ; graphRedraw () ; } /*************************************************************/ static void drawyChromosome (OX ox, float xlen) { float y0, dy, y, yend ; int i, box ; CHROMS *c2seg ; BOOL isBands = FALSE ; y0 = -(ox->c2min) ; yend = (ox->c2max - ox->c2min) / ox->pairhigh ; /* Draw the y chromosome alongside the box */ box = 2 + MIN_BOX ; for (i = 0 ; i < arrayMax (ox->c2segs) ; ++i) {c2seg = arrayp (ox->c2segs, i, CHROMS) ; if (class (c2seg->key) == _VChrom_Band) {isBands = TRUE ; y = yOff + ( y0 + c2seg->x) / yend ; dy = ( 0.5 * c2seg->dx) / yend ; if (c2seg->flag & FLAG_CENTROMERE) {graphColor (WHITE) ; graphFillRectangle (xOff-4, y-dy, xOff, y+dy) ; graphColor (BLACK) ; graphLine (xOff-3, y-dy, xOff-1, y+dy) ; graphLine (xOff-1, y-dy, xOff-3, y+dy) ; graphLine (xOff-3, y-dy, xOff-1, y-dy) ; graphLine (xOff-1, y+dy, xOff-3, y+dy) ; if (box != graphBoxStart ()) messcrash ("minLiveBox wrong in pairMapDraw () box %d", box) ; graphTextHeight (0.5) ; graphText (name (c2seg->key), xOff-6-xlen, y-0.25) ; graphBoxEnd () ; graphBoxDraw (box, BLUE, WHITE) ; box++ ; graphTextHeight (1) ; } else {if (c2seg->flag & FLAG_DARK_BAND) graphColor (DARKGRAY) ; else if (c2seg->flag & FLAG_NOR) graphColor (LIGHTGRAY) ; else graphColor (WHITE) ; if (c2seg->flag >> 28) graphColor((c2seg->flag >> 28) + WHITE) ; graphFillRectangle (xOff-4, y-dy, xOff, y+dy) ; graphColor (BLACK) ; graphRectangle (xOff-4, y-dy, xOff, y+dy) ; if (box != graphBoxStart ()) messcrash ("minLiveBox wrong in pairMapDraw () box %d", box) ; graphTextHeight (0.5) ; graphText (name (c2seg->key), xOff-6-xlen, y-0.25) ; graphBoxEnd () ; graphBoxDraw (box, BLUE, WHITE) ; box++ ; graphTextHeight (1) ; } } } } static void drawxChromosome (OX ox, float ylen) { float x0, dx, x, xend ; int i, box ; CHROMS *c1seg ; BOOL isBands = FALSE ; x0 = -(ox->c1min) ; xend = (ox->c1max - ox->c1min) / ox->pairwide ; /* Draw the x chromosome alongside the box */ box = 2 + MIN_BOX + arrayMax (ox->c2segs) ; for (i = 0 ; i < arrayMax (ox->c1segs) ; ++i) {c1seg = arrayp (ox->c1segs, i, CHROMS) ; if (class(c1seg->key) == _VChrom_Band) {isBands = TRUE ; x = xOff + ox->pairwide - ( x0 + c1seg->x) / xend ; /* bacwards ?? */ /* x = xOff + ( x0 + c1seg->x) / xend ; */ dx = ( 0.5 * c1seg->dx) / xend ; if (c1seg->flag & FLAG_CENTROMERE) {graphColor (WHITE) ; graphFillRectangle (x-dx, yOff-2.4, x+dx, yOff) ; graphColor (BLACK) ; graphLine (x-dx, yOff-1.4, x+dx, yOff-1) ; graphLine (x-dx, yOff-1, x+dx, yOff-1.4) ; graphLine (x-dx, yOff-1.4, x-dx, yOff-1) ; graphLine (x+dx, yOff-1, x+dx, yOff-1.4) ; if (box != graphBoxStart ()) messcrash ("minLiveBox wrong in pairMapDraw () box %d", box) ; graphTextHeight (0.5) ; japanese (name (c1seg->key), x-0.2, yOff-3-ylen) ; graphBoxEnd () ; graphBoxDraw (box, BLUE, WHITE) ; box++ ; graphTextHeight (1) ; } else {if (c1seg->flag & FLAG_DARK_BAND) graphColor (DARKGRAY) ; else if (c1seg->flag & FLAG_NOR) graphColor (LIGHTGRAY) ; else graphColor (WHITE) ; if (c1seg->flag >> 28) graphColor ((c1seg->flag >> 28) + WHITE) ; graphFillRectangle (x-dx, yOff-2.4, x+dx, yOff) ; graphColor (BLACK) ; graphRectangle (x-dx, yOff-2.4, x+dx, yOff) ; if (box != graphBoxStart ()) messcrash ("minLiveBox wrong in pairMapDraw () box %d", box) ; graphTextHeight (0.5) ; japanese (name (c1seg->key), x-0.2, yOff-3-ylen) ; graphBoxEnd () ; graphBoxDraw (box, BLUE, WHITE) ; box++ ; graphTextHeight (1) ; } } } } static void drawyScale (void) { int i, j, k ; float unit , y0 ; OXGET ("drawyScale") ; /* If no banding data or if the chromosomes are hidden, draw a scale instead */ graphTextHeight (0.5) ; y0 = yOff + ox->pairhigh * (1-(ox->c2max / (ox->c2max-ox->c2min))) ; unit = ox->pairhigh / (ox->c2max - ox->c2min) ; for (i = 0 ; i < (ox->c2max + 1) ; i++) graphLine (xOff-3, y0+i*unit, xOff-3.9, y0+i*unit) ; for (k = 0 ; k < (ox->c2max + 1) ; k+=10) {graphLine (xOff-3, y0+k*unit, xOff-4.5, y0+k*unit) ; graphText (messprintf ("%3d",k), xOff - 8, y0+k*unit-0.5) ; } for (j = 0 ; j < -(ox->c2min - 1) ; j++) graphLine (xOff-3, y0-j*unit, xOff-3.9, y0-j*unit) ; for (k = 0 ; k < -(ox->c2min - 1) ; k+=10) {graphLine (xOff-3, y0-k*unit, xOff-4.5, y0-k*unit) ; graphText (messprintf ("%3d",-k), xOff - 8, y0-k*unit-0.5) ; } graphLine (xOff-3, y0-(j-1)*unit, xOff-3, y0+(i-1)*unit) ; graphTextHeight (1) ; } static void drawxScale (void) { int i, j, k ; float unit, x0 ; OXGET ("drawxScale") ; /* If no banding data or if the chromosomes are hidden, draw a scale instead */ graphTextHeight (0.5) ; x0 = xOff + ox->pairwide * (ox->c1max / (ox->c1max - ox->c1min)) ; unit = ox->pairwide / (ox->c1max - ox->c1min) ; for (i = 0 ; i < (ox->c1max + 1) ; i++) graphLine (x0 - i*unit, yOff - 1, x0 - i*unit, yOff - 1.6) ; for (k = 0 ; k < (ox->c1max + 1) ; k += 10) {graphLine (x0 - k*unit, yOff - 1, x0 - k*unit, yOff - 2) ; graphText (messprintf ("%3d", k), x0 - k*unit - 2, yOff - 3) ; } for (j = 0 ; j < -(ox->c1min - 1) ; j++) graphLine (x0 + j*unit, yOff - 1, x0 + j*unit, yOff - 1.6) ; for (k = 0 ; k < -(ox->c1min - 1) ; k += 10) {graphLine (x0 + k*unit, yOff - 1, x0 + k*unit, yOff - 2) ; graphText (messprintf ("%3d", -k), x0 + k*unit - 2, yOff - 3) ; } graphLine (x0 - (i - 1)*unit, yOff - 1, x0 + (j - 1)*unit, yOff - 1) ; graphTextHeight (1) ; } static void drawShade (OX ox) { int i, j ; float x0, dx, x, xend ; float y0, dy, y, yend ; CHROMS *c1seg, *c2seg ; BOOL isyBands = FALSE ; BOOL isxBands = FALSE ; x0 = -(ox->c1min) ; xend = (ox->c1max - ox->c1min) / ox->pairwide ; y0 = -(ox->c2min) ; yend = (ox->c2max - ox->c2min) / ox->pairhigh ; for (i = 0 ; i < arrayMax (ox->c2segs) ; ++i) {c2seg = arrayp (ox->c2segs, i, CHROMS) ; if (class (c2seg->key) == _VChrom_Band) {isyBands = TRUE ; y = yOff + ( y0 + c2seg->x) / yend ; dy = ( 0.5 * c2seg->dx) / yend ; for (j = 0 ; j < arrayMax (ox->c1segs) ; ++j) {c1seg = arrayp (ox->c1segs, j, CHROMS) ; if (class (c1seg->key) == _VChrom_Band) {isxBands = TRUE ; x = xOff + ox->pairwide - ( x0 + c1seg->x) / xend ; dx = ( 0.5 * c1seg->dx) / xend ; if ((c1seg->flag & FLAG_DARK_BAND) && (c2seg->flag & FLAG_DARK_BAND)) {graphColor (DARKGRAY) ; graphFillRectangle (x-dx,y-dy,x+dx,y+dy) ; graphColor (BLACK) ;} else if (((c1seg->flag & FLAG_DARK_BAND) && !(c2seg->flag & FLAG_DARK_BAND)) || (!(c1seg->flag & FLAG_DARK_BAND) && (c2seg->flag & FLAG_DARK_BAND))) {graphColor (LIGHTGRAY) ; graphFillRectangle (x-dx,y-dy,x+dx,y+dy) ; graphColor (BLACK) ;} } } } } graphLine (xOff, yOff, xOff+ox->pairwide, yOff) ; graphLine (xOff, yOff, xOff, yOff+ox->pairhigh) ; } static void drawSegs (OX ox) { int i, p ; float x, dx, y, dy ; float x0, xend, y0, yend ; HOMOL *seg ; y0 = -(ox->c2min) ; yend = (ox->c2max - ox->c2min) / ox->pairhigh ; x0 = -(ox->c1min) ; xend = (ox->c1max - ox->c1min) / ox->pairwide ; /* Draw the homologies, with error bars and with Homology_group names */ p = MIN_BOX + ox->pair_labels ; for (i = 0 ; i < arrayMax(ox->points) ; i++) {seg = arrayp (ox->points, i, HOMOL) ; if (seg->flag & FLAG_XPOS && seg->flag & FLAG_YPOS) if (!(seg->flag & FLAG_HOMHIDE)) {x = xOff + ox->pairwide - (x0 + seg->x1) / xend ; dx = (seg->dx1) / xend ; y = yOff + (y0 + seg->x2) / yend ; dy = (seg->dx2) / yend ; if (p != graphBoxStart ()) messcrash ("problems with pairMap point %d", p) ; graphRectangle (x-0.4, y-0.4, x+0.4, y+0.4) ; graphBoxEnd () ; if (seg->flag & FLAG_HIGHLIGHT) graphBoxDraw (p, WHITE, MAGENTA) ; else graphBoxDraw (p, WHITE, BLUE) ; seg->pbox = p ; p++ ; if (ox->flag & FLAG_BARS) {graphLine (x, y-dy, x, y+dy) ; graphLine (x-dx, y, x+dx, y) ; graphLine (x-0.25, y-dy, x+0.25, y-dy) ; graphLine (x-0.25, y+dy, x+0.25, y+dy) ; graphLine (x-dx, y-0.25, x-dx, y+0.25) ; graphLine (x+dx, y-0.25, x+dx, y+0.25) ; } } } } extern int ksetClassComplete (char *text, int len, int classe) ; static int pairhomolCompletion (char *cp, int len) { return ksetClassComplete (cp, len, _VHomology_group) ; } static int pairlocusCompletion (char *cp, int len) { return ksetClassComplete (cp, len, _VLocus) ; } static void pairFindHom (char* string) { int i ; KEY key ; HOMOL *seg ; BOOL found = FALSE ; OXGET ("pairFindHom") ; if (!(lexword2key (string, &key, _VHomology_group))) {messout ("Sorry, %s is not a homology name", string) ; return ; } for (i = 0 ; i < arrayMax (ox->points) ; i++) {seg = arrayp (ox->points, i, HOMOL) ; if (chkSpecies (seg->hom, key)) {found = TRUE ; pairMapSelect (ox, seg->pbox) ; } } if (found == FALSE) {messout ("Sorry, this homology is not in this grid") ; return ; } } static void pairFindLoc (char* string) { int i ; KEY key ; HOMOL *seg ; BOOL found = FALSE ; OXGET ("pairFindLoc") ; if (!(lexword2key (string, &key, _VLocus))) {messout ("Sorry, %s is not a locus name", string) ; return ; } for (i = 0 ; i < arrayMax (ox->points) ; i++) {seg = arrayp (ox->points, i, HOMOL) ; if (chkSpecies (seg->key1, key) || chkSpecies (seg->key2, key)) {found = TRUE ; pairMapSelect (ox, seg->pbox) ; } } if (found == FALSE) {messout ("Sorry, this locus is not in this grid") ; return ; } } static void pairZoomOut (void) { OXGET ("pairZoomOut") ; if (ox->pairwide >= 30 && ox->pairhigh >= 20) {ox->pairwide -= 15 ; ox->pairhigh -= 10 ; pairMapDraw () ; } } static void pairZoomIn (void) { OXGET ("pairZoomIn") ; if (ox->pairwide <= 120 && ox->pairhigh <= 80) {ox->pairwide += 15 ; ox->pairhigh += 10 ; pairMapDraw () ; } } static void pairMapPick (int box, double x_unused, double y_unused, int modifier_unused) { int xmax, ymax ; OXGET ("pairMapPick") ; xmax = arrayMax (ox->c1segs) ; ymax = arrayMax (ox->c2segs) ; /* The usual - check if the box number is legal, select it if a single click and follow it if a double */ if (box >= ox->pair_labels + MIN_BOX && box <= (arrayMax (ox->points) + ox->pair_labels + MIN_BOX))/*a seg*/ {if (box == ox->pairBox) pairMapFollow (ox) ; graphActivate (ox->pairGraph) ; pairMapSelect (ox, box) ; } else if (box == MIN_BOX) {if (box == ox->pairBox) display (ox->c1, 0, 0) ; graphActivate (ox->pairGraph) ; pairMapSelect (ox, box) ; } else if (box == MIN_BOX + 1) {if (box == ox->pairBox) display (ox->c2, 0, 0) ; graphActivate (ox->pairGraph) ; pairMapSelect (ox, box) ; } else if (box >= MIN_BOX + 2 && box < MIN_BOX + 2 + ymax) {if (box == ox->pairBox) display (arrayp (ox->c2segs, box - MIN_BOX - 2, CHROMS)->key, 0, 0) ; graphActivate (ox->pairGraph) ; pairMapSelect (ox, box) ; } else if (box >= MIN_BOX + 2 + ymax && box < ox->pair_labels + MIN_BOX) {if (box == ox->pairBox) display (arrayp (ox->c1segs, box-MIN_BOX-2-ymax, CHROMS)->key, 0, 0) ; graphActivate (ox->pairGraph) ; pairMapSelect (ox, box) ; } else if (box == FINDHOM_BOX) graphCompScrollEntry (0, ox->pairhom, 0, 0, 0, 0, 0) ; else if (box == FINDLOC_BOX) graphCompScrollEntry (0, ox->pairloc, 0, 0, 0, 0, 0) ; } static void pairMapSelect (OX ox, int box) { int i ; KEY hit=0, key1=0, key2=0 ; HOMOL *seg ; BOOL HID = FALSE ; /* The usual - return the old box to normal and colour in the new */ if (ox->pairBox == box) return ; for (i = 0 ; i < arrayMax (ox->points) ; ++i) {seg = arrp (ox->points, i, HOMOL) ; if (seg->pbox == ox->pairBox) if (seg->flag & FLAG_HIGHLIGHT) HID = TRUE ; } if (ox->pairBox) {if (ox->pairBox >= ox->pair_labels + MIN_BOX) {if (HID == TRUE) graphBoxDraw (ox->pairBox, WHITE, MAGENTA) ; else graphBoxDraw (ox->pairBox, WHITE, BLUE) ; } else if (ox->pairBox == MIN_BOX || ox->pairBox == MIN_BOX + 1) graphBoxDraw (ox->pairBox, BLACK, WHITE) ; else if (ox->pairBox >= MIN_BOX + 2 && ox->pairBox < MIN_BOX + ox->pair_labels) graphBoxDraw (ox->pairBox, BLUE, WHITE) ; } ox->pairBox = box ; if (ox->pairBox >= ox->pair_labels + MIN_BOX) graphBoxDraw (ox->pairBox, WHITE, GREEN) ; else if (ox->pairBox == MIN_BOX || ox->pairBox == MIN_BOX + 1) graphBoxDraw (ox->pairBox, WHITE, BLACK) ; else if (ox->pairBox >= MIN_BOX+2 && ox->pairBox < MIN_BOX + ox->pair_labels) graphBoxDraw (ox->pairBox, WHITE, BLUE) ; graphCompScrollEntry (0, ox->pairhom, 0, 0, 0, 0, 0) ; graphEntryDisable () ; graphCompScrollEntry (0, ox->pairloc, 0, 0, 0, 0, 0) ; graphEntryDisable () ; if (ox->messageBox) if (ox->pairBox >= ox->pair_labels + MIN_BOX) {for (i = 0 ; i < arrayMax (ox->points) ; i++) {seg = arrayp (ox->points, i, HOMOL) ; if (seg->pbox == ox->pairBox) {hit = seg->hom ; key1 = seg->key1 ; key2 = seg->key2 ;} } if (hit) { strncpy (ox->messageText, messprintf ("Homology "), 80) ; strcat (ox->messageText, messprintf ("%s ", name (hit))) ; strcat (ox->messageText, messprintf ("between %s and %s", name (key1), name (key2))) ; } } else *ox->messageText = 0 ; graphBoxDraw (ox->messageBox, BLACK, LIGHTBLUE) ; } static void pairMapFollow (OX ox) { int i ; KEY hit = 0 ; HOMOL *seg ; /* Similar to usual - seg->pbox needed to make the keyset option work */ for (i=0 ; i < arrayMax (ox->points) ; i++) {seg = arrayp (ox->points, i, HOMOL) ; if (seg->pbox == ox->pairBox) hit = seg->hom ; } if (hit) display (hit, 0, 0) ; } static void noChroms (void) { OXGET ("noChroms") ; /* Inactivate the Hide chromosomes button if there isn't any band data */ messout ("Sorry, there's no band data") ; return ; } static void toggleChroms (void) { OXGET ("toggleChroms") ; /* Toggle for the Hide chromosomes button */ if (!(ox->flag & FLAG_XBANDS && ox->flag & FLAG_YBANDS)) {messout ("Sorry, there's no band data") ; return ;} else {ox->flag ^= FLAG_PAIR_CHROMS ; pairMapDraw () ;} } static void toggleBars (void) { OXGET("toggleBars") ; /* Toggle for the Hide error bars button */ ox->flag ^= FLAG_BARS ; pairMapDraw () ; } static void toggleShade (void) { OXGET ("toggleShade") ; /* Toggle for the Shade button */ if (!(ox->flag & FLAG_XBANDS && ox->flag & FLAG_YBANDS)) {messout ("Sorry, there's no band data") ; return ;} else {ox->flag ^= FLAG_SHADE ; pairMapDraw () ;} } #ifdef JUNK static void pairMapShowAll (void) { int i ; HOMOL *seg ; OXGET ("pairMapShowAll") ; /* Show all homologies, whether in or out of the keyset */ seg = arrayp (ox->points,0,HOMOL) ; i = arrayMax (ox->points) ; while (i--) {seg->flag &= ~FLAG_HOMHIDE ; /* bitwise NOT */ seg++ ; } pairMapDraw () ; } #endif static void pairMapFlip (void) { int i ; float dx, x, min, max ; KEY chrom, key, spec ; HOMOL *seg ; Array temp ; OXGET ("pairMapFlip") ; ox->flag ^= FLAG_PAIR_FLIP ; /* Swap all x and y data so that the box will flip over when redrawn */ spec = ox->s3 ; ox->s3 = ox->s4 ; ox->s4 = spec ; chrom = ox->c1 ; ox->c1 = ox->c2 ; ox->c2 = chrom ; temp = arrayCopy (ox->c1segs) ; ox->c1segs = arrayCopy (ox->c2segs) ; ox->c2segs = arrayCopy (temp) ; arrayDestroy (temp) ; min = ox->c1min ; ox->c1min = ox->c2min ; ox->c2min = min ; max = ox->c1max ; ox->c1max = ox->c2max ; ox->c2max = max ; /* if (!(ox->flag & FLAG_YCEN)) cen = TRUE ; else cen = FALSE ; if (!(ox->flag & FLAG_XCEN)) ox->flag |= FLAG_YCEN ; else ox->flag |= ~FLAG_YCEN ; if (cen) ox->flag |= FLAG_XCEN ; else ox->flag |= ~FLAG_XCEN ; */ for (i = 0 ; i < arrayMax (ox->points) ; i++) {seg = arrayp (ox->points, i, HOMOL) ; key = seg->key1 ; seg->key1 = seg->key2 ; seg->key2 = key ; x = seg->x1 ; seg->x1 = seg->x2 ; seg->x2 = x ; dx = seg->dx1 ; seg->dx1 = seg->dx2 ; seg->dx2 = dx ;} pairMapDraw () ; } static void pairClear (void) { int i ; HOMOL *seg ; OXGET ("pairClear") ; seg = arrayp (ox->points, 0, HOMOL) ; i = arrayMax (ox->points) ; while(i--) {seg->flag &= ~FLAG_HOMHIDE ; /* bitwise NOT */ seg->flag &= ~FLAG_HIGHLIGHT ; seg++ ; } pairMapDraw () ; } static void pairLightAll (void) { int i ; OXGET ("pairLightAll") ; for (i = 0 ; i < arrayMax (ox->points) ; ++i) arrp (ox->points, i, HOMOL)->flag |= FLAG_HIGHLIGHT ; ox->pairBox = 0 ; pairMapDraw () ; } static void pairLight (void) { int i, j ; HOMOL *seg ; KeySetDisp dummy ; KEYSET keySet = 0 ; OXGET ("pairLight") ; if (!keySetActive (&keySet, &dummy)) { messout ("First select a keySet window, thank you.") ; return ; } for (i = 0 ; i < arrayMax (ox->points) ; ++i) { seg = arrp (ox->points, i, HOMOL) ; if (keySetFind (keySet, seg->hom, &j) || keySetFind (keySet, seg->key1, &j) || keySetFind (keySet, seg->key2, &j)) seg->flag |= FLAG_HIGHLIGHT ; } pairMapDraw () ; } static void pairUnLight (void) { int i, j ; HOMOL *seg ; KeySetDisp dummy ; KEYSET keySet = 0 ; OXGET ("pairUnLight") ; if (!keySetActive (&keySet, &dummy)) { messout ("First select a keySet window, thank you.") ; return ; } for (i = 0 ; i < arrayMax (ox->points) ; ++i) { seg = arrp (ox->points, i, HOMOL) ; if (keySetFind (keySet, seg->hom, &j) || keySetFind (keySet, seg->key1, &j) || keySetFind (keySet, seg->key2, &j)) seg->flag &= ~FLAG_HIGHLIGHT ; } pairMapDraw () ; } static void pairLightHom (void) { int i ; HOMOL *seg ; OXGET ("pairLightHom") ; if (!(ox->pairBox)) {messout ("You have not selected a homology") ; return ;} for (i = 0 ; i < arrayMax (ox->points) ; i++) {seg = arrayp (ox->points, i, HOMOL) ; if (seg->pbox == ox->pairBox) seg->flag |= FLAG_HIGHLIGHT ; } pairMapDraw () ; } static void pairUnLightHom (void) { int i ; HOMOL *seg ; OXGET ("pairUnLightHom") ; if (!(ox->pairBox)) {messout ("You have not selected a homology") ; return ;} for (i = 0 ; i < arrayMax (ox->points) ; i++) {seg = arrayp (ox->points, i, HOMOL) ; if (seg->pbox == ox->pairBox) seg->flag &= ~FLAG_HIGHLIGHT ; } pairMapDraw () ; } static void pairHide (void) { int i, j ; HOMOL *seg ; KeySetDisp dummy ; KEYSET keySet = 0 ; OXGET ("pairHide") ; if (!keySetActive (&keySet, &dummy)) {messout ("First select a keySet window, thank you.") ; return ; } seg = arrp (ox->points, 0, HOMOL) ; i = arrayMax (ox->points) ; while(i--) {seg->flag &= ~FLAG_HOMHIDE ; if (!keySetFind (keySet, seg->hom, &j) && !keySetFind (keySet, seg->key1, &j) && !keySetFind (keySet, seg->key2, &j)) seg->flag |= FLAG_HOMHIDE ; seg++ ; } pairMapDraw () ; } static void pairHideLight (void) { int i ; HOMOL *seg ; OXGET ("pairHideLight") ; for (i = 0 ; i < arrayMax (ox->points) ; ++i) { seg = arrp (ox->points, i, HOMOL) ; if (seg->flag & FLAG_HIGHLIGHT) seg->flag |= FLAG_HOMHIDE ; } pairMapDraw () ; } static void pairUnHide (void) { int i ; HOMOL *seg ; OXGET ("pairUnHide") ; for (i = 0 ; i < arrayMax (ox->points) ; ++i) { seg = arrp (ox->points, i, HOMOL) ; seg->flag &= ~FLAG_HOMHIDE ; } pairMapDraw () ; } static void pairExport (void) { int i, j, k = 0 ; HOMOL *seg ; static KEYSET kset = 0 ; BOOL found = FALSE ; OXGET ("pairExport") ; kset = keySetReCreate (kset) ; for (i = 0 ; i < arrayMax (ox->points) ; ++i) { found = FALSE ; seg = arrp (ox->points, i, HOMOL) ; if (seg->flag & FLAG_HIGHLIGHT) {for (j = 0 ; j < keySetMax (kset) ; j++) {if (chkSpecies (seg->hom, keySet (kset, j))) found = TRUE ;} if (found == FALSE) keySet (kset, k++) = seg->hom ; } } keySetSort (kset) ; keySetCompress (kset) ; keySetNewDisplay (kset, "Ox") ; } /************** end of file ****************/