pypsbuilder 2.6.2__tar.gz → 2.6.4__tar.gz
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.
- pypsbuilder-2.6.4/.zenodo.json +20 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/CHANGELOG.md +10 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/PKG-INFO +6 -1
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/README.md +5 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/codecov.yml +1 -1
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.tcapi.TC34API.rst +9 -11
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.tcapi.TC35API.rst +9 -11
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/__init__.py +1 -1
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/psclasses.py +111 -8
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/psexplorer.py +107 -88
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/tcapi.py +536 -491
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/tests/test_pclasses.py +12 -12
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/.github/dependabot.yml +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/.github/workflows/release.yml +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/.github/workflows/testing.yml +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/.github/workflows/testrelease.yml +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/.gitignore +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/.pre-commit-config.yaml +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/.readthedocs.yaml +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/AUTHORS.md +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/CONTRIBUTING.md +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/LICENSE +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/_static/theme_overrides.css +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psclasses.Dogmin.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psclasses.InvPoint.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psclasses.PTsection.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psclasses.PXsection.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psclasses.TCResult.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psclasses.TCResultSet.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psclasses.TXsection.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psclasses.UniLine.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psexplorer.PTPS.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psexplorer.PXPS.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api/pypsbuilder.psexplorer.TXPS.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/api.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/authors.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/command-line.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/conf.py +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/create_environment.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/crossing.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/delta.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/install_locally.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/invsearch.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/isopleths_1.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/isopleths_2.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/modes.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psbuilder_areas.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psbuilder_dogmin.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psbuilder_finished.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psbuilder_highlight.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psbuilder_init.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psbuilder_inv.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psbuilder_modes.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psbuilder_uni.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psiso_alm.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psiso_labelkey.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psiso_mode.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psiso_other.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/psshow_out.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/ptpath.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/show_data.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/show_grid.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/show_label.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/show_out.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/show_plain.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/images/status.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/index.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/psbuilders-tutorial.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/psexplorer-tutorial.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/docs/readme.rst +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/environment.yml +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/avgpelite/tc-avgpelite.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/avgpelite/tc-ds62.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/avgpelite/tc-mp50MnNCKFMASHTO.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/avgpelite/tc-prefs.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/avgpelite_34/tc-6axmn.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/avgpelite_34/tc-avgpelite.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/avgpelite_34/tc-ds62.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/avgpelite_34/tc-prefs.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/inv1-ic.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/inv1-log.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/inv2-ic.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/inv2-log.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/inv3-ic.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/inv3-log.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/uni1-ic.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/uni1-log.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/uni2-ic.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/uni2-log.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/uni3-ic.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/examples/outputs/uni3-log.txt +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/notebooks/pypsbuilder.ipynb +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pyproject.toml +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/images/ptbuilder.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/images/pxbuilder.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/images/pypsbuilder.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/images/txbuilder.png +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/psbuilders.py +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/tcinit.py +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/tests/__init__.py +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui/addinv.ui +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui/adduni.ui +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui/compile_ui.sh +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui/ptbuilder.ui +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui/pxbuilder.ui +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui/txbuilder.ui +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui/uniguess.ui +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui_addinv.py +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui_adduni.py +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui_ptbuilder.py +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui_pxbuilder.py +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui_txbuilder.py +0 -0
- {pypsbuilder-2.6.2 → pypsbuilder-2.6.4}/pypsbuilder/ui_uniguess.py +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"creators": [
|
|
3
|
+
{
|
|
4
|
+
"name": "Lexa, Ondrej",
|
|
5
|
+
"orcid": "0000-0002-1825-0097",
|
|
6
|
+
"affiliation": "IPSG, Charles University, Prague, Czech Republic",
|
|
7
|
+
"type": "ProjectLeader"
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"title": "pypsbuilder - THERMOCALC front-end for constructing and visualizations of P-T, T-X and P-X pseudosections",
|
|
11
|
+
"access_right": "open",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"metamorphic petrology",
|
|
14
|
+
"python",
|
|
15
|
+
"pseudosections"
|
|
16
|
+
],
|
|
17
|
+
"license": "mit",
|
|
18
|
+
"upload_type": "software",
|
|
19
|
+
"language": "eng"
|
|
20
|
+
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
All notable pypsbuilder changes.
|
|
3
3
|
|
|
4
|
+
## [2.6.4] - 2025-08-03
|
|
5
|
+
### Fixed
|
|
6
|
+
- TC 3.51 compatibility added
|
|
7
|
+
### Added
|
|
8
|
+
- `sys` could be used as phase to access G H S V rho variables
|
|
9
|
+
|
|
10
|
+
## [2.6.3] - 2025-04-03
|
|
11
|
+
### Fixed
|
|
12
|
+
- fixed multipolygon bug when subsections are merged
|
|
13
|
+
|
|
4
14
|
## [2.6.2] - 2025-02-11
|
|
5
15
|
### Fixed
|
|
6
16
|
- f-string py3.10 bugfix
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pypsbuilder
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.4
|
|
4
4
|
Summary: THERMOCALC front-end for constructing and analyzing PT pseudosections
|
|
5
5
|
Project-URL: Homepage, https://github.com/ondrolexa/pypsbuilder
|
|
6
6
|
Project-URL: Documentation, https://pypsbuilder.readthedocs.io
|
|
@@ -95,6 +95,11 @@ for Windows use Command Prompt or PowerShell:
|
|
|
95
95
|
python -m venv .venv
|
|
96
96
|
.venv\Scripts\activate
|
|
97
97
|
|
|
98
|
+
or, if you will got error *'python' is not recognized as an internal or external command*, try:
|
|
99
|
+
|
|
100
|
+
py -m venv .venv
|
|
101
|
+
.venv\Scripts\activate
|
|
102
|
+
|
|
98
103
|
> [!NOTE]
|
|
99
104
|
> On Microsoft Windows, it may be required to set the execution policy in PowerShell for the user.
|
|
100
105
|
> You can do this by issuing the following PowerShell command:
|
|
@@ -19,6 +19,11 @@ for Windows use Command Prompt or PowerShell:
|
|
|
19
19
|
python -m venv .venv
|
|
20
20
|
.venv\Scripts\activate
|
|
21
21
|
|
|
22
|
+
or, if you will got error *'python' is not recognized as an internal or external command*, try:
|
|
23
|
+
|
|
24
|
+
py -m venv .venv
|
|
25
|
+
.venv\Scripts\activate
|
|
26
|
+
|
|
22
27
|
> [!NOTE]
|
|
23
28
|
> On Microsoft Windows, it may be required to set the execution policy in PowerShell for the user.
|
|
24
29
|
> You can do this by issuing the following PowerShell command:
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
.. autoclass:: TC34API
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
.. automethod:: __init__
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
.. rubric:: Methods
|
|
13
13
|
|
|
14
14
|
.. autosummary::
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
~TC34API.__init__
|
|
17
17
|
~TC34API.calc_assemblage
|
|
18
18
|
~TC34API.calc_p
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
~TC34API.rundr
|
|
32
32
|
~TC34API.runtc
|
|
33
33
|
~TC34API.update_scriptfile
|
|
34
|
-
|
|
35
|
-
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
39
|
.. rubric:: Attributes
|
|
40
40
|
|
|
41
41
|
.. autosummary::
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
~TC34API.axfile
|
|
44
44
|
~TC34API.csvfile
|
|
45
45
|
~TC34API.dataset
|
|
@@ -52,7 +52,5 @@
|
|
|
52
52
|
~TC34API.ofile
|
|
53
53
|
~TC34API.prefsfile
|
|
54
54
|
~TC34API.scriptfile
|
|
55
|
-
~TC34API.
|
|
55
|
+
~TC34API.tcversionfloat
|
|
56
56
|
~TC34API.tcversion
|
|
57
|
-
|
|
58
|
-
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
.. autoclass:: TC35API
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
.. automethod:: __init__
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
.. rubric:: Methods
|
|
13
13
|
|
|
14
14
|
.. autosummary::
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
~TC35API.__init__
|
|
17
17
|
~TC35API.calc_assemblage
|
|
18
18
|
~TC35API.calc_p
|
|
@@ -30,15 +30,15 @@
|
|
|
30
30
|
~TC35API.rundr
|
|
31
31
|
~TC35API.runtc
|
|
32
32
|
~TC35API.update_scriptfile
|
|
33
|
-
|
|
34
|
-
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
38
|
.. rubric:: Attributes
|
|
39
39
|
|
|
40
40
|
.. autosummary::
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
~TC35API.axfile
|
|
43
43
|
~TC35API.csvfile
|
|
44
44
|
~TC35API.dataset
|
|
@@ -51,7 +51,5 @@
|
|
|
51
51
|
~TC35API.ofile
|
|
52
52
|
~TC35API.prefsfile
|
|
53
53
|
~TC35API.scriptfile
|
|
54
|
-
~TC35API.
|
|
54
|
+
~TC35API.tcversionfloat
|
|
55
55
|
~TC35API.tcversion
|
|
56
|
-
|
|
57
|
-
|
|
@@ -451,7 +451,7 @@ class TCResult:
|
|
|
451
451
|
)
|
|
452
452
|
# bulk composition
|
|
453
453
|
bulk_vals = {}
|
|
454
|
-
oxhead, vals = bulk.split("\n")[1:] # skip oxide compositions row
|
|
454
|
+
oxhead, vals = bulk.split("\n")[1:3] # skip oxide compositions row
|
|
455
455
|
for ox, val in zip(oxhead.split(), vals.split()[1:]):
|
|
456
456
|
bulk_vals[ox] = float(val)
|
|
457
457
|
data["bulk"] = bulk_vals
|
|
@@ -525,6 +525,109 @@ class TCResult:
|
|
|
525
525
|
# Finally
|
|
526
526
|
return cls(T, p, variance=variance, c=c, data=data, ptguess=ptguess)
|
|
527
527
|
|
|
528
|
+
@classmethod
|
|
529
|
+
def from_block351(cls, block, ptguess):
|
|
530
|
+
info, ax, sf, rbi, mode, factor, td, *mems, pems = block.split("\n\n")
|
|
531
|
+
bulk = "\n".join(rbi.split("\n")[:3])
|
|
532
|
+
rbi = "\n".join(rbi.split("\n")[3:])
|
|
533
|
+
# heading
|
|
534
|
+
data = {phase: {} for phase in info.split("{")[0].split()}
|
|
535
|
+
p, T = (float(v.strip()) for v in info.split("{")[1].split("}")[0].split(","))
|
|
536
|
+
# var or ovar?
|
|
537
|
+
variance = int(info.split("var = ")[1].split(" ")[0].replace(";", ""))
|
|
538
|
+
# a-x variables
|
|
539
|
+
for head, vals in zip(ax.split("\n")[::2], ax.split("\n")[1::2]):
|
|
540
|
+
phase, *names = head.split()
|
|
541
|
+
data[phase].update(
|
|
542
|
+
{
|
|
543
|
+
name.replace("({})".format(phase), ""): float(val)
|
|
544
|
+
for name, val in zip(names, vals.split())
|
|
545
|
+
}
|
|
546
|
+
)
|
|
547
|
+
# site fractions
|
|
548
|
+
for head, vals in zip(
|
|
549
|
+
sf.split("\n")[1::2], sf.split("\n")[2::2]
|
|
550
|
+
): # skip site fractions row
|
|
551
|
+
phase, *names = head.split()
|
|
552
|
+
data[phase].update(
|
|
553
|
+
{name: float(val) for name, val in zip(names, vals.split())}
|
|
554
|
+
)
|
|
555
|
+
# bulk composition
|
|
556
|
+
bulk_vals = {}
|
|
557
|
+
oxhead, vals = bulk.split("\n")[1:3] # skip oxide compositions row
|
|
558
|
+
for ox, val in zip(oxhead.split(), vals.split()[1:]):
|
|
559
|
+
bulk_vals[ox] = float(val)
|
|
560
|
+
data["bulk"] = bulk_vals
|
|
561
|
+
# x for TX and pX
|
|
562
|
+
if "step" in vals:
|
|
563
|
+
c = float(vals.split("step")[1].split(", x =")[1])
|
|
564
|
+
else:
|
|
565
|
+
c = 0
|
|
566
|
+
# rbi
|
|
567
|
+
for row in rbi.split("\n"):
|
|
568
|
+
phase, *vals = row.split()
|
|
569
|
+
data[phase].update(
|
|
570
|
+
{ox: float(val) for ox, val in zip(oxhead.split(), vals)}
|
|
571
|
+
)
|
|
572
|
+
# modes (zero mode is empty field in tc350 !!!)
|
|
573
|
+
head, vals = mode.split("\n")
|
|
574
|
+
phases = head.split()[1:]
|
|
575
|
+
# fixed width parsing !!!
|
|
576
|
+
valsf = [
|
|
577
|
+
(
|
|
578
|
+
float(vals[6:][9 * i : 9 * (i + 1)].strip())
|
|
579
|
+
if vals[6:][9 * i : 9 * (i + 1)].strip() != ""
|
|
580
|
+
else 0.0
|
|
581
|
+
)
|
|
582
|
+
for i in range(len(phases))
|
|
583
|
+
]
|
|
584
|
+
for phase, val in zip(phases, valsf):
|
|
585
|
+
data[phase].update({"mode": float(val)})
|
|
586
|
+
# factors
|
|
587
|
+
head, vals = factor.split("\n")
|
|
588
|
+
phases = head.split()[1:]
|
|
589
|
+
valsf = [
|
|
590
|
+
(
|
|
591
|
+
float(vals[6:][9 * i : 9 * (i + 1)].strip())
|
|
592
|
+
if vals[6:][9 * i : 9 * (i + 1)].strip() != ""
|
|
593
|
+
else 0.0
|
|
594
|
+
)
|
|
595
|
+
for i in range(len(phases))
|
|
596
|
+
]
|
|
597
|
+
for phase, val in zip(phases, valsf):
|
|
598
|
+
data[phase].update({"factor": float(val)})
|
|
599
|
+
# thermodynamic state
|
|
600
|
+
head, *rows = td.split("\n")
|
|
601
|
+
for row in rows[:-1]:
|
|
602
|
+
phase, *vals = row.split()
|
|
603
|
+
data[phase].update(
|
|
604
|
+
{name: float(val) for name, val in zip(head.split(), vals)}
|
|
605
|
+
)
|
|
606
|
+
# bulk thermodynamics
|
|
607
|
+
sys = {}
|
|
608
|
+
for name, val in zip(head.split(), rows[-1].split()[1:]):
|
|
609
|
+
sys[name] = float(val)
|
|
610
|
+
data["sys"] = sys
|
|
611
|
+
# model end-members
|
|
612
|
+
if len(mems) > 0:
|
|
613
|
+
_, mem0 = mems[0].split("\n", maxsplit=1)
|
|
614
|
+
head = ["ideal", "gamma", "activity", "prop", "mu", "RTlna"]
|
|
615
|
+
mems[0] = mem0
|
|
616
|
+
for mem in mems:
|
|
617
|
+
ems = mem.split("\n")
|
|
618
|
+
phase, ems0 = ems[0].split(maxsplit=1)
|
|
619
|
+
ems[0] = ems0
|
|
620
|
+
for row in ems:
|
|
621
|
+
em, *vals = row.split()
|
|
622
|
+
phase_em = "{}({})".format(phase, em)
|
|
623
|
+
data[phase_em] = {name: float(val) for name, val in zip(head, vals)}
|
|
624
|
+
# pure end-members
|
|
625
|
+
for row in pems.split("\n")[:-1]:
|
|
626
|
+
pem, val = row.split()
|
|
627
|
+
data[pem].update({"mu": float(val)})
|
|
628
|
+
# Finally
|
|
629
|
+
return cls(T, p, variance=variance, c=c, data=data, ptguess=ptguess)
|
|
630
|
+
|
|
528
631
|
def __repr__(self):
|
|
529
632
|
return "p:{:g} T:{:g} V:{} c:{:g}, Phases: {}".format(
|
|
530
633
|
self.p, self.T, self.variance, self.c, " ".join(self.phases)
|
|
@@ -815,20 +918,20 @@ class SectionBase:
|
|
|
815
918
|
def splitme(edges):
|
|
816
919
|
"""Recursive boundary splitter"""
|
|
817
920
|
for idx, edge in enumerate(edges):
|
|
818
|
-
for _,
|
|
819
|
-
if edge.intersects(
|
|
820
|
-
m = linemerge([edge,
|
|
921
|
+
for _, ln in lns:
|
|
922
|
+
if edge.intersects(ln):
|
|
923
|
+
m = linemerge([edge, ln])
|
|
821
924
|
if m.geom_type == "MultiLineString":
|
|
822
|
-
p = edge.intersection(
|
|
925
|
+
p = edge.intersection(ln)
|
|
823
926
|
if (
|
|
824
927
|
p.geom_type == "LineString"
|
|
825
928
|
): # seems to occur whe duplicate points are on line
|
|
826
929
|
p = MultiPoint(p.coords)
|
|
827
930
|
if p.geom_type == "MultiPoint":
|
|
828
|
-
pts = [
|
|
931
|
+
pts = [ln.interpolate(ln.project(pt)) for pt in p.geoms]
|
|
829
932
|
pts = sorted(pts, key=lambda pt: edge.project(pt))
|
|
830
933
|
else:
|
|
831
|
-
pts = [
|
|
934
|
+
pts = [ln.interpolate(ln.project(p))]
|
|
832
935
|
edges.pop(idx)
|
|
833
936
|
pts = (
|
|
834
937
|
[Point(edge.coords[0])] + pts + [Point(edge.coords[-1])]
|
|
@@ -858,7 +961,7 @@ class SectionBase:
|
|
|
858
961
|
while do:
|
|
859
962
|
edges, do = splitme(edges)
|
|
860
963
|
# polygonize
|
|
861
|
-
polys = list(polygonize(edges + [
|
|
964
|
+
polys = list(polygonize(edges + [ln for _, ln in lns]))
|
|
862
965
|
# create shapes
|
|
863
966
|
shapes = {}
|
|
864
967
|
unilists = {}
|
|
@@ -245,7 +245,7 @@ class PS:
|
|
|
245
245
|
for comp in (
|
|
246
246
|
set(self.all_data_keys.keys())
|
|
247
247
|
.difference(self.phases)
|
|
248
|
-
.difference(
|
|
248
|
+
.difference({'sys'})
|
|
249
249
|
):
|
|
250
250
|
k, v = comp.split(")")[0].split("(")
|
|
251
251
|
if k in em:
|
|
@@ -434,6 +434,7 @@ class PS:
|
|
|
434
434
|
# if len(res) > 0:
|
|
435
435
|
# for k in res[0]['data'].keys():
|
|
436
436
|
# data[k] = list(res[0]['data'][k].keys())
|
|
437
|
+
data['sys'] = ['G', 'H', 'S', 'V', 'rho']
|
|
437
438
|
self.all_data_keys = data
|
|
438
439
|
|
|
439
440
|
def collect_inv_data(self, key, phase, expr):
|
|
@@ -612,7 +613,7 @@ class PS:
|
|
|
612
613
|
mn, mx = sys.float_info.max, -sys.float_info.max
|
|
613
614
|
recs = OrderedDict()
|
|
614
615
|
for key in self:
|
|
615
|
-
if phase.split("(")[0] in key:
|
|
616
|
+
if phase.split("(")[0] in key or phase == "sys":
|
|
616
617
|
d = self.collect_data(key, phase, expr, which=which)
|
|
617
618
|
z = d["data"]
|
|
618
619
|
if z:
|
|
@@ -700,13 +701,18 @@ class PS:
|
|
|
700
701
|
show = False
|
|
701
702
|
ax = fig.add_subplot()
|
|
702
703
|
for k, shape in self.shapes.items():
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
704
|
+
if shape.geom_type == "MultiPolygon":
|
|
705
|
+
shapelist = list(shape.geoms)
|
|
706
|
+
else:
|
|
707
|
+
shapelist = [shape]
|
|
708
|
+
for shape in shapelist:
|
|
709
|
+
patch = PolygonPatch(
|
|
710
|
+
shape, fc=pscmap(norm(self.variance[k])), ec="none"
|
|
711
|
+
)
|
|
712
|
+
ax.add_patch(patch)
|
|
713
|
+
if show_vertices:
|
|
714
|
+
x, y = zip(*patch.get_path().vertices)
|
|
715
|
+
ax.plot(x, y, "k.", ms=3)
|
|
710
716
|
ax.autoscale_view()
|
|
711
717
|
self.add_overlay(ax, label=label, skiplabels=skiplabels, fontsize=labelfs)
|
|
712
718
|
if out:
|
|
@@ -831,27 +837,42 @@ class PS:
|
|
|
831
837
|
def add_overlay(self, ax, fc="none", ec="k", label=False, skiplabels=0, fontsize=6):
|
|
832
838
|
area = (self.xrange[1] - self.xrange[0]) * (self.yrange[1] - self.yrange[0])
|
|
833
839
|
for k, shape in self.shapes.items():
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
if
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
for
|
|
847
|
-
|
|
848
|
-
|
|
840
|
+
if shape.geom_type == "MultiPolygon":
|
|
841
|
+
shapelist = list(shape.geoms)
|
|
842
|
+
else:
|
|
843
|
+
shapelist = [shape]
|
|
844
|
+
for shape in shapelist:
|
|
845
|
+
ax.add_patch(PolygonPatch(shape, ec=ec, fc=fc, lw=0.5))
|
|
846
|
+
if label and (100 * shape.area / area > skiplabels):
|
|
847
|
+
# multiline for long labels
|
|
848
|
+
tl = sorted(list(k.difference(self.tc.excess)))
|
|
849
|
+
extra = self.tc.excess.difference(self.tc.excess.intersection(k))
|
|
850
|
+
# if excess in scriptfile is not accurate
|
|
851
|
+
if extra:
|
|
852
|
+
tl += ["-{}".format(pp) for pp in extra]
|
|
853
|
+
wp = len(tl) // 4 + int(len(tl) % 4 > 1)
|
|
854
|
+
txt = "\n".join(
|
|
855
|
+
[
|
|
856
|
+
" ".join([self.abbr.get(sa, sa) for sa in s])
|
|
857
|
+
for s in [
|
|
858
|
+
tl[i * len(tl) // wp : (i + 1) * len(tl) // wp]
|
|
859
|
+
for i in range(wp)
|
|
860
|
+
]
|
|
849
861
|
]
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
862
|
+
)
|
|
863
|
+
if shape.geom_type == "MultiPolygon":
|
|
864
|
+
for part in shape:
|
|
865
|
+
xy = part.representative_point().coords[0]
|
|
866
|
+
ax.annotate(
|
|
867
|
+
text=txt,
|
|
868
|
+
xy=xy,
|
|
869
|
+
weight="bold",
|
|
870
|
+
fontsize=fontsize,
|
|
871
|
+
ha="center",
|
|
872
|
+
va="center",
|
|
873
|
+
)
|
|
874
|
+
else:
|
|
875
|
+
xy = shape.representative_point().coords[0]
|
|
855
876
|
ax.annotate(
|
|
856
877
|
text=txt,
|
|
857
878
|
xy=xy,
|
|
@@ -860,16 +881,6 @@ class PS:
|
|
|
860
881
|
ha="center",
|
|
861
882
|
va="center",
|
|
862
883
|
)
|
|
863
|
-
else:
|
|
864
|
-
xy = shape.representative_point().coords[0]
|
|
865
|
-
ax.annotate(
|
|
866
|
-
text=txt,
|
|
867
|
-
xy=xy,
|
|
868
|
-
weight="bold",
|
|
869
|
-
fontsize=fontsize,
|
|
870
|
-
ha="center",
|
|
871
|
-
va="center",
|
|
872
|
-
)
|
|
873
884
|
|
|
874
885
|
def show_data(self, key, phase, expr=None, which=7):
|
|
875
886
|
"""Convinient function to show values of expression
|
|
@@ -1325,6 +1336,7 @@ class PS:
|
|
|
1325
1336
|
Default False.
|
|
1326
1337
|
labelkeys (frozenset or list): Keys of divariant fields where contours
|
|
1327
1338
|
should be labeled.
|
|
1339
|
+
clabelfs (int): Contour labels font size. Default 9
|
|
1328
1340
|
nosplit (bool): Controls whether the contour underlying labels are
|
|
1329
1341
|
removed or not. Defaut True
|
|
1330
1342
|
gradient (bool): Whether the first derivate of values should be used.
|
|
@@ -1425,7 +1437,7 @@ class PS:
|
|
|
1425
1437
|
ax = fig.add_subplot()
|
|
1426
1438
|
for key in recs:
|
|
1427
1439
|
phase_parts = phase.split(")")[0].split("(")
|
|
1428
|
-
if phase_parts[0] in key:
|
|
1440
|
+
if phase_parts[0] in key or phase == "sys":
|
|
1429
1441
|
tmin, pmin, tmax, pmax = self.shapes[key].bounds
|
|
1430
1442
|
# ttspace = self.xspace[np.logical_and(self.xspace >= tmin - self.xstep, self.xspace <= tmax + self.xstep)]
|
|
1431
1443
|
# ppspace = self.yspace[np.logical_and(self.yspace >= pmin - self.ystep, self.yspace <= pmax + self.ystep)]
|
|
@@ -1556,57 +1568,62 @@ class PS:
|
|
|
1556
1568
|
else:
|
|
1557
1569
|
cntv = 10
|
|
1558
1570
|
# ------------
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1571
|
+
if self.shapes[key].geom_type == "MultiPolygon":
|
|
1572
|
+
shapelist = list(self.shapes[key].geoms)
|
|
1573
|
+
else:
|
|
1574
|
+
shapelist = [self.shapes[key]]
|
|
1575
|
+
for shape in shapelist:
|
|
1576
|
+
with warnings.catch_warnings():
|
|
1577
|
+
warnings.filterwarnings("ignore", category=UserWarning)
|
|
1578
|
+
if filled:
|
|
1579
|
+
if colors is not None:
|
|
1580
|
+
cont = ax.contourf(
|
|
1581
|
+
tg, pg, zg, cntv, colors=colors, alpha=alpha
|
|
1569
1582
|
)
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
tg, pg, zg, cntv,
|
|
1583
|
+
if filled_over:
|
|
1584
|
+
contover = ax.contour(
|
|
1585
|
+
tg, pg, zg, cntv, colors=colors
|
|
1586
|
+
)
|
|
1587
|
+
else:
|
|
1588
|
+
cont = ax.contourf(
|
|
1589
|
+
tg, pg, zg, cntv, cmap=cmap, alpha=alpha
|
|
1577
1590
|
)
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1591
|
+
if filled_over:
|
|
1592
|
+
contover = ax.contour(
|
|
1593
|
+
tg, pg, zg, cntv, colors="whitesmoke"
|
|
1594
|
+
)
|
|
1581
1595
|
else:
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
+
if colors is not None:
|
|
1597
|
+
cont = ax.contour(tg, pg, zg, cntv, colors=colors)
|
|
1598
|
+
else:
|
|
1599
|
+
cont = ax.contour(tg, pg, zg, cntv, cmap=cmap)
|
|
1600
|
+
patch = PolygonPatch(shape, fc="none", ec="none")
|
|
1601
|
+
ax.add_patch(patch)
|
|
1602
|
+
# label if needed
|
|
1603
|
+
if (not filled or filled_over) and key in labelkyes_ok:
|
|
1604
|
+
positions = []
|
|
1605
|
+
contlbl = contover if filled_over else cont
|
|
1606
|
+
for seg in contlbl.get_paths():
|
|
1607
|
+
inside = np.fromiter(
|
|
1608
|
+
map(
|
|
1609
|
+
shape.contains,
|
|
1610
|
+
MultiPoint(seg.vertices).geoms,
|
|
1611
|
+
),
|
|
1612
|
+
dtype=bool,
|
|
1613
|
+
)
|
|
1614
|
+
if np.any(inside):
|
|
1615
|
+
positions.append(seg.vertices[inside].mean(axis=0))
|
|
1616
|
+
ax.clabel(
|
|
1617
|
+
contlbl,
|
|
1618
|
+
fontsize=kwargs.get("clabelfs", 9),
|
|
1619
|
+
manual=positions,
|
|
1620
|
+
fmt="%g",
|
|
1621
|
+
inline_spacing=3,
|
|
1622
|
+
inline=not nosplit,
|
|
1596
1623
|
)
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
contlbl,
|
|
1601
|
-
fontsize=9,
|
|
1602
|
-
manual=positions,
|
|
1603
|
-
fmt="%g",
|
|
1604
|
-
inline_spacing=3,
|
|
1605
|
-
inline=not nosplit,
|
|
1606
|
-
)
|
|
1607
|
-
cont.set_clip_path(patch)
|
|
1608
|
-
if filled and filled_over:
|
|
1609
|
-
contover.set_clip_path(patch)
|
|
1624
|
+
cont.set_clip_path(patch)
|
|
1625
|
+
if filled and filled_over:
|
|
1626
|
+
contover.set_clip_path(patch)
|
|
1610
1627
|
|
|
1611
1628
|
if only is None:
|
|
1612
1629
|
self.add_overlay(ax)
|
|
@@ -2720,7 +2737,9 @@ class PTPS(PS):
|
|
|
2720
2737
|
)
|
|
2721
2738
|
plt.show()
|
|
2722
2739
|
|
|
2723
|
-
def pointcalc(
|
|
2740
|
+
def pointcalc(
|
|
2741
|
+
self, t=None, p=None, label=False, skiplabels=0, labelfs=6, show_output=False
|
|
2742
|
+
):
|
|
2724
2743
|
if t is None or p is None:
|
|
2725
2744
|
fig, ax = plt.subplots()
|
|
2726
2745
|
ax.autoscale_view()
|