pyEQL 0.5.2__py3-none-any.whl → 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. pyEQL/__init__.py +50 -43
  2. pyEQL/activity_correction.py +481 -707
  3. pyEQL/database/geothermal.dat +5693 -0
  4. pyEQL/database/llnl.dat +19305 -0
  5. pyEQL/database/phreeqc_license.txt +54 -0
  6. pyEQL/database/pyeql_db.json +35902 -0
  7. pyEQL/engines.py +793 -0
  8. pyEQL/equilibrium.py +148 -228
  9. pyEQL/functions.py +121 -416
  10. pyEQL/pint_custom_units.txt +2 -2
  11. pyEQL/presets/Ringers lactate.yaml +20 -0
  12. pyEQL/presets/normal saline.yaml +17 -0
  13. pyEQL/presets/rainwater.yaml +17 -0
  14. pyEQL/presets/seawater.yaml +29 -0
  15. pyEQL/presets/urine.yaml +26 -0
  16. pyEQL/presets/wastewater.yaml +21 -0
  17. pyEQL/salt_ion_match.py +53 -284
  18. pyEQL/solute.py +126 -191
  19. pyEQL/solution.py +2163 -2090
  20. pyEQL/utils.py +165 -0
  21. pyEQL-1.1.0.dist-info/AUTHORS.md +13 -0
  22. {pyEQL-0.5.2.dist-info → pyEQL-1.1.0.dist-info}/COPYING +1 -1
  23. pyEQL-0.5.2.dist-info/LICENSE → pyEQL-1.1.0.dist-info/LICENSE.txt +3 -7
  24. pyEQL-1.1.0.dist-info/METADATA +129 -0
  25. pyEQL-1.1.0.dist-info/RECORD +27 -0
  26. {pyEQL-0.5.2.dist-info → pyEQL-1.1.0.dist-info}/WHEEL +2 -1
  27. pyEQL/chemical_formula.py +0 -1006
  28. pyEQL/database/Erying_viscosity.tsv +0 -18
  29. pyEQL/database/Jones_Dole_B.tsv +0 -32
  30. pyEQL/database/Jones_Dole_B_inorganic_Jenkins.tsv +0 -75
  31. pyEQL/database/LICENSE +0 -4
  32. pyEQL/database/dielectric_parameter.tsv +0 -30
  33. pyEQL/database/diffusion_coefficient.tsv +0 -116
  34. pyEQL/database/hydrated_radius.tsv +0 -35
  35. pyEQL/database/ionic_radius.tsv +0 -35
  36. pyEQL/database/partial_molar_volume.tsv +0 -22
  37. pyEQL/database/pitzer_activity.tsv +0 -169
  38. pyEQL/database/pitzer_volume.tsv +0 -132
  39. pyEQL/database/template.tsv +0 -14
  40. pyEQL/database.py +0 -300
  41. pyEQL/elements.py +0 -4552
  42. pyEQL/logging_system.py +0 -53
  43. pyEQL/parameter.py +0 -435
  44. pyEQL/tests/__init__.py +0 -32
  45. pyEQL/tests/test_activity.py +0 -578
  46. pyEQL/tests/test_bulk_properties.py +0 -86
  47. pyEQL/tests/test_chemical_formula.py +0 -279
  48. pyEQL/tests/test_debye_length.py +0 -79
  49. pyEQL/tests/test_density.py +0 -106
  50. pyEQL/tests/test_dielectric.py +0 -153
  51. pyEQL/tests/test_effective_pitzer.py +0 -276
  52. pyEQL/tests/test_mixed_electrolyte_activity.py +0 -154
  53. pyEQL/tests/test_osmotic_coeff.py +0 -99
  54. pyEQL/tests/test_pyeql_volume_concentration.py +0 -428
  55. pyEQL/tests/test_salt_matching.py +0 -337
  56. pyEQL/tests/test_solute_properties.py +0 -251
  57. pyEQL/water_properties.py +0 -352
  58. pyEQL-0.5.2.dist-info/AUTHORS +0 -7
  59. pyEQL-0.5.2.dist-info/METADATA +0 -72
  60. pyEQL-0.5.2.dist-info/RECORD +0 -47
  61. pyEQL-0.5.2.dist-info/entry_points.txt +0 -3
  62. {pyEQL-0.5.2.dist-info → pyEQL-1.1.0.dist-info}/top_level.txt +0 -0
