Commit 34103671 authored by Aleksandra Mnich's avatar Aleksandra Mnich
Browse files

Merge branch 'dev' into 'master'

Release 1.5.21

See merge request !154
parents 30e8e4d1 cf5de71e
Pipeline #4143770 failed with stages
in 13 minutes and 50 seconds
......@@ -2,6 +2,9 @@ include:
- project: acc-co/devops/python/acc-py-devtools
file: acc_py_devtools/templates/gitlab-ci/python.yml
default:
image: registry.cern.ch/docker.io/library/python:3.8
variables:
test_folder: test
project_name: lhcsmapi
......@@ -20,7 +23,6 @@ doc:
MKDOCS_VERSION: '1.2.1'
MATERIAL_VERSION: '7.1.10'
I18NSTATIC_VERSION: '0.17'
image: registry.cern.ch/docker.io/library/python:3.7
stage: build
script:
- pip install --upgrade pip setuptools wheel
......@@ -40,7 +42,6 @@ doc:
- tags
pages:
image: registry.cern.ch/docker.io/library/python:3.7
stage: pages
script:
- mv doc/ public/
......@@ -52,7 +53,6 @@ pages:
- tags
doctest:
image: registry.cern.ch/docker.io/library/python:3.7
stage: syntax_check_test_dev
extends: .acc_py_dev_test
artifacts:
......@@ -67,6 +67,7 @@ doctest:
test_dev:
stage: syntax_check_test_dev
extends: .acc_py_dev_test
image: registry.cern.ch/docker.io/library/python:3.8
artifacts:
untracked: true
paths:
......@@ -75,11 +76,11 @@ test_dev:
script:
- apt-get -y update
- apt install -y openjdk-11-jdk
- pip install -r test-requirements.txt
- pytest ${project_root}/${test_folder} --cov=${project_name} --junitxml=report.xml
- pytest --cov-report xml:coverage-reports/coverage-lhcsmapi.xml --cov=${project_name} ${project_root}/${test_folder}
type_checking:
image: registry.cern.ch/docker.io/library/python:3.7
stage: syntax_check_test_dev
script:
- pip3 install mypy
......@@ -94,7 +95,6 @@ sonar:
deploy_production:
# Deploy package
image: registry.cern.ch/docker.io/library/python:3.7
stage: deploy
script:
- pip install twine
......
RELEASE NOTES
=============
Version: 1.5.21
- `cern` prefix removed from the nxcals imports: [SIGMON-307](https://its.cern.ch/jira/browse/SIGMON-307)
- separate class to resolve signal metadata: [SIGMON-297](https://its.cern.ch/jira/browse/SIGMON-297)
- QPS thresholds added: [SIGMON-48](https://its.cern.ch/jira/browse/SIGMON-48)
- list of the HWC_Operation_YETS updated
- signal_metadata package refactored (previously SignalMetadata): [SIGMON-309](https://its.cern.ch/jira/browse/SIGMON-309)
- use python 3.8 on GitLab: [SIGMON-282](https://its.cern.ch/jira/browse/SIGMON-282)
Version: 1.5.20
- package data (metadata files) correctly included in the `lhcsmapi`: [SIGMON-312](https://its.cern.ch/jira/browse/SIGMON-312)
- new, lightweight api to query Nxcals: [SIGMON-294](https://its.cern.ch/jira/browse/SIGMON-294)
......
......@@ -1036,7 +1036,7 @@
}
],
"source": [
"from lhcsmapi.metadata.SignalMetadata import SignalMetadata\n",
"from lhcsmapi.metadata import signal_metadata\n",
"\n",
"SignalMetadata.get_beam_mode_details()"
]
......@@ -2,7 +2,7 @@ from pathlib import Path
from typing import Union
name = "lhcsmapi"
__version__ = "1.5.20"
__version__ = "1.5.21"
nb_version_env = "NOTEBOOKS_VERSION"
......
......@@ -9,7 +9,7 @@ from lhcsmapi.analysis.pc.PcQuery import PcQuery
from lhcsmapi.analysis.pic.PicQuery import PicQuery
from lhcsmapi.analysis.qds.QdsQuery import QdsIpdQuery
from lhcsmapi.analysis.qh.QuenchHeaterQuery import QuenchHeaterQuery
from lhcsmapi.metadata.SignalMetadata import SignalMetadata
from lhcsmapi.metadata import signal_metadata
from lhcsmapi import reference
......@@ -20,7 +20,7 @@ class IpdCircuitQuery(PicQuery, PcQuery, QdsIpdQuery, QuenchHeaterQuery, BusbarR
def __init__(self, circuit_type, circuit_name, max_executions=None, verbose=True):
super().__init__(circuit_type, circuit_name, max_executions, verbose)
self.circuit_type = SignalMetadata.get_circuit_type_for_circuit_name(circuit_name)
self.circuit_type = signal_metadata.get_circuit_type_for_circuit_name(circuit_name)
def create_report_analysis_template(self, timestamp_fgc: int, init_file_path: str, author='') -> pd.DataFrame:
""" Method creating a report analysis template for IPD circuits
......
......@@ -12,7 +12,7 @@ from lhcsmapi.analysis.dfb.DfbAnalysis import DfbAnalysis
from lhcsmapi.analysis.pc.PcAnalysis import PcAnalysis
from lhcsmapi.analysis.qds.QdsAnalysis import QdsAnalysis
from lhcsmapi.analysis.qh.QuenchHeaterVoltageAnalysis import QuenchHeaterVoltageAnalysis
from lhcsmapi.metadata.SignalMetadata import SignalMetadata
from lhcsmapi.metadata import signal_metadata
from lhcsmapi.pyedsl.PlotBuilder import PlotBuilder, create_title
from lhcsmapi import reference
......@@ -24,7 +24,7 @@ class IpqCircuitAnalysis(DfbAnalysis, PcAnalysis, QdsAnalysis, QuenchHeaterVolta
"""
def __init__(self, circuit_type, results_table, *, is_automatic=True, colormap='default', circuit_name):
super().__init__(circuit_type, results_table, is_automatic, colormap)
self.circuit_type = SignalMetadata.get_circuit_type_for_circuit_name(circuit_name)
self.circuit_type = signal_metadata.get_circuit_type_for_circuit_name(circuit_name)
# Timestamp table
def create_timestamp_table(self,
......
......@@ -10,7 +10,7 @@ from lhcsmapi.analysis.qds.QdsQuery import QdsIpdQuery
from lhcsmapi.analysis.qh.QuenchHeaterQuery import QuenchHeaterQuery
from lhcsmapi.analysis.CircuitQuery import CircuitQuery
from lhcsmapi.metadata.MappingMetadata import MappingMetadata
from lhcsmapi.metadata.SignalMetadata import SignalMetadata
from lhcsmapi.metadata import signal_metadata
from lhcsmapi import reference
......@@ -23,7 +23,7 @@ class IpqCircuitQuery(PicQuery, PcItQuery, QuenchHeaterQuery, QdsIpdQuery, DfbQu
def __init__(self, circuit_type, circuit_name, max_executions=None, verbose=True):
super().__init__(circuit_type, circuit_name, max_executions, verbose)
self.circuit_type = SignalMetadata.get_circuit_type_for_circuit_name(circuit_name)
self.circuit_type = signal_metadata.get_circuit_type_for_circuit_name(circuit_name)
@staticmethod
def get_circuit_name_to_earth_measurement_dataframe(circuit_type: str, circuit_name: str) -> pd.DataFrame:
......
......@@ -11,7 +11,7 @@ from lhcsmapi.analysis.dfb.DfbAnalysis import DfbAnalysis
from lhcsmapi.analysis.pc.PcAnalysis import PcAnalysis
from lhcsmapi.analysis.qds.QdsAnalysis import QdsAnalysis
from lhcsmapi.analysis.warnings import warning_on_one_line
from lhcsmapi.metadata.SignalMetadata import SignalMetadata
from lhcsmapi.metadata import signal_metadata
from lhcsmapi.pyedsl.PlotBuilder import PlotBuilder, create_title
from lhcsmapi import reference
import lhcsmapi.signal.features as signal_analysis
......@@ -83,7 +83,6 @@ class R600ACircuitAnalysis(PcAnalysis, QdsAnalysis, DfbAnalysis, CircuitAnalysis
:type circuit_name: str
"""
super().create_timestamp_table(timestamp_dct)
if 'RCD' in circuit_name:
timestamp_check(timestamp_dct, qds_a_name='QDS_A_RCD', qds_b_name='QDS_B_RCD', fgc_ee_name='FGC_RCD')
timestamp_check(timestamp_dct, qds_a_name='QDS_A_RCO', qds_b_name='QDS_B_RCO', fgc_ee_name='FGC_RCO')
......@@ -93,7 +92,7 @@ class R600ACircuitAnalysis(PcAnalysis, QdsAnalysis, DfbAnalysis, CircuitAnalysis
else:
timestamp_check(timestamp_dct, qds_a_name='QDS_A', qds_b_name='QDS_B', fgc_ee_name='FGC')
timestamp = list(timestamp_dct.values())[0] if timestamp_dct else None
if 'EE' in SignalMetadata.get_system_types_per_circuit_name(self.circuit_type, circuit_name, timestamp):
if 'EE' in signal_metadata.get_system_types_per_circuit_name(self.circuit_type, circuit_name, timestamp):
timestamp_check(timestamp_dct, qds_a_name='QDS_A', qds_b_name='QDS_B', fgc_ee_name='EE')
# PC
......
......@@ -70,7 +70,7 @@ class R600ACircuitQuery(PicQuery, PcQuery, EeQuery, QdsQuery, DfbQuery, CircuitQ
results_table = pd.DataFrame(columns=columns, index=[0])
# Assumes that circuit_names[0] is always RCD
results_table['Circuit Name'] = circuit_names[0].replace('RCD', 'RCD-RCO')
results_table['Circuit Family'] = 'RCD-RCO'
results_table['Circuit Family'] = 'RCD'
timestamp_fgc = min_nan(timestamp_fgc_rcd, timestamp_fgc_rco)
results_table['Period'] = reference.get_mp3_period(timestamp_fgc)
......
......@@ -6,7 +6,7 @@ from tqdm.notebook import tqdm
from lhcsmapi.Time import Time
from lhcsmapi.metadata.MappingMetadata import MappingMetadata
from lhcsmapi.metadata.SignalMetadata import SignalMetadata
from lhcsmapi.metadata import signal_metadata
def show_schematic(circuit_type: str,
......@@ -56,7 +56,7 @@ def show_schematic(circuit_type: str,
pc_df = pd.DataFrame({
'name': {
0: SignalMetadata.get_circuit_name_metadata(circuit_type, circuit_name)['PC']['%PC%']
0: signal_metadata.get_pc_names(circuit_type, circuit_name, timestamp_fgc)[0]
},
'timestamp': {
0: Time.to_string_short(timestamp_fgc)
......
......@@ -7,6 +7,9 @@ import pandas as pd
from IPython.display import display, HTML
from ipywidgets import Output
import lhcsmapi.analysis.features_helper as utility_features
import lhcsmapi.signal.features as signal_analysis
import lhcsmapi.signal.functions as signal_analysis_functions
from lhcsmapi.Time import Time
from lhcsmapi.analysis import comparison
from lhcsmapi.analysis.CircuitAnalysis import CircuitAnalysis
......@@ -14,9 +17,6 @@ from lhcsmapi.analysis.decorators import check_dataframe_empty, check_nan_timest
from lhcsmapi.pyedsl import SignalTransformationBuilder
from lhcsmapi.pyedsl.AssertionBuilder import AssertionBuilder
from lhcsmapi.pyedsl.PlotBuilder import create_title, convert_plot_features_map_to_text, PlotBuilder
import lhcsmapi.signal.features as signal_analysis
import lhcsmapi.signal.functions as signal_analysis_functions
import lhcsmapi.analysis.features_helper as utility_features
class PcAnalysis(CircuitAnalysis):
......@@ -37,11 +37,7 @@ class PcAnalysis(CircuitAnalysis):
:param title: plot title
:return: None
"""
PlotBuilder().with_signal(i_meas_df, title=title, grid=True) \
.with_ylabel(ylabel='I, [A]') \
.with_xlim(lim=xlim) \
.with_ylim(lim=ylim) \
.plot()
_plot_i_dfs(i_meas_df, title, None, None, xlim, ylim)
@staticmethod
@check_dataframe_empty(mode='any', warning='PC signals are empty, plot is skipped!')
......@@ -103,11 +99,12 @@ class PcAnalysis(CircuitAnalysis):
plt.show()
print('Analysis result')
if value_min < v_meas_at_assertion < value_max:
print('%s signal value at t = %f s (%.1f V) is within of the acceptance range [%.1f, %.1f] V.' %
(v_meas_df.columns[0], t_assertion, v_meas_at_assertion, value_min, value_max))
print(f'{v_meas_df.columns[0]} signal value at t = {t_assertion:.6f} s ({v_meas_at_assertion[0]:.1f} V) '
f'is within of the acceptance range [{value_min:.1f}, {value_max:.1f}] V.')
else:
warnings.warn('%s signal value at t = %f s (%.1f V) is outside of the acceptance range [%.1f, %.1f] V.' %
(v_meas_df.columns[0], t_assertion, v_meas_at_assertion, value_min, value_max))
warnings.warn(
f'{v_meas_df.columns[0]} signal value at t = {t_assertion:.6f} s ({v_meas_at_assertion[0]:.1f} V) is '
f'outside of the acceptance range [{value_min:.1f}, {value_max:.1f}] V.')
@check_dataframe_empty(mode='all', warning='PC signals are empty, plot is skipped!')
def plot_i_meas_pc(self, circuit_name: str, timestamp_fgc: int, i_dfs, xlim=(np.nan, np.nan),
......@@ -140,25 +137,13 @@ class PcAnalysis(CircuitAnalysis):
i_dfs = list(filter(has_data, i_dfs))
i_meas_dfs = [i_df for i_df in i_dfs if ('I_MEAS' in i_df.columns[0])]
i_a_dfs = [i_df for i_df in i_dfs if ('I_A' in i_df.columns[0])]
i_ref_dfs = [i_df for i_df in i_dfs if ('I_REF' in i_df.columns[0])]
i_meas_dfs, i_a_dfs, i_ref_dfs = _split_i_dataframes(i_dfs)
color = _get_color(i_meas_dfs, i_a_dfs, i_ref_dfs)
len_i_meas, len_i_ref, len_i_a = len(i_meas_dfs), len(i_ref_dfs), len(i_a_dfs)
color_i_meas = ['C%d' % i for i in range(len_i_meas)]
color_i_ref = ['C%d' % i for i in range(len_i_ref)]
color_i_a = ['C%d' % i for i in range(max(len_i_meas, len_i_ref), max(len_i_meas, len_i_ref) + len_i_a)]
color = color_i_meas + color_i_ref + color_i_a
marker = [None] * len_i_meas + ['x'] * len_i_ref + [None] * len_i_a
# Global view
PlotBuilder().with_signal(i_meas_dfs + i_ref_dfs + i_a_dfs, title=title, color=color, marker=marker, grid=True) \
.with_ylabel(ylabel='I, [A]') \
.with_xlim(lim=xlim) \
.with_ylim(lim=ylim) \
.plot()
_plot_i_dfs(i_meas_dfs + i_ref_dfs + i_a_dfs, title, color, marker, xlim, ylim)
@staticmethod
@check_dataframe_empty(mode='any', warning='PC signals are empty, plot is skipped!')
......@@ -182,17 +167,9 @@ class PcAnalysis(CircuitAnalysis):
title = create_title(circuit_name, timestamp_fgc, 'I_MEAS, I_A, I_REF')
i_meas_dfs = [i_df for i_df in i_dfs if ('I_MEAS' in i_df.columns[0])]
i_a_dfs = [i_df for i_df in i_dfs if ('I_A' in i_df.columns[0])]
i_ref_dfs = [i_df for i_df in i_dfs if ('I_REF' in i_df.columns[0])]
i_meas_dfs, i_a_dfs, i_ref_dfs = _split_i_dataframes(i_dfs)
color = _get_color(i_meas_dfs, i_a_dfs, i_ref_dfs)
len_i_meas, len_i_ref, len_i_a = len(i_meas_dfs), len(i_ref_dfs), len(i_a_dfs)
color_i_meas = ['C%d' % i for i in range(len_i_meas)]
color_i_ref = ['C%d' % i for i in range(len_i_ref)]
color_i_a = ['C%d' % i for i in range(max(len_i_meas, len_i_ref), max(len_i_meas, len_i_ref) + len_i_a)]
color = color_i_meas + color_i_ref + color_i_a
marker = ['o'] * len_i_meas + ['x'] * len_i_ref + ['s'] * len_i_a
fig, ax = plt.subplots(figsize=(13, 6.5))
......@@ -212,16 +189,16 @@ class PcAnalysis(CircuitAnalysis):
display(out)
with out:
print('Our algorithm estimated %.3f s as start of the quench. \n'
'Press right button on a mouse on the figure above to adjust the quench start.' % t_quench,
end='\r')
print(
f'Our algorithm estimated {t_quench:.3f} s as start of the quench. \n'
f'Press right button on a mouse on the figure above to adjust the quench start.',
end='\r')
t_quench_correction = [[t_quench, False]]
def onclick(event):
if event.button == 3:
x = event.xdata
y = event.ydata
ylim = ax2.get_ylim()
xlim = ax2.get_xlim()
ax2.clear()
......@@ -233,9 +210,10 @@ class PcAnalysis(CircuitAnalysis):
t_quench_correction.append([x, True])
with out:
print('Expert selected %.3f s as start of the quench. '
'This value will be used for further computation.' % x,
end='\r')
print(
f'Expert selected {x:.3f} s as start of the quench. '
f'This value will be used for further computation.',
end='\r')
# plot cursor
ax2 = ax.twinx()
......@@ -252,16 +230,16 @@ class PcAnalysis(CircuitAnalysis):
def choose_quench_time_from_auto_or_manual(t_quench_correction) -> float:
if t_quench_correction is None:
t_quench = 0.0
print('Automatically computed quench start %.3f s is used for further computation '
'(e.g., quench current, MIIts).' % t_quench)
print(f'Automatically computed quench start {t_quench:.3f} s is used for further computation '
f'(e.g., quench current, MIIts).')
elif len(t_quench_correction) == 1:
t_quench = t_quench_correction[0][0]
print('Automatically computed quench start %.3f s is used for further computation '
'(e.g., quench current, MIIts).' % t_quench)
print(f'Automatically computed quench start {t_quench:.3f} s is used for further computation '
f'(e.g., quench current, MIIts).')
else:
t_quench = t_quench_correction[-1][0]
print('Manually adjusted quench start %.3f s is used for further computation '
'(e.g., quench current, MIIts).' % t_quench)
print(f'Manually adjusted quench start {t_quench:.3f} s is used for further computation '
f'(e.g., quench current, MIIts).')
return t_quench
......@@ -305,28 +283,15 @@ class PcAnalysis(CircuitAnalysis):
:param ylim: limits of the y-axis
:type ylim: Tuple[float]
"""
i_meas_dfs = [i_df for i_df in i_dfs if ('I_MEAS' in i_df.columns[0])]
i_a_dfs = [i_df for i_df in i_dfs if ('I_A' in i_df.columns[0])]
i_ref_dfs = [i_df for i_df in i_dfs if ('I_REF' in i_df.columns[0])]
title = create_title(circuit_name, timestamp_fgc, 'I_MEAS, I_A, I_REF')
i_meas_dfs, i_a_dfs, i_ref_dfs = _split_i_dataframes(i_dfs)
color = _get_color(i_meas_dfs, i_a_dfs, i_ref_dfs)
len_i_meas, len_i_ref, len_i_a = len(i_meas_dfs), len(i_ref_dfs), len(i_a_dfs)
color_i_meas = ['C%d' % i for i in range(len_i_meas)]
color_i_ref = ['C%d' % i for i in range(len_i_ref)]
color_i_a = ['C%d' % i for i in range(max(len_i_meas, len_i_ref), max(len_i_meas, len_i_ref) + len_i_a)]
color = color_i_meas + color_i_ref + color_i_a
marker = [None] * len_i_meas + ['x'] * len_i_ref + [None] * len_i_a
# Global view
PlotBuilder() \
.with_signal(i_meas_dfs + i_ref_dfs + i_a_dfs, title=title, color=color, marker=marker, grid=True) \
.with_ylabel(ylabel='I, [A]') \
.with_xlim(lim=xlim) \
.with_ylim(lim=ylim) \
.plot()
_plot_i_dfs(i_meas_dfs + i_ref_dfs + i_a_dfs, title, color, marker, xlim, ylim)
@check_dataframe_empty(mode='any', warning='PC signals are empty, zoomed plot is skipped!')
def plot_i_meas_pc_zoom(self,
......@@ -369,17 +334,9 @@ class PcAnalysis(CircuitAnalysis):
mid = max(mid, i_df[i_df.index == i_df.index[idx]].values[0][0])
ylim = [mid - 10, mid + 10]
i_meas_dfs = [i_df for i_df in i_dfs if ('I_MEAS' in i_df.columns[0])]
i_a_dfs = [i_df for i_df in i_dfs if ('I_A' in i_df.columns[0])]
i_ref_dfs = [i_df for i_df in i_dfs if ('I_REF' in i_df.columns[0])]
i_meas_dfs, i_a_dfs, i_ref_dfs = _split_i_dataframes(i_dfs)
color = _get_color(i_meas_dfs, i_a_dfs, i_ref_dfs)
len_i_meas, len_i_ref, len_i_a = len(i_meas_dfs), len(i_ref_dfs), len(i_a_dfs)
color_i_meas = ['C%d' % i for i in range(len_i_meas)]
color_i_ref = ['C%d' % i for i in range(len_i_ref)]
color_i_a = ['C%d' % i for i in range(max(len_i_meas, len_i_ref), max(len_i_meas, len_i_ref) + len_i_a)]
color = color_i_meas + color_i_ref + color_i_a
marker = [None] * len_i_meas + ['x'] * len_i_ref + [None] * len_i_a
# Global view
......@@ -432,8 +389,8 @@ class PcAnalysis(CircuitAnalysis):
i_meas_df_der = i_meas_df[i_meas_df.index < 0]
last_di_dt, last_di_dt_duration = SignalTransformationBuilder.calculate_last_const_di_dt(i_meas_df_der)
print('Last di/dt prior to an FPA is %f A/s.' % last_di_dt)
print('Duration of the last di/dt prior to an FPA is %f s (as seen in the PM buffer).' % last_di_dt_duration)
print(f'Last di/dt prior to an FPA is {last_di_dt:.6f} A/s.')
print(f'Duration of the last di/dt prior to an FPA is {last_di_dt_duration:.6f} s (as seen in the PM buffer).')
# Store analysis result
if self.results_table is not None:
if abs(last_di_dt) > 0.1:
......@@ -461,8 +418,8 @@ class PcAnalysis(CircuitAnalysis):
i_meas_pos_df = i_meas_df[i_meas_df.index >= t_quench]
miits_i_meas = signal_analysis.calculate_features(i_meas_pos_df, signal_analysis_functions.miits)
print('%s is %s MA^2s from t_1 = %f s (quench detection) to t_2 = %f s (end of PM buffer).' %
(col_name, miits_i_meas, i_meas_pos_df.index[0], i_meas_pos_df.index[-1]))
print(f'{col_name} is {miits_i_meas} MA^2s from t_1 = {i_meas_pos_df.index[0]:.6f} s (quench detection) '
f'to t_2 = {i_meas_pos_df.index[-1]:.6f} s (end of PM buffer).')
# Store analysis result
if self.results_table is not None:
......@@ -496,8 +453,8 @@ class PcAnalysis(CircuitAnalysis):
i_df = i_meas_abs_pos_df
miits_i_meas = signal_analysis.calculate_features(i_df, signal_analysis_functions.miits)
print('%s is %s MA^2s from t_1 = %f s (quench detection) to t_2 = %f s (end of PM buffer).' %
(col_name, miits_i_meas, i_df.index[0], i_df.index[-1]))
print(f'{col_name} is {miits_i_meas} MA^2s from t_1 = {i_df.index[0]:.6f} s (quench detection) '
f'to t_2 = {i_df.index[-1]:.6f} s (end of PM buffer).')
# Store analysis result
if self.results_table is not None:
......@@ -519,7 +476,7 @@ class PcAnalysis(CircuitAnalysis):
i_earth_unbiased = 1000 * i_earth_df - i_earth_median
i_earth_max_unbiased = signal_analysis.calculate_features(i_earth_unbiased, utility_features.max_abs)
print('The maximum unbiased abs(I_EARTH) is %s mA.' % (round(i_earth_max_unbiased, 2)))
print(f'The maximum unbiased abs(I_EARTH) is {i_earth_max_unbiased:.2f} mA.')
# Store analysis result
if self.results_table is not None:
......@@ -575,11 +532,12 @@ class PcAnalysis(CircuitAnalysis):
:type col_name: str
"""
i_meas_pos_df = i_meas_df[i_meas_df.index >= t_quench]
print('%s is %s A.' % (col_name, round(i_meas_pos_df.iloc[0].values[0], 1)))
quench_current = round(i_meas_pos_df.iloc[0].values[0], 1)
print(f'{col_name} is {quench_current} A.')
# Store analysis result
if self.results_table is not None:
self.results_table[col_name] = round(i_meas_pos_df.iloc[0].values[0], 1)
self.results_table[col_name] = quench_current
@staticmethod
@check_dataframe_empty(mode='any', warning='I_A_REF, I_A signals are empty, t_quench calculation skipped!')
......@@ -616,8 +574,7 @@ class PcAnalysis(CircuitAnalysis):
mask = (diff_df.index > t_i_ref_max) & (diff_df.index < 0) & (diff_df.values > max_diff)
if diff_df[mask].empty:
return 0.0
else:
return diff_df[mask].idxmin()
return diff_df[mask].idxmin()
@staticmethod
def estimate_quench_start_from_i_ref(i_ref_df: pd.DataFrame) -> float:
......@@ -660,8 +617,8 @@ class Pc13kAAnalysis(PcAnalysis):
"""
# Plot
title = '{} {}: I_MEAS(t) and I_MEAS(t)/dI_MEAS(t) (Reference)\n'. \
format(Time.to_string_short(timestamp_fgc), circuit_name)
title = f'{Time.to_string_short(timestamp_fgc)} {circuit_name}: I_MEAS(t) and I_MEAS(t)/dI_MEAS(t) ' \
f'(Reference)\n'
tau_i_meas_df = SignalTransformationBuilder.calculate_char_time_profile(i_meas_df)
tau_i_meas_ref_df = SignalTransformationBuilder.calculate_char_time_profile(i_meas_ref_df)
......@@ -744,7 +701,7 @@ class Pc13kAAnalysis(PcAnalysis):
i_meas_discharge_dt_dt_df = i_meas_discharge_dt_df.rolling(window) \
.apply(lambda x: (x[window - 1] - x[0]) / dt, raw=True)
signal_name = i_meas_discharge_df.columns[0]
i_meas_discharge_dt_dt_df.rename(columns={signal_name: 'd%s/dt^2' % signal_name}, inplace=True)
i_meas_discharge_dt_dt_df.rename(columns={signal_name: f'd{signal_name}/dt^2'}, inplace=True)
AssertionBuilder().with_signal([i_meas_discharge_dt_dt_df]) \
.has_min_max_value(value_min=value_min, value_max=value_max) \
......@@ -770,7 +727,7 @@ class Pc13kAAnalysis(PcAnalysis):
:return: None
"""
title = '{} {}: I_A and I_EARTH (Reference)'.format(Time.to_string_short(timestamp_fgc), circuit_name)
title = f'{Time.to_string_short(timestamp_fgc)} {circuit_name}: I_A and I_EARTH (Reference)'
PlotBuilder().with_signal(i_a_df, title=title, grid=True) \
.with_ylabel(ylabel='I_A, [A]') \
......@@ -814,14 +771,14 @@ class Pc13kAAnalysis(PcAnalysis):
:return: None
"""
title = '{} {}: I_MEAS and I_EARTH_PCNT (Reference)'.format(Time.to_string_short(timestamp_fgc), circuit_name)
title = f'{Time.to_string_short(timestamp_fgc)} {circuit_name}: I_MEAS and I_EARTH_PCNT (Reference)'
if scaling is None:
scaling = (i_meas_df.max() / i_meas_ref_df.max()).values[0]
PlotBuilder() \
.with_signal(i_meas_df, title=title, grid=True) \
.with_ylabel(ylabel='I_MEAS, [A]') \
.with_signal([i_earth_pcnt_df[i_earth_pcnt_df.index > start_point],
i_earth_pcnt_ref_df[i_earth_pcnt_ref_df.index > start_point] * scaling], yerr=[None, offset]) \
i_earth_pcnt_ref_df[i_earth_pcnt_ref_df.index > start_point] * scaling], yerr=[None, offset])\
.with_ylabel(ylabel='I_EARTH_PCNT, [%]') \
.with_legend(labels=['I_EARTH_PCNT', 'I_EARTH_PCNT (Reference)']) \
.with_xlim(xlim) \
......@@ -857,3 +814,26 @@ class Pc13kARqAnalysis(Pc13kAAnalysis):
super(Pc13kARqAnalysis,
Pc13kARqAnalysis).analyze_i_earth_pcnt_pc("RQ", circuit_name, timestamp_fgc, i_meas_df, i_meas_ref_df,
i_earth_pcnt_df, i_earth_pcnt_ref_df, xlim, start_point, offset)
def _split_i_dataframes(i_dfs):
i_meas_dfs = [i_df for i_df in i_dfs if 'I_MEAS' in i_df.columns[0]]
i_a_dfs = [i_df for i_df in i_dfs if 'I_A' in i_df.columns[0]]
i_ref_dfs = [i_df for i_df in i_dfs if 'I_REF' in i_df.columns[0]]
return i_meas_dfs, i_a_dfs, i_ref_dfs
def _get_color(i_meas_dfs, i_a_dfs, i_ref_dfs):
len_i_meas, len_i_ref, len_i_a = len(i_meas_dfs), len(i_ref_dfs), len(i_a_dfs)
color_i_meas = [f'C{i}' for i in range(len_i_meas)]
color_i_ref = [f'C{i}' for i in range(len_i_ref)]
color_i_a = [f'C{i}' for i in range(max(len_i_meas, len_i_ref), max(len_i_meas, len_i_ref) + len_i_a)]
return color_i_meas + color_i_ref + color_i_a
def _plot_i_dfs(dfs, title, color, marker, xlim, ylim):
PlotBuilder().with_signal(dfs, title=title, color=color, marker=marker, grid=True) \
.with_ylabel(ylabel='I, [A]') \
.with_xlim(lim=xlim) \
.with_ylim(lim=ylim) \
.plot()
......@@ -6,7 +6,7 @@ import pandas as pd
from lhcsmapi.analysis.CircuitQuery import CircuitQuery, execution_count
from lhcsmapi.analysis.decorators import check_nan_timestamp, check_nan_timestamp_signals
from lhcsmapi.metadata.SignalMetadata import SignalMetadata
from lhcsmapi.metadata import signal_metadata
from lhcsmapi.pyedsl.QueryBuilder import QueryBuilder
from lhcsmapi import reference
......@@ -179,11 +179,11 @@ class PcItQuery(PcQuery):
return [pd.DataFrame()] * len(signal_names)
# Get metadata
md_pc_pm = SignalMetadata.get_circuit_signal_database_metadata(self.circuit_type,
self.circuit_name,
'PC',
'PM',
timestamp_query=timestamp_fgc)
md_pc_pm = signal_metadata.get_signal_metadata(self.circuit_type,
self.circuit_name,
'PC',
'PM',
timestamp_fgc)
# Get signal names to query - using general-purpose query
if any([signal_name not in md_pc_pm for signal_name in signal_names]):
......
......@@ -7,7 +7,7 @@ from tqdm.notebook import tqdm
from lhcsmapi.Time import Time
from lhcsmapi.analysis.CircuitQuery import CircuitQuery, execution_count
from lhcsmapi.analysis.decorators import check_nan_timestamp_signals, check_nan_timestamp
from lhcsmapi.metadata.SignalMetadata import SignalMetadata
from lhcsmapi.metadata import signal_metadata
from lhcsmapi.pyedsl.QueryBuilder import QueryBuilder
......@@ -230,14 +230,15 @@ class QdsRbQuery(QdsQuery):
:return: table with iQPS board types (1, 0)