diff --git a/Makefile.in b/Makefile.in index cc16190b5ac7bb328d05dfcf0ded8d2bf623bc2a..749fa170cc860dbe2a5692e728dfbf7903021df9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -83,10 +83,25 @@ start: "echo narf" @tmux select-layout even-vertical + @# AHRS + @# + @tmux new-window -n ahrs -t ${SESSION_NAME} + @tmux split-window -v -t ${SESSION_NAME}:ahrs + @tmux send-keys -t ${SESSION_NAME}:ahrs.1 \ + "python scripts/ahrs_calibration.py -d ${DETECTOR_ID} -p ${MONITORING_LIGIER_PORT}" Enter + @tmux select-layout even-vertical + + @# Log.io + @# + @tmux new-window -n logio -t ${SESSION_NAME} + @tmux split-window -v -t ${SESSION_NAME}:logio + @tmux send-keys -t ${SESSION_NAME}:logio.1 \ + "python scripts/logio.py -p ${MONITORING_LIGIER_PORT} -x ${LOGIO_IP} -q ${LOGIO_PORT}" Enter + @tmux select-layout even-vertical stop: - killall gunicorn tmux kill-session -t ${SESSION_NAME} + killall gunicorn clean: rm Makefile diff --git a/README.md b/README.md index 0efa47c142be59cbdb9448ce35439388823ed477..559eee5d9c830cec3a111956616cb7590184cab9 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,21 @@ If you want to stop it: make stop easy. + +## Configuration file + +A file called `pipeline.toml` can be placed into the root folder of the +monitoring software (usually `~/monitoring`) which can be used to set +different kind of parameters, like plot attributes or ranges. +Here is an example `pipeline.toml`: + + [DOMRates] + lowest_rate = 200 + highest_rate = 400 + + [PMTRates] + lowest_rate = 1000 + highest_rate = 10000 + +After a `make stop` and `make start`, the file is parsed and the default +values are overwritten by those defined in the configuration file. diff --git a/app/routes.py b/app/routes.py index 1906dff473670dcbc373ccac283c1fd1c92ef473..3cf64f24ed70939d7d693d3125d4f8da52388e52 100644 --- a/app/routes.py +++ b/app/routes.py @@ -8,6 +8,9 @@ app.config['FREEZER_DESTINATION'] = '../km3web' PLOTS = [['dom_activity', 'dom_rates'], ['pmt_rates', 'pmt_hrv'], ['trigger_rates'], ['ztplot', 'triggermap']] +AHRS_PLOTS = [['yaw_calib'], ['pitch_calib'], ['roll_calib']] +TRIGGER_PLOTS = [['trigger_rates'], ['trigger_rates_lin']] + @app.after_request def add_header(r): @@ -27,6 +30,16 @@ def index(): return render_template('plots.html', plots=PLOTS) +@app.route('/ahrs.html') +def ahrs(): + return render_template('plots.html', plots=AHRS_PLOTS) + + +@app.route('/trigger.html') +def trigger(): + return render_template('plots.html', plots=TRIGGER_PLOTS) + + @app.route('/plots/<path:filename>') def custom_static(filename): print(filename) diff --git a/app/templates/base.html b/app/templates/base.html index f4e2f213d123aa8b6d2d5e6875f2d63286abdb14..54273262e27596753923f77c631c9dcf86aacb54 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -29,11 +29,17 @@ <ul class="nav navbar-nav"> <li class="active"><a href="index.html">Overview</a></li> </ul> + <!-- <ul class="nav navbar-nav"> --> + <!-- <li class="active"><a href="#">Intra DOM Calibration</a></li> --> + <!-- </ul> --> + <!-- <ul class="nav navbar-nav"> --> + <!-- <li class="active"><a href="#">K40 Rate Dist</a></li> --> + <!-- </ul> --> <ul class="nav navbar-nav"> - <li class="active"><a href="#">Intra DOM Calibration</a></li> + <li class="active"><a href="trigger.html">Trigger</a></li> </ul> <ul class="nav navbar-nav"> - <li class="active"><a href="#">K40 Rate Dist</a></li> + <li class="active"><a href="ahrs.html">AHRS</a></li> </ul> <ul class="nav navbar-nav"> <li class="active"><a href="https://git.km3net.de/km3py/km3mon/issues">Issues</a></li> diff --git a/configure b/configure index 1d292ff406e227bdbdbe091abea336e29893d157..0d95310c0986a4ecc3e620d704ca5fd291131de3 100755 --- a/configure +++ b/configure @@ -5,6 +5,8 @@ daq_ligier_ip="192.168.0.110" daq_ligier_port=5553 monitoring_ligier_ip="127.0.0.1" monitoring_ligier_port=5553 +logio_ip="127.0.0.1" +logio_port=28777 webserver_port=8080 tmux_session_name="km3mon" @@ -37,6 +39,14 @@ for arg in "$@"; do monitoring_ligier_port=`echo $arg | sed 's/--monitoring-ligier-port=//'` ;; + --logio-ip=*) + logio_ip=`echo $arg | sed 's/--logio-ip=//'` + ;; + + --logio-port=*) + logio_port=`echo $arg | sed 's/--logio-port=//'` + ;; + --tmux-session-name=*) tmux_session_name=`echo $arg | sed 's/--tmux-session-name=//'` ;; @@ -54,6 +64,8 @@ for arg in "$@"; do echo " --daq-ligier-ip DAQ Ligier ${daq_ligier_ip}" echo " --daq-ligier-port Port of the DAQ Ligier ${daq_ligier_port}" echo " --monitoring-ligier-port Port of the monitoring Ligier ${monitoring_ligier_port}" + echo " --logio-ip Log.io IP ${logio_ip}" + echo " --logio-port Port of the Log.io server ${logio_port}" echo " --tmux-session-name TMUX session name ${tmux_session_name}" echo " --webserver-port Port of the web server ${webserver_port}" echo @@ -67,6 +79,8 @@ echo "DETECTOR_ID = ${detector_id}" > Makefile echo "DAQ_LIGIER_IP = ${daq_ligier_ip}" >> Makefile echo "DAQ_LIGIER_PORT = ${daq_ligier_port}" >> Makefile echo "MONITORING_LIGIER_PORT = ${monitoring_ligier_port}" >> Makefile +echo "LOGIO_IP = ${logio_ip}" >> Makefile +echo "LOGIO_PORT = ${logio_port}" >> Makefile echo "WEBSERVER_PORT = ${webserver_port}" >> Makefile echo "SESSION_NAME = ${tmux_session_name}" >> Makefile @@ -76,6 +90,7 @@ show_km3mon_banner echo "Detector ID: ${detector_id}" echo "DAQ Ligier: ${daq_ligier_ip}:${daq_ligier_port}" echo "Monitoring Ligier: ${monitoring_ligier_ip}:${monitoring_ligier_port}" +echo "Log.io Server: ${logio_ip}:${logio_port}" echo "Webserver: 0.0.0.0:${webserver_port}" echo "TMUX session: ${tmux_session_name}" echo diff --git a/frontail.json b/frontail.json new file mode 100644 index 0000000000000000000000000000000000000000..24a32b74b587fb02636e7dc1fb382e56c539ce9e --- /dev/null +++ b/frontail.json @@ -0,0 +1,12 @@ +{ + "words": { + "ERROR": "color: #CC0C28;", + "STATUS": "color: #2F76CC;", + "DataFilter": "background-color: #138799; color: #ffffff", + "DataWriter": "background-color: #FFBE05; color: #000000", + "DataQueue": "background-color: #674591; color=: #ffffff" + }, + "lines": { + "ERROR": "font-weight: bold;" + } +} diff --git a/scripts/ahrs_calibration.py b/scripts/ahrs_calibration.py new file mode 100755 index 0000000000000000000000000000000000000000..db5faa365a8c6f1b53cf9686bce19d99ca71f17d --- /dev/null +++ b/scripts/ahrs_calibration.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python +# coding=utf-8 +# vim: ts=4 sw=4 et +""" +Runs the AHRS calibration online. + +Usage: + ahrs_calibration.py [options] + ahrs_calibration.py (-h | --help) + +Options: + -l LIGIER_IP The IP of the ligier [default: 127.0.0.1]. + -p LIGIER_PORT The port of the ligier [default: 5553]. + -d DET_ID Detector ID [default: 29]. + -o PLOT_DIR The directory to save the plot [default: plots]. + -h --help Show this screen. + +""" +from __future__ import division + +from datetime import datetime +from collections import deque, defaultdict +from functools import partial +import io +import os +import threading + +import numpy as np +import matplotlib +matplotlib.use('Agg') +import matplotlib.pyplot as plt +import matplotlib.dates as md +import seaborn as sns + +import km3pipe as kp +from km3pipe.io.daq import TMCHData +from km3modules.ahrs import fit_ahrs, get_latest_ahrs_calibration +import km3pipe.style +km3pipe.style.use('km3pipe') + + +class CalibrateAHRS(kp.Module): + def configure(self): + self.plots_path = self.require('plots_path') + det_id = self.require('det_id') + self.detector = kp.hardware.Detector(det_id=det_id) + self.du = self.get('du', default=1) + + self.clbmap = kp.db.CLBMap(det_oid=det_id) + + self.cuckoo = kp.time.Cuckoo(60, self.create_plot) + self.cuckoo_log = kp.time.Cuckoo(10, print) + self.data = {} + queue_size = 50000 + for ahrs_param in ('yaw', 'pitch', 'roll'): + self.data[ahrs_param] = defaultdict( + partial(deque, maxlen=queue_size)) + self.times = defaultdict(partial(deque, maxlen=queue_size)) + self.lock = threading.Lock() + self.index = 0 + + def process(self, blob): + self.index += 1 + if self.index % 29 != 0: + return blob + now = datetime.utcnow() + tmch_data = TMCHData(io.BytesIO(blob['CHData'])) + dom_id = tmch_data.dom_id + clb = self.clbmap.dom_id[dom_id] + if clb.floor == 0: + self.log.info("Skipping base CLB") + return blob + + if clb.du != self.du: + return blob + + yaw = tmch_data.yaw + calib = get_latest_ahrs_calibration(clb.upi, max_version=4) + + if calib is None: + return blob + + cyaw, cpitch, croll = fit_ahrs(tmch_data.A, tmch_data.H, *calib) + self.cuckoo_log("DU{}-DOM{} (random pick): calibrated yaw={}".format( + clb.du, clb.floor, cyaw)) + with self.lock: + self.data['yaw'][clb.floor].append(cyaw) + self.data['pitch'][clb.floor].append(cpitch) + self.data['roll'][clb.floor].append(croll) + self.times[clb.floor].append(now) + + self.cuckoo.msg() + return blob + + def create_plot(self): + print(self.__class__.__name__ + ": updating plot.") + # xfmt = md.DateFormatter('%Y-%m-%d %H:%M') + xfmt = md.DateFormatter('%H:%M') + for ahrs_param in self.data.keys(): + fig, ax = plt.subplots(figsize=(16, 6)) + sns.set_palette("husl", 18) + ax.set_title("AHRS {} Calibration on DU{}\n{}".format( + ahrs_param, self.du, datetime.utcnow())) + ax.set_xlabel("UTC time") + ax.xaxis.set_major_formatter(xfmt) + ax.set_ylabel(ahrs_param) + with self.lock: + for floor in sorted(self.data[ahrs_param].keys()): + ax.plot( + self.times[floor], + self.data[ahrs_param][floor], + marker='.', + linestyle='none', + label="Floor {}".format(floor)) + lgd = plt.legend( + bbox_to_anchor=(1.005, 1), loc=2, borderaxespad=0.) + fig.tight_layout() + plt.savefig( + os.path.join(self.plots_path, ahrs_param + '_calib.png'), + bbox_extra_artists=(lgd, ), + bbox_inches='tight') + plt.close('all') + + +def main(): + from docopt import docopt + args = docopt(__doc__) + + det_id = int(args['-d']) + plots_path = args['-o'] + ligier_ip = args['-l'] + ligier_port = int(args['-p']) + + pipe = kp.Pipeline() + pipe.attach( + kp.io.ch.CHPump, + host=ligier_ip, + port=ligier_port, + tags='IO_MONIT', + timeout=60 * 60 * 24 * 7, + max_queue=2000) + pipe.attach(kp.io.daq.DAQProcessor) + pipe.attach(CalibrateAHRS, det_id=det_id, plots_path=plots_path) + pipe.drain() + + +if __name__ == '__main__': + main() diff --git a/scripts/dom_activity.py b/scripts/dom_activity.py index 899ec61d9392876ef0dc5ba8586f0e1419017fc9..29e3c2e36e3b117779e819d53cd8f7f59ae2037f 100755 --- a/scripts/dom_activity.py +++ b/scripts/dom_activity.py @@ -91,7 +91,8 @@ class DOMActivityPlotter(kp.Module): self.detector, filename, 'last activity [s]', - "DOM Activity - via Summary Slices", + "DOM Activity for DetID-{} - via Summary Slices".format( + self.detector.det_id), vmin=0.0, vmax=15 * 60) diff --git a/scripts/dom_rates.py b/scripts/dom_rates.py index 8d2267f511871f3d4aa4ebae563c3087bfa76a59..91d1974a0a1fa502130fa4cdc8c7217c8b6a12ae 100755 --- a/scripts/dom_rates.py +++ b/scripts/dom_rates.py @@ -80,7 +80,7 @@ class DOMRates(kp.Module): self.detector, filename, 'rate [kHz]', - "DOM Rates", + "DOM Rates for DetID-{}".format(self.detector.det_id), vmin=self.lowest_rate, vmax=self.highest_rate, cmap='coolwarm', diff --git a/scripts/live_triggermap.py b/scripts/live_triggermap.py index 1fd198320e663636158cf048192d9ef9ffba4f0e..d50e9b463d226ae76c2d22a5854e7ec96322db35 100755 --- a/scripts/live_triggermap.py +++ b/scripts/live_triggermap.py @@ -125,9 +125,10 @@ class DOMHits(Module): ax.tick_params(labelbottom=False) ax.tick_params(labeltop=False) ax.set_xlabel("event (latest on the right)") - ax.set_title("{0} - via the last {1} Events\n{2} UTC".format( - title, self.max_events, - datetime.utcnow().strftime("%c"))) + ax.set_title( + "{0} for DetID-{1} - via the last {2} Events\n{3} UTC".format( + title, self.det.det_id, self.max_events, + datetime.utcnow().strftime("%c"))) cb = fig.colorbar(im, pad=0.05) cb.set_label("number of hits") @@ -180,7 +181,7 @@ def main(): kp.io.ch.CHPump, host=ligier_ip, port=ligier_port, - tags='IO_EVT, IO_SUM', + tags='IO_EVT', timeout=60 * 60 * 24 * 7, max_queue=2000) pipe.attach(kp.io.daq.DAQProcessor) diff --git a/scripts/logio.py b/scripts/logio.py new file mode 100755 index 0000000000000000000000000000000000000000..779214f8474c61fa7bebc7b6a8f342a4335847d8 --- /dev/null +++ b/scripts/logio.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# coding=utf-8 +# Filename: logio.py +# Author: Tamas Gal <tgal@km3net.de> +# vim: ts=4 sw=4 et +""" +Sends MSG data from Ligier to a log.io server to be displayed in real-time. + +Usage: + logio.py [options] + logio.py (-h | --help) + +Options: + -l LIGIER_IP The IP of the ligier [default: 127.0.0.1]. + -p LIGIER_PORT The port of the ligier [default: 5553]. + -x LOGIO_IP The IP of the ligier [default: 127.0.0.1]. + -q LOGIO_PORT The port of the ligier [default: 28777]. + -h --help Show this screen. + +""" +import socket +import time + +from km3pipe import Pipeline, Module +from km3pipe.io import CHPump + + +class LogIO(Module): + def configure(self): + url = self.get('logio_ip', default='127.0.0.1') + port = self.get('logio_port', default=28777) + + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.connect((url, port)) + + def process(self, blob): + data = blob['CHData'] + log_level = 'info' + if "ERROR" in data: + log_level = 'error' + if "WARNING" in data: + log_level = 'warning' + source = "Other" + if " F0" in data: + source = "DataFilter" + if " Q0" in data: + source = "DataQueue" + if " W0" in data: + source = "DataWriter" + self.sock.send("+log|{0}|Portopalo DAQ|{1}|{2}\r\n".format( + source, log_level, data)) + return blob + + def finish(self): + self.sock.close() + + +def main(): + from docopt import docopt + args = docopt(__doc__) + + ligier_ip = args['-l'] + ligier_port = int(args['-p']) + logio_ip = args['-x'] + logio_port = int(args['-q']) + + pipe = Pipeline() + pipe.attach( + CHPump, + host=ligier_ip, + port=ligier_port, + tags='MSG', + timeout=7 * 60 * 60 * 24, + max_queue=500) + pipe.attach(LogIO, logio_ip=logio_ip, logio_port=logio_port) + pipe.drain() + + +if __name__ == '__main__': + main() diff --git a/scripts/msg_dumper.py b/scripts/msg_dumper.py new file mode 100755 index 0000000000000000000000000000000000000000..66e9d2d0c8d6c1e6f5b9c62d63fc21b4e1f1e61a --- /dev/null +++ b/scripts/msg_dumper.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# coding=utf-8 +# Filename: msg_dumper.py +# Author: Tamas Gal <tgal@km3net.de> +# vim: ts=4 sw=4 et +""" +Dumps MSG data from Ligier to a file. + +Usage: + msg_dumper.py [options] + msg_dumper.py (-h | --help) + +Options: + -l LIGIER_IP The IP of the ligier [default: 127.0.0.1]. + -p LIGIER_PORT The port of the ligier [default: 5553]. + -f LOG_FILE Log file to dump the messages [default: MSG.log]. + -h --help Show this screen. + +""" +import os +import time + +from km3pipe import Pipeline, Module +from km3pipe.io import CHPump + + +class MSGDumper(Module): + def configure(self): + self.filename = self.get('filename', default='MSG.log') + self.fobj = open(os.path.abspath(self.filename), 'a') + + def process(self, blob): + data = blob['CHData'].decode() + source = "Other" + if " F0" in data: + source = "DataFilter" + if " Q0" in data: + source = "DataQueue" + if " W0" in data: + source = "DataWriter" + + entry = "{} [{}]: {}\n".format( + os.path.basename(self.filename), source, data) + self.fobj.write(entry) + return blob + + def finish(self): + self.fobj.close() + + +def main(): + from docopt import docopt + args = docopt(__doc__) + + ligier_ip = args['-l'] + ligier_port = int(args['-p']) + filename = args['-f'] + + pipe = Pipeline() + pipe.attach( + CHPump, + host=ligier_ip, + port=ligier_port, + tags='MSG', + timeout=7 * 60 * 60 * 24, + max_queue=500) + pipe.attach(MSGDumper, filename=filename) + pipe.drain() + + +if __name__ == '__main__': + main() diff --git a/scripts/trigger_rates.py b/scripts/trigger_rates.py index bc7a207dbd3ceb6e982ca1a3f13b57f053f40b88..b16505151632099ed53f379d1209951144c7c273 100755 --- a/scripts/trigger_rates.py +++ b/scripts/trigger_rates.py @@ -21,6 +21,7 @@ from __future__ import division, print_function from datetime import datetime from collections import defaultdict, deque, OrderedDict +from itertools import chain import sys from io import BytesIO from os.path import join @@ -35,11 +36,10 @@ import matplotlib.dates as md import km3pipe as kp from km3pipe.config import Config -from km3pipe.io.daq import (DAQPreamble, DAQEvent, - is_3dshower, is_3dmuon, is_mxshower) +from km3pipe.io.daq import (DAQPreamble, DAQEvent, is_3dshower, is_3dmuon, + is_mxshower) import km3pipe.style - VERSION = "1.0" km3pipe.style.use('km3pipe') @@ -47,8 +47,8 @@ km3pipe.style.use('km3pipe') class TriggerRate(kp.Module): def configure(self): self.plots_path = self.require('plots_path') - self.interval = self.get("interval", - default=self.trigger_rate_sampling_period()) + self.interval = self.get( + "interval", default=self.trigger_rate_sampling_period()) self.filename = self.get("filename", default="trigger_rates") self.with_minor_ticks = self.get("with_minor_ticks", default=False) print("Update interval: {}s".format(self.interval)) @@ -56,18 +56,25 @@ class TriggerRate(kp.Module): self.trigger_rates = OrderedDict() self.styles = { - "xfmt": md.DateFormatter('%Y-%m-%d %H:%M'), - "general": dict(markersize=6, linestyle='None'), - "Overall": dict(marker='D', - markerfacecolor='None', - markeredgecolor='tomato', - markeredgewidth=1), - "3DMuon": dict(marker='X', markerfacecolor='dodgerblue'), - "MXShower": dict(marker='v', markerfacecolor='orange'), - "3DShower": dict(marker='^', markerfacecolor='olivedrab'), + "xfmt": + md.DateFormatter('%Y-%m-%d %H:%M'), + "general": + dict(markersize=6, linestyle='None'), + "Overall": + dict( + marker='D', + markerfacecolor='None', + markeredgecolor='tomato', + markeredgewidth=1), + "3DMuon": + dict(marker='X', markerfacecolor='dodgerblue'), + "MXShower": + dict(marker='v', markerfacecolor='orange'), + "3DShower": + dict(marker='^', markerfacecolor='olivedrab'), } - queue_len = int(60*24/(self.interval/60)) + queue_len = int(60 * 24 / (self.interval / 60)) for trigger in ["Overall", "3DMuon", "MXShower", "3DShower"]: self.trigger_rates[trigger] = deque(maxlen=queue_len) @@ -75,6 +82,10 @@ class TriggerRate(kp.Module): self.thread = threading.Thread(target=self.plot).start() self.lock = threading.Lock() + self.run_changes = [] + self.current_run_id = 0 + self.det_id = 0 + def process(self, blob): if not str(blob['CHPrefix'].tag) == 'IO_EVT': return blob @@ -85,6 +96,10 @@ class TriggerRate(kp.Module): data_io = BytesIO(data) preamble = DAQPreamble(file_obj=data_io) # noqa event = DAQEvent(file_obj=data_io) + self.det_id = event.header.det_id + if event.header.run > self.current_run_id: + self.current_run_id = event.header.run + self._log_run_change() tm = event.trigger_mask with self.lock: self.trigger_counts["Overall"] += 1 @@ -96,6 +111,27 @@ class TriggerRate(kp.Module): return blob + def _log_run_change(self): + self.print("New run: %s" % self.current_run_id) + now = datetime.utcnow() + self.run_changes.append((now, self.current_run_id)) + + def _get_run_changes_to_plot(self): + self.print("Checking run changes out of range") + overall_rates = self.trigger_rates['Overall'] + if not overall_rates: + self.print("No trigger rates logged yet, nothing to remove.") + return + self.print(" all: {}".format(self.run_changes)) + run_changes_to_plot = [] + min_timestamp = min(overall_rates)[0] + self.print(" earliest timestamp to plot: {}".format(min_timestamp)) + for timestamp, run in self.run_changes: + if timestamp > min_timestamp: + run_changes_to_plot.append((timestamp, run)) + self.print(" to plot: {}".format(run_changes_to_plot)) + return run_changes_to_plot + def plot(self): while self.run: time.sleep(self.interval) @@ -119,12 +155,35 @@ class TriggerRate(kp.Module): self.log.warning("Empty rates, skipping...") continue timestamps, trigger_rates = zip(*rates) - ax.plot(timestamps, trigger_rates, - **self.styles[trigger], - **self.styles['general'], - label=trigger) - ax.set_title("Trigger Rates\n{0} UTC" - .format(datetime.utcnow().strftime("%c"))) + ax.plot( + timestamps, + trigger_rates, + **self.styles[trigger], + **self.styles['general'], + label=trigger) + + run_changes_to_plot = self._get_run_changes_to_plot() + self.print("Recorded run changes: {}".format(run_changes_to_plot)) + all_rates = [r for d, r in chain(*self.trigger_rates.values())] + if not all_rates: + self.log.warning("Empty rates, skipping...") + return + min_trigger_rate = min(all_rates) + max_trigger_rate = max(all_rates) + for run_start, run in run_changes_to_plot: + plt.text( + run_start, (min_trigger_rate + max_trigger_rate) / 2, + "\nRUN %s " % run, + rotation=60, + verticalalignment='top', + fontsize=8, + color='gray') + ax.axvline( + run_start, color='#ff0f5b', linestyle='--', alpha=0.8) # added + + ax.set_title("Trigger Rates for DetID-{0}\n{1} UTC".format( + self.det_id, + datetime.utcnow().strftime("%c"))) ax.set_xlabel("time") ax.set_ylabel("trigger rate [Hz]") ax.xaxis.set_major_formatter(self.styles["xfmt"]) @@ -175,11 +234,13 @@ def main(): ligier_port = int(args['-p']) pipe = kp.Pipeline() - pipe.attach(kp.io.ch.CHPump, host=ligier_ip, - port=ligier_port, - tags='IO_EVT', - timeout=60*60*24*7, - max_queue=200000) + pipe.attach( + kp.io.ch.CHPump, + host=ligier_ip, + port=ligier_port, + tags='IO_EVT', + timeout=60 * 60 * 24 * 7, + max_queue=200000) pipe.attach(TriggerRate, interval=300, plots_path=plots_path) pipe.drain() diff --git a/scripts/ztplot.py b/scripts/ztplot.py index f3aab3c22781be716ddb0915ce85b3419729894c..82b8b0cd01fb2050dc029a56adb3920f601513bd 100755 --- a/scripts/ztplot.py +++ b/scripts/ztplot.py @@ -135,13 +135,17 @@ class ZTPlot(Module): label.set_rotation(45) if idx % n_cols == 0: - ax.set_ylabel('time [ns]', fontsize=fontsize) + ax.set_ylabel('z [m]', fontsize=fontsize) if idx >= len(axes) - n_cols: - ax.set_xlabel('z [m]', fontsize=fontsize) + ax.set_xlabel('time [ns]', fontsize=fontsize) + print plt.suptitle( - "FrameIndex {0}, TriggerCounter {1}\n{2} UTC".format( - event_info.frame_index, event_info.trigger_counter, + "z-t-Plot for DetID-{0}, Run {1}, FrameIndex {2}, " + "TriggerCounter {3}, Overlays {4}\n{5} UTC".format( + event_info.det_id[0], event_info.run_id[0], + event_info.frame_index[0], event_info.trigger_counter[0], + event_info.overlays[0], datetime.utcfromtimestamp(event_info.utc_seconds)), fontsize=fontsize, y=1.05)