source: fact/tools/pyscripts/pyfact/extractor.py@ 13019

Last change on this file since 13019 was 12986, checked in by neise, 13 years ago
generator now allows for more than one spike .... generator option string changedsvn diff extractor.py | colordiff ! so I had to change it in extractor as well... sorry
File size: 5.5 KB
Line 
1#!/usr/bin/python
2#
3# Dominik Neise, Werner Lustermann
4# TU Dortmund, ETH Zurich
5#
6import numpy as np
7import matplotlib.pyplot as plt
8from generator import *
9from fir_filter import *
10
11class GlobalMaxFinder(object):
12 """ Pulse Extractor
13 Finds the global maximum in the given window.
14 (Best used with filtered data)
15 """
16
17 def __init__(self, min=30, max=250 , name = 'GlobalMaxFinder'):
18 """ initialize search Window
19
20 """
21 self.min = min
22 self.max = max
23 self.name = name
24
25 def __call__(self, data):
26 if data.ndim > 1:
27 time = np.argmax( data[ : , self.min:self.max ], 1)
28 amplitude = np.max( data[ : , self.min:self.max], 1)
29 else:
30 time = np.argmax( data[self.min:self.max])
31 amplitude = np.max( data[self.min:self.max])
32 return amplitude, time+self.min
33
34 def __str__(self):
35 s = self.name + '\n'
36 s += 'window:\n'
37 s += '(min,max) = (' + str(self.min) + ',' + str(self.max) + ')'
38 return s
39
40 def test(self):
41 pass
42
43
44class FixedWindowIntegrator(object):
45 """ Integrates in a given intergration window
46 """
47
48 def __init__(self, min=55, max=105 , name = 'FixedWindowIntegrator'):
49 """ initialize integration Window
50 """
51 self.min = min
52 self.max = max
53 self.name = name
54
55 def __call__(self, data):
56 integral = np.empty( data.shape[0] )
57 for pixel in range( data.shape[0] ):
58 integral[pixel] = data[pixel, self.min:self.max].sum()
59 return integral
60
61 def __str__(self):
62 s = self.name + '\n'
63 s += 'window:\n'
64 s += '(min,max) = (' + str(self.min) + ',' + str(self.max) + ')'
65 return s
66
67class ZeroXing(object):
68 """ Finds zero crossings in given data
69 (should be used on CFD output for peak finding)
70 returns list of lists of time_of_zero_crossing
71 """
72 def __init__(self, slope=1, name = 'ZeroXing'):
73 if (slope >= 0):
74 self.slope = 1 # search for rising edge crossing
75 elif (slope < 0):
76 self.slope = -1 # search for falling edge crossing
77 self.name = name
78
79
80 def __call__(self, data):
81 all_hits = []
82 for pix_data in data:
83 hits = []
84 for i in range( data.shape[1]-1 ):
85 if ( self.slope > 0 ):
86 if ( pix_data[i] > 0 ):
87 continue
88 else:
89 if ( pix_data[i] < 0):
90 continue
91 if ( pix_data[i] * pix_data[i+1] <= 0 ):
92 # interpolate time of zero crossing with
93 # linear polynomial: y = ax + b
94 a = (pix_data[i+1] - pix_data[i]) / ((i+1) - i)
95 time = -1.0/a * pix_data[i] + i
96 hits.append(time)
97 all_hits.append(hits)
98 return all_hits
99
100 def __str__(self):
101 s = self.name + '\n'
102 if (self.slope == 1):
103 s += 'search for rising edge crossing.\n'
104 else:
105 s += 'search for falling edge crossing.\n'
106 return s
107
108
109def plotter(signal, text):
110 x=range(len(signal))
111 ax = plt.plot(x, signal, 'b.', label='signal')
112 plt.title(text)
113 plt.xlabel('sample')
114 plt.legend()
115 plt.grid(True)
116 plt.show()
117
118def histplotter(signal, text):
119 plt.xlabel('time of zero crossing')
120 plt.title(text)
121 plt.axis([0, 300,0,1440])
122 plt.grid(True)
123 n, bins, patches = plt.hist(signal, 3000, facecolor='r', alpha=0.75)
124 plt.show()
125
126
127if __name__ == '__main__':
128 """ test the extractors """
129 sg = SignalGenerator()
130 pulse_str = 'len 300 bsl -0.5 noise 0.5 triangle 65 10 8 100'
131 pulse = sg(pulse_str)
132 event = []
133 for i in range(1440):
134 event.append(sg(pulse_str))
135 event = np.array(event)
136 print 'test event with 1000 pixel generated, like this:'
137 print pulse_str
138 print
139
140 # Test GlobalMaxFinder
141 gmf = GlobalMaxFinder(30,250)
142 print gmf
143 amplitude, time = gmf(event)
144 if abs(amplitude.mean() - 10) < 0.5:
145 print "Test 1: OK GlobalMaxFinder found amplitude correctly", amplitude.mean()
146 if abs(time.mean() - 65) < 2:
147 print "Test 1: OK GlobalMaxFinder found time correctly", time.mean()
148 else:
149 print "BAD: time mean:", time.mean()
150
151 print
152
153 # Test FixedWindowIntegrator
154 fwi = FixedWindowIntegrator(50,200)
155 print fwi
156 integral = fwi(event)
157 #value of integral should be: 150*bsl + 8*10/2 + 100*10/2 = 465
158 if abs( integral.mean() - 465) < 2:
159 print "Test 2: OK FixedWindowIntegrator found integral correctly", integral.mean()
160 else:
161 print "Test 2: X FixedWindowIntegrator integral.mean failed:", integral.mean()
162
163 print
164 cfd = CFD()
165 sa = SlidingAverage(8)
166 print sa
167 cfd_out = sa(event)
168 cfd_out = cfd(cfd_out )
169 cfd_out = sa(cfd_out)
170 zx = ZeroXing()
171 print zx
172 list_of_list_of_times = zx(cfd_out)
173 times = []
174 for list_of_times in list_of_list_of_times:
175 times.extend(list_of_times)
176 times = np.array(times)
177
178 hist,bins = np.histogram(times,3000,(0,300))
179 most_probable_time = np.argmax(hist)
180 print 'most probable time of zero-crossing', most_probable_time/10.
181 print 'this includes filter delays ... for average filter setting 8 this turns out to be 78.8 most of the time'
182
183 #histplotter(times.flatten(), 'times.flatten()')
184 #plotter(cfd_out[0], 'cfd_out')
185 #plotter (pulse, pulse_str)
186
187
188
Note: See TracBrowser for help on using the repository browser.