Home Andrew Hamilton’s Homepage

For her PhD thesis at MIT, Molly Swanson developed an improved version of mangle. It is improved in the sense that it is able to deal with huge masks more efficiently. Whereas the original mangle did its work by looping over all pairs of polygons, Swanson’s mangle adaptively tesselates the sky, and loops over pairs of polygons only within the same tile.
  The improved mangle code is available at
http://space.mit.edu/~molly/mangle
  The paper describing the improved algorithms is
Swanson, Tegmark, Hamilton, & Hill (2008)
   
 
mangle
Software to deal accurately and efficiently with complex angular masks of galaxy surveys.
   
 

2QZ 10k North mask; click on the image for a larger version (200K)
Angular mask of the Northern part of the 2dF QSO Redshift Survey 10k release. The upper panel depicts the exact mask. The 5° × 5° rectangles delineate the parent UKST fields, while the black 2° diameter circles are the fields of the 2dF spectroscopic survey. The red things are holes in the UKST fields. The middle panel shows the 1178 connected polygons, bounded by 4883 edges (including abutting edges), into which mangle resolves the mask. The lower panel shows the mask reconstructed by mangle from harmonics up to \(l = 1000\).

mă′ngle² (-nggel) v.t.
Hack, cut about, mutilate, by blows; cut roughly so as to disfigure; spoil (quotation, text, etc.) by gross blunders, make (words) unrecognizable by mispronouncing. [f. AF. ma(ha)ngler, app. frequent. of mahaigner MAIM]
— The Concise Oxford Dictionary.

  The URL of this page is
http://jila.colorado.edu/~ajsh/mangle/ .
  The algorithms and mathematics underlying mangle are written up in
Hamilton & Tegmark (2004).
  This page contains the documentation for the mangle software. The only other ways to find out about mangle are
(1) by reading the above-referenced paper,
(2) by running the commands,
(3) by reading the source code.

Contents of this page

  1. Download
  2. What is mangle?
  3. Definition of Terms
  4. Commands
  5. Format of Polygon Files
  6. Troubleshooting
  7. References, Links

1. Download

  Source and executable compiled for Linux-Intel:
mangle1.4.3-i386.tar.gz (5.5MB version of 14 Sep 2006)
mangle1.4.1-i386.tar.gz (5.4MB version of 30 Mar 2004)
mangle1.4-i386.tar.gz (5.4MB version of 3 Sep 2003)
  Source and executable compiled for Solaris:
mangle1.4.3-sun.tar.gz (5.6MB version of 14 Sep 2006)
mangle1.4.1-sun.tar.gz (5.0MB version of 30 Mar 2004)
mangle1.4-sun.tar.gz (5.1MB version of 3 Sep 2003)
  Patch to upgrade mangle 1.4.1 to 1.4.3 mangle1.4.1_to_1.4.3.patch (17K)
  Patch to upgrade mangle 1.4 to 1.4.1 mangle1.4_to_1.4.1.patch (33K)

Both of the above include mask files for PSCz, for the 2dF QSO 10k Redshift Survey, and for the 2dFGRS 100k.

2. What is mangle?

Mangle is a suite of software designed to deal accurately and efficiently with complex angular masks, such as occur typically in galaxy surveys. A mask is an arbitrary union of arbitrarily weighted angular regions bounded by arbitrary numbers of edges. The restrictions on the mask are (1) that each edge must be part of some circle on the sphere (but not necessarily a great circle), and (2) that the weight within each subregion of the mask must be constant.

Mangle works by resolving a mask into disjoint polygons. Each polygon is a convex angular region bounded by an arbitrary number of edges. The polygons may be regarded as the ‘pixels’ of a mask, with the feature that the pixels are allowed to take a rather general shape, rather than following some predefined regular pattern.

Among other things, mangle computes analytically the spherical harmonics of a mask. The algorithm for computing spherical harmonics is recursive and stable, and can reasonably defended as being fast, considering what it does. However, you should be aware that there is a numerical penalty to be paid for allowing a mask to have arbitrary shape: the computation time for harmonics up to \(l\) increases as \(l^3\), a pretty steep penalty when \(l\) is large. The computation time is proportional to the number of edges of the mask, and on my laptop (a 750MHz Pentium III), it takes 3 cpu minutes per edge to compute harmonics up to \(l = 1000\).

The mangle software consists of two parts:
  a frontend, a set of commands written in c;
  a backend, a suite of fortran routines that do much of the angular mathematics.

The scheme that evolved into mangle began life in the delightful atmosphere of an Aspen Center for Physics workshop in 1985. The mathematics of harmonization and other aspects of the computation of angular integrals are written up in the Appendix of Hamilton (1993) ApJ 417, 19-35. The mathematics of balkanization and other features of mangle are described by Hamilton & Tegmark (2004), MNRAS, 349, 115-128.

3. How do I use mangle?

To start using mangle, you must first define your mask. A description of a mask is contained in ‘polygon files’, which may take a variety of formats. For example, the masks of the 2dF survey are defined by 3 polygon files which define the boundaries of: (1) UKST plates, (2) 2° fields, (3) holes in UKST plates.

You do not need to resolve your mask into polygons: mangle will do that for you with the balkanize command. Typically, a mask is defined by boundaries of plates or fields or cuts in declination or galatic latitude, and by holes drilled in those plates or fields to avoid bright stars, satellite trails, and such.

Commands, listed in the order that they would normally be applied
command does purpose
snap identifies almost coincident cap boundaries and snaps them together The positions of the intersections of two almost but not exactly coincident cap boundaries may be subject to significant numerical uncertainty. To avoid numerical problems, such boundaries must be made exactly coincident.
balkanize subdivides the angular mask into many disjoint polygons Polygons must not overlap, to avoid regions being double-counted.
weight assigns a weight to each polygon Define the weight to be applied to each polygon, for example in computing the weighted sum of spherical harmonics of polygons. This command may be avoided in many cases: see Losing Weight.
unify unifies polygons where possible Reduce the number of polygons, for grace and efficiency.
The commands above yield a functioning polygon file. The commands below let you play with it.
harmonize computes the spherical harmonics of a mask Investigations of large scale structure, especially at the largest scales, often proceed most advantageously through spherical harmonics. The area of the mask is proportional to the zeroth harmonic.
map maps the mask reconstructed from its spherical harmonics So you can see what you got.
drangle computes the angle subtended by that part of a circle lying within the mask This is the basic element needed to compute the cross-correlation (commonly denoted <DR>, for Data-Random, in cosmological parlance), between a given point and points in the mask separated from it by a given angle.

If the points are random points generated by ransack, then the result will be a Monte Carlo realization of the auto-correlation (commonly denoted <RR>, for Random-Random, in cosmological parlance), between pairs of points in the mask separated by a given angle.

ransack generates random points within the mask Correlation functions are often measured with the help of random backgrounds of points.
poly2poly converts a polygon file from one format to another For example, you can generate points suitable for plotting the polygons of your mask by converting to graphics format. Or, you can determine the vertices of the polygons of your mask by converting to vertices format, or you can find a point inside each polygon of your mask by converting to midpoint format.
polyid determines which polygon(s) a point lies inside Useful utility. Is there such a thing as a useless utility?

Fortran subroutines, in alphabetical order
code computes
garea the area of a polygon
gcmlim the minimum and maximum angular distances from a point to anywhere on a polygon
gphi the angle subtended by that part of a circle which lies inside a polygon
gptin whether a point lies inside or outside a polygon
gspher the spherical harmonics of a polygon
gsphera the spherical harmonics of a rectangle (accelerated)
gvert points on the edges of a polygon, ordered right-handedly about it
gvlim the minimum and maximum angular distances between a point and each edge of a polygon
gvphi find that point on a circle which (a) lies inside a polygon, and (b) lies closest to a given point
iylm \(\int_{\theta_\min}^{\theta_\max} Y_{lm}(\theta,0) \sin\theta \, d\theta\)
wlm contribution to spherical harmonics from an edge
wrho value of summed harmonics at a specified angular position

3. Definition of terms

For convenience, the following table defines the precise meaning of terms used in the context of the mangle software.

For example, the most general angular region that mangle can handle is a mask, as defined in the table.

Definition of terms, in alphabetical order
term definition
boundary A set of edges bounding a polygon.
cap A spherical disk, a region above a circle on the unit sphere.
circle A line of constant latitude with respect to some arbitrary polar axis on the unit sphere.
edge An edge is part of a circle. A polygon is enclosed by its edges.
great circle A line of zero latitude with respect to some arbitrary polar axis on the unit sphere. A great circle is a circle, but a circle is not necessarily a great circle.
group The circles of a polygon partition into groups: two circles are friends, belonging to the same group, if they intersect (anywhere, not necessarily inside the polygon), and friends of friends are friends.
mask The union of an arbitrary number of weighted polygons.
polygon The intersection of an arbitrary number of caps.
rectangle A special kind of polygon, a rectangular polygon bounded by lines of constant longitude and latitude.
vertex A point of intersection of two circles. A vertex of a polygon is a point where two of its edges meet.
weight The weight assigned to a polygon. The spherical harmonics of a mask is the sum of the spherical harmonics of its polygons, each weighted according to its weight. A weight of 1 is the usual weight. A weight of 0 signifies an empty polygon, a hole. In general the weight may be some arbitrary positive or negative real number.

4. Commands

A summary table of mangle commands appears above. The mangle commands are:
	snap
	balkanize
	unify
	weight
	harmonize
	map
	drangle
	ransack
	poly2poly
	polyid

Typing a command with no arguments will give you a brief summary of its usage.

Typing a command with the -d switch will tell you what the defaults are.

Most commands read and/or write to ‘polygon files’. Here is the Format of Polygon Files.

Command line switches are consistent over all mangle commands, although any one command will admit only some subset of switches.

