-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* CLI and I/O * Simplify deploy
- Loading branch information
Showing
16 changed files
with
923 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ API reference | |
model | ||
transform | ||
utils | ||
io | ||
fdesign | ||
tmtemod | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
I/O | ||
=== | ||
|
||
.. automodapi:: empymod.io | ||
:no-inheritance-diagram: | ||
:no-heading: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ User Guide | |
installation | ||
usage | ||
info | ||
iocli | ||
transforms | ||
credits | ||
citation | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
I/O & CLI | ||
######### | ||
|
||
Starting with ``empymod v2.2.0`` there are some basic saving and loading | ||
routines together with a command line interface. This makes it possible to | ||
model EM responses relatively straight forward from any other code. | ||
|
||
|
||
.. _I/O: | ||
|
||
I/O | ||
--- | ||
|
||
There are currently two saving and two loading routines, one each for inputs | ||
and one for data. «Input» in this context means all the parameters a modelling | ||
routine takes. The saving/loading routines are on one hand good for persistence | ||
and reproducibility, but on the other hand also necessary for the command-line | ||
interface (see section `CLI`_). | ||
|
||
``{save;load}_input`` | ||
~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Let's look at a simple example. From the start, we collect the input parameters | ||
in a dictionary instead of providing them directly to the function. | ||
|
||
.. ipython:: | ||
|
||
In [1]: import empymod | ||
...: import numpy as np | ||
...: | ||
...: # Define input parameters | ||
...: inp = { | ||
...: 'src': [[0, 0], [0, 1000], 250, [0, 90], 0], | ||
...: 'rec': [np.arange(1, 6)*2000, np.zeros(5), 300, 0, 0], | ||
...: 'freqtime': np.logspace(-1, 1, 3), | ||
...: 'depth': [0, 300, 1500, 1600], | ||
...: 'res': [2e14, 0.3, 1, 100, 1], | ||
...: } | ||
...: | ||
...: # Model it | ||
...: efield = empymod.bipole(**inp) | ||
We can now simply save this dictionary to disk via | ||
|
||
|
||
.. ipython:: | ||
|
||
In [1]: empymod.io.save_input('myrun.json', inp) | ||
|
||
This will save the input parameters in the file ``myrun.json`` (you can provide | ||
absolute or relative paths in addition to the file name). The file name must | ||
currently include ``.json``, as it is the only backend implemented so far. The | ||
json-file is a plain text file, so you can open it with your favourite editor. | ||
Let's have a look at it: | ||
|
||
.. ipython:: | ||
|
||
In [1]: !cat myrun.json | ||
|
||
As you can see, it is basically the dictionary written as json. You can | ||
therefore write your input parameter file with any program you want to. | ||
|
||
These input files can then be loaded to run the *exactly* same simulation | ||
again. | ||
|
||
.. ipython:: | ||
|
||
In [1]: inp_loaded = empymod.io.load_input('myrun.json') | ||
...: efield2 = empymod.bipole(**inp_loaded) | ||
...: # Let's check if the result is indeed the same. | ||
...: print(f"Result is identical: {np.allclose(efield, efield2, atol=0)}") | ||
|
||
``{save;load}_data`` | ||
~~~~~~~~~~~~~~~~~~~~ | ||
|
||
These functions are to store or load data. Using the computation from above, | ||
we can store the data in one of the following two ways, either as json or as | ||
text file: | ||
|
||
.. ipython:: | ||
|
||
In [1]: empymod.io.save_data('mydata.json', efield) | ||
...: empymod.io.save_data('mydata.txt', efield, info='some data info') | ||
|
||
|
||
Let's have a look at the text file: | ||
|
||
.. ipython:: | ||
|
||
In [1]: !cat mydata.txt | ||
|
||
First is a header with the date, the version of empymod with which it was | ||
generated, and the shape and type of the data. This is followed by a line of | ||
additional information, which you can define by providing a string to the input | ||
parameter ``info``. The columns are the sources (two in this case), and in the | ||
rows there are first all receivers for the first frequency (or time), then all | ||
receivers for the second frequency (or time), and so on. | ||
|
||
The json file is very similar. Here we print just the first twenty lines as an | ||
example: | ||
|
||
.. ipython:: | ||
|
||
In [1]: !head -n 20 mydata.json | ||
|
||
The main difference, besides the structure, is that the json-format does not | ||
support complex data. It lists therefore first all real parts, and then all | ||
imaginary parts. If you load it with another json reader it will therefore | ||
have the dimension ``(2, nfreqtime, nrec, nsrc)``, where the 2 stands for real | ||
and imaginary parts. (Only for frequency-domain data of course, not for | ||
time-domain data.) | ||
|
||
To load it in Python simply use the corresponding functions: | ||
|
||
.. ipython:: | ||
|
||
In [1]: efield_json = empymod.io.load_data('mydata.json') | ||
...: efield_txt = empymod.io.load_data('mydata.txt') | ||
...: # Let's check they are the same as the original. | ||
...: print(f"Json-data: {np.allclose(efield, efield_json, atol=0)}") | ||
...: print(f"Txt-data : {np.allclose(efield, efield_txt, atol=0)}") | ||
|
||
|
||
Caution | ||
~~~~~~~ | ||
|
||
There is a limitation to the ``save_input``-functionality: The data *must* be | ||
three dimensional, ``(nfreqtime, nrec, nsrc)``. Now, in the above example that | ||
is the case, we have 3 frequencies, 5 receivers, and 2 sources. However, if any | ||
of these three quantities would be 1, empymod would by default squeeze the | ||
dimension. To avoid this, you have to pass the keyword ``squeeze=False`` to the | ||
empymod-routine. | ||
|
||
|
||
.. _CLI: | ||
|
||
CLI | ||
--- | ||
|
||
The command-line interface is a simple wrapper for the main top-level modelling | ||
routines :func:`empymod.model.bipole`, :func:`empymod.model.dipole`, | ||
:func:`empymod.model.loop`, and :func:`empymod.model.analytical`. To call it | ||
you must write a json-file containing all your input parameters as described in | ||
the section `I/O`_. The basic syntax of the CLI is | ||
|
||
.. code-block:: console | ||
empymod <routine> <inputfile> <outputfile> | ||
You can find some description as well by running the regular help | ||
|
||
.. code-block:: console | ||
empymod --help | ||
As an example, to reproduce the example given above in the I/O-section, run | ||
|
||
.. code-block:: console | ||
empymod bipole myrun.json mydata.txt | ||
If you do not specify the output file (the last argument) the result will be | ||
printed to the STDOUT. | ||
|
||
|
||
Warning re runtime | ||
~~~~~~~~~~~~~~~~~~ | ||
|
||
A warning with regards to runtime: The CLI has an overhead, as it has to load | ||
Python and empymod with all its dependencies each time (which is cached if | ||
running in Python). Currently, the overhead should be less than 1s, and it will | ||
come down further with changes happening in the dependencies. For doing some | ||
simple forward modelling that should not be significant. However, it would | ||
potentially be a bad idea to use the CLI for a forward modelling kernel in an | ||
inversion. The inversion would spend a significant if not most of its time | ||
starting Python and importing empymod over and over again. | ||
|
||
Consult the following issue if you are interested in the overhead and its | ||
status: `github.com/emsig/empymod/issues/162 | ||
<https://github.com/emsig/empymod/issues/162>`_. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.