Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions sbndprmdaq/analysis/analysis_estimate.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,20 +324,20 @@ def _sanity_check(self):
Checks values are sensible
'''
if np.abs((self._max_a - self._baseline_a) / (self._baseline_rms_a)) < 5:
print('no_anode')
return 'no_anode'
print('no_anode, anode too small, ignoring')
# return 'no_anode'

if self._max_a < 0:
if self._max_a - self._baseline_a < 0:
print('no_anode')
return 'no_anode'
return 'anode is negative'

if np.abs((self._max_c - self._baseline_c) / (self._baseline_rms_a)) < 5:
print('no_cathode')
if np.abs((self._max_c - self._baseline_c) / (self._baseline_rms_c)) < 5:
print('no_cathode, cathode too small')
return 'no_cathode'

if self._max_c > 0:
if self._max_c - self._baseline_c > 0:
print('no_cathode')
return 'no_cathode'
return 'cathode is positive'

if self._deltat_c > 100:
print('cathode_deltat_large')
Expand Down
4 changes: 2 additions & 2 deletions sbndprmdaq/data_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def update_dataframe(self, measurement, prm_id):
'''
#pylint: disable=invalid-name

self._logger.warning('Updating dataframe.')
self._logger.info('Updating dataframe.')

if measurement is None:
self._logger.warning('No measurement available to save to dataframe.')
Expand Down Expand Up @@ -188,7 +188,7 @@ def update_dataframe(self, measurement, prm_id):

df = df.append(meas, ignore_index=True)

df.to_csv(dataframe_file_name)
df.to_csv(dataframe_file_name, index=False)

def get_dataframe_path(self):
'''
Expand Down
2 changes: 1 addition & 1 deletion sbndprmdaq/eclapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def __init__(self, url, user, password):
self._password = password
self._user = user

self._to = 10 # timeout in seconds
self._to = 60 # timeout in seconds


def generate_salt(self):
Expand Down
65 changes: 65 additions & 0 deletions sbndprmdaq/externals.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def pmt_hv_on():

voltages = []
for pv in pvs:
# print(pv, epics.caget(pv))
voltages.append(epics.caget(pv))

voltages = np.array(voltages)
Expand Down Expand Up @@ -177,3 +178,67 @@ def prm_covered(self, prm_id):
if float(formatted[0][1]) > 20:
return True
return False

def plc_on(self, prm_id):
'''
Returns True if the PrM PLC is ON (PrMs can operate)

Args:
prm_id (int): the PrM ID
'''

if self._connection is None:
self.connect()

if self._connection.status != psycopg2.extensions.STATUS_READY:
self.connect()

if prm_id == 3:
# Inline can always operate
return True
else:
pv = 'prm'


current_time = datetime.datetime.now()
this_month = current_time.month
month_2digit = str(this_month).zfill(2)

query = """SELECT d.tagid, COALESCE((d.intvalue::numeric)::text, (trunc(d.floatvalue::numeric,3))::text), d.t_stamp
FROM cryo_prd.sqlt_data_1_2024_{} d, cryo_prd.sqlth_te s
WHERE d.tagid=s.id
AND s.tagpath LIKE '%sbnd%'
AND s.tagpath LIKE '%{}%'
AND s.tagpath LIKE '%{}%'
ORDER BY d.t_stamp DESC
LIMIT {}""".format(month_2digit, '', pv, 1)

cursor = self._connection.cursor()

cursor.execute(query)

dbrows = cursor.fetchall()

cursor.close()

formatted = []
for row in dbrows:
try:
time = datetime.datetime.fromtimestamp(row[2]/1000) # ms since epoch
time = time.strftime("%Y-%m-%d %H:%M:%S")
except:
time = row[2]
formatted.append((row[0], row[1], row[2], time))


return int(formatted[0][1])



if __name__ == "__main__":

api = IgnitionAPI()

print(api.plc_on(prm_id=1))


8 changes: 8 additions & 0 deletions sbndprmdaq/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,14 @@ def _check_external_status(self):
self._prm_controls[2]._liquid_level_label.setDisabled(True)
self._prm_controls[2]._digitizer_image.setDisabled(True)

if self._config['check_plc']:
for prm_id in [1, 2, 3]:
if not self._ignition_api.plc_on(prm_id=prm_id):
self.inhibit_run(True, [prm_id])
else:
self.inhibit_run(False, [prm_id])



def inhibit_run(self, do_inhibit=True, prm_ids=(1, 2)):
'''
Expand Down
141 changes: 136 additions & 5 deletions sbndprmdaq/summary_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@
import time
import datetime
import xml.etree.ElementTree as ET
import requests

import pandas as pd
from PyQt5.QtCore import QTimer

import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from labellines import labelLine, labelLines
import numpy as np

from sbndprmdaq.eclapi import ECL, ECLEntry

Expand Down Expand Up @@ -105,9 +110,20 @@ def make_summary_plots(self):
# Read the dataframe
df = pd.read_csv(self._dataframe_filename)

# Add Qa/Qc ratio
df['qaqc'] = df['qa']/df['qc']

# Convert the date string to datetime object
df['date'] = pd.to_datetime(df['date'])

# Add a datetime index
df['datetime'] = pd.to_datetime(df['date'])
df = df.set_index('datetime')

# Drop old column
df = df.drop(['Unnamed: 0'], axis=1)


self._make_summary_plot(df)

self._number_of_runs(df, prm_ids=[1, 2, 3])
Expand Down Expand Up @@ -148,14 +164,15 @@ def _make_summary_plot(self, df):
mask = df['date'] > first_day
df_s = df[mask]

dfs[prm_id] = df_s.query(f'prm_id == {prm_id}')
dfs[prm_id] = df_s.query(f'prm_id == {prm_id} and qaqc > 0 and qaqc < 1')

