double median(double *aa, int len) // should be O(len) algorithm { double *b, y ; int t, x, a, n ; ZALLOC(b, len, double) ; n = 0 ; for (a=0; a<len; ++a) { y = aa[a] ; if (isfinite(y)) { b[n] = y ; ++n ; } } if (n==0) fatalx("(median) no valids\n") ; if (n==1) return b[0] ; if (n==2) return 0.5*(b[0]+b[1]) ; sortit(b, NULL, n) ; t = n % 2 ; x = n/2 ; y = b[x] ; if (t==0) y = 0.5*(b[x] + b[x-1]) ; free(b) ; // printf("zzmed: %d %d %d %9.3f\n", len, n, x, y) ; return y ; }
int main (int argc, char **argv) { FILE *ofile; int nlambda = 0; int i, m; double zn, zvar, tw, tail; double *xx[0], *lambda; readcommands (argc, argv); settwxtable (twxtab); if (oname == NULL) ofile = stdout; else openit (oname, &ofile, "w"); if (iname == NULL) fatalx ("i paraameter compulsory\n"); nlambda = numlines (iname); ZALLOC(lambda, nlambda, double); xx[0] = lambda; nlambda = getxx (xx, nlambda, 1, iname); vst (lambda, lambda, -1.0, nlambda); sortit (lambda, NULL, nlambda); vst (lambda, lambda, -1.0, nlambda); m = numgtz (lambda, nlambda); fprintf (ofile, "%4s %12s", "#N", "eigenvalue"); fprintf (ofile, "%12s", "difference"); fprintf (ofile, " %9s %12s", "twstat", "p-value"); fprintf (ofile, " %9s", "effect. n"); fprintf (ofile, "\n"); for (i = 0; i < m; ++i) { zn = nval; tail = dotwcalc (lambda + i, m - i, &tw, &zn, &zvar, minleneig); fprintf (ofile, "%4d %12.6f", i + 1, lambda[i]); if (i == 0) fprintf (ofile, "%12s", "NA"); else fprintf (ofile, "%12.6f", lambda[i] - lambda[i - 1]); if (tail >= 0.0) fprintf (ofile, " %9.3f %12.6g", tw, tail); else fprintf (ofile, " %9s %12s", "NA", "NA"); if (zn > 0.0) { fprintf (ofile, " %9.3f", zn); } else { fprintf (ofile, " %9s", "NA"); } fprintf (ofile, "\n"); } return 0; }
void ransamp(int *samp, int nsamp, double *p, int plen) /** pick nsamp elements from random distribution uses randis but array is at least sorted optimally */ { double *px ; int *indx ; double y ; int i, j, k ; if (plen<=1) { ivzero(samp, nsamp) ; return ; } ZALLOC(px, plen, double) ; ZALLOC(indx, plen, int) ; y = asum(p, plen) ; vst(px, p, -1.0/y, plen) ; sortit(px, indx, plen) ; vst(px, px, -1.0, plen) ; for (i=0; i<nsamp; i++) { /** really need binary chop picker */ j = randis(px, plen) ; if (j<0) { for (k=0; k<plen; k++) { printf("zz %d %d %12.6f %12.6f\n",k, indx[k], p[k], px[k]) ; } fatalx("bad ransamp\n") ; } k = indx[j] ; samp[i] = k ; } free (px) ; free (indx) ; }
bool propagate() { //fprintf(stderr, "AllDiffBounds::propagate()\n"); sortit(); return filterlower() && filterupper(); }
/****************************** scanimage ************************************ PROTO void scanimage(picstruct *field, picstruct *dfield, picstruct *ffield, picstruct *wfield, picstruct *dwfield) PURPOSE Scan of the large pixmap(s). Main loop and heart of the program. INPUT Measurement field pointer, Detection field pointer, Flag field pointer, Measurement weight-map field pointer, Detection weight-map field pointer, OUTPUT -. NOTES -. AUTHOR E. Bertin (IAP) VERSION 21/12/2011 ***/ void scanimage(picstruct *field, picstruct *dfield, picstruct **pffield, int nffield, picstruct *wfield, picstruct *dwfield) { static infostruct curpixinfo, *info, *store, initinfo, freeinfo, *victim; picstruct *ffield; checkstruct *check; objliststruct objlist; objstruct *cleanobj; pliststruct *pixel, *pixt; picstruct *cfield, *cdwfield; char *marker, newmarker, *blankpad, *bpt,*bpt0; int co, i,j, flag, luflag,pstop, xl,xl2,yl, cn, nposize, stacksize, w, h, blankh, maxpixnb, varthreshflag, ontotal; short trunflag; PIXTYPE thresh, relthresh, cdnewsymbol, cdwthresh,wthresh, *scan,*dscan,*cdscan,*dwscan,*dwscanp,*dwscann, *cdwscan,*cdwscanp,*cdwscann,*wscand, *scant, *wscan,*wscann,*wscanp; FLAGTYPE *pfscan[MAXFLAG]; status cs, ps, *psstack; int *start, *end, ymax; /* Avoid gcc -Wall warnings */ scan = dscan = cdscan = cdwscan = cdwscann = cdwscanp = dwscan = dwscann = dwscanp = wscan = wscann = wscanp = NULL; victim = NULL; /* Avoid gcc -Wall warnings */ blankh = 0; /* Avoid gcc -Wall warnings */ /*----- Beginning of the main loop: Initialisations */ thecat.ntotal = thecat.ndetect = 0; /* cfield is the detection field in any case */ cfield = dfield? dfield:field; /* cdwfield is the detection weight-field if available */ cdwfield = dwfield? dwfield:(prefs.dweight_flag?wfield:NULL); cdwthresh = cdwfield ? cdwfield->weight_thresh : 0.0; if (cdwthresh>BIG*WTHRESH_CONVFAC); cdwthresh = BIG*WTHRESH_CONVFAC; wthresh = wfield? wfield->weight_thresh : 0.0; /* If WEIGHTing and no absolute thresholding, activate threshold scaling */ varthreshflag = (cdwfield && prefs.thresh_type[0]!=THRESH_ABSOLUTE); relthresh = varthreshflag ? prefs.dthresh[0] : 0.0;/* To avoid gcc warnings*/ w = cfield->width; h = cfield->height; objlist.dthresh = cfield->dthresh; objlist.thresh = field->thresh; cfield->yblank = 1; field->y = field->stripy = 0; field->ymin = field->stripylim = 0; field->stripysclim = 0; if (dfield) { dfield->y = dfield->stripy = 0; dfield->ymin = dfield->stripylim = 0; dfield->stripysclim = 0; } if (nffield) for (i=0; i<nffield; i++) { ffield = pffield[i]; ffield->y = ffield->stripy = 0; ffield->ymin = ffield->stripylim = 0; ffield->stripysclim = 0; } if (wfield) { wfield->y = wfield->stripy = 0; wfield->ymin = wfield->stripylim = 0; wfield->stripysclim = 0; } if (dwfield) { dwfield->y = dwfield->stripy = 0; dwfield->ymin = dwfield->stripylim = 0; dwfield->stripysclim = 0; } /*Allocate memory for buffers */ stacksize = w+1; QMALLOC(info, infostruct, stacksize); QCALLOC(store, infostruct, stacksize); QMALLOC(marker, char, stacksize); QMALLOC(dumscan, PIXTYPE, stacksize); QMALLOC(psstack, status, stacksize); QCALLOC(start, int, stacksize); QMALLOC(end, int, stacksize); blankpad = bpt = NULL; lutzalloc(w,h); allocparcelout(); /* Some initializations */ thresh = objlist.dthresh; initinfo.pixnb = 0; initinfo.flag = 0; initinfo.firstpix = initinfo.lastpix = -1; for (xl=0; xl<stacksize; xl++) { marker[xl] = 0 ; dumscan[xl] = -BIG ; } co = pstop = 0; objlist.nobj = 1; curpixinfo.pixnb = 1; /* Init cleaning procedure */ initclean(); /*----- Allocate memory for the pixel list */ init_plist(); if (!(pixel = objlist.plist = malloc(nposize=prefs.mem_pixstack*plistsize))) error(EXIT_FAILURE, "Not enough memory to store the pixel stack:\n", " Try to decrease MEMORY_PIXSTACK"); /*----- at the beginning, "free" object fills the whole pixel list */ freeinfo.firstpix = 0; freeinfo.lastpix = nposize-plistsize; pixt = pixel; for (i=plistsize; i<nposize; i += plistsize, pixt += plistsize) PLIST(pixt, nextpix) = i; PLIST(pixt, nextpix) = -1; /* Allocate memory for other buffers */ if (prefs.filter_flag) { QMALLOC(cdscan, PIXTYPE, stacksize); if (cdwfield) { QCALLOC(cdwscan, PIXTYPE, stacksize); if (PLISTEXIST(wflag)) { QCALLOC(cdwscanp, PIXTYPE, stacksize); QCALLOC(cdwscann, PIXTYPE, stacksize); } } /*-- One needs a buffer to protect filtering if source-blanking applies */ if (prefs.blank_flag) { blankh = thefilter->convh/2+1; QMALLOC(blankpad, char, w*blankh); cfield->yblank -= blankh; if (dfield) field->yblank = cfield->yblank; bpt = blankpad; } } /*----- Here we go */ for (yl=0; yl<=h;) { ps = COMPLETE; cs = NONOBJECT; if (yl==h) { /*---- Need an empty line for Lutz' algorithm to end gracely */ if (prefs.filter_flag) { free(cdscan); if (cdwfield) { if (PLISTEXIST(wflag)) { free(cdwscanp); free(cdwscann); cdwscanp = cdwscan; } else free(cdwscan); } } cdwscan = cdwscann = cdscan = dumscan; } else { if (nffield) for (i=0; i<nffield; i++) { ffield = pffield[i]; pfscan[i] = (ffield->stripy==ffield->stripysclim)? (FLAGTYPE *)loadstrip(ffield, (picstruct *)NULL) : &ffield->fstrip[ffield->stripy*ffield->width]; } if (wfield) { /*------ Copy the previous weight line to track bad pixel limits */ wscan = (wfield->stripy==wfield->stripysclim)? (PIXTYPE *)loadstrip(wfield, (picstruct *)NULL) : &wfield->strip[wfield->stripy*wfield->width]; if (PLISTEXIST(wflag)) { if (yl>0) wscanp = &wfield->strip[((yl-1)%wfield->stripheight)*wfield->width]; if (yl<h-1) wscann = &wfield->strip[((yl+1)%wfield->stripheight)*wfield->width]; } } scan = (field->stripy==field->stripysclim)? (PIXTYPE *)loadstrip(field, wfield) : &field->strip[field->stripy*field->width]; if (dwfield) { dwscan = (dwfield->stripy==dwfield->stripysclim)? (PIXTYPE *)loadstrip(dwfield, dfield?(picstruct *)NULL:dwfield) : &dwfield->strip[dwfield->stripy*dwfield->width]; if (PLISTEXIST(wflag)) { if (yl>0) dwscanp = &dwfield->strip[((yl-1)%dwfield->stripheight) *dwfield->width]; if (yl<h-1) dwscann = &dwfield->strip[((yl+1)%dwfield->stripheight) *dwfield->width]; } } else { dwscan = wscan; if (PLISTEXIST(wflag)) { dwscanp = wscanp; dwscann = wscann; } } if (dfield) dscan = (dfield->stripy==dfield->stripysclim)? (PIXTYPE *)loadstrip(dfield, dwfield) : &dfield->strip[dfield->stripy*dfield->width]; else dscan = scan; if (prefs.filter_flag) { filter(cfield, cdscan, cfield->y); if (cdwfield) { if (PLISTEXIST(wflag)) { if (yl==0) filter(cdwfield, cdwscann, yl); wscand = cdwscanp; cdwscanp = cdwscan; cdwscan = cdwscann; cdwscann = wscand; if (yl < h-1) filter(cdwfield, cdwscann, yl + 1); } else filter(cdwfield, cdwscan, yl); } } else { cdscan = dscan; cdwscan = dwscan; if (PLISTEXIST(wflag)) { cdwscanp = dwscanp; cdwscann = dwscann; } } if ((check=prefs.check[CHECK_FILTERED])) writecheck(check, cdscan, w); } trunflag = (yl==0 || yl==h-1)? OBJ_TRUNC:0; for (xl=0; xl<=w; xl++) { if (xl == w) cdnewsymbol = -BIG; else cdnewsymbol = cdscan[xl]; newmarker = marker[xl]; marker[xl] = 0; curpixinfo.flag = trunflag; if (varthreshflag) thresh = relthresh*sqrt((xl==w || yl==h)? 0.0:cdwscan[xl]); luflag = cdnewsymbol > thresh?1:0; if (luflag) { if (xl==0 || xl==w-1) curpixinfo.flag |= OBJ_TRUNC; pixt = pixel + (cn=freeinfo.firstpix); freeinfo.firstpix = PLIST(pixt, nextpix); /*------- Running out of pixels, the largest object becomes a "victim" ------*/ if (freeinfo.firstpix==freeinfo.lastpix) { sprintf(gstr, "%d,%d", xl+1, yl+1); warning("Pixel stack overflow at position ", gstr); maxpixnb = 0; for (i=0; i<=w; i++) if (store[i].pixnb>maxpixnb) if (marker[i]=='S' || (newmarker=='S' && i==xl)) { flag = 0; if (i<xl) for (j=0; j<=co; j++) flag |= (start[j]==i); if (!flag) maxpixnb = (victim = &store[i])->pixnb; } for (j=1; j<=co; j++) if (info[j].pixnb>maxpixnb) maxpixnb = (victim = &info[j])->pixnb; if (!maxpixnb) error(EXIT_FAILURE, "*Fatal Error*: something is badly bugged in ", "scanimage()!"); if (maxpixnb <= 1) error(EXIT_FAILURE, "Pixel stack overflow in ", "scanimage()"); freeinfo.firstpix = PLIST(pixel+victim->firstpix, nextpix); PLIST(pixel+victim->lastpix, nextpix) = freeinfo.lastpix; PLIST(pixel+(victim->lastpix=victim->firstpix), nextpix) = -1; victim->pixnb = 1; victim->flag |= OBJ_OVERFLOW; } /*---------------------------------------------------------------------------*/ curpixinfo.lastpix = curpixinfo.firstpix = cn; PLIST(pixt, nextpix) = -1; PLIST(pixt, x) = xl; PLIST(pixt, y) = yl; PLIST(pixt, value) = scan[xl]; if (PLISTEXIST(dvalue)) PLISTPIX(pixt, dvalue) = dscan[xl]; if (PLISTEXIST(cdvalue)) PLISTPIX(pixt, cdvalue) = cdnewsymbol; if (PLISTEXIST(flag)) for (i=0; i<nffield; i++) PLISTFLAG(pixt, flag[i]) = pfscan[i][xl]; /*--------------------- Detect pixels with a low weight ---------------------*/ if (PLISTEXIST(wflag) && wscan) { PLISTFLAG(pixt, wflag) = 0; if (wscan[xl] >= wthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWWEIGHT; if (cdwscan[xl] >= cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (yl>0) { if (cdwscanp[xl] >= cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl>0 && cdwscanp[xl-1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl<w-1 && cdwscanp[xl+1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; } if (xl>0 && cdwscan[xl-1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl<w-1 && cdwscan[xl+1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (yl<h-1) { if (cdwscann[xl] >= cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl>0 && cdwscann[xl-1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl<w-1 && cdwscann[xl+1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; } } if (PLISTEXIST(dthresh)) PLISTPIX(pixt, dthresh) = thresh; if (PLISTEXIST(var)) PLISTPIX(pixt, var) = wscan[xl]; if (cs != OBJECT) /*------------------------------- Start Segment -----------------------------*/ { cs = OBJECT; if (ps == OBJECT) { if (start[co] == UNKNOWN) { marker[xl] = 'S'; start[co] = xl; } else marker[xl] = 's'; } else { psstack[pstop++] = ps; marker[xl] = 'S'; start[++co] = xl; ps = COMPLETE; info[co] = initinfo; } } /*---------------------------------------------------------------------------*/ } if (newmarker) /*---------------------------- Process New Marker ---------------------------*/ { if (newmarker == 'S') { psstack[pstop++] = ps; if (cs == NONOBJECT) { psstack[pstop++] = COMPLETE; info[++co] = store[xl]; start[co] = UNKNOWN; } else update (&info[co],&store[xl], pixel); ps = OBJECT; } else if (newmarker == 's') { if ((cs == OBJECT) && (ps == COMPLETE)) { pstop--; xl2 = start[co]; update (&info[co-1],&info[co], pixel); if (start[--co] == UNKNOWN) start[co] = xl2; else marker[xl2] = 's'; } ps = OBJECT; } else if (newmarker == 'f') ps = INCOMPLETE; else if (newmarker == 'F') { ps = psstack[--pstop]; if ((cs == NONOBJECT) && (ps == COMPLETE)) { if (start[co] == UNKNOWN) { if ((int)info[co].pixnb >= prefs.ext_minarea) { sortit(field, dfield, wfield, cdwfield, &info[co], &objlist, cdwscan, wscan); } /* ------------------------------------ free the chain-list */ PLIST(pixel+info[co].lastpix, nextpix) = freeinfo.firstpix; freeinfo.firstpix = info[co].firstpix; } else { marker[end[co]] = 'F'; store[start[co]] = info[co]; } co--; ps = psstack[--pstop]; } } } /*---------------------------------------------------------------------------*/ if (luflag) update (&info[co],&curpixinfo, pixel); else { if (cs == OBJECT) /*-------------------------------- End Segment ------------------------------*/ { cs = NONOBJECT; if (ps != COMPLETE) { marker[xl] = 'f'; end[co] = xl; } else { ps = psstack[--pstop]; marker[xl] = 'F'; store[start[co]] = info[co]; co--; } } } if (prefs.blank_flag && xl<w) { if (prefs.filter_flag) *(bpt++) = (luflag)?1:0; else if (luflag) dscan[xl] = -BIG; if (dfield && luflag) scan[xl] = -BIG; } /*--------------------- End of the loop over the x's -----------------------*/ } /* Detected pixel removal at the end of each line */ if (prefs.blank_flag && yl<h) { if (prefs.filter_flag) { bpt = bpt0 = blankpad + w*((yl+1)%blankh); if (cfield->yblank >= 0) { scant = &PIX(cfield, 0, cfield->yblank); for (i=w; i--; scant++) if (*(bpt++)) *scant = -BIG; if (dfield) { bpt = bpt0; scant = &PIX(field, 0, cfield->yblank); for (i=w; i--; scant++) if (*(bpt++)) *scant = -BIG; } bpt = bpt0; } } cfield->yblank++; if (dfield) field->yblank = cfield->yblank; } /*-- Prepare markers for the next line */ yl++; field->stripy = (field->y=yl)%field->stripheight; if (dfield) dfield->stripy = (dfield->y=yl)%dfield->stripheight; if (nffield) for (i=0; i<nffield; i++) { ffield = pffield[i]; ffield->stripy = (ffield->y=yl)%ffield->stripheight; } if (wfield) wfield->stripy = (wfield->y=yl)%wfield->stripheight; if (dwfield) dwfield->stripy = (dwfield->y=yl)%dwfield->stripheight; /*-- Remove objects close to the ymin limit if ymin is ready to increase */ if (cfield->stripy==cfield->stripysclim) { cleanobj = cleanobjlist->obj+cleanobjlist->nobj-1; ontotal = 0; for (i=cleanobjlist->nobj; i--; cleanobj--) { if (cleanobj->ycmin <= cfield->ymin) { /*-------- Warn if there is a possibility for any aperture to be truncated */ if ((ymax=cleanobj->ycmax) > cfield->ymax) { sprintf(gstr, "Object at position %.0f,%.0f ", cleanobj->mx+1, cleanobj->my+1); QWARNING(gstr, "may have some apertures truncated:\n" " You might want to increase MEMORY_BUFSIZE"); } else if (ymax>cfield->yblank && prefs.blank_flag) { sprintf(gstr, "Object at position %.0f,%.0f ", cleanobj->mx+1, cleanobj->my+1); QWARNING(gstr, "may have some unBLANKed neighbours:\n" " You might want to increase MEMORY_PIXSTACK"); } if ((prefs.prof_flag && !(thecat.ntotal%10) && thecat.ntotal != ontotal) || !(thecat.ntotal%400)) NPRINTF(OUTPUT, "\33[1M> Line:%5d " "Objects: %8d detected / %8d sextracted\n\33[1A", yl>h? h:yl, thecat.ndetect, thecat.ntotal); ontotal = thecat.ntotal; endobject(field, dfield, wfield, cdwfield, i, cleanobjlist); subcleanobj(i); cleanobj = cleanobjlist->obj+i; /* realloc in subcleanobj() */ } } } if ((prefs.prof_flag && !(thecat.ntotal%10)) || !(yl%25)) NPRINTF(OUTPUT, "\33[1M> Line:%5d " "Objects: %8d detected / %8d sextracted\n\33[1A", yl>h?h:yl, thecat.ndetect, thecat.ntotal); /*--------------------- End of the loop over the y's -----------------------*/ } /* Removal or the remaining pixels */ if (prefs.blank_flag && prefs.filter_flag && (cfield->yblank >= 0)) for (j=blankh-1; j--; yl++) { bpt = bpt0 = blankpad + w*(yl%blankh); scant = &PIX(cfield, 0, cfield->yblank); for (i=w; i--; scant++) if (*(bpt++)) *scant = -BIG; if (dfield) { bpt = bpt0; scant = &PIX(field, 0, cfield->yblank); for (i=w; i--; scant++) if (*(bpt++)) *scant = -BIG; } cfield->yblank++; if (dfield) field->yblank = cfield->yblank; } /* Now that all "detected" pixels have been removed, analyse detections */ ontotal = 0; for (j=cleanobjlist->nobj; j--;) { if ((prefs.prof_flag && !(thecat.ntotal%10) && thecat.ntotal != ontotal) || !(thecat.ntotal%400)) NPRINTF(OUTPUT, "\33[1M> Line:%5d " "Objects: %8d detected / %8d sextracted\n\33[1A", h, thecat.ndetect, thecat.ntotal); ontotal = thecat.ntotal; endobject(field, dfield, wfield, cdwfield, 0, cleanobjlist); subcleanobj(0); } endclean(); /*Free memory */ if (prefs.filter_flag && cdwfield && PLISTEXIST(wflag)) free(cdwscanp); freeparcelout(); free(pixel); pixel = NULL; lutzfree(); free(info); info = NULL; free(store); store = NULL; free(marker); marker = NULL; free(dumscan); dumscan = NULL; free(psstack); psstack = NULL; free(start); start = NULL; free(end); end = NULL; if (prefs.blank_flag && prefs.filter_flag) free(blankpad); blankpad = NULL; return; }
double dottest(char *sss, double *vec, char **eglist, int numeg, int *xtypes, int len) // vec will always have mean 0 // perhaps should rewrite to put xa1 etc in arrays { double *w1 ; int *xt ; int i, k1, k2, k, n, x1, x2 ; double ylike ; double ychi ; double *wmean ; int imax, imin, *isort ; static int ncall = 0 ; char ss1[MAXSTR] ; char ss2[MAXSTR] ; double ans, ftail, ftailx, ansx ; ZALLOC(wmean, numeg, double) ; ZALLOC(w1, len + numeg, double) ; ZALLOC(isort, numeg, int) ; ZALLOC(xt, len, int) ; strcpy(ss1, "") ; calcmean(wmean, vec, len, xtypes, numeg) ; if (pubmean) { copyarr(wmean, w1, numeg) ; sortit(w1, isort, numeg) ; printf("%s:means\n", sss) ; for (i=0; i<numeg; i++) { k = isort[i] ; printf("%20s ", eglist[k]) ; printf(" %9.3f\n", wmean[k]) ; } } vlmaxmin(wmean, numeg, &imax, &imin) ; if (chisqmode) { ylike = anova1(vec, len, xtypes, numeg) ; ans = 2.0*ylike ; } else { ans = ftail = anova(vec, len, xtypes, numeg) ; } ++ncall ; if (numeg>2) { sprintf(ss2, "%s %s ", sss, "overall") ; publishit(ss2, numeg-1, ans) ; printf(" %20s minv: %9.3f %20s maxv: %9.3f\n", eglist[imin], wmean[imin], eglist[imax], wmean[imax]) ; } for (k1 = 0; k1<numeg; ++k1) { for (k2 = k1+1; k2<numeg; ++k2) { n = 0 ; x1 = x2 = 0 ; for (i=0; i<len ; i++) { k = xtypes[i] ; if (k == k1) { w1[n] = vec[i] ; xt[n] = 0 ; ++n ; ++x1 ; } if (k == k2) { w1[n] = vec[i] ; xt[n] = 1 ; ++n ; ++x2 ; } } if (x1 <= 1) continue ; if (x2 <= 1) continue ; ylike = anova1(w1, n, xt, 2) ; ychi = 2.0*ylike ; chitot[k1*numeg + k2] += ychi ; if (chisqmode) { ansx = ychi ; } else { ansx = ftailx = anova(w1, n, xt, 2) ; } sprintf(ss2,"%s %s %s ", sss, eglist[k1], eglist[k2]) ; publishit(ss2, 1, ansx) ; } } free(w1) ; free(xt) ; free(wmean) ; free(isort) ; return ans ; }
int main(int argc, char **argv) { char **eglist ; int numeg ; int i, j, k, pos; int *vv ; SNP *cupt, *cupt2 ; Indiv *indx ; double y1, y2, y ; int n0, n1, nkill ; int nindiv = 0 ; int nignore, numrisks = 1 ; SNP **xsnplist ; Indiv **xindlist ; int *xindex ; int nrows, ncols, m ; double *XTX, *cc, *evecs, *ww ; double *lambda ; double *tvecs ; int weightmode = NO ; int t ; double *xmean, *xfancy ; double *ldmat = NULL, *ldmat2 = NULL; double *ldvv = NULL, *ldvv2 = NULL, *vv2 = NULL ; int chrom, numclear ; double gdis ; int outliter, numoutiter, *badlist, nbad ; int a, b, n ; FILE *outlfile ; int xblock, blocksize=10000 ; double *tblock ; OUTLINFO *outpt ; int *idperm, *vecind ; // for sort readcommands(argc, argv) ; printf("## smartrel version: %s\n", WVERSION) ; packmode = YES ; setomode(&outputmode, omode) ; if (parname == NULL) return 0 ; if (xchrom == (numchrom+1)) noxdata = NO ; if (fstonly) { printf("fstonly\n") ; numeigs = 0 ; numoutliter = 0 ; numoutiter = 0 ; outputname = NULL ; snpeigname = NULL ; } if (fancynorm) printf("norm used\n\n") ; else printf("no norm used\n\n") ; nostatslim = MAX(nostatslim, 3) ; outlfile = ofile = stdout; if (outputname != NULL) openit(outputname, &ofile, "w") ; if (outliername != NULL) openit(outliername, &outlfile, "w") ; if (fstdetailsname != NULL) openit(fstdetailsname, &fstdetails, "w") ; numsnps = getsnps(snpname, &snpmarkers, 0.0, badsnpname, &nignore, numrisks) ; numindivs = getindivs(indivname, &indivmarkers) ; k = getgenos(genotypename, snpmarkers, indivmarkers, numsnps, numindivs, nignore) ; if (poplistname != NULL) { ZALLOC(eglist, numindivs, char *) ; numeg = loadlist(eglist, poplistname) ; seteglist(indivmarkers, numindivs, poplistname); } else { setstatus(indivmarkers, numindivs, NULL) ; ZALLOC(eglist, MAXPOPS, char *) ; numeg = makeeglist(eglist, MAXPOPS, indivmarkers, numindivs) ; } for (i=0; i<numeg; i++) { /* printf("%3d %s\n",i, eglist[i]) ; */ } nindiv=0 ; for (i=0; i<numindivs; i++) { indx = indivmarkers[i] ; if(indx -> affstatus == YES) ++nindiv ; } for (i=0; i<numsnps; i++) { cupt = snpmarkers[i] ; chrom = cupt -> chrom ; if ((noxdata) && (chrom == (numchrom+1))) cupt-> ignore = YES ; if (chrom == 0) cupt -> ignore = YES ; if (chrom > (numchrom+1)) cupt -> ignore = YES ; } for (i=0; i<numsnps; i++) { cupt = snpmarkers[i] ; pos = nnint(cupt -> physpos) ; if ((xchrom>0) && (cupt -> chrom != xchrom)) cupt -> ignore = YES ; if ((xchrom > 0) && (pos < lopos)) cupt -> ignore = YES ; if ((xchrom > 0) && (pos > hipos)) cupt -> ignore = YES ; if (cupt -> ignore) continue ; if (numvalidgtx(indivmarkers, cupt, YES) <= 1) { printf("nodata: %20s\n", cupt -> ID) ; cupt -> ignore = YES ; } } if (killr2) { nkill = killhir2(snpmarkers, numsnps, numindivs, r2physlim, r2genlim, r2thresh) ; if (nkill>0) printf("killhir2. number of snps killed: %d\n", nkill) ; } ZALLOC(vv, numindivs, int) ; numvalidgtallind(vv, snpmarkers, numsnps, numindivs) ; for (i=0; i<numindivs; ++i) { if (vv[i] == 0) { indx = indivmarkers[i] ; indx -> ignore = YES ; } } free(vv) ; numsnps = rmsnps(snpmarkers, numsnps, NULL) ; // rid ignorable snps if (missingmode) { setmiss(snpmarkers, numsnps) ; fancynorm = NO ; } if (weightname != NULL) { weightmode = YES ; getweights(weightname, snpmarkers, numsnps) ; } if (ldregress>0) { ZALLOC(ldvv, ldregress*numindivs, double) ; ZALLOC(ldvv2, ldregress*numindivs, double) ; ZALLOC(vv2, numindivs, double) ; ZALLOC(ldmat, ldregress*ldregress, double) ; ZALLOC(ldmat2, ldregress*ldregress, double) ; setidmat(ldmat, ldregress) ; vst(ldmat, ldmat, 1.0e-6, ldregress*ldregress) ; } ZALLOC(xindex, numindivs, int) ; ZALLOC(xindlist, numindivs, Indiv *) ; ZALLOC(xsnplist, numsnps, SNP *) ; if (popsizelimit > 0) { setplimit(indivmarkers, numindivs, eglist, numeg, popsizelimit) ; } nrows = loadindx(xindlist, xindex, indivmarkers, numindivs) ; ncols = loadsnpx(xsnplist, snpmarkers, numsnps, indivmarkers) ; printf("number of samples used: %d number of snps used: %d\n", nrows, ncols) ; /** cupt = xsnplist[0] ; for (j=0; j<nrows; ++j) { k = xindex[j] ; g = getgtypes(cupt, k) ; indx = indivmarkers[k] ; t = indxindex(eglist, numeg, indx -> egroup) ; printf("yy1 %20s %20s %20s %d %d %d\n", cupt ->ID, indx -> ID, indx -> egroup, j, k, g) ; } printf("yya: ") ; printimat(xindex, 1, nrows) ; printf("zzindxa: %s\n", indivmarkers[230] -> egroup) ; */ /* printf("## nrows: %d ncols %d\n", nrows, ncols) ; */ ZALLOC(xmean, ncols, double) ; ZALLOC(xfancy, ncols, double) ; ZALLOC(XTX, nrows*nrows, double) ; ZALLOC(evecs, nrows*nrows, double) ; ZALLOC(tvecs, nrows*nrows, double) ; ZALLOC(lambda, nrows, double) ; ZALLOC(cc, nrows, double) ; ZALLOC(ww, nrows, double) ; ZALLOC(badlist, nrows, int) ; blocksize = MIN(blocksize, ncols) ; ZALLOC(tblock, nrows*blocksize, double) ; // xfancy is multiplier for column xmean is mean to take off // badlist is list of rows to delete (outlier removal) numoutiter = 1 ; if (numoutliter>=1) { numoutiter = numoutliter+1 ; ZALLOC(outinfo, nrows, OUTLINFO *) ; for (k=0; k<nrows; k++) { ZALLOC(outinfo[k], 1, OUTLINFO) ; } /* fprintf(outlfile, "##%18s %4s %6s %9s\n", "ID", "iter","eigvec", "score") ; */ } for (outliter = 1; outliter <= numoutiter ; ++outliter) { if (fstonly) { setidmat(XTX, nrows) ; vclear(lambda, 1.0, nrows) ; break ; } if (outliter>1) { ncols = loadsnpx(xsnplist, snpmarkers, numsnps, indivmarkers) ; } vzero(XTX, nrows*nrows) ; vzero(tblock, nrows*blocksize) ; xblock = 0 ; vzero(xmean, ncols) ; vclear(xfancy, 1.0, ncols) ; for (i=0; i<ncols; i++) { cupt = xsnplist[i] ; chrom = cupt -> chrom ; getcolxz(cc, cupt, xindex, nrows, i, xmean, xfancy, &n0, &n1) ; t = MIN(n0, n1) ; if (t <= minallelecnt) { cupt -> ignore = YES ; vzero(cc, nrows) ; } if (weightmode) { vst(cc, cc, xsnplist[i] -> weight, nrows) ; } if (ldregress>0) { numclear = 0 ; for (k=1; k<= ldregress; ++k) { j = i-k ; if (j<0) { numclear = ldregress-k+1 ; break ; } cupt2 = xsnplist[j] ; if (cupt2 -> chrom != chrom) gdis = ldlimit + 1.0 ; else gdis = cupt -> genpos - cupt2 -> genpos ; if (gdis>=ldlimit) { numclear = ldregress-k+1 ; break ; } } if (numclear>0) clearld(ldmat, ldvv, ldregress, nrows, numclear) ; ldreg(ldmat, ldmat2, cc, vv2, ldvv, ldvv2, ldregress, nrows) ; copyarr(ldmat2, ldmat, ldregress*ldregress) ; copyarr(vv2, cc, nrows) ; copyarr(ldvv2, ldvv, ldregress*nrows) ; } copyarr(cc, tblock+xblock*nrows, nrows) ; ++xblock ; /** this is the key code to parallelize */ if (xblock==blocksize) { domult(tvecs, tblock, xblock, nrows) ; vvp(XTX, XTX, tvecs, nrows*nrows) ; xblock = 0 ; vzero(tblock, nrows*blocksize) ; } } if (xblock>0) { domult(tvecs, tblock, xblock, nrows) ; vvp(XTX, XTX, tvecs, nrows*nrows) ; } symit(XTX, nrows) ; /** a = 0; b=0 ; printf("zz1 %12.6f ", XTX[a*nrows+b]) ; a = nrows-1; b=nrows-1 ; printf(" %12.6f %15.9g\n", XTX[a*nrows+b], asum(XTX, nrows*nrows)) ; */ if (verbose) { printdiag(XTX, nrows) ; } y = trace(XTX, nrows) / (double) (nrows-1) ; if (isnan(y)) fatalx("bad XTX matrix\n") ; /* printf("trace: %9.3f\n", y) ; */ if (y<=0.0) fatalx("XTX has zero trace (perhaps no data)\n") ; vst(XTX, XTX, 1.0/y, nrows * nrows) ; /// mean eigenvalue is 1 eigvecs(XTX, lambda, evecs, nrows) ; // eigenvalues are in decreasing order if (outliter > numoutliter) break ; // last pass skips outliers numoutleigs = MIN(numoutleigs, nrows-1) ; nbad = ridoutlier(evecs, nrows, numoutleigs, outlthresh, badlist, outinfo) ; if (nbad == 0) break ; for (i=0; i<nbad; i++) { j = badlist[i] ; indx = xindlist[j] ; outpt = outinfo[j] ; fprintf(outlfile, "REMOVED outlier %s iter %d evec %d sigmage %.3f\n", indx -> ID, outliter, outpt -> vecno, outpt -> score) ; indx -> ignore = YES ; } nrows = loadindx(xindlist, xindex, indivmarkers, numindivs) ; printf("number of samples after outlier removal: %d\n", nrows) ; } if (outliername != NULL) fclose(outlfile) ; m = numgtz(lambda, nrows) ; /* printf("matrix rank: %d\n", m) ; */ if (m==0) fatalx("no data\n") ; /** smartrel code */ for (i=0; i<numeigs; i++) { y = sqrt(lambda[i]) ; vst(ww, evecs+i*nrows, y, nrows) ; subouter(XTX, ww, nrows) ; } free(tvecs) ; n = 0 ; ZALLOC(vecind, nrows*nrows/2, int) ; for (i=0; i<nrows; i++) { for (j=i+1; j<nrows; j++) { k = i*nrows + j ; y1 = XTX[i*nrows+i] ; y2 = XTX[j*nrows+j] ; y = XTX[k]/sqrt(y1*y2) ; y += 1/(double)(nrows-1); if (y<relthresh) continue ; vecind[n] = k ; evecs[n] = -y ; ++n ; } } free(XTX) ; if (n==0) { printf("## nothing above relthresh!\n") ; printf("##end of smartrel run\n") ; return 0 ; } ZALLOC(idperm, n, int) ; sortit(evecs, idperm, n) ; for (i=0; i<n; i++) { j = idperm[i] ; k = vecind[j] ; a = k/nrows ; b = k%nrows ; printf("rel: %20s ", xindlist[a] ->ID) ; printf("%20s ", xindlist[b] ->ID) ; printf(" %9.3f", -evecs[i]) ; printnl() ; } printf("##end of smartrel run\n") ; return 0 ; }
/****************************** extract **************************************/ int sep_extract(PIXTYPE *im, PIXTYPE *var, int w, int h, PIXTYPE thresh, int minarea, float *conv, int convw, int convh, int deblend_nthresh, double deblend_mincont, int clean_flag, double clean_param, int *nobj, sepobj **objects) { static infostruct curpixinfo, *info, *store, initinfo, freeinfo, *victim; objliststruct objlist, *finalobjlist; pliststruct *pixel, *pixt; char *marker, newmarker; int co, i, j, flag, luflag, pstop, xl, xl2, yl, cn, nposize, stacksize, maxpixnb, convn, status; short trunflag; PIXTYPE relthresh, cdnewsymbol; PIXTYPE *scan,*cdscan,*cdwscan,*wscan,*dumscan; float sum, *convnorm; pixstatus cs, ps, *psstack; int *start, *end, *survives; status = RETURN_OK; char errtext[80]; /* 80 should be more than enough */ pixel = NULL; convnorm = NULL; scan = wscan = cdscan = cdwscan = dumscan = NULL; victim = NULL; info = NULL; store = NULL; marker = NULL; psstack = NULL; start = end = NULL; finalobjlist = NULL; /* final return value */ convn = 0; sum = 0.0; /* var is the image variance to use for thresholding, if available */ relthresh = var? thresh : 0.0;/* To avoid gcc warnings*/ objlist.dthresh = thresh; objlist.thresh = thresh; /*Allocate memory for buffers */ stacksize = w+1; QMALLOC(info, infostruct, stacksize, status); QCALLOC(store, infostruct, stacksize, status); QMALLOC(marker, char, stacksize, status); QMALLOC(dumscan, PIXTYPE, stacksize, status); QMALLOC(psstack, pixstatus, stacksize, status); QCALLOC(start, int, stacksize, status); QMALLOC(end, int, stacksize, status); if ((status = lutzalloc(w, h)) != RETURN_OK) goto exit; if ((status = allocdeblend(deblend_nthresh)) != RETURN_OK) goto exit; /* More initializations */ initinfo.pixnb = 0; initinfo.flag = 0; initinfo.firstpix = initinfo.lastpix = -1; for (xl=0; xl<stacksize; xl++) { marker[xl] = 0 ; dumscan[xl] = -BIG ; } co = pstop = 0; objlist.nobj = 1; curpixinfo.pixnb = 1; /* Init finalobjlist (the return catalog) */ QMALLOC(finalobjlist, objliststruct, 1, status); finalobjlist->obj = NULL; finalobjlist->plist = NULL; finalobjlist->nobj = finalobjlist->npix = 0; /* Allocate memory for the pixel list */ plistinit(conv, var); if (!(pixel = objlist.plist = malloc(nposize=MEMORY_PIXSTACK*plistsize))) { status = MEMORY_ALLOC_ERROR; goto exit; } /*----- at the beginning, "free" object fills the whole pixel list */ freeinfo.firstpix = 0; freeinfo.lastpix = nposize-plistsize; pixt = pixel; for (i=plistsize; i<nposize; i += plistsize, pixt += plistsize) PLIST(pixt, nextpix) = i; PLIST(pixt, nextpix) = -1; if (conv) { /* allocate memory for convolved buffers */ QMALLOC(cdscan, PIXTYPE, stacksize, status); if (var) QCALLOC(cdwscan, PIXTYPE, stacksize, status); /* normalize the filter */ convn = convw * convh; QMALLOC(convnorm, PIXTYPE, convn, status); for (i=0; i<convn; i++) sum += fabs(conv[i]); for (i=0; i<convn; i++) convnorm[i] = conv[i] / sum; } /*----- MAIN LOOP ------ */ for (yl=0; yl<=h; yl++) { ps = COMPLETE; cs = NONOBJECT; /* Need an empty line for Lutz' algorithm to end gracely */ if (yl==h) { if (conv) { free(cdscan); cdscan = NULL; if (var) { free(cdwscan); cdwscan = NULL; } } cdwscan = cdscan = dumscan; } else { scan = im + yl*w; if (var) wscan = var + yl*w; /* filter the lines */ if (conv) { convolve(im, w, h, yl, convnorm, convw, convh, cdscan); if (var) convolve(var, w, h, yl, convnorm, convw, convh, cdwscan); } else { cdscan = scan; cdwscan = wscan; } } trunflag = (yl==0 || yl==h-1)? SEP_OBJ_TRUNC:0; for (xl=0; xl<=w; xl++) { if (xl == w) cdnewsymbol = -BIG; else cdnewsymbol = cdscan[xl]; newmarker = marker[xl]; /* marker at this pixel */ marker[xl] = 0; curpixinfo.flag = trunflag; if (var) thresh = relthresh * sqrt((xl==w || yl==h)? 0.0:cdwscan[xl]); luflag = cdnewsymbol > thresh? 1: 0; /* is pixel above thresh? */ if (luflag) { /* flag the current object if we're near the image bounds */ if (xl==0 || xl==w-1) curpixinfo.flag |= SEP_OBJ_TRUNC; /* point pixt to first free pixel in pixel list */ /* and increment the "first free pixel" */ pixt = pixel + (cn=freeinfo.firstpix); freeinfo.firstpix = PLIST(pixt, nextpix); curpixinfo.lastpix = curpixinfo.firstpix = cn; /* set values for the new pixel */ PLIST(pixt, nextpix) = -1; PLIST(pixt, x) = xl; PLIST(pixt, y) = yl; PLIST(pixt, value) = scan[xl]; if (PLISTEXIST(cdvalue)) PLISTPIX(pixt, cdvalue) = cdnewsymbol; if (PLISTEXIST(var)) PLISTPIX(pixt, var) = wscan[xl]; /* Check if we are running out of free pixels in objlist.plist */ /* (previously, the largest object became a "victim") */ if (freeinfo.firstpix==freeinfo.lastpix) { status = SEP_INTERNAL_ERROR; sprintf(errtext, "Pixel stack overflow at position %d,%d.", xl+1, yl+1); put_errdetail(errtext); goto exit; /* NOTE: The above error was originally just a warning. with the change to an error, the following code in this if block is never executed. TODO: should this just be a warning (or nothing?) */ /* loop over pixels in row to find largest object */ maxpixnb = 0; for (i=0; i<=w; i++) if (store[i].pixnb>maxpixnb) if (marker[i]=='S' || (newmarker=='S' && i==xl)) { flag = 0; if (i<xl) for (j=0; j<=co; j++) flag |= (start[j]==i); if (!flag) maxpixnb = (victim = &store[i])->pixnb; } for (j=1; j<=co; j++) if (info[j].pixnb>maxpixnb) maxpixnb = (victim = &info[j])->pixnb; if ((!maxpixnb) || (maxpixnb <= 1)) { status = SEP_INTERNAL_ERROR; goto exit; } freeinfo.firstpix = PLIST(pixel+victim->firstpix, nextpix); PLIST(pixel+victim->lastpix, nextpix) = freeinfo.lastpix; PLIST(pixel+(victim->lastpix=victim->firstpix), nextpix) = -1; victim->pixnb = 1; victim->flag |= SEP_OBJ_OVERFLOW; } /*------------------------------------------------------------*/ /* if the current status on this line is not already OBJECT... */ /* start segment */ if (cs != OBJECT) { cs = OBJECT; if (ps == OBJECT) { if (start[co] == UNKNOWN) { marker[xl] = 'S'; start[co] = xl; } else marker[xl] = 's'; } else { psstack[pstop++] = ps; marker[xl] = 'S'; start[++co] = xl; ps = COMPLETE; info[co] = initinfo; } } } /* closes if pixel above threshold */ /* process new marker ---------------------------------------------*/ /* newmarker is marker[ ] at this pixel position before we got to it. We'll only enter this if marker[ ] was set on a previous loop iteration. */ if (newmarker) { if (newmarker == 'S') { psstack[pstop++] = ps; if (cs == NONOBJECT) { psstack[pstop++] = COMPLETE; info[++co] = store[xl]; start[co] = UNKNOWN; } else update(&info[co], &store[xl], pixel); ps = OBJECT; } else if (newmarker == 's') { if ((cs == OBJECT) && (ps == COMPLETE)) { pstop--; xl2 = start[co]; update (&info[co-1],&info[co], pixel); if (start[--co] == UNKNOWN) start[co] = xl2; else marker[xl2] = 's'; } ps = OBJECT; } else if (newmarker == 'f') ps = INCOMPLETE; else if (newmarker == 'F') { ps = psstack[--pstop]; if ((cs == NONOBJECT) && (ps == COMPLETE)) { if (start[co] == UNKNOWN) { if ((int)info[co].pixnb >= minarea) { status = sortit(&info[co], &objlist, minarea, finalobjlist, deblend_nthresh,deblend_mincont); if (status != RETURN_OK) goto exit; } /* free the chain-list */ PLIST(pixel+info[co].lastpix, nextpix) = freeinfo.firstpix; freeinfo.firstpix = info[co].firstpix; } else { marker[end[co]] = 'F'; store[start[co]] = info[co]; } co--; ps = psstack[--pstop]; } } } /* end of if (newmarker) ------------------------------------------*/ /* update the info or end segment */ if (luflag) { update(&info[co], &curpixinfo, pixel); } else if (cs == OBJECT) { cs = NONOBJECT; if (ps != COMPLETE) { marker[xl] = 'f'; end[co] = xl; } else { ps = psstack[--pstop]; marker[xl] = 'F'; store[start[co]] = info[co]; co--; } } } /*------------ End of the loop over the x's -----------------------*/ } /*---------------- End of the loop over the y's -----------------------*/ /* convert `finalobjlist` to an array of `sepobj` structs */ if (clean_flag) { /* Calculate mthresh for all objects in the list (needed for cleaning) */ for (i=0; i<finalobjlist->nobj; i++) { status = analysemthresh(i, finalobjlist, minarea, thresh); if (status != RETURN_OK) goto exit; } QMALLOC(survives, int, finalobjlist->nobj, status); clean(finalobjlist, clean_param, survives); /* count surviving objects and allocate space accordingly*/ *nobj = 0; for (i=0; i<finalobjlist->nobj; i++) *nobj += survives[i]; QMALLOC(*objects, sepobj, *nobj, status); /* fill */ j=0; for (i=0; i<finalobjlist->nobj; i++) if (survives[i]) convertobj(i, finalobjlist, (*objects) + j++, w); } else {
static void read_psffm(char *file) { int fd; static char msgfile[MAXPATHLEN]; wchar_t *linebufptr, *p; char *bufptr = 0; int quotefound; /* double quote was seen */ int inmsgid = 0; /* indicates "msgid" was seen */ int inmsgstr = 0; /* indicates "msgstr" was seen */ int indomain = 0; /* indicates "domain" was seen */ wchar_t wc; char mb; int n; char token_found; /* Boolean value */ unsigned int bufptr_index = 0; /* current index of bufptr */ char *mbuf, *addr; size_t fsize, ln_size, ll; wchar_t *linebufhead = NULL; struct stat64 statbuf; char *filename; /* * For each po file to be read, * 1) set domain to default and * 2) set linenumer to 0. */ (void) strcpy(gcurrent_domain, DEFAULT_DOMAIN); linenum = 0; if (!inputdir) { filename = Xstrdup(file); } else { size_t dirlen, filelen, len; dirlen = strlen(inputdir); filelen = strlen(file); len = dirlen + 1 + filelen + 1; filename = (char *)Xmalloc(len); (void) memcpy(filename, inputdir, dirlen); *(filename + dirlen) = '/'; (void) memcpy(filename + dirlen + 1, file, filelen); *(filename + dirlen + 1 + filelen) = '\0'; } fd = open(filename, O_RDONLY); if (fd == -1) { error(gettext(ERR_OPEN_FAILED), filename); /* NOTREACHED */ } if (fstat64(fd, &statbuf) == -1) { error(gettext(ERR_STAT_FAILED), filename); /* NOTREACHED */ } fsize = (size_t)statbuf.st_size; if (fsize == 0) { /* * The size of the specified po file is 0. * In Solaris 8 and earlier, msgfmt was silent * for the null po file. So, just returns * without generating an error message. */ (void) close(fd); free(filename); return; } addr = mmap(NULL, fsize, PROT_READ, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { error(gettext(ERR_MMAP_FAILED), filename); /* NOTREACHED */ } (void) close(fd); if (!sun_p) check_gnu(addr, fsize); mbuf = addr; for (;;) { if (linebufhead) { free(linebufhead); linebufhead = NULL; } ln_size = _mbsntowcs(&linebufhead, &mbuf, &fsize); if (ln_size == (size_t)-1) { error(gettext(ERR_READ_FAILED), filename); /* NOTREACHED */ } else if (ln_size == 0) { break; /* End of File. */ } linenum++; linebufptr = linebufhead; quotefound = 0; switch (*linebufptr) { case L'#': /* comment */ case L'\n': /* empty line */ continue; case L'\"': /* multiple lines of msgid and msgstr */ quotefound = 1; break; } /* * Process MSGID Tokens. */ token_found = (wcsncmp(MSGID_TOKEN, linebufptr, MSGID_LEN) == 0) ? 1 : 0; if (token_found || (quotefound && inmsgid)) { if (token_found) { if (!CK_NXT_CH(linebufptr, MSGID_LEN+1)) { diag(gettext(ERR_NOSPC), linenum); error(gettext(ERR_EXITING)); /* NOTREACHED */ } } if (inmsgid && !quotefound) { warning(gettext(WARN_NO_MSGSTR), msgid_linenum); continue; } if (inmsgstr) { sortit(gmsgid, gmsgstr); (void) memset(gmsgid, 0, gmsgid_size); (void) memset(gmsgstr, 0, gmsgstr_size); } if (inmsgid) { /* multiple lines of msgid */ /* cancel the previous null termination */ bufptr_index--; } else { /* * The first line of msgid. * Save linenum of msgid to be used when * printing warning or error message. */ msgid_linenum = linenum; p = linebufptr; linebufptr = consume_whitespace( linebufptr + MSGID_LEN); ln_size -= linebufptr - p; bufptr = gmsgid; bufptr_index = 0; } inmsgid = 1; inmsgstr = 0; indomain = 0; goto load_buffer; } /* * Process MSGSTR Tokens. */ token_found = (wcsncmp(MSGSTR_TOKEN, linebufptr, MSGSTR_LEN) == 0) ? 1 : 0; if (token_found || (quotefound && inmsgstr)) { if (token_found) { if (!CK_NXT_CH(linebufptr, MSGSTR_LEN+1)) { diag(gettext(ERR_NOSPC), linenum); error(gettext(ERR_EXITING)); /* NOTREACHED */ } } if (inmsgstr && !quotefound) { warning(gettext(WARN_NO_MSGID), msgstr_linenum); continue; } if (inmsgstr) { /* multiple lines of msgstr */ /* cancel the previous null termination */ bufptr_index--; } else { /* * The first line of msgstr. * Save linenum of msgid to be used when * printing warning or error message. */ msgstr_linenum = linenum; p = linebufptr; linebufptr = consume_whitespace( linebufptr + MSGSTR_LEN); ln_size -= linebufptr - p; bufptr = gmsgstr; bufptr_index = 0; } inmsgstr = 1; inmsgid = 0; indomain = 0; goto load_buffer; } /* * Process DOMAIN Tokens. * Add message id and message string to sorted list * if msgstr was processed last time. */ token_found = (wcsncmp(DOMAIN_TOKEN, linebufptr, DOMAIN_LEN) == 0) ? 1 : 0; if ((token_found) || (quotefound && indomain)) { if (token_found) { if (!CK_NXT_CH(linebufptr, DOMAIN_LEN+1)) { diag(gettext(ERR_NOSPC), linenum); error(gettext(ERR_EXITING)); /* NOTREACHED */ } } /* * process msgid and msgstr pair for previous domain */ if (inmsgstr) { sortit(gmsgid, gmsgstr); } /* refresh msgid and msgstr buffer */ if (inmsgstr || inmsgid) { (void) memset(gmsgid, 0, gmsgid_size); (void) memset(gmsgstr, 0, gmsgstr_size); } if (indomain) { /* multiple lines of domain */ /* cancel the previous null termination */ bufptr_index--; } else { p = linebufptr; linebufptr = consume_whitespace( linebufptr + DOMAIN_LEN); (void) memset(gcurrent_domain, 0, sizeof (gcurrent_domain)); ln_size -= linebufptr - p; bufptr = gcurrent_domain; bufptr_index = 0; } indomain = 1; inmsgid = 0; inmsgstr = 0; } /* if */ load_buffer: /* * Now, fill up the buffer pointed by bufptr. * At this point bufptr should point to one of * msgid, msgptr, or current_domain. * Otherwise, the entire line is ignored. */ if (!bufptr) { warning(gettext(WARN_SYNTAX_ERR), linenum); continue; } if (*linebufptr++ != L'\"') { warning(gettext(WARN_MISSING_QUOTE), linenum); --linebufptr; } quotefound = 0; /* * If there is not enough space in the buffer, * increase buffer by ln_size by realloc. */ ll = ln_size * mbcurmax; if (bufptr == gmsgid) { if (gmsgid_size < (bufptr_index + ll)) { gmsgid = (char *)Xrealloc(gmsgid, bufptr_index + ll); bufptr = gmsgid; gmsgid_size = bufptr_index + ll; } } else if (bufptr == gmsgstr) { if (gmsgstr_size < (bufptr_index + ll)) { gmsgstr = (char *)Xrealloc(gmsgstr, bufptr_index + ll); bufptr = gmsgstr; gmsgstr_size = bufptr_index + ll; } } while (wc = *linebufptr++) { switch (wc) { case L'\n': if (!quotefound) { warning(gettext(WARN_MISSING_QUOTE_AT_EOL), linenum); } break; case L'\"': quotefound = 1; break; case L'\\': if ((mb = expand_meta(&linebufptr)) != NULL) bufptr[bufptr_index++] = mb; break; default: if ((n = wctomb(&bufptr[bufptr_index], wc)) > 0) bufptr_index += n; } /* switch */ if (quotefound) { /* * Check if any remaining characters * after closing quote. */ linebufptr = consume_whitespace(linebufptr); if (*linebufptr != L'\n') { warning(gettext(WARN_INVALID_STRING), linenum); } break; } } /* while */ bufptr[bufptr_index++] = '\0'; (void) strcpy(msgfile, gcurrent_domain); (void) strcat(msgfile, ".mo"); } /* for(;;) */ if (inmsgstr) { sortit(gmsgid, gmsgstr); } if (linebufhead) free(linebufhead); if (munmap(addr, statbuf.st_size) == -1) { error(gettext(ERR_MUNMAP_FAILED), filename); /* NOTREACHED */ } free(filename); return; } /* read_psffm */