Skip to content

Commit

Permalink
Rename Loop to Strand (#98)
Browse files Browse the repository at this point in the history
* infrastructure cleanup

* rename Loop->Strand

* fix circular import
  • Loading branch information
wtbarnes authored Oct 4, 2024
1 parent ecb6d61 commit c45f6aa
Show file tree
Hide file tree
Showing 19 changed files with 244 additions and 258 deletions.
File renamed without changes.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<div align="center">
<img src="docs/_static/synthesizar_logo.png" width=55%><br>
</div>

# synthesizAR

[![Powered by SunPy Badge]( http://img.shields.io/badge/powered%20by-SunPy-orange.svg?style=flat)](http://www.sunpy.org)
![synthesizAR CI status](https://github.com/wtbarnes/synthesizAR/workflows/Run%20tests/badge.svg)
[![synthesizAR CI status](https://github.com/wtbarnes/synthesizAR/actions/workflows/ci.yml/badge.svg)](https://github.com/wtbarnes/synthesizAR/actions/workflows/ci.yml)
[![Documentation Status](http://readthedocs.org/projects/synthesizar/badge/?version=latest)](http://synthesizar.readthedocs.io/en/latest/?badge=latest)
[![codecov](https://codecov.io/gh/wtbarnes/synthesizAR/branch/master/graph/badge.svg)](https://codecov.io/gh/wtbarnes/synthesizAR)
[![codecov](https://codecov.io/gh/wtbarnes/synthesizAR/graph/badge.svg?token=QUTQZGWQKB)](https://codecov.io/gh/wtbarnes/synthesizAR)

synthesizAR is a Python package for forward modeling emission from solar active regions using hydrodynamic simulations of coronal loops
synthesizAR is a Python package for forward modeling optically-thin emission from field-aligned hydrodynamic simulations of astrophysical plasmas.

## Install

To clone the repository and install the package and all of its needed dependencies,

```shell
$ git clone https://github.com/wtbarnes/synthesizAR.git
$ cd synthesizAR
$ pip install -e .[all]
git clone https://github.com/wtbarnes/synthesizAR.git
cd synthesizAR
pip install -e .[all]
```

## Help

See the [docs](http://synthesizar.readthedocs.io). To report bugs or request features, create an issue or submit a pull request.
10 changes: 6 additions & 4 deletions examples/arcade-rtv.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
of semi-circular loops who's thermal structure is modeled
using the RTV scaling laws.
"""
import astropy.units as u
import astropy.time
import astropy.units as u

from astropy.coordinates import SkyCoord
from sunpy.coordinates import get_earth

import synthesizAR
from synthesizAR.models import semi_circular_arcade
from synthesizAR.interfaces import RTVInterface

from synthesizAR.instruments import InstrumentSDOAIA
from synthesizAR.interfaces import RTVInterface
from synthesizAR.models import semi_circular_arcade

#########################################################################
# First, set up the coordinates for loops in the arcade.
Expand All @@ -24,7 +26,7 @@

#########################################################################
# Next, assemble the arcade.
strands = [synthesizAR.Loop(f'strand{i}', c) for i, c in enumerate(arcade_coords)]
strands = [synthesizAR.Strand(f'strand{i}', c) for i, c in enumerate(arcade_coords)]
arcade = synthesizAR.Skeleton(strands)

#########################################################################
Expand Down
9 changes: 6 additions & 3 deletions examples/loop-bundle-rtv.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@
bundle of semi-circular strands for two different
viewpoints.
"""
import matplotlib.pyplot as plt
import astropy.time
import astropy.units as u
from astropy.visualization import quantity_support
import matplotlib.pyplot as plt

from astropy.coordinates import SkyCoord
from astropy.visualization import quantity_support
from sunpy.map import pixelate_coord_path, sample_at_coords

import synthesizAR

from synthesizAR.instruments import InstrumentSDOAIA
from synthesizAR.interfaces import RTVInterface
from synthesizAR.models import semi_circular_bundle

# sphinx_gallery_thumbnail_number = -1

###########################################################################
Expand All @@ -32,7 +35,7 @@
###########################################################################
# As in other examples, we then use the coordinates of our strands to
# construct the `~synthesizAR.Skeleton` object.
strands = [synthesizAR.Loop(f'strand{i}', c) for i, c in enumerate(bundle_coords)]
strands = [synthesizAR.Strand(f'strand{i}', c) for i, c in enumerate(bundle_coords)]
bundle = synthesizAR.Skeleton(strands)
bundle.peek(observer=pos)

Expand Down
24 changes: 16 additions & 8 deletions examples/multi-instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@
instrument class.
"""
import astropy.units as u
from astropy.coordinates import SkyCoord
import numpy as np
import matplotlib.pyplot as plt
from sunpy.coordinates import get_earth, get_horizons_coord, HeliographicStonyhurst, Helioprojective
import numpy as np

from astropy.coordinates import SkyCoord
from astropy.visualization import quantity_support
from sunpy.coordinates import (
get_earth,
get_horizons_coord,
HeliographicStonyhurst,
Helioprojective,
)

import synthesizAR
from synthesizAR.models import semi_circular_arcade

from synthesizAR.instruments import InstrumentHinodeXRT, InstrumentSDOAIA
from synthesizAR.interfaces import MartensInterface
from synthesizAR.instruments import InstrumentSDOAIA, InstrumentHinodeXRT
from synthesizAR.models import semi_circular_arcade

# sphinx_gallery_thumbnail_number = -1

###############################################################################
Expand All @@ -27,7 +35,7 @@
obstime = '2021-10-28T15:00:00'
loc = SkyCoord(HeliographicStonyhurst(lon=0*u.deg,lat=-30*u.deg, radius=1*u.R_sun, obstime=obstime))
arcade = semi_circular_arcade(150*u.Mm, 10*u.deg, 50, loc, gamma=90*u.deg, n_points=5000)
skeleton = synthesizAR.Skeleton([synthesizAR.Loop(f'{i}', c) for i,c in enumerate(arcade)])
skeleton = synthesizAR.Skeleton([synthesizAR.Strand(f'{i}', c) for i,c in enumerate(arcade)])

###############################################################################
# We'll select a few different observer locations for SDO and STERO-A and use
Expand Down Expand Up @@ -64,10 +72,10 @@ def get_heating_constant(self, loop):
with quantity_support():
plt.figure(figsize=(11, 5))
ax1 = plt.subplot(121)
for l in skeleton.loops:
for l in skeleton.strands:
plt.plot(l.field_aligned_coordinate_center.to('Mm'), l.electron_temperature[0].to('MK'), color='k')
plt.subplot(122)
for l in skeleton.loops:
for l in skeleton.strands:
plt.plot(l.field_aligned_coordinate_center.to('Mm'), l.density[0], color='k')
plt.yscale('log')

Expand Down
9 changes: 0 additions & 9 deletions licenses/README.rst

This file was deleted.

31 changes: 0 additions & 31 deletions licenses/TEMPLATE_LICENSE.rst

This file was deleted.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ authors = [
{name="Will Barnes", email="[email protected]"}
]
license = {file="LICENSE.rst"}
description = "A Python package for forward-modeling optically-thin emission from field-aligned coronal loop models"
description = "A Python package for forward modeling optically-thin emission from field-aligned hydrodynamic simulations of astrophysical plasmas."
readme = {file="README.md", content-type = "text/markdown"}
requires-python = ">=3.10"
dependencies = [
Expand Down
9 changes: 5 additions & 4 deletions synthesizAR/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
hydrodynamic simulations of coronal loops.
"""
try:
from .version import __version__
from synthesizAR.version import __version__
except ImportError:
__version__ = "unknown"


from .loop import *
from .skeleton import *

# Set up logger
from synthesizAR.util.logger import _init_log

from .strand import * # NOQA
from .skeleton import * # NOQA

log = _init_log()
9 changes: 5 additions & 4 deletions synthesizAR/conftest.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
"""
Configure test skeletons here so that they can be used everywhere
"""
import astropy.units as u
import pytest

import astropy.units as u
from sunpy.coordinates import get_earth

import synthesizAR
from synthesizAR.models import semi_circular_loop, semi_circular_arcade

from synthesizAR.interfaces import MartensInterface
from synthesizAR.models import semi_circular_arcade, semi_circular_loop


@pytest.fixture
def bare_skeleton():
observer = get_earth(time='2020-01-01T00:00:00')
arcade = semi_circular_arcade(100*u.Mm, 20*u.deg, 10, observer)
loops = [synthesizAR.Loop(f'{i}', c) for i, c in enumerate(arcade)]
loops = [synthesizAR.Strand(f'{i}', c) for i, c in enumerate(arcade)]
return synthesizAR.Skeleton(loops)


Expand All @@ -29,4 +30,4 @@ def skeleton_with_model(bare_skeleton):
@pytest.fixture
def semi_circle_strand(bare_skeleton):
coords = semi_circular_loop(length=100*u.Mm)
return synthesizAR.Loop('test', coords)
return synthesizAR.Strand('test', coords)
36 changes: 18 additions & 18 deletions synthesizAR/instruments/base.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
"""
Base class for instrument objects.
"""
import astropy.units as u
import copy
import tempfile
import numpy as np
import pathlib
from dataclasses import dataclass
import tempfile
import zarr

import numpy as np
from astropy.coordinates import SkyCoord
from dataclasses import dataclass
from scipy.interpolate import interp1d
from scipy.ndimage import gaussian_filter
import astropy.units as u
from astropy.coordinates import SkyCoord
from sunpy.coordinates.frames import Helioprojective, HeliographicStonyhurst
from sunpy.coordinates.frames import HeliographicStonyhurst, Helioprojective
from sunpy.map import make_fitswcs_header, Map
import zarr

from synthesizAR.util import is_visible, find_minimum_fov
from synthesizAR.util import find_minimum_fov, is_visible
from synthesizAR.util.decorators import return_quantity_as_tuple

__all__ = ['ChannelBase', 'InstrumentBase']
Expand All @@ -27,7 +27,7 @@ class ChannelBase:
channel: u.Quantity = None


class InstrumentBase(object):
class InstrumentBase:
"""
Base class for instruments. This object is not meant to be instantiated directly. Instead,
specific instruments should subclass this base object and implement a
Expand Down Expand Up @@ -170,17 +170,17 @@ def observe(self, skeleton, save_directory=None, channels=None, **kwargs):
if client:
# Parallel
kernel_futures = client.map(self.calculate_intensity_kernel,
skeleton.loops,
skeleton.strands,
channel=channel,
**kwargs)
kernel_interp_futures = client.map(self.interpolate_to_instrument_time,
kernel_futures,
skeleton.loops,
skeleton.strands,
observing_time=(self.observing_time.value, self.observing_time.unit.to_string()))
else:
# Serial
kernels_interp = []
for l in skeleton.loops:
for l in skeleton.strands:
k = self.calculate_intensity_kernel(l, channel=channel, **kwargs)
k = self.interpolate_to_instrument_time(
k, l, observing_time=(self.observing_time.value, self.observing_time.unit.to_string()),
Expand All @@ -189,22 +189,22 @@ def observe(self, skeleton, save_directory=None, channels=None, **kwargs):

if kwargs.get('save_kernels_to_disk', False):
with tempfile.TemporaryDirectory() as tmpdir:
self._make_stacked_kernel_array(tmpdir, skeleton.loops, channel)
indices = self._find_loop_array_bounds(skeleton.loops)
self._make_stacked_kernel_array(tmpdir, skeleton.strands, channel)
indices = self._find_loop_array_bounds(skeleton.strands)
if client:
files = client.map(self.write_kernel_to_file,
kernel_interp_futures,
skeleton.loops,
skeleton.strands,
indices,
channel=channel,
name=self.name,
tmp_store=tmpdir)
# NOTE: block here to avoid pileup of tasks that can overwhelm the scheduler
distributed.wait(files)
else:
for k, l, i in zip(kernels_interp, skeleton.loops, indices):
for k, l, i in zip(kernels_interp, skeleton.strands, indices):
self.write_kernel_to_file(k, l, i, channel, self.name, tmpdir)
self._rechunk_stacked_kernels(tmpdir, skeleton.loops[0].model_results_filename, channel)
self._rechunk_stacked_kernels(tmpdir, skeleton.strands[0].model_results_filename, channel)
kernels = self.observing_time.shape[0]*[None] # placeholder so we know to read from a file
else:
# NOTE: this can really blow up your memory if you are not careful
Expand Down Expand Up @@ -336,7 +336,7 @@ def integrate_los(self, time, channel, skeleton, coordinates_centers, bins, bin_
# Compute weights
if kernels is None:
i_time = np.where(time == self.observing_time)[0][0]
root = skeleton.loops[0].zarr_root
root = skeleton.strands[0].zarr_root
ds = root[f'{self.name}/{channel.name}_stacked_kernels']
kernels = u.Quantity(ds[i_time, :], ds.attrs['unit'])
# If a volumetric quantity, integrate over the cell and normalize by pixel area.
Expand Down
Loading

0 comments on commit c45f6aa

Please sign in to comment.