timestr = time.strftime("%Y%m%d-%H%M%S")

self._current_plots = {}

events = {
datetime.datetime(2024, 3, 25, 15, 00): 'Lowered HV on PrM 2',
datetime.datetime(2024, 5, 26, 8, 50): 'Increased HV on PrM 2',
}

#
Expand All @@ -178,7 +195,7 @@ def _make_summary_plot(self, df):
ax.set_title('Preliminary', loc='right', color='gray')
ax.legend(fontsize=12, loc=2)

ax.set_ylim([0.050, 3.0])
ax.set_ylim([0.050, 8.0])

plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")

Expand Down Expand Up @@ -229,13 +246,116 @@ def _make_summary_plot(self, df):
self._logger.info(f'Plot saved to {filename}.')
self._current_plots[f'prm{prm_id}_qcqa'] = filename

#
# Qa/Qc Plot
#

for prm_id in self._config['prms']:

df_daily_mean = dfs[prm_id].resample('D').mean()
df_daily_std = dfs[prm_id].resample('D').std()

df_daily_mean['date'] = df_daily_mean.index
df_daily_std['date'] = df_daily_std.index

print(df_daily_mean)

_, ax = plt.subplots(ncols=1, nrows=1, figsize=(10, 8))

def qaqc(t, tau):
return np.exp(-t/tau)

date = np.array(dfs[prm_id]['date'])
qa = np.array(dfs[prm_id]['qa'])
qc = np.array(dfs[prm_id]['qc'])

mask = (qa != -1) & (qc != -1)

ax.plot(date[mask], qa[mask]/qc[mask], label=labels[prm_id],
linestyle='None', marker="o", markersize=5, color='green', alpha=0.5, zorder=1)

ax.errorbar(df_daily_mean['date'], df_daily_mean['qaqc'], yerr=df_daily_std['qaqc'],
label=labels[prm_id] + ' Daily Average', linestyle='None', marker="o", markersize=5, color='black', alpha=1, zorder=2)


ax.set_ylabel(r'$Q_A/Q_C$',fontsize=16)
ax.set_xlabel('Time',fontsize=16)
ax.tick_params(labelsize=12)
ax.grid(True)
ax.set_title('Preliminary', loc='right', color='gray')

today = datetime.date.today()
ax.axvline(today, color='red', label='Today', linestyle='solid')

if prm_id == 1:
d = datetime.datetime(2024, 6, 28, 17, 00)
num = mpl.dates.date2num(d)
xmin, xmax = ax.get_xlim()
frac = (num - xmin) / (xmax - xmin)

for i, tau in enumerate([0.50, 1, 3, 6, 9]):
ax.axhline(qaqc(1.1, tau),
xmin=0,
xmax=frac,
color='black', label=f'{tau:.2f} ms', linestyle=linestyles[i])

ax.axhline(qaqc(1.6, tau),
xmin=frac,
xmax=1,
color='black', linestyle=linestyles[i])
else:
d = datetime.datetime(2024, 3, 25, 15, 00)
num = mpl.dates.date2num(d)
xmin, xmax = ax.get_xlim()
frac = (num - xmin) / (xmax - xmin)

d = datetime.datetime(2024, 5, 26, 8, 50)
num = mpl.dates.date2num(d)
xmin, xmax = ax.get_xlim()
frac2 = (num - xmin) / (xmax - xmin)

for i, tau in enumerate([0.10, 1, 3, 6, 9]):
ax.axhline(qaqc(0.25, tau),
xmin=0,
xmax=frac,
color='black', label=f'{tau:.2f} ms', linestyle=linestyles[i])

ax.axhline(qaqc(0.39, tau),
xmin=frac,
xmax=frac2,
color='black', linestyle=linestyles[i])

ax.axhline(qaqc(0.25, tau),
xmin=frac2,
xmax=1,
color='black', linestyle=linestyles[i])

ax.set_title('Preliminary', loc='right', color='gray')

# labelLines(ax.get_lines())# , zorder=2.5)#, xvals=xvals)
ax.legend(fontsize=12, loc=2)
# for l in ax.get_lines():
# print('LINE:', l)
ax.set_ylim([0, 1.1])

plt.xticks(rotation=45, ha="right", rotation_mode="anchor")

plt.tight_layout()
if self._plot_savedir is not None:
filename = self._plot_savedir + f'prm{prm_id}_qa_over_qc_{timestr}.png'
plt.savefig(filename)
self._logger.info(f'Plot saved to {filename}.')
self._current_plots[f'prm{prm_id}_qa_over_qc'] = filename


# plt.show()


def _number_of_runs(self, df, prm_ids=(1, 2, 3)):

password = self._read_ecl_password()

# https://dbweb0.fnal.gov/ECL/sbnd
ecl = ECL(url='https://dbweb9.fnal.gov:8443/ECL/sbnd/E', user='sbndprm', password=password)

# Retrieve the last 20 entries
Expand All @@ -251,7 +371,11 @@ def _number_of_runs(self, df, prm_ids=(1, 2, 3)):

# Loop over entries (they are in decreasing order in time)
for entry in entries:
text = entry.find('./text').text

text = entry.find('./text')
if text is None:
continue
text = text.text

if 'Purity Monitors Automated Plots' in text:

Expand Down Expand Up @@ -308,7 +432,14 @@ def _send_to_ecl(self):
print(entry.show())

if self._config['post_to_ecl']:
ecl.post(entry, do_post=True)

try:
ecl.post(entry, do_post=True)
except:
self._logger.info('Post timeout. Trying one more time in 5 secs')
time.sleep(5)
ecl.post(entry, do_post=True)


def _read_ecl_password(self):

Expand Down
Loading