Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable time-dependent effective areas determination in iris_tools #108

Merged

Conversation

kakirastern
Copy link
Contributor

@kakirastern kakirastern commented Apr 9, 2019

Picks up from PR #102 and addresses issue #27.

Goal

To allow the time-dependent effective areas to be derived using get_iris_response() in iris_tools in the same way that it is done in SSW.

Expected Outcomes

  1. A function for deriving the time-dependent IRIS response function.
  2. Benchmarking and unit tests so this new software can be reliably maintained.
  3. Updated intensity conversion methods between instrument and physical units that correct for the time observations were taken.

Project Description

The Interface Region Imaging Spectrograph (IRIS) is a NASA Small Explorer satellite designed to make spectroscopic and imaging observations of the solar chromosphere and transition region. An important tool in interpreting these observations is the instrument response function which expresses the relationship between the physical intensity of light entering the instrument and the data number (DN) recorded by the CCD detectors. The response function was carefully measured by the IRIS team before launch and this is currently available to IRISpy users for their analysis.

However, due to time-dependent factors like degradation, it is known that the response function evolves with time in orbit. For this reason the IRIS team has developed a fitting algorithm based on calibration flights that predicts the response function as a function of time. A direct translation of this algorithm from its original language, IDL (Interactive Data Langauage), into Python has already been performed but requires more work before it can be merged into IRISpy.

The .geny files needed can be accessed at https://sohowww.nascom.nasa.gov/solarsoft/iris/response/.

References:
iris_get_response.pro
fit_iris_xput.pro

Roadmap - fit_iris_xput

Triaging

  • Figure out how to run the function without crashing assuming, this is possible.
    • If the function cannot be made to run, are there simple bug fixes that can address this or is deeper understanding of what the function is doing required?
  • Use print statements or other techniques to go through the code and understand what each variable represents, or at the very least what type it is. It may be helpful to look at the docstring and comments of the IDL version of the code as part of this. Write up a document that explains this, perhaps on the IRISpy wiki.
  • From the above step, write a preliminary docstring for fit_iris_xput explaining what the inputs and outputs.

Benchmarking

  • Write a test function that will allow us to test and understand the output.
  • Coordinate efforts to compare results from the IDL and IRISpy versions to verify they are giving the same answers or where differences are occurring. (Dan have the IDL version installed.)
  • From this, write up required To-Do tasks needed to fix any discrepancies.

Bug-fixing

Make code fixes to get the Python version giving the same or effectively the same answers as the IDL version.

  • Most common type of bugs encountered comes from syntax, especially from converting between programming languages.
  • One of the more glaring and easily omitted error encountered stemmed from erroneous indentation.

Improving Code Pythonically

Once we have a function that returns the same or similar values as the IDL version, the code will have to be made more Pythonic as well as updated to reflect more recent changes in SunPy practices. Benchmarking/testing must be repeated and updated at each stage to ensure we are not changing the values of the output.

  • Using AstroPy's download_file instead of Requests' get to download the .geny files. This adds the cache and timeout functionalities to the download process.
  • Converting the time_obs and time_cal_coeffs into astropy.time.time objects before subtracting to obtain a time difference called t_diff (to be converted into years), which is used to compute the final fit.

Incorporating Time-dependent Fitted Response into get_iris_response

  • Modify the get_iris_response function in iris_tools.py to incorporate consideration of time-dependency.
  • _get_interpolated_effective_area must include a call to fit_iris_xput and add a time input.
  • Add a docstring to the _get_interpolated_effective_area function.
  • Tests of above functions must include cases where a fitted effective area is used.

Benchmarking Cases from SSW

The .geny files can be read in Python using scipy's read save function. See here for an example. Also note that the out is converted to a dict for easier handling the line after. The same attribute names should be maintained between the the IDL and Python structures.

1: Result for a start time of period of constant coef/cal_coef

Lines starting with IDL> are input
; is the IDL comment symbol
Lines without IDL> at the start are output.

IDL> restore, 'iris_sra_c_20161022.geny', /ver ; Restore 2016 response function file. Structure read out in to variable, p0.  For Python version, read in file using scipy's readsav function.  See https://github.com/sunpy/irispy/blob/master/irispy/iris_tools.py#L156
% RESTORE: Portable (XDR) SAVE/RESTORE file.
% RESTORE: Save file written by wuelser@berna, Thu Dec  8 15:50:09 2016.
% RESTORE: IDL version 8.5 (darwin, x86_64).
% RESTORE: Restored variable: P0.
IDL> time_cal_coeffs = p0.c_f_time ; Define FUV time_cal_coeffs input from the p0 variable
IDL> print, time_cal_coeffs
  1.09417e+09  1.10186e+09
  1.10532e+09  1.12933e+09
  1.12951e+09  1.13201e+09
  1.13642e+09  1.16182e+09
  1.16199e+09  2.24052e+09

IDL> ; Define FUV cal_coeffs input from the p0 variable
IDL> cal_coeffs0 = p0.coeffs_fuv[*, *, 0]
IDL> print, cal_coeffs0
     0.523856     0.274797     -6.45654
     0.236928     0.395193     -3.80189
     0.411110    0.0621537     -24.5471
     0.228041     0.247113     -1.99526
     0.128971     0.198371    -0.891251

IDL> cal_coeffs1 = p0.coeffs_fuv[*, *, 1]
IDL> print, cal_coeffs1
    -0.654571      2.90411    -0.891251
     0.957263     0.792720     -7.58577
     0.209228     0.834837     -1.94984
     0.825466     0.156275     -2.69153
     0.675337     0.149698     -1.65959

IDL> cal_coeffs2 = p0.coeffs_fuv[*, *, 2]
IDL> print, cal_coeffs2
    -0.654571      2.90411    -0.891251
     0.957263     0.792720     -7.58577
     0.209228     0.834837     -1.94984
     0.825466     0.156275     -2.69153
     0.675337     0.149698     -1.65959

IDL> ; Define time(s)
IDL> tt = fltarr(1)
IDL> tt[0] = 1.0941696e+09 ; tt is equivalent to time_obs in Python version.

IDL> ; Perform fits for FUV ranges.
IDL> fit0_fuv = fit_iris_xput(tt, p0.c_f_time, p0.coeffs_fuv[*, *, 0])
IDL> fit1_fuv = fit_iris_xput(tt, p0.c_f_time, p0.coeffs_fuv[*, *, 1])
IDL> fit2_fuv = fit_iris_xput(tt, p0.c_f_time, p0.coeffs_fuv[*, *, 2])
IDL> print, fit0_fuv, fit1_fuv, fit2_fuv
0.79865301
2.2495413
2.2495413

IDL> ; Perform fits for NUV ranges. Note the changes in p0.c_n_time and p0.coeffs_nuv variable names.
IDL> fit0_nuv = fit_iris_xput(tt, p0.c_n_time, p0.coeffs_nuv[*, , 0])
IDL> fit1_nuv = fit_iris_xput(tt, p0.c_n_time, p0.coeffs_nuv[
, , 1])
IDL> fit2_nuv = fit_iris_xput(tt, p0.c_n_time, p0.coeffs_nuv[
, *, 2])
IDL> print, fit0_nuv, fit1_nuv, fit2_nuv
0.23529011
0.25203046
0.25265095

Incorporating Time-dependent Fitted Response into Wider IRISpy Code-base

  • Functions further up the chain must also include a time input and pass that on to _get_interpolated_effective_area. This chain includes iris_tools.calculate_photons_per_sec_to_radiance_factor, iris_tools.convert_or_undo_photons_per_sec_to_radiance, andIRISSpectrogramCube.convert_to. Must confirm if there are more cases where this chain leads.
  • Tests of above functions must include cases where a fitted effective area is used.

Final Pythonic Tidy Up

