From 4c4ed2e4c149e39746f271ce86760a47e2060053 Mon Sep 17 00:00:00 2001 From: jebba Date: Sun, 9 Jan 2022 13:15:55 -0700 Subject: [PATCH] Stripped down recorder, copied bits from ozel --- README.md | 1 + requirements.txt | 1 + witgit-rec | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) diff --git a/README.md b/README.md index 1a4fe8d..b099905 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ witgit is free software gamma ray spectroscopy software under development intended to be used with low cost and DIY hardware running on a free operating system. +For educational use only, and probably not even that. # Hardware diff --git a/requirements.txt b/requirements.txt index 6ba612d..4f2a0d9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ msgpack numpy pandas pyaudio +pyqtgraph scipy diff --git a/witgit-rec b/witgit-rec index 47bab2d..67a7f92 100755 --- a/witgit-rec +++ b/witgit-rec @@ -10,3 +10,123 @@ https://github.com/ozel/DIY_particle_detector @date: January 2022 """ +import sys +import time +from pyqtgraph.Qt import QtCore, QtGui, QtWidgets +import numpy as np +import pyqtgraph as pg +import pyaudio +import pandas as pd +import datetime +from functools import partial +from scipy.signal import argrelextrema + +class Scope(QtGui.QMainWindow): + def __init__(self, parent=None): + global app + QtGui.QMainWindow.__init__(self, parent) + + self.app = app + self.app.aboutToQuit.connect(self.close) + self.pcounter=0 + self.creation_time=datetime.datetime.now() + + self.df = pd.DataFrame(columns = ['ts','ptype']) + self.ptypes = pd.Series(["alpha", "beta", "betagamma", "x-ray", "muon" ,"unknown"], dtype="category") + + self.thl = -300 + self.hl = -1243 # green cursor, highlight line for measuring only + self.peaks=[] + + def audio_callback(in_data, frame_count, time_info, status): + now = time.time() + samples = np.frombuffer(in_data, dtype=np.int16) + peak = samples.min() + if peak < self.thl: + t = pd.datetime.fromtimestamp(now) + print("* ", t, end="") + pulse = pd.DataFrame() + pulse = pulse.assign(ts=[t]) + if peak < -1243: + pulse = pulse.assign(ptype=[self.ptypes[0]]) #alpha + print(" alpha ", end="") + else: + pulse = pulse.assign(ptype=[self.ptypes[1]]) #beta/electron + print(" elect ", end="") + print(self.pcounter, " ", end="") + print(peak) + minima=argrelextrema(samples, np.less) + self.peaks.append(sum(minima[0])/len(minima[0]/2)) + self.peaks = self.peaks[-100:] #only keep the last 100 for averaging + pulse = pulse.assign(pulse=[samples]) + self.df = self.df.append(pulse, ignore_index=True,sort=False) + self.pcounter+=1 + # calculate pulse rate in counts per second + dt = (now-self.lastupdate) + if dt <= 0: + dt = 0.000000000001 + cps2 = 1.0 / dt + self.lastupdate = now + self.cps = self.cps * 0.9 + cps2 * 0.1 # simple weighted average + tx = 'Mean pulse rate: {cps:.1f} CPS'.format(cps=self.cps ) + self.label.setText(tx + ", THL (red): " + str(self.thl) + ", cursor(green): " + str(self.hl) + ", (avg peak: "+str(round(sum(self.peaks)/100,1)) + ")") + self.ydata=np.frombuffer(in_data, dtype=np.int16) + self.frame_counter+=frame_count + self.h2.setData(self.ydata) + self.thlp.setData(4096*[self.thl]) + self.hlp.setData(4096*[self.hl]) #draw green highlight line + + return (in_data, pyaudio.paContinue) + + #### Create Gui Elements ########### + self.mainbox = QtGui.QWidget() + self.setCentralWidget(self.mainbox) + self.mainbox.setLayout(QtGui.QVBoxLayout()) + + self.canvas = pg.GraphicsLayoutWidget() + self.mainbox.layout().addWidget(self.canvas) + + self.label = QtGui.QLabel() + self.mainbox.layout().addWidget(self.label) + + self.otherplot = self.canvas.addPlot() + self.h2 = self.otherplot.plot(pen='y') + self.thlp = self.otherplot.plot(pen='r') + self.hlp = self.otherplot.plot(pen='g') + + self.p = pyaudio.PyAudio() + self.stream = self.p.open(format=pyaudio.paInt16, channels=1, rate=48000, input=True, frames_per_buffer=4096,stream_callback=audio_callback) + + #### Set Data ##################### + self.x = np.linspace(0,50., num=100) + self.X,self.Y = np.meshgrid(self.x,self.x) + + self.frame_counter = 0 + self.cps = 0. + self.lastupdate = time.time() + + #### Start ##################### + self.stream.start_stream() + + def close_stream(self): + self.stream.close() + self.stream.stop_stream() + + def close(self): + timediff = datetime.datetime.now() - self.creation_time + self.close_stream() + if self.pcounter > 0: + td_str = '-'.join(str(timediff).split(':')[:2]) + _ = self.df.to_pickle("./data" + self.creation_time.strftime("/pulses_%Y-%m-%d_%H-%M-%S") + "___" + str(self.pcounter) + "___" + td_str + ".pkl") + print('Number of recorded waveforms:', self.pcounter, "of",self.frame_counter, "total audio frames") + print(len(self.df[self.df['ptype'] == 'alpha']) ,"alphas detected") + print(len(self.df[self.df['ptype'] == 'beta']) ,"electrons/betas detected") + self.p.terminate() + app.exit() + +if __name__ == '__main__': + app = QtWidgets.QApplication(sys.argv) + mainWin = Scope() + mainWin.show() + app.exec_() +