AN_RB_PLI3.a5.ipynb 25.5 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
49
50
51
52
53
54
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 0. Initialise Working Environment\n",
    "## 0.1. Import Necessary Packages"
   ]
  },
  {
   "cell_type": "code",
55
   "execution_count": 2,
56
57
58
59
60
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
Michal Maciejewski's avatar
Michal Maciejewski committed
61
62
    "import io\n",
    "import re\n",
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    "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",
    "from lhcsmapi.pyedsl.ResistanceBuilder import ResistanceBuilder\n",
83
    "from lhcsmapi.pyedsl.SignalTransformationBuilder import get_current_plateau_start_end # Could this come from the BusbarResistance?"
84
85
86
87
88
89
90
91
92
93
94
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 0.2. LHCSMAPI Version"
   ]
  },
  {
   "cell_type": "code",
95
   "execution_count": 3,
96
97
98
99
100
101
102
103
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
104
      "Analysis executed with lhcsmapi version: 1.3.266\n"
105
106
107
108
109
110
111
112
113
114
115
116
     ]
    }
   ],
   "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
117
118
119
120
121
    "## 0.3. Notebook Version"
   ]
  },
  {
   "cell_type": "code",
122
   "execution_count": 4,
Michal Maciejewski's avatar
Michal Maciejewski committed
123
124
125
126
127
128
129
130
131
132
133
134
135
136
   "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))"
137
138
139
140
141
142
143
144
145
146
147
148
   ]
  },
  {
   "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",
149
   "execution_count": 5,
150
151
152
   "metadata": {
    "scrolled": true
   },
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7e00f79b35294f7ba856abd61fc1682c",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "VBox(children=(HBox(children=(Dropdown(description='Circuit name:', options=('RB.A12', 'RB.A23'), value='RB.A1…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
   "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
186
   "execution_count": null,
187
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
188
   "outputs": [],
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
   "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",
    "\n",
    "\n",
320
321
322
    "|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",
323
324
325
326
327
328
    "\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",
329
330
    "- 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"
331
332
333
334
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
335
   "execution_count": null,
336
337
338
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
339
   "outputs": [],
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
   "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",
    "\n",
358
359
360
361
    "|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",
362
363
364
365
366
367
368
    "\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",
369
    "- The green box denotes the validity region of the busbar resostance (0, 3] nOhm"
370
371
372
373
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
374
   "execution_count": null,
375
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
376
   "outputs": [],
377
378
379
   "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
380
    "    .calculate_mean_resistance(circuit_type).df\n",
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
    "\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",
    "\n",
396
397
398
399
    "|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_mag_feature_df | DataFrame | V |NXCALS| Mean, std, and count values of the magnet voltage labeled (1,2,...) at the current plateaus, U_RES|\n",
400
401
402
    "\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",
403
404
    "\n",
    "*CRITERIA*\n",
405
406
407
408
    "- The resistance should be below 50 nOhm\n",
    "\n",
    "*PLOT*:\n",
    "- The busbar resistance, R\n",
409
    "- The green box denotes the validity region of the magnet resistance (0, 50] nOhm\n"
410
411
412
413
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
414
   "execution_count": null,
415
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
416
   "outputs": [],
417
418
419
   "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
420
    "    .calculate_mean_resistance(circuit_type).df\n",
421
422
423
424
425
426
427
428
429
430
431
432
    "\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": [
433
434
    "# 5. DFB\n",
    "## 5.1. DFB Voltage - U_RES\n",
435
436
437
438
439
    "\n",
    "U_RES - Voltage of the resistive part of the current lead (QPS threshold at 100 mV, 100 ms)  \n",
    "\n",
    "*QUERY*:\n",
    "\n",
440
441
442
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
    "|u_res_dfs\t|list of DataFrames\t|V\t|NXCALS|Voltage of the resistive part of even and odd leads, U_RES|\n",
443
444
    "\n",
    "*ANALYSIS*:  \n",
445
    "- At constant current, U_RES must stay constant (no drift < 2mV/h)\n",
446
447
448
    "\n",
    "*PLOT*:  \n",
    "- Voltage of the normal conducting leads on the right axis, U_RES\n",
449
    "- t = 0 s corresponds to the start time of the test\n"
450
451
452
453
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
454
   "execution_count": null,
455
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
456
   "outputs": [],
457
458
459
460
461
462
463
464
465
466
467
   "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": [
468
    "## 5.2. DFB Voltage - U_HTS\n",
469
470
471
472
473
    "\n",
    "U_HTS - Voltage of the HTS part of the current lead (QPS threshold at 1 mV, 100 ms)  \n",
    "\n",
    "*QUERY*:\n",
    "\n",
474
475
476
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
    "|u_hts_dfs\t|list of DataFrames\t|V\t|NXCALS|Voltage of the HTS part of even and odd leads, U_HTS|\n",
477
    "\n",
478
    "*CRITERIA*:  \n",
479
480
481
    "- Voltage must stay below 50% of the threshold -> Abs(U_HTS) < 0.5 mV\n",
    "\n",
    "*PLOT*:  \n",
482
483
    "- Voltage of the HTS leads on the left axis, U_HTS\n",
    "- t = 0 s corresponds to the start time of the test"
484
485
486
487
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
488
   "execution_count": null,
489
490
491
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
492
   "outputs": [],
493
494
495
496
497
498
499
500
501
502
503
   "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": [
504
    "## 5.3. DFB Temperature - TT893.TEMPERATURECALC\n",
505
506
507
508
509
510
511
512
    "\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",
513
514
515
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
    "|tt893_dfs\t|list of DataFrames\t|K\t|NXCALS|Temperature at the top of the current lead, TT893.TEMPERATURECALC|\n",
516
    "\n",
517
    "*CRITERIA*:  \n",
518
519
520
521
522
523
    "- Temperature must be over the dew point, but not overheated -> 280 K < TT893 < 320 K, even without current\n",
    "\n",
    "*PLOT*:  \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",
    "- Green box denotes the temperature validity region [280, 320] K of the temperature at the top of the current lead\n",
524
    "- t = 0 s corresponds to the start time of the test"
525
526
527
528
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
529
   "execution_count": null,
530
531
532
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
533
   "outputs": [],
534
535
536
537
538
539
540
541
542
543
544
   "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": [
545
    "## 5.4. DFB Temperature - TT891A.TEMPERATURECALC\n",
546
547
548
549
550
    "\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",
551
552
553
    "|Variable Name\t|Variable Type\t|Variable Unit\t|Database|Comment\n",
    "|---------------|---------------|---------------|--------|------|\n",
    "|tt891a_dfs\t|list of DataFrames\t|K\t|NXCALS|Temperature between the HTS and resistive part of the current lead, TT891A.TEMPERATURECALC|\n",
554
    "\n",
555
    "*CRITERIA*:  \n",
556
557
558
559
560
561
    "- 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",
562
    "- t = 0 s corresponds to the start time of the test\n"
563
564
565
566
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
567
   "execution_count": null,
568
569
570
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
571
   "outputs": [],
572
573
574
575
576
577
578
579
580
581
   "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": [
582
    "## 5.5. DFB Valve Regulation - CV891.POSST\n",
583
584
585
    "\n",
    "CV891.POSST - Valve for regulation of TT891A\n",
    "\n",
586
    "*QUERY*: \n",
587
    "\n",
588
589
590
    "|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",
591
    "\n",
592
    "*CRITERIA*:  \n",
593
594
595
596
597
598
599
    "- 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",
    "- 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",
600
    "- Green box denotes the valve opening validity region [2, 50] % of the TT891A temperature regulation\n"
601
602
603
604
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
605
   "execution_count": null,
606
607
608
   "metadata": {
    "scrolled": false
   },
Michal Maciejewski's avatar
Michal Maciejewski committed
609
   "outputs": [],
610
611
612
613
614
615
616
617
   "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
618
   "execution_count": null,
619
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
620
   "outputs": [],
621
622
623
624
625
626
627
628
629
630
631
   "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": [
632
    "# 6. Final Report"
633
634
635
636
   ]
  },
  {
   "cell_type": "code",
Michal Maciejewski's avatar
Michal Maciejewski committed
637
   "execution_count": null,
638
   "metadata": {},
Michal Maciejewski's avatar
Michal Maciejewski committed
639
   "outputs": [],
640
641
642
643
644
   "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
645
646
647
648
649
650
651
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
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
680
681
682
683
684
685
686
  }
 ],
 "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
687
   "list_of_options": []
688
689
690
691
692
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}