Go through code produced above and make any cumbersome bits of code more Pythonic. This may also involve tidying up or writing a few new tests.

irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
@DanRyanIrish
Copy link
Member

Hi @kakirastern. Thanks for setting up this PR! I've left some comments outlining some simple initial changes.

I think there are a few things we could do to help us understand what we need to do. I've laid those out in the description of the PR above for easy reference. Let me know here what you think.

@kakirastern
Copy link
Contributor Author

You are welcome @DanRyanIrish! I really like the look of the PR and think the plan appears very sound... Looking forward to contributing more to it soon. I have made some preliminary changes as per the comments in PR #102.

@DanRyanIrish
Copy link
Member

They look good! Let me know whenever you're ready to report on whether you were able to get fit_iris_xput running and what bugs you found.

@kakirastern
Copy link
Contributor Author

Yup, sure. Will take a while so will get back to you at least a couple days later.

@kakirastern
Copy link
Contributor Author

Hi @DanRyanIrish! So I have managed to use flake8 to check on fit_iris_xput and get it running/working on a functional level with a new commit 9215373, though I am not sure what meaningful input to feed into it to debug it rigorously. I am wondering if you have some good example I could use for debugging against?

irispy/iris_tools.py Outdated Show resolved Hide resolved
@DanRyanIrish
Copy link
Member

Hi @DanRyanIrish! So I have managed to use flake8 to check on fit_iris_xput and get it running/working on a functional level with a new commit 9215373, though I am not sure what meaningful input to feed into it to debug it rigorously. I am wondering if you have some good example I could use for debugging against?

I'll figure out what the meaningful input should be and run the SSW version to get the expected output.

@DanRyanIrish
Copy link
Member

Hi @kakirastern. I've added a section to the description of this issue above for benchmarking cases listing the result from the SSWIDL software. You should be able to compare the output of the Python version with this to start with.

But first see the comment I left about the indentations as nothing will work properly until that is resolved.

@kakirastern
Copy link
Contributor Author

Thanks @DanRyanIrish for the suggestions and info! I did run into some bugs regarding the shape of a few variables defined as numpy arrays... which will need some work to fix. From what I understand of the situation thisfit_iris_xput is basically a rendering of some least-squares fit? In that case it might be easy to find out what's wrong and debug.

@kakirastern
Copy link
Contributor Author

I will focus my time and effort to completing sunpy/ndcube#151 first for the time being and get back to this soon after that. Hope this arrangement is okay with you.

@DanRyanIrish
Copy link
Member

Sounds like a good plan @kakirastern

@kakirastern
Copy link
Contributor Author

kakirastern commented May 17, 2019

So I finally was able to get the new function fit_iris_xput working... and I did the following:

>>> import numpy as np
>>> import scipy.io
>>> import requests

>>> from irispy.iris_tools import fit_iris_xput

>>> response_url = 'https://sohowww.nascom.nasa.gov/solarsoft/iris/response/iris_sra_c_20161022.geny'
>>> r = requests.get(response_url)
>>> with open('./irispy/data/temp.geny', 'wb') as handle:
    handle.write(r.content)
>>> raw_response_data = scipy.io.readsav('./irispy/data/temp.geny')
>>> iris_response = dict([(name, raw_response_data["p0"][name][0]) for name in raw_response_data["p0"].dtype.names])

>>> time_obs = np.array([1.0941696e+09])
>>> time_cal_coeffs = iris_response.get('C_F_TIME')
>>> cal_coeffs0 = iris_response.get('COEFFS_FUV')[0,:,:]
>>> cal_coeffs1 = iris_response.get('COEFFS_FUV')[1,:,:]
>>> cal_coeffs2 = iris_response.get('COEFFS_FUV')[2,:,:]

>>> fit_iris_xput(time_obs, time_cal_coeffs, cal_coeffs0)
array([0.79865301])
>>> fit_iris_xput(time_obs, time_cal_coeffs, cal_coeffs1)
array([2.24954128])
>>> fit_iris_xput(time_obs, time_cal_coeffs, cal_coeffs2)
array([2.24954128])

