/* * read the new lines from a file */ int rwfile(struct kqfile *f, char *buf, size_t len, int nbytes) { int i, total = 0; printf("%10.10s: ", f->name); do { i = rdline(f->fd, buf, len); if (i == -1) return(-1); if (write(STDOUT_FILENO, buf, i) != i) warn("write stdout"); else total += i; /* * if this is true rdline has read one whole line * from the file, so print the filename again */ if (i < len && total < nbytes) printf("%10.10s: ", f->name); memset(buf, 0x00, len); } while (i > 0 && total < nbytes); return(total); }
/*------------------------------------------------------------------------------ Try to read weight from file. After arbitrary header lines, the file should contain a list of weights, one weight in each line. If the file contains only one weight, then that weight will be returned every time. Otherwise a new weight will be returned each time, and it is an error if the file does not contain enough weights. Input: survey = name of file containing weights. Return value: weight. */ double rdweight(char *survey) { #ifndef BUFSIZE # define BUFSIZE 64 #endif static int init = 0, nweight = 0; static double weight; static inputfile file = { '\0', /* input filename */ 0x0, /* input file stream */ '\0', /* line buffer */ BUFSIZE, /* size of line buffer (will expand as necessary) */ 0, /* line number */ 0 /* maximum number of characters to read (0 = no limit) */ }; int ird, iscan; /* first call */ if (!init) { /* test if survey is name of file */ file.file = fopen(survey, "r"); /* unknown survey */ if (!file.file) { fprintf(stderr, "weight_fn: unknown file or survey %s\n", survey); fprintf(stderr, "please look in weight_fn.c for the names of known surveys\n"); exit(1); } file.name = survey; /* survey appears to be a file */ msg("will read weights for each polygon from %s\n", survey); init = 1; } /* every call */ if (nweight >= 0) do { /* read line of data */ ird = rdline(&file); /* serious error */ if (ird == -1) exit(1); /* EOF */ if (ird == 0) { /* flag there's only one weight */ if (nweight == 1) { nweight = -1; break; /* premature EOF */ } else { fprintf(stderr, "weight_fn: unexpected EOF at line %d of %s\n", file.line_number, survey); exit(1); } } /* read contents of line into weight */ iscan = sscanf(file.line, "%lg", &weight); nweight++; } while (!iscan); return(weight); }
int main() { int t, i, cnt, n; char line[82]; char ln[82]; char input[811]; rdline(ln, sizeof(ln)); t = atoi(ln); cnt = 0; while( t != 0 ) { memset(macro_table, 0, sizeof(macro_table)); entry_cnt = 0; printf("Case %d\n", ++cnt); for(i = 0; i < 79; i++) putchar('-'); putchar('\n'); n = 0; for(i = 0; i < t; i++) { //scanf("%s", line); rdline(line, sizeof(line)); sprintf(input, "%s%s", input, line); } macro_proc(input); for(i = 0; i < 79; i++) putchar('-'); putchar('\n'); putchar('\n'); rdline(ln, sizeof(ln)); t = atoi(ln); input[0] = '\0'; } return 0; }
/* Append an input line to a String. * * Returns a pointer to the character string (or 0). * Leading whitespace and newlines are removed. * Lines starting with #include cause us to descend into the new file. * Empty lines and other lines starting with '#' are ignored. */ extern char * s_rdinstack(Sinstack *sp, String *to) { char *p; Biobuf *fp, *nfp; s_terminate(to); fp = sp->fp[sp->depth]; for(;;){ p = rdline(fp, to); if(p == nil){ if(sp->depth == 0) break; Bterm(fp); sp->depth--; return s_rdinstack(sp, to); } if(strncmp(p, "#include", 8) == 0 && (p[8] == ' ' || p[8] == '\t')){ to->ptr = p; p += 8; /* sanity (and looping) */ if(sp->depth >= nelem(sp->fp)) sysfatal("s_recgetline: includes too deep"); /* skip white */ while(*p == ' ' || *p == '\t') p++; nfp = Bopen(p, OREAD); if(nfp == nil) continue; sp->depth++; sp->fp[sp->depth] = nfp; return s_rdinstack(sp, to); } /* got milk? */ if(*p != '#') break; /* take care of comments */ to->ptr = p; s_terminate(to); } return p; }
/* * Search for nth occurrence of regular expression contained in buf in the file */ int search(char *buf, FILE *file, int n) { off_t startline = Ftell(file); off_t line1 = startline; off_t line2 = startline; off_t line3 = startline; off_t saveln; int lncount, rv; char ebuf[BUFSIZ]; static regex_t reg; static int initialized; context.line = saveln = Currline; context.chrctr = startline; lncount = 0; if (buf != NULL && *buf != '\0') { if ((rv = regcomp(®, buf, REG_NOSUB)) != 0) { initialized = 0; regerror(rv, ®, ebuf, sizeof(ebuf)); regfree(®); error(ebuf); return (-1); } initialized = 1; } else if (!initialized) { error("No previous regular expression"); return (-1); } while (!feof(file)) { line3 = line2; line2 = line1; line1 = Ftell(file); rdline(file); lncount++; if ((rv = regexec(®, Line, 0, NULL, 0)) == 0) { if (--n == 0) { if (lncount > 3 || (lncount > 1 && no_intty)) { putchar('\n'); if (clreol) cleareol(); fputs("...skipping\n", stdout); } if (!no_intty) { Currline -= (lncount >= 3 ? 3 : lncount); Fseek(file, line3); if (noscroll) { if (clreol) { home(); cleareol(); } else doclear(); } } else { kill_line(); if (noscroll) { if (clreol) { home(); cleareol(); } else doclear(); } fputs(Line, stdout); putchar('\n'); } break; } } else if (rv != REG_NOMATCH) { regerror(rv, ®, ebuf, sizeof(ebuf)); error(ebuf); return (-1); } } if (feof(file)) { if (!no_intty) { Currline = saveln; Fseek(file, startline); } else { fputs("\nPattern not found\n", stdout); end_it(); } error("Pattern not found"); return (-1); } return (0); }
/*------------------------------------------------------------------------------ Map. Implemented as interpretive read/write, to permit interactive behaviour. Input: in_filename = name of file to read from; "" or "-" means read from standard input. out_filename = name of file to write to; "" or "-" means write to standard output. fmt = pointer to format structure. w = array containing spherical harmonics. lmax = maximum harmonic number. lsmooth = smoothing harmonic number (0. = no smooth). esmooth = smoothing exponent (2. = gaussian). Return value: number of items written, or -1 if error occurred. */ int map(char *in_filename, char *out_filename, format *fmt, int lmax, harmonic w[/*NW*/], double lsmooth, double esmooth) { /* precision of map values written to file */ #define PRECISION 8 #define AZEL_STR_LEN 32 inputfile file = { '\0', /* input filename */ 0x0, /* input file stream */ '\0', /* line buffer */ 64, /* size of line buffer (will expand as necessary) */ 0, /* line number */ 0 /* maximum number of characters to read (0 = no limit) */ }; char input[] = "input", output[] = "output"; char *word, *next; char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN]; int ird, len, mmax, nmap, width; double rho; azel v; char *out_fn; FILE *outfile; /* open in_filename for reading */ if (!in_filename || strcmp(in_filename, "-") == 0) { file.file = stdin; file.name = input; } else { file.file = fopen(in_filename, "r"); if (!file.file) { fprintf(stderr, "cannot open %s for reading\n", in_filename); return(-1); } file.name = in_filename; } file.line_number = 0; /* open out_filename for writing */ if (!out_filename || strcmp(out_filename, "-") == 0) { outfile = stdout; out_fn = output; } else { outfile = fopen(out_filename, "w"); if (!outfile) { fprintf(stderr, "cannot open %s for writing\n", out_filename); return(-1); } out_fn = out_filename; } /* advise angular units */ msg("will take units of input az, el angles in %s to be ", file.name); switch (fmt->inunit) { #include "angunit.h" } msg("\n"); if (fmt->outunit != fmt->inunit) { msg("units of output az, el angles will be "); switch (fmt->outunit) { #include "angunit.h" } msg("\n"); } /* setting mmax = lmax ensures complete set of azimuthal harmonics */ mmax = lmax; /* width of map value */ width = PRECISION + 6; /* write header */ v.az = 0.; wrangle(v.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str); len = strlen(az_str); if (fmt->outunit == 'h') { sprintf(az_str, "az(hms)"); sprintf(el_str, "el(dms)"); } else { sprintf(az_str, "az(%c)", fmt->outunit); sprintf(el_str, "el(%c)", fmt->outunit); } fprintf(outfile, "%*s %*s %*s\n", len, az_str, len, el_str, width - 4, "wrho"); /* interpretive read/write loop */ nmap = 0; while (1) { /* read line */ ird = rdline(&file); /* serious error */ if (ird == -1) return(-1); /* EOF */ if (ird == 0) break; /* read <az> */ word = file.line; ird = rdangle(word, &next, fmt->inunit, &v.az); /* skip header */ if (ird != 1 && nmap == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* read <el> */ word = next; ird = rdangle(word, &next, fmt->inunit, &v.el); /* skip header */ if (ird != 1 && nmap == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* convert az and el from input units to radians */ scale_azel(&v, fmt->inunit, 'r'); /* The entire of map.c is an interface to the next line of code. Bizarre, huh? */ /* compute the value of the window function at this point */ rho = wrho(v.az, v.el, lmax, mmax, w, lsmooth, esmooth); /* convert az and el from radians to output units */ scale_azel(&v, 'r', fmt->outunit); /* write result */ wrangle(v.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str); wrangle(v.el, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, el_str); fprintf(outfile, "%s %s %- #*.*lg\n", az_str, el_str, width, PRECISION, rho); fflush(outfile); /* increment counter of results */ nmap++; } if (outfile != stdout) { msg("map: %d values written to %s\n", nmap, out_fn); } return(nmap); }
/*------------------------------------------------------------------------------ Angles within mask along circles centred at az el, radii th. Anglar positions az, el are read from azel_in_filename, angular radii th are read from th_in_filename, or from azel_in_filename if th_in_filename is null, and the results are written to out_filename. Implemented as interpretive read/write, to permit interactive behaviour. Input: azel_in_filename = name of file to read az, el from; "" or "-" means read from standard input. th_in_filename = name of file to read th from; null means read from azel_in_filename; "-" means read from standard input. out_filename = name of file to write to; "" or "-" means write to standard output. fmt = pointer to format structure. npoly = number of polygons in poly array. poly = array of pointers to polygons. Return value: number of lines written, or -1 if error occurred. */ int drangle(char *azel_in_filename, char *th_in_filename, char *out_filename, format *fmt, int npoly, polygon *poly[/*npoly*/]) { #define AZEL_STR_LEN 32 char input[] = "input", output[] = "output"; /* maximum number of angular angular radii: will expand as necessary */ static int nthmax = 0; static int ndrmax = 0; static long double *th = 0x0, *cm = 0x0, *drsum = 0x0; static long double *dr = 0x0; #ifdef TIME clock_t time; #endif char inunit, outunit; char *word, *next; char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN], th_str[AZEL_STR_LEN], dr_str[AZEL_STR_LEN]; int ier, ird, ith, len, lenth, np, nt, nth; long double rp[3], s, t; azel v; char *out_fn; FILE *outfile; inunit = (fmt->inunit == 'h')? 'd' : fmt->inunit; /* read angular radii from th_in_filename */ if (th_in_filename) { /* open th_in_filename for reading */ if (strcmp(th_in_filename, "-") == 0) { file.file = stdin; file.name = input; } else { file.file = fopen(th_in_filename, "r"); if (!file.file) { fprintf(stderr, "cannot open %s for reading\n", th_in_filename); return(-1); } file.name = th_in_filename; } file.line_number = 0; msg("will take units of input th angles in %s to be ", file.name); switch (inunit) { #include "angunit.h" } msg("\n"); /* read angular radii from th_in_filename */ nth = 0; while (1) { /* read line */ ird = rdline(&file); /* serious error */ if (ird == -1) return(-1); /* EOF */ if (ird == 0) break; /* read angular radius from line */ ird = rdangle(file.line, &next, inunit, &t); /* error */ if (ird < 1) { /* retry if nothing read, otherwise break */ if (nth > 0) break; /* ok */ } else if (ird == 1) { if (nth >= nthmax) { if (nthmax == 0) { nthmax = 64; } else { nthmax *= 2; } /* (re)allocate memory for th array */ th = (long double *) realloc(th, sizeof(long double) * nthmax); if (!th) { fprintf(stderr, "drangle: failed to allocate memory for %d long doubles\n", nthmax); return(-1); } } /* copy angular radius into th array */ th[nth] = t; nth++; } } if (file.file != stdin) { /* close th_in_filename */ fclose(file.file); /* advise */ msg("%d angular radii read from %s\n", nth, file.name); } if (nth == 0) return(nth); /* (re)allocate memory for th array */ th = (long double *) realloc(th, sizeof(long double) * nth); if (!th) { fprintf(stderr, "drangle: failed to allocate memory for %d long doubles\n", nth); return(-1); } /* (re)allocate memory for cm array */ cm = (long double *) realloc(cm, sizeof(long double) * nth); if (!cm) { fprintf(stderr, "drangle: failed to allocate memory for %d long doubles\n", nth); return(-1); } /* (re)allocate memory for drsum array */ drsum = (long double *) realloc(drsum, sizeof(long double) * nth); if (!drsum) { fprintf(stderr, "drangle: failed to allocate memory for %d long doubles\n", nth); return(-1); } nthmax = nth; } /* open azel_in_filename for reading */ if (!azel_in_filename || strcmp(azel_in_filename, "-") == 0) { file.file = stdin; file.name = input; } else { file.file = fopen(azel_in_filename, "r"); if (!file.file) { fprintf(stderr, "cannot open %s for reading\n", azel_in_filename); return(-1); } file.name = azel_in_filename; } file.line_number = 0; /* open out_filename for writing */ if (!out_filename || strcmp(out_filename, "-") == 0) { outfile = stdout; out_fn = output; } else { outfile = fopen(out_filename, "w"); if (!outfile) { fprintf(stderr, "cannot open %s for writing\n", out_filename); return(-1); } out_fn = out_filename; } /* advise input angular units */ if (th_in_filename) { msg("will take units of input az, el angles in %s to be ", file.name); } else { msg("will take units of input az, el, and th angles in %s to be ", file.name); } switch (fmt->inunit) { #include "angunit.h" } if (!th_in_filename && fmt->inunit == 'h') { msg(", th in deg"); } msg("\n"); /* advise output angular unit */ outunit = (fmt->outunit == 'h')? 'd' : fmt->outunit; msg("units of output DR angles will be "); switch (outunit) { #include "angunit.h" } msg("\n"); #ifdef TIME printf("timing ... "); fflush(stdout); time = clock(); #endif /* length of az, el and th, dr strings to be written to output */ t = 0.; wrangle(t, fmt->inunit, fmt->outprecision, AZEL_STR_LEN, az_str); len = strlen(az_str); t = 0.; wrangle(t, inunit, fmt->outprecision, AZEL_STR_LEN, th_str); lenth = strlen(th_str); /* write header */ if (!summary) { if (fmt->inunit == 'h') { sprintf(az_str, "az(hms)"); sprintf(el_str, "el(dms)"); sprintf(th_str, "th(d):"); } else { sprintf(az_str, "az(%c)", fmt->inunit); sprintf(el_str, "el(%c)", fmt->inunit); sprintf(th_str, "th(%c):", fmt->inunit); } if (th_in_filename) { fprintf(outfile, "%*s %*s %*s\n", len, " ", len, " ", lenth, th_str); } fprintf(outfile, "%*s %*s", len, az_str, len, el_str); if (th_in_filename) { for (ith = 0; ith < nth; ith++) { wrangle(th[ith], inunit, fmt->outprecision, AZEL_STR_LEN, th_str); fprintf(outfile, " %s", th_str); } fprintf(outfile, "\n"); } else { fprintf(outfile, " %*s\n", lenth, th_str); } } /* initialize th and drsum */ if (th_in_filename) { /* convert th from input units to radians */ for (ith = 0; ith < nth; ith++) { scale(&th[ith], inunit, 'r'); } /* initialize sum of dr to zero */ for (ith = 0; ith < nth; ith++) { drsum[ith] = 0.; } } /* interpretive read/write loop */ np = 0; nt = 0; while (1) { /* read line */ ird = rdline(&file); /* serious error */ if (ird == -1) return(-1); /* EOF */ if (ird == 0) break; /* read <az> */ word = file.line; ird = rdangle(word, &next, fmt->inunit, &v.az); /* skip header */ if (ird != 1 && np == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* read <el> */ word = next; ird = rdangle(word, &next, fmt->inunit, &v.el); /* skip header */ if (ird != 1 && np == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* convert az and el from input units to radians */ scale_azel(&v, fmt->inunit, 'r'); /* read th */ if (!th_in_filename) { nth = 0; while (1) { word = next; ird = rdangle(word, &next, inunit, &t); /* done */ if (ird < 1) break; /* ok */ if (nth >= nthmax) { if (nthmax == 0) { nthmax = 64; } else { nthmax *= 2; } th = (long double *) realloc(th, sizeof(long double) * nthmax); if (!th) { fprintf(stderr, "drangle: failed to allocate memory for %d long doubles\n", nthmax); return(-1); } /* (re)allocate memory for cm array */ cm = (long double *) realloc(cm, sizeof(long double) * nthmax); if (!cm) { fprintf(stderr, "drangle: failed to allocate memory for %d long doubles\n", nthmax); return(-1); } } th[nth] = t; /* increment count of angular radii */ nth++; } /* convert th from input units to radians */ for (ith = 0; ith < nth; ith++) { scale(&th[nth], inunit, 'r'); } } /* allocate memory for dr */ if (nth > ndrmax) { ndrmax = nth; dr = (long double *) realloc(dr, sizeof(long double) * ndrmax); if (!dr) { fprintf(stderr, "drangle: failed to allocate memory for %d long doubles\n", ndrmax); return(-1); } } /* unit vector corresponding to angular position az, el */ azel_to_rp(&v, rp); /* limiting cm = 1-cosl(th) values to each polygon */ ier = cmlim_polys(npoly, poly, mtol, rp); if (ier == -1) return(-1); /* cm = 1 - cosl(th) */ for (ith = 0; ith < nth; ith++) { s = sinl(th[ith] / 2.); cm[ith] = 2. * s * s; } /* angles about rp direction at radii th */ ier = drangle_polys(npoly, poly, mtol, rp, nth, cm, dr); if (ier == -1) return(-1); /* sum of dr at radii th */ if (th_in_filename) { for (ith = 0; ith < nth; ith++) { drsum[ith] += dr[ith]; } } /* convert az and el from radians to original input units */ scale_azel(&v, 'r', fmt->inunit); /* write result */ if (!summary) { wrangle(v.az, fmt->inunit, fmt->outprecision, AZEL_STR_LEN, az_str); wrangle(v.el, fmt->inunit, fmt->outprecision, AZEL_STR_LEN, el_str); fprintf(outfile, "%s %s", az_str, el_str); for (ith = 0; ith < nth; ith++) { scale(&dr[ith], 'r', outunit); wrangle(dr[ith], outunit, fmt->outprecision, AZEL_STR_LEN, dr_str); fprintf(outfile, " %s", dr_str); } fprintf(outfile, "\n"); fflush(outfile); } /* increment counters of results */ np++; nt += nth; /* warn about a potentially huge output file */ if (np == 100 && !summary && th_in_filename && outfile != stdout) { msg("hmm, looks like %s could grow pretty large ...\n", out_fn); msg("try using the -h switch if you only want a summary in the output file\n"); } } /* write sum of dr */ if (summary) { sprintf(th_str, "th(%c)", inunit); sprintf(dr_str, "DR(%c)", outunit); fprintf(outfile, "%*s %*s\n", lenth, th_str, lenth, dr_str); for (ith = 0; ith < nth; ith++) { scale(&th[ith], 'r', inunit); wrangle(th[ith], inunit, fmt->outprecision, AZEL_STR_LEN, th_str); scale(&drsum[ith], 'r', outunit); wrangle(drsum[ith] / (long double)np, outunit, fmt->outprecision, AZEL_STR_LEN, dr_str); fprintf(outfile, "%s %s\n", th_str, dr_str); } fflush(outfile); } else if (th_in_filename) { fprintf(outfile, "%*s", 2 * len + 1, "Average:"); for (ith = 0; ith < nth; ith++) { scale(&drsum[ith], 'r', outunit); wrangle(drsum[ith] / (long double)np, outunit, fmt->outprecision, AZEL_STR_LEN, dr_str); fprintf(outfile, " %s", dr_str); } fprintf(outfile, "\n"); fflush(outfile); } /* close azel_in_filename */ if (file.file != stdin) { fclose(file.file); } #ifdef TIME time = clock() - time; printf("done in %Lg sec\n", (float)time / (float)CLOCKS_PER_SEC); #endif /* advise */ if (outfile != stdout) { fclose(outfile); if (summary) { msg("drangle: header + %d lines written to %s\n", nth, out_fn); } else { if (th_in_filename) { msg("drangle: %d x %d = ", nth, np); } else { msg("drangle: total of "); } msg("%d angles at %d positions written to %s\n", nt, np, out_fn); } } return(nt); }
/*------------------------------------------------------------------------------ Rotate az, el positions from one frame to another. The az, el positions are read from in_filename, and rotated az, el positions are written to out_filename. Implemented as interpretive read/write, to permit interactive behaviour. Input: in_filename = name of file to read from; "" or "-" means read from standard input. out_filename = name of file to write to; "" or "-" means write to standard output. fmt = pointer to format structure. Return value: number of lines written, or -1 if error occurred. */ int rotate(char *in_filename, char *out_filename, format *fmt) { #ifndef BUFSIZE # define BUFSIZE 64 #endif #define AZEL_STR_LEN 32 static inputfile file = { '\0', /* input filename */ 0x0, /* input file stream */ '\0', /* line buffer */ BUFSIZE, /* size of line buffer (will expand as necessary) */ 0, /* line number */ 0 /* maximum number of characters to read (0 = no limit) */ }; char input[] = "input", output[] = "output"; char *word, *next; char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN]; int ird, len, np; long double circle; azel vi, vf; char *out_fn; FILE *outfile; /* open in_filename for reading */ if (!in_filename || strcmp(in_filename, "-") == 0) { file.file = stdin; file.name = input; } else { file.file = fopen(in_filename, "r"); if (!file.file) { fprintf(stderr, "cannot open %s for reading\n", in_filename); return(-1); } file.name = in_filename; } file.line_number = 0; /* open out_filename for writing */ if (!out_filename || strcmp(out_filename, "-") == 0) { outfile = stdout; out_fn = output; } else { outfile = fopen(out_filename, "w"); if (!outfile) { fprintf(stderr, "cannot open %s for writing\n", out_filename); return(-1); } out_fn = out_filename; } /* advise custom transformation */ if (fmt->outframe == -1) { /* multiple transformation */ if (strchr(fopt, ':')) { msg(" -f%s is equivalent to\n", fopt); msg(" -f%.16Lg,%.16Lg,%.16Lg%c\n", places(fmt->azn, 14), places(fmt->eln, 14), places(fmt->azp, 14), fmt->trunit); /* single transformation */ } else { msg("rotate -f%.16Lg,%.16Lg,%.16Lg%c\n", fmt->azn, fmt->eln, fmt->azp, fmt->trunit); } /* advise standard transformation */ } else if (fmt->inframe != fmt->outframe) { msg("rotate from %s to %s\n", frames[fmt->inframe], frames[fmt->outframe]); msg(" -f%s,%s is equivalent to\n", frames[fmt->inframe], frames[fmt->outframe]); msg(" -f%.16Lg,%.16Lg,%.16Lg%c\n", places(fmt->azn, 14), places(fmt->eln, 14), places(fmt->azp, 14), fmt->trunit); } /* angular units */ msg("will take units of input az, el angles in %s to be ", file.name); switch (fmt->inunit) { #include "angunit.h" } msg("\n"); if (fmt->outunit != fmt->inunit) { msg("units of output az, el angles will be "); switch (fmt->outunit) { #include "angunit.h" } msg("\n"); } /* write header */ vf.az = 0.; wrangle(vf.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str); len = strlen(az_str); if (fmt->outunit == 'h') { sprintf(az_str, "az(hms)"); sprintf(el_str, "el(dms)"); } else { sprintf(az_str, "az(%c)", fmt->outunit); sprintf(el_str, "el(%c)", fmt->outunit); } fprintf(outfile, "%*s %*s\n", len, az_str, len, el_str); /* interpretive read/write loop */ np = 0; while (1) { /* read line */ ird = rdline(&file); /* serious error */ if (ird == -1) return(-1); /* EOF */ if (ird == 0) break; /* read <az> */ word = file.line; ird = rdangle(word, &next, fmt->inunit, &vi.az); /* skip header */ if (ird != 1 && np == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* read <el> */ word = next; ird = rdangle(word, &next, fmt->inunit, &vi.el); /* skip header */ if (ird != 1 && np == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* identity: treat specially to avoid loss of precision in scaling */ if (fmt->inframe == fmt->outframe) { /* output angles = input angles */ vf.az = vi.az; vf.el = vi.el; circle = 360.; scale(&circle, 'd', fmt->inunit); /* phase az */ switch (fmt->outphase) { case '+': if (vf.az < 0.) vf.az += circle; break; case '-': if (vf.az > circle / 2.) vf.az -= circle; break; } /* convert az and el from input to output units */ scale_azel(&vf, fmt->inunit, fmt->outunit); /* normal rotation */ } else { /* convert az and el from input units to degrees */ scale_azel(&vi, fmt->inunit, 'd'); /* rotate az and el */ rotate_azel(fmt, &vi, &vf); /* phase az */ switch (fmt->outphase) { case '+': if (vf.az < 0.) vf.az += 360.; break; case '-': if (vf.az > 180.) vf.az -= 360.; break; } /* convert az and el from degrees to output units */ scale_azel(&vf, 'd', fmt->outunit); } /* write result */ wrangle(vf.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str); wrangle(vf.el, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, el_str); fprintf(outfile, "%s %s\n", az_str, el_str); fflush(outfile); /* increment counters of results */ np++; } if (outfile != stdout) { msg("rotate: %d positions written to %s\n", np, out_fn); } return(np); }
/*------------------------------------------------------------------------------ Id numbers of polygons containing az, el positions. The az, el positions are read from in_filename, and the results are written to out_filename. Implemented as interpretive read/write, to permit interactive behaviour. Input: in_filename = name of file to read from; "" or "-" means read from standard input. out_filename = name of file to write to; "" or "-" means write to standard output. fmt = pointer to format structure. poly = array of pointers to polygons. npoly = number of polygons in poly array. Return value: number of lines written, or -1 if error occurred. */ int poly_ids(char *in_filename, char *out_filename, format *fmt, int npoly, polygon *poly[/*npoly*/]) { #define AZEL_STR_LEN 32 char input[] = "input", output[] = "output"; char *word, *next; char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN]; int i, idwidth, ird, len, nid, nids, nid0, nid2, np; long long idmin, idmax; long long *id; long double *weight; azel v; char *out_fn; FILE *outfile; int *start; int *total; int *parent_pixels; int p, res, max_pixel, ier, sorted; ier=-1; sorted=0; while(ier!=0){ max_pixel= poly[npoly-1]->pixel; res_max=get_res(max_pixel, scheme); max_pixel=pixel_start(res_max+1,scheme); /* allocate memory for pixel info arrays start and total */ msg("res_max=%d, max_pixel=%d\n",res_max,max_pixel); start = (int *) malloc(sizeof(int) * max_pixel); if (!start) { fprintf(stderr, "polyid: failed to allocate memory for %d integers\n", max_pixel); return(-1); } total = (int *) malloc(sizeof(int) * max_pixel); if (!total) { fprintf(stderr, "polyid: failed to allocate memory for %d integers\n", max_pixel); return(-1); } parent_pixels = (int *) malloc(sizeof(int) * (res_max+1)); if (!parent_pixels) { fprintf(stderr, "polyid: failed to allocate memory for %d integers\n", res_max+1); return(-1); } /* build lists of starting indices of each pixel and total number of polygons in each pixel*/ ier=pixel_list(npoly, poly, max_pixel, start, total); if (ier == -1) { // if pixel_list returns an error, try sorting the polygons and trying again if(!sorted){ msg("sorting polygons...\n"); poly_sort(npoly,poly,'p'); sorted=1; } else{ fprintf(stderr, "poly_ids: error building pixel index lists\n"); return(-1); } } } /* open in_filename for reading */ if (!in_filename || strcmp(in_filename, "-") == 0) { file.file = stdin; file.name = input; } else { file.file = fopen(in_filename, "r"); if (!file.file) { fprintf(stderr, "cannot open %s for reading\n", in_filename); return(-1); } file.name = in_filename; } file.line_number = 0; /* open out_filename for writing */ if (!out_filename || strcmp(out_filename, "-") == 0) { outfile = stdout; out_fn = output; } else { outfile = fopen(out_filename, "w"); if (!outfile) { fprintf(stderr, "cannot open %s for writing\n", out_filename); return(-1); } out_fn = out_filename; } /* advise angular units */ msg("will take units of input az, el angles in %s to be ", file.name); switch (fmt->inunit) { #include "angunit.h" } msg("\n"); if (fmt->outunit != fmt->inunit) { msg("units of output az, el angles will be "); switch (fmt->outunit) { #include "angunit.h" } msg("\n"); } /* largest width of polygon id number */ idmin = 0; idmax = 0; for (i = 0; i < npoly; i++) { if (!poly[i]) continue; if (poly[i]->id < idmin) idmin = poly[i]->id; if (poly[i]->id > idmax) idmax = poly[i]->id; } idmin = ((idmin < 0)? floorl(log10l((long double)-idmin)) + 2 : 1); idmax = ((idmax > 0)? floorl(log10l((long double)idmax)) + 1 : 1); idwidth = ((idmin > idmax)? idmin : idmax); /* write header */ v.az = 0.; wrangle(v.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str); len = strlen(az_str); if (fmt->outunit == 'h') { sprintf(az_str, "az(hms)"); sprintf(el_str, "el(dms)"); } else { sprintf(az_str, "az(%c)", fmt->outunit); sprintf(el_str, "el(%c)", fmt->outunit); } fprintf(outfile, "%*s %*s", len, az_str, len, el_str); if (npoly > 0){ if(polyid_weight==1){ fprintf(outfile, " polygon_weights"); } else{ fprintf(outfile, " polygon_ids"); } } fprintf(outfile, "\n"); /* interpretive read/write loop */ np = 0; nid = 0; nids = 0; nid0 = 0; nid2 = 0; while (1) { /* read line */ ird = rdline(&file); /* serious error */ if (ird == -1) return(-1); /* EOF */ if (ird == 0) break; /* read <az> */ word = file.line; ird = rdangle(word, &next, fmt->inunit, &v.az); /* skip header */ if (ird != 1 && np == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* read <el> */ word = next; ird = rdangle(word, &next, fmt->inunit, &v.el); /* skip header */ if (ird != 1 && np == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* convert az and el from input units to radians */ scale_azel(&v, fmt->inunit, 'r'); //find out what pixel the az el point is in at the maximum resolution p=which_pixel(v.az, v.el, res_max, scheme); //get the list of all the possible parent pixels get_parent_pixels(p, parent_pixels, scheme); nid=0; for(res=res_max;res>=0;res--){ p=parent_pixels[res]; //if this pixel isn't in the polygon list, go to next parent pixel if(total[p]==0) continue; // id numbers of the polygons containing position az, el nid = poly_id(total[p], &poly[start[p]], v.az, v.el, &id, &weight); } /* convert az and el from radians to output units */ scale_azel(&v, 'r', fmt->outunit); /* write result */ wrangle(v.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str); wrangle(v.el, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, el_str); fprintf(outfile, "%s %s", az_str, el_str); for (i = 0; i < nid; i++) { if(polyid_weight==1){ fprintf(outfile, " %.18Lg", weight[i]); } else{ fprintf(outfile, " %*lld", idwidth, id[i]); } } fprintf(outfile, "\n"); fflush(outfile); /* increment counters of results */ np++; nids += nid; if (nid == 0) { nid0++; } else if (nid >= 2) { nid2++; } } /* advise */ if (nid0 > 0) msg("%d points were not inside any polygon\n", nid0); if (nid2 > 0) msg("%d points were inside >= 2 polygons\n", nid2); if (outfile != stdout) { if(polyid_weight==1){ msg("polyid: %d weights at %d positions written to %s\n", nids, np, out_fn); } else { msg("polyid: %d id numbers at %d positions written to %s\n", nids, np, out_fn); } } free(start); free(total); free(parent_pixels); return(np); }
int rowload(Row *row, char *file, int initing) { int i, j, line, percent, y, nr, nfontr, n, ns, ndumped, dumpid, x, fd; Biobuf *b, *bout; char *buf, *l, *t, *fontname; Rune *r, rune, *fontr; Column *c, *c1, *c2; uint q0, q1; Rectangle r1, r2; Window *w; buf = fbufalloc(); if(file == nil){ if(home == nil){ warning(nil, "can't find file for load: $home not defined\n"); goto Rescue1; } sprint(buf, "%s/acme.dump", home); file = buf; } b = Bopen(file, OREAD); if(b == nil){ warning(nil, "can't open load file %s: %r\n", file); goto Rescue1; } /* current directory */ line = 0; l = rdline(b, &line); if(l == nil) goto Rescue2; l[Blinelen(b)-1] = 0; if(chdir(l) < 0){ warning(nil, "can't chdir %s\n", l); goto Rescue2; } /* global fonts */ for(i=0; i<2; i++){ l = rdline(b, &line); if(l == nil) goto Rescue2; l[Blinelen(b)-1] = 0; if(*l && strcmp(l, fontnames[i])!=0) rfget(i, TRUE, i==0 && initing, l); } if(initing && row->ncol==0) rowinit(row, screen->clipr); l = rdline(b, &line); if(l == nil) goto Rescue2; j = Blinelen(b)/12; if(j<=0 || j>10) goto Rescue2; for(i=0; i<j; i++){ percent = atoi(l+i*12); if(percent<0 || percent>=100) goto Rescue2; x = row->r.min.x+percent*Dx(row->r)/100; if(i < row->ncol){ if(i == 0) continue; c1 = row->col[i-1]; c2 = row->col[i]; r1 = c1->r; r2 = c2->r; r1.max.x = x; r2.min.x = x+Border; if(Dx(r1) < 50 || Dx(r2) < 50) continue; draw(screen, Rpt(r1.min, r2.max), display->white, nil, ZP); colresize(c1, r1); colresize(c2, r2); r2.min.x = x; r2.max.x = x+Border; draw(screen, r2, display->black, nil, ZP); } if(i >= row->ncol) rowadd(row, nil, x); } for(;;){ l = rdline(b, &line); if(l == nil) break; dumpid = 0; switch(l[0]){ case 'e': if(Blinelen(b) < 1+5*12+1) goto Rescue2; l = rdline(b, &line); /* ctl line; ignored */ if(l == nil) goto Rescue2; l = rdline(b, &line); /* directory */ if(l == nil) goto Rescue2; l[Blinelen(b)-1] = 0; if(*l == '\0'){ if(home == nil) r = bytetorune("./", &nr); else{ t = emalloc(strlen(home)+1+1); sprint(t, "%s/", home); r = bytetorune(t, &nr); free(t); } }else r = bytetorune(l, &nr); l = rdline(b, &line); /* command */ if(l == nil) goto Rescue2; t = emalloc(Blinelen(b)+1); memmove(t, l, Blinelen(b)); run(nil, t, r, nr, TRUE, nil, nil, FALSE); /* r is freed in run() */ continue; case 'f': if(Blinelen(b) < 1+5*12+1) goto Rescue2; fontname = l+1+5*12; ndumped = -1; break; case 'F': if(Blinelen(b) < 1+6*12+1) goto Rescue2; fontname = l+1+6*12; ndumped = atoi(l+1+5*12+1); break; case 'x': if(Blinelen(b) < 1+5*12+1) goto Rescue2; fontname = l+1+5*12; ndumped = -1; dumpid = atoi(l+1+1*12); break; default: goto Rescue2; } l[Blinelen(b)-1] = 0; fontr = nil; nfontr = 0; if(*fontname) fontr = bytetorune(fontname, &nfontr); i = atoi(l+1+0*12); j = atoi(l+1+1*12); q0 = atoi(l+1+2*12); q1 = atoi(l+1+3*12); percent = atoi(l+1+4*12); if(i<0 || i>10) goto Rescue2; if(i > row->ncol) i = row->ncol; c = row->col[i]; y = c->r.min.y+(percent*Dy(c->r))/100; if(y<c->r.min.y || y>=c->r.max.y) y = -1; if(dumpid == 0) w = coladd(c, nil, nil, y); else w = coladd(c, nil, lookid(dumpid, TRUE), y); if(w == nil) continue; w->dumpid = j; l = rdline(b, &line); if(l == nil) goto Rescue2; l[Blinelen(b)-1] = 0; r = bytetorune(l+5*12, &nr); ns = -1; for(n=0; n<nr; n++){ if(r[n] == '/') ns = n; if(r[n] == ' ') break; } if(dumpid == 0) winsetname(w, r, n); for(; n<nr; n++) if(r[n] == '|') break; wincleartag(w); textinsert(&w->tag, w->tag.file->nc, r+n+1, nr-(n+1), TRUE); if(ndumped >= 0){ /* simplest thing is to put it in a file and load that */ sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser()); fd = create(buf, OWRITE|ORCLOSE, 0600); if(fd < 0){ free(r); warning(nil, "can't create temp file: %r\n"); goto Rescue2; } bout = emalloc(sizeof(Biobuf)); Binit(bout, fd, OWRITE); for(n=0; n<ndumped; n++){ rune = Bgetrune(b); if(rune == '\n') line++; if(rune == (Rune)Beof){ free(r); Bterm(bout); free(bout); close(fd); goto Rescue2; } Bputrune(bout, rune); } Bterm(bout); free(bout); textload(&w->body, 0, buf, 1); close(fd); w->body.file->mod = TRUE; for(n=0; n<w->body.file->ntext; n++) w->body.file->text[n]->w->dirty = TRUE; winsettag(w); }else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-') get(&w->body, nil, nil, FALSE, XXX, nil, 0); if(fontr){ fontx(&w->body, nil, nil, 0, 0, fontr, nfontr); free(fontr); } free(r); if(q0>w->body.file->nc || q1>w->body.file->nc || q0>q1) q0 = q1 = 0; textshow(&w->body, q0, q1, 1); w->maxlines = min(w->body.nlines, max(w->maxlines, w->body.maxlines)); } Bterm(b); fbuffree(buf); return TRUE; Rescue2: warning(nil, "bad load file %s:%d\n", file, line); Bterm(b); Rescue1: fbuffree(buf); return FALSE; }
/*------------------------------------------------------------------------------ Counts of pairs in bins bounded by radii th, centred at az el. Anglar positions az, el are read from azel_in_filename, angular radii th are read from th_in_filename, or from azel_in_filename if th_in_filename is null, and the results are written to out_filename. Implemented as interpretive read/write, to permit interactive behaviour. Input: azel_in_filename = name of file to read az, el from; "" or "-" means read from standard input. th_in_filename = name of file to read th from; "" or "-" means read from standard input. out_filename = name of file to write to; "" or "-" means write to standard output. fmt = pointer to format structure. npoly = number of polygons in poly array. poly = array of pointers to polygons. Return value: number of distinct pairs counted, or -1 if error occurred. */ long ddcount(char *azel_in_filename, char *th_in_filename, char *out_filename, format *fmt, int npoly, polygon *poly[/*npoly*/]) { #define AZEL_STR_LEN 32 char input[] = "input", output[] = "output"; /* maximum number of angular angular radii: will expand as necessary */ static int nthmax = 0; /* maximum number of az-el points: will expand as necessary */ static int nazelmax = 0; static int *dd = 0x0, *id = 0x0, *iord = 0x0; static long double *cm = 0x0, *th = 0x0; static azel *v = 0x0; static vec *rp = 0x0; #ifdef TIME clock_t time; #endif char inunit; char *word, *next; char th_str[AZEL_STR_LEN]; int i, iazel, idi, ird, ith, j, jazel, manyid, nazel, nid, noid, nth; int *id_p; long np; long double az, cmm, el, s, t; char *out_fn; FILE *outfile; /* open th_in_filename for reading */ if (strcmp(th_in_filename, "-") == 0) { file.file = stdin; file.name = input; } else { file.file = fopen(th_in_filename, "r"); if (!file.file) { fprintf(stderr, "cannot open %s for reading\n", th_in_filename); return(-1); } file.name = th_in_filename; } file.line_number = 0; inunit = (fmt->inunit == 'h')? 'd' : fmt->inunit; msg("will take units of input th angles in %s to be ", file.name); switch (inunit) { #include "angunit.h" } msg("\n"); /* read angular radii th from th_in_filename */ nth = 0; while (1) { /* read line */ ird = rdline(&file); /* serious error */ if (ird == -1) return(-1); /* EOF */ if (ird == 0) break; /* read angular radius from line */ ird = rdangle(file.line, &next, inunit, &t); /* error */ if (ird < 1) { /* retry if nothing read, otherwise break */ if (nth > 0) break; /* ok */ } else if (ird == 1) { if (nth >= nthmax) { if (nthmax == 0) { nthmax = 64; } else { nthmax *= 2; } /* (re)allocate memory for th array */ th = (long double *) realloc(th, sizeof(long double) * nthmax); if (!th) { fprintf(stderr, "ddcount: failed to allocate memory for %d long doubles\n", nthmax); return(-1); } } /* store th */ th[nth] = t; nth++; } } if (file.file != stdin) { /* close th_in_filename */ fclose(file.file); /* advise */ msg("%d angular radii read from %s\n", nth, file.name); } if (nth == 0) return(nth); /* open azel_in_filename for reading */ if (!azel_in_filename || strcmp(azel_in_filename, "-") == 0) { file.file = stdin; file.name = input; } else { file.file = fopen(azel_in_filename, "r"); if (!file.file) { fprintf(stderr, "cannot open %s for reading\n", azel_in_filename); return(-1); } file.name = azel_in_filename; } file.line_number = 0; /* advise input angular units */ msg("will take units of input az, el angles in %s to be ", file.name); switch (fmt->inunit) { #include "angunit.h" } msg("\n"); /* read angular positions az, el from azel_in_filename */ nazel = 0; while (1) { /* read line */ ird = rdline(&file); /* serious error */ if (ird == -1) return(-1); /* EOF */ if (ird == 0) break; /* read <az> */ word = file.line; ird = rdangle(word, &next, fmt->inunit, &az); /* skip header */ if (ird != 1 && nazel == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* read <el> */ word = next; ird = rdangle(word, &next, fmt->inunit, &el); /* skip header */ if (ird != 1 && nazel == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* (re)allocate memory for array of az-el points */ if (nazel >= nazelmax) { if (nazelmax == 0) { nazelmax = 64; } else { nazelmax *= 2; } v = (azel *) realloc(v, sizeof(azel) * nazelmax); if (!v) { fprintf(stderr, "ddcount: failed to allocate memory for %d az-el points\n", nazelmax); return(-1); } } /* record az-el */ v[nazel].az = az; v[nazel].el = el; /* increment number of az-el points */ nazel++; } if (file.file != stdin) { /* close azel_in_filename */ fclose(file.file); /* advise */ msg("%d angular positions az, el read from %s\n", nazel, file.name); } if (nazel == 0) return(nazel); /* open out_filename for writing */ if (!out_filename || strcmp(out_filename, "-") == 0) { outfile = stdout; out_fn = output; } else { outfile = fopen(out_filename, "w"); if (!outfile) { fprintf(stderr, "cannot open %s for writing\n", out_filename); return(-1); } out_fn = out_filename; } /* (re)allocate memory */ cm = (long double *) realloc(dd, sizeof(long double) * nth); if (!cm) { fprintf(stderr, "ddcount: failed to allocate memory for %d long doubles\n", nth); return(-1); } dd = (int *) realloc(dd, sizeof(int) * nth); if (!dd) { fprintf(stderr, "ddcount: failed to allocate memory for %d ints\n", nth); return(-1); } id = (int *) realloc(id, sizeof(int) * nazel); if (!id) { fprintf(stderr, "ddcount: failed to allocate memory for %d ints\n", nazel); return(-1); } rp = (vec *) realloc(rp, sizeof(vec) * nazel); if (!rp) { fprintf(stderr, "ddcount: failed to allocate memory for %d unit vectors\n", nazel); return(-1); } iord = (int *) realloc(iord, sizeof(int) * nazel); if (!iord) { fprintf(stderr, "ddcount: failed to allocate memory for %d ints\n", nazel); return(-1); } /* store 1 - cosl(th) in cm array */ for (ith = 0; ith < nth; ith++) { t = th[ith]; scale(&t, inunit, 'r'); s = sinl(t / 2.); cm[ith] = 2. * s * s; } /* convert az-el angles to radians */ for (iazel = 0; iazel < nazel; iazel++) { scale_azel(&v[iazel], fmt->inunit, 'r'); } /* convert az-el points to unit vectors */ for (iazel = 0; iazel < nazel; iazel++) { azel_to_rp(&v[iazel], rp[iazel]); } /* polygon id number(s) of az-el points */ msg("figuring polygon id number(s) of each az-el point ..."); noid = 0; manyid = 0; for (iazel = 0; iazel < nazel; iazel++) { nid = poly_id(npoly, poly, v[iazel].az, v[iazel].el, &id_p); if (nid == 0) { noid++; } else if (nid > 1) { manyid++; } /* store first polygon id of point */ if (nid == 0) { id[iazel] = -1; } else { id[iazel] = id_p[0]; } } msg(" done\n"); if (noid > 0) { msg("%d az-el points lie outside the angular mask: discard them\n", noid); } if (manyid > 0) { msg("%d az-el points lie inside more than one polygon: use only first polygon\n", manyid); } /* order az-el points in increasing order of polygon id */ finibot(id, nazel, iord, nazel); /* write header */ fprintf(outfile, "th(%c):", inunit); for (ith = 0; ith < nth; ith++) { wrangle(th[ith], inunit, fmt->outprecision, AZEL_STR_LEN, th_str); fprintf(outfile, "\t%s", th_str); } fprintf(outfile, "\n"); msg("counting pairs ..."); #ifdef TIME printf(" timing ... "); fflush(stdout); time = clock(); #endif /* loop over az-el points */ idi = -1; nid = 0; np = 0; for (iazel = 0; iazel < nazel; iazel++) { i = iord[iazel]; /* skip points outside mask */ if (id[i] == -1) continue; /* new polygon */ if (id[i] != idi) { idi = id[i]; /* reset pair counts to zero */ for (ith = 0; ith < nth; ith++) dd[ith] = 0; } //printf(" %d", idi); /* az-el neighbours within same polygon */ for (jazel = iazel + 1; jazel < nazel; jazel++) { j = iord[jazel]; /* exit at new polygon */ if (id[j] != idi) break; /* 1 - cosl(th_ij) */ cmm = cmij(rp[i], rp[j]); /* ith such that cm[ith-1] <= cmm < cm[ith] */ ith = search(nth, cm, cmm); /* increment count in this bin */ if (ith < nth) dd[ith]++; /* increment total pair count */ np++; } /* write counts for this polygon */ if (iazel + 1 == nazel || id[iord[iazel + 1]] != idi) { fprintf(outfile, "%d", idi); for (ith = 0; ith < nth; ith++) { fprintf(outfile, "\t%d", dd[ith]); } fprintf(outfile, "\n"); fflush(outfile); nid++; //printf("\n"); } } #ifdef TIME time = clock() - time; printf("done in %Lg sec\n", (float)time / (float)CLOCKS_PER_SEC); #else msg("\n"); #endif /* advise */ if (outfile != stdout) { fclose(outfile); msg("%d distinct pairs in %d th-bins x %d polygons written to %s\n", np, nth, nid, out_fn); } return(np); }