2018-06-17 19:16:53 +00:00
|
|
|
|
#! /usr/bin/python
|
|
|
|
|
|
# encoding: UTF-8
|
|
|
|
|
|
|
|
|
|
|
|
""" phasefit
|
|
|
|
|
|
|
|
|
|
|
|
Read .EI file(s) (irena with SolO Trigger).
|
|
|
|
|
|
Collect all hits above thr*mV and make a histogram of the phase parameter.
|
|
|
|
|
|
Integrate and normalize the histogram.
|
|
|
|
|
|
Fit a polynom to the phase funtion.
|
|
|
|
|
|
Print the data and fit
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
import sys, getopt, fileinput, math, numpy, numpy.linalg
|
2018-06-18 10:06:03 +00:00
|
|
|
|
from numpy import array, zeros, arange, newaxis
|
2018-06-17 19:16:53 +00:00
|
|
|
|
|
2018-06-18 10:06:03 +00:00
|
|
|
|
options,files = getopt.getopt(sys.argv[1:], "V:t:N:r:L:")
|
2018-06-17 19:16:53 +00:00
|
|
|
|
|
|
|
|
|
|
mV = 14000
|
|
|
|
|
|
thr = 50
|
|
|
|
|
|
nCh = 0
|
|
|
|
|
|
binW = 0.0005
|
2018-06-18 10:06:03 +00:00
|
|
|
|
rank = 3
|
|
|
|
|
|
ph_min = 0.01
|
|
|
|
|
|
ph_max = 1 - ph_min
|
2018-06-17 19:16:53 +00:00
|
|
|
|
|
|
|
|
|
|
for o,v in options:
|
|
|
|
|
|
if o=='-V':
|
|
|
|
|
|
mV = float(v)
|
|
|
|
|
|
if o=='-t':
|
|
|
|
|
|
thr = float(v)
|
|
|
|
|
|
if o=='-N':
|
|
|
|
|
|
nCh = int(v)
|
|
|
|
|
|
if o=='-r':
|
|
|
|
|
|
rank = int(v)
|
2018-06-18 10:06:03 +00:00
|
|
|
|
if o=='-L':
|
|
|
|
|
|
vv = map(float, v.split())
|
|
|
|
|
|
if len(vv)==1:
|
|
|
|
|
|
ph_min,ph_max = vv[0],1-vv[0]
|
|
|
|
|
|
else:
|
|
|
|
|
|
ph_min,ph_max = vv
|
2018-06-17 19:16:53 +00:00
|
|
|
|
|
|
|
|
|
|
class histogram(object):
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, w):
|
|
|
|
|
|
self.h = {}
|
2018-06-18 10:06:03 +00:00
|
|
|
|
self.w = w
|
2018-06-17 19:16:53 +00:00
|
|
|
|
self.offs = 0.5
|
|
|
|
|
|
|
|
|
|
|
|
def add(self, b, n=1):
|
2018-06-18 10:06:03 +00:00
|
|
|
|
b = numpy.floor(b/self.w + self.offs)
|
|
|
|
|
|
try:
|
|
|
|
|
|
self.addb(int(b), n)
|
|
|
|
|
|
except TypeError:
|
|
|
|
|
|
self.addb(tuple(map(int, b)), n)
|
|
|
|
|
|
|
|
|
|
|
|
def addb(self, b, n=1):
|
2018-06-17 19:16:53 +00:00
|
|
|
|
if b in self.h:
|
|
|
|
|
|
self.h[b] += n
|
|
|
|
|
|
else:
|
|
|
|
|
|
self.h[b] = n
|
|
|
|
|
|
|
|
|
|
|
|
def bins(self):
|
|
|
|
|
|
bb = self.h.keys()
|
|
|
|
|
|
bb.sort()
|
|
|
|
|
|
return bb
|
|
|
|
|
|
|
|
|
|
|
|
def copy(self):
|
|
|
|
|
|
hh = histogram(self.w)
|
|
|
|
|
|
hh.offs = self.offs
|
|
|
|
|
|
return hh
|
|
|
|
|
|
|
|
|
|
|
|
def integrate(self):
|
|
|
|
|
|
s = 0
|
|
|
|
|
|
hh = self.copy()
|
|
|
|
|
|
for b in self.bins():
|
|
|
|
|
|
s = s + self.h[b]
|
|
|
|
|
|
hh.h[b] = s
|
|
|
|
|
|
return hh
|
|
|
|
|
|
|
|
|
|
|
|
def __iadd__(self, b):
|
|
|
|
|
|
self.add(b)
|
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
|
|
def hist(self):
|
|
|
|
|
|
return [(b*self.w, self.h[b]) for b in self.bins()]
|
|
|
|
|
|
|
|
|
|
|
|
def normalize(self, n):
|
|
|
|
|
|
hh = self.copy()
|
|
|
|
|
|
for b in self.h:
|
|
|
|
|
|
hh.h[b] = self.h[b] / n
|
|
|
|
|
|
return hh
|
|
|
|
|
|
|
|
|
|
|
|
class regression(object):
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, r=1):
|
|
|
|
|
|
self.n = 0
|
2018-06-18 10:06:03 +00:00
|
|
|
|
self.tb = arange(r+1)
|
|
|
|
|
|
self.ta = self.tb.reshape((-1,1)) + self.tb.reshape((1,-1))
|
|
|
|
|
|
self.tb = self.tb
|
|
|
|
|
|
self.ta = self.ta
|
|
|
|
|
|
self.B = zeros(self.tb.shape)
|
|
|
|
|
|
self.A = zeros(self.ta.shape)
|
2018-06-17 19:16:53 +00:00
|
|
|
|
self.yy = 0
|
|
|
|
|
|
|
|
|
|
|
|
def add(self, x, y, n=1):
|
2018-06-18 10:06:03 +00:00
|
|
|
|
y = array(y)
|
|
|
|
|
|
x = array(x)
|
|
|
|
|
|
n = array(n)
|
2018-06-17 19:16:53 +00:00
|
|
|
|
self.n += 1
|
|
|
|
|
|
self.yy += n*y*y
|
2018-06-18 10:06:03 +00:00
|
|
|
|
self.B = self.B + (x[...,newaxis]**self.tb) * (n * y)[...,newaxis]
|
|
|
|
|
|
self.A = self.A + (x[...,newaxis,newaxis]**self.ta) * n[...,newaxis,newaxis]
|
2018-06-17 19:16:53 +00:00
|
|
|
|
|
|
|
|
|
|
def solve(self):
|
2018-06-18 10:06:03 +00:00
|
|
|
|
self.solution = numpy.linalg.solve(self.A,self.B)
|
2018-06-17 19:16:53 +00:00
|
|
|
|
return self.solution
|
|
|
|
|
|
|
|
|
|
|
|
def evaluate(self, x):
|
|
|
|
|
|
try:
|
2018-06-18 10:06:03 +00:00
|
|
|
|
s = self.solution
|
2018-06-17 19:16:53 +00:00
|
|
|
|
except AttributeError:
|
2018-06-18 10:06:03 +00:00
|
|
|
|
s = self.solve()
|
|
|
|
|
|
return numpy.add.reduce(x**self.tb * s, axis=-1)
|
2018-06-17 19:16:53 +00:00
|
|
|
|
|
|
|
|
|
|
def rank(self):
|
2018-06-18 10:06:03 +00:00
|
|
|
|
return self.tb.shape[0]-1
|
2018-06-17 19:16:53 +00:00
|
|
|
|
|
|
|
|
|
|
def correlation(self):
|
|
|
|
|
|
if not self.rank():
|
|
|
|
|
|
return ()
|
2018-06-18 10:06:03 +00:00
|
|
|
|
dx = self.A[...,1,1]*self.A[...,0,0] - self.A[...,1,0]**2
|
|
|
|
|
|
dy = self.yy*self.A[...,0,0] - self.B[...,0]**2
|
|
|
|
|
|
r = (self.B[...,1]*self.A[...,0,0] - self.A[...,1,0]*self.B[...,0])/numpy.sqrt(dx*dy)
|
|
|
|
|
|
return self.n, self.A[...,0,0], r, dx/self.A[...,0,0], dy/self.A[...,0,0]
|
|
|
|
|
|
|
|
|
|
|
|
def reduce(self, axis=0, x=True, y=True, n=True):
|
|
|
|
|
|
rr = regression(self.rank())
|
|
|
|
|
|
rr.n = self.n
|
|
|
|
|
|
rr.tb = self.tb
|
|
|
|
|
|
rr.ta = self.ta
|
|
|
|
|
|
if x or y or n:
|
|
|
|
|
|
rr.B = numpy.add.reduce(self.B, axis=axis)
|
|
|
|
|
|
else:
|
|
|
|
|
|
rr.B = self.B
|
|
|
|
|
|
if x or n:
|
|
|
|
|
|
rr.A = numpy.add.reduce(self.A, axis=axis)
|
|
|
|
|
|
else:
|
|
|
|
|
|
rr.A = self.A
|
|
|
|
|
|
if y or n:
|
|
|
|
|
|
rr.yy = numpy.add.reduce(self.yy, axis=axis)
|
|
|
|
|
|
else:
|
|
|
|
|
|
rr.yy = self.yy
|
|
|
|
|
|
return rr
|
|
|
|
|
|
|
2018-06-17 19:16:53 +00:00
|
|
|
|
h = histogram(binW)
|
|
|
|
|
|
|
|
|
|
|
|
for l in fileinput.input(files):
|
|
|
|
|
|
if l[0:2] != 'EI':
|
|
|
|
|
|
continue
|
|
|
|
|
|
ll = [int(ll,0) for ll in l.split()[1:]]
|
|
|
|
|
|
|
|
|
|
|
|
if not nCh:
|
|
|
|
|
|
nCh = (len(ll)-4)//3
|
2018-06-18 10:06:03 +00:00
|
|
|
|
sys.stdout.write("# %d channels\n" % nCh)
|
2018-06-17 19:16:53 +00:00
|
|
|
|
if len(ll) != 4+3*nCh:
|
|
|
|
|
|
sys.stderr.write("nCh mismatch: "+l)
|
|
|
|
|
|
continue
|
|
|
|
|
|
for c in range(nCh):
|
|
|
|
|
|
if ll[4+3*c] < thr*mV:
|
|
|
|
|
|
continue
|
|
|
|
|
|
if ll[5+3*c] < 2:
|
|
|
|
|
|
continue
|
2018-06-18 10:06:03 +00:00
|
|
|
|
n = zeros((nCh,))
|
2018-06-17 19:16:53 +00:00
|
|
|
|
n[c] = 1
|
|
|
|
|
|
h.add(ll[6+3*c] / float(ll[4+3*c]), n)
|
|
|
|
|
|
|
|
|
|
|
|
hi = h.integrate()
|
|
|
|
|
|
I = hi.hist()[-1][1]
|
|
|
|
|
|
hi = hi.normalize(I)
|
|
|
|
|
|
sys.stdout.write("# Integral: %s\n" % repr(I))
|
|
|
|
|
|
|
|
|
|
|
|
r = regression(rank)
|
2018-06-18 10:06:03 +00:00
|
|
|
|
hh = hi.hist()
|
|
|
|
|
|
x,y = map(array, zip(*hh))
|
|
|
|
|
|
r.add(x[...,newaxis], y, (y>=ph_min)*(y<=ph_max))
|
|
|
|
|
|
r = r.reduce()
|
2018-06-17 19:16:53 +00:00
|
|
|
|
|
|
|
|
|
|
p = r.solve()
|
2018-06-18 10:06:03 +00:00
|
|
|
|
rr = r.reduce(x=False)
|
|
|
|
|
|
pp = rr.solve()
|
|
|
|
|
|
for n,c in enumerate(p.transpose()):
|
|
|
|
|
|
sys.stdout.write("# c%d: %s\n" % (n,repr(c)))
|
|
|
|
|
|
for n,c in enumerate(pp.transpose()):
|
|
|
|
|
|
sys.stdout.write("# cc%d: %s\n" % (n,repr(c)))
|
|
|
|
|
|
for n,c in zip(("n", "w", "r","σ²x", "σ²y"), r.correlation()):
|
|
|
|
|
|
sys.stdout.write("# %s: %s\n" % (n,repr(c)))
|
2018-06-17 19:16:53 +00:00
|
|
|
|
|
2018-06-18 10:06:03 +00:00
|
|
|
|
for x,y in hh:
|
2018-06-17 19:16:53 +00:00
|
|
|
|
n = y.shape[0]
|
|
|
|
|
|
sys.stdout.write("%g" % x)
|
|
|
|
|
|
sys.stdout.write((" %g"*n) % tuple(y))
|
|
|
|
|
|
sys.stdout.write((" %g"*n) % tuple(r.evaluate(x)))
|
2018-06-18 10:06:03 +00:00
|
|
|
|
sys.stdout.write((" %g") % rr.evaluate(x))
|
2018-06-17 19:16:53 +00:00
|
|
|
|
sys.stdout.write("\n")
|