pyEQL/database.py DELETED
@@ -1,300 +0,0 @@
1
- """
2
- This module contains classes, functions, and methods for reading input files
3
- and assembling database entries for use by pyEQL.
4
-
5
- By default, pyEQL searches all files in the /database subdirectory for parameters.
6
-
7
- :copyright: 2013-2020 by Ryan S. Kingsbury
8
- :license: LGPL, see LICENSE for more details.
9
-
10
- """
11
-
12
- # logging system
13
- import logging
14
-
15
- # add a filter to emit only unique log messages to the handler
16
- from pyEQL.logging_system import Unique
17
-
18
- # for parameter creation functions
19
- import pyEQL.parameter as pm
20
-
21
- # for file input/output functions
22
- import os
23
-
24
- logger = logging.getLogger(__name__)
25
- unique = Unique()
26
- logger.addFilter(unique)
27
-
28
- # add a handler for console output, since pyEQL is meant to be used interactively
29
- ch = logging.StreamHandler()
30
-
31
- # create formatter for the log
32
- formatter = logging.Formatter("(%(name)s) - %(levelname)s - %(message)s")
33
-
34
- # add formatter to the handler
35
- ch.setFormatter(formatter)
36
- logger.addHandler(ch)
37
-
38
- # Database Management Functions
39
-
40
-
41
- class Paramsdb:
42
- """
43
- create a global dictionary to contain a dynamically-generated list of Parameters
44
- for solute species. The dictionary keys are the individual chemical species
45
- formulas. The dictionary's values are a python set object containing all parameters
46
- that apply to the species.
47
- """
48
-
49
- def __init__(self):
50
-
51
- self.parameters_database = {}
52
-
53
- # set the directory containing database files
54
- self.database_dir = [os.path.dirname(__file__) + "/database"]
55
-
56
- def add_path(self, path):
57
- """
58
- Add a user-defined directory to the database search path
59
- """
60
- self.database_dir.append(path)
61
-
62
- def list_path(self):
63
- """
64
- List all search paths for database files
65
- """
66
- for path in self.database_dir:
67
- print(path)
68
-
69
- def search_parameters(self, formula):
70
- """Each time a new solute species is created in a solution, this function:
71
-
72
- 1) searches to see whether a list of parameters for the species has already been
73
- compiled from the database
74
- 2) searches all files in the specified database directory(ies) for the species
75
- 3) creates a Parameter object for each value found
76
- 4) compiles these objects into a set
77
- 5) adds the set to a dictionary indexed by species name (formula)
78
- 6) points the new solute object to the dictionary
79
-
80
- formula : str
81
- String representing the chemical formula of the species.
82
- """
83
- # get the hill_order() and is_valid_formula() methods from the chemistry module
84
- import pyEQL.chemical_formula as chem
85
-
86
- # if the formula is already in the database, then we've already searched
87
- # and compiled parameters, so there is no need to do it again.
88
- if formula in self.parameters_database:
89
- pass
90
- else:
91
- # add an entry to the parameters database
92
- self.parameters_database[formula] = set()
93
-
94
- # search all the files in each database directory
95
- for directory in self.database_dir:
96
- for file in os.listdir(directory):
97
- # reset the line number count
98
- line_num = 0
99
-
100
- # ignore the template file
101
- if file == "template.tsv":
102
- continue
103
-
104
- # look at only .csv files
105
- if ".tsv" in file:
106
-
107
- # open each file
108
- current_file = open(directory + "/" + file, "r")
109
-
110
- # read each line of the file, looking for the formula
111
- try:
112
- for line in current_file:
113
-
114
- line_num += 1
115
-
116
- try:
117
- # look for keywords in the first column of each file. If found,
118
- # store the entry from the 2nd column
119
- if "Name" in line:
120
- param_name = _parse_line(line)[1]
121
-
122
- elif "Description" in line:
123
- param_desc = _parse_line(line)[1]
124
-
125
- elif "Unit" in line:
126
- param_unit = _parse_line(line)[1]
127
-
128
- elif "Reference" in line:
129
- param_ref = _parse_line(line)[1]
130
-
131
- elif "Temperature" in line:
132
- param_temp = _parse_line(line)[1]
133
-
134
- elif "Pressure" in line:
135
- param_press = _parse_line(line)[1]
136
-
137
- elif "Ionic Strength" in line:
138
- param_ionic = _parse_line(line)[1]
139
-
140
- elif "Comment" in line:
141
- param_comment = _parse_line(line)[1]
142
-
143
- # use the hill_order() function to standardize the
144
- # supplied formula. Then standardize teh formulas in the
145
- # database and see if they match.
146
- # this allows a database entry for 'MgCl2' to be matched
147
- # even if the user enters 'Mg(Cl)2', for example
148
- elif chem.is_valid_formula(_parse_line(line)[0]):
149
- if chem.hill_order(formula) == chem.hill_order(
150
- _parse_line(line)[0]
151
- ):
152
- # if there are multiple columns, pass the values as a list.
153
- # If a single column, then just pass the value
154
- if len(_parse_line(line)) > 2:
155
- param_value = _parse_line(line)[1:]
156
- else:
157
- param_value = _parse_line(line)[1]
158
-
159
- # Create a new parameter object
160
- parameter = pm.Parameter(
161
- param_name,
162
- param_value,
163
- param_unit,
164
- reference=param_ref,
165
- pressure=param_press,
166
- temperature=param_temp,
167
- ionic_strength=param_ionic,
168
- description=param_desc,
169
- comment=param_comment,
170
- )
171
-
172
- # Add the parameter to the set for this species
173
- self.parameters_database[formula].add(
174
- parameter
175
- )
176
-
177
- except ValueError:
178
- logger.warning(
179
- "Error encountered when reading line %s in %s"
180
- % (line_num, file)
181
- )
182
- continue
183
-
184
- # log a warning if an invalid character prevents reading a line
185
- except UnicodeDecodeError:
186
- logger.warning(
187
- "Invalid character found when reading %s. File skipped."
188
- % file
189
- )
190
-
191
- current_file.close()
192
-
193
- def has_parameter(self, formula, name):
194
- """
195
- Boolean test to determine whether a parameter exists in the database for a given species
196
- """
197
- # search the available database files if the species is not currently
198
- # in the database
199
- if self.has_species(formula) is False:
200
- self.search_parameters(formula)
201
-
202
- found = False
203
-
204
- try:
205
- for item in self.parameters_database[formula]:
206
- if item.get_name() == name:
207
- found = True
208
- else:
209
- continue
210
-
211
- return found
212
-
213
- except KeyError:
214
- logger.error("Species %s not found in database" % formula)
215
- return None
216
-
217
- def get_parameter(self, formula, name):
218
- """
219
- Retrieve a parameter from the database
220
- """
221
- found = False
222
-
223
- try:
224
- for item in self.parameters_database[formula]:
225
- if item.get_name() == name:
226
- found = True
227
- return item
228
-
229
- if not found:
230
- logger.error(
231
- "Parameter %s for species %s not found in database"
232
- % (name, formula)
233
- )
234
-
235
- except KeyError:
236
- logger.error("Species %s not found in database" % formula)
237
- return None
238
-
239
- def add_parameter(self, formula, parameter):
240
- """
241
- Add a parameter to the database
242
- """
243
- self.parameters_database[formula].add(parameter)
244
-
245
- def has_species(self, formula):
246
- """
247
- Boolean test to determine whether a species is present in the database
248
- """
249
- if formula in self.parameters_database:
250
- return True
251
- else:
252
- return False
253
-
254
- def print_database(self, solute=None):
255
- """ Function to generate a human-friendly summary of all the database parameters
256
- that are actually used in the simulation
257
-
258
- Parameters
259
- ----------
260
- solute : str, optional
261
- The chemical formula for a species. If this argument of supplied, the output
262
- will contain only the database entries for this species. Otherwise,
263
- all database entries will be printed.
264
-
265
- """
266
- if solute is not None:
267
- try:
268
- key = solute
269
- print("Parameters for species %s:" % key)
270
- print("--------------------------\n")
271
- for item in self.parameters_database[key]:
272
- print(item)
273
- except KeyError:
274
- print("Species %s not found in database." % solute)
275
- else:
276
- for key in self.parameters_database.keys():
277
- print("Parameters for species %s:" % key)
278
- print("--------------------------\n")
279
- for item in self.parameters_database[key]:
280
- print(item)
281
-
282
-
283
- def _parse_line(line):
284
- """
285
- Function to parse lines in a tab-seprated value file format.
286
-
287
- This function accepts a string (a line read from a tab-separated
288
- input file). It removes the newline character and splits the string
289
- at each tab stop, returning a list of the remaining substrings in which each
290
- list entry corresponds to the contents of one cell in the file.
291
-
292
- """
293
- # remove the newline character
294
- line = line.replace("\n", "")
295
-
296
- # separate the string at every tab stop
297
- str_list = line.split("\t")
298
-
299
- # return the list of string entries
300
- return str_list