/* * K A R Y F I X . C -- Karyotype interaction * * Image Recognition Systems * 720 Birchwood Boulevard * Birchwood Science Park * Warrington * Cheshire * WA3 7PX * * Copyright (c) and intellectual property rights Image Recognition Systems (1988) * * Based on: kinteract.c/karyfix.c * Jim Piper, MRC CAPCU * 23 Jan 1984 * * Modifications * * 4 Oct 1994 JimP Fixed bug in kdentify resulting from 4/5/92 fix. * 4 May 1992 Joanne make MAXCLASS dependent on species: alc->scrf->undefclass * 27 Feb 1992 JimP Added "recover" and "single/all" in presentation options menu * 25 Feb 1992 Joanne give option in "enlage menu" to draw profiles * 5 Feb 1992 Joanne add NEF coordinates to karyotype options menu * 3 Feb 1992 Joanne made filename for ideograms dependent on current species * 11 Jun 1991 ih Check for null objlist before notgood and null newobj in dohance * 30 Apr 1991 ih/cas Deactivate any null objects in ool in cellview * 12 Feb 1991 CAS Undisplay correct (ie mol not kol) object in `noiseor' * 2 Feb 1991 ih/gjp Check OPT_FLEX before allowing flex screen * 31 Jan 1991 JimP@MRC Try to get cursor identification back * after flexible screen - but just guessing. * 12 Nov 1990 Bill Hill @ MRC HGU Take out existing flex screen * stuff and put in own. * 19 Jul 1990 dcb kinteract: Pass phase to enhanceopt * 04 Jun 1990 dcb Start adding flex screen stuff (under devel) * 23 Mar 1990 IH Added code to set header version when correcting * 12 Mar 1990 dcb cellview: replace setcolour by lin_colour_lut * upkary: Use lin_colour_lut instead of setcolour * 01 Mar 1990 dcb remove setcolour, and changecolour definitions * 21 Aug 1989 CAS Set up colours atomatically for fluor * 26 Jul 1989 SEAJ Made chekactv make all objects active. * 4 Jul 1989 SEAJ Added call to newCpgroup. * 31 May 1989 SEAJ Made notgood2() into notgood(0) in movevert(). * 18 Apr 1989 SEAJ Restore enhanced objects before eliminating. * 10 Mar 1989 SEAJ Phase bug fix in ktypeopts. * 10 Mar 1989 dcb Rip out resegm() * 21 Feb 1989 CAS Make posn 0,0 disable showclass * 20 Feb 1989 SEAJ Made showcell setup kcont->current_obj as well. * 17 Feb 1989 SEAJ Modified kinteract for new chromlyse. * 16 Feb 1989 SEAJ Reversed sense of new in upkary now parameter is * called old. * 14 Feb 1989 CAS tryfile changed to opencfile * chdir removed * 27 Jan 1989 SEAJ Scaled Ideogram to size of enlarged chroms. & * undisplay it. * 26 Jan 1989 SEAJ Tidied ideogram stuff. * 19 Jan 1989 SEAJ Modified chgobj for mouse select, keyboard choose. * 18 Jan 1989 SEAJ Force boxing after rotate, eliminate, view met. * and resegment. * 6 Dec 1988 SEAJ Reset cursor for karyotype after a null object * returned from turnchrom in dohance. * 4 Dec 1988 CAS Change params to newclass/swapclass * 18 Nov 1988 CAS Move atchromosome to kycurs * 8 Oct 1988 CAS chekread - needed elsewhere - no longer static * 6 Oct 1988 CAs Start adding SMG ideogram stuff * 3 Oct 1988 CAS Laserktype option.. * 5 Sep 1988 CAS Fiddling with display * 2 Sep 1988 CAS Textclass - get class from alc->scrf * Allow mark with random text * 30 Aug 1988 CAS Showclass - pick up pos from alc->scrf * 3 Aug 1988 CAS Move cellsize to karylib * 8 Jul 1988 SEAJ Don't destroy active list status in chekactv * 6 Jul 1988 CAS Tidy cmmd lines * 16 Jun 1988 CAS Range checking * 25 May 1988 CAS Mods to chekread to preserve header etc * more on met/ktype * Pulled karyfixbis into here. * 24 May 1988 CAS Play with view met, new devel fn to display * met on ktype * 23 May 1988 CAS Change colour calls * 12 May 1988 CAS Remove 'hom' from enlarge * 5 Feb 1988 CAS karyotype comments '?' problems * kytpeopts - phase 1 need screen tidy bits * 2 Feb 1988 CAS No resegment in ktype review */ #include #include #include #include #include #include #include #include #include #include #include #include #define KSCALE 8 /* Default kary display scale */ #define NORMAL 1 #define CHANGE 2 #define ABNORMAL 25 #define RADIANS .01745 #define BORDER 20 #define MAX(i,j) (((i)>(j))? (i): (j)) #define MIN(i,j) (((i)<(j))? (i): (j)) /* * globals defined here, presumably used elsewhere */ int DOWN=0; /* * external variables */ extern struct allkontr *alc; extern struct kcontrol *kcont; extern char *colours[]; extern struct ipoint cursor; extern FILE *debug_channel; extern struct kclasscont kcc[]; /* defined in karysubs1.c */ extern int stackocc[]; /* defined in karysubs1.c */ extern int enhanceopt(), enhancement(), flex_Main(); extern char *getspec(); /* defined in utilities.c */ extern int setname(); /* * statics used only in this module */ static int ang; static int xobj1 ; static int xobj2 ; static struct chromosome **objlist; struct kident kid1, kid2; static *gotcell; static htype; static hdcopy(){} static char ccl[4]; static char psl[4]; static cnum,pnum; static char cs[4],ps[4]; static state ; static int cellonktype = 0; /* Displaying cell on ktype */ static int karychanged; /* Used to remember if k-type changed but not yet filed */ /* * The "keeplist" (kcont->kol) array is now an explicit copy of the original * pointers in * "kcont->mol". When an object is rotated/straightened the pointer * to the NEW object is stored in "kcont->mol". This has the side-effect * that this copying must also be done when composites/overlaps are split. */ /* * internal function definitions */ int kycurs(); static int textfn(); movevert(); static int ideogram(); void markit(); static profiles(); /* * External function definitions */ #ifdef UNUSED extern int setcolour(), changecolour(); #endif extern karyscale(); extern int laserktype(); /* * T I D Y K A R Y * */ tidykary() { tidyscreen(kcont); } /* * A L L H A N C E * */ allhance(type) { struct kclasscont *kcc,*kccwhere(); switch (type) { case 1: mp_k_serv(kcont,K_STRAIGHTEN); /* * the positioning of the chromosomes by the * slaves is only approximate, tidy it up here */ fast(); mpclear(kcont); slow(); displayall(kcont,0); return(0); case 2: mp_k_serv(kcont,K_ENHANCE); return(0); case 5: mp_k_serv(kcont,K_NORMALISE); return(0); default: for (cnum=0; cnummaxn; ++ pnum) if (kdentify(&kid1,cnum,pnum)) dohance(type); } } } /* * D O H A N C E * */ dohance(type) { struct chromosome *nobj,*newnobj,*sing_mp_k_serv(); struct chromosome *manualstraight(); struct chromosome *turnchrom(); if (!objlist||!objlist[kid1.no]) return(0); if (notgood(0)) return(0); nobj = objlist[kid1.no]; erasecursor(); switch(type) { case 1: newnobj = sing_mp_k_serv(kcont,K_STRAIGHTEN,kid1.no); break; case 2: newnobj = sing_mp_k_serv(kcont,K_ENHANCE,kid1.no); break; case 3: newnobj = turnchrom(ang,kcont,kid1.no); ang = 0; if (!newnobj) { setmsv(kycurs); /* reset cursor */ return(0); } break; case 4: /* recover original from kcont->kol */ newnobj = kcont->kol[kid1.no]; if (!newnobj) { setmsv(kycurs); /* reset cursor */ return(0); } /* if same object, don't bother with remainder */ if (newnobj == nobj) return(0); break; case 5: newnobj = sing_mp_k_serv(kcont,K_NORMALISE,kid1.no); break; case 6: newnobj = manualstraight(kcont,kid1.no); if (!newnobj) { setmsv(kycurs); /* reset cursor */ return(0); } break; default: newnobj = nobj; break; /* does nothing ?? */ if (!newnobj) { setmsv(kycurs); /* reset cursor */ return(0); } } setmsv(kycurs); newnobj->plist = nobj->plist; /* * delete old object if manual straighten or recover * (auto-straight and rotate deleted by slave) */ switch(type) { case 4: case 6: unkdisplay(&kid1,kcont); break; default: break; } /* * display new object - done by slave if enhance or normalise */ objlist[kid1.no] = newnobj; switch(type) { case 1: case 3: case 4: case 6: kdisplay(&kid1,kcont); break; default: break; } /* * remove any intermediate rotated/straightened objects * nobj == newnobj if nothing done (eg manual straight quit etc) */ if ((nobj != kcont->kol[kid1.no]) && (nobj != newnobj)) { nobj->plist = NULL; /* prop lists always shared */ freeobj(nobj); } } /* * S W O P -- * */ static swop(a, b) register int *a, *b; { register int x; x = *a; *a = *b; *b = x; } /* * K I D S W O P -- * */ static kidswop() { swop(&kid1.pos,&kid2.pos); swop(&kid1.stackpos,&kid2.stackpos); swop(&kid1.kclass,&kid2.kclass); swop(&kid1.no,&kid2.no); } /* * K I D C P Y -- * */ static kidcpy() { kid1.pos = kid2.pos; kid1.stackpos = kid2.stackpos; kid1.kclass = kid2.kclass; kid1.no = kid2.no; } /* * T E X T P O S -- * */ static textpos(ps, pn) register char *ps; { *ps++ = 'a'+ pn; *ps = 0; } /* * N O T G O O D -- * * note that cnum and pnum are set by kycurs and by menu line 1 */ notgood(silent) int silent; { if (! kdentify(&kid1,cnum,pnum) ) { cs[0] = ' '; ps[0] = ' '; if (!silent) { displin(0,1); screengo(ENDLINE,0); fprintf(output,"Please check chromosome selection ! \007 "); putprompt(); } return(1); } return (0); } /* * N O T G O O D 2 -- * */ static notgood2() { if (! kdentify(&kid2,cnum,pnum) ) { screengo(ENDLINE,0); fprintf(output,"Please check chromosome selection ! \007 "); putprompt(); return(1); } return (0); } /* * C L A S S P O S * */ static classpos(s,p) register char *s,*p; { switch ( *s ) { case 'x' : case 'X' : cnum = alc->scrf->undefclass - 1; break; case 'y' : case 'Y' : cnum = alc->scrf->undefclass; break; case 'a' : case 'A' : cnum = alc->scrf->undefclass + 1; break; default : if (isdigit(*s)) { cnum = *s++ -'0'; if (isdigit(*s)) cnum = 10*cnum +(*s - '0'); else --s; if (cnum < 1 || cnum >alc->scrf->undefclass+1) { screengo(ENDLINE,0); fprintf(output, "Bad class selection - please try again\007\n"); return(-1); } } } ++s; /* set input pointer to position, in case combined num/pos */ --cnum; pnum = *p; if ((pnum == ' ') || (pnum == '\0')) { if (*s && *s != ' ') { pnum = *s ; *s = 0; *p = pnum; /* for redisplay purposese */ } else pnum = 0; } if (pnum >= 'a') pnum -= 32; if (pnum != 0) { if ( pnum >= 'A' && pnum <= 'Z') pnum -= 'A' ; else pnum = -1; } /* insert a space behind the pnum-indicator; this displays OK and allows detection of default condition */ *(p+1) = *p; *(p+2) = 0; *p = ' '; return(cnum); } /* * C E L L V I E W -- clear screen, display original objects in * original frame */ static cellview() { if (! chekread(0)) return(0); lin_colour_lut(); /* dcb */ showcell (); go_on(); lin_colour_lut(); /* dcb */ showkary(); if (cellonktype) celloverlay(&cellonktype); return(0); } /* * C E L L O V E R L A Y -- * */ static celloverlay(onoff) int *onoff; { SMALL aclsav[MAXOBJS]; int i, xmin, xmax, ymin, ymax, xsize, ysize; struct pframe *f; DDGS *dgp; if (*onoff) { if (!chekread(0)) return(0); for (i=0; imaxnumber; i++) { aclsav[i] = kcont->acl[i]; if (kcont->ool[i] != NULL && !kcont->ool[i]->plist->history[1]) kcont->acl[i] |= ACTIVE; else kcont->acl[i] &= ~ACTIVE; } cellsize(kcont->ool,kcont->maxnumber,&xmin,&xmax,&ymin,&ymax); xsize = xmax - xmin + BORDER; ysize = ymax - ymin + BORDER; f = kcont->f; dgp = kcont->ddgschannel; f->scale = 1; f->ix = (dgp->lineln * 4) / xsize; /* Max half width of screen */ f->iy = ((kcont->FIP == DIGFIP) ? 3*f->ix/4: f->ix); f->ox = (xmax + xmin) / 2; f->oy = (ymax + ymin) / 2; xsize *= f->ix; ysize *= f->iy; f->dx = (dgp->lineln << dgp->xshift) - xsize/2; f->dy = ysize/2; fast(); moveto((dgp->lineln << dgp->xshift) - xsize,0); wclear(xsize,ysize,0); colour(OVERLAY2); lineby(0,ysize); lineby(xsize,0); mpcpic(kcont,GREYCOLS,1); slow(); for (i=0; imaxnumber; i++) kcont->acl[i] = aclsav[i]; } else { showkary(); } return(0); } static kid2was = -1; /* * C H G O B J -- Select for transfer using the alternate kid "kid2" * */ static chgobj(tccl, ccl, tpsl, psl) char *tccl, *ccl, *tpsl, *psl; { int ret; if ((mukont->wasmouse) || ((*tccl == '\0') && (*tpsl == '\0'))) { kylocate(&cursor); /* relocate on cursor */ cnum = kid1.kclass; /* reset cnum and pnum */ pnum = kid1.pos - 1; textclass (ccl, cnum+1); textpos (psl, pnum ); *tccl = '\0'; *tpsl = '\0'; } else { ret = classpos(tccl, tpsl); if (ret >= 0) { strcpy(ccl, tccl); strcpy(psl, tpsl); } *tccl = '\0'; *tpsl = '\0'; if (ret < 0) return(0); } unbacklight(); state = NORMAL; if (! kdentify(&kid2,cnum,pnum) ) { screengo(ENDLINE,0); kid2was = kid2.no = -1; printf( "Incorrect chromosome selection - please try again\007\n"); return(0); } if (kid2was == kid2.no) { kid2was = kid2.no = -1; return(0); } backlight(objlist[kid2.no],kcont->ivf + kid2.no, 1); kid2was = kid2.no; displin(0,2); state = CHANGE ; return(0); } /* select kid1 */ static pickobj() { if (! mukont->wasmouse) if ( classpos(cs,ps) < 0 ) return(0); if (! kdentify(&kid1,cnum,pnum) ) { screengo(ENDLINE,0); kid2.no = -1; printf( "Incorrect chromosome selection - please try again\007\n"); } else rebox(1); /* show box around object */ } /* * C H G C L S -- * */ static chgcls() { if (kid2.no < 0) { screengo(ENDLINE,0); fprintf(output,"Please check chromosome selection \007\n"); putprompt(); return(0); } *ps = ' '; if (! mukont->wasmouse) { if ( classpos(cs,ps) < 0 ) return(0); } if (state == CHANGE) { unkdisplay(&kid2,kcont); remove_class(&kid2); re_use_if_poss(&kid2,kcont); newCpgroup(&kid2, cnum, kcont); newclass(&kid2,cnum,kcont,alc->scrf->disppos); kdisplay(&kid2,kcont); if (kid2.stackpos > 0) hiddenstackcount(); unbacklight(); /* * A choice comes here - what to "rebox". * We "rebox" the moved chromosome if it's NOT in * the stack, otherwise we rebox where the cursor was * before the movement, since we know there is a chromosome * there (otherwise the moved chromosome would not be in * the stack !!). */ if (kid2.stackpos < 0) { kidcpy(); strcpy(cs,ccl); strcpy(ps,psl); kid2was = -1; } pnum = kid1.pos - 1; textpos(ps,pnum); rebox(1); state = NORMAL; } } /* * E X C H A N G E -- swap two objects * */ static exchange() { register int kid_swap = 0; if (!mukont->wasmouse) { if (classpos(cs,ps) < 0) return(0); if (!kdentify(&kid1,cnum,pnum)) return(0); } if ( notgood(0) ) return(0); if ( kid1.no == kid2.no ) return(0); if (state == CHANGE ) { unbacklight(); /* * If the chromosomes are in fact in the same class * then we can only swap their positions by taking * the order in which they were selected into account, * since "swapclass" will always assign its first kid * argument object to the first free position in the * class. */ if (kid1.kclass == kid2.kclass && kid1.pos > kid2.pos) { kid_swap++; kidswop(); } unkdisplay(&kid1,kcont); unkdisplay(&kid2,kcont); swapclass(&kid1,&kid2,kcont,alc->scrf->disppos); kdisplay(&kid1,kcont); kdisplay(&kid2,kcont); if (kid_swap) kidswop(); cnum = kid1.kclass; pnum = kid1.pos - 1; textpos(ps,pnum); rebox(1); state = NORMAL; return(1); } } /* * I N V E R T -- invert a chromosome */ static invert() { if (!objlist||!objlist[kid1.no]) return(0); if ( notgood(0) ) return(0); unkdisplay(&kid1,kcont); objlist[kid1.no]->plist->dispor *= -1; kdisplay(&kid1,kcont); rebox(1); #ifdef GGG cnum = kid1.kclass; pnum = kid1.pos -1 ; #endif GGG return(0); } /* * N O I S E O R -- * */ static noiseor(c) { register struct chromplist *qlist; if (!objlist||!objlist[kid1.no]) return(0); if (!kcont->mol||!kcont->mol[kid1.no]) return(0); if ( notgood(0) ) return(0); unkdisplay(&kid1,kcont); /* free any enhanced objects before removing */ if (kcont->mol[kid1.no] != kcont->kol[kid1.no]) { kcont->mol[kid1.no]->plist = NULL; freeobj(kcont->mol[kid1.no]); kcont->mol[kid1.no] = kcont->kol[kid1.no]; } remove_class(&kid1); kcont->acl[kid1.no] &= ~ACTIVE; qlist = (struct chromplist *) objlist[kid1.no]->plist; qlist->Cotype = (c? NUCLEUS : NOISE); /* noise or nucleus */ qlist->otype = qlist->Cotype; qlist->otconf = 100; re_use_if_poss(&kid1,kcont); kid1.no = -1; return(0); } /* * N E W D I S P -- * */ static newdisp() { displayall(kcont,0); return(0); } /* * R E D R A W * */ static void redraw() { if (notgood(0)) return; kdisplay(&kid1,kcont); } /* * D O L A R G E * */ void dolarge() { int xsize, ysize, line1, line2, line3, col, length; static int ideo_size = 600; struct chrom_data *iptr = NULL; char tstring[100],cstring[100],kstring[100]; if (kid1.no < 0) return; setmsv(NULL); length = enlarge(kcont,kid1.kclass); findtsize(&xsize,&ysize); tsize(96,96); line1 = (alc->ddgschannel->maxy << alc->ddgschannel->yshift) - 400; line2 = line1 - 260; line3 = line2 - 260; col = 400; sprintf(tstring,"Case %s %s %d ",alc->nameids.case, alc->nameids.slide, alc->nameids.cellno); textclass(tstring+strlen(tstring),kid1.kclass+1); textfn(tstring,&line1,&col); cstring[0] = '\0'; kstring[0] = '\0'; newmenu("Enlarge options"); cmmd("title;%60S%-+d%-+d%f",tstring,&line1,&col,textfn); cmmd("karyotype;%60S%-+d%-+d%f",kstring,&line2,&col,textfn); cmmd("comment;%60S%-+d%-+d%f",cstring,&line3,&col,textfn); cmmd("ideogram;%?d%-+d%-+d%f",&ideo_size, length, &iptr, ideogram); cmmd("profile;%-+d%f", kid1.kclass, profiles); while (thismu()) ; if (iptr) free_ideogram(iptr); tsize(xsize,ysize); showkary(); if (cellonktype) celloverlay(&cellonktype); setmsv(kycurs); putprompt(); } /* * I D E O G R A M -- * */ static int ideogram(size, length, chptr) int *size, length; struct chrom_data **chptr; { FILE *fp; int res, ilength; char tbuf[20], s[100], *getspec(); static int dispy=1800, scale=12; if (*chptr) { intens(0); draw_ideogram(*chptr, 300, dispy, scale); free_ideogram(*chptr); *chptr = NULL; } if (*size > 750) { *size = 900; res = P900; } else if (*size < 450) { *size = 300; res = P300; } else { *size = 600; res = P600; } textclass(tbuf,kid1.kclass+1); sprintf(s, "/dd/params/%s.col",getspec()); fp = fopen(s,"r"); printf("Searching for '%s' at %d\n",tbuf,*size); *chptr = get_ideogram(fp,tbuf,res); fclose(fp); if (*chptr) { intens(1); colour(GREYCOLS); ilength = (*chptr)->p_length + (*chptr)->q_length + (*chptr)->sat_length; scale = length / ilength; if (scale % 2) scale++; dispy = 256 + ((*chptr)->q_length * scale); draw_ideogram(*chptr,300,dispy,scale); } else printf("Can't find ideogram data\n"); } #define ENLARGE_FACTOR 150 /* Percentage enlargement by interpolation */ #define ENLARGE_SCALE 16 /* Enlarged object display scale */ static profiles (class) int class; { register struct chromosome *nobj; register int i, num; register struct pframe *f; struct kident kid1; int width, fx; num = 0; for (i=0; imol[kid1.no]; f = kcont->ivf + kid1.no; f->scale = ENLARGE_SCALE; f->dy = 256; width = f->scale * ENLARGE_FACTOR * (nobj->idom->lastkl - nobj->idom->kol1)/100; if (num == 0) fx = 1024+128; f->dx = fx + width/2; enprof(kcont->mol[kid1.no], f); fx += 2*(128 + width); num++; } } enprof(obj,f) struct object *obj; struct pframe *f; { struct iwspace iwsp; struct gwspace gwsp; struct object *h,*makemain(); struct histogramdomain *hdom, *makehistodmn(); register GREY *g; register int *hv,n,l,l1; struct pframe lf; l1 = obj->idom->line1; hdom = makehistodmn(1,obj->idom->lastln - l1 + 1); hdom->r = 0; h = makemain(13,hdom,NULL,NULL,NULL); initgreyscan(obj,&iwsp,&gwsp); while (nextgreyinterval(&iwsp) == 0) { g = gwsp.grintptr; l = iwsp.linpos - l1; n = iwsp.colrmn; hv = hdom->hv + l; while (n-- > 0) *hv += *g++; } histovnorm(h,48); _strass(&lf,f,sizeof(struct pframe)); hdom->k = lf.ox; hdom->l = lf.oy; lf.dx += 192; /* * Upside-down display of chromosome - change origins. * The enlarged chromosome (in the slave) will be about * 50% longer than the one we have here. */ if (lf.ix < 0) { lf.ix = -lf.ix; hdom->l -= (obj->idom->lastln - obj->idom->line1); } /* * Increase Y scale by 50%, but X-scale decreased */ lf.scale = lf.scale/2; lf.iy *= 3; colour(GREYCOLS); /* black */ picframe(h,&lf); } histovnorm(obj,maxval) struct object *obj; { register struct histogramdomain *hdom; register int i, maxh, *h; if (wzcheckobj(obj) > 0 ) return(1); hdom = (struct histogramdomain *) obj->idom; h = hdom->hv; maxh = 0; for (i=0; inpoints; i++) { if (*h > maxh) maxh = *h; h++; } h = hdom->hv; for (i=0; inpoints; i++) { *h = *h * maxval / maxh; h++; } return(0); } static textfn(str,line,col) char *str; int *line,*col; { colour(OVERLAY2); moveto(*col,*line-48); pixbegin(8,1,1,(alc->ddgschannel->lineln << alc->ddgschannel->xshift) - *col,240); pixel(0); pixend(); moveto(*col,*line); text(str); } /* * M O V E V E R T * * Do this using obj->plist->dispopts, which is interpreted * by function "setframe()" (karysubs1.c). The move is coded * as a positive or negative number. */ movevert() { register struct chromplist *plist; register int vertinc, thm, MOV_CMD; static int incr=2; newmenu("Move object down or up"); cmmd("down");mouse(LEFTBT); cmmd("up");mouse(RIGHTBT); cmmd("coarse down");mouse(LONGLB); cmmd("coarse up");mouse(LONGRB); cmmd("movement increment;:k40<1/10>%d",&incr);MOV_CMD = mmcmd; while (thm = thismu()) { if (notgood(0)) continue; plist= kcont->mol[kid1.no]->plist; vertinc = plist->dispopts / plist->dispor; switch(thm) { default: break; case 1: vertinc += incr; break; case 2: vertinc -= incr; break; case 3: vertinc += (10*incr); break; case 4: vertinc -= (10*incr); break; } if (thm != MOV_CMD) { unkdisplay(&kid1,kcont); plist->dispopts = vertinc * plist->dispor; kdisplay(&kid1,kcont); } } } /* * S C R E E N O P T -- * */ static screenopt() { int (*linkerbug)(); int opt, Res_cmd, single = 1, all = 1; char string[8]; dostring(&all, string); newmenu("Class and object presentation options"); cmmd("single/all;%+t:k40%-s%f", &all, string, dostring); cmmd("auto-straighten;:k40%+i%-+d%+i%f", KARYOTYPE, &all, 1, enhancement);mouse(LONGRB); cmmd("recover;:k40%+i%-+d%+i%f", KARYOTYPE, &all, 4, enhancement); mouse(LONGMB); cmmd("manual-straighten selected chromosome;%+i%+i%+i%f",KARYOTYPE, &single, 6, enhancement);mouse(LONGLB); Res_cmd = cmmd("rescale;<1/24>%d%f",&kcont->kdispscale,showkary); cmmd("tidy;%f",tidykary); mouse(LEFTBT); cmmd("enlarge selected class;%f",dolarge);mouse(MIDBT); if (alc->devel) { cmmd("move all down;%d%f",&DOWN,newdisp); } cmmd("vertical movement;%f",movevert);mouse(RIGHTBT); cmmd("show reduced metaphase;:k38%t%f",&cellonktype,celloverlay); if (alc->devel) { cmmd("redraw selected chromosome;%f", redraw); if (alc->devel > 10) cmmd("hard copy; type<1/3>%?d%g",&htype,hdcopy); } while (opt = thismu()) if ((opt == Res_cmd) && (cellonktype)) celloverlay(&cellonktype); } /* * C H E K A C T V -- * */ static chekactv() { register int i=0; register SMALL *activelist = kcont->acl; for (i=0; i< kcont->maxnumber; i++) { if (objlist[i]) { *activelist |= ACTIVE; kcont->rol[i] = objlist[i]; } else *activelist &= ~ACTIVE; ++activelist; } } /* * U P K A R Y -- * */ upkary(old) { register int i; if (!(objlist=(struct chromosome **) kcont->mol)) return(0); for (i=0; imaxnumber; i++) kcont->kol[i] = objlist[i]; kcont->kdispscale = KSCALE; /* Default kary scale */ SI_attach(kcont); /* attach SI to kcont - segfix.c */ if (!kcont->SI->initialised) seg_control_init(kcont->SI); lin_colour_lut(); /* Use appropriate LUT */ if (old) { chekactv(); karyogram(kcont) ; displayall(kcont,0); } else kary(kcont); } /* * K I N T E R A C T * * gc is an array indicating what is in memory now. * it is used to determine whether we need to read original * obj's for reseg or not (currently we dont use it) */ kinteract(phase,gc) int phase, *gc; { int Sel_cmd, Cho_cmd, View_cmd, Elim_cmd, Rot_cmd, Res_cmd; int Flex_cmd; int i, enhanced = 0, single = 1; char buffer[40], tmp_ccl[4], tmp_psl[4]; extern seg_display_opts(); gotcell = gc; buffer[0] = '\0'; karychanged = 1; /* K-type needs filing */ cs[0] = ccl[0] = ps[0] = psl[0] = ' '; tmp_ccl[0] = tmp_psl[0] = '\0'; kickkry(&kid1,&kid2); initselect( alc->m2s, &kid1, &cursor, 1); setmsv(kycurs); state = NORMAL; kid1.no = -1; kid1.kclass = ABNORMAL+1; if (alc->debug) fprintf(debug_channel, "KINTERACT - downmenu()\n"); downmenu(); newmenu("Correct Karyotype"); cmmd("select;class %?3s position %?1s%f",cs,ps,pickobj);Sel_cmd = mmcmd; cmmd("choose for transfer;:k30 class %?3+s%-s :k40 position %?1+s%-s%f", tmp_ccl,ccl,tmp_psl,psl,chgobj); mouse(MIDBT); Cho_cmd = mmcmd; cmmd( ":k8;new class;:k30 <^[{1[0-9]}{2[0-5]}{[1-9]}{[XYAxya]}]$>%?s%g", cs,chgcls);mouse(RIGHTBT); cmmd(":k8;xchange;:k30 class %?3s :k40 position %?1s%f" ,cs,ps,exchange); mouse(LONGRB); cmmd("invert;%f",invert);mouse(LEFTBT); cmmd("mark;%?S%f",buffer,markit); cmmd("rotate;%+i%+i%+i:k30 degrees:k20%?d%f", KARYOTYPE, &single, 3, &ang, enhancement); mouse(LONGMB); Rot_cmd=mmcmd; cmmd("eliminate noise;%+i%f",0,noiseor);Elim_cmd=mmcmd; if (alc->devel) cmmd("eliminate nucleus;%+i%f",1,noiseor); cmmd("view metaphase;%f",cellview);View_cmd=mmcmd; if (phase == 0 || alc->devel) { cmmd("resegment"); mouse(LONGLB);Res_cmd=mmcmd; } else cmmd("resegment - not available in karyotype review"); cmmd("class and object presentation options;%g",screenopt); cmmd("enhancement options;%+i%+i%f",KARYOTYPE, phase, enhanceopt); cmmd("display modes and options;%+i%f",1,seg_display_opts); if (alc->options & OPT_FLEX) { cmmd ("flexible screen;%+i%f", 1, flex_Main); Flex_cmd = mmcmd; } while (1) { rebox(1); while (thismu()) { if (nncmd == Res_cmd) { enhanced = 0; /* * resegment from karyotype */ /* if (gotcell[1] > 0) { for (i = 0; i < kcont->maxnumber; i++) { kcont->ool[i] = kcont->mol[i]; fprintf(stderr, " i=%d plist->otype %d\n", i, kcont->ool[i]->plist->otype); } } else */ /* * check if objs different */ for (i = 0; i < kcont->maxnumber; i++) { if (kcont->mol[i] != kcont->kol[i]) { fprintf(stderr, "Please restore chromosome(s) before resegmentation.\007\n"); putprompt(); enhanced = 1; break; } } if (!enhanced) { setmsv(NULL); endselect(&cursor,1); if (alc->debug) fprintf(debug_channel, "KINTERACT - upmenu() - return(SEGMENT)\n"); upmenu(); return(SEGMENT); } } if ((nncmd != Sel_cmd) && (nncmd != Cho_cmd) && (nncmd != View_cmd)) karychanged = 1; if ((nncmd == Rot_cmd) || (nncmd == Elim_cmd) || (nncmd == View_cmd)) kycurs(); if (nncmd == Flex_cmd) { kickkry(&kid1,&kid2); initselect( alc->m2s, &kid1, &cursor, 1); setmsv(kycurs); } } setmsv(NULL); /* dont listen to the mouse movements */ endselect(&cursor,1); upmenu(); return(EXIT); } } /* * K T Y P E O P T S * * Phase = 0 for orig ktype operations * 1 for ktype review */ ktypeopts(phase) int phase; { int File_cmd, Com1_cmd, Com2_cmd, Chk_cmd, End_cmd, Pat_cmd; int notput, zero = 0; char workbuf[100]; int (*linkerbug)(), strncpy(); Chk_cmd = 0; erasecursor(); unbacklight(); /* Remove any backlighted stuff */ rebox(0); /* Un-display box and class */ if (cellonktype) celloverlay(&zero); if (phase == 0) { karyheadfill(alc->cell_h); } else { alc->cell_h->version = HEADER_VERSION; } if ((alc->ddgschannel->type == FS_VIRTUOSO) || (alc->ddgschannel->type == FS_VIRTUOSO_INVERT) ) dispidbox(4550,465,1); else /* this ought to be vme-512 but is also sensible default */ dispidbox(3036,438,1); /* Display id box in bottom right corner */ downmenu(); newmenu( "Karyotype options"); cmmd("file karyotype");File_cmd = mmcmd; cmmd("karyotype;?-?%40S",alc->cell_h->krtype); linkerbug = strncpy; cmmd("comment 1;:k38%-s?-?%+S%+i%f;t4",alc->cell_h->comments[0],workbuf,TEXTLENGTH-1,linkerbug);Com1_cmd = mmcmd; cmmd(" 2;:k38%-s?-?%+S%+i%f",alc->cell_h->comments[1],workbuf,TEXTLENGTH-1,linkerbug);Com2_cmd = mmcmd; linkerbug = setname; cmmd("NEF coordinate;:k38%+S%-39s%f",workbuf,alc->cell_h->patnam,linkerbug); Pat_cmd = mmcmd; cmmd("hardcopy karyotype;%f",laserktype); cmmd("end karyotype interaction");End_cmd = mmcmd; if ((getuid()&0xffff0000) == 0) cmmd("checked OK;%-s%-s",alc->cell_h->supid,alc->cell_h->supdate);Chk_cmd = mmcmd; while (thismu()) { if (nncmd == File_cmd) { notput = 0; alc->nameids.type = KARYFILE; while (1) { if (notput || !makefilename(alc->picname, &alc->nameids)) { if (getid(KARYFILE,WRITE) == 0) break; } else if (checkoverwrite(alc->dir, alc->picname) == 0) { putprompt(); break; } if (alc->debug) fprintf(stderr,"Cell will be filed to %s\n",alc->picname); if (putkfile(alc->picname,kcont->mol)) { karychanged = 0; putprompt(); break; } notput = 1; } } else if (nncmd == Com2_cmd) { displin(0,Com1_cmd); displin(0,Com2_cmd); putprompt(); if ( (alc->ddgschannel->type == FS_VIRTUOSO) || (alc->ddgschannel->type == FS_VIRTUOSO_INVERT) ) dispidbox(4550,465,1); else /* this ought to be vme-512 but is also sensible default */ dispidbox(3036,438,1); /* Display id box in bottom right corner */ } else if (nncmd == End_cmd) { if (karychanged) { screengo(ENDLINE,0); printf("Warning - Karyotype not saved - exit ? "); if (!tryboth(1)) { putprompt(); break; } } endselect(&cursor, 1); setmsv(NULL); upmenu(); return(QUIT); } else if (Chk_cmd && nncmd == Chk_cmd) { strncpy(alc->cell_h->supid,alc->user,OPERLENGTH); strncpy(alc->cell_h->supdate,alc->mydate,20); displin(0,Chk_cmd); putprompt(); } else if ( (alc->ddgschannel->type == FS_VIRTUOSO) || (alc->ddgschannel->type == FS_VIRTUOSO_INVERT) ) dispidbox(4550,465,1); else /* this ought to be vme-512 but is also sensible default */ dispidbox(3036,438,1); /* Display id box in bottom right corner */ } if ((alc->ddgschannel->type == FS_VIRTUOSO) || (alc->ddgschannel->type == FS_VIRTUOSO_INVERT)) dispidbox(4550,465,0); else /* this ought to be vme-512 but is also sensible default */ dispidbox(3036,438,0); /* Display id box in bottom right corner */ if (cellonktype) celloverlay(&cellonktype); fprintf( output, " Continue interaction ...\n"); putprompt(); upmenu(); return(KARYOTYPE); } /* * K Y C U R S * */ kycurs() { if (alc->m2s->moving) tmousecurs(); else { if (alc->m2s->clear) { if (kylocate(&cursor)) { textclass ( cs,(cnum = kid1.kclass)+1); if (kid1.no >= 0 ) textpos( ps, (pnum = kid1.pos -1 )); else *ps = ' '; displin(0,1); putprompt(); } } } } /* * C H E K R E A D * */ chekread(j) register int j; { SMALL aclsav[MAXOBJS]; register int i; int typesave, maxnumsav, stat; struct cell_header cellhead; stat = 0; if (!gotcell[j] && (j == 0)) { for (i=0; iool[i] == kcont->mol[i]) kcont->ool[i] = NULL; aclsav[i] = kcont->acl[i]; } maxnumsav = kcont->maxnumber; typesave = alc->nameids.type; alc->nameids.type = CELLFILE; makefilename(alc->picname,&(alc->nameids)); _strass(&cellhead,alc->cell_h,sizeof(struct cell_header)); if (opencfile() != -1) { if (stat = readcfile(j)) { gotcell[j] = 1; } closecfile(); } if (stat) lin_colour_lut(); /* Read OK, now set lut */ alc->nameids.type = typesave; makefilename(alc->picname,&(alc->nameids)); _strass(alc->cell_h,&cellhead,sizeof(struct cell_header)); if (kcont->maxnumber < maxnumsav) kcont->maxnumber = maxnumsav; for (i=0; iacl[i] = aclsav[i]; } else stat = 1; return(stat); } /* * S H O W C E L L -- Display cell in original form in original frame * * This requires modifying object list to reactivate all last generation * noise and nuc bits * Further problems in ktype review * when what is read from original cell file is generally * insufficient to recreate entire set of original objects in ool. */ showcell() { SMALL aclsav[MAXOBJS]; int i; for (i=0; imaxnumber; i++) { aclsav[i] = kcont->acl[i]; if (kcont->ool[i] != NULL && !kcont->ool[i]->plist->history[1]) kcont->acl[i] |= ACTIVE; } cellframe(kcont); fast(); mpclear(kcont); mpcpic(kcont,GREYCOLS,1); slow(); if (kid1.no >= 0 && kid1.no < kcont->maxnumber && kcont->ool[kid1.no] != NULL) boxobj(kcont->ool[kid1.no],kcont->f,OVERLAY2); kcont->current_obj = kid1.no + 1; for (i=0; imaxnumber; i++) kcont->acl[i] = aclsav[i]; } /* * K I C K K R Y -- * */ kickkry(k1,k2) struct kident *k1,*k2; { colour(GREYCOLS); kickkry1(k1,k2); /* pokes kreseg.c */ } /* * identify which chromosome user is referring to when input is typed. * fill details into the identification structure */ kdentify(k,class,pos) register struct kident *k; { register struct kclasscont *kccp; kccp = kcc+class; if (class>=0 && class<=alc->scrf->undefclass && pos >= 0 && pos < MAXCHILD) { k->no = kccp->kno[pos]; if (k->no >= 0) { k->kclass = class; k->pos = pos+1; k->stackpos = kccp->sp[pos]; return(1); } } return(0); } /* * M A R K I T -- * */ void markit(str) char *str; { register struct chromplist *iplist; struct pframe f; if (!objlist||!objlist[kid1.no]) return; if (notgood(1)) return; setframe(&f,&kid1,kcont); iplist = objlist[kid1.no]->plist; if (str && *str) { colour(OVERLAY1); intens(1); tsize(50,50); dispstring(str,f.dx - (50 * strlen(str) / 2),f.dy-190); iplist->dispmark |= PERM_MARK; *str = '\0'; } else { if (!(iplist->dispmark & PERM_MARK)) { iplist->dispmark |= PERM_MARK; dispmark(&f); } else { iplist->dispmark &= ~PERM_MARK; intens(0); dispmark(&f); intens(1); } } } showkary() { displayall(kcont,0); rebox(1); } /* * T E X T C L A S S -- */ textclass(s,k) register char *s; int k; { if (k<1) k = 1; else if (k > ABNORMAL) k = ABNORMAL; strcpy(s,alc->scrf->disppos[k-1].tag); } /* * S H O W C L A S S -- Display class of current chrom in coloured box * at bottom richt of screen */ void showclass(k,onoff) { char str[9]; static int xsize=320, ysize=200; int newxsize; if (cellonktype) return; if ((alc->scrf->chromclass.x == 0) && (alc->scrf->chromclass.y == 0)) return; moveto (alc->scrf->chromclass.x,alc->scrf->chromclass.y); if (!onoff) { wclear(xsize,ysize,0); } else { intens(1); textclass(str,k); newxsize = strlen(str) * 120 + 80; if (newxsize < xsize) { moveto (alc->scrf->chromclass.x+newxsize,alc->scrf->chromclass.y); wclear(xsize-newxsize,ysize,0); moveto (alc->scrf->chromclass.x,alc->scrf->chromclass.y); } xsize = newxsize; wclear(xsize,ysize,OVERLAY2); colour(OVERLAY1); moveto(alc->scrf->chromclass.x + 40,alc->scrf->chromclass.y + 20); tsize(120,100); text(str); } } /* * R E B O X -- * */ rebox(onoff) { struct pframe *fr; unbox(); /* delete previous box, if any */ if (!onoff) { showclass(0,0); return(0); } intens(1); showclass(kid1.kclass + 1,1); if ( kid1.no >= 0 && kid1.no < kcont->maxnumber) { boxobj ( kcont->mol[kid1.no], kcont->ivf +(kid1.no) ,OVERLAY2); fr = kcont->ivf +kid1.no ; abscursor(fr->dy,fr->dx); }; } /* * K C C W H E R E * */ struct kclasscont *kccwhere () { return (kcc); } /* * D O S T R I N G -- copy whether single or all into given string * */ dostring(single, string) int *single; char *string; { if (*single) strcpy(string, "single"); else strcpy(string, "all"); }