Summary of command line switches. Click on the switch letter for more detail.
Switch Commands Meaning
-a<angle>[<unit>] snap, balkanize If the axes of two caps are within <angle> of each other, then snap the axis of the second cap to that of the first cap.
-b<angle>[<unit>] snap, balkanize If the axes of two caps coincide, and their latitude boundaries are within <angle> of each other, then snap the latitude of the second cap to that of the first cap.
-c<seed> ransack Set the seed for the random number generator.
-d all Advise defaults.
-e<n> snap, balkanize, unify, weight, drangle, poly2poly Read only the first <n> characters of each line of data in the input polygon files.
-f   Undocumented, but used.
-g<lsmooth> map Gaussian smoothing harmonic number.
-h drangle Write only a summary of results to the output file, rather than the full table of results.
-i<format>[<n>][<unit>] snap, balkanize, unify, weight, harmonize, drangle, ransack, poly2poly,
but not polyid
Specify the format of input polygon files.
-j<min>,<max> poly2poly Retain only polygons with weights in the interval [<min>,<max>].
-k<min>,<max> poly2poly Retain only polygons with areas in the interval [<min>,<max>] steradians.
-l<lmax> harmonize, map Maximum harmonic number.
-m<angle>[<unit>] snap, balkanize, unify, weight, harmonize, drangle, ransack, poly2poly Treat multiple intersections within <angle> of each other as being coincident.
-n poly2poly Polygons read from polygon_infile1 are to be intersected with polygons with the same id number from polygon_infile2 and subsequent polygon_infiles.
-o<format>[<unit>] snap, balkanize, unify, weight, poly2poly Specify the format of output polygon files.
-p[+|-]<n> snap, balkanize, unify, weight, map, drangle, ransack, poly2poly, polyid Write angles to the outfile with <n> digits after the decimal point. The optional + (default) sets output azimuths in the interval \([0,2\pi)\); the optional - sets output azimuths in the interval \((-\pi,\pi]\).
-q all Run quietly.
-r<n> ransack <n> is the number of random points to generate.
-s<n> snap, balkanize, unify, weight, drangle, poly2poly Skip the first <n> characters of each line of data in the input polygon files.
-S snap Self-snap: snap only edges belonging to the same polygon, not edges of different polygons.
-t<angle>[<unit>]
-y<ratio>
snap, balkanize If the two endpoints and midpoint of an edge are closer to a cap boundary than the lesser of (1) <angle>, and (2) <ratio> times the length of the edge, and if at least one of the two endpoints or midpoint of the edge lie inside all other caps of the polygon that owns the cap boundary, then snap the edge to the cap boundary.
-u<inunit>[,<outunit>] map, drangle, ransack, polyid Units of azimuth, elevation, and polar angular in input and output files that are not polygon files. Angular units in input and output polygon files are specified as part of the -i<format>[<unit>] and -o<format>[<unit>] switches, or with the unit keyword in an input polygon file.

If only one unit -u<unit> is specified, then it applies to both input and output files.

The angular units <inunit> and <outunit> may be one of:
r radians, d degrees, m arcmin, s arcsec, or h hms(RA) & dms(Dec).

-vo|n snap, balkanize, weight, unify, poly2poly Whether to apply old or new polygon id numbers to output polygons.

The default is -vo for weight and poly2poly, and -vn for snap, balkanize, and unify.

-w<Wlmfile> map <Wlmfile> is the name of the input file of harmonics.

-x   Undocumented, but used.
-y<ratio> snap, balkanize See -t.

-z<survey> weight <survey> is either the name of the input file of weights, or a string telling weight which user-supplied subroutine to use to compute weights.

4.1 snap

snap identifies almost coincident cap boundaries and snaps them together.
snap [-d] [-q] [-S] [-a<a>[u]] [-b<a>[u]] [-t<a>[u]] [-y<r>] [-m<a>[u]] [-s<n>] [-e<n>] [-vo|-vn] [-p[+|-]<n>] [-i<f>[<n>][u]] [-o<f>[u]] polygon_infile1 [polygon_infile2 ...] polygon_outfile
You should always start by running snap on all the original files that define your mask. If you have several original files, then you should also run snap on the combined output. If you do not run snap, then you are asking for trouble, and you can email complaints to /dev/null.

The problem is that the positions of the intersections of two almost but not exactly coincident circles (cap boundaries) on the unit sphere may be subject to significant numerical uncertainty. To avoid numerical problems, such circles must be made exactly coincident, and snap does just that. You might think that that near-but-not-exactly-coincident circles would hardly ever happen, but in practice they occur often, because a mask designer tries to make two polygons abut, but imprecision or numerical round-off defeats an exact abutment.

Snap adjusts the edges of each polygon, but it leaves the number and order of polygons the same as in the input file(s). Edges that appear later in the input file(s) are snapped to earlier edges.

Here for example is the incantation for the 2QZ 10k North survey (my private convention is to begin all junk files with a j):

	snap -ir1r ngp_ukstfld.lims.txt jnu
	snap -ic1h -s6 ngp_field_coords.txt jnf
	snap -iv4r ngp.used.rahole.txt jnh
	snap jnu jnf jnh jnufh
The first three snap commands snap the cap boundaries of each of the three original mask files. The fourth snap snaps the combined set of cap boundaries. The -i.. switches specify the format of the input polygon files. The -i.. switches can be omitted if each polygon file is prefaced with a few lines containing keywords with appropriate parameters that specify the format.

The snap command offers four tunable tolerances

	snap -a<angle>[<unit>] -b<angle>[<unit>] -t<angle>[<unit>] -y<ratio> ...
The various <angle>s and ratio are real numbers, while [<unit>] is an optional angular unit, one of r (radians), d (degrees), m (arcminutes), s (arcseconds), or h (Right Ascension in hours, minutes, and seconds, Declination in degrees, arcminutes, and arcseconds). You can find out what the defaults are with
	snap -d
As of writing (June 2001), the default angles are all 2s, which is two arcseconds, while the default value of ratio is 0.01.

If the boundaries of your mask are precisely defined, then you should tighten the snap angles appropriately (the default value of ratio, the argument of the -y switch, should be fine in virtually all cases), in order to prevent snap from snapping boundaries that should not be snapped.

snap accomplishes its work in two stages:
  Stage 1:  Snap axes and latitudes of pairs of caps together, passing repeatedly through all pairs of caps until no more caps are snapped.
  Stage 2:  Snap edges of polygons to other edges, again passing repeatedly through all pairs of caps until no more caps are snapped.

-S self-snap Snap only edges belonging to the same polygon, not edges of different polygons.
-a<angle>[<unit>] axis tolerance Are the axes of two caps within <angle> of each other, either parallel or anti-parallel? If so, change the axis of the second cap to equal that of the first cap.
-b<angle>[<unit>] latitude tolerance If the axes of two caps coincide, are their latitude boundaries within <angle> of each other? If so, change the latitude of the second cap to equal that of the first cap. The two caps may lie either on the same or on opposite sides of the latitude boundary.
-t<angle>[<unit>] edge tolerance Are the two endpoints and midpoint of an edge closer to a cap boundary than the lesser of (1) <angle>, and (2) <ratio> times the length of the edge? In addition, does at least one of the two endpoints or midpoint of the edge lie inside all other caps of the polygon that owns the cap boundary? If so, change the edge to align with the cap boundary.
-y<ratio> edge to length tolerance

4.2 balkanize

balkanize subdivides the angular mask into many disjoint polygons.
balkanize [-d] [-q] [-a<a>[u]] [-b<a>[u]] [-t<a>[u]] [-y<r>]  [-m<a>[u]] [-s<n>] [-e<n>] [-vo|-vn] [-p[+|-]<n>] [-i<f>[<n>][u]] [-o<f>[u]] polygon_infile1 [polygon_infile2 ...] polygon_outfile
The idea for this routine emerged in a phone conversation with Max Tegmark, who spontaneously invented the name. Balkanization fragments an input set of possibly overlapping polygons into many non-overlapping connected polygons. The process involves two successive stages:
  Stage 1: Fragment the polygons into non-overlapping polygons, some of which may be disconnected.
  Stage 2: Identify disconnected polygons and subdivide them into connected parts.

The algorithm for the first stage is simple and pretty:
  (a) Is the intersection of two polygons neither empty nor equal to the first polygon? If so, find a circle, a cap boundary, of the second polygon that divides the first polygon, and split the first polygon into two along that circle.
  (b) Iterate.

Notice that only one of the two parts of the split polygon overlaps the second polygon, and that only the overlapping part needs iterating. For any pair of polygons, iteration ceases when the overlapping part lies entirely inside the second polygon. The final overlapping part is equal to the intersection of the original first polygon with the second polygon. All other fragments of the first polygon lie outside the second polygon.

Stage one of the balkanization procedure yields polygons that can contain two or more disconnected parts, as illustrated below. Stage two subdivides such disconnected polygons into connected parts by computing the connected boundaries of the polygon, and lassoing each connected boundary with an extra cap.

A polygon that contains two disconnected parts
A polygon that contains two disconnected parts.

Polygons can have intricate multiply-connected shapes, with many disconnected parts, each punctuated with many holes. mangle is designed to deal with almost any polygon you can throw at it, though it could fail on a polygon whose vertices are arranged in a sufficiently complex fractal pattern. If mangle fails on a polygon, it is a bug; please email me.

Approximation of Batman logo
A non-simply-connected polygon.
Fractal
A multiply-connected polygon
containing 7 parts
bounded by 13 boundaries.

To complete its task, balkanize snaps the edges of each balkanized polygon, prunes redundant edges, and discards polygons with zero area.

4.3 Losing Weight

The weight command is needed only for complicated masks, such as that of 2QZ 10k or 2dF 100k, where each polygon of the mask has a different weight. But if the weighting scheme is simpler (for example, the weight is either 0 or 1), then it should be possible to arrange the input polygon files to avoid weight.

Assume that you have run snap on the original files that define your mask. By default, snap writes output files in polygon format. The polygon format includes a weight attached to each polygon. You can edit these by hand.

The rule used by balkanize is that the weight of a polygon that appears later in the input file overrides weights of earlier polygons. In other words, if balkanize finds that two polygons intersect, then the weight applied to the intersection is the weight of the later polygon. The non-intersecting parts of the polygons inherit the weights of their parents.

For example, if you want to add (subtract?) a hole, an empty polygon, to a mask, then append a polygon with zero weight to the file of polygons. In practice, you might do this in the following way. Suppose you have a file fields.dat defining a list of fields, and another file holes.dat defining a list of holes. The first step is, as usual, to apply snap:

	snap fields jf
	snap holes jh
