|
5 | 5 | Tools Example
|
6 | 6 | #############
|
7 | 7 |
|
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. |
9 | 24 | Using the tools module, we can efficiently get them in terms of a dictionary.
|
10 | 25 |
|
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 |
13 | 35 |
|
14 | 36 | from diffpy.utils.tools import get_user_info
|
15 | 37 | user_info = get_user_info()
|
16 | 38 |
|
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 | +-------------------------------------------------------- |
24 | 83 |
|
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., |
26 | 87 |
|
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 |
29 | 89 |
|
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]"}) |
32 | 91 |
|
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 |
35 | 94 |
|
36 |
| - new_username = {"username": new_username} |
37 |
| - new_user_info = get_user_info(new_username) |
| 95 | +.. code-block:: python |
38 | 96 |
|
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}) |
41 | 98 |
|
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, |
44 | 102 |
|
45 |
| - This updates the email to "[email protected]" while fetching the username from inputs or the configuration files. |
| 103 | +.. code-block:: python |
46 | 104 |
|
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 :: |
51 | 118 |
|
52 | 119 | {
|
53 | 120 | "username": "John Doe",
|
54 | 121 |
|
55 | 122 | }
|
56 | 123 |
|
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., |
58 | 133 |
|
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 |
63 | 143 |
|
64 | 144 | from diffpy.utils.tools import get_package_info
|
65 | 145 | package_metadata = get_package_info("my_package")
|
66 | 146 |
|
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 |
68 | 163 |
|
69 | 164 | existing_dict = {"key": "value"}
|
70 | 165 | updated_dict = get_package_info("my_package", metadata=existing_dict))
|
71 | 166 |
|
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``. |
0 commit comments