AN_RB_PLI3.a5.ipynb 29.6 KB
Newer Older
1
2
3
4
5
6
7
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1><center>Analysis of a PLI3.a5 HWC in an RB Circuit</center></h1>\n",
8
    "<img src = \"https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/RB.png\" width=75%>\n",
9
10
11
    "\n",
    "PLI3.A2 is a simple current cycle at I_INTERM_2 during TIME_INTERM_2, while PLI3.A5 is a current cycle with 2 current levels (I_SM, I_INTERM_2) during TIME_INTERM_2 each. PLI3.A5 can be performed with calorimetric measurement (original purpose). In case of calorimetric measurement, the cryogenic cooling must be stable and maintained constant during the whole cycle. The aim of this test is to check the performance of the current leads and also the splices resistance, and, in case of calorimetric measurements, to detect abnormal heating in the magnets environment.\n",
    "\n",
12
    "<img src=\"https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/PLI3_current.png\" width=50%>\n",
13
14
15
16
17
    "\n",
    "The required analysis and signatures are listed below.\n",
    "\n",
    "|Responsible|Type of analysis|Criterion|\n",
    "|-----------|----------------|---------|\n",
18
19
20
    "|-|Automatic analysis on earth current and error current|I_EARTH_PLI2_S1 < I_EARTH_MAX and I_ERR_PLI2_S1 < I_ERR_MAX|\n",
    "|MP3|Splice signals|From board A and board B separately R_bus_max <3 nOhm. Individual R_splice_max<0.5nOhm R_mag<50 nOhm|\n",
    "|MP3|Current lead|46 < TT891A < 54K; Abs(U_RES)< 40mV; and no drift Abs(U_HTS) < 0.5mV|\n",
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    "\n",
    "source: Powering Procedure and Acceptance Criteria for the 13 kA Dipole Circuits, MP3 Procedure, <a href=\"https://edms.cern.ch/document/874713/5.1\">https://edms.cern.ch/document/874713/5.1</a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Analysis Assumptions\n",
    "- We consider standard analysis scenarios, i.e., all signals can be queried. Depending on what signal is missing, an analysis can raise a warning and continue or an error and abort the analysis.\n",
    "- In case an analyzed signal can't be queried, a particular analysis is skipped. In other words, all signals have to be available in order to perform an analysis.\n",
    "- It is recommended to execute each cell one after another. However, since the signals are queried prior to an 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 the square bracket, 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",
    "- Title contains timestamp, circuit name, signal name allowing for re-access the signal.\n",
    "- The plots assigned to the left scale got 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, change color of the label to match the signal's color. Otherwise, the label color is black.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 0. Initialise Working Environment\n",
    "In order to update the lhcsmapi, please execute the following command in the SWAN terminal <a href=\"https://github.com/swan-cern/help/blob/master/swan/open_terminal.md\">[?]</a>:  \n",
    "`pip install --user --upgrade lhcsmapi`\n",
    "## 0.1. Import Necessary Packages"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
57
   "execution_count": 1,
58
59
60
61
62
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
Michal Maciejewski's avatar
Michal Maciejewski committed
63
64
    "import io\n",
    "import re\n",
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    "import sys\n",
    "import pandas as pd\n",
    "\n",
    "# NXCALS libraries\n",
    "from cern.nxcals.pyquery.builders import *\n",
    "\n",
    "# lhc-sm-api\n",
    "from lhcsmapi.Time import Time\n",
    "from lhcsmapi.Timer import Timer\n",
    "\n",
    "# GUI\n",
    "from lhcsmapi.gui.hwc.HwcBrowser import HwcBrowser\n",
    "\n",
    "# Query\n",
    "from lhcsmapi.pyedsl.QueryBuilder import QueryBuilder\n",
    "from lhcsmapi.analysis.RbCircuitQuery import RbCircuitQuery\n",
    "\n",
    "# Analysis\n",
    "from lhcsmapi.pyedsl.AssertionBuilder import AssertionBuilder\n",
