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

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