Skip to content

Measurement (External)

This example example shows how to:

  1. Start a measurement without built-in predictions
  2. Read out the spectra
  3. Write a prediction back to the device
  4. Stop the measurement

The addition of external predictions allows you to use your own machine learning models or analysis algorithms while still leveraging the Monipa 1 to handle data acquisition.

Measurement with external predictions
import time

import requests

base_url = "http://10.0.0.2:5555"
name = "example-external-measurement"

requests.post(
    url=f"{base_url}/api/measurement/start",
    json={
        "name": name,
        # we do not perform any analytics in this example, since we are providing them ourselves
        "analytics_type": "no_analytics",
        # set other parameters as usual, we could also skip those to use the defaults
        # NOTE: you can check the default measurement parameters in the frontend http://10.0.0.2/Monipa/templates/default
        "spectrometer_resolution": 400,
        "spectrometer_measurement_time": 10,
        "blanking_mode": "first_spectrum",
    },
)
print("Measurement started, running for one minute...")

# get wavenumbers for later use
wavenumbers = requests.get(
    f"{base_url}/api/storage/measurements/{name}/params/wavenumbers",
).json()

time_start = time.time()

n_predictions, stopped = 0, False

while not stopped:
    if time.time() - time_start > 60:
        # NOTE: after sending the stop request, we still need to write one more prediction below
        requests.post(f"{base_url}/api/measurement/stop")
        stopped = True
        print("Measurement stopped, still need to write one more prediction.")

    n_samples = requests.get(
        f"{base_url}/api/storage/measurements/{name}/params/n-samples",
    ).json()

    print(f"Status: {n_samples=} {n_predictions=}")

    # we only want to add predictions for new samples
    if n_samples > n_predictions:
        new_spectra_list = requests.get(
            f"{base_url}/api/storage/measurements/{name}/spectra/processed/absorbance",
            params={
                "index_from": n_samples - 1,
                "index_to": n_samples,
            },
        ).json()
        new_spectrum = new_spectra_list[0]

        # for our prediction, we are only interested in the protein region from ~1500-1700 cm^-1
        spectrum_cropped = [
            s for w, s in zip(wavenumbers, new_spectrum) if 1500 <= w <= 1700
        ]

        # we use a very simple "prediction" here: the absorbance in the protein region multiplied by an arbitrary factor
        prediction = sum(spectrum_cropped) * 1000

        # NOTE: this is using the HTTP PATCH method
        requests.patch(
            f"{base_url}/api/storage/measurements/{name}/predictions",
            params={
                "index": n_samples - 1,
            },
            json={
                "protein": prediction,
            },
        )
        print(f"Added prediction for sample {n_samples}: {prediction:.5f}...")

        n_predictions += 1

    # NOTE: we need to make sure that the sampling and prediction intervals are lower than the measurement time to not loose any samples
    time.sleep(0.5)