Example Applications

Read a raw measurement file, fit a curve, save and plot the 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 my-results.sdf will look like this:

Listing 1 my-results.sdf
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE workspace>
<workspace>
   <name>
      top-level workspace
   </name>
   <owner>
      Albertus
   </owner>
   <par name="fit results">
      <par name="a" value="2.9781712899700308" unit="nmol"/>
      <par name="b" value="1.5456773747402146" unit="nmol/mm"/>
      <par name="method">
         <par name="degree" value="1"/>
         <par name="name" value="np.polyfit"/>
      </par>
   </par>
   <instrument>
      <name>
         Supermeter 2000
      </name>
      <par name="nickname" value="Sir cannot-fail"/>
      <par name="settings">
         <par name="good day" value="True"/>
         <par name="mood" value="10"/>
      </par>
   </instrument>
   <dataset type="sc">
      <name>
         x
      </name>
      <unit value="mm"/>
      <data rows="20" cols="1" type="float">
         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
      </data>
   </dataset>
   <dataset type="sc">
      <name>
         y
      </name>
      <unit value="nmol"/>
      <data rows="20" cols="1" type="float">
         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
      </data>
   </dataset>
</workspace>

The plot will look like this:

example curve fit plot

Fig. 19 my-results.png

Generate a nested Workspace with multiple Datasets

>>> 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 my-results.sdf would look like this:

Listing 2 my-results.sdf
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE workspace>
<workspace>
   <name>
      my experiment
   </name>
   <owner>
      me
   </owner>
   <date>
      2021.03.03 11:01:28
   </date>
   <comment>
      comment on the experiment
   </comment>
   <sample>
      <name>
         my first sample
      </name>
      <comment>
         sample description
      </comment>
   </sample>
   <sample>
      <name>
         my second sample
      </name>
      <comment>
         sample description
      </comment>
   </sample>
   <workspace>
      <name>
         my first measurement
      </name>
      <comment>
         comment on my first measurement:
           - it consists of two images
           - they are random, but beautiful!
      </comment>
      <instrument>
         <name>
            my microscope
         </name>
         <par name="color" value="black"/>
         <par name="cost" value="9001" unit="EUR"/>
      </instrument>
      <dataset type="img">
         <name>
            image 1
         </name>
         <par name="zoom-level" value="30"/>
         <par name="wavelength" value="509" unit="nm"/>
         <data encoding="base64" type="image/png">
            iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAAAAACoWZBhAAAAeUlEQVR4nAFuAJH/AZAWa0VE4fDv
            DEMAWrhy8Ap+NRE0VwIP2W6xVnz36/tkBECg6Br6DZSfxtwArc1sCMhI+QTlQASDQCtSFPwonKkl
            ABlDAnNLCJI3owsBn1+a/M2JOlv88QBxoT/oB/x8FtApAak8PoLosFYFybBPszA9DBBXFAAAAABJ
            RU5ErkJggg==
         </data>
      </dataset>
      <dataset type="img">
         <name>
            image 2
         </name>
         <data encoding="base64" type="image/png">
            iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAAAAACoWZBhAAAAeUlEQVR4nAFuAJH/AV2nPj/syu3s
            q1EAGGJHzgLvp7gliQJd+s1UeOgI0TtGALgZ+RDJLsZBD6cC0WE59UEZBdHxFwAhlFXietBCH3tj
            AFEbsOITtH4B3qcAzD/+lO8Iz5QyfAGIISIjCDwTyvp2AFHbtb0Fkcn8INWzmDFI/vtkfAAAAABJ
            RU5ErkJggg==
         </data>
      </dataset>
   </workspace>
   <workspace>
      <name>
         my second measurement
      </name>
      <comment>
         comment on my first measurement
      </comment>
      <dataset type="sc">
         <name>
            x
         </name>
         <data rows="100" cols="1" type="int">
            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
         </data>
      </dataset>
      <dataset type="sc">
         <name>
            y
         </name>
         <data rows="100" cols="1" type="int">
            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
         </data>
      </dataset>
   </workspace>
</workspace>