Accessing Roman Catalogs: Leveraging Ancillary Tables and Visualization to Apply Data Quality Cuts#


Learning Goals#

By the end of this tutorial, you will:

  • Understand how to launch and programatically control MAST Aladin to view targets on the sky from within a notebook, including overlaying a set of targets and observation footprints on the sky.

  • Understand how to use the MAST catalog schema browser to discover ancillary tables.

  • Understand how to “decode” catalog bitflags, aided by a bitflag “helper” class and the bitflag definition documentation (or database flag definition tables).

Table of Contents#

Introduction#

This notebook demonstrates how to leverage catalog queries together with MAST Aladin (to view objects on the sky) and the MAST Catalog Schema Browser to examine a selected sample, investigate data quality issues, and identify quality flags that can be used to refine the sample for analysis.

MAST will provide access to a range of Roman catalog products. In addition to analysis-ready measurements of observed and derived physical quantities, Roman catalogs will include ancillary information about, e.g., data quality, processing flags, and data provenance (such as the primary/overlap designation bit flag in the flagged_spatial_id identifiers in WFI multiband photometric source catalogs). This notebook demonstrates how to query candidate stars in the Galactic Bulge using multiband photometry, view the targets in MAST Aladin, and then examine data quality flag information from ancillary tables/columns to determine how to exclude data artifacts and spurious sources from the analysis.

Imports#

This tutorial makes use of the following packages:

from astroquery.mast import Catalogs, Observations
from astropy.coordinates import SkyCoord
from astropy.table import Table
import astropy.units as u
import numpy as np

from mast_aladin import MastAladin
from sidecar import Sidecar
import matplotlib.pyplot as plt
from flag_helper import PanSTARRSFlagHelper
import time

Identification and quality checks on candidate stars in the Galactic Bulge#

In this notebook, we will construct a color-magnitude diagram (\(r-i\) vs \(z\)) of stars in the Milky Way bulge near the Galactic Center, from which specific categories of stars can be selected for further analysis.

For demonstration purposes (as Roman catalogs are not yet available), PanSTARRS will be used as the example dataset. Similar to Roman (particularly the WFI multiband photometric source catalogs), PanSTARRS features a rich set of ancillary tables containing data quality and processing flags — providing a reasonable analog to demonstrate MAST data access and visualization tools that will be available for use with Roman.

(In the interest of simplicity, this example will omit crossmatching to Gaia to leverage Gaia-derived distances to exclude fore/background objects.)

Identifying candidate stars in the Galactic Bulge#

In this example, we aim to identify stars in the Galactic Bulge by constructing a \(r-i\) vs \(z\) color magnitude diagram. We begin with the following selection criteria:

  • Located within 0.1 degree of the Galactic center

  • Are point sources (excluding extended objects, such as galaxies).

  • Have measured \(r\), \(i\), \(z\) magnitudes

Querying the PanSTARRS catalog#

First, we consult the PanSTARRS DR2 catalogs documentation and the MAST Catalog Schema Browser to investigate the available tables and columns.

We determine that we can obtain all necessary information from the PanSTARRS DR2 “mean” table, which we can access using astroquery.mast.

To construct our query, we begin by obtaining the sky coordinates for the Galactic center using astropy.

# Use the Astropy SkyCoord name resolver to get 
# the position of the galactic center in the ICRS frame
gc = SkyCoord.from_name("Galactic center")
gc
<SkyCoord (ICRS): (ra, dec) in deg
    (266.41500889, -29.00611111)>

Based on PanSTARRS documentation (from astroquery.mast and the PanSTARRS DR2 documentation), we see the MeanObject catalog provides the relevant photometric information (in the columns rMeanPSFMag, iMeanPSFMag, zMeanPSFMag), as well as position information (RA/Dec).

Using the Catalogs module of astroquery.mast, we query the PanSTARRS mean_object table to perform a cone search of 0.1 degree around the Galactic Center, restricting the results to objcts with \(r\), \(i\), \(z\) magnitudes > -999 (the placeholder used for missing values in the database).

# Query the PanSTARRS DR2 Mean catalog aroung the 
# Galactic center, with available z,r,i magnitudes
sample = Catalogs.query_criteria(
    collection="ps1_dr2",
    catalog="mean_object",
    coordinates=gc,
    radius=0.1*u.deg,
    rMeanPSFMag=">-999",   # missing magnitudes are -999
    iMeanPSFMag=">-999",   # missing magnitudes are -999
    zMeanPSFMag=">-999",   # missing magnitudes are -999
)

(Note: the returned table column names are all lower case, which we use below.)

Next, to distinguish stars (point sources) from extended objects, we will make a cut using the PSF and Kron magnitudes in the i band, as point sources typically have iMeanPSFMag-iMeanKronMag <= 0.05 (as recommended in the PanSTARRS documentation).

sample = sample[
    sample['imeanpsfmag']-sample['imeankronmag'] <= 0.05
]

Finally, we will sort our sample by descending “objID” for consistent ordering.

sample.sort("objid", reverse=True)

Our resulting sample has 2906 candidate stars:

sample
Table length=2906
objnameobjaltname1objaltname2objaltname3objiduniquepspsobidippobjidsurveyidhtmidzoneidtessidprojectionidskycellidrandomidbatchiddvoregionidprocessingversionobjinfoflagqualityflagrastackdecstackrastackerrdecstackerrrameanerrdecmeanerrepochmeanposmeanchisqcxcyczlambdabetalbnstackobjectrowsnstackdetectionsndetectionsngnrninznygqfperfectgmeanpsfmaggmeanpsfmagerrgmeanpsfmagstdgmeanpsfmagnptgmeanpsfmagmingmeanpsfmagmaxgmeankronmaggmeankronmagerrgmeankronmagstdgmeankronmagnptgmeanapmaggmeanapmagerrgmeanapmagstdgmeanapmagnptgflagsrqfperfectrmeanpsfmagrmeanpsfmagerrrmeanpsfmagstdrmeanpsfmagnptrmeanpsfmagminrmeanpsfmagmaxrmeankronmagrmeankronmagerrrmeankronmagstdrmeankronmagnptrmeanapmagrmeanapmagerrrmeanapmagstdrmeanapmagnptrflagsiqfperfectimeanpsfmagimeanpsfmagerrimeanpsfmagstdimeanpsfmagnptimeanpsfmagminimeanpsfmagmaximeankronmagimeankronmagerrimeankronmagstdimeankronmagnptimeanapmagimeanapmagerrimeanapmagstdimeanapmagnptiflagszqfperfectzmeanpsfmagzmeanpsfmagerrzmeanpsfmagstdzmeanpsfmagnptzmeanpsfmagminzmeanpsfmagmaxzmeankronmagzmeankronmagerrzmeankronmagstdzmeankronmagnptzmeanapmagzmeanapmagerrzmeanapmagstdzmeanapmagnptzflagsyqfperfectymeanpsfmagymeanpsfmagerrymeanpsfmagstdymeanpsfmagnptymeanpsfmagminymeanpsfmagmaxymeankronmagymeankronmagerrymeankronmagstdymeankronmagnptymeanapmagymeanapmagerrymeanapmagstdymeanapmagnptyflagsastrometrycorrectionflagpmrapmdecpmraerrpmdecerrdecmeanramean
degdegmasmasmasmasddegdegdegdegmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmagmasmasmasmasdegdeg
objectobjectobjectobjectint64int64int64uint8int64int32uint8int16uint8float64int64int32uint8int32uint8float64float64float32float32float32float32float64float32float64float64float64float64float64float64float64int16int16int16int16int16int16int16int16float32float32float32float32int16float32float32float32float32float32int16float32float32float32int16int32float32float32float32float32int16float32float32float32float32float32int16float32float32float32int16int32float32float32float32float32int16float32float32float32float32float32int16float32float32float32int16int32float32float32float32float32int16float32float32float32float32float32int16float32float32float32int16int32float32float32float32float32int16float32float32float32float32float32int16float32float32float32int16int32uint8float32float32float32float32float64float64
PSO J266.4148-28.9061-999-999-99973312664147912990352671800001343951110969817203201171082371468073311693700.7643685226928153526718119002343652710452266.41478676-28.906105980.0010.0010.00705863070.007058630755927.672184213592.977626-0.05474229746111264-0.8736995987831238-0.48337593232895626266.847371042176-5.5060672725111910.030103058088871790.00834130681494409-99954308101312-999.0-999.0-999.0-999.00-999.0-999.0-999.0-999.0-999.00-999.0-999.0-999.001147200.99889121.34980.0613160.219186521.294221.745821.31050.1056650.609897421.20820.0800920.76699651150000.99910419.86970.0728250.111847419.816619.995119.9650.0955450.159543419.88270.1036180.17808741150000.99881719.17330.0220560.194126719.134219.621519.36040.0655330.351007619.2270.0378130.1221861149920.99895618.92960.0397350.120504718.768119.061719.70130.317070.589191619.79930.017510.33685371150007-5.892208-21.0739425.39196635.3919663-28.90612260697708266.4147770200182
PSO J266.4113-28.9084-999-999-99973312664113250267352671800001283951110969817143201171082370433573311693700.4894215543655883526718119002350363596860266.41132436-28.908383890.0010.0010.00029028390.000290778956064.8303650967161.33877-0.05479397074219825-0.8736771513453905-0.4834106494351431266.8443757444756-5.5084106767701760.026583741673972460.009753797166211999-99956317101212120.99982816.74770.0063010.0149031016.728416.770616.79890.0035050.0171621116.72980.0054690.01737111150000.99894315.76870.0066290.011305615.753115.781815.82480.0077630.014294715.75770.0109880.0216971150000.99945315.25560.0001770.00558515.245215.25915.3140.0029960.010585815.25170.0057020.01064681150000.9998514.94330.0033420.009762714.925314.951814.9860.0054340.030208914.9270.0081660.0246391149920.99928514.78550.0055870.042941014.719714.837914.82010.0127290.0102571114.78770.0091230.0569171111500070.37823653-11.7279190.214896410.21511844-28.908394866718794266.4113096737104
PSO J266.4065-28.9078-999-999-99973312664065420964352671800001198051110969817057301171082388915773311693700.5196995963525953526718119002350363596860266.40653886-28.907806780.0010.0010.000457433370.0004595581355968.4316929615328.340628-0.05486724274815632-0.8736774656835025-0.4834017704043577266.8401521219629-5.507929456983190.024900791514809770.013636306219625104-9995621781213120.99970217.81050.0086510.0180451117.776417.831517.88240.0097930.0271381117.79780.0109120.026471111150000.99945316.60780.0036830.007635516.603716.617916.65770.0030960.01514616.59280.0085470.01338761150000.99878115.97790.0060930.011615915.96415.993216.02810.0039230.0065771015.96850.0039570.00653101150000.99935215.56570.0056430.015029515.542915.582315.61240.0100040.028709615.56310.009740.03145461149920.99901415.32970.0093690.024988715.295415.360115.40450.0124960.033631715.3160.009410.02829471150007-2.8506730.90824830.327121140.32724363-28.907813722987918266.40652463391956
PSO J266.3928-28.9082-999-999-99973312663928400552352671800000951851110969816811101171082384317573311693700.1734655137858033526718119002343652710452266.39283765-28.908153990.0010.0010.00273507650.002707080455928.416776322424.3475966-0.05507598317521397-0.8736613841739089-0.48340709746611416266.8281194934244-5.5085829145943510.018352321809244980.023685916930894287-99955914101112120.99953121.31440.0455760.148403921.059321.445621.48770.0928550.202394721.47790.2088160.52166791150000.99902519.57110.0059760.045692619.525419.656719.65940.0460310.155451619.56110.0330740.06543861150000.99936918.68010.0157810.018193918.662718.710118.75830.0211130.063553918.67980.0229480.04330391150000.99899618.14860.0107290.033271718.077718.169518.28480.0211130.131731718.19510.014310.03256971149920.99984217.99070.0320320.1279721117.76418.145218.2210.0108750.089552918.1230.0162460.3073581111500076.2684032.10766651.9806871.9685138-28.908162385488396266.39282319368255
PSO J266.4596-28.9166-999-999-99973302664596120485352671800002133451110969817992701171082055935173301693700.2606857458694713526718119002350363596860266.45961358-28.916540440.0010.0010.000290771480.000283312355911.3653421161112.62389-0.05405319632704648-0.8736543842366525-0.4835351785246916266.8870419988373-5.5155106116392580.041643385717449015-0.030585140109685893-9995762581414150.9998616.72130.0034310.0109222216.699416.737516.78960.0030580.0134532516.71420.0031940.013862251150000.99837515.91740.0031670.006655415.908615.923615.96240.0022090.006378615.90780.0051810.00816661150000.99882315.55210.0029370.007409715.542215.560715.59470.0030040.007486915.53610.0036110.01024491150000.9994715.33040.003060.007746615.322615.34515.38160.0073190.017477915.30850.0046280.01187591149920.99983515.23380.0157080.0390211215.16415.234715.3080.0144480.0360451215.24480.0190150.047709121150007-0.16482891-8.9380350.192129460.18769103-28.91654579525221266.4596098804736
PSO J266.4557-28.9145-999-999-99973302664557452925352671800002066751110969817926001171082057123473301693700.8810591240237093526718119002343652710452266.45574003-28.914514110.0010.0010.00112106070.001085821755833.999702695755.112461-0.054113318695001314-0.8736678421942318-0.4835041367511638266.8835872042989-5.5135644068567520.04161213428694835-0.02663392285882768-99957826101414140.99983619.69690.0118790.061742619.630819.881119.85480.0222470.1308612619.85070.0325950.238899261150000.99893618.42680.007030.021514818.38818.44118.54490.0289930.060575818.45520.0199290.05542781150000.99960617.79050.0019560.032377917.736317.820517.84020.017080.022406917.76780.0042210.03207491150000.99937917.34640.0071680.0382441017.323517.41317.45240.0158140.0631121017.36740.0126810.055227101149920.99911917.11540.0070050.018891817.093317.142517.23080.0195220.081095817.11960.0193760.06272281149927-0.81038105-5.0469620.785911740.7709051-28.91451392670525266.4557364604022
PSO J266.4551-28.9129-999-999-99973302664550964871352671800002055251110969817914501171082055442073301693700.6652351931345053526718119002343652710452266.45509699-28.912889670.0010.0010.00102191550.001012237355914.466242912963.5007098-0.05412396863838971-0.8736809003583604-0.48347934843986373266.88297906670664-5.5119558115440870.0427034555252411-0.02530613701194428-99958126101416150.99956519.61350.0106990.0384552419.520419.68819.76710.0125740.0796662619.68980.0214470.093802261150000.99873818.35320.0099450.026508918.304418.388118.47680.0211280.044339918.390.0184480.03246791150000.99943917.68330.0034580.017937817.654317.694417.7740.008610.020461817.68850.005360.01419581150000.99926917.26620.0063710.030518817.206317.31417.37480.0151310.05203917.29570.0058030.01902291149920.99962817.02130.0437090.0393361116.965417.092317.18490.013420.0971861017.0760.0058210.047435121150007-2.6508658-9.3216290.676984550.6729033-28.912891413004118266.4550935473552
PSO J266.4544-28.9167-999-999-99973302664543610230352671800002042851110969817902101171082058077473301693700.4918857426307033526718119002343652710452266.45436476-28.916748310.0010.0010.0080733050.00807330555908.532650458442.7811184-0.05413325808800559-0.873647766004334-0.48353817980012054266.88242547582115-5.5158209988469390.0390796070127061-0.026759075737074783-99933900101217-999.027.062-999.0-999.00-999.0-999.0-999.0-999.0-999.00-999.0-999.0-999.0016420-999.023.207-999.0-999.00-999.0-999.0-999.0-999.0-999.00-999.0-999.0-999.00164200.99915221.26710.0462450.129863821.09321.458421.36330.1714280.200328521.32770.1662560.52089681150000.99933119.57790.0217680.077072719.521719.720419.79920.0731630.203064519.73080.0858280.20930371149920.99984718.380.0111550.1633661518.267518.670918.47340.0434790.320322718.34110.1058910.4235341111500078.7209774.30333385.7034525.703452-28.916742248674723266.4543525512401
PSO J266.4507-28.9145-999-999-99973302664506962987352671800001981851110969817841101171082057070673301693700.04364058751951963526718119002343652710452266.45069911-28.914462450.0010.0010.00138233850.001343491655846.414527712977.5354714-0.054190256561050476-0.8736634905309293-0.4835033830359002266.8791548937404-5.5136136217649970.03936616894062861-0.02283628161515323-9995792691217150.99939119.98170.0174030.0801032319.858920.131320.15190.0255710.1105512320.11260.0303030.166824231150000.99970818.70170.0023620.044273618.633818.709118.81780.0243380.064314618.73260.0241720.02824461150000.99866918.03610.0240.026817717.986718.053818.13830.0061680.035655818.05990.0129470.0329681150000.99961517.61340.0048020.020473917.572517.638417.67520.0080350.0322641017.56640.008390.03023101149920.9994917.31750.0120270.0402761217.220617.3417.30190.0229910.0698311217.31980.0256680.1113521211499274.4773464-0.632288340.95261220.9410091-28.91446459205714266.45069249505644
...................................................................................................................................................................................................................................................................................................................................................................................................
PSO J266.4163-29.1059-999-999-99973072664163533243352696200001437551109251830378601171081472108573071693700.5513128438511053526962118998343652710452266.41634343-29.105917860.0010.0010.00415109470.004151094756040.480765407026.2278366-0.05461292574532506-0.8720134735557573-0.486425667783638266.85375482834365-5.705762461567769359.8602729082378-0.09690259025787783-9995342610970.99808821.93830.0640840.091509221.883222.0114-999.0-999.0-999.0221.53350.0458510.0654621149920.99822920.34680.103480.206601220.346420.553420.65640.101168-999.0120.69432.8e-05-999.021150000.99970619.32410.0199930.068775719.302319.468719.47580.0556060.082484719.38580.0543220.08210571150000.99967218.79310.0160660.045283818.722718.852418.97810.031740.168035818.92410.0301540.1709581149920.99882218.4070.0512680.195363518.187218.72618.60280.0117770.05122318.52440.0639720.168108511500070.13514704-9.421433.1944013.194401-29.105920574402727266.41632986593146
PSO J266.4148-29.1040-999-999-99973072664148225512352696200001402651109251830343701171081473923773071693700.3744513861597063526962118998350363596860266.41481665-29.104033520.0010.0010.00030204190.0002855822756225.0459685395170.21924-0.05463701025152244-0.872027973396164-0.48639696825263434266.85236925496497-5.703915992241392359.8611839745609-0.09478592941077839-9995632581010100.99976616.10480.0023970.0080471616.090716.118316.1630.0020450.0086411716.09690.0016710.005784171150000.99880315.33390.0047010.00907415.323815.342215.3670.0039650.006855515.32880.0095570.0252851150000.99855114.92670.0026520.014285514.904614.939914.98640.0022460.00524514.92110.0019090.0039251150000.99960214.68590.0018030.004734414.680914.69214.78840.0033640.009755714.70520.0143390.03419471149920.99880714.54140.003740.030501514.504514.582514.73960.0748950.148003614.72380.102540.20984611500075.8455477-8.5724730.2215260.21033978-29.104038571850154266.41481303420676
PSO J266.4135-29.1027-999-999-99973072664135277120352696200001378151109251830319201171081474030873071693700.1657121890836513526962118998350363596860266.41351423-29.102680240.0010.0010.00232818260.002233870656022.429663622174.0016465-0.05465754563729599-0.8720381583189122-0.48637640068229737266.85119457651757-5.702594073247435359.8617454071643-0.09311305569772489-999434069811-999.023.381-999.0-999.00-999.0-999.0-999.0-999.0-999.00-999.0-999.0-999.00164200.99822320.4540.0692960.112992620.31420.601920.55860.0833030.219656620.47680.1374710.29519961150000.99934418.65920.0316980.0264618.616818.683218.83820.0290830.044432518.71260.0264040.03113451150000.99963817.46910.014010.062837717.452917.579917.56870.0093260.067788517.650.0782130.33800671149920.99951916.6570.0065410.033099816.64916.712716.67530.0299320.157221816.6370.0126940.123787811500079.5356381.56974892.0627521.9609464-29.102689852515642266.41351083331534
PSO J266.4121-29.1036-999-999-99973072664120656079352696200001350751109251830291801171081474513873071693700.6862568917556263526962118998343652710452266.41204779-29.103552020.0010.0010.00152380220.001499031156187.04171032156617.621878-0.05467946390609488-0.8720294428831148-0.48638956297592023266.84993492214244-5.7034954556026305359.8603384722594-0.09247737508697682-99956823101012130.99948120.02380.0199780.0762231819.901720.206520.13330.0306870.10121820.11730.0382110.116103181150000.99932418.63590.0129220.028001518.625418.67118.70320.0025220.029865518.60220.0090650.03629151150000.99876817.88990.0130510.022656617.862117.922717.99110.0039320.008708517.89610.0064960.00843651150000.99970317.42230.0125490.037071717.355817.4717.49080.0072590.052571717.39570.0289630.08350671149920.99964417.13870.0292220.049898917.093117.222717.2650.0080560.083565917.15880.0187220.096538911500077.0741681.29389981.09477421.0652758-29.103552968466015266.4120406028719
PSO J266.4112-29.1036-999-999-99973072664112026015352696200001333051109251830274101171081474526073071693700.9190586720770773526962118998343652710452266.4111924-29.103590460.0010.0010.00667841130.006678411356043.2074100436956.0418587-0.054692732637680624-0.8720282240867459-0.4863902562682965266.8491581415507-5.703549951542324359.85990520923116-0.0918349716895232-99942004664-999.0-999.0-999.0-999.00-999.0-999.0-999.0-999.0-999.00-999.0-999.0-999.00164160.99844820.70660.0029690.072583320.60420.709920.83310.0320970.103045320.71620.0086530.01225431150000.99755119.60710.000980.03285419.590219.661419.69070.0178440.038877419.59510.0050670.01314741150000.9980818.92710.0118670.016789218.914918.938618.85850.0127450.018051218.72690.0359530.0508612168922080.99810518.49490.0742610.19951318.419318.756318.11220.1705051.90978318.15110.0772520.10925231689221674.630359-5.89782574.818224.81822-29.10359843123767266.4111672070801
PSO J266.4008-29.1022-999-999-99973072664007687767352696200001145851109251830086901171081466758973071693700.1048280914359063526962118998343652710452266.40075211-29.10214980.0010.0010.0023691410.002285266555890.4517264171456.8113775-0.05485204825189232-0.8720304474493089-0.48636832907163075266.8399783046498-5.702343775201733359.8563878132956-0.08331909847796636-99956818101214140.99910420.19440.0466980.101868820.064920.360920.1120.0738730.168596819.94570.0532720.1464768168922160.99875518.92160.0048030.011998418.908318.937418.97550.0313790.076098418.86620.0190750.06287741150000.99737818.22750.0002930.018876318.227418.254218.32410.0207690.0214318.23750.0090630.00977331150000.99963117.80030.0142520.086934917.671617.949217.88710.0218830.13519817.76960.0362840.1163991149920.99910517.53060.0176030.0843851017.368717.621217.38440.060270.228541117.38330.0553060.09961211115000712.017826-22.827261.57072541.5209632-29.10216056111791266.4007498140779
PSO J266.3870-29.1028-999-999-99973072663870577034352696200000902751109251829843801171081272614873071693700.5596192763742243526962118998343652710452266.3870477-29.102767810.0010.0010.0073170690.00731706955965.947343177723.2577538-0.055060418512013626-0.8720120272660552-0.486377810571809266.8279563677007-5.703269624074106359.8496106784922-0.07341820858572076-9994350213128-999.0-999.0-999.0-999.00-999.0-999.0-999.0-999.0-999.00-999.0-999.0-999.00164160.99878221.78530.0796850.15807221.627221.786621.68010.254074-999.0123.62650.000238-999.021150000.99973520.4560.0267720.106254920.292220.534320.67330.0165410.196798820.61980.0721360.22852191150000.99979519.35370.0222180.170094819.080819.629819.41860.046490.301055719.25310.0410380.32623881149920.99881818.68210.0107960.096289818.549118.810218.66660.095490.304906818.5510.028560.178773811500076.25897818.7954585.2044375.204437-29.102782305518506266.3870371246228
PSO J266.3863-29.1018-999-999-99973072663863428135352696200000889951109251829831001171081462223473071693700.5154543328242883526962118998343652710452266.38634245-29.101828180.0010.0010.0021710670.002167336956017.455510581715.218551-0.05507162975089041-0.8720192471729693-0.48636359666042916266.8273181783258-5.702343108681077359.8500961419852-0.07240528190906456-99957019111413130.99982620.89860.0589310.1464391720.708821.157720.90070.0930040.3321571620.89360.1214670.31166171150000.99902419.62920.0192940.067861919.595819.747919.77680.0336420.167174919.70420.0243520.14457991150000.99889918.92840.0207450.0336081318.862418.968319.00690.0158950.063931318.94280.019020.072479131150000.99933318.41650.0120230.040184918.349918.458918.42250.0203620.07992918.32850.0181660.06845191149920.9996518.01050.0153180.1532011017.73518.03417.76820.0409090.2434631017.67780.0409750.185175101689221677.37343269.1473271.54406851.5455455-29.101850237140827266.38633325346336
PSO J266.3820-29.1007-999-999-99973072663820319580352696200000817251109251829758201171081273094873071693700.9218698031472693526962118998343652710452266.38201553-29.100639130.0010.0010.00151016810.001512818355948.5503048566845.243683-0.055138045861233984-0.8720252345643736-0.48634533634193877266.8234856459903-5.7012480446995359.84913994666965-0.06855454449437284-99955059141390.99803620.59140.0011360.114785320.590620.753720.59340.0111140.184051320.430.0650580.1272463168922160.9997219.19330.0108360.020971519.16619.204919.35390.0104260.041265519.01540.0389440.06601951150000.99916118.38150.0110110.0257121118.334518.408618.47510.0153160.0382071118.39180.0142220.034072111150000.99894317.84210.0094710.0176421017.821517.873917.92430.0121170.065841017.81520.0174790.0732210168922080.99900817.58810.0113360.122282817.402917.606117.7680.0212550.286346817.64950.0536130.4789128168922167-11.9918525.79480081.04595741.0523597-29.100652840525328266.3820115338496

