/*------------------------------------------------------------------------------ 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 which_pixel(double az, double el, int res, char scheme) { int n,m,pix,base_pix,i; unsigned long pixnum; double az_check, el_check; int *parent_pixels; if(az<0){ az+=TWOPI; } if(az>TWOPI || az<0){ fprintf(stderr, "error in which_pixel: az must lie between 0 and 2*PI.\n"); return(-1); } if(el>PIBYTWO || el<-PIBYTWO){ fprintf(stderr, "error in which_pixel: el must lie between -PI/2 and PI/2.\n"); return(-1); } if(res<0){ fprintf(stderr, "error in which_pixel: resolution must be an integer >=0.\n"); return(-1); } if(scheme=='s'){ // this scheme divides up the sphere by rectangles in az and el, and is numbered // such that the resolution is encoded in each pixel number. The whole sky is pixel 0, // pixels 1, 2, 3, and 4 are each 1/4 of the sky (resolution 1), pixels 5-20 are each // 1/16 of the sky (resolution 2), etc. if(az==TWOPI) az=0; n=(sin(el)==1) ? 0 : ceil((1-sin(el))/2*pow(2,res))-1; m=floor(az/(TWOPI)*pow(2,res)); base_pix=pow(2,res)*n+m; pix=pixel_start(res,scheme)+base_pix; return(pix); } else if(scheme=='d'){ assign_parameters(); if(az==TWOPI) az=0; /* ang2pix_radec takes az and el in degrees */ az *= (180.0/PI); el *= (180.0/PI); if(res==0){ return(0); } else if(res==1){ parent_pixels = (int *) malloc(sizeof(int) * (3)); if(!parent_pixels){ fprintf(stderr, "error in which_pixel: failed to allocate memory for 3 integers\n"); return(-1); } ang2pix_radec(1, az, el, &pixnum); pix = (int)pixnum; i = get_parent_pixels(pix+pixel_start(2,scheme), parent_pixels, scheme); if(i==1){ fprintf(stderr, "error in which_pixel: get_parent_pixels failed\n"); return(-1); } return(parent_pixels[1]); } else{ ang2pix_radec((int)pow(2,res-2), az, el, &pixnum); pix = (int)pixnum; /* check pix2ang_radec((int)pow(2,res-1), pixnum, &az_check, &el_check); printf("pix2ang_radec(pixnum = %d) = %f, %f\n", (int)pixnum, az_check, el_check); */ return(pix+pixel_start(res, scheme)); } } else{ fprintf(stderr, "error in which_pixel: pixel scheme %c not recognized.\n", scheme); return(-1); } }
/*------------------------------------------------------------------------------ Take pixelized polygons, find the average weight within each pixel, and return a set of polygons consisting of the pixels weighted with the average weight. Input: poly = array of pointers to polygons. npoly = pointer to number of polygons. Output: polys = array of pointers to polygons; Return value: number of polygons discarded by pixelmapping, or -1 if error occurred. */ int pixelmap(int *npoly, polygon *poly[/**npoly*/]) { int i, j, nadj, k, kstart,kend,numpix; int *start; int *total; int *parent_pixels; int begin, end, p,max_pixel,min_pixel, ier, verb,res1,res2; long double tol,area, tot_area; long double *av_weight; long double *av_weight0; poly_sort(*npoly,poly,'p'); min_pixel = poly[0]->pixel; max_pixel = poly[*npoly-1]->pixel+1; res1=get_res(min_pixel,scheme); res2=get_res(max_pixel,scheme); if(res1<res_max){ fprintf(stderr,"pixelmap: there are pixels in the mask with a lower resolution than the desired pixelmap resolution %d. The desired pixelmap resolution can be set with the -P option.\n",res_max); fprintf(stderr,"Before using pixelmap, use pixelize with the -P0,r option to pixelize the entire mask to the desired resolution r.\n"); return(-1); } /* allocate memory for pixel info arrays start and total */ start = (int *) malloc(sizeof(int) * max_pixel); if (!start) { fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", max_pixel); return(-1); } total = (int *) malloc(sizeof(int) * max_pixel); if (!total) { fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", max_pixel); 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) { fprintf(stderr, "pixelmap: error building pixel index lists\n"); return(-1); } //allocate memory for parent pixels array parent_pixels = (int *) malloc(sizeof(int) * (res2+1)); if (!parent_pixels) { fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", res2+1); return(-1); } //kstart=number of first pixel at desired output resolution //kend=number of last pixel at desired output resolution if(res_max==-1){ kstart=pixel_start(res1,scheme); kend=pixel_start(res2+1,scheme)-1; } else{ kstart=pixel_start(res_max,scheme); kend=pixel_start(res_max+1,scheme)-1; } av_weight0= (long double *) malloc(sizeof(long double) * (kend-kstart+1) ); if (!av_weight0) { fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", kend-kstart+1 ); return(-1); } //make av_weight an array indexed by the pixel number av_weight=av_weight0-kstart; //set av_weight array to 0 initially for(k=kstart;k<=kend;k++){ av_weight[k]=0; } nadj = 0; verb=1; /*find average weight of polygons within each pixel*/ for(p=min_pixel;p<max_pixel;p++){ begin=start[p]; end=start[p]+total[p]; ier=get_parent_pixels(p,parent_pixels,scheme); if(ier) return(-1); //set k to the pixel at the desired output resolution, or to the pixel number if using //existing resolution k=(res_max==-1) ? p : parent_pixels[res_max]; for (i = begin; i < end; i++) { if (!poly[i]) continue; tol=mtol; ier = garea(poly[i], &tol, verb, &area); if(ier==1 || ier == -1){ fprintf(stderr, "error %d in garea in polygon %d\n", ier, poly[i]->id); continue; } av_weight[k]+=poly[i]->weight * area; } } //replace polygons in input array with non-zero weight pixels j=0; for(k=kstart;k<=kend;k++){ if(av_weight[k]==0) continue; free_poly(poly[j]); poly[j]=get_pixel(k,scheme); tol=mtol; ier = garea(poly[j], &tol, verb, &tot_area); if(ier==1 || ier == -1){ fprintf(stderr, "pixelmap: error in garea in pixel %d\n",p); continue; } poly[j]->weight=av_weight[k]/tot_area; j++; if(j> *npoly ){ fprintf(stderr,"pixelmap: number of pixels with non-zero weight exceeds number of polygons.\n"); fprintf(stderr, "Try running unify on your mask to remove zero-weight polygons before using pixelmap.\n"); } } numpix=j; for(j=numpix; j< *npoly; j++){ free_poly(poly[j]); poly[j] = 0x0; nadj++; } *npoly=numpix; free(start); free(total); free(parent_pixels); free(av_weight0); /* assign new polygon id numbers */ if (fmt.newid == 'n') { for (i = 0; i < *npoly; i++) { poly[i]->id = i; } } if (fmt.newid == 'p') { for (i = 0; i < *npoly; i++) { poly[i]->id = poly[i]->pixel; } } /* advise */ msg("pixelmap: %d pixels in map\n", numpix); return(nadj); }