Commit 619ccbd8 authored by Thibaud Marie Eric Buffet's avatar Thibaud Marie Eric Buffet
Browse files

remove typo on the lhcsmnb.utils.get_at with dataframe as parameter

parent 6c1ff8e9
Pipeline #3163588 passed with stage
in 25 seconds
%% Cell type:markdown id: tags:
<h1><center>Analysis of an FPA in an RB Circuit</center></h1>
<img src="https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/RB.png" width=75%>
source: Powering Procedure and Acceptance Criteria for the 13 kA Dipole Circuits, MP3 Procedure, <a href="https://edms.cern.ch/document/874713">https://edms.cern.ch/document/874713</a>
%% Cell type:markdown id: tags:
Original text: 2020-2021 (Michal); Last corrections: June-2021 (Zinur)
%% 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.
- 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
%% Cell type:code id: tags:
``` python
# External libraries
print('Loading (1/15)'); import sys, warnings, datetime
print('Loading (2/15)'); from IPython.display import display, Javascript, HTML, clear_output
print('Loading (3/15)'); import pandas as pd
print('Loading (4/15)'); import numpy as np
# Internal libraries
print('Loading (5/15)'); import lhcsmapi
print('Loading (6/15)'); from lhcsmapi.Time import Time
print('Loading (7/15)'); from lhcsmapi.Timer import Timer
print('Loading (8/15)'); from lhcsmapi.analysis.RbCircuitQuery import RbCircuitQuery
print('Loading (9/15)'); from lhcsmapi.analysis.RbCircuitAnalysis import RbCircuitAnalysis
print('Loading (10/15)'); from lhcsmapi.analysis.report_template import apply_report_template
print('Loading (11/15)'); from lhcsmapi.analysis.expert_input import get_expert_decision
print('Loading (12/15)'); from lhcsmapi.gui.DateTimeBaseModule import DateTimeBaseModule
print('Loading (13/15)'); from lhcsmapi.gui.pc.FgcPmSearchModuleMediator import FgcPmSearchModuleMediator
print('Loading (14/15)'); from lhcsmnb.parameters import are_all_parameters_injected, NbType
print('Loading (15/15)'); import lhcsmnb.utils
clear_output()
lhcsmapi.get_lhcsmapi_version()
lhcsmapi.get_lhcsmhwc_version('../__init__.py')
```
%% Cell type:markdown id: tags:
# 1. Select FGC Post Mortem Entry
%% Cell type:markdown id: tags:skip_cell
In order to perform the analysis of a FPA in an RB circuit please:
1. Select circuit name (e.g., RB.A12)
2. Choose start and end time
3. Choose analysis mode (Automatic by default)
Once these inputs are provided, click 'Find FGC PM entries' button. This will trigger a search of the PM database in order to provide a list of timestamps of FGC events associated with the selected circuit name for the provided period of time. Select one timestamp from the 'FGC PM Entries' list to be processed by the following cells.
**Note that 24 hours is the maximum duration of a single PM query for an event. To avoid delays in querying events, please restrict your query duration as much as possible.**
%% Cell type:code id: tags:
``` python
# Pre-define a time window for search the FPA-events, by default 48 hours from now
search_end = datetime.datetime.now().astimezone()
search_start = search_end - datetime.timedelta(days = 2)
```
%% Cell type:code id: tags:parameters
``` python
circuit_type = 'RB'
fgc_pm_search = FgcPmSearchModuleMediator(DateTimeBaseModule(start_date_time = search_start.isoformat(sep=' '), end_date_time = search_end.isoformat(sep=' ')), circuit_type=circuit_type)
```
%% Cell type:markdown id: tags:
# 2. Query All Signals Prior to Analysis
%% Cell type:code id: tags:skip_output
``` python
with Timer():
if not are_all_parameters_injected(NbType.FGC, locals()):
timestamp_fgc = fgc_pm_search.get_fgc_timestamp()
circuit_name = fgc_pm_search.get_fgc_circuit()
author = fgc_pm_search.get_author()
is_automatic = fgc_pm_search.is_automatic_mode()
rb_query = RbCircuitQuery(circuit_type, circuit_name, max_executions=45)
# PIC
timestamp_pic = rb_query.find_timestamp_pic(timestamp_fgc, spark=spark)
# PC Current
i_meas_df, i_a_df, i_earth_df, i_earth_pcnt_df, i_ref_df = rb_query.query_pc_pm(timestamp_fgc, timestamp_fgc, signal_names=['I_MEAS', 'I_A', 'I_EARTH', 'I_EARTH_PCNT', 'I_REF'])
timestamp_fgc_ref = rb_query.get_timestamp_ref(col='fgcPm')
i_meas_ref_df, i_earth_ref_df, i_earth_pcnt_ref_df = rb_query.query_pc_pm(timestamp_fgc_ref, timestamp_fgc_ref, signal_names=['I_MEAS', 'I_EARTH', 'I_EARTH_PCNT'])
# EE Voltage
source_timestamp_ee_odd_df = rb_query.find_source_timestamp_ee(timestamp_fgc, system='EE_ODD')
timestamp_ee_odd = lhcsmnb.utils.get_at(source_timestamp_ee_odd_df.loc, 0, 'timestamp')
timestamp_ee_odd = lhcsmnb.utils.get_at(source_timestamp_ee_odd_df, 0, 'timestamp')
source_ee_odd = lhcsmnb.utils.get_at(source_timestamp_ee_odd_df, 0, 'source')
u_dump_res_odd_df = rb_query.query_ee_u_dump_res_pm(timestamp_ee_odd, timestamp_fgc, system='EE_ODD', signal_names=['U_DUMP_RES'])[0]
source_timestamp_ee_even_df = rb_query.find_source_timestamp_ee(timestamp_fgc, system='EE_EVEN')
timestamp_ee_even = lhcsmnb.utils.get_at(source_timestamp_ee_even_df, 0, 'timestamp')
source_ee_even = lhcsmnb.utils.get_at(source_timestamp_ee_even_df, 0, 'source')
u_dump_res_even_df = rb_query.query_ee_u_dump_res_pm(timestamp_ee_even, timestamp_fgc, system='EE_EVEN', signal_names=['U_DUMP_RES'])[0]
# EE TEMPERATURE
t_res_odd_0_df = rb_query.query_ee_t_res_pm(lhcsmnb.utils.get_at(source_timestamp_ee_odd_df, 0, 'timestamp'), timestamp_fgc, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_ODD')
if len(source_timestamp_ee_odd_df) > 1:
t_res_odd_1_df = rb_query.query_ee_t_res_pm(lhcsmnb.utils.get_at(source_timestamp_ee_odd_df, 1, 'timestamp'), timestamp_fgc, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_ODD')
else:
t_res_odd_1_df = [pd.DataFrame(columns=['T_RES_BODY_1']), pd.DataFrame(columns=['T_RES_BODY_2']), pd.DataFrame(columns=['T_RES_BODY_3'])]
t_res_even_0_df = rb_query.query_ee_t_res_pm(lhcsmnb.utils.get_at(source_timestamp_ee_even_df, 0, 'timestamp'), timestamp_fgc, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_EVEN')
if len(source_timestamp_ee_even_df) > 1:
t_res_even_1_df = rb_query.query_ee_t_res_pm(lhcsmnb.utils.get_at(source_timestamp_ee_even_df, 1, 'timestamp'), timestamp_fgc, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_EVEN')
else:
t_res_even_1_df = [pd.DataFrame(columns=['T_RES_BODY_1']), pd.DataFrame(columns=['T_RES_BODY_2']), pd.DataFrame(columns=['T_RES_BODY_3'])]
# EE TEMPERATURE REF
source_timestamp_ee_odd_ref_df = rb_query.find_source_timestamp_ee(timestamp_fgc_ref, system='EE_ODD')
source_timestamp_ee_even_ref_df = rb_query.find_source_timestamp_ee(timestamp_fgc_ref, system='EE_EVEN')
t_res_odd_0_ref_df = rb_query.query_ee_t_res_pm(lhcsmnb.utils.get_at(source_timestamp_ee_odd_ref_df, 0, 'timestamp'), timestamp_fgc_ref, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_ODD')
if len(source_timestamp_ee_odd_ref_df) > 1:
t_res_odd_1_ref_df = rb_query.query_ee_t_res_pm(lhcsmnb.utils.get_at(source_timestamp_ee_odd_ref_df, 1, 'timestamp'), timestamp_fgc_ref, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_ODD')
else:
t_res_odd_1_ref_df = [pd.DataFrame(columns=['T_RES_BODY_1']), pd.DataFrame(columns=['T_RES_BODY_2']), pd.DataFrame(columns=['T_RES_BODY_3'])]
t_res_even_0_ref_df = rb_query.query_ee_t_res_pm(lhcsmnb.utils.get_at(source_timestamp_ee_even_ref_df, 0, 'timestamp'), timestamp_fgc_ref, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_EVEN')
if len(source_timestamp_ee_even_ref_df) > 1:
t_res_even_1_ref_df = rb_query.query_ee_t_res_pm(lhcsmnb.utils.get_at(source_timestamp_ee_even_ref_df, 1, 'timestamp'), timestamp_fgc_ref, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_EVEN')
else:
t_res_even_1_ref_df = [pd.DataFrame(columns=['T_RES_BODY_1']), pd.DataFrame(columns=['T_RES_BODY_2']), pd.DataFrame(columns=['T_RES_BODY_3'])]
# U_DIODE - CALS
# Good to know: nQPS PM are transmitted with 600 s delay from triggering
#
u_diode_rb_dfs = rb_query.query_voltage_nxcals('DIODE_RB', 'U_DIODE_RB', timestamp_fgc, spark=spark, duration=[(50, 's'), (500, 's')])
# iQPS, nQPS - PM
source_timestamp_qds_df = rb_query.find_source_timestamp_qds(timestamp_fgc, duration=[(50, 's'), (500, 's')])
source_timestamp_nqps_df = rb_query.find_source_timestamp_nqps(timestamp_fgc, warn_on_missing_pm_buffers=True)
results_table = rb_query.create_report_analysis_template(source_timestamp_qds_df, source_timestamp_nqps_df, min(timestamp_pic), timestamp_fgc, '../__init__.py', i_meas_df, author)
# QDS
u_qds_dfs = rb_query.query_voltage_logic_iqps(source_timestamp_qds_df, signal_names=['U_QS0', 'U_1', 'U_2', 'ST_NQD0', 'ST_MAGNET_OK'])
u_nqps_dfs = rb_query.query_voltage_nqps(source_timestamp_nqps_df, source_timestamp_qds_df, timestamp_fgc, spark=spark)
# QDS from second board (A/B)
source_timestamp_qds_df['timestamp'] = source_timestamp_qds_df['timestamp'] + 2000000
u_qds_dfs2 = rb_query.query_voltage_logic_iqps(source_timestamp_qds_df, signal_names=['U_QS0', 'U_1', 'U_2', 'ST_NQD0', 'ST_MAGNET_OK'])
source_timestamp_qds_df['timestamp'] = source_timestamp_qds_df['timestamp'] - 2000000
# QH
source_timestamp_qh_df = rb_query.find_source_timestamp_qh(timestamp_fgc, duration=[(10, 's'), (500, 's')])
i_hds_dfs = rb_query.query_qh_pm(source_timestamp_qh_df, signal_names='I_HDS')
u_hds_dfs = rb_query.query_qh_pm(source_timestamp_qh_df, signal_names='U_HDS')
# QH REF
i_hds_ref_dfs = rb_query.query_qh_pm(source_timestamp_qds_df, signal_names='I_HDS', is_ref=True)
u_hds_ref_dfs = rb_query.query_qh_pm(source_timestamp_qds_df, signal_names='U_HDS', is_ref=True)
# DIODE LEADS
i_a_u_diode_u_ref_pm_dfs = rb_query.query_current_voltage_diode_leads_pm(timestamp_fgc, source_timestamp_qds_df)
i_meas_u_diode_nxcals_dfs = rb_query.query_current_voltage_diode_leads_nxcals(source_timestamp_qds_df, spark=spark, duration=[(50, 's'), (350, 's')])
# U_EARTH
u_earth_rb_dfs = rb_query.query_voltage_nxcals('VF', 'U_EARTH_RB', timestamp_fgc, spark=spark, duration=[(50, 's'), (500, 's')])
# DFB
source_timestamp_leads_odd_df = rb_query.find_timestamp_leads(timestamp_fgc, 'LEADS_ODD')
u_hts_odd_dfs = rb_query.query_leads(timestamp_fgc, source_timestamp_leads_odd_df, system='LEADS_ODD', signal_names=['U_HTS'], spark=spark)
u_res_odd_dfs = rb_query.query_leads(timestamp_fgc, source_timestamp_leads_odd_df, system='LEADS_ODD', signal_names=['U_RES'], spark=spark)
source_timestamp_leads_even_df = rb_query.find_timestamp_leads(timestamp_fgc, 'LEADS_EVEN')
u_hts_even_dfs = rb_query.query_leads(timestamp_fgc, source_timestamp_leads_even_df, system='LEADS_EVEN', signal_names=['U_HTS'], spark=spark)
u_res_even_dfs = rb_query.query_leads(timestamp_fgc, source_timestamp_leads_even_df, system='LEADS_EVEN', signal_names=['U_RES'], spark=spark)
# EE after 3 hours
unix_time_now = Time.to_unix_timestamp(Time.now())
time_diff = (unix_time_now - timestamp_fgc)*1e-9
if time_diff > 3 * 3600:
t_res_body_long_dfs = rb_query.query_ee_nxcals(timestamp_fgc, system='EE_ODD', signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], spark=spark) \
+ rb_query.query_ee_nxcals(timestamp_fgc, system='EE_EVEN', signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], spark=spark)
st_res_overtemp_long_dfs = rb_query.query_ee_nxcals(timestamp_fgc, system='EE_ODD', signal_names='ST_RES_OVERTEMP', spark=spark, t_thr=0) \
+ rb_query.query_ee_nxcals(timestamp_fgc, system='EE_EVEN', signal_names='ST_RES_OVERTEMP', spark=spark, t_thr=0)
else:
t_res_body_long_dfs = []
st_res_overtemp_long_dfs = []
print('Wait {} seconds to query EE temperature and status signals'.format(time_diff))
rb_analysis = RbCircuitAnalysis(circuit_type, results_table, is_automatic=is_automatic)
```
%% Cell type:markdown id: tags:
# 3. Timestamps
## 3.1. Fast Power Abort event (FPA)
Table below provides timestamps ordered achronologically and represents the sequence of events that occurred in the analyzed circuit. Only the first PIC timestamp from the logging DB is reported. Note that for iQPS and nQPS only the very first PM timestamp is reported. Tables with all iQPS and nQPS PM timestamps are presented in the section dedicated to magnet quench protection analysis. The table also contains a time difference in milliseconds from the first trigger event, from the FGC and PIC trigger times.
In short, the following criteria should be kept:
- The PC PM (FGC, lhc_self) timestamp is expected within 1st iQPS PM timestamp +/-40 ms;
- Time delay between PIC and EE at an odd (RR or UJ) point is 100±50 ms;
- Time delay between PIC and EE at an even (UA) point is 600±50 ms;
%% Cell type:code id: tags:
``` python
timestamp_dct = {'FGC': timestamp_fgc, 'PIC': min(timestamp_pic), 'EE_EVEN': timestamp_ee_even, 'EE_ODD': timestamp_ee_odd,
'iQPS': source_timestamp_qds_df, 'nQPS': source_timestamp_nqps_df,
'LEADS_ODD': source_timestamp_leads_odd_df, 'LEADS_EVEN': source_timestamp_leads_even_df}
rb_analysis.create_timestamp_table(timestamp_dct)
```
%% Cell type:code id: tags:
``` python
value_range_ee_odd = (0.05, 0.15)
if not rb_analysis.check_pic_ee_timestamp_difference(min(timestamp_pic), timestamp_ee_odd, value_range_ee_odd):
warnings.warn(f"The time difference between PIC and EE ODD is not within the given range_value {value_range_ee_odd}.PIC :{min(timestamp_pic)} and EE_ODD {timestamp_ee_odd}")
```
%% Cell type:code id: tags:
``` python
value_range_ee_even = (0.55, 0.65)
if not rb_analysis.check_pic_ee_timestamp_difference(min(timestamp_pic), timestamp_ee_even, value_range_ee_even):
warnings.warn(f"The time difference between PIC and EE EVEN is not within the given range_value {value_range_ee_even}.PIC :{min(timestamp_pic)} and EE_EVEN {timestamp_ee_even}")
```
%% Cell type:markdown id: tags:
## 3.1.1. Quenched magnets
%% Cell type:code id: tags:
``` python
rb_analysis.results_table[['Circuit Name', 'Position', 'I_Q_M', 'Delta_t(iQPS-PIC)', 'nQPS crate name', 'Delta_t(nQPS-PIC)']]
```
%% Cell type:markdown id: tags:
## 3.2. Reference Event
Table below contains the reference event timestamps of signals used for comparison to the analyzed FPA. The reference comes as the last succesfull PNO.b2 HWC test.
%% Cell type:code id: tags:
``` python
timestamp_ref_dct = {'FGC': timestamp_fgc_ref,
'EE_ODD_first': lhcsmnb.utils.get_at(source_timestamp_ee_odd_ref_df, 0, 'timestamp'), 'EE_ODD_second': lhcsmnb.utils.get_at(source_timestamp_ee_odd_ref_df, 1, 'timestamp'),
'EE_EVEN_first': lhcsmnb.utils.get_at(source_timestamp_ee_even_ref_df, 0, 'timestamp'), 'EE_EVEN_second': lhcsmnb.utils.get_at(source_timestamp_ee_even_ref_df, 1, 'timestamp')}
rb_analysis.create_ref_timestamp_table(timestamp_ref_dct)
```
%% Cell type:markdown id: tags:
# 4. Circuit Schematic
The interactive schematic represents the analyzed circuit and contains:
- All magnets (the quenched ones are in red and the order of quenching is displayed)
- All nQPS crates in gray with yellow frames (the ones with the quenched magnets in red)
- Power converter with FGC timestamp
- Energy extraction systems (even and odd) with corresponding timestamps
- Current leads with PM timestamps (if applicable)
**Note that the drawing may take about 5 minutes**. The most of the time is spent on initializing the plotting library.
%% Cell type:code id: tags:
``` python
if len(results_table) > 1:
print('Loading RbCircuitSchematic...'); from lhcsmapi.analysis.RbCircuitSchematic import show_schematic
show_schematic(circuit_type, circuit_name, results_table, source_timestamp_nqps_df, source_timestamp_leads_odd_df, source_timestamp_leads_even_df,
timestamp_fgc, source_ee_odd, timestamp_ee_odd, source_ee_even, timestamp_ee_even, show_magnet_name=False)
```
%% Cell type:markdown id: tags:
# 5. Powering Iinterlock system (PIC)
## 5.1. Analysis of the PIC Timestamps
*ANALYSIS*:
- Show warning if the two PIC timestamps (ODD and EVEN) differ by more than a 1 ms. (Obsolete)
- If your precision is in ms, the criterion for the RBs (even and odd) of "**1 ms < PIC Timestamp Diff <5 ms**" suits me and sticks with the current PIC capability.
- For all other circuits, as only one PIC is implied to control them, the criterion could be more tightened like "**1 ms <PIC Timestamp Diff <3 ms**"
Regards,
Alain
29/04/2021
%% Cell type:code id: tags:
``` python
rb_analysis.analyze_pic(timestamp_pic)
```
%% Cell type:markdown id: tags:
# 6. Power Converter
## 6.1. Analysis of the Power Converter Main Current
This analysis module displays the main current of the power converter (I_MEAS) compared to the one obtained from the reference FPA (HWC PNO.b2 test with opening of EE systems and without magnet quench).
*ANALYSIS*:
- The evolution of the characteristic time $\tau$ of an exponential decay $f(t)$ is obtained as
\begin{equation}
-\frac{f(t)}{\partial_t f(t)} = -\frac{f_0 e^{-t/\tilde{\tau}}}{\partial_t (f_0 e^{-t/\tilde{\tau}})} = -\frac{f_0 e^{-t/\tilde{\tau}}}{-f_0/\tilde{\tau} e^{-t/\tilde{\tau}}}=-\frac{1}{-1/\tau}=\tau
\end{equation}
Naturally, this formula only applies to exponential decayed characterised by a time constant. Nonetheless, for pseudo-exponential decays, this formula gives a notion of the change of the characteristic time $\tilde{\tau}$. For a circuit we compute the time-varying characteristic time as
\begin{equation}
\tilde{\tau} = \frac{\partial \text{I_MEAS}}{\partial_t}
\end{equation}
*CRITERIA*
- Characteristic time of pseudo-exponential decay of I_MEAS from t=1 to 120 s: 90 s< Tau <110 s
*PLOT*:
- The main power converter current (analyzed and reference) on the left axis, I_MEAS
- The characteristic time calculated for the main current (reference and actual) on the right axis, -I_MEAS/dI_MEAS_dt
The actual characteristic time can contains steps, which indicate a quenching magnet if so (decrease of circuit inductance); note that for the reference one the steps are not present. Timing of PIC abort, FGC timestamp, and the maximum current are reported next to the graph.
- t = 0 s corresponds to the respective (analyzed and reference) FGC timestamps.
%% Cell type:code id: tags:
``` python
%matplotlib notebook
rb_analysis.analyze_i_meas_pc(circuit_name, timestamp_fgc, timestamp_fgc_ref, min(timestamp_pic), i_meas_df, i_meas_ref_df)
rb_analysis.calculate_current_miits_i_meas_i_a(i_meas_df, i_a_df, t_quench=0, col_name='MIITS_circ')
rb_analysis.calculate_quench_current(i_meas_df, t_quench=0, col_name='I_Q_circ')
rb_analysis.calculate_current_slope(i_meas_df, col_name=['Ramp rate', 'Plateau duration'])
```
%% Cell type:markdown id: tags:
## 6.1.1. Long plateau analysis
If the plateau duraion is less than 60 s you can skip this analysis and jump to 6.2!
%% Cell type:code id: tags:
``` python
pm_plateau_duration = rb_analysis.results_table['Plateau duration'][0]
print(f"PM Plateau duration = {pm_plateau_duration} s")
```
%% Cell type:markdown id: tags:
Next cell: User input (manual or from AccTesting)
- hwc_test = 'PNO.b2' or 'Beam Operation'?
- campaign= 'Recommissioning post LS2' or 'Run3'?
- t_start = '2021-05-26 12:36:06.238000000' -> if Run3 will be manual?
- t_end = '2021-05-26 12:45:37.719000000' -> if Run3 will FPA time stamp?
%% Cell type:code id: tags:
``` python
# User Input (manual or from AccTesting)
hwc_test = 'PNO.b2'
campaign= 'Recommissioning post LS2'
t_start = '2021-06-03 06:36:57.787000000'
t_end = '2021-06-03 07:34:32.694000000'
```
%% Cell type:code id: tags:
``` python
if pm_plateau_duration > 60:
circuit_type = circuit_name[0:2]
print('circuit_type = \'%s\'\nhwc_test = \'%s\'\ncircuit_name = \'%s\'\ncampaign = \'%s\'\nt_start = \'%s\'\nt_end = \'%s\'' % (circuit_type, hwc_test, circuit_name, campaign, t_start, t_end))
```
%% Cell type:code id: tags:skip_cell
``` python
if pm_plateau_duration > 60:
i_meas_full_df = rb_query.query_signal_nxcals(t_start, t_end, t0=Time.to_unix_timestamp(t_start), system='PC', signal_names='I_MEAS', spark=spark)[0]
i_meas_full_raw_df = rb_query.query_raw_signal_nxcals(t_start, t_end, system='PC', signal_names='I_MEAS', spark=spark)[0]
plateau_start, plateau_end = rb_analysis.find_plateau_start_and_end(i_meas_full_raw_df, i_meas_threshold=500, min_duration_in_sec=120, time_shift_in_sec=(0, 0))
```
%% Cell type:code id: tags:
``` python
if pm_plateau_duration > 60:
title = f"{hwc_test}, circuit_name: {circuit_name}, Start Time: {t_start[:23]}"
i_meas_full_df.rename(columns = {'I_MEAS': rb_query.circuit_name + ':I_MEAS'}, inplace = True)
rb_analysis.plot_i_meas_with_current_plateau(i_meas_full_df, t0=i_meas_full_raw_df.index[0], plateau_start=plateau_start, plateau_end=plateau_end, title=title)
long_plateau_duration = (plateau_end[0] - plateau_start[0])*1e-9
print('Plateau_Duration =', long_plateau_duration, 's')
```
%% Cell type:markdown id: tags:
## 6.2. Analysis of the Power Converter Earth Current
*CRITERIA*:
- Checks whether for t > 3 s, I_EARTH_PCNT is within +/-3 % w.r.t. the reference;
- Note: 100% corresponds to 55 mA, 3% to 1.65 mA;
*PLOT*:
t = 0 s corresponds to respective (actual and reference) FGC PM timestamps
First plot (I_EARTH, absolute scale, mA)
- The main power converter current on the left axis, I_A
- Actual and reference earth current on the right axis, I_EARTH
Second plot (I_EARTH_PCNT, percentage scale)
- The main power converter current on the left axis, I_MEAS
- Actual and reference earth current on the right axis, I_EARTH_PCNT; I_EARTH_PCNT scaled according to the peak value of the main reference current
%% Cell type:code id: tags:
``` python
rb_analysis.analyze_i_earth_pc(circuit_name, timestamp_fgc, i_a_df, i_earth_df, i_earth_ref_df, xlim=(-1, 5))
rb_analysis.calculate_max_i_earth_pc(i_earth_df, col_name='I_Earth_max')
```
%% Cell type:code id: tags:
``` python
%matplotlib inline
rb_analysis.analyze_i_earth_pcnt_pc(circuit_type, circuit_name, timestamp_fgc, i_meas_df, i_meas_ref_df, i_earth_pcnt_df, i_earth_pcnt_ref_df, xlim=(-50, 400), scaling=1)
```
%% Cell type:markdown id: tags:
# 7. Energy Extraction System
## 7.1. Analysis of the Energy Extraction Voltage
*ANALYSIS*:
- Calculate U_dump_res (t=0)
- Calculate the characteristic time of pseudo-exponential current decay with the charge approach
*CRITERIA*:
- Check if U_dump_res (t=0) = 0.075*I V (±10%).
- Check if the characteristic time of pseudo-exponential decay of I_MEAS from t=1 to 120 s is 110 s<-Tau <130 s
- Check if the timestamp difference between PIC and EE an odd point is 100±50 ms
The opening delay was 290±50 ms prior to YETS 2017/8
- Check if the time stamp difference between PIC and EE an even point: 600±50 ms
*GRAPHS*:
t = 0 s corresponds to the PM timestamp of the FGC
First plot (global view):
- the power converter converter current on the left axis, I_MEAS
- the two energy extraction voltages on the right, U_DUMP_RES, U_DUMP_RES
Second plot (triggering view):
- the power converter current on the left axis, I_MEAS
- the power converter reference current on the left axis, STATUS.I_REF (should stop at the moment of the FGC PM timestamp)
- the two energy extraction voltages on the right axis, U_DUMP_RES, U_DUMP_RES
- the green dashed line denotes the PIC timestamp
%% Cell type:code id: tags:
``` python
rb_analysis.analyze_char_time_u_dump_res_ee(circuit_name, timestamp_fgc, [u_dump_res_odd_df, u_dump_res_even_df], i_meas_df)
rb_analysis.results_table['U_EE_max_ODD'] = u_dump_res_odd_df.max()[0]
rb_analysis.results_table['U_EE_max_EVEN'] = u_dump_res_even_df.max()[0]
```
%% Cell type:code id: tags:
``` python
rb_analysis.analyze_delay_time_u_dump_res_ee(circuit_name, timestamp_fgc, min(timestamp_pic), [timestamp_ee_odd, timestamp_ee_even],
i_a_df, i_ref_df, [u_dump_res_odd_df, u_dump_res_even_df])
```
%% Cell type:markdown id: tags:
## 7.2. Analysis of the Energy Extraction resistance Temperature
*CRITERIA*
- Checks whether temperature profile is +/-25 K w.r.t. the reference temperature profile
- Checks whether maximum temperatures are within [100, 200] K range
*PLOT*:
- Temperature signals on the left axis, T
- A reference signal with an acceptable signal range is also provided on the left axis
- t = 0 s corresponds to PM timestamps of each temperature PM entry
*PASS or FAIL*:
- Please check the EE-openings by java-application in AccTesting!
%% Cell type:code id: tags:
``` python
rb_analysis.analyze_ee_temp(circuit_name + '_EE_ODD', timestamp_ee_odd, t_res_odd_0_df + t_res_odd_1_df, t_res_odd_0_ref_df + t_res_odd_1_ref_df, abs_margin=25, scaling=1)
```
%% Cell type:code id: tags:
``` python
rb_analysis.analyze_ee_temp(circuit_name + '_EE_EVEN', timestamp_ee_even, t_res_even_0_df + t_res_even_1_df, t_res_even_0_ref_df + t_res_even_1_ref_df, abs_margin=25, scaling=1)
```
%% Cell type:code id: tags:
``` python
if not is_automatic:
print('Please check the EE-openings by java-application in AccTesting!')
rb_analysis.results_table['EE analysis'] = get_expert_decision('EE analysis: ', ['PASS', 'FAIL'])
```
%% Cell type:markdown id: tags:
# 8. Quench Protection System: QDS, QH and by pass Diode
<img src="https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/RB_QPS_Signals.png" width=75%>
The table below shows the sign of the resistive voltages and inductive voltages (for positive ramp rate) of U1 and U2. U_QS0=-U1-U2.
|Circuit |Resistive voltage U1 |Resistive voltage U2 |Inductive voltage U1 |Inductive voltage U2|
|-----------|-----------------------|-----------------------|-----------------------|--------------------|
|RB.A12 |Pos |Neg |Pos |Neg|
|RB.A23 |Neg |Pos |Neg |Pos|
|RB.A34 |Neg |Pos |Neg |Pos|
|RB.A45 |Neg |Pos |Neg |Pos|
|RB.A56 |Pos |Neg |Pos |Neg|
|RB.A67 |Pos |Neg |Pos |Neg|
|RB.A78 |Pos |Neg |Pos |Neg|
|RB.A81 |Neg |Pos |Neg |Pos|
The thresholds and evaluation times for the QPS on the RB circuits are given in the following table:
|Class |System |Threshold |Evaluation time |Signal |Comment|
|-------|-------|-----------|-------------------|-------|:------|
|DQAMCNMB_PMSTD |iQPS, DQQDL |100/200 mV |10 ms discrimination |U_QS0 |Old QPS. Detection of quench in one aperture based upon voltage difference between both apertures in same magnet U_QS0 >10 ms above threshold, otherwise discriminator is reset|
|DQAMCNMB_PMHSU |iQPS, nQPS |-|-|-|Firing of quench heaters by quench protection. Generation of PM buffers sometimes happens even if there is no heater firing.|
|DQAMGNSRB (slow sampling rate), DQAMGNSRB_PMREL (fast sampling rate) |nQPS, DQQDS |500 mV * |>20 ms moving average +1 ms discrimination |U_DIODE |New QPS. Detection of quench in both apertures based upon comparing voltage across the magnet (bypass diode) from 3 magnets in same half-cell and one reference from adjacent half-cell. 50Hz notch moving average filter (20ms worst case). The signals in the 2 classes are identical, only the sampling rate differs. The data with the slow sampling rate is no longer generated as they can be found in the logging database. The recording of data is usually triggered during a FPA, depending on current in circuit, and always when a symmetric quench occurs. The PM buffers are only sent if the DQAMGNS crate trips (what ever the reason).PMs are transmitted with 600 s delay from triggering time.|
|DQAMGNSRB |nQPS, DQQBS| 4 mV | >10 s moving average | U_RES |New QPS. Busbar protection. The signal is not compensated for inductive voltage during ramp.|
|DQAMGNDRB_EVEN, DQAMGNDRB_ODD |iQPS, DQQDC |1 mV, 100 mV |1 s |U_HTS, U_RES |Old QPS. Leads protection. U_HTS is for the high temperature superconducting leads, and U_RES is for the room temperature leads.|
|DQAMGNDRB_EVEN, DQAMGNDRB_ODD |iQPS, DQQDB |+200 V | -50 V | U_BB1, U_BB2 |Old QPS. U_BB1 is the total voltage across the sector. U_BB2 is the voltage across the energy extraction in ODD-point (EE)|
|DQAMSNRB |-|-|-|-|Opening of energy extraction (EE) switches during fast power abort (FPA). 2 EE switches per sector. One for "even" points (EE2). One for "odd" points (EE1).|
*: It was 800 mV before LS1. After LS1 we changed it to 300 or 400 mV. During the training after LS1 we increased it to 500 mV.
%% Cell type:markdown id: tags:
## 8.1. Plot of Voltage Across All Magnets (U_DIODE_RB)
*PLOT*:
t = 0 s corresponds to the PM timestamp of the FGC
First plot (global)
- the power converter current on the left axis, I_MEAS
- diode voltage on the right axis, U_DIODE_RB
Second plot (zoom)
- the power converter current on the left axis, I_MEAS
- diode voltage on the right axis, U_DIODE_RB
%% Cell type:code id: tags:
``` python
%matplotlib notebook
rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', xlim=(-25, 500))
```
%% Cell type:code id: tags:
``` python
rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', xlim=(-1, 3))
```
%% Cell type:code id: tags:
``` python
%matplotlib notebook
u_diode_with_quench_rb_dfs = rb_analysis.filter_quenched_magnets(u_diode_rb_dfs, results_table['Position'])
rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_with_quench_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', legend=True, xlim=(-25, 500))
print("done!")
```
%% Cell type:code id: tags:
``` python
rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_with_quench_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', legend=True, xlim=(-1, 3))
```
%% Cell type:markdown id: tags:
## 8.2. Analysis of Quenched Magnets by QDS - PMs
*ANALYSIS*:
- calculates the current at which a quench occured by finding the timestamp of the current dataframe (i_meas_df) closest to the quench time and the curresponding value of current - I_MEAS_quench
- compute the time difference (in milliseconds) from the first quench - dt_quench
%% Cell type:code id: tags:
``` python
rb_analysis.results_table[['Circuit Name', 'I_Q_circ', 'Position', 'I_Q_M', 'Delta_t(iQPS-PIC)', 'nQPS crate name', 'Delta_t(nQPS-PIC)']]
```
%% Cell type:markdown id: tags:
## 8.3. Analysis of Quench Detection Voltage and Logic Signals for Quenched Magnets
%% Cell type:markdown id: tags: