AN_RQ_FPA.ipynb 47.5 KB
Newer Older
1
2
3
4
{
 "cells": [
  {
   "cell_type": "markdown",
5
6
7
   "metadata": {
    "deletable": false
   },
8
9
   "source": [
    "<h1><center>Analysis of an FPA in an RQ Circuit</center></h1>\n",
10
    "<img src=\"https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rq/RQ.png\" width=75%>\n",
11
    "source: Test Procedure and Acceptance Criteria for the 13 kA Quadrupole (RQD-RQF) Circuits, MP3 Procedure, <a href=\"https://edms.cern.ch/document/874714\">https://edms.cern.ch/document/874714</a> (Please follow this link for the latest version)"
12
13
14
15
   ]
  },
  {
   "cell_type": "markdown",
16
17
18
   "metadata": {
    "deletable": false
   },
19
20
   "source": [
    "# Analysis Assumptions\n",
21
22
    "- 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",
23
24
    "\n",
    "# Plot Convention\n",
25
26
    "- 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",
27
    "- 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",
28
29
30
    "- 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",
31
    "- Each plot has an individual time-synchronization mentioned explicitly in the description.\n",
32
    "- If an axis has a single signal, then the color of the label matches the signal's color. Otherwise, the label color is black.\n"
33
34
35
36
   ]
  },
  {
   "cell_type": "markdown",
37
38
39
   "metadata": {
    "deletable": false
   },
40
   "source": [
41
    "# 0. Initialise Working Environment"
42
43
44
45
   ]
  },
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
46
   "execution_count": null,
47
48
49
   "metadata": {
    "deletable": false
   },
thbuffet's avatar
thbuffet committed
50
   "outputs": [],
51
   "source": [
52
    "# External libraries\n",
53
    "print('Loading (1/12)'); import pandas as pd\n",
54
    "print('Loading (2/12)'); import sys, warnings\n",
55
    "print('Loading (3/12)'); from IPython.display import display, Javascript, clear_output, HTML\n",
56
57
    "\n",
    "# Internal libraries\n",
58
59
60
61
62
63
    "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.RqCircuitQuery import RqCircuitQuery\n",
    "print('Loading (8/12)'); from lhcsmapi.analysis.RqCircuitAnalysis import RqCircuitAnalysis\n",
    "print('Loading (9/12)'); from lhcsmapi.analysis.report_template import apply_report_template\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
64
    "print('Loading (10/12)'); from lhcsmapi.gui.DateTimeBaseModule import DateTimeBaseModule\n",
65
66
    "print('Loading (11/12)'); from lhcsmapi.gui.pc.FgcPmSearchModuleMediator import FgcPmSearchModuleMediator\n",
    "print('Loading (12/12)'); from lhcsmapi.analysis.expert_input import get_expert_decision\n",
67
    "\n",
68
69
70
    "clear_output()\n",
    "lhcsmapi.get_lhcsmapi_version()\n",
    "lhcsmapi.get_lhcsmhwc_version('../__init__.py')"
71
72
73
74
   ]
  },
  {
   "cell_type": "markdown",
75
76
77
   "metadata": {
    "deletable": false
   },
78
   "source": [
79
80
81
82
83
84
85
86
87
88
89
90
91
    "# 1. Select FGC Post Mortem Entry"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false,
    "tags": [
     "skip_cell"
    ]
   },
   "source": [
    "In order to perform an analysis of a quench in the RQ circuits please:\n",
92
93
94
95
    "1. Select circuit name (e.g., RQ.A12, this corresponds to circuits RQD.A12, RQF.A12)\n",
    "2. Choose start and end time\n",
    "3. Choose analysis mode (Automatic by default)\n",
    "\n",
96
97
98
    "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 a timestamp from the 'FGC PM Entries' list to be processed by the following cells.\n",
    "\n",
    "**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.**"
99
100
   ]
  },
101
102
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
103
   "execution_count": null,
104
   "metadata": {
105
    "deletable": false,
106
    "scrolled": false
107
   },
thbuffet's avatar
thbuffet committed
108
   "outputs": [],
109
110
   "source": [
    "circuit_type = 'RQ'\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
111
    "fgc_pm_search = FgcPmSearchModuleMediator(DateTimeBaseModule(start_date_time='2021-02-25 00:00:00+01:00', \n",
112
    "                                                             end_date_time='2021-03-17 00:00:00+01:00'), circuit_type=circuit_type)"
113
114
115
116
   ]
  },
  {
   "cell_type": "markdown",
117
118
119
   "metadata": {
    "deletable": false
   },
120
121
122
123
124
125
   "source": [
    "# 2. Query All Signals Prior to Analysis"
   ]
  },
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
126
   "execution_count": null,
127
   "metadata": {
128
    "deleteable": false,
129
    "scrolled": false,
130
131
132
    "tags": [
     "skip_output"
    ]
133
   },
thbuffet's avatar
thbuffet committed
134
   "outputs": [],
135
136
137
138
139
140
   "source": [
    "author = fgc_pm_search.get_author()\n",
    "circuit_names = fgc_pm_search.get_fgc_circuit()\n",
    "timestamp_fgc_rqd, timestamp_fgc_rqf = fgc_pm_search.get_fgc_timestamp()\n",
    "is_automatic = fgc_pm_search.is_automatic_mode()\n",
    "\n",
141
142
    "rqd_query = RqCircuitQuery(circuit_type, circuit_names[0], max_executions=30)\n",
    "rqf_query = RqCircuitQuery(circuit_type, circuit_names[1], max_executions=25)\n",
143
144
145
    "\n",
    "with Timer():\n",
    "    # PC\n",
146
147
    "    i_meas_rqd_df, i_a_rqd_df, i_earth_rqd_df, i_earth_pcnt_rqd_df, i_ref_rqd_df = rqd_query.query_pc_pm(timestamp_fgc_rqd, timestamp_fgc_rqd, signal_names=['I_MEAS', 'I_A', 'IEARTH', 'I_EARTH_PCNT', 'I_REF'])\n",
    "    i_meas_rqf_df, i_a_rqf_df, i_earth_rqf_df, i_earth_pcnt_rqf_df, i_ref_rqf_df = rqf_query.query_pc_pm(timestamp_fgc_rqf, timestamp_fgc_rqf, signal_names=['I_MEAS', 'I_A', 'IEARTH', 'I_EARTH_PCNT', 'I_REF'])\n",
148
149
150
151
    "\n",
    "    timestamp_fgc_ref_rqd = rqd_query.get_timestamp_ref(col='fgcPm')\n",
    "    timestamp_fgc_ref_rqf = rqf_query.get_timestamp_ref(col='fgcPm')\n",
    "\n",
152
153
    "    i_meas_ref_rqd_df, i_earth_rqd_ref_df, i_earth_pcnt_rqd_ref_df = rqd_query.query_pc_pm(timestamp_fgc_ref_rqd, timestamp_fgc_ref_rqd, signal_names=['I_MEAS', 'IEARTH', 'I_EARTH_PCNT'])\n",
    "    i_meas_ref_rqf_df, i_earth_rqf_ref_df, i_earth_pcnt_rqf_ref_df = rqf_query.query_pc_pm(timestamp_fgc_ref_rqf, timestamp_fgc_ref_rqf, signal_names=['I_MEAS', 'IEARTH', 'I_EARTH_PCNT'])\n",
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    "\n",
    "    # PIC\n",
    "    timestamp_pic_rqd = rqd_query.find_timestamp_pic(timestamp_fgc_rqd, spark=spark)\n",
    "    timestamp_pic_rqf = rqf_query.find_timestamp_pic(timestamp_fgc_rqf, spark=spark)\n",
    "\n",
    "    # EE\n",
    "    source_timestamp_ee_rqd_df = rqd_query.find_source_timestamp_ee(timestamp_fgc_rqd)\n",
    "    timestamp_ee_rqd = source_timestamp_ee_rqd_df.loc[0, 'timestamp']\n",
    "    u_dump_res_rqd_df = rqd_query.query_ee_u_dump_res_pm(timestamp_ee_rqd, timestamp_fgc_rqd, system='EE', signal_names=['U_DUMP_RES'])[0]\n",
    "\n",
    "    source_timestamp_ee_rqf_df = rqf_query.find_source_timestamp_ee(timestamp_fgc_rqf)\n",
    "    timestamp_ee_rqf = source_timestamp_ee_rqf_df.loc[0, 'timestamp']\n",
    "    u_dump_res_rqf_df = rqf_query.query_ee_u_dump_res_pm(timestamp_ee_rqf, timestamp_fgc_rqf, system='EE', signal_names=['U_DUMP_RES'])[0]\n",
    "\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
168
    "    t_res_0_rqd_df = rqd_query.query_ee_t_res_pm(source_timestamp_ee_rqd_df.loc[0, 'timestamp'], timestamp_fgc_rqd, system='EE', signal_names=['T_RES'])[0]\n",
169
170
171
172
    "    if len(source_timestamp_ee_rqd_df) > 1:\n",
    "        t_res_1_rqd_df = rqd_query.query_ee_t_res_pm(source_timestamp_ee_rqd_df.loc[1, 'timestamp'], timestamp_fgc_rqd, system='EE', signal_names=['T_RES'])[0]\n",
    "    else:\n",
    "        t_res_1_rqd_df = pd.DataFrame(columns=['T_RES'])\n",
173
    "\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
174
    "    t_res_0_rqf_df = rqf_query.query_ee_t_res_pm(source_timestamp_ee_rqf_df.loc[0, 'timestamp'], timestamp_fgc_rqf, system='EE', signal_names=['T_RES'])[0]\n",
175
176
177
178
    "    if len(source_timestamp_ee_rqf_df) > 1:\n",
    "        t_res_1_rqf_df = rqf_query.query_ee_t_res_pm(source_timestamp_ee_rqf_df.loc[1, 'timestamp'], timestamp_fgc_rqf, system='EE', signal_names=['T_RES'])[0]\n",
    "    else:\n",
    "        t_res_1_rqf_df = pd.DataFrame(columns=['T_RES'])\n",
179
180
181
182
183
184
185
186
    "\n",
    "    # EE - REF\n",
    "    timestamp_ee_ref_rqd = rqd_query.get_timestamp_ref(col='eePm')\n",
    "    timestamp_ee_ref_rqf = rqf_query.get_timestamp_ref(col='eePm')\n",
    "\n",
    "    source_timestamp_ee_rqd_ref_df = rqd_query.find_source_timestamp_ee(timestamp_ee_ref_rqd)\n",
    "    source_timestamp_ee_rqf_ref_df = rqf_query.find_source_timestamp_ee(timestamp_ee_ref_rqf)\n",
    "\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
187
    "    t_res_0_rqd_ref_df = rqd_query.query_ee_t_res_pm(source_timestamp_ee_rqd_ref_df.loc[0, 'timestamp'], timestamp_fgc_ref_rqd, system='EE', signal_names=['T_RES'])[0]\n",
188
189
190
191
    "    if len(source_timestamp_ee_rqd_ref_df) > 1:\n",
    "        t_res_1_rqd_ref_df = rqd_query.query_ee_t_res_pm(source_timestamp_ee_rqd_ref_df.loc[1, 'timestamp'], timestamp_fgc_ref_rqd, system='EE', signal_names=['T_RES'])[0]\n",
    "    else:\n",
    "        t_res_1_rqd_ref_df = pd.DataFrame(columns=['T_RES'])\n",
192
    "\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
193
    "    t_res_0_rqf_ref_df = rqf_query.query_ee_t_res_pm(source_timestamp_ee_rqf_ref_df.loc[0, 'timestamp'], timestamp_fgc_ref_rqf, system='EE', signal_names=['T_RES'])[0]\n",
194
195
196
197
    "    if len(source_timestamp_ee_rqf_ref_df) > 1:\n",
    "        t_res_1_rqf_ref_df = rqf_query.query_ee_t_res_pm(source_timestamp_ee_rqf_ref_df.loc[1, 'timestamp'], timestamp_fgc_ref_rqf, system='EE', signal_names=['T_RES'])[0]\n",
    "    else:\n",
    "        t_res_1_rqf_ref_df = pd.DataFrame(columns=['T_RES'])\n",
198
199
    "\n",
    "    # iQPS\n",
200
    "    source_timestamp_qds_rq_df = rqd_query.find_source_timestamp_qds(timestamp_fgc_rqd, duration=[(10, 's'), (200, 's')])\n",
201
202
203
204
205
206
207
    "    \n",
    "    if Time.to_unix_timestamp(timestamp_fgc_rqd) > 1577833200000000000:\n",
    "        iqps_analog_dfs = rqd_query.query_iqps_analog_pm(source_timestamp_qds_rq_df, signal_names=['U_QS0_INT_A', 'U_QS0_EXT_A'])\n",
    "        iqps_digital_dfs = rqd_query.query_iqps_analog_pm(source_timestamp_qds_rq_df, signal_names=['ST_NOLATCH_BR_EXT_A', 'ST_NOLATCH_BR_INT_A', 'ST_NOTRIG_BR_EXT_A', 'ST_NOTRIG_BR_INT_A'])\n",
    "    else:\n",
    "        iqps_analog_dfs = rqd_query.query_iqps_analog_pm(source_timestamp_qds_rq_df, signal_names=['U_QS0_EXT', 'U_QS0_INT', 'U_1_EXT', 'U_2_EXT', 'U_1_INT', 'U_2_INT'])\n",
    "        iqps_digital_dfs = rqd_query.query_iqps_analog_pm(source_timestamp_qds_rq_df, signal_names=['ST_MAGNET_OK', 'ST_MAGNET_OK_INT', 'ST_NQD0_EXT', 'ST_NQD0_INT'])\n",
208
209
210
211
212
213
214
    "\n",
    "    # nQPS\n",
    "    source_timestamp_nqps_rqd_df = rqd_query.find_source_timestamp_nqps(timestamp_fgc_rqd)\n",
    "    source_timestamp_nqps_rqf_df =  rqf_query.find_source_timestamp_nqps(timestamp_fgc_rqf)\n",
    "\n",
    "    u_nqps_rqd_dfs = rqd_query.query_nqps_voltage_pm(source_timestamp_qds_rq_df)\n",
    "    u_nqps_rqf_dfs = rqf_query.query_nqps_voltage_pm(source_timestamp_qds_rq_df)\n",
215
216
    "    \n",
    "    # Results table\n",
217
    "    results_table = rqd_query.create_report_analysis_template(source_timestamp_qds_rq_df, source_timestamp_nqps_rqd_df, min(timestamp_fgc_rqd, timestamp_fgc_rqf), min(timestamp_pic_rqd, timestamp_pic_rqf), '../__init__.py', i_meas_rqd_df, i_meas_rqf_df, author)\n",
218
219
    "\n",
    "    # QH\n",
220
221
    "    source_timestamp_qh_rq_df = rqd_query.find_source_timestamp_qh(timestamp_fgc_rqd, duration=[(10, 's'), (200, 's')])\n",
    "    u_hds_rq_dfs = rqd_query.query_qh_pm(source_timestamp_qh_rq_df, signal_names='U_HDS') \n",
Michal Maciejewski's avatar
Michal Maciejewski committed
222
223
    "    if Time.to_unix_timestamp(timestamp_fgc_rqd) > 1577833200000000000:\n",
    "        i_hds_rq_dfs = rqd_query.query_qh_pm(source_timestamp_qh_rq_df, signal_names='I_HDS') \n",
224
    "    u_hds_rq_ref_dfs = rqd_query.query_qh_pm(source_timestamp_qh_rq_df, signal_names='U_HDS', is_ref=True)\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
225
226
    "    if Time.to_unix_timestamp(timestamp_fgc_rqd) > 1577833200000000000:\n",
    "        i_hds_rq_ref_dfs = rqd_query.query_qh_pm(source_timestamp_qh_rq_df, signal_names='I_HDS', is_ref=True)\n",
227
228
    "\n",
    "    # DIODE LEADS\n",
229
230
    "    i_meas_u_diode_u_ref_rqd_pm_dfs = rqd_query.query_current_voltage_diode_leads_pm(timestamp_fgc_rqd, source_timestamp_qds_rq_df)\n",
    "    i_meas_u_diode_rqd_nxcals_dfs = rqd_query.query_current_voltage_diode_leads_nxcals(source_timestamp_qds_rq_df, spark=spark)\n",
231
    "\n",
232
233
    "    i_meas_u_diode_u_ref_rqf_pm_dfs = rqf_query.query_current_voltage_diode_leads_pm(timestamp_fgc_rqf, source_timestamp_qds_rq_df)\n",
    "    i_meas_u_diode_rqf_nxcals_dfs = rqf_query.query_current_voltage_diode_leads_nxcals(source_timestamp_qds_rq_df, spark=spark)\n",
234
235
236
    "\n",
    "    # DFB\n",
    "    source_timestamp_leads_rqd_df = rqd_query.find_timestamp_leads(timestamp_fgc_rqd)\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
237
238
    "    u_hts_rqd_dfs = rqd_query.query_leads(timestamp_fgc_rqd, source_timestamp_leads_rqd_df, signal_names=['U_HTS'], spark=spark)\n",
    "    u_res_rqd_dfs = rqd_query.query_leads(timestamp_fgc_rqd, source_timestamp_leads_rqd_df, signal_names=['U_RES'], spark=spark)\n",
239
240
    "\n",
    "    source_timestamp_leads_rqf_df = rqf_query.find_timestamp_leads(timestamp_fgc_rqf)\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
241
242
    "    u_hts_rqf_dfs = rqf_query.query_leads(timestamp_fgc_rqf, source_timestamp_leads_rqf_df, signal_names=['U_HTS'], spark=spark)\n",
    "    u_res_rqf_dfs = rqf_query.query_leads(timestamp_fgc_rqf, source_timestamp_leads_rqf_df, signal_names=['U_RES'], spark=spark)\n",
243
244
    "\n",
    "    # U_DIODE\n",
245
246
    "    u_diode_rqd_dfs = rqd_query.query_voltage_nxcals('DIODE_RQD', 'U_DIODE_RQD', timestamp_fgc_rqd, spark=spark)\n",
    "    u_diode_rqf_dfs = rqf_query.query_voltage_nxcals('DIODE_RQF', 'U_DIODE_RQF', timestamp_fgc_rqf, spark=spark)\n",
247
248
    "\n",
    "    # U_EARTH\n",
249
250
    "    u_earth_rqd_dfs = rqd_query.query_voltage_nxcals('VF_RQD', 'U_EARTH_RQD', timestamp_fgc_rqd, spark=spark)\n",
    "    u_earth_rqf_dfs = rqf_query.query_voltage_nxcals('VF_RQF', 'U_EARTH_RQF', timestamp_fgc_rqf, spark=spark)\n",
251
252
253
254
255
256
    "\n",
    "    rq_analysis = RqCircuitAnalysis(circuit_type, results_table, is_automatic=is_automatic)"
   ]
  },
  {
   "cell_type": "markdown",
257
258
259
   "metadata": {
    "deletable": false
   },
260
   "source": [
261
262
263
264
265
    "# 3. Circuit Parameters Table"
   ]
  },
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
266
   "execution_count": null,
