ixpe_protractor

Contributed by: Phil Kaaret

Last updated: Dec 15 2025

Download: Python script Example region file

ixpe_protractor is a python script to make protractor (polar) plots of polarization as calculated by ixpepolarization given an input list of level2 event files, a region file, and an energy band.

Example:


# This example assumes that the user is running bash shell and CALDB environment variable is defined. 
# Plot the X-ray polarization of 1ES 1959+650 from an IXPE observation.
# 1 - Download data for IXPE observation of 1ES 1959+650 on 2024-12-18.
# 2 - Filter out instrumental background events.
# 3 - Find source region file. (Sample region file included src.reg)
# 4 - Calculate model-independent polarization and make a protractor plot.


# Start by moving to the directory where you wish to download and process the data.

### Define the observation ID.
export OBS=03250801
### 1- Get data from HEASARC using wget command.
# Note the data are stored in a directory which is the first two digits of ObsID.
wget -nH --no-check-certificate --cut-dirs=5 -r -l0 -c -N -np -R 'index*' -erobots=off --retr-symlinks https://heasarc.gsfc.nasa.gov/FTP/ixpe/data/obs/${OBS:0:2}/${OBS}/

### gunzip level2 event files
gunzip ${OBS}/event_l2/*.gz

### 2 - Background filtering for data processed after 18 Dec 2025
ftselect clobber=yes ${OBS}/event_l2/ixpe${OBS}_det1_evt2_v??.fits ${OBS}/event_l2/ixpe${OBS}_det1_evt2_rej.fits  status.NE.bxxxxxxx1xxxxxxxx
ftselect clobber=yes ${OBS}/event_l2/ixpe${OBS}_det2_evt2_v??.fits ${OBS}/event_l2/ixpe${OBS}_det2_evt2_rej.fits  status.NE.bxxxxxxx1xxxxxxxx
ftselect clobber=yes ${OBS}/event_l2/ixpe${OBS}_det3_evt2_v??.fits ${OBS}/event_l2/ixpe${OBS}_det3_evt2_rej.fits  status.NE.bxxxxxxx1xxxxxxxx

### 3 - define source region file using ds9 and save in detector coordinates
# using the same source region for all three DUs usually works
# source region is circle, radius = 60 arcsec
# command to start ds9 and load level 2 event files after background rejection
ds9 ${OBS}/event_l2/ixpe${OBS}_det1_evt2_rej.fits ${OBS}/event_l2/ixpe${OBS}_det2_evt2_rej.fits  ${OBS}/event_l2/ixpe${OBS}_det3_evt2_rej.fits &

# 4 - calculate model-independent polarization and make protractor plot
python3 ixpe_protractor.py ${OBS}/event_l2/ixpe${OBS}_det?_evt2_rej.fits --region=src.reg --eband='2.0 8.0'


### For observations processed before December 2025, do background filtering via Di Marco tool
# see https://heasarc.gsfc.nasa.gov/docs/ixpe/analysis/contributed.html
# code available at https://github.com/aledimarco/IXPE-background
# gunzip level2 event files, needed for filter_background
gunzip ${OBS}/event_l2/*.gz
### 2 - run filter_background.py 
# this code assumes a single event l1 file for each observation
python3 filter_background.py ${OBS}/event_l2/ixpe${OBS}_det1_evt2_v??.fits ${OBS}/event_l1/ixpe${OBS}_det1_evt1_v??.fits.gz
python3 filter_background.py ${OBS}/event_l2/ixpe${OBS}_det2_evt2_v??.fits ${OBS}/event_l1/ixpe${OBS}_det2_evt1_v??.fits.gz
python3 filter_background.py ${OBS}/event_l2/ixpe${OBS}_det3_evt2_v??.fits ${OBS}/event_l1/ixpe${OBS}_det3_evt1_v??.fits.gz

### 4 - calculate model-independent polarization and make protractor plot (slightly different file names)
python3 ixpe_protractor.py ${OBS}/event_l2/ixpe${OBS}_det?_evt2_v??_rej.fits --region=src.reg --eband='2.0 8.0'