[2]:
import straxen
import matplotlib.pyplot as plt
2026-01-13 09:41:14,117 - admix - WARNING - Initializing utilix DB failed. You cannot do database operations
DB initialization failed

Tutorial SCADA-Python

In this notebook we show the basic functionalities of our SCADA interface. As a first step we have to initialize the interface. Please note that this is only possible for XENON members who are working on Midway. The straxen client will request a security token from our slowcontrol webservice. This token is only valid 3 hrs.

[3]:
sc = straxen.SCADAInterface()
/home/gvolta/.local/lib/python3.11/site-packages/utilix/mongo_storage.py:378: DownloadWarning: Downloading PMTmap_SCADA.json to ./resource_cache/694d47e7cf82ecd0f80b11bed94acbb9
  warn(f"Downloading {config_name} to {destination_path}", DownloadWarning)
Received token, the token is valid for 3 hrs.
 from 13.01. 15:41:17 UTC
 till 13.01. 18:41:17 UTC
We will automatically refresh the token for you :). Have a nice day and a fruitful analysis!

After getting the token we can query some parameters. Lets try to get some data for a certain time range and set of different parameters. The parameters can be specified via a dictionary which takes as values the Historian database names of the required parameter and some short name as key. Let us query as an example some different parameters:

[4]:
parameters = {
    "para1": "XE1T.CTPC.Board06.Chan011.VMon",
    "para2": "XE1T.CRY_TE101_TCRYOBOTT_AI.PI",
    "para3": "XE1T.CRY_PT101_PCHAMBER_AI.PI",
    "para4": "XE1T.GEN_CE911_SLM1_HMON.PI",
    "para5": "XE1T.CRY_FCV104FMON.PI",
}

Feel free to give in your own analysis more meaningful parameter keys. Since it can be quite annoying to look up all those parameter names we also offer some functions which can return the corresponding names. For example for our PMTs the following function returns the high-voltage and current names:

[5]:
pmts = sc.find_pmt_names(range(10, 12), hv=True, current=True)
pmts
[5]:
{'PMT10_HV': 'XE1T.CTPC.BOARD03.CHAN008.VMON',
 'PMT10_I': 'XE1T.CTPC.BOARD03.CHAN008.IMON',
 'PMT11_HV': 'XE1T.CTPC.BOARD04.CHAN002.VMON',
 'PMT11_I': 'XE1T.CTPC.BOARD04.CHAN002.IMON'}

Beside the parameters we also have to specify the time range we would like to query. Since straxen handles time intervals in unix time nano-seconds it is natural to do the same here (Do not worry we can also query times in a human readable way which is shown below).

[6]:
start = 1709682275000000000
end = 1709736527000000000

df = sc.get_scada_values(parameters, start=start, end=end, every_nth_value=1)

As the name already suggest the data is returned as a simple data DataFrame:

[7]:
df.head()
[7]:
para1 para2 para3 para4 para5
time UTC
2024-03-05 23:44:35+00:00 1211.0 -94.566826 2.041337 -1.1 3.572651
2024-03-05 23:44:36+00:00 1211.0 -94.564354 2.041424 -1.1 3.572651
2024-03-05 23:44:37+00:00 1211.0 -94.559937 2.041635 -1.1 3.572651
2024-03-05 23:44:38+00:00 1211.0 -94.554665 2.041380 -1.1 3.572651
2024-03-05 23:44:39+00:00 1211.0 -94.551048 2.041904 -1.1 3.572651
[8]:
plt.plot(df["para2"])
plt.xlabel("Time [UTC]")
plt.ylabel("Temperature at TE101 [°C]")
plt.xticks(rotation=45, horizontalalignment="right")
plt.show()
../_images/tutorials_ScadaInterfaceExample_11_0.png

Querying data in a human readable way:

Querying data with timestamps in nano-seconds unix times can be a bit tedious, especially, if you are not working with any straxen data. In order to allow a query in a human readable way we added some widgets:

[9]:
tw = straxen.TimeWidgets()

After initialization you can render the widgets via…

[10]:
tw.create_widgets()
[10]:

… and select any time range you would like. After specifying a time you can get the start and end time via:

[11]:
start, end = tw.get_start_end()
print(start, end)
1768311900000000000 1768315500000000000

In addition to this time widget we also offer analyst to query data via run_ids. This can be quite handy if you would like to correlate your data with other detector parameters. Further, you can also query data with a coarser binning e.g. every 300 seconds. Before we can use run_ids though we have to specify the context we are working with:

[12]:
st = straxen.contexts.xenonnt_online()
sc.context = st
You specified _auto_append_rucio_local=True and you are not on dali compute nodes, so we will add the following rucio local path: /project/lgrandi/rucio/
[13]:
df = sc.get_scada_values(parameters, run_id="020280", every_nth_value=10)

Changing the time zone

You can also easily change the timezone of your data if needed:

[14]:
dfcet = straxen.convert_time_zone(df, "CET")
dfcet.head()
[14]:
para1 para2 para3 para4 para5
time CET
2021-05-24 15:03:52+02:00 1211.0 -96.117081 1.887699 -16.963255 4.632631
2021-05-24 15:04:02+02:00 1211.0 -96.118813 1.888073 -16.958317 4.983373
2021-05-24 15:04:12+02:00 1211.0 -96.130096 1.887873 -16.958286 4.983373
2021-05-24 15:04:22+02:00 1211.0 -96.134781 1.888285 -16.958317 5.216488
2021-05-24 15:04:32+02:00 1211.0 -96.126343 1.887630 -16.958317 5.216488
[15]:
dfcet["para2"].plot()
plt.xlabel("Time [CET]")
plt.ylabel("Temperature at TE101 [°C]")
plt.xticks(rotation=45, horizontalalignment="right")
plt.show()
../_images/tutorials_ScadaInterfaceExample_23_0.png
[ ]: