From 896aa6bd3567ed3a3fbf40829d91a79c2d9dfcde Mon Sep 17 00:00:00 2001
From: Allen Downey If you are running this notebook on Colab, you should run the following cell to install the libraries we’ll need. If you are running this notebook on your own computer, you might have to install these libraries yourself. The library we’ll use to get Gaia data is Astroquery.
@@ -425,6 +402,20 @@ Astroquery provides This import statement creates a TAP+ connection; TAP stands for “Table Access Protocol”, which is a network protocol for sending queries to the database and getting back the results. The following So that’s a lot of tables. The ones we’ll use are: Jupyter shows that the result is an object of type To see the metadata, we have to print the object. The following loop prints the names of the columns in the table. You can probably infer what many of these columns are by looking at the names, but you should resist the temptation to guess.
To find out what the columns mean, read the documentation. The result is an object that represents the job running on a Gaia server. If you print it, it displays metadata for the forthcoming results. Don’t worry about However, The Optional detail: Why is Each column has a name, units, and a data type. For example, the units of Installing libraries¶
-# If we're running on Colab, install libraries
-
-import sys
-IN_COLAB = 'google.colab' in sys.modules
-
-if IN_COLAB:
- !pip install astroquery
-
Connecting to Gaia¶
Created TAP+ (v1.2.1) - Connection:
+ Host: gea.esac.esa.int
+ Use HTTPS: True
+ Port: 443
+ SSL Port: 443
+Created TAP+ (v1.2.1) - Connection:
+ Host: geadata.esac.esa.int
+ Use HTTPS: True
+ Port: 443
+ SSL Port: 443
+
+INFO: Retrieving tables... [astroquery.utils.tap.core]
+INFO: Parsing tables... [astroquery.utils.tap.core]
+INFO: Done. [astroquery.utils.tap.core]
+
for loop prints the names of the tables.for table in tables:
print(table.name)
external.apassdr9
+external.gaiadr2_geometric_distance
+external.gaiaedr3_distance
+external.galex_ais
+external.ravedr5_com
+external.ravedr5_dr5
+external.ravedr5_gra
+external.ravedr5_on
+external.sdssdr13_photoprimary
+external.skymapperdr1_master
+external.skymapperdr2_master
+external.tmass_xsc
+public.hipparcos
+public.hipparcos_newreduction
+public.hubble_sc
+public.igsl_source
+public.igsl_source_catalog_ids
+public.tycho2
+public.dual
+tap_config.coord_sys
+tap_config.properties
+tap_schema.columns
+tap_schema.key_columns
+tap_schema.keys
+tap_schema.schemas
+tap_schema.tables
+gaiaedr3.gaia_source
+gaiaedr3.agn_cross_id
+gaiaedr3.commanded_scan_law
+gaiaedr3.dr2_neighbourhood
+gaiaedr3.frame_rotator_source
+gaiaedr3.allwise_best_neighbour
+gaiaedr3.allwise_neighbourhood
+gaiaedr3.apassdr9_best_neighbour
+gaiaedr3.apassdr9_join
+gaiaedr3.apassdr9_neighbourhood
+gaiaedr3.gsc23_best_neighbour
+gaiaedr3.gsc23_join
+gaiaedr3.gsc23_neighbourhood
+gaiaedr3.hipparcos2_best_neighbour
+gaiaedr3.hipparcos2_neighbourhood
+gaiaedr3.panstarrs1_best_neighbour
+gaiaedr3.panstarrs1_join
+gaiaedr3.panstarrs1_neighbourhood
+gaiaedr3.ravedr5_best_neighbour
+gaiaedr3.ravedr5_join
+gaiaedr3.ravedr5_neighbourhood
+gaiaedr3.sdssdr13_best_neighbour
+gaiaedr3.sdssdr13_join
+gaiaedr3.sdssdr13_neighbourhood
+gaiaedr3.skymapperdr2_best_neighbour
+gaiaedr3.skymapperdr2_join
+gaiaedr3.skymapperdr2_neighbourhood
+gaiaedr3.tmass_psc_xsc_best_neighbour
+gaiaedr3.tmass_psc_xsc_join
+gaiaedr3.tmass_psc_xsc_neighbourhood
+gaiaedr3.tycho2tdsc_merge_best_neighbour
+gaiaedr3.tycho2tdsc_merge_neighbourhood
+gaiaedr3.urat1_best_neighbour
+gaiaedr3.urat1_neighbourhood
+gaiaedr3.gaia_source_simulation
+gaiaedr3.gaia_universe_model
+gaiaedr3.tycho2tdsc_merge
+gaiadr1.aux_qso_icrf2_match
+gaiadr1.ext_phot_zero_point
+gaiadr1.allwise_best_neighbour
+gaiadr1.allwise_neighbourhood
+gaiadr1.gsc23_best_neighbour
+gaiadr1.gsc23_neighbourhood
+gaiadr1.ppmxl_best_neighbour
+gaiadr1.ppmxl_neighbourhood
+gaiadr1.sdss_dr9_best_neighbour
+gaiadr1.sdss_dr9_neighbourhood
+gaiadr1.tmass_best_neighbour
+gaiadr1.tmass_neighbourhood
+gaiadr1.ucac4_best_neighbour
+gaiadr1.ucac4_neighbourhood
+gaiadr1.urat1_best_neighbour
+gaiadr1.urat1_neighbourhood
+gaiadr1.cepheid
+gaiadr1.phot_variable_time_series_gfov
+gaiadr1.phot_variable_time_series_gfov_statistical_parameters
+gaiadr1.rrlyrae
+gaiadr1.variable_summary
+gaiadr1.allwise_original_valid
+gaiadr1.gsc23_original_valid
+gaiadr1.ppmxl_original_valid
+gaiadr1.sdssdr9_original_valid
+gaiadr1.tmass_original_valid
+gaiadr1.ucac4_original_valid
+gaiadr1.urat1_original_valid
+gaiadr1.gaia_source
+gaiadr1.tgas_source
+gaiadr2.aux_allwise_agn_gdr2_cross_id
+gaiadr2.aux_iers_gdr2_cross_id
+gaiadr2.aux_sso_orbit_residuals
+gaiadr2.aux_sso_orbits
+gaiadr2.dr1_neighbourhood
+gaiadr2.allwise_best_neighbour
+gaiadr2.allwise_neighbourhood
+gaiadr2.apassdr9_best_neighbour
+gaiadr2.apassdr9_neighbourhood
+gaiadr2.gsc23_best_neighbour
+gaiadr2.gsc23_neighbourhood
+gaiadr2.hipparcos2_best_neighbour
+gaiadr2.hipparcos2_neighbourhood
+gaiadr2.panstarrs1_best_neighbour
+gaiadr2.panstarrs1_neighbourhood
+gaiadr2.ppmxl_best_neighbour
+gaiadr2.ppmxl_neighbourhood
+gaiadr2.ravedr5_best_neighbour
+gaiadr2.ravedr5_neighbourhood
+gaiadr2.sdssdr9_best_neighbour
+gaiadr2.sdssdr9_neighbourhood
+gaiadr2.tmass_best_neighbour
+gaiadr2.tmass_neighbourhood
+gaiadr2.tycho2_best_neighbour
+gaiadr2.tycho2_neighbourhood
+gaiadr2.urat1_best_neighbour
+gaiadr2.urat1_neighbourhood
+gaiadr2.sso_observation
+gaiadr2.sso_source
+gaiadr2.vari_cepheid
+gaiadr2.vari_classifier_class_definition
+gaiadr2.vari_classifier_definition
+gaiadr2.vari_classifier_result
+gaiadr2.vari_long_period_variable
+gaiadr2.vari_rotation_modulation
+gaiadr2.vari_rrlyrae
+gaiadr2.vari_short_timescale
+gaiadr2.vari_time_series_statistics
+gaiadr2.panstarrs1_original_valid
+gaiadr2.gaia_source
+gaiadr2.ruwe
+
@@ -466,6 +602,16 @@ Astroquery provides
Retrieving table 'gaiadr2.gaia_source'
+Parsing table 'gaiadr2.gaia_source'...
+Done.
+
<astroquery.utils.tap.model.taptable.TapTableMeta at 0x7f50edd2aeb0>
+
TapTableMeta, but it does not display the contents.
+TAP Table name: gaiadr2.gaiadr2.gaia_source
+Description: This table has an entry for every Gaia observed source as listed in the
+Main Database accumulating catalogue version from which the catalogue
+release has been generated. It contains the basic source parameters,
+that is only final data (no epoch data) and no spectra (neither final
+nor epoch).
+Num. columns: 96
+
Columns¶
for column in meta.columns:
print(column.name)
solution_id
+designation
+source_id
+random_index
+ref_epoch
+ra
+ra_error
+dec
+dec_error
+parallax
+parallax_error
+parallax_over_error
+pmra
+pmra_error
+pmdec
+pmdec_error
+ra_dec_corr
+ra_parallax_corr
+ra_pmra_corr
+ra_pmdec_corr
+dec_parallax_corr
+dec_pmra_corr
+dec_pmdec_corr
+parallax_pmra_corr
+parallax_pmdec_corr
+pmra_pmdec_corr
+astrometric_n_obs_al
+astrometric_n_obs_ac
+astrometric_n_good_obs_al
+astrometric_n_bad_obs_al
+astrometric_gof_al
+astrometric_chi2_al
+astrometric_excess_noise
+astrometric_excess_noise_sig
+astrometric_params_solved
+astrometric_primary_flag
+astrometric_weight_al
+astrometric_pseudo_colour
+astrometric_pseudo_colour_error
+mean_varpi_factor_al
+astrometric_matched_observations
+visibility_periods_used
+astrometric_sigma5d_max
+frame_rotator_object_type
+matched_observations
+duplicated_source
+phot_g_n_obs
+phot_g_mean_flux
+phot_g_mean_flux_error
+phot_g_mean_flux_over_error
+phot_g_mean_mag
+phot_bp_n_obs
+phot_bp_mean_flux
+phot_bp_mean_flux_error
+phot_bp_mean_flux_over_error
+phot_bp_mean_mag
+phot_rp_n_obs
+phot_rp_mean_flux
+phot_rp_mean_flux_error
+phot_rp_mean_flux_over_error
+phot_rp_mean_mag
+phot_bp_rp_excess_factor
+phot_proc_mode
+bp_rp
+bp_g
+g_rp
+radial_velocity
+radial_velocity_error
+rv_nb_transits
+rv_template_teff
+rv_template_logg
+rv_template_fe_h
+phot_variable_flag
+l
+b
+ecl_lon
+ecl_lat
+priam_flags
+teff_val
+teff_percentile_lower
+teff_percentile_upper
+a_g_val
+a_g_percentile_lower
+a_g_percentile_upper
+e_bp_min_rp_val
+e_bp_min_rp_percentile_lower
+e_bp_min_rp_percentile_upper
+flame_flags
+radius_val
+radius_percentile_lower
+radius_percentile_upper
+lum_val
+lum_percentile_lower
+lum_percentile_upper
+datalink_url
+epoch_photometry_url
+
load_table to get the metadata for this table. How many columns are there and what are their names?
# Solution goes here
+
# Solution
+
+meta2 = Gaia.load_table('gaiadr2.panstarrs1_original_valid')
+print(meta2)
+
+for column in meta2.columns:
+ print(column.name)
+
Retrieving table 'gaiadr2.panstarrs1_original_valid'
+Parsing table 'gaiadr2.panstarrs1_original_valid'...
+Done.
+TAP Table name: gaiadr2.gaiadr2.panstarrs1_original_valid
+Description: The Panoramic Survey Telescope and Rapid Response System (Pan-STARRS) is
+a system for wide-field astronomical imaging developed and operated by
+the Institute for Astronomy at the University of Hawaii. Pan-STARRS1
+(PS1) is the first part of Pan-STARRS to be completed and is the basis
+for Data Release 1 (DR1). The PS1 survey used a 1.8 meter telescope and
+its 1.4 Gigapixel camera to image the sky in five broadband filters (g,
+r, i, z, y).
+
+The current table contains a filtered subsample of the 10 723 304 629
+entries listed in the original ObjectThin table.
+We used only ObjectThin and MeanObject tables to extract
+panstarrs1OriginalValid table, this means that objects detected only in
+stack images are not included here. The main reason for us to avoid the
+use of objects detected in stack images is that their astrometry is not
+as good as the mean objects astrometry: “The stack positions (raStack,
+decStack) have considerably larger systematic astrometric errors than
+the mean epoch positions (raMean, decMean).” The astrometry for the
+MeanObject positions uses Gaia DR1 as a reference catalog, while the
+stack positions use 2MASS as a reference catalog.
+
+In details, we filtered out all objects where:
+
+- nDetections = 1
+
+- no good quality data in Pan-STARRS, objInfoFlag 33554432 not set
+
+- mean astrometry could not be measured, objInfoFlag 524288 set
+
+- stack position used for mean astrometry, objInfoFlag 1048576 set
+
+- error on all magnitudes equal to 0 or to -999;
+
+- all magnitudes set to -999;
+
+- error on RA or DEC greater than 1 arcsec.
+
+The number of objects in panstarrs1OriginalValid is 2 264 263 282.
+
+The panstarrs1OriginalValid table contains only a subset of the columns
+available in the combined ObjectThin and MeanObject tables. A
+description of the original ObjectThin and MeanObjects tables can be
+found at:
+https://outerspace.stsci.edu/display/PANSTARRS/PS1+Database+object+and+detection+tables
+
+Download:
+http://mastweb.stsci.edu/ps1casjobs/home.aspx
+Documentation:
+https://outerspace.stsci.edu/display/PANSTARRS
+http://pswww.ifa.hawaii.edu/pswww/
+References:
+The Pan-STARRS1 Surveys, Chambers, K.C., et al. 2016, arXiv:1612.05560
+Pan-STARRS Data Processing System, Magnier, E. A., et al. 2016,
+arXiv:1612.05240
+Pan-STARRS Pixel Processing: Detrending, Warping, Stacking, Waters, C.
+Z., et al. 2016, arXiv:1612.05245
+Pan-STARRS Pixel Analysis: Source Detection and Characterization,
+Magnier, E. A., et al. 2016, arXiv:1612.05244
+Pan-STARRS Photometric and Astrometric Calibration, Magnier, E. A., et
+al. 2016, arXiv:1612.05242
+The Pan-STARRS1 Database and Data Products, Flewelling, H. A., et al.
+2016, arXiv:1612.05243
+
+Catalogue curator:
+SSDC - ASI Space Science Data Center
+https://www.ssdc.asi.it/
+Num. columns: 26
+obj_name
+obj_id
+ra
+dec
+ra_error
+dec_error
+epoch_mean
+g_mean_psf_mag
+g_mean_psf_mag_error
+g_flags
+r_mean_psf_mag
+r_mean_psf_mag_error
+r_flags
+i_mean_psf_mag
+i_mean_psf_mag_error
+i_flags
+z_mean_psf_mag
+z_mean_psf_mag_error
+z_flags
+y_mean_psf_mag
+y_mean_psf_mag_error
+y_flags
+n_detections
+zone_id
+obj_info_flag
+quality_flag
<astroquery.utils.tap.model.job.Job at 0x7f50edd2adc0>
+
<Table length=10>
+ name dtype unit description n_bad
+--------- ------- ---- ------------------------------------------------------------------ -----
+source_id int64 Unique source identifier (unique within a particular Data Release) 0
+ ra float64 deg Right ascension 0
+ dec float64 deg Declination 0
+ parallax float64 mas Parallax 2
+Jobid: None
+Phase: COMPLETED
+Owner: None
+Output file: sync_20210315090602.xml.gz
+Results: None
+
Results: None. That does not actually mean there are no results.Phase: COMPLETED indicates that the job is complete, so we can get the results like this:astropy.table.table.Table
+
type function indicates that the result is an Astropy Table.table repeated three times? The first is the name of the module, the second is the name of the submodule, and the third is the name of the class. Most of the time we only care about the last one. It’s like the Linnean name for gorilla, which is Gorilla gorilla gorilla.
+
+source_id ra dec parallax
+deg deg mas
+int64 float64 float64 float64
+5887983246081387776 227.978818386372 -53.64996962450103 1.0493172163332998
+5887971250213117952 228.32280834041364 -53.66270726203726 0.29455652682279093
+5887991866047288704 228.1582047014091 -53.454724911639794 -0.5789179941669236
+5887968673232040832 228.07420888099884 -53.8064612895961 0.41030970779603076
+5887979844465854720 228.42547805195946 -53.48882284470035 -0.23379683441525864
+5887978607515442688 228.23831627636855 -53.56328249482688 -0.9252161956789068
+5887978298278520704 228.26015640396173 -53.607284412896476 --
+5887995581231772928 228.12871598211902 -53.373625663608316 -0.3325818206439385
+5887982043490374016 227.985260087594 -53.683444499055575 0.02878111976456593
+5887982971205433856 227.89884570686218 -53.67430215342567 -- ra and dec are degrees, and their data type is float64, which is a 64-bit floating-point number, used to store measurements with a fraction part.
# Solution goes here
+# Solution
+
+# Let's add
+#
+# radial_velocity : Radial velocity (double, Velocity[km/s] )
+#
+# Spectroscopic radial velocity in the solar barycentric
+# reference frame.
+#
+# The radial velocity provided is the median value of the
+# radial velocity measurements at all epochs.
+
+query = """SELECT
+TOP 10
+source_id, ra, dec, parallax, radial_velocity
+FROM gaiadr2.gaia_source
+"""
INFO: Query finished. [astroquery.utils.tap.core]
+<astroquery.utils.tap.model.job.Job at 0x7f50edd40f40>
+And here are the results.
| source_id | ra | dec | parallax | radial_velocity |
|---|---|---|---|---|
| deg | deg | mas | km / s | |
| int64 | float64 | float64 | float64 | float64 |
| 5895270396817359872 | 213.08433715252883 | -56.64104701005694 | 2.041947005434917 | -- |
| 5895272561481374080 | 213.2606587905109 | -56.55044401535715 | 0.15693467895110133 | -- |
| 5895247410183786368 | 213.38479712976664 | -56.97008551185148 | -0.19017525742552605 | -- |
| 5895249226912448000 | 213.41587389088238 | -56.849596577635786 | -- | -- |
| 5895261875598904576 | 213.5508930114549 | -56.61037780154348 | -0.29471722363529257 | -- |
| 5895258302187834624 | 213.87631129557286 | -56.678537259039906 | 0.6468437015289753 | -- |
| 5895247444506644992 | 213.33215109206796 | -56.975347759380995 | 0.390215490234287 | -- |
| 5895259470417635968 | 213.78815034206346 | -56.64585047451594 | 0.953377710788918 | -- |
| 5895264899260932352 | 213.21521027193236 | -56.78420864489118 | -- | -- |
| 5895265925746051584 | 213.17082359534547 | -56.74540885107754 | 0.2986918215101751 | -- |
You might notice that some values of parallax are negative. As this FAQ explains, “Negative parallaxes are caused by errors in the observations.” They have “no physical meaning,” but they can be a “useful diagnostic on the quality of the astrometric solution.”
# Solution goes here
+# Solution
+
+# In this example, the WHERE clause is in the wrong place
+
+query = """SELECT
+TOP 3000
+WHERE parallax < 1
+source_id, ref_epoch, ra, dec, parallax
+FROM gaiadr2.gaia_source
+"""
Read about SQL operators here and then modify the previous query to select rows where bp_rp is between -0.75 and 2.
# Solution goes here
+# Solution
+
+# Here's a solution using > and < operators
+
+query = """SELECT
+TOP 10
+source_id, ref_epoch, ra, dec, parallax
+FROM gaiadr2.gaia_source
+WHERE parallax < 1
+ AND bp_rp > -0.75 AND bp_rp < 2
+"""
+
+# And here's a solution using the BETWEEN operator
+
+query = """SELECT
+TOP 10
+source_id, ref_epoch, ra, dec, parallax
+FROM gaiadr2.gaia_source
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+"""
'SELECT \nTOP 10 \nsource_id, ra, dec, pmra, pmdec\nFROM gaiadr2.gaia_source\nWHERE parallax < 1\n AND bp_rp BETWEEN -0.75 AND 2\n'
+But if you print it, the line breaks appear as… line breaks.
SELECT
+TOP 10
+source_id, ra, dec, pmra, pmdec
+FROM gaiadr2.gaia_source
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+Notice that the format specifier has been replaced with the value of columns.
Let’s run it and see if it works:
@@ -772,6 +1263,23 @@ That’s not required, but it is a common style. +<Table length=10>
+ name dtype unit description
+--------- ------- -------- ------------------------------------------------------------------
+source_id int64 Unique source identifier (unique within a particular Data Release)
+ ra float64 deg Right ascension
+ dec float64 deg Declination
+ pmra float64 mas / yr Proper motion in right ascension direction
+ pmdec float64 mas / yr Proper motion in declination direction
+Jobid: None
+Phase: COMPLETED
+Owner: None
+Output file: sync_20210315091929.xml.gz
+Results: None
+| source_id | ra | dec | pmra | pmdec |
|---|---|---|---|---|
| deg | deg | mas / yr | mas / yr | |
| int64 | float64 | float64 | float64 | float64 |
| 5895272561481374080 | 213.2606587905109 | -56.55044401535715 | 0.3894438898301715 | 1.2299266281737415 |
| 5895261875598904576 | 213.5508930114549 | -56.61037780154348 | 0.16203641364393007 | -4.672602679543312 |
| 5895247444506644992 | 213.33215109206796 | -56.975347759380995 | -7.474003156859284 | -3.538080792097856 |
| 5895259470417635968 | 213.78815034206346 | -56.64585047451594 | -5.287202255231853 | -0.8163762113468646 |
| 5895265925746051584 | 213.17082359534547 | -56.74540885107754 | -7.880749306158471 | -4.8585444120179595 |
| 5895260913525974528 | 213.66936020541976 | -56.66655190442016 | -4.7820929042428215 | -1.5566420086447643 |
| 5895264212062283008 | 213.7755742121852 | -56.51570859067397 | -6.657690998559842 | -1.7616494482071872 |
| 5895253457497979136 | 213.30929960610283 | -56.78849448744587 | -5.242106718924749 | -0.18655636353898095 |
| 4143614130253524096 | 269.1749117455479 | -18.53415139972117 | 2.6164274510804826 | 1.3244248889980894 |
| 4065443904433108992 | 273.26868565443743 | -24.421651815402857 | -1.663096652191022 | -2.6514745376067683 |
Good so far.
Modify query3_base to replace 1 with a format specifier like {max_parallax}. Now, when you call format, add a keyword argument that assigns a value to max_parallax, and confirm that the format specifier gets replaced with the value you provide.
# Solution goes here
+# Solution
+
+query_base = """SELECT
+TOP 10
+{columns}
+FROM gaiadr2.gaia_source
+WHERE parallax < {max_parallax} AND
+bp_rp BETWEEN -0.75 AND 2
+"""
+
+query = query_base.format(columns=columns,
+ max_parallax=0.5)
+print(query)
+
+
+SELECT
+TOP 10
+source_id, ra, dec, pmra, pmdec
+FROM gaiadr2.gaia_source
+WHERE parallax < 0.5 AND
+bp_rp BETWEEN -0.75 AND 2
Download the results of a query and store them in a file.
If you are running this notebook on Colab, you can run the following cell to install the libraries we’ll use.
-If you are running this notebook on your own computer, you might have to install these libraries yourself. See the instructions in the preface.
-# If we're running on Colab, install libraries
-
-# TODO: When Colab can install gala, switch from astro-gala
-
-import sys
-IN_COLAB = 'google.colab' in sys.modules
-
-if IN_COLAB:
- !pip install astroquery astro-gala
-The measurements we will work with are physical quantities, which means that they have two parts, a value and a unit. @@ -394,6 +369,1011 @@ For example, the coordinate \(30^{\ci
['A',
+ 'AA',
+ 'AB',
+ 'ABflux',
+ 'ABmag',
+ 'AU',
+ 'Angstrom',
+ 'B',
+ 'Ba',
+ 'Barye',
+ 'Bi',
+ 'Biot',
+ 'Bol',
+ 'Bq',
+ 'C',
+ 'Celsius',
+ 'Ci',
+ 'CompositeUnit',
+ 'D',
+ 'Da',
+ 'Dalton',
+ 'Debye',
+ 'Decibel',
+ 'DecibelUnit',
+ 'Dex',
+ 'DexUnit',
+ 'EA',
+ 'EAU',
+ 'EB',
+ 'EBa',
+ 'EC',
+ 'ED',
+ 'EF',
+ 'EG',
+ 'EGal',
+ 'EH',
+ 'EHz',
+ 'EJ',
+ 'EJy',
+ 'EK',
+ 'EL',
+ 'EN',
+ 'EOhm',
+ 'EP',
+ 'EPa',
+ 'ER',
+ 'ERy',
+ 'ES',
+ 'ESt',
+ 'ET',
+ 'EV',
+ 'EW',
+ 'EWb',
+ 'Ea',
+ 'Eadu',
+ 'Earcmin',
+ 'Earcsec',
+ 'Eau',
+ 'Eb',
+ 'Ebarn',
+ 'Ebeam',
+ 'Ebin',
+ 'Ebit',
+ 'Ebyte',
+ 'Ecd',
+ 'Echan',
+ 'Ecount',
+ 'Ect',
+ 'Ed',
+ 'Edeg',
+ 'Edyn',
+ 'EeV',
+ 'Eerg',
+ 'Eg',
+ 'Eh',
+ 'EiB',
+ 'Eib',
+ 'Eibit',
+ 'Eibyte',
+ 'Ek',
+ 'El',
+ 'Elm',
+ 'Elx',
+ 'Elyr',
+ 'Em',
+ 'Emag',
+ 'Emin',
+ 'Emol',
+ 'Eohm',
+ 'Epc',
+ 'Eph',
+ 'Ephoton',
+ 'Epix',
+ 'Epixel',
+ 'Erad',
+ 'Es',
+ 'Esr',
+ 'Eu',
+ 'Evox',
+ 'Evoxel',
+ 'Eyr',
+ 'F',
+ 'Farad',
+ 'Fr',
+ 'Franklin',
+ 'FunctionQuantity',
+ 'FunctionUnitBase',
+ 'G',
+ 'GA',
+ 'GAU',
+ 'GB',
+ 'GBa',
+ 'GC',
+ 'GD',
+ 'GF',
+ 'GG',
+ 'GGal',
+ 'GH',
+ 'GHz',
+ 'GJ',
+ 'GJy',
+ 'GK',
+ 'GL',
+ 'GN',
+ 'GOhm',
+ 'GP',
+ 'GPa',
+ 'GR',
+ 'GRy',
+ 'GS',
+ 'GSt',
+ 'GT',
+ 'GV',
+ 'GW',
+ 'GWb',
+ 'Ga',
+ 'Gadu',
+ 'Gal',
+ 'Garcmin',
+ 'Garcsec',
+ 'Gau',
+ 'Gauss',
+ 'Gb',
+ 'Gbarn',
+ 'Gbeam',
+ 'Gbin',
+ 'Gbit',
+ 'Gbyte',
+ 'Gcd',
+ 'Gchan',
+ 'Gcount',
+ 'Gct',
+ 'Gd',
+ 'Gdeg',
+ 'Gdyn',
+ 'GeV',
+ 'Gerg',
+ 'Gg',
+ 'Gh',
+ 'GiB',
+ 'Gib',
+ 'Gibit',
+ 'Gibyte',
+ 'Gk',
+ 'Gl',
+ 'Glm',
+ 'Glx',
+ 'Glyr',
+ 'Gm',
+ 'Gmag',
+ 'Gmin',
+ 'Gmol',
+ 'Gohm',
+ 'Gpc',
+ 'Gph',
+ 'Gphoton',
+ 'Gpix',
+ 'Gpixel',
+ 'Grad',
+ 'Gs',
+ 'Gsr',
+ 'Gu',
+ 'Gvox',
+ 'Gvoxel',
+ 'Gyr',
+ 'H',
+ 'Henry',
+ 'Hertz',
+ 'Hz',
+ 'IrreducibleUnit',
+ 'J',
+ 'Jansky',
+ 'Joule',
+ 'Jy',
+ 'K',
+ 'Kayser',
+ 'Kelvin',
+ 'KiB',
+ 'Kib',
+ 'Kibit',
+ 'Kibyte',
+ 'L',
+ 'L_bol',
+ 'L_sun',
+ 'LogQuantity',
+ 'LogUnit',
+ 'Lsun',
+ 'MA',
+ 'MAU',
+ 'MB',
+ 'MBa',
+ 'MC',
+ 'MD',
+ 'MF',
+ 'MG',
+ 'MGal',
+ 'MH',
+ 'MHz',
+ 'MJ',
+ 'MJy',
+ 'MK',
+ 'ML',
+ 'MN',
+ 'MOhm',
+ 'MP',
+ 'MPa',
+ 'MR',
+ 'MRy',
+ 'MS',
+ 'MSt',
+ 'MT',
+ 'MV',
+ 'MW',
+ 'MWb',
+ 'M_bol',
+ 'M_e',
+ 'M_earth',
+ 'M_jup',
+ 'M_jupiter',
+ 'M_p',
+ 'M_sun',
+ 'Ma',
+ 'Madu',
+ 'MagUnit',
+ 'Magnitude',
+ 'Marcmin',
+ 'Marcsec',
+ 'Mau',
+ 'Mb',
+ 'Mbarn',
+ 'Mbeam',
+ 'Mbin',
+ 'Mbit',
+ 'Mbyte',
+ 'Mcd',
+ 'Mchan',
+ 'Mcount',
+ 'Mct',
+ 'Md',
+ 'Mdeg',
+ 'Mdyn',
+ 'MeV',
+ 'Mearth',
+ 'Merg',
+ 'Mg',
+ 'Mh',
+ 'MiB',
+ 'Mib',
+ 'Mibit',
+ 'Mibyte',
+ 'Mjup',
+ 'Mjupiter',
+ 'Mk',
+ 'Ml',
+ 'Mlm',
+ 'Mlx',
+ 'Mlyr',
+ 'Mm',
+ 'Mmag',
+ 'Mmin',
+ 'Mmol',
+ 'Mohm',
+ 'Mpc',
+ 'Mph',
+ 'Mphoton',
+ 'Mpix',
+ 'Mpixel',
+ 'Mrad',
+ 'Ms',
+ 'Msr',
+ 'Msun',
+ 'Mu',
+ 'Mvox',
+ 'Mvoxel',
+ 'Myr',
+ 'N',
+ 'NamedUnit',
+ 'Newton',
+ 'Ohm',
+ 'P',
+ 'PA',
+ 'PAU',
+ 'PB',
+ 'PBa',
+ 'PC',
+ 'PD',
+ 'PF',
+ 'PG',
+ 'PGal',
+ 'PH',
+ 'PHz',
+ 'PJ',
+ 'PJy',
+ 'PK',
+ 'PL',
+ 'PN',
+ 'POhm',
+ 'PP',
+ 'PPa',
+ 'PR',
+ 'PRy',
+ 'PS',
+ 'PSt',
+ 'PT',
+ 'PV',
+ 'PW',
+ 'PWb',
+ 'Pa',
+ 'Padu',
+ 'Parcmin',
+ 'Parcsec',
+ 'Pascal',
+ 'Pau',
+ 'Pb',
+ 'Pbarn',
+ 'Pbeam',
+ 'Pbin',
+ 'Pbit',
+ 'Pbyte',
+ 'Pcd',
+ 'Pchan',
+ 'Pcount',
+ 'Pct',
+ 'Pd',
+ 'Pdeg',
+ 'Pdyn',
+ 'PeV',
+ 'Perg',
+ 'Pg',
+ 'Ph',
+ 'PiB',
+ 'Pib',
+ 'Pibit',
+ 'Pibyte',
+ 'Pk',
+ 'Pl',
+ 'Plm',
+ 'Plx',
+ 'Plyr',
+ 'Pm',
+ 'Pmag',
+ 'Pmin',
+ 'Pmol',
+ 'Pohm',
+ 'Ppc',
+ 'Pph',
+ 'Pphoton',
+ 'Ppix',
+ 'Ppixel',
+ 'Prad',
+ 'PrefixUnit',
+ 'Ps',
+ 'Psr',
+ 'Pu',
+ 'Pvox',
+ 'Pvoxel',
+ 'Pyr',
+ 'Quantity',
+ 'QuantityInfo',
+ 'QuantityInfoBase',
+ 'R',
+ 'R_earth',
+ 'R_jup',
+ 'R_jupiter',
+ 'R_sun',
+ 'Rayleigh',
+ 'Rearth',
+ 'Rjup',
+ 'Rjupiter',
+ 'Rsun',
+ 'Ry',
+ 'S',
+ 'ST',
+ 'STflux',
+ 'STmag',
+ 'Siemens',
+ 'SpecificTypeQuantity',
+ 'St',
+ 'Sun',
+ 'T',
+ 'TA',
+ 'TAU',
+ 'TB',
+ 'TBa',
+ 'TC',
+ 'TD',
+ 'TF',
+ 'TG',
+ 'TGal',
+ 'TH',
+ 'THz',
+ 'TJ',
+ 'TJy',
+ 'TK',
+ 'TL',
+ 'TN',
+ 'TOhm',
+ 'TP',
+ 'TPa',
+ 'TR',
+ 'TRy',
+ 'TS',
+ 'TSt',
+ 'TT',
+ 'TV',
+ 'TW',
+ 'TWb',
+ 'Ta',
+ 'Tadu',
+ 'Tarcmin',
+ 'Tarcsec',
+ 'Tau',
+ 'Tb',
+ 'Tbarn',
+ 'Tbeam',
+ 'Tbin',
+ 'Tbit',
+ 'Tbyte',
+ 'Tcd',
+ 'Tchan',
+ 'Tcount',
+ 'Tct',
+ 'Td',
+ 'Tdeg',
+ 'Tdyn',
+ 'TeV',
+ 'Terg',
+ 'Tesla',
+ 'Tg',
+ 'Th',
+ 'TiB',
+ 'Tib',
+ 'Tibit',
+ 'Tibyte',
+ 'Tk',
+ 'Tl',
+ 'Tlm',
+ 'Tlx',
+ 'Tlyr',
+ 'Tm',
+ 'Tmag',
+ 'Tmin',
+ 'Tmol',
+ 'Tohm',
+ 'Torr',
+ 'Tpc',
+ 'Tph',
+ 'Tphoton',
+ 'Tpix',
+ 'Tpixel',
+ 'Trad',
+ 'Ts',
+ 'Tsr',
+ 'Tu',
+ 'Tvox',
+ 'Tvoxel',
+ 'Tyr',
+ 'Unit',
+ 'UnitBase',
+ 'UnitConversionError',
+ 'UnitTypeError',
+ 'UnitsError',
+ 'UnitsWarning',
+ 'UnrecognizedUnit',
+ 'V',
+ 'Volt',
+ 'W',
+ 'Watt',
+ 'Wb',
+ 'Weber',
+ 'YA',
+ 'YAU',
+ 'YB',
+ 'YBa',
+ 'YC',
+ 'YD',
+ 'YF',
+ 'YG',
+ 'YGal',
+ 'YH',
+ 'YHz',
+ 'YJ',
+ 'YJy',
+ 'YK',
+ 'YL',
+ 'YN',
+ 'YOhm',
+ 'YP',
+ 'YPa',
+ 'YR',
+ 'YRy',
+ 'YS',
+ 'YSt',
+ 'YT',
+ 'YV',
+ 'YW',
+ 'YWb',
+ 'Ya',
+ 'Yadu',
+ 'Yarcmin',
+ 'Yarcsec',
+ 'Yau',
+ 'Yb',
+ 'Ybarn',
+ 'Ybeam',
+ 'Ybin',
+ 'Ybit',
+ 'Ybyte',
+ 'Ycd',
+ 'Ychan',
+ 'Ycount',
+ 'Yct',
+ 'Yd',
+ 'Ydeg',
+ 'Ydyn',
+ 'YeV',
+ 'Yerg',
+ 'Yg',
+ 'Yh',
+ 'Yk',
+ 'Yl',
+ 'Ylm',
+ 'Ylx',
+ 'Ylyr',
+ 'Ym',
+ 'Ymag',
+ 'Ymin',
+ 'Ymol',
+ 'Yohm',
+ 'Ypc',
+ 'Yph',
+ 'Yphoton',
+ 'Ypix',
+ 'Ypixel',
+ 'Yrad',
+ 'Ys',
+ 'Ysr',
+ 'Yu',
+ 'Yvox',
+ 'Yvoxel',
+ 'Yyr',
+ 'ZA',
+ 'ZAU',
+ 'ZB',
+ 'ZBa',
+ 'ZC',
+ 'ZD',
+ 'ZF',
+ 'ZG',
+ 'ZGal',
+ 'ZH',
+ 'ZHz',
+ 'ZJ',
+ 'ZJy',
+ 'ZK',
+ 'ZL',
+ 'ZN',
+ 'ZOhm',
+ 'ZP',
+ 'ZPa',
+ 'ZR',
+ 'ZRy',
+ 'ZS',
+ 'ZSt',
+ 'ZT',
+ 'ZV',
+ 'ZW',
+ 'ZWb',
+ 'Za',
+ 'Zadu',
+ 'Zarcmin',
+ 'Zarcsec',
+ 'Zau',
+ 'Zb',
+ 'Zbarn',
+ 'Zbeam',
+ 'Zbin',
+ 'Zbit',
+ 'Zbyte',
+ 'Zcd',
+ 'Zchan',
+ 'Zcount',
+ 'Zct',
+ 'Zd',
+ 'Zdeg',
+ 'Zdyn',
+ 'ZeV',
+ 'Zerg',
+ 'Zg',
+ 'Zh',
+ 'Zk',
+ 'Zl',
+ 'Zlm',
+ 'Zlx',
+ 'Zlyr',
+ 'Zm',
+ 'Zmag',
+ 'Zmin',
+ 'Zmol',
+ 'Zohm',
+ 'Zpc',
+ 'Zph',
+ 'Zphoton',
+ 'Zpix',
+ 'Zpixel',
+ 'Zrad',
+ 'Zs',
+ 'Zsr',
+ 'Zu',
+ 'Zvox',
+ 'Zvoxel',
+ 'Zyr',
+ '__builtins__',
+ '__cached__',
+ '__doc__',
+ '__file__',
+ '__loader__',
+ '__name__',
+ '__package__',
+ '__path__',
+ '__spec__',
+ 'a',
+ 'aA',
+ 'aAU',
+ 'aB',
+ 'aBa',
+ 'aC',
+ 'aD',
+ 'aF',
+ 'aG',
+ 'aGal',
+ 'aH',
+ 'aHz',
+ 'aJ',
+ 'aJy',
+ 'aK',
+ 'aL',
+ 'aN',
+ 'aOhm',
+ 'aP',
+ 'aPa',
+ 'aR',
+ 'aRy',
+ 'aS',
+ 'aSt',
+ 'aT',
+ 'aV',
+ 'aW',
+ 'aWb',
+ 'aa',
+ 'aadu',
+ 'aarcmin',
+ 'aarcsec',
+ 'aau',
+ 'ab',
+ 'abA',
+ 'abC',
+ 'abampere',
+ 'abarn',
+ 'abcoulomb',
+ 'abeam',
+ 'abin',
+ 'abit',
+ 'abyte',
+ 'acd',
+ 'achan',
+ 'acount',
+ 'act',
+ 'ad',
+ 'add_enabled_equivalencies',
+ 'add_enabled_units',
+ 'adeg',
+ 'adu',
+ 'adyn',
+ 'aeV',
+ 'aerg',
+ 'ag',
+ 'ah',
+ 'ak',
+ 'al',
+ 'allclose',
+ 'alm',
+ 'alx',
+ 'alyr',
+ 'am',
+ 'amag',
+ 'amin',
+ 'amol',
+ 'amp',
+ 'ampere',
+ 'angstrom',
+ 'annum',
+ 'aohm',
+ 'apc',
+ 'aph',
+ 'aphoton',
+ 'apix',
+ 'apixel',
+ 'arad',
+ 'arcmin',
+ 'arcminute',
+ 'arcsec',
+ 'arcsecond',
+ 'asr',
+ 'astronomical_unit',
+ 'astrophys',
+ 'attoBarye',
+ 'attoDa',
+ 'attoDalton',
+ 'attoDebye',
+ 'attoFarad',
+ 'attoGauss',
+ 'attoHenry',
+ 'attoHertz',
+ 'attoJansky',
+ 'attoJoule',
+ 'attoKayser',
+ 'attoKelvin',
+ 'attoNewton',
+ 'attoOhm',
+ 'attoPascal',
+ 'attoRayleigh',
+ 'attoSiemens',
+ 'attoTesla',
+ 'attoVolt',
+ 'attoWatt',
+ 'attoWeber',
+ 'attoamp',
+ 'attoampere',
+ 'attoannum',
+ 'attoarcminute',
+ 'attoarcsecond',
+ 'attoastronomical_unit',
+ 'attobarn',
+ 'attobarye',
+ 'attobit',
+ 'attobyte',
+ 'attocandela',
+ 'attocoulomb',
+ 'attocount',
+ 'attoday',
+ 'attodebye',
+ 'attodegree',
+ 'attodyne',
+ 'attoelectronvolt',
+ 'attofarad',
+ 'attogal',
+ 'attogauss',
+ 'attogram',
+ 'attohenry',
+ 'attohertz',
+ 'attohour',
+ 'attohr',
+ 'attojansky',
+ 'attojoule',
+ 'attokayser',
+ 'attolightyear',
+ 'attoliter',
+ 'attolumen',
+ 'attolux',
+ 'attometer',
+ 'attominute',
+ 'attomole',
+ 'attonewton',
+ 'attoparsec',
+ 'attopascal',
+ 'attophoton',
+ 'attopixel',
+ 'attopoise',
+ 'attoradian',
+ 'attorayleigh',
+ 'attorydberg',
+ 'attosecond',
+ 'attosiemens',
+ 'attosteradian',
+ 'attostokes',
+ 'attotesla',
+ 'attovolt',
+ 'attovoxel',
+ 'attowatt',
+ 'attoweber',
+ 'attoyear',
+ 'au',
+ 'avox',
+ 'avoxel',
+ 'ayr',
+ 'b',
+ 'bar',
+ 'barn',
+ 'barye',
+ 'beam',
+ 'beam_angular_area',
+ 'becquerel',
+ 'bin',
+ 'binary_prefixes',
+ 'bit',
+ 'bol',
+ 'brightness_temperature',
+ 'byte',
+ 'cA',
+ 'cAU',
+ 'cB',
+ 'cBa',
+ 'cC',
+ 'cD',
+ 'cF',
+ 'cG',
+ 'cGal',
+ 'cH',
+ 'cHz',
+ 'cJ',
+ 'cJy',
+ 'cK',
+ 'cL',
+ 'cN',
+ 'cOhm',
+ 'cP',
+ 'cPa',
+ 'cR',
+ 'cRy',
+ 'cS',
+ 'cSt',
+ 'cT',
+ 'cV',
+ 'cW',
+ 'cWb',
+ 'ca',
+ 'cadu',
+ 'candela',
+ 'carcmin',
+ 'carcsec',
+ 'cau',
+ 'cb',
+ 'cbarn',
+ 'cbeam',
+ 'cbin',
+ 'cbit',
+ 'cbyte',
+ 'ccd',
+ 'cchan',
+ 'ccount',
+ 'cct',
+ 'cd',
+ 'cdeg',
+ 'cdyn',
+ 'ceV',
+ 'centiBarye',
+ 'centiDa',
+ 'centiDalton',
+ 'centiDebye',
+ 'centiFarad',
+ 'centiGauss',
+ 'centiHenry',
+ 'centiHertz',
+ 'centiJansky',
+ 'centiJoule',
+ 'centiKayser',
+ 'centiKelvin',
+ 'centiNewton',
+ 'centiOhm',
+ 'centiPascal',
+ 'centiRayleigh',
+ 'centiSiemens',
+ 'centiTesla',
+ 'centiVolt',
+ 'centiWatt',
+ 'centiWeber',
+ 'centiamp',
+ 'centiampere',
+ 'centiannum',
+ 'centiarcminute',
+ 'centiarcsecond',
+ 'centiastronomical_unit',
+ 'centibarn',
+ 'centibarye',
+ 'centibit',
+ 'centibyte',
+ 'centicandela',
+ 'centicoulomb',
+ 'centicount',
+ 'centiday',
+ 'centidebye',
+ 'centidegree',
+ 'centidyne',
+ 'centielectronvolt',
+ 'centifarad',
+ 'centigal',
+ 'centigauss',
+ 'centigram',
+ 'centihenry',
+ 'centihertz',
+ 'centihour',
+ 'centihr',
+ 'centijansky',
+ 'centijoule',
+ 'centikayser',
+ 'centilightyear',
+ 'centiliter',
+ 'centilumen',
+ 'centilux',
+ 'centimeter',
+ 'centiminute',
+ 'centimole',
+ 'centinewton',
+ 'centiparsec',
+ 'centipascal',
+ 'centiphoton',
+ 'centipixel',
+ 'centipoise',
+ 'centiradian',
+ 'centirayleigh',
+ 'centirydberg',
+ 'centisecond',
+ 'centisiemens',
+ 'centisteradian',
+ 'centistokes',
+ 'centitesla',
+ 'centivolt',
+ 'centivoxel',
+ 'centiwatt',
+ 'centiweber',
+ 'centiyear',
+ 'cerg',
+ 'cg',
+ 'cgs',
+ 'ch',
+ 'chan',
+ 'ck',
+ 'cl',
+ 'clm',
+ 'clx',
+ 'clyr',
+ 'cm',
+ 'cmag',
+ 'cmin',
+ 'cmol',
+ 'cohm',
+ 'core',
+ 'coulomb',
+ 'count',
+ 'cpc',
+ 'cph',
+ 'cphoton',
+ 'cpix',
+ 'cpixel',
+ 'crad',
+ 'cs',
+ 'csr',
+ 'ct',
+ 'cu',
+ 'curie',
+ 'cvox',
+ 'cvoxel',
+ 'cy',
+ 'cycle',
+ 'cyr',
+ 'd',
+ 'dA',
+ 'dAU',
+ 'dB',
+ 'dBa',
+ 'dC',
+ 'dD',
+ 'dF',
+ 'dG',
+ 'dGal',
+ 'dH',
+ 'dHz',
+ 'dJ',
+ 'dJy',
+ 'dK',
+ 'dL',
+ 'dN',
+ 'dOhm',
+ 'dP',
+ 'dPa',
+ 'dR',
+ 'dRy',
+ 'dS',
+ 'dSt',
+ ...]
+To create a quantity, we multiply a value by a unit.
astropy.units.quantity.Quantity
+The result is a Quantity object.
Jupyter knows how to display Quantities like this:
+
+
+\[10 \; \mathrm{{}^{\circ}}\]
+
Quantities provide a method called to that converts to other units. For example, we can compute the number of arcminutes in angle:
@@ -421,6 +1410,10 @@ Jupyter knows how to display
+
+
+\[600 \; \mathrm{{}^{\prime}}\]
+
If you add quantities, Astropy converts them to compatible units, if possible:
@@ -429,6 +1422,10 @@ Jupyter knows how to display
+
+
+\[10.5 \; \mathrm{{}^{\circ}}\]
+
If the units are not compatible, you get an error.
For example:
@@ -442,10 +1439,22 @@ For example:
Then convert it to degrees.
-# Solution goes here
+# Solution
+
+radius = 5 * u.arcmin
+print(radius)
+
+radius.to(u.degree)
+
+5.0 arcmin
+
+
+
+\[0.083333333 \; \mathrm{{}^{\circ}}\]
+
@@ -485,6 +1494,23 @@ Here’s how we run it.
+
+Created TAP+ (v1.2.1) - Connection:
+ Host: gea.esac.esa.int
+ Use HTTPS: True
+ Port: 443
+ SSL Port: 443
+Created TAP+ (v1.2.1) - Connection:
+ Host: geadata.esac.esa.int
+ Use HTTPS: True
+ Port: 443
+ SSL Port: 443
+
+
+<astroquery.utils.tap.model.job.Job at 0x7f277785fa30>
+
+
+
@@ -493,6 +1519,22 @@ Here’s how we run it.
+
+Table length=10
+
+source_id
+int64
+3322773965056065536
+3322773758899157120
+3322774068134271104
+3322773930696320512
+3322774377374425728
+3322773724537891456
+3322773724537891328
+3322773930696321792
+3322773724537890944
+3322773930696322176
+
Exercise¶
@@ -501,10 +1543,29 @@ Here’s how we run it.
In the previous query, replace TOP 10 source_id with COUNT(source_id) and run the query again. How many stars has Gaia identified in the cone we searched?
-# Solution goes here
+# Solution
+
+query = """SELECT
+COUNT(source_id)
+FROM gaiadr2.gaia_source
+WHERE 1=CONTAINS(
+ POINT(ra, dec),
+ CIRCLE(88.8, 7.4, 0.08333333))
+"""
+
+job = Gaia.launch_job(query)
+results = job.get_results()
+results
+
+Table length=1
+
+count
+int64
+594
+
@@ -544,6 +1605,12 @@ Here’s how we run it.
+
+<SkyCoord (ICRS): (ra, dec) in deg
+ (88.8, 7.4)>
+
+
+
SkyCoord provides a function that transforms to other frames.
For example, we can transform coords_icrs to Galactic coordinates like this:
@@ -554,6 +1621,12 @@ For example, we can transform
+
+<SkyCoord (Galactic): (l, b) in deg
+ (199.79693102, -8.95591653)>
+
+
+
Notice that in the Galactic frame, the coordinates are called l and b, not ra and dec.
To transform to and from GD-1 coordinates, we’ll use a frame defined by Gala, which is an Astropy-affiliated library that provides tools for galactic dynamics.
@@ -567,6 +1640,11 @@ For example, we can transform
+
+<GD1Koposov10 Frame>
+
+
+
We can use it to find the coordinates of Betelgeuse in the GD-1 frame, like this:
@@ -576,6 +1654,12 @@ For example, we can transform
+
+<SkyCoord (GD1Koposov10): (phi1, phi2) in deg
+ (-94.97222038, 34.5813813)>
+
+
+
Notice that the coordinates are called phi1 and phi2.
These are the coordinates shown in the figure from the paper, above.
@@ -589,7 +1673,30 @@ These are the coordinates shown in the figure from the paper, above.
Hint: Because ICRS is built into Astropy, you can specify it by name, icrs (as we did with galactic).
-# Solution goes here
+# Solution
+
+origin_gd1 = SkyCoord(0*u.degree, 0*u.degree, frame=gd1_frame)
+
+# OR
+
+origin_gd1 = SkyCoord(phi1=0*u.degree,
+ phi2=0*u.degree,
+ frame=gd1_frame)
+
+# Note: because ICRS is built into Astropy,
+# we can identify it by string name
+origin_gd1.transform_to('icrs')
+
+# More formally, we could instantiate it
+from astropy.coordinates import ICRS
+icrs_frame = ICRS()
+origin_gd1.transform_to(icrs_frame)
+
+
+
+
+<SkyCoord (ICRS): (ra, dec) in deg
+ (200., 59.4504341)>
@@ -641,6 +1748,12 @@ These are the coordinates shown in the figure from the paper, above.
+
+<SkyCoord (GD1Koposov10): (phi1, phi2) in deg
+ [(-55., -8.), (-55., 4.), (-45., 4.), (-45., -8.), (-55., -8.)]>
+
+
+
Now we can use transform_to to convert to ICRS coordinates.
@@ -650,6 +1763,14 @@ These are the coordinates shown in the figure from the paper, above.
+
+<SkyCoord (ICRS): (ra, dec) in deg
+ [(146.27533314, 19.26190982), (135.42163944, 25.87738723),
+ (141.60264825, 34.3048303 ), (152.81671045, 27.13611254),
+ (146.27533314, 19.26190982)]>
+
+
+
Notice that a rectangle in one coordinate system is not necessarily a rectangle in another. In this example, the result is a (non-rectangular) polygon.
@@ -672,6 +1793,15 @@ These are the coordinates shown in the figure from the paper, above.
+
+['146.275 19.2619',
+ '135.422 25.8774',
+ '141.603 34.3048',
+ '152.817 27.1361',
+ '146.275 19.2619']
+
+
+
We can use the Python string function join to join t into a single string (with spaces between the pairs):
@@ -681,6 +1811,11 @@ These are the coordinates shown in the figure from the paper, above.
+
+'146.275 19.2619 135.422 25.8774 141.603 34.3048 152.817 27.1361 146.275 19.2619'
+
+
+
That’s almost what we need, but we have to replace the spaces with commas.
@@ -689,6 +1824,11 @@ These are the coordinates shown in the figure from the paper, above.
+
+'146.275, 19.2619, 135.422, 25.8774, 141.603, 34.3048, 152.817, 27.1361, 146.275, 19.2619'
+
+
+
The following function combines these steps.
@@ -710,6 +1850,11 @@ These are the coordinates shown in the figure from the paper, above.
+
+'146.275, 19.2619, 135.422, 25.8774, 141.603, 34.3048, 152.817, 27.1361, 146.275, 19.2619'
+
+
+
@@ -763,6 +1908,18 @@ We need columns
+
+SELECT
+TOP 10
+source_id, ra, dec, pmra, pmdec
+FROM gaiadr2.gaia_source
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+ AND 1 = CONTAINS(POINT(ra, dec),
+ POLYGON(146.275, 19.2619, 135.422, 25.8774, 141.603, 34.3048, 152.817, 27.1361, 146.275, 19.2619))
+
+
+
As always, we should take a minute to proof-read the query before we launch it.
@@ -772,6 +1929,24 @@ We need columns
+
+INFO: Query finished. [astroquery.utils.tap.core]
+<Table length=10>
+ name dtype unit description
+--------- ------- -------- ------------------------------------------------------------------
+source_id int64 Unique source identifier (unique within a particular Data Release)
+ ra float64 deg Right ascension
+ dec float64 deg Declination
+ pmra float64 mas / yr Proper motion in right ascension direction
+ pmdec float64 mas / yr Proper motion in declination direction
+Jobid: 1615815873808O
+Phase: COMPLETED
+Owner: None
+Output file: async_20210315094433.vot
+Results: None
+
+
+
Here are the results.
@@ -781,6 +1956,23 @@ We need columns
+
+Table length=10
+
+source_id ra dec pmra pmdec
+deg deg mas / yr mas / yr
+int64 float64 float64 float64 float64
+637987125186749568 142.48301935991023 21.75771616932985 -2.5168384683875766 2.941813096629439
+638285195917112960 142.25452941346344 22.476168171141378 2.6627020143457996 -12.165984395577347
+638073505568978688 142.64528557468074 22.16693224953078 18.30674739454163 -7.950659620550862
+638086386175786752 142.57739430926034 22.22791951401365 0.9877856720147953 -2.584105480335548
+638049655615392384 142.58913564478618 22.110783166677418 0.24443878227817095 -4.941079187010136
+638267565075964032 141.81762228999614 22.375696125322275 -3.413174589660796 1.8838892877285924
+638028902333511168 143.18339801317677 22.2512465812369 7.848511762712128 -21.391145547787154
+638085767700610432 142.9347319464589 22.46244080823965 -3.6585960944321476 -12.486419770278376
+638299863230178304 142.26769745823267 22.640183776884836 -1.8168370892218297 1.0537342990941316
+637973067758974208 142.89551292869012 21.612824100339875 -8.645166256559063 -44.41164172204947
+
Finally, we can remove TOP 10 run the query again.
The result is bigger than our previous queries, so it will take a little longer.
@@ -806,6 +1998,17 @@ We need columns
+
+SELECT
+source_id, ra, dec, pmra, pmdec
+FROM gaiadr2.gaia_source
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+ AND 1 = CONTAINS(POINT(ra, dec),
+ POLYGON(146.275, 19.2619, 135.422, 25.8774, 141.603, 34.3048, 152.817, 27.1361, 146.275, 19.2619))
+
+
+
@@ -814,6 +2017,24 @@ We need columns
+
+INFO: Query finished. [astroquery.utils.tap.core]
+<Table length=140339>
+ name dtype unit description
+--------- ------- -------- ------------------------------------------------------------------
+source_id int64 Unique source identifier (unique within a particular Data Release)
+ ra float64 deg Right ascension
+ dec float64 deg Declination
+ pmra float64 mas / yr Proper motion in right ascension direction
+ pmdec float64 mas / yr Proper motion in declination direction
+Jobid: 1615815886707O
+Phase: COMPLETED
+Owner: None
+Output file: async_20210315094446.vot
+Results: None
+
+
+
@@ -822,6 +2043,11 @@ We need columns
+
+140339
+
+
+
There are more than 100,000 stars in this polygon, but that’s a manageable size to work with.
@@ -850,6 +2076,11 @@ We need columns
+
+5.36407470703125
+
+
+
diff --git a/03_motion.html b/03_motion.html
index c1fe0a6..a544a5c 100644
--- a/03_motion.html
+++ b/03_motion.html
@@ -243,11 +243,6 @@
Outline
-
-
- Installing libraries
-
-
Reload the data
@@ -373,24 +368,6 @@
Save a DataFrame in an HDF5 file.
-
-Installing libraries¶
-If you are running this notebook on Colab, you can run the following cell to install the libraries we’ll use.
-If you are running this notebook on your own computer, you might have to install these libraries yourself. See the instructions in the preface.
-
-
-# If we're running on Colab, install libraries
-
-import sys
-IN_COLAB = 'google.colab' in sys.modules
-
-if IN_COLAB:
- !pip install astroquery astro-gala
-
-
-
-
-
Reload the data¶
In the previous lesson, we ran a query on the Gaia server and downloaded data for roughly 140,000 stars. We saved the data in a FITS file so that now, picking up where we left off, we can read the data from a local file rather than running the query again.
@@ -432,6 +409,19 @@
+
+<Table length=140339>
+ name dtype unit description
+--------- ------- -------- ------------------------------------------------------------------
+source_id int64 Unique source identifier (unique within a particular Data Release)
+ ra float64 deg Right ascension
+ dec float64 deg Declination
+ pmra float64 mas / yr Proper motion in right ascension direction
+ pmdec float64 mas / yr Proper motion in declination direction
+ parallax float64 mas Parallax
+
+
+
@@ -444,6 +434,11 @@
+
+['source_id', 'ra', 'dec', 'pmra', 'pmdec', 'parallax']
+
+
+
And select an individual column like this:
@@ -452,6 +447,35 @@
+
+<Column name='ra' dtype='float64' unit='deg' description='Right ascension' length=140339>
+
+142.48301935991023
+142.25452941346344
+142.64528557468074
+142.57739430926034
+142.58913564478618
+141.81762228999614
+143.18339801317677
+142.9347319464589
+142.26769745823267
+142.89551292869012
+142.2780935768316
+142.06138786534987
+...
+143.05456487172972
+144.0436496516182
+144.06566578919313
+144.13177563215973
+143.77696341662764
+142.945956347594
+142.97282480557786
+143.4166017695258
+143.64484588686904
+143.41554585481808
+143.6908739159247
+143.7702681295401
+
The result is a Column object that contains the data, and also the data type, units, and name of the column.
@@ -460,6 +484,11 @@
+
+astropy.table.column.Column
+
+
+
The rows in the Table are numbered from 0 to n-1, where n is the number of rows. We can select the first row like this:
@@ -468,6 +497,14 @@
+
+Row index=0
+
+source_id ra dec pmra pmdec parallax
+deg deg mas / yr mas / yr mas
+int64 float64 float64 float64 float64 float64
+637987125186749568 142.48301935991023 21.75771616932985 -2.5168384683875766 2.941813096629439 -0.2573448962333354
+
As you might have guessed, the result is a Row object.
@@ -476,6 +513,11 @@
+
+astropy.table.row.Row
+
+
+
Notice that the bracket operator selects both columns and rows. You might wonder how it knows which to select.
If the expression in brackets is a string, it selects a column; if the expression is an integer, it selects a row.
@@ -486,6 +528,11 @@ If the expression in brackets is a string, it selects a column; if the expressio
+
+142.48301935991023
+
+
+
Or you can select a row and then an element from the row.
@@ -494,6 +541,11 @@ If the expression in brackets is a string, it selects a column; if the expressio
+
+142.48301935991023
+
+
+
You get the same result either way.
@@ -534,6 +586,9 @@ In that case, you might want to run the following Jupyter
+
+
The arguments to plt.plot are x, y, and a string that specifies the style. In this case, the letters ko indicate that we want a black, round marker (k is for black because b is for blue).
The functions xlabel and ylabel put labels on the axes.
@@ -548,7 +603,14 @@ The functions xlabe
Note: Once you have made these changes, you might notice that the figure shows stripes with lower density of stars. These stripes are caused by the way Gaia scans the sky, which you can read about here. The dataset we are using, Gaia Data Release 2, covers 22 months of observations; during this time, some parts of the sky were scanned more than others.
-# Solution goes here
+# Solution
+
+# x = results['ra']
+# y = results['dec']
+# plt.plot(x, y, 'ko', markersize=0.1, alpha=0.1)
+
+# plt.xlabel('ra (degree ICRS)')
+# plt.ylabel('dec (degree ICRS)');
@@ -648,6 +710,9 @@ The coordinates in
+
+
+
Remember that we started with a rectangle in the GD-1 frame. When transformed to the ICRS frame, it’s a non-rectangular region. Now, transformed back to the GD-1 frame, it’s a rectangle again.
@@ -660,6 +725,11 @@ The coordinates in
+
+astropy.table.table.Table
+
+
+
And skycoord_gd1 is a SkyCoord object that contains the transformed coordinates and proper motions.
@@ -668,6 +738,11 @@ The coordinates in
+
+astropy.coordinates.sky_coordinate.SkyCoord
+
+
+
On one hand, this division of labor makes sense because each object provides different capabilities. But working with multiple object types can be awkward.
It will be more convenient to choose one object and get all of the data into it. We’ll choose a Pandas DataFrame, for two reasons:
@@ -693,6 +768,11 @@ The coordinates in
+
+(140339, 6)
+
+
+
It also provides head, which displays the first few rows. head is useful for spot-checking large results as you go along.
@@ -701,6 +781,82 @@ The coordinates in
+
+
+
+
+
+
+
+ source_id
+ ra
+ dec
+ pmra
+ pmdec
+ parallax
+
+
+
+
+ 0
+ 637987125186749568
+ 142.483019
+ 21.757716
+ -2.516838
+ 2.941813
+ -0.257345
+
+
+ 1
+ 638285195917112960
+ 142.254529
+ 22.476168
+ 2.662702
+ -12.165984
+ 0.422728
+
+
+ 2
+ 638073505568978688
+ 142.645286
+ 22.166932
+ 18.306747
+ -7.950660
+ 0.103640
+
+
+ 3
+ 638086386175786752
+ 142.577394
+ 22.227920
+ 0.987786
+ -2.584105
+ -0.857327
+
+
+ 4
+ 638049655615392384
+ 142.589136
+ 22.110783
+ 0.244439
+ -4.941079
+ 0.099625
+
+
+
+
Python detail: shape is an attribute, so we display its value without calling it as a function; head is a function, so we need the parentheses.
Now we can extract the columns we want from skycoord_gd1 and add them as columns in the DataFrame. phi1 and phi2 contain the transformed coordinates.
@@ -712,6 +868,11 @@ The coordinates in
+
+(140339, 8)
+
+
+
pm_phi1_cosphi2 and pm_phi2 contain the components of proper motion in the transformed frame.
@@ -722,6 +883,11 @@ The coordinates in
+
+(140339, 10)
+
+
+
Detail: If you notice that SkyCoord has an attribute called proper_motion, you might wonder why we are not using it.
We could have: proper_motion contains the same data as pm_phi1_cosphi2 and pm_phi2, but in a different format.
@@ -736,6 +902,145 @@ One of the most useful of these functions is
+
+
+
+
+
+
+ source_id
+ ra
+ dec
+ pmra
+ pmdec
+ parallax
+ phi1
+ phi2
+ pm_phi1
+ pm_phi2
+
+
+
+
+ count
+ 1.403390e+05
+ 140339.000000
+ 140339.000000
+ 140339.000000
+ 140339.000000
+ 140339.000000
+ 140339.000000
+ 140339.000000
+ 140339.000000
+ 140339.000000
+
+
+ mean
+ 6.792399e+17
+ 143.823122
+ 26.780285
+ -2.484404
+ -6.100777
+ 0.179492
+ -50.091158
+ -1.803301
+ -0.868963
+ 1.409208
+
+
+ std
+ 3.792177e+16
+ 3.697850
+ 3.052592
+ 5.913939
+ 7.202047
+ 0.759590
+ 2.892344
+ 3.444398
+ 6.657714
+ 6.518615
+
+
+ min
+ 6.214900e+17
+ 135.425699
+ 19.286617
+ -106.755260
+ -138.065163
+ -15.287602
+ -54.999989
+ -8.029159
+ -115.275637
+ -161.150142
+
+
+ 25%
+ 6.443517e+17
+ 140.967966
+ 24.592490
+ -5.038789
+ -8.341561
+ -0.035981
+ -52.602952
+ -4.750426
+ -2.948723
+ -1.107128
+
+
+ 50%
+ 6.888060e+17
+ 143.734409
+ 26.746261
+ -1.834943
+ -4.689596
+ 0.362708
+ -50.147362
+ -1.671502
+ 0.585037
+ 1.987149
+
+
+ 75%
+ 6.976579e+17
+ 146.607350
+ 28.990500
+ 0.452893
+ -1.937809
+ 0.657637
+ -47.593279
+ 1.160514
+ 3.001768
+ 4.628965
+
+
+ max
+ 7.974418e+17
+ 152.777393
+ 34.285481
+ 104.319923
+ 20.981070
+ 0.999957
+ -44.999985
+ 4.014609
+ 39.802471
+ 79.275199
+
+
+
+
Exercise¶
@@ -746,7 +1051,17 @@ One of the most useful of these functions is
-# Solution goes here
+# Solution
+
+# The most noticeable issue is that some of the
+# parallax values are negative, which is non-physical.
+
+# The reason is that parallax measurements are less accurate
+# for stars that are far away.
+
+# Fortunately, we don't use the parallax measurements in
+# the analysis (one of the reasons we used constant distance
+# for reflex correction).
@@ -776,6 +1091,9 @@ Then we will use the bounds of the cluster to select stars that are more likely
+
+
+
Most of the proper motions are near the origin, but there are a few extreme values.
Following the example in the paper, we’ll use xlim and ylim to zoom in on the region near the origin.
@@ -793,6 +1111,9 @@ Following the example in the paper, we’ll use
+
+
There is a hint of an overdense region near (-7.5, 0), but if you didn’t know where to look, you would miss it.
To see the cluster more clearly, we need a sample that contains a higher proportion of stars in GD-1.
@@ -811,6 +1132,11 @@ We’ll do that by selecting stars close to the centerline.
+
+pandas.core.series.Series
+
+
+
The result is a Series, which is the structure Pandas uses to represent columns.
We can use a comparison operator, >, to compare the values in a Series to a constant.
@@ -824,6 +1150,11 @@ We’ll do that by selecting stars close to the centerline.
+
+pandas.core.series.Series
+
+
+
The result is a Series of Boolean values, that is, True and False.
@@ -832,6 +1163,16 @@ We’ll do that by selecting stars close to the centerline.
+
+0 False
+1 False
+2 False
+3 False
+4 False
+Name: phi2, dtype: bool
+
+
+
To select values that fall between phi2_min and phi2_max, we’ll use the & operator, which computes “logical AND”.
The result is true where elements from both Boolean Series are true.
@@ -851,6 +1192,11 @@ The result is true where elements from both Boolean
+25084
+
+
+
A Boolean Series is sometimes called a “mask” because we can use it to mask out some of the rows in a DataFrame and select the rest, like this:
@@ -860,6 +1206,11 @@ The result is true where elements from both Boolean
+pandas.core.frame.DataFrame
+
+
+
centerline_df is a DataFrame that contains only the rows from results_df that correspond to True values in mask.
So it contains the stars near the centerline of GD-1.
@@ -870,6 +1221,11 @@ So it contains the stars near the centerline of GD-1.
+
+25084
+
+
+
And what fraction of the rows we’ve selected.
@@ -878,6 +1234,11 @@ So it contains the stars near the centerline of GD-1.
+
+0.1787386257562046
+
+
+
There are about 25,000 stars in this region, about 18% of the total.
@@ -911,6 +1272,9 @@ So it contains the stars near the centerline of GD-1.
+
+
+
Now we can see more clearly that there is a cluster near (-7.5, 0).
You might notice that our figure is less dense than the one in the paper. That’s because we started with a set of stars from a relatively small region. The figure in the paper is based on a region about 10 times bigger.
@@ -961,6 +1325,9 @@ So it contains the stars near the centerline of GD-1.
+
+
+
Now that we’ve identified the bounds of the cluster in proper motion, we’ll use it to select rows from results_df.
We’ll use the following function, which uses Pandas operators to make a mask that selects rows where series falls between low and high.
@@ -992,6 +1359,11 @@ So it contains the stars near the centerline of GD-1.
+
+1049
+
+
+
Now we can use this mask to select rows from results_df.
@@ -1001,6 +1373,11 @@ So it contains the stars near the centerline of GD-1.
+
+1049
+
+
+
These are the stars we think are likely to be in GD-1. Let’s see what they look like, plotting their coordinates (not their proper motion).
@@ -1014,6 +1391,9 @@ So it contains the stars near the centerline of GD-1.
+
+
+
Now that’s starting to look like a tidal stream!
@@ -1028,6 +1408,11 @@ So it contains the stars near the centerline of GD-1.
+
+astropy.table.table.Table
+
+
+
Then we could write the Table to a FITS file, as we did in the previous lesson.
But Pandas provides functions to write DataFrames in other formats; to see what they are find the functions here that begin with to_.
@@ -1055,7 +1440,9 @@ So it contains the stars near the centerline of GD-1.
Hint: Since the file already exists, you should not use mode='w'.
-# Solution goes here
+# Solution
+
+centerline_df.to_hdf(filename, 'centerline_df')
@@ -1070,6 +1457,11 @@ So it contains the stars near the centerline of GD-1.
+
+2.2084197998046875
+
+
+
If you forget what the names of the Datasets in the file are, you can read them back like this:
@@ -1079,6 +1471,11 @@ So it contains the stars near the centerline of GD-1.
+
+['/centerline_df', '/selected_df']
+
+
+
Python note: We use a with statement here to open the file before the print statement and (automatically) close it after. Read more about context managers.
The keys are the names of the Datasets. Notice that they start with /, which indicates that they are at the top level of the Dataset hierarchy, and not in a named “group”.
diff --git a/04_select.html b/04_select.html
index 3f95a5f..1227416 100644
--- a/04_select.html
+++ b/04_select.html
@@ -243,11 +243,6 @@
Outline
-
-
- Installing libraries
-
-
Reload the data
@@ -332,24 +327,6 @@ We’ll also see how to write the results to a CSV file.
Save data in CSV format.
-
-Installing libraries¶
-If you are running this notebook on Colab, you can run the following cell to install the libraries we’ll use.
-If you are running this notebook on your own computer, you might have to install these libraries yourself. See the instructions in the preface.
-
-
-# If we're running on Colab, install libraries
-
-import sys
-IN_COLAB = 'google.colab' in sys.modules
-
-if IN_COLAB:
- !pip install astroquery astro-gala
-
-
-
-
-
Reload the data¶
You can download the data from the previous lesson or run the following cell, which downloads it if necessary.
@@ -466,6 +443,9 @@ We’ll also see how to write the results to a CSV file.
+
+
+
Now we’ll make the same plot using proper motions in the ICRS frame, which are stored in columns pmra and pmdec.
@@ -486,6 +466,9 @@ We’ll also see how to write the results to a CSV file.
+
+
+
The proper motions of the selected stars are more spread out in this frame, which is why it was preferable to do the selection in the GD-1 frame.
But now we can define a polygon that encloses the proper motions of these stars in ICRS, and use that polygon as a selection criterion in an ADQL query.
@@ -503,6 +486,11 @@ We’ll also see how to write the results to a CSV file.
+
+(1049, 2)
+
+
+
NOTE: If you are using an older version of Pandas, you might not have to_numpy(); you can use values instead, like this:
points = selected_df[['pmra','pmdec']].values
@@ -519,6 +507,11 @@ We’ll also see how to write the results to a CSV file.
+
+<scipy.spatial.qhull.ConvexHull at 0x7ff6207866a0>
+
+
+
hull.vertices contains the indices of the points that fall on the perimeter of the hull.
@@ -527,6 +520,12 @@ We’ll also see how to write the results to a CSV file.
+
+array([ 692, 873, 141, 303, 42, 622, 45, 83, 127, 182, 1006,
+ 971, 967, 1001, 969, 940], dtype=int32)
+
+
+
We can use them as an index into the original array to select the corresponding rows.
@@ -536,6 +535,26 @@ We’ll also see how to write the results to a CSV file.
+
+array([[ -4.05037121, -14.75623261],
+ [ -3.41981085, -14.72365546],
+ [ -3.03521988, -14.44357135],
+ [ -2.26847919, -13.7140236 ],
+ [ -2.61172203, -13.24797471],
+ [ -2.73471401, -13.09054471],
+ [ -3.19923146, -12.5942653 ],
+ [ -3.34082546, -12.47611926],
+ [ -5.67489413, -11.16083338],
+ [ -5.95159272, -11.10547884],
+ [ -6.42394023, -11.05981295],
+ [ -7.09631023, -11.95187806],
+ [ -7.30641519, -12.24559977],
+ [ -7.04016696, -12.88580702],
+ [ -6.00347705, -13.75912098],
+ [ -4.42442296, -14.74641176]])
+
+
+
To plot the resulting polygon, we have to pull out the x and y coordinates.
@@ -567,6 +586,9 @@ We’ll also see how to write the results to a CSV file.
+
+
+
So pm_vertices represents the polygon we want to select.
The next step is to use it as part of an ADQL query.
@@ -651,6 +673,11 @@ Here’s the function from Lesson 2 we used to do that.
+
+'135.306, 8.39862, 126.51, 13.4449, 163.017, 54.2424, 172.933, 46.4726, 135.306, 8.39862'
+
+
+
Here are the columns we want to select.
@@ -669,6 +696,17 @@ Here’s the function from Lesson 2 we used to do that.
+
+SELECT
+source_id, ra, dec, pmra, pmdec
+FROM gaiadr2.gaia_source
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+ AND 1 = CONTAINS(POINT(ra, dec),
+ POLYGON(135.306, 8.39862, 126.51, 13.4449, 163.017, 54.2424, 172.933, 46.4726, 135.306, 8.39862))
+
+
+
But don’t try to run that query.
Because it selects a larger region, there are too many stars to handle in a single query.
@@ -688,6 +726,11 @@ Using flatten
+
+'[ -4.05037121,-14.75623261, -3.41981085,-14.72365546, -3.03521988,-14.44357135, -2.26847919,-13.7140236 , -2.61172203,-13.24797471, -2.73471401,-13.09054471, -3.19923146,-12.5942653 , -3.34082546,-12.47611926, -5.67489413,-11.16083338, -5.95159272,-11.10547884, -6.42394023,-11.05981295, -7.09631023,-11.95187806, -7.30641519,-12.24559977, -7.04016696,-12.88580702, -6.00347705,-13.75912098, -4.42442296,-14.74641176]'
+
+
+
We just have to remove the brackets.
@@ -697,13 +740,29 @@ Using flatten
+
+' -4.05037121,-14.75623261, -3.41981085,-14.72365546, -3.03521988,-14.44357135, -2.26847919,-13.7140236 , -2.61172203,-13.24797471, -2.73471401,-13.09054471, -3.19923146,-12.5942653 , -3.34082546,-12.47611926, -5.67489413,-11.16083338, -5.95159272,-11.10547884, -6.42394023,-11.05981295, -7.09631023,-11.95187806, -7.30641519,-12.24559977, -7.04016696,-12.88580702, -6.00347705,-13.75912098, -4.42442296,-14.74641176'
+
+
+
Exercise¶
Define query6_base, starting with query5_base and adding a new clause to select stars whose coordinates of proper motion, pmra and pmdec, fall within the polygon defined by pm_point_list.
-# Solution goes here
+# Solution
+
+query6_base = """SELECT
+{columns}
+FROM gaiadr2.gaia_source
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+ AND 1 = CONTAINS(POINT(ra, dec),
+ POLYGON({point_list}))
+ AND 1 = CONTAINS(POINT(pmra, pmdec),
+ POLYGON({pm_point_list}))
+"""
@@ -714,7 +773,25 @@ Using flattenUse format to format query6_base and define query6, filling in the values of columns, point_list, and pm_point_list.
-# Solution goes here
+# Solution
+
+query6 = query6_base.format(columns=columns,
+ point_list=point_list,
+ pm_point_list=pm_point_list)
+print(query6)
+
+
+
+
+SELECT
+source_id, ra, dec, pmra, pmdec
+FROM gaiadr2.gaia_source
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+ AND 1 = CONTAINS(POINT(ra, dec),
+ POLYGON(135.306, 8.39862, 126.51, 13.4449, 163.017, 54.2424, 172.933, 46.4726, 135.306, 8.39862))
+ AND 1 = CONTAINS(POINT(pmra, pmdec),
+ POLYGON( -4.05037121,-14.75623261, -3.41981085,-14.72365546, -3.03521988,-14.44357135, -2.26847919,-13.7140236 , -2.61172203,-13.24797471, -2.73471401,-13.09054471, -3.19923146,-12.5942653 , -3.34082546,-12.47611926, -5.67489413,-11.16083338, -5.95159272,-11.10547884, -6.42394023,-11.05981295, -7.09631023,-11.95187806, -7.30641519,-12.24559977, -7.04016696,-12.88580702, -6.00347705,-13.75912098, -4.42442296,-14.74641176))
@@ -729,6 +806,24 @@ Using flatten
+
+INFO: Query finished. [astroquery.utils.tap.core]
+<Table length=7345>
+ name dtype unit description
+--------- ------- -------- ------------------------------------------------------------------
+source_id int64 Unique source identifier (unique within a particular Data Release)
+ ra float64 deg Right ascension
+ dec float64 deg Declination
+ pmra float64 mas / yr Proper motion in right ascension direction
+ pmdec float64 mas / yr Proper motion in declination direction
+Jobid: 1616771462206O
+Phase: COMPLETED
+Owner: None
+Output file: async_20210326111102.vot
+Results: None
+
+
+
And get the results.
@@ -738,6 +833,11 @@ Using flatten
+
+7345
+
+
+
We call the results candidate_table because it contains stars that are good candidates for GD-1.
For the next lesson, we’ll need point_list and pm_point_list again, so we should save them in a file.
@@ -752,6 +852,12 @@ To make one, we’ll start with a dictionary:
+
+{'point_list': '135.306, 8.39862, 126.51, 13.4449, 163.017, 54.2424, 172.933, 46.4726, 135.306, 8.39862',
+ 'pm_point_list': ' -4.05037121,-14.75623261, -3.41981085,-14.72365546, -3.03521988,-14.44357135, -2.26847919,-13.7140236 , -2.61172203,-13.24797471, -2.73471401,-13.09054471, -3.19923146,-12.5942653 , -3.34082546,-12.47611926, -5.67489413,-11.16083338, -5.95159272,-11.10547884, -6.42394023,-11.05981295, -7.09631023,-11.95187806, -7.30641519,-12.24559977, -7.04016696,-12.88580702, -6.00347705,-13.75912098, -4.42442296,-14.74641176'}
+
+
+
And use it to initialize a Series.
@@ -761,6 +867,13 @@ To make one, we’ll start with a dictionary:
+
+point_list 135.306, 8.39862, 126.51, 13.4449, 163.017, 54...
+pm_point_list -4.05037121,-14.75623261, -3.41981085,-14.723...
+dtype: object
+
+
+
Now we can save it in the usual way.
@@ -787,6 +900,9 @@ To make one, we’ll start with a dictionary:
+
+
+
Here we can see why it was useful to transform these coordinates. In ICRS, it is more difficult to identity the stars near the centerline of GD-1.
So let’s transform the results back to the GD-1 frame.
@@ -844,6 +960,9 @@ Here’s the code we used to transform the coordinates and make a Pandas
+
+
+
We’re starting to see GD-1 more clearly.
We can compare this figure with this panel from Figure 1 from the original paper:
diff --git a/05_join.html b/05_join.html
index 6b98ba7..bd422a1 100644
--- a/05_join.html
+++ b/05_join.html
@@ -243,11 +243,6 @@
Outline
-
-
- Installing libraries
-
-
Getting photometry data
@@ -361,24 +356,6 @@ The following figure from the paper is a color-magnitude diagram for the stars s
Write ADQL queries involving JOIN operations.
-
-Installing libraries¶
-If you are running this notebook on Colab, you can run the following cell to install the libraries we’ll use.
-If you are running this notebook on your own computer, you might have to install these libraries yourself. See the instructions in the preface.
-
-
-# If we're running on Colab, install libraries
-
-import sys
-IN_COLAB = 'google.colab' in sys.modules
-
-if IN_COLAB:
- !pip install astroquery
-
-
-
-
-
Getting photometry data¶
The Gaia dataset contains some photometry data, including the variable bp_rp, which contains BP-RP color (the difference in mean flux between the BP and RP bands).
@@ -414,6 +391,13 @@ Here’s the metadata for
+
+Retrieving table 'gaiadr2.panstarrs1_best_neighbour'
+Parsing table 'gaiadr2.panstarrs1_best_neighbour'...
+Done.
+
+
+
@@ -421,6 +405,16 @@ Here’s the metadata for
+
+TAP Table name: gaiadr2.gaiadr2.panstarrs1_best_neighbour
+Description: Pan-STARRS1 BestNeighbour table lists each matched Gaia object with its
+best neighbour in the external catalogue.
+There are 1 327 157 objects in the filtered version of Pan-STARRS1 used
+to compute this cross-match that have too early epochMean.
+Num. columns: 7
+
+
+
And here are the columns.
@@ -430,6 +424,17 @@ Here’s the metadata for
+
+source_id
+original_ext_source_id
+angular_distance
+number_of_neighbours
+number_of_mates
+best_neighbour_multiplicity
+gaia_astrometric_params
+
+
+
Here’s the documentation for these variables .
The ones we’ll use are:
@@ -458,6 +463,11 @@ Here’s the metadata for
+
+INFO: Query finished. [astroquery.utils.tap.core]
+
+
+
@@ -466,6 +476,17 @@ Here’s the metadata for
+
+Table length=5
+
+source_id number_of_neighbours number_of_mates original_ext_source_id
+int64 int32 int16 int64
+6745938972433480704 1 0 69742925668851205
+6030466788955954048 1 0 69742509325691172
+6756488099308169600 1 0 69742879438541228
+6700154994715046016 1 0 69743055581721207
+6757061941303252736 1 0 69742856540241198
+
@@ -477,6 +498,13 @@ Here’s the metadata for
+
+Retrieving table 'gaiadr2.panstarrs1_original_valid'
+Parsing table 'gaiadr2.panstarrs1_original_valid'...
+Done.
+
+
+
@@ -484,6 +512,77 @@ Here’s the metadata for
+
+TAP Table name: gaiadr2.gaiadr2.panstarrs1_original_valid
+Description: The Panoramic Survey Telescope and Rapid Response System (Pan-STARRS) is
+a system for wide-field astronomical imaging developed and operated by
+the Institute for Astronomy at the University of Hawaii. Pan-STARRS1
+(PS1) is the first part of Pan-STARRS to be completed and is the basis
+for Data Release 1 (DR1). The PS1 survey used a 1.8 meter telescope and
+its 1.4 Gigapixel camera to image the sky in five broadband filters (g,
+r, i, z, y).
+
+The current table contains a filtered subsample of the 10 723 304 629
+entries listed in the original ObjectThin table.
+We used only ObjectThin and MeanObject tables to extract
+panstarrs1OriginalValid table, this means that objects detected only in
+stack images are not included here. The main reason for us to avoid the
+use of objects detected in stack images is that their astrometry is not
+as good as the mean objects astrometry: “The stack positions (raStack,
+decStack) have considerably larger systematic astrometric errors than
+the mean epoch positions (raMean, decMean).” The astrometry for the
+MeanObject positions uses Gaia DR1 as a reference catalog, while the
+stack positions use 2MASS as a reference catalog.
+
+In details, we filtered out all objects where:
+
+- nDetections = 1
+
+- no good quality data in Pan-STARRS, objInfoFlag 33554432 not set
+
+- mean astrometry could not be measured, objInfoFlag 524288 set
+
+- stack position used for mean astrometry, objInfoFlag 1048576 set
+
+- error on all magnitudes equal to 0 or to -999;
+
+- all magnitudes set to -999;
+
+- error on RA or DEC greater than 1 arcsec.
+
+The number of objects in panstarrs1OriginalValid is 2 264 263 282.
+
+The panstarrs1OriginalValid table contains only a subset of the columns
+available in the combined ObjectThin and MeanObject tables. A
+description of the original ObjectThin and MeanObjects tables can be
+found at:
+https://outerspace.stsci.edu/display/PANSTARRS/PS1+Database+object+and+detection+tables
+
+Download:
+http://mastweb.stsci.edu/ps1casjobs/home.aspx
+Documentation:
+https://outerspace.stsci.edu/display/PANSTARRS
+http://pswww.ifa.hawaii.edu/pswww/
+References:
+The Pan-STARRS1 Surveys, Chambers, K.C., et al. 2016, arXiv:1612.05560
+Pan-STARRS Data Processing System, Magnier, E. A., et al. 2016,
+arXiv:1612.05240
+Pan-STARRS Pixel Processing: Detrending, Warping, Stacking, Waters, C.
+Z., et al. 2016, arXiv:1612.05245
+Pan-STARRS Pixel Analysis: Source Detection and Characterization,
+Magnier, E. A., et al. 2016, arXiv:1612.05244
+Pan-STARRS Photometric and Astrometric Calibration, Magnier, E. A., et
+al. 2016, arXiv:1612.05242
+The Pan-STARRS1 Database and Data Products, Flewelling, H. A., et al.
+2016, arXiv:1612.05243
+
+Catalogue curator:
+SSDC - ASI Space Science Data Center
+https://www.ssdc.asi.it/
+Num. columns: 26
+
+
+
And here are the columns.
@@ -493,6 +592,36 @@ Here’s the metadata for
+
+obj_name
+obj_id
+ra
+dec
+ra_error
+dec_error
+epoch_mean
+g_mean_psf_mag
+g_mean_psf_mag_error
+g_flags
+r_mean_psf_mag
+r_mean_psf_mag_error
+r_flags
+i_mean_psf_mag
+i_mean_psf_mag_error
+i_flags
+z_mean_psf_mag
+z_mean_psf_mag_error
+z_flags
+y_mean_psf_mag
+y_mean_psf_mag_error
+y_flags
+n_detections
+zone_id
+obj_info_flag
+quality_flag
+
+
+
Here’s the documentation for these variables .
The ones we’ll use are:
@@ -519,6 +648,11 @@ Here’s the metadata for
+
+INFO: Query finished. [astroquery.utils.tap.core]
+
+
+
@@ -527,6 +661,18 @@ Here’s the metadata for
+
+Table length=5
+
+obj_id g_mean_psf_mag i_mean_psf_mag
+mag
+int64 float64 float64
+67130655389101425 -- 20.3516006469727
+67553305590067819 -- 19.779899597168
+67551423248967849 -- 19.8889007568359
+67132026238911331 -- 20.9062995910645
+67553513677687787 -- 21.2831001281738
+
The following figure shows how these tables are related.
@@ -565,6 +711,11 @@ As a starting place, let’s go all the way back to the cone search from Lesson
+
+INFO: Query finished. [astroquery.utils.tap.core]
+
+
+
@@ -573,6 +724,22 @@ As a starting place, let’s go all the way back to the cone search from Lesson
+
+Table length=10
+
+source_id
+int64
+3322773965056065536
+3322773758899157120
+3322774068134271104
+3322773930696320512
+3322774377374425728
+3322773724537891456
+3322773724537891328
+3322773930696321792
+3322773724537890944
+3322773930696322176
+
Now we can start adding features.
First, let’s replace source_id with a format specifier, columns:
@@ -599,6 +766,16 @@ First, let’s replace
+SELECT
+source_id, ra, dec, pmra, pmdec
+FROM gaiadr2.gaia_source
+WHERE 1=CONTAINS(
+ POINT(ra, dec),
+ CIRCLE(88.8, 7.4, 0.08333333))
+
+
+
And let’s run the query again.
@@ -607,6 +784,11 @@ First, let’s replace
+INFO: Query finished. [astroquery.utils.tap.core]
+
+
+
@@ -615,6 +797,33 @@ First, let’s replace
+Table length=594
+
+source_id ra dec pmra pmdec
+deg deg mas / yr mas / yr
+int64 float64 float64 float64 float64
+3322773965056065536 88.78178020183375 7.334936530583141 0.2980633722108194 -2.5057036964736907
+3322773758899157120 88.83227057144585 7.325577341429926 -- --
+3322774068134271104 88.8206092188033 7.353158142762173 -1.1065462654445488 -1.5260889445858044
+3322773930696320512 88.80843339290348 7.334853162299928 2.6074384482375215 -0.9292104395445717
+3322774377374425728 88.86806108182265 7.371287731275939 3.9555477866915383 -3.8676624830902435
+3322773724537891456 88.81308602813434 7.32488574492059 51.34995462741039 -33.078133430952086
+3322773724537891328 88.81570329208743 7.3223019772324855 1.9389988498951845 0.3110526931576576
+3322773930696321792 88.8050736770331 7.332371472206583 2.264014834476311 1.0772755505138008
+3322773724537890944 88.81241651540533 7.327864052479726 -0.36003627434304625 -6.393939291541333
+... ... ... ... ...
+3322962118983356032 88.76109637722949 7.380564308268047 -- --
+3322963527732585984 88.78813701704823 7.456696889759524 1.1363354614104264 -2.46251296961979
+3322961775385969024 88.79723215862369 7.359756552906535 2.121021366548921 -6.605711792572964
+3322962084625312512 88.78286756313868 7.384598632215225 -0.09350717810996487 1.3495903680571226
+3322962939322692608 88.73289357818679 7.407688975612043 -0.11002934783569704 1.002126813991455
+3322963768250760576 88.7592444035961 7.469624531882018 -- --
+3322963459013111808 88.80348931842845 7.438699901204871 0.800833828337078 -3.3780655466364626
+3322963355935626368 88.75528507586058 7.427795463027667 -- --
+3322963287216149888 88.7658164932195 7.415726370886557 2.3743092647634034 -0.5046963243400879
+3322962015904143872 88.74740822271643 7.387057037713974 -0.7201178533250112 0.5565841272341593
+
@@ -666,6 +875,18 @@ Here’s the complete query, including the columns we want from the Gaia and bes
+
+SELECT
+gaia.source_id, gaia.ra, gaia.dec, gaia.pmra, gaia.pmdec, best.best_neighbour_multiplicity, best.number_of_mates
+FROM gaiadr2.gaia_source AS gaia
+JOIN gaiadr2.panstarrs1_best_neighbour AS best
+ ON gaia.source_id = best.source_id
+WHERE 1=CONTAINS(
+ POINT(gaia.ra, gaia.dec),
+ CIRCLE(88.8, 7.4, 0.08333333))
+
+
+
@@ -673,6 +894,11 @@ Here’s the complete query, including the columns we want from the Gaia and bes
+
+INFO: Query finished. [astroquery.utils.tap.core]
+
+
+
@@ -681,6 +907,33 @@ Here’s the complete query, including the columns we want from the Gaia and bes
+
+Table length=490
+
+source_id ra dec pmra pmdec best_neighbour_multiplicity number_of_mates
+deg deg mas / yr mas / yr
+int64 float64 float64 float64 float64 int16 int16
+3322773965056065536 88.78178020183375 7.334936530583141 0.2980633722108194 -2.5057036964736907 1 0
+3322774068134271104 88.8206092188033 7.353158142762173 -1.1065462654445488 -1.5260889445858044 1 0
+3322773930696320512 88.80843339290348 7.334853162299928 2.6074384482375215 -0.9292104395445717 1 0
+3322774377374425728 88.86806108182265 7.371287731275939 3.9555477866915383 -3.8676624830902435 1 0
+3322773724537891456 88.81308602813434 7.32488574492059 51.34995462741039 -33.078133430952086 1 0
+3322773724537891328 88.81570329208743 7.3223019772324855 1.9389988498951845 0.3110526931576576 1 0
+3322773930696321792 88.8050736770331 7.332371472206583 2.264014834476311 1.0772755505138008 1 0
+3322773724537890944 88.81241651540533 7.327864052479726 -0.36003627434304625 -6.393939291541333 1 0
+3322773930696322176 88.80128682574824 7.334292036448643 -- -- 1 0
+... ... ... ... ... ... ...
+3322962359501481088 88.85037722908271 7.402162717053584 2.058216493648542 -2.249255322558584 1 0
+3322962393861228544 88.82108234976155 7.4044425496203 -0.916760881643629 -1.1113319053861441 1 0
+3322955831151254912 88.74620347799508 7.342728619145855 0.1559833902071379 -1.750598455959734 1 0
+3322962118983356032 88.76109637722949 7.380564308268047 -- -- 1 0
+3322963527732585984 88.78813701704823 7.456696889759524 1.1363354614104264 -2.46251296961979 1 0
+3322961775385969024 88.79723215862369 7.359756552906535 2.121021366548921 -6.605711792572964 1 0
+3322962084625312512 88.78286756313868 7.384598632215225 -0.09350717810996487 1.3495903680571226 1 0
+3322962939322692608 88.73289357818679 7.407688975612043 -0.11002934783569704 1.002126813991455 1 0
+3322963459013111808 88.80348931842845 7.438699901204871 0.800833828337078 -3.3780655466364626 1 0
+3322962015904143872 88.74740822271643 7.387057037713974 -0.7201178533250112 0.5565841272341593 1 0
+
Notice that this result has fewer rows than the previous result.
That’s because there are sources in the Gaia table with no corresponding source in the Pan-STARRS table.
@@ -697,10 +950,82 @@ This default is called an “inner” join because the results include only the
The result should contain 490 rows and 9 columns.
-# Solution goes here
+# Solution
+
+query_base = """SELECT
+{columns}
+FROM gaiadr2.gaia_source as gaia
+JOIN gaiadr2.panstarrs1_best_neighbour as best
+ ON gaia.source_id = best.source_id
+JOIN gaiadr2.panstarrs1_original_valid as ps
+ ON best.original_ext_source_id = ps.obj_id
+WHERE 1=CONTAINS(
+ POINT(gaia.ra, gaia.dec),
+ CIRCLE(88.8, 7.4, 0.08333333))
+"""
+
+column_list = ['gaia.source_id',
+ 'gaia.ra',
+ 'gaia.dec',
+ 'gaia.pmra',
+ 'gaia.pmdec',
+ 'best.best_neighbour_multiplicity',
+ 'best.number_of_mates',
+ 'ps.g_mean_psf_mag',
+ 'ps.i_mean_psf_mag']
+
+columns = ', '.join(column_list)
+
+query = query_base.format(columns=columns)
+print(query)
+
+job = Gaia.launch_job_async(query=query)
+results = job.get_results()
+results
+
+SELECT
+gaia.source_id, gaia.ra, gaia.dec, gaia.pmra, gaia.pmdec, best.best_neighbour_multiplicity, best.number_of_mates, ps.g_mean_psf_mag, ps.i_mean_psf_mag
+FROM gaiadr2.gaia_source as gaia
+JOIN gaiadr2.panstarrs1_best_neighbour as best
+ ON gaia.source_id = best.source_id
+JOIN gaiadr2.panstarrs1_original_valid as ps
+ ON best.original_ext_source_id = ps.obj_id
+WHERE 1=CONTAINS(
+ POINT(gaia.ra, gaia.dec),
+ CIRCLE(88.8, 7.4, 0.08333333))
+
+INFO: Query finished. [astroquery.utils.tap.core]
+
+
+Table length=490
+
+source_id ra dec pmra pmdec best_neighbour_multiplicity number_of_mates g_mean_psf_mag i_mean_psf_mag
+deg deg mas / yr mas / yr mag
+int64 float64 float64 float64 float64 int16 int16 float64 float64
+3322773965056065536 88.78178020183375 7.334936530583141 0.2980633722108194 -2.5057036964736907 1 0 19.9431991577148 17.4221992492676
+3322774068134271104 88.8206092188033 7.353158142762173 -1.1065462654445488 -1.5260889445858044 1 0 18.6212005615234 16.6007995605469
+3322773930696320512 88.80843339290348 7.334853162299928 2.6074384482375215 -0.9292104395445717 1 0 -- 20.2203998565674
+3322774377374425728 88.86806108182265 7.371287731275939 3.9555477866915383 -3.8676624830902435 1 0 18.0676002502441 16.9762001037598
+3322773724537891456 88.81308602813434 7.32488574492059 51.34995462741039 -33.078133430952086 1 0 20.1907005310059 17.8700008392334
+3322773724537891328 88.81570329208743 7.3223019772324855 1.9389988498951845 0.3110526931576576 1 0 22.6308002471924 19.6004009246826
+3322773930696321792 88.8050736770331 7.332371472206583 2.264014834476311 1.0772755505138008 1 0 21.2119998931885 18.3528003692627
+3322773724537890944 88.81241651540533 7.327864052479726 -0.36003627434304625 -6.393939291541333 1 0 20.8094005584717 18.1343002319336
+3322773930696322176 88.80128682574824 7.334292036448643 -- -- 1 0 19.7306003570557 --
+... ... ... ... ... ... ... ... ...
+3322962359501481088 88.85037722908271 7.402162717053584 2.058216493648542 -2.249255322558584 1 0 17.4034996032715 15.9040002822876
+3322962393861228544 88.82108234976155 7.4044425496203 -0.916760881643629 -1.1113319053861441 1 0 -- --
+3322955831151254912 88.74620347799508 7.342728619145855 0.1559833902071379 -1.750598455959734 1 0 18.4960994720459 17.3892993927002
+3322962118983356032 88.76109637722949 7.380564308268047 -- -- 1 0 18.0643997192383 16.7395000457764
+3322963527732585984 88.78813701704823 7.456696889759524 1.1363354614104264 -2.46251296961979 1 0 17.8034992218018 16.1214008331299
+3322961775385969024 88.79723215862369 7.359756552906535 2.121021366548921 -6.605711792572964 1 0 18.2070007324219 15.9947996139526
+3322962084625312512 88.78286756313868 7.384598632215225 -0.09350717810996487 1.3495903680571226 1 0 16.7978992462158 15.1180000305176
+3322962939322692608 88.73289357818679 7.407688975612043 -0.11002934783569704 1.002126813991455 1 0 17.18630027771 16.3645992279053
+3322963459013111808 88.80348931842845 7.438699901204871 0.800833828337078 -3.3780655466364626 1 0 -- 16.294900894165
+3322962015904143872 88.74740822271643 7.387057037713974 -0.7201178533250112 0.5565841272341593 1 0 18.4706993103027 16.8038005828857
+
@@ -735,6 +1060,13 @@ The result should contain 490 rows and 9 columns.
+
+point_list 135.306, 8.39862, 126.51, 13.4449, 163.017, 54...
+pm_point_list -4.05037121,-14.75623261, -3.41981085,-14.723...
+dtype: object
+
+
+
Now we can assemble the query.
@@ -749,6 +1081,19 @@ The result should contain 490 rows and 9 columns.
+
+SELECT
+source_id, ra, dec, pmra, pmdec
+FROM gaiadr2.gaia_source
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+ AND 1 = CONTAINS(POINT(ra, dec),
+ POLYGON(135.306, 8.39862, 126.51, 13.4449, 163.017, 54.2424, 172.933, 46.4726, 135.306, 8.39862))
+ AND 1 = CONTAINS(POINT(pmra, pmdec),
+ POLYGON( -4.05037121,-14.75623261, -3.41981085,-14.72365546, -3.03521988,-14.44357135, -2.26847919,-13.7140236 , -2.61172203,-13.24797471, -2.73471401,-13.09054471, -3.19923146,-12.5942653 , -3.34082546,-12.47611926, -5.67489413,-11.16083338, -5.95159272,-11.10547884, -6.42394023,-11.05981295, -7.09631023,-11.95187806, -7.30641519,-12.24559977, -7.04016696,-12.88580702, -6.00347705,-13.75912098, -4.42442296,-14.74641176))
+
+
+
Again, let’s run it to make sure we are starting with a working query.
@@ -757,6 +1102,11 @@ The result should contain 490 rows and 9 columns.
+
+INFO: Query finished. [astroquery.utils.tap.core]
+
+
+
@@ -765,6 +1115,33 @@ The result should contain 490 rows and 9 columns.
+
+Table length=7345
+
+source_id ra dec pmra pmdec
+deg deg mas / yr mas / yr
+int64 float64 float64 float64 float64
+635559124339440000 137.58671691646745 19.1965441084838 -3.770521900009566 -12.490481778113859
+635860218726658176 138.5187065217173 19.09233926905897 -5.941679495793577 -11.346409129876392
+635674126383965568 138.8428741026386 19.031798198627634 -3.8970011609340207 -12.702779525389634
+635535454774983040 137.8377518255436 18.864006786112604 -4.335040664412791 -14.492308604905652
+635497276810313600 138.0445160213759 19.00947118796605 -7.1729306406216615 -12.291499169815987
+635614168640132864 139.59219748145836 18.807955539071433 -3.309602916796381 -13.708904908478631
+635821843194387840 139.88094034815086 19.62185456718988 -6.544201177153814 -12.55978220563274
+635551706931167104 138.04665586038192 19.248909662830798 -6.224595114220405 -12.224246333795001
+635518889086133376 137.2374229207837 18.7428630711791 -3.3186800714801046 -12.710314902969365
+... ... ... ... ...
+612282738058264960 134.0445768189235 18.11915820167003 -2.5972485319419127 -13.651740929272187
+612485911486166656 134.96582769047063 19.309965857307247 -4.519325315774155 -11.998725329569156
+612386332668697600 135.45701048323093 18.63266345155342 -5.07684899854408 -12.436641304786672
+612296172717818624 133.80060286960668 18.08186533343457 -6.112792578821885 -12.50750861370402
+612250375480101760 134.64754712466774 18.122419425065015 -2.8969262278467127 -14.061676353845487
+612394926899159168 135.51997060013844 18.817675531233004 -3.9968965218753763 -13.526821099431533
+612288854091187712 134.07970733489358 18.15424015818678 -5.96977151283562 -11.162471664228455
+612428870024913152 134.8384242853297 18.758253070693225 -4.0022333299353825 -14.247379430659198
+612256418500423168 134.90752972739924 18.280596648172743 -6.109836304219565 -12.145212331165776
+612429144902815104 134.77293979509543 18.73628415871413 -5.257085979310591 -13.962312685889454
+
Exercise¶
@@ -774,10 +1151,82 @@ Format the query base using the column names in
-# Solution goes here
+# Solution
+
+query7_base = """
+SELECT
+{columns}
+FROM gaiadr2.gaia_source as gaia
+JOIN gaiadr2.panstarrs1_best_neighbour as best
+ ON gaia.source_id = best.source_id
+JOIN gaiadr2.panstarrs1_original_valid as ps
+ ON best.original_ext_source_id = ps.obj_id
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+ AND 1 = CONTAINS(POINT(gaia.ra, gaia.dec),
+ POLYGON({point_list}))
+ AND 1 = CONTAINS(POINT(gaia.pmra, gaia.pmdec),
+ POLYGON({pm_point_list}))
+"""
+
+columns = ', '.join(column_list)
+
+query7 = query7_base.format(columns=columns,
+ point_list=point_series['point_list'],
+ pm_point_list=point_series['pm_point_list'])
+print(query7)
+
+
+job = Gaia.launch_job_async(query=query7)
+results = job.get_results()
+results
+
+SELECT
+gaia.source_id, gaia.ra, gaia.dec, gaia.pmra, gaia.pmdec, best.best_neighbour_multiplicity, best.number_of_mates, ps.g_mean_psf_mag, ps.i_mean_psf_mag
+FROM gaiadr2.gaia_source as gaia
+JOIN gaiadr2.panstarrs1_best_neighbour as best
+ ON gaia.source_id = best.source_id
+JOIN gaiadr2.panstarrs1_original_valid as ps
+ ON best.original_ext_source_id = ps.obj_id
+WHERE parallax < 1
+ AND bp_rp BETWEEN -0.75 AND 2
+ AND 1 = CONTAINS(POINT(gaia.ra, gaia.dec),
+ POLYGON(135.306, 8.39862, 126.51, 13.4449, 163.017, 54.2424, 172.933, 46.4726, 135.306, 8.39862))
+ AND 1 = CONTAINS(POINT(gaia.pmra, gaia.pmdec),
+ POLYGON( -4.05037121,-14.75623261, -3.41981085,-14.72365546, -3.03521988,-14.44357135, -2.26847919,-13.7140236 , -2.61172203,-13.24797471, -2.73471401,-13.09054471, -3.19923146,-12.5942653 , -3.34082546,-12.47611926, -5.67489413,-11.16083338, -5.95159272,-11.10547884, -6.42394023,-11.05981295, -7.09631023,-11.95187806, -7.30641519,-12.24559977, -7.04016696,-12.88580702, -6.00347705,-13.75912098, -4.42442296,-14.74641176))
+
+INFO: Query finished. [astroquery.utils.tap.core]
+
+
+Table length=3725
+
+source_id ra dec pmra pmdec best_neighbour_multiplicity number_of_mates g_mean_psf_mag i_mean_psf_mag
+deg deg mas / yr mas / yr mag
+int64 float64 float64 float64 float64 int16 int16 float64 float64
+635860218726658176 138.5187065217173 19.09233926905897 -5.941679495793577 -11.346409129876392 1 0 17.8978004455566 17.5174007415771
+635674126383965568 138.8428741026386 19.031798198627634 -3.8970011609340207 -12.702779525389634 1 0 19.2873001098633 17.6781005859375
+635535454774983040 137.8377518255436 18.864006786112604 -4.335040664412791 -14.492308604905652 1 0 16.9237995147705 16.478099822998
+635497276810313600 138.0445160213759 19.00947118796605 -7.1729306406216615 -12.291499169815987 1 0 19.9242000579834 18.3339996337891
+635614168640132864 139.59219748145836 18.807955539071433 -3.309602916796381 -13.708904908478631 1 0 16.1515998840332 14.6662998199463
+635598607974369792 139.20920023089508 18.624132868942702 -6.124445176881091 -12.833824027100611 1 0 16.5223999023438 16.1375007629395
+635737661835496576 139.93327552473934 19.167962454651423 -7.119403303682826 -12.687947497633793 1 0 14.5032997131348 13.9849004745483
+635850945892748672 139.86542888472115 20.011312663154804 -3.786655365804428 -14.28415600718206 1 0 16.5174999237061 16.0450000762939
+635600532119713664 139.22869949616816 18.685939084485494 -3.9742788217925122 -12.342426623384245 1 0 20.4505996704102 19.5177001953125
+... ... ... ... ... ... ... ... ...
+612241781249124608 134.3755835065194 18.129179169751275 -2.831807894848964 -13.902118573613597 1 0 20.2343997955322 18.6518001556396
+612332147361443072 134.14584721363653 18.45685585044513 -6.234287981021865 -11.500464195695072 1 0 21.3848991394043 20.3076000213623
+612426744016802432 134.68522805061076 18.77090626983678 -3.7691372464459554 -12.889167493118862 1 0 17.8281002044678 17.4281005859375
+612331739340341760 134.12176196902254 18.42768872157865 -3.9894012386388735 -12.60504410507441 1 0 21.8656997680664 19.5223007202148
+612282738058264960 134.0445768189235 18.11915820167003 -2.5972485319419127 -13.651740929272187 1 0 22.5151996612549 19.9743995666504
+612386332668697600 135.45701048323093 18.63266345155342 -5.07684899854408 -12.436641304786672 1 0 19.3792991638184 17.9923000335693
+612296172717818624 133.80060286960668 18.08186533343457 -6.112792578821885 -12.50750861370402 1 0 17.4944000244141 16.926700592041
+612250375480101760 134.64754712466774 18.122419425065015 -2.8969262278467127 -14.061676353845487 1 0 15.3330001831055 14.6280002593994
+612394926899159168 135.51997060013844 18.817675531233004 -3.9968965218753763 -13.526821099431533 1 0 16.4414005279541 15.8212003707886
+612256418500423168 134.90752972739924 18.280596648172743 -6.109836304219565 -12.145212331165776 1 0 20.8715991973877 19.9612007141113
+
@@ -790,6 +1239,35 @@ Format the query base using the column names in
+<MaskedColumn name='best_neighbour_multiplicity' dtype='int16' description='Number of neighbours with same probability as best neighbour' length=3725>
+
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+...
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+
It looks like most of the values are 1, which is good; that means that for each candidate star we have identified exactly one source in Pan-STARRS that is likely to be the same star.
To check whether there are any values other than 1, we can convert this column to a Pandas Series and use describe, which we saw in in Lesson 3.
@@ -802,6 +1280,19 @@ Format the query base using the column names in
+count 3725.0
+mean 1.0
+std 0.0
+min 1.0
+25% 1.0
+50% 1.0
+75% 1.0
+max 1.0
+dtype: float64
+
+
+
In fact, 1 is the only value in the Series, so every candidate star has a single best match.
Similarly, number_of_mates indicates the number of other stars in Gaia that match with the same star in Pan-STARRS.
@@ -812,6 +1303,19 @@ Format the query base using the column names in
+count 3725.0
+mean 0.0
+std 0.0
+min 0.0
+25% 0.0
+50% 0.0
+75% 0.0
+max 0.0
+dtype: float64
+
+
+
All values in this column are 0, which means that for each match we found in Pan-STARRS, there are no other stars in Gaia that also match.
Detail: The table also contains number_of_neighbors which is the number of stars in Pan-STARRS that match in terms of position, before using other criteria to choose the most likely match. But we are more interested in the final match, using both criteria.
@@ -877,6 +1381,9 @@ Format the query base using the column names in
+
+
The result is similar to what we saw in the previous lesson, except that have fewer stars now, because we did not find photometry data for all of the candidate sources.
@@ -903,6 +1410,11 @@ The HDF file should already exist, so we’ll add
+3.5835609436035156
+
+
+
@@ -933,6 +1445,11 @@ We won’t cover all of them, but one other important one is
+0.7606849670410156
+
+
+
We can see the first few lines like this:
@@ -952,6 +1469,15 @@ We won’t cover all of them, but one other important one is
+,source_id,ra,dec,pmra,pmdec,best_neighbour_multiplicity,number_of_mates,g_mean_psf_mag,i_mean_psf_mag,phi1,phi2,pm_phi1,pm_phi2
+
+0,635860218726658176,138.5187065217173,19.09233926905897,-5.941679495793577,-11.346409129876392,1,0,17.8978004455566,17.5174007415771,-59.247329893833296,-2.016078400820631,-7.527126084640531,1.7487794924176672
+
+1,635674126383965568,138.8428741026386,19.031798198627634,-3.8970011609340207,-12.702779525389634,1,0,19.2873001098633,17.6781005859375,-59.13339098769217,-2.306900745179831,-7.560607655557415,-0.7417999555980248
+
+
+
The CSV file contains the names of the columns, but not the data types.
We can read the CSV file back like this:
@@ -969,6 +1495,92 @@ We won’t cover all of them, but one other important one is
+
+
+
+
+
+
+ source_id
+ ra
+ dec
+ pmra
+ pmdec
+ best_neighbour_multiplicity
+ number_of_mates
+ g_mean_psf_mag
+ i_mean_psf_mag
+ phi1
+ phi2
+ pm_phi1
+ pm_phi2
+
+
+
+
+ 0
+ 635860218726658176
+ 138.518707
+ 19.092339
+ -5.941679
+ -11.346409
+ 1
+ 0
+ 17.8978
+ 17.517401
+ -59.247330
+ -2.016078
+ -7.527126
+ 1.748779
+
+
+ 1
+ 635674126383965568
+ 138.842874
+ 19.031798
+ -3.897001
+ -12.702780
+ 1
+ 0
+ 19.2873
+ 17.678101
+ -59.133391
+ -2.306901
+ -7.560608
+ -0.741800
+
+
+ 2
+ 635535454774983040
+ 137.837752
+ 18.864007
+ -4.335041
+ -14.492309
+ 1
+ 0
+ 16.9238
+ 16.478100
+ -59.785300
+ -1.594569
+ -9.357536
+ -1.218492
+
+
+
+
@@ -976,6 +1588,96 @@ We won’t cover all of them, but one other important one is
+
+
+
+
+
+
+ Unnamed: 0
+ source_id
+ ra
+ dec
+ pmra
+ pmdec
+ best_neighbour_multiplicity
+ number_of_mates
+ g_mean_psf_mag
+ i_mean_psf_mag
+ phi1
+ phi2
+ pm_phi1
+ pm_phi2
+
+
+
+
+ 0
+ 0
+ 635860218726658176
+ 138.518707
+ 19.092339
+ -5.941679
+ -11.346409
+ 1
+ 0
+ 17.8978
+ 17.517401
+ -59.247330
+ -2.016078
+ -7.527126
+ 1.748779
+
+
+ 1
+ 1
+ 635674126383965568
+ 138.842874
+ 19.031798
+ -3.897001
+ -12.702780
+ 1
+ 0
+ 19.2873
+ 17.678101
+ -59.133391
+ -2.306901
+ -7.560608
+ -0.741800
+
+
+ 2
+ 2
+ 635535454774983040
+ 137.837752
+ 18.864007
+ -4.335041
+ -14.492309
+ 1
+ 0
+ 16.9238
+ 16.478100
+ -59.785300
+ -1.594569
+ -9.357536
+ -1.218492
+
+
+
+
Notice that the index in candidate_df has become an unnamed column in read_back_csv. The Pandas functions for writing and reading CSV files provide options to avoid that problem, but this is an example of the kind of thing that can go wrong with CSV files.
diff --git a/06_photo.html b/06_photo.html
index 57657ec..af4b435 100644
--- a/06_photo.html
+++ b/06_photo.html
@@ -412,6 +412,9 @@ The input can be an Astropy
+
+
+
Our figure does not look exactly like the one in the paper because we are working with a smaller region of the sky, so we don’t have as many stars. But we can see an overdense region in the lower left that contains stars with the photometry we expect for GD-1.
In the next section we’ll use an isochrone to specify a polygon that contains this overdense regioin.
@@ -456,6 +459,11 @@ The input can be an Astropy
+
+Reading in: MIST_iso_5fd2532653c27.iso.cmd
+
+
+
The result is an ISOCMD object.
@@ -464,6 +472,11 @@ The input can be an Astropy
+
+read_mist_models.ISOCMD
+
+
+
It contains a list of arrays, one for each isochrone.
@@ -472,6 +485,11 @@ The input can be an Astropy
+
+list
+
+
+
We only got one isochrone.
@@ -480,6 +498,11 @@ The input can be an Astropy
+
+1
+
+
+
So we can select it like this:
@@ -496,6 +519,11 @@ The input can be an Astropy
+
+numpy.ndarray
+
+
+
But it’s an unusual NumPy array, because it contains names for the columns.
@@ -504,6 +532,11 @@ The input can be an Astropy
+
+dtype([('EEP', '<i4'), ('isochrone_age_yr', '<f8'), ('initial_mass', '<f8'), ('star_mass', '<f8'), ('log_Teff', '<f8'), ('log_g', '<f8'), ('log_L', '<f8'), ('[Fe/H]_init', '<f8'), ('[Fe/H]', '<f8'), ('PS_g', '<f8'), ('PS_r', '<f8'), ('PS_i', '<f8'), ('PS_z', '<f8'), ('PS_y', '<f8'), ('PS_w', '<f8'), ('PS_open', '<f8'), ('phase', '<f8')])
+
+
+
Which means we can select columns using the bracket operator:
@@ -512,6 +545,11 @@ The input can be an Astropy
+
+array([0., 0., 0., ..., 6., 6., 6.])
+
+
+
We can use phase to select the part of the isochrone for stars in the main sequence and red giant phases.
@@ -521,6 +559,11 @@ The input can be an Astropy
+
+354
+
+
+
@@ -529,6 +572,11 @@ The input can be an Astropy
+
+354
+
+
+
The other two columns we’ll use are PS_g and PS_i, which contain simulated photometry data for stars with the given age and metallicity, based on a model of the Pan-STARRS sensors.
We’ll use these columns to superimpose the isochrone on the color-magnitude diagram, but first we have to use a distance modulus to scale the isochrone based on the estimated distance of GD-1.
@@ -544,6 +592,11 @@ The input can be an Astropy
+
+14.4604730134524
+
+
+
Now we can compute the scaled magnitude and color of the isochrone.
@@ -562,6 +615,9 @@ The input can be an Astropy
+
+
+
The theoretical isochrone passes through the overdense region where we expect to find stars in GD-1.
Let’s save this result so we can reload it later without repeating the steps in this section.
@@ -578,6 +634,58 @@ The input can be an Astropy
+
+
+
+
+
+
+
+ mag_g
+ color_g_i
+
+
+
+
+ 0
+ 28.294743
+ 2.195021
+
+
+ 1
+ 28.189718
+ 2.166076
+
+
+ 2
+ 28.051761
+ 2.129312
+
+
+ 3
+ 27.916194
+ 2.093721
+
+
+ 4
+ 27.780024
+ 2.058585
+
+
+
+
And then save it.
@@ -609,6 +717,58 @@ The input can be an Astropy
+
+
+
+
+
+
+
+ mag_g
+ color_g_i
+
+
+
+
+ 0
+ 28.294743
+ 2.195021
+
+
+ 1
+ 28.189718
+ 2.166076
+
+
+ 2
+ 28.051761
+ 2.129312
+
+
+ 3
+ 27.916194
+ 2.093721
+
+
+ 4
+ 27.780024
+ 2.058585
+
+
+
+
Here’s what the isochrone looks like on the color-magnitude diagram.
@@ -618,6 +778,9 @@ The input can be an Astropy
+
+
+
In the bottom half of the figure, the isochrone passes through the overdense region where the stars are likely to belong to GD-1.
In the top half, the isochrone passes through other regions where the stars have higher magnitude and metallicity than we expect for stars in GD-1.
@@ -632,6 +795,11 @@ The input can be an Astropy
+
+117
+
+
+
We can use it to select the corresponding rows in iso_df:
@@ -641,6 +809,58 @@ The input can be an Astropy
+
+
+
+
+
+
+
+ mag_g
+ color_g_i
+
+
+
+
+ 94
+ 21.411746
+ 0.692171
+
+
+ 95
+ 21.322466
+ 0.670238
+
+
+ 96
+ 21.233380
+ 0.648449
+
+
+ 97
+ 21.144427
+ 0.626924
+
+
+ 98
+ 21.054549
+ 0.605461
+
+
+
+
Now, to select the stars in the overdense region, we have to define a polygon that includes stars near the isochrone.
The original paper uses the following formulas to define the left and right boundaries.
@@ -676,6 +896,9 @@ The input can be an Astropy
+
+
+
@@ -711,6 +934,11 @@ The input can be an Astropy
+
+(234,)
+
+
+
And a corresponding loop with the elements of g in forward and reverse order.
@@ -720,6 +948,11 @@ The input can be an Astropy
+
+(234,)
+
+
+
Here’s what the loop looks like.
@@ -729,6 +962,9 @@ The input can be an Astropy
+
+
+
To make a Polygon, it will be convenient to put color_loop and mag_loop into a DataFrame:
@@ -740,6 +976,58 @@ The input can be an Astropy
+
+
+
+
+
+
+
+ color_loop
+ mag_loop
+
+
+
+
+ 0
+ 0.632171
+ 21.411746
+
+
+ 1
+ 0.610238
+ 21.322466
+
+
+ 2
+ 0.588449
+ 21.233380
+
+
+ 3
+ 0.566924
+ 21.144427
+
+
+ 4
+ 0.545461
+ 21.054549
+
+
+
+
Now we can pass loop_df to Polygon:
@@ -751,6 +1039,11 @@ The input can be an Astropy
+
+<matplotlib.patches.Polygon at 0x7f439d33fdf0>
+
+
+
The result is a Polygon object , which provides contains_points, which figures out which points are inside the polygon.
To test it, we’ll create a list with two points, one inside the polygon and one outside.
@@ -770,6 +1063,11 @@ The input can be an Astropy
+
+array([ True, False])
+
+
+
The result is an array of Boolean values.
We are almost ready to select stars whose photometry data falls in this polygon. But first we need to do some data cleaning.
@@ -805,6 +1103,58 @@ We’ll put color and magnitude data from
+
+
+
+
+
+
+ color
+ mag
+
+
+
+
+ 0
+ 0.3804
+ 17.8978
+
+
+ 1
+ 1.6092
+ 19.2873
+
+
+ 2
+ 0.4457
+ 16.9238
+
+
+ 3
+ 1.5902
+ 19.9242
+
+
+ 4
+ 1.4853
+ 16.1516
+
+
+
+
Which we can pass to contains_points:
@@ -814,6 +1164,11 @@ We’ll put color and magnitude data from
+array([False, False, False, ..., False, False, False])
+
+
+
The result is a Boolean array. We can use sum to see how many stars fall in the polygon.
@@ -822,6 +1177,11 @@ We’ll put color and magnitude data from
+454
+
+
+
Now we can use inside as a mask to select stars that fall inside the polygon.
@@ -844,6 +1204,9 @@ We’ll put color and magnitude data from
+
+
It looks like the selected stars are, in fact, inside the polygon, which means they have photometry data consistent with GD-1.
Finally, we can plot the coordinates of the selected stars:
@@ -862,6 +1225,9 @@ We’ll put color and magnitude data from
+
+
This example includes two new Matplotlib commands:
@@ -890,6 +1256,11 @@ We’ll put color and magnitude data from
+3.6441001892089844
+
+
+
diff --git a/07_plot.html b/07_plot.html
index 80e445f..00f906f 100644
--- a/07_plot.html
+++ b/07_plot.html
@@ -406,7 +406,36 @@
-# Solution goes here
+# Solution
+
+# Some topics that might come up in this discussion:
+
+# 1. The primary result is that the multiple stages of selection
+# make it possible to separate likely candidates from the
+# background more effectively than in previous work, which makes
+# it possible to see the structure of GD-1 in "unprecedented detail".
+
+# 2. The figure documents the selection process as a sequence of
+# steps. Reading right-to-left, top-to-bottom, we see selection
+# based on proper motion, the results of the first selection,
+# selection based on color and magnitude, and the results of the
+# second selection. So this figure documents the methodology and
+# presents the primary result.
+
+# 3. It's mostly black and white, with minimal use of color, so
+# it will work well in print. The annotations in the bottom
+# left panel guide the reader to the most important results.
+# It contains enough technical detail for a professional audience,
+# but most of it is also comprehensible to a more general audience.
+# The two left panels have the same dimensions and their axes are
+# aligned.
+
+# 4. Since the panels represent a sequence, it might be better to
+# arrange them left-to-right. The placement and size of the axis
+# labels could be tweaked. The entire figure could be a little
+# bigger to match the width and proportion of the caption.
+# The top left panel has unnused white space (but that leaves
+# space for the annotations in the bottom left).
@@ -471,6 +500,9 @@
+
+
+
@@ -492,7 +524,23 @@
And here is some additional information about text and arrows.
-# Solution goes here
+# Solution
+
+# plt.axvline(-55, ls='--', color='gray',
+# alpha=0.4, dashes=(6,4), lw=2)
+# plt.text(-60, 5.5, 'Previously\nundetected',
+# fontsize='small', ha='right', va='top');
+
+# arrowprops=dict(color='gray', shrink=0.05, width=1.5,
+# headwidth=6, headlength=8, alpha=0.4)
+
+# plt.annotate('Spur', xy=(-33, 2), xytext=(-35, 5.5),
+# arrowprops=arrowprops,
+# fontsize='small')
+
+# plt.annotate('Gap', xy=(-22, -1), xytext=(-25, -5.5),
+# arrowprops=arrowprops,
+# fontsize='small')
@@ -519,7 +567,9 @@
Read the documentation of tick_params and use it to put ticks on the top and right sides of the axes.
-# Solution goes here
+# Solution
+
+# plt.gca().tick_params(top=True, right=True)
@@ -536,6 +586,11 @@
+
+10.0
+
+
+
And sets it to a new value:
@@ -560,6 +615,36 @@
+
+['Solarize_Light2',
+ '_classic_test_patch',
+ 'bmh',
+ 'classic',
+ 'dark_background',
+ 'fast',
+ 'fivethirtyeight',
+ 'ggplot',
+ 'grayscale',
+ 'seaborn',
+ 'seaborn-bright',
+ 'seaborn-colorblind',
+ 'seaborn-dark',
+ 'seaborn-dark-palette',
+ 'seaborn-darkgrid',
+ 'seaborn-deep',
+ 'seaborn-muted',
+ 'seaborn-notebook',
+ 'seaborn-paper',
+ 'seaborn-pastel',
+ 'seaborn-poster',
+ 'seaborn-talk',
+ 'seaborn-ticks',
+ 'seaborn-white',
+ 'seaborn-whitegrid',
+ 'tableau-colorblind10']
+
+
+
Note that seaborn-paper, seaborn-talk and seaborn-poster are particularly intended to prepare versions of a figure with text sizes and other features that work well in papers, talks, and posters.
To use any of these style sheets, run plt.style.use like this:
@@ -674,6 +759,14 @@
+
+array([[-8.9, -2.2],
+ [-8.9, 1. ],
+ [-6.9, 1. ],
+ [-6.9, -2.2]])
+
+
+
The following function takes a DataFrame as a parameter, plots the proper motion for each star, and adds a shaded Polygon to show the region we selected.
@@ -707,6 +800,9 @@
+
+
+
@@ -745,6 +841,9 @@
+
+
+
@@ -781,6 +880,9 @@
+
+
+
And here’s how we read it back.
@@ -791,6 +893,58 @@
+
+
+
+
+
+
+
+ color_loop
+ mag_loop
+
+
+
+
+ 0
+ 0.632171
+ 21.411746
+
+
+ 1
+ 0.610238
+ 21.322466
+
+
+ 2
+ 0.588449
+ 21.233380
+
+
+ 3
+ 0.566924
+ 21.144427
+
+
+ 4
+ 0.545461
+ 21.054549
+
+
+
+
Exercise¶
@@ -798,7 +952,11 @@
Hint: pass coords as an argument to Polygon and plot it using add_patch.
-# Solution goes here
+# Solution
+
+# poly = Polygon(loop_df, closed=True,
+# facecolor='C1', alpha=0.4)
+# plt.gca().add_patch(poly)
@@ -837,6 +995,9 @@
+
+
+
We use plt.tight_layout at the end, which adjusts the sizes of the panels to make sure the titles and axis labels don’t overlap.
As an exercise, see what happens if you leave out tight_layout.
@@ -872,6 +1033,9 @@
+
+
+
This is looking more and more like the figure in the paper.
@@ -879,7 +1043,27 @@
In this example, the ratio of the widths of the panels is 3:1. How would you adjust it if you wanted the ratio to be 3:2?
-# Solution goes here
+# Solution
+
+# plt.figure(figsize=(9, 4.5))
+
+# shape = (2, 5) # CHANGED
+# plt.subplot2grid(shape, (0, 0), colspan=3)
+# plot_first_selection(candidate_df)
+
+# plt.subplot2grid(shape, (0, 3), colspan=2) # CHANGED
+# plot_proper_motion(centerline_df)
+
+# plt.subplot2grid(shape, (1, 0), colspan=3)
+# plot_second_selection(winner_df)
+
+# plt.subplot2grid(shape, (1, 3), colspan=2) # CHANGED
+# plot_cmd(candidate_df)
+# poly = Polygon(coords, closed=True,
+# facecolor='C1', alpha=0.4)
+# plt.gca().add_patch(poly)
+
+# plt.tight_layout()
diff --git a/_images/04_select_16_0.png b/_images/04_select_16_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..42dcc0e96b7289babadc02f472ce4efb58355bc2
GIT binary patch
literal 83706
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
mw{)Q`S9y$c03-N0!)u4lZw9B8l{jx^
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