Example Applications ******************** Read a raw measurement file, fit a curve, save and plot the results =================================================================== .. doctest:: generates-my-results >>> import matplotlib.pyplot as plt >>> import numpy as np >>> from SDF.data_model import Workspace, ArrayDataset1D >>> from SDF.file_io import write_sdf, load_from_sdf >>> # 0. create some data (usually read from measurement file) >>> n_points = 20 >>> a, b = 3, 1.5 >>> x = np.linspace(0, 10, n_points) >>> y = a*x + b + np.random.normal(size=n_points) >>> ws = Workspace(name="top-level workspace", owner="Albertus") >>> ws.datasets.add(ArrayDataset1D(name="x", data=x, unit="mm")) >>> ws.datasets.add(ArrayDataset1D(name="y", data=y, unit="nmol")) >>> ws.instruments["Supermeter 2000"] = {"nickname": "Sir cannot-fail", ... "settings": {"good day": True, "mood": 10}} >>> write_sdf(ws, "my-results.sdf") >>> # 1. read data, fit curve >>> ws = load_from_sdf("my-results.sdf") >>> fit_a, fit_b = np.polyfit(x, y, deg=1) >>> # 2. add fit results to workspace >>> ws.parameters["fit results"] = {"a": (fit_a, "nmol"), ... "b": (fit_b, "nmol/mm"), ... "method": {"name": "np.polyfit", "degree": 1}} >>> write_sdf(ws, "my-results.sdf") >>> # 3. plot >>> x = ws.datasets["x"].data >>> x_unit = ws.datasets["x"].unit >>> y = ws.datasets["y"].data >>> y_unit = ws.datasets["y"].unit >>> fit_a = float(ws.parameters["fit results"]["a"].value) >>> fit_b = float(ws.parameters["fit results"]["b"].value) >>> def plot(x, y, y_fit, x_unit, y_unit): ... plt.plot(x, y, "xk", label="measurement") ... plt.plot(x, y_fit, "--r", label="fit") ... plt.xlabel(f"$x$ /{x_unit}") ... plt.ylabel(f"$y$ /{y_unit}") ... plt.legend() ... plt.title("Results") ... plt.tight_layout() >>> plot(x, y, fit_a*x + fit_b, x_unit, y_unit) >>> plt.savefig("my-results.png") The resulting file :code:`my-results.sdf` will look like this: .. code-block:: xml :caption: my-results.sdf top-level workspace Albertus Supermeter 2000 x 0.0 0.5263157894736842 1.0526315789473684 1.5789473684210527 2.1052631578947367 2.631578947368421 3.1578947368421053 3.6842105263157894 4.2105263157894735 4.7368421052631575 5.263157894736842 5.789473684210526 6.315789473684211 6.842105263157895 7.368421052631579 7.894736842105263 8.421052631578947 8.947368421052632 9.473684210526315 10.0 y 1.0194935272080436 3.313324719409985 4.016299212544986 7.627843194351737 6.31005069389586 10.487992770591923 11.123057149457448 11.80545784430888 14.494353262577148 14.824419224980307 18.545437261147292 18.63781216938566 20.146171321403752 22.963561113724747 23.964314703838614 25.80381228448588 24.440242187106243 27.620432980775806 29.404287266310554 32.18231360430237 The plot will look like this: .. figure:: /img/sdf-data-model-example-plot-curve-fit.png :alt: example curve fit plot my-results.png Generate a nested Workspace with multiple Datasets ================================================== .. doctest:: generates-my-results >>> from datetime import datetime >>> from PIL import Image >>> import numpy as np >>> from SDF.data_model import Workspace, ImageDataset, ArrayDataset1D >>> from SDF.file_io import write_sdf >>> sdf = Workspace(name="my experiment", owner="me", date=datetime.now()) >>> sdf.comment = "comment on the experiment" >>> sdf.samples["my first sample"] = "sample description" >>> sdf.samples["my second sample"] = "sample description" >>> measurement_1 = Workspace("my first measurement") >>> sdf.workspaces.add(measurement_1) >>> measurement_1.comment = "comment on my first measurement:\n" \ ... " - it consists of two images\n" \ ... " - they are random, but beautiful!" >>> measurement_1.instruments["my microscope"] = dict(cost=(9001, "EUR"), color="black") >>> image_1 = Image.fromarray(np.random.randint(0, 255, (10, 10), dtype=np.uint8)) # random 10x10 image >>> image_2 = Image.fromarray(np.random.randint(0, 255, (10, 10), dtype=np.uint8)) >>> measurement_1.datasets.add(ImageDataset("image 1", image_1)) >>> measurement_1.datasets["image 1"].parameters["zoom-level"] = 30 >>> measurement_1.datasets["image 1"].parameters["wavelength"] = 509, "nm" >>> measurement_1.datasets.add(ImageDataset("image 2", image_2)) >>> measurement_2 = Workspace("my second measurement") >>> sdf.workspaces.add(measurement_2) >>> measurement_2.comment = "comment on my first measurement" >>> x = np.arange(100) >>> y = np.random.randint(0, 10, 100) >>> measurement_2.datasets.add(ArrayDataset1D("x", x)) >>> measurement_2.datasets.add(ArrayDataset1D("y", y)) >>> write_sdf(sdf, "my-results.sdf") The resulting file :code:`my-results.sdf` would look like this: .. code-block:: xml :caption: my-results.sdf my experiment me 2021.03.03 11:01:28 comment on the experiment my first sample sample description my second sample sample description my first measurement comment on my first measurement: - it consists of two images - they are random, but beautiful! my microscope image 1 iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAAAAACoWZBhAAAAeUlEQVR4nAFuAJH/AZAWa0VE4fDv DEMAWrhy8Ap+NRE0VwIP2W6xVnz36/tkBECg6Br6DZSfxtwArc1sCMhI+QTlQASDQCtSFPwonKkl ABlDAnNLCJI3owsBn1+a/M2JOlv88QBxoT/oB/x8FtApAak8PoLosFYFybBPszA9DBBXFAAAAABJ RU5ErkJggg== image 2 iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAAAAACoWZBhAAAAeUlEQVR4nAFuAJH/AV2nPj/syu3s q1EAGGJHzgLvp7gliQJd+s1UeOgI0TtGALgZ+RDJLsZBD6cC0WE59UEZBdHxFwAhlFXietBCH3tj AFEbsOITtH4B3qcAzD/+lO8Iz5QyfAGIISIjCDwTyvp2AFHbtb0Fkcn8INWzmDFI/vtkfAAAAABJ RU5ErkJggg== my second measurement comment on my first measurement x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 y 0 1 4 6 7 3 4 0 8 5 9 7 7 6 2 8 1 4 9 5 8 9 5 6 8 4 5 8 1 9 8 9 1 5 1 3 7 2 0 9 0 2 0 6 6 2 0 3 6 4 0 1 2 2 5 6 4 6 9 9 2 0 6 3 4 1 6 2 8 7 7 6 5 5 6 4 0 6 7 5 8 7 8 4 2 0 3 0 4 5 2 7 5 7 4 5 8 2 2 0 .. testcleanup:: generates-my-results import os if os.path.isfile("my-results.sdf"): os.remove(os.path.abspath("my-results.sdf")) if os.path.isfile("my-results.png"): os.remove("my-results.png")