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

First step to simplify NDCubeSequence slicing implementation #251

Merged
merged 12 commits into from
Apr 13, 2020

Conversation

hayesla
Copy link
Member

@hayesla hayesla commented Apr 2, 2020

First pass at #248

To Do

  • Add changelog file.
  • Fix any failing test(s).

@pep8speaks
Copy link

pep8speaks commented Apr 2, 2020

Hello @hayesla! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

There are currently no PEP 8 issues detected in this Pull Request. Cheers! 🍻

Comment last updated at 2020-04-13 03:58:08 UTC

@DanRyanIrish DanRyanIrish added this to the 2.0 milestone Apr 3, 2020
@DanRyanIrish
Copy link
Member

Hi @hayesla. I think this PR should also change the type of self.data to any array. I think the most efficient way to do this would be to change this line to self.data = np.asanyarray(data_list).

I don't think should cause any tests to fail, but if it does I think they should be simple enough fixes.

Also change the docstring accordingly, i.e. this line to

data: 1D `numpy.ndarray`
    Array of cubes

@DanRyanIrish
Copy link
Member

It also looks like there is only one test that's failing: ndcube/tests/test_sequence_plotting.py:482

This PR also needs a trivial-type changelog, i.e. 251.trivial.rst in the changelog directory. See here for more instructions.

@DanRyanIrish
Copy link
Member

DanRyanIrish commented Apr 9, 2020

@hayesla, could you move the code in __getitem__ to replace the code in utils.sequence.slice_sequence and then simply have __getitem__ return the output of utils.sequence.slice_sequence. This implementation is needed in sunraster.

@hayesla
Copy link
Member Author

hayesla commented Apr 9, 2020

so do you mean that getitem just returns the utils.sequence.slice_sequence - as this works for ints, slices and tuples?

@DanRyanIrish
Copy link
Member

Yep, that's right, e.g.

def __getitem__(self, item):
    return utils.sequence.slice_sequence(self, item)

@DanRyanIrish DanRyanIrish modified the milestones: 2.0, 1.3.1 Apr 9, 2020
@DanRyanIrish
Copy link
Member

Added a To Do checklist in the PR description to show what's left to do. As you can see there is not much to do. I am considering doing a bugfix release soon, perhaps at the start of next week? Since this is needed for sunraster we could include it. The _common_axis slicing bug can be fixed in a separate PR and released as part of 2.0.

How does this sound?

@DanRyanIrish
Copy link
Member

This commit doesn't do things the way I meant. I think this is my fault for a confusing explanation. I suggest you wind back this commit and proceed without it. I'll remove the slice_sequence step in the above to do list too.

@hayesla hayesla force-pushed the ndcube_sequence_slicing branch from 18f88fb to 231c641 Compare April 10, 2020 19:45
@hayesla
Copy link
Member Author

hayesla commented Apr 10, 2020

@DanRyanIrish - I think this is more along the lines you were thinking?

It still don't fix the common_axis issue but as you mentioned maybe that could go in another PR?

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.

This looks good!

@@ -84,14 +84,21 @@ def cube_like_world_axis_physical_types(self):
return self.data[0].world_axis_physical_types

def __getitem__(self, item):

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change

@@ -0,0 +1 @@
use the `utils.sequence.slice_sequence` for __getitem__
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
use the `utils.sequence.slice_sequence` for __getitem__
Simplify and speed up implementation of NDCubeSequence slicing.

@DanRyanIrish
Copy link
Member

It still don't fix the common_axis issue but as you mentioned maybe that could go in another PR?

Yes, let's keep that for a separate PR.

@DanRyanIrish DanRyanIrish modified the milestones: 1.3.1, 2.0 Apr 10, 2020
result = copy.deepcopy(self)
result.data = self.data[item]
if isinstance(item, slice):
result.data = self.data[item]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
result.data = self.data[item]
result.data = self.data[item]

Copy link
Member

Choose a reason for hiding this comment

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

Over-indented line.

@DanRyanIrish
Copy link
Member

Hmmm. I don't understand those test failures... Perhaps @nabobalis can interpret them for us?

@DanRyanIrish
Copy link
Member

To get the tests to behave correctly, we have to pin pytest to <5.4. To do this change this line in setup.cfg to pytest < 5.4. Then commit and push.

Be sure to make this the only change in the commit. It makes it easy to cherry-pick later it I need it for the bugfix release. Thanks!!

@hayesla
Copy link
Member Author

hayesla commented Apr 10, 2020

done!

@DanRyanIrish
Copy link
Member

Great! Hopefully that'll make the test fails more understandable.

@nabobalis
Copy link
Contributor

nabobalis commented Apr 10, 2020

Seems to be:

===================================================================================== ERRORS ======================================================================================
_________________________________________________ ERROR collecting .tox/py38/Lib/site-packages/ndcube/tests/test_ndcollection.py __________________________________________________
..\..\.tox\py38\Lib\site-packages\ndcube\tests\test_ndcollection.py:77: in <module>
    NDCollection([("seq0", sequence02[:, 1, 1:3]), ("seq1", sequence20[:, 1, 1:3])],
..\..\.tox\py38\Lib\site-packages\ndcube\ndcube_sequence.py:97: in __getitem__
    elif isinstance(item[0], slice) and item[0].stop - item[0].start == 1:
E   TypeError: unsupported operand type(s) for -: 'NoneType' and 'NoneType'

The mac os build failed due to threading, so we will need to add posargs: -n=1 to the last line of the mac os block in the azure template.

@hayesla
Copy link
Member Author

hayesla commented Apr 10, 2020

Seems to be:

===================================================================================== ERRORS ======================================================================================
_________________________________________________ ERROR collecting .tox/py38/Lib/site-packages/ndcube/tests/test_ndcollection.py __________________________________________________
..\..\.tox\py38\Lib\site-packages\ndcube\tests\test_ndcollection.py:77: in <module>
    NDCollection([("seq0", sequence02[:, 1, 1:3]), ("seq1", sequence20[:, 1, 1:3])],
..\..\.tox\py38\Lib\site-packages\ndcube\ndcube_sequence.py:97: in __getitem__
    elif isinstance(item[0], slice) and item[0].stop - item[0].start == 1:
E   TypeError: unsupported operand type(s) for -: 'NoneType' and 'NoneType'

The mac os build failed due to threading, so we will need to add posargs: -n=1 to the last line of the mac os block in the azure template.

I think this may be an actually bug in the code no?

@nabobalis
Copy link
Contributor

I would say yes?

else:
if isinstance(item[0], numbers.Integral):
result = result.data[item[0]][item[1:]]
elif isinstance(item[0], slice) and item[0].stop - item[0].start == 1:
Copy link
Member

Choose a reason for hiding this comment

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

Just looked at this again. I don't think this line and the one below are needed at all? The line after the else will do the same job in all remaining cases, I'm pretty sure? If so, that'll also get rid of the test failure.

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah its needed, as if you just do the list comprehension on the NDCube rather on the list of NDCubes it then loops through the arrays in the NDCube if that makes sense

Copy link
Member Author

Choose a reason for hiding this comment

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

i.e. as in for this result.data = [cube[item[1:]] for cube in result.data[item[0]]] to work you need result.data[item[0]] to be a list of NDCubes rather than an NDCube. but if item[0] is a 0, or slice(0, 1) this doesn't work ... the way it is currently implemented also follows similar logic to the way the utils.sequence.slice_sequence kind of did it without the need of a SequenceItem

Copy link
Member

Choose a reason for hiding this comment

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

Ah! You're dead right!

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
elif isinstance(item[0], slice) and item[0].stop - item[0].start == 1:
elif isinstance(item[0], slice):
start = 0 if item[0].start is None else item[0].start
stop = len(self.data) if item[0].stop is None else item[0].stop
if stop - start == 1:
result.data = [result.data[item[0].start][item[1:]]]

@DanRyanIrish DanRyanIrish modified the milestones: 2.0, 1.3.1 Apr 11, 2020
@DanRyanIrish
Copy link
Member

So this code passes tests now with the exception of one doctest in ndcubesequence.rst. However, when I run the same code locally after pulling @hayesla's branch, it gives the right output. I can't understand why that is! @nabobalis have you ever seen that before?

Comparison of test output:
Azure case:

189 independently!) However, with `~ndcube.NDCubeSequence` this becomes as
190 simple as indexing a single array::
191 
192   >>> regions_of_interest_in_sequence = my_sequence[1:3, 0, 1:3, 1:4]
193   >>> regions_of_interest_in_sequence.dimensions
Expected:
    (<Quantity 2. pix>, <Quantity 2. pix>, <Quantity 3. pix>)
Got:
    (<Quantity 3. pix>, <Quantity 3. pix>, <Quantity 4. pix>, <Quantity 5. pix>)

/home/vsts/work/1/s/docs/ndcubesequence.rst:193: DocTestFailure

Output when executing code locally:

>>> regions_of_interest_in_sequence = my_sequence[1:3, 0, 1:3, 1:4]
>>> regions_of_interest_in_sequence.dimensions
(<Quantity 2. pix>, <Quantity 2. pix>, <Quantity 3. pix>)  # This is the same as what the doctest expects.

@nabobalis
Copy link
Contributor

I am not sure. There has to be some difference but what I can't say for now.

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.

Just realised why this was failing. The case where item[0] is a slice but stop - start != 1 is not handled!

ndcube/ndcube_sequence.py Outdated Show resolved Hide resolved
ndcube/ndcube_sequence.py Outdated Show resolved Hide resolved
ndcube/ndcube_sequence.py Outdated Show resolved Hide resolved
ndcube/ndcube_sequence.py Outdated Show resolved Hide resolved
ndcube/ndcube_sequence.py Outdated Show resolved Hide resolved
ndcube/ndcube_sequence.py Show resolved Hide resolved
ndcube/ndcube_sequence.py Outdated Show resolved Hide resolved
The case where the slice item was a tuple, item[0] is a slice of length > 1 so simply dropped. This fixes that oversight.
ndcube/ndcube_sequence.py Outdated Show resolved Hide resolved
ndcube/ndcube_sequence.py Outdated Show resolved Hide resolved
ndcube/ndcube_sequence.py Outdated Show resolved Hide resolved
@DanRyanIrish
Copy link
Member

Hi @hayesla. I got this PR working. Hooray!!!

Before merging, could I ask you to squash all the commits? If you aren't sure how to do that we can walk through it together. Making this a 1 commit PR will make cherry-picking it for the release of 1.3.1 much easier.

@DanRyanIrish DanRyanIrish merged commit b5db986 into sunpy:master Apr 13, 2020
@DanRyanIrish
Copy link
Member

Thanks for this successful PR @hayesla!!

@hayesla
Copy link
Member Author

hayesla commented Apr 13, 2020

whoop whoop first NDCube PR 👯

DanRyanIrish added a commit to DanRyanIrish/ndcube that referenced this pull request Apr 13, 2020
First step to simplify NDCubeSequence slicing implementation
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.

4 participants