source: trunk/Mars/melectronics/MAnalogSignal.cc@ 19344

Last change on this file since 19344 was 17682, checked in by ftemme, 11 years ago
Added the clipping of the trigger signal
File size: 8.7 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of CheObs, the Modular Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appears in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 1/2009 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: CheObs Software Development, 2000-2009
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MAnalogSignal
28//
29// This is the equivalent to an analog signal. The signal is stored by
30// a sampling in equidistant bins.
31//
32//////////////////////////////////////////////////////////////////////////////
33#include "MAnalogSignal.h"
34
35#include <TF1.h>
36#include <TRandom.h>
37#include <TObjArray.h>
38
39#include "MLog.h"
40#include "MLogManip.h"
41
42#include "MSpline3.h"
43#include "MDigitalSignal.h"
44
45#include "MExtralgoSpline.h"
46
47ClassImp(MAnalogSignal);
48
49using namespace std;
50
51// ------------------------------------------------------------------------
52//
53// Set the array length and the length of the buffers.
54//
55void MAnalogSignal::Set(UInt_t n)
56{
57 // FIXME: Maybe we move this before initializing the spline
58 // with a check?
59 fDer1.Set(n);
60 fDer2.Set(n);
61
62 MArrayF::Set(n);
63}
64
65// ------------------------------------------------------------------------
66//
67// Evaluate the spline an add the result between t+xmin and t+xmax
68// (xmin and xmax are the limits of the spline) to the signal.
69// The spline is evaluated at the bin-center of the analog signal
70// and multiplied by f.
71//
72// Return kTRUE if the full range of the spline could be added to the
73// analog signal, kFALSE otherwise.
74//
75Bool_t MAnalogSignal::AddPulse(const MSpline3 &spline, Float_t t, Float_t f)
76{
77 // FIXME: This could be improved using a MExtralgoSpline with
78 // the identical stepping as the signal and we could use
79 // the integral instead of the pure y-value if we want.
80
81 // Both in units of the sampling frequency
82 const Float_t start = t+spline.GetXmin();
83 const Float_t end = t+spline.GetXmax();
84
85 Int_t first = TMath::CeilNint(start);
86 UInt_t last = TMath::CeilNint(end); // Ceil:< Floor:<=
87
88 Bool_t rc = kTRUE;
89 if (first<0)
90 {
91 first=0;
92 rc = kFALSE;
93 }
94 if (last>GetSize())
95 {
96 last=GetSize();
97 rc = kFALSE;
98 }
99
100 // FIXME: As soon as we have access to TSpline3::fPoly we can
101 // gain a lot in execution speed here.
102
103 Float_t *arr = GetArray();
104 for (UInt_t i=first; i<last; i++)
105 arr[i] += spline.Eval(i-t)*f;
106
107 return rc;
108}
109
110// ------------------------------------------------------------------------
111//
112// Evaluate the spline an add the result between t+xmin and t+xmax
113// (xmin and xmax are the limits of the TF1) to the signal.
114// The spline is evaluated at the bin-center of the analog signal
115// and multiplied by f.
116//
117// Return kTRUE if the full range of the function could be added to the
118// analog signal, kFALSE otherwise.
119//
120Bool_t MAnalogSignal::AddPulse(const TF1 &func, Float_t t, Float_t f)
121{
122 // Both in units of the sampling frequency
123 const Float_t start = t+func.GetXmin();
124 const Float_t end = t+func.GetXmax();
125
126 Int_t first = TMath::CeilNint(start);
127 UInt_t last = TMath::CeilNint(end); // Ceil:< Floor:<=
128
129 Bool_t rc = kTRUE;
130 if (first<0)
131 {
132 first=0;
133 rc = kFALSE;
134 }
135 if (last>GetSize())
136 {
137 last=GetSize();
138 rc = kFALSE;
139 }
140
141 // FIXME: As soon as we have access to TSpline3::fPoly we can
142 // gain a lot in execution speed here.
143
144 Float_t *arr = GetArray();
145 for (UInt_t i=first; i<last; i++)
146 arr[i] += func.Eval(i-t)*f;
147
148 return rc;
149}
150
151// ------------------------------------------------------------------------
152//
153// Add a second analog signal. Just by addining it bin by bin.
154//
155void MAnalogSignal::AddSignal(const MAnalogSignal &s, Int_t delay,
156 Float_t dampingFactor )
157{
158 Add(s.GetArray(), s.fN, delay, dampingFactor);
159}
160
161
162// Deprecated. Use MSimRandomPhotons instead
163void MAnalogSignal::AddRandomPulses(const MSpline3 &spline, Float_t num)
164{
165 // Average number (1./freq) of pulses per slice
166
167 const Float_t start = 0 -spline.GetXmin();
168 const Float_t end = (fN-1)-spline.GetXmax();
169
170 const UInt_t first = TMath::CeilNint(start);
171 const UInt_t last = TMath::CeilNint(end); // Ceil:< Floor:<=
172
173 Double_t d = first;
174
175 while (d<last)
176 {
177 d += gRandom->Exp(num);
178 AddPulse(spline, d);
179 }
180}
181
182// ------------------------------------------------------------------------
183//
184// Add a random gaussian with amplitude and offset to every bin
185// of the analog signal. The default offset is 0. The default amplitude 1.
186//
187void MAnalogSignal::AddGaussianNoise(Float_t amplitude, Float_t offset)
188{
189 for (Float_t *ptr = GetArray(); ptr<GetArray()+fN; ptr++)
190 *ptr += gRandom->Gaus(offset, amplitude);
191}
192
193// ------------------------------------------------------------------------
194//
195// The signal is evaluated using the spline MExtralgoSpline.
196// Searching upwards from the beginning all points are calculated at
197// which the spline is equal to threshold. After a rising edge
198// a leading edge is searched. From this an MDigitalSignal is
199// created and added to an newly created TObjArray. If len<0 then
200// the signal length is equal to the time above threshold, otherwise
201// the length is fixed to len. The start of the digital signal is the
202// rising edge. If due to fixed length two digital signal overlap the
203// digital signals are combined into one signal.
204//
205// For numerical reasons we have to avoid to find the same x-value twice.
206// Therefor a "dead-time" of 1e-4 is implemented after each edge.
207//
208// The user is responsible of deleting the TObjArray.
209//
210TObjArray *MAnalogSignal::Discriminate(Float_t threshold, Double_t start, Double_t end, Float_t len) const
211{
212 TObjArray *ttl = new TObjArray;
213 ttl->SetOwner();
214
215 // The time after which we start searching for a falling or leading
216 // edge at threshold after a leading or falling edge respectively.
217 // This value has mainly numerical reasons. If starting the search
218 // too early we might end up in an endless loop finding the same
219 // value again and again. This just means that a glitch above or
220 // below the threshold which is shorter than this value can
221 // stay unnoticed. This shouldn't hurt.
222 const Double_t deadtime = 1e-4;
223
224 // FIXME: Are local maximum/minima handled correctly?
225
226 const MExtralgoSpline sp(GetArray(), fN, fDer1.GetArray(), fDer2.GetArray());
227
228 Double_t x1 = 0;
229 Double_t x2 = start; // Start searching at x2
230
231 while (1)
232 {
233 // Search for the next rising edge (starting at x2)
234 while (1)
235 {
236 x1 = sp.SearchYup(x2+deadtime, threshold);
237 if (x1<0 || x1>=end)
238 return ttl;
239
240 const Bool_t rising = sp.Deriv1(x1)>0;
241 if (rising)
242 break;
243
244 x2 = x1;
245 }
246
247 // Search for the next falling edge (starting at x1)
248 while (1)
249 {
250 x2 = sp.SearchYup(x1+deadtime, threshold);
251 if (x2<0)
252 x2 = end;
253 if (x2>=end)
254 break;
255
256 const Bool_t falling = sp.Deriv1(x2)<0;
257 if (falling)
258 break;
259
260 x1 = x2;
261 }
262
263 // We found a rising and a falling edge
264 MDigitalSignal *sig = new MDigitalSignal(x1, len>0?len:x2-x1);
265
266 // In case of a fixed length we have to check for possible overlapping
267 if (len>0 && ttl->GetEntriesFast()>0)
268 {
269 // FIXME: What if in such a case the electronics is just dead?
270 MDigitalSignal *last = static_cast<MDigitalSignal*>(ttl->Last());
271 // Combine both signals to one if they overlap
272 if (last->Combine(*sig))
273 {
274 // Both signals overlap and have been combined into the existing one
275 delete sig;
276 continue;
277 }
278 // The signals don't overlap we add the new signal as usual
279 }
280
281 // Add the new signal to the list of signals
282 ttl->Add(sig);
283 }
284
285 return ttl;
286}
Note: See TracBrowser for help on using the repository browser.