Skip to content

Commit b5056c0

Browse files
authored
Merge pull request #663 from bobmyhill/add_phase_diagram_mask
add optional phase diagram mask
2 parents bd694e1 + c2f2304 commit b5056c0

File tree

2 files changed

+50
-26
lines changed

2 files changed

+50
-26
lines changed

contrib/perplex/create_phase_diagram.py

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import os
22
import shutil
3-
3+
import numpy as np
44
import burnman
55
from perplex_utils import databases, make_build_file
66
from perplex_utils import run_vertex, run_pssect
77
from perplex_utils import create_mode_table
88
from perplex_utils import pretty_plot_phase_diagram
99

1010
import matplotlib.pyplot as plt
11+
import pickle
1112

1213

1314
def run_perplex(
@@ -71,25 +72,11 @@ def run_perplex(
7172
"molar",
7273
),
7374
"harzburgite": burnman.Composition(
74-
{
75-
"SiO2": 36.07,
76-
"MgO": 56.51,
77-
"FeO": 6.07,
78-
"CaO": 0.81,
79-
"Al2O3": 0.53,
80-
"Na2O": 0.001,
81-
},
75+
{"SiO2": 36.07, "MgO": 56.51, "FeO": 6.07, "CaO": 0.81, "Al2O3": 0.53},
8276
"molar",
8377
),
8478
"modified_harzburgite": burnman.Composition(
85-
{
86-
"SiO2": 36.04,
87-
"MgO": 56.54,
88-
"FeO": 5.97,
89-
"CaO": 0.79,
90-
"Al2O3": 0.65,
91-
"Na2O": 0.001,
92-
},
79+
{"SiO2": 36.04, "MgO": 56.54, "FeO": 5.97, "CaO": 0.79, "Al2O3": 0.65},
9380
"molar",
9481
),
9582
}
@@ -100,15 +87,15 @@ def run_perplex(
10087
project_name = "basalt"
10188
database = databases["stx21"]
10289
composition = compositions[project_name]
103-
pressure_range_total = [1.0e5, 140.0e9]
104-
temperature_range_total = [200.0, 3000.0]
90+
pressure_range_total = [1.0, 140.0e9]
91+
temperature_range_total = [200.0, 4000.0]
10592

10693
# Split pressure and temperature so that PerpleX
10794
# no temperature splits seems to make diagram with
10895
# less prominent discontinuities
109-
n_pressures_per_split = 121
110-
n_temperatures_per_split = 601
111-
n_splits_pressure = 14
96+
n_pressures_per_split = 101
97+
n_temperatures_per_split = 761
98+
n_splits_pressure = 28
11299
n_splits_temperature = 1
113100

114101
# If this script has already been run, and you just want to
@@ -258,6 +245,10 @@ def run_perplex(
258245

259246
modes_filenames.append(split_project_name + "_modes.dat")
260247

248+
mask_polygon = np.array(
249+
[[0.0, 2150.0], [12.0e9, 4000.0001], [0.0, 4000.001], [0.0, 2150.0]]
250+
)
251+
261252
fig = plt.figure(figsize=(12, 8))
262253
ax = fig.add_subplot(1, 1, 1)
263254

@@ -273,15 +264,23 @@ def run_perplex(
273264
label_scaling=3.0,
274265
label_clearance=0.01,
275266
number_small_fields=True,
267+
mask_polygon=mask_polygon,
276268
)
277269

278-
with open(f"{project_name}_field_ids.txt", "w") as f:
270+
# Save the assemblage data for all the small fields
271+
with open(f"{project_name}_phase_diagram_field_ids.txt", "w") as f:
279272
for i, small_field in enumerate(small_fields):
280273
line = f"{i+1}: {small_field}"
281274
print(line)
282275
f.write(f"{line}\n")
283276

284-
fig.savefig(f"{project_name}.pdf")
277+
# Save figure as a pdf
278+
fig.savefig(f"{project_name}_phase_diagram.pdf")
279+
280+
# Save figure as a pickle file to reload later
281+
with open(f"{project_name}_phase_diagram.pkl", "wb") as f:
282+
pickle.dump(fig, f)
283+
285284
plt.show()
286285

287286
print("Processing complete.")

contrib/perplex/perplex_utils.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,11 @@ def _smooth_polygon_edges_between_intersections(
809809

810810

811811
def get_fields_assemblages_and_bounds(
812-
filename, phase_name_replacements, smoothing_window, smoothing_order
812+
filename,
813+
phase_name_replacements,
814+
smoothing_window,
815+
smoothing_order,
816+
mask_polygon=None,
813817
):
814818
"""
815819
Extract phase assemblage fields and plot bounds from a mode tab file.
@@ -823,6 +827,9 @@ def get_fields_assemblages_and_bounds(
823827
:type smoothing_window: int
824828
:param smoothing_order: Polynomial order for smoothing polygon edges.
825829
:type smoothing_order: int
830+
:param mask_polygon: 2D array of points (P in Pa, T in K),
831+
defining a polygon to mask out.
832+
:type mask_polygon: 2D numpy array
826833
:return: Tuple containing list of polygon data dicts and bounds
827834
[[P_min, P_max], [T_min, T_max]].
828835
:rtype: (list[dict], list[list[float]])
@@ -832,8 +839,21 @@ def get_fields_assemblages_and_bounds(
832839
P, T = data[:2]
833840
pressures = P[:, 0]
834841
temperatures = T[0]
835-
836842
phase_modes = data[2:]
843+
844+
if mask_polygon is not None:
845+
846+
mask_polygon_bar = mask_polygon.copy()
847+
mask_polygon_bar[:, 0] = mask_polygon_bar[:, 0] / 1.0e5
848+
849+
poly = Polygon(mask_polygon_bar)
850+
points = np.vstack((P.ravel(), T.ravel())).T
851+
mask = np.array(
852+
[poly.contains(Point(pt)) or poly.touches(Point(pt)) for pt in points]
853+
)
854+
mask = mask.reshape(P.shape)
855+
phase_modes[:, mask] = 0.0
856+
837857
num_phases = phase_modes.shape[0]
838858
phase_names = [phase_name_replacements.get(name, name) for name in column_names[2:]]
839859

@@ -1067,6 +1087,7 @@ def pretty_plot_phase_diagram(
10671087
label_scaling=3.0,
10681088
label_clearance=0.01,
10691089
number_small_fields=True,
1090+
mask_polygon=None,
10701091
):
10711092
"""
10721093
Plot the Perple_X calculated phase diagram on a matplotlib axis.
@@ -1097,6 +1118,9 @@ def pretty_plot_phase_diagram(
10971118
:param number_small_fields: Replace assemblage labels with numbers if
10981119
there is not enough clearance around the label.
10991120
:type number_small_fields: bool
1121+
:param mask_polygon: 2D array of points (P in Pa, T in K),
1122+
defining a polygon to mask out.
1123+
:type mask_polygon: 2D numpy array
11001124
:return: List of assemblages corresponding to numbered small fields.
11011125
:rtype: [str]
11021126
"""
@@ -1110,6 +1134,7 @@ def pretty_plot_phase_diagram(
11101134
phase_name_replacements,
11111135
smoothing_window,
11121136
smoothing_order,
1137+
mask_polygon,
11131138
)
11141139
polygon_data.extend(polygon_data_i)
11151140
bounds.append(bounds_i)

0 commit comments

Comments
 (0)