where of course you may need to use the -i.. switch to specify the format of the input polygon files. Now edit the holes file jh to set the weight for all polygons to zero. You can probably leave the fields file jf as is, since the default weight is 1, which may be what you want. Then snap the fields and holes files together:
	snap jf jh jfh
The order of the input files jf and jh is important here, fields first and holes second, because you want the holes to override the fields. Next balkanize:
	balkanize jfh jb
In the output file jb of balkanized polygons, some of the polygons will have weight 1 (those inside the fields but not in a hole), and the rest will have weight 0 (the holes). Applying unify to the balkanized file
	unify jb pretty.poly
gets rid of the polygons of weight 0, the holes, and merges, as far as possible, the polygons of weight 1, giving a pruned file pretty.poly of non-overlapping polygons ready to harmonize. If you are daring, you can pipe the snap-balkanize-unify commands together with
	snap -q jf jh - | balkanize -q - - | unify - pretty.poly
since an input filename of - instructs to read from stdin, while an output filename of - instructs to write to stdout. The -q switch instructs the first two commands to be quiet, since otherwise they would write advice to their output polygon files, which is probably not what you want. Note that advice is written to stdout; only error messages are written to stderr.

4.4 weight

weight assigns a weight to each polygon.
weight [-d] [-q] -z<survey> [-m<a>[u]] [-s<n>] [-e<n>] [-vo|-vn] [-p[+|-]<n>] [-i<f>[<n>][u]] [-o<f>[u]] polygon_infile1 [polygon_infile2 ...] polygon_outfile

weight requires the -z<survey> switch as an argument. The <survey> argument may be either:
  (a) the name of a file containing a list of weights, or
  (b) a string that tells weight which (user-supplied) subroutine to use in computing the weight at a point.

Option (a) is much more practical, because there is no need to recompile mangle.

In case (a), where <survey> is the name of a file containing a list of weights, then that file should consist of an arbitrary numbers of header lines (not beginning with a number), followed by a list of weights, one weight per line for each polygon in the polygon_infiles. The weight is taken to be the first number in the line; anything beyond the first number on a line is ignored. If the weight file contains only a single weight, then that weight is applied to every polygon. Otherwise the weight file should contain a separate weight for each polygon, and it is an error for there to be fewer weights than polygons.

Suppose you have your own software which returns a weight given an angular position. You can get mangle to create a file containing a list of angular positions of midpoints of polygons by

	poly2poly -om polygon_infile midpoint_outfile
Here the -om switch specifies an output file in midpoint format. The midpoint_outfile becomes input to your own software, which should produce another file containing a list of weights, which can be fed to weight.

In case (b), where <survey> is a string telling weight which (user-supplied) subroutine to use in computing the weight, then you will need to write a fortran or c subroutine that returns a weight given an azimuth and an elevation. You might like to use the 2QZ 10k subroutine twoqz.f as a template. Having written such a subroutine, you must then plumb it into the mangle code by updating weight_fn.c, which should be self-explanatory. Finally, you must update the Makefile to include your subroutine, and recompile with the make command.

As of writing (June 2001), the only survey plumbed into mangle is the 2QZ 10k survey. Thus

	weight -z2QZ10k jb jw
reads polygons from the balkanized polygon file jb, applies weights from the 2QZ 10k survey, and writes the polygon file jw.

Update (1 July 2001): Peder Norberg and Shaun Cole’s weights for the 2dFGRS 100k survey are now also plumbed in. The incantation is -z2dF100k.

4.5 unify

unify unifies polygons where possible.
unify [-d] [-q] [-m<a>[u]] [-s<n>] [-e<n>] [-vo|-vn] [-p[+|-]<n>] [-i<f>[<n>][u]] [-o<f>[u]] polygon_infile1 [polygon_infile2 ...] polygon_outfile
The unify command eliminates polygons with zero weight, and does its best to merge polygons with the same weight, so as to yield a minimal file of non-overlapping polygons. The command is not strictly necessary, but it tidies things up, and it can save harmonize and other programs a lot of computer time.

If the old-id -vo switch is used, then unify will unify only polygons sharing the same id in the input polygon file(s). That is, if the -vo switch is used, then to be considered as candidates for merging, a pair of polygons must have not only the same weight, but also the same id number. The default (-vn) is that unify attempts to merge polygons of the same weight regardless of their id numbers, and assigns new polygon ids to polygons in the output polygon file.

Note that unify does not necessarily accomplish the most efficient unification, nor, as illustrated below, is the unification necessarily exhaustive. What unify does is pass repeatedly through the polygon file, merging a pair of polygons wherever the pair can be merged into a single polygon by eliminating a single abutting boundary.

System of 4 polygons that unify fails to merge into a single polygon
A system of 4 polygons that unify fails to merge into a single polygon, because no pair of polygons can be merged.

4.6 harmonize

harmonize computes the weighted sum of harmonics of the polygons in the input polygon files. The weighted area of the mask equals \(\sqrt{4\pi}\) times the zeroth harmonic.
harmonize [-d] [-q] [-l<lmax>] [-m<a>[u]] [-s<n>] [-e<n>] [-p[+|-]<n>] [-i<f>[<n>][u]] polygon_infile1 [polygon_infile2 ...] Wlm_outfile
The spherical harmonics are computed analytically, in the manner described in the Appendix of Hamilton (1993), MNRAS, ApJ 417, 19-35. The algorithm is recursive and stable, able to compute harmonics to machine precision to arbitrarily high order, limited only by computer power and patience. The recursion recovers correctly from underflow, which can occur at large harmonic number \(l\).

The spherical harmonics of an angular mask are given by integrals of spherical harmonics over the area of the mask. As detailed in the aforementioned reference, the key mathematical trick is to integrate by parts to convert the integrals over the area of the mask into integrals over its boundary. If the boundary is resolved into arc segments, or edges, then the integral over each arc segment can be done analytically, and the integral over the boundary is the sum of the integrals over each arc segment. The problem is well-suited to computation: the computational problem is to identify the arc segments of the boundary of the mask, and then to accumulate the harmonics contributed by each arc segment. The computation is naturally parallelizable, if there were need.

The most time-consuming part of the computation is rotating the harmonics of an arc segment from its natural frame of reference into the final frame of reference. The computational time for a rotation goes as \(l^3\) where \(l\) is the maximum harmonic number. The rotation is unnecessary if the circle is a line of constant latitude in the final reference frame, and the computation goes faster (as \(l^2\)) in this case.

harmonize detects polygons which are rectangles, polygons bounded by lines of constant azimuth and elevation, and applies an accelerated computation for such polygons. The computation is accelerated in two respects:
(1) the computation of the harmonics contributed by lines of constant elevation is naturally faster, because no rotation to the final frame is necessary;
(2) if two rectangles have the same minimum and maximum elevation, then the harmonics contributed by lines of constant azimuth are related by a simple rotation about the polar axis, for which the rotation matrix is diagonal.
Note that the second acceleration works only if at least two rectangles have the same minimum and maximum elevation. Two such rectangles need not be adjacent in the polygon file: mangle reorders the computation of polygons so as to take advantage of accelerations where possible.

4.7 map

map maps the mask reconstructed from its spherical harmonics.
map [-d] [-q] -w<Wlmfile> [-l<lmax>] [-g<lsmooth>] [-u<inunit>[,<outunit>]] [-p[+|-]<n>] azel_infile outfile
map requires the -w<Wlmfile> switch as an argument. The command
	map -w<Wlmfile> azel_infile outfile
reads harmonics from the <Wlmfile> created by harmonize, reads lines of azimuthal and elevation from azel_infile, and writes lines of azimuthal, elevation, and value to outfile.

The azel_infile may contain arbitrary numbers of header lines, after which each line should contain two angles, an azimuth az and an elevation el, as in

Header lines
...
az1	el1
az2	el2
...
An example is the file azel.dat in the mangle directory.

The outfile contains the azimuth and elevation from azel_infile, together with the value \(w\)(\(n\)) of the summed weighted harmonics at that position (see the formula in the table below).

The

	-u<inunit>[,<outunit>]
switch specifies the units of the angles az and el in azel_infile and outfile. The -u<unit> switch, with only one unit present, specifies the units of the angles in both azel_infile and outfile. You can find the default angular units by running
	map -d

The map command may be run interactively with

	map -w<Wlmfile> - -
which instructs map to read from stdin, and to write to stdout.

map offers two optional parameters, a maximum harmonic number lmax, and a Gaussian smoothing harmonic number lsmooth

	map -l<lmax> -g<lsmooth> ...

-l<lmax> maximum harmonic <lmax> is the value of \(l_\max\) in \[ w(\boldsymbol{n}) = \sum_{l = 0}^{l_\max} \sum_{m = -l}^{l} G_l w_{lm} Y_{lm}(\boldsymbol{n}) \] Here:
\(\boldsymbol{n}\) denotes a unit direction, as specified by an azimuth and elevation read from azel_infile;
\(w(\boldsymbol{n})\) is the value written to outfile;
\(G_l\) are the harmonics of an optional Gaussian smoothing window (see immediately below);
\(w_{lm}\) are the harmonics of the mask, read from Wlmfile;
\(Y_{lm}(\boldsymbol{n})\) are the usual orthonormal spherical harmonics.

If <lmax> is not specified on the command line, then its value is the maximum harmonic read from Wlmfile.

If <lmax> is specified on the command line, then its value is the lesser of the value specified on the command line and the value read from Wlmfile.

-g<lsmooth> smoothing harmonic The default is <lsmooth> = 0, in which case no smoothing is done, i.e. \(G_l = 1\) for all \(l\).

If <lsmooth> > 0, then <lsmooth> is the value of \(l_s\) in the Gaussian smoothing window
\[ G_l = \exp \left( {l ( l + 1 ) \over l_s ( l_s + 1 )} \right) \ . \]

-g<lsmooth>,<xsmooth> smoothing harmonic
and exponent
Similar to Gaussian smoothing, but with an additional parameter <xsmooth>, the value of the exponent \(x\) in the smoothing window \[ G_l = \exp \left[ \left( {l ( l + 1 ) \over l_s ( l_s + 1 )} \right)^{x/2} \right] \ . \] The default is Gaussian smoothing, <xsmooth> = 2.

4.8 drangle

drangle computes, for a specified set of circles, the angle subtended by that part of each circle lying with the mask. Each circle is defined by the azimuth az and elevation el of its centre, and by its angular radius th. The angle subtended is the weighted sum over polygons in the mask of the angle subtended by the part of the circle within each polygon. For example, if the circle happens to lie entirely inside a polygon of weight 1, then the angle is \(2\pi\).

The result is equivalent to the angular cross-correlation (commonly denoted <DR>, or Data-Random, in cosmological parlance) between given points D and points R in the mask separated from the D points by a given angle. If the data points D are random points generated by ransack, then the result will be equivalent to the angular auto-correlation (commonly denoted <RR>, or Random-Random, in cosmological parlance) between pairs of points in the mask separated by a given angle.

drangle [-d] [-q] [-h] [-m<a>[u]] [-s<n>] [-e<n>] [-u<inunit>[,<outunit>]] [-p[+|-]<n>] [-i<f>[<n>][u]] polygon_infile azel[th]_infile [th_infile] dr_outfile

The first file given on the command line is the mask, a polygon file polygon_infile.

If three files are given on the command line, then the second file, azelth_infile, is taken to contain the centre az and el, and radii th, of each circle, as in

Header lines
...
az1	el1	th11	th12	...	th1n1
az2	el2	th21	th22	...	th2n2
...
The azimuth and elevation on each line specifies the centre of concentric circles with radii th running over the values in the rest of the line. The number of values of th may vary from line to line. If there are \(m\) centres, and the \(i\)’th centre has \(n_i\) radii, then there are \(n_1 {+} n_2 {+} \cdots {+} n_m\) circles altogether.

Alternatively, if four files are given on the command line, then the second file, azel_infile, is taken to contain the centre of each circle, its azimuth az and elevation el, as in

Header lines
...
az1	el1
az2	el2
...
while the third file, th_infile, contains the angular radii th, as in
Header lines
...
th1
th2
...
The azimuth and elevation on each line of the azel_infile file specifies the centre of concentric circles with radii th running over all values in the th_infile file. Thus if the second file azel_infile contains \(m\) centres, and the third file th_infile contains \(n\) radii, then the two files specify \(mn\) circles altogether.

The last of the three or four files specified on the command line is the output file dr_outfile.

The default is to write a full table of results to the output file, a value for each input az, el, and th. If there are separate azel_infile and th_infile input files (4 files on the command line), then the output file looks like:

              th(u):
az(u)  el(u)  th1     th2     ...    thn 
az1    el1    dr11    dr12    ...    dr1n
az2    el2    dr21    dr22    ...    dr2n
...
azm    elm    drm1    drmm    ...    drmn
   Average:   dr1     dr2     ...    drn 
The first line is a header line. The second line is a header line that repeats the values of th from the th_infile. The last, Average, line contains the averages drj of the values driji = 1, ..., m, on the preceding m lines.

If there is a single azelth_infile file (3 files on the command line), then the output file looks similar, but without the final line containing the Average.

If you don’t want the full table of results, but only the summary Average, then use the -h switch

	drangle -h polygon_infile azel_infile th_infile dr_outfile
The -h option is available only if there are separate azel_infile and th_infile input files (4 files on the command line).

The algorithm is as follows. drangle loops in turn through each point azel of azimuth and elevation. Thus two points take twice as much CPU time as one point. For each point, drangle attempts to accelerate the computation with respect to the angular separations th by first computing the minimum and maximum angles between the point and each polygon in the mask. drangle uses the information about the minimum and maximum angles to decide whether the circle lies entirely outside or entirely inside a polygon, in which case the (unweighted) angle subtended within the polygon is zero or \(2\pi\). In practical cases the angle subtended is often zero for the great majority of polygons of a mask, especially when the mask is composed of many polygons. Since calculation of the subtended angle can be skipped if the angle is zero, computation can be greatly speeded. Further acceleration comes from ordering the polygons in increasing order of the minimum angle from the point to each polygon. This allows the computation to loop to the next value of th as soon as it hits a polygon for which the subtended angle is zero, rather than checking through large numbers of polygons that all have zero subtended angle.

4.9 ransack

ransack generates random points inside the mask.
ransack [-d] [-q] [-c<n>] [-r<n>] [-m<a>[u]] [-s<n>] [-e<n>] [-u<inunit>[,<outunit>]] [-p[+|-]<n>] [-i<f>[<n>][u]] polygon_infile1 [polygon_infile2 ...] azel_outfile
The -c<n> switch seeds the random number generator with integral seed <n>.

The -r<n> switch commands to generate <n> random numbers.

polygon_infile1 [polygon_infile2 ...] are polygon files specifying the mask.

azel_outfile is the name of a file to which to write the random positions. In addition to recording the azimuth and elevation of each position, ransack writes the id number of the polygon inside which the random position falls.

The algorithm is as follows. ransack first selects randomly a polygon in the mask, with probability proportional to the product of the polygon’s weight and area. It lassos that polygon with a circle that is intended to be a tight fit, but is not necessarily minimal. It generates a point randomly within the circle, tests whether the point lies inside the polygon, and keeps the point if it does.

ransack lassos polygons as needed, recording a lasso so that a lasso is computed only once for any polygon. If the desired number of random points exceeds the number of polygons in the mask, then ransack starts by lassoing every polygon in the mask.

ransack is quite fast.

4.10 poly2poly

poly2poly converts a polygon file from one format to another. The different formats are described in Format of Polygon Files.
poly2poly [-d] [-q] [-m<a>[u]] [-j[<min>][,<max>]] [-k[<min>][,<max>]] [-n] [-s<n>] [-e<n>] [-vo|-vn] [-p[+|-]<n>] [-i<f>[<n>][u]] [-o<f>[u]] polygon_infile1 [polygon_infile2 ...] polygon_outfile

The default output format is polygon format. Thus both

	poly2poly polygon_infile polygon_outfile
and
	poly2poly -op polygon_infile polygon_outfile
have the same effect of converting polygons in the polygon_infile to an output polygon file polygon_outfile written in polygon format.

One particularly useful output format is the graphics format. The command

	poly2poly -og<n> polygon_infile polygon_outfile
produces a polygon file containing <n> points per (\(2\pi\)) along each edge of each polygon.

Not all polygons are rectangles. The command

	poly2poly -or polygon_infile polygon_outfile
reads polygons from polygon file polygon_infile, identifies which of the polygons are rectangles (polygons bounded by lines of constant azimuth and elevation), and writes the surviving polygons in rectangle format to outfile. Polygons that are not rectangles are discarded.

If conversion with poly2poly produces lots of errors, chances are it’s because the input polygon file needs snapping. Use snap instead. For example, poly2poly will often fail if the input file is in edges edges format, even if that input file was created from a snap’d polygon file, because the edges format discards information about two edges coming from the same cap.

By default poly2poly retains the polygon id numbers found in the input polygon file(s), unlike the snap, balkanize, and unify commands. If you want poly2poly to stamp the polygons in the output file with a new set of sequential polygon id numbers (perhaps because the input polygon file contained no polygon id numbers), then use the -vn switch.

poly2poly offers the following optional parameters:

	poly2poly -j[<min>][,<max>] -k[<min>][,<max>] -n -vo|-vn -p[+|-]<n> ...

-j<min>,<max> If <min> is less than or equal to <max>, then only polygons with weights greater than or equal to <min> and less than or equal to <max>, i.e. with weights in the interval [<min>,<max>], are to be retained.

If <min> is greater than <max>, then only polygons with weights greater than or equal to <min> or less than or equal to <max>, i.e. with weights outside the interval (<max>,<min>), are to be retained.

The defaults are that there is no minimum or maximum weight.

-j<min> Only polygons with weights greater than or equal to <min> are to be retained.
-j,<max> (with a comma before <max>) Only polygons with weights less than or equal to <max> are to be retained.
-k<min>,<max> If <min> is less than or equal to <max>, then only polygons with areas greater than or equal to <min> steradians and less than or equal to <max> steradians, i.e. with areas in the interval [<min>,<max>] steradians, are to be retained.

If <min> is greater than <max>, then only polygons with areas greater than or equal to <min> steradians or less than or equal to <max> steradians, i.e. with areas outside the interval (<max>,<min>) steradians, are to be retained.

The defaults are that there is no minimum or maximum area.

-k<min> Only polygons with areas greater than or equal to <min> steradians are to be retained.
-k,<max> (with a comma before <max>) Only polygons with areas less than or equal to <max> steradians are to be retained.
-n Polygons read from polygon_infile1 are to be intersected with polygons with the same id number from polygon_infile2 and subsequent polygon_infiles.

For example, if polygon_infile1 contains a polygon with id number 12, and polygon_infile2 contains a polygon with id number 12, then the polygon 12 written to the outfile will be the intersection of the two polygons. In this example, if polygon_infile2 contains no polygon 12, then the polygon 12 written to the outfile will be the original polygon 12 from polygon_infile1. If polygon_infile2 contains two or more polygons with the same id number 12, then the polygon 12 written to the outfile will be the intersection of polygon 12 from polygon_infile1 with all polygons numbered 12 in polygon_infile2.

-vo

-vn

-vo means apply old polygon id numbers, as found in the input polygon files, to output polygons.
This is the default for weight, poly2poly, and polyid.

-vn means apply new polygon id numbers to output polygons. Here output polygons are renumbered sequentially.
This is the default for snap, balkanize, and unify.

-p[+|-]<n> Write angles to the outfile with <n> digits after the decimal point.

The optional + (default) prefix sets output azimuths in the interval \([0,2\pi)\); the optional - prefix sets output azimuths in the interval \((-\pi,\pi]\).

4.11 polyid

polyid determines which polygon(s) a point lies inside. A point may lie inside zero polygons, or one polygon, or more than one polygon.
polyid [-d] [-q] [-u<inunit>[,<outunit>]] [-p[+|-]<n>] polygon_infile azel_infile outfile

The polygon_infile is a single polygon file, complete with polygon id numbers. The polygon file will normally have been created as the output of some other mangle command. To avoid ambiguity in id numbers, the -i switch (specifying the format of the polygon_infile) is not supported by the polyid command.

The azel_infile may contain arbitrary numbers of header lines, after which each line should contain two angles, an azimuth and an elevation, as in

Header lines
...
az1	el1
az2	el2
...
An example is the file azel.dat in the mangle directory.

