source: trunk/MagicSoft/Mars/msignal/MExtractSignal3.cc@ 4693

Last change on this file since 4693 was 3769, checked in by moralejo, 21 years ago
*** empty log message ***
File size: 10.5 KB
Line 
1/* ======================================================================== *\
2 !
3 ! *
4 ! * This file is part of MARS, the MAGIC 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 appear 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): Abelardo Moralejo, 4/2004 <mailto:moralejo@pd.infn.it>
19 !
20 ! Copyright: MAGIC Software Development, 2000-2004
21 !
22 !
23 \* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MExtractSignal3
28//
29// Calculate the signal integrating fWindowSize time slices, the same for
30// all pixels. The integrated slices change from event to event, since the
31// pulse positions in the FADC jump between events, but apparently in a
32// "coherent" fashion. We first loop over all pixels and find the one
33// which has the highest sum of fPeakSearchWindowSize (default: 4) consecutive
34// non-saturated high gain slices. The position of the peak in this pixel
35// determines the integration window position for all pixels of this event.
36// For the moment we neglect time delays between pixels (which are in most
37// cases small). The class is based on MExtractSignal2.
38//
39//////////////////////////////////////////////////////////////////////////////
40
41#include "MExtractSignal3.h"
42
43#include "MLog.h"
44#include "MLogManip.h"
45
46#include "MParList.h"
47
48#include "MRawEvtData.h"
49#include "MRawEvtPixelIter.h"
50
51#include "MPedestalCam.h"
52#include "MPedestalPix.h"
53
54#include "MExtractedSignalCam.h"
55#include "MExtractedSignalPix.h"
56
57ClassImp(MExtractSignal3);
58
59using namespace std;
60
61const Byte_t MExtractSignal3::fgSaturationLimit = 254;
62const Byte_t MExtractSignal3::fgFirst = 0;
63const Byte_t MExtractSignal3::fgLast = 14;
64const Byte_t MExtractSignal3::fgWindowSize = 6;
65const Byte_t MExtractSignal3::fgPeakSearchWindowSize = 4;
66
67// --------------------------------------------------------------------------
68//
69// Default constructor.
70//
71MExtractSignal3::MExtractSignal3(const char *name, const char *title)
72 : fNumHiGainSamples(15), fNumLoGainSamples(15), fSaturationLimit(fgSaturationLimit)
73{
74
75 fName = name ? name : "MExtractSignal3";
76 fTitle = title ? title : "Task to extract the signal from the FADC slices";
77
78 AddToBranchList("MRawEvtData.*");
79
80 SetWindows();
81}
82
83void MExtractSignal3::SetWindows(Byte_t windowh, Byte_t windowl, Byte_t peaksearchwindow)
84{
85 //
86 // Set windows to even number of slices due to clock noise (odd/even slice effect).
87 //
88 fWindowSizeHiGain = windowh & ~1;
89 fWindowSizeLoGain = windowl & ~1;
90 fPeakSearchWindowSize = peaksearchwindow & ~1;
91
92
93 if (fWindowSizeHiGain != windowh)
94 *fLog << endl << warn <<
95 "MExtractSignal3::SetWindows - Hi Gain window size has to be even, set to: "
96 << int(fWindowSizeHiGain) << " samples " << endl;
97
98 if (fWindowSizeLoGain != windowl)
99 *fLog << endl << warn <<
100 "MExtractSignal3::SetWindows - Lo Gain window size has to be even, set to: "
101 << int(fWindowSizeLoGain) << " samples " << endl;
102
103 if (fPeakSearchWindowSize != peaksearchwindow)
104 *fLog << endl << warn <<
105 "MExtractSignal3::SetWindows - Peak Search window size has to be even, set to: "
106 << int(fPeakSearchWindowSize) << " samples " << endl;
107
108
109 if (fWindowSizeHiGain<2)
110 {
111 fWindowSizeHiGain = 2;
112 *fLog << warn << "MExtractSignal3::SetWindows - Hi Gain window size set to two samples" << endl;
113 }
114
115 if (fWindowSizeLoGain<2)
116 {
117 fWindowSizeLoGain = 2;
118 *fLog << warn << "MExtractSignal3::SetWindows - Lo Gain window size set to two samples" << endl;
119 }
120
121 if (fPeakSearchWindowSize<2)
122 {
123 fPeakSearchWindowSize = 2;
124 *fLog << warn << "MExtractSignal3::SetWindows - Peak Search window size set to two samples" << endl;
125 }
126
127
128 if (fWindowSizeHiGain > fNumHiGainSamples)
129 {
130 fWindowSizeHiGain = fNumHiGainSamples & ~1;
131 *fLog << warn << "MExtractSignal3::SetWindows - Hi Gain window size set to "
132 << int(fWindowSizeHiGain) << " samples " << endl;
133 }
134
135 if (fWindowSizeLoGain > fNumLoGainSamples)
136 {
137 fWindowSizeLoGain = fNumLoGainSamples & ~1;
138 *fLog << warn << "MExtractSignal3::SetWindows - Lo Gain window size set to "
139 << int(fWindowSizeLoGain) << " samples " << endl;
140 }
141
142 fWindowSqrtHiGain = TMath::Sqrt((Float_t)fWindowSizeHiGain);
143 fWindowSqrtLoGain = TMath::Sqrt((Float_t)fWindowSizeLoGain);
144
145}
146
147
148// --------------------------------------------------------------------------
149//
150// The PreProcess searches for the following input containers:
151// - MRawEvtData
152// - MPedestalCam
153//
154// The following output containers are also searched and created if
155// they were not found:
156//
157// - MExtractedSignalCam
158//
159Int_t MExtractSignal3::PreProcess(MParList *pList)
160{
161 fRawEvt = (MRawEvtData*)pList->FindObject(AddSerialNumber("MRawEvtData"));
162 if (!fRawEvt)
163 {
164 *fLog << err << AddSerialNumber("MRawEvtData") << " not found... aborting." << endl;
165 return kFALSE;
166 }
167
168 fSignals = (MExtractedSignalCam*)pList->FindCreateObj(AddSerialNumber("MExtractedSignalCam"));
169 if (!fSignals)
170 return kFALSE;
171
172 //
173 // FIXME? We should keep track in MExtractedSignalCam of the signal extraction method used.
174 //
175 fSignals->SetUsedFADCSlices(0, fNumHiGainSamples-1, (Float_t)fWindowSizeHiGain,
176 0, fNumLoGainSamples-1, (Float_t)fWindowSizeLoGain);
177
178 fPedestals = (MPedestalCam*)pList->FindObject(AddSerialNumber("MPedestalCam"));
179 if (!fPedestals)
180 {
181 *fLog << err << AddSerialNumber("MPedestalCam") << " not found... aborting" << endl;
182 return kFALSE;
183 }
184
185 return kTRUE;
186}
187
188// --------------------------------------------------------------------------
189//
190// FindPeak
191// Finds highest sum of "window" consecutive FADC slices in a pixel, and store
192// in "startslice" the first slice of the group which yields the maximum sum.
193// In "max" the value of the maximum sum is stored, in "sat" the number of
194// saturated slices.
195//
196void MExtractSignal3::FindPeak(Byte_t *ptr, Byte_t window, Byte_t &startslice,
197 Int_t &max, Int_t &sat) const
198{
199 const Byte_t *end = ptr + fNumHiGainSamples;
200
201 Int_t sum=0;
202
203 //
204 // Calculate the sum of the first "window" slices
205 //
206 sat = 0;
207 Byte_t *p = ptr;
208
209 while (p<ptr+window)
210 {
211 sum += *p;
212 if (*p++ >= fSaturationLimit)
213 sat++;
214 }
215
216 //
217 // Check for saturation in all other slices
218 //
219 while (p<end)
220 if (*p++ >= fSaturationLimit)
221 sat++;
222
223 //
224 // Calculate the i-th sum of n as
225 // sum_i+1 = sum_i + slice[i+window] - slice[i]
226 // This is fast and accurate (because we are using int's)
227 //
228 max=sum;
229 for (p=ptr; p+window<end; p++)
230 {
231 sum += *(p+window) - *p;
232 if (sum > max)
233 {
234 max = sum;
235 startslice = p-ptr;
236 }
237 }
238
239 return;
240}
241
242// --------------------------------------------------------------------------
243//
244// FindSignal
245// Adds up "window" slices starting in slice to which "ptr" points. The result
246// is stored in "sum", and the number of saturated slices in "sat".
247//
248void MExtractSignal3::FindSignal(Byte_t *ptr, Byte_t window, Int_t &sum, Int_t &sat) const
249{
250 //
251 // Calculate the sum of the "window" slices starting in ptr
252 //
253 sum=0;
254 sat = 0;
255 Byte_t *p = ptr;
256
257 while (p<ptr+window)
258 {
259 sum += *p;
260 if (*p++ >= fSaturationLimit)
261 sat++;
262 }
263
264 return;
265}
266
267// --------------------------------------------------------------------------
268//
269// Process
270// First find the pixel with highest sum of fPeakSearchWindowSize slices (default:4)
271// "startslice" will mark the slice at which the highest sum begins for that pixel.
272// Then define the beginning of the integration window for ALL pixels as the slice
273// before that: startslice-1 (this is somehow arbitrary), unless of course startslice=0,
274// in which case we start at 0. We will also check that the integration window does not
275// go beyond the FADC limits.
276//
277Int_t MExtractSignal3::Process()
278{
279 MRawEvtPixelIter pixel(fRawEvt);
280
281 Int_t sat;
282 Int_t maxsumhi = 0;
283 Byte_t startslice;
284 Byte_t hiGainFirst = 0;
285 Byte_t loGainFirst = 0;
286
287 while (pixel.Next())
288 {
289 Int_t sumhi;
290 sat = 0;
291
292 FindPeak(pixel.GetHiGainSamples(), fPeakSearchWindowSize, startslice, sumhi, sat);
293 if (sumhi > maxsumhi && sat == 0 )
294 {
295 maxsumhi = sumhi;
296 if (startslice > 0)
297 hiGainFirst = startslice-1;
298 else
299 hiGainFirst = 0;
300 }
301 }
302
303
304 loGainFirst = hiGainFirst;
305
306 // Make sure we will not integrate beyond the hi gain limit:
307 if (hiGainFirst+fWindowSizeHiGain > pixel.GetNumHiGainSamples())
308 hiGainFirst = pixel.GetNumHiGainSamples()-fWindowSizeHiGain;
309
310 // Make sure we will not integrate beyond the lo gain limit:
311 if (loGainFirst+fWindowSizeLoGain > pixel.GetNumLoGainSamples())
312 loGainFirst = pixel.GetNumLoGainSamples()-fWindowSizeLoGain;
313
314 pixel.Reset();
315 fSignals->Clear();
316
317 sat = 0;
318 while (pixel.Next())
319 {
320 //
321 // Find signal in hi- and lo-gain
322 //
323 Int_t sumhi, sathi;
324
325 FindSignal(pixel.GetHiGainSamples()+hiGainFirst, fWindowSizeHiGain, sumhi, sathi);
326
327 Int_t sumlo=0;
328 Int_t satlo=0;
329 if (pixel.HasLoGain())
330 {
331 FindSignal(pixel.GetLoGainSamples()+loGainFirst, fWindowSizeLoGain, sumlo, satlo);
332 if (satlo)
333 sat++;
334 }
335
336 //
337 // Take corresponding pedestal
338 //
339 const Int_t pixid = pixel.GetPixelId();
340
341 const MPedestalPix &ped = (*fPedestals)[pixid];
342 MExtractedSignalPix &pix = (*fSignals)[pixid];
343
344 const Float_t pedes = ped.GetPedestal();
345 const Float_t pedrms = ped.GetPedestalRms();
346
347 //
348 // Set extracted signal with pedestal substracted
349 //
350 pix.SetExtractedSignal(sumhi - pedes*fWindowSizeHiGain, pedrms*fWindowSqrtHiGain,
351 sumlo - pedes*fWindowSizeLoGain, pedrms*fWindowSqrtLoGain);
352
353 pix.SetGainSaturation(sathi, sathi, satlo);
354 } /* while (pixel.Next()) */
355
356 //
357 // Print a warning if event has saturationg lo-gains
358 //
359 if (sat)
360 *fLog << warn << "WARNING - Lo Gain saturated in " << sat << " pixels." << endl;
361
362 fSignals->SetReadyToSave();
363
364 return kTRUE;
365}
Note: See TracBrowser for help on using the repository browser.