Visualizing the candidate stars#

Next, we plot a preliminary \(r-i\) vs \(z\) color-magnitude diagram of our candidate stars in the Galactic Bulge.

f, ax = plt.subplots()
f.set_size_inches((4, 4))
ax.scatter(
    sample['rmeanpsfmag']-sample['imeanpsfmag'],
    sample['zmeanpsfmag'], 
    s=5, lw=0, 
    alpha=0.5
)

ax.set_xlabel("r-i, PSF Mag")
ax.set_ylabel("z, PSF Mag")

# Invert y axis limits to plot fainter -> brighter
ax.set_ylim(ax.get_ylim()[::-1])
(22.22845063209534, 7.958129072189331)
../../../_images/d8b71945a1926fb21d88295a1ca158b58ed2f1a3b9f701219714d440be071ff7.png

We see a lot of objects in our preliminary sample that are surprisingly red or blue in \(r-i\). This suggests there may be data quality cuts that need to be made for our final sample.

To investigate, we first define a color cut to roughly select these very blue or red candidates, where objects with \(r-i > 3\) or \(<0\) are flagged as potentially suspect (overplotted in red below).

f, ax = plt.subplots()
f.set_size_inches((4, 4))

# Plot full preliminary sample
ax.scatter(
    sample['rmeanpsfmag']-sample['imeanpsfmag'],
    sample['zmeanpsfmag'], 
    s=5, lw=0, 
    alpha=0.2
)

# Rough suspect target color cut
whsuspect = (
    (sample['rmeanpsfmag']-sample['imeanpsfmag'] > 3)
) | (
    (sample['rmeanpsfmag']-sample['imeanpsfmag'] < 0)
) 

# Overplot potentially suspect targets
ax.scatter(
    (sample['rmeanpsfmag']-sample['imeanpsfmag'])[whsuspect],
    sample['zmeanpsfmag'][whsuspect], 
    s=5, lw=0, 
    alpha=0.5,
    color='red'
)


ax.set_xlabel("r-i, PSF Mag")
ax.set_ylabel("z, PSF Mag")

ax.set_ylim(ax.get_ylim()[::-1])
(22.22845063209534, 7.958129072189331)
../../../_images/5c4b2c6c1e317b8fde26b88f6006c45f6ff484a45ee4f7d227f2f4fd022c7db4.png

Overall, this selection includes 65 (potentially) suspect objects.

len(sample[whsuspect])
65

Launching MAST-Aladin to inspect targets & outliers#

We’ll now launch MAST-Aladin to the side of our notebook, to visually examine these suspect targets over a sky map of PanSTARRS imaging to hunt for clues regarding what type of quality issues might be at play with these very red/blue objects.

# Launch MAST-Aladin
with Sidecar(title="Aladin Viewer", anchor="split-right"):
    mast_aladin = MastAladin()
    display(mast_aladin)

As we’re working with PanSTARRS data in the galactic bulge, we will also change the base survey imaging to the PanSTARRS1 imaging, and center the viewport at the center of the GBTDS imaging (with a 5 degree field of view).

(See the documentation for ipyaladin, on which MAST-Aladin is built, for examples of how to set the sky survey displayed and changing the center and FOV).

# Change base imaging survey
mast_aladin.survey = "P/PanSTARRS/DR1/color-i-r-g"

# Change viewport location and FOV (in degrees)
mast_aladin.target = gc
mast_aladin.fov = 0.1   # FOV in degrees

Adding targets to MAST-Aladin#

We then plot the full set of objects as an overlay to MAST-Aladin, for reference.

Note that we must specify the columns of our sample table the contain the RA/Dec information (raMean and decMean).

mast_aladin.add_table(
    sample,
    ra_field="ramean",
    dec_field="decmean",
    name="Sample",
    shape="circle",
    color="yellow",
)
{'type': 'table',
 'table': <Table length=2906>
        objname        objaltname1 ...       decmean             ramean      
                                   ...         deg                deg        
         object           object   ...       float64            float64      
 --------------------- ----------- ... ------------------- ------------------
 PSO J266.4148-28.9061        -999 ...  -28.90612260697708  266.4147770200182
 PSO J266.4113-28.9084        -999 ... -28.908394866718794  266.4113096737104
 PSO J266.4065-28.9078        -999 ... -28.907813722987918 266.40652463391956
 PSO J266.3928-28.9082        -999 ... -28.908162385488396 266.39282319368255
 PSO J266.4596-28.9166        -999 ...  -28.91654579525221  266.4596098804736
 PSO J266.4557-28.9145        -999 ...  -28.91451392670525  266.4557364604022
 PSO J266.4551-28.9129        -999 ... -28.912891413004118  266.4550935473552
 PSO J266.4544-28.9167        -999 ... -28.916742248674723  266.4543525512401
 PSO J266.4507-28.9145        -999 ...  -28.91446459205714 266.45069249505644
                   ...         ... ...                 ...                ...
 PSO J266.4163-29.1059        -999 ... -29.105920574402727 266.41632986593146
 PSO J266.4148-29.1040        -999 ... -29.104038571850154 266.41481303420676
 PSO J266.4135-29.1027        -999 ... -29.102689852515642 266.41351083331534
 PSO J266.4121-29.1036        -999 ... -29.103552968466015  266.4120406028719
 PSO J266.4112-29.1036        -999 ...  -29.10359843123767  266.4111672070801
 PSO J266.4008-29.1022        -999 ...  -29.10216056111791  266.4007498140779
 PSO J266.3870-29.1028        -999 ... -29.102782305518506  266.3870371246228
 PSO J266.3863-29.1018        -999 ... -29.101850237140827 266.38633325346336
 PSO J266.3820-29.1007        -999 ... -29.100652840525328  266.3820115338496,
 'options': {'ra_field': 'ramean',
  'dec_field': 'decmean',
  'name': 'Sample',
  'color': 'yellow',
  'shape': 'circle'}}

By going into the “Overlays” menu (upper left, 3 “layers” stacked symbol), this table overlay can be turned off and back on — which can be helpful when investigating the suspect targets.

Next we add the potentially suspect candidates as another overlay table.

mast_aladin.add_table(
    sample[whsuspect],
    ra_field="ramean",
    dec_field="decmean",
    name="Outliers",
    shape="circle",
    color="cyan",
)
{'type': 'table',
 'table': <Table length=65>
        objname        objaltname1 ...       decmean             ramean      
                                   ...         deg                deg        
         object           object   ...       float64            float64      
 --------------------- ----------- ... ------------------- ------------------
 PSO J266.4656-28.9322        -999 ...        -28.93224898       266.46558802
 PSO J266.4586-28.9277        -999 ...  -28.92773489101772 266.45859674997916
 PSO J266.4568-28.9370        -999 ...  -28.93704063251521 266.45683174983714
 PSO J266.4984-28.9447        -999 ... -28.944662715413212  266.4984285545497
 PSO J266.4794-28.9423        -999 ...    -28.942277513343  266.4793867087948
 PSO J266.4765-28.9445        -999 ... -28.944538035176077  266.4765353570233
 PSO J266.4765-28.9446        -999 ... -28.944550047982744 266.47653568833647
 PSO J266.4801-28.9564        -999 ...        -28.95638239       266.48011513
 PSO J266.5115-28.9589        -999 ... -28.958921355911773 266.51148801741255
                   ...         ... ...                 ...                ...
 PSO J266.4038-29.0648        -999 ...  -29.06479528659513 266.40378791522704
 PSO J266.4812-29.0680        -999 ...  -29.06799782313279  266.4812231985844
 PSO J266.3901-29.0709        -999 ... -29.070926639866524  266.3901078931627
 PSO J266.4504-29.0787        -999 ... -29.078672733721874 266.45037142120907
 PSO J266.4043-29.0785        -999 ... -29.078561806869555  266.4042465928765
 PSO J266.3988-29.0876        -999 ...  -29.08761376271378 266.39881294292843
 PSO J266.3651-29.0918        -999 ...  -29.09180716355119  266.3651002579534
 PSO J266.3526-29.0886        -999 ... -29.088616273886714  266.3525890683952
 PSO J266.4243-29.0978        -999 ... -29.097772833999297  266.4243431315527,
 'options': {'ra_field': 'ramean',
  'dec_field': 'decmean',
  'name': 'Outliers',
  'color': 'cyan',
  'shape': 'circle'}}

Adding observation footprints to MAST-Aladin#

It’s also possible to add footprints corresponding to individual observations (or reduced mosaic tiles) to MAST-Aladin, using those observations’ associated s_region metadata.

In this case, all objects in our sample fall within a single PanSTARRS tile per band. The tile boundaries can be seen by zooming out.

(This visualization of where objects fall within images can be useful when investigating whether entire images or regions of images are driving data quality issues.)

First, we query for all PanSTARRS images overlapping our cone search region.

ps_obs = Observations.query_criteria(
    obs_collection="PS1",
    coordinates=gc,
    radius=0.1*u.deg,
)

We then add these image footprints to MAST-Aladin as overlays.

colors = ['green', 'blue', 'red', 'yellow', 'orange']
for i in range(len(ps_obs)):
    mast_aladin.add_graphic_overlay_from_stcs(
        ps_obs['s_region'][i], name=ps_obs['filters'][i], 
        color=colors[i]
    )

Setting the Viewport to center a target#

In addition to panning and zooming in MAST-Aladin, and then clicking on the region circle to obtain information on a specific object (the full table row), it is also possible to programatically change the viewport center and field of view (FOV) to go to a specific target.

For example, we can center and zoom the viewport to the first potentially suspect target using it’s RA/Dec from our sample table:

ind = 0
mast_aladin.target = SkyCoord(
    sample["ramean"][whsuspect][ind],
    sample["decmean"][whsuspect][ind],
    unit=u.deg,
)
mast_aladin.fov = 30*u.arcsec.to(u.deg)  # FOV in degrees

We can also iterate through a subset of these suspect objects using a for loop going to every object together with a short time delay, as follows:

