quench_digger2.ipynb 32.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "<h1><center>Analysis of an FPA in an RB Circuit</center></h1>\n",
    "<img src=\"https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/RB.png\" width=75%>\n",
    "source: Powering Procedure and Acceptance Criteria for the 13 kA Dipole Circuits, MP3 Procedure, <a href=\"https://edms.cern.ch/document/874713\">https://edms.cern.ch/document/874713</a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Original text: 2020-2021 (Michal); Last corrections: 29/03/2021 (Zinur)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# Analysis Assumptions\n",
    "- 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",
    "\n",
    "# Plot Convention\n",
    "- 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",
    "- 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",
    "- 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",
    "- Each plot has an individual time-synchronization mentioned explicitly in the description.\n",
    "- If an axis has a single signal, then the color of the label matches the signal's color. Otherwise, the label color is black."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 0. Initialise Working Environment"
   ]
  },
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
53
   "execution_count": null,
54
55
56
57
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
thbuffet's avatar
thbuffet committed
58
   "outputs": [],
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
   "source": [
    "# External libraries\n",
    "print('Loading (1/12)'); import sys, warnings\n",
    "print('Loading (2/12)'); from IPython.display import display, Javascript, HTML, clear_output\n",
    "print('Loading (3/12)'); import pandas as pd\n",
    "\n",
    "# Internal libraries\n",
    "print('Loading (4/12)'); import lhcsmapi\n",
    "print('Loading (5/12)'); from lhcsmapi.Time import Time\n",
    "print('Loading (6/12)'); from lhcsmapi.Timer import Timer\n",
    "print('Loading (7/12)'); from lhcsmapi.analysis.RbCircuitQuery import RbCircuitQuery\n",
    "print('Loading (8/12)'); from lhcsmapi.analysis.RbCircuitAnalysis import RbCircuitAnalysis\n",
    "print('Loading (9/12)'); from lhcsmapi.analysis.report_template import apply_report_template\n",
    "print('Loading (10/12)'); from lhcsmapi.analysis.expert_input import get_expert_decision\n",
    "print('Loading (11/12)'); from lhcsmapi.gui.DateTimeBaseModule import DateTimeBaseModule\n",
    "print('Loading (12/12)'); from lhcsmapi.gui.pc.FgcPmSearchModuleMediator import FgcPmSearchModuleMediator\n",
    "\n",
    "clear_output()\n",
    "lhcsmapi.get_lhcsmapi_version()\n",
    "lhcsmapi.get_lhcsmhwc_version('../__init__.py')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 1. Select FGC Post Mortem Entry"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false,
    "tags": [
     "skip_cell"
    ]
   },
   "source": [
    "In order to perform the analysis of a FPA in an RB circuit please:\n",
    "1. Select circuit name (e.g., RB.A12)\n",
    "2. Choose start and end time\n",
    "3. Choose analysis mode (Automatic by default)\n",
    "\n",
    "Once these inputs are provided, click 'Find FGC PM entries' button. This will trigger a search of the PM database in order to provide a list of timestamps of FGC events associated with the selected circuit name for the provided period of time. Select one timestamp from the 'FGC PM Entries' list to be processed by the following cells.\n",
    "\n",
    "**Note that 24 hours is the maximum duration of a single PM query for an event. To avoid delays in querying events, please restrict your query duration as much as possible.**"
   ]
  },
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
111
   "execution_count": null,
112
113
114
115
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
thbuffet's avatar
thbuffet committed
116
   "outputs": [],
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
   "source": [
    "circuit_type = 'RB'\n",
    "fgc_pm_search = FgcPmSearchModuleMediator(DateTimeBaseModule(start_date_time='2021-04-25 15:23:24+02:00',\n",
    "                                                             end_date_time='2021-04-25 15:28:29+02:00'), circuit_type=circuit_type)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 2. Query All Signals Prior to Analysis"
   ]
  },
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
134
   "execution_count": null,
135
136
137
138
139
140
141
   "metadata": {
    "deleteable": true,
    "scrolled": false,
    "tags": [
     "skip_output"
    ]
   },
thbuffet's avatar
thbuffet committed
142
   "outputs": [],
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
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
   "source": [
    "timestamp_fgc = fgc_pm_search.get_fgc_timestamp()\n",
    "circuit_name = fgc_pm_search.get_fgc_circuit()\n",
    "author = fgc_pm_search.get_author()\n",
    "is_automatic = fgc_pm_search.is_automatic_mode()\n",
    "rb_query = RbCircuitQuery(circuit_type, circuit_name, max_executions=45)\n",
    "\n",
    "with Timer():\n",
    "    timestamp_pic = rb_query.find_timestamp_pic(timestamp_fgc, spark=spark)\n",
    "\n",
    "     # PC Current\n",
    "    i_meas_df, i_a_df, i_earth_df, i_earth_pcnt_df, i_ref_df = rb_query.query_pc_pm(timestamp_fgc, timestamp_fgc, signal_names=['I_MEAS', 'I_A', 'I_EARTH', 'I_EARTH_PCNT', 'I_REF'])\n",
    "    \n",
    "    source_timestamp_qds_df = rb_query.find_source_timestamp_qds(timestamp_fgc)\n",
    "    source_timestamp_nqps_df = rb_query.find_source_timestamp_nqps(timestamp_fgc)\n",
    "    source_timestamp_qh_df = rb_query.find_source_timestamp_qh(timestamp_fgc, duration=[(10, 's'), (500, 's')])\n",
    "\n",
    "    \n",
    "    # U_DIODE - CALS\n",
    "    u_diode_rb_dfs = rb_query.query_voltage_nxcals('DIODE_RB', 'U_DIODE_RB', timestamp_fgc, spark=spark, duration=[(50, 's'), (350, 's')])\n",
    "    results_table = rb_query.create_report_analysis_template(source_timestamp_qds_df, source_timestamp_nqps_df, min(timestamp_pic), timestamp_fgc, '../__init__.py', i_meas_df, author)\n",
    "\n",
    "\n",
    "\n",
    "rb_analysis = RbCircuitAnalysis(circuit_type, results_table, is_automatic=is_automatic)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 8. Quench Protection System: QDS, QH and by pass Diode\n",
    "<img src=\"https://gitlab.cern.ch/LHCData/lhc-sm-hwc/raw/master/figures/rb/RB_QPS_Signals.png\" width=75%>\n",
    "\n",
    "The table below shows the sign of the resistive voltages and inductive voltages (for positive ramp rate) of U1 and U2. U_QS0=-U1-U2.\n",
    "\n",
    "|Circuit\t|Resistive voltage U1\t|Resistive voltage U2\t|Inductive voltage U1\t|Inductive voltage U2|\n",
    "|-----------|-----------------------|-----------------------|-----------------------|--------------------|\n",
    "|RB.A12\t|Pos\t|Neg\t|Pos\t|Neg|\n",
    "|RB.A23\t|Neg\t|Pos\t|Neg\t|Pos|\n",
    "|RB.A34\t|Neg\t|Pos\t|Neg\t|Pos|\n",
    "|RB.A45\t|Neg\t|Pos\t|Neg\t|Pos|\n",
    "|RB.A56\t|Pos\t|Neg\t|Pos\t|Neg|\n",
    "|RB.A67\t|Pos\t|Neg\t|Pos\t|Neg|\n",
    "|RB.A78\t|Pos\t|Neg\t|Pos\t|Neg|\n",
    "|RB.A81\t|Neg\t|Pos\t|Neg\t|Pos|\n",
    "\n",
    "The thresholds and evaluation times for the QPS on the RB circuits are given in the following table:\n",
    "\n",
    "|Class\t|System\t|Threshold\t|Evaluation time\t|Signal\t|Comment|\n",
    "|-------|-------|-----------|-------------------|-------|:------|\n",
    "|DQAMCNMB_PMSTD\t|iQPS, DQQDL |100 mV\t|10 ms discrimination\t|U_QS0\t|Old QPS. Detection of quench in one aperture based upon voltage difference between both apertures in same magnet U_QS0 >10 ms above threshold, otherwise discriminator is reset|\n",
    "|DQAMCNMB_PMHSU\t|iQPS, nQPS |-|-|-|Firing of quench heaters by quench protection. Generation of PM buffers sometimes happens even if there is no heater firing.|\n",
    "|DQAMGNSRB (slow sampling rate), DQAMGNSRB_PMREL (fast sampling rate) |nQPS, DQQDS |500 mV *\t|>20 ms moving average +1 ms discrimination\t|U_DIODE\t|New QPS. Detection of quench in both apertures based upon comparing voltage across the magnet (bypass diode) from 3 magnets in same half-cell and one reference from adjacent half-cell. 50Hz notch moving average filter (20ms worst case). The signals in the 2 classes are identical, only the sampling rate differs. The data with the slow sampling rate is no longer generated as they can be found in the logging database. The recording of data is usually triggered during a FPA, depending on current in circuit, and always when a symmetric quench occurs. The PM buffers are only sent if the DQAMGNS crate trips (what ever the reason).|\n",
    "|DQAMGNSRB\t|nQPS, DQQBS| 4 mV\t| >10 s moving average\t| U_RES\t|New QPS. Busbar protection. The signal is not compensated for inductive voltage during ramp.|\n",
    "|DQAMGNDRB_EVEN, DQAMGNDRB_ODD |iQPS, DQQDC |1 mV, 100 mV |1 s\t|U_HTS, U_RES |Old QPS. Leads protection. U_HTS is for the high temperature superconducting leads, and U_RES is for the room temperature leads.|\n",
    "|DQAMGNDRB_EVEN, DQAMGNDRB_ODD |iQPS, DQQDB |+200 V | -50 V | \tU_BB1, U_BB2\t|Old QPS. U_BB1 is the total voltage across the sector. U_BB2 is the voltage across the energy extraction (EE)|\n",
    "|DQAMSNRB |-|-|-|-|Opening of energy extraction (EE) switches during fast power abort (FPA). 2 EE switches per sector. One for \"even\" points (EE2). One for \"odd\" points (EE1).|\n",
    "\n",
    "*: It was 800 mV before LS1. After LS1 we changed it to 300 or 400 mV. During the training after LS1 we increased it to 500 mV."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "## 8.1. Plot of Voltage Across All Magnets (U_DIODE_RB)\n",
    "\n",
    "*PLOT*: \n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the FGC\n",
    "\n",
    "First plot  (global)\n",
    "- the power converter current on the left axis, I_MEAS\n",
    "- diode voltage on the right axis, U_DIODE_RB\n",
    "\n",
    "Second plot (zoom)\n",
    "- the power converter current on the left axis, I_MEAS\n",
    "- diode voltage on the right axis, U_DIODE_RB"
   ]
  },
  {
   "cell_type": "code",
thbuffet's avatar
thbuffet committed
230
231
232
233
234
235
236
237
238
239
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rb_analysis.results_table[['Circuit Name', 'Position', 'I_Q_M', 'Delta_t(iQPS-PIC)', 'nQPS crate name', 'Delta_t(nQPS-PIC)']] "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
240
241
242
243
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
thbuffet's avatar
thbuffet committed
244
   "outputs": [],
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
331
332
333
334
335
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
381
382
383
384
385
386
387
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
430
431
432
433
434
435
436
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
488
489
490
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
535
536
537
538
539
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
583
584
585
586
587
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
632
633
634
635
636
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
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
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
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
   "source": [
    "%matplotlib notebook\n",
    "rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', xlim=(-25, 350))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', xlim=(-1, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "u_diode_with_quench_rb_dfs = rb_analysis.filter_quenched_magnets(u_diode_rb_dfs, results_table['Position'])\n",
    "rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_with_quench_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', legend=True, xlim=(-25, 350))\n",
    "print(\"done!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "rb_analysis.analyze_u_diode_nqps(circuit_name, timestamp_fgc, i_meas_df, u_diode_with_quench_rb_dfs, 'U_DIODE_RB', 'DIODE_RB', legend=True, xlim=(-1, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "## 8.2. Analysis of Quenched Magnets by QDS - PMs\n",
    "\n",
    "*ANALYSIS*:\n",
    "- calculates the current at which a quench occured by finding the timestamp of the current dataframe (i_meas_df) closest to the quench time and the curresponding value of current - I_MEAS_quench\n",
    "- compute the time difference (in milliseconds) from the first quench - dt_quench"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false
   },
   "outputs": [],
   "source": [
    "rb_analysis.results_table[['Circuit Name', 'I_Q_circ', 'Position', 'I_Q_M', 'Delta_t(iQPS-PIC)', 'nQPS crate name', 'Delta_t(nQPS-PIC)']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "## 8.3. Analysis of Quench Detection Voltage and Logic Signals for Quenched Magnets\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "*ANALYSIS*:\n",
    "- finds the first timestamp, t_st_magnet_ok, for which the ST_MAGNET_OK signal is False indicating that the quench detection signal U_QS0 is outside of the +/- 100/200 mV threshold.\n",
    "- for t > t_st_magnet_ok, finds the first timestamp, t_st_nqd0 for which the ST_NQD0 signal is False indicating that the U_QS0 signal is outside of the +/- 100/200 mV threshold for more than the 10 ms discrimination time. This signifies quench detection and results in triggering quench heaters;\n",
    "- finds U_QS0 value at the moment of quench detection, u_ST_NQD0 = U_QS0(t=t_st_nqd0);\n",
    "- if the minimum value of the absolute value of U_QS0 is above greater than 100 ms, then find the start time of a quench, t_start_quench, as a moment at which U_QS0 value is 10 mV greater than its initial value. Otherwise, the start time of a quench is set to 0 s;\n",
    "- finds U_QS0 value, u_start_quench, at the moment of quench start as u_start_quench = U_QS0(t=t_start_quench);\n",
    "- the slope of the quench detection signals is calculated as du_dt = (u_ST_NQD0 - u_start_quench) / (t_st_nqd0 - t_start_quench);\n",
    "- the quench detection signal polarity is taken as the sign of its slope;\n",
    "- the delay of the quench heaters triggering, t_delay_qh_trigger, is assumed to be the negative value of t_st_magnet_ok, t_delay_qh_trigger = -t_st_magnet_ok;\n",
    "\n",
    "Determine possible source of QH trigger for nQPS signals in PM:\n",
    "- calculates nQPS differences for the symmetric quench detection;\n",
    "- selects only the differences that involve the quenched magnet and exclude already quenched magnets in the cell;\n",
    "- for t in [-0.2 s, t_st_magnet_ok] take the maximum value of voltage difference;\n",
    "- if the maximum is above 1V (considering sun glasses active from t = 0 s) and the time of maximum is less than t_st_magnet_ok, than the QH system was triggered by nQPS, otherwise iQPS;\n",
    "- it is assumed that the first training quench was detected by iQPS;\n",
    "\n",
    "*PLOT*:\n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the QDS (iQPS or nQPS)\n",
    "\n",
    "Upper left  (iQPS analog signals)\n",
    "- the quench detection voltage on the left axis, U_QS0;\n",
    "- voltage across the first and the second aperture on the right axis, respectively, U_1 and U_2;\n",
    "- the green box denotes an envelope of the +/- 100/200 mV quench detection threshold;\n",
    "- the orange box denotes an envelope of the rise of the quench signal from its start until reaching the threshold;\n",
    "\n",
    "Lower left  (iQPS digital signals)\n",
    "- the quench detection voltage on the left axis, U_QS0;\n",
    "- digital quench detection signals, ST_MAGNET_OK, ST_NQD0;\n",
    "- the green box denotes an envelope of the +/- 100/200 mV quench detection threshold;\n",
    "- the orange box denotes an envelope of the rise of the quench signal from its start until reaching the threshold;\n",
    "\n",
    "Upper right (nQPS analog signals)  \n",
    "For PM signals (global view)\n",
    "- the diode voltages used by the nQPS crate for quench detection on the left axis, U_DIODE_RB and U_REF_N1;\n",
    "\n",
    "For NXCALS signals (global view)\n",
    "- the diode voltages used by the nQPS crate for quench detection on the left axis, U_DIODE_RB and U_REF_N1;\n",
    "\n",
    "Lower right (nQPS analog signals)  \n",
    "For PM signals  (difference view) \n",
    "- the differences of diode voltages (containing the quenched magnet; in case the signals are missing, the plot is not displayed) used by the nQPS crate for quench detection on the left axis, U (Calculated U_DIODE and U_REF_N1 differences);\n",
    "- the green box denotes an envelope of 1 V quench detection threshold (assuming active 'sun glasses') before the iQPS quench detection. If the nQPS difference goes outside of the envelope, it means that the quench was detected by nQPS.\n",
    "\n",
    "For NXCALS signals (zoomed view)\n",
    "- the diode voltages used by the nQPS crate for quench detection on the left axis, U_DIODE_RB and U_REF_N1;\n",
    "\n",
    "Note: The iQPS threshold can be changed in the cell below before you run it. Now it is 0.2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# iQPS Threshold\n",
    "threshold_iqps = 0.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "rb_analysis.analyze_qds(timestamp_fgc, min(timestamp_pic), u_qds_dfs, u_qds_dfs2, u_nqps_dfs, i_meas_df, threshold=threshold_iqps)\n",
    "rb_analysis.results_table[['Circuit Name', 'Position', 'nQPS crate name', 'Delta_t(iQPS-PIC)','I_Q_circ', 'I_Q_M', 'Delta_t(nQPS-PIC)', 'QDS trigger origin', 'dU_iQPS/dt', 'Type of Quench']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "## 8.4. Check of Quench Heater Discharges\n",
    "\n",
    "*CRITERIA*:\n",
    "- all characteristic times of an exponential decay calculated with the 'charge' approach for voltage and current are +/- 3 ms from the reference ones;\n",
    "- all initial resistances are +/- 0.5 Ohm from the reference ones;\n",
    "- all initial voltages are between 780 and 980 V;\n",
    "- all final voltages are between 15 and 70 V;\n",
    "\n",
    "*PLOT*:  \n",
    "\n",
    "t = 0 s corresponds to the start of the decay.  \n",
    "Line for actual signal is continuous and dashed for the reference.\n",
    "\n",
    "Left plot (Voltage view)\n",
    "- the querried and filtered quench heater voltage on the left axis, U_HDS;\n",
    "\n",
    "Middle plot (Current view)\n",
    "- the querried and filtered quench heater current on the left axis, I_HDS;\n",
    "\n",
    "Right plot (Resistance view)\n",
    "- the calculated quench heater resistance on the left axis, R_HDS = U_HDS/I_HDS;\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "rb_analysis.analyze_qh(source_timestamp_qh_df, u_hds_dfs, i_hds_dfs, u_hds_ref_dfs, i_hds_ref_dfs)\n",
    "rb_analysis.results_table[['Circuit Name', 'Position', 'Delta_t(iQPS-PIC)', 'I_Q_circ', 'I_Q_M', 'Delta_t(nQPS-PIC)', 'QDS trigger origin', 'QH analysis']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "## 8.5. Evaluation of Diode Leads Resistance\n",
    "\n",
    "**NB: It is not a reason to fail and flag the circuit! It is just a subject to be discussed and to pay an attention.**\n",
    "\n",
    "*ANALYSIS*:\n",
    "- calculates diode lead resistance from voltage difference between board A and B and current;\n",
    "\n",
    "NB: The offset for an inintial (not quenched) U_DIODE_RB is not yet compensated!\n",
    "\n",
    "Note: Offset compensation is implemented in General QPS Browser from Labview MP3-tools (just in case).\n",
    "\n",
    "*CRITERIA*\n",
    "- if the maximum resistance is above 50 uOhm, then raise a warning;\n",
    "- if the maximum resistance is above 150 uOhm, then raise an alarm;\n",
    "\n",
    "*PLOT*:  \n",
    "Upper PM (Input view)  \n",
    "- the main power converter current on the left axis, IAB.I_A;\n",
    "- quenched magnet voltage from two boards, U_DIODE_A, U_DIODE_B. The difference between both signals is the diode lead voltage;\n",
    "- reference nQPS board voltage on the right axis, U_REF_N1;\n",
    "- displayed on the left only if a quench occured no later than 2 seconds after the FGC PM timestamp;\n",
    "- t = 0 s corresponds to the PM timestamp of the nQPS;\n",
    "\n",
    "Lower PM (Output view)  \n",
    "- the main power converter current on the left axis, IAB.I_A;\n",
    "- the calculated diode lead resistance on the right axis, R_DIODE_LEADS;\n",
    "- diplayed on the left only if a quench occured no later than 2 seconds after the FGC PM timestamp;\n",
    "- t = 0 s corresponds to the PM timestamp of the nQPS;\n",
    "\n",
    "Upper CALS (Input view)  \n",
    "- the main power converter current on the left axis, I_MEAS;\n",
    "- quenched magnet voltage from two boards is saved as a single signal, U_DIODE_RB. The two signals are stored by means of value toggling between board A and board B. The difference between both sub-signals is the diode lead voltage;\n",
    "- t = 0 s corresponds to the PM timestamp of the iQPS;\n",
    "\n",
    "Lower CALS (Output view)  \n",
    "- the main power converter current on the left axis, I_MEAS\n",
    "- the calculated diode lead resistance on the right axis, R_DIODE_LEADS;\n",
    "- t = 0 s corresponds to the PM timestamp of the iQPS;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "rb_analysis.analyze_diode_leads(source_timestamp_qds_df, timestamp_fgc, results_table['I_Q_M'], circuit_name, i_a_u_diode_u_ref_pm_dfs, i_meas_u_diode_nxcals_dfs)\n",
    "rb_analysis.results_table[['Circuit Name', 'Date (FGC)', 'Time (FGC)', 'I_Q_circ', 'Position', 'I_Q_M', 'R_DL_max', 'I at R_DL_max']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "## 8.6. General view of Voltage Feelers (nQPS)\n",
    "\n",
    "Every nQPS crate (54 per circuit) has one Voltage Feeler card, so about every 3rd magnet has an earth leakage aqcuisition. It can help to localize the problem in case of an earth fault in the circuit. The simulations on some use cases had been done by STEAM-team (links?).\n",
    "\n",
    "*Voltage Feeler STATUS*:\n",
    "- if the voltage of a voltage feeler is equal to 0 V, then it means that the corresponding card is disabled;\n",
    "- if the voltage of a voltage feeler is equal to -2000 V, then it means that the corresponding card is not communicating;\n",
    "- otherwise it is OK;\n",
    "\n",
    "*PLOT*:  \n",
    "\n",
    "t = 0 s corresponds to the PM timestamp of the FGC\n",
    "\n",
    "First plot (global)\n",
    "- the power converter current on the left axis, I_MEAS;\n",
    "- earth voltage on the right axis, U_EARTH_RB;\n",
    "\n",
    "Second plot (zoom)\n",
    "- the power converter current on the left axis, I_MEAS;\n",
    "- earth voltage on the right axis, U_EARTH_RB;i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "rb_analysis.analyze_voltage_feelers(circuit_name, timestamp_fgc, i_meas_df, u_earth_rb_dfs, 'U_EARTH_RB', 'VF')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false
   },
   "outputs": [],
   "source": [
    "if not fgc_pm_search.is_automatic_mode():\n",
    "    rb_analysis.results_table['V feeler analysis'] = get_expert_decision('Voltage feeler analysis: ', ['PASS', 'FAIL'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "\n",
    "## 8.7. Check QDS of Current Leads\n",
    "\n",
    "*CRITERIA*:\n",
    "\n",
    "- Check if the quench detection signal for U_HTS is below the threshold (3 mV);\n",
    "- Check if the quench detection signal for U_RES is below the threshold (100 mV);\n",
    "\n",
    "**NB: The discrimination time is not taken into account!** ;(\n",
    "\n",
    "*PLOT*:  \n",
    "\n",
    "- t = 0 s corresponds to the FGC timestamp;\n",
    "\n",
    "Global view (for odd and even leads)\n",
    "- voltage of the HTS leads on the left axis, U_HTS;\n",
    "- voltage of the normal conducting leads on the left axis, U_RES;\n",
    "- blue horizontal dashed line denotes the QPS timestamp;\n",
    "\n",
    "Zoom view (for odd and even leads)\n",
    "- voltage of the HTS leads on the left axis, U_HTS;\n",
    "- blue horizontal dashed line denotes the QPS timestamp;\n",
    "- cyan horizontal dashed line denotes the EE odd timestamp;\n",
    "- green horizontal dashed line denotes the EE even timestamp;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "rb_analysis.analyze_leads_voltage(u_hts_odd_dfs+u_hts_even_dfs, circuit_name, timestamp_fgc, timestamp_qps=source_timestamp_qds_df.loc[0, 'timestamp'], signal='U_HTS', value_min=-0.003, value_max=0.003)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false
   },
   "outputs": [],
   "source": [
    "rb_analysis.plot_leads_voltage_zoom(u_hts_odd_dfs+u_hts_even_dfs, circuit_name, timestamp_fgc, source_timestamp_qds_df.loc[0, 'timestamp'], timestamp_ee_odd, timestamp_ee_even, signal='U_HTS')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false
   },
   "outputs": [],
   "source": [
    "rb_analysis.analyze_leads_voltage(u_res_odd_dfs+u_res_even_dfs, circuit_name, timestamp_fgc, timestamp_qps=source_timestamp_qds_df.loc[0, 'timestamp'], signal='U_RES', value_min=-0.1, value_max=0.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 9. Cooling of Energy Extraction resistance after 3 h from FPA\n",
    "\n",
    "*ANALYSIS*:\n",
    "- Checks if all 6 temperature signals are below 70 degC after 2 hours from the FPA\n",
    "\n",
    "*PLOT*:\n",
    "\n",
    "- Temperature signals on the left axis, T_RES_BODY;\n",
    "- Temperature status on the right axis (1 - temperature exceeds the safe limit, 0 - temperature in the safe limit), ST_RES_OVERTEMP;\n",
    "- t = 0 s corresponds to FGC PM timestamp;\n",
    "- Green box denotes range of temperature check. The temperature should be below 70 degC after 2 hours from the FPA;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "unix_time_now = Time.to_unix_timestamp(Time.now())\n",
    "time_diff = (unix_time_now - timestamp_fgc)*1e-9\n",
    "\n",
    "if t_res_body_long_dfs and st_res_overtemp_long_dfs:\n",
    "    st_res_overtemp_long_dfs = [st_res_overtemp_long_df.astype(int) for st_res_overtemp_long_df in st_res_overtemp_long_dfs]\n",
    "    rb_analysis.analyze_ee_temp_and_cooling(t_res_body_long_dfs, st_res_overtemp_long_dfs, t_greater=2*3600, value_max=70)\n",
    "elif time_diff > 3*3600:\n",
    "    t_res_body_long_dfs = rb_query.query_ee_nxcals(timestamp_fgc, system='EE_ODD', signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], spark=spark) \\\n",
    "                        + rb_query.query_ee_nxcals(timestamp_fgc, system='EE_EVEN', signal_names=['T_RES_BODY_1', 'T_RES_BODY_2', 'T_RES_BODY_3'], spark=spark)\n",
    "    st_res_overtemp_long_dfs = rb_query.query_ee_nxcals(timestamp_fgc, system='EE_ODD', signal_names='ST_RES_OVERTEMP', spark=spark, t_thr=0) \\\n",
    "                            + rb_query.query_ee_nxcals(timestamp_fgc, system='EE_EVEN', signal_names='ST_RES_OVERTEMP', spark=spark, t_thr=0)\n",
    "    st_res_overtemp_long_dfs = [st_res_overtemp_long_df.astype(int) for st_res_overtemp_long_df in st_res_overtemp_long_dfs]\n",
    "    rb_analysis.analyze_ee_temp_and_cooling(t_res_body_long_dfs, st_res_overtemp_long_dfs, t_greater=2*3600, value_max=70)\n",
    "else:\n",
    "    print('Wait {} seconds to query EE temperature and status signals'.format(3*3600 - time_diff))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false
   },
   "outputs": [],
   "source": [
    "if not fgc_pm_search.is_automatic_mode():\n",
    "    rb_analysis.results_table['FPA Reason'] = get_expert_decision('Reason for FPA: ', ['QPS trip', 'Converter trip', 'EE spurious opening', 'Spurious heater firing', 'Busbar quench', 'Magnet quench', 'HTS current lead quench' ,'RES current lead overvoltage', 'No quench', 'Unknown'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "\n",
    "# 10. Analysis General Comment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false
   },
   "outputs": [],
   "source": [
    "if not fgc_pm_search.is_automatic_mode():\n",
    "    rb_analysis.results_table['Comment'] = input('Comment: ')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": false
   },
   "source": [
    "# 11. Final Report"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "deletable": false
   },
   "outputs": [],
   "source": [
    "# pd.set_option('display.max_columns', None)\n",
    "pd.set_option('display.max_rows', None)\n",
    "analysis_start_time = Time.get_analysis_start_time()\n",
    "date_time_fgc = Time.to_datetime(timestamp_fgc).strftime(\"%Y-%m-%d-%Hh%M\")\n",
    "!mkdir -p /eos/project/m/mp3/RB/$circuit_name/FPA\n",
    "\n",
    "file_name = \"{}_FPA-{}-{}\".format(circuit_name, date_time_fgc, analysis_start_time)\n",
    "full_path = '/eos/project/m/mp3/RB/{}/FPA/{}.csv'.format(circuit_name, file_name)\n",
    "\n",
    "mp3_results_table = rb_analysis.create_mp3_results_table(min(timestamp_pic), timestamp_fgc)\n",
    "display(HTML(mp3_results_table.T.to_html()))\n",
    "mp3_results_table.to_csv(full_path, index=False)\n",
    "print('MP3 results table saved to (Windows): ' + '\\\\\\\\cernbox-smb' + full_path.replace('/', '\\\\'))\n",
    "\n",
    "apply_report_template()\n",
    "file_name_html = file_name + '.html'\n",
    "full_path = '/eos/project/m/mp3/RB/{}/FPA/{}'.format(circuit_name, 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_FPA.ipynb' --output /eos/project/m/mp3/RB/$circuit_name/FPA/$file_name_html --TemplateExporter.exclude_input=True --TagRemovePreprocessor.remove_all_outputs_tags='[\"skip_output\"]' --TagRemovePreprocessor.remove_cell_tags='[\"skip_cell\"]'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Edit 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": [
    "NXCALS",
    "SparkMetrics"
   ],
   "list_of_options": []
  },
  "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": {
    "height": "837px",
    "left": "1331px",
    "top": "113.453125px",
    "width": "384px"
   },
   "toc_section_display": false,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}