The outfile contains the azimuth and elevation from azel_infile, together with a list of the id numbers of polygons containing that angular position.

How does mangle determine polygon id numbers? By default, the snap, balkanize, and unify commands produce sequential polygon id numbers in the output polygon file, ignoring any polygon id numbers in the input polygon files. The weight, poly2poly, and polyid commands, on the other hand, use the polygon id numbers found in the input polygon file(s). You can change this default behaviour with the -vo|n switch.

The -u<inunit>[,<outunit>] switch specifies the units of the angles az and el in azel_infile and outfile. The -u<unit> switch, with only one unit present, specifies the units of the angles in both azel_infile and outfile. You can find the default angular units by running

	polyid -d

polyid takes no short cuts: it tests all points against all polygons. This can take time if there are large numbers of points and large numbers of polygons.

5. Format of Polygon Files

If you want to apply mangle to your angular mask, then you will need to define your mask in a format that mangle can read. This section describes the possible formats.

The mangle software recognizes a variety of formats for files defining an angular mask, hereafter called ‘polygon files’. All mangle programs read and write polygon files through the same subroutines rdmask.c and wrmask.c. If the worst comes to the worst, you can look in those subroutines to see what is happening.

The intention is that the read subroutine rdmask should be flexible, and fairly tolerant of syntax. If a line of data yields an error on the first or second words (all formats expect at least two numbers in a line of data), then rdmask goes to the next line, on the assumption that the line contains a header or a comment. Thus polygon files can contain arbitrary quantities of commentary. If on the other hand rdmask reads the first and second words of a line successfully, then it assumes that it has found a line in the required format. Any error encountered later in the line is then considered to be a genuine error, upon which rdmask issues an error message, and proceeds to the next line. The policy is to carry on regardless as long as possible.

The formats mimic those actually used by various galaxy surveys, and it should not be difficult to cast the mask for your survey into one or other of the formats. It may well be that your existing mask files are already in a suitable format, and can be read without change. If you think your format is different and deserves to be plumbed in, email me. There are seven possible input formats:

	c	circle
	v	vertices
	e	edges
	r	rectangle
	p	polygon
	s	spolygon
	R	Region
There are five additional formats that can be written but not read:
	a	area
	g	graphics
	i	id
	m	midpoint
	w	weight

5.1 Keywords in input files

The format of an input file can be specified on the command line with the -i (input) switch, or it can be specified with lines inside the input file that start with certain keywords.

It is good practice to adopt the policy of specifying the format of polygon files with keywords inside the polygon file, since in that way the polygon file becomes self-documenting: the polygon file remembers its own format without further intervention.

Command line switches apply to all input polygon files, but keywords inside an input polygon file affect only that file, not any subsequent input polygon files.

List of keywords. Click on the keyword for more information about the format.
command line switch keyword arguments meaning of arguments
-ic[<n>] circle [<id> <n>] <id> is an integer id number, which has no effect whatsoever. It is there for compatibility with the (identical) format of output files, in which an id number is convenient for keeping track.

For edges, <m> is an integer specifying the number of points per edge. The default is 2 points per edge, consisting of one vertex and one midpoint per edge.

<n> is an integer specifying the number of objects to expect per line. If the <n> argument is missing, which is the default for circle, edges, rectangle, and vertices, then the number of objects per line is variable, and mangle will deduce the number of objects from the number of angles it reads on the line.

The -ip and -iR switches are allowed, but have no effect, since the polygon and Region keywords must be specified in the polygon infile. The polygon and Region keywords in the polygon infile must be followed by the <id> and <n> arguments.

-ie[<m>[,<n>]] edges [<id> <m> [<n>]]
-ir[<n>] rectangle  
-iv[<n>] vertices [<id> <n>]
[-ip] polygon <id> <n>
[-iR] Region <id> <n>
[-is] [spolygon] <id> <n> spolygon format is a stripped down version of the polygon format. The -is switch is allowed, but has no effect. The spolygon keyword is allowed, but not required. The spolygon format is detected by the presence of a line that starts with two integers, <id> and <n>. Mangle expects such a line to be followed by <n> lines containing 4 real numbers on each line.
-i<format>[..]<unit> unit <unit> The input angular unit <unit> may be one of:
r radians, d degrees, m arcmin, s arcsec, h hms(RA) & dms(Dec).

The default input angular unit is d degrees.

-s<n> skip <n> Skip the first <n> characters of each line of data.
The default is <n> = 0.
-e<n> end <n> Read only the first <n> characters of each line of data.
For example, to read characters 11 through 20, use -s10 -e20.
The default is <n> = 0, which means no limit to the number of characters.

5.2 Output format

The output format of polygon files is compatible where possible with the input format. Output files created in circle, edges, polygon, rectangle, Region, spolygon, and vertices formats can all be read as input polygon files. Output files created in area, graphics, id, midpoint, and weight formats cannot be read as input polygon files, because they contain too little information, or in the case of graphics format because the interpretation on input would be ambiguous.

The default output format is polygon. The output format can be changed with the -o (output) switch.

The only formats that retain complete information about polygons are the circle, polygon, and spolygon formats. The edges, rectangle, and vertices formats in general lose information about polygons.

List of output formats. Click on the output format for more information.
command line switch output format remarks
Formats valid for both input and output
-oc circle  
-oe[<m>] edges <m> is an integer specifying the number of points per edge. The default is 2 points per edge, consisting of one vertex and one midpoint per edge.
[-op] polygon This is the default output format. The -op switch is permitted, but not required.
-or rectangle  
-oR Region  
-os spolygon A stripped down version of the polygon format.
-ov vertices  
Formats valid only for output
-oa area  
-og[<m>] graphics <m> is an integer specifying the number of points per (\(2\pi\)) of azimuthal angle around each edge. The default is 2 points per (\(2\pi\)). You will probably want to specify a larger number.
-oi id  
-om midpoint  
-ow weight  
Output angular unit
-o<format>[..]<unit> circle, edges, rectangle, vertices, midpoint The output angular unit <unit> may be one of:
r radians, d degrees, m arcmin, s arcsec, h hms(RA) & dms(Dec).

The default output angular unit is d degrees.

5.3 circle format

This format is able to describe polygons in all generality. A circle is defined by the azimuth and elevation of its north polar axis, and by the angular radius, the polar angle theta, of the circle. Each circle defines a cap. A polygon is an intersection of caps, and a line of the form

az1 el1 th1 ... azn eln thn

defines a polygon with n caps. In circle format, a line with 3n angles defines a polygon with n caps.

For convenience, and to allow extra precision in defining caps covering the whole sky except for a tiny hole, the sign of a polar angle th is used to signify whether the cap is the region north or south of the circle. If the polar angle is positive, th \(\geq\) 0, then the cap is the region north of the circle. If the polar angle is negative, th \(<\) 0, then the cap is the region south of the circle. A circle with th = 0 (or th = \(-\pi\)) signifies a cap with zero area, while a circle with th = pi signifies a cap covering the entire sky.

Here for example is a part of the 2QZ 10k North field file:

           coordinates  (B1950)  radius
Field   hh mm ss.ss   dd mm ss.s   d
ngp178  11 58 42.31  -02 17 59.2   1
ngp179  12 04 35.46  -02 17 59.2   1
ngp180  12 10 26.56  -02 17 59.2   1
...
This can be read with
	-s6 -ic1h
The -s6 switch says to skip the first 6 characters of each line. The -ic switch specifies that the input format is circle. The 1 on -ic1 says to read only 1 circle on each line. Notice that the specification is 1 circle, not 3 angles; mangle expects to read 3 angles per circle. The h on -ic1h declares that the azimuth and elevation are in hms(RA) and dms(Dec) format, while the radius is in degrees. The above example could also be read with
	-s6 -ich
in which the 1 on the -ic1h switch is omitted, since there are no trailing characters on the line to confuse matters. With the 1 omitted, mangle counts the number of angles on the line, namely 3, and deduces that there is 1 circle per line.

The command line switches can be omitted if appropriate keywords and corresponding arguments are incorporated into the input file before the relevant lines of data. In the above example, the addition of 3 lines at the beginning of the file:

skip 6
circle 0 1
unit h
           coordinates  (B1950)  radius
Field   hh mm ss.ss   dd mm ss.s   d
ngp178  11 58 42.31  -02 17 59.2   1
ngp179  12 04 35.46  -02 17 59.2   1
ngp180  12 10 26.56  -02 17 59.2   1
...
is equivalent to specifying the -s6 -ic1h switches on the command line, and indeed overrides any such switches that may have been specified on the command line. The first integer, 0, following the circle keyword is an id number, whose value here is irrelevant. The point of the id number is that it is sensible to stick to the same format in both input and output files, and it is useful for polygons in output files to be labelled with id numbers, to help keep track of things. The second integer, 1, following the circle keyword is the number of circles per line. Actually the arguments of the circle keyword could be omitted in this case, because mangle can deduce the number of circles by counting the number of angles, here 3, on each line.

If you create polygon files in circle format by using the -oc switch, and you find that the precision of angles in the output polygon files is inadequate, then you should use the -p[+|-]<n> switch to adjust the number <n> of digits after the decimal point in output angles.

5.4 vertices format

The vertices format specifies polygons by a sequence of vertices. The vertices are assumed to be joined by great circles, so this format is not as general as the circle or polygon formats. There is a short way (angle < pi) and a long way (angle > pi) along the great circle from any one vertex to the next; the shorter way is assumed. The vertices wind right-handedly about the enclosed polygon, as in
	4  1
	3  2
with elevation increasing upward, and azimuth increasing to the LEFT (as it does when you look at the sky with the north pole at zenith). Imagine that the above rectangle of numbers forms a constellation of 4 stars on the sky. Point at the stars with your right hand, and you see that the numbers increase right-handedly.

There must be at least 3 vertices per polygon: a polygon bounded by 1 vertex is ill-defined, and a polygon bounded by 2 vertices is null. The interior angle at each vertex must be less than or equal to 180° (that is, the polygon must be convex; convex here means precisely that each interior angle must be less than or equal to 180°). It is up to you to ensure that your polygon is convex; mangle does not check that it is.

The general form of a line specifying a polygon in vertices format is

az1 el1 az2 el2 ... azn eln

which defines a polygon with n caps. In vertices format, a line with 2n angles defines a polygon with n caps.

If a successive pair of vertices is the same, then the line joining them is suppressed. Thus, for example, it is ok to specify a triangle by 4 vertices, with 2 of the vertices coincident.

If a successive pair of vertices is antipodeal, then the line joining them is quietly suppressed, since the great circle joining antipodeal pairs is not unique.

Here for example is part of the 2QZ 10k North holes file:

 #     RA3           dec3         RA4          dec4            RA2           dec2          RA1           dec1   plate hole field
 #
   2.6431146954  0.0260858968  2.6431114304  0.0229366782  2.6462475007  0.0229342082  2.6462509201  0.0260833404  1  1 j10658_853
   2.6387513686  0.0213119826  2.6387495321  0.0192968522  2.6407561104  0.0192953857  2.6407579987  0.0213104873  1  4 j10658_853
   2.6176910610 -0.0128549279  2.6176890352 -0.0159353951  2.6207561335 -0.0159372895  2.6207580623 -0.0128568247  1  5 j10658_853
...
Each of the lines defines a polygon with 4 vertices. You can see from the header that I had to permute the columns of the original file, since mangle wants the vertices in order about the polygon, whereas the original file had the vertices in bow-tie order.

A few lines down, the 2QZ 10k North holes file has the following line:

r  2.6601273142 -0.0478372811  2.6548644982 -0.0478373114  2.6548692406 -0.0415046876  2.6601289920 -0.0388904455  1 17 j10658_853
which boasts a single character r (followed by a blank) at the beginning of the line. The initial r character is a flag (ok, a hack) that tells mangle to reverse the order of the vertices. The problem is that mangle wants the vertices ordered right-handedly about the polygon. If the vertices are ordered in the opposite direction, it specifies a different polygon (antipodeal to the desired polygon, since in vertices format the edges are great circles). In the original 2QZ 10k holes file, some of the vertices were ordered one way, and some the other. Rather than mess about permuting the numbers, I introduced the r flag, to tell mangle to reverse the order of vertices on that line.

The above holes file can be read with

	-iv4r
in which v specifies the vertices format, the 4 specifies 4 vertices per line, and the r specifies radians. With 4 vertices per line, mangle expects 8 angles per line.

5.5 edges format

Output polygon files in edges format can be useful for making plots of polygons, although you may prefer the graphics format (§5.6 below), which is more economical than edges format.

edges format can also be useful on input for defining certain kinds of polygons. If you know the angular positions of the vertices and a midpoint on each edge of your polygon, then edges format is a good choice — though read the caveat in the last paragraph of this section. Or, if you want to construct a polygon that passes exactly through some given angular position, then again edges format is a good way to do this.

The edges format is a souped-up version of the vertices format (see §5.4 above). Whereas the vertices format joins each pair of vertices with a great circle, the edges format uses an additional point, or additional points, between each pair of vertices to define the shape of the circle joining the vertices. There may be several points on each edge between a pair of vertices, but on input only one of the points between each pair of vertices — the first one not at the position of the first vertex — is used to define the shape of the circle; any additional points are ignored, and no check for consistency is made. An exception to this rule is that if there is only one edge, then the last point on the edge is taken to be a second vertex. On output, points are spaced uniformly along the edge between each pair of vertices. The vertices and edges points wind right-handedly about the enclosed polygon, as in

				   1
	   1			  9 2
	 6   2		or	 8   3
       5   4   3		7 6 5 4
with elevation increasing upward, and azimuth increasing to the LEFT (as it does when you look at the sky with the north pole at zenith). Imagine that the above triangles of numbers form constellations of stars on the sky. Point at the stars with your right hand, and you see that the numbers increase right-handedly. In the triangle above left, the points 1, 3, 5 are vertices, while the points 2, 4, 6 are edgepoints. In the triangle above right, the points 1, 4, 7 are vertices, and the remainder are edgepoints.

The form of a line specifying a polygon in edges format is

az1 el1 az2 el2 ... azm elm ... azmn elmn

which defines a polygon with n caps. There are m points per edge, and n edges, for a total of mn points. A line with 2mn angles defines a polygon with n caps. The sequence of points is


mn points
 

m – 1 points
 

m – 1 points
 

m – 1 points
vertex edgepoint · · · edgepoint vertex edgepoint · · · edgepoint · · · vertex edgepoint · · · edgepoint

The final point is an edgepoint that joins to the first point, a vertex.

On input, edges format with <m> points per edge is specified with

	-ie<m>
and on output
	-oe<m>
The default is 2 points per edge, a vertex and a midpoint. On input, to specify <m> points per edge and <n> edges, for a total of <m> × <n> points, use
	-ie<m>,<n>
The default is to deduce the number of edges from the number of angles on the line.

The only difference between edges format with 1 point per edge and vertices format is that on output edges writes points along all boundaries of a polygon, including boundaries which are circles with no intersections, whereas vertices does not record points on circles with no intersections, since such circles contain no vertices.

If all the points of a vertex–edgepoints–vertex sequence are the same, then the edge joining them is suppressed. Thus, for example, it is ok to specify a triangle by 4 edges, with 1 of the edges being degenerate.

If the two vertices of a vertex–edgepoints–vertex sequence differ, but the intervening edgepoints are all equal to either of the vertices, then the line joining them is taken to be a great circle, as in the vertices format.

In accordance with this rule, a polygon with one edge and 2 points per edge has one cap, whose boundary is a great circle running right-handedly from the vertex to the edgepoint and back around to the vertex.

On input in edges format, the usual rule is to discard all but one but one of the edgepoints between any pair of vertices. As a special case, however, if there is just one edge and there are 3 or more points per edge, then the edge is taken to define a polygon with a single cap, whose boundary is a circle running right-handedly from the vertex, through the first edgepoint not equal to the vertex, through the last edgepoint, and back around to the vertex.

To define a cap whose boundary is a non-intersecting circle that is not a great circle, it is necessary to specify either 1 edge with at least 3 points per edge, requiring at least 6 angles, or 2 or more edges with at least 2 points per edge, requiring at least 8 angles. Evidently this is less efficient than circle format, where a single cap is defined with just 3 angles. On output in edges format, each cap whose boundary is a non-intersecting circle is written with two edges.

If all the points of a vertex–edgepoints–vertex sequence are the same or antipodeal to each other, then the line joining them is quietly suppressed, since the great circle joining antipodeal pairs is not unique.

The interior angle at each vertex must be less than or equal to 180° (that is, the polygon must be convex; convex here means precisely that each interior angle must be less than or equal to 180°). It is up to you to ensure that your polygon is convex; mangle does not check that it is.

Warning: Although the edges format retains more information about a polygon than the vertices format, in general it does not retain all information about a polygon. The only formats that retain all information are the circle and polygon formats. When mangle reads a polygon in edges format, it converts each edge to a cap. The resulting polygon is, as usual, taken to be the intersection of the caps. As illustrated below, this polygon may not be the same as the polygon you intended, although in most cases it will be. If a polygon file is translated from polygon format into edge format and then back into polygon format, then the final polygon file may not be exactly the same as the original.

A complicated polygon
A polygon in which the 6 points delineating the 3 edges of a triangle actually define a more complicated polygon, with two disconnected parts.

5.5 graphics format

Output polygon files in graphics format are useful for making plots of polygons. The mangle software does not incorporate any plotting software: it is assumed that you have your own favourite plotting package.

The graphics format is similar to edges format, but is generally more economical. Whereas in edges format there is a specified number of points per edge, in graphics format there is a specified number of points per (\(2\pi\)) of azimuthal angle along each edge. Thus in graphics format curvier edges get more points than straighter edges.

For example, a triangular polygon in graphics format might have 6 vertices as follows:

	       1
	   6
       5  4  3  2
in which the three edges have zero, one, and two intermediate points.

The graphics format is implemented only as output, not as input, because of ambiguity in the interpretation of the format. That is, mangle can write a polygon file in graphics format, but it will refuse to read such a file.

On output, graphics format with m points per (\(2\pi\)) along each edge is specified with

	-og<m>
The default is m = 2, giving 2 points per (\(2\pi\)) of azimuthal angle, which is a pretty miserable resolution. In practice you will probably want higher resolution, with m = 12 or more.

5.7 rectangle format

A rectangle is defined by a minimum and maximum azimuth, and a minimum and maximum elevation. A rectangle is a polygon with 4 caps. But it is not just any old polygon with 4 caps: it is a special species whose boundaries are lines of constant azimuth and elevation. This format is offered not only because some masks are defined this way (for example, the IRAS masks), but also because the symmetry of rectangles permits accelerated computation of their spherical harmonics.

Warning: The azimuthal extent of a rectangle is constrained to be in the interval \([0,\pi]\) radians, or else to be a full circle of \(2\pi\) radians. This follows from the requirement that a rectangle be a polygon, an intersection of caps. If the azimuthal extent is a full circle, azmax – azmin = \(2\pi\), then there is no azimuthal constraint. Otherwise the azmin limit is implemented with a hemispherical cap which constrains the azimuth to lie within [azminazmin + \(\pi\)] (modulo \(2\pi\)); similarly the azmax limit is implemented with a hemispherical cap which constrains the azimuth to lie within [azmax – \(\pi\), azmax] (modulo \(2\pi\)). This works fine if the azimuthal extent (azmax – azmin) (modulo \(2\pi\)) is less than or equal to \(\pi\), but if (azmax – azmin) (modulo \(2\pi\)) exceeds \(\pi\), then the computed polygon will actually have azimuthal extent from azmax – \(\pi\) to azmin + \(\pi\), which is probably not what was intended. In the latter case mangle issues a warning, but passes the rectangle through. It is up to you to make sure that every rectangle has azimuthal extent in the interval \([0,\pi]\) radians, or else to be a full circle of \(2\pi\) radians.

A line in rectangle format looks like

azmin azmax elmin elmax

Here for example is a part of the 2QZ UKST North field file:

# 2dF QSO Redshift Survey: UKST field limits for the NGP
# RA/Dec in radians, B1950, original APM coord. system
#  RA_min    RA_max   Dec_min   Dec_max  UKST_field
  2.572862  2.660129 -0.047837  0.039429   853
  2.660129  2.746899 -0.047563  0.039704   854
  2.746899  2.833492 -0.047460  0.039806   855
...
This can be read with
	-ir1r
The -ir switch specifies that the input format is rectangle. The 1 on -ir1 says to read only 1 rectangle on each line. The final r on -ir1r declares that the angles are in radians. Actually, the 1 argument in -ir1r is redundant, because mangle insists on only one rectangle per line. This is reasonable because the polygon defined by the intersection of two rectangles is itself a rectangle, so there is never any point in allowing more than one rectangle. Thus it suffices to specify
	-irr
and the read will succeed, even though the lines of the input file contain trailing characters, namely the UKST field numbers.

In the above example, the command line switches can be omitted if the rectangle and unit keywords are specified in the input file, as in

rectangle
unit r
# 2dF QSO Redshift Survey: UKST field limits for the NGP
# RA/Dec in radians, B1950, original APM coord. system
#  RA_min    RA_max   Dec_min   Dec_max  UKST_field
  2.572862  2.660129 -0.047837  0.039429   853
  2.660129  2.746899 -0.047563  0.039704   854
  2.746899  2.833492 -0.047460  0.039806   855
...
The rectangle keyword requires no arguments (any arguments present are ignored), because it is assumed (and required) that there is one rectangle per line.

5.8 polygon format

The polygon format is the default output format. It differs from the circle, edges, rectangle, and vertices formats in two important respects. Firstly, each cap of a polygon in polygon format is written on a separate line, whereas in the other formats the caps of a polygon appear altogether on a single line. Secondly, and associated with this difference, each polygon in polygon format must be introduced with the polygon keyword, which specifies the number of caps. Amongst other things, the requirement that the polygon keyword appear in the input file means that the -ip command-line switch, which supposedly specifies polygon format, actually has no effect, although it is permitted.

It seems doubtful that one would want to create an original mask file in polygon format, since it is a bit peculiar, but it is the standard format used by the mangle software, since it specifies polygons in the manner expected for many years past by the fortran backend. If you don’t like that, blame history, which can be blamed for a lot of things.

An entry for a polygon in polygon format looks like:

polygon <id> ( <n> caps, <double> weight, <double> str):
x0 y0 z0 cm0
x1 y1 z1 cm1
...
zn yn zn cmn

Each xi yi zi is a unit vector (xi2 + yi2 + zi2 = 1) defining the north polar axis of the cap, while cmi = 1 - cos(thetai) defines the cap latitude, thetai being the polar angle. Positive cmi designates the region north of the latitude, while negative cmi designates the region south of the latitude.

Here are two example polygons, the first two in 2QZ 10k North, specified in polygon format:

polygon 0 ( 6 caps, 0.736196 weight, 0.000207860166080 str):
 -0.9989940782261225 -0.0200145430763467 -0.0401279171473552 0.0001523048436087608
  0.0000000000000000  0.0000000000000000  1.0000000000000000 1.0469757058067
 -0.9981574940502457 -0.0455122767695589 -0.0401279171473552 -0.0001523048436087608
 -0.9991937369794350  0.0012752436969931 -0.0401279171473552 -0.0001523048436087608
 -0.9991645123188478 -0.0373565773479794 -0.0165759902112463 -0.0001523048436087608
 -0.9998014206069079 -0.0110614601624467 -0.0165759902112463 -0.0001523048436087608
polygon 1 ( 4 caps, 0.666667 weight, 0.000115712115129 str):
 -0.9981574940502457 -0.0455122767695589 -0.0401279171473552 0.0001523048436087608
  0.0000000000000000  0.0000000000000000  1.0000000000000000 1.0469757058067
 -0.9989940782261225 -0.0200145430763467 -0.0401279171473552 0.0001523048436087608
 -0.9991645123188478 -0.0373565773479794 -0.0165759902112463 -0.0001523048436087608

In accordance with the mangle philosophy of being as tolerant as possible of the format of input polygon files, the polygon lines in polygon format can be abbreviated on input. For example, the above excerpt from the 2QZ 10k North polygon file could be abbreviated to

polygon 0 6
 -0.9989940782261225 -0.0200145430763467 -0.0401279171473552 0.0001523048436087608
  0.0000000000000000  0.0000000000000000  1.0000000000000000 1.0469757058067
 -0.9981574940502457 -0.0455122767695589 -0.0401279171473552 -0.0001523048436087608
 -0.9991937369794350  0.0012752436969931 -0.0401279171473552 -0.0001523048436087608
 -0.9991645123188478 -0.0373565773479794 -0.0165759902112463 -0.0001523048436087608
 -0.9998014206069079 -0.0110614601624467 -0.0165759902112463 -0.0001523048436087608
polygon 1 4
 -0.9981574940502457 -0.0455122767695589 -0.0401279171473552 0.0001523048436087608
  0.0000000000000000  0.0000000000000000  1.0000000000000000 1.0469757058067
 -0.9989940782261225 -0.0200145430763467 -0.0401279171473552 0.0001523048436087608
 -0.9991645123188478 -0.0373565773479794 -0.0165759902112463 -0.0001523048436087608
and mangle will still happily read it.

5.8“ spolygon format

For the benefit of those who would like to write their own software to read polygon files, but find the polygon lines in the polygon format cumbersome, there is a spolygon, or simplified polygon, format which is the same as the polygon format but without the words. Whereas in polygon format there are polygon lines that look like
polygon <id> ( <n> caps, <double> weight, <double> str):
in spolygon format the corresponding lines are a stripped down version consisting only of numbers:
<id> <n> <double> <double>

The -is command line switch, which supposedly specifies that an input polygon file is in spolygon format, has no effect, although it is permitted. Similarly, the spolygon keyword is not required in the polygon file, although it is permitted. Instead, mangle detects that an input polygon file is in spolygon format from the presence of a line that starts with two integers, which are interpreted as specifying the id number <id> and the number <n> of caps of the polygon. Mangle expects such a line to be followed by <n> lines containing 4 real numbers on each line. To avoid misinterpretation, lines that start with two integers are considered as possible spolygon lines only if no other input format has been specified, either on the command line or with a keyword in the input polygon file. However, it is possible to switch from another format to spolygon format by explicitly prefixing a spolygon line with the spolygon keyword in the input polygon file.

To specify the spolygon format on output, use the -os switch, as in

	poly2poly -os polygon_infile spolygon_outfile

For example, the first two polygons in in 2QZ 10k North, specified in spolygon format, are:

0 6 0.736196 0.000207860166080
 -0.9989940782261225 -0.0200145430763467 -0.0401279171473552 0.0001523048436087608
  0.0000000000000000  0.0000000000000000  1.0000000000000000 1.0469757058067
 -0.9981574940502457 -0.0455122767695589 -0.0401279171473552 -0.0001523048436087608
 -0.9991937369794350  0.0012752436969931 -0.0401279171473552 -0.0001523048436087608
 -0.9991645123188478 -0.0373565773479794 -0.0165759902112463 -0.0001523048436087608
 -0.9998014206069079 -0.0110614601624467 -0.0165759902112463 -0.0001523048436087608
1 4 0.666667 0.000115712115129
 -0.9981574940502457 -0.0455122767695589 -0.0401279171473552 0.0001523048436087608
  0.0000000000000000  0.0000000000000000  1.0000000000000000 1.0469757058067
 -0.9989940782261225 -0.0200145430763467 -0.0401279171473552 0.0001523048436087608
 -0.9991645123188478 -0.0373565773479794 -0.0165759902112463 -0.0001523048436087608

5.9 Region format

The Region format is a precursor of the polygon format, and is provided for backwards compatibility.

5.10 area format

The area format is available only on output.
	poly2poly -oa polygon_infile area_outfile
creates a file area_outfile in area format which contains on successive lines the area and id of each polygon of polygon_infile.

5.11 id format

The id format is available only on output.
	poly2poly -oi polygon_infile id_outfile
creates a file id_outfile in id format which contains on successive lines the id of each polygon of polygon_infile.

5.12 midpoint format

The midpoint format is available only on output.
	poly2poly -om polygon_infile midpoint_outfile
creates a file midpoint_outfile in midpoint format which contains on successive lines a midpoint and id of each polygon of polygon_infile.

The midpoint selected by mangle is not guaranteed to be the midpoint, but it is guaranteed to lie inside the polygon, and mangle tries hard to select a point well inside the polygon, away from its edges. mangle tries several judiciously chosen trial points, and picks the best one, namely the one which is farthest from any edge of the polygon.

5.13 weight format

The weight format is available only on output.
	poly2poly -ow polygon_infile weight_outfile
creates a file weight_outfile in weight format which contains on successive lines the weight and id of each polygon of polygon_infile.

6. Troubleshooting

6.1 Mangle won’t compile
6.2 Did you remember to run snap on your input polygon files?
6.3 Multiply-intersecting and kissing circles
6.4 A routine complains of ‘total failure’ or some other fatal error
6.5 balkanize is making unexpectedly vast numbers of polygons
6.6 Some of the polygons that come from my vertices file are 180° away from where they should be
6.7 Some of the polygons that come from my edges file are not right — the polygon does not even pass through the points!
6.8 How can I get rid of all the tiny polygons?
6.9 How can I get rid of all the polygons with zero weight?
6.10 When I output to graphics (or vertices, or edges) format, it tells me that some of the polygons of my balkanized mask have multiple boundaries
6.11 Your fortran refuses to read the unformatted fortran files made on another system
6.12 Is there a simple way to determine the area of a mask?
6.13 How to define a polygon which is the entire sky?
6.14 How to make the complement of a mask?
6.15 Is there a way to harmonize the complement of a mask directly from the holes?

6.1 Mangle won’t compile

This is bound to happen in early days of a release, before mangle has been tested over a wide range of systems. If you are having trouble compiling, please email me, and I’ll do what I can to help.

Mangle requires both c and fortran 77 compilers.

Mangle is known to compile with the gnu versions of cc, f77, and make, namely with gcc, g77, and gmake.

6.2 Did you remember to run snap on your input polygon files?

You should always run snap on all the input polygon files that define your mask, before running balkanize. If you have several input files, you should run snap on the combined set of input files before balkanizing. Look at the 2QZ 10k North incantation for an example.

