Skip to content

Commit 112d0a1

Browse files
authored
Merge pull request #243 from sbillinge/tooldoc
simon tweaks to tools example
2 parents f3be5a6 + b5ab9fe commit 112d0a1

File tree

2 files changed

+140
-38
lines changed

2 files changed

+140
-38
lines changed

Diff for: doc/source/examples/toolsexample.rst

+138-36
Original file line numberDiff line numberDiff line change
@@ -5,69 +5,171 @@
55
Tools Example
66
#############
77

8-
This example will demonstrate how diffpy.utils allows us to conveniently load and manage user and package information.
8+
The tools module contains various tools that may be useful when you manipulate and analyze diffraction data.
9+
10+
Automatically Capture User Info
11+
===============================
12+
13+
One task we would like to do is to capture and propagate useful metadata that describes the diffraction data.
14+
Some is essential such as wavelength and radiation type. Other metadata is useful such as information about the
15+
sample, co-workers and so on. However, one of the most important bits of information is the name of the data owner.
16+
For example, in ``DiffractionObjects`` this is stored in the ``metadata`` dictionary as ``username``, ``user_email``,
17+
and ``user_orcid``.
18+
19+
To reduce experimenter overhead when collecting this information, we have developed an infrastructure that helps
20+
to capture this information automatically when you are using `DiffractionObjects` and other diffpy tools.
21+
You may also reuse this infrastructure for your own projects using tools in this tutorial.
22+
23+
This example will demonstrate how ``diffpy.utils`` allows us to conveniently load and manage user and package information.
924
Using the tools module, we can efficiently get them in terms of a dictionary.
1025

11-
1) We have the function ``get_user_info`` that neatly returns a dictionary containing the username and email.
12-
You can use this function without arguments. ::
26+
Load user info into your program
27+
--------------------------------
28+
29+
To use this functionality in your own code make use of the ``get_user_info`` function in
30+
``diffpy.utils.tools`` which will search for information about the user, parse it, and return
31+
it in a dictionary object e.g. if the user is "Jane Doe" with email "[email protected]" and the
32+
function can find the information, if you type this
33+
34+
.. code-block:: python
1335
1436
from diffpy.utils.tools import get_user_info
1537
user_info = get_user_info()
1638
17-
This function will first attempt to load the information from configuration files looking first in
18-
the current working directory and then in the user's home directory.
19-
If no configuration files exist, it prompts for user input and creates a configuration file in the home directory
20-
so that the next time the program is run it will no longer have to prompt the user.
21-
It can be passed user information which overrides looking in config files, and so could be passed
22-
information that is entered through a gui or command line interface to override default information at runtime.
23-
It prioritizes prompted user inputs, then current working directory config file, and finally home directory config file.
39+
The function will return
40+
41+
.. code-block:: python
42+
43+
{"email": "[email protected]", "username": "Jane Doe"}
44+
45+
46+
Where does ``get_user_info()`` get the user information from?
47+
-------------------------------------------------------------
48+
49+
The function will first attempt to load the information from configuration files with the name ``diffpyconfig.json``
50+
on your hard-drive.
51+
It looks first for the file in the current working directory. If it cannot find it there it will look
52+
user's home, i.e., login, directory. To find this directory, open a terminal and a unix or mac system type ::
53+
54+
cd ~
55+
pwd
56+
57+
Or type ``Echo $HOME``. On a Windows computer ::
58+
59+
echo %USERPROFILE%"
60+
61+
What if no config files exist yet?
62+
-----------------------------------
63+
64+
If no configuration files can be found, the function attempts to create one in the user's home
65+
directory. The function will pause execution and ask for a user-response to enter the information.
66+
It will then write the config file in the user's home directory.
67+
68+
In this way, the next, and subsequent times the program is run, it will no longer have to prompt the user
69+
as it will successfully find the new config file.
70+
71+
Getting user data with no config files and with no interruption of execution
72+
----------------------------------------------------------------------------
73+
74+
If you would like get run ``get_user_data()`` but without execution interruption even if it cannot find
75+
an input file, type
76+
77+
.. code-block:: python
78+
79+
user_data = get_user_data(skip_config_creation=True)
80+
81+
Passing user information directly to ``get_user_data()``
82+
--------------------------------------------------------
2483

25-
The function returns a dictionary containing the username and email information.
84+
It can be passed user information which fully or partially overrides looking in config files
85+
For example, in this way it would be possible to pass in information
86+
that is entered through a gui or command line interface. E.g.,
2687

27-
2) There are a few ways you could use to override the user information in the configuration files
28-
* You can override existing values by passing a dictionary to the function with the keys ``"username"`` and ``"email"`` ::
88+
.. code-block:: python
2989
30-
new_args = {"username": "new_username", "email": "[email protected]"}
31-
new_user_info = get_user_info(new_args)
90+
new_user_info = get_user_info({"username": "new_username", "email": "[email protected]"})
3291
33-
This returns "new_username" and "[email protected]" instead of the
34-
* You can update only the username or email individually, for example ::
92+
This returns ``{"username": "new_username", "email": "[email protected]"}`` (and so, effectively, does nothing)
93+
However, You can update only the username or email individually, for example
3594