If instead I perform fits for NUV ranges, I'd get the values array([0.23529011]), array([0.25203046]), and array([0.25265094]), with the last value deviating/smaller by 0.00000001.

I am not sure why the last fit carried out with the Python code yields a result that is different from the IDL fit. @DanRyanIrish, do you reckon this would imply some significant differences (in the long run)?

@kakirastern
Copy link
Contributor Author

@DanRyanIrish Any suggestions as to what I should do next?

@DanRyanIrish
Copy link
Member

DanRyanIrish commented May 17, 2019

That's excellent news @kakirastern! Well done! A difference of 0.00000001 is insignificant. It's probably a rounding error in the computer itself.

The next thing to do is formalize this into a test, and to do it using the parameterize decorator so we can add more cases later. Once that's working, we should look into trying more times so we adequately cover the parameter space.

We're moving onto phase two of the roadmap already!

(By the way, next time you compare values like this can you put the IDL and Python values side-by-side so I can easily see what the differences are? Thanks!)

@kakirastern
Copy link
Contributor Author

Yup, sure @DanRyanIrish. I will do better data presentation next time. (Should have made a table for it.) And, onto testing now...

@kakirastern
Copy link
Contributor Author

And, I will set the only error of 0.00000001 as the tolerance for the test then.

@DanRyanIrish
Copy link
Member

And, I will set the only error of 0.00000001 as the tolerance for the test then.

1e-6 Is loads. Probably too tight but we can loosen it as needed when we see results from other times later.

@kakirastern
Copy link
Contributor Author

Used the default 6 decimal places as the tolerance for the fit_iris_xput test in the end...

Now I see the following failure thrown:

=================================== FAILURES ===================================
__________________________ test_fits_data_comparison ___________________________

iris_l2_test_raster = <iris.IRISSpectrograph instance
OBS ID: 3690215148
OBS Description: Large sparse 32-step raster 31x120 32s  C II   Si ... 1336 : [1, 32, 196, 514]    pix
     Si IV 1394 : [1, 32, 196, 510]    pix
   Mg II k 2796 : [1, 32, 196, 508]    pix>

    def test_fits_data_comparison(iris_l2_test_raster):
        """Make sure the data is the same in pyfits and irispy"""
        hdulist = fits.open(os.path.join(
            testpath, 'iris_l2_20170222_153635_3690215148_raster_t000_r00000.fits'))
        spectral_window1 = hdulist[0].header["TDESC1"]
        spectral_window2 = hdulist[0].header["TDESC2"]
        spectral_window3 = hdulist[0].header["TDESC3"]
    
        data1 = copy.deepcopy(hdulist[1].data)
        data2 = copy.deepcopy(hdulist[2].data)
        data3 = copy.deepcopy(hdulist[3].data)
    
        data1[hdulist[1].data == -200.] = np.nan
        data2[hdulist[2].data == -200.] = np.nan
        data3[hdulist[3].data == -200.] = np.nan
    
        np.testing.assert_array_almost_equal(
>           iris_l2_test_raster.data[spectral_window1].data[0].data, data1)

irispy/tests/test_spectrograph.py:145: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

x = array([[[-200., -200., -200., ..., -200., -200., -200.],
        [-200., -200., -200., ..., -200., -200., -200.],
    ...00., -200., -200., ..., -200., -200., -200.],
        [-200., -200., -200., ..., -200., -200., -200.]]], dtype=float32)
y = array([[[nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ...,..., nan, nan],
        [nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan]]], dtype=float32)
