source: trunk/MagicSoft/Mars/msignal/MExtractTimeAndCharge.cc@ 8294

Last change on this file since 8294 was 8294, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 14.2 KB
Line 
1/* ======================================================================== *\
2! $Name: not supported by cvs2svn $:$Id: MExtractTimeAndCharge.cc,v 1.61 2007-02-03 15:10:14 tbretz Exp $
3! --------------------------------------------------------------------------
4!
5! *
6! * This file is part of MARS, the MAGIC Analysis and Reconstruction
7! * Software. It is distributed to you in the hope that it can be a useful
8! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
9! * It is distributed WITHOUT ANY WARRANTY.
10! *
11! * Permission to use, copy, modify and distribute this software and its
12! * documentation for any purpose is hereby granted without fee,
13! * provided that the above copyright notice appear in all copies and
14! * that both that copyright notice and this permission notice appear
15! * in supporting documentation. It is provided "as is" without express
16! * or implied warranty.
17! *
18!
19!
20! Author(s): Markus Gaug, 05/2004 <mailto:markus@ifae.es>
21! Author(s): Thomas Bretz, 05/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
22!
23! Copyright: MAGIC Software Development, 2000-2006
24!
25!
26\* ======================================================================== */
27
28//////////////////////////////////////////////////////////////////////////////
29//
30// MExtractTimeAndCharge
31//
32// Base class for the signal extractors which extract the arrival time
33// and the signal at the same time. Uses the functions
34// FindTimeAndChargeHiGain() and FindTimeAndChargeLoGain() to extract the signal and
35// substract the pedestal value.
36//
37// The following figure gives and example of possible inheritance trees.
38// An extractor class can inherit from each of the following base classes:
39// - MExtractor
40// - MExtractTime
41// - MExtractTimeAndCharge
42//
43//Begin_Html
44/*
45<img src="images/ExtractorClasses.gif">
46*/
47//End_Html
48//
49// The following variables have to be set by the derived class and
50// do not have defaults:
51// - fNumHiGainSamples
52// - fNumLoGainSamples
53// - fSqrtHiGainSamples
54// - fSqrtLoGainSamples
55//
56// Input Containers:
57// MRawEvtData
58// MRawRunHeader
59// MPedestalCam
60//
61// Output Containers:
62// MArrivalTimeCam
63// MExtractedSignalCam
64//
65// For weired events check: Run 94127 Event 672, 1028
66//
67//////////////////////////////////////////////////////////////////////////////
68#include "MExtractTimeAndCharge.h"
69
70#include <TRandom.h>
71#include <TVector3.h>
72
73#include "MMath.h"
74
75#include "MLog.h"
76#include "MLogManip.h"
77
78#include "MParList.h"
79
80#include "MRawEvtPixelIter.h"
81#include "MRawRunHeader.h"
82
83#include "MArrivalTimeCam.h"
84#include "MArrivalTimePix.h"
85
86#include "MExtractedSignalCam.h"
87#include "MExtractedSignalPix.h"
88
89#include "MPedestalSubtractedEvt.h"
90
91ClassImp(MExtractTimeAndCharge);
92
93using namespace std;
94
95const Float_t MExtractTimeAndCharge::fgLoGainStartShift = -2.5;
96const Byte_t MExtractTimeAndCharge::fgLoGainSwitch = 120;
97
98// --------------------------------------------------------------------------
99//
100// Default constructor.
101//
102// Sets:
103// - fWindowSizeHiGain and fWindowSizeLoGain to 0
104// - fLoGainStartShift to fgLoGainStartShift
105// - fLoGainSwitch to fgLoGainSwitch
106//
107MExtractTimeAndCharge::MExtractTimeAndCharge(const char *name, const char *title)
108 : fWindowSizeHiGain(0), fWindowSizeLoGain(0)
109{
110 fName = name ? name : "MExtractTimeAndCharge";
111 fTitle = title ? title : "Base class for signal and time extractors";
112
113 SetLoGainStartShift();
114 SetLoGainSwitch();
115}
116
117// --------------------------------------------------------------------------
118//
119// The PreProcess searches for the following input containers:
120// - MRawEvtData
121// - MRawRunHeader
122// - MPedestalCam
123//
124// The following output containers are also searched and created if
125// they were not found:
126//
127// - MExtractedSignalCam
128// - MArrivalTimeCam
129//
130Int_t MExtractTimeAndCharge::PreProcess(MParList *pList)
131{
132 if (!MExtractTime::PreProcess(pList))
133 return kFALSE;
134
135 fSignals = (MExtractedSignalCam*)pList->FindCreateObj("MExtractedSignalCam",AddSerialNumber(fNameSignalCam));
136 if (!fSignals)
137 return kFALSE;
138
139 *fLog << flush << inf;
140 return kTRUE;
141}
142
143// --------------------------------------------------------------------------
144//
145// The ReInit calls:
146// - MExtractor::ReInit()
147//
148// Call:
149// - MArrivalTimeCam::SetUsedFADCSlices(fHiGainFirst, fHiGainLast, fNumHiGainSamples,
150// fLoGainFirst, fLoGainLast, fNumLoGainSamples);
151// - InitArrays();
152//
153Bool_t MExtractTimeAndCharge::ReInit(MParList *pList)
154{
155 if (!MExtractTime::ReInit(pList))
156 return kFALSE;
157
158 if (!InitArrays(fRunHeader->GetNumSamplesHiGain()+fRunHeader->GetNumSamplesLoGain()))
159 return kFALSE;
160
161 if (fSignals)
162 fSignals->SetUsedFADCSlices(fHiGainFirst, fHiGainLast, fNumHiGainSamples,
163 fLoGainFirst, fLoGainLast, fNumLoGainSamples);
164 return kTRUE;
165}
166
167// --------------------------------------------------------------------------
168//
169// Return the x-value lower than sat0 at which the signal has been
170// fallen bwlow maxcont/2. This time is determined using a simple second
171// order polynomial interpolation.
172//
173Double_t MExtractTimeAndCharge::GetSaturationTime(Int_t sat0, const Float_t *sig, Int_t maxcont) const
174{
175 const Int_t p = sat0>1 ? sat0-2 : sat0-1;
176 if (sat0<=0)
177 return 0;
178 if (sat0==1)
179 return sig[0]>maxcont/2 ? 0 : 0.5;
180
181 if (sig[p]>sig[p+1] || sig[p+1]>sig[p+2])
182 return sig[p+1]>maxcont/2 ? sat0-1 : sat0-0.5;
183
184 // Find the place at which the signal is maxcont/2
185 const TVector3 vx(sig[p], sig[p+1], sig[p+2]);
186 const TVector3 vy(p, p+1, p+2);
187
188 return MMath::InterpolParabLin(vx, vy, maxcont/2);
189}
190
191// --------------------------------------------------------------------------
192//
193// Calculate the integral of the FADC time slices and store them as a new
194// pixel in the MArrivalTimeCam container.
195// Calculate the integral of the FADC time slices and store them as a new
196// pixel in the MExtractedSignalCam container.
197// The functions FindTimeAndChargeHiGain() and FindTimeAndChargeLoGain() are
198// supposed to extract the signal themselves.
199//
200Int_t MExtractTimeAndCharge::Process()
201{
202 MRawEvtPixelIter pixel(fRawEvt);
203
204 while (pixel.Next())
205 {
206 const Int_t pixidx = pixel.GetPixelId();
207
208 const Float_t *sig = fSignal->GetSamples(pixidx);
209
210 const Int_t numh = pixel.GetNumHiGainSamples();
211
212 Int_t sathi0 = fHiGainFirst; // First slice to extract and first saturating slice
213 Int_t sathi1 = fHiGainLast; // Last slice to extract and last saturating slice
214
215 Int_t maxcont;
216 Int_t maxposhi = fSignal->GetMax(pixidx, sathi0, sathi1, maxcont);
217 // Would it be better to take lastsat-firstsat?
218 Int_t numsathi = fSignal->GetSaturation(pixidx, fSaturationLimit, sathi0, sathi1);
219
220 Float_t sumhi =0., deltasumhi =-1; // Set hi-gain of MExtractedSignalPix valid
221 Float_t timehi=0., deltatimehi=-1; // Set hi-gain of MArrivalTimePix valid
222
223 // Do not even try to extract the hi-gain if we have
224 // more than one saturating slice
225 const Int_t rangehi = fHiGainLast - fHiGainFirst + 1;
226
227 if (numsathi<2)
228 FindTimeAndChargeHiGain2(sig+fHiGainFirst, rangehi,
229 sumhi, deltasumhi, timehi, deltatimehi,
230 numsathi, maxposhi);
231
232 // If we have saturating slices try to get a better estimate
233 // of the arrival time than timehi or sathi0. This is
234 // usefull to know where to start lo-gain extraction.
235 if (numsathi>1)
236 {
237 timehi = GetSaturationTime(sathi0, sig, maxcont)-fHiGainFirst;
238 deltatimehi = 0;
239 }
240
241 // Make sure that in cases the time couldn't be correctly determined
242 // more meaningfull default values are assigned.
243 // For extractors like the digital filter and the spline
244 // we allow extracpolation by one slice.
245 if (deltatimehi>-0.5 && (timehi<-1 || timehi>=rangehi))
246 {
247 // Flag this as unreliable!
248 timehi = gRandom->Uniform(rangehi+1)-1;
249 // deltatimehi=-1;
250 }
251
252 timehi += fHiGainFirst;
253
254 Float_t sumlo =0, deltasumlo =-1; // invalidate logain of MExtractedSignalPix
255 Float_t timelo=0, deltatimelo=-1; // invalidate logain of MArrivalTimePix
256 Int_t numsatlo=0;
257
258 //
259 // Adapt the low-gain extraction range from the obtained high-gain time
260 //
261
262 // IN THIS CASE THE PIXEL SHOULD BE MARKED BAD!!!!
263 // MEANS: Hi gain has saturated, but the signal is to dim
264 // to extract the lo-gain properly
265 // This could happen because the maxcont was not extracted from
266 // all slices!
267 // THIS produces pulse positions ~= -1
268 // The signal might be handled in MCalibrateData, but hwat's about
269 // the arrival times in MCalibrateRelTime
270 if (numsathi>0 && maxcont<=fLoGainSwitch)
271 deltasumlo=deltasumhi=deltatimelo=deltatimehi=-1;
272
273 // If more than 8 hi-gain slices have saturated this is
274 // no physical event. We just assume that something with
275 // the extraction is wrong
276 if (numsathi>8) // FIXME: Should be something like 2?
277 deltasumhi=deltatimehi=-1;
278
279 // FIXME: What to do with the pixel if it saturates too early???
280 if (pixel.HasLoGain() && maxcont>fLoGainSwitch)
281 {
282 Int_t first = numh+fLoGainFirst;
283 Int_t last = numh+fLoGainLast;
284
285 // To determin the window in which the lo-gain is extracted
286 // clearly more information about the relation between the
287 // extraction window and the reslting time is necessary.
288 //
289 // numh + fLoGainStartShift == 14 / fLoGainStartShift=-1
290 //
291 // The lo-gain is expected to have its raising edge
292 // at timehi+numh+fOffsetLoGain. We start to search for the
293 // lo-gain fLoGainStartShift slices earlier.
294 //
295 // Instead of fLoGainStartShift the extractor should now how many
296 // slices before the expected raising edge the start of the
297 // search must be placed and from there we can step 1.5 slices
298 // back to be on the safe side.
299 //
300 // The jitter in the hi-/lo-gain offset ssems to be around +/-0.5
301 const Float_t tm = deltatimehi<0 ? -1.+fHiGainFirst : timehi;
302 first = TMath::FloorNint(tm+numh+fOffsetLoGain+fLoGainStartShift);
303
304 if (first<0)
305 first = 0;
306 if (first>last)
307 first=last;
308
309 /*
310 // Currently we have to stick to this check because at least
311 // the spline has arrays of this size...
312 if (first>last)
313 first = last;
314 if (first<numh+fLoGainFirst)
315 first = numh+fLoGainFirst;
316 */
317 Int_t satlo0 = first; // First slice to extract and first saturating slice
318 Int_t satlo1 = last; // Last slice to extract and last saturating slice
319
320 // Would it be better to take lastsat-firstsat?
321 Int_t maxlo;
322 Int_t maxposlo = fSignal->GetMax(pixidx, satlo0, satlo1, maxlo);
323 numsatlo = fSignal->GetSaturation(pixidx, fSaturationLimit, satlo0, satlo1);
324
325 const Int_t rangelo = last-first+1;
326 FindTimeAndChargeLoGain2(sig+first, rangelo,
327 sumlo, deltasumlo, timelo, deltatimelo,
328 numsatlo, maxposlo);
329
330 // If we have saturating slices try to get a better estimate
331 // of the arrival time than timehi or sathi0. This is
332 // usefull to know where to start lo-gain extraction.
333 if (numsatlo>1)
334 {
335 timelo = GetSaturationTime(satlo0, sig, maxlo)-numh-first;
336 deltatimelo = 0;
337 }
338
339 // Make sure that in cases the time couldn't be correctly determined
340 // more meaningfull default values are assigned
341 // For extractors like the digital filter and the spline
342 // we allow extracpolation by one slice.
343 if (deltatimelo>-0.5 && (timelo<-1 || timelo>=rangelo))
344 {
345 // Flag this as unreliable!
346 timelo = gRandom->Uniform(rangelo+1)-1;
347 //deltatimelo=-1;
348 }
349
350 timelo += first-numh;
351
352 // If more than 6 lo-gain slices have saturated this is
353 // no physical event. We just assume that something with
354 // the extraction is wrong
355 if (numsatlo>6)
356 deltasumlo=deltatimelo=-1;
357
358 //if (TMath::Abs(timelo-fOffsetLoGain - timehi)>1.0)
359 // deltatimelo = -1;
360 }
361
362
363 // Now store the result in the corresponding containers
364 MExtractedSignalPix &pix = (*fSignals)[pixidx];
365 MArrivalTimePix &tix = (*fArrTime)[pixidx];
366 pix.SetExtractedSignal(sumhi, deltasumhi, sumlo, deltasumlo);
367 pix.SetGainSaturation(numsathi, numsatlo);
368
369 tix.SetArrivalTime(timehi, deltatimehi, timelo-fOffsetLoGain, deltatimelo);
370 tix.SetGainSaturation(numsathi, numsatlo);
371 } /* while (pixel.Next()) */
372
373 fArrTime->SetReadyToSave();
374 fSignals->SetReadyToSave();
375
376 return kTRUE;
377}
378
379// --------------------------------------------------------------------------
380//
381// In addition to the resources of the base-class MExtractor:
382// MJPedestal.MExtractor.LoGainStartShift: -2.8
383//
384Int_t MExtractTimeAndCharge::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
385{
386 Bool_t rc = MExtractTime::ReadEnv(env, prefix, print);
387
388 if (IsEnvDefined(env, prefix, "LoGainStartShift", print))
389 {
390 fLoGainStartShift = GetEnvValue(env, prefix, "LoGainStartShift", fgLoGainStartShift);
391 SetLoGainStartShift(fLoGainStartShift);
392 rc = kTRUE;
393 }
394
395 if (IsEnvDefined(env, prefix, "LoGainSwitch", print))
396 {
397 fLoGainSwitch = GetEnvValue(env, prefix, "LoGainSwitch", fLoGainSwitch);
398 rc = kTRUE;
399 }
400
401 return rc;
402}
403
404void MExtractTimeAndCharge::Print(Option_t *o) const
405{
406 MExtractTime::Print(o);
407
408 *fLog << dec;
409 *fLog << " LoGainStartShift: " << fLoGainStartShift << endl;
410 *fLog << " LoGainSwitch: " << (Int_t)fLoGainSwitch << endl;
411}
Note: See TracBrowser for help on using the repository browser.