AN_RB_PLI3.a5.ipynb 25.2 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
    "\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",
30
31
32
    "- 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",
    "- In case a signal is not needed for the analysis, a particular analysis is skipped. In other words, all signals have to be available in order to perform an analysis.\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",
33
34
    "\n",
    "# Plot Convention\n",
35
36
    "- 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",
37
    "- 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",
38
39
40
    "- 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",
41
    "- Each plot has an individual time-synchronization mentioned explicitly in the description.\n",
42
    "- If an axis has a single signal, then the color of the label matches the signal's color. Otherwise, the label color is black."
43
44
45
46
47
48
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
49
    "# 0. Initialise Working Environment"
50
51
52
53
   ]
  },
  {
   "cell_type": "code",
54
   "execution_count": null,
55
   "metadata": {
56
57
    "deletable": false,
    "editable": false,
58
59
60
61
    "scrolled": false
   },
   "outputs": [],
   "source": [
Michal Maciejewski's avatar
Michal Maciejewski committed
62
63
    "import io\n",
    "import re\n",
64
    "import sys\n",
65
    "import time\n",
66
    "import pandas as pd\n",
67
68
    "import numpy as np\n",
    "from IPython.display import display, Javascript\n",
69
70
71
72
73
74
75
76
77
78
    "\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.analysis.RbCircuitQuery import RbCircuitQuery\n",
79
    "from lhcsmapi.pyedsl.QueryBuilder import QueryBuilder\n",
80
81
    "\n",
    "# Analysis\n",
82
    "from lhcsmapi.analysis.report_template import apply_report_template\n",
83
    "from lhcsmapi.pyedsl.AssertionBuilder import AssertionBuilder\n",
84
85
    "from lhcsmapi.analysis.busbar.BusbarResistanceAnalysis import convert_to_col, find_plateau_start_and_end\n",
    "\n",
86
    "import lhcsmapi\n",
87
88
    "print('Analysis executed with lhcsmapi version: {}'.format(lhcsmapi.__version__))\n",
    "\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
89
90
91
    "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))"
92
93
94
95
96
97
98
99
100
101
102
103
   ]
  },
  {
   "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",
104
   "execution_count": null,
105
   "metadata": {
106
107
    "deletable": false,
    "editable": false,
108
109
    "scrolled": true
   },
110
   "outputs": [],
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
   "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
128
   "execution_count": null,
129
130
131
132
133
134
135
   "metadata": {
    "deletable": false,
    "editable": false,
    "tags": [
     "skip_output"
    ]
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
136
   "outputs": [],
137
138
139
140
   "source": [
    "circuit_name = hwcb.get_circuit_name()\n",
    "t_start = hwcb.get_start_time()\n",
    "t_end = hwcb.get_end_time()\n",
141
    "rb_query = RbCircuitQuery(circuit_type, circuit_name, max_executions=12)\n",
142
143
    "\n",
    "with Timer():\n",
144
145
146
147
148
149
150
151
    "    # PC\n",
    "    i_meas_nxcals_df = rb_query.query_signal_nxcals(t_start, t_end, system='PC', signal_names='I_MEAS', spark=spark)[0]\n",
    "    i_meas_raw_nxcals_df = rb_query.query_raw_signal_nxcals(t_start, t_end, system='PC', signal_names='I_MEAS', spark=spark)[0]\n",
    "    plateau_start, plateau_end = find_plateau_start_and_end(i_meas_raw_nxcals_df, i_meas_threshold=500)\n",
    "\n",
    "    # BUSBAR\n",
    "    res_busbar_row_df = rb_query.get_busbar_resistances(Time.to_unix_timestamp(t_start), Time.to_unix_timestamp(t_end), signal_name='U_RES', spark=spark, i_meas_threshold=500)\n",
    "    res_busbar_df = convert_to_col(res_busbar_row_df, signal_name='U_RES')\n",
152
    "    \n",
153
154
155
    "    # MAGNET\n",
    "    res_magnet_row_df = rb_query.get_busbar_resistances(Time.to_unix_timestamp(t_start), Time.to_unix_timestamp(t_end), signal_name='U_MAG', spark=spark, i_meas_threshold=500)\n",
    "    res_magnet_df = convert_to_col(res_magnet_row_df, signal_name='U_MAG')\n",
156
    "    \n",
157
158
159
    "    # LEADS\n",
    "    u_res_nxcals_dfs = rb_query.query_signal_nxcals(t_start, t_end, system=['LEADS_EVEN', 'LEADS_ODD'], signal_names='U_RES', spark=spark)\n",
    "    u_hts_nxcals_dfs = rb_query.query_signal_nxcals(t_start, t_end, system=['LEADS_EVEN', 'LEADS_ODD'], signal_names='U_HTS', spark=spark)\n",
160
    "\n",
161
162
163
    "    tt891a_nxcals_dfs = rb_query.query_dfb_signal_nxcals(t_start, t_end, system=['LEADS_EVEN_WINCCOA', 'LEADS_ODD_WINCCOA'], signal_names='TT891A', spark=spark)\n",
    "    tt893_nxcals_dfs = rb_query.query_dfb_signal_nxcals(t_start, t_end, system=['LEADS_EVEN_WINCCOA', 'LEADS_ODD_WINCCOA'], signal_names='TT893', spark=spark)\n",
    "    cv891_nxcals_dfs = rb_query.query_dfb_signal_nxcals(t_start, t_end, system=['LEADS_EVEN_WINCCOA', 'LEADS_ODD_WINCCOA'], signal_names='CV891', spark=spark)\n"
164
165
166
167
168
169
170
171
172
173
174
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. Power Converter\n",
    "## 3.1. Plot of the Power Converter Main Current\n",
    "\n",
    "*QUERY*:\n",
    "\n",
175
176
177
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
    "|i_meas_df | DataFrame | A |NXCALS| Main power converter current, I_MEAS|\n",
178
179
    "\n",
    "*ANALYSIS*:\n",
180
    "\n",
181
182
    "- Calculation of the duration of current plateaus\n",
    "\n",
183
184
    "*GRAPHS*:\n",
    "\n",
185
186
    "- t = 0 s corresponds to the start of the test\n",
    "- Orange box(es) represent period(s) of time with constant current used for calculation of busbar resistance and DFB thresholds"
187
188
189
190
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
191
   "execution_count": null,
192
   "metadata": {
193
194
    "deletable": false,
    "editable": false,
195
196
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
197
   "outputs": [],
198
199
   "source": [
    "ax = i_meas_nxcals_df.plot(figsize=(30, 10), grid=True)\n",
200
201
202
    "for ps, pe in zip(plateau_start, plateau_end):\n",
    "    ax.axvspan(xmin=(ps-Time.to_unix_timestamp(i_meas_raw_nxcals_df.index[0]))/1e9, \n",
    "               xmax=(pe-Time.to_unix_timestamp(i_meas_raw_nxcals_df.index[0]))/1e9, facecolor='xkcd:goldenrod')\n",
203
204
205
206
207
208
209
210
211
212
213
214
215
216
    "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",
    "\n",
217
218
219
220
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
    "|i_meas_feature_df | DataFrame | A |NXCALS| Mean, std, and count values of the main power converter current labeled (1,2,...) at the current plateaus, I_MEAS|\n",
    "|u_res_feature_df | DataFrame | V |NXCALS| Mean, std, and count values of the busbar voltage labeled (1,2,...) at the current plateaus, U_RES|\n",
221
222
    "\n",
    "*ANALYSIS*:\n",
223
    "\n",
224
225
    "- 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",
    "\n",
226
227
228
229
230
231
    "*CRITERIA*:\n",
    "\n",
    "- Check if the busbar resistance is below 3 nOhm\n",
    "\n",
    "*GRAPHS*:\n",
    "\n",
232
    "- The busbar resistance, R\n",
233
    "- The green box denotes the validity region of the busbar resostance (0, 3] nOhm"
234
235
236
237
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
238
   "execution_count": null,
239
240
241
242
   "metadata": {
    "deletable": false,
    "editable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
243
   "outputs": [],
244
   "source": [
245
    "res_busbar_outliers_df = AssertionBuilder().with_feature(res_busbar_df) \\\n",
246
    "    .has_min_max_value(feature='R_RES', min_value=0, max_value=3e-9) \\\n",
247
    "    .show_plot(xlabel='Busbar, [-]', ylabel='R_RES (Calculated), [Ohm]') \\\n",
248
249
250
    "    .get_features_outside_range()"
   ]
  },
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
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1.1. Display the list of busbars with resistance outside of range"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "editable": false
   },
   "outputs": [],
   "source": [
    "res_busbar_outliers_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1.2. Query and plot busbar voltage with resistance outside of range"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "editable": false
   },
   "outputs": [],
   "source": [
    "if len(res_busbar_outliers_df) > 0:\n",
    "    u_res_busbar_outlier_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='BUSBAR', wildcard={'BUSBAR': res_busbar_outliers_df['nxcals_variable_name']}) \\\n",
    "        .signal_query() \\\n",
    "        .synchronize_time() \\\n",
    "        .convert_index_to_sec().dfs\n",
    "\n",
    "    for u_res_busbar_outlier_df in u_res_busbar_outlier_dfs:\n",
    "        if not u_res_busbar_outlier_df.empty:\n",
    "            ax = u_res_outlier_df.plot(figsize=(15, 7), grid=True)\n",
    "            # Add ranges of detected plateaus in orange\n",
    "            for ps, pe in zip(plateau_start, plateau_end):\n",
    "                ax.axvspan(xmin=(ps-Time.to_unix_timestamp(i_meas_raw_nxcals_df.index[0]))/1e9, \n",
    "                           xmax=(pe-Time.to_unix_timestamp(i_meas_raw_nxcals_df.index[0]))/1e9, facecolor='xkcd:goldenrod')\n",
    "            ax.set_xlabel(\"time, [s]\", fontsize=15)\n",
    "            ax.set_ylabel(\"U_RES, [V]\", fontsize=15)\n",
    "            ax.tick_params(labelsize=15)"
   ]
  },
307
308
309
310
311
312
313
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.2. Magnet Resistance\n",
    "*QUERY*:\n",
    "\n",
314
315
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
316
    "|res_magnet_df | DataFrame | Ohm |NXCALS| Magnet resistance, R_MAG|\n",
317
318
    "\n",
    "*ANALYSIS*:\n",
319
    "\n",
320
    "- 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",
321
322
    "\n",
    "*CRITERIA*\n",
323
    "\n",
324
325
326
327
328
    "- Check if the resistance is below 50 nOhm\n",
    "\n",
    "*GRAPHS*:\n",
    "\n",
    "- The magnet resistance, R\n",
329
    "- The green box denotes the validity region of the magnet resistance (0, 50] nOhm\n"
330
331
332
333
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
334
   "execution_count": null,
335
336
337
338
   "metadata": {
    "deletable": false,
    "editable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
339
   "outputs": [],
340
   "source": [
341
    "res_magnet_outliers_df = AssertionBuilder().with_feature(res_magnet_df) \\\n",
342
    "    .has_min_max_value(feature='R_MAG', min_value=0, max_value=50e-9) \\\n",
343
    "    .show_plot(xlabel='Magnet, [-]', ylabel='R_MAG (Calculated), [Ohm]') \\\n",
344
345
346
    "    .get_features_outside_range()"
   ]
  },
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
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2.1. Display the list of magnets with resistance outside of range"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "editable": false
   },
   "outputs": [],
   "source": [
    "res_magnet_outliers_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2.2. Query and plot busbar voltage with resistance outside of range"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "editable": false
   },
   "outputs": [],
   "source": [
    "if len(res_magnet_outliers_df) > 0:\n",
    "    u_res_magnet_outlier_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='BUSBAR', wildcard={'BUSBAR': res_magnet_outliers_df['nxcals_variable_name']}) \\\n",
    "        .signal_query() \\\n",
    "        .synchronize_time() \\\n",
    "        .convert_index_to_sec().dfs\n",
    "\n",
    "    for u_res_magnet_outlier_df in u_res_magnet_outlier_dfs:\n",
    "        if not u_res_magnet_outlier_df.empty:\n",
    "            ax = u_res_magnet_outlier_df.plot(figsize=(15, 7), grid=True)\n",
    "            # Add ranges of detected plateaus in orange\n",
    "            for ps, pe in zip(plateau_start, plateau_end):\n",
    "                ax.axvspan(xmin=(ps-Time.to_unix_timestamp(i_meas_raw_nxcals_df.index[0]))/1e9, \n",
    "                           xmax=(pe-Time.to_unix_timestamp(i_meas_raw_nxcals_df.index[0]))/1e9, facecolor='xkcd:goldenrod')\n",
    "            ax.set_xlabel(\"time, [s]\", fontsize=15)\n",
    "            ax.set_ylabel(\"U_RES, [V]\", fontsize=15)\n",
    "            ax.tick_params(labelsize=15)"
   ]
  },
403
404
405
406
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
407
408
    "# 5. DFB\n",
    "## 5.1. DFB Voltage - U_RES\n",
409
410
411
412
413
    "\n",
    "U_RES - Voltage of the resistive part of the current lead (QPS threshold at 100 mV, 100 ms)  \n",
    "\n",
    "*QUERY*:\n",
    "\n",
414
415
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
416
    "|u_res_nxcals_dfs\t|list of DataFrames\t|V\t|NXCALS|Voltage of the resistive part of even and odd leads, U_RES|\n",
417
    "\n",
418
419
    "*CRITERIA*:\n",
    "- Check if, at constant current, U_RES is constant (no drift < 2mV/h)\n",
420
    "\n",
421
    "*GRAPHS*:\n",
422
    "- t = 0 s corresponds to the start time of the test\n"
423
424
425
426
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
427
   "execution_count": null,
428
429
430
431
   "metadata": {
    "deletable": false,
    "editable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
432
   "outputs": [],
433
434
   "source": [
    "AssertionBuilder().with_signal(u_res_nxcals_dfs) \\\n",
435
    "    .with_time_range(t_start=(np.array(plateau_start)-Time.to_unix_timestamp(t_start))/1e9, t_end=(np.array(plateau_end)-Time.to_unix_timestamp(t_start))/1e9) \\\n",
436
437
438
439
440
441
442
443
    "    .has_min_max_slope(slope_min=-2, slope_max=2) \\\n",
    "    .show_plot(ylabel='U_RES, [V]')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
444
    "## 5.2. DFB Voltage - U_HTS\n",
445
446
447
448
449
    "\n",
    "U_HTS - Voltage of the HTS part of the current lead (QPS threshold at 1 mV, 100 ms)  \n",
    "\n",
    "*QUERY*:\n",
    "\n",
450
451
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
452
    "|u_hts_nxcals_dfs\t|list of DataFrames\t|V\t|NXCALS|Voltage of the HTS part of even and odd leads, U_HTS|\n",
453
    "\n",
454
    "*CRITERIA*:  \n",
455
    "- Check if the voltage is below 50% of the threshold -> Abs(U_HTS) < 0.5 mV\n",
456
    "\n",
457
    "*GRAPHS*:\n",
458
    "- t = 0 s corresponds to the start time of the test"
459
460
461
462
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
463
   "execution_count": null,
464
   "metadata": {
465
466
    "deletable": false,
    "editable": false,
467
468
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
469
   "outputs": [],
470
471
   "source": [
    "AssertionBuilder().with_signal(u_hts_nxcals_dfs) \\\n",
472
    "    .with_time_range(t_start=(np.array(plateau_start)-Time.to_unix_timestamp(t_start))/1e9, t_end=(np.array(plateau_end)-Time.to_unix_timestamp(t_start))/1e9) \\\n",
473
474
475
476
477
478
479
480
    "    .has_min_max_slope(slope_min=-0.5, slope_max=0.5) \\\n",
    "    .show_plot(ylabel='U_HTS')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
481
    "## 5.3. DFB Temperature - TT893.TEMPERATURECALC\n",
482
483
484
485
486
487
488
489
    "\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",
490
491
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
492
    "|tt893_nxcals_dfs\t|list of DataFrames\t|K\t|NXCALS|Temperature at the top of the current lead, TT893.TEMPERATURECALC|\n",
493
    "\n",
494
495
496
497
498
    "*CRITERIA*:\n",
    "\n",
    "- Check if the temperature is over the dew point, but not overheated -> 280 K < TT893 < 320 K, even without current\n",
    "\n",
    "*GRAPHS*:\n",
499
500
501
    "\n",
    "- Temperature at the top of the current lead on the right axis, TT893.TEMPERATURECALC\n",
    "- Green box denotes the temperature validity region [280, 320] K of the temperature at the top of the current lead\n",
502
    "- t = 0 s corresponds to the start time of the test"
503
504
505
506
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
507
   "execution_count": null,
508
   "metadata": {
509
510
    "deletable": false,
    "editable": false,
511
512
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
513
   "outputs": [],
514
515
516
517
518
519
520
521
522
523
524
   "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": [
525
    "## 5.4. DFB Temperature - TT891A.TEMPERATURECALC\n",
526
527
528
529
530
    "\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",
    "\n",
531
532
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
533
    "|tt891a_nxcals_dfs\t|list of DataFrames\t|K\t|NXCALS|Temperature between the HTS and resistive part of the current lead, TT891A.TEMPERATURECALC|\n",
534
    "\n",
535
536
537
538
539
    "*CRITERIA*:\n",
    "\n",
    "- Check if the temperature is regulated around 50 K -> 46 K < TT891A < 54 K, even without current\n",
    "\n",
    "*GRAPHS*:\n",
540
541
542
543
    "\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",
544
    "- t = 0 s corresponds to the start time of the test\n"
545
546
547
548
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
549
   "execution_count": null,
550
   "metadata": {
551
552
    "deletable": false,
    "editable": false,
553
554
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
555
   "outputs": [],
556
557
558
559
560
561
562
563
564
565
   "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": [
566
    "## 5.5. DFB Valve Regulation - CV891.POSST\n",
567
568
569
    "\n",
    "CV891.POSST - Valve for regulation of TT891A\n",
    "\n",
570
    "*QUERY*: \n",
571
    "\n",
572
573
574
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
    "|cv891_nxcals_dfs\t|list of DataFrames\t|%\t|NXCALS|Valve for regulation of TT891A, CV891.POSST|\n",
575
    "\n",
576
577
578
579
580
581
    "*CRITERIA*:\n",
    "\n",
    "- Check if the valve is opened (>2%), but not fully (<50%)\n",
    "- Check if the valve variation (defined as difference between the maximum and minimum value) does not exceed 8% at constant current (the ramp of the current is excluded this criterion)\n",
    "\n",
    "*GRAPHS*:\n",
582
583
584
585
    "\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",
586
    "- Green box denotes the valve opening validity region [2, 50] % of the TT891A temperature regulation"
587
588
589
590
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
591
   "execution_count": null,
592
   "metadata": {
593
594
    "deletable": false,
    "editable": false,
595
596
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
597
   "outputs": [],
598
599
600
601
602
603
604
605
   "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
606
   "execution_count": null,
607
608
609
610
   "metadata": {
    "deletable": false,
    "editable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
611
   "outputs": [],
612
613
   "source": [
    "AssertionBuilder().with_signal(cv891_nxcals_dfs) \\\n",
614
    "    .with_time_range(t_start=(np.array(plateau_start)-Time.to_unix_timestamp(t_start))/1e9, t_end=(np.array(plateau_end)-Time.to_unix_timestamp(t_start))/1e9) \\\n",
615
616
617
618
619
620
621
622
    "    .has_min_max_variation(variation_min_max=8) \\\n",
    "    .show_plot(ylabel='CV891')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
623
    "# 6. Final Report"
624
625
626
627
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
628
   "execution_count": null,
629
630
631
632
   "metadata": {
    "deletable": false,
    "editable": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
633
   "outputs": [],
634
635
   "source": [
    "campaign = hwcb.get_campaign()\n",
636
    "apply_report_template()\n",
637
    "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",
638
639
640
641
642
    "full_path = '/eos/project/l/lhcsm/hwc/RB/{}/{}/{}/{}'.format(circuit_name, hwc_test, campaign, file_name_html)\n",
    "print('Compact notebook report saved to (Windows): ' + '\\\\\\\\cernbox-smb' + full_path.replace('/', '\\\\'))\n",
    "display(Javascript('IPython.notebook.save_notebook();'))\n",
    "time.sleep(5)\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 --TemplateExporter.exclude_input=True --TagRemovePreprocessor.remove_all_outputs_tags='[\"skip_output\"]'"
643
   ]
Michal Maciejewski's avatar
Michal Maciejewski committed
644
645
646
647
648
649
650
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
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
  }
 ],
 "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",
   "version": "3.6.5"
  },
  "sparkconnect": {
   "bundled_options": [
    "SparkMetrics",
    "NXCALS"
   ],
Michal Maciejewski's avatar
Michal Maciejewski committed
676
   "list_of_options": []
677
678
679
680
681
682
683
684
685
686
687
688
689
  },
  "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": {},
   "toc_section_display": true,
   "toc_window_display": false
690
691
692
693
694
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}