X-ray observations of a sample of clusters selected from eFEDS
This case study searches for X-ray observations of the eFEDS sample of galaxy clusters, and is intended to show how DAXA missions can be used to create multi-mission archives of data for large samples of objects; this case study would apply just as well to any type of X-ray source. The clusters we use will all have eFEDS observations, as they were selected from that survey, but many should also have serendipitous XMM and Chandra observations.
Import Statements
[1]:
import numpy as np
import pandas as pd
from astropy.coordinates import SkyCoord
from daxa.mission import XMMPointed, Chandra, eROSITACalPV
from daxa.archive import Archive
Other Tutorials
These case studies are meant to be highly specific examples of how you might acquire data for a particular science case, they do not provide general instruction on how to use DAXA missions or archives. We instead direct you to:
Using DAXA missions - Here we explain what DAXA mission classes are and how to use them to select only the data you need.
Creating a DAXA archive - This explains how to create an archive, load an existing archive, and the various properties and features of DAXA archives.
Processing telescope data - The processing tutorials for different missions are presented here, though there may not yet be processing support for all missions.
Reading through these should give you a good understanding of how DAXA can be used to acquire, organise, and process multi-mission X-ray datasets for your specific use case.
Sample
We read in the sample of galaxy clusters we’ll be searching for observations of - they were selected from the eROSITA Final-Equatorial Depth Survey (eFEDS), and many should have XMM and Chandra observations:
[2]:
samp = pd.read_csv("samp_files/efeds_xray_cluster_candidates.csv")
samp.head(5)
[2]:
| ID | ID_SRC | RA | DEC | EXT_LIKE | DET_LIKE | z | z_type | T_300kpc | T_300kpc_L | ... | L_500kpc_L | L_500kpc_U | Lbol_500kpc | Lbol_500kpc_L | Lbol_500kpc_U | F_500kpc | F_500kpc_L | F_500kpc_U | SNR_MAX | R_SNR_MAX_ARCMIN | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | eFEDS J082626.6-003429 | 28993 | 126.610799 | -0.574787 | 8.486203 | 5.029723 | 0.161110 | 0 | -1.000000 | -1.000000 | ... | -1.000000e+00 | 3.924900e+42 | -1.000000e+00 | -1.000000e+00 | 1.782000e+43 | -1.000000e+00 | -1.000000e+00 | 6.040400e-14 | 1.32 | 0.8011 |
| 1 | eFEDS J082751.8-002853 | 11248 | 126.965471 | -0.481638 | 12.791595 | 27.865910 | 0.257160 | 0 | -1.000000 | -1.000000 | ... | -1.000000e+00 | 1.061100e+43 | -1.000000e+00 | -1.000000e+00 | 1.796300e+43 | -1.000000e+00 | -1.000000e+00 | 4.903300e-14 | 3.07 | 0.7393 |
| 2 | eFEDS J082808.8-001003 | 4800 | 127.036645 | -0.167715 | 28.492811 | 62.512480 | 0.076155 | 0 | 0.885294 | 0.786329 | ... | 2.339100e+42 | 3.424700e+42 | 4.402300e+42 | 3.640200e+42 | 5.339000e+42 | 1.976100e-13 | 1.624400e-13 | 2.382600e-13 | 8.78 | 2.6312 |
| 3 | eFEDS J082820.6-000721 | 4169 | 127.085556 | -0.122752 | 42.376125 | 81.378350 | 0.844900 | 0 | -1.000000 | -1.000000 | ... | 1.890600e+44 | 2.762200e+44 | 6.207600e+44 | 5.089800e+44 | 8.013600e+44 | 7.796600e-14 | 6.555100e-14 | 8.961400e-14 | 7.30 | 1.4667 |
| 4 | eFEDS J082840.6-000500 | 7991 | 127.169202 | -0.083552 | 18.438711 | 37.515427 | 0.319705 | 0 | -1.000000 | -1.000000 | ... | 1.419400e+43 | 2.065400e+43 | 3.993600e+43 | 3.175500e+43 | 4.931700e+43 | 5.510200e-14 | 4.443600e-14 | 6.466500e-14 | 5.61 | 1.3388 |
5 rows × 34 columns
[3]:
coords = SkyCoord(samp['RA'].values, samp['DEC'].values, unit='deg')
Defining missions
[4]:
er = eROSITACalPV()
xm = XMMPointed()
ch = Chandra()
/Users/dt237/code/DAXA/daxa/mission/xmm.py:83: UserWarning: 140 of the 17697 observations located for this mission have been removed due to NaN RA or Dec values
self._fetch_obs_info()
Searching for observations
We search for observations around the coordinates of our cluster sample - it is worth noting that we are using the default FoV radius/half-width multiplied by a factor of 1.2 as a search radius. You may also set this value yourself, for each instrument individually (for missions like Chandra) or for all instruments, using the search_distance argument and an astropy quantity in units convertible to degrees.
Also, if return_obs_info is set to True, a dataframe is returned from the method to allow the user to link specific ObsIDs to particular entries in our original sample table. The dataframe contains a ‘pos_ind’ column, which contains indexes corresponding to the input positions (i.e. the 4th entry of pos would have index 3), it also contains ObsIDs matched to that coordinate.
[5]:
er_assoc = er.filter_on_positions(coords, return_pos_obs_info=True)
xm_assoc = xm.filter_on_positions(coords, return_pos_obs_info=True)
ch_assoc = ch.filter_on_positions(coords, return_pos_obs_info=True)
/Users/dt237/code/DAXA/daxa/mission/base.py:1095: UserWarning: A field-of-view cannot be easily defined for eROSITACalPV and this number is the approximate half-length of an eFEDS section, the worst case separation - this is unnecessarily large for pointed observations, and you should make your own judgement on a search distance.
fov = self.fov
/Users/dt237/code/DAXA/daxa/mission/base.py:1095: UserWarning: Chandra FoV are difficult to define, as they can be strongly dependant on observation mode; as such take these as very approximate.
fov = self.fov
Exploring the selected data
We can examine the filtered_obs_info property (see the missions tutorial for a fuller explanation):
[6]:
er.filtered_obs_info
[6]:
| ra | dec | ObsID | science_usable | start | end | duration | Field_Name | Field_Type | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 129.55 | 1.5 | 300007 | True | 2019-11-03 02:42:50 | 2019-11-04 03:36:37 | 89627.0 | EFEDS | SURVEY |
| 1 | 133.86 | 1.5 | 300008 | True | 2019-11-04 03:49:16 | 2019-11-05 05:16:39 | 91643.0 | EFEDS | SURVEY |
| 2 | 138.14 | 1.5 | 300009 | True | 2019-11-05 05:29:18 | 2019-11-06 06:40:06 | 90648.0 | EFEDS | SURVEY |
| 3 | 142.45 | 1.5 | 300010 | True | 2019-11-06 07:24:46 | 2019-11-07 08:20:08 | 89722.0 | EFEDS | SURVEY |
[7]:
xm.filtered_obs_info
[7]:
| ra | dec | ObsID | start | science_usable | duration | proprietary_end_date | revolution | proprietary_usable | end | |
|---|---|---|---|---|---|---|---|---|---|---|
| 3629 | 130.198335 | 0.763056 | 0202940101 | 2004-05-08 16:32:31 | True | 0 days 08:03:28 | 2006-03-04 | 808 | True | 2004-05-09 00:35:59 |
| 3630 | 130.198335 | 0.763056 | 0202940201 | 2004-10-26 17:36:30 | True | 0 days 06:28:36 | 2006-03-04 | 894 | True | 2004-10-27 00:05:06 |
| 5137 | 136.602495 | 0.965556 | 0402780801 | 2007-04-20 15:52:25 | True | 0 days 07:33:33 | 2008-05-20 | 1348 | True | 2007-04-20 23:25:58 |
| 7355 | 138.022125 | 0.483667 | 0602340201 | 2009-12-01 01:27:07 | True | 0 days 07:11:13 | 2010-12-17 | 1827 | True | 2009-12-01 08:38:20 |
| 7385 | 138.723585 | 4.442889 | 0602830401 | 2009-11-16 01:38:06 | True | 0 days 02:17:00 | 2010-12-01 | 1820 | True | 2009-11-16 03:55:06 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 17163 | 140.539000 | 3.775000 | 0920001301 | 2023-10-27 11:23:39 | True | 0 days 03:50:00 | 2024-11-13 | 4374 | False | 2023-10-27 15:13:39 |
| 17164 | 140.539000 | 3.775000 | 0920002501 | 2023-10-27 07:26:59 | True | 0 days 03:56:40 | 2024-11-13 | 4374 | False | 2023-10-27 11:23:39 |
| 17166 | 129.890833 | -1.679000 | 0920000901 | 2023-10-29 11:14:11 | True | 0 days 04:46:40 | 2024-11-27 | 4375 | False | 2023-10-29 16:00:51 |
| 17167 | 129.890833 | -1.679000 | 0920002601 | 2023-10-29 07:19:11 | True | 0 days 03:55:00 | 2024-11-27 | 4375 | False | 2023-10-29 11:14:11 |
| 17285 | 139.106000 | 1.385000 | 0920980301 | 2023-11-30 05:12:14 | True | 0 days 12:55:00 | 2024-12-28 | 4391 | False | 2023-11-30 18:07:14 |
113 rows × 10 columns
[8]:
ch.filtered_obs_info
[8]:
| ra | dec | ObsID | science_usable | proprietary_usable | start | end | duration | proprietary_end_date | target_category | instrument | grating | data_mode | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1702 | 136.91667 | -0.69994 | 17084 | True | True | 2015-01-10 00:32:52.999996 | 2015-01-10 16:07:22.999996 | 0 days 15:34:30 | 2016-01-12 | AGN | ACIS-S | NONE | TE_006C8 |
| 2148 | 144.43375 | 2.76094 | 20348 | True | True | 2018-01-22 17:22:56.000004 | 2018-01-23 07:18:06.000004 | 0 days 13:55:10 | 2019-01-23 | NGS | ACIS-S | NONE | TE_005C6 |
| 3684 | 140.94625 | 4.04850 | 23835 | True | True | 2022-05-16 13:22:45.999995 | 2022-05-17 00:28:45.999995 | 0 days 11:06:00 | 2023-05-17 | AGN | ACIS-S | NONE | TE_007F2 |
| 3885 | 137.31625 | 3.91186 | 23162 | True | True | 2020-02-20 03:27:14.999999 | 2020-02-20 14:10:44.999999 | 0 days 10:43:30 | 2021-02-20 | AGN | ACIS-S | NONE | TE_0065E |
| 4605 | 137.86458 | 5.84778 | 14958 | True | True | 2012-12-30 10:27:00.999997 | 2012-12-30 19:54:40.999997 | 0 days 09:27:40 | 2013-12-31 | AGN | ACIS-S | NONE | TE_009C8 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 20574 | 145.23833 | 3.40033 | 11451 | True | True | 2010-01-04 14:03:12.999998 | 2010-01-04 14:39:12.999998 | 0 days 00:36:00 | 2011-01-05 | AGN | ACIS-S | NONE | TE_008FC |
| 20890 | 135.83750 | 4.96056 | 11448 | True | True | 2010-01-04 15:01:54.999999 | 2010-01-04 15:35:44.999999 | 0 days 00:33:50 | 2011-01-05 | AGN | ACIS-S | NONE | TE_008FC |
| 21229 | 143.81125 | 3.59603 | 5705 | True | True | 2005-03-07 04:46:24.000001 | 2005-03-07 05:16:24.000001 | 0 days 00:30:00 | 2006-03-08 | AGN | ACIS-S | NONE | TE_006B0 |
| 21409 | 130.27833 | 3.20189 | 13347 | True | True | 2011-12-11 12:21:05.000000 | 2011-12-11 12:47:05.000000 | 0 days 00:26:00 | 2012-12-12 | AGN | ACIS-S | NONE | TE_0076A |
| 21559 | 137.35000 | 0.03639 | 5703 | True | True | 2004-12-28 09:24:24.999999 | 2004-12-28 09:46:54.999999 | 0 days 00:22:30 | 2005-12-29 | AGN | ACIS-S | NONE | TE_006B0 |
90 rows × 13 columns
We can also use the tables that were returned from the search methods to match observations to specific objects:
[9]:
xm_assoc['name'] = samp.loc[xm_assoc['pos_ind'].values.astype(int), 'ID'].values
xm_assoc
[9]:
| pos_ind | pos_ra | pos_dec | ObsIDs | name | |
|---|---|---|---|---|---|
| 0 | 45 | 129.3486854874346 | 1.40366630348438 | 0903700101 | eFEDS J083723.7+012413 |
| 1 | 47 | 129.48802147587307 | -1.7049345640737046 | 0920001601,0920002401 | eFEDS J083757.2-014217 |
| 2 | 52 | 129.5393896036211 | -2.0807673161720084 | 0920001601,0920002401 | eFEDS J083809.5-020450 |
| 3 | 54 | 129.54957579257595 | -1.9929684395330654 | 0920001601,0920002401 | eFEDS J083812.0-015934 |
| 4 | 56 | 129.5732303438282 | -2.284546510019436 | 0920001601,0920002401 | eFEDS J083817.6-021704 |
| ... | ... | ... | ... | ... | ... |
| 110 | 469 | 141.93603300405417 | 4.941812984556808 | 0901870201,0901871201 | eFEDS J092744.6+045631 |
| 111 | 491 | 142.47325179257808 | 0.4670133405850062 | 0802220601 | eFEDS J092953.6+002801 |
| 112 | 521 | 143.75324046077222 | 0.9047856577567157 | 0920000801,0920002301 | eFEDS J093500.8+005417 |
| 113 | 522 | 143.80457579850201 | 0.7993807870395315 | 0920000801,0920002301 | eFEDS J093513.1+004757 |
| 114 | 523 | 143.8362603912554 | 0.5801534818576921 | 0920000801,0920002301 | eFEDS J093520.7+003448 |
115 rows × 5 columns
[10]:
ch_assoc['name'] = samp.loc[ch_assoc['pos_ind'].values.astype(int), 'ID'].values
ch_assoc
[10]:
| pos_ind | pos_ra | pos_dec | ObsIDs | name | |
|---|---|---|---|---|---|
| 0 | 9 | 127.79401199149834 | 1.9378392793445995 | 19734 | eFEDS J083110.6+015616 |
| 1 | 12 | 127.85804170868693 | 1.925897930055847 | 19734 | eFEDS J083125.9+015533 |
| 2 | 16 | 127.97336088473476 | 1.4252588642845447 | 19734 | eFEDS J083153.6+012531 |
| 3 | 18 | 128.11694107938197 | -0.1156644071035969 | 23614 | eFEDS J083228.1-000656 |
| 4 | 22 | 128.31476848695075 | 0.106508629638464 | 23614 | eFEDS J083315.6+000623 |
| ... | ... | ... | ... | ... | ... |
| 187 | 537 | 144.43405705683216 | 2.760045545939909 | 20348 | eFEDS J093744.2+024536 |
| 188 | 538 | 144.6271718639683 | 4.256395791583636 | 18099 | eFEDS J093830.5+041523 |
| 189 | 539 | 144.909595641361 | 4.371716376951857 | 26035 | eFEDS J093938.3+042218 |
| 190 | 540 | 145.0245934774472 | 3.224725957866028 | 22270,11451 | eFEDS J094005.9+031329 |
| 191 | 541 | 145.03072779231115 | 3.965204479523988 | 26035,22270 | eFEDS J094007.3+035755 |
192 rows × 5 columns
[11]:
er_assoc['name'] = samp.loc[er_assoc['pos_ind'].values.astype(int), 'ID'].values
er_assoc
[11]:
| pos_ind | pos_ra | pos_dec | ObsIDs | name | |
|---|---|---|---|---|---|
| 0 | 0 | 126.61080512258118 | -0.5747925179258094 | 300007 | eFEDS J082626.6-003429 |
| 1 | 1 | 126.96547689559516 | -0.4816435127681215 | 300007 | eFEDS J082751.8-002853 |
| 2 | 2 | 127.03665115606483 | -0.1677211251616217 | 300007 | eFEDS J082808.8-001003 |
| 3 | 3 | 127.08556215338794 | -0.1227575917789436 | 300007 | eFEDS J082820.6-000721 |
| 4 | 4 | 127.1692087960137 | -0.08355838266078222 | 300007 | eFEDS J082840.6-000500 |
| ... | ... | ... | ... | ... | ... |
| 537 | 537 | 144.43406327204823 | 2.7600402745537114 | 300010 | eFEDS J093744.2+024536 |
| 538 | 538 | 144.62717799852624 | 4.256390530427462 | 300010 | eFEDS J093830.5+041523 |
| 539 | 539 | 144.90960176777745 | 4.3717111308643295 | 300010 | eFEDS J093938.3+042218 |
| 540 | 540 | 145.0245996650002 | 3.2247207179507202 | 300010 | eFEDS J094005.9+031329 |
| 541 | 541 | 145.03073393985625 | 3.9651992399385168 | 300010 | eFEDS J094007.3+035755 |
542 rows × 5 columns
Defining an archive
The filtered missions can then be used to define an archive containing the selected data:
[12]:
arch = Archive('eFEDS_clusters', [er, xm, ch])
arch.info()
/Users/dt237/code/DAXA/daxa/archive/base.py:133: UserWarning: The raw data for this mission have already been downloaded.
mission.download()
/Users/dt237/code/DAXA/daxa/archive/base.py:133: UserWarning: Proprietary data have been selected, but no credentials provided; as such the proprietary data have been excluded from download and further processing.
mission.download()
Downloading XMM-Newton Pointed data: 100%|██████████████████████████████████| 100/100 [00:18<00:00, 5.38it/s]
Downloading Chandra data: 100%|███████████████████████████████████████████████| 90/90 [03:01<00:00, 2.02s/it]
-----------------------------------------------------
Number of missions - 3
Total number of observations - 194
Beginning of earliest observation - 1999-11-02 17:31:43.000001
End of latest observation - 2023-02-26 11:24:55.000001
-- eROSITACalPV --
Internal DAXA name - erosita_calpv
Chosen instruments - TM1, TM2, TM3, TM4, TM5, TM6, TM7
Number of observations - 4
Fully Processed - False
-- XMM-Newton Pointed --
Internal DAXA name - xmm_pointed
Chosen instruments - M1, M2, PN
Number of observations - 100
Fully Processed - False
-- Chandra --
Internal DAXA name - chandra
Chosen instruments - ACIS-I, ACIS-S, HRC-I, HRC-S
Number of observations - 90
Fully Processed - False
-----------------------------------------------------