Plasmapy: Serializable `Particle`s

Created on 8 Feb 2020  路  14Comments  路  Source: PlasmaPy/PlasmaPy

I'd like to be able to put (some form of) Particles in a dict and dump it to JSON, or put them in an xarray attributes dictionary, save an xarray, load it from file and (possibly with some convenient additional steps to handle any necessary conversion) get the particle back.

A basic test-ish use case:

import xarray
array = xarray.DataSet()
array.attrs['particle'] = Particle('tritium')
array.to_zarr("~/storage")       # without crashing
# store for 12.3 years
array2 = xarray.read_zarr("~/storage")
# optional stuff happens here
assert array2.attrs['particle'] == array.attrs['particle']   # not just a string, but a Particle!

I have no idea how best to achieve this, though.

Good first contribution Help wanted Particles low

All 14 comments

I had to look up what serializable means in this context. Oh, the joys of not being a formally trained computer scientist or software engineer... :joy_cat:

Glad I could help you pick that up, then! :D I actually found a way to do that - I just put str(p) in attrs, and when I need the particle, I use Particle on that!

Of course, it's going to be more difficult once we have CustomParticles. Maybe a from_str factory method on a base class that assigns either a Particle or CustomParticle?

We could use the library "pickle" to save it as a binary file, the downside would be if in the future the class particle change, the file would not be useful. Also it can't be readed as a json file because it s a binary file. I guess that a function to_json and from_json would be useful in this case.

````
import pickle

obj = Particle('tritium')

f = open('store.pckl', 'wb')
pickle.dump(obj, f)
f.close()

f = open('store.pckl', 'rb')
obj = pickle.load(f)
f.close()

I'd definitely prefer the to_json approach.

Hey @StanczakDominik, if this issue is still up for grabs, I'd like to have a go at trying to create a function that will produce a JSON representation of a Particle object. I'm a total newbie to Open Source contributions. Any advice and/or suggestions are appreciated.

It absolutely is! Go for it! One piece of advice - open up a PR with your experiments early, so suggestions can be made early on :)

Awesome! I'm glad to hear that. Thank you for the advice, I'll be sure to share my experiments early. I had a quick question. May I know the policy with regards to communications regarding issues? I wasn't sure whether to use the Matrix chat or the GitHub comments system for clarifications and assistance.

I usually start with keeping discussions in their related issues and PRs, and if nobody responds there, I reach out to the chat :)

Thank you for the response!

I started off with some basics and got a basic JSON representation working (my first experiment). I had some queries with regards to the PR:

  1. The PR guide suggests that I make some tests for the new feature I've added. Should I add some samples into the docstring of my methods?
  2. Since the feature is not yet complete, should this be a Draft PR or a standard one?

Thank you.

Docstrings would definitely be great! They're primarily simple showcases of functionality for users, though. They're also tested, but that's not their primary goal. We thus also tend to add some basic tests (such as the following) https://github.com/PlasmaPy/PlasmaPy/blob/4fa67e233eb13028c007a2711ddbe65a94afcb11/plasmapy/formulary/tests/test_relativity.py#L12-L41

Of course, with JSON representations you probably won't need as many numerical comparisons ;)

The Draft PR feature is basically just a statement of "please don't merge this yet, I'm just looking for feedback for now/I'm not yet perfectly satisfied with this". Perhaps I should add that to the PR template as a hint :) Anyway, whichever is fine :)

Thank you for the information. I'll add some examples and a simple test function before I make a Draft PR.

>>> u.Quantity("nan C")
<Quantity nan C>
>>> u.Quantity("nan C") == np.nan * u.C
False
>>> np.nan * u.C
<Quantity nan C>
>>> u.Quantity("nan C") is np.nan * u.C
False
>>> u.Quantity("nan C") is (np.nan * u.C)
False

I was having some difficulties with converting the NaN back into the nan of the CustomParticle. In the above snippet, I am unable to check whether the particle was created correctly because the charges are not matching for the nan case. Any advice?

>>> u.Quantity("nan C")
<Quantity nan C>
>>> u.Quantity("nan C") == np.nan * u.C
False
>>> np.nan * u.C
<Quantity nan C>
>>> u.Quantity("nan C") is np.nan * u.C
False
>>> u.Quantity("nan C") is (np.nan * u.C)
False

I was having some difficulties with converting the NaN back into the nan of the CustomParticle. In the above snippet, I am unable to check whether the particle was created correctly because the charges are not matching for the nan case. Any advice?

I happened upon a potential solution (in the test_particle_class.py file) that I took a look at. This was the u.isclose method.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lemmatum picture lemmatum  路  4Comments

namurphy picture namurphy  路  5Comments

namurphy picture namurphy  路  3Comments

lemmatum picture lemmatum  路  6Comments

namurphy picture namurphy  路  3Comments