source: trunk/MagicSoft/Mars/mbadpixels/MBadPixelsTreat.cc@ 4793

Last change on this file since 4793 was 4770, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 20.8 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!
21! Copyright: MAGIC Software Development, 2000-2004
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MBadPixelsTreat
29//
30// You can use MBadPixelsTreat::SetUseInterpolation to replaced the
31// bad pixels by the average of its neighbors instead of unmapping
32// them. If you want to include the central pixel use
33// MBadPixelsTreat::SetUseCentralPixel. The bad pixels are taken from
34// an existing MBadPixelsCam.
35//
36// It check if there are enough neighbors to calculate the mean
37// If not, unmap the pixel. The minimum number of good neighbors
38// should be set using SetNumMinNeighbors
39//
40// If you want to interpolate unreliable pixels and unsuitable
41// (broken) pixels use SetHardTreatment().
42//
43//
44// Options:
45// --------
46// SetHardTreatment: Also interpolate unreliable pixels not only unsuitable
47// SetUseInterpolation: Interpolate pixels instead of unmapping them
48// SetUseCentralPixel: also use the pixel itself for interpolation
49// SetProcessPedestalRun: process the pedestals once per run/file
50// SetProcessPedestalEvt: process the pedestal once per event
51// SetProcessTimes: also do some rough interpolation of the arrival time
52//
53//
54// Input Containers:
55// MCerPhotEvt
56// MPedPhotCam
57// MBadPixelsCam
58// [MGeomCam]
59//
60// Output Containers:
61// MCerPhotEvt
62//
63/////////////////////////////////////////////////////////////////////////////
64#include "MBadPixelsTreat.h"
65
66#include <fstream>
67
68#include <TEnv.h>
69
70#include "MArrayD.h" // Used instead of TArrayD because operator[] has no range check
71
72#include "MLog.h"
73#include "MLogManip.h"
74
75#include "MParList.h"
76
77#include "MGeomPix.h"
78#include "MGeomCam.h"
79
80#include "MCerPhotPix.h"
81#include "MCerPhotEvt.h"
82
83#include "MPedPhotPix.h"
84#include "MPedPhotCam.h"
85
86#include "MBadPixelsPix.h"
87#include "MBadPixelsCam.h"
88
89#include "MArrivalTime.h"
90
91ClassImp(MBadPixelsTreat);
92
93using namespace std;
94
95static const TString gsDefName = "MBadPixelsTreat";
96static const TString gsDefTitle = "Task to treat bad pixels (interpolation, unmapping)";
97
98// --------------------------------------------------------------------------
99//
100// Default constructor.
101//
102MBadPixelsTreat::MBadPixelsTreat(const char *name, const char *title)
103 : fFlags(0), fNumMinNeighbors(3), fNamePedPhotCam("MPedPhotCam")
104{
105 fName = name ? name : gsDefName.Data();
106 fTitle = title ? title : gsDefTitle.Data();
107
108 SetProcessPedestalRun();
109}
110
111// --------------------------------------------------------------------------
112//
113// Returns the status of a pixel. If kHardTreatment is set a pixel must
114// be unsuitable or uriliable to be treated. If not it is treated only if
115// it is unsuitable
116// (IsBad() checks for any flag)
117//
118Bool_t MBadPixelsTreat::IsPixelBad(Int_t idx) const
119{
120 return TESTBIT(fFlags, kHardTreatment) ? (*fBadPixels)[idx].IsBad():(*fBadPixels)[idx].IsUnsuitable() ;
121}
122
123// --------------------------------------------------------------------------
124//
125// - Try to find or create MBlindPixels in parameter list.
126// - get the MCerPhotEvt from the parlist (abort if missing)
127// - if no pixels are given by the user try to determin the starfield
128// from the monte carlo run header.
129//
130Int_t MBadPixelsTreat::PreProcess (MParList *pList)
131{
132 fBadPixels = (MBadPixelsCam*)pList->FindObject(AddSerialNumber("MBadPixelsCam"));
133 if (!fBadPixels)
134 {
135 *fLog << err << AddSerialNumber("MBadPixelsCam") << " not found... aborting." << endl;
136 return kFALSE;
137 }
138
139 fEvt = (MCerPhotEvt*)pList->FindObject(AddSerialNumber("MCerPhotEvt"));
140 if (!fEvt)
141 {
142 *fLog << err << AddSerialNumber("MCerPhotEvt") << " not found... aborting." << endl;
143 return kFALSE;
144 }
145
146 fGeomCam = 0;
147 if (!IsUseInterpolation())
148 return kTRUE;
149
150 fGeomCam = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam"));
151 if (!fGeomCam)
152 {
153 *fLog << err << AddSerialNumber("MGeomCam") << " not found - can't use interpolation... abort." << endl;
154 return kFALSE;
155 }
156
157 fPedPhot = 0;
158 if (IsProcessPedestalEvt() || IsProcessPedestalRun())
159 {
160 fPedPhot = (MPedPhotCam*)pList->FindObject(AddSerialNumber(fNamePedPhotCam), "MPedPhotCam");
161 if (!fPedPhot)
162 {
163 *fLog << err << AddSerialNumber("MPedPhotCam") << " not found... aborting." << endl;
164 return kFALSE;
165 }
166 }
167
168 fTimes = 0;
169 if (IsProcessTimes())
170 {
171 fTimes = (MArrivalTime*)pList->FindObject(AddSerialNumber("MArrivalTime"));
172 if (!fTimes)
173 {
174 *fLog << err << AddSerialNumber("MArrivalTime") << " not found... aborting." << endl;
175 return kFALSE;
176 }
177 }
178
179 if (IsProcessPedestalEvt())
180 *fLog << inf << "Processing Pedestals once per event..." << endl;
181 if (IsProcessPedestalRun())
182 *fLog << inf << "Processing Pedestals once per run..." << endl;
183 if (IsProcessTimes())
184 *fLog << inf << "Processing Arrival Times once per event..." << endl;
185
186 return kTRUE;
187}
188
189// --------------------------------------------------------------------------
190//
191// Replaces each pixel (signal, signal error, pedestal, pedestal rms)
192// by the average of its surrounding pixels.
193// If TESTBIT(fFlags, kUseCentralPixel) is set the central pixel is also
194// included.
195//
196void MBadPixelsTreat::InterpolateSignal() const
197{
198 const UShort_t entries = fGeomCam->GetNumPixels();
199
200 //
201 // Create arrays (FIXME: Check if its possible to create it only once)
202 //
203 MArrayD nphot(entries);
204 MArrayD perr(entries);
205
206 //
207 // Loop over all pixels
208 //
209 for (UShort_t i=0; i<entries; i++)
210 {
211 MCerPhotPix *pix = fEvt->GetPixById(i);
212
213 //
214 // Check whether pixel with idx i is blind
215 //
216 if (pix && !IsPixelBad(i))
217 continue;
218
219 //
220 // Get a pointer to this pixel. If it is not yet existing
221 // create a new entry for this pixel in MCerPhotEvt
222 //
223 if (!pix)
224 {
225 pix = fEvt->AddPixel(i, 0, 0);
226 (*fBadPixels)[i].SetUnsuitable(MBadPixelsPix::kUnsuitableEvt);
227 }
228
229 //
230 // Get the corresponding geometry and pedestal
231 //
232 const MGeomPix &gpix = (*fGeomCam)[i];
233
234 // Do Not-Use-Central-Pixel
235 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
236
237 Int_t num = nucp ? 0 : 1;
238
239 nphot[i] = nucp ? 0 : pix->GetNumPhotons();
240 perr[i] = nucp ? 0 : Pow2(pix->GetErrorPhot());
241
242 //
243 // The values are rescaled to the small pixels area for the right comparison
244 //
245 const Double_t ratio = fGeomCam->GetPixRatio(i);
246
247 nphot[i] *= ratio;
248 perr[i] *= ratio;
249
250 //
251 // Loop over all its neighbors
252 //
253 const Int_t n = gpix.GetNumNeighbors();
254 for (int j=0; j<n; j++)
255 {
256 const UShort_t nidx = gpix.GetNeighbor(j);
257
258 //
259 // Do not use blind neighbors
260 //
261 if (IsPixelBad(nidx))
262 continue;
263
264 //
265 // Check whether the neighbor has a signal stored
266 //
267 const MCerPhotPix *evtpix = fEvt->GetPixById(nidx);
268 if (!evtpix)
269 continue;
270
271 //
272 // Get the geometry for the neighbor
273 //
274 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
275
276 //
277 //The error is calculated as the quadratic sum of the errors
278 //
279 nphot[i] += nratio*evtpix->GetNumPhotons();
280 perr[i] += nratio* Pow2(evtpix->GetErrorPhot());
281
282 num++;
283 }
284
285 // Check if there are enough neighbors to calculate the mean
286 // If not, unmap the pixel. The maximum number of blind neighbors
287 // should be 2
288 if (num<fNumMinNeighbors)
289 {
290 pix->SetPixelUnmapped();
291 continue;
292 }
293
294 //
295 // Now the mean is calculated and the values rescaled back
296 // to the pixel area
297 //
298 nphot[i] /= (num*ratio);
299 perr[i] = TMath::Sqrt(perr[i]/(num*ratio));
300
301 pix->Set(nphot[i], perr[i]);
302 }
303}
304
305// --------------------------------------------------------------------------
306//
307void MBadPixelsTreat::InterpolatePedestals() const
308{
309 const Int_t entries = fPedPhot->GetSize();
310
311 // Create arrays (FIXME: Check if its possible to create it only once)
312 MArrayD ped(entries);
313 MArrayD rms(entries);
314
315 //
316 // Loop over all pixels
317 //
318 for (UShort_t i=0; i<entries; i++)
319 {
320 //
321 // Check whether pixel with idx i is blind
322 //
323 if (!IsPixelBad(i))
324 continue;
325
326 //
327 // Get the corresponding geometry and pedestal
328 //
329 const MGeomPix &gpix = (*fGeomCam)[i];
330 const MPedPhotPix &ppix = (*fPedPhot)[i];
331
332 // Do Not-Use-Central-Pixel
333 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
334
335 Int_t num = nucp ? 0 : 1;
336
337 ped[i] = nucp ? 0 : ppix.GetMean();
338 rms[i] = nucp ? 0 : Pow2(ppix.GetRms());
339
340 //
341 // The values are rescaled to the small pixels area for the right comparison
342 //
343 const Double_t ratio = fGeomCam->GetPixRatio(i);
344
345 ped[i] *= ratio;
346 rms[i] *= ratio;
347
348 //
349 // Loop over all its neighbors
350 //
351 const Int_t n = gpix.GetNumNeighbors();
352 for (int j=0; j<n; j++)
353 {
354 const UShort_t nidx = gpix.GetNeighbor(j);
355
356 //
357 // Do not use blind neighbors
358 //
359 if (IsPixelBad(nidx))
360 continue;
361
362 //
363 // Get the geometry for the neighbor
364 //
365 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
366 const MPedPhotPix &nppix = (*fPedPhot)[nidx];
367
368 //
369 //The error is calculated as the quadratic sum of the errors
370 //
371 ped[i] += nratio*nppix.GetMean();
372 rms[i] += nratio*Pow2(nppix.GetRms());
373
374 num++;
375 }
376
377 // Check if there are enough neighbors to calculate the mean
378 // If not, unmap the pixel. The minimum number of good neighbors
379 // should be fNumMinNeighbors
380 if (num < fNumMinNeighbors)
381 {
382 MCerPhotPix *pix =fEvt->GetPixById(i);
383 if (!pix)
384 pix = fEvt->AddPixel(i, 0, 0);
385 pix->SetPixelUnmapped();
386 continue;
387 }
388
389 //
390 // Now the mean is calculated and the values rescaled back
391 // to the pixel area
392 //
393 ped[i] /= (num*ratio);
394 rms[i] = TMath::Sqrt(rms[i]/(num*ratio));
395
396 (*fPedPhot)[i].Set(ped[i], rms[i]);
397 }
398}
399
400// --------------------------------------------------------------------------
401//
402void MBadPixelsTreat::InterpolateTimes() const
403{
404 Int_t n = fTimes->GetSize();
405
406 for (int i=0; i<n; i++)
407 {
408 //
409 // Check whether pixel with idx i is blind
410 //
411 if (!IsPixelBad(i))
412 continue;
413
414 //
415 // Get the corresponding geometry and pedestal
416 //
417 const MGeomPix &gpix = (*fGeomCam)[i];
418
419 const Int_t n0 = gpix.GetNumNeighbors();
420
421 MArrayD time(6);
422 for (int j=0; j<n0; j++)
423 time[j] = (*fTimes)[gpix.GetNeighbor(j)];
424
425 Int_t p0=0;
426 Int_t p1=0;
427
428 Double_t min=FLT_MAX;
429 for (int j=0; j<n0; j++)
430 for (int k=1; k<j+1; k++)
431 {
432 const Double_t diff = TMath::Abs(time[n0-k] - time[n0-k-j]);
433
434 if (diff>=min && diff<250)
435 continue;
436
437 p0 = n0-k;
438 p1 = n0-k-j;
439 min = diff;
440 }
441
442 if (TMath::Abs(time[p0] - time[p1])<250)
443 fTimes->SetTime(i, (time[p0]+time[p1])/2);
444 }
445}
446
447// --------------------------------------------------------------------------
448//
449// Replaces each pixel (signal, signal error, pedestal, pedestal rms)
450// by the average of its surrounding pixels.
451// If TESTBIT(fFlags, kUseCentralPixel) is set the central pixel is also
452// included.
453//
454// NT: Informations about the interpolated pedestals are added.
455// When the option Interpolated is called, the blind pixel with the new
456// values of signal and fluttuation is included in the calculation of
457// the Image Parameters.
458//
459/*
460void MBadPixelsTreat::Interpolate() const
461{
462 const UShort_t entries = fGeomCam->GetNumPixels();
463
464 //
465 // Create arrays
466 //
467 TArrayD nphot(entries);
468 TArrayD perr(entries);
469 TArrayD ped(entries);
470 TArrayD pedrms(entries);
471
472 //
473 // Loop over all pixels
474 //
475 for (UShort_t i=0; i<entries; i++)
476 {
477 MCerPhotPix *pix = fEvt->GetPixById(i);
478
479 //
480 // Check whether pixel with idx i is blind
481 //
482 if (pix && (*fBadPixels)[i].IsOK())
483 continue;
484
485 //
486 // Get a pointer to this pixel. If it is not yet existing
487 // create a new entry for this pixel in MCerPhotEvt
488 //
489 if (!pix)
490 {
491 pix = fEvt->AddPixel(i, 0, 0);
492 (*fBadPixels)[i].SetUnsuitable(MBadPixelsPix::kUnsuitableEvt);
493 }
494
495 //
496 // Get the corresponding geometry and pedestal
497 //
498 const MGeomPix &gpix = (*fGeomCam)[i];
499 const MPedPhotPix &ppix = (*fPedPhot)[i];
500
501 // Do Not-Use-Central-Pixel
502 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
503
504 Int_t num = nucp ? 0 : 1;
505
506 nphot[i] = nucp ? 0 : pix->GetNumPhotons();
507 ped[i] = nucp ? 0 : ppix.GetMean();
508 perr[i] = nucp ? 0 : Pow2(pix->GetErrorPhot());
509 pedrms[i] = nucp ? 0 : Pow2(ppix.GetRms());
510
511 //
512 // The values are rescaled to the small pixels area for the right comparison
513 //
514 const Double_t ratio = fGeomCam->GetPixRatio(i);
515
516 if (nucp)
517 {
518 nphot[i] *= ratio;
519 perr[i] *= ratio;
520 ped[i] *= ratio;
521 pedrms[i] *= ratio;
522 }
523
524 //
525 // Loop over all its neighbors
526 //
527 const Int_t n = gpix.GetNumNeighbors();
528 for (int j=0; j<n; j++)
529 {
530 const UShort_t nidx = gpix.GetNeighbor(j);
531
532 //
533 // Do not use blind neighbors
534 //
535 if ((*fBadPixels)[nidx].IsBad())
536 continue;
537
538 //
539 // Check whether the neighbor has a signal stored
540 //
541 const MCerPhotPix *evtpix = fEvt->GetPixById(nidx);
542 if (!evtpix)
543 continue;
544
545 //
546 // Get the geometry for the neighbor
547 //
548 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
549 MPedPhotPix &nppix = (*fPedPhot)[nidx];
550
551 //
552 // The error is calculated as the quadratic sum of the errors
553 //
554 nphot[i] += nratio*evtpix->GetNumPhotons();
555 ped[i] += nratio*nppix.GetMean();
556 perr[i] += nratio*Pow2(evtpix->GetErrorPhot());
557 pedrms[i] += nratio*Pow2(nppix.GetRms());
558
559 num++;
560 }
561
562 if (num<fNumMinNeighbors)
563 {
564 pix->SetPixelUnmapped();
565 nphot[i] = 0;
566 ped[i] = 0;
567 perr[i] = 0;
568 pedrms[i] = 0;
569 continue;
570 }
571
572 //
573 // Now the mean is calculated and the values rescaled back to the pixel area
574 //
575 nphot[i] /= num*ratio;
576 ped[i] /= num*ratio;
577 perr[i] = TMath::Sqrt(perr[i]/(num*ratio));
578 pedrms[i] = TMath::Sqrt(pedrms[i]/(num*ratio));
579
580 }
581
582 //
583 // Now the new pixel values are calculated and can be replaced in
584 // the corresponding containers
585 //
586 for (UShort_t i=0; i<entries; i++)
587 {
588 //
589 // Do not use blind neighbors
590 //
591 if ((*fBadPixels)[i].IsOK())
592 continue;
593
594 //
595 // It must exist, we have created it in the loop before.
596 //
597 fEvt->GetPixById(i)->Set(nphot[i], perr[i]);
598 (*fPedPhot)[i].Set(ped[i], pedrms[i]);
599 }
600}
601*/
602
603// --------------------------------------------------------------------------
604//
605// Removes all blind pixels from the analysis by setting their state
606// to unused.
607//
608void MBadPixelsTreat::Unmap() const
609{
610 const UShort_t entries = fEvt->GetNumPixels();
611
612 //
613 // remove the pixels in fPixelsIdx if they are set to be used,
614 // (set them to 'unused' state)
615 //
616 for (UShort_t i=0; i<entries; i++)
617 {
618 MCerPhotPix &pix = (*fEvt)[i];
619
620 if (IsPixelBad(pix.GetPixId()))
621 pix.SetPixelUnmapped();
622 }
623}
624
625// --------------------------------------------------------------------------
626//
627// Interpolate Pedestals if kProcessPedestal not set
628//
629Bool_t MBadPixelsTreat::ReInit(MParList *pList)
630{
631 if (IsUseInterpolation() && IsProcessPedestalRun())
632 InterpolatePedestals();
633 return kTRUE;
634}
635
636// --------------------------------------------------------------------------
637//
638// Treat the blind pixels
639//
640Int_t MBadPixelsTreat::Process()
641{
642 if (IsUseInterpolation())
643 {
644 InterpolateSignal();
645 if (IsProcessPedestalEvt())
646 InterpolatePedestals();
647 if (IsProcessTimes())
648 InterpolateTimes();
649 }
650 else
651 Unmap();
652
653 return kTRUE;
654}
655
656void MBadPixelsTreat::StreamPrimitive(ofstream &out) const
657{
658 out << " MBadPixelsTreat " << GetUniqueName();
659 if (fName!=gsDefName || fTitle!=gsDefTitle)
660 {
661 out << "(\"" << fName << "\"";
662 if (fTitle!=gsDefTitle)
663 out << ", \"" << fTitle << "\"";
664 out <<")";
665 }
666 out << ";" << endl;
667
668 if (IsUseInterpolation())
669 out << " " << GetUniqueName() << ".SetUseInterpolation();" << endl;
670 if (IsUseCentralPixel())
671 out << " " << GetUniqueName() << ".SetUseCentralPixel();" << endl;
672 if (IsProcessPedestalRun())
673 out << " " << GetUniqueName() << ".SetProcessPedestalRun();" << endl;
674 if (IsProcessPedestalEvt())
675 out << " " << GetUniqueName() << ".SetProcessPedestalEvt();" << endl;
676 if (IsProcessTimes())
677 out << " " << GetUniqueName() << ".SetProcessTimes();" << endl;
678 if (IsHardTreatment())
679 out << " " << GetUniqueName() << ".SetHardTreatment();" << endl;
680 if (fNumMinNeighbors!=3)
681 out << " " << GetUniqueName() << ".SetNumMinNeighbors(" << (int)fNumMinNeighbors << ");" << endl;
682}
683
684// --------------------------------------------------------------------------
685//
686// Read the setup from a TEnv, eg:
687// MBadPixelsTreat.UseInterpolation: no
688// MBadPixelsTreat.UseCentralPixel: no
689// MBadPixelsTreat.HardTreatment: no
690// MBadPixelsTreat.ProcessPedestalRun: no
691// MBadPixelsTreat.ProcessPedestalEvt: no
692// MBadPixelsTreat.NumMinNeighbors: 3
693//
694Int_t MBadPixelsTreat::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
695{
696 Bool_t rc = kFALSE;
697 if (IsEnvDefined(env, prefix, "UseInterpolation", print))
698 {
699 rc = kTRUE;
700 SetUseInterpolation(GetEnvValue(env, prefix, "UseInterpolation", IsUseInterpolation()));
701 }
702 if (IsEnvDefined(env, prefix, "UseCentralPixel", print))
703 {
704 rc = kTRUE;
705 SetUseCentralPixel(GetEnvValue(env, prefix, "UseCentralPixel", IsUseCentralPixel()));
706 }
707 if (IsEnvDefined(env, prefix, "HardTreatment", print))
708 {
709 rc = kTRUE;
710 SetHardTreatment(GetEnvValue(env, prefix, "HardTreatment", IsHardTreatment()));
711 }
712 if (IsEnvDefined(env, prefix, "ProcessPedestalRun", print))
713 {
714 rc = kTRUE;
715 SetProcessPedestalRun(GetEnvValue(env, prefix, "ProcessPedestalRun", IsProcessPedestalRun()));
716 }
717 if (IsEnvDefined(env, prefix, "ProcessPedestalEvt", print))
718 {
719 rc = kTRUE;
720 SetProcessPedestalEvt(GetEnvValue(env, prefix, "ProcessPedestalEvt", IsProcessPedestalEvt()));
721 }
722 if (IsEnvDefined(env, prefix, "ProcessTimes", print))
723 {
724 rc = kTRUE;
725 SetProcessTimes(GetEnvValue(env, prefix, "ProcessTimes", IsProcessTimes()));
726 }
727 if (IsEnvDefined(env, prefix, "NumMinNeighbors", print))
728 {
729 rc = kTRUE;
730 SetNumMinNeighbors(GetEnvValue(env, prefix, "NumMinNeighbors", fNumMinNeighbors));
731 }
732 return rc;
733}
Note: See TracBrowser for help on using the repository browser.