/* * prof_cands.c Jim Piper 04-09-86 * * Find centromere candidates from profile associated with a mid-points polygon, * returned as a position in mid-points polygon, * inserted in a candidates structure. * * The parameter "quantum" quantises the depth to which a local minimum * must sink below the adjacent maxima in order to be recognised as such. * * MODIFICATIONS * ------------- * jimp 07-06-90 Added type3_cand() function * st 28-01-87 put in "cnd->candtype = 1;" */ #include #include #include prof_basics(prof,quantum,chc) struct object *prof; struct chromcands *chc; { register int *hv; register i,end,max; register struct histogramdomain *hdom; hdom = (struct histogramdomain *)prof->idom; end = hdom->npoints; /* * find max value and use to determine quantisation of profile */ max = 0; hv = hdom->hv; for (i=0; i max) max = *hv; hv++; } quantum = max*quantum/100; chc->profmax = max; chc->quantum = quantum; } prof_cands(prof,chc) struct object *prof; struct chromcands *chc; { register int *hv; register i,m,quantum; int curmin, curmax, pt, orig, end; register struct histogramdomain *hdom; register struct cand *cnd = chc->cands; orig = 0; hdom = (struct histogramdomain *)prof->idom; end = hdom->npoints; quantum = chc->quantum; /* * search profile for extrema */ m = 1; curmax = 0; hv = hdom->hv; for (i=0; i curmax) { curmax = *hv; pt = i; } else if (*hv < curmax - quantum) { m = -m; curmin = *hv; pt = i; } break; case -1: /* looking for minimum */ if (*hv < curmin) { curmin = *hv; pt = i; } else if (*hv > curmin + quantum) { /* * If profile value is nearly zero something * very funny has happened and we * certainly don't want to know !! */ if (100*curmin > chc->profmax) { cnd->profpos = pt; cnd->u.sy.profval = curmin; chc->ncands++; cnd->candtype = 1; cnd->candnum = chc->ncands; cnd++; } m = -m; curmax = *hv; pt = i; } break; } hv++; } } /* * generate a randomly placed candidate: * if one candidate found so far, in the larger * segment between it and one or other chromosome end; * if no candidates found so far, randomly along chromosome; * if more than one candidate, choose the first one, * treat as the single candidate above. */ type3_cand(prof,chc) struct object *prof; struct chromcands *chc; { register int *hv; register int i,m,quantum; int end,pos,which,npcands; register struct histogramdomain *hdom; register struct cand *cnd; hdom = (struct histogramdomain *)prof->idom; end = hdom->npoints; hv = hdom->hv; cnd = chc->cands; npcands=0; for (i=0; incands; i++,cnd++) if (cnd->candtype == 1) npcands++; if (npcands >= 1) { cnd = chc->cands; while (cnd->candtype != 1) cnd++; pos = cnd->profpos; if (end-pos < pos) pos = newpos(pos,0); else pos = newpos(end,pos); } else if (npcands == 0) pos = newpos(end,0); cnd = chc->cands + chc->ncands; cnd->profpos = pos; cnd->u.sy.profval = hv[pos]; chc->ncands++; cnd->candtype = 3; cnd->candnum = chc->ncands; } /* * return a number between b and e that is * (if possible) between b+8 and e-8 * but is otherwise pseudo-random. At * present this is achieved by cycling * a fractional part of the interval */ static int cyc=0; static int newpos(e,b) { if (e-b < 20) return((e+b)/2); e -= 8; b += 8; cyc++; if (cyc == 5) cyc = 0; return(b + (e-b)*cyc/4); }