Example notebook

This notebook shows how to run ORIGIN on a sub-cube from the UDF10 (http://muse-vlt.eu/science/udf/).

[1]:
%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt
from mpdaf.obj import Image, Cube
from mpdaf.sdetect import Catalog

import muse_origin
from muse_origin import ORIGIN

print(muse_origin.__version__)
3.2.dev168+g37122b7.d20190716
WARNING: AstropyDeprecationWarning: Composition of model classes will be removed in 4.0 (but composition of model instances is not affected) [astropy.modeling.core]

To run ORIGIN we need a data cube and its associate FSF. There are two ways to specify the PSF informations:

  • with the PSF, FWHM_PSF, and LBDA_FWHM parameters.

  • or it can be read from the cube header, when the cube contains the keywords required by mpdaf.MUSE.FSFModel, see below.

[2]:
DATACUBE = 'UDF10-small/DATACUBE_UDF-10-small.fits'
NAME = 'UDF10-example'

This cube has been cropped both spatially and spectrally to make the example simpler and faster to run:

[3]:
Cube(DATACUBE).info()
[INFO] 800 x 100 x 200 Cube (UDF10-small/DATACUBE_UDF-10-small.fits)
[INFO] .data(800 x 100 x 200) (1e-20 erg / (Angstrom cm2 s)), .var(800 x 100 x 200)
[INFO] center:(-27:47:05.8675,03:32:39.6074) size:(20.000",40.000") step:(0.200",0.200") rot:-0.0 deg frame:FK5
[INFO] wavelength: min:5000.00 max:5998.75 step:1.25 Angstrom

And it contains the FSF information:

[4]:
from mpdaf.MUSE import FSFModel

fsfmodel = FSFModel.read(DATACUBE)
fsfmodel.to_header()
[4]:
FSFMODE = 'MOFFAT1 '           / Old model with a fixed beta
FSF00BET=                  2.8
FSF00FWA=                0.831
FSF00FWB=           -3.007E-05

Create the ORIGIN object

[5]:
orig = ORIGIN.init(DATACUBE, name=NAME, loglevel='DEBUG', logcolor=True)
INFO: Step 00 - Initialization (ORIGIN v3.2.dev168+g37122b7.d20190716)
INFO: Read the Data Cube UDF10-small/DATACUBE_UDF-10-small.fits
INFO: Compute FSFs from the datacube FITS header keywords
INFO: mean FWHM of the FSFs = 3.33 pixels
INFO: 00 Done

The logging level can be modified with the set_loglevel method:

[6]:
orig.set_loglevel('INFO')

Step01 - Preprocessing

Now let’s run the first which subtract the continuum with a DCT, standardize the cube, and creates a segmentation map.

Note that there are progress bar but they are not rendered in the HTML version.

[7]:
orig.step01_preprocessing()
INFO: Step 01 - Preprocessing
INFO: DCT computation

INFO: Data standardizing
INFO: Std signal saved in self.cube_std and self.ima_std
INFO: Compute local maximum of std cube values
INFO: Save self.cube_local_max/self.cube_local_min from max/min correlations
INFO: DCT continuum saved in self.cont_dct and self.ima_dct
INFO: Segmentation based on the continuum
INFO: Found 26 regions, threshold=1.28
INFO: Segmentation based on the residual
INFO: Found 16 regions, threshold=0.46
INFO: Merging both maps
INFO: Segmap saved in self.segmap_merged (35 regions)
INFO: 01 Done - 9.62 sec.

This produces several MPDAF Image and Cube objects: ima_dct is the continuum image estimated with the DCT, and ima_std is the image from the standardized cube.

[8]:
orig.ima_white, orig.ima_dct, orig.ima_std
[8]:
(<Image(shape=(100, 200), unit='1e-20 erg / (Angstrom cm2 s)', dtype='float64')>,
 <Image(shape=(100, 200), unit='', dtype='float64')>,
 <Image(shape=(100, 200), unit='', dtype='float64')>)
[9]:
fig, axes = plt.subplots(1, 3, sharex=True, sharey=True, figsize=(21, 4))
images = [orig.ima_white, orig.ima_dct, orig.ima_std]
titles = ['white image', 'cont image (dct)', 'std image: (raw-dct)/std']
for ax, im, title in zip(axes.flat, images, titles):
    im.plot(ax=ax, title=title, zscale=True)
_images/example_17_0.png

This step also produced two segmentation maps which will be useful in the following steps:

[10]:
orig.plot_segmaps(figsize=(7, 4))
_images/example_19_0.png

Step02: Define areas for PCA

This step computes areas which will be used to dispatch the PCA computation on multiple processes. Here for the example we use a small size for areas, but for a normal cube the default setting (minsize=100) is more reasonable.

[11]:
orig.step02_areas(minsize=50, maxsize=100)
INFO: Step 02 - Areas creation
INFO: First segmentation of 2^2 square
INFO: Save the map of areas in self.areamap
INFO: 4 areas generated
INFO: 02 Done - 0.20 sec.
[12]:
orig.plot_areas()
_images/example_23_0.png

Step03: PCA threshold

Now we compute the thresholds for the PCA, for each area.

[13]:
orig.step03_compute_PCA_threshold(pfa_test=0.01)
INFO: Step 03 - PCA threshold computation
INFO: Area 1, estimation mean/std/threshold: 0.396939/0.032494/0.472532
INFO: Area 2, estimation mean/std/threshold: 0.380288/0.023576/0.435133
INFO: Area 3, estimation mean/std/threshold: 0.412613/0.035166/0.494422
INFO: Area 4, estimation mean/std/threshold: 0.397165/0.028599/0.463696
INFO: 03 Done - 0.13 sec.
[14]:
fig = plt.figure(figsize=(15, 4))
orig.plot_step03_PCA_threshold(fig=fig, xlim=(0.3, 0.5), ncol=4)
_images/example_27_0.png

Step04: Compute PCA

Loop on each area and compute the greedy PCA.

[15]:
orig.step04_compute_greedy_PCA()
INFO: Step 04 - Greedy PCA computation
INFO:    - List of threshold = 0.47 0.44 0.49 0.46
INFO: Compute greedy PCA on each zone

INFO: Save the faint signal in self.cube_faint
INFO: Save numbers of iterations used by testO2 for each spaxel in self.mapO2
INFO: 04 Done - 2.63 sec.
[16]:
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 4))
orig.plot_mapPCA(ax=ax1)
ima_faint = orig.cube_faint.max(axis=0)
ima_faint.plot(ax=ax2, colorbar='v',zscale=True, title='White image for cube_faint');
_images/example_30_0.png

Saving and reloading the session

ORIGIN keeps all intermediate results in memory, as attributes of the ORIGIN object. Saving the session will write these objects to disk and unload them which can be useful to free some memory. When reloading the session ORIGIN loads only the attribute that are needed.

[17]:
orig.write()
INFO: Writing...
INFO: Current session saved in ./UDF10-example
[18]:
orig = ORIGIN.load(NAME)
INFO: Step 00 - Initialization (ORIGIN v3.2.dev168+g37122b7.d20190716)
INFO: Read the Data Cube UDF10-small/DATACUBE_UDF-10-small.fits
INFO: Compute FSFs from the datacube FITS header keywords
INFO: mean FWHM of the FSFs = 3.33 pixels
INFO: 00 Done
[19]:
orig.status()
- 01, preprocessing: DUMPED
- 02, areas: DUMPED
- 03, compute_PCA_threshold: DUMPED
- 04, compute_greedy_PCA: DUMPED
- 05, compute_TGLR: NOTRUN
- 06, compute_purity_threshold: NOTRUN
- 07, detection: NOTRUN
- 08, compute_spectra: NOTRUN
- 09, clean_results: NOTRUN
- 10, create_masks: NOTRUN
- 11, save_sources: NOTRUN

Step05: Compute Correlations

Computes the spatial correlation with the FSF and the spectral correlation with the profiles from the dictionary, keeping only the maximum and minimum correlations.

[20]:
pcut = 1e-08

orig.step05_compute_TGLR(ncpu=1, pcut=pcut)
orig.write()
INFO: Step 05 - GLR test
INFO: Correlation
INFO: Load dictionary of spectral profile /home/simon/dev/muse-origin/muse_origin/Dico_3FWHM.fits
INFO: Step 1/3 and 2/3: Spatial convolution of weighted data with the zero-mean FSF, Computing Spatial part of the norm of the 3D atoms

