/* * dcboxclass.c Jim Piper 09-09-86 * * Dicentric finding system - box classifier. * * MODIFICATIONS * ------------- * 25-10-90 jimp Explicitly reject type 3 candidates at classification stage * * Classifier construction methods * ------------------------------- * Coded as * (feature limit method) + 2*(box expansion method) + 4*(lower limit method) * Feature limit method * -------------------- * ORIGFL - retain only the PC1% at bottom of sorted list of * per-object object minima * ADAPTFL - adapt training set according to number of chromosomes * with candidates. Specifically, if number of objects * with candidates is larger than PC1% of number of objects, * reduce accordingly by retaining only the bottom of * list of per-object minima * Box expansion method * -------------------- * ORIGBE - original := max * PC2 / 100 * MEDINTQBE - median + PC2*interquartile range/100 * Lower limit method * ------------------ * NOLL - none (i.e. zero) * HALFMED - first quartile/2 for features selected by "sll" array * * Candidate selection method * -------------------------- * #ifdef INDMINS - choose minimum feature values independently within chromosome * #ifndef INDMINS - choose feature values associated with minimum width. */ #include #include #include #include #define ORIGFL 0 #define ADAPTFL 1 #define ORIGBE 0 #define MEDINTQBE 1 #define NOLL 0 #define HALFMED 1 dcboxclass(candtype,method,chc,nobjs,nfeat,slf,sll,PC1,PC2,PRINT,pf) struct chromcands *chc; register int *slf; int *sll; FILE *pf; { register int i,j,k; int l,min,minpos,nobjwithcand,cmerecount,compare(); int no2,no4,no34,methodbe,methodfl,methodll; struct chromcands *chcp; register struct cand *cnd; int mins[MAXFEATURES][MAXOBJECTS], pcmm[MAXFEATURES], llim[MAXFEATURES]; int mediana, areas[MAXOBJECTS]; methodll = (method&4)>>2; methodbe = (method&2)>>1; methodfl = method&1; /* * checks */ if (PC1 < 20 || PC1 > 100) { fprintf(pf,"Illegal percentile PC1 = %d\n",PC1); exit(1); } if (PC2 < 20 || PC2 > 500) { fprintf(pf,"Unlikely percentile PC2 = %d\n",PC2); exit(1); } /* * find median area */ chcp = chc; for (i=0; iarea; qsort(areas,nobjs,sizeof(int),compare); mediana = areas[nobjs/2]; /* * stage (1). * --------- * For each selected feature, find the per-object * minimum and place in array. */ nobjwithcand = 0; chcp = chc; for (i=0; iarea >= mediana && chcp->ncands > 0) { cnd = chcp->cands; for (l=0; lncands; l++,cnd++) if (cnd->candtype == candtype) goto TRAIN; continue; /* outer per-object loop */ TRAIN: #ifdef INDMINS for (j=0; jcands; while (cnd->candtype != candtype) { l++; cnd++; } min = cnd->u.af[k]; cnd++; for (; lncands; l++,cnd++) if (cnd->candtype == candtype && min > cnd->u.af[k]) min = cnd->u.af[k]; mins[j][nobjwithcand] = min; } #else INDMINS cnd = chcp->cands; min = cnd->u.sy.width; minpos = 0; cnd++; for (l=1; lncands; l++,cnd++) if (min > cnd->u.sy.width) { min = cnd->u.sy.width; minpos = l; } cnd = chcp->cands + minpos; for (j=0; ju.af[k]; } #endif INDMINS nobjwithcand++; } } /* * stage (2). * --------- * For each selected feature, sort minima into ascending order * * if ORIGFL find PC1'th percentile measured from minimum end. * if ADAPTFL PC1 = min(nobjwithcand, PC1% * nobs), and find * PC1'th percentile from minimum end. * * if ORIGBE multiply PC1'th percentile (above) by PC2% to give * box limit. * if MEDINTQBE find median of values from minimum to PC1'th * percentile and add PC2% * interquartile range to give box limit. */ switch (methodfl) { case ORIGFL: default: if (PRINT) fprintf(pf,"%d percent of %d'th percentile of per-object minima\n",PC2,PC1); PC1 = (nobjwithcand * PC1 + 50)/100 - 1; break; case ADAPTFL: if (PRINT) fprintf(pf,"adapt\n"); PC1 = (nobjs * PC1 + 50)/100 - 1; if (PC1 > nobjwithcand) PC1 = nobjwithcand - 1; break; } no2 = PC1 / 2; no4 = no2/2; no34 = no2+no4; for (j=0; jcands; for (l=0; lncands; l++,cnd++) { cnd->ctype = 0; if (cnd->candtype > 0 && cnd->candtype < 3) { cnd->ctype = 1; for (j=0; ju.af[k] > pcmm[j] || (sll[j] && cnd->u.af[k] < llim[j])) { cnd->ctype = 0; break; } } if (cnd->ctype == 1) cmerecount++; if (PRINT) { fprintf(pf,"Obj %d cand %d",chcp->number,l+1); if (cnd->ctype == 1) fprintf(pf," selected\n"); else fprintf(pf," rejected\n"); } } } switch (cmerecount) { case 0: chcp->btype = ACENTRIC; break; case 1: chcp->btype = MONOCENTRIC; break; case 2: default: if (chcp->area >= mediana) chcp->btype = DICENTRIC; else chcp->btype = DICENTRIC | UNSHURE; break; } } } static compare(a,b) register int *a, *b; { return(*a - *b); }