From 3443eb9db3e211694b310dbf275e52b65bf64e3a Mon Sep 17 00:00:00 2001 From: Brian McLean Date: Fri, 12 Jul 2024 11:30:23 -0400 Subject: [PATCH] Fixed Aladin add_catalog_from_url onClick option --- .../display_footprints.ipynb | 113 +++++++++--- .../display_footprints/getCatalog.py | 163 ++++++++++++++++++ .../display_footprints/requirements.txt | 5 +- .../display_footprints/selectSIAF.py | 103 ++++++----- 4 files changed, 317 insertions(+), 67 deletions(-) create mode 100644 notebooks/multi_mission/display_footprints/getCatalog.py diff --git a/notebooks/multi_mission/display_footprints/display_footprints.ipynb b/notebooks/multi_mission/display_footprints/display_footprints.ipynb index 0473f69d2..48c13f54d 100644 --- a/notebooks/multi_mission/display_footprints/display_footprints.ipynb +++ b/notebooks/multi_mission/display_footprints/display_footprints.ipynb @@ -33,9 +33,15 @@ "source": [ "from astroquery.mast import Mast\n", "from ipyaladin import Aladin\n", - "from selectSIAF import defineApertures, getVertices, computeStcsFootprint\n", + "from regions import Regions\n", + "from selectSIAF import defineApertures, getVertices, computeStcsFootprint, computeRegionFootprint\n", + "from getCatalog import gsss_stcsSearch, gsss_stcsSearchUrl\n", + "\n", + "from astropy import units as u\n", + "from astropy.coordinates import SkyCoord\n", "\n", "import matplotlib.pyplot as plt\n", + "import os\n", "import pysiaf\n", "import time" ] @@ -68,16 +74,16 @@ "# define telescope, instrument, and aperture\n", "\n", "selectedTelescope = 'roman'\n", - "selectedInstrument = 'WFI' #Allowed options ALL, WFI, CGI\n", - "selectedAperture = 'ALL' #Allowed options ALL or individual apertures listed in instrument documentation\n", + "selectedInstrument = 'WFI' # Allowed options ALL, WFI, CGI\n", + "selectedAperture = 'ALL' # Allowed options ALL or individual apertures listed in instrument documentation\n", "\n", "# selectedTelescope = 'hst'\n", - "# selectedInstrument = 'ALL' #Allowed options ALL, ACS, COS, FGS, NICMOS, STIS, WFC3\n", - "# selectedAperture = 'ALL' #Allowed options ALL or individual apertures listed in instrument documentation\n", + "# selectedInstrument = 'ALL' # Allowed options ALL, ACS, COS, FGS, NICMOS, STIS, WFC3\n", + "# selectedAperture = 'ALL' # Allowed options ALL or individual apertures listed in instrument documentation\n", "\n", "# selectedTelescope = 'jwst'\n", - "# selectedInstrument = 'ALL' #Allowed options ALL, FGS, MIRI, NIRCAM, NIRSPEC, NIRISS\n", - "# selectedAperture = 'ALL' #Allowed options ALL or individual apertures listed in instrument documentation" + "# selectedInstrument = 'ALL' # Allowed options ALL, FGS, MIRI, NIRCAM, NIRSPEC, NIRISS\n", + "# selectedAperture = 'ALL' # Allowed options ALL or individual apertures listed in instrument documentation" ] }, { @@ -127,7 +133,7 @@ "# iterate through apertures, then plot\n", "for aperture in apertureList:\n", " # circles are not properly plotted, skip\n", - " if aperture.AperShape!='CIRC':\n", + " if aperture.AperShape != 'CIRC':\n", " # set labels=False to remove them\n", " aperture.plot(label=True)\n", "\n", @@ -155,8 +161,11 @@ "outputs": [], "source": [ "# Resolve the target name to coordinates\n", - "coords = Mast.resolve_object(\"M101\")\n", - "coords" + "#coords = Mast.resolve_object(\"M101\")\n", + "#coords\n", + "\n", + "# Specify RA, Dec coordinates (This happens to be Arp 244)\n", + "coords = SkyCoord(180.46, -18.89, frame='icrs', unit='deg')" ] }, { @@ -251,16 +260,16 @@ "source": [ "# Loop through aperture list (only works for QUAD, RECT, CIRC aperture shapes)\n", "# Transform to sky coordinates, build footprints for passing to Aladin\n", - "combinedSregion=''\n", + "combinedSregion = ''\n", "for apertureSiaf in apertureList:\n", " apertureSiaf.set_attitude_matrix(attmat)\n", " xVertices, yVertices = getVertices(apertureSiaf)\n", " \n", - " # Skip PICK which do not have vertices\n", + " # Skip PICK which do not have vertices (HST/FGS is only instrument affected)\n", " if (xVertices is not None and yVertices is not None):\n", " skyRa, skyDec = apertureSiaf.idl_to_sky(xVertices, yVertices)\n", " apertureSregion = computeStcsFootprint(apertureSiaf, skyRa, skyDec)\n", - " combinedSregion+=apertureSregion\n", + " combinedSregion += apertureSregion\n", " \n", "print('\\n'+combinedSregion)" ] @@ -269,10 +278,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Initialize Aladin\n", - "Let's start the Aladin viewer. We're loading a default field of view of 1 degree, with DSS as the background survey. Depending on your screen size, you may need to adjust the `height` (in pixels) to get the best view.\n", + "Optional: Create DS9 region file with footprints\n", "\n", - "**NOTE:** The footprint will not be displayed in the rendered HTML. Please download and run it locally, or use [TIKE](https://timeseries.science.stsci.edu)." + "Although not necessary to generate the final image, it is possible to write the footprints to a DS9 region file if you prefer to use DS9 for displays" ] }, { @@ -281,17 +289,46 @@ "metadata": {}, "outputs": [], "source": [ - "aladin = Aladin(height=600,fov=1, survey=\"P/DSS2/color\", target=coords_str)\n", - "aladin" + "# OPTIONAL build same footprints for creating a DS9 region file\n", + "\n", + "regionList = []\n", + "for i in range(len(apertureList)):\n", + " apertureSiaf = apertureList[i]\n", + " apertureSiaf.set_attitude_matrix(attmat)\n", + " xVertices, yVertices = getVertices(apertureSiaf)\n", + " \n", + " # Skip PICK which do not have vertices\n", + " if (xVertices is not None and yVertices is not None):\n", + " skyRa, skyDec = apertureSiaf.idl_to_sky(xVertices, yVertices)\n", + " apertureRegion = computeRegionFootprint(apertureSiaf, skyRa, skyDec)\n", + " regionList.append(apertureRegion)\n", + " \n", + "# Provide a writeable file location on your system\n", + "regionFile = 'e:\\\\Projects\\\\Scratch\\\\regionTest.reg'\n", + "if os.path.isfile(regionFile):\n", + " os.remove(regionFile)\n", + "combinedRegion = Regions(regionList)\n", + "combinedRegion.write(regionFile)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This looks great, but where's our footprint? Well, we can only add an overlay once `Aladin` is already up and running. \n", + "## Initialize Aladin\n", + "Let's start the Aladin viewer. We're loading a default field of view of 1 degree, with DSS as the background survey. Depending on your screen size, you may need to adjust the `height` (in pixels) to get the best view.\n", "\n", - "Let's add the footprint now:" + "**NOTE:** The footprint will not be displayed in the rendered HTML. Please download and run it locally, or use [TIKE](https://timeseries.science.stsci.edu)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "aladin = Aladin(height=600, fov=1, survey=\"P/DSS2/color\", target=coords_str)\n", + "aladin" ] }, { @@ -323,7 +360,16 @@ "metadata": {}, "outputs": [], "source": [ - "aladin.fov=2" + "aladin.fov = 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This looks great, but where's our footprint? Well, we can only add an overlay once `Aladin` is already up and running. \n", + "\n", + "Let's add the footprint now:" ] }, { @@ -333,6 +379,29 @@ "Done! The footprint is now visible in the Aladin window." ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# Optional Retrieve catalog sources from MAST that lie within footprint and overlay them\n", + "# Supported catalogs : 'GSC11', 'GSC243', 'GSC30', '2MASS', 'GAIADR3' Will add more later\n", + "\n", + "#selectedCatalog = 'GSC11'\n", + "#selectedCatalog = 'GSC243'\n", + "#selectedCatalog = 'GSC30'\n", + "#selectedCatalog = '2MASS'\n", + "selectedCatalog = 'GAIADR3'\n", + "\n", + "url = gsss_stcsSearchUrl(combinedSregion, catalog = selectedCatalog)\n", + "print('\\n'+url)\n", + "options = {'source_size': 12, 'onClick': 'showTable', 'name': selectedCatalog}\n", + "aladin.add_catalog_from_URL(url, options)\n" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -367,7 +436,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.1" + "version": "3.11.5" } }, "nbformat": 4, diff --git a/notebooks/multi_mission/display_footprints/getCatalog.py b/notebooks/multi_mission/display_footprints/getCatalog.py new file mode 100644 index 000000000..94bc25afd --- /dev/null +++ b/notebooks/multi_mission/display_footprints/getCatalog.py @@ -0,0 +1,163 @@ +#! /usr/bin/env python +# Simple query for gsss catalog using requests interface +# This probably could be done more simply using some of the astropy services, but it is +# helpful to see how it works at a lower level +# +# R. White, 2024 May 15 original example +# B.McLean 2024 May 29 expanded to other search types and created url version for Aladin +# Documentation located at https://outerspace.stsci.edu/display/MASTDATA/Catalog+Access + +import requests +from io import BytesIO +from astropy.table import Table + +#import pyvo as vo + +def gsss_coneSearch(ra, dec, radius, catalog = 'GSC30', format = 'votable'): + serviceurl='https://gsss.stsci.edu/webservices/vo/CatalogSearch.aspx' + + # check catalog is allowed + if catalog not in ('GSC11', 'GSC243', 'GSC30', '2MASS', 'GAIADR3'): + raise ValueError('catalog must be one of GSC11, GSC243, GSC30, 2MASS, GAIADR3') + + # check format is allowed + if format not in ('votable', 'csv'): + raise ValueError('format must be one of votable, csv') + + # set up request with parameters + params = dict(ra = ra, dec = dec, sr = radius, cat = catalog, format = format) + r = requests.get(serviceurl, params = params) + # raise exception on error + r.raise_for_status() + + # read result into table + if format == 'csv': + tab = Table.read(r.text, format='ascii.csv', comment='#') + else: + tab = Table.read(BytesIO(r.content), format='votable') + return tab + +def gsss_boxSearch(raMin, decMin, raMax, decMax, catalog = 'GSC30', format = 'votable'): + serviceurl='https://gsss.stsci.edu/webservices/vo/CatalogSearch.aspx' + + #check catalog is allowed + if catalog not in ('GSC11', 'GSC243', 'GSC30', '2MASS', 'GAIADR3'): + raise ValueError('catalog must be one of GSC11, GSC243, GSC30, 2MASS, GAIADR3') + + # check format is allowed + if format not in ('votable', 'csv'): + raise ValueError('format must be one of votable, csv') + + # set up request with parameters + bbox=str(raMin) + ',' + str(decMin) + ',' + str(raMax) + ',' + str(decMax) + params = dict(bbox = bbox, cat = catalog, format = format) + r = requests.get(serviceurl, params = params) + # raise exception on error + r.raise_for_status() + + # read result into table + if format == 'csv': + tab = Table.read(r.text, format='ascii.csv', comment='#') + else: + tab = Table.read(BytesIO(r.content), format='votable') + return tab + +def gsss_stcsSearch(stcs, catalog = 'GSC30', format = 'votable'): + serviceurl='https://gsss.stsci.edu/webservices/vo/CatalogSearch.aspx' + + #check catalog is allowed + if catalog not in ('GSC11', 'GSC243', 'GSC30', '2MASS', 'GAIADR3'): + raise ValueError('catalog must be one of GSC11, GSC243, GSC30, 2MASS, GAIADR3') + + # check format is allowed + if format not in ('votable', 'csv'): + raise ValueError('format must be one of votable, csv') + + # set up request with parameters + params = dict(cat= catalog, stcs = stcs, format = format) + r = requests.get(serviceurl, params = params) + # raise exception on error + r.raise_for_status() + + # read result into table + if format == 'csv': + tab = Table.read(r.text, format='ascii.csv', comment='#') + else: + tab = Table.read(BytesIO(r.content), format='votable') + return tab + +def gsss_idSearch(catID, catalog = 'GSC30', format = 'votable'): + serviceurl='https://gsss.stsci.edu/webservices/vo/CatalogSearch.aspx' + + #check catalog is allowed + if catalog not in ('GSC11', 'GSC243', 'GSC30', '2MASS', 'GAIADR3'): + raise ValueError('catalog must be one of GSC11, GSC243, GSC30, 2MASS, GAIADR3') + + # check format is allowed + if format not in ('votable', 'csv'): + raise ValueError('format must be one of votable, csv') + + # set up request with parameters + params = dict(id = catID, cat = catalog, format = format) + r = requests.get(serviceurl, params = params) + # raise exception on error + r.raise_for_status() + + # read result into table + if format == 'csv': + tab = Table.read(r.text, format='ascii.csv', comment='#') + else: + tab = Table.read(BytesIO(r.content), format='votable') + return tab + +def gsss_stcsSearchUrl(stcs, catalog = 'GSC30', format = 'votable'): + serviceurl = 'https://gsss.stsci.edu/webservices/vo/CatalogSearch.aspx' + + #check catalog is allowed + if catalog not in ('GSC11', 'GSC243', 'GSC30', '2MASS', 'GAIADR3'): + raise ValueError('catalog must be one of GSC11, GSC243, GSC30, 2MASS, GAIADR3') + + # build simple parameterized request url + stcs = stcs.rstrip() + stcs = stcs.replace(' ', '+') + url = serviceurl +'?CAT=' + catalog + '&FORMAT=' + format + '&STCS=' + stcs + + return url + +if __name__ == '__main__': + + # Example calls + print('StcsSearch') + tab = gsss_stcsSearch('CIRCLE 83.633083 -22.0145 0.01', format='csv') + print(tab) + print('\n') + + print('StcsSearch') + tab = gsss_stcsSearch('POLYGON 180.428742 -18.893042 180.455582 -18.906816 180.488081 -18.858382 180.461245 -18.84461 180.428742 -18.893042', catalog='2MASS') + print(tab) + print('\n') + + print('StcsSearchUrl') + url = gsss_stcsSearchUrl('POLYGON 180.428742 -18.893042 180.455582 -18.906816 180.488081 -18.858382 180.461245 -18.84461 180.428742 -18.893042', catalog='2MASS') + print(url) + print('\n') + + print('StcsSearchUrl') + url = gsss_stcsSearchUrl('POLYGON ICRS 180.48076550 -18.90746286 180.36817811 -18.84599471 180.30142864 -18.95458865 180.41432099 -19.01546832 POLYGON ICRS 180.61337499 -18.98023404 180.50312512 -18.92019002 180.43676136 -19.02805554 180.54742848 -19.08735321 POLYGON ICRS 180.73180882 -19.04512674 180.62417451 -18.98663388 180.55826413 -19.09366679 180.66641297 -19.15127114 POLYGON ICRS 180.38476223 -19.01148376 180.27151502 -18.95039598 180.20444240 -19.05820395 180.31779889 -19.11865545 POLYGON ICRS 180.51784519 -19.08456614 180.40670457 -19.02503169 180.33977788 -19.13204690 180.45115278 -19.19078688 POLYGON ICRS 180.63621633 -19.14933193 180.52749585 -19.09145779 180.46082317 -19.19758215 180.56989072 -19.25453642 POLYGON ICRS 180.25335389 -19.09618812 180.13933659 -19.03514272 180.07241672 -19.14183101 180.18632000 -19.20224512 POLYGON ICRS 180.38735634 -19.16989687 180.27504199 -19.11044795 180.20799062 -19.21633154 180.32031836 -19.27498977 POLYGON ICRS 180.50441635 -19.23522897 180.39414431 -19.17747224 180.32711227 -19.28245617 180.43751048 -19.33930232 POLYGON ICRS 180.55186501 -18.79003011 180.43978571 -18.72802620 180.37369416 -18.83696491 180.48624657 -18.89847599 POLYGON ICRS 180.68422620 -18.86286330 180.57459440 -18.80208536 180.50908867 -18.91041251 180.61929164 -18.97052512 POLYGON ICRS 180.80236003 -18.92794523 180.69543451 -18.86855323 180.63056183 -18.97614645 180.73814330 -19.03472259 POLYGON ICRS 180.59805274 -18.65938855 180.48626383 -18.59681364 180.42103650 -18.70560914 180.53344622 -18.76782628 POLYGON ICRS 180.73061197 -18.73228130 180.62127088 -18.67067106 180.55680842 -18.77901247 180.66685926 -18.84007709 POLYGON ICRS 180.84833093 -18.79722860 180.74166672 -18.73677286 180.67800074 -18.84451218 180.78542545 -18.90427161 POLYGON ICRS 180.60897167 -18.50998880 180.49711324 -18.44690783 180.43278142 -18.55497840 180.54537773 -18.61789326 POLYGON ICRS 180.74222983 -18.58314454 180.63263703 -18.52068177 180.56922676 -18.62850933 180.67962961 -18.69061808 POLYGON ICRS 180.85952385 -18.64657059 180.75243600 -18.58495039 180.68994762 -18.69236940 180.79789349 -18.75348418', catalog='2MASS') + print(url) + print('\n') + + print('ConeSearch') + tab = gsss_coneSearch(180.0, 30.0, 0.05) + print(tab) + print('\n') + + print('BoxSearch') + tab = gsss_boxSearch(180.0, 30.0, 180.05, 30.05) + print(tab) + print('\n') + + print('IdSearch') + tab = gsss_idSearch('NBQI004317') + print(tab) + print('\n') diff --git a/notebooks/multi_mission/display_footprints/requirements.txt b/notebooks/multi_mission/display_footprints/requirements.txt index 9fdd53ff7..5c87ff48a 100644 --- a/notebooks/multi_mission/display_footprints/requirements.txt +++ b/notebooks/multi_mission/display_footprints/requirements.txt @@ -1,4 +1,7 @@ +astropy >= 6.1.0 astroquery >= 0.4.7 ipyaladin >= 0.3.0 matplotlib >= 3.8.3 -pysiaf >= 0.22.0 \ No newline at end of file +pysiaf >= 0.22.0 +pyvo >= 1.5.2 +regions >= 0.9 \ No newline at end of file diff --git a/notebooks/multi_mission/display_footprints/selectSIAF.py b/notebooks/multi_mission/display_footprints/selectSIAF.py index 666c7124e..6633edde6 100644 --- a/notebooks/multi_mission/display_footprints/selectSIAF.py +++ b/notebooks/multi_mission/display_footprints/selectSIAF.py @@ -2,12 +2,15 @@ # ASB-25623 Notebook to display Telescope/Instrument footprints on sky viewer # # ASB-25623 Brian McLean Initial prototype v0.1 2024-02-29 +# ASB-27005 Brian McLean Add DS9 region output 2024-05-15 ############################################################### # Imports import matplotlib.pyplot as plt import numpy as np import pysiaf +from astropy.coordinates import SkyCoord +from regions import CircleSkyRegion, PolygonSkyRegion ############################################################### # Take user input to create list of aperture siaf info and v2,v3 reference points @@ -49,7 +52,7 @@ def defineApertures(selectedTelescope, selectedInstrument, selectedAperture): if selectedInstrument.lower() == 'fgs': telescopeSiaf = pysiaf.Siaf(selectedInstrument) if selectedAperture.lower() == 'all' : - apertureNames=['FGS1_FULL','FGS2_FULL'] + apertureNames=['FGS1_FULL', 'FGS2_FULL'] V2Ref = +100.0 V3Ref = -700.0 else: @@ -61,7 +64,7 @@ def defineApertures(selectedTelescope, selectedInstrument, selectedAperture): elif selectedInstrument.lower() == 'miri': telescopeSiaf = pysiaf.Siaf(selectedInstrument) if selectedAperture.lower() == 'all' : - apertureNames=['MIRIM_FULL','MIRIM_MASKLYOT','MIRIM_MASK1550','MIRIM_MASK1140','MIRIM_MASK1065'] + apertureNames=['MIRIM_FULL', 'MIRIM_MASKLYOT', 'MIRIM_MASK1550', 'MIRIM_MASK1140', 'MIRIM_MASK1065'] V2Ref = -425.0 V3Ref = -375.0 else: @@ -73,8 +76,8 @@ def defineApertures(selectedTelescope, selectedInstrument, selectedAperture): elif selectedInstrument.lower() == 'nircam': telescopeSiaf = pysiaf.Siaf(selectedInstrument) if selectedAperture.lower() == 'all' : - apertureNames=['NRCA1_FULL','NRCA1_FULL','NRCA3_FULL','NRCA4_FULL','NRCA5_FULL', - 'NRCB1_FULL','NRCB1_FULL','NRCB3_FULL','NRCB4_FULL','NRCB5_FULL'] + apertureNames = ['NRCA1_FULL', 'NRCA1_FULL', 'NRCA3_FULL', 'NRCA4_FULL', 'NRCA5_FULL', + 'NRCB1_FULL', 'NRCB1_FULL', 'NRCB3_FULL', 'NRCB4_FULL', 'NRCB5_FULL'] V2Ref = 0.0 V3Ref = -500.0 else: @@ -86,8 +89,8 @@ def defineApertures(selectedTelescope, selectedInstrument, selectedAperture): elif selectedInstrument.lower() == 'nirspec': telescopeSiaf = pysiaf.Siaf(selectedInstrument) if selectedAperture.lower() == 'all' : - apertureNames=['NRS_FULL_MSA1','NRS_FULL_MSA2','NRS_FULL_MSA3','NRS_FULL_MSA4', - 'NRS1_FULL','NRS2_FULL'] + apertureNames = ['NRS_FULL_MSA1', 'NRS_FULL_MSA2', 'NRS_FULL_MSA3', 'NRS_FULL_MSA4', + 'NRS1_FULL', 'NRS2_FULL'] V2Ref = +375.0 V3Ref = -425.0 else: @@ -99,7 +102,7 @@ def defineApertures(selectedTelescope, selectedInstrument, selectedAperture): elif selectedInstrument.lower() == 'niriss': telescopeSiaf = pysiaf.Siaf(selectedInstrument) if selectedAperture.lower() == 'all' : - apertureNames=['NIS_CEN','NIS_AMIFULL'] + apertureNames = ['NIS_CEN', 'NIS_AMIFULL'] V2Ref = -300.0 V3Ref = -700.0 else: @@ -110,25 +113,25 @@ def defineApertures(selectedTelescope, selectedInstrument, selectedAperture): apertureList.append(telescopeSiaf[name]) elif selectedInstrument.lower() == 'all': telescopeSiaf = pysiaf.Siaf('FGS') - apertureNames = ['FGS1_FULL','FGS2_FULL'] + apertureNames = ['FGS1_FULL', 'FGS2_FULL'] for name in apertureNames: apertureList.append(telescopeSiaf[name]) telescopeSiaf = pysiaf.Siaf('MIRI') - apertureNames=['MIRIM_FULL','MIRIM_MASKLYOT','MIRIM_MASK1550','MIRIM_MASK1140','MIRIM_MASK1065'] + apertureNames =[ 'MIRIM_FULL', 'MIRIM_MASKLYOT', 'MIRIM_MASK1550', 'MIRIM_MASK1140', 'MIRIM_MASK1065'] for name in apertureNames: apertureList.append(telescopeSiaf[name]) telescopeSiaf = pysiaf.Siaf('NIRCAM') - apertureNames=['NRCA1_FULL','NRCA1_FULL','NRCA3_FULL','NRCA4_FULL','NRCA5_FULL', - 'NRCB1_FULL','NRCB1_FULL','NRCB3_FULL','NRCB4_FULL','NRCB5_FULL'] + apertureNames = ['NRCA1_FULL', 'NRCA1_FULL', 'NRCA3_FULL', 'NRCA4_FULL', 'NRCA5_FULL', + 'NRCB1_FULL', 'NRCB1_FULL', 'NRCB3_FULL', 'NRCB4_FULL', 'NRCB5_FULL'] for name in apertureNames: apertureList.append(telescopeSiaf[name]) telescopeSiaf = pysiaf.Siaf('NIRSPEC') - apertureNames=['NRS_FULL_MSA1','NRS_FULL_MSA2','NRS_FULL_MSA3','NRS_FULL_MSA4', - 'NRS1_FULL','NRS2_FULL'] + apertureNames = ['NRS_FULL_MSA1', 'NRS_FULL_MSA2', 'NRS_FULL_MSA3', 'NRS_FULL_MSA4', + 'NRS1_FULL', 'NRS2_FULL'] for name in apertureNames: apertureList.append(telescopeSiaf[name]) telescopeSiaf = pysiaf.Siaf('NIRISS') - apertureNames=['NIS_CEN','NIS_AMIFULL'] + apertureNames = ['NIS_CEN', 'NIS_AMIFULL'] for name in apertureNames: apertureList.append(telescopeSiaf[name]) V2Ref = 0.0 @@ -140,11 +143,11 @@ def defineApertures(selectedTelescope, selectedInstrument, selectedAperture): telescopeSiaf = pysiaf.Siaf(selectedTelescope) if selectedInstrument.lower() == 'acs': if selectedAperture.lower() == 'all' : - apertureNames=['JWFC1','JWFC2','JHRC','JSBC'] + apertureNames = ['JWFC1', 'JWFC2', 'JHRC', 'JSBC'] V2Ref = telescopeSiaf.apertures['JWFCENTER'].V2Ref V3Ref = telescopeSiaf.apertures['JWFCENTER'].V3Ref else: - apertureNames=[selectedAperture] + apertureNames = [selectedAperture] V2Ref = telescopeSiaf.apertures[selectedAperture].V2Ref V3Ref = telescopeSiaf.apertures[selectedAperture].V3Ref for name in apertureNames: @@ -152,66 +155,66 @@ def defineApertures(selectedTelescope, selectedInstrument, selectedAperture): elif selectedInstrument.lower() == 'cos': if selectedAperture.lower() == 'all' : - apertureNames=['LFMAC','LNMAC'] + apertureNames = ['LFMAC', 'LNMAC'] V2Ref = telescopeSiaf.apertures['LFMAC'].V2Ref V3Ref = telescopeSiaf.apertures['LFMAC'].V3Ref else: - apertureNames=[selectedAperture] + apertureNames = [selectedAperture] V2Ref = telescopeSiaf.apertures[selectedAperture].V2Ref V3Ref = telescopeSiaf.apertures[selectedAperture].V3Ref for name in apertureNames: apertureList.append(telescopeSiaf[name]) elif selectedInstrument.lower() == 'fgs': if selectedAperture.lower() == 'all' : - apertureNames=['FGS1','FGS2','FGS3'] + apertureNames = ['FGS1', 'FGS2', 'FGS3'] V2Ref = 0.0 V3Ref = 0.0 else: - apertureNames=[selectedAperture] + apertureNames = [selectedAperture] V2Ref = telescopeSiaf.apertures[selectedAperture].V2Ref V3Ref = telescopeSiaf.apertures[selectedAperture].V3Ref for name in apertureNames: apertureList.append(telescopeSiaf[name]) elif selectedInstrument.lower() == 'nicmos': if selectedAperture.lower() == 'all' : - apertureNames=['NIC1','NIC2','NIC3'] + apertureNames = ['NIC1', 'NIC2', 'NIC3'] V2Ref = telescopeSiaf.apertures['NIC1'].V2Ref V3Ref = telescopeSiaf.apertures['NIC1'].V3Ref else: - apertureNames=[selectedAperture] + apertureNames = [selectedAperture] V2Ref = telescopeSiaf.apertures[selectedAperture].V2Ref V3Ref = telescopeSiaf.apertures[selectedAperture].V3Ref for name in apertureNames: apertureList.append(telescopeSiaf[name]) elif selectedInstrument.lower() == 'stis': if selectedAperture.lower() == 'all' : - apertureNames=['OVIS','ONUV','OFUV'] + apertureNames = ['OVIS', 'ONUV', 'OFUV'] V2Ref = telescopeSiaf.apertures['OVIS'].V2Ref V3Ref = telescopeSiaf.apertures['OVIS'].V3Ref else: - apertureNames=[selectedAperture] + apertureNames = [selectedAperture] V2Ref = telescopeSiaf.apertures[selectedAperture].V2Ref V3Ref = telescopeSiaf.apertures[selectedAperture].V3Ref for name in apertureNames: apertureList.append(telescopeSiaf[name]) elif selectedInstrument.lower() == 'wfc3': if selectedAperture.lower() == 'all' : - apertureNames=['IUVIS1','IUVIS2','IIR'] + apertureNames = ['IUVIS1', 'IUVIS2', 'IIR'] V2Ref = telescopeSiaf.apertures['IIR'].V2Ref V3Ref = telescopeSiaf.apertures['IIR'].V3Ref else: - apertureNames=[selectedAperture] + apertureNames = [selectedAperture] V2Ref = telescopeSiaf.apertures[selectedAperture].V2Ref V3Ref = telescopeSiaf.apertures[selectedAperture].V3Ref for name in apertureNames: apertureList.append(telescopeSiaf[name]) elif selectedInstrument.lower() == 'all': - apertureNames=['JWFC1','JWFC2','JHRC','JSBC', - 'LFMAC', - 'FGS1','FGS2','FGS3', - 'NIC1','NIC2','NIC3', - 'OVIS','ONUV','OFUV', - 'IUVIS1','IUVIS2','IIR'] + apertureNames = ['JWFC1', 'JWFC2', 'JHRC', 'JSBC', + 'LFMAC', + 'FGS1', 'FGS2', 'FGS3', + 'NIC1', 'NIC2', 'NIC3', + 'OVIS', 'ONUV', 'OFUV', + 'IUVIS1', 'IUVIS2', 'IIR'] V2Ref = 0.0 V3Ref = 0.0 else: @@ -227,21 +230,21 @@ def defineApertures(selectedTelescope, selectedInstrument, selectedAperture): def getVertices(apertureSiaf): if (apertureSiaf.observatory == 'Roman' and apertureSiaf.AperShape == 'QUAD'): - xVertices = np.array([apertureSiaf.XIdlVert1,apertureSiaf.XIdlVert2,apertureSiaf.XIdlVert3,apertureSiaf.XIdlVert4]) - yVertices = np.array([apertureSiaf.YIdlVert1,apertureSiaf.YIdlVert2,apertureSiaf.YIdlVert3,apertureSiaf.YIdlVert4]) + xVertices = np.array([apertureSiaf.XIdlVert1, apertureSiaf.XIdlVert2, apertureSiaf.XIdlVert3, apertureSiaf.XIdlVert4]) + yVertices = np.array([apertureSiaf.YIdlVert1, apertureSiaf.YIdlVert2, apertureSiaf.YIdlVert3, apertureSiaf.YIdlVert4]) if (apertureSiaf.observatory == 'JWST' and apertureSiaf.AperShape == 'QUAD'): - xVertices = np.array([apertureSiaf.XIdlVert1,apertureSiaf.XIdlVert2,apertureSiaf.XIdlVert3,apertureSiaf.XIdlVert4]) - yVertices = np.array([apertureSiaf.YIdlVert1,apertureSiaf.YIdlVert2,apertureSiaf.YIdlVert3,apertureSiaf.YIdlVert4]) + xVertices = np.array([apertureSiaf.XIdlVert1, apertureSiaf.XIdlVert2, apertureSiaf.XIdlVert3, apertureSiaf.XIdlVert4]) + yVertices = np.array([apertureSiaf.YIdlVert1, apertureSiaf.YIdlVert2, apertureSiaf.YIdlVert3, apertureSiaf.YIdlVert4]) if (apertureSiaf.observatory == 'HST' and (apertureSiaf.AperShape == 'QUAD' or apertureSiaf.AperShape == 'RECT')): - xVertices = np.array([apertureSiaf.v1x,apertureSiaf.v2x,apertureSiaf.v3x,apertureSiaf.v4x]) - yVertices = np.array([apertureSiaf.v1y,apertureSiaf.v2y,apertureSiaf.v3y,apertureSiaf.v4y]) + xVertices = np.array([apertureSiaf.v1x, apertureSiaf.v2x, apertureSiaf.v3x, apertureSiaf.v4x]) + yVertices = np.array([apertureSiaf.v1y, apertureSiaf.v2y, apertureSiaf.v3y, apertureSiaf.v4y]) if (apertureSiaf.observatory == 'HST' and apertureSiaf.AperShape == 'CIRC'): xVertices = apertureSiaf.V2Ref yVertices = apertureSiaf.V3Ref if (apertureSiaf.observatory == 'HST' and apertureSiaf.AperShape == 'PICK'): - print('Unsupported shape ',apertureSiaf.AperShape) + print('Unsupported shape ', apertureSiaf.AperShape) xVertices = None yVertices = None @@ -251,15 +254,27 @@ def getVertices(apertureSiaf): def computeStcsFootprint(apertureSiaf, skyRa, skyDec): if (apertureSiaf.AperShape == 'QUAD' or apertureSiaf.AperShape == 'RECT'): - apertureSregion='POLYGON ICRS {:.8f} {:.8f} {:.8f} {:.8f} {:.8f} {:.8f} {:.8f} {:.8f} '.format(skyRa[0],skyDec[0],skyRa[1],skyDec[1],skyRa[2],skyDec[2],skyRa[3],skyDec[3]) + apertureSregion = 'POLYGON ICRS {:.8f} {:.8f} {:.8f} {:.8f} {:.8f} {:.8f} {:.8f} {:.8f} '.format(skyRa[0], skyDec[0], skyRa[1], skyDec[1], skyRa[2], skyDec[2], skyRa[3], skyDec[3]) elif apertureSiaf.AperShape == 'CIRC': radius = apertureSiaf.maj/3600.0 - apertureSregion='CIRCLE ICRS {} {} {} '.format(skyRa, skyDec, radius) - #elif apertureSiaf.AperShape == 'PICK': - #radius = apertureSiaf.maj/3600.0 - #apertureSregion='POLYGON ICRS {} {} {} '.format(skyRa, skyDec, radius) + apertureSregion = 'CIRCLE ICRS {} {} {} '.format(skyRa, skyDec, radius) else: print('Unsupported shape {}').format(apertureSiaf.AperShape) return apertureSregion ############################################################### +# Take the sky coordinates of the aperture vertices and convert to an SkyCoord region object + +def computeRegionFootprint(apertureSiaf, skyRa, skyDec): + if (apertureSiaf.AperShape == 'QUAD' or apertureSiaf.AperShape == 'RECT'): + vertices = SkyCoord([skyRa[0], skyRa[1], skyRa[2], skyRa[3]], [skyDec[0], skyDec[1], skyDec[2], skyDec[3]], unit='deg') + region_sky = PolygonSkyRegion(vertices=vertices) + elif apertureSiaf.AperShape == 'CIRC': + radius = apertureSiaf.maj/3600.0 + center_sky = SkyCoord(skyRa, skyDec, unit='deg') + region_sky = CircleSkyRegion(center=center_sky, radius=radius) + else: + print('Unsupported shape {}').format(apertureSiaf.AperShape) + + return region_sky +############################################################### \ No newline at end of file