| Next changeset 1:7fad1abc2e4a (2025-06-13) |
|
Commit message:
planemo upload for repository https://github.com/esg-epfl-apc/tools-astro/tree/main/tools commit 7315eeb043225f7cfd1cf0f3a95e181289d7de32 |
|
added:
Catalog.py Image.py Spectrum.py desi.py desi_legacy_survey_astro_tool.xml |
| b |
| diff -r 000000000000 -r ea39f416af9d Catalog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Catalog.py Mon Apr 28 14:59:01 2025 +0000 |
| [ |
| @@ -0,0 +1,255 @@ +#!/usr/bin/env python +# coding: utf-8 + +#!/usr/bin/env python + +# This script is generated with nb2galaxy + +# flake8: noqa + +import json +import os +import shutil + +import astropy.units as u +import numpy as np + +# Conventional astronomical tools, also to be traced by Renku plugin, there is domain-specific ontology built in +from astropy.coordinates import Angle # Angles +from astropy.coordinates import SkyCoord # High-level coordinates +from astropy.table import Table +from desi import DESILegacySurvey +from oda_api.json import CustomJSONEncoder + +nano_maggies_to_microJy = 3.631 # constant of conversion + +src_name = "Mrk 421" # http://odahub.io/ontology#AstrophysicalObject +RA = 166.113808 # http://odahub.io/ontology#PointOfInterestRA +DEC = 38.208833 # http://odahub.io/ontology#PointOfInterestDEC +Radius = 1 # http://odahub.io/ontology#AngleMinutes +data_release = ( + 10 # http://odahub.io/ontology#Integer ; oda:label "Data Release" +) + +_galaxy_wd = os.getcwd() + +with open("inputs.json", "r") as fd: + inp_dic = json.load(fd) +if "C_data_product_" in inp_dic.keys(): + inp_pdic = inp_dic["C_data_product_"] +else: + inp_pdic = inp_dic +src_name = str(inp_pdic["src_name"]) +RA = float(inp_pdic["RA"]) +DEC = float(inp_pdic["DEC"]) +Radius = float(inp_pdic["Radius"]) +data_release = int(inp_pdic["data_release"]) + +# https://arxiv.org/pdf/2208.08513 Table 2 +# def compute_magnitude(flux, mw_transmission): +# return 22.5 - 2.5 * np.log10(flux / mw_transmission) + +# def compute_error_mag(flux, flux_ivar): +# dflux = 1 / np.sqrt(flux_ivar) +# # 2.5 / ln(10) * (dflux / flux) +# return 1.0857 * dflux / flux + +def clean_flux(flux, flux_ivar): + new_flux = np.exp(np.log(flux * nano_maggies_to_microJy)) + new_flux_ivar = np.exp( + np.log(nano_maggies_to_microJy / np.sqrt(flux_ivar)) + ) + return new_flux, new_flux_ivar + +ra_s = RA +dec_s = DEC +dr = data_release +source = SkyCoord(ra_s, dec_s, unit="degree") +Radius = Angle(Radius * u.arcmin) + +case_ = 0 +if source.galactic.b > 0: + if dec_s >= 32: + print("MzLS") + case_ = 1 + else: + print("DECALS") +else: + print("DECALS") + +error_message = f"No data found, i.e. (RA, Dec) = ({ra_s}, {dec_s}) is outside the covered region by Data Release {dr}." +try: + query = DESILegacySurvey.query_region( + coordinates=source, radius=Radius, data_release=dr + ) +except: + raise RuntimeError(error_message) + +if len(query) == 0: + raise RuntimeError(error_message) + +tap_result = query + +from oda_api.data_products import ODAAstropyTable + +ra = tap_result["ra"] +dec = tap_result["dec"] +t = tap_result["type"] +s_r = tap_result["shape_r"] + +flux_g, flux_g_err = clean_flux( + tap_result["flux_g"], tap_result["flux_ivar_g"] +) +flux_r, flux_r_err = clean_flux( + tap_result["flux_r"], tap_result["flux_ivar_r"] +) +flux_z, flux_z_err = clean_flux( + tap_result["flux_z"], tap_result["flux_ivar_z"] +) +flux_w1, flux_w1_err = clean_flux( + tap_result["flux_w1"], tap_result["flux_ivar_w1"] +) +flux_w2, flux_w2_err = clean_flux( + tap_result["flux_w2"], tap_result["flux_ivar_w2"] +) +flux_w3, flux_w3_err = clean_flux( + tap_result["flux_w3"], tap_result["flux_ivar_w3"] +) +flux_w4, flux_w4_err = clean_flux( + tap_result["flux_w4"], tap_result["flux_ivar_w4"] +) + +ebv = tap_result["ebv"] +ref_cat = tap_result["ref_cat"] +ref_cat[ref_cat == ""] = "NN" + +try: + flux_i, flux_i_err = clean_flux( + tap_result["flux_i"], tap_result["flux_ivar_i"] + ) +except: + flux_i = -99 * np.ones_like(flux_g) + flux_i_err = -99 * np.ones_like(flux_g) + flux_i, flux_i_err = clean_flux(flux_i, flux_i_err) + +data = [ + ra, + dec, + t, + flux_g, + flux_g_err, + flux_r, + flux_r_err, + flux_z, + flux_z_err, + flux_i, + flux_i_err, + flux_w1, + flux_w1_err, + flux_w2, + flux_w2_err, + flux_w3, + flux_w3_err, + flux_w4, + flux_w4_err, + ebv, + ref_cat, + s_r, +] +names = ( + "RA", + "DEC", + "Type", + "flux_g", + "flux_g_err", + "flux_r", + "flux_r_err", + "flux_z", + "flux_z_err", + "flux_i", + "flux_i_err", + "flux_w1", + "flux_w1_err", + "flux_w2", + "flux_w2_err", + "flux_w3", + "flux_w3_err", + "flux_w4", + "flux_w4_err", + "ebv", + "ref_cat", + "shape_r", +) +cat = ODAAstropyTable(Table(data, names=names)) + +flux_error_list = [ + "flux_i_err", + "flux_g_err", + "flux_r_err", + "flux_z_err", + "flux_w1_err", + "flux_w2_err", +] +flux_list = ["flux_i", "flux_g", "flux_r", "flux_z", "flux_w1", "flux_w2"] +if case_ == 0: + filter_list = [ + "DECam|DECam.i", + "DECam|DECam.g", + "DECam|DECam.r", + "DECam|DECam.z", + "WISE|WISE.W1", + "WISE|WISE.W2", + ] +elif case_ == 1: + filter_list = [ + "DECam|DECam.i", + "DESI|bass.g", + "DESI|bass.r", + "DESI|MzLS.z", + "WISE|WISE.W1", + "WISE|WISE.W2", + ] + +dict_filters = { + "filter": filter_list, + "flux_error": flux_error_list, + "flux": flux_list, +} +dict_filters + +catalog_table = cat # http://odahub.io/ontology#ODAAstropyTable +dictionary_filters = dict_filters # http://odahub.io/ontology#ODATextProduct + +# output gathering +_galaxy_meta_data = {} +_oda_outs = [] +_oda_outs.append( + ("out_Catalog_catalog_table", "catalog_table_galaxy.output", catalog_table) +) +_oda_outs.append( + ( + "out_Catalog_dictionary_filters", + "dictionary_filters_galaxy.output", + dictionary_filters, + ) +) + +for _outn, _outfn, _outv in _oda_outs: + _galaxy_outfile_name = os.path.join(_galaxy_wd, _outfn) + if isinstance(_outv, str) and os.path.isfile(_outv): + shutil.move(_outv, _galaxy_outfile_name) + _galaxy_meta_data[_outn] = {"ext": "_sniff_"} + elif getattr(_outv, "write_fits_file", None): + _outv.write_fits_file(_galaxy_outfile_name) + _galaxy_meta_data[_outn] = {"ext": "fits"} + elif getattr(_outv, "write_file", None): + _outv.write_file(_galaxy_outfile_name) + _galaxy_meta_data[_outn] = {"ext": "_sniff_"} + else: + with open(_galaxy_outfile_name, "w") as fd: + json.dump(_outv, fd, cls=CustomJSONEncoder) + _galaxy_meta_data[_outn] = {"ext": "json"} + +with open(os.path.join(_galaxy_wd, "galaxy.json"), "w") as fd: + json.dump(_galaxy_meta_data, fd) +print("*** Job finished successfully ***") |
| b |
| diff -r 000000000000 -r ea39f416af9d Image.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Image.py Mon Apr 28 14:59:01 2025 +0000 |
| [ |
| @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# coding: utf-8 + +#!/usr/bin/env python + +# This script is generated with nb2galaxy + +# flake8: noqa + +import json +import os +import shutil + +import astropy.units as u + +# conventional python routines +import matplotlib.pyplot as plt +import numpy as np +from astropy.coordinates import Angle # Angles +from astropy.coordinates import SkyCoord # High-level coordinates +from astropy.io import fits + +# Conventional astronomical tools, also to be traced by Renku plugin, there is domain-specific ontology built in +from astropy.wcs import WCS + +# from astroquery.desi import DESILegacySurvey +# from astroq.desi import DESILegacySurvey +from desi import DESILegacySurvey +from matplotlib.colors import LogNorm +from oda_api.json import CustomJSONEncoder + +get_ipython().run_line_magic("matplotlib", "inline") # noqa: F821 +from matplotlib.colors import LogNorm + +# if not(os.path.isdir('figs')): +# os.makedirs('figs') +# if not(os.path.isdir('data')): +# os.makedirs('data') + +src_name = "Mrk 421" # http://odahub.io/ontology#AstrophysicalObject +RA = 166.113808 # http://odahub.io/ontology#PointOfInterestRA +DEC = 38.208833 # http://odahub.io/ontology#PointOfInterestDEC +Radius = 3 # http://odahub.io/ontology#AngleMinutes +pixsize = ( + 1.0 # http://odahub.io/ontology#AngleSeconds ; oda:label "Pixel size" +) +band = "g" # http://odahub.io/ontology#String ; oda:allowed_value "g","r","i","z" ; oda:label "Band" +data_release = ( + 10 # http://odahub.io/ontology#Integer ; oda:label "Data Release" +) + +_galaxy_wd = os.getcwd() + +with open("inputs.json", "r") as fd: + inp_dic = json.load(fd) +if "C_data_product_" in inp_dic.keys(): + inp_pdic = inp_dic["C_data_product_"] +else: + inp_pdic = inp_dic +src_name = str(inp_pdic["src_name"]) +RA = float(inp_pdic["RA"]) +DEC = float(inp_pdic["DEC"]) +Radius = float(inp_pdic["Radius"]) +pixsize = float(inp_pdic["pixsize"]) +band = str(inp_pdic["band"]) +data_release = int(inp_pdic["data_release"]) + +ra_s = RA +dec_s = DEC +image_size = Radius +image_band = band +dr = data_release +image_size = Angle(image_size * u.arcmin) +pixsize = Angle(pixsize * u.arcsec) +npix = int(2 * image_size / pixsize) +source = SkyCoord(ra_s, dec_s, unit="degree") + +if dr < 10 and band == "i": + raise RuntimeError( + f"No data found. Data Release {dr} does not have '{band}' band." + ) + +try: + query = DESILegacySurvey.get_images( + position=source, + survey="dr%d" % dr, + coordinates="icrs", + data_release=dr, + pixels=npix, + radius=image_size, + image_band=image_band, + ) +except: + raise RuntimeError( + f"No data found. Maybe (RA, Dec) = ({ra_s}, {dec_s}) is outside the covered region by Data Release {dr}." + ) + +hdul = query[0] +hdul[0].header + +query[0].writeto("Image.fits", overwrite=True) + +# paramstring='ra='+str(ra_s)+'&dec='+str(dec_s)+'&size='+str(npix)+'&layer=ls-dr'+str(dr)+'&pixscale='+str(pixsize)+'&bands='+image_band +# suffix = hashlib.md5(paramstring.encode()).hexdigest() +# filename='data/image_legacysurvey_%s.fits'%( suffix ) + +# if os.path.exists(filename): +# os.remove(filename) +# hdul.writeto(filename) + +hdu = hdul[0] +image = hdu.data +w = WCS(hdu.header) +sky = w.pixel_to_world(0, 0) +ra_max_image = sky.ra.degree +dec_min_image = sky.dec.degree +sky = w.pixel_to_world(npix - 1, npix - 1) +ra_min_image = sky.ra.degree +dec_max_image = sky.dec.degree + +plt.figure(figsize=(17, 13)) +im = plt.imshow( + image, + norm=LogNorm(vmax=np.max(image), vmin=np.max(image) / 1e3), + origin="lower", + extent=(ra_max_image, ra_min_image, dec_min_image, dec_max_image), +) +plt.grid(color="black", ls="solid") +# plt.scatter(ra,dec,color='red',alpha=0.9) +plt.scatter([ra_s], [dec_s], color="blue", linewidth=4, alpha=0.3) + +plt.xlabel("RA", fontsize=16) +plt.ylabel("DEC", fontsize=16) + +plt.tick_params(axis="both", which="major", labelsize=16) +plt.colorbar(im) + +plt.savefig("Image.png", format="png", bbox_inches="tight") + +from oda_api.data_products import ImageDataProduct, PictureProduct + +bin_image = PictureProduct.from_file("Image.png") +fits_image = ImageDataProduct.from_fits_file("Image.fits") + +picture = bin_image # http://odahub.io/ontology#ODAPictureProduct +fits = fits_image # http://odahub.io/ontology#Image + +# output gathering +_galaxy_meta_data = {} +_oda_outs = [] +_oda_outs.append(("out_Image_picture", "picture_galaxy.output", picture)) +_oda_outs.append(("out_Image_fits", "fits_galaxy.output", fits)) + +for _outn, _outfn, _outv in _oda_outs: + _galaxy_outfile_name = os.path.join(_galaxy_wd, _outfn) + if isinstance(_outv, str) and os.path.isfile(_outv): + shutil.move(_outv, _galaxy_outfile_name) + _galaxy_meta_data[_outn] = {"ext": "_sniff_"} + elif getattr(_outv, "write_fits_file", None): + _outv.write_fits_file(_galaxy_outfile_name) + _galaxy_meta_data[_outn] = {"ext": "fits"} + elif getattr(_outv, "write_file", None): + _outv.write_file(_galaxy_outfile_name) + _galaxy_meta_data[_outn] = {"ext": "_sniff_"} + else: + with open(_galaxy_outfile_name, "w") as fd: + json.dump(_outv, fd, cls=CustomJSONEncoder) + _galaxy_meta_data[_outn] = {"ext": "json"} + +with open(os.path.join(_galaxy_wd, "galaxy.json"), "w") as fd: + json.dump(_galaxy_meta_data, fd) +print("*** Job finished successfully ***") |
| b |
| diff -r 000000000000 -r ea39f416af9d Spectrum.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Spectrum.py Mon Apr 28 14:59:01 2025 +0000 |
| [ |
| @@ -0,0 +1,188 @@ +#!/usr/bin/env python +# coding: utf-8 + +#!/usr/bin/env python + +# This script is generated with nb2galaxy + +# flake8: noqa + +import json +import os +import shutil + +import astropy.units as u +import numpy as np + +# Conventional astronomical tools, also to be traced by Renku plugin, there is domain-specific ontology built in +from astropy.coordinates import Angle # Angles +from astropy.coordinates import SkyCoord # High-level coordinates +from astropy.table import Table +from desi import DESILegacySurvey +from numpy import pi, sqrt +from oda_api.json import CustomJSONEncoder + +nano_maggies_to_microJy = 3.631 # constant of conversion +nano_maggies_to_Jy = 3.631e-6 # constant of conversion + +import matplotlib.pyplot as plt + +src_name = "Mrk 421" # http://odahub.io/ontology#AstrophysicalObject +RA = 166.113808 # http://odahub.io/ontology#PointOfInterestRA +DEC = 38.208833 # http://odahub.io/ontology#PointOfInterestDEC +Radius = 0.1 # http://odahub.io/ontology#AngleMinutes +data_release = ( + 10 # http://odahub.io/ontology#Integer ; oda:label "Data Release" +) + +_galaxy_wd = os.getcwd() + +with open("inputs.json", "r") as fd: + inp_dic = json.load(fd) +if "C_data_product_" in inp_dic.keys(): + inp_pdic = inp_dic["C_data_product_"] +else: + inp_pdic = inp_dic +src_name = str(inp_pdic["src_name"]) +RA = float(inp_pdic["RA"]) +DEC = float(inp_pdic["DEC"]) +Radius = float(inp_pdic["Radius"]) +data_release = int(inp_pdic["data_release"]) + +def clean_flux(flux, flux_ivar): + new_flux = flux * nano_maggies_to_microJy + new_flux_ivar = nano_maggies_to_microJy / np.sqrt(flux_ivar) + return new_flux, new_flux_ivar + +ra_s = RA +dec_s = DEC +dr = data_release +source = SkyCoord(ra_s, dec_s, unit="degree") +Radius = Angle(Radius * u.arcmin) + +case_ = 0 +if source.galactic.b > 0: + if dec_s >= 32: + print("MzLS") + case_ = 1 + else: + print("DECALS") +else: + print("DECALS") + +error_message = f"No data found, i.e. (RA, Dec) = ({ra_s}, {dec_s}) is outside the covered region by Data Release {dr}." +try: + query = DESILegacySurvey.query_region( + coordinates=source, radius=Radius, data_release=dr + ) +except: + raise RuntimeError(error_message) + +if len(query) == 0: + raise RuntimeError(error_message) + +tap_result = query + +wavelength = np.array( + [4770, 6231, 9134, 3.368e4, 4.618e4, 12.082e4, 22.194e4] +) # in Angstroem +wavelength = wavelength * 1e-8 # in cm +frequency = 3.0e10 / wavelength # in Hz +energy = 2 * pi * 6.67e-16 * frequency # in eV +factor = 1e-23 * frequency # conversion of Jy to erg/cm2s + +filters = { + "g": 4770, + "r": 6231, + "z": 9134, + "w1": 3.368e4, + "w2": 4.618e4, + "w3": 12.082e4, + "w4": 22.194e4, +} +nsources = len(query["ra"]) +ras = np.array(query["ra"]) +decs = np.array(query["dec"]) + +coords = SkyCoord(ra=ras, dec=decs, unit="deg", frame="icrs") +sep = source.separation(coords).arcmin +t = query["type"] +for i in range(nsources): + if t[i] == "DUP": + sep[i] = 100.0 +index = np.argmin(sep) + +label = ["g", "r", "z", "w1", "w2", "w3", "w4"] +flux = np.zeros(len(label)) +flux_err = np.zeros(len(label)) +for ind in range(nsources): + if t[ind] != "DUP": + for j, i in enumerate(label): + y1 = query[ind]["flux_" + i] + if y1 > 0: + y1 = y1 / query["mw_transmission_" + i][ind] # in nanomaggies + y1_err = ( + 1.0 + / sqrt(query[ind]["flux_ivar_" + i]) + / query["mw_transmission_" + i][ind] + ) # in nanomaggies + flux[j] += y1 + flux_err[j] += y1_err**2 + +flux *= nano_maggies_to_Jy * factor +flux_err = sqrt(flux_err) +flux_err *= nano_maggies_to_Jy * factor +plt.errorbar(energy, flux, flux_err, marker="o", color="black", linewidth=2) +plt.yscale("log") +plt.xscale("log") +plt.legend(loc="lower right") +plt.xlabel("$E$, [eV]", fontsize=16) +plt.ylabel("$E^2dN/dE$, [erg/(cm$^2$s)]", fontsize=16) +plt.savefig("Spectrum.png") + +from oda_api.data_products import ODAAstropyTable + +data = [energy, flux, flux_err] +names = ("Energy[eV]", "Flux[erg/cm2s]", "Flux_err[erg/cm2s]") +spec = ODAAstropyTable(Table(data, names=names)) + +from oda_api.data_products import PictureProduct + +bin_image = PictureProduct.from_file("Spectrum.png") + +spectrum_table = spec # http://odahub.io/ontology#ODAAstropyTable +spectrum_png = bin_image # http://odahub.io/ontology#ODAPictureProduct + +# output gathering +_galaxy_meta_data = {} +_oda_outs = [] +_oda_outs.append( + ( + "out_Spectrum_spectrum_table", + "spectrum_table_galaxy.output", + spectrum_table, + ) +) +_oda_outs.append( + ("out_Spectrum_spectrum_png", "spectrum_png_galaxy.output", spectrum_png) +) + +for _outn, _outfn, _outv in _oda_outs: + _galaxy_outfile_name = os.path.join(_galaxy_wd, _outfn) + if isinstance(_outv, str) and os.path.isfile(_outv): + shutil.move(_outv, _galaxy_outfile_name) + _galaxy_meta_data[_outn] = {"ext": "_sniff_"} + elif getattr(_outv, "write_fits_file", None): + _outv.write_fits_file(_galaxy_outfile_name) + _galaxy_meta_data[_outn] = {"ext": "fits"} + elif getattr(_outv, "write_file", None): + _outv.write_file(_galaxy_outfile_name) + _galaxy_meta_data[_outn] = {"ext": "_sniff_"} + else: + with open(_galaxy_outfile_name, "w") as fd: + json.dump(_outv, fd, cls=CustomJSONEncoder) + _galaxy_meta_data[_outn] = {"ext": "json"} + +with open(os.path.join(_galaxy_wd, "galaxy.json"), "w") as fd: + json.dump(_galaxy_meta_data, fd) +print("*** Job finished successfully ***") |
| b |
| diff -r 000000000000 -r ea39f416af9d desi.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/desi.py Mon Apr 28 14:59:01 2025 +0000 |
| [ |
| b'@@ -0,0 +1,388 @@\n+# Licensed under a 3-clause BSD style license - see LICENSE.rst\n+\n+\n+# put all imports organized as shown below\n+# 1. standard library imports\n+import socket\n+# 2. third party imports\n+import urllib\n+\n+from astropy.coordinates import SkyCoord\n+import requests\n+from astropy.table import Table, vstack\n+from astropy.io import fits\n+from astropy import config as _config\n+import astropy.utils.data as aud\n+import time\n+\n+# 3. local imports - use relative imports\n+# commonly required local imports shown below as example\n+# all Query classes should inherit from BaseQuery.\n+from astroquery.exceptions import NoResultsWarning\n+\n+# from ..query import BaseQuery\n+# has common functions required by most modules\n+# prepend_docstr is a way to copy docstrings between methods\n+# async_to_sync generates the relevant query tools from _async methods\n+# import configurable items declared in __init__.py\n+# from . import conf\n+\n+import pyvo as vo\n+from numpy import cos, pi\n+# export all the public classes and methods\n+__all__ = [\'DESILegacySurvey\', \'DESILegacySurveyClass\']\n+\n+# declare global variables and constants if any\n+\n+\n+# Now begin your main class\n+# should be decorated with the async_to_sync imported previously\n+from astropy.io.fits import HDUList\n+\n+\n+class Conf(_config.ConfigNamespace):\n+ """\n+ Configuration parameters for `astroquery.desi`.\n+ """\n+ server = _config.ConfigItem(\n+ [\'https://portal.nersc.gov/cfs/cosmo/data/legacysurvey/\',\n+ ],\n+ \'base url\')\n+\n+ timeout = _config.ConfigItem(\n+ 30,\n+ \'Time limit for connecting to template_module server.\')\n+\n+\n+class FileContainer:\n+ """\n+ A File Object container, meant to offer lazy access to downloaded FITS\n+ files.\n+ """\n+\n+ def __init__(self, target, **kwargs):\n+ kwargs.setdefault(\'cache\', True)\n+ self._target = target\n+ self._timeout = kwargs.get(\'remote_timeout\', aud.conf.remote_timeout)\n+ self._readable_object = get_readable_fileobj(target, **kwargs)\n+\n+ def get_fits(self):\n+ """\n+ Assuming the contained file is a FITS file, read it\n+ and return the file parsed as FITS HDUList\n+ """\n+ filedata = self.get_string()\n+\n+ if len(filedata) == 0:\n+ raise TypeError("The file retrieved was empty.")\n+\n+ self._fits = fits.HDUList.fromstring(filedata)\n+\n+ return self._fits\n+\n+ def get_string(self):\n+ """\n+ Download the file as a string\n+ """\n+ if not hasattr(self, \'_string\'):\n+ try:\n+ with self._readable_object as f:\n+ data = f.read()\n+ self._string = data\n+ except urllib.error.URLError as e:\n+ if isinstance(e.reason, socket.timeout):\n+ raise TimeoutError("Query timed out, time elapsed {t}s".\n+ format(t=self._timeout))\n+ else:\n+ raise e\n+\n+ return self._string\n+\n+ def __repr__(self):\n+ if hasattr(self, \'_fits\'):\n+ return f"Downloaded FITS file: {self._fits!r}"\n+ else:\n+ return f"Downloaded object from URL {self._target} with ID {id(self._readable_object)}"\n+\n+\n+def get_readable_fileobj(*args, **kwargs):\n+ """\n+ Overload astropy\'s get_readable_fileobj so that we can safely monkeypatch\n+ it in astroquery without affecting astropy core functionality\n+ """\n+ return aud.get_readable_fileobj(*args, **kwargs)\n+\n+\n+class DESILegacySurveyClass():\n+\n+ """\n+ Not all the methods below are necessary but these cover most of the common\n+ cases, new methods may be added if necessary, follow the guidelines at\n+ <http://astroquery.readthedocs.io/en/latest/api.html>\n+ """\n+ # use the Configuration Items imported from __init__.py to set the URL,\n+ # TIMEOUT, etc.\n+ conf = Conf()\n+ URL = conf.server\n+ TIMEOUT = conf.timeout\n+\n+ # all query'..b'er(image_url, encoding=\'binary\', show_progress=show_progress)\n+\n+ try:\n+ fits_file = file_container.get_fits()\n+ except (requests.exceptions.HTTPError, urllib.error.HTTPError) as e:\n+ # TODO not sure this is the most suitable exception\n+ raise NoResultsWarning(f"{str(e)} - Problem retrieving the file at the url: {str(image_url)}")\n+\n+ return [fits_file]\n+\n+ def get_images(self, position, survey, coordinates=None, data_release=9,\n+ projection=None, pixels=None, scaling=None,\n+ sampler=None, resolver=None, deedger=None, lut=None,\n+ grid=None, gridlabels=None, radius=None, height=None,\n+ width=None, cache=True, show_progress=True, image_band=\'g\'):\n+ response = self.get_images_async(position, survey, coordinates=coordinates, data_release=data_release,\n+ projection=projection, pixels=pixels, scaling=scaling,\n+ sampler=sampler, resolver=resolver, deedger=deedger, lut=lut,\n+ grid=grid, gridlabels=gridlabels, radius=radius, height=height,\n+ width=width, cache=cache, show_progress=show_progress, image_band=image_band)\n+ # if get_query_payload:\n+ return response\n+ # result = self._parse_result(response)\n+ # return result\n+\n+ # as we mentioned earlier use various python regular expressions, etc\n+ # to create the dict of HTTP request parameters by parsing the user\n+ # entered values. For cleaner code keep this as a separate private method:\n+\n+ def _args_to_payload(self, *args, **kwargs):\n+ request_payload = dict()\n+ # code to parse input and construct the dict\n+ # goes here. Then return the dict to the caller\n+\n+ return request_payload\n+\n+ # the methods above call the private _parse_result method.\n+ # This should parse the raw HTTP response and return it as\n+ # an `astropy.table.Table`. Below is the skeleton:\n+\n+ def _parse_result(self, responses):\n+ tables_list = []\n+ output_table = Table()\n+\n+ # handles the cases of query_region with TAP which returns a Table\n+ # or get_images which should return a list of HDUList, and here in DESILegacySurvey\n+ # a list of one HDUList object is returned\n+ if isinstance(responses, Table) or \\\n+ (isinstance(responses, list) and isinstance(responses[0], HDUList)):\n+ return responses\n+\n+ # try to parse the result into an astropy.Table, else\n+ # return the raw result with an informative error message.\n+ try:\n+ if not isinstance(responses, list):\n+ responses = [responses]\n+\n+ # do something with regex to get the result into\n+ # astropy.Table form. return the Table.\n+ # data = io.BytesIO(response.content)\n+ # table = Table.read(data)\n+\n+ for r in responses:\n+ if r.status_code == 200:\n+ # TODO figure out on how to avoid writing in a file\n+ with open(\'/tmp/file_content\', \'wb\') as fin:\n+ fin.write(r.content)\n+\n+ table = Table.read(\'/tmp/file_content\', hdu=1)\n+ tables_list.append(table)\n+\n+ if len(tables_list) > 0:\n+ output_table = vstack(tables_list)\n+\n+ except ValueError:\n+ # catch common errors here, but never use bare excepts\n+ # return raw result/ handle in some way\n+ pass\n+\n+ return output_table\n+\n+\n+# the default tool for users to interact with is an instance of the Class\n+DESILegacySurvey = DESILegacySurveyClass()\n+\n+# once your class is done, tests should be written\n+# See ./tests for examples on this\n+\n+# Next you should write the docs in astroquery/docs/module_name\n+# using Sphinx.\n' |
| b |
| diff -r 000000000000 -r ea39f416af9d desi_legacy_survey_astro_tool.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/desi_legacy_survey_astro_tool.xml Mon Apr 28 14:59:01 2025 +0000 |
| [ |
| @@ -0,0 +1,125 @@ +<tool id="desi_legacy_survey_astro_tool" name="DESI Legacy Survey" version="0.0.1+galaxy0" profile="24.0"> + <requirements> + <requirement type="package" version="6.1.4">astropy</requirement> + <requirement type="package" version="3.10.1">matplotlib</requirement> + <requirement type="package" version="1.21.4">wget</requirement> + <requirement type="package" version="7.16.6">nbconvert</requirement> + <requirement type="package" version="0.4.10">astroquery</requirement> + <requirement type="package" version="1.2.33">oda-api</requirement> + <requirement type="package" version="9.1.0">ipython</requirement> + <!--Requirements string 'nb2workflow>=1.3.30' can't be converted automatically. Please add the galaxy/conda requirement manually or modify the requirements file!--> + </requirements> + <command detect_errors="exit_code">ipython '$__tool_directory__/${C_data_product_.DPselector_}.py'</command> + <environment_variables> + <environment_variable name="BASEDIR">$__tool_directory__</environment_variable> + <environment_variable name="GALAXY_TOOL_DIR">$__tool_directory__</environment_variable> + </environment_variables> + <configfiles> + <inputs name="inputs" filename="inputs.json" data_style="paths" /> + </configfiles> + <inputs> + <conditional name="C_data_product_"> + <param name="DPselector_" type="select" label="Data Product"> + <option value="Catalog" selected="true">Catalog</option> + <option value="Spectrum" selected="false">Spectrum</option> + <option value="Image" selected="false">Image</option> + </param> + <when value="Catalog"> + <param name="src_name" type="text" value="Mrk 421" label="src_name" optional="false" /> + <param name="RA" type="float" value="166.113808" label="RA (unit: deg)" optional="false" /> + <param name="DEC" type="float" value="38.208833" label="DEC (unit: deg)" optional="false" /> + <param name="Radius" type="float" value="1" label="Radius (unit: arcmin)" optional="false" /> + <param name="data_release" type="integer" value="10" label="Data Release" optional="false" /> + </when> + <when value="Spectrum"> + <param name="src_name" type="text" value="Mrk 421" label="src_name" optional="false" /> + <param name="RA" type="float" value="166.113808" label="RA (unit: deg)" optional="false" /> + <param name="DEC" type="float" value="38.208833" label="DEC (unit: deg)" optional="false" /> + <param name="Radius" type="float" value="0.1" label="Radius (unit: arcmin)" optional="false" /> + <param name="data_release" type="integer" value="10" label="Data Release" optional="false" /> + </when> + <when value="Image"> + <param name="src_name" type="text" value="Mrk 421" label="src_name" optional="false" /> + <param name="RA" type="float" value="166.113808" label="RA (unit: deg)" optional="false" /> + <param name="DEC" type="float" value="38.208833" label="DEC (unit: deg)" optional="false" /> + <param name="Radius" type="float" value="3" label="Radius (unit: arcmin)" optional="false" /> + <param name="pixsize" type="float" value="1.0" label="Pixel size (unit: arcsec)" optional="false" /> + <param name="band" type="select" label="Band" optional="false"> + <option value="g" selected="true">g</option> + <option value="i">i</option> + <option value="r">r</option> + <option value="z">z</option> + </param> + <param name="data_release" type="integer" value="10" label="Data Release" optional="false" /> + </when> + </conditional> + </inputs> + <outputs> + <data label="${tool.name} -> Catalog catalog_table" name="out_Catalog_catalog_table" format="auto" from_work_dir="catalog_table_galaxy.output"> + <filter>C_data_product_['DPselector_'] == 'Catalog'</filter> + </data> + <data label="${tool.name} -> Catalog dictionary_filters" name="out_Catalog_dictionary_filters" format="auto" from_work_dir="dictionary_filters_galaxy.output"> + <filter>C_data_product_['DPselector_'] == 'Catalog'</filter> + </data> + <data label="${tool.name} -> Spectrum spectrum_table" name="out_Spectrum_spectrum_table" format="auto" from_work_dir="spectrum_table_galaxy.output"> + <filter>C_data_product_['DPselector_'] == 'Spectrum'</filter> + </data> + <data label="${tool.name} -> Spectrum spectrum_png" name="out_Spectrum_spectrum_png" format="auto" from_work_dir="spectrum_png_galaxy.output"> + <filter>C_data_product_['DPselector_'] == 'Spectrum'</filter> + </data> + <data label="${tool.name} -> Image picture" name="out_Image_picture" format="auto" from_work_dir="picture_galaxy.output"> + <filter>C_data_product_['DPselector_'] == 'Image'</filter> + </data> + <data label="${tool.name} -> Image fits" name="out_Image_fits" format="auto" from_work_dir="fits_galaxy.output"> + <filter>C_data_product_['DPselector_'] == 'Image'</filter> + </data> + </outputs> + <tests> + <test expect_num_outputs="2"> + <conditional name="C_data_product_"> + <param name="DPselector_" value="Catalog" /> + <param name="src_name" value="Mrk 421" /> + <param name="RA" value="166.113808" /> + <param name="DEC" value="38.208833" /> + <param name="Radius" value="1" /> + <param name="data_release" value="10" /> + </conditional> + <assert_stdout> + <has_text text="*** Job finished successfully ***" /> + </assert_stdout> + </test> + <test expect_num_outputs="2"> + <conditional name="C_data_product_"> + <param name="DPselector_" value="Spectrum" /> + <param name="src_name" value="Mrk 421" /> + <param name="RA" value="166.113808" /> + <param name="DEC" value="38.208833" /> + <param name="Radius" value="0.1" /> + <param name="data_release" value="10" /> + </conditional> + <assert_stdout> + <has_text text="*** Job finished successfully ***" /> + </assert_stdout> + </test> + <test expect_num_outputs="2"> + <conditional name="C_data_product_"> + <param name="DPselector_" value="Image" /> + <param name="src_name" value="Mrk 421" /> + <param name="RA" value="166.113808" /> + <param name="DEC" value="38.208833" /> + <param name="Radius" value="3" /> + <param name="pixsize" value="1.0" /> + <param name="band" value="g" /> + <param name="data_release" value="10" /> + </conditional> + <assert_stdout> + <has_text text="*** Job finished successfully ***" /> + </assert_stdout> + </test> + </tests> + <help>And here, the help text for the galaxy tool goes. +</help> + <citations> + <citation type="doi">10.3847/1538-3881/ab089d</citation> + </citations> +</tool> \ No newline at end of file |