This is a fixed-text formatted version of a Jupyter notebook
- Try online
- You can contribute with your own notebooks in this GitHub repository.
- Source files: cwt.ipynb | cwt.py
CWT Algorithm¶
This notebook tutorial shows how to work with CWT
algorithm for detecting gamma-ray sources.
You can find the docs here and source code on GitHub here for better understanding how the algorithm is constructed.
Setup¶
On this section we just import some packages that can be used (or maybe not) in this tutorial. You can also see the versions of the packages in the outputs below and notice that this notebook was written on Python 2.7. Don’t worry about that because the code is also Python 3 compatible.
[1]:
# Render our plots inline
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
[2]:
from astropy.io import fits
from astropy.coordinates import Angle, SkyCoord
from gammapy.maps import Map
from gammapy.detect import CWTKernels, CWT, CWTData
CWT Algorithm¶
First of all we import the data which should be analysied.
[3]:
counts = Map.read("$GAMMAPY_DATA/fermi-3fhl-gc/fermi-3fhl-gc-counts.fits.gz")
background = Map.read(
"$GAMMAPY_DATA/fermi-3fhl-gc/fermi-3fhl-gc-background.fits.gz"
)
maps = {"counts": counts, "background": background}
[4]:
fig = plt.figure(figsize=(15, 3))
ax = fig.add_subplot(121, projection=maps["counts"].geom.wcs)
maps["counts"].plot(vmax=8, ax=ax)
ax = fig.add_subplot(122, projection=maps["background"].geom.wcs)
maps["background"].plot(vmax=8, ax=ax);
Let’s explore how CWT works. At first define parameters of the algorithm. An imperative parameter is kernels (detect.CWTKernels
object). So we should create it.
[5]:
# Input parameters for CWTKernels
N_SCALE = 2 # Number of scales considered.
MIN_SCALE = 6.0 # First scale used.
STEP_SCALE = 1.3 # Base scaling factor.
[6]:
cwt_kernels = CWTKernels(
n_scale=N_SCALE, min_scale=MIN_SCALE, step_scale=STEP_SCALE
)
cwt_kernels.info_table
[6]:
Name | Source |
---|---|
str46 | str32 |
Number of scales | 2 |
Minimal scale | 6.0 |
Step scale | 1.3 |
Scales | [6. 7.8] |
Kernels approx width | 83 |
Kernels approx sum | 0.9999153345163221 |
Kernels approx max | 0.0015479047097235869 |
Kernels base width for 6.0 scale | 63 |
Kernels base sum for 6.0 scale | 3.0166320971388447e-05 |
Kernels base max for 6.0 scale | 8.599470609575481e-05 |
Kernels base width for 7.800000000000001 scale | 83 |
Kernels base sum for 7.800000000000001 scale | 1.456141213300368e-05 |
Kernels base max for 7.800000000000001 scale | 3.0109136968507695e-05 |
Other parameters are optional, in this demonstration define them all.
[7]:
MAX_ITER = 10 # The maximum number of iterations of the CWT algorithm.
TOL = 1e-5 # Tolerance for stopping criterion.
SIGNIFICANCE_THRESHOLD = 2.0 # Measure of statistical significance.
SIGNIFICANCE_ISLAND_THRESHOLD = (
None
) # Measure is used for cleaning of isolated pixel islands.
REMOVE_ISOLATED = True # If True, isolated pixels will be removed.
KEEP_HISTORY = True # If you want to save images of all the iterations
Let’s start to analyse input data. Import Logging module to see how the algorithm works during data analysis.
[8]:
cwt = CWT(
kernels=cwt_kernels,
tol=TOL,
significance_threshold=SIGNIFICANCE_THRESHOLD,
significance_island_threshold=SIGNIFICANCE_ISLAND_THRESHOLD,
remove_isolated=REMOVE_ISOLATED,
keep_history=KEEP_HISTORY,
)
In order to the algorithm was able to analyze source images, you need to convert them to a special format, i.e. create an CWTData object. Do this.
[9]:
cwt_data = CWTData(
counts=maps["counts"], background=maps["background"], n_scale=N_SCALE
)
[10]:
# Start the algorithm
cwt.analyze(cwt_data)
Results of analysis¶
Look at the results of CWT algorithm. Print all the images.
[11]:
PLOT_VALUE_MAX = 5
FIG_SIZE = (15, 35)
fig = plt.figure(figsize=FIG_SIZE)
images = cwt_data.images()
for index, (name, image) in enumerate(images.items()):
ax = fig.add_subplot(len(images), 2, index + 1, projection=image.geom.wcs)
image.plot(vmax=PLOT_VALUE_MAX, fig=fig, ax=ax)
plt.title(name) # Maybe add a Name in SkyImage.plots?
plt.subplots_adjust(hspace=0.4)
As you can see in the implementation of CWT above, it has the parameter keep_history
. If you set to it True
-value, it means that CWT would save all the images from iterations. Algorithm keeps images of only last CWT start. Let’s do this in the demonstration.
[12]:
history = cwt.history
print(
"Number of iterations: {0}".format(len(history) - 1)
) # -1 because CWT save start images too
Number of iterations: 10
Let’s have a look, what’s happening with images after the first iteration.
[13]:
N_ITER = 1
assert 0 < N_ITER < len(history)
data_iter = history[N_ITER]
fig = plt.figure(figsize=FIG_SIZE)
images_iter = data_iter.images()
for index, (name, image) in enumerate(images_iter.items()):
ax = fig.add_subplot(
len(images_iter), 2, index + 1, projection=image.geom.wcs
)
image.plot(vmax=PLOT_VALUE_MAX, fig=fig, ax=ax)
plt.title(name) # Maybe add a Name in SkyImage.plots?
plt.subplots_adjust(hspace=0.4)
You can get the information about the one particular image in that way:
[14]:
data_iter.image_info(name="approx_bkg")
[14]:
Metrics | Source |
---|---|
str10 | str19 |
Name | approx_bkg |
Shape | 2D image |
Variance | 0.06792041028304846 |
Mean | 0.3450471835001858 |
Max value | 1.3431556509385707 |
Min value | 0.02507055240537183 |
Sum values | 27603.774680014863 |
You can also get the information about cubes. Or information about all the data.
[15]:
data_iter.cube_info(name="support", per_scale=True)
[15]:
Scale power | Metrics | Source |
---|---|---|
int64 | str10 | str19 |
1 | Name | support |
-- | Shape | 2D image |
-- | Variance | 0.08244281109375 |
-- | Mean | 0.0906625 |
-- | Max value | True |
-- | Min value | False |
-- | Sum values | 7253 |
2 | Name | support |
-- | Shape | 2D image |
-- | Variance | 0.10431465234374998 |
-- | Mean | 0.1183125 |
-- | Max value | True |
-- | Min value | False |
-- | Sum values | 9465 |
[16]:
data_iter.cube_info(name="support", per_scale=False)
[16]:
Metrics | Source |
---|---|
str10 | str19 |
Name | support |
Shape | 3D cube |
Variance | 0.09356986234375002 |
Mean | 0.1044875 |
Max value | True |
Min value | False |
Sum values | 16718 |
Also you can see the difference betwen the iterations in that way:
[17]:
history = cwt.history # get list of 'CWTData' objects
difference = (
history[1] - history[0]
) # get new `CWTData` obj, let's work with them
[18]:
difference.cube_info("support")
[18]:
Metrics | Source |
---|---|
str10 | str19 |
Name | support |
Shape | 3D cube |
Variance | 0.09356986234375002 |
Mean | 0.1044875 |
Max value | True |
Min value | False |
Sum values | 16718 |
[19]:
difference.info_table.show_in_notebook()
[19]:
idx | Name | Shape | Variance | Mean | Max value | Min value | Sum values |
---|---|---|---|---|---|---|---|
0 | counts | 2D image | 0.6844118975 | 0.40855 | 39.0 | 0.0 | 32684.0 |
1 | background | 2D image | 0.08880340319596491 | 0.35685790374986825 | 2.4512903690338135 | 0.07625773549079895 | 28548.632299989462 |
2 | model | 2D image | 8.921001389341453e-06 | 0.0005671301395686342 | 0.05625939349628156 | 0.0 | 45.37041116549074 |
3 | approx | 2D image | 0.013881625888627153 | 0.050778161816230565 | 0.9352658503232087 | -0.2205906209437781 | 4062.252945298445 |
4 | approx_bkg | 2D image | 0.06792041028304846 | 0.3450471835001858 | 1.3431556509385707 | 0.02507055240537183 | 27603.774680014863 |
5 | transform_2d | 2D image | 8.921001389341453e-06 | 0.0005671301395686342 | 0.05625939349628156 | 0.0 | 45.37041116549074 |
6 | model_plus_approx | 2D image | 0.014392003909626066 | 0.0513452919557992 | 0.9915252438194904 | -0.2205906209437781 | 4107.623356463936 |
7 | residual | 2D image | 0.6216115263935782 | 0.3572047080442008 | 38.02873658648009 | -0.9239475941327672 | 28576.376643536063 |
8 | maximal | 2D image | 3.90899157890424e-06 | 0.00038485530141128534 | 0.04032730333779305 | 0.0 | 30.788424112902828 |
9 | support_2d | 2D image | 0.11123443734374998 | 0.1274875 | 1.0 | 0.0 | 10199.0 |
10 | transform_3d | 3D cube | 3.3095296022395382e-06 | 1.3167352804236912e-05 | 0.04032730333779305 | -0.009794629903234316 | 2.106776448677906 |
11 | error | 3D cube | 3.499614659470687e-08 | 0.00033874490842014524 | 0.001149678241925183 | 6.127092233422893e-05 | 54.199185347223235 |
12 | support | 3D cube | 0.09356986234375002 | 0.1044875 | 1.0 | 0.0 | 16718.0 |
[20]:
fig = plt.figure(figsize=FIG_SIZE)
images_diff = difference.images()
for index, (name, image) in enumerate(images_diff.items()):
ax = fig.add_subplot(
len(images_diff), 2, index + 1, projection=image.geom.wcs
)
image.plot(vmax=PLOT_VALUE_MAX, fig=fig, ax=ax)
plt.title(name) # Maybe add a Name in SkyImage.plots?
plt.subplots_adjust(hspace=0.4)
You can save the results if you want
[21]:
# cwt_data.write('test-cwt.fits', True)