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

Make PeaksAndMetrics pickle-able #1195

Merged
merged 14 commits into from Mar 22, 2017
Merged

Make PeaksAndMetrics pickle-able #1195

merged 14 commits into from Mar 22, 2017

Conversation

arokem
Copy link
Contributor

@arokem arokem commented Mar 20, 2017

@coveralls
Copy link

Coverage Status

Coverage remained the same at 88.431% when pulling 7d53841 on arokem:pickle-pam-3.6 into ab2032b on nipy:master.

@arokem
Copy link
Contributor Author

arokem commented Mar 20, 2017

Travis failure unrelated to this PR, and only on Python 3.3

@matthew-brett
Copy link
Contributor

@@ -38,6 +38,10 @@ cdef class PeaksAndMetricsDirectionGetter(DirectionGetter):
self.ang_thr = 60
self.total_weight = .5

def __getstate__(self): return self.__dict__

def __setstate__(self, d): self.__dict__.update(d)
Copy link
Contributor

Choose a reason for hiding this comment

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

The update will leave any previous members in place, that are not defined in d. Is that the right thing to do?

@arokem
Copy link
Contributor Author

arokem commented Mar 20, 2017 via email

@matthew-brett
Copy link
Contributor

No, that is puzzling. I wonder whether it's something random about when classes get thrown around by the multiprocessing ?

@matthew-brett
Copy link
Contributor

Sorry - I hate to say - but it would be good to have a test of pickling and unpickling these guys in fresh and used state.

@codecov-io
Copy link

codecov-io commented Mar 20, 2017

Codecov Report

Merging #1195 into master will increase coverage by <.01%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #1195      +/-   ##
==========================================
+ Coverage   85.93%   85.94%   +<.01%     
==========================================
  Files         219      219              
  Lines       26403    26419      +16     
  Branches     2711     2716       +5     
==========================================
+ Hits        22689    22705      +16     
+ Misses       3052     3050       -2     
- Partials      662      664       +2
Impacted Files Coverage Δ
dipy/direction/peaks.py 79.35% <100%> (+0.19%) ⬆️
dipy/direction/tests/test_peaks.py 99.44% <100%> (+0.02%) ⬆️
dipy/utils/six.py 45.71% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ab2032b...02c4ee7. Read the comment docs.

@arokem
Copy link
Contributor Author

arokem commented Mar 20, 2017 via email

@arokem
Copy link
Contributor Author

arokem commented Mar 20, 2017 via email

@arokem
Copy link
Contributor Author

arokem commented Mar 20, 2017 via email

Checking that switching on and off some of the requested returns still de-/serializes properly.
@arokem
Copy link
Contributor Author

arokem commented Mar 20, 2017

I'm learning so many things about pickles over here 😄

Previous attempt seemed to be failing on Python 2. Here's a new approach that might work on both.

@arokem
Copy link
Contributor Author

arokem commented Mar 20, 2017

Changing the title of the PR accordingly 😉

@arokem arokem changed the title Add get_state, set_state methods to PeaksAndMetrics. Make PeaksAndMetrics pickle-able Mar 20, 2017
@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) to 88.442% when pulling d4bed65 on arokem:pickle-pam-3.6 into ab2032b on nipy:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) to 88.442% when pulling d4bed65 on arokem:pickle-pam-3.6 into ab2032b on nipy:master.

