Mercurial > repos > muon-spectroscopy-computational-project > larch_plot
changeset 0:886949a03377 draft
planemo upload for repository https://github.com/MaterialsGalaxy/larch-tools/tree/main/larch_plot commit 5be486890442dedfb327289d597e1c8110240735
author | muon-spectroscopy-computational-project |
---|---|
date | Tue, 14 Nov 2023 15:35:36 +0000 |
parents | |
children | 002c18a3e642 |
files | common.py larch_plot.py larch_plot.xml macros.xml test-data/test.prj |
diffstat | 5 files changed, 256 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common.py Tue Nov 14 15:35:36 2023 +0000 @@ -0,0 +1,46 @@ +from typing import Iterable + +from larch.io import extract_athenagroup, read_athena +from larch.io.athena_project import AthenaGroup +from larch.symboltable import Group +from larch.xafs import autobk, pre_edge, xftf + + +def get_group(athena_group: AthenaGroup, key: str = None) -> Group: + if key is None: + group_keys = list(athena_group._athena_groups.keys()) + key = group_keys[0] + return extract_athenagroup(athena_group._athena_groups[key]) + + +def read_group(dat_file: str, key: str = None, xftf_params: dict = None): + athena_group = read_athena(dat_file) + group = get_group(athena_group, key) + bkg_parameters = group.athena_params.bkg + print(group.athena_params.fft) + print(group.athena_params.fft.__dict__) + pre_edge( + group, + e0=bkg_parameters.e0, + pre1=bkg_parameters.pre1, + pre2=bkg_parameters.pre2, + norm1=bkg_parameters.nor1, + norm2=bkg_parameters.nor2, + nnorm=bkg_parameters.nnorm, + make_flat=bkg_parameters.flatten, + ) + autobk(group) + if xftf_params is None: + xftf(group) + else: + print(xftf_params) + xftf(group, **xftf_params) + xftf_details = Group() + setattr(xftf_details, "call_args", xftf_params) + group.xftf_details = xftf_details + return group + + +def read_groups(dat_files: "list[str]", key: str = None) -> Iterable[Group]: + for dat_file in dat_files: + yield read_group(dat_file=dat_file, key=key)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/larch_plot.py Tue Nov 14 15:35:36 2023 +0000 @@ -0,0 +1,101 @@ +import json +import sys + +from common import read_groups + +import matplotlib +import matplotlib.pyplot as plt + +import numpy as np + + +Y_LABELS = { + "norm": r"x$\mu$(E), normalised", + "dmude": r"d(x$\mu$(E))/dE, normalised", + "chir_mag": r"|$\chi$(r)|", +} + + +def main(dat_files: "list[str]", plot_settings: "list[dict]"): + groups = list(read_groups(dat_files)) + + for i, settings in enumerate(plot_settings): + data_list = [] + e0_min = None + e0_max = None + variable = settings["variable"]["variable"] + x_min = settings["variable"]["energy_min"] + x_max = settings["variable"]["energy_max"] + plot_path = f"plots/{i}_{variable}.png" + plt.figure() + + for group in groups: + label = group.athena_params.annotation or group.athena_params.id + if variable == "chir_mag": + x = group.r + energy_format = None + else: + x = group.energy + energy_format = settings["variable"]["energy_format"] + if energy_format == "relative": + e0 = group.athena_params.bkg.e0 + e0_min = find_relative_limit(e0_min, e0, min) + e0_max = find_relative_limit(e0_max, e0, max) + + y = getattr(group, variable) + if x_min is None and x_max is None: + plt.plot(x, y, label=label) + else: + data_list.append({"x": x, "y": y, "label": label}) + + if variable != "chir_mag" and energy_format == "relative": + if x_min is not None: + x_min += e0_min + if x_max is not None: + x_max += e0_max + + if x_min is not None or x_max is not None: + for data in data_list: + index_min = None + index_max = None + x = data["x"] + if x_min is not None: + index_min = max(np.searchsorted(x, x_min) - 1, 0) + if x_max is not None: + index_max = min(np.searchsorted(x, x_max) + 1, len(x)) + plt.plot( + x[index_min:index_max], + data["y"][index_min:index_max], + label=data["label"], + ) + + plt.xlim(x_min, x_max) + + save_plot(variable, plot_path) + + +def find_relative_limit(e0_min: "float|None", e0: float, function: callable): + if e0_min is None: + e0_min = e0 + else: + e0_min = function(e0_min, e0) + return e0_min + + +def save_plot(y_type: str, plot_path: str): + plt.grid(color="r", linestyle=":", linewidth=1) + plt.xlabel("Energy (eV)") + plt.ylabel(Y_LABELS[y_type]) + plt.legend() + plt.savefig(plot_path, format="png") + plt.close("all") + + +if __name__ == "__main__": + # larch imports set this to an interactive backend, so need to change it + matplotlib.use("Agg") + + dat_files = sys.argv[1] + input_values = json.load(open(sys.argv[2], "r", encoding="utf-8")) + + main(dat_files.split(","), input_values["plots"])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/larch_plot.xml Tue Nov 14 15:35:36 2023 +0000 @@ -0,0 +1,83 @@ +<tool id="larch_plot" name="Larch Plot" version="@TOOL_VERSION@+galaxy@WRAPPER_VERSION@" python_template_version="3.5" profile="22.05" license="MIT"> + <description>plot Athena projects</description> + <macros> + <!-- version of underlying tool (PEP 440) --> + <token name="@TOOL_VERSION@">0.9.71</token> + <!-- version of this tool wrapper (integer) --> + <token name="@WRAPPER_VERSION@">0</token> + <!-- citation should be updated with every underlying tool version --> + <!-- typical fields to update are version, month, year, and doi --> + <token name="@TOOL_CITATION@">10.1088/1742-6596/430/1/012007</token> + <import>macros.xml</import> + </macros> + <creator> + <person givenName="Patrick" familyName="Austin" url="https://github.com/patrick-austin" identifier="https://orcid.org/0000-0002-6279-7823"/> + </creator> + <requirements> + <requirement type="package" version="@TOOL_VERSION@">xraylarch</requirement> + <requirement type="package" version="3.5.2">matplotlib</requirement> + </requirements> + <required_files> + <include type="literal" path="larch_plot.py"/> + <include type="literal" path="common.py"/> + </required_files> + <command detect_errors="exit_code"><![CDATA[ + mkdir plots + && python '${__tool_directory__}/larch_plot.py' '$dat_files' '$inputs' + ]]></command> + <configfiles> + <inputs name="inputs"/> + </configfiles> + <inputs> + <param name="dat_files" type="data" format="prj" multiple="true" min="1" label="Athena projects" help="X-ray Absorption Spectroscopy (XAS) data, in Athena project format"/> + <repeat name="plots" title="Plots" min="1" default="1" help="Each additional entry will create another output plot"> + <conditional name="variable"> + <param name="variable" type="select" display="radio" label="Variable" help="Variable to plot on the y axis"> + <option value="norm" selected="true">Normalised xμ</option> + <option value="dmude">Derivative of xμ</option> + <option value="chir_mag">Magnitude of χ(r)</option> + </param> + <when value="norm"> + <expand macro="energy_limits"/> + </when> + <when value="dmude"> + <expand macro="energy_limits"/> + </when> + <when value="chir_mag"> + <param name="energy_min" type="float" label="Minimum r (ang)" optional="true" help="If set, data will be cropped below this value in angstroms."/> + <param name="energy_max" type="float" label="Maximum r (ang)" optional="true" help="If set, data will be cropped above this value in angstroms."/> + </when> + </conditional> + </repeat> + </inputs> + <outputs> + <collection name="plot_collection" format="png" type="list"> + <discover_datasets pattern="__name_and_ext__" directory="plots"/> + </collection> + </outputs> + <tests> + <test expect_num_outputs="1"> + <param name="dat_files" value="test.prj"/> + <param name="variable" value="norm"/> + <param name="energy_format" value="absolute"/> + <param name="energy_min" value="7000"/> + <param name="variable" value="dmude"/> + <param name="energy_format" value="relative"/> + <param name="energy_max" value="10"/> + <output_collection name="plot_collection" type="list" count="2"/> + </test> + </tests> + <help><![CDATA[ + Using Larch, read Athena project files and plot data from them. + + Only Athena project files are accepted as input. If data is plaintext, + first load it using the Larch Athena tool. + All input files will appear on the same plot(s). + To generate multiple types of plot with the same set of files, + add additional sections to the form. + ]]></help> + <citations> + <citation type="doi">@TOOL_CITATION@</citation> + <citation type="doi">10.1107/S0909049505012719</citation> + </citations> +</tool> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macros.xml Tue Nov 14 15:35:36 2023 +0000 @@ -0,0 +1,26 @@ +<macros> + <xml name="energy_limits"> + <param name="energy_format" type="select" display="radio" label="Energy limits" help="Whether to limit the energy relative to the absorption edge or with absolute values."> + <option value="relative" selected="true">Relative</option> + <option value="absolute">Absolute</option> + </param> + <param name="energy_min" type="float" label="Minimum energy (eV)" optional="true" help="If set, data will be cropped below this value in electron volts."/> + <param name="energy_max" type="float" label="Maximum energy (eV)" optional="true" help="If set, data will be cropped above this value in electron volts."/> + </xml> + <xml name="xftf_params"> + <param argument="kmin" type="float" value="0" min="0.0" help="Minimum k value."/> + <param argument="kmax" type="float" value="20" min="0.0" help="Maximum k value."/> + <param argument="kweight" type="float" value="2" help="Exponent for weighting spectra by raising k to this power."/> + <param argument="dk" type="float" value="4" help="Tapering parameter for Fourier Transform window."/> + <param argument="window" type="select" help="Fourier Transform window type."> + <option value="hanning">Hanning (cosine-squared taper)</option> + <option value="parzen">Parzen (linear taper)</option> + <option value="welch">Welch (quadratic taper)</option> + <option value="gaussian">Gaussian function window</option> + <option value="sine">Sine function window</option> + <option value="kaiser" selected="true">Kaiser-Bessel function-derived window</option> + </param> + <param argument="rmin" type="float" value="0.0" min="0.0" help="Minimum radial distance."/> + <param argument="rmax" type="float" value="10.0" min="0.0" help="Maximum radial distance."/> + </xml> +</macros> \ No newline at end of file