/* File: cmapdisp.c * Author: Richard Durbin (rd@mrc-lmb.cam.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1992 * ------------------------------------------------------------------- * 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: physical unit display of a chromosome based on gmap * Exported functions: cmapDisplay() * HISTORY: * Last edited: May 6 10:40 2003 (edgrif) * Created: Thu Jan 9 22:54:23 1992 (rd) *------------------------------------------------------------------- */ /* $Id: cmapdisp.c,v 1.34 2003/05/06 13:13:38 edgrif Exp $ */ #include "acedb.h" #include "aceio.h" #include "lex.h" #include "bs.h" #include "a.h" #include "session.h" #include "query.h" #include "grid.h" #include "bump.h" #include "whooks/systags.h" #include "whooks/classes.h" #include "whooks/sysclass.h" #include "whooks/tags.h" #include "display.h" #include "keysetdisp.h" /* the basic units are Mb - left end is 0 - calculate length from contigs */ /*******************************************/ typedef struct { float bin ; float wfac ; /* width factor */ int colour ; int offset ; Array coords, ctgs, seqlen, count ; Graph graph ; char name[32] ; int isLine ; } COLUMN ; typedef struct LOOKSTUFF { int magic ; /* == MAGIC */ KEY key ; /* a chromosome */ int activeBox ; unsigned int flag ; float centre, mag ; float max ; Array segs, /* info on things to be drawn */ boxes, /* a BOX structure of each box */ neighbours ; /* 0-terminated lists of neighbours */ Associator ctgAss ; Array columns ; /* of COLUMN* */ STORE_HANDLE handle ; } *LOOK ; static int MAGIC = 361718 ; typedef struct { KEY key ; float x1, x2 ; float p1, p2 ; int flag ; } SEG ; typedef struct { SEG* seg ; /* pointer OK: segs fixed when drawing */ int neigh ; /* index in look->neighbours */ int col ; } BOX ; /* p1, p2 are used for contigs: cmap <-> pmap for in_situ data for in_situ clones */ /* seg->flag flags */ #define FLAG_HIGHLIGHT 0x0001 #define FLAG_PROCESSED 0x0002 #define FLAG_INSITU 0x0004 #define FLAG_HYB 0x0008 #define FLAG_DELETING 0x0010 #define LOOKGET(name) LOOK look ; \ if (!graphAssFind (&MAGIC, &look)) \ messcrash ("graph not found in %s",name) ; \ if (look->magic != MAGIC) \ messcrash ("%s received a wrong pointer",name) static void cMapDestroy (void) ; static void cMapRecalculate(void) ; static void cMapPick (int box, double x , double y, int modifier_unused) ; static void cMapDragCursor (float *x, float *y, BOOL isDone) ; static void cMapMiddleDown (double x, double y) ; static void cMapDrag (double x, double y) ; static void cMapUp (double x, double y) ; static void cMapDraw (LOOK look, KEY key) ; static BOOL cMapConvert (LOOK look, BOOL isForce) ; static void cMapResize (void) ; static void cMapSelect (LOOK look, int box) ; static void cMapFollow (LOOK look, double x, double y) ; static void cMapHighlight (void) ; static void cMapAdd (void) ; static void cMapSubtract (void) ; static void cMapWhole (void) ; static int cMapOrder(void *a, void *b) ; /* for arraySort() call */ static void cMapFullGenome (void) ; static void cMapPartGenome (void) ; static void cMapChangeSymbolSize (void) ; static void cMapSetSloppyBump (void) ; static void cMapSetMag (void) ; static void cMapColFromKeySet (void) ; static void cMapColFromFile (void) ; static void cMapColEdit (void) ; static void cMapColDraw (LOOK look, COLUMN *col) ; static void cMapHardColumns (void) ; static BOOL isCoverage = FALSE ; static void changeCoverage (void) { isCoverage = 1 - isCoverage ; } static MENUOPT cMapMenu[] = { {graphDestroy, "Quit"}, {help,"Help"}, {graphPrint,"Print"}, {displayPreserve,"Preserve"}, {cMapRecalculate,"Recalculate"}, {cMapHighlight,"Highlight Selected Objects"}, {cMapAdd,"Add Selected Objects"}, {cMapSubtract,"Subtract Selected Objects"}, {cMapFullGenome,"Full Genome Distribution"}, {cMapPartGenome, "II, III, X Distribution"}, {cMapChangeSymbolSize,"Change Symbol Size"}, {cMapSetSloppyBump,"Change bump sloppiness"}, {changeCoverage,"Coverage <-> bump"}, {cMapSetMag,"Set magnification"}, {cMapColFromKeySet, "Create histogram from keyset"}, {cMapColFromFile, "Create histogram from file"}, {cMapColEdit, "Edit histogram columns"}, {cMapHardColumns, "Cheat - direct column set"}, {0, 0} } ; static int cursorBox ; /**********************************/ /* Recalculate all cMaps */ void cMapMakeAll(void) { KEY chromosome = 0, cacheKey ; /* 0 primes lexNext() */ struct LOOKSTUFF lookStuff ; KEY key = 0, _VcMap; lexword2key("cMap", &key, _VMainClasses); _VcMap = KEYKEY(key); if (!key) return ; while (lexNext (_VMap, &chromosome)) { lookStuff.key = chromosome ; lookStuff.segs = 0 ; if (lexReClass (chromosome, &cacheKey, _VcMap)) /* force recalculation */ arrayKill (cacheKey) ; if (cMapConvert (&lookStuff, TRUE)) arrayDestroy (lookStuff.segs) ; if (messIsInterruptCalled ()) break ; } } /**********************/ BOOL cMapDisplay (KEY key, KEY from, BOOL isOldGraph, void *unused) { STORE_HANDLE handle = handleCreate () ; LOOK look=(LOOK)halloc(sizeof(struct LOOKSTUFF), handle) ; /* I hope either key or from is a chromo */ #ifdef ACEDB1 if (key && class(key) != _VChromosome) #else if (key && class(key) != _VMap) #endif { KEY tmp = from ; from = key ; #ifdef ACEDB1 if (class(tmp) == _VChromosome) #else if (class(tmp) == _VMap) #endif key = tmp ; else key = 0 ; } /* if not try to get it using from */ if (!key && from) { OBJ obj = bsCreate(from) ; if (obj) { #ifdef ACEDB1 bsGetKey(obj, _gMap, &key) ; #else bsGetKey(obj, _Map, &key) ; #endif bsDestroy(obj) ; } } if (!key) { if (from) display (from, 0, "TREE") ; goto abort ; } look->handle = handle ; look->activeBox = 0 ; look->magic = MAGIC; look->flag = 0 ; look->max = 15.0 ; /* arbitrary min */ look->key = key ; look->segs = arrayHandleCreate (128, SEG, handle) ; look->boxes = arrayHandleCreate (64, BOX, handle) ; look->neighbours = arrayHandleCreate (32, int, handle) ; look->columns = arrayHandleCreate (8, COLUMN*, handle) ; look->ctgAss = assHandleCreate (handle) ; if (!cMapConvert (look, FALSE) || !look->max) goto abort ; if (isOldGraph) { graphRetitle (name (key)) ; cMapDestroy () ; graphAssRemove (&MAGIC) ; } else { displayCreate("CMAP"); graphRetitle (name(key)) ; graphRegister (RESIZE,(GraphFunc)cMapResize) ; graphRegister (DESTROY, cMapDestroy) ; graphRegister (PICK, (GraphFunc)cMapPick) ; graphRegister (MIDDLE_DOWN, (GraphFunc)cMapMiddleDown) ; graphRegister (MIDDLE_DRAG, (GraphFunc) cMapDrag) ; graphRegister (MIDDLE_UP, (GraphFunc) cMapUp) ; graphMenu (cMapMenu) ; } graphAssociate (&MAGIC, look) ; cMapWhole () ; /* sets ->centre, ->mag and calls Draw() */ return TRUE ; abort : messfree (look) ; return FALSE ; } /*********************/ static void cMapDestroy (void) { LOOKGET("cMapDestroy") ; graphAssRemove (&MAGIC) ; look->magic = 0 ; messfree (look->handle) ; } /**********************************/ static void cMapResize (void) { LOOKGET("cMapResize") ; cMapDraw (look, 0) ; } /***********************************/ static void cMapPick (int box, double x, double y, int modifier_unused) { LOOKGET("cMapPick") ; if (!box) return ; if (box == cursorBox) graphBoxDrag (cursorBox, cMapDragCursor) ; else if (box == look->activeBox) cMapFollow (look, x, y) ; else cMapSelect (look, box) ; } /*********************/ static void cMapClear (void) { KEY curr ; LOOKGET("cMapClear") ; if (look->activeBox && arrp(look->boxes,look->activeBox,BOX)->seg) curr = arrp(look->boxes,look->activeBox,BOX)->seg->key ; else curr = 0 ; cMapConvert (look, FALSE) ; cMapDraw (look, curr) ; } static void cMapRecalculate (void) { KEY cacheKey ; KEY key = 0, _VcMap; LOOKGET("cMapRecalculate") ; lexaddkey("cMap", &key, _VMainClasses); _VcMap = KEYKEY(key); if (!key) return ; if (lexReClass (look->key, &cacheKey, _VcMap)) arrayKill (cacheKey) ; cMapClear () ; } static void cMapSelect (LOOK look, int box) { int i, j ; if (look->activeBox) { graphBoxDraw (look->activeBox, DARKBLUE, LIGHTBLUE) ; if ((i = arrp(look->boxes, box, BOX)->neigh)) while ((j = arr(look->neighbours, i--, int))) graphBoxDraw (j, DARKBLUE, LIGHTBLUE) ; } if (arrp(look->boxes, box, BOX)->seg) { look->activeBox = box ; graphBoxDraw (box, DARKBLUE, RED) ; if ((i = arrp(look->boxes, box, BOX)->neigh)) while ((j = arr(look->neighbours, i--, int))) graphBoxDraw (j, DARKBLUE, LIGHTRED) ; } else look->activeBox = 0 ; } static void cMapFollow (LOOK look, double x, double y) { display (arrp(look->boxes, look->activeBox, BOX)->seg->key, look->key, 0) ; } /**************************************************/ /**************** drawing info ********************/ static int nx, ny ; /* window dimensions */ static float yCentre ; /* ny/2 */ static float yLength ; /* length of picture */ static float topMargin = 2 ; /* space at top for buttons etc */ static float bottomMargin = 1 ; /* space at bottom */ static float xCursor = 5 ; /* midline of mini-chromosome */ static float xScale = 10 ; /* scale bar text LHS */ static float xContig = 14 ; /* midline of contig boxes */ static int xItem = 16 ; /* left edge of item field */ static int xInSitu = 30 ; /* for insitu clones */ static float symbolSize = 1.0 ; /* size of little squares */ static BOOL isFullGenome = FALSE ; #define MAP2GRAPH(look,x) \ (yCentre + look->mag * ((x) - look->centre)) #define GRAPH2MAP(look,x) \ (((x) - yCentre) / look->mag + look->centre) /********* start off with some utility routines ********/ static void getNxNy(void) { graphFitBounds (&nx, &ny) ; yLength = (ny - topMargin - bottomMargin) ; yCentre = topMargin + 0.5*yLength ; } /***************************************/ static void cMapWhole (void) { LOOKGET("cMapWhole") ; getNxNy() ; look->centre = 0.5 * look->max ; look->mag = yLength / look->max ; cMapDraw (look, 0) ; } static void cMapZoomIn (void) { LOOKGET("cMapZoomIn") ; look->mag *= 2 ; cMapDraw (look, 0) ; } static void cMapZoomOut (void) { LOOKGET("cMapZoomOut") ; look->mag /= 2 ; cMapDraw (look, 0) ; } static void cMapChangeSymbolSize (void) { ACEIN size_in; if ((size_in = messPrompt ("Change size of little square symbols to", messprintf ("%f", symbolSize), "fz", 0))) { aceInFloat (size_in, &symbolSize) ; aceInDestroy (size_in); } return; } /* cMapChangeSymbolSize */ static void cMapSetMag (void) { ACEIN mag_in; LOOKGET("cMapZoomIn") ; if ((mag_in = messPrompt ("Give new magnification ", messprintf ("%.2f", look->mag), "fz", 0))) { aceInFloat (mag_in, &look->mag) ; aceInDestroy (mag_in); } cMapDraw (look, 0) ; return; } /* cMapSetMag */ /**************************************************************/ /***************** dragging code - middle button **************/ static double oldy, oldDy, oldx; static BOOL dragFast ; #define DRAGFASTLIMIT xScale static void cMapDrag (double x, double y) { if (dragFast) { graphXorLine (0, oldy - oldDy, DRAGFASTLIMIT, oldy - oldDy) ; graphXorLine (0, oldy + oldDy, DRAGFASTLIMIT, oldy + oldDy) ; } else graphXorLine (DRAGFASTLIMIT, oldy, nx, oldy) ; oldy = y ; if (dragFast) { oldDy *= exp ((x - oldx) / 25.) ; oldx = x ; graphXorLine (0, y - oldDy, DRAGFASTLIMIT, y - oldDy) ; graphXorLine (0, y + oldDy, DRAGFASTLIMIT, y + oldDy) ; } else graphXorLine (DRAGFASTLIMIT, y, nx, y) ; } static void cMapUp (double x, double y) { float x1,x2,y1,y2 ; LOOKGET("cMapUp") ; if (dragFast) { graphBoxDim (cursorBox, &x1, &y1, &x2, &y2) ; look->mag *= (y2 - y1) / (2. * oldDy) ; look->centre = look->max * (y - topMargin) / yLength ; } else look->centre += (y - 0.5 - yCentre) / look->mag ; cMapDraw (look, 0) ; } static void cMapMiddleDown (double x, double y) { float x1,x2,y1,y2 ; LOOKGET("cMapMiddleDown") ; getNxNy () ; graphBoxDim (cursorBox, &x1, &y1, &x2, &y2) ; oldDy = (y2 - y1) / 2. ; dragFast = (x < DRAGFASTLIMIT) ? TRUE : FALSE ; if(dragFast) { graphXorLine (0, y - oldDy, DRAGFASTLIMIT, y - oldDy) ; graphXorLine (0, y + oldDy, DRAGFASTLIMIT, y + oldDy) ; } else graphXorLine (DRAGFASTLIMIT, y, nx, y) ; oldx = x ; oldy = y ; graphRegister (MIDDLE_DRAG, (GraphFunc) cMapDrag) ; graphRegister (MIDDLE_UP, (GraphFunc) cMapUp) ; } static void cMapDragCursor (float *x, float *y, BOOL isDone) { if (isDone) { float x1,y1,x2,y2 ; LOOKGET("cMapDragCursor") ; getNxNy() ; graphBoxDim (cursorBox, &x1, &y1, &x2, &y2) ; look->centre = look->max * ((*y + 0.5*(y2-y1)) - topMargin) / yLength ; cMapDraw (look, 0) ; } else *x = xCursor - 0.5 ; } static float cmapSloppyness = 0 ; static void cMapSetSloppyBump (void) { ACEIN sloppy_in; if ((sloppy_in = messPrompt ("Set sloppiness of bump system - " "0 for nosloppy", messprintf ("%f", cmapSloppyness), "fz", 0))) { aceInFloat (sloppy_in, &cmapSloppyness) ; aceInDestroy (sloppy_in); } return; } /* cMapSetSloppyBump */ /**************************************************/ /**************************************************/ static void drawScale (LOOK look) { float cutoff = 5 / look->mag ; float unit = 0.01 ; float subunit = 0.001 ; float x, y, start, end, oldxScale = xScale ; while (unit < cutoff) { unit *= 2 ; subunit *= 5 ; if (unit >= cutoff) break ; unit *= 2.5 ; if (unit >= cutoff) break ; unit *= 2 ; subunit *= 2 ; } if (isFullGenome) { graphTextHeight (0.8) ; xScale = xContig-0.5 ; } start = GRAPH2MAP(look, topMargin) ; if (start < 0) { start = 0 ; /* graphLine (xScale-1.5, MAP2GRAPH(look,start), xScale-0.5, MAP2GRAPH(look,start)) ; */ } end = GRAPH2MAP(look, ny-bottomMargin) ; if (end > look->max) { end = look->max ; /* graphLine (xScale-1.5, MAP2GRAPH(look,end), xScale-0.5, MAP2GRAPH(look,end)) ; */ } x = unit * (((start > 0) ? 1 : 0) + (int)(start/unit)) ; while (x <= end) { y = MAP2GRAPH(look, x) ; if (isFullGenome) { graphLine (xScale-1.5,y,xScale-0.5,y) ; if (unit >= 1) graphText (messprintf ("%4.0f",x),xScale-4.2,y-.3) ; else if (unit >= .1) graphText (messprintf ("%4.1f",x),xScale-4.2,y-.3) ; else if (unit >= .01) graphText (messprintf ("%4.2f",x),xScale-4.2,y-.3) ; else if (unit >= .001) graphText (messprintf ("%4.3f",x),xScale-4.2,y-.3) ; } else { graphLine (xScale-1.5,y,xScale-0.5,y) ; if(unit >= 1) graphText (messprintf ("%-4.0f",x),xScale,y-.5) ; else if(unit >= .1) graphText (messprintf ("%-4.1f",x),xScale,y-.5) ; else if(unit >= .01) graphText (messprintf ("%-4.2f",x),xScale,y-.5) ; else if(unit >= .001) graphText (messprintf ("%-4.3f",x),xScale,y-.5) ; } x += unit ; } if (!isFullGenome) { x = subunit * (((start>=0)?1:0) + (int)(start/subunit)) ; while (x <= end) { y = MAP2GRAPH(look,x) ; graphLine (xScale-1.0,y,xScale-0.5,y) ; x += subunit ; } } graphLine (xScale-0.5, MAP2GRAPH(look,start), xScale-0.5, MAP2GRAPH(look,end)) ; if (isFullGenome) { xScale = oldxScale ; graphTextHeight (0.0) ; } } static void drawChromosome (LOOK look) { int i ; #define MAP2CHROM(x) \ (topMargin + yLength * (x) / look->max) graphFillRectangle (xCursor - 0.25, topMargin, xCursor + 0.25, ny - bottomMargin) ; cursorBox = graphBoxStart() ; arrayp(look->boxes,cursorBox,BOX)->seg = 0 ; graphRectangle (xCursor - 0.5, MAP2CHROM(GRAPH2MAP(look, topMargin)), xCursor + 0.5, MAP2CHROM(GRAPH2MAP(look, ny - bottomMargin))) ; graphBoxEnd () ; graphBoxDraw (cursorBox,DARKGREEN,GREEN) ; graphColor (DARKGRAY) ; graphLine (xCursor, MAP2CHROM(GRAPH2MAP(look,topMargin)), xScale-0.5, topMargin ) ; graphLine (xCursor, MAP2CHROM(GRAPH2MAP(look,ny - bottomMargin)), xScale-0.5, ny - bottomMargin) ; graphColor (BLACK) ; graphTextHeight (0.75) ; for (i = 0 ; i <= 10 ; ++i) graphText (messprintf ("%3d%%",10*i), 1, topMargin + yLength * i / 10.0 - 0.25) ; graphTextHeight (0) ; } /***********************************************/ static void cMapDrawBoxFinish (int ibox, BOX *box) { graphBoxEnd () ; if (box->seg && box->seg->flag & FLAG_HIGHLIGHT) graphBoxDraw (ibox, BLACK, MAGENTA) ; else graphBoxDraw (ibox, BLACK, box->col) ; } static void cMapAddNeigh (LOOK look, BOX *box, int ibox) { if (!box->neigh) { array(look->neighbours, arrayMax(look->neighbours), int) = 0 ; box->neigh = arrayMax(look->neighbours) ; } array(look->neighbours, arrayMax(look->neighbours), int) = ibox ; } /***********************************************/ static MENUOPT buttonOpts[] = { {cMapWhole, "Whole"}, {cMapZoomIn, "Zoom In"}, {cMapZoomOut, "Zoom Out"}, {cMapClear, "Clear"}, {0, 0}} ; static void cMapDraw (LOOK look, KEY curr) { int iseg, ibox ; SEG *seg ; float screenMin, screenMax ; int x, xs ; float y, y1s, y2s ; BUMP keyBump, inSituBump ; BOX *box ; look->neighbours = arrayReCreate (look->neighbours, 32, int) ; look->boxes = arrayReCreate (look->boxes, 64, BOX) ; look->activeBox = 0 ; if (!isFullGenome) { graphClear () ; graphColor (BLACK) ; getNxNy () ; if (yLength < 6) { messout ("Sorry, this window is too small for a chromo map") ; return ; } drawScale (look) ; drawChromosome (look) ; graphText (name(look->key), 1, 0.7) ; } screenMin = GRAPH2MAP(look, topMargin) ; screenMax = GRAPH2MAP(look, ny - bottomMargin) ; keyBump = bumpCreate ((nx-xItem)/symbolSize, 20) ; bumpSetSloppy(keyBump, cmapSloppyness) ; inSituBump = bumpCreate (nx-xInSitu, 20) ; bumpSetSloppy(inSituBump, cmapSloppyness) ; for (iseg = 0 ; iseg < arrayMax(look->segs) ; ++iseg) { seg = arrp(look->segs, iseg, SEG) ; if (seg->x2 < screenMin || seg->x1 > screenMax) continue ; ibox = graphBoxStart () ; box = arrayp(look->boxes, ibox, BOX) ; box->seg = seg ; box->neigh = 0 ; if (class(seg->key) == _VContig) { graphRectangle (xContig - 0.5, MAP2GRAPH(look, seg->x1), xContig + 0.5, MAP2GRAPH(look, seg->x2)) ; box->col = YELLOW ; cMapDrawBoxFinish (ibox, box) ; } #ifdef ACEDB1 else if (class(seg->key) == _VClone || class(seg->key) == _VGene) #else else if (class(seg->key) == _VClone || class(seg->key) == _VGene || class(seg->key) == _VSequence) #endif { x = 0 ; y = MAP2GRAPH(look,0.5*(seg->x1+seg->x2)) ; if (isFullGenome) { bumpItem (keyBump, 1, 0.04, &x, &y) ; graphLine (xItem + x, y, xItem + x + 1, y) ; } else if (isCoverage) graphFillRectangle (xItem, MAP2GRAPH(look,seg->x1), xItem+symbolSize, MAP2GRAPH(look,seg->x2)) ; else { bumpItem (keyBump, 1, symbolSize * 0.75, &x, &y) ; graphRectangle (xItem + x*symbolSize, y, xItem + (x+0.8)*symbolSize, y + 0.6*symbolSize) ; } box->col = LIGHTBLUE ; cMapDrawBoxFinish (ibox, box) ; if (!isFullGenome && (seg->flag & FLAG_INSITU)) { xs = 0 ; y1s = MAP2GRAPH(look, look->max * seg->p1) ; y2s = MAP2GRAPH(look, look->max * seg->p2) ; bumpItem (inSituBump, 1, y2s - y1s + 1.0, &xs, &y1s) ; xs += xInSitu ; graphLine (xs, y1s, x + xItem + 0.8, y) ; graphLine (xs, y2s, x + xItem + 0.8, y + 0.6) ; ibox = graphBoxStart() ; cMapAddNeigh (look, box, ibox) ; /* to old box */ box = arrayp(look->boxes, ibox, BOX) ; box->seg = seg ; box->neigh = 0 ; cMapAddNeigh (look, box, ibox-1) ; graphRectangle (xs, y1s, xs + 0.5, y2s) ; box->col = LIGHTBLUE ; cMapDrawBoxFinish (ibox, box) ; } } else graphBoxEnd() ; } bumpDestroy (keyBump) ; bumpDestroy (inSituBump) ; /* draw histogram columns */ { int i ; for (i = 0 ; i < arrayMax (look->columns) ; ++i) cMapColDraw (look, arr(look->columns, i, COLUMN*)) ; } if (!isFullGenome) graphButtons (buttonOpts, 5, 0.5, nx) ; /* at end of mapDraw() */ else drawScale (look) ; graphRedraw () ; } /*********************************************************/ /********************* conversion code *******************/ #define PMAP_FAC (1830.0 / 1000000.0) static int cMapOrder(void *a, void *b) /* for arraySort() call */ { SEG *seg1 = (SEG*)a, *seg2 = (SEG*)b ; float diff = seg1->x1 - seg2->x1 ; if (diff > 0) return 1 ; else if (diff < 0) return -1 ; else return 0 ; } /********************/ typedef struct { int pmap ; float vmap ; SEG *seg ; KEY key ; } BLIT ; static int blitOrder(void *a1, void *a2) /* for arraySort() call */ { BLIT *b1 = (BLIT*)a1, *b2 = (BLIT*)a2 ; float diff = b1->vmap - b2->vmap ; if (diff > 0) return 1 ; else if (diff < 0) return -1 ; else return 0 ; } static BOOL cMapConvert (LOOK look, BOOL isForce) { KEY contig, clone, key, _VcMap; OBJ Chrom, Contig, Clone ; int i, min, max, x1, x2 ; float vaxmap, total = 0.0, end ; SEG *seg ; int iseg = 0 ; BLIT *blit, *blitOld ; int iblit = 0 ; static Array blits = 0 ; if (!(Chrom = bsCreate (look->key))) return FALSE ; lexword2key("cMap", &key, _VMainClasses); _VcMap = KEYKEY(key); if (!isForce && lexReClass (look->key, &key, _VcMap)) { arrayDestroy (look->segs) ; if ((look->segs = arrayGet (key, SEG, "kkkkfi"))) { end = 0.0 ; for (i = 0 ; i < arrayMax(look->segs) ; ++i) { seg = arrp(look->segs, i, SEG) ; if (seg->x2 > end) end = seg->x2 ; } look->max = end ; return TRUE ; } } look->segs = arrayReCreate (look->segs, 64, SEG) ; blits = arrayReCreate (blits,64,BLIT) ; if (bsGetKey (Chrom, _Contig, &contig)) do { if (!(Contig = bsCreate (contig))) continue ; seg = arrayp (look->segs, iseg, SEG) ; seg->key = contig ; seg->flag = 0 ; min = 1000000 ; max = -1000000 ; if (bsGetKey (Contig, _Clone, &clone)) do { if (!(Clone = bsCreate (clone))) continue ; if (bsGetKey (Clone, _pMap, &key) && bsGetData (Clone, _bsRight, _Int, &x1) && bsGetData (Clone, _bsRight, _Int, &x2)) { if (x1 < min) min = x1 ; if (x2 > max) max = x2 ; if (bsGetData (Clone, _Vaxmap, _Float, &vaxmap)) { blit = arrayp (blits, iblit, BLIT) ; blit->pmap = 0.5 * (x1 + x2) ; blit->vmap = vaxmap ; blit->seg = seg ; blit->key = clone ; ++iblit ; } } bsDestroy (Clone) ; } while (bsGetKey (Contig, _bsDown, &clone)) ; seg->p1 = min ; seg->p2 = max ; seg->x1 = 0.0 ; if (max > min) seg->x2 = (max-min) * PMAP_FAC ; else seg->x2 = 0.0 ; total += seg->x2 ; bsDestroy (Contig) ; ++iseg ; } while (bsGetKey (Chrom, _bsDown, &contig)) ; bsDestroy (Chrom) ; arraySort (blits, blitOrder) ; blitOld = 0 ; end = 0.0 ; for (iblit = 0 ; iblit < arrayMax(blits) ; ++iblit) { blit = arrp(blits, iblit, BLIT) ; seg = blit->seg ; if ((!blitOld || blitOld->seg != seg) && !(seg->flag & FLAG_PROCESSED)) { end += 0.1 ; seg->x1 = end ; end += seg->x2 ; seg->x2 = end ; end += 0.1 ; seg->flag |= FLAG_PROCESSED ; } blitOld = blit ; } look->max = end ; arraySort (look->segs, cMapOrder) ; lexaddkey (name(look->key), &key, _VcMap) ; arrayStore (key, look->segs, "kkkkfi") ; return TRUE ; } static LOOK aLook ; static SEG* cMapAddSeg (KEY key, int ictg, float x1, float x2) { SEG *seg = arrayp (aLook->segs, arrayMax (aLook->segs), SEG) ; SEG *ctgSeg = arrp (aLook->segs, ictg, SEG) ; seg->key = key ; seg->x1 = ctgSeg->x1 + PMAP_FAC*(x1 - ctgSeg->p1) ; seg->x2 = ctgSeg->x1 + PMAP_FAC*(x2 - ctgSeg->p1) ; seg->flag = 0 ; return seg ; } static void cMapAdd (void) /* add keys from active keyset */ { int i, k, x1, x2 ; int iseg; void *ictg; SEG *seg ; KEY key, contig, clone ; OBJ obj, Clone ; KEYSET kSet = 0 ; static Array map = 0 ; static Array units = 0 ; GRIDMAP *grid ; LOOKGET("cMapAdd") ; if (!keySetActive(&kSet, 0)) { messout("First select a keySet window, thank you.") ; return ; } map = arrayReCreate (map, 8, GRIDMAP) ; look->ctgAss = assReCreate (look->ctgAss) ; for (iseg = 0 ; iseg < arrayMax(look->segs) ; ++iseg) { seg = arrp(look->segs, iseg, SEG) ; if (class(seg->key) == _VContig) assInsert (look->ctgAss, assVoid(seg->key), assVoid(iseg)) ; } aLook = look ; /* static for cMapAddSeg() */ iseg = arrayMax (look->segs) ; for (i = 0 ; i < keySetMax(kSet) ; ++i) { key = arr(kSet, i, KEY) ; if (!(obj = bsCreate (key))) continue ; if (class (key) == _VLocus) { if (bsGetKey (obj, _Positive_clone, &clone) && (Clone = bsCreate (clone))) { if (bsGetKey (Clone, _pMap, &contig) && bsGetData (Clone, _bsRight, _Int, &x1) && bsGetData (Clone, _bsRight, _Int, &x2) && assFind (look->ctgAss, assVoid(contig), &ictg)) cMapAddSeg (key, assInt(ictg), x1, x2) ; bsDestroy (Clone) ; } } else if (class(key) == _VClone) { if (bsGetKey (obj, _pMap, &contig) && bsGetData (obj, _bsRight, _Int, &x1) && bsGetData (obj, _bsRight, _Int, &x2) && assFind (look->ctgAss, assVoid(contig), &ictg)) { seg = cMapAddSeg (key, assInt(ictg), x1, x2) ; if (bsGetData (obj, _In_Situ, _Int, &x1) && bsGetData (obj, _bsRight, _Int, &x2)) { seg->flag |= FLAG_INSITU ; seg->p1 = x1/100.0 ; /* NB p is a float, x an int */ seg->p2 = x2/100.0 ; } } else if (gridClusterKey (key, map, 200)) for (k = 0 ; k < arrayMax(map) ; ++k) { grid = arrp (map, k, GRIDMAP) ; if (!assFind (look->ctgAss, assVoid(grid->ctg), &ictg)) continue ; seg = cMapAddSeg (key, assInt(ictg), grid->x1, grid->x2) ; seg->flag = FLAG_HYB ; } } else if (class(key) == _VSequence) { units = arrayReCreate (units, 1024, BSunit) ; if (bsFindTag (obj, _Homol) && bsFlatten (obj, 7, units)) for (k = 0 ; k < arrayMax (units) ; k += 7) if (lexReClass (arr(units,k,BSunit).k, &clone, _VClone) && (Clone = bsCreate (clone))) { if (bsGetKey (Clone, _pMap, &contig) && bsGetData (Clone, _bsRight, _Int, &x1) && bsGetData (Clone, _bsRight, _Int, &x2) && assFind (look->ctgAss, assVoid(contig), &ictg)) cMapAddSeg (key, assInt(ictg), x1 + arr(units,k+5,BSunit).i * PMAP_FAC, x1 + arr(units,k+5,BSunit).i * PMAP_FAC) ; bsDestroy (Clone) ; } } bsDestroy (obj) ; } arraySort (look->segs, cMapOrder) ; if (!isFullGenome) cMapDraw (look, 0) ; } static void cMapSubtract (void) { int i, j; SEG *seg, *seg2 ; KEYSET kSet = 0 ; LOOKGET("cMapSubtract") ; if (!keySetActive(&kSet, 0)) { messout("First select a keySet window, thank you.") ; return ; } for (seg = arrp(look->segs,0,SEG), i = arrayMax(look->segs) ; i-- ; seg++) if (keySetFind (kSet, seg->key, &j)) seg->flag |= FLAG_DELETING ; for (seg = seg2 = arrp(look->segs,0,SEG), i = arrayMax(look->segs) ; i-- ; seg++) if (!(seg->flag & FLAG_DELETING)) *seg2++ = *seg ; arrayMax(look->segs) = seg2 - arrp(look->segs,0,SEG) + 1 ; cMapDraw (look, 0) ; } static void cMapHighlight (void) { int i, j ; SEG *seg ; KEYSET kSet = 0 ; LOOKGET("cMapHighlight") ; if (!keySetActive(&kSet, 0)) { messout("First select a keySet window, thank you.") ; return ; } seg = arrp(look->segs,0,SEG) ; i = arrayMax(look->segs) ; while(i--) { seg->flag &= ~FLAG_HIGHLIGHT ; if (keySetFind (kSet, seg->key, &j)) seg->flag |= FLAG_HIGHLIGHT ; seg++ ; } cMapDraw (look, 0) ; } /************* special function for cDNA paper display **********/ static void cMapFullGenome (void) { static char* chroms[] = {"I", "II", "III", "IV", "V", "X"} ; KEY key ; int i, xOff ; LOOKGET ("cdnaPaperDisplay") ; graphClear () ; graphColor (BLACK) ; isFullGenome = TRUE ; nx = 100 ; ny = 100 ; look->mag = 1.0 ; for (i = 0 ; i < 6 ; ++i) { lexword2key (chroms[i], &key, _VMap) ; look->key = key ; if (!cMapConvert (look, FALSE)) messcrash ("lost a chromosome!") ; look->centre = 0.0 ; yCentre = 3.5 + 20 * (i / 3) ; xOff = -7 + 20 * (i % 3) ; xContig += xOff ; xItem += xOff ; graphTextHeight (1.5) ; graphText (chroms[i], xContig-7, MAP2GRAPH(look,-1)) ; graphTextHeight (0.0) ; { int ii ; COLUMN *col ; for (ii = 0 ; ii < arrayMax (look->columns) ; ++ii) { col = arr(look->columns, ii, COLUMN*) ; graphText (col->name, xItem + col->offset, MAP2GRAPH(look,-2)) ; } } cMapDraw (look, 0) ; xContig -= xOff ; xItem -= xOff ; } isFullGenome = FALSE ; } static void cMapPartGenome (void) { static char* chroms[] = {"II", "III", "X"} ; KEY key ; int i ; COLUMN *col ; LOOKGET ("cdnaPaperDisplay") ; graphClear () ; graphColor (BLACK) ; isFullGenome = TRUE ; nx = 100 ; ny = 100 ; look->mag = 0.8 ; yCentre = 3.5 ; xContig -= 6 ; xItem -= 6 ; for (i = 0 ; i < arrayMax (look->columns) ; ++i) { col = arr(look->columns, i, COLUMN*) ; graphText (col->name, xItem + col->offset, 2) ; } for (i = 0 ; i < 3 ; ++i) { lexword2key (chroms[i], &key, _VMap) ; look->key = key ; if (!cMapConvert (look, FALSE)) messcrash ("lost a chromosome!") ; look->centre = 0.0 ; graphTextHeight (1.5) ; graphText (chroms[i], xContig-7, MAP2GRAPH(look,-1)) ; graphTextHeight (0.0) ; cMapDraw (look, 0) ; yCentre += look->mag * (look->max + 4) ; } xContig += 6 ; xItem += 6 ; isFullGenome = FALSE ; } /*******************************************************************/ /*******************************************************************/ static void cMapColDraw (LOOK look, COLUMN *col) { int i, ihis ; float *px, y1, y2, w, x1, x2 ; KEY *pctg ; SEG *seg ; Array his, seq, binEnd ; int oldColour ; static Associator ctg2seg = 0 ; if (!col->bin || !col->wfac || !arrayMax (col->coords)) return ; ctg2seg = assReCreate (ctg2seg) ; for (i = 0 ; i < arrayMax(look->segs) ; ++i) { seg = arrp(look->segs, i, SEG) ; if (class(seg->key) == _VContig) assInsert (ctg2seg, assVoid(seg->key), seg) ; } oldColour = graphColor (col->colour) ; if (col->isLine) { px = arrp (col->coords, 0, float) ; pctg = arrp (col->ctgs, 0, KEY) ; for (i = 0 ; i < arrayMax (col->coords) ; ++i, ++px, ++pctg) if (assFind (ctg2seg, assVoid(*pctg), &seg)) { x1 = seg->x1 + PMAP_FAC * (*px - seg->p1) ; y1 = MAP2GRAPH (look, x1) ; w = col->wfac * array(col->count, i, int) ; graphLine (xItem + col->offset, y1, xItem + col->offset + w, y1) ; } } else { his = arrayCreate (32, int) ; seq = arrayCreate (32, int) ; binEnd = arrayCreate (32, float) ; px = arrp (col->coords, 0, float) ; pctg = arrp (col->ctgs, 0, KEY) ; ihis = -1 ; for (i = 0 ; i < arrayMax (col->coords) ; ++i, ++px, ++pctg) if (assFind (ctg2seg, assVoid(*pctg), &seg)) { w = seg->x1 + PMAP_FAC * (*px - seg->p1) ; if (arrayMax (col->seqlen)) { #ifdef VARIABLE if (ihis == -1) /* start */ array(binEnd,++ihis,float) = w ; else if (arr(seq, ihis, int) > 1000000 * col->bin) ++ihis ; array(binEnd,ihis+1,float) = w ; #else ihis = (int)(w/col->bin) ; #endif array(his, ihis, int) += arr(col->count, i, int) ; array(seq, ihis, int) += arr(col->seqlen, i, int) ; } else ++array(his, (int)(w/col->bin), int) ; } for (i = 0 ; i < arrayMax (his) ; ++i) if ((w = col->wfac * arr(his, i, int))) { x1 = i*col->bin ; x2 = (i+1)*col->bin ; if (arrayMax (col->seqlen)) w *= 1000000.0 / arr(seq, i, int) ; else { w /= col->bin ; if (x2 > look->max) w *= (x2 - x1) / (look->max - x1) ; } if (x2 > look->max) x2 = look->max ; y1 = MAP2GRAPH (look, x1) ; y2 = MAP2GRAPH (look, x2) ; graphFillRectangle (xItem + col->offset, y1, xItem + col->offset + w, y2) ; } arrayDestroy (his) ; arrayDestroy (seq) ; arrayDestroy (binEnd) ; } graphColor (oldColour) ; assDestroy (ctg2seg) ; } /********** little window for controlling the column *******/ static int colGraphHolder ; static Graph cMapColGraphCreate (LOOK look, COLUMN *col) { int i, n = 0 ; if (graphActivate (col->graph)) { graphPop () ; return col->graph ; } col->graph = graphCreate (TEXT_FIT, "column", 0, 0, .3, .2) ; for (i = 0 ; i < arrayMax(col->count) ; ++i) n += arr(col->count, i, int) ; graphText (messprintf ("%d objects", n), 2, 0.5) ; graphFloatEditor ("Histogram bin", &col->bin, 1, 2, 0) ; graphFloatEditor ("Width factor", &col->wfac, 1, 3, 0) ; graphIntEditor ("Colour", &col->colour, 1, 4, 0) ; graphIntEditor ("Offset", &col->offset, 1, 5, 0) ; graphWordEditor ("Name", col->name, 30, 1, 6, 0) ; graphIntEditor ("Is line", &col->isLine, 1, 7, 0) ; graphRedraw () ; graphAssociate (&colGraphHolder, col) ; return col->graph ; } /*******************************************/ static void cMapColEdit (void) { int i ; LOOKGET("cMapColEdit") ; for (i = 0 ; i < arrayMax (look->columns) ; ++i) cMapColGraphCreate (look, arr(look->columns, i, COLUMN*)) ; } /*******************************************/ static void cMapColFillFromKeySet (LOOK look, COLUMN *col) { KEY key, contig ; KEYSET kSet = 0 ; GRIDMAP *grid ; static Array map = 0 ; int i, k, x1, x2, n = 0 ; OBJ obj ; if (!keySetActive (&kSet, 0)) return ; col->coords = arrayReCreate (col->coords, 128, float) ; map = arrayReCreate (map, 8, GRIDMAP) ; for (i = 0 ; i < keySetMax(kSet) ; ++i) { key = arr(kSet, i, KEY) ; if (!(obj = bsCreate (key))) continue ; if (class(key) == _VClone) { if (bsGetKey (obj, _pMap, &contig) && bsGetData (obj, _bsRight, _Int, &x1) && bsGetData (obj, _bsRight, _Int, &x2)) { array (col->coords, n, float) = (x1+x2)/2 ; array (col->ctgs, n, KEY) = contig ; array (col->count, n, int) = 1 ; ++n ; } else if (gridClusterKey (key, map, 200)) for (k = 0 ; k < arrayMax(map) ; ++k) { grid = arrp (map, k, GRIDMAP) ; array (col->coords, n, float) = (grid->x1+grid->x2)/2 ; array (col->ctgs, n, KEY) = grid->ctg ; array (col->count, n, int) = 1 ; ++n ; } } } } static void cMapColFillFromFile (LOOK look, COLUMN *col, ACEIN colinfo_in) { int level, n = 0, x1, x2, k ; OBJ obj ; KEY key, contig ; char *word ; /* expected file format: CLONE [N] [SEQLEN] */ while (aceInCard (colinfo_in)) { if (!(word = aceInWord (colinfo_in)) || !lexword2key (word, &key, _VClone) || !(obj = bsCreate (key))) continue ; if (bsGetKey (obj, _pMap, &contig) && bsGetData (obj, _bsRight, _Int, &x1) && bsGetData (obj, _bsRight, _Int, &x2)) { array (col->coords, n, float) = (x1+x2)/2 ; array (col->ctgs, n, KEY) = contig ; k = 1 ; aceInInt (colinfo_in, &k) ; array (col->count, n, int) = k ; if (aceInInt (colinfo_in, &k)) array (col->seqlen, n, int) = k ; ++n ; } bsDestroy (obj) ; } return; } /* cMapColFillFromFile */ /*******************************************/ static void cMapColFinalise (void *p) { COLUMN *col = (COLUMN*)p ; if (graphActivate (col->graph)) graphDestroy() ; } static COLUMN *cMapColCreate (LOOK look) { COLUMN *col ; col = array (look->columns, arrayMax(look->columns), COLUMN*) = (COLUMN*) halloc (sizeof (COLUMN), look->handle) ; col->bin = 0 ; col->wfac = 0 ; col->colour = BLACK ; col->coords = arrayHandleCreate (128, float, look->handle) ; col->ctgs = arrayHandleCreate (128, KEY, look->handle) ; col->seqlen = arrayHandleCreate (128, int, look->handle) ; col->count = arrayHandleCreate (128, int, look->handle) ; blockSetFinalise (col, cMapColFinalise) ; return col ; } static void cMapColFromKeySet (void) { COLUMN *col ; LOOKGET("cMapColCreate") ; col = cMapColCreate (look) ; cMapColFillFromKeySet (look, col) ; cMapColGraphCreate (look, col) ; } static void cMapColFromFile (void) { static char directory[DIR_BUFFER_SIZE] = ""; static char filename[FIL_BUFFER_SIZE] = ""; COLUMN *col ; ACEIN colinfo_in; LOOKGET("cMapColCreate") ; colinfo_in = aceInCreateFromChooser ("info for column", directory, filename, "hisinf", "r", 0); if (!colinfo_in) return; col = cMapColCreate (look) ; cMapColFillFromFile (look, col, colinfo_in) ; aceInDestroy (colinfo_in); cMapColGraphCreate (look, col) ; return; } /* cMapColFromFile */ static void colMake (LOOK look, char *fname, char *name, float bin, float wfac, int colour, int offset) { ACEIN colinfo_in; COLUMN *col; char *path = messprintf("%s.hisinf", fname); if (!(colinfo_in = aceInCreateFromFile (path, "r", "", 0))) return ; col = cMapColCreate (look) ; col->bin = bin ; col->wfac = wfac ; col->colour = colour ; col->offset = offset ; col->isLine = TRUE ; strcpy (col->name, name) ; cMapColFillFromFile (look, col, colinfo_in) ; aceInDestroy (colinfo_in); return; } /* colMake */ static void cMapHardColumns (void) { LOOKGET("cMapColCreate") ; colMake (look, "/nfs/griffin2/rd/worm.data/maps.971209/1", "L", 0.1, 1, BLACK, 2) ; colMake (look, "/nfs/griffin2/rd/worm.data/maps.971209/3", "S", 0.1, 1, DARKGREEN, 3.5) ; colMake (look, "/nfs/griffin2/rd/worm.data/maps.971209/4", "A", 0.1, 1, BLUE, 5) ; colMake (look, "/nfs/griffin2/rd/worm.data/maps.971209/5", "P", 0.1, 1, MAGENTA, 6.5) ; #ifdef REPS colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/Q", "REP-Q", 1.5, 0.4, DARKGRAY, 5) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/D", "REP-D", 1.5, 0.3, DARKGRAY, 20) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/N", "REP-N", 1.5, 0.08, DARKGRAY, 35) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/T", "REP-T", 1.5, 0.2, DARKRED, 5) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/M", "REP-M", 1.5, 0.2, DARKGRAY, 5) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/A", "REP-A", 1.5, 0.08, DARKRED, 20) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/A", "REP-A", 1.0, 0.02, DARKRED, 0) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/A", "REP-D", 1.0, 0.05, DARKRED, 5) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/E", "REP-E", 1.0, 0.02, DARKRED, 10) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/F", "REP-F", 1.0, 0.05, DARKRED, 15) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/G", "REP-G", 1.0, 0.05, DARKRED, 20) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/J", "REP-J", 1.0, 0.08, DARKRED, 25) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/L", "REP-L", 1.0, 0.10, DARKRED, 30) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/M", "REP-M", 1.0, 0.05, DARKRED, 35) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/N", "REP-N", 1.0, 0.02, DARKRED, 40) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/P", "REP-P", 1.0, 0.15, DARKRED, 45) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/Q", "REP-Q", 1.0, 0.15, DARKRED, 50) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/R", "REP-R", 1.0, 0.20, DARKRED, 55) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/S", "REP-S", 1.0, 0.08, DARKRED, 60) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/T", "REP-T", 1.0, 0.07, DARKRED, 65) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/V", "REP-V", 1.0, 0.03, DARKRED, 70) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/W", "REP-W", 1.0, 0.03, DARKRED, 75) ; colMake (look, "/nfs/griffin2/rd/worm.data/9510/REP/hisinf/X", "REP-X", 1.0, 0.10, DARKRED, 80) ; #endif cMapPartGenome () ; } /*******************************************************************/ /*******************************************************************/