267
268
269
   "metadata": {
    "deletable": false
   },
thbuffet's avatar
thbuffet committed
270
   "outputs": [],
271
272
273
274
275
276
   "source": [
    "rq_analysis.display_parameters_table(circuit_names[0])"
   ]
  },
  {
   "cell_type": "markdown",
277
278
279
   "metadata": {
    "deletable": false
   },
280
281
282
   "source": [
    "# 4. Timestamps\n",
    "## 4.1. FPA\n",
283
284
285
286
287
288
289
    "Table below provides timestamps ordered achronologically and represents the sequence of events that occurred in the analyzed circuit: PIC_RQD, PIC_RQF, iQPS, nQPS, FGC_RQD, FGC_RQF, EE_RQD, EE_RQF and optionally LEADS_RQD and LEADS_RQF, provided they exist. 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",
    "- Time stamp difference between FGC and EE: 100±15 ms \n",
    "\n",
    "If one or more of these conditions are not fulfilled, then an in-depth analysis has to be performed by the QPS team."
290
291
292
293
   ]
  },
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
294
   "execution_count": null,
295
   "metadata": {
296
    "deletable": false,
297
298
    "scrolled": true
   },
thbuffet's avatar
thbuffet committed
299
   "outputs": [],
300
301
302
303
304
305
306
307
308
309
   "source": [
    "timestamp_dct = {'FGC_RQD': timestamp_fgc_rqd, 'FGC_RQF': timestamp_fgc_rqf, \n",
    "                 'PIC_RQD': timestamp_pic_rqd, 'PIC_RQF': timestamp_pic_rqf,\n",
    "                 'EE_RQD': source_timestamp_ee_rqd_df, 'EE_RQF': source_timestamp_ee_rqf_df,\n",
    "                 'iQPS': source_timestamp_qds_rq_df, 'nQPS': source_timestamp_nqps_rqd_df,\n",
    "                 'LEADS_RQD': source_timestamp_leads_rqd_df, 'LEADS_RQF': source_timestamp_leads_rqf_df}\n",
    "\n",
    "rq_analysis.create_timestamp_table(timestamp_dct)"
   ]
  },