It should be necessary to run snap only on the initial input files, not on balkanized or subsequent polygon files. On the other hand, running snap on balkanized or subsequent polygon files should be harmless, and in most cases should have no effect.

Whatever the case, if you are getting lots of incomprehensible error messages, your first reaction should be to run snap on the input polygon files.

Snapped polygon files should be stored in polygon (the default) or circle format, since other formats (edges, vertices, and rectangle) can lose information about having been snapped. All snapped files should be stored in the same format, to avoid introducing numerical discrepancies.

6.3 Multiply-intersecting and kissing circles

Multiple intersections occur where 3 or more circles (cap boundaries) intersect at a single point. Circles kiss if they just touch. Mangle should deal correctly with multiply-intersecting and kissing circles in almost all cases.

However, multiply-intersecting and kissing circles do pose a potential source of numerical problems, because the topology of the distribution of near multiply-intersecting and near kissing circles may vary depending on precisely how the intersections are computed, as illustrated in the animation below right. Mangle is equipped to deal with these problems, and is designed to cope in almost all cases. But it is possible to fool mangle with a sufficiently complicated polygon, for example a polygon whose vertices have a fractal distribution of separations.

Example of 3 circles intersecting at a single point   Numerical roundoff can change the topology of the distribution of intersection points
Mangle can deal with this   and this
     
Example of 2 kissing at a single point   Numerical roundoff can change the topology of the distribution of kissing points
and this   and this.

The strategy adopted by mangle is to consider all vertices closer than a certain tolerance angle to be coincident. The algorithm is friends-of-friends: two vertices closer than the tolerance are friends, and a friend of a friend is a friend.

There is a command line switch

	-m<angle>[<unit>]
that adjusts the initial tolerance angle for multiple intersections and kisses. You may want to use this switch if your polygons have many multiple intersections or kisses and the default tolerance proves too loose or too tight.

If you use the -m switch in balkanizing your polygons, then you should make sure to use the -m switch with the same tolerance angle in subsequent operations, for example with the unify or poly2poly commands.

You can find out the default value of the initial tolerance angle for multiple intersections with

	balkanize -d
As of writing (June 2003), the default initial angle is 10-5 arcseconds.

-m<angle>[<unit>] multiple intersection tolerance Are two points of intersection within <angle> of each other? If so, treat the points as being coincident.

The specified <angle> is the initial tolerance applied to each polygon. If an inconsistency is detected, then the tolerance angle is changed, and the computation is repeated for the inconsistent polygon, repeatedly until consistency is achieved. The strategy is to try both tightening and loosening the tolerance, see-sawing between tighter and looser values that are successive factors of 2 away from the initial tolerance angle. In the case that the initial tolerance angle is zero, if an inconsistency is detected, then the tolerance angle is set to a tiny number, and thereafter is doubled repeatedly until consistency is achieved.


6.4 A routine complains of ‘total failure’ or some other fatal error

First look at 6.2.

If that is not the problem, then either you have a rather complicated polygon, like a fractal, or this is a genuine bug.

If it is a bug, I’d love to know. Please email me the following information:

  1. The input polygon files that give the problem;
  2. The sequence of commands that give the problem;
  3. The output of the sequence of commands (with verbose on, i.e. without the -q quiet flag).

6.5 balkanize is making unexpectedly vast numbers of polygons

Diagnosis: balkanize thinks that the input polygons are much larger than they really are, so there are many more intersections than there should be.

Solution: Doublecheck the units, and the format in general. For example, the h unit tells balkanize that the RA and Dec in the input file(s) are in hms and ° ′ ″ respectively, and that any other angle, such as the radius of a circular field, is in degrees.

6.6 Some of the polygons that come from my vertices file are 180° away from where they should be

Diagnosis: The vertices in the input polygon file (in vertices format) are not ordered as desired.

Solution: Reorder the vertices right-handedly about the polygon. Alternatively, introduce an r character (followed by a blank) as the first character of each line of vertices that you wish to reverse.

6.7 Some of the polygons that come from my edges file are not right — the polygon does not even pass through the points!

Diagnosis: The points in the input polygon file (in edges format) are not ordered as desired.

Solution: Reorder the points right-handedly about the polygon. Alternatively, introduce an r character (followed by a blank) as the first character of each line of points that you wish to reverse.

6.8 How can I get rid of all the tiny polygons?

Use the -k switch on the poly2poly command. For example
	poly2poly -k1e-10 polygon_infile polygon_outfile
copies polygon file polygon_infile to polygon file polygon_outfile keeping only polygons with areas greater than or equal to 1e-10 steradians.

6.9 How can I get rid of all the polygons with zero weight?

The unify command does this as part of the procedure of unifying polygons.

But if you want to get rid of zero weight polygons without unifying them, then use the -j switch on the poly2poly command. For example

	poly2poly -j1e-10 polygon_infile polygon_outfile
copies polygon file polygon_infile to polygon file polygon_outfile keeping only polygons with weights greater than or equal to 1e-10.

6.10 When I output to graphics (or vertices, or edges) format, it tells me that some of the polygons of my balkanized mask have multiple boundaries

Diagnosis: Your mask contains some non-simply-connected polygons, such as the one below.
A non-simply-connected polygon
A non-simply-connected polygon.

Solution: It’s not a problem.

Alternative diagnosis: When balkanizing, you used the -m<angle> switch to specify a non-default value for the tolerance <angle> for multiple intersections.

Solution: Use the -m<angle> switch with the same tolerance <angle> when converting your file to graphics format. More generally, if you use the -m<angle> switch, then you should apply the switch consistently with the same tolerance <angle> in all mangle commands.

6.11 Your fortran refuses to read the unformatted fortran files made on another system

Diagnosis: Your computer stores bytes with opposite endianness.

Solution:
WARNING: The following hack only works if each number in the unformatted fortran file is a single word, i.e. an INTEGER or REAL (not DOUBLE PRECISION).

On a 32-bit machine, each word contains 4 bytes. Convert the files to the other endianness using the cpio command, famous for its obtuseness:
1. Make a cpio archive file from the original files, as in
	ls -1 file1 file2 ... | cpio -o > files.cpio
Notice that the switch -1 is a one, not an ell.
2. Move the cpio archive to another directory where it will not overwrite the old files
	mv files.cpio other_directory
3. Extract the files from the cpio archive in the new directory
	cd other_directory
	cpio -i -b < files.cpio
The -b switch is the thing that does the byte-swapping.

6.12 Is there a simple way to determine the area of a mask?

Suppose that your mask is in a polygon file pretty.poly. Run
	harmonize pretty.poly -

6.13 How to define a polygon which is the entire sky?

A polygon with 0 caps is the entire sky. The file allsky.pol in the mangle/masks/allsky/ directory is a polygon file specifying the allsky polygon. It should contain the following single line:
polygon 0 ( 0 caps, 1 weight, 12.56637061435917 str):
The line could be abbreviated to
polygon 0 0
which specifies a polygon of 0 caps, with a default weight of 1.

Similarly, in circle format, the allsky polygon can be specified with

circle 0 0
or more verbosely with
circle 0 ( 0 caps, 1 weight, 12.56637061435917 str):
Normally, a line of the form
circle 0 n
in a polygon file (n is some integer) would instruct mangle to expect subsequent lines in the file to contain n circles per line. However, for the particular case where n is zero, mangle assumes that only one polygon can be an allsky polygon. Therefore, it is essential that the format be re-initialized following the declaration of an allsky polygon, as for example in
circle 0 0
circle
az1 el1 th1 ... azn eln thn
...
The first line, circle 0 0, specifies an allsky polygon (you can add an optional blank line for clarity, if you want), while the circle keyword on the second line instructs mangle that subsequent lines are in circle format. The fact that circle appears with no arguments declares that the number of circles per line is variable; mangle deduces the number of circles from the number of angles it finds in a line.

6.14 How to make the complement of a mask?

Suppose that your mask consists of the entire sky except for a list of excluded regions, or holes, which you have prepared in a polygon file holes.pol. How do you make a polygon file, complement.pol, that defines the entire sky less the excluded regions in holes.pol?
1. As always, start by running snap:
	snap holes.pol jh
where you may need to use the -i.. switch to specify the format of the input polygon file holes.pol.
2. Edit the snap’d output polygon file jh so that the weights of all polygons are zero. A weight of 0 will cause balkanize to treat the holes as being empty.
3. Run balkanize on the allsky polygon file allsky.pol (in the mangle/masks/allsky/ directory) and the editted polygon file jh of excluded regions:
	balkanize allsky.pol jh jb
The order here is important, the allsky file allsky.pol first and the holes file jh second, because you want the holes to override the allsky. If the allsky file came second, it would override the holes, the net result (after much worthless work) being allsky again.
4. Run unify on the balkanized polygon file jb:
	unify jb complement.pol
Voilą. You have a polygon file complement.pol defining the complement of your mask.

If the resulting set of balkanized polygons looks a mess, or if you think there are more balkanized polygons than there should be, then you might consider creating a special allsky.pol polygon file that subdivides the whole sky in a judiciously chosen fashion better matched to the geometry of your holes. See mangle/masks/pscz/allsky.rect for an example.

6.15 Is there a way to harmonize the complement of a mask directly from the holes?

Suppose that you want to compute the harmonics of a mask consisting of the whole sky less the excluded regions which you have prepared in a polygon file holes.pol. Instead of taking the complement of the mask as in §6.13, an alternative way to proceed is to compute the harmonics of the holes from holes.pol, and subtract those from the harmonics of the whole sky, whose only nonzero harmonic is the monopole harmonic \(w_{00} = \sqrt{4\pi}\).

In practice, you could proceed as follows:
1. As always, start by running snap:
	snap holes.pol jh
where you may need to use the -i.. switch to specify the format of the input polygon file holes.pol.
2. Edit the snap’d output polygon file jh so that the weights of all polygons are -1. A weight of -1 will cause harmonize to subtract (add with weight -1) the harmonics of each excluded polygon in jh.
3. Run harmonize on the combination of the allsky polygon in allsky.pol (in the mangle/masks/allsky/ directory) and the holes in jh
	harmonize -l<lmax> allsky.pol jh complement.wlm
The file complement.wlm contains the harmonics of the sky less the excluded regions.

7. References, Links


Last updated 31 Mar 2009; converted to mathjax 5 Feb 2018.