# Change viewport location for set of suspect objects:
for ind in range(20):
    mast_aladin.target = SkyCoord(
        sample["ramean"][whsuspect][ind],
        sample["decmean"][whsuspect][ind],
        unit=u.deg
    )
    time.sleep(2)

(It is also possible to delay until a key input by using instead, e.g., input("Press any key to continue")).

Flipping through the suspect objects, we see that these very red or blue targets include objects that appear to be very faint and/or irregular, or have very extreme colors (which may indicate cosmic rays or hot pixels in one or more filters); that are in a saturated region (and thus the colors may be unreliable); and also some objects that could indeed be real.


Examining quality flag information#

To avoid throwing out real stars in these very red/blue regions, we’ll now examine the PanSTARRS catalog columns and flagging flag documentation to see if there are relevant quality cuts that can be made.

From the Mean object table columns (also as seen in the MAST catalog schema browser, searching for “flag”), we see there is a qualityFlag column which contains a bitflag. The description for the flags in each bit is described in the documentation for the PanSTARRS/PS1 object flags.

There are also flag columns for each of the PanSTARRS filters, including zFlags, rFlags, iFlags.

We construct a quick list of all MeanObject table columns containing the word “flag” (case-insensitive)

# Get a quick list of all mean table columns containing "flag" (case-insensitive)
flags = []
for key in sample.keys():
    if "flag" in key.lower():
        flags.append(key)
print(flags)
['objinfoflag', 'qualityflag', 'gflags', 'rflags', 'iflags', 'zflags', 'yflags', 'astrometrycorrectionflag']

Using this column name list, we inspect the values of these flags for our suspect objects, also displaying the “objName” column.

sample[whsuspect][
    "objname",
    *flags
]
Table length=65
objnameobjinfoflagqualityflaggflagsrflagsiflagszflagsyflagsastrometrycorrectionflag
objectint32uint8int32int32int32int32int32uint8
PSO J266.4656-28.9322335622144404416440
PSO J266.4586-28.927750363596860164201147241150001149921149927
PSO J266.4568-28.937050363596860164201157681150001149921152487
PSO J266.4984-28.944743652710452164201147241150001149921150007
PSO J266.4794-28.94234365271045216420114724115000114992168922167
PSO J266.4765-28.94453694182404416777488272280447
PSO J266.4765-28.9446436527104521150001150001149921147361188327
PSO J266.4801-28.9564151026892818016416167946721689221616892208164160
PSO J266.5115-28.958943652710452164201147241150001149921150007
...........................
PSO J266.4129-29.06095036359686016420164201150001149921150007
PSO J266.4038-29.06485036359686016420164201150001149921150007
PSO J266.4812-29.06804365271045216420164201150001152481149927
PSO J266.3901-29.070950363596860164201642011500016892208168922167
PSO J266.4504-29.07874365271045216420164201150001149921149927
PSO J266.4043-29.07854365271045216416167936481150001149921147205
PSO J266.3988-29.0876503635968601642016420115000114992168922167
PSO J266.3651-29.091843652710452164201147241150001149921150007
PSO J266.3526-29.08865036359686016420168924641150001149921149927
PSO J266.4243-29.097850363596860164201642016793904168922081150007

While the flag description documentation provides details on the flag values and descriptions, we will also create an instance of a bitflag “helper” class PanSTARRSFlagHelper — which will help us interpret the bitflag values of individual entries, and create masks to select objects with a specific flag (or sets of flags).

(This “helper” class is defined in the accompanying python file with this notebook.)

We first obtain the flag information for thequalityFlag column, which is available in the “ObjectQualityFlags” table via the MAST PS1 DR2 TAP service.

