예제 #1
0
파일: polyid.c 프로젝트: abensonca/mangle
/*------------------------------------------------------------------------------
  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);
}
예제 #2
0
파일: which_pixel.c 프로젝트: MCTwo/DEIMOS
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);  
  }
}
예제 #3
0
/*------------------------------------------------------------------------------
  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);
}