310
311
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
312
   "execution_count": null,
313
   "metadata": {},
thbuffet's avatar
thbuffet committed
314
   "outputs": [],
315
316
   "source": [
    "value_range_ee_rqf = (0.085, 0.115)\n",
thbuffet's avatar
thbuffet committed
317
    "if not rq_analysis.check_pic_ee_timestamp_difference(timestamp_pic_rqf, timestamp_ee_rqf, value_range_ee_rqf):\n",
318
    "    warnings.warn(f\"The time difference between PIC and EE RQF is not within the given range_value {value_range_ee_rqf}.PIC :{timestamp_fgc_rqf} and EE_RQF {timestamp_ee_rqf}\")"
319
320
321
322
323
324
325
326
327
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "value_range_ee_rqd = (0.085, 0.115)\n",
thbuffet's avatar
thbuffet committed
328
    "if not rq_analysis.check_pic_ee_timestamp_difference(timestamp_pic_rqd, timestamp_ee_rqd, value_range_ee_rqd):\n",
329
    "    warnings.warn(f\"The time difference between PIC and EE RQD is not within the given range_value {value_range_ee_rqf}.PIC :{timestamp_pic_rqd} and EE_RQD {timestamp_ee_rqd}\")"
330
331
   ]
  },
332
333
  {
   "cell_type": "markdown",
334
335
336
   "metadata": {
    "deletable": false
   },
337
   "source": [
338
    "## 4.2. Reference\n",
339
340
341
342
343
344
345
    "Table below contains reference timestamps of signals used for comparison to the analyzed FPA. The reference comes as the last PNO.b3 HWC test with activation of EE systems and no magnets quenching."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
346
    "deletable": false
347
348
349
350
351
352
353
354
355
   },
   "outputs": [],
   "source": [
    "timestamp_ref_dct = {'FGC_RQD': timestamp_fgc_ref_rqd, 'FGC_RQF': timestamp_fgc_ref_rqf, \n",
    "                     'EE_RQD_first': source_timestamp_ee_rqd_ref_df.loc[0, 'timestamp'], 'EE_RQD_second': source_timestamp_ee_rqd_ref_df.loc[1, 'timestamp'],\n",
    "                     'EE_RQF_first': source_timestamp_ee_rqd_ref_df.loc[0, 'timestamp'], 'EE_RQF_second': source_timestamp_ee_rqd_ref_df.loc[1, 'timestamp']}\n",
    "rq_analysis.create_ref_timestamp_table(timestamp_ref_dct)"
   ]
  },