84
    "# from lhcsmapi.analysis.RbCircuitAnalysis import RbCircuitAnalysis\n",
85
86
87
88
89
90
91
92
93
94
95
96
97
    "from lhcsmapi.pyedsl.ResistanceBuilder import ResistanceBuilder\n",
    "from lhcsmapi.analysis.CircuitAnalysis import get_current_plateau_start_end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 0.2. LHCSMAPI Version"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
98
   "execution_count": 2,
99
100
101
102
103
104
105
106
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
Michal Maciejewski's avatar
Michal Maciejewski committed
107
      "Analysis executed with lhcsmapi version: 1.3.225\n"
108
109
110
111
112
113
114
115
116
117
118
119
     ]
    }
   ],
   "source": [
    "import lhcsmapi\n",
    "print('Analysis executed with lhcsmapi version: {}'.format(lhcsmapi.__version__))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
Michal Maciejewski's avatar
Michal Maciejewski committed
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    "## 0.3. Notebook Version"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Analysis executed with lhc-sm-hwc notebooks version: 1.0.3\n"
     ]
    }
   ],
   "source": [
    "with io.open(\"../__init__.py\", \"rt\", encoding=\"utf8\") as f:\n",
    "    version = re.search(r'__version__ = \"(.*?)\"', f.read()).group(1)\n",
    "    print('Analysis executed with lhc-sm-hwc notebooks version: {}'.format(version))"
140
141
142
143
144
145
146
147
148
149
150
151
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. Select PLI3.a5 HWC Test\n",
    "- Choose a circuit name in order to display HWC test with, campaign name as well as start and end time"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
152
   "execution_count": null,
153
154
155
   "metadata": {
    "scrolled": true
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
156
   "outputs": [],
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
   "source": [
    "circuit_type = 'RB'\n",
    "hwc_test = 'PLI3.a5'\n",
    "hwc_test_history_df = pd.read_csv('/eos/project/l/lhcsm/hwc/RB/hwc_test_history.csv')\n",
    "hwcb = HwcBrowser(hwc_test_history_df, circuit_type, hwc_test)\n",
    "display(hwcb.widget)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. Query All Signals Prior to Analysis"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
174
   "execution_count": null,
175
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
176
   "outputs": [],
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
   "source": [
    "circuit_name = hwcb.get_circuit_name()\n",
    "t_start = hwcb.get_start_time()\n",
    "t_end = hwcb.get_end_time()\n",
    "\n",
    "with Timer():\n",
    "    # I_MEAS\n",
    "    i_meas_nxcals_df = QueryBuilder().with_nxcals(spark) \\\n",
    "            .with_duration(t_start=t_start, t_end=t_end) \\\n",
    "            .with_circuit_type(circuit_type) \\\n",
    "            .with_metadata(circuit_name=circuit_name, system='PC', signal='I_MEAS') \\\n",
    "            .signal_query() \\\n",
    "            .synchronize_time() \\\n",
    "            .convert_index_to_sec().dfs[0]\n",
    "    \n",
    "    # LEADS\n",
    "    u_res_nxcals_dfs = QueryBuilder().with_nxcals(spark) \\\n",
    "        .with_duration(t_start=t_start, t_end=t_end) \\\n",
    "        .with_circuit_type(circuit_type) \\\n",
    "        .with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='U_RES') \\\n",
    "        .signal_query() \\\n",
    "        .synchronize_time() \\\n",
    "        .convert_index_to_sec() \\\n",
    "        .dfs\n",
    "    \n",
    "    u_hts_nxcals_dfs = QueryBuilder().with_nxcals(spark) \\\n",
    "        .with_duration(t_start=t_start, t_end=t_end)\\\n",
    "        .with_circuit_type(circuit_type) \\\n",
    "        .with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='U_HTS') \\\n",
    "        .signal_query()\\\n",
    "        .synchronize_time() \\\n",
    "        .convert_index_to_sec() \\\n",
    "        .filter_median() \\\n",
    "        .dfs\n",
    "    \n",
    "    tt891a_nxcals_dfs = QueryBuilder().with_nxcals(spark) \\\n",
    "        .with_duration(t_start=t_start, t_end=t_end) \\\n",
    "        .with_circuit_type(circuit_type) \\\n",
    "        .with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='TT891A') \\\n",
    "        .signal_query() \\\n",
    "        .synchronize_time() \\\n",
    "        .convert_index_to_sec() \\\n",
    "        .filter_median() \\\n",
    "        .dfs\n",
    "    \n",
    "    tt893_nxcals_dfs = QueryBuilder().with_nxcals(spark) \\\n",
    "        .with_duration(t_start=t_start, t_end=t_end) \\\n",
    "        .with_circuit_type(circuit_type) \\\n",
    "        .with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='TT893') \\\n",
    "        .signal_query()\\\n",
    "        .synchronize_time() \\\n",
    "        .convert_index_to_sec() \\\n",
    "        .filter_median() \\\n",
    "        .dfs\n",
    "    \n",
    "    cv891_nxcals_dfs = QueryBuilder().with_nxcals(spark) \\\n",
    "        .with_duration(t_start=t_start, t_end=t_end) \\\n",
    "        .with_circuit_type(circuit_type) \\\n",
    "        .with_metadata(circuit_name=circuit_name, system=['LEADS_EVEN', 'LEADS_ODD'], signal='CV891') \\\n",
    "        .signal_query() \\\n",
    "        .synchronize_time() \\\n",
    "        .convert_index_to_sec() \\\n",
    "        .filter_median() \\\n",
    "        .dfs\n",
    "    \n",
    "    i_meas_raw_df = QueryBuilder().with_nxcals(spark) \\\n",
    "        .with_duration(t_start=t_start, t_end=t_end) \\\n",
    "        .with_circuit_type(circuit_type) \\\n",
    "        .with_metadata(circuit_name=circuit_name, system='PC', signal='I_MEAS') \\\n",
    "        .signal_query() \\\n",
    "        .dfs[0]\n",
    "    \n",
    "    plateau_timing_df = get_current_plateau_start_end(i_meas_raw_df, i_meas_threshold=500)\n",
    "    \n",
    "    # Label columns with a function for current\n",
    "    from pyspark.sql.functions import udf\n",
    "    from pyspark.sql.types import IntegerType\n",
    "    import numpy as np\n",
    "\n",
    "    plateau_start = plateau_timing_df['plateau_start'].values\n",
    "    plateau_end = plateau_timing_df['plateau_end'].values\n",
    "\n",
    "    def translate(timestamp):\n",
    "        mask_plateau = (timestamp >= plateau_start) & (timestamp <= plateau_end)\n",
    "        index_plateau = np.where(mask_plateau == True)[0]\n",
    "\n",
    "        if len(index_plateau) > 0:\n",
    "            return int((index_plateau[0]+1))\n",
    "\n",
    "        return -1\n",
    "\n",
    "    translate_udf = udf(translate, IntegerType())\n",
    "    \n",
    "    i_meas_feature_df = QueryBuilder() \\\n",
    "        .with_nxcals(spark) \\\n",
    "        .with_duration(t_start=t_start, t_end=t_end) \\\n",
    "        .with_circuit_type(circuit_type) \\\n",
    "        .with_metadata(circuit_name=circuit_name, system='PC', signal='I_MEAS') \\\n",
    "        .feature_query(['mean', 'std', 'max', 'min', 'count'], function=translate_udf) \\\n",
    "        .sort_values(by='class') \\\n",
    "        .df\n",
    "\n",
    "    u_res_feature_df = QueryBuilder() \\\n",
    "        .with_nxcals(spark) \\\n",
    "        .with_duration(t_start=t_start, t_end=t_end) \\\n",
    "        .with_circuit_type(circuit_type) \\\n",
    "        .with_metadata(circuit_name=circuit_name, system='BUSBAR', signal='U_RES', wildcard={'BUSBAR': '*'}) \\\n",
    "        .feature_query(['mean', 'std', 'max', 'min', 'count'], function=translate_udf) \\\n",
    "        .sort_busbar_location(circuit_type, circuit_name) \\\n",
    "        .df\n",
    "\n",
    "    u_mag_feature_df = QueryBuilder() \\\n",
    "        .with_nxcals(spark) \\\n",
    "        .with_duration(t_start=t_start, t_end=t_end) \\\n",
    "        .with_circuit_type(circuit_type) \\\n",
    "        .with_metadata(circuit_name=circuit_name, system='BUSBAR', signal='U_MAG', wildcard={'BUSBAR': '*'}) \\\n",
    "        .feature_query(['mean', 'std', 'max', 'min', 'count'], function=translate_udf) \\\n",
    "        .sort_busbar_location(circuit_type, circuit_name) \\\n",
    "        .df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. Power Converter\n",
    "## 3.1. Plot of the Power Converter Main Current\n",
    "\n",
    "*QUERY*:\n",
    "- NXCALS for the main power converter current, I_MEAS\n",
    "\n",
    "*INPUT*:\n",
    "\n",
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Comment\n",
    "|---------------|---------------|---------------|------|\n",
    "|i_meas_df | DataFrame | A | Main power converter current, I_MEAS|\n",
    "| plateau_start_sync | list of float | s | List with start points of current plateau in relative time|\n",
    "| plateau_end_sync | list of float | s | List with end points of current plateau in relative time|\n",
    "\n",
    "*ANALYSIS*:\n",
    "- Calculation of the duration of current plateaus\n",
    "\n",
    "*PLOT*:\n",
    "- The main power converter current (reference and actual) on the left axis, I_MEAS\n",
    "- t = 0 s corresponds to the respective (actual and reference) FGC timestamps.\n",
    "- Orange box(es) represent period(s) of time with constant current used for calculation of busbar resistance and DFB thresholds\n",
    "\n",
    "*OUTPUT*:\n",
    "\n",
    "- *No output is generated*"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
331
   "execution_count": null,
332
333
334
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
335
   "outputs": [],
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
   "source": [
    "ax = i_meas_nxcals_df.plot(figsize=(30, 10), grid=True)\n",
    "for index, row in plateau_timing_df.iterrows():\n",
    "    ax.axvspan(xmin=row['plateau_start_sync'], xmax=row['plateau_end_sync'], facecolor='xkcd:goldenrod')\n",
    "ax.set_xlabel(\"time, [s]\", fontsize=15)\n",
    "ax.set_ylabel(\"I_MEAS, [A]\", fontsize=15)\n",
    "ax.tick_params(labelsize=15)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. Busbar\n",
    "## 4.1. Busbar Resistance\n",
    "\n",
    "*QUERY*:\n",
    "- NXCALS for the mean, std, and count values of the main power converter current at current plateaus, I_MEAS\n",
    "- NXCALS for the mean, std, and count value of the busbar voltage (board A and B) at current plateaus, U_RES\n",
    "\n",
    "*INPUT*:\n",
    "\n",
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Comment\n",
    "|---------------|---------------|---------------|------|\n",
    "|i_meas_feature_df | DataFrame | A | Mean, std, and count values of the main power converter current labeled (1,2,...) at the current plateaus, I_MEAS|\n",
    "|u_res_a_feature_df | DataFrame | V | Mean, std, and count values of the busbar voltage from board A labeled (1,2,...) at the current plateaus, U_RES|\n",
    "|u_res_b_feature_df | DataFrame | V | Mean, std, and count values of the busbar voltage from board B labeled (1,2,...) at the current plateaus, U_RES|\n",
    "|plateau_start | list of float | s | List with start points of current plateau in absolute time|\n",
    "|plateau_end | list of float | s | List with end points of current plateau in absolute time|\n",
    "\n",
    "*ANALYSIS*:\n",
    "- Calculation of the busbar resistance as the slope of a linear fit of U,I curve obtained from the corresponding mean alues of the voltage and current\n",
    "- The resistance should be below 3 nOhm\n",
    "\n",
    "*PLOT*:\n",
    "- The busbar resistance, R\n",
    "- The green box denotes the validity region of the busbar resostance (0, 3] nOhm\n",
    "\n",
    "*OUTPUT*:\n",
    "\n",
    "- *No output is generated*"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
381
   "execution_count": null,
382
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
383
   "outputs": [],
384
385
386
   "source": [
    "res_busbar_df = ResistanceBuilder().with_busbar_voltage(u_res_feature_df) \\\n",
    "    .with_busbar_current(i_meas_feature_df) \\\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
387
    "    .calculate_mean_resistance(circuit_type).df\n",
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
416
417
418
419
420
421
422
423
424
425
426
427
428
429
    "\n",
    "# Plot\n",
    "res_outliers_df = AssertionBuilder().with_feature(res_busbar_df) \\\n",
    "    .has_min_max_value(feature='R_RES', min_value=0, max_value=3e-9) \\\n",
    "    .show_plot(xlabel='Busbar, [-]', ylabel='R_RES (Calculated), [V]') \\\n",
    "    .get_features_outside_range()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.2. Magnet Resistance\n",
    "*QUERY*:\n",
    "- NXCALS for the mean, std, and count values of the main power converter current at current plateaus, I_MEAS\n",
    "- NXCALS for the mean, std, and count value of the magnet voltage (board A and B) at current plateaus, U_RES\n",
    "\n",
    "*INPUT*:\n",
    "\n",
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Comment\n",
    "|---------------|---------------|---------------|------|\n",
    "|i_meas_feature_df | DataFrame | A | Mean, std, and count values of the main power converter current labeled (1,2,...) at the current plateaus, I_MEAS|\n",
    "|u_mag_a_feature_df | DataFrame | V | Mean, std, and count values of the magnet voltage from board A labeled (1,2,...) at the current plateaus, U_RES|\n",
    "|u_mag_b_feature_df | DataFrame | V | Mean, std, and count values of the magnet voltage from board B labeled (1,2,...) at the current plateaus, U_RES|\n",
    "|plateau_start | list of float | s | List with start points of current plateau in absolute time|\n",
    "|plateau_end | list of float | s | List with end points of current plateau in absolute time|\n",
    "\n",
    "*ANALYSIS*:\n",
    "- Calculation of the magnet resistance as the slope of a linear fit of U,I curve obtained from the corresponding mean alues of the voltage and current\n",
    "- The resistance should be below 50 nOhm\n",
    "\n",
    "*PLOT*:\n",
    "- The busbar resistance, R\n",
    "- The green box denotes the validity region of the magnet resistance (0, 50] nOhm\n",
    "\n",
    "*OUTPUT*:\n",
    "\n",
    "- *No output is generated*"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
430
   "execution_count": null,
431
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
432
   "outputs": [],
433
434
435
   "source": [
    "res_magnet_df = ResistanceBuilder().with_busbar_voltage(u_mag_feature_df) \\\n",
    "    .with_busbar_current(i_meas_feature_df) \\\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
436
    "    .calculate_mean_resistance(circuit_type).df\n",
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
    "\n",
    "# Plot\n",
    "res_outliers_df = AssertionBuilder().with_feature(res_magnet_df) \\\n",
    "    .has_min_max_value(feature='R_MAG', min_value=0, max_value=50e-9) \\\n",
    "    .show_plot(xlabel='Magnet, [-]', ylabel='R_MAG (Calculated), [V]') \\\n",
    "    .get_features_outside_range()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 6. DFB\n",
    "## 6.1. DFB Voltage - U_RES\n",
    "\n",
    "U_RES - Voltage of the resistive part of the current lead (QPS threshold at 100 mV, 100 ms)  \n",
    "\n",
    "*QUERY*:\n",
    "- NXCALS for voltage of even and odd leads, U_RES\n",
    "\n",
    "*INPUT*:  \n",
    "\n",
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Comment\n",
    "|---------------|---------------|---------------|------|\n",
    "|t_start\t|str\t|-\t|Start date and time of the test|\n",
    "|t_end\t|str\t|-\t|End date and time of the test|\n",
    "|t_end\t|str\t|-\t|End date and time of the test|\n",
    "|u_res_dfs\t|list of DataFrames\t|V\t|Voltage of the resistive part of even and odd leads, U_RES|\n",
    "|plateau_start_sync | list of float | s | List with start points of current plateau in relative time|\n",
    "|plateau_end_sync | list of float | s | List with end points of current plateau in relative time|\n",
    "\n",
    "*ANALYSIS*:  \n",
    "- Median filter with window of size 3\n",
    "- Quench detection for U_HTS for 2 consecutive datapoints above the threshold (3 mV)\n",
    "- Detection for U_RES for 2 consecutive datapoints above the threshold (100 mV)\n",
    "- At constant current, U_RES must stay constant (no drift < 2mV/h) and Abs (U_RES) < 65 mV @ 11 kA  \n",
    "\n",
    "*PLOT*:  \n",
    "For odd and even leads\n",
    "- Main power converter current on the left axis, I_MEAS\n",
    "- Voltage of the normal conducting leads on the right axis, U_RES\n",
    "- t = 0 s corresponds to the start time of the test\n",
    "- The green box denotes the validity region of the voltage of the resistive part of the current lead [-50, 50] mV\n",
    "\n",
    "*OUTPUT*:\n",
    "\n",
    "- *No output is generated*\n"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
488
   "execution_count": null,
489
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
490
   "outputs": [],
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
   "source": [
    "AssertionBuilder().with_signal(u_res_nxcals_dfs) \\\n",
    "    .with_time_range(t_start=plateau_timing_df['plateau_start_sync'], t_end=plateau_timing_df['plateau_end_sync']) \\\n",
    "    .has_min_max_slope(slope_min=-2, slope_max=2) \\\n",
    "    .show_plot(ylabel='U_RES, [V]')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.2. DFB Voltage - U_HTS\n",
    "\n",
    "U_HTS - Voltage of the HTS part of the current lead (QPS threshold at 1 mV, 100 ms)  \n",
    "\n",
    "*QUERY*:\n",
    "- NXCALS for voltage of even and odd leads, U_HTS\n",
    "\n",
    "*INPUT*:  \n",
    "\n",
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Comment\n",
    "|---------------|---------------|---------------|------|\n",
    "|t_start\t|str\t|-\t|Start date and time of the test|\n",
    "|t_end\t|str\t|-\t|End date and time of the test|\n",
    "|u_hts_dfs\t|list of DataFrames\t|V\t|Voltage of the HTS part of even and odd leads, U_HTS|\n",
    "\n",
    "*ANALYSIS*:  \n",
    "- Median filter with window of size 3\n",
    "- Qench detection for U_HTS for 2 consecutive datapoints above the threshold (3 mV)\n",
    "- Voltage must stay below 50% of the threshold -> Abs(U_HTS) < 0.5 mV\n",
    "\n",
    "*PLOT*:  \n",
    "For odd and even leads\n",
    "- Main power converter current on the left axis, I_MEAS\n",
    "- Voltage of the HTS leads on the right axis, U_HTS\n",
    "- t = 0 s corresponds to the start time of the test\n",
    "\n",
    "*OUTPUT*:\n",
    "\n",
    "- *No output is generated*"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
535
   "execution_count": null,
536
537
538
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
539
   "outputs": [],
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
   "source": [
    "AssertionBuilder().with_signal(u_hts_nxcals_dfs) \\\n",
    "    .with_time_range(t_start=plateau_timing_df['plateau_start_sync'], t_end=plateau_timing_df['plateau_end_sync']) \\\n",
    "    .has_min_max_slope(slope_min=-0.5, slope_max=0.5) \\\n",
    "    .show_plot(ylabel='U_HTS')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.3. DFB Temperature - TT893.TEMPERATURECALC\n",
    "\n",
    "TT893.TEMPERATURECALC - Temperature at the top of the current lead (supposed to be at the room temperature) \n",
    "\n",
    "*QUERY*:\n",
    "- NXCALS for temperature at the top of the current lead (even and odd), TT893.TEMPERATURECALC\n",
    "\n",
    "*INPUT*:  \n",
    "\n",
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Comment\n",
    "|---------------|---------------|---------------|------|\n",
    "|t_start\t|str\t|-\t|Start date and time of the test|\n",
    "|t_end\t|str\t|-\t|End date and time of the test|\n",
    "|tt893_dfs\t|list of DataFrames\t|K\t|Temperature at the top of the current lead, TT893.TEMPERATURECALC|\n",
    "\n",
    "*ANALYSIS*:  \n",
    "- Temperature must be over the dew point, but not overheated -> 280 K < TT893 < 320 K, even without current\n",
    "\n",
    "*PLOT*:  \n",
    "For odd and even leads\n",
    "- Main power converter current on the left axis, I_MEAS\n",
    "- Temperature at the top of the current lead on the right axis, TT893.TEMPERATURECALC\n",
    "- t = 0 s corresponds to the start time of the test\n",
    "- Green box denotes the temperature validity region [280, 320] K of the temperature at the top of the current lead\n",
    "\n",
    "*OUTPUT*:\n",
    "\n",
    "- *No output is generated*"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
583
   "execution_count": null,
584
585
586
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
587
   "outputs": [],
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
620
621
622
623
624
625
626
627
628
629
630
631
   "source": [
    "AssertionBuilder() \\\n",
    "    .with_signal(tt893_nxcals_dfs) \\\n",
    "    .has_min_max_value(value_min=280, value_max=320) \\\n",
    "    .show_plot(ylabel='TT893.TEMPERATURECALC [K]')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.4. DFB Temperature - TT891A.TEMPERATURECALC\n",
    "\n",
    "TT891A.TEMPERATURECALC - Temperature between the HTS and resistive part of the current leads (supposed to be regulated around 50 K)\n",
    "\n",
    "*QUERY*:\n",
    "- NXCALS for temperature between the HTS and resistive part of the current leads (even and odd), TT891A.TEMPERATURECALC\n",
    "\n",
    "*INPUT*:  \n",
    "\n",
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Comment\n",
    "|---------------|---------------|---------------|------|\n",
    "|t_start\t|str\t|-\t|Start date and time of the test|\n",
    "|t_end\t|str\t|-\t|End date and time of the test|\n",
    "|tt891a_dfs\t|list of DataFrames\t|K\t|Temperature between the HTS and resistive part of the current lead, TT891A.TEMPERATURECALC|\n",
    "|plateau_start_sync | list of float | s | List with start points of current plateau in relative time|\n",
    "|plateau_end_sync | list of float | s | List with end points of current plateau in relative time|\n",
    "\n",
    "*ANALYSIS*:  \n",
    "- Temperature must be regulated around 50 K -> 46 K < TT891A < 54 K, even without current\n",
    "\n",
    "*PLOT*:  \n",
    "For odd and even leads\n",
    "- Main power converter current, I_MEAS\n",
    "- Temperature between the HTS and resistive part of the current lead on the right axis, TT891A.TEMPERATURECALC\n",
    "- t = 0 s corresponds to the start time of the test\n",
    "\n",
    "*OUTPUT*:\n",
    "\n",
    "- *No output is generated*"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
632
   "execution_count": null,
633
634
635
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
636
   "outputs": [],
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
   "source": [
    "AssertionBuilder().with_signal(tt891a_nxcals_dfs) \\\n",
    "    .has_min_max_value(value_min=46, value_max=54) \\\n",
    "    .show_plot(ylabel='TT891A.TEMPERATURECALC [K]')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.5. DFB Valve Regulation - CV891.POSST\n",
    "\n",
    "CV891.POSST - Valve for regulation of TT891A\n",
    "\n",
    "*QUERY*:\n",
    "- NXCALS for valve for regulation of TT891Atemperature of current leads (even and odd), CV891.POSST\n",
    "\n",
    "*INPUT*:  \n",
    "\n",
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Comment\n",
    "|---------------|---------------|---------------|------|\n",
    "|t_start\t|str\t|-\t|Start date and time of the test|\n",
    "|t_end\t|str\t|-\t|End date and time of the test|\n",
    "|cv891_dfs\t|list of DataFrames\t|%\t|Valve for regulation of TT891A, CV891.POSST|\n",
    "\n",
    "*ANALYSIS*:  \n",
    "- The valve must be opened (>2%), but not fully (<50%)\n",
    "- The valve variation (defined as difference between the maximum and minimum value) shouldn't exceed 8% at constant current (the ramp of the current is excluded this criterion)\n",
    "\n",
    "*PLOT*:  \n",
    "For odd and even leads\n",
    "- Main power converter current, I_MEAS\n",
    "- Valve for regulation of TT891A, CV891.POSST\n",
    "- t = 0 s corresponds to the start time of the test\n",
    "- Green box denotes the valve opening validity region [2, 50] % of the TT891A temperature regulation\n",
    "\n",
    "*OUTPUT*:\n",
    "\n",
    "- *No output is generated*"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
680
   "execution_count": null,
681
682
683
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
684
   "outputs": [],
685
686
687
688
689
690
691
692
   "source": [
    "AssertionBuilder().with_signal(cv891_nxcals_dfs) \\\n",
    "    .has_min_max_value(value_min=2, value_max=50) \\\n",
    "    .show_plot(ylabel='CV891.POSST [%]')"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
693
   "execution_count": null,
694
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
695
   "outputs": [],
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
   "source": [
    "AssertionBuilder().with_signal(cv891_nxcals_dfs) \\\n",
    "    .with_time_range(t_start=plateau_timing_df['plateau_start_sync'], t_end=plateau_timing_df['plateau_end_sync']) \\\n",
    "    .has_min_max_variation(variation_min_max=8) \\\n",
    "    .show_plot(ylabel='CV891')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 7. Final Report"
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
712
   "execution_count": null,
713
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
714
   "outputs": [],
715
716
717
718
719
   "source": [
    "campaign = hwcb.get_campaign()\n",
    "file_name_html = '{}-{}_report.html'.format(Time.to_datetime(t_start).strftime(\"%Y.%m.%d_%H%M%S.%f\"), Time.to_datetime(t_end).strftime(\"%Y.%m.%d_%H%M%S.%f\"))\n",
    "!{sys.executable} -m jupyter nbconvert --to html $'AN_RB_PLI3.a5.ipynb' --output /eos/project/l/lhcsm/hwc/RB/$circuit_name/$hwc_test/$campaign/$file_name_html"
   ]
Michal Maciejewski's avatar
Michal Maciejewski committed
720
721
722
723
724
725
726
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
  }
 ],
 "metadata": {
  "celltoolbar": "Raw Cell Format",
  "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",
   "version": "3.6.5"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "metadata": {
     "collapsed": false
    },
    "source": []
   }
  },
  "sparkconnect": {
   "bundled_options": [
    "SparkMetrics",
    "NXCALS"
   ],
Michal Maciejewski's avatar
Michal Maciejewski committed
762
   "list_of_options": []
763
764
765
766
767
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}