/* File: gmapmarkercol.c * Author: Simon Kelley (srk@sanger.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1991 * ------------------------------------------------------------------- * 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 genome database package, written by * Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * Description: marker display columns for the genetic map * Exported functions: * gMapMainMarkersColumn * gMapMiniChromBandsColumn * HISTORY: * Last edited: Mar 5 01:46 1999 (rd) *------------------------------------------------------------------- */ /* $Id: gmapmarkercol.c,v 1.13 1999/09/01 10:54:31 fw Exp $ */ /* NB uses GMAPSEG format, and gMapOrder */ #include "gmap.h" static void *gMapMarkerConvert (MAPCONTROL map, void *params) { KEY chrom = map->key; KEY locus; OBJ Chrom, Locus; Array segs, loci; GMAPSEG *seg; float x, dx; int i, flags; segs = arrayHandleCreate (20,GMAPSEG, map->handle) ; /* If we inherit from another map, we look there for markers */ while ((Chrom = bsCreate(chrom))) { if (bsFindTag (Chrom,_Main_Marker)) goto gotit; if (!bsGetKey(Chrom, _From_map, &chrom)) break; /* can't find markers, can't go back */ bsDestroy(Chrom); } bsDestroy(Chrom); return segs; /* failed to open map, return empty array */ gotit: loci = arrayCreate(100, BSunit); if (bsFindTag (Chrom,_Main_Marker) && bsFlatten(Chrom, 2, loci)) for (i = 1; ikey = locus; seg->x = x; seg->dx = dx; seg->flag = flags; bsDestroy (Locus) ; } bsDestroy (Chrom) ; arrayDestroy(loci); arraySort (segs, gMapOrder) ; return (void *)segs ; } /***************************/ /* marker chromosome bands */ /***************************/ static void miniChromBandsDraw (COLINSTANCE instance, float *offset) { MAPCONTROL map = instance->map; float y, dy, x = *offset + 0.5 , l, max = 0 , ylast = - 1000 ; int i ; GMAPSEG* seg ; BOOL isBands = FALSE ; Array segs = instance->private; int firstSeg, lastSeg, countDir; if (map->mag > 0) { firstSeg = 0; lastSeg = arrayMax(segs); countDir = 1; } else { firstSeg = arrayMax(segs)-1 ; lastSeg = -1; countDir = -1; } graphTextHeight (0.75) ; for (i = firstSeg; i != lastSeg; i += countDir) { seg = arrp(segs,i,GMAPSEG) ; if (seg->flag & FLAG_ANY_INTERVAL) { isBands = TRUE ; y = MAP2WHOLE(map, seg->x) ; dy = seg->dx *map->thumb.fac ; if (seg->flag & FLAG_DARK_BAND) graphColor (DARKGRAY) ; else if (seg->flag & FLAG_NOR) graphColor (LIGHTGRAY) ; else graphColor (WHITE) ; if (seg->flag & FLAG_CENTROMERE) { graphFillRectangle (x, y-dy, x + 2., y+dy) ; graphColor (BLACK) ; graphLine (x, y-dy, x + 2., y+dy) ; graphLine (x + 2., y-dy, x, y+dy) ; graphLine (x, y-dy, x + 2., y-dy) ; graphLine (x + 2., y+dy, x, y+dy) ; } else if ((seg->flag & FLAG_Q_TELOMERE || seg->flag & FLAG_P_TELOMERE) && (dy>1.0 || dy<(-1.0))) { /* dy<0 if flipped */ /* P is at the top unless flipped */ BOOL up; if (dy>0) { up = seg->flag & FLAG_P_TELOMERE; } else { up = seg->flag & FLAG_Q_TELOMERE; dy = -dy; } if (up) { graphFillRectangle(x, y+1-dy, x+2, y+dy); graphFillArc(x+1, y+1-dy, 1, 0, 180); graphColor(BLACK); graphArc(x+1, y+1-dy, 1, 0, 180); graphLine(x + 2., y+dy, x, y+dy); graphLine(x, y+dy, x, y+1-dy); graphLine(x+2., y+dy, x+2., y+1-dy); } else /* down */ { graphFillRectangle(x, y-dy, x+2, y+dy-1); graphFillArc(x+1, y+dy-1, 1, 180, 180); graphColor(BLACK); graphArc(x+1, y+dy-1, 1, 180, 180); graphLine(x + 2., y-dy, x, y-dy); graphLine(x, y-dy, x, y+dy-1); graphLine(x+2., y-dy, x+2., y+dy-1); } } else { graphFillRectangle (x, y-dy, x + 2., y+dy) ; graphColor (BLACK) ; graphRectangle (x, y-dy, x + 2., y+dy) ; } if (y > ylast + 1) { graphText (name(seg->key),x+2.5,y-0.25) ; l = .65 * strlen(name(seg->key)) ; if (l > max) max = l ; ylast = y ; } } } graphTextHeight (0) ; if (isBands) *offset += 3.5 + max ; } static BOOL miniChromBandsCreate(COLINSTANCE instance, OBJ init) { instance->draw = miniChromBandsDraw; instance->private = *(instance->proto->convertResults); return TRUE; } struct ProtoStruct gMapMiniChromBandsColumn = { 0, miniChromBandsCreate, 0, "Marker_intervals", 0, FALSE, gMapMarkerConvert, 0, "This column displays intervals as chromosome bands. The whole extent of " "the map is always shown, making it useful for navigation around the map. " "All interval objects two to the right of the tag Main_markers are " "drawn. The style of drawing is affected by the presence of the " "following tags in the interval objects.\n\n" "Dark\nNOR\nCentromere\np_telomere\nq_telomere\n" }; /****************************************************************************/ /* Marker Loci */ /****************************************************************************/ static void mainMarkersDraw(COLINSTANCE instance, float *offset) { MAPCONTROL map = instance->map; float y, xx, max = 0 ; int i, box ; GMAPSEG* seg ; Array segs = instance->private; graphTextHeight (0.75) ; box = graphBoxStart () ; for (i = 0 ; i < arrayMax(segs) ; ++i) { seg = arrp(segs,i,GMAPSEG) ; if (seg->flag & FLAG_ANY_LOCUS) { y = MAP2WHOLE(map, seg->x) ; graphText (name(seg->key), *offset+0.5, y-0.25) ; xx = (isGifDisplay ? 1 : .65) * strlen(name(seg->key)) ; if (xx > max) max = xx ; } } /* draw lines to ensure box is full size */ y = MAP2WHOLE(map,map->min) ; graphLine (*offset, y, *offset + max/2, y) ; y = MAP2WHOLE(map,map->max) ; graphLine (*offset, y, *offset + max/2, y) ; graphBoxEnd() ; array(instance->map->control->boxIndex, box, COLINSTANCE) = instance; graphTextHeight (0) ; *offset += max + 1.0 ; } static void mainMarkerPick(COLINSTANCE instance, int box, double x, double y) { MAPCONTROL map = instance->map ; map->centre = WHOLE2MAP(map, y + MAP2WHOLE(map,map->min)) ; controlDraw() ; } /* mainMarkerPick */ static BOOL mainMarkerCreate(COLINSTANCE instance, OBJ init) { instance->draw = mainMarkersDraw; instance->private = *(instance->proto->convertResults); instance->pick = mainMarkerPick ; return TRUE; } struct ProtoStruct gMapMainMarkersColumn = { 0, mainMarkerCreate, 0, "Marker_points", 0, FALSE, gMapMarkerConvert, 0, "This column displays points. The whole extent of " "the map is always shown, making it useful for navigation around the map. " "All point objects two to the right of the tag Main_markers are " "drawn." };