INFO: Step 3/3 Computing second cube of correlation values

INFO: Save the TGLR value in self.cube_correl
INFO: Save the number of profile associated to the TGLR in self.cube_profile
INFO: Save the map of maxima in self.maxmap
INFO: Compute p-values of local maximum of correlation values
INFO: Save self.cube_local_max from max correlations
INFO: Save self.cube_local_min from min correlations
INFO: 05 Done - 11.57 sec.
INFO: Writing...
INFO: Current session saved in /home/simon/dev/muse-origin-work/UDF10-example
[21]:
fig, (ax1, ax2) = plt.subplots(1,2,figsize=(14, 4))
orig.maxmap.plot(ax=ax1, title='maxmap', cmap='Spectral_r')
(-1*orig.minmap).plot(ax=ax2, title='minmap', cmap='Spectral_r');
_images/example_37_0.png

Step06: Compute detection threshold

Find the thresholds for a given purity.

[23]:
orig.step06_compute_purity_threshold(purity=0.8, purity_std=0.95)
INFO: Step 06 - Compute Purity threshold
INFO: Estimation of threshold with purity = 0.80
INFO: using only background pixels (83.4%)

INFO: Interpolated Threshold 4.61 Detection 30 for Purity 0.80
INFO: Threshold: 4.61
INFO: Estimation of threshold std with purity = 0.95

INFO: Interpolated Threshold 3.50 Detection 8 for Purity 0.95
INFO: Threshold: 3.50
INFO: 06 Done - 0.50 sec.

We can plot the purity to see how it was computed. Note that here the plot is noisy because of the small field size, which means that we don’t have enough statistics.

[24]:
fig, (ax1, ax2) = plt.subplots(1,2,figsize=(14, 4))
orig.plot_purity(ax=ax1)
orig.plot_purity(ax=ax2, comp=True)
_images/example_41_0.png

We can also look at the histograms of local maxima and minima:

[25]:
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 4), sharey=True, sharex=True)
orig.plot_min_max_hist(ax=ax1)
orig.plot_min_max_hist(ax=ax2, comp=True)
_images/example_43_0.png

Step07: Detection

Build the catalog of detections using the thresholds computed above (it is also possible to pass thresholds as arguments).

[26]:
orig.threshold_correl, orig.threshold_std
[26]:
(4.6122018469052914, 3.5039276373749044)
[27]:
orig.step07_detection()
INFO: Step 07 - Thresholding and spatio-spectral merging
INFO: Thresholding correl (>4.61)
INFO: 32 detected lines
INFO: Thresholding std (>3.50)
INFO: 8 detected lines
INFO: kept 5 lines from std after filtering
INFO: Using segmap_cont with an additional deblending step
INFO: Spatio-spectral merging...
INFO: Purity estimation
INFO: Save the catalog in self.Cat1 (34 [+0] sources, 37 [+5] lines)
INFO: 07 Done - 0.78 sec.

We get two catalogs if the individual line detections and the matched detections, with their position and detection score.

  • Cat0 : The catalog with all detections (correl and comp).

  • Cat1 : The catalog with filtered and matched detections.

[28]:
orig.Cat1
[28]:
Table length=37
IDradeclbdax0y0z0compSTDT_GLRprofileseg_labelimatchimatch2purity
int64float64float64float64int64int64int64int64float64float64int64int64int64int64float64
153.1648108850977-27.7857687382913885025.010335200nan4.6315110.831
253.1712788889-27.784768888858145030.0053240nan5.3410221.000
353.1683903263454-27.7834910810576655202.546761620nan5.1610331.000
453.16845312984622-27.783157749018065261.2545822090nan5.7110441.000
553.16455979661396-27.784213170828695345.0107632760nan4.8410551.000
653.16236178503014-27.786379713788245367.5142242940nan6.3910661.000
753.16054066993131-27.786546251626085422.5171213380nan8.09229771.000
853.16493650656938-27.7852687440856065425.0101443400nan5.70110881.000
953.164999369812364-27.7841020802818055431.25100653450nan6.4310991.000
1053.16072914598064-27.7856573771869155435.0168373480nan4.620010100.816
.............................................
2553.17077652377746-27.7848799990607135791.258516330nan7.201025251.000
2653.169897375636815-27.7856022153208855816.2522386530nan4.771026260.963
2753.17071371571987-27.7872688877059285818.75986550nan4.730027270.872
2853.1651248941619-27.7852687525581675833.7598446670nan4.852028281.000
2953.165752849981-27.785324334510275888.7588437110nan4.761029290.954
3053.16895544783517-27.7849910916513565896.2537497170nan6.161030301.000
3153.16625510934304-27.7876576869071925915.08017320nan5.5112331311.000
3253.16600415215225-27.7828798998503045938.7584877510nan16.091032321.000
3353.1649364482374-27.7862687440783035298.751012623913.52nan0033331.000
3453.17033695092634-27.7852688856638755537.5154443017.94nan0834341.000
[29]:
cat0 = Catalog(orig.Cat1[orig.Cat1['comp']==0])
cat1 = Catalog(orig.Cat1[orig.Cat1['comp']==1])

