12. Creating a DataStore from numpy arrays

The goal of this notebook is to demonstrate how to create a DataStore from scratch. This can be useful if your device is not supported or if you would like to integrate the dtscalibration library in your current routine.

[1]:
import numpy as np
import os
import matplotlib.pyplot as plt
import xarray as xr

from dtscalibration import DataStore, read_silixa_files

For a DataStore object, a few things are needed:

  • timestamps

  • Stokes signal

  • anti-Stokes signal

  • x (length along fiber)

Let’s grab the data from an existing silixa dataset:

[2]:
filepath = os.path.join("..", "..", "tests", "data", "single_ended")

ds_silixa = read_silixa_files(directory=filepath, silent=True)
/home/docs/checkouts/readthedocs.org/user_builds/python-dts-calibration/envs/latest/lib/python3.9/site-packages/dtscalibration/datastore.py:81: UserWarning: Converting non-nanosecond precision timedelta values to nanosecond precision. This behavior can eventually be relaxed in xarray, as it is an artifact from pandas which is now beginning to support non-nanosecond precision values. This warning is caused by passing non-nanosecond np.datetime64 or np.timedelta64 values to the DataArray or Variable constructor; it can be silenced by converting the values to nanosecond precision ahead of time.
  super().__init__(*args, **kwargs)
/home/docs/checkouts/readthedocs.org/user_builds/python-dts-calibration/envs/latest/lib/python3.9/site-packages/dtscalibration/datastore.py:81: UserWarning: Converting non-nanosecond precision timedelta values to nanosecond precision. This behavior can eventually be relaxed in xarray, as it is an artifact from pandas which is now beginning to support non-nanosecond precision values. This warning is caused by passing non-nanosecond np.datetime64 or np.timedelta64 values to the DataArray or Variable constructor; it can be silenced by converting the values to nanosecond precision ahead of time.
  super().__init__(*args, **kwargs)

We will get all the numpy arrays from this DataStore to create a new one from ‘scratch’.

Let’s start with the most basic data:

[3]:
x = ds_silixa.x.values
time = ds_silixa.time.values
ST = ds_silixa.st.values
AST = ds_silixa.ast.values

Now this data has to be inserted into an xarray Dataset

[4]:
ds = xr.Dataset()
ds["x"] = ("x", x)
ds["time"] = ("time", time)
ds["st"] = (["x", "time"], ST)
ds["ast"] = (["x", "time"], AST)
[5]:
ds = DataStore(ds)
print(ds)
<dtscalibration.DataStore>
Sections:                  ()
Dimensions:    (x: 1461, time: 3, trans_att: 0)
Coordinates:
  * x          (x) float64 -80.74 -80.62 -80.49 -80.36 ... 104.6 104.7 104.8
  * time       (time) datetime64[ns] 2018-05-04T12:22:17.710000 ... 2018-05-0...
  * trans_att  (trans_att) float64
Data variables:
    st         (x, time) float64 -0.8058 0.4287 -0.513 ... 27.99 27.83 28.81
    ast        (x, time) float64 -0.2459 -0.5932 0.1111 ... 36.2 35.7 35.16
Attributes:
    _sections:  null\n...\n

For calibration, a few more paramaters are needed:

  • acquisition time (for calculating residuals for WLS calibration)

  • reference temperatures

  • a double ended flag

We’ll put these into the custom DataStore:

[6]:
ds["acquisitiontimeFW"] = ds_silixa["acquisitiontimeFW"].values
ds["userAcquisitionTimeFW"] = ds_silixa["acquisitiontimeFW"].values
ds["temp1"] = ds_silixa["probe1Temperature"]
ds["temp2"] = ds_silixa["probe2Temperature"]

ds.attrs["isDoubleEnded"] = "0"

Now we can calibrate the data as usual (ordinary least squares in this example).

[7]:
ds = ds.sel(x=slice(-30, 101))
sections = {
    "temp1": [slice(20, 25.5)],  # warm bath
    "temp2": [slice(5.5, 15.5)],  # cold bath
}
ds.sections = sections

st_var, resid = ds.variance_stokes_constant(st_label="st")
ast_var, _ = ds.variance_stokes_constant(st_label="ast")
ds.calibration_single_ended(st_var=st_var, ast_var=ast_var)

ds.isel(time=0).tmpf.plot();
../_images/notebooks_12Datastore_from_numpy_arrays_12_0.png
[8]:
ds
/home/docs/checkouts/readthedocs.org/user_builds/python-dts-calibration/envs/latest/lib/python3.9/site-packages/xarray/core/dataarray.py:861: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
  return key in self.data
/home/docs/checkouts/readthedocs.org/user_builds/python-dts-calibration/envs/latest/lib/python3.9/site-packages/xarray/core/dataarray.py:861: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
  return key in self.data
[8]:
<dtscalibration.DataStore>
Sections:
    temp1                  ( 18.02 +/- 0.00°C)      20.00 - 25.50
    temp2                  (  6.62 +/- 0.00°C)      5.50 - 15.50
Dimensions:                (x: 1030, time: 3, trans_att: 0,
                            acquisitiontimeFW: 3, userAcquisitionTimeFW: 3,
                            comp_fw: 12, params1: 5, params2: 5)
Coordinates:
  * x                      (x) float64 -29.9 -29.78 -29.65 ... 100.6 100.8 100.9
  * time                   (time) datetime64[ns] 2018-05-04T12:22:17.710000 ....
  * trans_att              (trans_att) float64
  * acquisitiontimeFW      (acquisitiontimeFW) timedelta64[ns] 00:00:30 ... 0...
  * userAcquisitionTimeFW  (userAcquisitionTimeFW) timedelta64[ns] 00:00:30 ....
    filename               (time) <U31 'channel 2_20180504132202074.xml' ... ...
    filename_tstamp        (time) int64 20180504132202074 ... 20180504132303723
    timestart              (time) datetime64[ns] 2018-05-04T12:22:02.710000 ....
    timeend                (time) datetime64[ns] 2018-05-04T12:22:32.710000 ....
  * comp_fw                (comp_fw) object 'dT_dst' 'dT_dast' ... 'dta_ddalpha'
Dimensions without coordinates: params1, params2
Data variables: (12/21)
    st                     (x, time) float64 6.267e+03 6.272e+03 ... 2.619e+03
    ast                    (x, time) float64 5.473e+03 5.473e+03 ... 2.09e+03
    temp1                  (time) float32 18.02 18.02 18.02
    temp2                  (time) float32 6.62 6.617 6.617
    gamma                  float64 481.9
    gamma_var              float64 0.4209
    ...                     ...
    talpha_fw_full_var     (x, time) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
    tmpf                   (x, time) float64 25.46 25.36 25.47 ... 10.1 10.18
    var_fw_da              (comp_fw, x, time) float64 0.0003519 ... 0.0
    tmpf_var               (x, time) float64 0.006567 0.006543 ... 0.01329
    p_val                  (params1) float64 481.9 -2.073e-05 1.478 1.477 1.477
    p_cov                  (params1, params2) float64 0.4209 ... 5.666e-06
Attributes:
    _sections:      temp1:\n- !!python/object/apply:builtins.slice\n  - 20.0\...
    isDoubleEnded:  0
[ ]: