Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F66395446
database.pyx
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Jun 10, 06:25
Size
9 KB
Mime Type
text/x-python
Expires
Wed, Jun 12, 06:25 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
18216463
Attached To
rSPECMICP SpecMiCP / ReactMiCP
database.pyx
View Options
# Copyright (c) 2014,2015 Fabien Georget <fabieng@princeton.edu>, Princeton University
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of SpecMiCP nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from
libcpp.map
cimport
map
as
cmap
from
libcpp.pair
cimport
pair
from
memory
cimport
shared_ptr
from
database
cimport
Database
,
DataContainer
# Used to indicate that something does not exist
cdef
enum
:
no_species
=
-
1
cdef
class
DatabaseManager
:
""" The Python database handler
Use this class for checking values in the database
or switching basis/dropping minerals or components...
"""
def
__cinit__
(
self
,
bytes
filepath
):
"""filepath is the path to the database file"""
self
.
database
=
new
Database
(
filepath
)
self
.
container
=
self
.
database
.
get_database
()
def
__dealloc__
(
self
):
del
self
.
database
cdef
shared_ptr
[
DataContainer
]
get_raw_db
(
self
):
return
self
.
container
cdef
DataContainer
*
_get
(
self
):
return
self
.
container
.
get
()
def
is_valid
(
self
):
return
self
.
database
.
is_valid
();
# --------- #
# Component #
# --------- #
property
nb_component
:
"""The number of component in the database."""
def
__get__
(
self
):
return
self
.
_get
()
.
nb_component
()
# labels and id
# --------------
def
component_label_to_id
(
self
,
bytes
comp
):
""" Return the id of a component."""
cdef
int
ans
=
self
.
database
.
component_label_to_id
(
comp
)
if
(
ans
==
no_species
):
raise
ValueError
(
"Species : '"
+
comp
.
decode
()
+
"' is not a component."
)
return
ans
def
component_id_to_label
(
self
,
int
idc
):
""" Return the label of a component."""
if
(
idc
>=
self
.
nb_component
):
raise
ValueError
(
"'"
+
str
(
idc
)
+
"' is not a valid index for a component"
)
return
bytes
(
self
.
_get
()
.
get_label_component
(
idc
))
def
print_basis
(
self
):
"""Print the components in the basis, with their ID"""
print
(
"The basis is :"
)
cdef
int
i
for
i
in
range
(
self
.
nb_component
):
print
(
" - "
+
str
(
i
)
+
" : "
+
bytes
(
self
.
_get
()
.
get_label_component
(
i
))
.
decode
())
# basis switch
# ------------
def
swap_components
(
self
,
dict
swapping
):
"""Swap components in the basis
swapping is a dictionnary where the keys are the labels of the
components to replace and the values are the labels of the secondary
species to add in the basis.
Raise value errors if the labels are invalid
"""
cdef
cmap
[
string
,
string
]
input_map
cdef
int
idsp
for
(
key
,
value
)
in
swapping
.
items
():
idsp
=
self
.
component_label_to_id
(
key
)
if
(
idsp
==
no_species
):
raise
ValueError
(
"'"
+
key
.
decode
()
+
"' is not a valid component."
)
idsp
=
self
.
aqueous_label_to_id
(
value
)
if
(
idsp
==
no_species
):
raise
ValueError
(
"'"
+
key
.
decode
()
+
"' is not a valid secondary aqueous species."
)
input_map
.
insert
(
pair
[
string
,
string
](
key
,
value
))
self
.
database
.
swap_components
(
input_map
)
# --------------- #
# Aqueous species #
# --------------- #
property
nb_aqueous
:
"""The number of aqueous species in the database"""
def
__get__
(
self
):
return
self
.
_get
()
.
nb_aqueous
()
# labels and id
# -------------
def
aqueous_id_to_label
(
self
,
int
ids
):
if
(
ids
>=
self
.
nb_aqueous
):
raise
ValueError
(
"'"
+
str
(
ids
)
+
"' is not a valid index for a secondary aqueous species"
)
return
bytes
(
self
.
_get
()
.
get_label_aqueous
(
ids
))
def
aqueous_label_to_id
(
self
,
bytes
aqueous
):
""" Return the id of a secondary aqueous species"""
cdef
int
ans
=
self
.
database
.
aqueous_label_to_id
(
aqueous
)
if
(
ans
==
no_species
):
raise
ValueError
(
"Species : '"
+
aqueous
.
decode
()
+
"' is not a secondary aqueous species."
)
return
ans
def
print_aqueous
(
self
):
""" Print the secondary species"""
print
(
"The secondary aqueous species are :"
)
cdef
int
i
for
i
in
range
(
self
.
nb_aqueous
):
print
(
" - "
+
str
(
i
)
+
" : "
+
bytes
(
self
.
_get
()
.
get_label_aqueous
(
i
))
.
decode
())
# properties
# ----------
def
nu_aqueous
(
self
,
int
ids
,
int
idc
):
"""Return stoichiometric coefficient of a secondary aqueous species"""
if
(
ids
>=
self
.
nb_aqueous
or
idc
>=
self
.
nb_component
):
raise
ValueError
(
"Incorrect bounds"
)
return
self
.
_get
()
.
nu_aqueous
(
ids
,
idc
)
def
l_nu_aqueous
(
self
,
bytes
aqueous
,
bytes
component
):
"""Return stoichiometric coefficient of a secondary aqueous species"""
return
self
.
_get
()
.
nu_aqueous
(
self
.
aqueous_label_to_id
(
aqueous
),
self
.
component_label_to_id
(
component
))
def
logk_aqueous
(
self
,
int
ids
):
"""Return the equilibrium constant of a secondary aqueous species"""
if
(
ids
>=
self
.
nb_aqueous
):
raise
ValueError
(
"Index : '"
+
str
(
ids
)
+
"' is not valid for an aqueous species"
)
return
self
.
_get
()
.
logk_aqueous
(
ids
)
def
l_logk_aqueous
(
self
,
bytes
aqueous
):
"""Return the equilibrium constant of a secondary aqueous species"""
return
self
.
_get
()
.
logk_aqueous
(
self
.
aqueous_label_to_id
(
aqueous
))
# ------------ #
# Solid phases #
# ------------ #
property
nb_mineral
:
"""The number of mineral in the database"""
def
__get__
(
self
):
return
self
.
_get
()
.
nb_mineral
()
# labels and id
# -------------
def
mineral_id_to_label
(
self
,
int
idm
):
"""Return the label of a mineral."""
if
(
idm
>=
self
.
nb_mineral
):
raise
ValueError
(
"'"
+
str
(
idm
)
+
"' is not a valid index for a solid phase"
)
return
bytes
(
self
.
_get
()
.
get_label_mineral
(
idm
))
def
mineral_label_to_id
(
self
,
bytes
mineral
):
""" Return the id of a secondary aqueous species"""
ans
=
self
.
database
.
mineral_label_to_id
(
mineral
)
if
(
ans
==
no_species
):
raise
ValueError
(
"Species : '"
+
mineral
.
decode
()
+
"' is not a solid phase at equilibrium in the database."
)
return
ans
def
print_minerals
(
self
):
""" Print the solid phases at equilibrium"""
print
(
"The solid phases at equilibrium are :"
)
cdef
int
i
for
i
in
range
(
self
.
nb_mineral
):
print
(
" - "
+
str
(
i
)
+
" : "
+
bytes
(
self
.
_get
()
.
get_label_mineral
(
i
))
.
decode
())
def
minerals_keep_only
(
self
,
list_mineral_to_keep
):
"""Keep only the solid phases in 'list_mineral_to_keep'"""
# we first verify that the list is valid
for
label
in
list_mineral_to_keep
:
self
.
mineral_label_to_id
(
label
)
# just check that it is not raising any error
self
.
database
.
minerals_keep_only
(
list_mineral_to_keep
)
# properties
# ----------
def
logk_mineral
(
self
,
int
idm
):
"""Return the equilibrium constant of a solid phase"""
if
(
idm
>=
self
.
nb_mineral
):
raise
ValueError
(
"Index : '"
+
str
(
idm
)
+
"'is not valid for a solid phase"
)
return
self
.
_get
()
.
logk_mineral
(
idm
)
def
l_logk_mineral
(
self
,
bytes
mineral
):
"""Return the equilibrium constant of a solid phase"""
return
self
.
_get
()
.
logk_mineral
(
self
.
mineral_label_to_id
(
mineral
))
def
nu_mineral
(
self
,
int
idm
,
int
idc
):
"""Return stoichometric coefficient of a mineral"""
if
(
idm
>=
self
.
nb_mineral
or
idc
>=
self
.
nb_component
):
raise
ValueError
(
"Incorrect argument, exceed bounds"
)
return
self
.
_get
()
.
nu_mineral
(
idm
,
idc
)
def
l_nu_mineral
(
self
,
bytes
mineral
,
bytes
component
):
"""Return stoichometric coefficient of a mineral"""
return
self
.
_get
()
.
nu_mineral
(
self
.
mineral_label_to_id
(
mineral
),
self
.
component_label_to_id
(
component
))
Event Timeline
Log In to Comment