AN_RB_PLI3.a5.ipynb 17.8 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
    "- We consider standard analysis scenarios, i.e., all signals can be queried. If a signal is missing, an analysis can raise a warning and continue or an error and abort the analysis.\n",
    "- It is recommended to execute each cell one after another. However, since the signals are queried prior to analysis, any order of execution is allowed. In case an analysis cell is aborted, the following ones may not be executed (e.g. I\\_MEAS not present). \n",
32
33
    "\n",
    "# Plot Convention\n",
34
35
    "- 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",
36
    "- 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",
37
38
39
    "- 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",
40
    "- Each plot has an individual time-synchronization mentioned explicitly in the description.\n",
41
    "- If an axis has a single signal, then the color of the label matches the signal's color. Otherwise, the label color is black."
42
43
44
45
46
47
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
48
    "# 0. Initialise Working Environment"
49
50
51
52
   ]
  },
  {
   "cell_type": "code",
53
   "execution_count": null,
54
   "metadata": {
55
    "editable": false,
56
57
    "scrolled": false
   },
58
   "outputs": [],
59
   "source": [
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    "# External libraries\n",
    "print('Loading (1/10)'); import sys\n",
    "print('Loading (2/10)'); from IPython.display import display, Javascript, clear_output\n",
    "\n",
    "# Internal libraries\n",
    "print('Loading (3/10)'); import lhcsmapi\n",
    "print('Loading (4/10)'); from lhcsmapi.Time import Time\n",
    "print('Loading (5/10)'); from lhcsmapi.Timer import Timer\n",
    "print('Loading (6/10)'); from lhcsmapi.analysis.RbCircuitQuery import RbCircuitQuery\n",
    "print('Loading (7/10)'); from lhcsmapi.analysis.RbCircuitAnalysis import RbCircuitAnalysis\n",
    "print('Loading (8/10)'); from lhcsmapi.analysis.report_template import apply_report_template\n",
    "print('Loading (9/10)'); from lhcsmapi.gui.hwc.HwcSearchModuleMediator import HwcSearchModuleMediator\n",
    "print('Loading (10/10)'); from lhcsmapi.pyedsl.PlotBuilder import create_hwc_plot_title_with_circuit_name\n",
    "\n",
    "analysis_start_time = Time.get_analysis_start_time()\n",
    "clear_output()\n",
    "lhcsmapi.get_lhcsmapi_version()\n",
    "lhcsmapi.get_lhcsmhwc_version('../__init__.py')"
78
79
80
81
82
83
84
85
86
87
88
89
   ]
  },
  {
   "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",
90
   "execution_count": null,
91
   "metadata": {
92
    "editable": false,
Michal Maciejewski's avatar
Michal Maciejewski committed
93
    "scrolled": false
94
   },
95
   "outputs": [],
96
97
98
   "source": [
    "circuit_type = 'RB'\n",
    "hwc_test = 'PLI3.a5'\n",
99
    "hwcb = HwcSearchModuleMediator(circuit_type=circuit_type, hwc_test=hwc_test, hwc_summary_path='/eos/project/l/lhcsm/hwc/HWC_Summary.csv')"
100
101
102
103
104
105
106
107
108
109
110
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. Query All Signals Prior to Analysis"
   ]
  },
  {
   "cell_type": "code",
111
   "execution_count": null,
112
113
114
115
116
   "metadata": {
    "tags": [
     "skip_output"
    ]
   },
117
   "outputs": [],
118
119
   "source": [
    "circuit_name = hwcb.get_circuit_name()\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
120
121
    "t_start = Time.to_unix_timestamp(hwcb.get_start_time())\n",
    "t_end = Time.to_unix_timestamp(hwcb.get_end_time())\n",
122
    "is_automatic = hwcb.is_automatic_mode()\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
123
    "rb_query = RbCircuitQuery(circuit_type, circuit_name, max_executions=6)\n",
124
    "rb_analysis = RbCircuitAnalysis(circuit_type, None, is_automatic=is_automatic)\n",
125
126
    "\n",
    "with Timer():\n",
127
    "    # PC\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
128
    "    i_meas_nxcals_df = rb_query.query_signal_nxcals(t_start, t_end, t0=t_start, system='PC', signal_names='I_MEAS', spark=spark)[0]\n",
129
    "    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",
Michal Maciejewski's avatar
Michal Maciejewski committed
130
    "    plateau_start, plateau_end = rb_analysis.find_plateau_start_and_end(i_meas_raw_nxcals_df, i_meas_threshold=0, min_duration_in_sec=360, time_shift_in_sec=(240, 60))\n",
131
132
    "\n",
    "    # BUSBAR\n",
133
    "    u_res_feature_df, i_meas_feature_df = rb_query.get_busbar_resistances(Time.to_unix_timestamp(t_start), Time.to_unix_timestamp(t_end), plateau_start, plateau_end, signal_name='U_RES', spark=spark)\n",
134
    "    res_busbar_row_df = rb_analysis.calculate_resistance(i_meas_feature_df, u_res_feature_df, 'U_RES', Time.to_unix_timestamp(t_start), circuit_name)\n",
135
    "    res_busbar_df = rb_analysis.convert_to_col(res_busbar_row_df, signal_name='U_RES')\n",
136
    "    \n",
137
    "    # MAGNET\n",
138
    "    u_mag_feature_df, i_meas_feature_df = rb_query.get_busbar_resistances(Time.to_unix_timestamp(t_start), Time.to_unix_timestamp(t_end), plateau_start, plateau_end, signal_name='U_MAG', spark=spark)\n",
139
    "    res_magnet_row_df = rb_analysis.calculate_resistance(i_meas_feature_df, u_mag_feature_df, 'U_MAG', Time.to_unix_timestamp(t_start), circuit_name)\n",
140
    "    res_magnet_df = rb_analysis.convert_to_col(res_magnet_row_df, signal_name='U_MAG')\n",
141
    "    \n",
142
    "    # LEADS\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
143
144
    "    u_res_nxcals_dfs = rb_query.query_signal_nxcals(t_start, t_end, t0=t_start, 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, t0=t_start, system=['LEADS_EVEN', 'LEADS_ODD'], signal_names='U_HTS', spark=spark)\n",
145
    "\n",
146
147
148
    "    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"
149
150
151
152
153
154
155
156
157
158
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. Power Converter\n",
    "## 3.1. Plot of the Power Converter Main Current\n",
    "\n",
    "*ANALYSIS*:\n",
159
    "\n",
160
161
    "- Calculation of the duration of current plateaus\n",
    "\n",
162
163
    "*GRAPHS*:\n",
    "\n",
164
165
    "- 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"
166
167
168
169
   ]
  },
  {
   "cell_type": "code",
170
   "execution_count": null,
171
172
173
   "metadata": {
    "scrolled": false
   },
174
   "outputs": [],
175
   "source": [
176
177
178
179
180
181
    "import matplotlib as mpl\n",
    "mpl.rcParams['savefig.dpi'] = 80\n",
    "mpl.rcParams['figure.dpi'] = 80\n",
    "%matplotlib notebook\n",
    "title = '%s, %s: %s-%s' % (circuit_name, hwc_test, Time.to_string(t_start).split('.')[0], Time.to_string(t_end).split('.')[0])\n",
    "rb_analysis.plot_i_meas_with_current_plateau(i_meas_nxcals_df, t0=i_meas_raw_nxcals_df.index[0], plateau_start=plateau_start, plateau_end=plateau_end, title=title)"
182
183
184
185
186
187
188
189
190
191
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. Busbar\n",
    "## 4.1. Busbar Resistance\n",
    "\n",
    "*ANALYSIS*:\n",
192
    "\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
193
    "- Calculation of the busbar resistance as the slope of a linear fit of U,I curve obtained from the corresponding mean values of the voltage and current\n",
194
    "\n",
195
196
197
198
199
200
    "*CRITERIA*:\n",
    "\n",
    "- Check if the busbar resistance is below 3 nOhm\n",
    "\n",
    "*GRAPHS*:\n",
    "\n",
201
    "- The busbar resistance, R\n",
202
    "- The green box denotes the validity region of the busbar resostance (0, 3] nOhm"
203
204
205
206
   ]
  },
  {
   "cell_type": "code",
207
   "execution_count": null,
208
209
210
   "metadata": {
    "editable": false
   },
211
   "outputs": [],
212
   "source": [
213
    "res_busbar_outliers_df = rb_analysis.analyze_busbar_magnet_resistance(res_busbar_df, signal_name='R_RES', max_value=3e-9)"
214
215
216
217
   ]
  },
  {
   "cell_type": "code",
218
   "execution_count": null,
219
220
221
222
223
   "metadata": {
    "editable": false
   },
   "outputs": [],
   "source": [
224
    "RbCircuitQuery.query_and_plot_outlier_voltage(res_busbar_outliers_df, t_start, t_end, i_meas_raw_nxcals_df.index[0], plateau_start, plateau_end, spark=spark)"
225
226
   ]
  },
227
228
229
230
231
232
233
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.2. Magnet Resistance\n",
    "\n",
    "*ANALYSIS*:\n",
234
    "\n",
235
    "- 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",
236
237
    "\n",
    "*CRITERIA*\n",
238
    "\n",
239
240
241
242
243
    "- Check if the resistance is below 50 nOhm\n",
    "\n",
    "*GRAPHS*:\n",
    "\n",
    "- The magnet resistance, R\n",
244
    "- The green box denotes the validity region of the magnet resistance (0, 50] nOhm\n"
245
246
247
248
   ]
  },
  {
   "cell_type": "code",
249
   "execution_count": null,
250
251
252
   "metadata": {
    "editable": false
   },
253
   "outputs": [],
254
   "source": [
255
    "res_magnet_outliers_df = rb_analysis.analyze_busbar_magnet_resistance(res_magnet_df, signal_name='R_MAG', max_value=50e-9)"
256
257
258
259
   ]
  },
  {
   "cell_type": "code",
260
   "execution_count": null,
261
   "metadata": {},
262
263
   "outputs": [],
   "source": [
264
    "RbCircuitQuery.query_and_plot_outlier_voltage(res_magnet_outliers_df.reset_index(), t_start, t_end, i_meas_raw_nxcals_df.index[0], plateau_start, plateau_end, spark=spark)"
265
266
   ]
  },
