A4. Loading sensortran files

This example loads sensortran files. Only single-ended measurements are currently supported. Sensortran files are in binary format. The library requires the *BinaryRawDTS.dat and *BinaryTemp.dat files.

[1]:
import os
import glob
import matplotlib.pyplot as plt
from pandas.plotting import register_matplotlib_converters

register_matplotlib_converters()

from dtscalibration import read_sensortran_files

The example data files are located in ./python-dts-calibration/tests/data.

[2]:
filepath = os.path.join("..", "..", "tests", "data", "sensortran_binary")
print(filepath)
../../tests/data/sensortran_binary
[3]:
filepathlist = sorted(glob.glob(os.path.join(filepath, "*.dat")))
filenamelist = [os.path.basename(path) for path in filepathlist]

for fn in filenamelist:
    print(fn)
15_56_47_BinaryRawDTS.dat
15_56_47_BinaryTemp.dat
16_11_31_BinaryRawDTS.dat
16_11_31_BinaryTemp.dat
16_29_23_BinaryRawDTS.dat
16_29_23_BinaryTemp.dat

We will simply load in the binary files

[4]:
ds = read_sensortran_files(directory=filepath)
3 files were found, each representing a single timestep
Recorded at 11582 points along the cable
The measurement is single ended
/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)

The object tries to gather as much metadata from the measurement files as possible (temporal and spatial coordinates, filenames, temperature probes measurements). All other configuration settings are loaded from the first files and stored as attributes of the DataStore. Sensortran’s data files contain less information than the other manufacturer’s devices, one being the acquisition time. The acquisition time is needed for estimating variances, and is set a constant 1s.

[5]:
print(ds)
<dtscalibration.DataStore>
Sections:                  ()
Dimensions:                (x: 11582, time: 3, trans_att: 0)
Coordinates:
  * x                      (x) float32 -451.4 -450.9 ... 5.408e+03 5.409e+03
    filename               (time) <U25 '15_56_47_BinaryRawDTS.dat' ... '16_29...
    filename_temp          (time) <U23 '15_56_47_BinaryTemp.dat' ... '16_29_2...
    timestart              (time) datetime64[ns] 2009-09-23T22:56:46 ... 2009...
    timeend                (time) datetime64[ns] 2009-09-23T22:56:47 ... 2009...
  * time                   (time) datetime64[ns] 2009-09-23T22:56:47 ... 2009...
    acquisitiontimeFW      (time) timedelta64[ns] 00:00:01 00:00:01 00:00:01
  * trans_att              (trans_att) float64
Data variables:
    st                     (x, time) int32 39040680 39057147 ... 39071213
    ast                    (x, time) int32 39048646 39064414 ... 39407668
    tmp                    (x, time) float64 -273.1 -273.1 ... 82.41 82.71
    referenceTemperature   (time) float64 28.61 29.24 30.29
    st_zero                (time) float64 3.904e+07 3.906e+07 3.907e+07
    ast_zero               (time) float64 3.905e+07 3.907e+07 3.908e+07
    userAcquisitionTimeFW  (time) float64 1.0 1.0 1.0
Attributes: (12/16)
    survey_type:                 2
    hdr_version:                 3
    x_units:                     n/a
    y_units:                     counts
    num_points:                  12000
    num_pulses:                  25000
    ...                          ...
    hdr_size:                    176
    hw_config:                   84

.. and many more attributes. See: ds.attrs

The sensortran files differ from other manufacturers, in that they return the ‘counts’ of the Stokes and anti-Stokes signals. These are not corrected for offsets, which has to be done manually for proper calibration.

Based on the data available in the binary files, the library estimates a zero-count to correct the signals, but this is not perfectly accurate or constant over time. For proper calibration, the offsets would have to be incorporated into the calibration routine.

[6]:
ds
[6]:
<dtscalibration.DataStore>
Sections:                  ()
Dimensions:                (x: 11582, time: 3, trans_att: 0)
Coordinates:
  * x                      (x) float32 -451.4 -450.9 ... 5.408e+03 5.409e+03
    filename               (time) <U25 '15_56_47_BinaryRawDTS.dat' ... '16_29...
    filename_temp          (time) <U23 '15_56_47_BinaryTemp.dat' ... '16_29_2...
    timestart              (time) datetime64[ns] 2009-09-23T22:56:46 ... 2009...
    timeend                (time) datetime64[ns] 2009-09-23T22:56:47 ... 2009...
  * time                   (time) datetime64[ns] 2009-09-23T22:56:47 ... 2009...
    acquisitiontimeFW      (time) timedelta64[ns] 00:00:01 00:00:01 00:00:01
  * trans_att              (trans_att) float64
Data variables:
    st                     (x, time) int32 39040680 39057147 ... 39071213
    ast                    (x, time) int32 39048646 39064414 ... 39407668
    tmp                    (x, time) float64 -273.1 -273.1 ... 82.41 82.71
    referenceTemperature   (time) float64 28.61 29.24 30.29
    st_zero                (time) float64 3.904e+07 3.906e+07 3.907e+07
    ast_zero               (time) float64 3.905e+07 3.907e+07 3.908e+07
    userAcquisitionTimeFW  (time) float64 1.0 1.0 1.0
Attributes: (12/16)
    survey_type:                 2
    hdr_version:                 3
    x_units:                     n/a
    y_units:                     counts
    num_points:                  12000
    num_pulses:                  25000
    ...                          ...
    hdr_size:                    176
    hw_config:                   84

.. and many more attributes. See: ds.attrs
[7]:
ds0 = ds.isel(time=0)

plt.figure()
ds0.st.plot(label="Stokes signal")
plt.axhline(ds0.st_zero.values, c="r", label="'zero' measurement")
plt.legend()
plt.title("")
plt.axhline(c="k")
[7]:
<matplotlib.lines.Line2D at 0x7f9c2bbc6910>
../_images/notebooks_A4Load_sensortran_files_11_1.png

After a correction and rescaling (for human readability) the data will look more like other manufacturer’s devices

[8]:
ds["st"] = (ds.st - ds.st_zero) / 1e4
ds["ast"] = (ds.ast - ds.ast_zero) / 1e4
[9]:
ds.isel(time=0).st.plot(label="Stokes intensity")
ds.isel(time=0).ast.plot(label="anti-Stokes intensity")
plt.legend()
plt.axhline(c="k", lw=1)
plt.xlabel("")
plt.title("")
plt.ylim([-50, 500])
[9]:
(-50.0, 500.0)
../_images/notebooks_A4Load_sensortran_files_14_1.png
[ ]: