Commit 8327fe24 authored by Michal Maciejewski's avatar Michal Maciejewski
Browse files

Added HWC notebooks for IT

parent 79b123da
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -304,4 +304,4 @@
},
"nbformat": 4,
"nbformat_minor": 2
}
\ No newline at end of file
}
%% Cell type:markdown id: tags:
<h1><center>Analysis of a PLI3.a5 HWC in an RB Circuit</center></h1>
<img src = "https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/RB.png" width=75%>
PLI3.A2 is a simple current cycle at I_INTERM_2 during TIME_INTERM_2, while PLI3.A5 is a current cycle with 2 current levels (I_SM, I_INTERM_2) during TIME_INTERM_2 each. PLI3.A5 can be performed with calorimetric measurement (original purpose). In case of calorimetric measurement, the cryogenic cooling must be stable and maintained constant during the whole cycle. The aim of this test is to check the performance of the current leads and also the splices resistance, and, in case of calorimetric measurements, to detect abnormal heating in the magnets environment.
<img src="https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/PLI3_current.png" width=50%>
The required analysis and signatures are listed below.
|Responsible|Type of analysis|Criterion|
|-----------|----------------|---------|
|-|Automatic analysis on earth current and error current|I_EARTH_PLI2_S1 < I_EARTH_MAX and I_ERR_PLI2_S1 < I_ERR_MAX|
|MP3|Splice signals|From board A and board B separately R_bus_max <3 nOhm. Individual R_splice_max<0.5nOhm R_mag<50 nOhm|
|MP3|Current lead|46 < TT891A < 54K; Abs(U_RES)< 40mV; and no drift Abs(U_HTS) < 0.5mV|
source: Powering Procedure and Acceptance Criteria for the 13 kA Dipole Circuits, MP3 Procedure, <a href="https://edms.cern.ch/document/874713/5.1">https://edms.cern.ch/document/874713/5.1</a>
%% Cell type:markdown id: tags:
# Analysis Assumptions
- We consider standard analysis scenarios, i.e., all signals can be queried. If a signal is missing, an analysis can raise a warning and continue or an error and abort the analysis.
- In case a signal is not needed for the analysis, a particular analysis is skipped. In other words, all signals have to be available in order to perform an analysis.
- It is recommended to execute each cell one after another. However, since the signals are queried prior to analysis, any order of execution is allowed. In case an analysis cell is aborted, the following ones may not be executed (e.g. I\_MEAS not present).
# Plot Convention
- Scales are labeled with signal name followed by a comma and a unit in square brackets, e.g., I_MEAS, [A].
- If a reference signal is present, it is represented with a dashed line.
- If the main current is present, its axis is on the left. Remaining signals are attached to the axis on the right. The legend of these signals is located on the lower left and upper right, respectively.
- The grid comes from the left axis.
- The title contains timestamp, circuit name, and signal name allowing to re-access the signal.
- The plots assigned to the left scale have colors: blue (C0) and orange (C1). Plots presented on the right have colors red (C2) and green (C3).
- Each plot has an individual time-synchronization mentioned explicitly in the description.
- If an axis has a single signal, then the color of the label matches the signal's color. Otherwise, the label color is black.
%% Cell type:markdown id: tags:
# 0. Initialise Working Environment
## 0.1. Import Necessary Packages
%% Cell type:code id: tags:
``` python
import io
import re
import sys
import pandas as pd
# NXCALS libraries
from cern.nxcals.pyquery.builders import *
# lhc-sm-api
from lhcsmapi.Time import Time
from lhcsmapi.Timer import Timer
# GUI
from lhcsmapi.gui.hwc.HwcBrowser import HwcBrowser
# Query
from lhcsmapi.pyedsl.QueryBuilder import QueryBuilder
from lhcsmapi.analysis.RbCircuitQuery import RbCircuitQuery
# Analysis
from lhcsmapi.pyedsl.AssertionBuilder import AssertionBuilder
from lhcsmapi.pyedsl.ResistanceBuilder import ResistanceBuilder
from lhcsmapi.pyedsl.SignalTransformationBuilder import get_current_plateau_start_end # Could this come from the BusbarResistance?
```
%% Cell type:markdown id: tags:
## 0.2. LHCSMAPI Version
%% Cell type:code id: tags:
``` python
import lhcsmapi
print('Analysis executed with lhcsmapi version: {}'.format(lhcsmapi.__version__))
```
%% Output
Analysis executed with lhcsmapi version: 1.3.225
Analysis executed with lhcsmapi version: 1.3.266
%% Cell type:markdown id: tags:
## 0.3. Notebook Version
%% Cell type:code id: tags:
``` python
with io.open("../__init__.py", "rt", encoding="utf8") as f:
version = re.search(r'__version__ = "(.*?)"', f.read()).group(1)
print('Analysis executed with lhc-sm-hwc notebooks version: {}'.format(version))
```
%% Output
Analysis executed with lhc-sm-hwc notebooks version: 1.0.3
%% Cell type:markdown id: tags:
# 1. Select PLI3.a5 HWC Test
- Choose a circuit name in order to display HWC test with, campaign name as well as start and end time
%% Cell type:code id: tags:
``` python
circuit_type = 'RB'
hwc_test = 'PLI3.a5'
hwc_test_history_df = pd.read_csv('/eos/project/l/lhcsm/hwc/RB/hwc_test_history.csv')
hwcb = HwcBrowser(hwc_test_history_df, circuit_type, hwc_test)
display(hwcb.widget)
```
%% Output
%% Cell type:markdown id: tags:
# 2. Query All Signals Prior to Analysis
%% Cell type:code id: tags:
``` python
circuit_name = hwcb.get_circuit_name()
t_start = hwcb.get_start_time()
t_end = hwcb.get_end_time()
with Timer():
# I_MEAS
i_meas_nxcals_df = QueryBuilder().with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end) \
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system='PC', signal='I_MEAS') \
.signal_query() \
.synchronize_time() \
.convert_index_to_sec().dfs[0]
# LEADS
u_res_nxcals_dfs = QueryBuilder().with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end) \
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='U_RES') \
.signal_query() \
.synchronize_time() \
.convert_index_to_sec() \
.dfs
u_hts_nxcals_dfs = QueryBuilder().with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end)\
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='U_HTS') \
.signal_query()\
.synchronize_time() \
.convert_index_to_sec() \
.filter_median() \
.dfs
tt891a_nxcals_dfs = QueryBuilder().with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end) \
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='TT891A') \
.signal_query() \
.synchronize_time() \
.convert_index_to_sec() \
.filter_median() \
.dfs
tt893_nxcals_dfs = QueryBuilder().with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end) \
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='TT893') \
.signal_query()\
.synchronize_time() \
.convert_index_to_sec() \
.filter_median() \
.dfs
cv891_nxcals_dfs = QueryBuilder().with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end) \
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='CV891') \
.signal_query() \
.synchronize_time() \
.convert_index_to_sec() \
.filter_median() \
.dfs
i_meas_raw_df = QueryBuilder().with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end) \
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system='PC', signal='I_MEAS') \
.signal_query() \
.dfs[0]
plateau_timing_df = get_current_plateau_start_end(i_meas_raw_df, i_meas_threshold=500)
# Label columns with a function for current
from pyspark.sql.functions import udf
from pyspark.sql.types import IntegerType
import numpy as np
plateau_start = plateau_timing_df['plateau_start'].values
plateau_end = plateau_timing_df['plateau_end'].values
def translate(timestamp):
mask_plateau = (timestamp >= plateau_start) & (timestamp <= plateau_end)
index_plateau = np.where(mask_plateau == True)[0]
if len(index_plateau) > 0:
return int((index_plateau[0]+1))
return -1
translate_udf = udf(translate, IntegerType())
i_meas_feature_df = QueryBuilder() \
.with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end) \
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system='PC', signal='I_MEAS') \
.feature_query(['mean', 'std', 'max', 'min', 'count'], function=translate_udf) \
.sort_values(by='class') \
.df
u_res_feature_df = QueryBuilder() \
.with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end) \
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system='BUSBAR', signal='U_RES', wildcard={'BUSBAR': '*'}) \
.feature_query(['mean', 'std', 'max', 'min', 'count'], function=translate_udf) \
.sort_busbar_location(circuit_type, circuit_name) \
.df
u_mag_feature_df = QueryBuilder() \
.with_nxcals(spark) \
.with_duration(t_start=t_start, t_end=t_end) \
.with_circuit_type(circuit_type) \
.with_metadata(circuit_name=circuit_name, system='BUSBAR', signal='U_MAG', wildcard={'BUSBAR': '*'}) \
.feature_query(['mean', 'std', 'max', 'min', 'count'], function=translate_udf) \
.sort_busbar_location(circuit_type, circuit_name) \
.df
```
%% Cell type:markdown id: tags:
# 3. Power Converter
## 3.1. Plot of the Power Converter Main Current
*QUERY*:
|Variable Name |Variable Type |Variable Unit |Database|Comment
|---------------|---------------|---------------|--------|------|
|i_meas_df | DataFrame | A |NXCALS| Main power converter current, I_MEAS|
*ANALYSIS*:
- Calculation of the duration of current plateaus
*PLOT*:
- The main power converter current (reference and actual) on the left axis, I_MEAS
- t = 0 s corresponds to the start of the test
- Orange box(es) represent period(s) of time with constant current used for calculation of busbar resistance and DFB thresholds
%% Cell type:code id: tags:
``` python
ax = i_meas_nxcals_df.plot(figsize=(30, 10), grid=True)
for index, row in plateau_timing_df.iterrows():
ax.axvspan(xmin=row['plateau_start_sync'], xmax=row['plateau_end_sync'], facecolor='xkcd:goldenrod')
ax.set_xlabel("time, [s]", fontsize=15)
ax.set_ylabel("I_MEAS, [A]", fontsize=15)
ax.tick_params(labelsize=15)
```
%% Cell type:markdown id: tags:
# 4. Busbar
## 4.1. Busbar Resistance
*QUERY*:
|Variable Name |Variable Type |Variable Unit |Database|Comment
|---------------|---------------|---------------|--------|------|
|i_meas_feature_df | DataFrame | A |NXCALS| Mean, std, and count values of the main power converter current labeled (1,2,...) at the current plateaus, I_MEAS|
|u_res_feature_df | DataFrame | V |NXCALS| Mean, std, and count values of the busbar voltage labeled (1,2,...) at the current plateaus, U_RES|
*ANALYSIS*:
- Calculation of the busbar resistance as the slope of a linear fit of U,I curve obtained from the corresponding mean alues of the voltage and current
- The resistance should be below 3 nOhm
*PLOT*:
- The busbar resistance, R
- The green box denotes the validity region of the busbar resostance (0, 3] nOhm
%% Cell type:code id: tags:
``` python
res_busbar_df = ResistanceBuilder().with_busbar_voltage(u_res_feature_df) \
.with_busbar_current(i_meas_feature_df) \
.calculate_mean_resistance(circuit_type).df
# Plot
res_outliers_df = AssertionBuilder().with_feature(res_busbar_df) \
.has_min_max_value(feature='R_RES', min_value=0, max_value=3e-9) \
.show_plot(xlabel='Busbar, [-]', ylabel='R_RES (Calculated), [V]') \
.get_features_outside_range()
```
%% Cell type:markdown id: tags:
## 4.2. Magnet Resistance
*QUERY*:
|Variable Name |Variable Type |Variable Unit |Database|Comment
|---------------|---------------|---------------|--------|------|
|i_meas_feature_df | DataFrame | A |NXCALS| Mean, std, and count values of the main power converter current labeled (1,2,...) at the current plateaus, I_MEAS|
|u_mag_feature_df | DataFrame | V |NXCALS| Mean, std, and count values of the magnet voltage labeled (1,2,...) at the current plateaus, U_RES|
*ANALYSIS*:
- Calculation of the magnet resistance as the slope of a linear fit of U,I curve obtained from the corresponding mean alues of the voltage and current
*CRITERIA*
- The resistance should be below 50 nOhm
*PLOT*:
- The busbar resistance, R
- The green box denotes the validity region of the magnet resistance (0, 50] nOhm
%% Cell type:code id: tags:
``` python
res_magnet_df = ResistanceBuilder().with_busbar_voltage(u_mag_feature_df) \
.with_busbar_current(i_meas_feature_df) \
.calculate_mean_resistance(circuit_type).df
# Plot
res_outliers_df = AssertionBuilder().with_feature(res_magnet_df) \
.has_min_max_value(feature='R_MAG', min_value=0, max_value=50e-9) \
.show_plot(xlabel='Magnet, [-]', ylabel='R_MAG (Calculated), [V]') \
.get_features_outside_range()
```
%% Cell type:markdown id: tags:
# 5. DFB
## 5.1. DFB Voltage - U_RES
U_RES - Voltage of the resistive part of the current lead (QPS threshold at 100 mV, 100 ms)
*QUERY*:
|Variable Name |Variable Type |Variable Unit |Database|Comment
|---------------|---------------|---------------|--------|------|
|u_res_dfs |list of DataFrames |V |NXCALS|Voltage of the resistive part of even and odd leads, U_RES|
*ANALYSIS*:
- At constant current, U_RES must stay constant (no drift < 2mV/h)
*PLOT*:
- Voltage of the normal conducting leads on the right axis, U_RES
- t = 0 s corresponds to the start time of the test
%% Cell type:code id: tags:
``` python
AssertionBuilder().with_signal(u_res_nxcals_dfs) \
.with_time_range(t_start=plateau_timing_df['plateau_start_sync'], t_end=plateau_timing_df['plateau_end_sync']) \
.has_min_max_slope(slope_min=-2, slope_max=2) \
.show_plot(ylabel='U_RES, [V]')
```
%% Cell type:markdown id: tags:
## 5.2. DFB Voltage - U_HTS
U_HTS - Voltage of the HTS part of the current lead (QPS threshold at 1 mV, 100 ms)
*QUERY*:
|Variable Name |Variable Type |Variable Unit |Database|Comment
|---------------|---------------|---------------|--------|------|
|u_hts_dfs |list of DataFrames |V |NXCALS|Voltage of the HTS part of even and odd leads, U_HTS|
*CRITERIA*:
- Voltage must stay below 50% of the threshold -> Abs(U_HTS) < 0.5 mV
*PLOT*:
- Voltage of the HTS leads on the left axis, U_HTS
- t = 0 s corresponds to the start time of the test
%% Cell type:code id: tags:
``` python
AssertionBuilder().with_signal(u_hts_nxcals_dfs) \
.with_time_range(t_start=plateau_timing_df['plateau_start_sync'], t_end=plateau_timing_df['plateau_end_sync']) \
.has_min_max_slope(slope_min=-0.5, slope_max=0.5) \
.show_plot(ylabel='U_HTS')
```
%% Cell type:markdown id: tags:
## 5.3. DFB Temperature - TT893.TEMPERATURECALC
TT893.TEMPERATURECALC - Temperature at the top of the current lead (supposed to be at the room temperature)
*QUERY*:
- NXCALS for temperature at the top of the current lead (even and odd), TT893.TEMPERATURECALC
*INPUT*:
|Variable Name |Variable Type |Variable Unit |Database|Comment
|---------------|---------------|---------------|--------|------|
|tt893_dfs |list of DataFrames |K |NXCALS|Temperature at the top of the current lead, TT893.TEMPERATURECALC|
*CRITERIA*:
- Temperature must be over the dew point, but not overheated -> 280 K < TT893 < 320 K, even without current
*PLOT*:
- Main power converter current on the left axis, I_MEAS
- Temperature at the top of the current lead on the right axis, TT893.TEMPERATURECALC
- Green box denotes the temperature validity region [280, 320] K of the temperature at the top of the current lead
- t = 0 s corresponds to the start time of the test
%% Cell type:code id: tags:
``` python
AssertionBuilder() \
.with_signal(tt893_nxcals_dfs) \
.has_min_max_value(value_min=280, value_max=320) \
.show_plot(ylabel='TT893.TEMPERATURECALC [K]')
```
%% Cell type:markdown id: tags:
## 5.4. DFB Temperature - TT891A.TEMPERATURECALC
TT891A.TEMPERATURECALC - Temperature between the HTS and resistive part of the current leads (supposed to be regulated around 50 K)
*QUERY*:
|Variable Name |Variable Type |Variable Unit |Database|Comment
|---------------|---------------|---------------|--------|------|
|tt891a_dfs |list of DataFrames |K |NXCALS|Temperature between the HTS and resistive part of the current lead, TT891A.TEMPERATURECALC|
*CRITERIA*:
- Temperature must be regulated around 50 K -> 46 K < TT891A < 54 K, even without current
*PLOT*:
For odd and even leads
- Main power converter current, I_MEAS
- Temperature between the HTS and resistive part of the current lead on the right axis, TT891A.TEMPERATURECALC
- t = 0 s corresponds to the start time of the test
%% Cell type:code id: tags:
``` python
AssertionBuilder().with_signal(tt891a_nxcals_dfs) \
.has_min_max_value(value_min=46, value_max=54) \
.show_plot(ylabel='TT891A.TEMPERATURECALC [K]')
```
%% Cell type:markdown id: tags:
## 5.5. DFB Valve Regulation - CV891.POSST
CV891.POSST - Valve for regulation of TT891A
*QUERY*:
|Variable Name |Variable Type |Variable Unit |Database|Comment
|---------------|---------------|---------------|--------|------|
|cv891_nxcals_dfs |list of DataFrames |% |NXCALS|Valve for regulation of TT891A, CV891.POSST|
*CRITERIA*:
- The valve must be opened (>2%), but not fully (<50%)
- The valve variation (defined as difference between the maximum and minimum value) shouldn't exceed 8% at constant current (the ramp of the current is excluded this criterion)
*PLOT*:
- Main power converter current, I_MEAS
- Valve for regulation of TT891A, CV891.POSST
- t = 0 s corresponds to the start time of the test
- Green box denotes the valve opening validity region [2, 50] % of the TT891A temperature regulation
%% Cell type:code id: tags:
``` python
AssertionBuilder().with_signal(cv891_nxcals_dfs) \
.has_min_max_value(value_min=2, value_max=50) \
.show_plot(ylabel='CV891.POSST [%]')
```
%% Cell type:code id: tags:
``` python
AssertionBuilder().with_signal(cv891_nxcals_dfs) \
.with_time_range(t_start=plateau_timing_df['plateau_start_sync'], t_end=plateau_timing_df['plateau_end_sync']) \
.has_min_max_variation(variation_min_max=8) \
.show_plot(ylabel='CV891')
```
%% Cell type:markdown id: tags:
# 6. Final Report
%% Cell type:code id: tags:
``` python
campaign = hwcb.get_campaign()
file_name_html = '{}-{}_report.html'.format(Time.to_datetime(t_start).strftime("%Y.%m.%d_%H%M%S.%f"), Time.to_datetime(t_end).strftime("%Y.%m.%d_%H%M%S.%f"))
!{sys.executable} -m jupyter nbconvert --to html $'AN_RB_PLI3.a5.ipynb' --output /eos/project/l/lhcsm/hwc/RB/$circuit_name/$hwc_test/$campaign/$file_name_html
```
%% Cell type:code id: tags:
``` python
```
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment