Beispiel #1
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);
}
Beispiel #2
0
/*------------------------------------------------------------------------------
  Weight polygons.

   Input: poly = array of pointers to polygons.
	  npoly = pointer to number of polygons.
	  survey = name of survey, or of filename containing list of weights.
  Output: polys = array of pointers to polygons;
  Return value: number of polygons weighted,
		or -1 if error occurred.
*/
int weight(int npoly, polygon *poly[/*npoly*/], char *survey)
{
    const int per = 0;
    const int nve = 2;

    int do_vcirc, i, imid, ipoly, iverts, ivm, nev, nev0, nomid, nv, nvm, nzero;
    int *ipv, *gp, *ev;
    long double tol;
    long double *angle;
    vec *ve, *vm;
    azel v;

    nomid = 0;
    nzero = 0;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	/* vertices of polygon */
	do_vcirc = 0;
	tol = mtol;
	iverts = gverts(poly[ipoly], do_vcirc, &tol, per, nve, &nv, &ve, &angle, &ipv, &gp, &nev, &nev0, &ev);
	if (iverts != 0) return(-1);
	/* point somewhere in the middle of the polygon */
	imid = vmid(poly[ipoly], tol, nv, nve, ve, ipv, ev, &nvm, &vm);
	if (imid == -1) return(-1);
	/* check found a point inside the polygon */
	imid = 0;
	for (ivm = 0; ivm < nvm; ivm++) {
	    if (vm[ivm][0] != 0. || vm[ivm][1] != 0. || vm[ivm][2] != 0.) {
		imid = 1;
		if (ivm > 0) for (i = 0; i < 3; i++) vm[0][i] = vm[ivm][i];
		break;
	    }
	}
	/* found a point */
        if (imid == 1) {
	    /* convert unit vector to az, el */
	    rp_to_azel(*vm, &v);
	    /* scale angles from radians to degrees */
	    scale_azel(&v, 'r', 'd');
	    /* weight at that point */
	    poly[ipoly]->weight = weight_fn(v.az, v.el, survey);
	    if (poly[ipoly]->weight == 0.) nzero++;
	/* failed to find a point */
	} else {
	  //call weight_fn to stay in right place in weight file if reading from weights from a file
	    weight_fn(v.az, v.el, survey);
	    if (nomid == 0) msg("weight: failed to find interior point for the following polygons:\n");
	    msg(" %lld", (fmt.newid == 'n')? (long long)ipoly+fmt.idstart : poly[ipoly]->id);
	    nomid++;
	}
    }
    if (nomid > 0) msg("\n");
    if (nomid > 0) {
	msg("weight: failed to find interior point for %d polygons\n", nomid);
        msg("FAILURE TO FIND INTERIOR POINT PROBABLY MEANS YOU HAVE A WEIRD-SHAPED POLYGON.\n");
	msg("PLEASE FILL IN THE CORRECT WEIGHT BY HAND.\n");
    }

    /* assign new polygon id numbers in place of inherited ids */
    if (fmt.newid == 'n') {
	for (ipoly = 0; ipoly < npoly; ipoly++) {
	  poly[ipoly]->id = (long long)ipoly+fmt.idstart;
	}
    }

    if (fmt.newid == 'p') {
      for (ipoly = 0; ipoly < npoly; ipoly++) {
	poly[ipoly]->id = (long long)poly[ipoly]->pixel;
      }
    }

    /* warn about zero weights */
    if (nzero > 0) msg("weight: %d polygons have zero weight\n", nzero);

    return(npoly);
}
Beispiel #3
0
/*------------------------------------------------------------------------------
  Generate random az, el positions within mask defined by poly.
  The results are written to out_filename.

   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.
	  npolysmax = maximum number of polygons in poly array.
	  poly = array of pointers to polygons.
	  mtol = initial tolerance angle for multiple intersections.
  Return value: number of random points generated,
		or -1 if error occurred.
*/
int ransack(char *out_filename, format *fmt, int npoly, int npolysmax, polygon *poly[/*npolysmax*/])
{
/* number of extra caps to allocate to polygon, to allow for expansion */
#define DNP			4
/* length of state vector for random number generator */
#define STATELEN		256
    static char state[STATELEN], stateo[STATELEN];
#define AZEL_STR_LEN		32
    char output[] = "output";
    char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN];
    int dnp, dnwl, i, idwidth, ier, in, inull, ip, ipmin, ipoly, iprune, irandom, lassoed, np, nwl, tries, verb, width, k;
    long long idmin,idmax;
    int *dlasso=0x0, *lasso=0x0;
    long double area, cmmin, cmi, phi, rpoly, si, tol, w, wcum, x, y, z;
    long double *wpoly;
    vec rp, xi, yi;
    azel v;
    char *out_fn;
    FILE *outfile;

    /* 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, "ransack: cannot open %s for writing\n", out_filename);
	    goto error;
	}
	out_fn = out_filename;
    }

    /* advise angular units */
    if (fmt->outunit != fmt->inunit) {
	msg("units of output az, el angles will be ");
	switch (fmt->outunit) {
#include "angunit.h"
	}
	msg("\n");
    }

    /* initialize random number generator used by ransack() */
    initstate(seed, state, STATELEN);
    /* initialize random number generator used by ikrand() */
    initstate(seed, stateo, STATELEN);

    /* prune polygons, discarding those with zero weight * area */
    msg("pruning %d polygons ...\n", npoly);
    ier = 0;
    inull = 0;
    np = 0;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	/* zero weight polygon */
	if (poly[ipoly]->weight == 0.) {
            inull++;
	    free_poly(poly[ipoly]);
	    poly[ipoly] = 0x0;
	} else {
	/* prune polygon */
	    iprune = prune_poly(poly[ipoly], mtol);
	    /* error */
	    if (iprune == -1) {
		ier++;
		free_poly(poly[ipoly]);
		poly[ipoly] = 0x0;
		fprintf(stderr, "ransack: failed to prune polygon %d; discard it\n", ipoly);
		/* goto error; */
	    /* zero area polygon */
	    } else if (iprune >= 2) {
		inull++;
		free_poly(poly[ipoly]);
		poly[ipoly] = 0x0;
	    } else {
		np++;
	    }
	}
    }
   /*copy down non-null polygons*/
    k=0;
    for(ipoly = 0; ipoly < npoly; ipoly++){
      if(poly[ipoly]){
	poly[k++]=poly[ipoly];
      }
    }
    /*after copying non-null polygons, k should be equal to np */
    if(k!=np){
      fprintf(stderr, "ransack: should be left with %d non-null polygons, but actually have %d\n",np,k);
    }

    /*nullify the rest of the array, but don't free, since pointers have been copied above*/
    for(ipoly=np; ipoly < npoly; ipoly++){
      poly[ipoly]=0x0;
    }

    if (ier > 0) {
	msg("discarding %d unprunable polygons\n", ier);
    }
    if (inull > 0) {
	msg("discarding %d polygons with zero weight * area\n", inull);
    }
    /* number of polygons with finite weight * area */
    npoly = np;

    /* no polygons */
    if (npoly == 0) {
	fprintf(stderr, "ransack: no polygons to generate random points inside!\n");
	goto error;
    }

    /* pre-lasso polygons if there are many random points */
    if (nrandom >= npoly) {
	msg("lassoing %d polygons ...\n", npoly);

	/* lasso each polygon */
	np = npoly;
	for (ipoly = 0; ipoly < npoly; ipoly++) {
	    ier = lasso_poly(&poly[ipoly], npolysmax - np, &poly[np], mtol, &dnp);
	    if (ier == -1) {
		fprintf(stderr, "ransack: UHOH at polygon %lld; continuing ...\n", poly[ipoly]->id);
	    }

	    /* lassoed polygons are an improvement over original polygon */
	    if (dnp > 0) {
		/* check whether exceeded maximum number of polygons */
		if (np + dnp > npolysmax) {
		    fprintf(stderr, "ransack: total number of polygons exceeded maximum %d\n", npolysmax);
		    fprintf(stderr, "if you need more space, enlarge NPOLYSMAX in defines.h, and recompile\n");
		    goto error;
		}

		/* decrement dnp by 1 */
		dnp--;

		/* increment number of polygons */
		np += dnp;

		/* move last polygon part into poly[ipoly] */
		free_poly(poly[ipoly]);
		poly[ipoly] = poly[np];
		poly[np] = 0x0;
	    }
	}

	/* revised number of polygons */
	npoly = np;

	/* flag that all polygons have been lassoed */
	lassoed = 1;

    /* two few random points to make it worth pre-lassoing */
    } else {
	/* flag that all polygons have not been lassoed */
	lassoed = 0;

    }

    /* allocate memory for wpoly array */
    nwl = npoly;
    wpoly = (long double *) malloc(sizeof(long double) * nwl);
    if (!wpoly) {
        fprintf(stderr, "ransack: failed to allocate memory for %d long doubles\n", nwl);
        goto error;
    }
    if (!lassoed) {
	/* allocate memory for lasso and dlasso arrays */
	lasso = (int *) malloc(sizeof(int) * nwl);
	if (!lasso) {
	    fprintf(stderr, "ransack: failed to allocate memory for %d ints\n", nwl);
	    goto error;
	}
	dlasso = (int *) malloc(sizeof(int) * nwl);
	if (!dlasso) {
	    fprintf(stderr, "ransack: failed to allocate memory for %d ints\n", nwl);
	    goto error;
	}

	/* initialize dlasso array to zero */
	for (ipoly = 0; ipoly < nwl; ipoly++) dlasso[ipoly] = 0;
    }

    /* largest width of polygon id number */
    idmin = 0;
    idmax = 0;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	if (poly[ipoly]->id < idmin) idmin = poly[ipoly]->id;
	if (poly[ipoly]->id > idmax) idmax = poly[ipoly]->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 */
    wrangle(0., fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str);
    width = 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\t%*s\t%*s\n", width, az_str, width, el_str, idwidth, "id");

    /* accept error messages from garea */
    /* unprunable polygons were already discarded, so garea should give no errors */
    verb = 1;

    /* cumulative area times weight of polygons */
    w = 0.;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	/* skip null polygons */
	if (poly[ipoly]) {
	    /* area of polygon */
	    tol = mtol;
	    ier = garea(poly[ipoly], &tol, verb, &area);
	    if (ier) goto error;
	    /* accumulate weight times area */
	    w += poly[ipoly]->weight * area;
	}
	wpoly[ipoly] = w;
    }
    wcum = w;

    /* random points */
    if (strcmp(out_fn, output) != 0) {
	msg("generating %d random points from seed %u in %d polygons ...\n", nrandom, seed, npoly);
    }
    for (irandom = 0; irandom < nrandom; irandom++) {

	/* random number in interval [0, 1) wcum */
	setstate(state);
	rpoly = drandom() * wcum;
	setstate(stateo);

	/* which polygon to put random point in */
	ipoly = search(npoly, wpoly, rpoly);

	/* guard against roundoff */
	if (ipoly >= npoly) {
	    fprintf(stderr, "ransack: %d should be < %d (i.e. %.15Lg < %.15Lg)\n", ipoly, npoly, rpoly, wpoly[npoly - 1]);
	    ipoly = npoly - 1;
	}

	/* all polygons have not been lassoed */
	if (!lassoed) {

	    /* polygon has not yet been lassoed */
	    if  (dlasso[ipoly] == 0) {

		/* lasso polygon */
		ier = lasso_poly(&poly[ipoly], npolysmax - np, &poly[np], mtol, &dnp);
		if (ier == -1) {
		    fprintf(stderr, "ransack: UHOH at polygon %lld; continuing ...\n", poly[ipoly]->id);
		}

		/* go with original polygon */
		if (dnp == 0) {
		    /* lasso, dlasso */
		    lasso[ipoly] = ipoly;
		    dlasso[ipoly] = 1;

		/* lassoed polygons are an improvement over original */
		} else {
		    /* check whether exceeded maximum number of polygons */
		    if (np + dnp > npolysmax) {
			fprintf(stderr, "ransack: total number of polygons exceeded maximum %d\n", npolysmax);
			fprintf(stderr, "if you need more space, enlarge NPOLYSMAX in defines.h, and recompile\n");
			goto error;
		    }

		    /* just one lassoed polygon */
		    if (dnp == 1) {
			/* move last polygon part into poly[ipoly] */
			free_poly(poly[ipoly]);
			poly[ipoly] = poly[np];
			poly[np] = 0x0;

			/* lasso, dlasso */
			lasso[ipoly] = ipoly;
			dlasso[ipoly] = 1;

		    /* more than one lassoed polygon */
		    } else {
			/* enlarge memory for wpoly, lasso, and dlasso arrays */
			if (np + dnp > nwl) {
			    dnwl = dnp + 1024;
			    wpoly = (long double *) realloc(wpoly, sizeof(long double) * (nwl + dnwl));
			    if (!wpoly) {
				fprintf(stderr, "ransack: failed to reallocate memory for %d long doubles\n", nwl + dnwl);
				goto error;
			    }
			    lasso = (int *) realloc(lasso, sizeof(int) * (nwl + dnwl));
			    if (!lasso) {
				fprintf(stderr, "ransack: failed to reallocate memory for %d ints\n", nwl + dnwl);
				goto error;
			    }
			    dlasso = (int *) realloc(dlasso, sizeof(int) * (nwl + dnwl));
			    if (!dlasso) {
				fprintf(stderr, "ransack: failed to reallocate memory for %d ints\n", nwl + dnwl);
				goto error;
			    }

			    /* initialize new part of lasso and dlasso arrays to inconsistent values */
			    for (ipoly = nwl; ipoly < nwl + dnwl; ipoly++) lasso[ipoly] = 1;
			    for (ipoly = nwl; ipoly < nwl + dnwl; ipoly++) dlasso[ipoly] = 0;

			    /* revised size of wpoly, lasso, and dlasso arrays */
			    nwl += dnwl;
			}

			/* lasso, dlasso */
			lasso[ipoly] = np;
			dlasso[ipoly] = dnp;

			/* cumulative weight times area of lassoed polygons */
			w = (ipoly == 0)? 0. : wpoly[ipoly-1];
			for (ip = np; ip < np + dnp; ip++) {
			    /* area of polygon */
			    tol = mtol;
			    ier = garea(poly[ip], &tol, verb, &area);
			    if (ier) goto error;
			    /* accumulate area times weight */
			    w += poly[ip]->weight * area;
			    wpoly[ip] = w;
			}

			/* increment number of polygons */
			np += dnp;
		    }

		}

	    }

	    /* polygon was partitioned into at least two */
	    if (dlasso[ipoly] >= 2) {
		/* which polygon to put random point in */
		ip = search(dlasso[ipoly], &wpoly[lasso[ipoly]], rpoly);

		/* guard against roundoff */
		if (ip >= lasso[ipoly] + dlasso[ipoly]) {
		    fprintf(stderr, "ransack: %d should be < %d (i.e. %.15Lg < %.15Lg)\n", ip, lasso[ipoly] + dlasso[ipoly], rpoly, wpoly[lasso[ipoly] + dlasso[ipoly] - 1]);
		    ip = lasso[ipoly] + dlasso[ipoly] - 1;
		}

		/* revised polygon number to put random point in */
		ipoly = ip;
	    }
	}

	/* smallest cap of polygon */
	cmminf(poly[ipoly], &ipmin, &cmmin);

	/* random point within polygon */
	tries = 0;
	do {
	    tries++;
	    /* random point within smallest cap */
	    setstate(state);
	    phi = TWOPI * drandom();
	    cmi = cmmin * drandom();
	    setstate(stateo);
	    /* coordinates of random point in cap frame */
	    si=sqrtl(cmi * (2. - cmi));
	    x = si * cosl(phi);
	    y = si * sinl(phi);
	    z = 1. - cmi;
	    /* polygon has caps */
	    if (poly[ipoly]->np > 0) {
		if (poly[ipoly]->cm[ipmin] < 0.) z = -z;
		/* Cartesian axes with z-axis along cap axis */
		gaxisi_(poly[ipoly]->rp[ipmin], xi, yi);
		/* coordinates of random point */
		for (i = 0; i < 3; i++) rp[i] = x * xi[i] + y * yi[i] + z * poly[ipoly]->rp[ipmin][i];
		/* whether random point is inside polygon */
		in = gptin(poly[ipoly], rp);
	    /* polygon has no caps, so is the whole sphere */
	    } else {
		rp[0] = x;
		rp[1] = y;
		rp[2] = z;
		in = 1;
	    }
	} while (!in);

	/* convert unit vector to az, el */
	rp_to_azel(rp, &v);
	v.az -= floorl(v.az / TWOPI) * TWOPI;

	/* 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\t%s\t%*lld\n", az_str, el_str, idwidth, poly[ipoly]->id);
	/* fprintf(outfile, "%s %s %d %d %d %Lg %Lg %Lg %Lg %d %d\n", az_str, el_str, irandom, ipoly, tries, wcum, rpoly / wcum, area, TWOPI * cmmin / area, ipmin, poly[ipoly]->np); */

    }

    /* advise */
    if (outfile != stdout) {
	msg("ransack: %d random positions written to %s\n", nrandom, out_fn);
    }

    return(nrandom);

    /* error returns */
    error:
    return(-1);
}
Beispiel #4
0
/*------------------------------------------------------------------------------
  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);
}
Beispiel #5
0
/*------------------------------------------------------------------------------
  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);
}
Beispiel #6
0
/*------------------------------------------------------------------------------
  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);
}
Beispiel #7
0
/*------------------------------------------------------------------------------
  Write midpoints.

  Input: filename = name of file to write to;
  "" or "-" means write to standard output.
  fmt = pointer to format structure.
  polys = polygons to write.
  npolys = number of polygons.
  npolyw = number of polygons to write.
  Return value: number of polygons written,
  or -1 if error occurred.
*/
int wr_midpoint(char *filename, format *fmt, int npolys, polygon *polys[/*npolys*/], int npolyw)
{
  const int per = 0;
  const int nve = 2;
  const int do_vcirc = 0;
  char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN];
  int i, idmin, idmax, idwidth, ier, imid, ipoly, ivm, nev, nev0, npoly, nv, nvm, width;
  int *ipv, *gp, *ev;
  double tol;
  double *angle;
  vec *ve, *vm;
  azel v;
  FILE *file;

  /* open filename for writing */
  if (!filename || strcmp(filename, "-") == 0) {
    file = stdout;
  } else {
    file = fopen(filename, "w");
    if (!file) {
	    fprintf(stderr, "wr_midpoint: cannot open %s for writing\n", filename);
	    return(-1);
    }
  }

  /* largest width of polygon id number */
  idmin = 0;
  idmax = 0;
  for (ipoly = 0; ipoly < npolys; ipoly++) {
    if (!polys[ipoly]) continue;
    if (polys[ipoly]->id < idmin) idmin = polys[ipoly]->id;
    if (polys[ipoly]->id > idmax) idmax = polys[ipoly]->id;
  }
  idmin = ((idmin < 0)? floor(log10((double)-idmin)) + 2 : 1);
  idmax = ((idmax > 0)? floor(log10((double)idmax)) + 1 : 1);
  idwidth = ((idmin > idmax)? idmin : idmax);

  /* write header */
  wrangle(0., fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, az_str);
  width = strlen(az_str);
  if (fmt->outunitp == 'h') {
    sprintf(az_str, "az(hms)");
    sprintf(el_str, "el(dms)");
  } else {
    sprintf(az_str, "az(%c)", fmt->outunitp);
    sprintf(el_str, "el(%c)", fmt->outunitp);
  }
  fprintf(file, "midpoint of %d polygons\n", npolyw);
  fprintf(file, "%*s %*s %*s\n", width, az_str, width, el_str, idwidth, "id");

  npoly = 0;
  for (ipoly = 0; ipoly < npolys; ipoly++) {
    /* discard null polygons */
    if (!polys[ipoly]) continue;

    /* point somewhere in the middle of the polygon */
    tol = mtol;
    ier = gverts(polys[ipoly], do_vcirc, &tol, per, nve, &nv, &ve, &angle, &ipv, &gp, &nev, &nev0, &ev);
    if (ier == -1) return(-1);
    imid = vmid(polys[ipoly], tol, nv, nve, ve, ipv, ev, &nvm, &vm);
    if (imid == -1) return(-1);
    /* check found a point inside the polygon */
    imid = 0;
    for (ivm = 0; ivm < nvm; ivm++) {
	    if (vm[ivm][0] != 0. || vm[ivm][1] != 0. || vm[ivm][2] != 0.) {
        imid = 1;
        if (ivm > 0) for (i = 0; i < 3; i++) vm[0][i] = vm[ivm][i];
        break;
	    }
    }
    /* found a point */
    if (imid == 1) {
	    rp_to_azel(vm[0], &v);
	    switch (fmt->outphase) {
	    case '+':	if (v.az < 0.) v.az += TWOPI;	break;
	    case '-':	if (v.az > PI) v.az -= TWOPI;	break;
	    }
	    scale_azel(&v, 'r', fmt->outunitp);
    }

    /* write midpoint of polygon */
    wrangle(v.az, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, az_str);
    wrangle(v.el, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, el_str);
    fprintf(file, "%s %s %*d\n", az_str, el_str, idwidth, polys[ipoly]->id);

    /* increment polygon count */
    npoly++;
  }

  /* advise */
  msg("%d midpoints written to %s\n",
      npoly, (file == stdout)? "output": filename);

  /* close file */
  if (file != stdout) fclose(file);

  return(npoly);
}
Beispiel #8
0
/*------------------------------------------------------------------------------
  Write mask data in edges or vertices format.

  Input: filename = name of file to write to;
  "" or "-" means write to standard output.
  fmt = pointer to format structure.
  polys = polygons to write.
  npolys = number of polygons.
  npolyw = number of polygons to write.
  Return value: number of polygons written,
  or -1 if error occurred.
*/
int wr_edge(char *filename, format *fmt, int npolys, polygon *polys[/*npolys*/], int npolyw)
{
  const int per = 0;
  const int nve = 2;
  const char *edges_fmt = "edges %d ( %d points/edge, %d edges, %.15lg weight, %s %s mid):\n";
  const char *graphics_fmt = "graphics %d ( %d points, %d edges, %.15lg weight, %s %s mid):\n";
  const char *vertices_fmt = "vertices %d ( %d vertices, %.15lg weight, %s %s mid):\n";
  char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN];
  int do_vcirc, i, ier, imid, ipoly, iv, ive, ivm, jv, manybounds, nbadverts, nev, nev0, npoly, npt, nv, nvm;
  int *ipv, *gp, *ev;
  double azo, tol;
  double *angle;
  vec *ve, *vm;
  azel v;
  FILE *file;

  /* open filename for writing */
  if (!filename || strcmp(filename, "-") == 0) {
    file = stdout;
  } else {
    file = fopen(filename, "w");
    if (!file) {
	    fprintf(stderr, "wr_edge: cannot open %s for writing\n", filename);
	    return(-1);
    }
  }

  /* whether to write vertices also for circles with no intersections */
  if (strcmp(fmt->out, "vertices") == 0) {
    do_vcirc = 0;
  } else {
    do_vcirc = 1;
  }

  /* write number of polygons */
  fprintf(file, "%d polygons\n", npolyw);

  /* write angular unit */
  fprintf(file, "unit %c\n", fmt->outunitp);

  manybounds = 0;
  npoly = 0;
  nbadverts = 0;
  for (ipoly = 0; ipoly < npolys; ipoly++) {
    /* discard null polygons */
    if (!polys[ipoly]) continue;

    /* point somewhere in the middle of the polygon */
    tol = mtol;
    ier = gverts(polys[ipoly], do_vcirc, &tol, per, nve, &nv, &ve, &angle, &ipv, &gp, &nev, &nev0, &ev);
    if (ier == -1) return(-1);
    imid = vmid(polys[ipoly], tol, nv, nve, ve, ipv, ev, &nvm, &vm);
    if (imid == -1) return(-1);
    /* check found a point inside the polygon */
    imid = 0;
    for (ivm = 0; ivm < nvm; ivm++) {
	    if (vm[ivm][0] != 0. || vm[ivm][1] != 0. || vm[ivm][2] != 0.) {
        imid = 1;
        if (ivm > 0) for (i = 0; i < 3; i++) vm[0][i] = vm[ivm][i];
        break;
	    }
    }
    /* found a point */
    if (imid == 1) {
	    rp_to_azel(vm[0], &v);
	    switch (fmt->outphase) {
	    case '+':	if (v.az < 0.) v.az += TWOPI;	break;
	    case '-':	if (v.az > PI) v.az -= TWOPI;	break;
	    }
	    scale_azel(&v, 'r', fmt->outunitp);
    }

    /* points on edges of polygon */
    tol = mtol;
    ier = gverts(polys[ipoly], do_vcirc, &tol, fmt->outper, fmt->outnve, &nv, &ve, &angle, &ipv, &gp, &nev, &nev0, &ev);
    if (ier == -1) return(-1);
    if (ier) {
	    nbadverts++;
	    continue;
    }

    /* warn about multi-boundary polygon */
    if (nev > 1) {
	    if (WARNMAX > 0 && manybounds == 0) {
        msg("the following polygons have > 1 boundary (not simply-connected)\n");
        msg("   separate boundaries will be split over separate lines:\n");
	    }
	    if (manybounds < WARNMAX) {
        msg(" %d", polys[ipoly]->id);
	    } else if (manybounds == WARNMAX) {
        msg(" ... more\n");
	    }
	    manybounds++;
    }

    /* count number of points */
    npt = 0;
    for (iv = jv = 0; iv < nv; jv++) {
	    for (; iv < ev[jv]; iv++) {
        for (ive = 0; ive < fmt->outnve; ive++) {
          i = iv * fmt->outnve + ive;
          if (ve[i][0] == 0. && ve[i][1] == 0. && ve[i][2] == 0.) break;
          npt++;
        }
	    }
    }

    /* number of edges, weight, and midpoint of polygon */
    wrangle(v.az, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, az_str);
    wrangle(v.el, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, el_str);
    if (strcmp(fmt->out, "edges") == 0) {
	    fprintf(file, edges_fmt,
              polys[ipoly]->id, fmt->outnve, nv, polys[ipoly]->weight, az_str, el_str);
    } else if (strcmp(fmt->out, "graphics") == 0) {
	    fprintf(file, graphics_fmt,
              polys[ipoly]->id, npt, nv, polys[ipoly]->weight, az_str, el_str);
    } else {
	    fprintf(file, vertices_fmt,
              polys[ipoly]->id, nv, polys[ipoly]->weight, az_str, el_str);
    }

    /* write points, splitting separate boundaries over separate lines */
    for (iv = jv = 0; iv < nv; jv++) {
	    for (; iv < ev[jv]; iv++) {
        for (ive = 0; ive < fmt->outnve; ive++) {
          i = iv * fmt->outnve + ive;
          if (ve[i][0] == 0. && ve[i][1] == 0. && ve[i][2] == 0.) break;
          /* convert unit vector to azel vertex */
          rp_to_azel(ve[i], &v);
          /* set azimuth of first point */
          if (iv == 0 && ive == 0) {
            switch (fmt->outphase) {
            case '+':	if (v.az < 0.) v.az += TWOPI;	break;
            case '-':	if (v.az > PI) v.az -= TWOPI;	break;
            }
            /* phase azimuth of each subsequent point to the previous point */
          } else {
            v.az -= rint((v.az - azo) / TWOPI) * TWOPI;
          }
          azo = v.az;
          scale_azel(&v, 'r', fmt->outunitp);
          wrangle(v.az, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, az_str);
          wrangle(v.el, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, el_str);
          fprintf(file, " %s %s", az_str, el_str);
        }
	    }
	    fprintf(file, "\n");
    }
    /* increment polygon count */
    npoly++;
  }
  /* warn about multi-boundary polygon */
  if (WARNMAX > 0 && manybounds > 0 && manybounds <= WARNMAX) msg("\n");
  if (manybounds > 0) msg("%d polygons had more than one boundary (not simply-connected)\n", manybounds);

  /* warn about polygons producing fatal error */
  if (nbadverts > 0) {
    msg("%d polygons producing fatal error in gvert discarded\n");
  }

  /* advise */
  msg("%d polygons written to %s\n",
      npoly, (file == stdout)? "output": filename);

  /* close file */
  if (file != stdout) fclose(file);

  return(npoly);
}
Beispiel #9
0
/*------------------------------------------------------------------------------
  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);
}