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

Last change on this file since 4544 was 4467, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 15.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!
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 don't want to interpolate unreliable pixels but only unsuitable
41// (broken) pixels use SetSloppyTreatment().
42//
43//
44// Input Containers:
45// MCerPhotEvt
46// MPedPhotCam
47// MBadPixelsCam
48// [MGeomCam]
49//
50// Output Containers:
51// MCerPhotEvt
52//
53/////////////////////////////////////////////////////////////////////////////
54#include "MBadPixelsTreat.h"
55
56#include <fstream>
57
58#include <TArrayD.h>
59
60#include "MLog.h"
61#include "MLogManip.h"
62
63#include "MParList.h"
64
65#include "MGeomPix.h"
66#include "MGeomCam.h"
67
68#include "MCerPhotPix.h"
69#include "MCerPhotEvt.h"
70
71#include "MPedPhotPix.h"
72#include "MPedPhotCam.h"
73
74#include "MBadPixelsPix.h"
75#include "MBadPixelsCam.h"
76
77ClassImp(MBadPixelsTreat);
78
79using namespace std;
80
81static const TString gsDefName = "MBadPixelsTreat";
82static const TString gsDefTitle = "Task to treat bad pixels (interpolation, unmapping)";
83
84// --------------------------------------------------------------------------
85//
86// Default constructor.
87//
88MBadPixelsTreat::MBadPixelsTreat(const char *name, const char *title)
89 : fFlags(0), fNumMinNeighbors(3)
90{
91 fName = name ? name : gsDefName.Data();
92 fTitle = title ? title : gsDefTitle.Data();
93}
94
95// --------------------------------------------------------------------------
96//
97// Returns the status of a pixel. If kSloppyTreatment is set a pixel must
98// be unsuitable to be treated. If not it is enough if it is unreliable
99// (IsBad() checks for any flag)
100//
101Bool_t MBadPixelsTreat::IsPixelBad(Int_t idx) const
102{
103 return TESTBIT(fFlags, kSloppyTreatment) ? (*fBadPixels)[idx].IsUnsuitable() : (*fBadPixels)[idx].IsBad();
104}
105
106// --------------------------------------------------------------------------
107//
108// - Try to find or create MBlindPixels in parameter list.
109// - get the MCerPhotEvt from the parlist (abort if missing)
110// - if no pixels are given by the user try to determin the starfield
111// from the monte carlo run header.
112//
113Int_t MBadPixelsTreat::PreProcess (MParList *pList)
114{
115 fBadPixels = (MBadPixelsCam*)pList->FindObject(AddSerialNumber("MBadPixelsCam"));
116 if (!fBadPixels)
117 {
118 *fLog << err << "MBadPixelsCam not found... aborting." << endl;
119 return kFALSE;
120 }
121
122 fPedPhot = (MPedPhotCam*)pList->FindObject(AddSerialNumber("MPedPhotCam"));
123 if (!fPedPhot)
124 {
125 *fLog << err << "MPedPhotCam not found... aborting." << endl;
126 return kFALSE;
127 }
128
129 fEvt = (MCerPhotEvt*)pList->FindObject(AddSerialNumber("MCerPhotEvt"));
130 if (!fEvt)
131 {
132 *fLog << err << "MCerPhotEvt not found... aborting." << endl;
133 return kFALSE;
134 }
135
136 fGeomCam = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam"));
137 if (!fGeomCam && TESTBIT(fFlags, kUseInterpolation))
138 {
139 *fLog << err << "MGeomCam not found... can't use interpolation." << endl;
140 return kFALSE;
141 }
142
143 return kTRUE;
144}
145
146// --------------------------------------------------------------------------
147//
148// Replaces each pixel (signal, signal error, pedestal, pedestal rms)
149// by the average of its surrounding pixels.
150// If TESTBIT(fFlags, kUseCentralPixel) is set the central pixel is also
151// included.
152//
153void MBadPixelsTreat::InterpolateSignal() const
154{
155 const UShort_t entries = fGeomCam->GetNumPixels();
156
157 //
158 // Create arrays (FIXME: Check if its possible to create it only once)
159 //
160 TArrayD nphot(entries);
161 TArrayD perr(entries);
162
163 //
164 // Loop over all pixels
165 //
166 for (UShort_t i=0; i<entries; i++)
167 {
168 MCerPhotPix *pix = fEvt->GetPixById(i);
169
170 //
171 // Check whether pixel with idx i is blind
172 //
173 if (pix && !IsPixelBad(i))
174 continue;
175
176 //
177 // Get a pointer to this pixel. If it is not yet existing
178 // create a new entry for this pixel in MCerPhotEvt
179 //
180 if (!pix)
181 {
182 pix = fEvt->AddPixel(i, 0, 0);
183 (*fBadPixels)[i].SetUnsuitable(MBadPixelsPix::kUnsuitableEvt);
184 }
185
186 //
187 // Get the corresponding geometry and pedestal
188 //
189 const MGeomPix &gpix = (*fGeomCam)[i];
190
191 // Do Not-Use-Central-Pixel
192 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
193
194 Int_t num = nucp ? 0 : 1;
195
196 nphot[i] = nucp ? 0 : pix->GetNumPhotons();
197 perr[i] = nucp ? 0 : Pow2(pix->GetErrorPhot());
198
199 //
200 // The values are rescaled to the small pixels area for the right comparison
201 //
202 const Double_t ratio = fGeomCam->GetPixRatio(i);
203
204 nphot[i] *= ratio;
205 perr[i] *= ratio;
206
207 //
208 // Loop over all its neighbors
209 //
210 const Int_t n = gpix.GetNumNeighbors();
211 for (int j=0; j<n; j++)
212 {
213 const UShort_t nidx = gpix.GetNeighbor(j);
214
215 //
216 // Do not use blind neighbors
217 //
218 if (IsPixelBad(nidx))
219 continue;
220
221 //
222 // Check whether the neighbor has a signal stored
223 //
224 const MCerPhotPix *evtpix = fEvt->GetPixById(nidx);
225 if (!evtpix)
226 continue;
227
228 //
229 // Get the geometry for the neighbor
230 //
231 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
232
233 //
234 //The error is calculated as the quadratic sum of the errors
235 //
236 nphot[i] += nratio*evtpix->GetNumPhotons();
237 perr[i] += nratio* Pow2(evtpix->GetErrorPhot());
238
239 num++;
240 }
241
242 // Check if there are enough neighbors to calculate the mean
243 // If not, unmap the pixel. The maximum number of blind neighbors
244 // should be 2
245 if (num<fNumMinNeighbors)
246 {
247 pix->SetPixelUnmapped();
248 continue;
249 }
250
251 //
252 // Now the mean is calculated and the values rescaled back
253 // to the pixel area
254 //
255 nphot[i] /= (num*ratio);
256 perr[i] = TMath::Sqrt(perr[i]/(num*ratio));
257
258 pix->Set(nphot[i], perr[i]);
259 }
260}
261
262// --------------------------------------------------------------------------
263//
264void MBadPixelsTreat::InterpolatePedestals() const
265{
266 const Int_t entries = fPedPhot->GetSize();
267
268 // Create arrays (FIXME: Check if its possible to create it only once)
269 TArrayD ped(entries);
270 TArrayD rms(entries);
271
272 //
273 // Loop over all pixels
274 //
275 for (UShort_t i=0; i<entries; i++)
276 {
277 //
278 // Check whether pixel with idx i is blind
279 //
280 if (!IsPixelBad(i))
281 continue;
282
283 //
284 // Get the corresponding geometry and pedestal
285 //
286 const MGeomPix &gpix = (*fGeomCam)[i];
287 const MPedPhotPix &ppix = (*fPedPhot)[i];
288
289 // Do Not-Use-Central-Pixel
290 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
291
292 Int_t num = nucp ? 0 : 1;
293
294 ped[i] = nucp ? 0 : ppix.GetMean();
295 rms[i] = nucp ? 0 : Pow2(ppix.GetRms());
296
297 //
298 // The values are rescaled to the small pixels area for the right comparison
299 //
300 const Double_t ratio = fGeomCam->GetPixRatio(i);
301
302 ped[i] *= ratio;
303 rms[i] *= ratio;
304
305 //
306 // Loop over all its neighbors
307 //
308 const Int_t n = gpix.GetNumNeighbors();
309 for (int j=0; j<n; j++)
310 {
311 const UShort_t nidx = gpix.GetNeighbor(j);
312
313 //
314 // Do not use blind neighbors
315 //
316 if (IsPixelBad(nidx))
317 continue;
318
319 //
320 // Get the geometry for the neighbor
321 //
322 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
323 const MPedPhotPix &nppix = (*fPedPhot)[nidx];
324
325 //
326 //The error is calculated as the quadratic sum of the errors
327 //
328 ped[i] += nratio*nppix.GetMean();
329 rms[i] += nratio*Pow2(nppix.GetRms());
330
331 num++;
332 }
333
334 // Check if there are enough neighbors to calculate the mean
335 // If not, unmap the pixel. The minimum number of good neighbors
336 // should be fNumMinNeighbors
337 if (num < fNumMinNeighbors)
338 {
339 MCerPhotPix *pix =fEvt->GetPixById(i);
340 if (!pix)
341 pix = fEvt->AddPixel(i, 0, 0);
342 pix->SetPixelUnmapped();
343 continue;
344 }
345
346 //
347 // Now the mean is calculated and the values rescaled back
348 // to the pixel area
349 //
350 ped[i] /= (num*ratio);
351 rms[i] = TMath::Sqrt(rms[i]/(num*ratio));
352
353 (*fPedPhot)[i].Set(ped[i], rms[i]);
354 }
355}
356
357// --------------------------------------------------------------------------
358//
359// Replaces each pixel (signal, signal error, pedestal, pedestal rms)
360// by the average of its surrounding pixels.
361// If TESTBIT(fFlags, kUseCentralPixel) is set the central pixel is also
362// included.
363//
364// NT: Informations about the interpolated pedestals are added.
365// When the option Interpolated is called, the blind pixel with the new
366// values of signal and fluttuation is included in the calculation of
367// the Image Parameters.
368//
369/*
370void MBadPixelsTreat::Interpolate() const
371{
372 const UShort_t entries = fGeomCam->GetNumPixels();
373
374 //
375 // Create arrays
376 //
377 TArrayD nphot(entries);
378 TArrayD perr(entries);
379 TArrayD ped(entries);
380 TArrayD pedrms(entries);
381
382 //
383 // Loop over all pixels
384 //
385 for (UShort_t i=0; i<entries; i++)
386 {
387 MCerPhotPix *pix = fEvt->GetPixById(i);
388
389 //
390 // Check whether pixel with idx i is blind
391 //
392 if (pix && (*fBadPixels)[i].IsOK())
393 continue;
394
395 //
396 // Get a pointer to this pixel. If it is not yet existing
397 // create a new entry for this pixel in MCerPhotEvt
398 //
399 if (!pix)
400 {
401 pix = fEvt->AddPixel(i, 0, 0);
402 (*fBadPixels)[i].SetUnsuitable(MBadPixelsPix::kUnsuitableEvt);
403 }
404
405 //
406 // Get the corresponding geometry and pedestal
407 //
408 const MGeomPix &gpix = (*fGeomCam)[i];
409 const MPedPhotPix &ppix = (*fPedPhot)[i];
410
411 // Do Not-Use-Central-Pixel
412 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
413
414 Int_t num = nucp ? 0 : 1;
415
416 nphot[i] = nucp ? 0 : pix->GetNumPhotons();
417 ped[i] = nucp ? 0 : ppix.GetMean();
418 perr[i] = nucp ? 0 : Pow2(pix->GetErrorPhot());
419 pedrms[i] = nucp ? 0 : Pow2(ppix.GetRms());
420
421 //
422 // The values are rescaled to the small pixels area for the right comparison
423 //
424 const Double_t ratio = fGeomCam->GetPixRatio(i);
425
426 if (nucp)
427 {
428 nphot[i] *= ratio;
429 perr[i] *= ratio;
430 ped[i] *= ratio;
431 pedrms[i] *= ratio;
432 }
433
434 //
435 // Loop over all its neighbors
436 //
437 const Int_t n = gpix.GetNumNeighbors();
438 for (int j=0; j<n; j++)
439 {
440 const UShort_t nidx = gpix.GetNeighbor(j);
441
442 //
443 // Do not use blind neighbors
444 //
445 if ((*fBadPixels)[nidx].IsBad())
446 continue;
447
448 //
449 // Check whether the neighbor has a signal stored
450 //
451 const MCerPhotPix *evtpix = fEvt->GetPixById(nidx);
452 if (!evtpix)
453 continue;
454
455 //
456 // Get the geometry for the neighbor
457 //
458 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
459 MPedPhotPix &nppix = (*fPedPhot)[nidx];
460
461 //
462 // The error is calculated as the quadratic sum of the errors
463 //
464 nphot[i] += nratio*evtpix->GetNumPhotons();
465 ped[i] += nratio*nppix.GetMean();
466 perr[i] += nratio*Pow2(evtpix->GetErrorPhot());
467 pedrms[i] += nratio*Pow2(nppix.GetRms());
468
469 num++;
470 }
471
472 if (num<fNumMinNeighbors)
473 {
474 pix->SetPixelUnmapped();
475 nphot[i] = 0;
476 ped[i] = 0;
477 perr[i] = 0;
478 pedrms[i] = 0;
479 continue;
480 }
481
482 //
483 // Now the mean is calculated and the values rescaled back to the pixel area
484 //
485 nphot[i] /= num*ratio;
486 ped[i] /= num*ratio;
487 perr[i] = TMath::Sqrt(perr[i]/(num*ratio));
488 pedrms[i] = TMath::Sqrt(pedrms[i]/(num*ratio));
489
490 }
491
492 //
493 // Now the new pixel values are calculated and can be replaced in
494 // the corresponding containers
495 //
496 for (UShort_t i=0; i<entries; i++)
497 {
498 //
499 // Do not use blind neighbors
500 //
501 if ((*fBadPixels)[i].IsOK())
502 continue;
503
504 //
505 // It must exist, we have created it in the loop before.
506 //
507 fEvt->GetPixById(i)->Set(nphot[i], perr[i]);
508 (*fPedPhot)[i].Set(ped[i], pedrms[i]);
509 }
510}
511*/
512
513// --------------------------------------------------------------------------
514//
515// Removes all blind pixels from the analysis by setting their state
516// to unused.
517//
518void MBadPixelsTreat::Unmap() const
519{
520 const UShort_t entries = fEvt->GetNumPixels();
521
522 //
523 // remove the pixels in fPixelsIdx if they are set to be used,
524 // (set them to 'unused' state)
525 //
526 for (UShort_t i=0; i<entries; i++)
527 {
528 MCerPhotPix &pix = (*fEvt)[i];
529
530 if (IsPixelBad(pix.GetPixId()))
531 pix.SetPixelUnmapped();
532 }
533}
534
535// --------------------------------------------------------------------------
536//
537// Interpolate Pedestals if kProcessRMS not set
538//
539Bool_t MBadPixelsTreat::ReInit(MParList *pList)
540{
541 if (!TESTBIT(fFlags, kProcessRMS))
542 InterpolatePedestals();
543 return kTRUE;
544}
545
546// --------------------------------------------------------------------------
547//
548// Treat the blind pixels
549//
550Int_t MBadPixelsTreat::Process()
551{
552 if (TESTBIT(fFlags, kUseInterpolation) && fGeomCam)
553 {
554 InterpolateSignal();
555 if (TESTBIT(fFlags, kProcessRMS))
556 InterpolatePedestals();
557 }
558 else
559 Unmap();
560
561 return kTRUE;
562}
563
564void MBadPixelsTreat::StreamPrimitive(ofstream &out) const
565{
566 out << " MBadPixelsTreat " << GetUniqueName();
567 if (fName!=gsDefName || fTitle!=gsDefTitle)
568 {
569 out << "(\"" << fName << "\"";
570 if (fTitle!=gsDefTitle)
571 out << ", \"" << fTitle << "\"";
572 out <<")";
573 }
574 out << ";" << endl;
575
576 if (TESTBIT(fFlags, kUseInterpolation))
577 out << " " << GetUniqueName() << ".SetUseInterpolation();" << endl;
578 if (TESTBIT(fFlags, kUseCentralPixel))
579 out << " " << GetUniqueName() << ".SetUseCentralPixel();" << endl;
580}
Note: See TracBrowser for help on using the repository browser.