/* * K A R Y S U B S 2 . C -- More karyotype interaction * * Jim Piper * Image Recognition Systems * 720 Birchwood Boulevard * Birchwood Science Park * Warrington * Cheshire * WA3 7PX * * Date: 23rd January 1984 * * Copyright (c) and intellectual property rights Image Recognition Systems (1988) * * * Modifications * * 13 Oct 1994 JimP make MAXCLASS dependent on species: alc->scrf->undefclass * 25 Feb 1992 Joanne Added extra test in firstclass() to avoid * empty karyogram locations while there are * chrom. of that class in the stack line * 10 Jun 1991 ih Check for valid mol && mol->plist in various places * 7 Feb 1991 CAS voids * 24 Jul 1989 SEAJ Removed section in classify() which sets all * objects to be chromosomes with conf = 100. * 4 Jul 1989 SEAJ Added new functions newCpgroup & newpgroup, * newclass nolongewr sets pgroup. * 2 Dec 1988 CAS Make firstclass use plist if set up * displayall,hidenstackcount,kdisplay,unkdisplay * remove_class here in effort to * reduce duplication * 2 Dec 1988 CAS/SEAJ Moved newclass here from karysubs1 (kyy reasons) * and changed params to it and firstclass and swapclass * Wrote a proper firstclass * 02-09-87 jimp@IRS Tsize in dispmark * GJP 05-03-87 Use kary_exit not exit * jimp 05-02-87 NSTACKPOS removed to chromanal.h * jimp 04-02-87 stacktop() routine added for top-of-stack. * jimp 03-02-87 tellstack() returns stackocc value cleanly. * jimp 17-12-86 Noise/composites not confirmed by operator must * have otype/Cotype = CHROMOSOME, otherwise they * will disappear after writing to disc. * jp 09-12-86 Merge of karylib and kyy versions into karylib * jp 13-11-86 Merge of karylib and kyy versions * jp 12-11-86 includes * JP 28-10-86 Non-chromosome active objects classified as * abnormal in "classify()" (result of operator not * confirming machine object typing). * JP 17-10-86 display.h used * 12/5/86 GJP Position of Marker * 27/1/86 Denis stack notes number in stackocc */ #include #include #include #include #include #include #include #include extern struct allkontr *alc; int stackocc[NSTACKPOS+1]; extern struct kclasscont kcc[]; /* * get a stack location */ stack(n) /* and note number */ { register int i; for (i=1; i<=NSTACKPOS; i++) { if (stackocc[i] <= 0) { stackocc[i] = n+1; return(i); } } fprintf(stderr,"stack(): object stack overflow\n"); kary_exit(12); } /* * release a stack location */ unstack(i) { stackocc[i] = -1; } /* * report a stack location */ int tellstack(i) { return(stackocc[i]); } /* * report highest used stack location */ int stacktop() { register int i,iused; iused = 0; for (i=1; i<=NSTACKPOS; i++) if (stackocc[i] > 0) iused = i; return(iused); } /* * make a mark to draw attention to a particular chromosome */ dispmark(f) struct pframe *f; { static char *mark = "^"; int x,y; findtsize(&x,&y); colour(OVERLAY1); tsize(120,100); dispstring(mark,f->dx-60,f->dy-264); dispstring(mark,f->dx-60,f->dy-272); dispstring(mark,f->dx-60,f->dy-280); tsize(x,y); } /* * read chromosome class, one of figure 1-22, letter A, X, Y. */ getclass(in) FILE *in; { register int i, class; while ((class = getc(in)) == ' ') ; class &= 127; if (class == 'A' || class == 'a') return(24); else if (class == 'X' || class == 'x') return(22); else if (class == 'Y' || class == 'y') return(23); else if (class < '0' || class > '9') return(-1); else { class -= '0'; i = getc(in); if (i < '0' || i > '9') { ungetc(i,in); return(class-1); } else return(10*class + i-'0'-1); } } /* * read chromosome position in a class - * specified by upper or lower case letter */ getpos(in) FILE *in; { int pos; while ((pos = getc(in)) == ' ') ; pos &= 127; if (pos >= 'a' && pos <= 'z') return(pos-'a'); else if (pos >= 'A' && pos <= 'Z') return(pos-'A'); else return(-1); } /* * swap the class of two objects in identifying structures k1, k2. */ swapclass(k1,k2,kcont,disppos) struct kident *k1, *k2; struct kdisppos *disppos; { int c1, c2; c1 = k1->kclass; c2 = k2->kclass; remove_class(k1); remove_class(k2); newCpgroup(k2, c1, kcont); newclass(k2,c1,kcont,disppos); newCpgroup(k1, c2, kcont); newclass(k1,c2,kcont,disppos); } /* * F I R S T C L A S S -- * * This routine looks to see if data is previusly karyotyped and if * so tries to put things back in the same place */ firstclass(o,kcont,disppos) struct kcontrol *kcont; struct kdisppos *disppos; { struct kident kid; int class; kid.no = o; if (kcont->mol&&kcont->mol[o]&&kcont->mol[o]->plist) { if (kcont->mol[o]->plist->Cpgroup) class = kcont->mol[o]->plist->Cpgroup; else class = kcont->mol[o]->plist->pgroup; if ((kcont->mol[o]->plist->disppos > 0) && (kcont->mol[o]->plist->disppos < disppos[class-1].npos)) reposition(&kid,class-1,kcont,disppos); else newclass(&kid,class-1,kcont,disppos); } } /* * R E P O S I T I O N -- * * re-insert object from previously classified file in specified class * at specified position */ reposition(k,c,kcont,disppos) register struct kident *k; struct kcontrol *kcont; struct kdisppos *disppos; { register struct kclasscont *kc; register int i; register struct chromplist *plist; if (kcont->mol&&kcont->mol[k->no]&&kcont->mol[k->no]->plist) plist=kcont->mol[k->no]->plist; else return(0); if ((c < 0) || (c > alc->scrf->undefclass)) c = alc->scrf->undefclass; /* Abnormal if silly class */ kc = kcc + c; k->kclass = c; /* * Make sure there is somewhere to put it - if not newclass can cope */ if ((plist->disppos >= MAXCHILD) || (kc->kno[plist->disppos -1] != -1)) newclass(k,c,kcont,disppos); else { if (kc->maxn < plist->disppos) kc->maxn = plist->disppos; kc->n++; k->pos = plist->disppos; kc->kno[k->pos-1] = k->no; /* * check whether a stack position needs to be allocated */ if (k->pos > disppos[c].npos) k->stackpos = stack(k->no); else k->stackpos = -1; kc->sp[k->pos-1] = k->stackpos; } } /* * N E W C P G R O U P */ newCpgroup(k,c,kcont) register struct kident *k; int c; struct kcontrol *kcont; { if (kcont->mol&&kcont->mol[k->no]&&kcont->mol[k->no]->plist) { if ((c < 0) || (c > alc->scrf->undefclass)) c = alc->scrf->undefclass; /* Abnormal if silly class */ kcont->mol[k->no]->plist->Cpgroup = c+1; } } /* * N E W P G R O U P */ newpgroup(k,c,kcont) register struct kident *k; int c; struct kcontrol *kcont; { if (kcont->mol&&kcont->mol[k->no]&&kcont->mol[k->no]->plist) { if ((c < 0) || (c > alc->scrf->undefclass)) c = alc->scrf->undefclass; /* Abnormal if silly class */ kcont->mol[k->no]->plist->pgroup = c+1; } } /* * N E W C L A S S -- insert object in specified class */ newclass(k,c,kcont,disppos) register struct kident *k; int c; struct kcontrol *kcont; struct kdisppos *disppos; { register struct kclasscont *kc; register int i; if ((c < 0) || (c > alc->scrf->undefclass)) c = alc->scrf->undefclass; /* Abnormal if silly class */ /* * add to new class. 3 cases: * - nothing in new class - no problem * - number of object in new class == high water mark. * add object, increase high water mark. * - fewer objects than high water mark. Find first empty slot. */ kc = kcc + c; k->kclass = c; if (kc->n == 0) { kc->maxn = k->pos = kc->n = 1; kc->kno[0] = k->no; } else if (kc->n == MAXCHILD) { fprintf(stderr, "Newclass: class %d contents structure full\n", c+1); return(0); /* SOMETHING WILL BE LOST HERE. */ } else if (kc->n == kc->maxn) { kc->kno[kc->n] = k->no; kc->n++; kc->maxn++; k->pos = kc->n; } else { for (i=0; imaxn; i++) if (kc->kno[i] < 0) { k->pos = i+1; kc->kno[i] = k->no; break; } kc->n++; } if (kcont->mol&&kcont->mol[k->no]&&kcont->mol[k->no]->plist) kcont->mol[k->no]->plist->disppos = k->pos; /* * check whether a stack position needs to be allocated */ if (k->pos > disppos[c].npos) k->stackpos = stack(k->no); /* get stack pos, give number */ else k->stackpos = -1; kc->sp[k->pos-1] = k->stackpos; } /* * C L A S S I F Y -- if object active, but not classified make it abnormal. * */ classify(kc) struct kcontrol *kc; { register struct chromplist *plist; register i,j,ac; for (i=0; imaxnumber; i++) { ac = kc->acl[i]; ac &= ACTIVE; if ((ac!=0)&&kc->mol&&kc->mol[i]&&kc->mol[i]->plist) { plist = kc->mol[i]->plist; if (plist->otype <= CHROMOSOME) { if (plist->pgroup <= 0) { fprintf(stderr,"unclassified CHR %d called ABNORMAL\n",i); plist->pgroup = 25; } } else { /* * This is likely to be a composite or noise as determined * by the feature measurement but not confirmed by operator */ plist->pgroup = 25; } /* * Commented out as these should not be set here...SEAJ * plist->Cotype = plist->otype = CHROMOSOME; * plist->otconf = 100; */ } } } /* * K D I S P L A Y -- * * display a chromosome at the position implied by the * identification structure "k", which includes the chromosome * class and an ordinal within the class among other information. * Insert suitable frame values in kcont->ivf frame array. */ kdisplay(k,kcont) register struct kident *k; register struct kcontrol *kcont; { struct chromosome *obj = kcont->mol[k->no]; register struct chromplist *plist = obj->plist; struct pframe *f = kcont->ivf + k->no; /* * set up the frame, display marks, etc. */ kdsetup(k,kcont); /* * display the object */ colour(GREYCOLS); picframe(obj,f); /* * if temporary highlight required, draw a rectangle round the object * It is up to the user to ensure that kdisplay with intens(1) * follows the setting of TEMP_MARK_REQ. Then the next unkdisplay * or dispall call will eliminate the rectangle. */ if (plist->dispmark & TEMP_MARK_REQ) { plist->dispmark |= TEMP_MARK_DONE; plist->dispmark &= ~TEMP_MARK_REQ; colour(OVERLAY1); bdisprect(obj,f); } } /* * delete a chromosome and its label, mark, etc., from screen */ unkdisplay(k,kcont) register struct kident *k; register struct kcontrol *kcont; { register struct chromplist *plist = kcont->mol[k->no]->plist; intens(0); /* * delete the rectangle draw by the TEMP_MARK handling in kdisplay, * by setting TEMP_MARK_REQ, calling kdisplay, unsetting it. */ if (plist->dispmark & TEMP_MARK_DONE) plist->dispmark |= TEMP_MARK_REQ; kdisplay(k,kcont); /* * Then finally get rid of the TEMP_MARK_DONE bit */ plist->dispmark &= ~TEMP_MARK_DONE; unbox(); /* undisplay rectangle also, just in case */ intens(1); } /* * H I D D E N S T A C K C O U N T --- Count number of hidden objects * on stack * */ hiddenstackcount() { static int hidden_count = -1; char s[20]; colour(OVERLAY1); tsize(50,50); if (hidden_count > 0) { intens(0); sprintf(s,"(%d hidden objects)",hidden_count); moveto(200,8); text(s); } intens(1); hidden_count = stacktop() - VIEWED_STACK; if (hidden_count > 0) { sprintf(s,"(%d hidden objects)",hidden_count); moveto(200,8); text(s); } } /* * remove this object from the class it curently occupies */ remove_class(k) struct kident *k; { struct kclasscont *kc = kcc + k->kclass; kc->n--; kc->kno[k->pos-1] = -1; if (k->stackpos >= 0) { unstack(k->stackpos); kc->sp[k->pos-1] = -1; } } /* * initial orientation : * invert if area c.i. > 50 (should really be length c.i.), * or if c.i. unknown then if mwdd[0] positive */ initialorientation(i,kc) struct kcontrol *kc; { register struct chromplist *plist; plist = kc->mol[i]->plist; if (plist->dispor != 1 && plist->dispor != -1) { if (plist->cindexa > 50) plist->dispor = -1; else if (plist->cindexa == -1 && plist->mwdd[0] > 0) plist->dispor = -1; else plist->dispor = 1; } }