source: trunk/MagicSoft/Mars/melectronics/MAnalogSignal.cc@ 9251

Last change on this file since 9251 was 9243, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 7.6 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 <TRandom.h>
36
37#include "MLog.h"
38#include "MLogManip.h"
39
40#include "MSpline3.h"
41#include "MDigitalSignal.h"
42
43#include "MExtralgoSpline.h"
44
45ClassImp(MAnalogSignal);
46
47using namespace std;
48
49// ------------------------------------------------------------------------
50//
51// Set the array length and the length of the buffers.
52//
53void MAnalogSignal::Set(UInt_t n)
54{
55 // FIXME: Maybe we move this before initializing the spline
56 // with a check?
57 fDer1.Set(n);
58 fDer2.Set(n);
59
60 MArrayF::Set(n);
61}
62
63// ------------------------------------------------------------------------
64//
65// Evaluate the spline an add the result between t+xmin and t+xmax
66// (xmin and xmax are the limits of the spline) to the signal.
67// The spline is evaluated at the bin-center of the analog signal
68// and multiplied by f.
69//
70void MAnalogSignal::AddPulse(const MSpline3 &spline, Float_t t, Float_t f)
71{
72 // FIXME: This could be improved using a MExtralgoSpline with
73 // the identical stepping as the signal and we could use
74 // the integral instead of the pure y-value if we want.
75
76 // Both in units of the sampling frequency
77 const Float_t start = t+spline.GetXmin();
78 const Float_t end = t+spline.GetXmax();
79
80 /*const*/ Int_t first = TMath::CeilNint(start);
81 /*const*/ UInt_t last = TMath::CeilNint(end); // Ceil:< Floor:<=
82
83 if (first<0 || last>GetSize())
84 {
85 gLog << err << "ERROR - AddPulse: Out of bounds, ";
86 gLog << "Win=[" << first << "," << last << "] N=" << GetSize() << " t=" << t;
87 gLog << " Spline=[" << spline.GetXmin() << "," << spline.GetXmax() << "]" << endl;
88
89 if (first<0)
90 first=0;
91 if (last>GetSize())
92 last=GetSize();
93 }
94
95 Float_t *arr = GetArray();
96 for (UInt_t i=first; i<last; i++)
97 arr[i] += spline.Eval(i-t)*f;
98}
99
100// ------------------------------------------------------------------------
101//
102// Add a second analog signal. Just by addining it bin by bin.
103//
104void MAnalogSignal::AddSignal(const MAnalogSignal &s)
105{
106 Add(s.GetArray(), s.fN);
107}
108
109// Deprecated. Use MSimRandomPhotons instead
110void MAnalogSignal::AddRandomPulses(const MSpline3 &spline, Float_t num)
111{
112 // Average number (1./freq) of pulses per slice
113
114 const Float_t start = 0 -spline.GetXmin();
115 const Float_t end = (fN-1)-spline.GetXmax();
116
117 const UInt_t first = TMath::CeilNint(start);
118 const UInt_t last = TMath::CeilNint(end); // Ceil:< Floor:<=
119
120 Double_t d = first;
121
122 while (d<last)
123 {
124 d += gRandom->Exp(num);
125 AddPulse(spline, d);
126 }
127}
128
129// ------------------------------------------------------------------------
130//
131// Add a random gaussian with amplitude and offset to every bin
132// of the analog signal. The default offset is 0. The default amplitude 1.
133//
134void MAnalogSignal::AddGaussianNoise(Float_t amplitude, Float_t offset)
135{
136 for (Float_t *ptr = GetArray(); ptr<GetArray()+fN; ptr++)
137 *ptr += gRandom->Gaus(offset, amplitude);
138}
139
140// ------------------------------------------------------------------------
141//
142// The signal is evaluated using the spline MExtralgoSpline.
143// Searching upwards from the beginning all points are calculated at
144// which the spline is equal to threshold. After a rising edge
145// a leading edge is searched. From this an MDigitalSignal is
146// created and added to an newly created TObjArray. If len<0 then
147// the signal length is equal to the time above threshold, otherwise
148// the length is fixed to len. The start of the digital signal is the
149// rising edge. If due to fixed length two digital signal overlap the
150// digital signals are combined into one signal.
151//
152// For numerical reasons we have to avoid to find the same x-value twice.
153// Therefor a "dead-time" of 1e-4 is implemented after each edge.
154//
155// The user is responsible of deleting the TObjArray.
156//
157TObjArray *MAnalogSignal::Discriminate(Float_t threshold, Float_t len) const
158{
159 TObjArray *ttl = new TObjArray;
160 ttl->SetOwner();
161
162 // The time after which we start searching for a falling or leading
163 // edge at threshold after a leading or falling edge respectively.
164 // This value has mainly numerical reasons. If starting the search
165 // too early we might end up in an endless loop finding the same
166 // value again and again. This just means that a glitch above or
167 // below the threshold which is shorter than this value can
168 // stay unnoticed. This shouldn't hurt.
169 const Double_t deadtime = 1e-4;
170
171 // FIXME: Are local maximum/minima handled correctly?
172
173 const MExtralgoSpline sp(GetArray(), fN, fDer1.GetArray(), fDer2.GetArray());
174
175 Double_t x1 = 0;
176 Double_t x2 = 0;
177
178 while (1)
179 {
180 x1 = sp.SearchYup(x2+deadtime, threshold);
181 if (x1<0)
182 break;
183
184 const Bool_t rising = sp.Deriv1(x1)>0;
185 if (!rising)
186 {
187 // The last value might just have been a local max/min
188 // or its period was short than 1e-4
189 x2 = x1;
190 //gLog << warn << "Rising edge expected at " << x1 << " (after " << x2 << ", N=" << fN << ")" << endl;
191 continue;
192 }
193
194 x2 = sp.SearchYup(x1+deadtime, threshold);
195 if (x2<0)
196 break;
197
198 const Bool_t falling = sp.Deriv1(x2)<=0;
199 if (!falling)
200 {
201 // The last value might just have been a local max/min
202 // or its period was short than 1e-4
203 x1 = x2;
204 //gLog << warn << "Falling edge expected at " << x2 << " (after " << x1 << " N=" << fN << ")" << endl;
205 continue;
206 }
207
208 MDigitalSignal *sig = new MDigitalSignal(x1, len>0?len:x2-x1);
209
210 // In case of a fixed length we have to check for possible overlapping
211 if (len>0 && ttl->GetEntriesFast()>0)
212 {
213 // FIXME: What if in such a case the electronics is just dead?
214 MDigitalSignal *last = static_cast<MDigitalSignal*>(ttl->Last());
215 // Combine both signals to one if they overlap
216 if (last->Combine(*sig))
217 {
218 // Both signals overlap and have been combined into the existing one
219 delete sig;
220 continue;
221 }
222 // The signals don't overlap we add the new signal as usual
223 }
224
225 // Add the new signal to the list of signals
226 ttl->Add(sig);
227 }
228
229 if (x1>=0)
230 gLog << warn << "Falling edge expected before end at N=" << fN << "!" << endl;
231
232 return ttl;
233}
Note: See TracBrowser for help on using the repository browser.