267
268
269
270
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
271
272
    "# 5. DFB\n",
    "## 5.1. DFB Voltage - U_RES\n",
273
    "\n",
274
275
    "*CRITERIA*:\n",
    "- Check if, at constant current, U_RES is constant (no drift < 2mV/h)\n",
276
    "\n",
277
    "*GRAPHS*:\n",
278
    "- t = 0 s corresponds to the start time of the test\n"
279
280
281
282
   ]
  },
  {
   "cell_type": "code",
283
   "execution_count": null,
284
285
286
287
   "metadata": {
    "deletable": false,
    "editable": false
   },
288
   "outputs": [],
289
   "source": [
290
    "RbCircuitAnalysis.assert_u_res_min_max_slope(u_res_nxcals_dfs, plateau_start, plateau_end, Time.to_unix_timestamp(t_start), slope_range=(-2, 2))"
291
292
293
294
295
296
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
297
    "## 5.2. DFB Voltage - U_HTS\n",
298
    "\n",
299
    "*CRITERIA*:  \n",
300
    "- Check if the voltage is below 50% of the threshold -> Abs(U_HTS) < 0.5 mV\n",
301
    "\n",
302
    "*GRAPHS*:\n",
303
    "- t = 0 s corresponds to the start time of the test"
304
305
306
307
   ]
  },
  {
   "cell_type": "code",
308
   "execution_count": null,
309
   "metadata": {
310
311
    "deletable": false,
    "editable": false,
312
313
    "scrolled": false
   },
314
   "outputs": [],
315
   "source": [
316
    "RbCircuitAnalysis.assert_u_hts_min_max_slope(u_hts_nxcals_dfs, plateau_start, plateau_end, Time.to_unix_timestamp(t_start), slope_range=(-0.5, 0.5))"
317
318
319
320
321
322
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
323
    "## 5.3. DFB Temperature - TT893.TEMPERATURECALC\n",
324
    "\n",
325
326
327
328
329
    "*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",
330
331
332
    "\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",
333
    "- t = 0 s corresponds to the start time of the test"
334
335
336
337
   ]
  },
  {
   "cell_type": "code",
338
   "execution_count": null,
339
   "metadata": {
340
341
    "deletable": false,
    "editable": false,
342
343
    "scrolled": false
   },
344
   "outputs": [],
345
   "source": [
346
    "RbCircuitAnalysis.assert_tt893_min_max_value(tt893_nxcals_dfs, value_range=(280, 320))"
347
348
349
350
351
352
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
353
    "## 5.4. DFB Temperature - TT891A.TEMPERATURECALC\n",
354
    "\n",
355
356
357
358
359
    "*CRITERIA*:\n",
    "\n",
    "- Check if the temperature is regulated around 50 K -> 46 K < TT891A < 54 K, even without current\n",
    "\n",
    "*GRAPHS*:\n",
360
361
362
363
    "\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",
364
    "- t = 0 s corresponds to the start time of the test\n"
365
366
367
368
   ]
  },
  {
   "cell_type": "code",
369
   "execution_count": null,
370
   "metadata": {
371
372
    "deletable": false,
    "editable": false,
373
374
    "scrolled": false
   },
375
   "outputs": [],
376
   "source": [
377
    "RbCircuitAnalysis.assert_tt891a_min_max_value(tt891a_nxcals_dfs, value_range=(46, 54))"
378
379
380
381
382
383
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
384
    "## 5.5. DFB Valve Regulation - CV891.POSST\n",
385
    "\n",
386
387
388
389
390
391
    "*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",
392
393
394
395
    "\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",
396
    "- Green box denotes the valve opening validity region [2, 50] % of the TT891A temperature regulation"
397
398
399
400
   ]
  },
  {
   "cell_type": "code",
401
   "execution_count": null,
402
   "metadata": {
403
404
    "deletable": false,
    "editable": false,
405
406
    "scrolled": false
   },
407
   "outputs": [],
408
   "source": [
409
    "RbCircuitAnalysis.assert_cv891_min_max_value(cv891_nxcals_dfs, value_range=(2, 50))"
410
411
412
413
   ]
  },
  {
   "cell_type": "code",
414
   "execution_count": null,
415
416
417
418
   "metadata": {
    "deletable": false,
    "editable": false
   },
419
   "outputs": [],
420
   "source": [
421
    "RbCircuitAnalysis.assert_cv891_min_max_variation(cv891_nxcals_dfs, 8, plateau_start, plateau_end, Time.to_unix_timestamp(t_start))"
422
423
424
425
426
427
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
428
    "# 6. Final Report"
429
430
431
432
   ]
  },
  {
   "cell_type": "code",
433
   "execution_count": null,
434
435
436
   "metadata": {
    "editable": false
   },
437
   "outputs": [],
438
439
   "source": [
    "campaign = hwcb.get_campaign()\n",
440
    "apply_report_template()\n",
Michal Maciejewski's avatar
Michal Maciejewski committed
441
    "file_name_html = '{}_{}-{}-{}_report.html'.format(circuit_name, hwc_test, Time.to_datetime(t_start).strftime(\"%Y.%m.%d_%H%M%S\"), analysis_start_time)\n",
442
443
    "full_path = '/eos/project/m/mp3/RB/{}/{}/{}/{}'.format(circuit_name, hwc_test, campaign, file_name_html)\n",
    "!mkdir -p /eos/project/m/mp3/RB/$circuit_name/$hwc_test/$campaign\n",
444
445
    "print('Compact notebook report saved to (Windows): ' + '\\\\\\\\cernbox-smb' + full_path.replace('/', '\\\\'))\n",
    "display(Javascript('IPython.notebook.save_notebook();'))\n",
446
447
    "Time.sleep(5)\n",
    "!{sys.executable} -m jupyter nbconvert --to html $'AN_RB_PLI3.a5.ipynb' --output /eos/project/m/mp3/RB/$circuit_name/$hwc_test/$campaign/$file_name_html --TemplateExporter.exclude_input=True --TagRemovePreprocessor.remove_all_outputs_tags='[\"skip_output\"]'"
448
   ]
Michal Maciejewski's avatar
Michal Maciejewski committed
449
450
451
452
453
454
455
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
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
  }
 ],
 "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
481
   "list_of_options": []
482
483
484
485
486
487
488
489
490
491
492
493
494
  },
  "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
495
496
497
498
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
Michal Maciejewski's avatar
Michal Maciejewski committed
499
}