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

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