/* File: gmapsubmapcol.c * Author: Ian Longden (il@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@crbm.cnrs-mop.fr * * Description: Submap display column for the genetic map * Exported functions: * HISTORY: * Last edited: Apr 21 09:45 1999 (fw) *------------------------------------------------------------------- */ /* $Id: gmapsubmapcol.c,v 1.9 2001/06/15 17:48:50 srk Exp $ */ #include "gmap.h" #include "query.h" #include "bump.h" /************************************************************/ #define submapmarkerFormat "kffff" typedef struct { KEY key; float gpos; /* global positon i.e. chrom map coordinates*/ float lpos; /* local position with regards to submap*/ /* to calculate pos use extent + lpos to get overall position in contig */ float newpos; /* global coors after moved by lcoi midpoint*/ float posoncontig; /* global coors with repsect to contig */ } SUBMAPMARKERS; typedef struct { KEY key; int reject; /* True if markers lie outside the tolerance contig (coors from global) */ int rejectbyloci; /* True if markers lie outside the tolerance contig (coors calc from loci) */ float gstart, gend; /* global start/end on chrom map*/ float extentLeft, extentRight; /* extent i.e. size */ float lociLeft,lociRight; /* coors calculated from markers global positions. */ Array submapmarkers; /* contains the above marker information */ KEYSET negMarkers; /* keyset of the markers which are rejected */ KEYSET negMarkersbyLoci; /* as above but for when contigs placed by loci */ KEYSET markers; /* a Keyset of all the markers */ } GMAPSUBMAPSEG; #define submapFormat "kiiffffff" typedef struct { KEY key; int reject; /* True if markers lie outside the tolerance contig (coors from global) */ int rejectbyloci; /* True if markers lie outside the tolerance contig (coors calc from loci) */ float gstart, gend; /* global start/end on chrom map*/ float extentLeft, extentRight; /* extent i.e. size */ float lociLeft,lociRight; /* coors calculated from markers global positions. */ } SUBMAPTEMP; #define LOCI 0 #define INTERVAL 1 #define LINK 2 typedef struct { KEY key; int type; int index,subindex; } BOX2KEY; #define ALL 1 #define REJECTED 2 #define NON_REJECTED 3 typedef struct SubPrivStruct { char *lociQuery, *intQuery; KEYSET lociKeyset, intervalKeyset; int show; /* 1 ALL 2 rejected 3 Non rejected */ int tolerance; BOOL posByLoci; BOOL showAllMarkers; float scale; Array segs; Array box2key; int currmap; } *SUBPRIV; /************************************************************/ int gMapSubMapOrder (void *a, void *b); /* we know ym as this is the top/bot of the screen Therefore only need to calculate xm */ BOOL getCutoffwithBorder(float x1, float y1, float x2, float y2, float ym, float *xm) { float m; float c; m = (y2-y1)/(x2-x1); c = y1-(m*x1); if(m) *xm = (ym - c)/m; else return FALSE; return TRUE; } /* getCutoffwithBorder */ BOOL gMapIsNegMarkers(MAPCONTROL map, KEY key) { GeneticMap look = (GeneticMap)(map->look); /* make sure our map is in charge */ if (map->control->activeInstance && map == map->control->activeInstance->map) { if (look->negativeMarkersValid) if(look->negativeMarkers) if( keySetFind(look->negativeMarkers, key, 0)) return TRUE; } return FALSE; } /* gMapIsNegMarkers */ static BOOL submapSetSelect(COLINSTANCE instance, int box, double x, double y) { MAPCONTROL map = instance->map; COLCONTROL control = map->control; SUBPRIV private = instance->private; BOX2KEY *seg = arrp(private->box2key, box, BOX2KEY); GMAPSUBMAPSEG *seg2; GeneticMap look = (GeneticMap)(map->look); gMapUnselect(map); look->selectKey = seg->key; look->friendsInfoValid = TRUE; look->neighboursInfoValid = TRUE; (void)gMapNeighbours(map, &look->neighbours, seg->key); (void)gMapPositive(map, &look->positive, seg->key); if(seg->type == INTERVAL) { look->negativeMarkersValid = TRUE; (void)gMapNegative(map, &look->negative, seg->key); seg2 = arrp(private->segs, seg->index, GMAPSUBMAPSEG); if(private->posByLoci) look->negativeMarkers = seg2->negMarkersbyLoci; else look->negativeMarkers = seg2->negMarkers; private->currmap = seg->key; } else look->negativeMarkers = 0; control->activeKey = seg->key; if(seg->type == INTERVAL) controlDraw(); return FALSE; } /* submapSetSelect */ static BOOL submapUnSelect(COLINSTANCE instance, int box) { MAPCONTROL map = instance->map; COLCONTROL control = map->control; GeneticMap look = (GeneticMap)(map->look); control->activeKey = 0; *look->messageText = 0; if(look->messageBox) graphBoxDraw(look->messageBox, -1, -1); return FALSE; } /* submapUnSelect */ static BOOL getMarkerLocations(KEY markerkey, KEY subkey, KEY mainkey, float *gpos, float *lpos) { OBJ obj; int i; Array loci; float loc=0.000005,glob=0.000005; obj = bsCreate(markerkey); if(!obj) return FALSE; *lpos = *gpos = -99.0; loci = arrayCreate(200,BSunit); if(bsFindTag(obj,_Map) && bsFlatten(obj, 3, loci)){ if(arr(loci, 1, BSunit).k == str2tag("Position")){ for(i=0; i+2<=arrayMax(loci); i+=3){ if(arr(loci, i, BSunit).k == mainkey) glob = arr(loci, i+2, BSunit).f; else if(arr(loci, i, BSunit).k == subkey) loc = arr(loci, i+2, BSunit).f; } } } if(loc > 0.005 || loc < -0.005) /* becouse we can get small error number from incorrect*/ *lpos = loc; /* reading of number as what is being read may not be a number */ if(glob > 0.005 || glob < -0.005) *gpos = glob; bsDestroy(obj); arrayDestroy(loci); if((*lpos != -99.0 && *gpos != -99.0) && (*lpos != 0.0 && *gpos != 0.0)) return TRUE; else { /* perhaps it's a pac etc so find midpoint */ obj = bsCreate(markerkey); if(!obj) return FALSE; loci = arrayCreate(200,BSunit); if(bsFindTag(obj,_Map) && bsFlatten(obj, 4, loci)){ for(i=0; i+7<=arrayMax(loci); i+=8){ if(arr(loci, i, BSunit).k == mainkey) glob = (arr(loci, i+3, BSunit).f+arr(loci, i+7, BSunit).f)/2.0; else if(arr(loci, i, BSunit).k == subkey) loc = (arr(loci, i+3, BSunit).f+arr(loci, i+7, BSunit).f)/2.0; } } bsDestroy(obj); arrayDestroy(loci); if(loc > 0.005 || loc < -0.005) /* becouse we can get small error number from incorrect*/ *lpos = loc; /* reading of number as what is being read may not be a number */ if(glob > 0.005 || glob < -0.005) *gpos = glob; if((*lpos != -99.0 && *gpos != -99.0) && (*lpos != 0.0 && *gpos != 0.0)) return TRUE; } return FALSE; } /* getMarkerLocations */ static void gMapGetSubMapData(KEY submapkey, MAPCONTROL map, Array segs) { OBJ obj; SUBMAPMARKERS *marker; Array loci; GMAPSUBMAPSEG *seg; int i; KEY locus; float gpos, lpos, extentLeft, extentRight; static BOOL errormess=TRUE; obj = bsCreate(submapkey); if(!obj) return ; extentLeft = extentRight = -10.0; if (!bsGetData(obj, str2tag("Extent"), _Float, &extentLeft) || !bsGetData(obj, _bsRight, _Float, &extentRight)){ if(errormess){ messerror("Map %s is a submap of map %s, but does not have an extent", name(submapkey), name(map->key)); errormess = FALSE; } return; } else { seg = arrayp(segs, arrayMax(segs), GMAPSUBMAPSEG); seg->submapmarkers = 0; seg->key = submapkey; } if(seg->extentLeft <= seg->extentRight) {seg->extentLeft = extentLeft; seg->extentRight = extentRight; } else { seg->extentLeft = extentRight; seg->extentRight = extentLeft; } loci = arrayCreate(200,BSunit); if(bsFindTag(obj,_Contains) && bsFlatten(obj, 2, loci)) /* all the contains bits */ { for(i=1; ikey, &gpos, &lpos)) { if(!seg->submapmarkers) seg->submapmarkers = arrayCreate(10, SUBMAPMARKERS); marker = arrayp(seg->submapmarkers, arrayMax(seg->submapmarkers), SUBMAPMARKERS); marker->key = locus; marker->lpos = lpos; marker->gpos = gpos; } } } /* need to test Map for the correct map. */ if(bsFindTag(obj,str2tag("Map")) && bsFlatten(obj, 5, loci)) { i = 0; while(i+8 < arrayMax(loci)){ if(arr(loci,i,BSunit).k == map->key){ seg->gstart = arr(loci, i+3, BSunit).f; seg->gend = arr(loci, i+8, BSunit).f; break; } i+=10; } } if(seg->gstart > seg->gend) { seg->gstart = arr(loci, i+8, BSunit).f; seg->gend = arr(loci, i+3, BSunit).f; } arrayDestroy(loci); bsDestroy(obj); return ; } /* gMapGetSubMapData */ static void calcRejects(COLINSTANCE instance) { int i,j; GMAPSUBMAPSEG *seg; SUBMAPMARKERS *marker; SUBPRIV private = instance->private; float percentTol = ((float)private->tolerance*0.01); float range; Array segs = private->segs; MAPCONTROL map = instance->map; GeneticMap look= (GeneticMap)(map->look); look->negativeMarkers = 0; for(i = 0; i < arrayMax(segs); i++) { seg = arrayp(segs, i, GMAPSUBMAPSEG); seg->rejectbyloci = seg->reject = FALSE; /* create the keysets for wether the markers lie within the tolerance */ if(seg->negMarkers) keySetDestroy(seg->negMarkers); seg->negMarkers = keySetCreate(); if(seg->negMarkersbyLoci) keySetDestroy(seg->negMarkersbyLoci); seg->negMarkersbyLoci = keySetCreate(); if(seg->markers) keySetDestroy(seg->markers); seg->markers = keySetCreate(); if(seg->key == private->currmap) { if(private->posByLoci) look->negativeMarkers = seg->negMarkersbyLoci; else look->negativeMarkers = seg->negMarkers; } if(seg->submapmarkers) { range = seg->gend - seg->gstart; for(j = 0; j < arrayMax(seg->submapmarkers); j++) { /* check that the marker lies within the tolerance of the contig for the */ /*loci calculated positions */ marker = arrp(seg->submapmarkers,j,SUBMAPMARKERS); keySet(seg->markers, arrayMax(seg->markers)) = marker->key; /* ONLY REJECT THOSE BASED ON THOSE IN QUERY */ if(private->lociKeyset && !keySetFind(private->lociKeyset, marker->key, 0)) continue; if(marker->gpos < seg->lociLeft) { if((marker->gpos + (percentTol * range)) < seg->lociLeft) { seg->rejectbyloci = TRUE; keySet(seg->negMarkersbyLoci, arrayMax(seg->negMarkersbyLoci)) = marker->key; } } else if( marker->gpos > seg->lociRight) { if((marker->gpos - (percentTol * range)) > seg->lociRight) { seg->rejectbyloci = TRUE; keySet(seg->negMarkersbyLoci, arrayMax(seg->negMarkersbyLoci)) = marker->key; } } /* calculate the same for the standard positions */ if(marker->gpos < seg->gstart) { if((marker->gpos + (percentTol * range)) < seg->gstart) { seg->reject = TRUE; keySet(seg->negMarkers, arrayMax(seg->negMarkers)) = marker->key; } } else if( marker->gpos > seg->gend) { if((marker->gpos - (percentTol * range)) > seg->gend) { seg->reject = TRUE; keySet(seg->negMarkers, arrayMax(seg->negMarkers)) = marker->key; } } } keySetSort(seg->negMarkersbyLoci); keySetSort(seg->negMarkers); keySetSort(seg->markers); } } } /* calcRejects */ static void calcNewPos(COLINSTANCE instance) /* The position of the interval is calculated from mean position of its markers. The markers postion (to the interval) is then recalulated. */ { SUBPRIV private = instance->private; double offset, scale=0.0; int i, j, count; GMAPSUBMAPSEG *seg; SUBMAPMARKERS *marker; float range,temp; for(i = 0; i < arrayMax(private->segs); i++) { seg = arrp(private->segs, i, GMAPSUBMAPSEG); if(private->scale!= 0.0) range = seg->extentRight - seg->extentLeft; else range = (seg->gend - seg->gstart); if(range){ if(private->scale!= 0.0){ scale = private->scale; range*=private->scale; } else scale = (seg->gend - seg->gstart) / (seg->extentRight - seg->extentLeft); } else continue; if(seg->submapmarkers) /* POSITION ON ONLY THOSE IN QUERY */ { for(j = 0 , offset = 0, count = 0; j < arrayMax(seg->submapmarkers); j++) { marker = arrayp(seg->submapmarkers, j, SUBMAPMARKERS); if(private->lociKeyset) { if(keySetFind(private->lociKeyset, marker->key, 0)) { offset += (double)marker->gpos; count++; } } else { offset += (double)marker->gpos; count++; } } if(count) { offset = offset / (float)count; seg->lociLeft = offset - (range/2); seg->lociRight = offset + (range/2); } else /* ??? MAYBE THESE SHOULD BE IGNORED ???? */ { seg->lociLeft = seg->gstart; seg->lociRight = seg->gend; } for(j = 0; j < arrayMax(seg->submapmarkers); j++) { marker = arrp(seg->submapmarkers, j, SUBMAPMARKERS); temp = (marker->lpos - seg->extentLeft) * scale; /* if(seg->key == private->currmap) printf("temp = %f,scale = %f,lpos = %f,locileft =%f,lociright =%f\n",temp,scale,marker->lpos,seg->lociLeft,seg->lociRight);*/ marker->newpos = seg->lociLeft + temp; marker->posoncontig = seg->gstart + temp; } } else { seg->lociLeft = seg->gstart; seg->lociRight = seg->gend; } } arraySort(private->segs, gMapSubMapOrder); calcRejects(instance); return; } /* calcNewPos */ int gMapSubMapOrder (void *a, void *b) /* for arraySort() call */ { GMAPSUBMAPSEG *seg1 = (GMAPSUBMAPSEG*)a, *seg2 = (GMAPSUBMAPSEG*)b ; float diff; /* diff = seg1->gstart - seg2->gstart ;*/ diff = seg1->lociLeft - seg2->lociLeft; if (diff > 0) return 1 ; else if (diff < 0) return -1 ; else return seg2->key - seg1->key ; /* never give a random result please */ } /* gMapSubMapOrder */ void *submapConvert2(MAPCONTROL map, void *params) { Array segs = 0; return segs; } /* submapConvert2 */ void *submapConvert(MAPCONTROL map) { int i; Array loci; KEY locus; Array segs; char str1[200]; KEY cache; GMAPSUBMAPSEG *seg; Array tempsegs; SUBMAPTEMP *tempseg; getPos(map, 0, 0); /*Are they Cached */ if ((cache = gMapCacheKey(map->key, "subs")) && (tempsegs = arrayGet(cache, SUBMAPTEMP, submapFormat))) { segs = arrayCreate(arrayMax(tempsegs), GMAPSUBMAPSEG); for(i = 0; i < arrayMax(tempsegs); i++) { tempseg = arrp(tempsegs, i, SUBMAPTEMP); seg= arrp(segs, i, GMAPSUBMAPSEG); seg->reject = tempseg->reject ; seg->rejectbyloci = tempseg->rejectbyloci ; seg->gstart = tempseg->gstart ; seg->gend = tempseg->gend ; seg->extentLeft = tempseg->extentLeft ; seg->extentRight = tempseg->extentRight ; seg->lociLeft = tempseg->lociLeft ; seg->key = tempseg->key ; seg->lociRight = tempseg->lociRight ; } arrayDestroy(tempsegs); for(i = 0; i < arrayMax(segs); i++) { sprintf(str1,"subs.marker.%d", i); if ((cache = gMapCacheKey(map->key, str1))) { seg = arrp(segs, i, GMAPSUBMAPSEG); seg->submapmarkers = arrayGet(cache, SUBMAPMARKERS, submapmarkerFormat); } else seg->submapmarkers = 0; } return segs; } /* no segs */ if ((cache = gMapCacheKey(map->key, "subs.empty")) && (tempsegs = arrayGet(cache, SUBMAPTEMP, submapFormat))) return arrayCreate (1, GMAPSUBMAPSEG); segs = arrayCreate (128, GMAPSUBMAPSEG) ; /* is destroyed explicitly by subprivdestroy */ loci = gMapMapObjects(map->key); /* does not seem to get any map objects ???? */ for (i = 0; i reject = seg->reject ; tempseg->rejectbyloci = seg->rejectbyloci ; tempseg->gstart = seg->gstart ; tempseg->gend = seg->gend ; tempseg->extentLeft = seg->extentLeft ; tempseg->extentRight = seg->extentRight ; tempseg->lociLeft = seg->lociLeft ; tempseg->key = seg->key ; tempseg->lociRight = seg->lociRight ; } gMapCacheStore(map->key, "subs", tempsegs, submapFormat); if (arrayMax(tempsegs) == 0) { arrayMax(tempsegs) = 1; gMapCacheStore(map->key, "subs.empty", tempsegs, submapFormat); } arrayDestroy(tempsegs); for(i=0;isubmapmarkers) gMapCacheStore(map->key, str1, seg->submapmarkers, submapmarkerFormat); } return (void *) segs; } /* submapConvert */ static void submapDraw(COLINSTANCE instance, float *offset) { float y1, y2, y3, y4, x, z1, x3 = 0; MAPCONTROL map = instance->map; COLCONTROL control = map->control; SUBPRIV private = instance->private; GeneticMap look= (GeneticMap)(map->look); GMAPSEG *seg2; GMAPSUBMAPSEG *seg; SUBMAPMARKERS *marker; BOX2KEY *box2key; int i, box, j, ix, cmax = 0,x2 = 0,k; BUMP bump; float lx1, ly1, lx2, ly2; *offset +=1; if(private->box2key) arrayDestroy(private->box2key); private->box2key = arrayCreate(10, BOX2KEY); /* a quick dummy run to see the width (x3) */ bump = bumpCreate(24, 0); for(i= 0; i< arrayMax(private->segs); i++) { seg = arrp(private->segs,i,GMAPSUBMAPSEG); if(private->intervalKeyset && !keySetFind(private->intervalKeyset, seg->key, 0)) continue; if(keySetFind(look->hidden, seg->key, 0)) continue; if(private->posByLoci) { if(private->show == REJECTED && !seg->rejectbyloci) continue; else if(private->show == NON_REJECTED && seg->rejectbyloci) continue; y1 = MAP2GRAPH(map, seg->lociLeft); y2 = MAP2GRAPH(map, seg->lociRight); } else { if(private->show == REJECTED && !seg->reject) continue; else if(private->show == NON_REJECTED && seg->reject) continue; y1 = MAP2GRAPH(map, seg->gstart); y2 = MAP2GRAPH(map, seg->gend); } if(y2 < control->topMargin || y1 > control->graphHeight-1) continue; if(y1 < control->topMargin) y1 = control->topMargin; if(y2 > control->graphHeight) y2 = control->graphHeight; z1 =y1; ix = 0; bumpItem(bump, 3, (y2-y1+1)+0.2, &ix, &z1); if(cmax < ix) cmax = ix; } x3 =*offset + (cmax) + 6.0; bumpDestroy(bump); cmax = 0; bump = bumpCreate(24, 0); for(i = 0; i < arrayMax(private->segs); i++) { seg = arrp(private->segs, i, GMAPSUBMAPSEG); if(private->intervalKeyset && !keySetFind(private->intervalKeyset, seg->key, 0)) continue; if(keySetFind(look->hidden, seg->key, 0)) continue; if(private->posByLoci) { if(private->show == REJECTED && !seg->rejectbyloci) continue; else if(private->show == NON_REJECTED && seg->rejectbyloci) continue; y1 = MAP2GRAPH(map, seg->lociLeft); y2 = MAP2GRAPH(map, seg->lociRight); } else { if(private->show == REJECTED && !seg->reject) continue; else if(private->show == NON_REJECTED && seg->reject) continue; y1 = MAP2GRAPH(map, seg->gstart); y2 = MAP2GRAPH(map, seg->gend); } if(y2 < control->topMargin || y1 > control->graphHeight-1) continue; if(y1 < control->topMargin) y1 = control->topMargin; if(y2 > control->graphHeight) y2 = control->graphHeight; z1 =y1; ix = 0; bumpItem(bump,3,(y2-y1+1)+0.2, &ix, &z1); x = *offset + ix; if(cmax < ix) cmax = ix; box = graphBoxStart(); box2key = arrayp(private->box2key, box, BOX2KEY); box2key->key = seg->key; box2key->type = INTERVAL; box2key->index = i; controlRegBox(instance, box, box2key); if(y1 > control->topMargin) graphLine(x+0.25, y1, x+1.75, y1); if(y2 < control->graphHeight) graphLine(x+0.25, y2, x+1.75, y2); graphLine(x+0.25, y1, x+0.25, y2); graphLine(x+1.75, y1, x+1.75, y2); graphBoxEnd(); if(seg->submapmarkers) { for(j = 0; j < arrayMax(seg->submapmarkers); j++) { marker = arrp(seg->submapmarkers, j, SUBMAPMARKERS); /* ONLY DRAW BAND IF MARKER IS IN THE KEYSET */ if(private->lociKeyset && !keySetFind(private->lociKeyset, marker->key, 0)) continue; if(private->posByLoci) y3 = MAP2GRAPH(map, marker->newpos); else y3 = MAP2GRAPH(map, marker->posoncontig); y4 = MAP2GRAPH(map, marker->gpos); if((y3 > control->topMargin) && (y3 < control->graphHeight)){ box = graphBoxStart(); box2key = arrayp(private->box2key, box, BOX2KEY); box2key->key = marker->key; box2key->type = LINK; box2key->index = i; box2key->subindex = j; controlRegBox(instance, box, box2key); graphRectangle(x+1.75, y3-0.25, x+2.0, y3+0.25); graphBoxEnd(); } if(private->showAllMarkers || seg->key == private->currmap){ if(gMapIsNeighbour(map, marker->key)){ lx1 = x+2.0; lx2 = x3; ly1 = y3; ly2 = y4; if((y4 < control->topMargin)){ getCutoffwithBorder(x+2.0, y3, x3, y4,control->topMargin,&lx2); ly2 = control->topMargin; } if(y4 > control->graphHeight){ getCutoffwithBorder(x+2.0, y3, x3, y4,control->graphHeight,&lx2); ly2 = control->graphHeight; } if(y3 < control->topMargin){ getCutoffwithBorder(x+2.0, y3, x3, y4,control->topMargin,&lx1); ly1 = control->topMargin; } if(y3 > control->graphHeight){ getCutoffwithBorder(x+2.0, y3, x3, y4,control->graphHeight,&lx1); ly1 = control->graphHeight; } graphLine(lx1, ly1, lx2, ly2); /* printf("%s (%d) gpos = %f, lpos = %f, newpos =%f, posoncontig = %f\n",name(marker->key),marker->key,marker->gpos,marker->lpos,marker->newpos,marker->posoncontig);*/ } } if((y4 > control->topMargin) && (y4 < control->graphHeight)){ if(gMapIsNeighbour(map, marker->key)){ if(private->showAllMarkers || seg->key == private->currmap){ /* graphLine(x+2.0, y3, x3, y4);*/ box = graphBoxStart(); box2key = arrayp(private->box2key, box, BOX2KEY); box2key->key = marker->key; box2key->type = LINK; box2key->index = i; box2key->subindex = j; controlRegBox(instance, box, box2key); graphRectangle(x3-0.25, y4-0.25, x3+0.25, y4+0.25); graphBoxEnd(); } } } } } } bumpDestroy(bump); *offset = x3 +2.0; /* NEED TO DISPLAY ALL MARKERS IN THE QUERY NOT JUST THOSE WHICH ARE GLOBAL?????? */ bump = bumpCreate(1,0); if(private->showAllMarkers){ for(i = 0; i< arrayMax(look->segs); i++) { seg2 = arrp(look->segs, i, GMAPSEG); /* ONLY DRAW BAND IF MARKER IS IN THE KEYSET */ if(!(seg2->flag & FLAG_ANY_LOCUS)) continue; if(private->lociKeyset && !keySetFind(private->lociKeyset, seg2->key, 0)) continue; y4 = MAP2GRAPH(map,seg2->x); x2 = 0; if((y4 > control->topMargin +0.5 ) && (y4 < control->graphHeight)) { if(bumpText (bump, name(seg2->key), &x2, &y4, 1, TRUE) && y4 < control->graphHeight-0.5) { box = graphBoxStart(); box2key = arrayp(private->box2key, box, BOX2KEY); box2key->key = seg2->key; box2key->type = LOCI; box2key->index = i; box2key->subindex = j; controlRegBox(instance, box, box2key); graphText(name(seg2->key), *offset, y4-0.5); graphBoxEnd(); } } } } else { for(k = 0; k < arrayMax(private->segs); k++) { seg = arrp(private->segs, k, GMAPSUBMAPSEG); if(seg->key == private->currmap){ for(i = 0; i < arrayMax(look->segs); i++) { seg2 = arrp(look->segs, i, GMAPSEG); if(seg->markers && !keySetFind(seg->markers, seg2->key, 0)) continue; y4 = MAP2GRAPH(map,seg2->x); x2 = 0; if((y4 > control->topMargin +0.5 ) && (y4 < control->graphHeight)) { if(bumpText (bump, name(seg2->key), &x2, &y4, 1, TRUE) && y4 < control->graphHeight-0.5) { box = graphBoxStart(); box2key = arrayp(private->box2key, box, BOX2KEY); box2key->key = seg2->key; box2key->type = LOCI; box2key->index = i; box2key->subindex = j; controlRegBox(instance, box, box2key); graphText(name(seg2->key), *offset, y4-0.5); graphBoxEnd(); } } } } } } bumpDestroy(bump); *offset += 12.0; return; } /* submapDraw */ static void submapDoColour(COLINSTANCE instance, int box) { MAPCONTROL map = instance->map; COLCONTROL control = map->control; SUBPRIV private = instance->private; BOX2KEY *seg = arrp(private->box2key, box, BOX2KEY); GeneticMap look= (GeneticMap)(map->look); if((seg->key == look->selectKey) && (instance == control->activeInstance)) { if(seg->type != LINK) graphBoxDraw(box, BLACK, CYAN); else graphBoxDraw(box, BLACK, CYAN); strncpy(look->messageText, name(seg->key), 100); if(look->messageBox) graphBoxDraw(look->messageBox, -1, -1); control->activeBox = box; } else if (gMapIsNegMarkers(map, seg->key)) graphBoxDraw(box, BLACK, RED); else if (gMapIsNeighbour(map, seg->key)) graphBoxDraw(box, BLACK, PALECYAN); else graphBoxDraw(box, BLACK, WHITE); return; } /* submapDoColour */ /* MODELS for COLUMN SUBMAP Submaps Loci_Query UNIQUE Text Interval_Query UNIQUE Text Show UNIQUE Int Tolerance UNIQUE Int Pos_By_Loci Show_All_Markers Scale UNIQUE float */ static void submapSave(COLINSTANCE instance, OBJ init) { SUBPRIV private = instance->private; if(private->lociQuery) bsAddData(init, str2tag("Loci_Query"), _Text, &private->lociQuery); if(private->intQuery) bsAddData(init, str2tag("Interval_Query"), _Text, &private->intQuery); if(private->show) bsAddData(init, str2tag("Show"), _Int, &private->show); if(private->tolerance) bsGetData(init, str2tag("Tolerance"), _Int, &private->tolerance); if(private->posByLoci) bsAddTag(init, str2tag("pos_By_Loci")); if(private->showAllMarkers) bsAddTag(init, str2tag("Show_All_Markers")); if(private->scale) bsGetData(init, str2tag("Scale"), _Float, &private->scale); return; } /* submapSave */ struct configLocals { char lociQuery[280],intQuery[280]; int show; /* 1 ALL 2 rejected 3 Non rejected */ int tolerance; BOOL posByLoci; BOOL showAllMarkers; float scale; }; static BOOL submapConfigure(COLINSTANCE instance) { SUBPRIV private = instance->private; struct configLocals *cf =(struct configLocals *) messalloc(sizeof(struct configLocals)); float y; int tag; if(controlCreateConfig(instance, cf, "Configure submap column",0.8,0.4)) { /*initialise data */ if(private->lociQuery) strcpy(cf->lociQuery, private->lociQuery); if(private->intQuery) strcpy(cf->intQuery, private->intQuery); cf->show = private->show; cf->tolerance = private->tolerance; cf->posByLoci = private->posByLoci; y = 1.0; graphTextEditor("Loci Query:", cf->lociQuery, 280, 4.0, y+=1.2,0); graphTextEditor("Interval Query:", cf->intQuery, 280, 4.0, y+=1.2,0); tag = graphRadioCreate("Show:", &cf->show, 4.0, y+=1.2); graphAddRadioEditor("All",tag, 1, 12.0, y); graphAddRadioEditor("Rejected", tag, 2, 20.0, y); graphAddRadioEditor("Not Rejected", tag, 3, 31.0, y); graphSetRadioEditor(tag, cf->show); graphIntEditor("Tolerance:", &cf->tolerance, 4.0, y+=1.2, 0); graphToggleEditor("Position Intervals by Loci", &cf->posByLoci, 4.0, y+=1.2); graphToggleEditor("Show all Markers", &cf->showAllMarkers, 4.0, y+=1.2); graphFloatEditor("Scale:", &cf->scale, 4.0, y+=1.2, 0); graphRedraw(); } return FALSE; } /* submapConfigure */ static void submapPointFinal(COLINSTANCE instance, void *locals, BOOL ok) { struct configLocals *cf = locals; SUBPRIV private = instance->private; if(ok) { private->show = cf->show; if(private->tolerance != cf->tolerance) { private->tolerance = cf->tolerance; calcRejects(instance); } if(private->intQuery) messfree(private->intQuery); if(private->intervalKeyset) keySetDestroy(private->intervalKeyset); if (strlen(cf->intQuery) != 0) { private->intQuery = handleAlloc(0, instance->handle, 1+strlen(cf->intQuery)); strcpy(private->intQuery, cf->intQuery); private->intervalKeyset = queryKey(instance->map->key, private->intQuery); } else { private->intQuery = 0; private->intervalKeyset = 0; } if(private->lociQuery) messfree(private->lociQuery); if(private->lociKeyset) keySetDestroy(private->lociKeyset); if (strlen(cf->lociQuery) != 0) { private->lociQuery = handleAlloc(0, instance->handle, 1+strlen(cf->lociQuery)); strcpy(private->lociQuery, cf->lociQuery); private->lociKeyset = queryKey(instance->map->key, private->lociQuery); } else { private->lociQuery = 0; private->lociKeyset = 0; } private->posByLoci = cf->posByLoci; private->showAllMarkers = cf->showAllMarkers; private->scale = cf->scale; calcNewPos(instance); } else messfree(cf); return; } /* submapPointFinal */ static void subPrivDestroy (void *p) /* BlockFinalisation function for SUBPRIV-type */ { SUBPRIV private = (SUBPRIV)p; GMAPSUBMAPSEG *seg; int i; for(i = 0; i < arrayMax(private->segs); i++) { seg = arrp(private->segs, i, GMAPSUBMAPSEG); if(seg->submapmarkers) arrayDestroy(seg->submapmarkers); if(seg->negMarkers) keySetDestroy(seg->negMarkers); if(seg->negMarkersbyLoci) keySetDestroy(seg->negMarkersbyLoci); } arrayDestroy(private->segs); return; } /* subPrivDestroy */ static void submapFollowBox(COLINSTANCE instance, int box, double x, double y) { MAPCONTROL map = instance->map; SUBPRIV private = instance->private; BOX2KEY *seg = arrp(private->box2key, box, BOX2KEY); BOOL isMap = (class(seg->key) == _VMap); if(isMap) { displayPreserve(); display(seg->key, map->key, 0); } else display(seg->key, map->key, "TREE"); } static BOOL subMapCreate(COLINSTANCE instance, OBJ init) { char *s1; int i; float f; SUBPRIV private; MAPCONTROL map = instance->map; COLCONTROL control = map->control; private = (SUBPRIV)halloc(sizeof(struct SubPrivStruct), instance->handle); blockSetFinalise (private, subPrivDestroy); instance->draw = submapDraw; instance->setSelectBox = submapSetSelect; instance->unSelectBox = submapUnSelect; instance->save = submapSave; instance->doColour = submapDoColour; instance->followBox = submapFollowBox; instance->configFinal = submapPointFinal; instance->configure = submapConfigure; instance->private = private; private->lociQuery = 0; private->intQuery = 0; private->lociKeyset = private->intervalKeyset = 0; private->show = 1; private->tolerance = 7; private->posByLoci = TRUE; private->showAllMarkers = TRUE; private->scale = 0.0; private->currmap = 0; control->activeInstance = instance; private->segs = submapConvert(map); /*read in query's */ if(init) { if(bsGetData(init, str2tag("Loci_Query"), _Text, &s1)) { private->lociQuery =strnew(s1,instance->handle); private->lociKeyset = queryKey(instance->map->key, private->lociQuery); } if(bsGetData(init, str2tag("Interval_Query"), _Text, &s1)) { private->intQuery = strnew(s1,instance->handle); private->intervalKeyset = queryKey(instance->map->key, private->intQuery); } if(bsGetData(init, str2tag("Show"), _Int, &i)) private->show = i; if(bsGetData(init, str2tag("Tolerance"), _Int, &i)) private->tolerance = i; if(bsFindTag(init, str2tag("pos_By_Loci"))) private->posByLoci = TRUE; else private->posByLoci = FALSE; if(bsFindTag(init, str2tag("Show_All_Markers"))) private->showAllMarkers = TRUE; else private->showAllMarkers = FALSE; if(bsGetData(init, str2tag("Scale"), _Float, &f)) private->scale = f; } calcNewPos(instance); return TRUE; } /* subMapCreate */ struct ProtoStruct gMapSubMapColumn = { 0, subMapCreate, 0, "Submaps", 0, FALSE, submapConvert2, 0, "The submap column can display any maps contained in the displayed " "object with its global loci. " "Global loci are described as having positions in both the submap " "and the object being displayed. " "The map set is then filtered using the Interval Query in the configuration " "to give the set of Map objects to draw. The loci set is filtered " "using the Loci Query to give the loci to use and draw.\n" "Submap intervals are drawn as vertical boxes. From these boxes are " "drawn lines to the loci which are displayed as text\n." "From the configuration you can position the submaps from either " "the position listed in the object or from the mean position of " "the loci (the filtered set) it contains. The tolerance is used to " "calculate wether to reject submaps based on wether all the loci " "lie with the tolerance of the start and end of the submap.\n" "You can choose to select which submap to draw based on this " "rejection by selecting Show to be either All, Rejected or NOT " "Rejected.\n" "Upon clicking a submap the loci corresponding to this item " "are highligted blue if they are within the tolerance of the " "start and end of the submap else they are highlighted red. " "By clicking on a loci the submaps which it is contained in " "are highlighted." }; /************************ eof *******************************/