objqalflags = PanSTARRSFlagHelper(
    tap_url="https://mast.stsci.edu/vo-tap/api/v0.1/ps1dr2", 
    table="ObjectQualityFlags", 
)
/home/runner/micromamba/envs/ci-env/lib/python3.13/site-packages/pyvo/dal/query.py:403: DALOverflowWarning: Results truncated due to server limits. Consider setting a maxrec value.
  warn("Results truncated due to server limits. Consider "

Let’s examine the flag definition info table from this helper:

objqalflags.flag_info_table
Table length=9
descriptionhexadecimalnamevalue
objectobjectobjectint32
Initial value; resets all bits.0x00000000DEFAULT0
Extended in our data (eg; PS).0x00000001QF_OBJ_EXT1
Extended in external data (eg; 2MASS).0x00000002QF_OBJ_EXT_ALT2
Good-quality measurement in our data (eg; PS).0x00000004QF_OBJ_GOOD4
Good-quality measurement in external data (eg; 2MASS).0x00000008QF_OBJ_GOOD_ALT8
Good-quality object in the stack (> 1 good stack measurement).0x00000010QF_OBJ_GOOD_STACK16
The primary stack measurements are the best measurements.0x00000020QF_OBJ_BEST_STACK32
Suspect object in the stack (no more than 1 good measurement, 2 or more suspect or good stack measurement).0x00000040QF_OBJ_SUSPECT_STACK64
Poor-quality stack object (no more than 1 good or suspect measurement).0x00000080QF_OBJ_BAD_STACK128

These look quite promising as far as narrowing down our sample!

The helper class has a method to expand a bitflag into a table, with separate columns for each flag. We’ll use this to expand the qualityFlag entries for our suspect objects to investigate whether some of these flags can be used to refine our sample.

objqalflags.expand_to_table(
    sample["qualityflag"][whsuspect], 
    ids=sample["objname"][whsuspect],
)
Table length=65
idQF_OBJ_EXTQF_OBJ_EXT_ALTQF_OBJ_GOODQF_OBJ_GOOD_ALTQF_OBJ_GOOD_STACKQF_OBJ_BEST_STACKQF_OBJ_SUSPECT_STACKQF_OBJ_BAD_STACK
objectboolboolboolboolboolboolboolbool
PSO J266.4656-28.9322FalseFalseFalseTrueFalseTrueFalseFalse
PSO J266.4586-28.9277FalseFalseTrueTrueTrueTrueFalseFalse
PSO J266.4568-28.9370FalseFalseTrueTrueTrueTrueFalseFalse
PSO J266.4984-28.9447FalseFalseTrueFalseTrueTrueFalseFalse
PSO J266.4794-28.9423FalseFalseTrueFalseTrueTrueFalseFalse
PSO J266.4765-28.9445FalseFalseTrueTrueFalseTrueFalseFalse
PSO J266.4765-28.9446FalseFalseTrueFalseTrueTrueFalseFalse
PSO J266.4801-28.9564FalseFalseTrueFalseTrueTrueFalseTrue
PSO J266.5115-28.9589FalseFalseTrueFalseTrueTrueFalseFalse
...........................
PSO J266.4129-29.0609FalseFalseTrueTrueTrueTrueFalseFalse
PSO J266.4038-29.0648FalseFalseTrueTrueTrueTrueFalseFalse
PSO J266.4812-29.0680FalseFalseTrueFalseTrueTrueFalseFalse
PSO J266.3901-29.0709FalseFalseTrueTrueTrueTrueFalseFalse
PSO J266.4504-29.0787FalseFalseTrueFalseTrueTrueFalseFalse
PSO J266.4043-29.0785FalseFalseTrueFalseTrueTrueFalseFalse
PSO J266.3988-29.0876FalseFalseTrueTrueTrueTrueFalseFalse
PSO J266.3651-29.0918FalseFalseTrueFalseTrueTrueFalseFalse
PSO J266.3526-29.0886FalseFalseTrueTrueTrueTrueFalseFalse
PSO J266.4243-29.0978FalseFalseTrueTrueTrueTrueFalseFalse

Using this flag-expanded table, we see that PanSTARRS quality flags that seem relevant, such as QF_OBJ_GOOD (False = bad) or QF_OBJ_SUSPECT_STACK or QF_OBJ_BAD_STACK (True = suspect/bad), appear to have “good” values for many of these potentially suspect objects, so these won’t be particularly useful in this case.

Instead, data quality issues for the individual bands may be driving these outliers. Thus, we’ll next examine the flags for the individual bands: zFlags, rFlags, iFlags

From the documentation for the PanSTARRS/PS1 object flags, we see this flag information is in the “ObjectFilterFlags” metadata table.

We then create a new helper class instance from this metadata, and inspect the list of flags and their descriptions:

filterflags = PanSTARRSFlagHelper(
    tap_url="https://mast.stsci.edu/vo-tap/api/v0.1/ps1dr2", 
    table="ObjectFilterFlags", 
)

We’ll display the flag descriptions in two chunks as there are 23 total flags.

# Split up as there are many flag entries:
filterflags.flag_info_table[0:10]
Table length=10
descriptionhexadecimalnamevalue
objectobjectobjectint32
Initial value; resets all bits.0x00000000DEFAULT0
Used within relphot: skip star.0x00000001SECF_STAR_FEW1
Used within relphot: skip star.0x00000002SECF_STAR_POOR2
Synthetic photometry used in average measurement.0x00000004SECF_USE_SYNTH4
Ubercal photometry used in average measurement.0x00000008SECF_USE_UBERCAL8
PS1 photometry used in average measurement.0x00000010SECF_HAS_PS116
PS1 stack photometry exists.0x00000020SECF_HAS_PS1_STACK32
Tycho photometry used for synthetic magnitudes.0x00000040SECF_HAS_TYCHO64
Synthetic magnitudes repaired with zeropoint map.0x00000080SECF_FIX_SYNTH128
Average magnitude calculated in 0th pass.0x00000100SECF_RANK_0256
filterflags.flag_info_table[10:23]
Table length=13
descriptionhexadecimalnamevalue
objectobjectobjectint32
Average magnitude calculated in 1st pass.0x00000200SECF_RANK_1512
Average magnitude calculated in 2nd pass.0x00000400SECF_RANK_21024
Average magnitude calculated in 3rd pass.0x00000800SECF_RANK_32048
Average magnitude calculated in 4th pass.0x00001000SECF_RANK_44096
PS1 stack photometry comes from primary skycell.0x00004000SECF_STACK_PRIMARY16384
PS1 stack best measurement is a detection (not forced).0x00008000SECF_STACK_BESTDET32768
PS1 stack primary measurement is a detection (not forced).0x00010000SECF_STACK_PRIMDET65536
This photcode has SDSS photometry.0x00100000SECF_HAS_SDSS1048576
This photcode has HSC photometry.0x00200000SECF_HAS_HSC2097152
This photcode has CFH photometry (mostly Megacam).0x00400000SECF_HAS_CFH4194304
This photcode has DES photometry.0x00800000SECF_HAS_DES8388608
Extended in this band.0x01000000SECF_OBJ_EXT16777216
bad stack object due to mis-aligned warp images in this skycell, all magnitudes set to -999, see stackObjectThinBadSkycells or meanObjectBadSkycells for original magnitudes, data from this skycell will be corrected in a future release0x40000000BAD_STACK1073741824

We note that there are flags about whether or not synthetic photometry was used (SECF_USE_SYNTH) and whether PS1 stack photometry exists (SECF_HAS_PS1) or whether the stack best measurement is detected and not forced SECF_STACK_BESTDET. There is also a BAD_STACK flag.

As above, we’ll use this flag helper class to expand the flags for the z, r, i bands. This time we’ll expand only the flags we’ve noted above.

We’ll finish be aggregating the expanded columns into a single table for side-by-side inspection.

tfilts = None
filts = ['z', 'r', 'i']
for filt in filts:
    if tfilts is None:
        ids = sample["objname"][whsuspect]
    else:
        ids = None

    # Get expanded bitflag table for each band
    tabf = filterflags.expand_to_table(
        sample[f"{filt}flags"][whsuspect], 
        ids=ids,
        flags_to_include=["SECF_USE_SYNTH",
                          "SECF_HAS_PS1",
                          "SECF_STACK_BESTDET",
                          "BAD_STACK"],
    )

    # Create an aggregate table: list the "id":
    if tfilts is None:
        tfilts = Table({"id": tabf['id']})
        
    # Add the band/filter's flags to the aggregate table, 
    # with the filter name prepended:
    for key in tabf.keys():
        if key != "id":
            tfilts[f"{filt}_{key}"] = tabf[key]

# Reorder keys to list the same flag type together:
keys_out = ["id"]
for key in tabf.keys():
    for filt in filts:
        keys_out.append(f"{filt}_{key}")

tfilts = tfilts[keys_out]

tfilts
Table length=65
idz_SECF_USE_SYNTHr_SECF_USE_SYNTHi_SECF_USE_SYNTHz_SECF_HAS_PS1r_SECF_HAS_PS1i_SECF_HAS_PS1z_SECF_STACK_BESTDETr_SECF_STACK_BESTDETi_SECF_STACK_BESTDETz_BAD_STACKr_BAD_STACKi_BAD_STACK
objectboolboolboolboolboolboolboolboolboolboolboolbool
PSO J266.4656-28.9322TrueTrueFalseFalseFalseTrueFalseFalseFalseFalseFalseFalse
PSO J266.4586-28.9277FalseTrueFalseTrueFalseTrueTrueTrueTrueFalseFalseFalse
PSO J266.4568-28.9370FalseFalseFalseTrueTrueTrueTrueTrueTrueFalseFalseFalse
PSO J266.4984-28.9447FalseTrueFalseTrueFalseTrueTrueTrueTrueFalseFalseFalse
PSO J266.4794-28.9423FalseTrueFalseTrueFalseTrueTrueTrueTrueFalseFalseFalse
PSO J266.4765-28.9445TrueFalseFalseFalseTrueTrueFalseFalseFalseFalseFalseFalse
PSO J266.4765-28.9446FalseFalseFalseTrueTrueTrueTrueTrueTrueFalseFalseFalse
PSO J266.4801-28.9564FalseFalseFalseTrueTrueTrueTrueFalseTrueFalseFalseFalse
PSO J266.5115-28.9589FalseTrueFalseTrueFalseTrueTrueTrueTrueFalseFalseFalse
.......................................
PSO J266.4129-29.0609FalseTrueFalseTrueFalseTrueTrueFalseTrueFalseFalseFalse
PSO J266.4038-29.0648FalseTrueFalseTrueFalseTrueTrueFalseTrueFalseFalseFalse
PSO J266.4812-29.0680FalseTrueFalseTrueFalseTrueTrueFalseTrueFalseFalseFalse
PSO J266.3901-29.0709FalseTrueFalseTrueFalseTrueTrueFalseTrueFalseFalseFalse
PSO J266.4504-29.0787FalseTrueFalseTrueFalseTrueTrueFalseTrueFalseFalseFalse
PSO J266.4043-29.0785FalseFalseFalseTrueTrueTrueTrueFalseTrueFalseFalseFalse
PSO J266.3988-29.0876FalseTrueFalseTrueFalseTrueTrueFalseTrueFalseFalseFalse
PSO J266.3651-29.0918FalseTrueFalseTrueFalseTrueTrueTrueTrueFalseFalseFalse
PSO J266.3526-29.0886FalseFalseFalseTrueTrueTrueTrueTrueTrueFalseFalseFalse
PSO J266.4243-29.0978FalseTrueFalseTrueFalseTrueTrueFalseFalseFalseFalseFalse

Leveraging this breakdown, we now print aggregate counts for each flag with the number of objects with that flag set to True/False.

for key in tfilts.keys():
    if key != "id":
        strout = f"{key:>20}:   True: {np.sum(tfilts[key]):>3}"
        strout += f",  False: {np.sum(~tfilts[key]):>3}"
        print(strout)
    z_SECF_USE_SYNTH:   True:   9,  False:  56
    r_SECF_USE_SYNTH:   True:  46,  False:  19
    i_SECF_USE_SYNTH:   True:   0,  False:  65
      z_SECF_HAS_PS1:   True:  56,  False:   9
      r_SECF_HAS_PS1:   True:  19,  False:  46
      i_SECF_HAS_PS1:   True:  65,  False:   0
z_SECF_STACK_BESTDET:   True:  54,  False:  11
r_SECF_STACK_BESTDET:   True:  23,  False:  42
i_SECF_STACK_BESTDET:   True:  54,  False:  11
         z_BAD_STACK:   True:   0,  False:  65
         r_BAD_STACK:   True:   0,  False:  65
         i_BAD_STACK:   True:   0,  False:  65

We see that none of the suspect objects are marked as “bad” stacks, that some of the stack values are forced (and not detected, suggesting the objects are very faint in that filter), and also a decent number have no PS1 data & instead have synthetic data.

Revisiting the schema for the “mean” table, we note that there are columns nz, nr, ni, that contain the number of single-epoch detections in each filter.

sample[whsuspect]["objname", "nz", "nr", "ni"]
Table length=65
objnamenznrni
objectint16int16int16
PSO J266.4656-28.9322001
PSO J266.4586-28.9277809
PSO J266.4568-28.93706310
PSO J266.4984-28.944711011
PSO J266.4794-28.942313014
PSO J266.4765-28.94451338
PSO J266.4765-28.9446184
PSO J266.4801-28.9564316
PSO J266.5115-28.958911013
............
PSO J266.4129-29.060912010
PSO J266.4038-29.064814010
PSO J266.4812-29.0680403
PSO J266.3901-29.07091204
PSO J266.4504-29.0787706
PSO J266.4043-29.07851017
PSO J266.3988-29.08761209
PSO J266.3651-29.091813013
PSO J266.3526-29.088611111
PSO J266.4243-29.0978902

By a quick aggregate count, we see that quite a few of these outliers (65 total) have either 0 or only 1 r detection, and some for z and i as well.

for filt in filts:
    for val in [0, 1]:
        strout = f"n{filt}: number = {val}: "
        strout += f"{len(np.where(sample[whsuspect][f'n{filt}'] == val)[0])}"
        print(strout)
nz: number = 0: 6
nz: number = 1: 6
nr: number = 0: 46
nr: number = 1: 9
ni: number = 0: 0
ni: number = 1: 7

With only 1 detection, the magnitudes in those bands could be driven by data/noise artifacts, while those with 0 detections could be impacted by issues in the synthetic magnitudes derived from other data.


Refining the sample with data quality cuts#

As astroquery.mast currently doesn’t support bitflag-based filtering on only a subset of bits, we’ll first examine whether restriting our sample to only objects with \(\geq 2\) detections in each band is sufficient to resolve these suspect outliers.

We make a mask to select only the subset of our sample with >= 2 detections in all 3 bands.

whmultdet = (
    (sample['nz'] >= 2)
    & (sample['nr'] >= 2)
    & (sample['ni'] >= 2)
)

We then replot our sample, marking the suspect outliers, in two ways:

  • Showing all objects in the preliminary sample, with objects without at least 2 detections in all three bands outlined in yellow (left panel).

  • Showing only objects with at least 2 detections in all 3 bands, with color-outlier objects marked in red as before (right panel).

# Rough selection of suspect targets
f, axes = plt.subplots(1, 2)
f.set_size_inches((8.8, 4))

ax = axes[0]
ax.set_title("Preliminary sample")
ax.scatter(
    (sample['rmeanpsfmag']-sample['imeanpsfmag']),
    sample['zmeanpsfmag'], 
    s=5, lw=0, 
    alpha=0.2
)

ax.scatter(
    (sample['rmeanpsfmag']-sample['imeanpsfmag'])[whsuspect],
    sample['zmeanpsfmag'][whsuspect], 
    s=5, lw=0, 
    alpha=0.5,
    color='red'
)

ax.scatter(
    (sample['rmeanpsfmag']-sample['imeanpsfmag'])[~whmultdet],
    sample['zmeanpsfmag'][~whmultdet], 
    s=7, lw=1, 
    alpha=0.5,
    edgecolor='yellow', 
    zorder=-10
)


ax.set_xlabel("r-i, PSF Mag")
ax.set_ylabel("z, PSF Mag")

ax.set_ylim(ax.get_ylim()[::-1])

xlim = ax.get_xlim()
ylim = ax.get_ylim()


ax = axes[1]
ax.set_title(r"Sample with $\geq2$ detections in all bands")
ax.scatter(
    (sample['rmeanpsfmag']-sample['imeanpsfmag'])[whmultdet],
    sample['zmeanpsfmag'][whmultdet], 
    s=5, lw=0, 
    alpha=0.2
)

ax.scatter(
    (sample['rmeanpsfmag']-sample['imeanpsfmag'])[whmultdet & whsuspect],
    sample['zmeanpsfmag'][whmultdet & whsuspect], 
    s=5, lw=0, 
    alpha=0.5,
    color='red'
)


ax.set_xlabel("r-i, PSF Mag")
ax.set_ylabel("z, PSF Mag")

ax.set_xlim(xlim)
ax.set_ylim(ylim)
(22.22845063209534, 7.958129072189331)
../../../_images/a42d5252a3008e06a6aec6bbd8c5d506fe77afe963ab59550f012f5a297f8114.png

Many of our “color-outlier” suspect targets — as well as some others we hadn’t flagged — are removed by requiring more than one detection in each relevant band! The resulting sample is much closer to a clean color magnitude diagram.

These constraints are something that could have be applied as part of the initial query.

Further, similar checks can reveal whether an even more refined sample could be obtained by filtering on the information from the flags explored here, or if additional flags from, e.g., the individual detection catalog. This is left as an exercise for interested readers!


Additional Resources#

Astroquery.mast#

PanSTARRS 1 DR 2#


Citations#

If you use astropy for published research, please cite the authors. Follow these links for more information about citing astropy:

If you use PanSTARRS data accessed through MAST for published research, please include the following acknowledgements, found at the following links:

About This Notebook#

The use of MAST-Aladin in this notebook draws from the demonstrations in “Intro to MastAladinLite” by Hatice Karatay.

Authors: Sedona Price
Keywords: Tutorial, astroquery, MAST-Aladin, bitflags
Last updated: August 2026


Top of Page Space Telescope Logo