Giter Club home page Giter Club logo

pylanetary's Introduction

Pylanetary logo

data processing and modeling tools for ring, moon, and planet observations

Documentation Status Code Coverage Badge Powered by Astropy Badge Zenodo DOI Badge

Installation

pip install pylanetary (Python 3.9 to 3.12)

Features

  • Navigation and re-projection for solar system imaging observations (makes use of Cartopy); Nav Tutorial and example workflow.
  • Read/write navigated solar system images and backplanes in the NAV multi-extension fits format, originally developed for the HST OPAL program.
  • Easy access to solar system body static data (radius, mass, etc.) and ephemerides; Body Tutorial.
  • Utilities for solar-system-specific unit conversions like I/F; Units Tutorial.
  • Ring-moon system modeling and model-data comparison; Rings Tutorial.
  • (coming soon) Compute Doppler winds from image cubes and compare with simulation output (e.g. EPIC).

Usage

See our readthedocs page

Scope and Goal

The idea behind pylanetary is to bring solar system science tools into the open-source Python 3 / Astropy ecosystem. We, and many of our colleagues, rely heavily on useful code snippets passed down from other solar system scientists. But these pieces of code are untested, in multiple languages, closed-source, and have many untracked dependencies. We want to fix that. The eventual goal is to become Astropy-affiliated, but that is a long way off. We would love your help developing it! See Contributing.

Disclaimer

Pylanetary is developed and maintained by a small group of scientists. Most of us are not primarily software engineers, and we do not get paid to do this. While we do our best, there is no guarantee that every function works as intended. Use these tools with caution, and ensure that what you're getting out makes sense. If you do discover a problem, please help us out by submitting an issue on our issues page, or fix it yourself! See Contributing.

License

This project is Copyright (c) Edward Molter & Chris Moeckel and licensed under the terms of the GNU general public license. This package is based upon the Astropy package template which is licensed under the BSD 3-clause license. See the licenses folder for more information.

Contributing

We love contributions! Pylanetary is open source, built on open source, and we'd love to have you hang out in our community. Please read the contribution page before you start.

Imposter syndrome disclaimer: We want your help. No, really.

There may be a little voice inside your head that is telling you that you're not ready to be an open source contributor; that your skills aren't nearly good enough to contribute. What could you possibly offer a project like this one?

We assure you - the little voice in your head is wrong. If you can write code at all, you can contribute code to open source. Contributing to open source projects is a fantastic way to advance one's coding skills. Writing perfect code isn't the measure of a good developer (that would disqualify all of us!); it's trying to create something, making mistakes, and learning from those mistakes. That's how we all improve, and we are happy to help others learn.

Being an open source contributor doesn't just mean writing code, either. You can help out by writing documentation, tests, or even giving feedback about the project (and yes - that includes giving feedback about the contribution process). Some of these contributions may be the most valuable to the project as a whole, because you're coming to the project with fresh eyes, so you can see the errors and assumptions that seasoned contributors have glossed over.

Note: This disclaimer was originally written by Adrienne Lowe for a PyCon talk, and was adapted by pylanetary based on its use in the README file for the MetPy project.

Logo Credit

Our logo was designed by graphic designer Jacob Waliszewski. Check out his website at https://www.jwdesignco.com/.

pylanetary's People

Contributors

cmoeckel91 avatar emolter avatar rcosenti-stsci avatar rgcosentino avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

pylanetary's Issues

install error

Hi Ned, I was trying to install pylanetary and got the following error when running $ pip install -r requirements.txt

ERROR: Could not open requirements file: [Errno 2] No such file or directory: 'requirements.txt'

Is the problem on my end? If so maybe we should add some more explicit instructions to help future folks know for sure what to do.

Release CI failing

Describe the bug
Errors in pyproject.toml are preventing release

Additional context
Seems to be related to syntax errors in long_description

Restore compatability with Python 3.8

An error occurs when importing pylanetary using a Python 3.8 install. The issues seems to be the lack of a C compiler in Python 3.8 distributions in conda, which is required by recent Scipy versions.

Error message: version 'GLIBCXX_3.4.30' not found (required by .../scipy/spatial/fft/

Image below include full error message.
image

Planet fact sheet-like infomation

Adding the first capability for someone to initiate a planet class by the name and load attributes from a yaml file that has information like the equatorial and polar radii for use with astropy units. This snippet of code is to get the ball rolling for future additions and serve as an example for new contributors to pylanetary wanting to utilize yaml file loading as python dictionaries.

--- submitted code
class Planet:
def init(self, name):
self.name = name
with importlib.resources.open_binary(planet_info, f"{self.name}.yaml") as file:
yaml_bytes = file.read()
data = yaml.safe_load(yaml_bytes)

        # basic information and rewrite name
        self.name = data['planet']['name']
        self.mass = data['planet']['mass'] * u.kg
        self.Re = data['planet']['Re'] * u.km
        self.Rp = data['planet']['Rp'] * u.km
        self.Ravg = (self.Re + self.Rp) / 2
        self.Rvol = data['planet']['Rvol'] * u.km
        self.accel_g = data['planet']['accel_g'] * u.m / u.s**2
        self.num_moons = data['planet']['num_moons']

        # orbital information
        self.semi_major_axis = data['orbit']['semi_major_axis'] * u.au
        self.t_rot_hrs = data['orbit']['t_rot'] * u.hr

        # observational information
        self.app_dia_max = data['observational']['app_dia_max'] * u.arcsec
        self.app_dia_min = data['observational']['app_dia_min'] * u.arcsec

Spectral extraction code

make a code that extracts spectra from images as a function of lat/long/mu, number of bins, etc.

bug in ring geometry

The RingSystemModelObservation class currently fails to account for the peculiar inclinations and arguments of periapsis of individual rings, just the ring systems. This becomes important for modeling Uranus's epsilon ring and should be fixed

Improve the robustness of the CI checks

The most recent push broke the readthedocs build. This should not be able to happen - GitHub CI should be revisited to ensure:

  • readthedocs build happens prior to merge
  • codecov requirements can be relaxed or removed for now; we still want to be able to see the coverage with each new push, but tests are still optional for new contributors at this stage
  • need to add support for Python 3.11 and Python 3.12

documentation of supported Python versions is not correct

Describe the bug
Documentation incorrectly states that Python 3.7 and Python 3.8 are supported, but they no longer are supported.

To Reproduce
Steps to reproduce the behavior:

  1. Follow the installation instructions either in the GitHub readme or on the install page using any Python < 3.9

Additional context
Add any other context about the problem here.

Zonal Wind Maker

A new module to be named but will still with winds/zonal/ will read in zonal wind profiles from observations from published text files with wind velocities from cloud tracking as a function of latitude. The user will then be prompted or be given examples of how to build a zonal wind cube after supplying a latitude and longitude grid spacing. The vertical dimension will be in log pressure space to start, with later including the conversion of km above the 1 bar atmospheric level as an additional axis. Vertical wind shear will be available to allow a zonal wind profile to vary with height.

This is similar to how the general circulation model EPIC initializes a model domain where the wind velocity below the clouds is an explored parameter. Additional features to add the flexibility to probe stratospheric or thermospheric jets was added for exoplanet studies with solar system analogues that now might be useful for upcoming wind research and analysis of observational data from ALMA.

Color scheme and logo

We now have a logo and official color scheme. This needs to be added to the GitHub and Readthedocs pages. Some additional changes to the README should be done too

API changes to astroquery ring node queries will break rings modules

Problem

RingNode class was changed to RMSNode in astroquery as of Dec 15 2023. Therefore, any version of astroquery > 0.4.7.dev9008 will fail. see this page

Solution

Two-stage solution. For now, simply pin the dependencies for astroquery to be <= that dev version. Then, once astroquery does the 0.4.7 release, pin astroquery>=0.4.7

Split utils tutorials into Body class and unit conversions

Describe the problem
The usage, and even perhaps existence, of the Body class is hidden from new users because it sits underneath a "utils tutorial" dropdown menu. It isn't clear what the utils tutorial will contain.

Propose a solution
Split the Body class tutorial and unit conversions tutorials into their own notebooks. Add more examples of how to use the Body class, and how it can work together with navigation and other modules.

Readthedocs page URL
https://pylanetary.readthedocs.io/en/latest/utils-tutorial.html

Allow re-projection to arbitrary geometry

At present, navigation.Nav.reproject() only supports projection onto a rectilinear grid. This functionality should be expanded to allow projection into any arbitrary geometry, and at least to a polar projection. This should probably be implemented using cartopy.

pylanetary.__version__ is empty

Describe the bug
The version special attribute should print the version of Pylanetary that is being used, but instead it returns blank.

To Reproduce
Steps to reproduce the behavior:

  1. pip install pylanetary
  2. python
  3. import pylanetary
  4. pylanetary.version

Desktop (please complete the following information):

  • MacOS 13.6.3, Apple M2 chip
  • Python 3.11

make Nav work nicely with new Body object

To make the Nav module work well with Rick's new Body object, a few changes are needed:

  • change req, rpol to r_eq, r_pol in Nav
  • make Nav call Body explicitly and let default observation time be datetime.now()
  • update tutorials to show easier workflow for calling planets
  • more?

Shifting navigated data introduces edge effects

When navigated data are shifted to subpixel accuracy, sharp edges (Longitude: 359 -> 0) blow up.

Align model and observation

nav.xy_shift_model(np.round(dx), np.round(dy))

Options for fix:
Replace shifting routine
Force edge data to conform to mod 360
Shift data instead of model

utils unit tests

There are a bunch of functions in utils that lack unit tests right now, including convolve_with_beam() and the Body class, both of which are used all over the place within the rest of the code.

pylanetary.utils.tests.test_utils.py already exists and there are a few tests in there, so a new contributor could start working on this fairly easily, using the existing tests as examples. See also the tests in the rings module for examples of how to test more complicated functions and classes.

release on pypi failing due to unreleased dependencies

We rely on yet-unreleased versions of image_registration and astroquery, and this PEP prevents PyPI from packaging direct references to the unreleased GitHub versions of those packages. Until those packages make releases, simply pip install pylanetary will not run right

Compute solar zenith and emission angles

Building off of issue #38 it would be really helpful to finish the functionality for computing solar zenith and emission angles. This should be relatively easy to do given what Nav already does, but it needs to be finished and tested.

Using the nav tutorial w/ IRTF data

Hey Ned, I'm having trouble getting nav.colocate to work with some of my IRTF images. I think I've correctly assigned 'model' and 'data', but when I run this line:
dx, dy, dxerr, dyerr = nav.colocate(mode='disk', tb = flux, a = a, beam = fwhm_keck, err=rms_noise)
I'm getting an error that the model and data images aren't the same shape. I tried adding a definition of the size of the image using the optional shape argument in ModelBody(), but that didn't seem to work. What am I missing here? I can attach a screenshot of the error if that's helpful.

Calculate maps of azimuth angle in nav

Some radiative transfer codes (cough cough nemesis) require measurements of azimuth angle (cw angle between the projection of the solar emission angle and north, see fig. 1 in Nemesis manual). I have a python code that does this using various vectors and the zenith and solar zenith angles but it would need to be reformatted to work within pylanetary

Jupyter notebook tutorial for utils

There are some helper functions within utils that may be useful on their own, including unit conversions with beams, convolution with beams, and I/F calculations. These need their own tutorial.

Formatting and documentation guidelines

It would be good to have a guide on how new code should/could be formatted, commented, and include examples. It seems like some of this exists, but examples can be included if not?

navigation based on rings in nav.colocate

Add support for a third mode of nav.colocate that finds the planet's center based on cross-correlation between models and observations of planetary rings. This is useful because rings are often less time-variable than stormy planets, and they are also larger on the sky; together, this promises higher-accuracy centroiding.

move example notebooks to readthedocs

nbsphinx provides easy integration of Jupyter notebooks into readthedocs. Instead of having example scripts in notebooks/, they should be moved into docs/ and built into the readthedocs page

restructure and rename of planetnav

Based on tester feedback (thanks Chris), PlanetNav should be restructured to permit planet modeling with an ephemeris, but without data to compare. A new intermediate class called ModelBody that inherits from ModelPlanetEllipsoid should be created, and Nav should inherit from that class. All the names should be changed to remove the word "planet" because these methods work for any roughly ellipsoidal solar system body.

NAV file format - backplanes, metadata keywords

Topic: Format of navigated FITS image files. I am new to Pylanetary. I assume the navigation step is like what I do in my IDL Simnav code: add metadata and backplanes. There may also be some manipulation of the image data itself, such as rotating north up or resampling to a finer equivalent plate scale.

Motivation: I have tons of processed image data and I would love for the files to be compatible with Pylanetary. I also think my format has some nice features that help the usability of the data. I would be happy if the Pylanetary format had a superset of my IDL Simnav keywords, and I would still be happy if the keywords sometimes had different names. This is not just for HST/WFC3 data obviously. As long as there was some kind of keyword like PYLANVER that gave the version of the Pylanetary format, I could include translator code to handle any differences (until I migrate 100% to Pylanetary).

Backplanes: I copied HST image data. Different instruments and levels of data processing/products from the HST pipeline have different FITS structures, but the one I adapted for NAV files resembles HST/WFC3 "FLT" files: it has extension 0 (primary HDU) with no data and only metadata, followed by as many extensions as needed, with minimal metadata in those subsequent extensions. For example, a navigated Uranus image looks like this:

> fitsinfo 221110_845_1959_nav.fits                                                                           

No.    Name      Ver    Type      Cards   Dimensions   Format
  0  PRIMARY       1 PrimaryHDU     447   ()      
  1  SCI           1 ImageHDU        11   (530, 527)   float32   
  2  LAT           1 ImageHDU        12   (530, 527)   float32   
  3  LON           1 ImageHDU        12   (530, 527)   float32   
  4  EMI           1 ImageHDU        12   (530, 527)   float32   
  5  INC           1 ImageHDU        12   (530, 527)   float32   

Metadata: My principle has been to keep all the existing telescope/pipeline metadata, and add some keywords related to navigation. These keywords then can help with further science analysis, reprojection of the image data (cylindrical or polar maps), calibration to I/F reflectance units, etc.

Here are some of the most important keywords in my opion, but this is a draft list and hopefully there is a chance later on to refine the list. These are only Simnav-added keywords. Many telescope keywords (e.g., DATE-OBS and TIME-OBS) are equally important but assumed to not be Pylanetary's responsibility:

              / JPL EPHEMERIS DATA

TRG_ROT =        267.544900000 / Target N.Pole angle (degrees E of N)
TRG_RA  =        44.1721242500 / Target RA (degrees, J2000)
TRG_DEC =        16.4194880833 / Target DEC (degrees, J2000)
TRG_R_A =        1.88576990417 / Target equatorial radius (arcsec)
TRG_R_B =        1.84253420778 / Target polar radius (arcsec)
TRG_LON =        1.69132734167 / Sub-observer longitude (degrees, SysIII)
TRG_LAT =        59.3026484417 / Sub-observer latitude (degrees, planetographic)
SUN_LON =        1.76138321667 / Sub-solar longitude (degrees, SysIII)
SUN_LAT =        59.3716203417 / Sub-solar latitude (degrees, planetographic)
TRG_PHAS=      0.0739191666667 / Sun-object-observer angle (degrees)
TRG_R   =        19.6775273874 / Sun-Target distance (AU)
TRG_D   =        18.6876591479 / Observer-target distance (AU)

These always come in handy, and it's nice to be able to make tables of various things (usually longitude) without having to keep querying Horizons.

              / HUMAN OPERATOR LAT-LON FITTING

LLMETHOD= 'LIMB (simnav_fast 1.045)' / Lat-lon grid fitting method (LIMB/FEATURE
SIG_XPOS=     0.00142966361451 / Uncertainty in lat-lon grid offset (arcsec)
SIG_YPOS=     0.00142966361451 / Uncertainty in lat-lon grid offset (arcsec)
SIG_LAT =      0.0434378016642 / Equivalent lat. uncert. at sub-earth (degrees)
SIG_LON =      0.0434378016642 / Equivalent lon. uncert. at sub-earth (degrees)
XSHIFT  =     0.00699885162728 / Image center to ephemeris disk center (arcsec)
YSHIFT  =     0.00515903111723 / Image center to ephemeris disk center (arcsec)
NAV_X0  =        265.206597824 / X-pixel coord of sub-observer point (0-indexed)
NAV_Y0  =        263.520851185 / Y-pixel coord of sub-observer point (0-indexed)
LON_SYS = 'III     '           / IAU Longitude system used
LAT_TYPE= 'Planetographic'     / Latitude system for map
LAT_SHAP= 'Oblate spheroid'    / Shape model used
R_A_KM  =        25559.0000000 / Target equatorial radius (km)
R_B_KM  =        24973.0000000 / Target polar radius (km)
CROP_X0 =                  774 / pix trimmed from input, left (post-mag., 0-inde
CROP_Y0 =                  759 / pix trimmed from input, bottom (post-mag., 0-in

These are the main navigation keywords. Most of the first ones are related to the planet center relative to the image, or relative to the RA/DEC it's supposed to be at (which can also be found in telescope header keywords). The section mentions "human operator" because in my experience, automated methods are good but end up being biased by artifacts in individual frames. In Simnav, the human operator sets the final planet center, but the uncertainty estimate in the navigation is the rms offset between the human operator solution and the solutions from two automated algorithms.

In some cases, we made NAV files that are cropped with respect to the original image files, to remove blank space around the planet. This is fine, but it can cause issues trying to reconstruct what happened if you only have the final image. So the CROP_X0 and CROP_Y0 keywords are used to relate properties in the final image to properties in the input image to Simnav. With these keywords (not present in earlier versions of Simnav), recalibrated data can be renavigated without additional human interaction.

              / FRAME SCALE AND LIMIT DATA

MISSVAL =                  NAN / Missing data flag value
PPA     =        100.959109012 / Pixels per arcsec
PIXSCAL =           0.00990500 / Arcsec per pixel
NAVMAG  =                    4 / Magnification with respect to original data

I like NaN for a bad data flag, but this keyword always annoys FITS format checkers. So maybe the value should be 'NaN' (ascii). In any case, NaN lets you take averages and such only over good data using Numpy or IDL. Another bad data flag could be used, and listed here, and then codes could use that instead of NaN to do smarter averaging.

The other keywords are for magnification. I find it useful for some smaller targets to enlarge the image. These keywords track that process and ensure that the plate scale in the final product is known to the user (in case they try to reconstruct it from the telescope pipeline metadata and find inconsistencies).

BUNIT   = 'ELECTRONS/S'        / Units of science product
PHOTFLAM=        4.6016378E-19 / Inverse sensitivity, ergs/cm2/A/e-
PHOTIF  =    0.000148261705616 / Convert counts/sec to I/F
SIG_PHOT=    7.56008235524E-06 / Uncertainty estimate for PHOTIF

These photometry keywords are not well organized in the header. They apply to the SCI (science data) extension, which for drizzled WFC3 data has units of e-/sec. the PHOTFLAM is from the STScI pipeline, and multiplying this factor by the image array data in e-/sec converts the image to FLAM units of erg/s/cm^2/Angstrom.

For planetary work in the UV/vis/near-IR regime, we want reflectivity in I/F units, which we can get by PHOTIF*SCI. Similarly the SIG_PHOT gives the uncertainty, which includes uncertainty in the solar spectrum.

I made a Google Drive folder PYLAN_FITS_format with example Uranus NAV and REG format FITS files. REG is a cylindrical projection map format, but we can discuss that in a separate issue. Also included is a Python script from Troy that converts NAV to REG, although it is not fully debugged, so the REG file here was generated in IDL.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.