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

Explore refactor using a lower-level Function class #15

Open
marshallmcdonnell opened this issue Dec 10, 2018 · 1 comment
Open

Explore refactor using a lower-level Function class #15

marshallmcdonnell opened this issue Dec 10, 2018 · 1 comment
Labels

Comments

@marshallmcdonnell
Copy link
Member

To better improve the design and checks for the higher-level classes, specifically the Converter class, would like to explore the idea of a Function class that acts like a factory.

The idea of the class would be something like:

sq = Function(x, y, error=e, "S(Q)") # x,y,e are the Q, S(Q), and E[S(Q)], respectively
dcs = sq.to_DCS()
gr = sq.to_GofR(r) # r is the real space domain

Yet, the initial issue I see is that this requires both the capabilities of the Converter and Transformer into one class.

@marshallmcdonnell
Copy link
Member Author

I think a better approach will be to do a modified Translator pattern mixed with borrowing from ASE's functional approach to I/O.

I would like to have a high-level function convert instead of a class of functions (i.e. Converter).
An example would be:

import numpy as np
from pystog import convert
q = np.arange(0., 10.0, 0.1)
sq = np.random.rand(100)

q, dcs = convert(q, sq, from="S(Q)", to="DCS(Q)")

Behind the scenes, the from and to arguments would belong to dictionaries for the different function types.
Something similar in ASE is the define_io_format that maps strings to module names. (this fills in the ioformats dictionary in ASE)

Each module of ours will be real functions with to_gofr and from_gofr function and reciprocal functions with to_sofq and from_sofq (similarly to the read_* and write_* functions in ASE; see xyz example)

Based on the from and to we can:

  1. Figure out if they exist in the real space or reciprocal space dictionary of patterns supported
  2. Make sure they come from the same dictionary / function space
  3. Get the module to load for the from conversion to either G(r) (to_gofr function) or S(Q) (to_sofq function)
  4. Get the module to load for the to conversion from either G(r) (from_gofr function) or S(Q) (from_sofq function)

In ASE, the module lookup is accomplished via the _writefunc and _readfunc functions. These are then used by the _read_wrapper and _write_wrapper functions.

Then, I see the directory structure taking on (including a transform and fouier_filter function refactor, too) the following:

├── convert.py
├── fourier_filter.py
├── functions
│   ├── gofr.py
│   ├── real
│   │   ├── gk_of_r.py
│   │   └── small_g_of_r.py
│   ├── reciprocal
│   │   ├── dcs_of_q.py
│   │   ├── fk_of_q.py
│   │   └── f_of_q.py
│   └── sofq.py
└── tranform.py

All the files under the functions directory are the top-level G(r) and S(Q) followed by real and reciprocal space sub sets that hold these from_* and to_*.

Thus, we have a translator pattern using G(R) and S(Q) as our "common objects"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant