source: trunk/Mars/mbadpixels/MBadPixelsTreat.cc@ 14767

Last change on this file since 14767 was 10166, checked in by tbretz, 14 years ago
Removed the old obsolete cvs header line.
File size: 19.9 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): Oscar Blanch 12/2001 <mailto:blanch@ifae.es>
19! Author(s): Thomas Bretz 08/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
20! Author(s): Stefan Ruegamer <mailto:snruegam@astro.uni-wuerzburg.de>
21!
22! Copyright: MAGIC Software Development, 2000-2006
23!
24!
25\* ======================================================================== */
26
27/////////////////////////////////////////////////////////////////////////////
28//
29// MBadPixelsTreat
30//
31// You can use MBadPixelsTreat::SetUseInterpolation to replaced the
32// bad pixels by the average of its neighbors instead of unmapping
33// them. If you want to include the central pixel use
34// MBadPixelsTreat::SetUseCentralPixel. The bad pixels are taken from
35// an existing MBadPixelsCam.
36//
37// It check if there are enough neighbors to calculate the mean
38// If not, unmap the pixel. The minimum number of good neighbors
39// should be set using SetNumMinNeighbors
40//
41// If you want to interpolate unreliable pixels and unsuitable
42// (broken) pixels use SetHardTreatment().
43//
44//
45// Options:
46// --------
47// SetHardTreatment: Also interpolate unreliable pixels not only unsuitable
48// SetUseInterpolation: Interpolate pixels instead of unmapping them
49// SetUseCentralPixel: also use the pixel itself for interpolation
50// SetProcessPedestalRun: process the pedestals once per run/file
51// SetProcessPedestalEvt: process the pedestal once per event
52// SetProcessTimes: do interpolation of the arrival time
53//
54// If the arrival time treatment is switched on and "MPedPhotFromExtractor"
55// and "MPedPhotFromExtractorRndm" are found the pixel is filled with
56// a random gaus calculated from these two MPedPhotCams in the case
57// the pixels is detected as background.
58//
59//
60// Input Containers:
61// MSignalCam
62// MPedPhotCam
63// MBadPixelsCam
64// [MGeomCam]
65//
66// Output Containers:
67// MSignalCam
68//
69/////////////////////////////////////////////////////////////////////////////
70#include "MBadPixelsTreat.h"
71
72#include <fstream>
73
74#include <TEnv.h>
75#include <TRandom.h>
76#include <TObjString.h>
77
78//#include "MArrayD.h" // Used instead of TArrayD because operator[] has no range check
79
80#include "MLog.h"
81#include "MLogManip.h"
82
83#include "MParList.h"
84
85#include "MGeom.h"
86#include "MGeomCam.h"
87
88#include "MSignalPix.h"
89#include "MSignalCam.h"
90
91#include "MPedPhotPix.h"
92#include "MPedPhotCam.h"
93
94#include "MBadPixelsPix.h"
95#include "MBadPixelsCam.h"
96
97ClassImp(MBadPixelsTreat);
98
99using namespace std;
100
101static const TString gsDefName = "MBadPixelsTreat";
102static const TString gsDefTitle = "Task to treat bad pixels (interpolation, unmapping)";
103
104// --------------------------------------------------------------------------
105//
106// Default constructor.
107//
108MBadPixelsTreat::MBadPixelsTreat(const char *name, const char *title)
109 : fGeomCam(0), fEvt(0), fBadPixels(0), fPedPhot1(0), fPedPhot2(0),
110 fFlags(0), fNumMinNeighbors(3), fMaxArrivalTimeDiff(3.)
111{
112 fName = name ? name : gsDefName.Data();
113 fTitle = title ? title : gsDefTitle.Data();
114
115 SetUseInterpolation();
116 SetProcessPedestal();
117 SetProcessTimes();
118}
119
120// --------------------------------------------------------------------------
121//
122// Returns the status of a pixel. If kHardTreatment is set a pixel must
123// be unsuitable or uriliable to be treated. If not it is treated only if
124// it is unsuitable
125// (IsBad() checks for any flag)
126//
127Bool_t MBadPixelsTreat::IsPixelBad(Int_t idx) const
128{
129 return TESTBIT(fFlags, kHardTreatment) ? (*fBadPixels)[idx].IsBad():(*fBadPixels)[idx].IsUnsuitable();
130}
131
132void MBadPixelsTreat::AddNamePedPhotCam(const char *name)
133{
134 fNamePedPhotCams.Add(new TObjString(name));
135}
136
137// --------------------------------------------------------------------------
138//
139// - Try to find or create MBlindPixels in parameter list.
140// - get the MSignalCam from the parlist (abort if missing)
141// - if no pixels are given by the user try to determin the starfield
142// from the monte carlo run header.
143//
144Int_t MBadPixelsTreat::PreProcess (MParList *pList)
145{
146 fBadPixels = (MBadPixelsCam*)pList->FindObject(AddSerialNumber("MBadPixelsCam"));
147 if (!fBadPixels)
148 {
149 *fLog << err << AddSerialNumber("MBadPixelsCam") << " not found... aborting." << endl;
150 return kFALSE;
151 }
152
153 fEvt = (MSignalCam*)pList->FindObject(AddSerialNumber("MSignalCam"));
154 if (!fEvt)
155 {
156 *fLog << err << AddSerialNumber("MSignalCam") << " not found... aborting." << endl;
157 return kFALSE;
158 }
159
160 fGeomCam = 0;
161 if (!IsUseInterpolation())
162 return kTRUE;
163
164 fGeomCam = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam"));
165 if (!fGeomCam)
166 {
167 *fLog << err << AddSerialNumber("MGeomCam") << " not found - can't use interpolation... abort." << endl;
168 *fLog << " Use MBadPixelsTreat::SetUseInterpolation(kFALSE) to switch interpolation" << endl;
169 *fLog << " off and use unmapping instead." << endl;
170 return kFALSE;
171 }
172
173 const Bool_t proc = IsProcessPedestalEvt() || IsProcessPedestalRun();
174
175 if (fNamePedPhotCams.GetSize()>0 && !proc)
176 {
177 *fLog << err << "Pedestal list contains entries, but pedestal treatment is switched off... abort." << endl;
178 return kFALSE;
179 }
180
181 if (proc)
182 {
183 if (fNamePedPhotCams.GetSize()==0)
184 {
185 *fLog << inf << "No container names specified... using default: MPedPhotCam." << endl;
186 AddNamePedPhotCam();
187 }
188
189 fPedPhotCams.Clear();
190
191 TIter Next(&fNamePedPhotCams);
192 TObject *o=0;
193 while ((o=Next()))
194 {
195 TObject *p = pList->FindObject(AddSerialNumber(o->GetName()), "MPedPhotCam");
196 if (!p)
197 {
198 *fLog << err << AddSerialNumber(o->GetName()) << " [MPedPhotCam] not found... aborting." << endl;
199 return kFALSE;
200 }
201
202 fPedPhotCams.Add(p);
203 }
204 }
205
206 if (IsProcessTimes())
207 {
208 fPedPhot1 = (MPedPhotCam*)pList->FindObject("MPedPhotFromExtractor", "MPedPhotCam");
209 fPedPhot2 = (MPedPhotCam*)pList->FindObject("MPedPhotFromExtractorRndm", "MPedPhotCam");
210
211 *fLog << inf << "Additional no-signal-interpolation switched ";
212 *fLog << (fPedPhot1 && fPedPhot2 ? "on" : "off");
213 *fLog << "." << endl;
214
215 if (fPedPhot1 && fPedPhot2)
216 *fLog << "Maximum arrival time difference: " << fMaxArrivalTimeDiff << "ns" << endl;
217
218 }
219
220 *fLog << inf << "Minimum number of neighbor pixels: " << (int)fNumMinNeighbors << endl;
221
222 if (IsProcessPedestalEvt())
223 *fLog << "Processing Pedestals once per event..." << endl;
224 if (IsProcessPedestalRun())
225 *fLog << "Processing Pedestals once per run..." << endl;
226 if (IsProcessTimes())
227 *fLog << "Processing Arrival Times once per event..." << endl;
228
229 return kTRUE;
230}
231
232// --------------------------------------------------------------------------
233//
234// Replaces each pixel (signal, signal error, pedestal, pedestal rms)
235// by the average of its surrounding pixels.
236// If TESTBIT(fFlags, kUseCentralPixel) is set the central pixel is also
237// included.
238//
239void MBadPixelsTreat::InterpolateSignal() const
240{
241 const UShort_t entries = fGeomCam->GetNumPixels();
242
243 //
244 // Loop over all pixels
245 //
246 for (UShort_t i=0; i<entries; i++)
247 {
248 //
249 // Check whether pixel with idx i is blind
250 //
251 if (!IsPixelBad(i))
252 continue;
253
254 //
255 // Get the corresponding geometry and pedestal
256 //
257 MSignalPix &pix = (*fEvt)[i];
258 const MGeom &gpix = (*fGeomCam)[i];
259
260 // Do Not-Use-Central-Pixel
261 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
262
263 Int_t num = nucp ? 0 : 1;
264
265 Double_t nphot = nucp ? 0 : pix.GetNumPhotons();
266 Double_t perr = nucp ? 0 : Pow2(pix.GetErrorPhot());
267
268 //
269 // The values are rescaled to the small pixels area for the right comparison
270 //
271 const Double_t ratio = fGeomCam->GetPixRatio(i);
272
273 nphot *= ratio;
274 perr *= ratio;
275
276 //
277 // Loop over all its neighbors
278 //
279 const Int_t n = gpix.GetNumNeighbors();
280 for (int j=0; j<n; j++)
281 {
282 const UShort_t nidx = gpix.GetNeighbor(j);
283
284 //
285 // Do not use blind neighbors
286 //
287 if (IsPixelBad(nidx))
288 continue;
289
290 //
291 // Get the geometry for the neighbor
292 //
293 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
294
295 //
296 //The error is calculated as the quadratic sum of the errors
297 //
298 const MSignalPix &evtpix = (*fEvt)[nidx];
299
300 nphot += nratio*evtpix.GetNumPhotons();
301 perr += nratio*Pow2(evtpix.GetErrorPhot());
302
303 num++;
304 }
305
306 // Check if there are enough neighbors to calculate the mean
307 // If not, unmap the pixel. The maximum number of blind neighbors
308 // should be 2
309 if (num<fNumMinNeighbors)
310 {
311 pix.SetPixelUnmapped();
312 continue;
313 }
314
315 //
316 // Now the mean is calculated and the values rescaled back
317 // to the pixel area
318 //
319 nphot /= num*ratio;
320 perr = TMath::Sqrt(perr/(num*ratio));
321
322 pix.Set(nphot, perr);
323 }
324}
325
326// --------------------------------------------------------------------------
327//
328void MBadPixelsTreat::InterpolatePedestals(MPedPhotCam &pedphot) const
329{
330 const Int_t entries = pedphot.GetSize();
331
332 //
333 // Loop over all pixels
334 //
335 for (UShort_t i=0; i<entries; i++)
336 {
337 //
338 // Check whether pixel with idx i is blind
339 //
340 if (!IsPixelBad(i))
341 continue;
342
343 //
344 // Get the corresponding geometry and pedestal
345 //
346 const MGeom &gpix = (*fGeomCam)[i];
347 const MPedPhotPix &ppix = pedphot[i];
348
349 // Do Not-Use-Central-Pixel
350 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
351
352 Int_t num = nucp ? 0 : 1;
353
354 Double_t ped = nucp ? 0 : ppix.GetMean();
355 Double_t rms = nucp ? 0 : Pow2(ppix.GetRms());
356
357 //
358 // The values are rescaled to the small pixels area for the right comparison
359 //
360 const Double_t ratio = fGeomCam->GetPixRatio(i);
361
362 ped *= ratio;
363 rms *= ratio;
364
365 //
366 // Loop over all its neighbors
367 //
368 const Int_t n = gpix.GetNumNeighbors();
369 for (int j=0; j<n; j++)
370 {
371 const UShort_t nidx = gpix.GetNeighbor(j);
372
373 //
374 // Do not use blind neighbors
375 //
376 if (IsPixelBad(nidx))
377 continue;
378
379 //
380 // Get the geometry for the neighbor
381 //
382 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
383 const MPedPhotPix &nppix = pedphot[nidx];
384
385 //
386 //The error is calculated as the quadratic sum of the errors
387 //
388 ped += nratio*nppix.GetMean();
389 rms += nratio*Pow2(nppix.GetRms());
390
391 num++;
392 }
393
394 // Check if there are enough neighbors to calculate the mean
395 // If not, unmap the pixel. The minimum number of good neighbors
396 // should be fNumMinNeighbors
397 if (num<fNumMinNeighbors)
398 {
399 (*fEvt)[i].SetPixelUnmapped();
400 continue;
401 }
402
403 //
404 // Now the mean is calculated and the values rescaled back
405 // to the pixel area
406 //
407 ped /= num*ratio;
408 rms = TMath::Sqrt(rms/(num*ratio));
409
410 pedphot[i].Set(ped, rms);
411 }
412 pedphot.SetReadyToSave();
413}
414
415// --------------------------------------------------------------------------
416//
417// loop over all MPedPhotCam and interpolate them
418//
419void MBadPixelsTreat::InterpolatePedestals() const
420{
421 TIter Next(&fPedPhotCams);
422 MPedPhotCam *cam=0;
423 while ((cam=(MPedPhotCam*)Next()))
424 {
425 InterpolatePedestals(*cam);
426 cam->ReCalc(*fGeomCam, fBadPixels);
427 }
428}
429
430// --------------------------------------------------------------------------
431//
432void MBadPixelsTreat::InterpolateTimes() const
433{
434 const Int_t n = fEvt->GetNumPixels();
435 for (int i=0; i<n; i++)
436 {
437 // Check whether pixel with idx i is bad
438 if (!IsPixelBad(i))
439 continue;
440
441 // Geometry of bad pixel
442 const MGeom &gpix = (*fGeomCam)[i];
443
444 // Number of neighbor pixels
445 const Int_t n2 = gpix.GetNumNeighbors();
446
447 // Copy the arrival time of all neighboring bad pixels
448 // to a new array for simplicity
449 Double_t time[6];
450 Int_t cnt = 0;
451 for (Int_t j=0; j<n2; j++)
452 {
453 const Int_t idx = gpix.GetNeighbor(j);
454 if (!IsPixelBad(idx))
455 time[cnt++] = (*fEvt)[idx].GetArrivalTime();
456 }
457
458 // if there are too few neighbours, don't interpolate the pixel
459 //if ((cnt < 3 && n2 > 3) || (cnt < 2 && n2 == 3))
460 if (cnt<fNumMinNeighbors)
461 {
462 (*fEvt)[i].SetPixelUnmapped();
463 continue;
464 }
465
466 Double_t min = FLT_MAX; // Find minimum arrival time
467 Double_t max = -FLT_MAX; // Find maximum arrival time
468
469 Double_t sum2 = 0; // Sum of arrival times of the pixels
470 Int_t cnt2 = 0; // Number of pixels summed in sum2
471
472 for (Int_t j=0; j<cnt; j++)
473 {
474 const Double_t tm1 = time[j]; // time of one neighbor pixel
475 const Double_t tm2 = time[(j+1)%cnt]; // time of its neighbor pixel
476
477 // Calculate mean arrival time of pixel probably inside the shower
478 if (TMath::Abs(tm1 - tm2)<fMaxArrivalTimeDiff)
479 {
480 sum2 += tm1+tm2;
481 cnt2++;
482 }
483
484 // Find minimum arrival time
485 if (tm1<min)
486 min = tm1;
487
488 // Find maximum arrival time
489 if (tm1>max)
490 max = tm1;
491 }
492
493 // If less than two nbeighbors belong to a shower the pixel doesn't
494 // belong to the shower, too. Set the arrival time to a uniform
495 // random value, otherwise use the mean value of the pixels belonging
496 // to the shower.
497 if (cnt2<=2)
498 {
499 sum2 = gRandom->Uniform(max-min)+min; // FIXME? Set Seed value?
500
501 // Proceed with a treatment of the signal of empty pixels
502 // better than the interpolation. (FIXME: Maybe a function
503 // different from a gaussian could be a better choice...)
504 if (fPedPhot1 && fPedPhot2)
505 {
506 const Int_t aidx = gpix.GetAidx();
507 // This is to which bias level the signal fluctuates
508 const Double_t mean = fPedPhot1->GetArea(aidx).GetMean();
509 // This is how the signal fluctuates
510 const Double_t rms = fPedPhot2->GetArea(aidx).GetRms();
511 const Double_t phe = gRandom->Gaus(mean, rms);
512
513 (*fEvt)[i].SetNumPhotons(phe);
514 }
515 }
516 else
517 sum2 /= cnt2*2;
518
519 (*fEvt)[i].SetArrivalTime(sum2);
520 }
521}
522
523// --------------------------------------------------------------------------
524//
525// Removes all blind pixels from the analysis by setting their state
526// to unused.
527//
528void MBadPixelsTreat::Unmap() const
529{
530 const UShort_t entries = fEvt->GetNumPixels();
531
532 //
533 // remove the pixels in fPixelsIdx if they are set to be used,
534 // (set them to 'unused' state)
535 //
536 for (UShort_t i=0; i<entries; i++)
537 {
538 if (IsPixelBad(i))
539 (*fEvt)[i].SetPixelUnmapped();
540 }
541}
542
543// --------------------------------------------------------------------------
544//
545// Interpolate Pedestals if kProcessPedestal not set
546//
547Bool_t MBadPixelsTreat::ReInit(MParList *pList)
548{
549 if (IsUseInterpolation() && IsProcessPedestalRun())
550 InterpolatePedestals();
551 return kTRUE;
552}
553
554// --------------------------------------------------------------------------
555//
556// Treat the blind pixels
557//
558Int_t MBadPixelsTreat::Process()
559{
560 if (IsUseInterpolation())
561 {
562 InterpolateSignal();
563 if (IsProcessPedestalEvt())
564 InterpolatePedestals();
565 if (IsProcessTimes())
566 InterpolateTimes();
567 }
568 else
569 Unmap();
570
571 return kTRUE;
572}
573
574void MBadPixelsTreat::StreamPrimitive(ostream &out) const
575{
576 out << " MBadPixelsTreat " << GetUniqueName();
577 if (fName!=gsDefName || fTitle!=gsDefTitle)
578 {
579 out << "(\"" << fName << "\"";
580 if (fTitle!=gsDefTitle)
581 out << ", \"" << fTitle << "\"";
582 out <<")";
583 }
584 out << ";" << endl;
585
586 if (IsUseInterpolation())
587 out << " " << GetUniqueName() << ".SetUseInterpolation();" << endl;
588 if (IsUseCentralPixel())
589 out << " " << GetUniqueName() << ".SetUseCentralPixel();" << endl;
590 if (IsProcessPedestalRun())
591 out << " " << GetUniqueName() << ".SetProcessPedestalRun();" << endl;
592 if (IsProcessPedestalEvt())
593 out << " " << GetUniqueName() << ".SetProcessPedestalEvt();" << endl;
594 if (IsProcessTimes())
595 out << " " << GetUniqueName() << ".SetProcessTimes();" << endl;
596 if (IsHardTreatment())
597 out << " " << GetUniqueName() << ".SetHardTreatment();" << endl;
598 if (fNumMinNeighbors!=3)
599 out << " " << GetUniqueName() << ".SetNumMinNeighbors(" << (int)fNumMinNeighbors << ");" << endl;
600}
601
602// --------------------------------------------------------------------------
603//
604// Read the setup from a TEnv, eg:
605// MBadPixelsTreat.UseInterpolation: no
606// MBadPixelsTreat.UseCentralPixel: no
607// MBadPixelsTreat.HardTreatment: no
608// MBadPixelsTreat.ProcessPedestalRun: no
609// MBadPixelsTreat.ProcessPedestalEvt: no
610// MBadPixelsTreat.NumMinNeighbors: 3
611// MBadPixelsTreat.MaxArrivalTimeDiff: 0.9
612//
613Int_t MBadPixelsTreat::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
614{
615 Bool_t rc = kFALSE;
616 if (IsEnvDefined(env, prefix, "UseInterpolation", print))
617 {
618 rc = kTRUE;
619 SetUseInterpolation(GetEnvValue(env, prefix, "UseInterpolation", IsUseInterpolation()));
620 }
621 if (IsEnvDefined(env, prefix, "UseCentralPixel", print))
622 {
623 rc = kTRUE;
624 SetUseCentralPixel(GetEnvValue(env, prefix, "UseCentralPixel", IsUseCentralPixel()));
625 }
626 if (IsEnvDefined(env, prefix, "HardTreatment", print))
627 {
628 rc = kTRUE;
629 SetHardTreatment(GetEnvValue(env, prefix, "HardTreatment", IsHardTreatment()));
630 }
631 if (IsEnvDefined(env, prefix, "ProcessPedestalRun", print))
632 {
633 rc = kTRUE;
634 SetProcessPedestalRun(GetEnvValue(env, prefix, "ProcessPedestalRun", IsProcessPedestalRun()));
635 }
636 if (IsEnvDefined(env, prefix, "ProcessPedestalEvt", print))
637 {
638 rc = kTRUE;
639 SetProcessPedestalEvt(GetEnvValue(env, prefix, "ProcessPedestalEvt", IsProcessPedestalEvt()));
640 }
641 if (IsEnvDefined(env, prefix, "ProcessTimes", print))
642 {
643 rc = kTRUE;
644 SetProcessTimes(GetEnvValue(env, prefix, "ProcessTimes", IsProcessTimes()));
645 }
646 if (IsEnvDefined(env, prefix, "NumMinNeighbors", print))
647 {
648 rc = kTRUE;
649 SetNumMinNeighbors(GetEnvValue(env, prefix, "NumMinNeighbors", fNumMinNeighbors));
650 }
651 if (IsEnvDefined(env, prefix, "MaxArrivalTimeDiff", print))
652 {
653 rc = kTRUE;
654 SetMaxArrivalTimeDiff(GetEnvValue(env, prefix, "MaxArrivalTimeDiff", fMaxArrivalTimeDiff));
655 }
656 return rc;
657}
Note: See TracBrowser for help on using the repository browser.