pychnosz 1.1.11__cp312-cp312-win_amd64.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 (128) hide show
  1. pychnosz/__init__.py +129 -0
  2. pychnosz/biomolecules/__init__.py +29 -0
  3. pychnosz/biomolecules/ionize_aa.py +197 -0
  4. pychnosz/biomolecules/proteins.py +595 -0
  5. pychnosz/core/__init__.py +46 -0
  6. pychnosz/core/affinity.py +1256 -0
  7. pychnosz/core/animation.py +593 -0
  8. pychnosz/core/balance.py +334 -0
  9. pychnosz/core/basis.py +716 -0
  10. pychnosz/core/diagram.py +3336 -0
  11. pychnosz/core/equilibrate.py +813 -0
  12. pychnosz/core/equilibrium.py +554 -0
  13. pychnosz/core/info.py +821 -0
  14. pychnosz/core/retrieve.py +364 -0
  15. pychnosz/core/speciation.py +580 -0
  16. pychnosz/core/species.py +599 -0
  17. pychnosz/core/subcrt.py +1696 -0
  18. pychnosz/core/thermo.py +593 -0
  19. pychnosz/core/unicurve.py +1226 -0
  20. pychnosz/data/__init__.py +11 -0
  21. pychnosz/data/add_obigt.py +327 -0
  22. pychnosz/data/extdata/Berman/BDat17_2017.csv +2 -0
  23. pychnosz/data/extdata/Berman/Ber88_1988.csv +68 -0
  24. pychnosz/data/extdata/Berman/Ber90_1990.csv +5 -0
  25. pychnosz/data/extdata/Berman/DS10_2010.csv +6 -0
  26. pychnosz/data/extdata/Berman/FDM+14_2014.csv +2 -0
  27. pychnosz/data/extdata/Berman/Got04_2004.csv +5 -0
  28. pychnosz/data/extdata/Berman/JUN92_1992.csv +3 -0
  29. pychnosz/data/extdata/Berman/SHD91_1991.csv +12 -0
  30. pychnosz/data/extdata/Berman/VGT92_1992.csv +2 -0
  31. pychnosz/data/extdata/Berman/VPT01_2001.csv +3 -0
  32. pychnosz/data/extdata/Berman/VPV05_2005.csv +2 -0
  33. pychnosz/data/extdata/Berman/ZS92_1992.csv +11 -0
  34. pychnosz/data/extdata/Berman/sympy.R +99 -0
  35. pychnosz/data/extdata/Berman/testing/BA96.bib +12 -0
  36. pychnosz/data/extdata/Berman/testing/BA96_Berman.csv +21 -0
  37. pychnosz/data/extdata/Berman/testing/BA96_OBIGT.csv +21 -0
  38. pychnosz/data/extdata/Berman/testing/BA96_refs.csv +6 -0
  39. pychnosz/data/extdata/OBIGT/AD.csv +25 -0
  40. pychnosz/data/extdata/OBIGT/Berman_cr.csv +93 -0
  41. pychnosz/data/extdata/OBIGT/DEW.csv +211 -0
  42. pychnosz/data/extdata/OBIGT/H2O_aq.csv +4 -0
  43. pychnosz/data/extdata/OBIGT/SLOP98.csv +411 -0
  44. pychnosz/data/extdata/OBIGT/SUPCRT92.csv +178 -0
  45. pychnosz/data/extdata/OBIGT/inorganic_aq.csv +729 -0
  46. pychnosz/data/extdata/OBIGT/inorganic_cr.csv +273 -0
  47. pychnosz/data/extdata/OBIGT/inorganic_gas.csv +20 -0
  48. pychnosz/data/extdata/OBIGT/organic_aq.csv +1104 -0
  49. pychnosz/data/extdata/OBIGT/organic_cr.csv +481 -0
  50. pychnosz/data/extdata/OBIGT/organic_gas.csv +268 -0
  51. pychnosz/data/extdata/OBIGT/organic_liq.csv +533 -0
  52. pychnosz/data/extdata/OBIGT/testing/GEMSFIT.csv +43 -0
  53. pychnosz/data/extdata/OBIGT/testing/IGEM.csv +17 -0
  54. pychnosz/data/extdata/OBIGT/testing/Sandia.csv +8 -0
  55. pychnosz/data/extdata/OBIGT/testing/SiO2.csv +4 -0
  56. pychnosz/data/extdata/misc/AD03_Fig1a.csv +69 -0
  57. pychnosz/data/extdata/misc/AD03_Fig1b.csv +43 -0
  58. pychnosz/data/extdata/misc/AD03_Fig1c.csv +89 -0
  59. pychnosz/data/extdata/misc/AD03_Fig1d.csv +30 -0
  60. pychnosz/data/extdata/misc/BZA10.csv +5 -0
  61. pychnosz/data/extdata/misc/HW97_Cp.csv +90 -0
  62. pychnosz/data/extdata/misc/HWM96_V.csv +229 -0
  63. pychnosz/data/extdata/misc/LA19_test.csv +7 -0
  64. pychnosz/data/extdata/misc/Mer75_Table4.csv +42 -0
  65. pychnosz/data/extdata/misc/OBIGT_check.csv +423 -0
  66. pychnosz/data/extdata/misc/PM90.csv +7 -0
  67. pychnosz/data/extdata/misc/RH95.csv +23 -0
  68. pychnosz/data/extdata/misc/RH98_Table15.csv +17 -0
  69. pychnosz/data/extdata/misc/SC10_Rainbow.csv +19 -0
  70. pychnosz/data/extdata/misc/SK95.csv +55 -0
  71. pychnosz/data/extdata/misc/SOJSH.csv +61 -0
  72. pychnosz/data/extdata/misc/SS98_Fig5a.csv +81 -0
  73. pychnosz/data/extdata/misc/SS98_Fig5b.csv +84 -0
  74. pychnosz/data/extdata/misc/TKSS14_Fig2.csv +25 -0
  75. pychnosz/data/extdata/misc/bluered.txt +1000 -0
  76. pychnosz/data/extdata/protein/Cas/Cas_aa.csv +177 -0
  77. pychnosz/data/extdata/protein/Cas/Cas_uniprot.csv +186 -0
  78. pychnosz/data/extdata/protein/Cas/download.R +34 -0
  79. pychnosz/data/extdata/protein/Cas/mkaa.R +34 -0
  80. pychnosz/data/extdata/protein/POLG.csv +12 -0
  81. pychnosz/data/extdata/protein/TBD+05.csv +393 -0
  82. pychnosz/data/extdata/protein/TBD+05_aa.csv +393 -0
  83. pychnosz/data/extdata/protein/rubisco.csv +28 -0
  84. pychnosz/data/extdata/protein/rubisco.fasta +239 -0
  85. pychnosz/data/extdata/protein/rubisco_aa.csv +28 -0
  86. pychnosz/data/extdata/src/H2O92D.f.orig +3457 -0
  87. pychnosz/data/extdata/src/README.txt +5 -0
  88. pychnosz/data/extdata/taxonomy/names.dmp +215 -0
  89. pychnosz/data/extdata/taxonomy/nodes.dmp +63 -0
  90. pychnosz/data/extdata/thermo/Bdot_acirc.csv +60 -0
  91. pychnosz/data/extdata/thermo/buffer.csv +40 -0
  92. pychnosz/data/extdata/thermo/element.csv +135 -0
  93. pychnosz/data/extdata/thermo/groups.csv +6 -0
  94. pychnosz/data/extdata/thermo/opt.csv +2 -0
  95. pychnosz/data/extdata/thermo/protein.csv +506 -0
  96. pychnosz/data/extdata/thermo/refs.csv +343 -0
  97. pychnosz/data/extdata/thermo/stoich.csv.xz +0 -0
  98. pychnosz/data/loader.py +431 -0
  99. pychnosz/data/mod_obigt.py +322 -0
  100. pychnosz/data/obigt.py +471 -0
  101. pychnosz/data/worm.py +228 -0
  102. pychnosz/fortran/__init__.py +16 -0
  103. pychnosz/fortran/h2o92.dll +0 -0
  104. pychnosz/fortran/h2o92_interface.py +527 -0
  105. pychnosz/geochemistry/__init__.py +21 -0
  106. pychnosz/geochemistry/minerals.py +514 -0
  107. pychnosz/geochemistry/redox.py +500 -0
  108. pychnosz/models/__init__.py +47 -0
  109. pychnosz/models/archer_wang.py +165 -0
  110. pychnosz/models/berman.py +309 -0
  111. pychnosz/models/cgl.py +381 -0
  112. pychnosz/models/dew.py +997 -0
  113. pychnosz/models/hkf.py +523 -0
  114. pychnosz/models/hkf_helpers.py +231 -0
  115. pychnosz/models/iapws95.py +1113 -0
  116. pychnosz/models/supcrt92_fortran.py +238 -0
  117. pychnosz/models/water.py +480 -0
  118. pychnosz/utils/__init__.py +27 -0
  119. pychnosz/utils/expression.py +1074 -0
  120. pychnosz/utils/formula.py +830 -0
  121. pychnosz/utils/formula_ox.py +227 -0
  122. pychnosz/utils/reset.py +33 -0
  123. pychnosz/utils/units.py +259 -0
  124. pychnosz-1.1.11.dist-info/METADATA +197 -0
  125. pychnosz-1.1.11.dist-info/RECORD +128 -0
  126. pychnosz-1.1.11.dist-info/WHEEL +5 -0
  127. pychnosz-1.1.11.dist-info/licenses/LICENSE.txt +19 -0
  128. pychnosz-1.1.11.dist-info/top_level.txt +1 -0
@@ -0,0 +1,231 @@
1
+ """
2
+ Helper functions for HKF calculations, integrated from HKF_cgl.py.
3
+
4
+ This module contains the tested helper functions from the HKF_cgl.py notebook,
5
+ including calc_logK, calc_G_TP, G2logK, dissrxn2logK, and OBIGT2eos functions.
6
+ """
7
+
8
+ import pandas as pd
9
+ import numpy as np
10
+ import math
11
+ import copy
12
+ import warnings
13
+ from .hkf import hkf
14
+ from .cgl import cgl
15
+ from .water import water
16
+ from ..utils.formula import entropy
17
+
18
+ def calc_logK(OBIGT_df, Tc, P, TP_i, water_model):
19
+
20
+ OBIGT_TP, rows_added = calc_G_TP(OBIGT_df, Tc, P, water_model)
21
+
22
+ dissrxn2logK_out = []
23
+ for i in OBIGT_TP.index:
24
+ dissrxn2logK_out.append(dissrxn2logK(OBIGT_TP, i, Tc))
25
+ assert len(dissrxn2logK_out) == OBIGT_TP.shape[0]
26
+
27
+ OBIGT_TP['dissrxn_logK_'+str(TP_i)] = dissrxn2logK_out
28
+
29
+ # remove any rows added by calc_G_TP
30
+ OBIGT_TP.drop(OBIGT_TP.tail(rows_added).index, inplace = True)
31
+
32
+ return OBIGT_TP
33
+
34
+
35
+ def calc_G_TP(OBIGT, Tc, P, water_model):
36
+
37
+ aq_out, H2O_Pt = hkf(property=["G"], parameters=OBIGT,
38
+ T=273.15+Tc, P=P, contrib=["n", "s", "o"],
39
+ H2O_props=["rho"], water_model=water_model)
40
+
41
+ cgl_out = cgl(property=["G"], parameters=OBIGT, T=273.15+Tc, P=P)
42
+
43
+ aq_col = pd.DataFrame.from_dict(aq_out, orient="index")
44
+ cgl_col = pd.DataFrame.from_dict(cgl_out, orient="index")
45
+
46
+ G_TP_df = pd.concat([aq_col, cgl_col], axis=1)
47
+ G_TP_df.columns = ['aq','cgl']
48
+
49
+ OBIGT["G_TP"] = G_TP_df['aq'].combine_first(G_TP_df['cgl'])
50
+
51
+ rows_added = 0
52
+
53
+ # add a row for water
54
+ if "H2O" not in list(OBIGT["name"]):
55
+ # Set the water model (without printing messages)
56
+ water(water_model, messages=False)
57
+ # water() returns a scalar when called with single property and scalar T, P
58
+ # The result is in J/mol, need to convert to cal/mol by dividing by 4.184
59
+ G_water = water("G", T=Tc+273.15, P=P, messages=False)
60
+ # Handle both scalar and DataFrame returns
61
+ if isinstance(G_water, pd.DataFrame):
62
+ G_water_cal = G_water.iloc[0]["G"] / 4.184
63
+ else:
64
+ G_water_cal = float(G_water) / 4.184
65
+ OBIGT = pd.concat([OBIGT, pd.DataFrame({"name": "H2O", "tag": "nan", "G_TP": G_water_cal}, index=[OBIGT.shape[0]])], ignore_index=True)
66
+ rows_added += 1
67
+
68
+ # add a row for protons
69
+ if "H+" not in list(OBIGT["name"]):
70
+ OBIGT = pd.concat([OBIGT, pd.DataFrame({"name": "H+", "tag": "nan", "G_TP": 0}, index=[OBIGT.shape[0]])], ignore_index=True)
71
+ rows_added += 1
72
+
73
+ return OBIGT, rows_added
74
+
75
+
76
+
77
+ def _extract_scalar(val):
78
+ """
79
+ Extract Python scalar from pandas/numpy value.
80
+ Handles numpy scalars, 0-d arrays, and Python scalars.
81
+ """
82
+ return val.item() if hasattr(val, 'item') else val
83
+
84
+
85
+ def G2logK(G, Tc):
86
+ # Gas constant R is in cal/mol K
87
+ return G / (-math.log(10) * 1.9872 * (273.15+Tc))
88
+
89
+
90
+ def dissrxn2logK(OBIGT, i, Tc):
91
+
92
+ this_dissrxn = OBIGT.iloc[i, OBIGT.columns.get_loc('dissrxn')]
93
+
94
+ if this_dissrxn == "nan":
95
+ this_dissrxn = OBIGT.iloc[i, OBIGT.columns.get_loc('regenerate_dissrxn')]
96
+
97
+ # print(OBIGT["name"][i], this_dissrxn)
98
+
99
+ try:
100
+ this_dissrxn = this_dissrxn.strip()
101
+ split_dissrxn = this_dissrxn.split(" ")
102
+ except:
103
+ return float('NaN')
104
+
105
+
106
+
107
+ coeff = [float(n) for n in split_dissrxn[::2]]
108
+ species = split_dissrxn[1::2]
109
+ try:
110
+ G = sum([c * _extract_scalar(OBIGT.loc[OBIGT["name"]==sp, "G_TP"].values[0]) for c,sp in zip(coeff, species)])
111
+ except:
112
+ G_list = []
113
+ for ii, sp in enumerate(species):
114
+ G_TP = OBIGT.loc[OBIGT["name"]==sp, "G_TP"]
115
+ if len(G_TP) == 1:
116
+ G_list.append(coeff[ii] * _extract_scalar(OBIGT.loc[OBIGT["name"]==sp, "G_TP"].values[0]))
117
+ else:
118
+ ### check valid polymorph T
119
+
120
+ # get polymorph entries of OBIGT that match mineral
121
+ poly_df = copy.copy(OBIGT.loc[OBIGT["name"]==sp,:])
122
+ # ensure polymorph df is sorted according to cr, cr2, cr3... etc.
123
+ poly_df = poly_df.sort_values("state")
124
+
125
+ z_Ts = list(poly_df.loc[poly_df["name"]==sp, "z.T"])
126
+
127
+ last_t = float('-inf')
128
+ appended=False
129
+ for iii,t in enumerate(z_Ts):
130
+
131
+ if Tc+273.15 > last_t and Tc+273.15 < t:
132
+ G_list.append(coeff[ii] * _extract_scalar(poly_df.loc[poly_df["name"]==sp, "G_TP"].values[iii]))
133
+ appended=True
134
+ if not appended and z_Ts[-1] == t:
135
+ G_list.append(coeff[ii] * _extract_scalar(poly_df.loc[poly_df["name"]==sp, "G_TP"].values[iii]))
136
+ last_t = t
137
+
138
+ G = sum(G_list)
139
+
140
+ return G2logK(G, Tc)
141
+
142
+
143
+ def convert_cm3bar(value):
144
+ return value*4.184 * 10
145
+
146
+
147
+ def OBIGT2eos(OBIGT, fixGHS=True, tocal=True, messages=True):
148
+ """
149
+ Convert OBIGT dataframe to equation of state parameters.
150
+
151
+ This function processes the OBIGT thermodynamic database to prepare it for
152
+ equation of state calculations. It handles energy unit conversions and
153
+ optionally fills in missing G, H, or S values.
154
+
155
+ Parameters
156
+ ----------
157
+ OBIGT : pd.DataFrame
158
+ OBIGT thermodynamic database
159
+ fixGHS : bool, default True
160
+ Fill in one missing value among G, H, S using thermodynamic relations
161
+ tocal : bool, default True
162
+ Convert energy units from Joules to calories
163
+ messages : bool, default True
164
+ Print informational messages (currently not used, reserved for future)
165
+
166
+ Returns
167
+ -------
168
+ pd.DataFrame
169
+ Modified OBIGT dataframe with converted parameters
170
+ """
171
+ OBIGT_out = OBIGT.copy()
172
+
173
+ # Get column indices for named columns (to handle varying column positions)
174
+ G_idx = OBIGT.columns.get_loc('G')
175
+ H_idx = OBIGT.columns.get_loc('H')
176
+ S_idx = OBIGT.columns.get_loc('S')
177
+ Cp_idx = OBIGT.columns.get_loc('Cp')
178
+ V_idx = OBIGT.columns.get_loc('V')
179
+ omega_lambda_idx = OBIGT.columns.get_loc('omega.lambda')
180
+
181
+ for i in range(0, OBIGT.shape[0]):
182
+
183
+ # we only convert omega for aqueous species, not lambda for cgl species
184
+ if tocal and OBIGT.iloc[i, :]["E_units"] == "J" and OBIGT.iloc[i, :]["state"] == "aq":
185
+ # Convert G, H, S, Cp
186
+ OBIGT_out.iloc[i, G_idx:Cp_idx+1] = OBIGT.iloc[i, G_idx:Cp_idx+1]/4.184
187
+ # Convert V through omega (includes omega for aq species)
188
+ OBIGT_out.iloc[i, V_idx:omega_lambda_idx+1] = OBIGT.iloc[i, V_idx:omega_lambda_idx+1]/4.184
189
+ OBIGT_out.iloc[i, OBIGT.columns.get_loc('E_units')] = "cal"
190
+
191
+ elif tocal and OBIGT.iloc[i, :]["E_units"] == "J":
192
+ # Convert G, H, S, Cp
193
+ OBIGT_out.iloc[i, G_idx:Cp_idx+1] = OBIGT.iloc[i, G_idx:Cp_idx+1]/4.184
194
+ # Convert V through c2.f (exclude omega.lambda for non-aq species)
195
+ OBIGT_out.iloc[i, V_idx:omega_lambda_idx] = OBIGT.iloc[i, V_idx:omega_lambda_idx]/4.184
196
+ OBIGT_out.iloc[i, OBIGT.columns.get_loc('E_units')] = "cal"
197
+
198
+ # fill in one of missing G, H, S
199
+ # for use esp. by subcrt because NA for one of G, H or S
200
+ # will preclude calculations at high T
201
+ if fixGHS:
202
+ # which entries are missing just one
203
+ GHS_values = [OBIGT.iloc[i, G_idx], OBIGT.iloc[i, H_idx], OBIGT.iloc[i, S_idx]]
204
+ imiss = [pd.isna(v) for v in GHS_values]
205
+ if sum(imiss) == 1:
206
+
207
+ ii = imiss.index(True)
208
+
209
+ if ii == 0: # G is missing
210
+ H = OBIGT_out.iloc[i, H_idx]
211
+ S = OBIGT_out.iloc[i, S_idx]
212
+ Selem = entropy(OBIGT_out.iloc[i, OBIGT_out.columns.get_loc('formula')])
213
+ T = 298.15
214
+ G = H - T*(S - Selem)
215
+ OBIGT_out.iloc[i, G_idx] = G
216
+ elif ii == 1: # H is missing
217
+ G = OBIGT_out.iloc[i, G_idx]
218
+ S = OBIGT_out.iloc[i, S_idx]
219
+ Selem = entropy(OBIGT_out.iloc[i, OBIGT_out.columns.get_loc('formula')])
220
+ T = 298.15
221
+ H = G + T*(S - Selem)
222
+ OBIGT_out.iloc[i, H_idx] = H
223
+ elif ii == 2: # S is missing
224
+ G = OBIGT_out.iloc[i, G_idx]
225
+ H = OBIGT_out.iloc[i, H_idx]
226
+ Selem = entropy(OBIGT_out.iloc[i, OBIGT_out.columns.get_loc('formula')])
227
+ T = 298.15
228
+ S = Selem + (H - G)/T
229
+ OBIGT_out.iloc[i, S_idx] = S
230
+
231
+ return OBIGT_out