fig,(ax1, ax2) = plt.subplots(1,2,figsize=(20,10))

orig.maxmap.plot(ax=ax1, zscale=True, colorbar='v', cmap='gray', scale='asinh', title='maxmap')
orig.ima_white.plot(ax=ax2, zscale=True, colorbar='v', cmap='gray', scale='asinh', title='white image')

for ax in (ax1, ax2):
    cat0.plot_symb(ax, orig.maxmap.wcs, ecol='g', esize=1.0, ra='ra', dec='dec')
    if len(cat1) > 0:
        cat1.plot_symb(ax, orig.maxmap.wcs, ecol='r', esize=1.0, ra='ra', dec='dec')
_images/example_50_0.png

Use of the segmentation map

During the lines matching step, a segmentation map is used to know if the detected lines belong to a bright sources or not. For lines in a bright source area the matching of lines is more extended to avoid having multiple sources detected in these areas.

The consequence of this is that a good segmentation map is needed. By default a segmentation map is computed with photutils, and it is also possible to provide one (see below).

[30]:
from photutils.utils.colormaps import random_cmap

cmap = random_cmap(ncolors=len(np.unique(orig.segmap_label._data)))
cmap.colors[0] = (0.0, 0.0, 0.0)

orig.segmap_label.plot(cmap=cmap, title='segmentation map');
_images/example_52_0.png

Create a custom segmentation map

[31]:
from muse_origin import compute_deblended_segmap
[32]:
IMAGE = 'UDF10-small/IMAGE_UDF-10-small.fits'
im = Image(IMAGE)
[33]:
segmap = compute_deblended_segmap(im, fwhm=3)
INFO: Background Median -0.01 RMS 0.03 Threshold 0.09
[34]:
SEGMAP = 'UDF10-small/udf10-segmap-small.fits'
segmap.write(SEGMAP)
[35]:
cmap = random_cmap(ncolors=len(np.unique(segmap._data)))
cmap.colors[0] = (0.0, 0.0, 0.0)

fig, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(14, 4))
im.plot(ax=ax1, title='White image', zscale=True)
segmap.plot(ax=ax2, title='Segmentation map', cmap=cmap);
_images/example_58_0.png
[36]:
orig.step07_detection(segmap=SEGMAP)
orig.write()
INFO: Step 07 - Thresholding and spatio-spectral merging
INFO: Thresholding correl (>4.61)
INFO: 32 detected lines
INFO: Thresholding std (>3.50)
INFO: 8 detected lines
INFO: kept 5 lines from std after filtering
INFO: Overriding segmap_cont with the given one
INFO: Spatio-spectral merging...
INFO: Purity estimation
INFO: Save the catalog in self.Cat1 (34 [+0] sources, 37 [+5] lines)
INFO: 07 Done - 0.25 sec.
INFO: Writing...
INFO: Current session saved in /home/simon/dev/muse-origin-work/UDF10-example
[37]:
cat0 = Catalog(orig.Cat1[orig.Cat1['comp']==0])
cat1 = Catalog(orig.Cat1[orig.Cat1['comp']==1])

fig,(ax1, ax2) = plt.subplots(1,2,figsize=(20,10))

orig.maxmap.plot(ax=ax1, zscale=True, colorbar='v', cmap='gray', scale='asinh')
orig.ima_white.plot(ax=ax2, zscale=True, colorbar='v', cmap='gray', scale='asinh')

for ax in (ax1, ax2):
    cat0.plot_symb(ax, orig.maxmap.wcs, ecol='g', esize=1.0, ra='ra', dec='dec')
    if len(cat1) > 0:
        cat1.plot_symb(ax, orig.maxmap.wcs, ecol='r', esize=1.0, ra='ra', dec='dec')
_images/example_60_0.png
[38]:
orig.status()
- 01, preprocessing: DUMPED
- 02, areas: DUMPED
- 03, compute_PCA_threshold: DUMPED
- 04, compute_greedy_PCA: DUMPED
- 05, compute_TGLR: DUMPED
- 06, compute_purity_threshold: DUMPED
- 07, detection: DUMPED
- 08, compute_spectra: NOTRUN
- 09, clean_results: NOTRUN
- 10, create_masks: NOTRUN
- 11, save_sources: NOTRUN

Step08: Compute Spectra

Compute the estimated emission line and the optimal coordinates.

[39]:
orig.step08_compute_spectra()
INFO: Step 08 - Lines estimation

INFO: Save the updated catalog in self.Cat2 (37 lines)
INFO: Save estimated spectrum of each line in self.spectra
INFO: 08 Done - 2.64 sec.

Step09: Clean results

This step cleans the results of ORIGIN and create the final catalogs (see below).

[40]:
orig.step09_clean_results()
INFO: Step 09 - Results cleaning


INFO: Save the unique source catalog in self.Cat3_sources (34 sources)
INFO: Save the cleaned lines in self.Cat3_lines (37 lines)
INFO: 1 lines were merged in nearby lines
INFO: 09 Done - 0.98 sec.

Step10: Create masks

[41]:
orig.step10_create_masks()
INFO: Step 10 - Mask creation
WARNING: Source 7 mask can't be done with size 25 px at step 1. Trying with 37 px.
WARNING: Source 14 mask can't be done with size 25 px at step 1. Trying with 37 px.
WARNING: Source 16 mask can't be done with size 25 px at step 1. Trying with 37 px.
WARNING: Source 19 mask can't be done with size 25 px at step 1. Trying with 37 px.
WARNING: Source 20 mask can't be done with size 25 px at step 1. Trying with 37 px.
WARNING: Source 28 mask can't be done with size 25 px at step 1. Trying with 37 px.

INFO: 10 Done - 1.24 sec.
[42]:
orig.write()
INFO: Writing...
INFO: Current session saved in /home/simon/dev/muse-origin-work/UDF10-example

Step11: Create sources

[43]:
orig = ORIGIN.load(NAME)
INFO: Step 00 - Initialization (ORIGIN v3.2.dev168+g37122b7.d20190716)
INFO: Read the Data Cube UDF10-small/DATACUBE_UDF-10-small.fits
INFO: Compute FSFs from the datacube FITS header keywords
INFO: mean FWHM of the FSFs = 3.33 pixels
INFO: 00 Done
[44]:
orig.step11_save_sources('0.1')
INFO: Step 11 - Save sources
INFO: Writing...
INFO: Current session saved in /home/simon/dev/muse-origin-work/UDF10-example
WARNING: VerifyWarning: Card is too long, comment will be truncated. [astropy.io.fits.card]

INFO: Create the final catalog...
[INFO] Building catalog from path /home/simon/dev/muse-origin-work/UDF10-example/sources
 100%INFO: 11 Done - 31.68 sec.
[45]:
orig.write()
INFO: Writing...
INFO: Current session saved in /home/simon/dev/muse-origin-work/UDF10-example

Summary

[46]:
orig.status()
- 01, preprocessing: DUMPED
- 02, areas: DUMPED
- 03, compute_PCA_threshold: DUMPED
- 04, compute_greedy_PCA: DUMPED
- 05, compute_TGLR: DUMPED
- 06, compute_purity_threshold: DUMPED
- 07, detection: DUMPED
- 08, compute_spectra: DUMPED
- 09, clean_results: DUMPED
- 10, create_masks: DUMPED
- 11, save_sources: DUMPED

Detection statistics:

[47]:
orig.stat()
INFO: ORIGIN PCA pfa 0.01 Back Purity: 0.80 Threshold: 4.61 Bright Purity 0.95 Threshold 3.50
INFO: Nb of detected lines: 37
INFO: Nb of sources Total: 34 Background: 25 Cont: 9
INFO: Nb of sources detected in faint (after PCA): 30 in std (before PCA): 4

Computation time:

[48]:
orig.timestat()
INFO: step01_preprocessing executed: 2019-07-17T12:54:15.800018 run time: 0:00:09.618713
INFO: step02_areas executed: 2019-07-17T12:54:17.203380 run time: 0:00:00.198090
INFO: step03_compute_PCA_threshold executed: 2019-07-17T12:54:17.573866 run time: 0:00:00.128114
INFO: step04_compute_greedy_PCA executed: 2019-07-17T12:54:20.868338 run time: 0:00:02.628998
INFO: step05_compute_TGLR executed: 2019-07-17T12:54:36.129974 run time: 0:00:11.569625
INFO: step06_compute_purity_threshold executed: 2019-07-17T12:56:04.902311 run time: 0:00:00.498243
INFO: step07_detection executed: 2019-07-17T12:56:10.443848 run time: 0:00:00.247567
INFO: step08_compute_spectra executed: 2019-07-17T12:56:14.313520 run time: 0:00:02.641411
INFO: step09_clean_results executed: 2019-07-17T12:56:15.306764 run time: 0:00:00.984085
INFO: step10_create_masks executed: 2019-07-17T12:56:16.558158 run time: 0:00:01.240162
INFO: step11_save_sources executed: 2019-07-17T12:56:48.875564 run time: 0:00:31.680841
INFO: *** Total run time: 0:01:01.435850

Final catalogs

Step 9 creates two catalogs, Cat3_sources which is the final catalog with the detected sources, and Cat3_lines with all the detected lines:

[49]:
orig.Cat3_sources
[49]:
Table length=34
IDradecxyn_linesseg_labelcompline_merged_flagfluxSTDnsigSTDT_GLRnsigTGLRpurity
int64float64float64float64float64int64int64int64boolfloat64float64float64float64float64float64
153.165-27.786103.035.0190False54.5nannan4.635.640.831
253.171-27.7850.053.0100False197.5nannan5.346.501.000
353.168-27.78346.076.0100False76.9nannan5.166.281.000
453.168-27.78344.9999999999999982.0100False91.9nannan5.716.961.000
553.165-27.784107.063.00000000000001100False67.5nannan4.845.891.000
653.162-27.786142.024.0100False121.5nannan6.397.781.000
753.161-27.787171.021.01300False172.7nannan8.099.851.000
853.165-27.785101.044.01150False123.0nannan5.706.941.000
953.165-27.784100.065.0100False106.6nannan6.437.831.000
1053.161-27.786168.037.0100False-17.3nannan4.625.630.816
.............................................
2553.171-27.7858.40441546576220251.0201False272.2nannannannan1.000
2653.170-27.78622.038.0100False72.6nannan4.775.800.963
2753.171-27.7879.08.0100False35.7nannan4.735.760.872
2853.165-27.78598.0000000000000143.99999999999999100False93.3nannan4.855.911.000
2953.166-27.78588.042.99999999999999100False111.4nannan4.765.790.954
3053.169-27.78537.0000000000000149.0100False227.9nannan6.167.511.000
3153.166-27.78880.01.0110False45.4nannan5.516.701.000
3253.166-27.78384.087.0100False298.4nannan16.0919.591.000
3353.165-27.786101.026.0101False34.43.525.55nannan1.000
3453.170-27.78514.99999999999999844.01131False185.67.9412.53nannan1.000
[50]:
orig.Cat3_lines
[50]:
Table length=37
IDradeclbdaxx0yy0zz0compresidualfluxnum_lineSTDT_GLRprofileseg_labelimatchimatch2purityline_merged_flagmerged_innsigTGLRnsigSTD
int64float64float64float64int64int64int64int64int64int64int64float64float64int64float64float64int64int64int64int64float64boolint64float64float64
153.165-27.7865025.001031033535202000.73454.51nan4.6319110.831False-99995.64nan
253.171-27.7855030.00005353242400.578197.52nan5.3410221.000False-99996.50nan
353.168-27.7835201.254646767616116200.84376.93nan5.1610331.000False-99996.28nan
453.168-27.7835260.004545828220820900.62791.94nan5.7110441.000False-99996.96nan
553.165-27.7845343.75107107636327527600.73867.55nan4.8410551.000False-99995.89nan
653.162-27.7865367.50142142242429429400.618121.56nan6.3910661.000False-99997.78nan
753.161-27.7875422.50171171212133833800.376172.77nan8.09230771.000False-99999.85nan
853.165-27.7855425.00101101444434034000.567123.08nan5.70115881.000False-99996.94nan
953.165-27.7845431.25100100656534534500.451106.69nan6.4310991.000False-99997.83nan
1053.161-27.7865435.00168168373734834800.594-17.310nan4.620010100.816False-99995.63nan
...........................................................................
2553.171-27.7855791.2588515163363300.428272.228nan7.201025251.000False-99998.77nan
2653.170-27.7865815.002222383865265300.65372.629nan4.771026260.963False-99995.80nan
2753.171-27.7875817.50998865465500.62235.730nan4.730027270.872False-99995.76nan
2853.165-27.7855833.759898444466766700.78093.331nan4.852028281.000False-99995.91nan
2953.166-27.7855888.758888434371171100.658111.432nan4.761029290.954False-99995.79nan
3053.169-27.7855897.503737494971871700.462227.933nan6.161030301.000False-99997.51nan
3153.166-27.7885913.7580801173173200.88545.434nan5.511131311.000False-99996.70nan
3253.166-27.7835936.258484878774975100.210298.435nan16.091032321.000False-999919.59nan
3353.165-27.7865298.75101101262623923910.85234.4363.52nan0033331.000False-9999nan5.55
3453.170-27.7855537.501515444443043010.482185.6377.94nan01334341.000False-9999nan12.53

Sources

Step 11 creates MPDAF Source files, which gather all the information for each source:

[51]:
from mpdaf.sdetect import Source
[52]:
ls UDF10-example/sources
source-00001.fits  source-00010.fits  source-00019.fits  source-00028.fits
source-00002.fits  source-00011.fits  source-00020.fits  source-00029.fits
source-00003.fits  source-00012.fits  source-00021.fits  source-00030.fits
source-00004.fits  source-00013.fits  source-00022.fits  source-00031.fits
source-00005.fits  source-00014.fits  source-00023.fits  source-00032.fits
source-00006.fits  source-00015.fits  source-00024.fits  source-00033.fits
source-00007.fits  source-00016.fits  source-00025.fits  source-00034.fits
source-00008.fits  source-00017.fits  source-00026.fits
source-00009.fits  source-00018.fits  source-00027.fits
[53]:
orig.Cat3_sources.sort('n_lines')
[54]:
orig.Cat3_sources[-3:]
[54]:
Table length=3
IDradecxyn_linesseg_labelcompline_merged_flagfluxSTDnsigSTDT_GLRnsigTGLRpurity
int64float64float64float64float64int64int64int64boolfloat64float64float64float64float64float64
1453.164-27.783118.082.0100False107.2nannan4.765.800.960
2553.171-27.7858.40441546576220251.0201False272.2nannannannan1.000
1553.163-27.787125.2382239162716219.238223916271636261True557.2nannannannan1.000
[55]:
src = Source.from_file('UDF10-example/sources/source-00015.fits')
[56]:
src.info()
[INFO] ID      =                   15 / object ID %d
[INFO] RA      =     53.1634143468692 / RA u.degree %.7f
[INFO] DEC     =   -27.78664432046939 / DEC u.degree %.7f
[INFO] FROM    = 'ORIGIN  '           / detection software
[INFO] FROM_V  = '3.2.dev168+g37122b7.d20190716' / version of the detection software
[INFO] CUBE    = 'DATACUBE_UDF-10-small.fits' / datacube
[INFO] CUBE_V  = '1.0b1   '           / version of the datacube
[INFO] SRC_V   = '0.1     '           / Source version
[INFO] SRC_TS  = '2019-07-17T12:56:17.396584' / Timestamp of the source creation
[INFO] CAT3_TS = '2019-07-17T12:56:14.400207' / Timestamp of the catalog creation
[INFO] OR_X    =    125.2382239162716 / x position in pixels
[INFO] OR_Y    =    19.23822391627164 / y position in pixels
[INFO] OR_SEG  =                    6 / Label in the segmentation map
[INFO] OR_V    = '3.2.dev168+g37122b7.d20190716' / ORIGIN version
[INFO] OR_FLUX =    557.1857579038542 / flux maximum in all lines
[INFO] OR_PMAX =                  1.0 / maximum purity in all lines
[INFO] OR_PROF = '/home/simon/dev/muse-origin/muse_origin/Dico_3FWHM.fits' / OR input,
[INFO] OR_FSF  = 'MOFFAT1 '           / OR input, FSF cube
[INFO] OR_THL00=                 0.47 / OR input threshold per area
[INFO] OR_THL01=                 0.44 / OR input threshold per area
[INFO] OR_THL02=                 0.49 / OR input threshold per area
[INFO] OR_THL03=                 0.46 / OR input threshold per area
[INFO] OR_NA   =                    4 / OR number of areas
[INFO] OR_DCT  =                   10 / OR input, DCT order
[INFO] OR_PFAA =                  0.2 / OR input, PFA used to create the area map
[INFO] OR_SIZA =                  100 / OR input, maximum area size in pixels
[INFO] OR_MSIZA=                   50 / OR input, minimum area size in pixels
[INFO] OR_PFAT =                 0.01 / OR input, PFA test
[INFO] OR_FBG  =                   50 / OR input: fraction of spectra estimated
[INFO] OR_ITMAX=                  100 / OR input, maximum number of iterations
[INFO] OR_NG   =                    3 / OR input, connectivity size
[INFO] OR_DXY  =                    3 / OR input, spatial tolerance for merging (pix)
[INFO] OR_DZ   =                    5 / OR input, spectral tolerance for merging (pix)
[INFO] OR_NXZ  =                    0 / OR input, grid Nxy
[INFO] COMP_CAT=                    1 / 1/0 (1=Pre-detected in STD, 0=detected in CORRE
[INFO] OR_TH   =                  3.5 / OR input, threshold
[INFO] OR_PURI =                 0.95 / OR input, purity
[INFO] FSFMODE = 'MOFFAT1 '           / Old model with a fixed beta
[INFO] FSF00BET=                  2.8
[INFO] FSF00FWA=                0.831
[INFO] FSF00FWB=           -3.007E-05
[INFO] REFSPEC = 'ORI_CORR_16_SKYSUB'
[INFO] FORMAT  = '0.6     '           / Version of the Source format
[INFO] HISTORY [0.1] Source created with ORIGIN ( 2019-07-17)
[INFO] 14 spectra: MUSE_SKY MUSE_TOT_SKYSUB MUSE_WHITE_SKYSUB MUSE_TOT MUSE_WHITE ORI_CORR MUSE_PSF_SKYSUB MUSE_PSF ORI_SPEC_16 ORI_CORR_16_SKYSUB ORI_CORR_16 ORI_SPEC_15 ORI_CORR_15_SKYSUB ORI_CORR_15
[INFO] 10 images: MUSE_WHITE ORI_MAXMAP ORI_MASK_OBJ ORI_MASK_SKY ORI_SEGMAP_LABEL ORI_SEGMAP_MERGED NB_LINE_16 ORI_CORR_16 NB_LINE_15 ORI_CORR_15
[INFO] 2 cubes: MUSE_CUBE ORI_SNCUBE
[INFO] 3 tables: ORI_CAT ORI_LINES NB_PAR
[INFO] 2 lines
[57]:
nimg = len(src.images)
ncols = 5
nrows = nimg // ncols + min(1, nimg % ncols)
nrows, ncols
[57]:
(2, 5)
[58]:
fig, axes = plt.subplots(nrows, ncols, figsize=(3*ncols,3*nrows), sharex=True, sharey=True)
for ax, (name, im) in zip(axes.flat, src.images.items()):
    im.plot(ax=ax, title=name, show_xlabel=False, show_ylabel=False)
for i in range(nrows*ncols, nimg, -1):
    axes.flat[i - 1].axis('off')
_images/example_92_0.png
[59]:
plt.figure(figsize=(15,5))
for name, sp in src.spectra.items():
    sp.plot(label=name)
plt.legend(loc='upper left', bbox_to_anchor=(1,1));
_images/example_93_0.png