Last modified: February 2018

Jump to: Description · Bugs · See Also

AHELP for CIAO 4.16


Context: region


Provides a Python interface to the CXC region library


The CXC region library is used by the CXC datamodel to perform 2D filtering using various geometric shapes (circle, box, polygon, ellipse, etc.). It also provides information about the area and extent of regions which may be combined together using logical AND and OR operators, ie region Union and Intersection.

The region module is imported in the following ways

from region import *
import region

The CXCRegion object

The CXCRegion object is used to represent a region. A typical example may be to load a region from a ds9 region file:

>>> from region import *
>>> my_region = CXCRegion("region(ds9.reg)")

The argument to the CXCRegion constructor can be any valid region string

>>> my_region = CXCRegion("circle(4096,4096,100)")
>>> my_region = CXCRegion("circle(4096,4096,100)-box(4096,4096,10)")
>>> my_region = CXCRegion("region(ds9.reg)")
>>> my_region = CXCRegion("bounds(region(ds9.reg))")

Since using region files is so common, users can also omit the "region()" and just use the region file name directly

>>> my_region = CXCRegion("ds9.reg")

Users can also create an empty region (no shapes)

>>> my_region = CXCRegion()

There are two additional special construction methods. The CXC Datamodel stores any spatial filter which were used in the output file's data subspace. This information is available using dmlist

unix% dmlist img.fits subspace
 --- Component 1 --- 
   1 sky                  Real8               Polygon(3532.07,3282.84,3574.06,3282.75,4517.64,
   1 sky                  Real8               Field area = 1.88513e+06 Region area = 1.1546e+06

but can be difficult to parse, especially for complex filters. The CXCRegion object can obtain the region directly from the file's subspace using the file name and the column name such as

>>> my_subspace=CXCRegion("img.fits","sky")
>>> print(my_subspace)

Users can also use individual Shape objects which is discussed later in this document.

Shape functions

Users can also create CXCRegion objects using the following convenience functions

>>> myreg = annulus(x,y,inner,outer)
>>> myreg = box(x,y,xlen,ylen)
>>> myreg = box(x,y,xlen,ylen,rotang)
>>> myreg = circle(x,y,r)
>>> myreg = ellipse(x,y,r1,r2)
>>> myreg = ellipse(x,y,r1,r2,rotang)
>>> myreg = field()
>>> myreg = pie(x,y,inner,outer,start,stop)
>>> myreg = point(x,y)
>>> myreg = polygon(x1,y1,x2,y2,x3,y3,...)
>>> myreg = polygon(x_array,y_array)
>>> myreg = rectangle(llx,lly,urx,ury)
>>> myreg = rotbox(x,y,xlen,ylen,rotang)
>>> myreg = sector(x,y,start,stop)

where (x,y) are the center of the shape, rotang & start & stop are all angles measured in degrees from the +X axis.

Coordinate systems

Note that the region module does not have any intrinsic knowledge of WCS coordinates, so cannot be directly used to match pointed Chandra observations to specific regions. The dmcoords tool can be useful when converting between different Chandra coordinate systems.

CXCRegion methods

Each CXCRegion object has the following methods: area, edit, extent, is_inside, and write.


Computes the area of the region. If the region is simple, then it will compute the analytic area. However, if the region is complex, then it will pixelate the region and compute the area that way.

>>> a = circle(10,10,100)
>>> a.area()
>>> a.area(pixel=True)
>>> a.area(pixel=True,bin=0.1)


The extent of the region is given by the lower left corner location (x0,y0) and the upper right corner location (x1,y1)

>>> a.extent()
{'y1': 110.0, 'y0': -90.0, 'x0': -90.0, 'x1': 110.0}


The is_inside routine checks to see if the x,y pair is located within the region

>>> a.is_inside( 1,1)
>>> a.is_inside( -100,-100)


The edit method allows the user to shift all the x,y locations (dx and dy parameters), scale all the radii (stretch parameter), pad all the radii (pad parameter), and rotate (rotate parameter) the shapes in the region. A single shape within the region can be edited using the index parameter.

Note: edit does not modify the current region. It returns a new CXCRegion object with the modified shape parameters.

>>> a.edit( dx=-10 )
>>> a.edit( dy=-10 )
>>> a.edit( pad=-30)
>>> a.edit( stretch=1.5)
>>> a.edit(rotate=45)
>>> a.edit(index=0,stretch=2)


A CXCRegion can be written to either an ASCII region file or to a FITS region file.

>>> a.write("ciao.reg")
>>> a.write("ciao.fits", fits=True)
>>> a.write("ciao.reg", clobber=True)

>>> b=a.edit( dx=-10, dy=-10 )
>>> c=b-a
>>> c.write("ds9.reg", newline=True)

CXCRegion object logic operators

The CXCRegion objects can be manipulated using mathematical (ie logical) operators: * and & (intersection), + and | (union), ~ (negation), - (same as *~), and ^ (xor). Regions can also be tested for equality using ==.

>>> a=circle(10,10,20)
>>> b=box(10,10,30,30)
>>> c1 = a+b
>>> c2 = a*b
>>> c3 = b-a
>>> print(c3)
>>> c4 = a^b
>>> print(c4)
>>> c5 = a|b
>>> c6 = a&b
>>> c1 == c5
>>> c1 is c5

CXCRegion object list operators

CXCRegion objects also behave like lists. They support list indexing, and testing for membership. Note that slicing a CXCRegion object creates a new CXCRegion object. Remember, even a region with only 1 shape is still a region.

>>> new_a = c1[0]
>>> a in c1
>>> c1.index(a)
>>> new_a == a
>>> c4[2:]

Note that when a slice contains multiple shapes, they are always "included" and they are always or'ed ("+") together.

CXCRegion shapes property

Users can access the individual shapes and their properties using the via the CXCRegion().shapes property. This returns a python list of Shape objects which provides access to each shape in the region.

>>> a=circle(10,10,20)
>>> b=box(10,10,30,30)
>>> c = a+b
>>> z = c[0]
>>> type(z)
<class 'region.cxcregion.CXCRegion'>
>>> c.shapes
[<region.shape.Circle object at 0x7f21b726ff50>, 
<region.shape.Box object at 0x7f21b726ffd0>]

With access to the individual shapes, users then have access to its properties: name, xpoints, ypoints, radii, angles, component number, include flag, and logic operator.

>>> q = c.shapes[0]
>>> print(q)
>>> q.xpoints
array([ 10.])
>>> q.ypoints
array([ 10.])
>>> q.radii
array([ 20.])
>>> q.angles
>>> q.component
>>> q.include
ShapeInclusion(val=1, str='')
>>> q.logic
ShapeOperation(val=1, str='')

The component value and logic operation are related. All shapes with the same component value are intersected, and different components are unioned.

The Shape object properties are immutable. However, users can create a new CXCRegion object using an existing Shape object which can then be modified using the edit() method.

>>> new_q = CXCRegion( q )
>>> new_q = new_q.edit(dx=10,dy=20,stretch=0.5)
>>> new_q


See the bugs page for the region library on the CIAO website for an up-to-date listing of known bugs.

Refer to the CIAO bug pages for an up-to-date listing of known issues.

See Also

regarea, regextent, reginsideregion, region-old, regparse, regprintregion, regregionstring