/*------------------------------------------------------------------------------ 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); }
/*------------------------------------------------------------------------------ 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); }
/*------------------------------------------------------------------------------ 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); }
/*------------------------------------------------------------------------------ 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); }