356
357
  {
   "cell_type": "markdown",
358
359
360
   "metadata": {
    "deletable": false
   },
361
   "source": [
362
363
    "# 5. PIC\n",
    "## 5.1. Analysis of the PIC Timestamp\n",
364
    "\n",
365
366
    "*CRITERIA*:\n",
    "- Check iff the the difference between RQD and RQF PIC timestamps is less than 1 ms. If yes, then a warning is displayed."
367
368
369
370
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
371
   "execution_count": null,
372
   "metadata": {
373
    "deletable": false,
374
375
    "scrolled": true
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
376
   "outputs": [],
377
378
379
380
381
382
   "source": [
    "rq_analysis.analyze_pic([timestamp_pic_rqd, timestamp_pic_rqf])"
   ]
  },
  {
   "cell_type": "markdown",
383
384
385
   "metadata": {
    "deletable": false
   },
386
   "source": [
387
388
    "# 6. Power Converter\n",
    "## 6.1. Analysis of the Power Converter Main Current\n",
389
390
391
    "This analysis module displays the main current of the power converter (I_MEAS), and for comparison, a reference I_MEAS (PNO.b3).\n",
    "\n",
    "*ANALYSIS*:\n",
392
    "- The evolution of the characteristic time $\\tau$ of an exponential decay $f(t)$ is obtained as\n",
393
    "\\begin{equation}\n",
394
    "-\\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",
395
    "\\end{equation}\n",
396
397
398
399
400
401
402
    "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",
    "- Check if the characteristic time of the pseudo-exponential I_MEAS decay from t=1 to 100 s is 25 s< Tau < 35 s\n",
403
    "\n",
404
    "*GRAPHS* (one for each circuit):\n",
405
406
407
    "- The main power converter current (reference and actual) on the left axis, I_MEAS\n",
    "- The characteristic pseudo time constant calculated for the main current (reference and actual) on the right axis, -I_MEAS/dI_MEAS  \n",
    "The actual characteristic pseudo time constant contains discrete steps, which indicate a quenching magnet (decreasing L, increasing R); note that for the reference one the steps are not present (no quench). \n",
408
409
    "- Timing of PIC abort, FGC timestamps, the maximum currents, and the characteristic times are reported next to the graph.\n",
    "- t = 0 s corresponds to the respective (actual and reference) FGC timestamps.\n"
410
411
412
413
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
414
   "execution_count": null,
415
416
417
   "metadata": {
    "deletable": false
   },
418
419
   "outputs": [],
   "source": [
420
    "%matplotlib notebook\n",
421
    "rq_analysis.analyze_i_meas_pc(circuit_names[0], timestamp_fgc_rqd, timestamp_fgc_ref_rqd, timestamp_pic_rqd, i_meas_rqd_df, i_meas_ref_rqd_df)\n",
422
    "rq_analysis.calculate_current_miits_i_meas_i_a(i_meas_rqd_df, i_a_rqd_df, t_quench=0, col_name='MIITS_RQD')\n",
423
424
    "rq_analysis.calculate_quench_current(i_meas_rqd_df, t_quench=0, col_name='I_Q_RQD')\n",
    "rq_analysis.calculate_current_slope(i_meas_rqd_df, col_name=['Ramp rate RQD', 'Plateau duration RQD'])"
425
426
427
428
429
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
430
431
432
   "metadata": {
    "deletable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
433
   "outputs": [],
434
   "source": [
435
    "%matplotlib notebook\n",
436
    "rq_analysis.analyze_i_meas_pc(circuit_names[1], timestamp_fgc_rqf, timestamp_fgc_ref_rqf, timestamp_pic_rqf, i_meas_rqf_df, i_meas_ref_rqf_df)\n",
437
    "rq_analysis.calculate_current_miits_i_meas_i_a(i_meas_rqf_df, i_a_rqd_df, t_quench=0, col_name='MIITS_RQF')\n",
438
439
    "rq_analysis.calculate_quench_current(i_meas_rqf_df, t_quench=0, col_name='I_Q_RQF')\n",
    "rq_analysis.calculate_current_slope(i_meas_rqf_df, col_name=['Ramp rate RQF', 'Plateau duration RQF'])"
440
441
442
443
   ]
  },
  {
   "cell_type": "markdown",
444
445
446
   "metadata": {
    "deletable": false
   },
447
   "source": [
448
    "## 6.2. Analysis of the Power Converter Earth Current\n",
449
    "\n",
450
451
    "*GRAPHS (one for each circuit)*:  \n",
    "t = 0 s corresponds to respective (actual and reference) FGC PM timestamps\n",
452
453
454
455
456
457
458
    "\n",
    "First plot (absolute scale, zoom for t = [-0.1, 0.3])\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, for t > 3 s)\n",
    "- The main power converter current on the left axis, I_MEAS\n",
459
460
461
    "- Actual and reference earth current on the right axis, I_EARTH_PCNT\n"
   ]
  },
Michal Maciejewski's avatar
Michal Maciejewski committed
462
463
  {
   "cell_type": "code",
464
   "execution_count": null,
465
466
467
   "metadata": {
    "deletable": false
   },
468
469
   "outputs": [],
   "source": [
470
    "%matplotlib notebook\n",
471
472
    "rq_analysis.analyze_i_earth_pc(circuit_names[0], timestamp_fgc_rqd, i_a_rqd_df, i_earth_rqd_df, i_earth_rqd_ref_df)\n",
    "rq_analysis.calculate_max_i_earth_pc(i_earth_rqd_df, col_name='I_Earth_max_RQD')"
473
474
475
476
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
477
   "execution_count": null,
478
   "metadata": {
479
    "deletable": false,
480
481
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
482
   "outputs": [],
483
   "source": [
484
    "%matplotlib notebook\n",
485
486
    "rq_analysis.analyze_i_earth_pc(circuit_names[1], timestamp_fgc_rqf, i_a_rqf_df, i_earth_rqf_df, i_earth_rqf_ref_df)\n",
    "rq_analysis.calculate_max_i_earth_pc(i_earth_rqf_df, col_name='I_Earth_max_RQF')"
487
488
489
490
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
491
   "execution_count": null,
492
493
494
   "metadata": {
    "deletable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
495
   "outputs": [],
496
   "source": [
497
498
    "%matplotlib notebook\n",
    "rq_analysis.analyze_i_earth_pcnt_pc(circuit_names[0], timestamp_fgc_rqd, i_meas_rqd_df, i_meas_ref_rqd_df, i_earth_pcnt_rqd_df, i_earth_pcnt_rqd_ref_df)"
499
500
501
502
503
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
504
505
506
   "metadata": {
    "deletable": false
   },
507
508
   "outputs": [],
   "source": [
509
510
    "%matplotlib notebook\n",
    "rq_analysis.analyze_i_earth_pcnt_pc(circuit_names[1], timestamp_fgc_rqf, i_meas_rqf_df, i_meas_ref_rqf_df, i_earth_pcnt_rqf_df, i_earth_pcnt_rqf_ref_df)"
511
512
513
514
   ]
  },
  {
   "cell_type": "markdown",
515
516
517
   "metadata": {
    "deletable": false
   },
518
   "source": [
519
520
    "# 7. Energy Extraction System\n",
    "## 7.1. Analysis of the Energy Extraction Voltage\n",
521
    "\n",
522
523
524
    "*CRITERIA*:\n",
    "- Check if the characteristic time of the pseudo-exponential U_DUMP_RES decay from t=2 to 100 s is 25 s< Tau < 35 s\n",
    "- Check if the timestamp difference between FGC and EE is 100±15 ms \n",
525
    "\n",
526
    "*GRAPHS* (one for each circuit):\n",
527
    "\n",
528
    "t = 0 s corresponds to the PM timestamp of the FGC\n",
529
530
531
    "\n",
    "First plot (global view):\n",
    "- the power converter converter current on the left axis, I_MEAS\n",
532
    "- the two energy extraction voltages on the right, U_DUMP_RES\n",
533
534
535
536
    "\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",
537
    "- the  energy extraction voltage on the right axis, U_DUMP_RES\n"
538
539
540
541
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
542
   "execution_count": null,
543
544
545
   "metadata": {
    "deletable": false
   },
546
547
   "outputs": [],
   "source": [
548
    "%matplotlib notebook\n",
549
550
    "rq_analysis.analyze_char_time_u_dump_res_ee(circuit_names[0], timestamp_fgc_rqd, u_dump_res_rqd_df, i_meas_rqd_df)\n",
    "rq_analysis.results_table['U_EE_max_RQD'] = u_dump_res_rqd_df.max()[0]"
551
552
553
554
555
556
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
557
    "deletable": false,
558
559
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
560
   "outputs": [],
561
   "source": [
562
    "%matplotlib notebook\n",
563
564
    "rq_analysis.analyze_char_time_u_dump_res_ee(circuit_names[1], timestamp_fgc_rqf, u_dump_res_rqf_df, i_meas_rqf_df)\n",
    "rq_analysis.results_table['U_EE_max_RQF'] = u_dump_res_rqf_df.max()[0]"
565
566
567
568
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
569
   "execution_count": null,
570
571
572
   "metadata": {
    "deletable": false
   },
573
574
   "outputs": [],
   "source": [
575
    "%matplotlib notebook\n",
576
577
578
579
580
581
    "rq_analysis.analyze_delay_time_u_dump_res_ee(circuit_names[0], timestamp_fgc_rqd, timestamp_pic_rqd, timestamp_ee_rqd, i_a_rqd_df, i_ref_rqd_df, u_dump_res_rqd_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
582
583
584
   "metadata": {
    "deletable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
585
   "outputs": [],
586
   "source": [
587
    "%matplotlib notebook\n",
588
589
590
    "rq_analysis.analyze_delay_time_u_dump_res_ee(circuit_names[1], timestamp_fgc_rqf, timestamp_pic_rqf, timestamp_ee_rqf, i_a_rqf_df, i_ref_rqf_df, u_dump_res_rqf_df)"
   ]
  },
591
  {
Michal Maciejewski's avatar
Michal Maciejewski committed
592
   "cell_type": "markdown",
593
594
595
   "metadata": {
    "deletable": false
   },
596
   "source": [
Michal Maciejewski's avatar
Michal Maciejewski committed
597
598
599
600
601
602
603
604
605
606
    "## 7.2.  Analysis of the Energy Extraction Temperature\n",
    "\n",
    "*CRITERIA*:\n",
    "- Check if each temperature profile is +/-25 K w.r.t. the reference temperature profile\n",
    "\n",
    "*GRAPHS*:\n",
    "\n",
    "- Temperature signals on the left axis, T\n",
    "- A reference signal with an acceptable signal range is also presented on the left axis\n",
    "- t = 0 s corresponds to PM timestamps of each temperature PM entry"
607
608
609
610
611
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
612
613
614
   "metadata": {
    "deletable": false
   },
615
616
   "outputs": [],
   "source": [
Michal Maciejewski's avatar
Michal Maciejewski committed
617
618
    "%matplotlib notebook\n",
    "rq_analysis.analyze_ee_temp(circuit_names[0], timestamp_ee_rqd, [t_res_0_rqd_df, t_res_1_rqd_df], [t_res_0_rqd_ref_df, t_res_1_rqd_ref_df], abs_margin=25, scaling=1)"
619
620
   ]
  },
621
  {
Michal Maciejewski's avatar
Michal Maciejewski committed
622
623
   "cell_type": "code",
   "execution_count": null,
624
625
626
   "metadata": {
    "deletable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
627
   "outputs": [],
628
   "source": [
Michal Maciejewski's avatar
Michal Maciejewski committed
629
630
    "%matplotlib notebook\n",
    "rq_analysis.analyze_ee_temp(circuit_names[1], timestamp_ee_rqf, [t_res_0_rqf_df, t_res_1_rqf_df], [t_res_0_rqf_ref_df, t_res_1_rqf_ref_df], abs_margin=25, scaling=1)"
631
632
633
634
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
635
   "execution_count": null,
636
637
638
   "metadata": {
    "deletable": false
   },
639
640
   "outputs": [],
   "source": [
Michal Maciejewski's avatar
Michal Maciejewski committed
641
642
    "if not fgc_pm_search.is_automatic_mode():\n",
    "    rq_analysis.results_table['EE analysis RQD'] = get_expert_decision('EE analysis RQD comment: ', ['PASS', 'FAIL'])"
643
644
645
646
647
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
648
649
650
   "metadata": {
    "deletable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
651
   "outputs": [],
652
   "source": [
Michal Maciejewski's avatar
Michal Maciejewski committed
653
654
    "if not fgc_pm_search.is_automatic_mode():\n",
    "    rq_analysis.results_table['EE analysis RQF'] = get_expert_decision('EE analysis RQF comment: ', ['PASS', 'FAIL'])"
655
656
657
658
   ]
  },
  {
   "cell_type": "markdown",
659
660
661
   "metadata": {
    "deletable": false
   },
662
   "source": [
663
    "# 8. Quench Protection System\n",
664
665
    "<img src=\"https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rq/RQ_QPS_Signals.png\" width=75%>\n",
    "\n",
666
667
668
669
670
    "source: Test Procedure and Acceptance Criteria for the 13 kA Quadrupole (RQD-RQF) Circuits, MP3 Procedure, <a href=\"https://edms.cern.ch/document/874714/5.1\">https://edms.cern.ch/document/874714/5.1</a>"
   ]
  },
  {
   "cell_type": "markdown",
671
672
673
   "metadata": {
    "deletable": false
   },
674
   "source": [
675
    "## 8.1. Plot of Voltage Across All Magnets (U_DIODE_RQx)\n",
676
    "\n",
677
678
679
    "*GRAPHS* (one for each circuit):  \n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the FGC\n",
680
681
682
683
684
685
686
    "\n",
    "First plot  (global)\n",
    "- the power converter current on the left axis, I_MEAS\n",
    "- diode voltage on the right axis, U_DIODE_RQx\n",
    "\n",
    "Second plot (zoom)\n",
    "- the power converter current on the left axis, I_MEAS\n",
687
    "- diode voltage on the right axis, U_DIODE_RQx\n"
688
689
690
691
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
692
   "execution_count": null,
693
   "metadata": {
694
    "deletable": false,
695
696
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
697
   "outputs": [],
698
   "source": [
699
    "%matplotlib notebook\n",
700
    "rq_analysis.analyze_u_diode_nqps(circuit_names[0], timestamp_fgc_rqd, i_meas_rqd_df, u_diode_rqd_dfs, 'U_DIODE_RQD', system='DIODE_RQD')"
701
702
703
704
705
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
706
707
708
   "metadata": {
    "deletable": false
   },
709
710
   "outputs": [],
   "source": [
711
    "%matplotlib notebook\n",
712
    "rq_analysis.analyze_u_diode_nqps(circuit_names[1], timestamp_fgc_rqf, i_meas_rqf_df, u_diode_rqf_dfs, 'U_DIODE_RQF', system='DIODE_RQF')"
713
714
715
716
   ]
  },
  {
   "cell_type": "markdown",
717
718
719
   "metadata": {
    "deletable": false
   },
720
   "source": [
721
    "## 8.2. Analysis of Quenched Magnets by QDS - PM\n",
722
723
724
725
726
727
728
    "\n",
    "*QUERY*:\n",
    "\n",
    "- PM for quench detection signals for 1 s before and 400 s after the FGC PM timestamp; if a quench detection signal is present, it means that a magnet quenched. Since there are two QPS boards (so called boards A and B), there are twice as many PM entries as quenched magnets.\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\n",
729
    "- compute the time difference (in seconds) from the first quench - dt_quench"
730
731
732
733
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
734
   "execution_count": null,
735
736
737
   "metadata": {
    "deletable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
738
   "outputs": [],
739
   "source": [
740
    "rq_analysis.results_table[['Circuit Name', 'Position', 'Delta_t(iQPS-PIC)','I_Q_RQD', 'I_Q_RQF', 'Delta_t(nQPS_RQD-PIC)']]"
741
742
743
744
   ]
  },
  {
   "cell_type": "markdown",
745
746
747
   "metadata": {
    "deletable": false
   },
748
   "source": [
749
    "## 8.3. Analysis of Quench Detection Voltage and Logic Signals for Quenched Magnets\n",
750
751
752
753
754
755
    "\n",
    "If a quadrupole magnet naturally quenches the QPS system (old or iQPS) records a PM file. This file containts the data from the two quench detectors for RQD and RQF (called INT and EXT). The aperture which quenches first defines the common PM time stamp. The PM data is however recorded by two individual boards. Since there is only one common heater circuit for both apertures, the non-quenching aperture will also be warmed up by the heaters and will quench. This heater induced quench which comes some time after the primary quench which triggered the PM is recorded by its quench detector when it is reaching the 100mV. Since the system has only one absolute time stamp (the one of the primary quench) the secondary, heater induced, quench appears in the PM at the same time as the primary quench despite the fact that it happens later in time. This behaviour is a feature of the system which is foreseen to be fixed in LS2 with the new quadrupole quench detection system.\n",
    "In the following analysis one can see the typical shape of U_QS0 signals (up to LS2). Both reach 100 mV at the same time due to the synchronisation of the data. The non-quenching aperture typically has a spike some 40 ms earlier (due to QH firing) and a faster voltage rise (due to QH induced quench). The quenching aperture has a typical 5-6 V/s slope at nominal current.\n",
    "\n",
    "*ANALYSIS*:\n",
    "Determine aperture with a quenched magnet\n",
756
    "1. Find a diode signal which is the first to reach 1 V\n",
757
758
759
760
    "2. Take a circuit name (RQD/RQF) from the diode signal name\n",
    "3. With the circuit name and the magnet name, get the aperture (INT/EXT)\n",
    "4. With the aperture name, choose an appropriate U_QS0 signal and use for du_dt calculation\n",
    "- if |U_QS0| $\\geq$ 100 mV, then find the start time of a quench, t_start_quench, as the moment at which |U_QS0| is 10 mV greater than its initial value. Otherwise, the start time of a quench is set to 0 s\n",
761
762
    "- Find 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",
763
    "\n",
764
765
766
    "*GRAPHS*:\n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the QDS\n",
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
    "\n",
    "Upper left  (iQPS analog signals)\n",
    "- the quench detection voltage on the left axis, U_QS0_INT, U_QS0_EXT\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, ST_MAGNET_OK, ST_MAGNET_OK_INT, ST_NQD0_INT, ST_NQD0_EXT\n",
    "\n",
    "Upper right (nQPS analog signals)  \n",
    "\n",
    "For PM signals (raw view)\n",
    "- the diode voltages used by the nQPS crate for quench detection on the left axis, U_DIODE_RQx and U_REF_N1 \n",
    "\n",
    "Lower right (nQPS analog signals)  \n",
    "For PM signals  (zoomed view) \n",
783
    "- the diode voltages used by the nQPS crate for quench detection on the left axis, U_DIODE_RQx and U_REF_N1 \n"
784
785
786
787
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
788
   "execution_count": null,
Michal Maciejewski's avatar
Michal Maciejewski committed
789
   "metadata": {
790
    "deletable": false,
Michal Maciejewski's avatar
Michal Maciejewski committed
791
792
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
793
   "outputs": [],
794
   "source": [
795
    "%matplotlib inline\n",
796
797
798
799
    "if Time.to_unix_timestamp(timestamp_fgc_rqd) > 1577833200000000000:\n",
    "    rq_analysis.analyze_qds_run3(source_timestamp_qds_rq_df, circuit_names, iqps_analog_dfs, iqps_digital_dfs, u_nqps_rqd_dfs, u_nqps_rqf_dfs)\n",
    "else:\n",
    "    rq_analysis.analyze_qds(source_timestamp_qds_rq_df, circuit_names, iqps_analog_dfs, iqps_digital_dfs, u_nqps_rqd_dfs, u_nqps_rqf_dfs)\n",
800
    "\n",
801
    "rq_analysis.results_table[['Circuit Name', 'Position', 'Delta_t(iQPS-PIC)','I_Q_RQD', 'I_Q_RQF', 'Delta_t(nQPS_RQD-PIC)', 'QDS trigger origin', 'dU_iQPS/dt_RQD', 'dU_iQPS/dt_RQF']]"
802
803
804
805
   ]
  },
  {
   "cell_type": "markdown",
806
807
808
   "metadata": {
    "deletable": false
   },
809
   "source": [
810
    "## 8.4. Analysis of Quench Heater Discharges\n",
811
    "\n",
812
813
814
815
    "*CRITERIA*:\n",
    "- check if all characteristic times of the pseudo-exponential voltage decays calculated with the 'charge' approach is +/- 3 ms from the reference ones\n",
    "- check if the initial voltage should be between 810 V and 1020 V\n",
    "- check if the final voltage should be between 0 V and 10 V\n",
816
    "\n",
817
    "*GRAPHS*:  \n",
818
    "- the queried and filtered quench heater voltage on the left axis (actual signal continuous, reference dashed), U_HDS\n",
819
    "- t = 0 s corresponds to the start of the pseudo-exponential decay\n"
820
821
822
823
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
824
   "execution_count": null,
825
   "metadata": {
826
    "deletable": false,
827
828
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
829
   "outputs": [],
830
   "source": [
831
    "%matplotlib inline\n",
832
833
    "if u_hds_rq_dfs:\n",
    "    if Time.to_unix_timestamp(timestamp_fgc_rqd) > 1577833200000000000:\n",
thbuffet's avatar
thbuffet committed
834
    "        rq_analysis.analyze_multi_qh_voltage_current_with_ref(source_timestamp_qh_rq_df, u_hds_rq_dfs, i_hds_rq_dfs, u_hds_rq_ref_dfs, i_hds_rq_ref_dfs, current_offset=0.085)\n",
835
836
    "    else:\n",
    "        rq_analysis.analyze_single_qh_voltage_with_ref(source_timestamp_qh_rq_df, circuit_type, u_hds_rq_dfs, u_hds_rq_ref_dfs)\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
837
    "\n",
838
839
840
    "    rq_analysis.results_table[['Circuit Name', 'Position', 'Delta_t(iQPS-PIC)','I_Q_RQD', 'I_Q_RQF', 'QH analysis']]\n",
    "else:\n",
    "    print(f\"No Quench heater Discharges!\")"
841
842
843
844
   ]
  },
  {
   "cell_type": "markdown",
845
846
847
   "metadata": {
    "deletable": false
   },
848
   "source": [
849
    "## 8.5. Analysis of Diode Lead Resistance\n",
850
851
    "\n",
    "*ANALYSIS*:\n",
852
853
854
855
856
857
858
859
860
    "- calculate diode lead resistance\n",
    "\n",
    "*CRITERIA*\n",
    "- Check if the maximum resistance is above 50 uOhm. If yes, then raise a warning.\n",
    "- Check if the maximum resistance is above 150 uOhm. If yes, then raise an alarm.\n",
    "\n",
    "*GRAPHS*:  \n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the FGC\n",
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
    "\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",
    "\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",
    "\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_RQx. 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",
    "\n",
    "Lower CALS (Output view)  \n",
    "- the main power converter current on the left axis, I_MEAS\n",
879
880
881
882
883
884
    "- the calculated diode lead resistance on the right axis, R_DIODE_LEADS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
885
886
887
   "metadata": {
    "deletable": false
   },
888
889
   "outputs": [],
   "source": [
890
    "%matplotlib inline\n",
891
    "rq_analysis.analyze_diode_leads(source_timestamp_qds_rq_df, timestamp_fgc_rqd, results_table['I_Q_RQD'], circuit_names[0], i_meas_u_diode_u_ref_rqd_pm_dfs, i_meas_u_diode_rqd_nxcals_dfs)"
892
893
894
895
896
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
897
898
899
   "metadata": {
    "deletable": false
   },
900
901
   "outputs": [],
   "source": [
902
    "%matplotlib inline\n",
903
    "rq_analysis.analyze_diode_leads(source_timestamp_qds_rq_df, timestamp_fgc_rqf, results_table['I_Q_RQF'], circuit_names[1], i_meas_u_diode_u_ref_rqf_pm_dfs, i_meas_u_diode_rqf_nxcals_dfs)"
904
905
906
907
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
908
   "execution_count": null,
909
   "metadata": {
910
    "deletable": false,
911
912
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
913
   "outputs": [],
914
   "source": [
915
    "rq_analysis.results_table[['Circuit Name', 'Date (FGC)', 'Time (FGC)', 'R_DL_max_RQD', 'I_RQD at R_DL_max_RQD']]"
916
917
918
919
   ]
  },
  {
   "cell_type": "markdown",
920
921
922
   "metadata": {
    "deletable": false
   },
923
   "source": [
924
    "## 8.6. Plot of Voltage Feelers\n",
925
926
927
    "\n",
    "\n",
    "*ANALYSIS*:\n",
928
929
    "- Check if the voltage of a voltage feeler is equal to 0 V. If yes, then it means that the corresponding card is disabled.\n",
    "- Check if the voltage of a voltage feeler is equal to -2000 V. If yes, then it means that the corresponding card is not communicating.\n",
930
    "\n",
931
    "*GRAPHS* (one for each circuit):  \n",
932
    "\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
933
    "- t = 0 s corresponds to the PM timestamp of the FGC\n"
934
935
936
937
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
938
   "execution_count": null,
939
   "metadata": {
940
    "deletable": false,
941
    "scrolled": false
942
943
944
   },
   "outputs": [],
   "source": [
945
946
    "%matplotlib inline\n",
    "rq_analysis.analyze_voltage_feelers(circuit_names[0], timestamp_fgc_rqd, i_meas_rqd_df, u_earth_rqd_dfs, 'U_EARTH_RQD', system='VF_RQD', xlim=(-5, 150), ylim=(-50, 100))"
947
948
949
950
951
952
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
953
    "deletable": false,
954
955
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
956
   "outputs": [],
957
   "source": [
958
959
    "%matplotlib inline\n",
    "rq_analysis.analyze_voltage_feelers(circuit_names[1], timestamp_fgc_rqf, i_meas_rqf_df, u_earth_rqf_dfs, 'U_EARTH_RQF', system='VF_RQF', xlim=(-5, 150), ylim=(-50, 100))"
960
961
   ]
  },
962
963
964
  {
   "cell_type": "code",
   "execution_count": null,
965
966
967
   "metadata": {
    "deletable": false
   },
968
969
   "outputs": [],
   "source": [
970
971
    "if not fgc_pm_search.is_automatic_mode():\n",
    "    rq_analysis.results_table['V feeler analysis RQD'] = input('Voltage feeler analysis RQD comment: ')"
972
973
974
975
976
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
977
978
979
   "metadata": {
    "deletable": false
   },
980
981
   "outputs": [],
   "source": [
982
983
    "if not fgc_pm_search.is_automatic_mode():\n",
    "    rq_analysis.results_table['V feeler analysis RQF'] = input('Voltage feeler analysis RQF comment: ')"
984
985
   ]
  },
986
987
  {
   "cell_type": "markdown",
988
989
990
   "metadata": {
    "deletable": false
   },
991
   "source": [
992
    "## 8.7. Current Leads\n",
993
    "\n",
994
    "Note that **rq** in the table above denotes both RQD and RQF, i.e., there are two signals of each circuit.\n",
995
    "\n",
996
997
998
999
    "*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",
1000
    "\n",
1001
    "*GRAPHS*:  \n",
1002
    "\n",
1003
1004
    "- t = 0 s corresponds to the FGC timestamp\n",
    "- dasheded lines, on the U_HTS graph with zoom, represent the EE timestamps"
1005
1006
1007
1008
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
1009
   "execution_count": null,
1010
1011
1012
   "metadata": {
    "deletable": false
   },
1013
1014
   "outputs": [],
   "source": [
1015
    "%matplotlib inline\n",
1016
    "rq_analysis.analyze_leads_voltage(u_hts_rqd_dfs+u_hts_rqf_dfs, circuit_names[0], timestamp_fgc_rqd, signal='U_HTS', value_min=-0.001, value_max=0.001)"
1017
1018
1019
1020
1021
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
1022
1023
1024
   "metadata": {
    "deletable": false
   },
1025
1026
   "outputs": [],
   "source": [
1027
    "%matplotlib inline\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
1028
    "rq_analysis.plot_leads_voltage_zoom(u_hts_rqd_dfs+u_hts_rqf_dfs, circuit_names[0], timestamp_fgc_rqd, timestamp_ee_rqd, timestamp_ee_rqf, timestamp_ee_rqd, signal='U_HTS')"
1029
1030
1031
1032
1033
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
1034
1035
1036
   "metadata": {
    "deletable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
1037
   "outputs": [],
1038
   "source": [
1039
    "%matplotlib inline\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
1040
    "rq_analysis.analyze_leads_voltage(u_res_rqd_dfs+u_res_rqf_dfs, circuit_names[0], timestamp_fgc_rqd, signal='U_RES', value_min=-0.1, value_max=0.1)"
1041
1042
   ]
  },
1043
1044
1045
  {
   "cell_type": "code",
   "execution_count": null,
1046
1047
1048
   "metadata": {
    "deletable": false
   },
1049
1050
1051
   "outputs": [],
   "source": [
    "if not fgc_pm_search.is_automatic_mode():\n",
1052
1053
1054
    "    rq_analysis.results_table['FPA Reason'] = get_expert_decision('Reason for FPA: ', ['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",
    "    rq_analysis.results_table['Type of Quench'] = get_expert_decision('Type of Quench: ', ['Training', 'Heater-provoked', 'Beam-induced', 'GHe propagation', 'QPS crate reset', 'Single Event Upset' ,'Short-to-ground', 'EM disturbance', 'No quench', 'Unknown'])\n",
    "    rq_analysis.results_table['QDS trigger origin'] = get_expert_decision('QDS trigger origin: ', ['QPS', 'HTS current lead', 'RES current lead','Busbar', 'No quench'])"
1055
1056
1057
1058
   ]
  },
  {
   "cell_type": "markdown",
1059
1060
1061
   "metadata": {
    "deletable": false
   },
1062
   "source": [
1063
    "# 9. Analysis Comment"
1064
1065
1066
1067
1068
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
1069
1070
1071
   "metadata": {
    "deletable": false
   },
1072
1073
   "outputs": [],
   "source": [
1074
1075
    "if not fgc_pm_search.is_automatic_mode():\n",
    "    rq_analysis.results_table['Comment'] = input('Comment: ')"
1076
1077
   ]
  },
1078
1079
  {
   "cell_type": "markdown",
1080
1081
1082
   "metadata": {
    "deletable": false
   },
1083
   "source": [
1084
    "# 10. Final Report"
1085
1086
1087
1088
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
1089
   "execution_count": null,
1090
   "metadata": {
1091
    "deletable": false,
1092
    "scrolled": false
1093
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
1094
   "outputs": [],
1095
1096
   "source": [
    "pd.set_option('display.max_columns', None) \n",
1097
    "pd.set_option('display.max_rows', None)\n",
1098
    "analysis_start_time = Time.get_analysis_start_time()\n",
1099
    "date_time_fgc = Time.to_datetime(timestamp_fgc_rqd).strftime(\"%Y-%m-%d-%Hh%M\")\n",
1100
    "circuit_name = rq_analysis.results_table.at[0, 'Circuit Name']\n",
1101
1102
1103
    "!mkdir -p /eos/project/m/mp3/RQ/$circuit_name/FPA\n",
    "file_name = \"{}_FPA-{}-{}\".format(circuit_name, date_time_fgc, analysis_start_time)\n",
    "full_path = '/eos/project/m/mp3/RQ/{}/FPA/{}.csv'.format(circuit_name, file_name)\n",
1104
    "mp3_results_table = rq_analysis.create_mp3_results_table(min(timestamp_fgc_rqd, timestamp_fgc_rqf), min(timestamp_pic_rqd, timestamp_pic_rqf))\n",
1105
    "display(HTML(mp3_results_table.T.to_html()))\n",
1106
    "mp3_results_table.to_csv(full_path, index=False)\n",