36-
new_username = {"username": new_username}
37-
new_user_info = get_user_info(new_username)
95+
.. code-block:: python
3896
39-
This updates username to "new_username" while fetching the email from inputs or the configuration files.
40-
Similarly, you can update only the email. ::
97+
new_user_info = get_user_info({"username": new_username})
4198
42-
new_email = {"email": [email protected]}
43-
new_user_info = get_user_info(new_email)
99+
will return ``{"username": "new_username", "email": "[email protected]"}``
100+
if it found ``[email protected]`` as the email in the config file.
101+
Similarly, you can update only the email in the returned dictionary,
44102

45-
This updates the email to "[email protected]" while fetching the username from inputs or the configuration files.
103+
.. code-block:: python
46104
47-
3) You can also permanently update your default configuration file manually.
48-
Locate the file ``diffpyconfig.json``, which is usually in the user's home directory (``~/.diffpy/``) or ``~/.config/diffpy/``.
49-
Open the file using a text editor such as nano, vim, or a graphical editor like VS Code.
50-
Look for entries like these ::
105+
new_user_info = get_user_info({"email": new@email.com})
106+
107+
which will return ``{"username": "Jane Doe", "email": "[email protected]"}``
108+
if it found ``Jane Doe`` as the user in the config file.
109+
110+
I entered the wrong information in my config file so it always loads incorrect information
111+
------------------------------------------------------------------------------------------
112+
113+
You can use of the above methods to temporarily override the incorrect information in your
114+
global config file. However, it is easy to fix this simply by editing that file using a text
115+
editor.
116+
117+
Locate the file ``diffpyconfig.json``, in your home directory and open it in an editor ::
51118

52119
{
53120
"username": "John Doe",
54121
"email": "[email protected]"
55122
}
56123

57-
Then you can update the username and email as needed, make sure to save your edits.
124+
Then you can edit the username and email as needed, make sure to save your edits.
125+
126+
Automatically Capture Info about a Software Package Being Used
127+
==============================================================
128+
129+
We also have a handy tool for capturing information about a python package that is being used
130+
to save in the metadata. To use this functionality, use he function ``get_package_info``, which
131+
inserts or updates software package names and versions in a given metadata dictionary under
132+
the key "package_info", e.g.,
58133

59-
4) We also have the function ``get_package_info``, which inserts or updates package names and versions
60-
in the given metadata dictionary under the key "package_info".
61-
It stores the package information as {"package_info": {"package_name": "version_number"}}.
62-
This function can be used as follows. ::
134+
.. code-block:: python
135+
136+
{"package_info": {"diffpy.utils": "0.3.0", "my_package": "0.3.1"}}
137+
138+
If the installed version of the package "my_package" is 0.3.1.
139+
140+
This function can be used in your code as follows
141+
142+
.. code-block:: python
63143
64144
from diffpy.utils.tools import get_package_info
65145
package_metadata = get_package_info("my_package")
66146
67-
You can also specify an existing dictionary to be updated with the information. ::
147+
or
148+
149+
.. code-block:: python
150+
151+
package_metadata = get_package_info(["first_package", "second_package"])
152+
153+
which returns (for example)
154+
155+
.. code-block:: python
156+
157+
{"package_info": {"diffpy.utils": "0.3.0", "first_package": "1.0.1", "second_package": "0.0.7"}}
158+
159+
160+
You can also specify an existing dictionary to be updated with the information.
161+
162+
.. code-block:: python
68163
69164
existing_dict = {"key": "value"}
70165
updated_dict = get_package_info("my_package", metadata=existing_dict))
71166
72-
note that `"diffpy.utils"` is automatically included in the package info since the `get_user_info` function is
73-
part of diffpy.utils.
167+
Which returns
168+
169+
.. code-block:: python
170+
171+
{"key": "value", "package_info": {"diffpy.utils": "0.3.0", "my_package": "0.3.1"}}
172+
173+
174+
Note that ``"diffpy.utils"`` is automatically included in the package info since the ``get_user_info`` function is
175+
part of ``diffpy.utils``.

Diff for: src/diffpy/utils/tools.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ def get_user_info(args=None):
118118
print(
119119
"No global configuration file was found containing "
120120
"information about the user to associate with the data.\n"
121-
"By following the prompts below you can add your name and email to this file on the current"
122-
" computer and your name will be automatically associated with subsequent diffpy data by default.\n"
121+
"By following the prompts below you can add your name and email to this file on the current "
122+
"computer and your name will be automatically associated with subsequent diffpy data by default.\n"
123123
"This is not recommended on a shared or public computer. "
124124
"You will only have to do that once.\n"
125125
"For more information, please refer to www.diffpy.org/diffpy.utils/examples/toolsexample.html"

0 commit comments

Comments
 (0)