@@ -157,8 +157,63 @@ def peak_directions(odf, sphere, relative_peak_threshold=.5,
return directions, values, indices


def _rebuild_pam(sphere, peak_indices, peak_values, peak_dirs,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not make this a classmethod called from_params or similar?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It would be a bit weird as a class method, considering that it returns another instance of that class. Or would it?

There does seem to be an opportunity to reduce boiler-plate here though, so I am going to try out a couple more things. Stand by.

@arokem
Copy link
Contributor Author

arokem commented Mar 21, 2017

What do you think about this? I renamed it to _pam_from_attrs and I am now also using it to initialize the PAM instance in the peaks_from_model function below (which had a similar pattern). I prefer attrs to params, to not confuse this with model parameters.

@arokem
Copy link
Contributor Author

arokem commented Mar 21, 2017

And I think this looks better than:

pam = PeaksAndMetrics()
pam = pam._from_attrs(...)

which is what we would do if we had this implemented as a class method (I think).

@matthew-brett
Copy link
Contributor

The floating external function looks funny to me, especially for a class that is otherwise empty.

Here's the alternative classmethod I was thinking of:

pam = PeaksAndMetrics()
pam = PeaksAndMetrics.from_attrs(...)

To me it looks like a normal alternative class constructor pattern...

@arokem
Copy link
Contributor Author

arokem commented Mar 21, 2017 via email

@arokem
Copy link
Contributor Author

arokem commented Mar 21, 2017

Sadly, this approach does not work on Python 2: https://travis-ci.org/arokem/dipy/jobs/213491090#L2580

Any ideas?

@arokem
Copy link
Contributor Author

arokem commented Mar 22, 2017 via email

self.qa,
self.shm_coeff,
self.B,
self.odf)
Copy link
Contributor

Choose a reason for hiding this comment

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

Add self.__class__ as argument to allow sub-classing? Maybe, it would be better as first argument.

@arokem
Copy link
Contributor Author

arokem commented Mar 22, 2017 via email


Parameters
----------
klass : class, optional
Copy link
Contributor

Choose a reason for hiding this comment

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

No longer optional !

@coveralls
Copy link

Coverage Status

Coverage increased (+0.007%) to 88.438% when pulling 8f221a0 on arokem:pickle-pam-3.6 into ab2032b on nipy:master.

@matthew-brett
Copy link
Contributor

All OK for me, after fix of optional in docstring.

@arokem
Copy link
Contributor Author

arokem commented Mar 22, 2017 via email

@coveralls
Copy link

Coverage Status

Coverage increased (+0.007%) to 88.438% when pulling f47076a on arokem:pickle-pam-3.6 into ab2032b on nipy:master.


return pam
return _pam_from_attrs(PeaksAndMetrics, sphere, peak_indices, peak_values,
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess, if you can be bothered:

return _pam_from_attrs(PeaksAndMetrics,
                       sphere,
                       peak_indices,
                       peak_values,
                       peak_dirs,
                       gfa_array,
                       qa_array,
                       shm_coeff if return_sh else None,
                       B if return_sh else None,
                       odf_array if return_odf else None)

@arokem
Copy link
Contributor Author

arokem commented Mar 22, 2017 via email

@matthew-brett
Copy link
Contributor

Ah sorry - I mean particularly cleaning up the slightly ugly if blocks with the conditionals:

...
shm_coeff if return_sh else None,
B if return_sh else None,
odf_array if return_odf else None)

@arokem
Copy link
Contributor Author

arokem commented Mar 22, 2017 via email

@matthew-brett
Copy link
Contributor

Thanks for your patience. One of us merge when the tests pass (apart from the 3.3 failure)?

@coveralls
Copy link

Coverage Status

Coverage increased (+0.007%) to 88.438% when pulling ec3ac55 on arokem:pickle-pam-3.6 into ab2032b on nipy:master.

@arokem
Copy link
Contributor Author

arokem commented Mar 22, 2017

The patience is all yours. Last one to the merge button is a rotten egg.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.005%) to 88.435% when pulling 02c4ee7 on arokem:pickle-pam-3.6 into ab2032b on nipy:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.005%) to 88.435% when pulling 02c4ee7 on arokem:pickle-pam-3.6 into ab2032b on nipy:master.

@arokem arokem merged commit 0ea8af7 into dipy:master Mar 22, 2017
@arokem
Copy link
Contributor Author

arokem commented Mar 22, 2017

Beat you to it!

@matthew-brett
Copy link
Contributor

Good job - but - aren't the tests still running?

@arokem
Copy link
Contributor Author

arokem commented Mar 22, 2017 via email

@arokem
Copy link
Contributor Author

arokem commented Mar 22, 2017 via email

@matthew-brett
Copy link
Contributor

Well played sir.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.005%) to 88.435% when pulling 02c4ee7 on arokem:pickle-pam-3.6 into ab2032b on nipy:master.

ShreyasFadnavis pushed a commit to ShreyasFadnavis/dipy that referenced this pull request Sep 20, 2018
Make PeaksAndMetrics pickle-able
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