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();

[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
[ ]: