pychnosz 1.1.1__cp310-cp310-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.
- pychnosz/__init__.py +129 -0
- pychnosz/biomolecules/__init__.py +29 -0
- pychnosz/biomolecules/ionize_aa.py +197 -0
- pychnosz/biomolecules/proteins.py +595 -0
- pychnosz/core/__init__.py +46 -0
- pychnosz/core/affinity.py +1256 -0
- pychnosz/core/animation.py +593 -0
- pychnosz/core/balance.py +334 -0
- pychnosz/core/basis.py +716 -0
- pychnosz/core/diagram.py +3336 -0
- pychnosz/core/equilibrate.py +813 -0
- pychnosz/core/equilibrium.py +554 -0
- pychnosz/core/info.py +821 -0
- pychnosz/core/retrieve.py +364 -0
- pychnosz/core/speciation.py +580 -0
- pychnosz/core/species.py +599 -0
- pychnosz/core/subcrt.py +1700 -0
- pychnosz/core/thermo.py +593 -0
- pychnosz/core/unicurve.py +1226 -0
- pychnosz/data/__init__.py +11 -0
- pychnosz/data/add_obigt.py +327 -0
- pychnosz/data/extdata/Berman/BDat17_2017.csv +2 -0
- pychnosz/data/extdata/Berman/Ber88_1988.csv +68 -0
- pychnosz/data/extdata/Berman/Ber90_1990.csv +5 -0
- pychnosz/data/extdata/Berman/DS10_2010.csv +6 -0
- pychnosz/data/extdata/Berman/FDM+14_2014.csv +2 -0
- pychnosz/data/extdata/Berman/Got04_2004.csv +5 -0
- pychnosz/data/extdata/Berman/JUN92_1992.csv +3 -0
- pychnosz/data/extdata/Berman/SHD91_1991.csv +12 -0
- pychnosz/data/extdata/Berman/VGT92_1992.csv +2 -0
- pychnosz/data/extdata/Berman/VPT01_2001.csv +3 -0
- pychnosz/data/extdata/Berman/VPV05_2005.csv +2 -0
- pychnosz/data/extdata/Berman/ZS92_1992.csv +11 -0
- pychnosz/data/extdata/Berman/sympy.R +99 -0
- pychnosz/data/extdata/Berman/testing/BA96.bib +12 -0
- pychnosz/data/extdata/Berman/testing/BA96_Berman.csv +21 -0
- pychnosz/data/extdata/Berman/testing/BA96_OBIGT.csv +21 -0
- pychnosz/data/extdata/Berman/testing/BA96_refs.csv +6 -0
- pychnosz/data/extdata/OBIGT/AD.csv +25 -0
- pychnosz/data/extdata/OBIGT/Berman_cr.csv +93 -0
- pychnosz/data/extdata/OBIGT/DEW.csv +211 -0
- pychnosz/data/extdata/OBIGT/H2O_aq.csv +4 -0
- pychnosz/data/extdata/OBIGT/SLOP98.csv +411 -0
- pychnosz/data/extdata/OBIGT/SUPCRT92.csv +178 -0
- pychnosz/data/extdata/OBIGT/inorganic_aq.csv +729 -0
- pychnosz/data/extdata/OBIGT/inorganic_cr.csv +273 -0
- pychnosz/data/extdata/OBIGT/inorganic_gas.csv +20 -0
- pychnosz/data/extdata/OBIGT/organic_aq.csv +1104 -0
- pychnosz/data/extdata/OBIGT/organic_cr.csv +481 -0
- pychnosz/data/extdata/OBIGT/organic_gas.csv +268 -0
- pychnosz/data/extdata/OBIGT/organic_liq.csv +533 -0
- pychnosz/data/extdata/OBIGT/testing/GEMSFIT.csv +43 -0
- pychnosz/data/extdata/OBIGT/testing/IGEM.csv +17 -0
- pychnosz/data/extdata/OBIGT/testing/Sandia.csv +8 -0
- pychnosz/data/extdata/OBIGT/testing/SiO2.csv +4 -0
- pychnosz/data/extdata/misc/AD03_Fig1a.csv +69 -0
- pychnosz/data/extdata/misc/AD03_Fig1b.csv +43 -0
- pychnosz/data/extdata/misc/AD03_Fig1c.csv +89 -0
- pychnosz/data/extdata/misc/AD03_Fig1d.csv +30 -0
- pychnosz/data/extdata/misc/BZA10.csv +5 -0
- pychnosz/data/extdata/misc/HW97_Cp.csv +90 -0
- pychnosz/data/extdata/misc/HWM96_V.csv +229 -0
- pychnosz/data/extdata/misc/LA19_test.csv +7 -0
- pychnosz/data/extdata/misc/Mer75_Table4.csv +42 -0
- pychnosz/data/extdata/misc/OBIGT_check.csv +423 -0
- pychnosz/data/extdata/misc/PM90.csv +7 -0
- pychnosz/data/extdata/misc/RH95.csv +23 -0
- pychnosz/data/extdata/misc/RH98_Table15.csv +17 -0
- pychnosz/data/extdata/misc/SC10_Rainbow.csv +19 -0
- pychnosz/data/extdata/misc/SK95.csv +55 -0
- pychnosz/data/extdata/misc/SOJSH.csv +61 -0
- pychnosz/data/extdata/misc/SS98_Fig5a.csv +81 -0
- pychnosz/data/extdata/misc/SS98_Fig5b.csv +84 -0
- pychnosz/data/extdata/misc/TKSS14_Fig2.csv +25 -0
- pychnosz/data/extdata/misc/bluered.txt +1000 -0
- pychnosz/data/extdata/protein/Cas/Cas_aa.csv +177 -0
- pychnosz/data/extdata/protein/Cas/Cas_uniprot.csv +186 -0
- pychnosz/data/extdata/protein/Cas/download.R +34 -0
- pychnosz/data/extdata/protein/Cas/mkaa.R +34 -0
- pychnosz/data/extdata/protein/POLG.csv +12 -0
- pychnosz/data/extdata/protein/TBD+05.csv +393 -0
- pychnosz/data/extdata/protein/TBD+05_aa.csv +393 -0
- pychnosz/data/extdata/protein/rubisco.csv +28 -0
- pychnosz/data/extdata/protein/rubisco.fasta +239 -0
- pychnosz/data/extdata/protein/rubisco_aa.csv +28 -0
- pychnosz/data/extdata/src/H2O92D.f.orig +3457 -0
- pychnosz/data/extdata/src/README.txt +5 -0
- pychnosz/data/extdata/taxonomy/names.dmp +215 -0
- pychnosz/data/extdata/taxonomy/nodes.dmp +63 -0
- pychnosz/data/extdata/thermo/Bdot_acirc.csv +60 -0
- pychnosz/data/extdata/thermo/buffer.csv +40 -0
- pychnosz/data/extdata/thermo/element.csv +135 -0
- pychnosz/data/extdata/thermo/groups.csv +6 -0
- pychnosz/data/extdata/thermo/opt.csv +2 -0
- pychnosz/data/extdata/thermo/protein.csv +506 -0
- pychnosz/data/extdata/thermo/refs.csv +343 -0
- pychnosz/data/extdata/thermo/stoich.csv.xz +0 -0
- pychnosz/data/loader.py +431 -0
- pychnosz/data/mod_obigt.py +322 -0
- pychnosz/data/obigt.py +471 -0
- pychnosz/data/worm.py +228 -0
- pychnosz/fortran/__init__.py +16 -0
- pychnosz/fortran/h2o92.dll +0 -0
- pychnosz/fortran/h2o92_interface.py +527 -0
- pychnosz/geochemistry/__init__.py +21 -0
- pychnosz/geochemistry/minerals.py +514 -0
- pychnosz/geochemistry/redox.py +500 -0
- pychnosz/models/__init__.py +47 -0
- pychnosz/models/archer_wang.py +165 -0
- pychnosz/models/berman.py +309 -0
- pychnosz/models/cgl.py +381 -0
- pychnosz/models/dew.py +997 -0
- pychnosz/models/hkf.py +523 -0
- pychnosz/models/hkf_helpers.py +222 -0
- pychnosz/models/iapws95.py +1113 -0
- pychnosz/models/supcrt92_fortran.py +238 -0
- pychnosz/models/water.py +480 -0
- pychnosz/utils/__init__.py +27 -0
- pychnosz/utils/expression.py +1074 -0
- pychnosz/utils/formula.py +830 -0
- pychnosz/utils/formula_ox.py +227 -0
- pychnosz/utils/reset.py +33 -0
- pychnosz/utils/units.py +259 -0
- pychnosz-1.1.1.dist-info/METADATA +197 -0
- pychnosz-1.1.1.dist-info/RECORD +128 -0
- pychnosz-1.1.1.dist-info/WHEEL +5 -0
- pychnosz-1.1.1.dist-info/licenses/LICENSE.txt +19 -0
- pychnosz-1.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Implementation of mod_OBIGT() function for Python CHNOSZ.
|
|
3
|
+
|
|
4
|
+
This function modifies or adds entries to the thermodynamic database,
|
|
5
|
+
mimicking the behavior of R CHNOSZ mod.OBIGT() function.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pandas as pd
|
|
9
|
+
import numpy as np
|
|
10
|
+
from typing import Union, List, Dict, Any, Optional
|
|
11
|
+
import warnings
|
|
12
|
+
|
|
13
|
+
from ..core.thermo import thermo
|
|
14
|
+
from ..core.info import info
|
|
15
|
+
from ..utils.formula import makeup
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def mod_OBIGT(*args, zap: bool = False, **kwargs) -> Union[int, List[int]]:
|
|
19
|
+
"""
|
|
20
|
+
Add or modify species in the thermodynamic database.
|
|
21
|
+
|
|
22
|
+
This function replicates the behavior of R CHNOSZ mod.OBIGT() by allowing
|
|
23
|
+
modification of existing species or addition of new species to thermo().obigt.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
*args : int, str, list, or dict
|
|
28
|
+
If first argument is numeric: species index or indices to modify
|
|
29
|
+
If first argument is str: species name(s) to modify or add
|
|
30
|
+
If first argument is list/dict: contains all parameters
|
|
31
|
+
zap : bool, default False
|
|
32
|
+
If True, clear all properties except state and model before updating
|
|
33
|
+
**kwargs : any
|
|
34
|
+
Named properties to set (e.g., G=-100, S=50, formula="H2O")
|
|
35
|
+
Special properties: name, state, formula, model, E_units
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
int or list of int
|
|
40
|
+
Species index or indices that were modified/added
|
|
41
|
+
|
|
42
|
+
Examples
|
|
43
|
+
--------
|
|
44
|
+
>>> import pychnosz
|
|
45
|
+
>>> pychnosz.reset()
|
|
46
|
+
>>> # Add new species
|
|
47
|
+
>>> i = pychnosz.mod_OBIGT("myspecies", formula="C2H6", G=-100, S=50)
|
|
48
|
+
|
|
49
|
+
>>> # Modify existing species
|
|
50
|
+
>>> i = pychnosz.mod_OBIGT("water", state="liq", G=-56690)
|
|
51
|
+
|
|
52
|
+
>>> # Modify by index
|
|
53
|
+
>>> i_h2o = pychnosz.info("water", "liq")
|
|
54
|
+
>>> i = pychnosz.mod_OBIGT(i_h2o, G=-56690)
|
|
55
|
+
|
|
56
|
+
>>> # Add multiple species
|
|
57
|
+
>>> i = pychnosz.mod_OBIGT(["X", "Y"], formula=["C12", "C13"], state=["aq", "cr"])
|
|
58
|
+
|
|
59
|
+
Notes
|
|
60
|
+
-----
|
|
61
|
+
This function modifies the thermo() object in place.
|
|
62
|
+
The behavior exactly matches R CHNOSZ mod.OBIGT().
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
# Get the thermo system
|
|
66
|
+
thermo_sys = thermo()
|
|
67
|
+
|
|
68
|
+
# Ensure the thermodynamic system is initialized
|
|
69
|
+
if not thermo_sys.is_initialized() or thermo_sys.obigt is None:
|
|
70
|
+
raise RuntimeError("Thermodynamic system not initialized. Run reset() first.")
|
|
71
|
+
|
|
72
|
+
# Process arguments
|
|
73
|
+
# If called with a dict as first arg (like R's list)
|
|
74
|
+
if len(args) == 1 and isinstance(args[0], dict):
|
|
75
|
+
params = args[0].copy()
|
|
76
|
+
elif len(args) > 0:
|
|
77
|
+
# First positional argument could be species index or name
|
|
78
|
+
first_arg = args[0]
|
|
79
|
+
params = kwargs.copy()
|
|
80
|
+
|
|
81
|
+
# Check if first argument is numeric (species index/indices)
|
|
82
|
+
if isinstance(first_arg, (int, np.integer)):
|
|
83
|
+
params['_index'] = first_arg
|
|
84
|
+
elif isinstance(first_arg, (list, tuple)) and len(first_arg) > 0:
|
|
85
|
+
if isinstance(first_arg[0], (int, np.integer)):
|
|
86
|
+
params['_index'] = list(first_arg)
|
|
87
|
+
else:
|
|
88
|
+
# First arg is list of names
|
|
89
|
+
params['name'] = list(first_arg)
|
|
90
|
+
else:
|
|
91
|
+
# First arg is species name
|
|
92
|
+
# If first arg name is not in kwargs, it's the species name
|
|
93
|
+
if 'name' not in params:
|
|
94
|
+
params['name'] = first_arg
|
|
95
|
+
else:
|
|
96
|
+
params = kwargs.copy()
|
|
97
|
+
|
|
98
|
+
# Validate we have at least a name/index and one property
|
|
99
|
+
if '_index' not in params and 'name' not in params:
|
|
100
|
+
raise ValueError("Please supply at least a species name and a property to update")
|
|
101
|
+
|
|
102
|
+
# Check that we have at least one property
|
|
103
|
+
# When using index: exclude _index and state from property count
|
|
104
|
+
# When using name: exclude name and state from property count (name is identifier, not property)
|
|
105
|
+
if '_index' in params:
|
|
106
|
+
property_keys = set(params.keys()) - {'_index', 'state'}
|
|
107
|
+
else:
|
|
108
|
+
property_keys = set(params.keys()) - {'name', 'state'}
|
|
109
|
+
|
|
110
|
+
if len(property_keys) == 0:
|
|
111
|
+
raise ValueError("Please supply at least a species name and a property to update")
|
|
112
|
+
|
|
113
|
+
# Get species indices
|
|
114
|
+
if '_index' in params:
|
|
115
|
+
# Working with indices
|
|
116
|
+
ispecies_input = params['_index']
|
|
117
|
+
if not isinstance(ispecies_input, list):
|
|
118
|
+
ispecies_input = [ispecies_input]
|
|
119
|
+
del params['_index']
|
|
120
|
+
|
|
121
|
+
# Get species names from indices
|
|
122
|
+
speciesname = []
|
|
123
|
+
for idx in ispecies_input:
|
|
124
|
+
sp_info = info(idx)
|
|
125
|
+
speciesname.append(sp_info['name'].iloc[0] if isinstance(sp_info, pd.DataFrame) else sp_info['name'])
|
|
126
|
+
|
|
127
|
+
ispecies = ispecies_input
|
|
128
|
+
else:
|
|
129
|
+
# Working with names
|
|
130
|
+
names = params.get('name')
|
|
131
|
+
if not isinstance(names, list):
|
|
132
|
+
names = [names]
|
|
133
|
+
|
|
134
|
+
states = params.get('state')
|
|
135
|
+
if states is not None and not isinstance(states, list):
|
|
136
|
+
states = [states]
|
|
137
|
+
|
|
138
|
+
speciesname = names
|
|
139
|
+
|
|
140
|
+
# Find species indices
|
|
141
|
+
ispecies = []
|
|
142
|
+
for i, name in enumerate(names):
|
|
143
|
+
state = states[i] if states and i < len(states) else None
|
|
144
|
+
try:
|
|
145
|
+
if state:
|
|
146
|
+
idx = info(name, state)
|
|
147
|
+
else:
|
|
148
|
+
idx = info(name)
|
|
149
|
+
|
|
150
|
+
# info() returns an int if found
|
|
151
|
+
if isinstance(idx, (int, np.integer)):
|
|
152
|
+
ispecies.append(int(idx))
|
|
153
|
+
else:
|
|
154
|
+
# Not found
|
|
155
|
+
ispecies.append(None)
|
|
156
|
+
except:
|
|
157
|
+
# Species doesn't exist - will be added
|
|
158
|
+
ispecies.append(None)
|
|
159
|
+
|
|
160
|
+
# Convert params to DataFrame format
|
|
161
|
+
# Handle list values vs single values
|
|
162
|
+
nspecies = len(ispecies)
|
|
163
|
+
param_df = {}
|
|
164
|
+
for key, value in params.items():
|
|
165
|
+
if isinstance(value, list):
|
|
166
|
+
if len(value) != nspecies:
|
|
167
|
+
raise ValueError(f"Length of '{key}' ({len(value)}) doesn't match number of species ({nspecies})")
|
|
168
|
+
param_df[key] = value
|
|
169
|
+
else:
|
|
170
|
+
param_df[key] = [value] * nspecies
|
|
171
|
+
|
|
172
|
+
# Create DataFrame of arguments
|
|
173
|
+
args_df = pd.DataFrame(param_df)
|
|
174
|
+
|
|
175
|
+
# Get column names of OBIGT (handle split names with ".")
|
|
176
|
+
obigt_cols = thermo_sys.obigt.columns.tolist()
|
|
177
|
+
|
|
178
|
+
# Map parameter names to column names (handle dot notation)
|
|
179
|
+
# e.g., "E.units" can be accessed as "E_units"
|
|
180
|
+
col_mapping = {}
|
|
181
|
+
for col in obigt_cols:
|
|
182
|
+
col_mapping[col] = col
|
|
183
|
+
col_mapping[col.replace('_', '.')] = col
|
|
184
|
+
# Also map first part before dot
|
|
185
|
+
if '_' in col:
|
|
186
|
+
col_mapping[col.split('_')[0]] = col
|
|
187
|
+
|
|
188
|
+
# Determine which columns we're updating
|
|
189
|
+
icol = []
|
|
190
|
+
icol_names = []
|
|
191
|
+
for key in args_df.columns:
|
|
192
|
+
if key in col_mapping:
|
|
193
|
+
icol_names.append(col_mapping[key])
|
|
194
|
+
icol.append(obigt_cols.index(col_mapping[key]))
|
|
195
|
+
else:
|
|
196
|
+
raise ValueError(f"Property '{key}' not in thermo$OBIGT")
|
|
197
|
+
|
|
198
|
+
# Separate new species from existing ones
|
|
199
|
+
inew = [i for i, idx in enumerate(ispecies) if idx is None]
|
|
200
|
+
iold = [i for i, idx in enumerate(ispecies) if idx is not None]
|
|
201
|
+
|
|
202
|
+
result_indices = []
|
|
203
|
+
|
|
204
|
+
# Add new species
|
|
205
|
+
if len(inew) > 0:
|
|
206
|
+
# Create blank rows
|
|
207
|
+
newrows = pd.DataFrame(index=range(len(inew)), columns=obigt_cols)
|
|
208
|
+
newrows[:] = np.nan
|
|
209
|
+
|
|
210
|
+
# Set defaults
|
|
211
|
+
default_state = thermo_sys.opt.get('state', 'aq')
|
|
212
|
+
default_units = thermo_sys.opt.get('E.units', 'J')
|
|
213
|
+
|
|
214
|
+
newrows['state'] = default_state
|
|
215
|
+
newrows['E_units'] = default_units
|
|
216
|
+
|
|
217
|
+
# Set formula from name if not provided
|
|
218
|
+
for i, idx in enumerate(inew):
|
|
219
|
+
if 'formula' in args_df.columns:
|
|
220
|
+
newrows.at[i, 'formula'] = args_df.iloc[idx]['formula']
|
|
221
|
+
else:
|
|
222
|
+
newrows.at[i, 'formula'] = args_df.iloc[idx]['name']
|
|
223
|
+
|
|
224
|
+
# Fill in provided columns
|
|
225
|
+
for i, idx in enumerate(inew):
|
|
226
|
+
for col_name in icol_names:
|
|
227
|
+
if col_name in args_df.columns:
|
|
228
|
+
newrows.at[i, col_name] = args_df.at[idx, col_name]
|
|
229
|
+
|
|
230
|
+
# Guess model from state
|
|
231
|
+
for i in range(len(newrows)):
|
|
232
|
+
if pd.isna(newrows.iloc[i]['model']):
|
|
233
|
+
if newrows.iloc[i]['state'] == 'aq':
|
|
234
|
+
newrows.at[i, 'model'] = 'HKF'
|
|
235
|
+
else:
|
|
236
|
+
newrows.at[i, 'model'] = 'CGL'
|
|
237
|
+
|
|
238
|
+
# Validate formulas
|
|
239
|
+
for i in range(len(newrows)):
|
|
240
|
+
formula = newrows.iloc[i]['formula']
|
|
241
|
+
try:
|
|
242
|
+
makeup(formula)
|
|
243
|
+
except Exception as e:
|
|
244
|
+
warnings.warn("Please supply a valid chemical formula as the species name or in the 'formula' argument")
|
|
245
|
+
raise e
|
|
246
|
+
|
|
247
|
+
# Add to OBIGT
|
|
248
|
+
ntotal_before = len(thermo_sys.obigt)
|
|
249
|
+
thermo_sys.obigt = pd.concat([thermo_sys.obigt, newrows], ignore_index=True)
|
|
250
|
+
|
|
251
|
+
# Reset index to 1-based
|
|
252
|
+
thermo_sys.obigt.index = range(1, len(thermo_sys.obigt) + 1)
|
|
253
|
+
|
|
254
|
+
# Update ispecies for new entries
|
|
255
|
+
for i, idx in enumerate(inew):
|
|
256
|
+
new_idx = ntotal_before + i + 1
|
|
257
|
+
if idx < len(ispecies):
|
|
258
|
+
ispecies[idx] = new_idx
|
|
259
|
+
result_indices.append(new_idx)
|
|
260
|
+
|
|
261
|
+
# Print message
|
|
262
|
+
name = newrows.iloc[i]['name']
|
|
263
|
+
state = newrows.iloc[i]['state']
|
|
264
|
+
model = newrows.iloc[i]['model']
|
|
265
|
+
e_units = newrows.iloc[i]['E_units']
|
|
266
|
+
print(f"mod_OBIGT: added {name}({state}) with {model} model and energy units of {e_units}")
|
|
267
|
+
|
|
268
|
+
# Modify existing species
|
|
269
|
+
if len(iold) > 0:
|
|
270
|
+
for i in iold:
|
|
271
|
+
idx = ispecies[i]
|
|
272
|
+
|
|
273
|
+
# Get old values
|
|
274
|
+
oldprop = thermo_sys.obigt.loc[idx, icol_names].copy()
|
|
275
|
+
state = thermo_sys.obigt.loc[idx, 'state']
|
|
276
|
+
model = thermo_sys.obigt.loc[idx, 'model']
|
|
277
|
+
|
|
278
|
+
# If zap, clear all values except state and model
|
|
279
|
+
if zap:
|
|
280
|
+
thermo_sys.obigt.loc[idx, :] = np.nan
|
|
281
|
+
thermo_sys.obigt.loc[idx, 'state'] = state
|
|
282
|
+
thermo_sys.obigt.loc[idx, 'model'] = model
|
|
283
|
+
|
|
284
|
+
# Get new properties
|
|
285
|
+
newprop = args_df.iloc[i][icol_names].copy()
|
|
286
|
+
|
|
287
|
+
# Check if there's any change
|
|
288
|
+
# Compare values element-wise, treating NaN as equal to NaN
|
|
289
|
+
has_change = False
|
|
290
|
+
for col in icol_names:
|
|
291
|
+
old_val = oldprop[col] if col in oldprop.index else np.nan
|
|
292
|
+
new_val = newprop[col] if col in newprop.index else np.nan
|
|
293
|
+
|
|
294
|
+
# Check if both are NaN
|
|
295
|
+
if pd.isna(old_val) and pd.isna(new_val):
|
|
296
|
+
continue
|
|
297
|
+
# Check if one is NaN and other is not
|
|
298
|
+
elif pd.isna(old_val) or pd.isna(new_val):
|
|
299
|
+
has_change = True
|
|
300
|
+
break
|
|
301
|
+
# Check if values are different
|
|
302
|
+
elif old_val != new_val:
|
|
303
|
+
has_change = True
|
|
304
|
+
break
|
|
305
|
+
|
|
306
|
+
if not has_change:
|
|
307
|
+
# No change
|
|
308
|
+
print(f"mod_OBIGT: no change for {speciesname[i]}({state})")
|
|
309
|
+
else:
|
|
310
|
+
# Update the data
|
|
311
|
+
for col_name in icol_names:
|
|
312
|
+
if col_name in args_df.columns:
|
|
313
|
+
thermo_sys.obigt.loc[idx, col_name] = args_df.iloc[i][col_name]
|
|
314
|
+
|
|
315
|
+
print(f"mod_OBIGT: updated {speciesname[i]}({state})")
|
|
316
|
+
|
|
317
|
+
result_indices.append(idx)
|
|
318
|
+
|
|
319
|
+
# Return indices
|
|
320
|
+
if len(result_indices) == 1:
|
|
321
|
+
return result_indices[0]
|
|
322
|
+
return result_indices
|