ztplot.py 5.54 KiB
#!/usr/bin/env python
# coding=utf-8
# vim: ts=4 sw=4 et
"""
Creates z-t-plots for every DU.
Usage:
ztplot.py [options]
ztplot.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
import os
import queue
import shutil
import time
import threading
import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as md
import matplotlib.ticker as ticker
from matplotlib.colors import LogNorm
import numpy as np
import km3pipe as kp
from km3pipe import Pipeline, Module
from km3pipe.calib import Calibration
from km3pipe.hardware import Detector
from km3pipe.io import CHPump
from km3pipe.io.daq import (DAQProcessor, DAQPreamble, DAQSummaryslice,
DAQEvent)
import km3pipe.style
km3pipe.style.use('km3pipe')
from km3pipe.logger import logging
# for logger_name, logger in logging.Logger.manager.loggerDict.iteritems():
# if logger_name.startswith('km3pipe.'):
# print("Setting log level to debug for '{0}'".format(logger_name))
# logger.setLevel("DEBUG")
# xfmt = md.DateFormatter('%Y-%m-%d %H:%M')
lock = threading.Lock()
class ZTPlot(Module):
def configure(self):
self.plots_path = self.require('plots_path')
self.ytick_distance = self.get('ytick_distance', default=200)
self.min_dus = self.get('min_dus', default=1)
det_id = self.require('det_id')
self.calib = kp.calib.Calibration(det_id=det_id)
self.run = True
self.max_queue = 3
self.queue = queue.Queue()
self.thread = threading.Thread(target=self.plot, daemon=True)
self.thread.start()
def process(self, blob):
if 'Hits' not in blob:
return blob
hits = blob['Hits']
hits = self.calib.apply(hits)
event_info = blob['EventInfo']
n_triggered_dus = np.unique(hits[hits.triggered == True].du)
if n_triggered_dus < self.min_dus:
print("Skipping...")
return blob
print("OK")
# print("Event queue size: {0}".format(self.queue.qsize()))
if self.queue.qsize() < self.max_queue:
self.queue.put((event_info, hits))
return blob
def plot(self):
while self.run:
try:
event_info, hits = self.queue.get(timeout=50)
except queue.Empty:
continue
with lock:
self.create_plot(event_info, hits)
def create_plot(self, event_info, hits):
print(self.__class__.__name__ + ": updating plot.")
dus = set(hits.du)
fontsize = 16
n_plots = len(dus)
n_cols = int(np.ceil(np.sqrt(n_plots)))
n_rows = int(n_plots / n_cols) + (n_plots % n_cols > 0)
fig, axes = plt.subplots(
ncols=n_cols,
nrows=n_rows,
sharex=True,
sharey=True,
figsize=(16, 8))
axes = [axes] if n_plots == 1 else axes.flatten()
for ax, du in zip(axes, dus):
du_hits = hits[hits.du == du]
trig_hits = du_hits[du_hits.triggered == True]
ax.scatter(du_hits.time, du_hits.pos_z, c='#09A9DE', label='hit')
ax.scatter(
trig_hits.time,
trig_hits.pos_z,
c='#FF6363',
label='triggered hit')
ax.set_title(
'DU{0}'.format(int(du)), fontsize=fontsize, fontweight='bold')
for idx, ax in enumerate(axes):
ax.tick_params(labelsize=fontsize)
ax.yaxis.set_major_locator(
ticker.MultipleLocator(self.ytick_distance))
xlabels = ax.get_xticklabels()
for label in xlabels:
label.set_rotation(45)
if idx % n_cols == 0:
ax.set_ylabel('z [m]', fontsize=fontsize)
if idx >= len(axes) - n_cols:
ax.set_xlabel('time [ns]', fontsize=fontsize)
print
plt.suptitle(
"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)
filename = 'ztplot'
f = os.path.join(self.plots_path, filename + '.png')
f_tmp = os.path.join(self.plots_path, filename + '_tmp.png')
plt.savefig(f_tmp, dpi=120, bbox_inches="tight")
plt.close('all')
shutil.move(f_tmp, f)
def finish(self):
self.run = False
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_EVT, IO_SUM',
timeout=60 * 60 * 24 * 7,
max_queue=2000)
pipe.attach(kp.io.daq.DAQProcessor)
pipe.attach(ZTPlot, det_id=det_id, plots_path=plots_path)
pipe.drain()
if __name__ == '__main__':
main()