Building an Open Community around Software in Solar Physics

Stuart Mumford

How I Got Here!

My PhD:

What I actually did:

A lot of SunPy

Software in Science

It's quite hard to avoid it!

  • Scientists spend 30% of their time programming but 90% are self-taught. [1]
  • It can be challenging to be rewarded for contributing to software.
  • Lots of people writing the same code.
  • Software is not often shared with publications.
  • Communtiy software is rarely funded well. [2]

1. Wilson, G. et al. Best Practices for Scientific Computing. PLoS Biology 12, e1001745 (2014).
2. Muna, D. et al. The Astropy Problem. ArXiv e-prints (2016).

Open Community Driven Software

Objectives:

  • Build the core tools together.
  • Save everyone time!
  • Make the code citeable.
  • Get subject matter experts and software developers working together.

Questions:

  • How to collaborate effiectively?
  • How to keep the standard high when you have all levels of knowledge working on the code?
  • How to encourage people to get involved?
  • How to make it easy to use?

Python in Astronomy

Python has seen a rapid adoption in Solar Physics and Astronomy

1. Momcheva, I. & Tollerud, E. Software Use in Astronomy: an Informal Survey. ArXiv e-prints (2015).

Why Python?

Some Python Projects in Astronomy



  • An open community of solar physicists, focused on Python.
  • A project to manage the SunPy library and other related packages.
  • A library of core tools for solar physicists in Python.

SunPy Community

Mailing List

Real Time Chat

SunPy Community

Twitter

GitHub

Social Norms

Code of Conduct

A member of SunPy is:

Open

Considerate

Respectful

Collaboratively Writing Code

GitHub Workflow

Submit Code

Review Code

Test Code

Documentation

def rotate(self, angle=None):
        """
        Returns a new rotated and rescaled map.

        Parameters
        ----------
        angle : `~astropy.units.Quantity`
            The angle (degrees) to rotate counterclockwise.

        Returns
        -------
        out : `~sunpy.map.GenericMap` or subclass
            A new Map instance containing the rotated and rescaled data of the
            original map.

        See Also
        --------
        sunpy.image.transform.affine_transform : The routine this method calls
        for the rotation.

        Notes
        -----
        This function will remove old CROTA keywords from the header.
        This function will also convert a CDi_j matrix to a PCi_j matrix.

        See :func:`sunpy.image.transform.affine_transform` for details on the
        transformations, situations when the underlying data is modified prior
        to rotation, and differences from IDL's rot().
        """

66 Contributors to SunPy so far

In [3]:
labels, nums = np.array([[k, v] for k, v in authors_version.items()]).T

fig = plt.figure(figsize=(10, 5))
ax = plt.subplot()
ax.bar(np.arange(len(nums)), nums, color=['C0']*(len(nums)-1) + ['C7'])
ax.set_xticklabels(['']+list(labels))

ax.set_ylabel("Number of contributors")
ax.set_xlabel("SunPy Major Version")
ax.patch.set_alpha(0)

None

The SunPy Project

  • Library Started in 2011.
  • A board created to guide the project in 2015.
  • Consists of multiple packages:
    • SunPy
    • SolarBExtrapolation
    • IRISPy
    • sunkit-sst
  • Fiscally Sponsored by NumFOCUS

The SunPy Library

  • Nearly 8,000 changes (commits).
  • 66 Contributors.
  • 30 Releases.
  • 500 resolved issues.
  • 1,076 accepted code contributions (PRs).

SunPy!

In [7]:
from sunpy.data.sample import AIA_171_ROLL_IMAGE
import sunpy.map

aia = sunpy.map.Map(AIA_171_ROLL_IMAGE)

fig = plt.figure(figsize=(8,8))
ax = plt.subplot(projection=aia)

aia.plot()
aia.draw_grid()

a = ax.axis((500, 3000, 500, 3000))
In [25]:
import sunpy.timeseries
from sunpy.net import Fido, attrs as a

res = Fido.search(a.Time("2017/05/1", "2017/05/3"), a.Instrument("goes"))
files = Fido.fetch(res, progress=False)

ts = sunpy.timeseries.TimeSeries(files, concatenate=True)
fig = ts.peek()
/home/stuart/Git/sunpy/sunpy/util/config.py:18: DeprecationWarning: The SafeConfigParser class has been renamed to ConfigParser in Python 3.2. This alias will be removed in future versions. Use ConfigParser directly instead.
  config = configparser.SafeConfigParser()
/home/stuart/Git/sunpy/sunpy/util/config.py:18: DeprecationWarning: The SafeConfigParser class has been renamed to ConfigParser in Python 3.2. This alias will be removed in future versions. Use ConfigParser directly instead.
  config = configparser.SafeConfigParser()
/home/stuart/Git/sunpy/sunpy/util/config.py:18: DeprecationWarning: The SafeConfigParser class has been renamed to ConfigParser in Python 3.2. This alias will be removed in future versions. Use ConfigParser directly instead.
  config = configparser.SafeConfigParser()
/opt/miniconda/envs/sunpy-dev/lib/python3.6/site-packages/matplotlib/figure.py:403: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure
  "matplotlib is currently using a non-GUI backend, "

Interested?

  • Join the mailing list.
  • Try something out!
  • Open an Issue.
  • Hangout in the Chat.
  • Correct the documentation.
  • Write an example.
  • Contribute a Feature.
  • Get some grant money!

Thank You