func = <ufunc 'isnan'>, hasval = 'nan'

    def func_assert_same_pos(x, y, func=isnan, hasval='nan'):
        """Handling nan/inf.
    
        Combine results of running func on x and y, checking that they are True
        at the same locations.
    
        """
        x_id = func(x)
        y_id = func(y)
        # We include work-arounds here to handle three types of slightly
        # pathological ndarray subclasses:
        # (1) all() on `masked` array scalars can return masked arrays, so we
        #     use != True
        # (2) __eq__ on some ndarray subclasses returns Python booleans
        #     instead of element-wise comparisons, so we cast to bool_() and
        #     use isinstance(..., bool) checks
        # (3) subclasses with bare-bones __array_function__ implemenations may
        #     not implement np.all(), so favor using the .all() method
        # We are not committed to supporting such subclasses, but it's nice to
        # support them if possible.
        if bool_(x_id == y_id).all() != True:
            msg = build_err_msg([x, y],
                                err_msg + '\nx and y %s location mismatch:'
                                % (hasval), verbose=verbose, header=header,
                                names=('x', 'y'), precision=precision)
>           raise AssertionError(msg)
E           AssertionError: 
E           Arrays are not almost equal to 6 decimals
E           
E           x and y nan location mismatch:
E            x: array([[[-200., -200., -200., ..., -200., -200., -200.],
E                   [-200., -200., -200., ..., -200., -200., -200.],
E                   [-200., -200., -200., ..., -200., -200., -200.],...
E            y: array([[[nan, nan, nan, ..., nan, nan, nan],
E                   [nan, nan, nan, ..., nan, nan, nan],
E                   [nan, nan, nan, ..., nan, nan, nan],...

/anaconda3/envs/irispy-dev/lib/python3.6/site-packages/numpy/testing/_private/utils.py:733: AssertionError

@kakirastern
Copy link
Contributor Author

kakirastern commented May 18, 2019

So I found out there are 3 lines in the file "test_spectrograph.py" which were causing problems before I commented them out. Not sure why they were there in the first place. Could have been used for debugging earlier. They actually appeared out of place before:

https://github.com/sunpy/irispy/pull/108/files#diff-7c42eb0d015fb3346007f43ca206dd1aR140

#data1[hdulist[1].data == -200.] = np.nan
#data2[hdulist[2].data == -200.] = np.nan
#data3[hdulist[3].data == -200.] = np.nan

@DanRyanIrish
Copy link
Member

Well done on getting the tests to pass! Looks great. The next step is to make the code in fit_iris_xput more Pythonic without changing the output. I can go through the code an make suggestions on how to go about that.

@kakirastern
Copy link
Contributor Author

That would be great!

Copy link
Member

@DanRyanIrish DanRyanIrish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some changes to get started on. Do the time-related ones last as they are likely to cause the most trouble. Also, where possible, do each change one at a time and then check that the output hasn't changed by running the test.

irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
@kakirastern
Copy link
Contributor Author

Thanks @DanRyanIrish for the suggestions! Will definitely work on them over the next few days.

@kakirastern
Copy link
Contributor Author

Hi @DanRyanIrish, I have incorporated all of the suggested changes to render the fit_iris_xput function more pythonic, except for the ones that don't work in our case. Please have a look and let me know what steps to take next.

@kakirastern
Copy link
Contributor Author

So if I do the following:

import os
import pytest

import numpy as np
import numpy.testing as np_test
import astropy.units as u
from astropy.utils.data import download_file
import scipy.io
import requests

import irispy.iris_tools as iris_tools
from irispy.iris_tools import fit_iris_xput

response_url = 'https://sohowww.nascom.nasa.gov/solarsoft/iris/response/iris_sra_c_20161022.geny'
r = download_file(response_url)
raw_response_data = scipy.io.readsav(r)
iris_response = dict([(name, raw_response_data["p0"][name][0]) for name in raw_response_data["p0"].dtype.names])
time_obs = np.array([1.0941696e+09])
time_cal_coeffs0 = iris_response.get('C_F_TIME')
time_cal_coeffs1 = iris_response.get('C_N_TIME')
cal_coeffs0 = iris_response.get('COEFFS_FUV')[0,:,:]
cal_coeffs1 = iris_response.get('COEFFS_FUV')[1,:,:]
cal_coeffs2 = iris_response.get('COEFFS_FUV')[2,:,:]
cal_coeffs3 = iris_response.get('COEFFS_NUV')[0,:,:]
cal_coeffs4 = iris_response.get('COEFFS_NUV')[1,:,:]
cal_coeffs5 = iris_response.get('COEFFS_NUV')[2,:,:]
iris_fit_expected0 = np.array([0.79865301])
iris_fit_expected1 = np.array([2.2495413])
iris_fit_expected2 = np.array([2.2495413])
iris_fit_expected3 = np.array([0.23529011])
iris_fit_expected4 = np.array([0.25203046])
iris_fit_expected5 = np.array([0.25265095])

I would get the following

Case    IDL results    Pythonic results
====    ===========    ================
FUV1    0.79865301     0.79865301
FUV2    2.2495413      2.24954128
FUV3    2.2495413      2.24954128
NUV1    0.23529011     0.25605348
NUV2    0.25203046     0.2742711
NUV3    0.25265095     0.27494633

Question: Should I change the tolerance for the comparisons so that the tests will pass, or should I re-examine the code to try and debug, if it is a bug at all?

Copy link
Member

@DanRyanIrish DanRyanIrish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some more comments. After these are addressed we can take another look.

irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
@kakirastern
Copy link
Contributor Author

Weird, I still got the same data...

@kakirastern
Copy link
Contributor Author

Both get_iris_response and fit_iris_xput functions working now and are generating outputs as expected. Tests have been written to check both are performing well. (I have set the number of decimal places for the agreement to 6 for now.) Once everything checks out I can then move on to the final stage of the project...

@kakirastern
Copy link
Contributor Author

I believe the next stage is this:

Updated intensity conversion methods between instrument and physical units that correct for the time observations were taken.

But I will need guidance to do that.

irispy/iris_tools.py Show resolved Hide resolved
irispy/iris_tools.py Show resolved Hide resolved
irispy/tests/test_iris_tools.py Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
irispy/iris_tools.py Show resolved Hide resolved
irispy/iris_tools.py Outdated Show resolved Hide resolved
@kakirastern
Copy link
Contributor Author

@DanRyanIrish and @hayesla I have resolved all the issues brought up in the reviews and have resolved them one-by-one. Hopefully this PR can be merged soon so new PR's can be open to make it complete.

@DanRyanIrish
Copy link
Member

DanRyanIrish commented Jul 26, 2019

Hi @kakirastern. With @hayesla's help I figured out the confusion we were having earlier that prevented us from merging this PR today. I didn't realise that iris_fit was a required input to _get_interpolated_effective_area because it wasn't in the def statement.

So I suggest that one last change be made: undo the changes in commit "Revert changes previously made to the "_get_interpolated_effective_area" method" (c3abaf7). Then we will merge. Apologies for the confusion!

@kakirastern
Copy link
Contributor Author

@DanRyanIrish No worries. Also, will I need to add iris_fit as an argument to _get_interpolated_effective_area? Or would adding **kwargs suffice?

@kakirastern
Copy link
Contributor Author

Rebased PR and dropped commit c3abaf7. Then added another commit to change time.time in the in-code documentation to astropy.time.Time as previously instructed.

irispy/iris_tools.py Outdated Show resolved Hide resolved
@DanRyanIrish
Copy link
Member

Hi @kakirastern. I see that you've made those changes. Once the CI passes I'm happy to merge this. You've done a great job on a very tricky assignment! How about you @hayesla? Are you happy to approve this?

@hayesla
Copy link
Member

hayesla commented Jul 29, 2019

Good with me!

@DanRyanIrish DanRyanIrish merged commit 585b4d0 into sunpy:time_dependent_response Jul 29, 2019
This was referenced Jul 30, 2019
DanRyanIrish added a commit that referenced this pull request Aug 1, 2019
Polish up work on #108 on the irispy/time_dependent_response branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants