AN_RB_PLI2.f1.ipynb 51.5 KB
Newer Older
1
2
3
4
{
 "cells": [
  {
   "cell_type": "markdown",
5
6
7
   "metadata": {
    "deletable": false
   },
8
9
10
   "source": [
    "<h1><center>Analysis of PLI2.f1 HWC Test in an RB Circuit</center></h1>\n",
    "<img src=\"https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/RB.png\" width=75%>\n",
11
    "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>"
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# Analysis Assumptions\n",
    "- 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.\n",
    "- 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). \n",
    "\n",
    "# Plot Convention\n",
    "- Scales are labeled with signal name followed by a comma and a unit in square brackets, e.g., I_MEAS, [A].\n",
    "- If a reference signal is present, it is represented with a dashed line.\n",
    "- 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.\n",
    "- The grid comes from the left axis.\n",
    "- The title contains timestamp, circuit name, and signal name allowing to re-access the signal.\n",
    "- 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).\n",
    "- Each plot has an individual time-synchronization mentioned explicitly in the description.\n",
    "- 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",
   "metadata": {
38
    "deletable": false
39
40
41
42
43
44
45
   },
   "source": [
    "# 0. Initialise Working Environment"
   ]
  },
  {
   "cell_type": "code",
46
   "execution_count": null,
47
   "metadata": {
48
    "deletable": false,
49
50
    "scrolled": false
   },
51
   "outputs": [],
52
53
   "source": [
    "# External libraries\n",
Per Hagen's avatar
Per Hagen committed
54
    "print('Loading (1/12)'); import sys, warnings\n",
55
56
57
58
59
60
61
62
63
64
    "print('Loading (2/12)'); from IPython.display import display, Javascript, HTML, clear_output\n",
    "print('Loading (3/12)'); import pandas as pd\n",
    "\n",
    "# Internal libraries\n",
    "print('Loading (4/12)'); import lhcsmapi\n",
    "print('Loading (5/12)'); from lhcsmapi.Time import Time\n",
    "print('Loading (6/12)'); from lhcsmapi.Timer import Timer\n",
    "print('Loading (7/12)'); from lhcsmapi.analysis.RbCircuitQuery import RbCircuitQuery\n",
    "print('Loading (8/12)'); from lhcsmapi.analysis.RbCircuitAnalysis import RbCircuitAnalysis\n",
    "print('Loading (9/12)'); from lhcsmapi.analysis.report_template import apply_report_template\n",
Per Hagen's avatar
Per Hagen committed
65
66
67
    "print('Loading (10/12)'); from lhcsmapi.analysis.expert_input import get_expert_decision\n",
    "print('Loading (11/12)'); from lhcsmapi.gui.qh.DateTimeBaseModule import DateTimeBaseModule\n",
    "print('Loading (12/12)'); from lhcsmapi.gui.hwc.HwcSearchModuleMediator import HwcSearchModuleMediator\n",
68
69
70
    "\n",
    "clear_output()\n",
    "lhcsmapi.get_lhcsmapi_version()\n",
71
72
    "lhcsmapi.get_lhcsmhwc_version('../__init__.py')\n",
    "print('Analysis performed by %s' % HwcSearchModuleMediator.get_user())"
73
74
75
76
77
78
79
80
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
    "# 1. User Input\n",
    "1. Copy code from AccTesting and paste into an empty cell below\n",
    "<img src=\"https://gitlab.cern.ch/LHCData/lhc-sm-hwc/-/raw/master/figures/swan-manual-acctesting-integration.png\">\n",
    "\n",
    "    - If you only want to test the notebook only for the copy&paste feature (without opening the AccTesting), please copy and execute the code below\n",
    "    ```\n",
    "    hwc_test = 'PLI2.f1'\n",
    "    circuit_name = 'RB.A12'\n",
    "    campaign = 'HWC_2014'\n",
    "    t_start = '2014-12-11 21:35:48.943'\n",
    "    t_end = '2014-12-11 21:59:44.442'\n",
    "    ```\n",
    "\n",
    "2. To analyze a historical test with a browser GUI, copy and execute the following code in the cell below\n",
    "```\n",
    "circuit_type = 'RB'\n",
    "hwc_test = 'PLI2.f1'\n",
    "hwcb = HwcSearchModuleMediator(circuit_type=circuit_type, hwc_test=hwc_test, hwc_summary_path='/eos/project/l/lhcsm/hwc/HWC_Summary.csv')\n",
    "```\n",
    "\n",
    "    - After opening the browser GUI, choose a circuit name in order to display HWC test with, campaign name as well as start and end time"
102
103
104
105
   ]
  },
  {
   "cell_type": "code",
106
   "execution_count": null,
107
   "metadata": {
108
    "deletable": false,
109
110
    "scrolled": false
   },
111
   "outputs": [],
Michal Maciejewski's avatar
Michal Maciejewski committed
112
   "source": []
113
  },
114
115
116
117
118
119
120
121
122
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('hwc_test = \\'%s\\'\\ncircuit_name = \\'%s\\'\\ncampaign = \\'%s\\'\\nt_start = \\'%s\\'\\nt_end = \\'%s\\'' % (hwc_test, circuit_name, campaign, t_start, t_end))"
   ]
  },
123
124
125
  {
   "cell_type": "markdown",
   "metadata": {
126
    "deletable": false
127
128
129
130
131
132
133
   },
   "source": [
    "# 2. Query All Signals Prior to Analysis"
   ]
  },
  {
   "cell_type": "code",
134
   "execution_count": null,
135
   "metadata": {
136
    "deleteable": false,
137
    "scrolled": false,
138
139
140
141
    "tags": [
     "skip_output"
    ]
   },
142
   "outputs": [],
143
   "source": [
144
145
146
147
148
    "circuit_type = 'RB'\n",
    "if 'hwcb' in locals():\n",
    "    circuit_name = hwcb.get_circuit_name()\n",
    "    t_start = Time.to_unix_timestamp(hwcb.get_start_time())\n",
    "    t_end = Time.to_unix_timestamp(hwcb.get_end_time())\n",
149
150
    "    t_start_ref = Time.to_unix_timestamp(hwcb.get_ref_start_time())\n",
    "    t_end_ref = Time.to_unix_timestamp(hwcb.get_ref_end_time())\n",
151
152
153
154
    "    is_automatic = hwcb.is_automatic_mode()\n",
    "else:\n",
    "    t_start = Time.to_unix_timestamp(t_start)\n",
    "    t_end = Time.to_unix_timestamp(t_end)\n",
155
156
    "    t_start_ref, t_end_ref = HwcSearchModuleMediator.get_last_ref_start_end_time('/eos/project/l/lhcsm/hwc/HWC_Summary.csv', circuit_name, hwc_test, Time.to_string_short(t_start))\n",
    "    t_start_ref, t_end_ref = Time.to_unix_timestamp(t_start_ref), Time.to_unix_timestamp(t_end_ref)\n",
157
158
    "    is_automatic = False\n",
    "    \n",
Per Hagen's avatar
Per Hagen committed
159
    "rb_query = RbCircuitQuery(circuit_type, circuit_name, max_executions=40)\n",
160
161
162
163
164
165
166
167
168
169
170
    "\n",
    "with Timer():\n",
    "    source_timestamp_pc = rb_query.find_source_timestamp_pc(t_start, t_end)\n",
    "    timestamp_fgc = source_timestamp_pc.at[0, 'timestamp']\n",
    "    \n",
    "    # PIC\n",
    "    timestamp_pic = rb_query.find_timestamp_pic(timestamp_fgc, spark=spark)\n",
    "\n",
    "    # PC Current\n",
    "    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'])\n",
    "\n",
171
172
173
    "    source_timestamp_pc_ref_df = rb_query.find_source_timestamp_pc(t_start_ref, t_end_ref)\n",
    "    timestamp_fgc_ref = source_timestamp_pc_ref_df.at[0, 'timestamp']\n",
    "\n",
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
    "    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'])\n",
    "\n",
    "    # EE Voltage\n",
    "    source_timestamp_ee_odd_df = rb_query.find_source_timestamp_ee(timestamp_fgc, system='EE_ODD')\n",
    "    timestamp_ee_odd = source_timestamp_ee_odd_df.loc[0, 'timestamp']\n",
    "    source_ee_odd = source_timestamp_ee_odd_df.loc[0, 'source']\n",
    "    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]\n",
    "\n",
    "    source_timestamp_ee_even_df = rb_query.find_source_timestamp_ee(timestamp_fgc, system='EE_EVEN')\n",
    "    timestamp_ee_even = source_timestamp_ee_even_df.loc[0, 'timestamp']\n",
    "    source_ee_even = source_timestamp_ee_even_df.loc[0, 'source']\n",
    "    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]\n",
    "\n",
    "    # EE TEMPERATURE\n",
    "    t_res_odd_0_df = rb_query.query_ee_t_res_pm(source_timestamp_ee_odd_df.loc[0, 'timestamp'], timestamp_fgc, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_ODD')\n",
189
190
191
192
    "    if len(source_timestamp_ee_odd_df) > 1:\n",
    "        t_res_odd_1_df = rb_query.query_ee_t_res_pm(source_timestamp_ee_odd_df.loc[1, 'timestamp'], timestamp_fgc, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_ODD')\n",
    "    else:\n",
    "        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'])]\n",
193
    "    t_res_even_0_df = rb_query.query_ee_t_res_pm(source_timestamp_ee_even_df.loc[0, 'timestamp'], timestamp_fgc, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_EVEN')\n",
194
195
196
197
    "    if len(source_timestamp_ee_even_df) > 1:\n",
    "        t_res_even_1_df = rb_query.query_ee_t_res_pm(source_timestamp_ee_even_df.loc[1, 'timestamp'], timestamp_fgc, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_EVEN')\n",
    "    else:\n",
    "        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'])]\n",
Per Hagen's avatar
Per Hagen committed
198
    "        \n",
199
200
201
202
203
    "    # EE TEMPERATURE REF\n",
    "    source_timestamp_ee_odd_ref_df = rb_query.find_source_timestamp_ee(timestamp_fgc_ref, system='EE_ODD')\n",
    "    source_timestamp_ee_even_ref_df = rb_query.find_source_timestamp_ee(timestamp_fgc_ref, system='EE_EVEN')\n",
    "\n",
    "    t_res_odd_0_ref_df = rb_query.query_ee_t_res_pm(source_timestamp_ee_odd_ref_df.loc[0, 'timestamp'], timestamp_fgc_ref, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_ODD')\n",
204
205
206
207
    "    if len(source_timestamp_ee_odd_ref_df) > 1:\n",
    "        t_res_odd_1_ref_df = rb_query.query_ee_t_res_pm(source_timestamp_ee_odd_ref_df.loc[1, 'timestamp'], timestamp_fgc_ref, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_ODD')\n",
    "    else:\n",
    "        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'])]\n",
208
    "    t_res_even_0_ref_df = rb_query.query_ee_t_res_pm(source_timestamp_ee_even_ref_df.loc[0, 'timestamp'], timestamp_fgc_ref, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_EVEN')\n",
209
210
211
212
    "    if len(source_timestamp_ee_even_ref_df) > 1:\n",
    "        t_res_even_1_ref_df = rb_query.query_ee_t_res_pm(source_timestamp_ee_even_ref_df.loc[1, 'timestamp'], timestamp_fgc_ref, signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], system='EE_EVEN')\n",
    "    else:\n",
    "        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'])]\n",
Per Hagen's avatar
Per Hagen committed
213
    "    \n",
214
    "    # U_DIODE - CALS\n",
215
    "    u_diode_rb_dfs = rb_query.query_voltage_nxcals('DIODE_RB', 'U_DIODE_RB', timestamp_fgc, spark=spark, duration=[(50, 's'), (350, 's')])\n",
216
217
218
219
    "\n",
    "    # iQPS, nQPS - PM\n",
    "    source_timestamp_qds_df = rb_query.find_source_timestamp_qds(timestamp_fgc)\n",
    "    source_timestamp_nqps_df = rb_query.find_source_timestamp_nqps(timestamp_fgc)\n",
220
    "    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, HwcSearchModuleMediator.get_user())\n",
221
222
    "\n",
    "    # QDS\n",
223
224
225
226
227
    "    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'])\n",
    "    if not source_timestamp_nqps_df.empty:\n",
    "        u_nqps_dfs = rb_query.query_voltage_nqps(source_timestamp_nqps_df, source_timestamp_qds_df, timestamp_fgc, spark=spark)\n",
    "    else:\n",
    "        u_nqps_dfs = []\n",
228
229
    "\n",
    "    # QH\n",
230
231
232
    "    source_timestamp_qh_df = rb_query.find_source_timestamp_qh(timestamp_fgc, duration=[(10, 's'), (500, 's')])\n",
    "    i_hds_dfs = rb_query.query_qh_pm(source_timestamp_qh_df, signal_names='I_HDS')\n",
    "    u_hds_dfs = rb_query.query_qh_pm(source_timestamp_qh_df, signal_names='U_HDS')\n",
233
234
235
236
237
238
    "\n",
    "    # QH REF\n",
    "    i_hds_ref_dfs = rb_query.query_qh_pm(source_timestamp_qds_df, signal_names='I_HDS', is_ref=True)\n",
    "    u_hds_ref_dfs = rb_query.query_qh_pm(source_timestamp_qds_df, signal_names='U_HDS', is_ref=True)\n",
    "\n",
    "    # DIODE LEADS\n",
239
240
    "    i_a_u_diode_u_ref_pm_dfs = rb_query.query_current_voltage_diode_leads_pm(timestamp_fgc, source_timestamp_qds_df)\n",
    "    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')])\n",
241
242
    "\n",
    "    # U_EARTH\n",
Per Hagen's avatar
Per Hagen committed
243
    "    u_earth_rb_dfs = rb_query.query_voltage_nxcals('VF', 'U_EARTH_RB', timestamp_fgc, spark=spark, duration=[(50, 's'), (350, 's')])\n",
244
245
246
247
248
249
250
251
252
253
254
255
256
    "\n",
    "    # DFB\n",
    "    source_timestamp_leads_odd_df = rb_query.find_timestamp_leads(timestamp_fgc, 'LEADS_ODD')\n",
    "    u_hts_odd_dfs = rb_query.query_leads(timestamp_fgc, source_timestamp_leads_odd_df, system='LEADS_ODD', signal_names=['U_HTS'], spark=spark)\n",
    "    u_res_odd_dfs = rb_query.query_leads(timestamp_fgc, source_timestamp_leads_odd_df, system='LEADS_ODD', signal_names=['U_RES'], spark=spark)\n",
    "\n",
    "    source_timestamp_leads_even_df = rb_query.find_timestamp_leads(timestamp_fgc, 'LEADS_EVEN')\n",
    "    u_hts_even_dfs = rb_query.query_leads(timestamp_fgc, source_timestamp_leads_even_df, system='LEADS_EVEN', signal_names=['U_HTS'], spark=spark)\n",
    "    u_res_even_dfs = rb_query.query_leads(timestamp_fgc, source_timestamp_leads_even_df, system='LEADS_EVEN', signal_names=['U_RES'], spark=spark)\n",
    "\n",
    "    # EE after 3 hours\n",
    "    unix_time_now = Time.to_unix_timestamp(Time.now())\n",
    "    time_diff = (unix_time_now - timestamp_fgc)*1e-9\n",
257
258
259
260
261
    "    if time_diff > 3 * 3600:\n",
    "        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) \\\n",
    "                            + 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)\n",
    "        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) \\\n",
    "                                + rb_query.query_ee_nxcals(timestamp_fgc, system='EE_EVEN', signal_names='ST_RES_OVERTEMP', spark=spark, t_thr=0)\n",
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
    "    else:\n",
    "        t_res_body_long_dfs = []\n",
    "        st_res_overtemp_long_dfs = []\n",
    "        print('Wait {} seconds to query EE temperature and status signals'.format(time_diff))\n",
    "\n",
    "rb_analysis = RbCircuitAnalysis(circuit_type, results_table, is_automatic=is_automatic)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 3. Timestamps\n",
    "## 3.1. FPA\n",
    "Table below provides timestamps ordered achronologically and represents the sequence of events that occurred in the analyzed circuit. Only the first PIC timestamp is reported. Note that for iQPS and nQPS only the first timestamp is reported. Tables with all iQPS and NQPS timestamps are presented in the section dedicated to magnet and quench protection analysis. The table also contains time difference in milliseconds from the first event and from the FGC event.\n",
    "\n",
    "In short, the following criteria should be kept:\n",
    "- The PC timestamp (51_self) is QPS time stamp +/-20 ms. \n",
282
    "- Time stamp difference between FGC and EE at an odd (RR or UJ) point: 290±50 ms \n",
283
284
285
286
287
288
    "After YETS 2017/8 the EE timestamp odd has been reduced and should now be 100+-50 ms after the FGC time stamp\n",
    "- Time stamp difference between FGC and EE at an even (UA) point: 600±50 ms"
   ]
  },
  {
   "cell_type": "code",
289
   "execution_count": null,
290
291
292
293
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
294
   "outputs": [],
295
296
297
298
299
300
301
302
303
   "source": [
    "timestamp_dct = {'FGC': timestamp_fgc, 'PIC': min(timestamp_pic), 'EE_EVEN': timestamp_ee_even, 'EE_ODD': timestamp_ee_odd,\n",
    "                 'iQPS': source_timestamp_qds_df, 'nQPS': source_timestamp_nqps_df,\n",
    "                 'LEADS_ODD': source_timestamp_leads_odd_df, 'LEADS_EVEN': source_timestamp_leads_even_df}\n",
    "rb_analysis.create_timestamp_table(timestamp_dct)"
   ]
  },
  {
   "cell_type": "markdown",
304
305
306
   "metadata": {
    "deletable": false
   },
307
308
309
310
311
312
313
   "source": [
    "## 3.2. Reference\n",
    "Table below contains reference timestamps of signals used for comparison to the analyzed FPA. The reference comes as the last PNO.b2 HWC test with activation of EE systems and no magnets quenching."
   ]
  },
  {
   "cell_type": "code",
314
   "execution_count": null,
315
   "metadata": {
316
    "deletable": false,
317
318
    "scrolled": true
   },
319
   "outputs": [],
320
321
   "source": [
    "timestamp_ref_dct = {'FGC': timestamp_fgc_ref, \n",
322
323
    "                     'EE_ODD_first': source_timestamp_ee_odd_ref_df.loc[0, 'timestamp'], 'EE_ODD_second': source_timestamp_ee_odd_ref_df.loc[1, 'timestamp'] if len(source_timestamp_ee_odd_ref_df) > 1 else float('nan'),\n",
    "                     'EE_EVEN_first': source_timestamp_ee_even_ref_df.loc[0, 'timestamp'], 'EE_EVEN_second': source_timestamp_ee_even_ref_df.loc[1, 'timestamp'] if len(source_timestamp_ee_even_ref_df) > 1 else float('nan')}\n",
324
325
326
327
328
329
    "rb_analysis.create_ref_timestamp_table(timestamp_ref_dct)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
330
    "deletable": false
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
   },
   "source": [
    "# 4. Schematic\n",
    "The interactive schematic represents the analyzed circuit and contains:\n",
    "- All magnets (the quenched ones are in red and the order of quenching is displayed)\n",
    "- All nQPS crates in blue (the ones with the quenched magnets in red) \n",
    "- Power converter with FGC timestamp\n",
    "- Energy extraction systems (even and odd) with corresponding timestamps\n",
    "- Current leads with PM timestamps (if applicable)\n",
    "\n",
    "**Note that the drawing may take about 5 minutes**. The most of the time is spent on initializing the plotting library."
   ]
  },
  {
   "cell_type": "code",
346
   "execution_count": null,
347
348
349
   "metadata": {
    "deletable": false
   },
350
   "outputs": [],
351
352
   "source": [
    "if len(results_table) > 1:\n",
353
354
    "    print('Loading RbCircuitSchematic...'); \n",
    "    from lhcsmapi.analysis.RbCircuitSchematic import show_schematic\n",
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    "    show_schematic(circuit_type, circuit_name, results_table, source_timestamp_nqps_df, source_timestamp_leads_odd_df, source_timestamp_leads_even_df,\n",
    "                   timestamp_fgc, source_ee_odd, timestamp_ee_odd, source_ee_even, timestamp_ee_even, show_magnet_name=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 5. PIC\n",
    "## 5.1. Analysis of the PIC Timestamp\n",
    "\n",
    "*ANALYSIS*:\n",
    "- Show warning if the two PIC timestamps differ by more than a 1 ms."
   ]
  },
  {
   "cell_type": "code",
374
   "execution_count": null,
375
376
377
378
   "metadata": {
    "deletable": false,
    "scrolled": true
   },
379
   "outputs": [],
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
   "source": [
    "rb_analysis.analyze_pic(timestamp_pic)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 6. Power Converter\n",
    "## 6.1. Analysis of the Power Converter Main Current\n",
    "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).\n",
    "\n",
    "*ANALYSIS*:\n",
    "- The evolution of the characteristic time $\\tau$ of an exponential decay $f(t)$ is obtained as\n",
    "\\begin{equation}\n",
    "-\\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\n",
    "\\end{equation}\n",
    "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\n",
    "\\begin{equation}\n",
    "\\tilde{\\tau} = \\frac{\\partial \\text{I_MEAS}}{\\partial_t}\n",
    "\\end{equation}\n",
    "\n",
    "*CRITERIA*  \n",
    "- Characteristic time of pseudo-exponential decay of I_MEAS from t=1 to 120 s: 90 s< Tau <110 s\n",
    "\n",
    "*PLOT*:\n",
    "- The main power converter current (analyzed and reference) on the left axis, I_MEAS\n",
    "- The characteristic time calculated for the main current (reference and actual) on the right axis, -I_MEAS/dI_MEAS_dt \n",
    "The actual characteristic time contains steps, which indicate a quenching magnet (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.\n",
    "- t = 0 s corresponds to the respective (analyzed and reference) FGC timestamps."
   ]
  },
  {
   "cell_type": "code",
416
   "execution_count": null,
417
418
419
   "metadata": {
    "deletable": false
   },
420
   "outputs": [],
421
   "source": [
422
423
    "%matplotlib notebook\n",
    "rb_analysis.analyze_i_meas_pc(circuit_name, timestamp_fgc, timestamp_fgc_ref, min(timestamp_pic), i_meas_df, i_meas_ref_df)\n",
424
    "rb_analysis.calculate_current_miits_i_meas_i_a(i_meas_df, i_a_df, t_quench=0, col_name='MIITS_circ')\n",
425
426
    "rb_analysis.calculate_quench_current(i_meas_df, t_quench=0, col_name='I_Q_circ')\n",
    "rb_analysis.calculate_current_slope(i_meas_df, col_name=['Ramp rate', 'Plateau duration'])"
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "## 6.2. Analysis of the Power Converter Earth Current\n",
    "\n",
    "*CRITERIA*:\n",
    "- Checks whether for t > 3 s, I_EARTH_PCNT is within +/-3 % w.r.t. the reference\n",
    "\n",
    "*PLOT*:  \n",
    "t = 0 s corresponds to respective (actual and reference) FGC PM timestamps\n",
    "\n",
    "First plot (absolute scale)\n",
    "- The main power converter current on the left axis, I_A\n",
    "- Actual and reference earth current on the right axis, IEARTH\n",
    "\n",
    "Second plot (percentage scale)\n",
    "- The main power converter current on the left axis, I_MEAS\n",
    "- 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\n"
   ]
  },
  {
   "cell_type": "code",
454
   "execution_count": null,
455
456
457
   "metadata": {
    "deletable": false
   },
458
   "outputs": [],
459
   "source": [
460
461
    "rb_analysis.analyze_i_earth_pc(circuit_name, timestamp_fgc, i_a_df, i_earth_df, i_earth_ref_df, xlim=(-1, 5))\n",
    "rb_analysis.calculate_max_i_earth_pc(i_earth_df, col_name='I_Earth_max')"
462
463
464
465
   ]
  },
  {
   "cell_type": "code",
466
   "execution_count": null,
467
   "metadata": {
468
    "deletable": false
469
   },
470
   "outputs": [],
471
   "source": [
thbuffet's avatar
thbuffet committed
472
    "%matplotlib notebook\n",
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
    "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, 350))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 7. Energy Extraction System\n",
    "## 7.1. Analysis of the Energy Extraction Voltage\n",
    "\n",
    "*ANALYSIS*:\n",
    "\n",
    "- Calculate U_dump_res (t=0)\n",
    "- Calculate the characteristic time of pseudo-exponential current decay with the charge approach\n",
    "\n",
    "*CRITERIA*:\n",
    "\n",
    "- Check if U_dump_res (t=0) = 0.075*I V (±10%).\n",
    "- Check if the characteristic time of pseudo-exponential decay of I_MEAS from t=1 to 120 s is 110 s<-Tau <130 s\n",
    "- Check if the timestamp difference between FGC and EE an odd point is 100±50 ms  \n",
495
    "  The opening delay was 290±50 ms prior to YETS 2017/8\n",
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
    "- Check if the time stamp difference between FGC and EE an even point: 600±50 ms\n",
    "\n",
    "*GRAPHS*:\n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the FGC\n",
    "\n",
    "First plot (global view):\n",
    "- the power converter converter current on the left axis, I_MEAS\n",
    "- the two energy extraction voltages on the right, U_DUMP_RES, U_DUMP_RES\n",
    "\n",
    "Second plot (triggering view):\n",
    "- the power converter current on the left axis, I_MEAS\n",
    "- the power converter reference current on the left axis, STATUS.I_REF (should stop at the moment of the FGC PM timestamp)\n",
    "- the two energy extraction voltages on the right axis, U_DUMP_RES, U_DUMP_RES\n",
    "- the green dashed line denotes the PIC timestamp"
   ]
  },
  {
   "cell_type": "code",
515
   "execution_count": null,
516
517
518
   "metadata": {
    "scrolled": false
   },
519
   "outputs": [],
520
   "source": [
521
522
523
    "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)\n",
    "rb_analysis.results_table['U_EE_max_ODD'] = u_dump_res_odd_df.max()[0]\n",
    "rb_analysis.results_table['U_EE_max_EVEN'] = u_dump_res_even_df.max()[0]"
524
525
526
527
   ]
  },
  {
   "cell_type": "code",
528
   "execution_count": null,
529
   "metadata": {
530
    "deletable": false
531
   },
532
   "outputs": [],
533
534
535
536
537
538
539
540
   "source": [
    "rb_analysis.analyze_delay_time_u_dump_res_ee(circuit_name, timestamp_fgc, min(timestamp_pic), [timestamp_ee_odd, timestamp_ee_even],\n",
    "                                             i_a_df, i_ref_df, [u_dump_res_odd_df, u_dump_res_even_df])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
541
    "deletable": false
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
   },
   "source": [
    "## 7.2.  Analysis of the Energy Extraction Temperature\n",
    "\n",
    "*CRITERIA*\n",
    "- Checks whether temperature profile is +/-25 K w.r.t. the reference temperature profile\n",
    "- Checks whether maximum temperatures are within [100, 200] K range\n",
    "\n",
    "*PLOT*:\n",
    "\n",
    "- Temperature signals on the left axis, T\n",
    "- A reference signal with an acceptable signal range is also provided on the left axis\n",
    "- t = 0 s corresponds to PM timestamps of each temperature PM entry\n"
   ]
  },
  {
   "cell_type": "code",
559
   "execution_count": null,
560
561
562
563
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
564
   "outputs": [],
565
566
567
568
569
570
   "source": [
    "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",
571
   "execution_count": null,
572
   "metadata": {
573
    "deletable": false
574
   },
575
   "outputs": [],
576
577
578
579
580
581
582
   "source": [
    "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": "markdown",
   "metadata": {
583
    "deletable": false
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
   },
   "source": [
    "# 8. Quench Protection System\n",
    "<img src=\"https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/RB_QPS_Signals.png\" width=75%>\n",
    "\n",
    "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.\n",
    "\n",
    "|Circuit\t|Resistive voltage U1\t|Resistive voltage U2\t|Inductive voltage U1\t|Inductive voltage U2|\n",
    "|-----------|-----------------------|-----------------------|-----------------------|--------------------|\n",
    "|RB.A12\t|Pos\t|Neg\t|Pos\t|Neg|\n",
    "|RB.A23\t|Neg\t|Pos\t|Neg\t|Pos|\n",
    "|RB.A34\t|Neg\t|Pos\t|Neg\t|Pos|\n",
    "|RB.A45\t|Neg\t|Pos\t|Neg\t|Pos|\n",
    "|RB.A56\t|Pos\t|Neg\t|Pos\t|Neg|\n",
    "|RB.A67\t|Pos\t|Neg\t|Pos\t|Neg|\n",
    "|RB.A78\t|Pos\t|Neg\t|Pos\t|Neg|\n",
    "|RB.A81\t|Neg\t|Pos\t|Neg\t|Pos|\n",
    "\n",
    "The thresholds and evaluation times for the QPS on the RB circuits are given in the following table:\n",
    "\n",
    "|Class\t|System\t|Threshold\t|Evaluation time\t|Signal\t|Comment|\n",
    "|-------|-------|-----------|-------------------|-------|:------|\n",
    "|DQAMCNMB_PMSTD\t|iQPS, DQQDL |100 mV\t|10 ms discrimination\t|U_QS0\t|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|\n",
    "|DQAMCNMB_PMHSU\t|iQPS, nQPS |-|-|-|Firing of quench heaters by quench protection. Generation of PM buffers sometimes happens even if there is no heater firing.|\n",
    "|DQAMGNSRB (slow sampling rate), DQAMGNSRB_PMREL (fast sampling rate) |nQPS, DQQDS |500 mV *\t|>20 ms moving average +1 ms discrimination\t|U_DIODE\t|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).|\n",
    "|DQAMGNSRB\t|nQPS, DQQBS| 4 mV\t| >10 s moving average\t| U_RES\t|New QPS. Busbar protection. The signal is not compensated for inductive voltage during ramp.|\n",
    "|DQAMGNDRB_EVEN, DQAMGNDRB_ODD |iQPS, DQQDC |1 mV, 100 mV |1 s\t|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.|\n",
    "|DQAMGNDRB_EVEN, DQAMGNDRB_ODD |iQPS, DQQDB |+200 V | -50 V | \tU_BB1, U_BB2\t|Old QPS. U_BB1 is the total voltage across the sector. U_BB2 is the voltage across the energy extraction (EE)|\n",
    "|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).|\n",
    "\n",
    "*: 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",
   "metadata": {
620
    "deletable": false
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
   },
   "source": [
    "## 8.1. Plot of Voltage Across All Magnets (U_DIODE_RB)\n",
    "\n",
    "*PLOT*: \n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the FGC\n",
    "\n",
    "First plot  (global)\n",
    "- the power converter current on the left axis, I_MEAS\n",
    "- diode voltage on the right axis, U_DIODE_RB\n",
    "\n",
    "Second plot (zoom)\n",
    "- the power converter current on the left axis, I_MEAS\n",
    "- diode voltage on the right axis, U_DIODE_RB"
   ]
  },
  {
   "cell_type": "code",
640
   "execution_count": null,
641
642
643
   "metadata": {
    "deletable": false
   },
644
   "outputs": [],
645
   "source": [
646
    "rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', xlim=(-5, 350))"
647
648
649
650
   ]
  },
  {
   "cell_type": "code",
651
   "execution_count": null,
652
653
654
   "metadata": {
    "deletable": false
   },
655
   "outputs": [],
656
   "source": [
657
    "rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', xlim=(-2, 3))"
658
659
660
661
   ]
  },
  {
   "cell_type": "code",
662
   "execution_count": null,
663
664
665
   "metadata": {
    "deletable": false
   },
666
   "outputs": [],
667
   "source": [
Per Hagen's avatar
Per Hagen committed
668
    "u_diode_with_quench_rb_dfs = rb_analysis.filter_quenched_magnets(u_diode_rb_dfs, results_table['Position'])\n",
669
670
    "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=(-5, 350))\n",
    "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=(-2, 3))"
671
672
673
674
675
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
676
    "deletable": false
677
678
679
680
681
682
683
684
685
686
687
688
   },
   "source": [
    "## 8.2. Analysis of Quenched Magnets by QDS - PM\n",
    "\n",
    "*ANALYSIS*:\n",
    "- 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\n",
    "- determines the type of the QPS board that generated the PM entry (a board could fail to write to PM) - i_qps_board_type\n",
    "- compute the time difference (in seconds) from the first quench - dt_quench"
   ]
  },
  {
   "cell_type": "code",
689
   "execution_count": null,
690
691
692
   "metadata": {
    "deletable": false
   },
693
   "outputs": [],
694
   "source": [
695
    "rb_analysis.results_table[['Circuit Name', 'Position', 'nQPS crate name', 'Delta_t(iQPS-PIC)','I_Q_circ', 'Delta_t(nQPS-PIC)']]"
696
697
698
699
   ]
  },
  {
   "cell_type": "markdown",
700
701
702
   "metadata": {
    "deletable": false
   },
703
704
705
706
707
708
709
   "source": [
    "## 8.3. Analysis of Quench Detection Voltage and Logic Signals for Quenched Magnets\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
710
    "deletable": false
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
   },
   "source": [
    "*ANALYSIS*:\n",
    "- finds the first timestamp, t_st_magnet_ok, for which the ST_MAGNET_OK signal is False indicating that the quench detection signal U_QS0 is outside of the +/- 100 mV threshold.\n",
    "- for t > t_st_magnet_ok, finds the first timestamp, t_st_nqd0 for which the ST_NQD0 signal is Fals indicating that the U_QS0 signal is outside of the +/- 100 mV threshold for more than the 10 ms discrimination time. This signifies quench detection and results in triggering quench heaters.\n",
    "- finds U_QS0 value at the moment of quench detection, u_ST_NQD0 = U_QS0(t=t_st_nqd0)\n",
    "- if the minimum value of the absolute value of U_QS0 is above greater than 100 ms, then find the start time of a quench, t_start_quench, as a moment at which U_QS0 value is 10 mV greater than its initial value. Otherwise, the start time of a quench is set to 0 s.\n",
    "- finds U_QS0 value, u_start_quench, at the moment of quench start as u_start_quench = U_QS0(t=t_start_quench)\n",
    "- the slope of the quench detection signals is calculated as du_dt = (u_ST_NQD0 - u_start_quench) / (t_st_nqd0 - t_start_quench)\n",
    "- the quench detection signal polarity is taken as the sign of its slope\n",
    "- the delay of the quench heaters triggering, t_delay_qh_trigger, is assumed to be the negative value of t_st_magnet_ok, t_delay_qh_trigger = -t_st_magnet_ok\n",
    "\n",
    "Determine source of QH trigger for nQPS signals in PM:\n",
    "- calculates nQPS differences for the symmetric quench detection\n",
    "- selects only the differences that involve the quenched magnet and exclude already quenched magnets in the cell\n",
    "- for t in [-0.2 s, t_st_magnet_ok] take the maximum value of voltage difference\n",
    "- if the maximum is above 1V (considering sun glasses active from t = 0 s) and the time of maximum is less than t_st_magnet_ok, than the QH system was triggered by nQPS, otherwise iQPS\n",
    "- it is assumed that the first training quench was detected by iQPS\n",
    "\n",
    "*PLOT*:\n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the QDS\n",
    "\n",
    "Upper left  (iQPS analog signals)\n",
    "- the quench detection voltage on the left axis, U_QS0\n",
    "- voltage across the first and the second aperture on the right axis, respectively, U_1 and U_2\n",
    "- the green box denotes an envelope of the +/- 100 mV quench detection threshold\n",
    "- the orange box denotes an envelope of the rise of the quench signal from its start until reaching the threshold\n",
    "\n",
    "Lower left  (iQPS digital signals)\n",
    "- the quench detection voltage on the left axis, U_QS0\n",
742
    "- digital quench detection signals, ST_MAGNET_OK, ST_NQD0\n",
743
744
745
746
747
748
749
    "- the green box denotes an envelope of the +/- 100 mV quench detection threshold\n",
    "- the orange box denotes an envelope of the rise of the quench signal from its start until reaching the threshold\n",
    "\n",
    "Upper right (nQPS analog signals)  \n",
    "For PM signals (global view)\n",
    "- the diode voltages used by the nQPS crate for quench detection on the left axis, U_DIODE_RB and U_REF_N1\n",
    "\n",
750
    "For NXCALS signals (global view)\n",
751
752
753
754
755
    "- the diode voltages used by the nQPS crate for quench detection on the left axis, U_DIODE_RB and U_REF_N1 \n",
    "\n",
    "Lower right (nQPS analog signals)  \n",
    "For PM signals  (difference view) \n",
    "- the differences of diode voltages (containing the quenched magnet; in case the signals are missing, the plot is not displayed) used by the nQPS crate for quench detection on the left axis, U (Calculated diode differences)\n",
756
    "- the green box denotes an envelope of 1 V quench detection threshold (assuming active 'sun glasses') before the iQPS quench detection. If the nQPS difference goes outside of the envelope, it means that the quench was detected by nQPS.\n",
757
    "\n",
758
    "For NXCALS signals (zoomed view)\n",
759
760
761
    "- the diode voltages used by the nQPS crate for quench detection on the left axis, U_DIODE_RB and U_REF_N1 \n"
   ]
  },
Per Hagen's avatar
Per Hagen committed
762
763
764
765
766
767
768
769
770
771
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# iQPS Threshold\n",
    "threshold_iqps = 0.1"
   ]
  },
772
773
  {
   "cell_type": "code",
774
   "execution_count": null,
775
776
777
   "metadata": {
    "deletable": false
   },
778
   "outputs": [],
779
   "source": [
780
781
    "%matplotlib inline\n",
    "if u_nqps_dfs:\n",
Per Hagen's avatar
Per Hagen committed
782
    "    rb_analysis.analyze_qds(timestamp_fgc, min(timestamp_pic), u_qds_dfs, u_nqps_dfs, i_meas_df, threshold=threshold_iqps)\n",
783
    "    rb_analysis.results_table[['Circuit Name', 'Position', 'nQPS crate name', 'Delta_t(iQPS-PIC)','I_Q_circ', 'I_Q_M', 'Delta_t(nQPS-PIC)', 'QDS trigger origin', 'dU_iQPS/dt', 'Type of Quench']]"
784
785
786
787
   ]
  },
  {
   "cell_type": "markdown",
788
789
790
   "metadata": {
    "deletable": false
   },
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
   "source": [
    "## 8.4. Analysis of Quench Heater Discharges\n",
    "\n",
    "*CRITERIA*:\n",
    "- all characteristic times of an exponential decay calculated with the 'charge' approach for voltage and current are +/- 3 ms from the reference ones\n",
    "- all initial resistances are +/- 0.5 Ohm from the reference ones\n",
    "- all initial voltages are between 780 and 980 V\n",
    "- all final voltages are between 15 and 70 V\n",
    "\n",
    "*PLOT*:  \n",
    "\n",
    "t = 0 s corresponds to the start of the pseudo-exponential decay.  \n",
    "Line for actual signal is continuous and dashed for the reference.\n",
    "\n",
    "Left plot (Voltage view)\n",
    "- the querried and filtered quench heater voltage on the left axis, U_HDS\n",
    "\n",
    "Middle plot (Current view)\n",
    "- the querried and filtered quench heater current on the left axis, I_HDS\n",
    "\n",
    "Right plot (Resistance view)\n",
    "- the calculated quench heater resistance on the left axis, R_HDS\n"
   ]
  },
  {
   "cell_type": "code",
817
   "execution_count": null,
818
819
820
   "metadata": {
    "deletable": false
   },
821
   "outputs": [],
822
   "source": [
823
824
825
826
827
    "if u_hds_dfs:\n",
    "    rb_analysis.analyze_single_qh_voltage_current_with_ref(source_timestamp_qh_df, u_hds_dfs, i_hds_dfs, u_hds_ref_dfs, i_hds_ref_dfs)\n",
    "    rb_analysis.results_table[['Circuit Name', 'Position', 'Delta_t(iQPS-PIC)','I_Q_circ', 'Delta_t(nQPS-PIC)', 'QDS trigger origin', 'QH analysis']]\n",
    "else:\n",
    "    print(f\"No quench heater discharges!\")"
828
829
830
831
832
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
833
    "deletable": false
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
   },
   "source": [
    "## 8.5. Analysis of Diode Lead Resistance\n",
    "\n",
    "*ANALYSIS*:\n",
    "- calculates diode lead resistance from voltage (board A and B) and current\n",
    "\n",
    "*CRITERIA*\n",
    "- if the maximum resistance is above 50 uOhm, then raise a warning\n",
    "- if the maximum resistance is above 150 uOhm, then raise an alarm\n",
    "\n",
    "*PLOT*:  \n",
    "Upper PM (Input view)  \n",
    "- the main power converter current on the left axis, IAB.I_A\n",
    "- quenched magnet voltage from two boards, U_DIODE_A, U_DIODE_B. The difference between both signals is the diode lead voltage.\n",
    "- reference nQPS board voltage on the right axis, U_REF\n",
    "- diplayed on the left only if a quench occured no later than 2 seconds after the FGC PM timestamp\n",
    "- t = 0 s corresponds to the PM timestamp of the QPS\n",
    "\n",
    "Lower PM (Output view)  \n",
    "- the main power converter current on the left axis, IAB.I_A\n",
    "- the calculated diode lead resistance on the right axis, R_DIODE_LEADS\n",
    "- diplayed on the left only if a quench occured no later than 2 seconds after the FGC PM timestamp\n",
    "- t = 0 s corresponds to the PM timestamp of the QPS\n",
    "\n",
    "Upper CALS (Input view)  \n",
    "- the main power converter current on the left axis, I_MEAS\n",
    "- quenched magnet voltage from two boards is saved as a single signal, U_DIODE_RB. The two signals are stored by means of value toggling between board A and board B. The difference between both sub-signals is the diode lead voltage.\n",
    "- t = 0 s corresponds to the PM timestamp of the FGC\n",
    "\n",
    "Lower CALS (Output view)  \n",
    "- the main power converter current on the left axis, I_MEAS\n",
    "- the calculated diode lead resistance on the right axis, R_DIODE_LEADS\n",
    "- t = 0 s corresponds to the PM timestamp of the FGC"
   ]
  },
  {
   "cell_type": "code",
872
   "execution_count": null,
873
   "metadata": {
874
    "deletable": false,
875
876
    "scrolled": false
   },
877
   "outputs": [],
878
   "source": [
879
880
    "rb_analysis.analyze_diode_leads(source_timestamp_qds_df, timestamp_fgc, results_table['I_Q_M'], circuit_name, i_a_u_diode_u_ref_pm_dfs, i_meas_u_diode_nxcals_dfs)\n",
    "rb_analysis.results_table[['Circuit Name', 'Date (FGC)', 'Time (FGC)', 'R_DL_max', 'I at R_DL_max']]"
881
882
883
884
885
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
886
    "deletable": false
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
   },
   "source": [
    "## 8.6. Plot of Voltage Feelers\n",
    "\n",
    "*ANALYSIS*:\n",
    "- if the voltage of a voltage feeler is equal to 0 V, then it means that the corresponding card is disabled\n",
    "- if the voltage of a voltage feeler is equal to -2000 V, then it means that the corresponding card is not communicating\n",
    "\n",
    "*PLOT*:  \n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the FGC\n",
    "\n",
    "First plot (global)\n",
    "- the power converter current on the left axis, I_MEAS\n",
    "- earth voltage on the right axis, U_EARTH_RB\n",
    "\n",
    "Second plot (zoom)\n",
    "- the power converter current on the left axis, I_MEAS\n",
    "- earth voltage on the right axis, U_EARTH_RB\n"
   ]
  },
  {
   "cell_type": "code",
910
   "execution_count": null,
911
   "metadata": {
912
    "deletable": false,
913
914
    "scrolled": false
   },
915
   "outputs": [],
916
   "source": [
917
918
919
920
921
922
923
924
925
    "rb_analysis.analyze_voltage_feelers(circuit_name, timestamp_fgc, i_meas_df, u_earth_rb_dfs, 'U_EARTH_RB', 'VF')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
Per Hagen's avatar
Per Hagen committed
926
    "if not is_automatic:\n",
927
    "    rb_analysis.results_table['V feeler analysis'] = get_expert_decision('Voltage feeler analysis: ', ['PASS', 'FAIL'])"
928
929
930
931
932
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
933
    "deletable": false
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
   },
   "source": [
    "## 8.7. Plot of Current Leads\n",
    "\n",
    "*CRITERIA*:\n",
    "\n",
    "- Check if the quench detection signal for U_HTS is below the threshold (3 mV)\n",
    "- Check if the quench detection signal for U_RES is below the threshold (100 mV)\n",
    "\n",
    "*PLOT*:  \n",
    "\n",
    "- t = 0 s corresponds to the FGC timestamp\n",
    "\n",
    "Global view (for odd and even leads)\n",
    "- voltage of the HTS leads on the left axis, U_HTS\n",
    "- voltage of the normal conducting leads on the left axis, U_RES\n",
    "- blue horizontal dashed line denotes the QPS timestamp\n",
    "\n",
    "Zoom view (for odd and even leads)\n",
    "- voltage of the HTS leads on the left axis, U_HTS\n",
    "- blue horizontal dashed line denotes the QPS timestamp\n",
    "- cyan horizontal dashed line denotes the EE odd timestamp\n",
    "- green horizontal dashed line denotes the EE even timestamp"
   ]
  },
  {
   "cell_type": "code",
961
   "execution_count": null,
962
   "metadata": {
963
    "deletable": false,
964
965
    "scrolled": false
   },
966
   "outputs": [],
967
   "source": [
Per Hagen's avatar
Per Hagen committed
968
    "rb_analysis.analyze_leads_voltage(u_hts_odd_dfs+u_hts_even_dfs, circuit_name, timestamp_fgc, timestamp_qps=source_timestamp_qds_df.loc[0, 'timestamp'], signal='U_HTS', value_min=-0.003, value_max=0.003)"
969
970
971
972
   ]
  },
  {
   "cell_type": "code",
973
   "execution_count": null,
974
   "metadata": {
975
    "deletable": false
976
   },
977
   "outputs": [],
978
979
980
981
982
983
   "source": [
    "rb_analysis.plot_leads_voltage_zoom(u_hts_odd_dfs+u_hts_even_dfs, circuit_name, timestamp_fgc, source_timestamp_qds_df.loc[0, 'timestamp'], timestamp_ee_odd, timestamp_ee_even, signal='U_HTS')"
   ]
  },
  {
   "cell_type": "code",
984
   "execution_count": null,
985
   "metadata": {
986
    "deletable": false
987
   },
988
   "outputs": [],
989
990
991
992
   "source": [
    "rb_analysis.analyze_leads_voltage(u_res_odd_dfs+u_res_even_dfs, circuit_name, timestamp_fgc, timestamp_qps=source_timestamp_qds_df.loc[0, 'timestamp'], signal='U_RES', value_min=-0.1, value_max=0.1)"
   ]
  },
993
994
995
  {
   "cell_type": "code",
   "execution_count": null,
996
997
998
   "metadata": {
    "deletable": false
   },
999
1000
   "outputs": [],
   "source": [
Per Hagen's avatar
Per Hagen committed
1001
1002
    "if not is_automatic:\n",
    "    rb_analysis.results_table['FPA Reason'] = get_expert_decision('Reason for FPA: ', ['Heater-provoked', 'QPS trip', 'Converter trip', 'EE spurious opening', 'Spurious heater firing', 'Busbar quench', 'Magnet quench', 'HTS current lead quench' ,'RES current lead overvoltage', 'No quench', 'Unknown'])\n",
Per Hagen's avatar
Per Hagen committed
1003
    "    rb_analysis.results_table['QDS trigger origin'] = get_expert_decision('QDS trigger origin: ', ['iQPS', 'nQPS', 'HTS current lead', 'RES current lead','Busbar', 'No quench'])"
1004
1005
   ]
  },
1006
1007
1008
  {
   "cell_type": "markdown",
   "metadata": {
1009
    "deletable": false
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
   },
   "source": [
    "# 9. Plot of Energy Extraction after 3 h from an FPA\n",
    "\n",
    "*ANALYSIS*:\n",
    "- Checks if all 6 temperature signals are below 70 degC after 2 hours from the FPA\n",
    "\n",
    "*PLOT*:\n",
    "\n",
    "- Temperature signals on the left axis, T_RES_BODY\n",
    "- Temperature status on the right axis (1 - temperature exceeds the safe limit, 0 - temperature in the safe limit), ST_RES_OVERTEMP\n",
    "- t = 0 s corresponds to FGC PM timestamp\n",
    "- Green box denotes range of temperature check. The temperature should be below 70 degC after 2 hours from the FPA"
   ]
  },
  {
   "cell_type": "code",
1027
   "execution_count": null,
1028
   "metadata": {
1029
    "deletable": false,
1030
1031
    "scrolled": false
   },
1032
   "outputs": [],
1033
1034
1035
1036
1037
1038
1039
   "source": [
    "unix_time_now = Time.to_unix_timestamp(Time.now())\n",
    "time_diff = (unix_time_now - timestamp_fgc)*1e-9\n",
    "\n",
    "if t_res_body_long_dfs and st_res_overtemp_long_dfs:\n",
    "    rb_analysis.analyze_ee_temp_and_cooling(t_res_body_long_dfs, st_res_overtemp_long_dfs, t_greater=2*3600, value_max=70)\n",
    "elif time_diff > 3*3600:\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
1040
1041
1042
1043
    "    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) \\\n",
    "                        + 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)\n",
    "    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) \\\n",
    "                            + rb_query.query_ee_nxcals(timestamp_fgc, system='EE_EVEN', signal_names='ST_RES_OVERTEMP', spark=spark, t_thr=0)\n",
1044
1045
1046
1047
1048
1049
1050
    "    rb_analysis.analyze_ee_temp_and_cooling(t_res_body_long_dfs, st_res_overtemp_long_dfs, t_greater=2*3600, value_max=70)\n",
    "else:\n",
    "    print('Wait {} seconds to query EE temperature and status signals'.format(time_diff))"
   ]
  },
  {
   "cell_type": "markdown",
1051
1052
1053
   "metadata": {
    "deletable": false
   },
1054
1055
1056
1057
1058
1059
   "source": [
    "# 10. Signature Decision"
   ]
  },
  {
   "cell_type": "code",
1060
   "execution_count": null,
1061
1062
1063
   "metadata": {
    "deletable": false
   },
1064
   "outputs": [],
1065
   "source": [
Per Hagen's avatar
Per Hagen committed
1066
1067
    "if not is_automatic:\n",
    "    signature = get_expert_decision('Expert Signature Decision: ', ['PASSED', 'FAILED'])"
1068
1069
1070
1071
1072
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
1073
    "deletable": false
1074
1075
1076
1077
1078
1079
1080
   },
   "source": [
    "# 11. Final Report"
   ]
  },
  {
   "cell_type": "code",
1081
   "execution_count": null,
1082
   "metadata": {
1083
    "deletable": false,
1084
1085
    "scrolled": false
   },
1086
   "outputs": [],
1087
1088
1089
   "source": [
    "pd.set_option('display.max_columns', None)\n",
    "pd.set_option('display.max_rows', None)\n",
1090
    "analysis_start_time = Time.get_analysis_start_time()\n",
1091
1092
1093
    "date_time_fgc = Time.to_datetime(timestamp_fgc).strftime(\"%Y-%m-%d-%Hh%M\")\n",
    "!mkdir -p /eos/project/m/mp3/RB/$circuit_name/$hwc_test\n",
    "\n",
1094
    "file_name = \"{}_FPA-{}-{}_{}\".format(circuit_name, date_time_fgc, analysis_start_time, signature)\n",
1095
1096
    "full_path = '/eos/project/m/mp3/RB/{}/{}/{}.csv'.format(circuit_name, hwc_test, file_name)\n",
    "\n",
1097
    "mp3_results_table = rb_analysis.create_mp3_results_table(min(timestamp_pic), timestamp_fgc)\n",
1098
    "display(HTML(mp3_results_table.T.to_html()))\n",
1099
    "mp3_results_table.to_csv(full_path, index=False)\n",
1100
1101
1102
1103
    "print('MP3 results table saved to (Windows): ' + '\\\\\\\\cernbox-smb' + full_path.replace('/', '\\\\'))\n",
    "\n",
    "apply_report_template()\n",
    "file_name_html = file_name + '.html'\n",
1104
    "full_path = '/eos/project/m/mp3/RB/{}/{}/{}'.format(circuit_name, hwc_test, file_name_html)\n",
1105
1106
1107
    "print('Compact notebook report saved to (Windows): ' + '\\\\\\\\cernbox-smb' + full_path.replace('/', '\\\\'))\n",
    "display(Javascript('IPython.notebook.save_notebook();'))\n",
    "Time.sleep(5)\n",
1108
    "!{sys.executable} -m jupyter nbconvert --to html $'AN_RB_PLI2.f1.ipynb' --output /eos/project/m/mp3/RB/$circuit_name/$hwc_test/$file_name_html --TemplateExporter.exclude_input=True --TagRemovePreprocessor.remove_all_outputs_tags='[\"skip_output\"]' --TagRemovePreprocessor.remove_cell_tags='[\"skip_cell\"]'"
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
1135
   "version": "3.6.5"
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
  },
  "sparkconnect": {
   "bundled_options": [
    "NXCALS",
    "SparkMetrics"
   ],
   "list_of_options": []
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": false,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "837px",
    "left": "1331px",
    "top": "113.453125px",
    "width": "384px"
   },
   "toc_section_display": false,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}