/* * displaysubs.c 24/12/84 Jim Piper * * display subroutines for interactive counting, segmentation, karyotyping * *********************************************************************** * * Modifications: * * 3 Aug 1988 CAS Added cellsize * 2 Nov 1987 CAS Correct undisplay in dispotype * 21 Sep 1987 CAS moved explode to kcont * 20 Aug 1987 CAS Replace alc with kcont + remove VAX stuff * 13 Aug 1987 BDP Cope with cell scaling to or from FIP or TV * and output on either CRS or VIRTUOSO * 29 Jan 1987 CAS Cockup with kcont->FIP * 18 Dec 1986 CAS Include fileheaders.h to get symbolic * definition of kcont->FIP consistant * with data filed in kyy * 20 Nov 1986 CAS Mod to countdisp - to combine with kyy * Removed 'aspect ratio' message * 19 Nov 1986 CAS Modified dispotype routine * Name clash - dispblobs. Version here * wrongly named - should be dispexpblobs * hence renamed * JP 12-11-86 includes - otherwise same as replaced version * JP 17-10-86 display.h used *********************************************************************** */ #define P2N(a,b,c) #define P2(a,b,c) fprintf(stderr,"a b %d c %d\n",b,c); sleep(1) #include #include #include #include #include #include #include #define MAX(i,j) (i>j? i: j) #define MIN(i,j) (imaxnumber; objnum++) { if (kcont->acl[objnum]) { obj = kcont->ool[objnum]; colour(GREYCOLS); explodeframe(obj,kcont->f,&ef); picframe(obj,&ef); dispotype(obj,&ef,1); P2N(in alldisplay,objnum,obj); } } } /* * D I S P O T Y P E * * if not a chromosome, indicate type of object adjacent to it * (Currently, by printing number of chromosomes in object). */ dispotype(obj,f,onoff) struct chromosome *obj; struct pframe *f; { tsize(50,50); colour(OVERLAY2); if (!obj || !onoff || (obj->plist->otype == 1)) frameobjnnum(0,0,0,3); /* No obj - so undraw number */ else if (obj->plist->otype > 1) { frameobjnnum(obj->plist->history[2],obj,f,3); } } /* * display the marker "blobs", of wich there is one per object * at its darkest pixel. */ dispexpblobs(kcont) register struct kcontrol *kcont; { register int objnum; struct pframe ef; intens(1); for (objnum=0; objnummaxnumber; objnum++) { if (kcont->acl[objnum]) { explodeframe(kcont->ool[objnum],kcont->f,&ef); picframe(kcont->bol[objnum],&ef); } } } /* * display the serial numbers of active objects */ dispserials(kcont) struct kcontrol *kcont; { int objnum; struct chromosome **objlist = kcont->ool; SMALL *activelist = kcont->acl; tsize(50,50); for (objnum=0; objnummaxnumber; objnum++) { if (activelist[objnum]) { frameobjnum(objnum+1,objlist[objnum],kcont->f); } } } /* * display the boundaries of all objects */ allbound(kcont) register struct kcontrol *kcont; { register int objnum; colour(OVERLAY2); for (objnum=0; objnummaxnumber; objnum++) if (kcont->acl[objnum]) dispbound(kcont->ool[objnum],kcont->f); } /* * display the boundaries of an objects */ dispbound(obj,f) struct chromosome *obj; struct pframe *f; { struct object *bobj, *ibound(); struct pframe ef; explodeframe(obj,f,&ef); bobj = ibound(obj,1); picframe(bobj,&ef); freeobj(bobj); } /* * display the hulls of all objects */ allhull(kcont) register struct kcontrol *kcont; { register int objnum; colour(OVERLAY2); for (objnum=0; objnummaxnumber; objnum++) { if (kcont->acl[objnum]) disphull(kcont->ool[objnum],kcont->f); } } /* * display the hull of an objects */ disphull(obj,f) struct chromosome *obj; struct pframe *f; { struct object *bobj, *convhull(); struct pframe ef; explodeframe(obj,f,&ef); bobj = convhull(obj); picframe(bobj,&ef); freeobj(bobj); } /* * display the enclosing right rectangles of all objects */ allrect(kcont) register struct kcontrol *kcont; { int objnum; colour(OVERLAY2); for (objnum=0; objnummaxnumber; objnum++) if (kcont->acl[objnum]) disprect(kcont->ool[objnum],kcont->f); } /* * display the enclosing right rectangle of an objects */ disprect(obj,f) struct chromosome *obj; struct pframe *f; { register int k1,kl,l1,ll; register struct intervaldomain *idom; struct irect r; struct object ro; struct pframe ef; r.type = 1; ro.type = 20; ro.idom = (struct intervaldomain *)&r; idom = obj->idom; k1 = idom->kol1; kl = idom->lastkl; if (kl-k1 < 8) { kl += 4; k1 -= 4; } l1 = idom->line1; ll = idom->lastln; if (ll-l1 < 8) { ll += 4; l1 -= 4; } r.irk[0] = r.irk[1] = k1; r.irk[2] = r.irk[3] = kl; r.irl[0] = r.irl[3] = l1; r.irl[1] = r.irl[2] = ll; explodeframe(obj,f,&ef); picframe(&ro,&ef); } /* * display the enclosing right rectangle of an object, enlarged somewhat */ bdisprect(obj,f) struct chromosome *obj; struct pframe *f; { register struct intervaldomain *idom; struct irect r; struct object ro; r.type = 1; ro.type = 20; ro.idom = (struct intervaldomain *) &r; idom = obj->idom; r.irk[0] = r.irk[1] = idom->kol1 - 4; r.irk[2] = r.irk[3] = idom->lastkl + 4; r.irl[0] = r.irl[3] = idom->line1 - 4; r.irl[1] = r.irl[2] = idom->lastln + 4; picframe(&ro,f); } /* * make a modified picture frame for an exploded display */ explodeframe(obj,f,ef) struct object *obj; register struct pframe *f,*ef; { register int xoff,yoff; register struct intervaldomain *idom; ef->ix = f->ix; ef->iy = f->iy; ef->scale = f->scale; idom = obj->idom; if (kcont->explode) { xoff = f->ox - (idom->kol1+idom->lastkl)/2; yoff = f->oy - (idom->line1+idom->lastln)/2; } else { xoff = yoff = 0; } ef->ox = f->ox + xoff/8; ef->oy = f->oy + yoff/8; ef->dx = f->dx; ef->dy = f->dy; } /* * C E L L S I Z E -- Calculate size of list of objects * */ cellsize(objlist,count,xmin,xmax,ymin,ymax) struct chromosome **objlist; int *xmin,*xmax,*ymin,*ymax; { struct chromosome *obj; register struct intervaldomain *idom; int objnum; *ymin = 99999; *xmin = 99999; *ymax = -99999; *xmax = -99999; for (objnum = 0; objnum < count; objnum++) { if ((obj=objlist[objnum]) && obj->idom) { idom = obj->idom; *ymin = MIN(*ymin,idom->line1); *xmin = MIN(*xmin,idom->kol1); *ymax = MAX(*ymax,idom->lastln); *xmax = MAX(*xmax,idom->lastkl); } } } /* * C O U N T D I S P -- display a count at bottom left corner of the screen */ countdisp(n,onoff) int n,onoff; { static int countdisplayed = 0; /* Is there one displayed */ static int countbanc; /* If so this is what it is */ tsize(130,150); colour(OVERLAY1); if (countdisplayed) { intens(0); dispnum(countbanc,100,100); } countdisplayed = onoff; intens(1); if (onoff) { dispnum(n,100,100); countbanc = n; } tsize(50,50); } /* * find the darkest point of an object, * mark it with a blob. */ struct object *blobmark(obj) struct object *obj; { struct ipoint *blobpoint; struct iwspace iwsp; struct gwspace gwsp; COORD linmax, colmax; register GREY *g, gmax; register int k; gmax = 0; #ifdef MIZAR initgreyscan(obj,&iwsp,&gwsp); #else initgreyscan(obj,&iwsp,&gwsp); #endif while (nextgreyinterval(&iwsp) == 0) { g = gwsp.grintptr; for (k=0; k< iwsp.colrmn; k++) { if (*g > gmax) { gmax = *g; linmax = iwsp.linpos; colmax = iwsp.lftpos + k; } g++; } } blobpoint = (struct ipoint *) Calloc(sizeof(struct ipoint),1); blobpoint->type = 40; blobpoint->k = colmax; blobpoint->l = linmax; blobpoint->style = 2; return((struct object *) blobpoint); } /* * Compute the picture frame needed to display the enrtire * metaphase cell centered on the screen. A default scale is * used unless the cell is too large to fit, in which case * the scale is reduced */ cellframe(kcont) struct kcontrol *kcont; { struct chromosome **objlist; struct chromosome *obj; register struct intervaldomain *idom; register int objnum,cellkol1,cellline1,celllastkl; int scale,xscale,yscale,celllastln,celldiam; struct pframe *f; objlist = kcont->ool; f = kcont->f; for (objnum = 0; objnum < kcont->maxnumber; objnum++) { obj = objlist[objnum]; idom = obj->idom; if (objnum == 0) { cellline1 = idom->line1; cellkol1 = idom->kol1; celllastln = idom->lastln; celllastkl = idom->lastkl; } else { cellline1 = MIN(cellline1,idom->line1); cellkol1 = MIN(cellkol1,idom->kol1); celllastln = MAX(celllastln,idom->lastln); celllastkl = MAX(celllastkl,idom->lastkl); } } scale = 8; celldiam = celllastln - cellline1; /* first work out what the cell was digitised on , FIP or TV? */ if (kcont->FIP == DIGFIP) celldiam = 3*celldiam/4; /* now look at the output screen size, is it a CRS board or a virtuoso board? N.B. the code specifically has a default to CRS which is why it explicitly test for either of the virtuoso types first */ if ((kcont->ddgschannel->type == FS_VIRTUOSO) || (kcont->ddgschannel->type == FS_VIRTUOSO_INVERT) ) { xscale = yscale = 8; if (celldiam > 570) yscale = 8 * 570 / celldiam; celldiam = celllastkl - cellkol1; if (celldiam > 760) xscale = 8 * 760 / celldiam; scale = yscale < xscale? yscale : xscale; if (scale < 8) fprintf(stderr,"default scale changed to %d\n",scale); /* the following two values could be offset up and right a bit if the default scale is lowered, but probably not worth the effort */ f->dx = 3072; f->dy = 2304; } else { if (celldiam < celllastkl - cellkol1) celldiam = celllastkl - cellkol1; if (celldiam > 510) { scale = 8 * 510 / celldiam; fprintf(stderr,"default scale changed to %d\n",scale); /* fprintf(stderr,"aspect ratio may be slightly wrong\n");*/ } f->dx = 2080; f->dy = 2080; } f->scale = 1; f->ix = scale; f->iy = ((kcont->FIP == DIGFIP) ? 3*scale/4: scale); f->ox = (cellkol1+celllastkl)/2; f->oy = (cellline1+celllastln)/2; }