source: trunk/MagicSoft/Mars/msignal/MExtractor.cc@ 8011

Last change on this file since 8011 was 7881, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 13.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): Markus Gaug, 04/2004 <mailto:markus@ifae.es>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24//////////////////////////////////////////////////////////////////////////////
25//
26// MExtractor
27// ==========
28//
29// Base class for the signal extractors, used the functions
30// FindSignalHiGain() and FindSignalLoGain() to extract the signal and
31// substract the pedestal value
32//
33// The following variables have to be set by the derived class and
34// do not have defaults:
35// - fNumHiGainSamples
36// - fNumLoGainSamples
37// - fSqrtHiGainSamples
38// - fSqrtLoGainSamples
39//
40// The signal extractor classes can be setup from an environmental
41// setup file. For more information see ReadEnv and MEvtLoop::ReadEnv
42//
43//
44// IMPORTANT: For all classes you derive from MExtractor make sure that:
45// - Print() is correctly implemented
46// - Clone() works
47// - Class Version number != 0 and the I/O works PERFECTLY
48// - only data members which are necessary for the setup (not the ones
49// created in PreProcess and Process) are written
50// - the version number is maintained!
51// - If the flag fNoiseCalculation is set, the signal extractor should
52// calculate the pure noise contriubtion from a fixed window in time.
53//
54// The following figure gives and example of possible inheritance trees.
55// An extractor class can inherit from each of the following base classes:
56// - MExtractor
57// - MExtractTime
58// - MExtractTimeAndCharge
59//
60//Begin_Html
61/*
62<img src="images/ExtractorClasses.gif">
63*/
64//End_Html
65//
66// Class Version 6:
67// +Float_t fResolutionPerPheHiGain; // Extractor-dependent charge resolution per phe for high-gain (see TDAS-0502).
68// +Float_t fResolutionPerPheLoGain; // Extractor-dependent charge resolution per phe for low-gain (see TDAS-0502).
69//
70//
71// Input Containers:
72// MRawEvtData
73// MRawRunHeader
74// MPedestalCam
75//
76// Output Containers:
77// MExtractedSignalCam
78//
79//////////////////////////////////////////////////////////////////////////////
80#include "MExtractor.h"
81
82#include <fstream>
83
84#include "MLog.h"
85#include "MLogManip.h"
86
87#include "MParList.h"
88
89#include "MRawEvtData.h"
90#include "MRawEvtPixelIter.h"
91#include "MRawRunHeader.h"
92
93#include "MPedestalCam.h"
94#include "MPedestalPix.h"
95
96#include "MExtractedSignalCam.h"
97#include "MExtractedSignalPix.h"
98
99ClassImp(MExtractor);
100
101using namespace std;
102
103const Byte_t MExtractor::fgSaturationLimit = 250;
104const TString MExtractor::fgNamePedestalCam = "MPedestalCam";
105const TString MExtractor::fgNameSignalCam = "MExtractedSignalCam";
106const Float_t MExtractor::fgOffsetLoGain = 1.51; // 5 ns
107
108// --------------------------------------------------------------------------
109//
110// Default constructor.
111//
112// Set:
113// - all pointers to NULL
114// - all variables to 0
115// - fSaturationLimit to fgSaturationLimit
116// - fNamePedestalCam to fgNamePedestalCam
117// - fNameSignalCam to fgNameSignalCam
118// - fNoiseCalculation to kFALSE
119//
120// Call:
121// - AddToBranchList("MRawEvtData.*")
122//
123MExtractor::MExtractor(const char *name, const char *title)
124 : fResolutionPerPheHiGain(0), fResolutionPerPheLoGain(0),
125 fPedestals(NULL), fSignals(NULL), fRawEvt(NULL), fRunHeader(NULL),
126 fHiLoLast(0), fNumHiGainSamples(0), fNumLoGainSamples(0)
127{
128 fName = name ? name : "MExtractor";
129 fTitle = title ? title : "Base class for signal extractors";
130
131 AddToBranchList("MRawEvtData.*");
132
133 SetNamePedestalCam();
134 SetNameSignalCam();
135 SetOffsetLoGain();
136 SetSaturationLimit();
137 SetNoiseCalculation(kFALSE);
138}
139
140void MExtractor::SetRange(Byte_t hifirst, Byte_t hilast, Byte_t lofirst, Byte_t lolast)
141{
142
143 Clear();
144
145 fHiGainFirst = hifirst;
146 fHiGainLast = hilast;
147
148 fLoGainFirst = lofirst;
149 fLoGainLast = lolast;
150}
151
152//-----------------------------------------------------------------------
153//
154// - Set the variable fHiLoLast to 0 (will be initialized later in ReInit()
155// - Get the pointers to:
156// MRawEvtData
157// MRawRunHeader
158// MPedestalCam
159//
160Int_t MExtractor::PreProcessStd(MParList *pList)
161{
162
163 fRawEvt = (MRawEvtData*)pList->FindObject(AddSerialNumber("MRawEvtData"));
164 if (!fRawEvt)
165 {
166 *fLog << err << AddSerialNumber("MRawEvtData") << " not found... aborting." << endl;
167 return kFALSE;
168 }
169
170 fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader"));
171 if (!fRunHeader)
172 {
173 *fLog << err << AddSerialNumber("MRawRunHeader") << " not found... aborting." << endl;
174 return kFALSE;
175 }
176
177
178 if (fPedestals)
179 return kTRUE;
180
181 fPedestals = (MPedestalCam*)pList->FindObject(AddSerialNumber(fNamePedestalCam), "MPedestalCam");
182 if (!fPedestals)
183 {
184 *fLog << err << AddSerialNumber(fNamePedestalCam) << " [MPedestalCam] not found... aborting" << endl;
185 return kFALSE;
186 }
187
188 return kTRUE;
189}
190
191// --------------------------------------------------------------------------
192//
193// The PreProcess searches for the following input containers:
194// - MRawEvtData
195// - MRawRunHeader
196// - MPedestalCam
197//
198// The following output containers are also searched and created if
199// they were not found:
200//
201// - MExtractedSignalCam
202//
203Int_t MExtractor::PreProcess(MParList *pList)
204{
205 fSignals = (MExtractedSignalCam*)pList->FindCreateObj("MExtractedSignalCam",AddSerialNumber(fNameSignalCam));
206 if (!fSignals)
207 return kFALSE;
208
209 return PreProcessStd(pList);
210}
211
212// --------------------------------------------------------------------------
213//
214// The ReInit searches for:
215// - MRawRunHeader::GetNumSamplesHiGain()
216// - MRawRunHeader::GetNumSamplesLoGain()
217//
218// In case that the variable fLoGainLast is smaller than
219// the even part of the number of samples obtained from the run header, a
220// warning is given an the range is set back accordingly. A call to:
221// - SetRange(fHiGainFirst, fHiGainLast, fLoGainFirst, fLoGainLast-diff)
222// is performed in that case. The variable diff means here the difference
223// between the requested range (fLoGainLast) and the available one. Note that
224// the functions SetRange() are mostly overloaded and perform more checks,
225// modifying the ranges again, if necessary.
226//
227// In case that the variable fHiGainLast is smaller than the available range
228// obtained from the run header, a warning is given that a part of the low-gain
229// samples are used for the extraction of the high-gain signal.
230//
231Bool_t MExtractor::ReInit(MParList *pList)
232{
233
234 const Int_t logainsamples = fRunHeader->GetNumSamplesLoGain();
235
236 Int_t lastdesired;
237 Int_t lastavailable;
238
239 if (logainsamples)
240 {
241
242 lastdesired = (Int_t)(fLoGainLast);
243 lastavailable = logainsamples-1;
244
245 if (lastavailable < 0)
246 *fLog << warn << GetDescriptor() << " - WARNING: Number of available Low-Gain Slices is smaller than or equal zero!" << endl;
247
248 if (lastdesired > lastavailable)
249 {
250 const Int_t diff = lastdesired - lastavailable;
251
252 *fLog << endl;
253 *fLog << warn << GetDescriptor() << ": Selected Lo Gain FADC Window [";
254 *fLog << Form("%2i,%2i", (int)fLoGainFirst, lastdesired);
255 *fLog << "] ranges out of the available limits: [0," << Form("%2i", lastavailable) << "]" << endl;
256 *fLog << GetDescriptor() << ": Will reduce the upper edge to " << (int)(fLoGainLast - diff) << endl;
257 SetRange(fHiGainFirst, fHiGainLast, fLoGainFirst, fLoGainLast-diff);
258 }
259 }
260 else
261 SetRange(fHiGainFirst, fHiGainLast, 0,0);
262
263 const Int_t higainsamples = fRunHeader->GetNumSamplesHiGain();
264
265 if (higainsamples <= 0)
266 {
267 *fLog << err << GetDescriptor();
268 *fLog << " - ERROR: Number of available High-Gain Slices is smaller than or equal zero!" << endl;
269 return kFALSE;
270 }
271
272 lastdesired = (Int_t)fHiGainLast;
273 lastavailable = higainsamples-1;
274
275 if (lastdesired > lastavailable)
276 {
277 const Int_t diff = lastdesired - lastavailable;
278
279 *fLog << endl;
280 *fLog << inf << GetDescriptor() << ": Selected Hi Gain FADC Window [";
281 *fLog << Form("%2i,%2i", (int)fHiGainFirst,lastdesired);
282 *fLog << "] ranges out of the available limits: [0," << Form("%2i", lastavailable) << "]" << endl;
283 *fLog << inf << GetDescriptor() << ": Will use ";
284 *fLog << Form("%2i", diff) << " samples from the Low-Gain for the High-Gain extraction";
285 *fLog << endl;
286
287 fHiGainLast -= diff;
288 fHiLoLast = diff;
289 }
290
291 return kTRUE;
292}
293
294// --------------------------------------------------------------------------
295//
296// Calculate the integral of the FADC time slices and store them as a new
297// pixel in the MExtractedSignalCam container.
298//
299Int_t MExtractor::Process()
300{
301
302 MRawEvtPixelIter pixel(fRawEvt);
303
304 while (pixel.Next())
305 {
306 Float_t sumhi = 0.;
307 Byte_t sathi = 0;
308
309 FindSignalHiGain(pixel.GetHiGainSamples()+fHiGainFirst, pixel.GetLoGainSamples(), sumhi, sathi);
310
311 Float_t sumlo = 0.;
312 Byte_t satlo = 0;
313
314 if (pixel.HasLoGain())
315 FindSignalLoGain(pixel.GetLoGainSamples()+fLoGainFirst, sumlo, satlo);
316
317 const Int_t pixid = pixel.GetPixelId();
318
319 const MPedestalPix &ped = (*fPedestals)[pixid];
320 MExtractedSignalPix &pix = (*fSignals)[pixid];
321
322 const Float_t pedes = ped.GetPedestal();
323 const Float_t pedrms = ped.GetPedestalRms();
324
325 pix.SetExtractedSignal(sumhi - pedes*fNumHiGainSamples, pedrms*fSqrtHiGainSamples,
326 sumlo - pedes*fNumLoGainSamples, pedrms*fSqrtLoGainSamples);
327
328 pix.SetGainSaturation(sathi, satlo);
329
330 } /* while (pixel.Next()) */
331
332 fSignals->SetReadyToSave();
333
334 return kTRUE;
335}
336
337// --------------------------------------------------------------------------
338//
339// Implementation of SavePrimitive. Used to write the call to a constructor
340// to a macro. In the original root implementation it is used to write
341// gui elements to a macro-file.
342//
343void MExtractor::StreamPrimitive(ostream &out) const
344{
345 out << " " << ClassName() << " " << GetUniqueName() << "(\"";
346 out << "\"" << fName << "\", \"" << fTitle << "\");" << endl;
347
348 if (fSaturationLimit!=fgSaturationLimit)
349 {
350 out << " " << GetUniqueName() << ".SetSaturationLimit(";
351 out << (int)fSaturationLimit << ");" << endl;
352 }
353
354 out << " " << GetUniqueName() << ".SetRange(";
355 out << (int)fHiGainFirst;
356 out << ", " << (int)fHiGainLast;
357 out << ", " << (int)fLoGainFirst;
358 out << ", " << (int)fLoGainLast;
359 out << ");" << endl;
360}
361
362// --------------------------------------------------------------------------
363//
364// Read the setup from a TEnv, eg:
365// MJPedestal.MExtractor.HiGainFirst: 5
366// MJPedestal.MExtractor.LoGainFirst: 5
367// MJPedestal.MExtractor.HiGainLast: 10
368// MJPedestal.MExtractor.LoGainLast: 10
369// MJPedestal.MExtractor.SaturationLimit: 88
370//
371Int_t MExtractor::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
372{
373 Byte_t hf = fHiGainFirst;
374 Byte_t lf = fLoGainFirst;
375 Byte_t hl = fHiGainLast;
376 Byte_t ll = fLoGainLast;
377
378 Bool_t rc = kFALSE;
379
380 if (IsEnvDefined(env, prefix, "HiGainFirst", print))
381 {
382 hf = GetEnvValue(env, prefix, "HiGainFirst", hf);
383 rc = kTRUE;
384 }
385 if (IsEnvDefined(env, prefix, "LoGainFirst", print))
386 {
387 lf = GetEnvValue(env, prefix, "LoGainFirst", lf);
388 rc = kTRUE;
389 }
390
391 if (IsEnvDefined(env, prefix, "HiGainLast", print))
392 {
393 hl = GetEnvValue(env, prefix, "HiGainLast", hl);
394 rc = kTRUE;
395 }
396 if (IsEnvDefined(env, prefix, "LoGainLast", print))
397 {
398 ll = GetEnvValue(env, prefix, "LoGainLast", ll);
399 rc = kTRUE;
400 }
401
402 SetRange(hf, hl, lf, ll);
403
404 if (IsEnvDefined(env, prefix, "OffsetLoGain", print))
405 {
406 SetOffsetLoGain(GetEnvValue(env, prefix, "OffsetLoGain", fOffsetLoGain));
407 rc = kTRUE;
408 }
409
410 if (IsEnvDefined(env, prefix, "SaturationLimit", print))
411 {
412 SetSaturationLimit(GetEnvValue(env, prefix, "SaturationLimit", fSaturationLimit));
413 rc = kTRUE;
414 }
415
416 if (IsEnvDefined(env, prefix, "NoiseCalculation", print))
417 {
418 SetNoiseCalculation(GetEnvValue(env, prefix, "NoiseCalculation", fNoiseCalculation));
419 rc = kTRUE;
420 }
421
422 // Be carefull: Returning kERROR is not forseen in derived classes
423 return rc;
424}
425
426void MExtractor::Print(Option_t *o) const
427{
428 if (IsA()==MExtractor::Class())
429 *fLog << GetDescriptor() << ":" << endl;
430
431 *fLog << " Hi Gain Range: " << Form("%2d %2d", fHiGainFirst, fHiGainLast) << endl;
432 *fLog << " Lo Gain Range: " << Form("%2d %2d", fLoGainFirst, fLoGainLast) << endl;
433 *fLog << " Gain Overlap to Lo: " << Form("%2d", fHiLoLast) << endl;
434 *fLog << " Saturation Lim: " << Form("%3d", fSaturationLimit) << endl;
435 *fLog << " Num Samples Hi/Lo: " << Form("%2.1f %2.1f", fNumHiGainSamples, fNumLoGainSamples) << endl;
436 if (fPedestals)
437 *fLog << " Pedestals: " << fPedestals->GetName() << ", " << fPedestals << endl;
438}
Note: See TracBrowser for help on using the repository browser.