source: trunk/MagicSoft/Mars/manalysis/MImgCleanStd.cc@ 1557

Last change on this file since 1557 was 1540, checked in by tbretz, 22 years ago
*** empty log message ***
  • Property svn:executable set to *
File size: 12.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): Thomas Bretz 12/2000 <mailto:tbretz@uni-sw.gwdg.de>
19! Author(s): Harald Kornmayer 1/2001 (harald@mppmu.mpg.de)
20!
21! Copyright: MAGIC Software Development, 2000-2002
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27// //
28// MImgCleanStd //
29// //
30// This is the standard image cleaning. If you want to know how it works //
31// Please look at the three CleanSteps and Process //
32// //
33// FIXME: MImgCleanStd is not yet completely optimized for speed. //
34// Maybe we don't have to loop over all pixels all the time... //
35// //
36// Input Containers: //
37// MGeomCam, MCerPhotEvt //
38// //
39// Output Containers: //
40// -/- //
41// //
42/////////////////////////////////////////////////////////////////////////////
43#include "MImgCleanStd.h"
44
45#include <stdlib.h> // atof
46#include <fstream.h> // ofstream, SavePrimitive
47
48#include <TGFrame.h> // TGFrame
49#include <TGLabel.h> // TGLabel
50#include <TGTextEntry.h> // TGTextEntry
51
52#include "MLog.h"
53#include "MLogManip.h"
54
55#include "MParList.h"
56#include "MGeomPix.h"
57#include "MGeomCam.h"
58#include "MCerPhotPix.h"
59#include "MCerPhotEvt.h"
60
61#include "MGGroupFrame.h" // MGGroupFrame
62
63ClassImp(MImgCleanStd);
64
65enum {
66 kImgCleanLvl1,
67 kImgCleanLvl2
68};
69
70static const TString gsDefName = "MImgCleanStd";
71static const TString gsDefTitle = "Task to perform a standard image cleaning";
72
73// --------------------------------------------------------------------------
74//
75// Default constructor. Here you can specify the cleaning levels. If you
76// don't specify them the 'common standard' values 3.0 and 2.5 (sigma
77// above mean) are used
78//
79MImgCleanStd::MImgCleanStd(const Float_t lvl1, const Float_t lvl2,
80 const char *name, const char *title)
81 : fCleanLvl1(lvl1), fCleanLvl2(lvl2)
82{
83 fName = name ? name : gsDefName.Data();
84 fTitle = title ? title : gsDefTitle.Data();
85
86 Print();
87}
88
89// --------------------------------------------------------------------------
90//
91// This method looks for all pixels with an entry (photons)
92// that is three times bigger than the noise of the pixel
93// (std: 3 sigma, clean level 1)
94//
95// Returns the maximum Pixel Id (used for ispixused in CleanStep2)
96//
97Int_t MImgCleanStd::CleanStep1()
98{
99 const Int_t entries = fEvt->GetNumPixels();
100
101 Int_t max = entries;
102
103 //
104 // check the number of all pixels against the noise level and
105 // set them to 'unused' state if necessary
106 //
107 for (Int_t i=0; i<entries; i++ )
108 {
109 MCerPhotPix &pix = (*fEvt)[i];
110
111 const Float_t entry = pix.GetNumPhotons();
112 const Float_t noise = pix.GetErrorPhot();
113
114 // COBB: '<=' to skip entry=noise=0
115 if (entry <= fCleanLvl1 * noise)
116 pix.SetPixelUnused();
117
118 if (pix.GetPixId()>max)
119 max = pix.GetPixId();
120 }
121 return max;
122}
123
124// --------------------------------------------------------------------------
125//
126// check if the survived pixel have a neighbor, that also
127// survived, otherwise set pixel to unused. (removes pixels without
128// neighbors)
129//
130// takes the maximum pixel id from CleanStep1 as an argument
131//
132void MImgCleanStd::CleanStep2(Int_t max)
133{
134 const Int_t entries = fEvt->GetNumPixels();
135
136 //
137 // In the worst case we have to loop 6 times 577 times, to
138 // catch the behaviour of all next neighbors. Here we can gain
139 // much by using an array instead of checking through all pixels
140 // (MCerPhotEvt::IsPixelUsed) all the time.
141 //
142 Byte_t *ispixused = new Byte_t[max+1];
143 memset(ispixused, 0, max+1);
144
145 for (Int_t i=0; i<entries; i++)
146 {
147 MCerPhotPix &pix = (*fEvt)[i];
148 ispixused[pix.GetPixId()] = pix.IsPixelUsed();
149 }
150
151 for (Int_t i=0; i<entries; i++)
152 {
153 //
154 // get entry i from list
155 //
156 MCerPhotPix &pix = (*fEvt)[i];
157
158 //
159 // check if pixel is in use, if not goto next pixel in list
160 //
161#if 0
162 if (!pix.IsPixelUsed())
163 continue;
164#endif
165
166 //
167 // get pixel id of this entry
168 //
169 const Int_t id = pix.GetPixId();
170
171 //
172 // check for 'used' neighbors this pixel which
173 //
174 const MGeomPix &gpix = (*fCam)[id];
175 const Int_t nnmax = gpix.GetNumNeighbors();
176
177#if 0
178 Bool_t cnt = kFALSE;
179 for (Int_t j=0; j<nnmax; j++)
180 {
181 const Int_t id2 = gpix.GetNeighbor(j);
182
183 if (id2>max || !ispixused[id2])
184 continue;
185
186 cnt = kTRUE;
187 break;
188 }
189 if (cnt)
190 continue;
191#else
192 Int_t cnt = 0;
193 for (Int_t j=0; j<nnmax; j++)
194 {
195 const Int_t id2 = gpix.GetNeighbor(j);
196
197 if (id2>max || !ispixused[id2])
198 continue;
199
200 if (cnt++>nnmax-4)
201 break;
202 }
203 if (cnt==nnmax-2 && nnmax>=4)
204 {
205 pix.SetPixelUsed();
206 continue;
207 }
208 if (cnt>0)
209 continue;
210#endif
211
212 //
213 // check if no next neighbor has the state 'used'
214 // set this pixel to 'unused', too.
215 //
216 pix.SetPixelUnused();
217 }
218
219 delete ispixused;
220
221 //
222 // now we declare all pixels that survive as CorePixels
223 //
224 for (Int_t i=0; i<entries; i++)
225 {
226 MCerPhotPix &pix = (*fEvt)[i];
227
228 if (pix.IsPixelUsed())
229 pix.SetPixelCore();
230 }
231}
232
233// --------------------------------------------------------------------------
234//
235// Look for the boundary pixels around the core pixels
236// if a pixel has more than 2.5 (clean level 2.5) sigma, and
237// a core neigbor it is declared as used.
238//
239void MImgCleanStd::CleanStep3()
240{
241 const Int_t entries = fEvt->GetNumPixels();
242
243 for (Int_t i=0; i<entries; i++)
244 {
245 //
246 // get pixel as entry il from list
247 //
248 MCerPhotPix &pix = (*fEvt)[i];
249
250 //
251 // if pixel is a core pixel go to the next pixel
252 //
253 if (pix.IsPixelCore())
254 continue;
255
256 //
257 // check the num of photons against the noise level
258 //
259 const Float_t entry = pix.GetNumPhotons();
260 const Float_t noise = pix.GetErrorPhot();
261
262 if (entry <= fCleanLvl2 * noise)
263 continue;
264
265 //
266 // get pixel id of this entry
267 //
268 const Int_t id = pix.GetPixId();
269
270 //
271 // check if the pixel's next neighbor is a core pixel.
272 // if it is a core pixel set pixel state to: used.
273 //
274 MGeomPix &gpix = (*fCam)[id];
275 const Int_t nnmax = gpix.GetNumNeighbors();
276
277 for (Int_t j=0; j<nnmax; j++)
278 {
279 const Int_t id2 = gpix.GetNeighbor(j);
280
281 if (!fEvt->IsPixelCore(id2))
282 continue;
283
284 pix.SetPixelUsed();
285 break;
286 }
287 }
288}
289
290// --------------------------------------------------------------------------
291//
292// check if MEvtHeader exists in the Parameter list already.
293// if not create one and add them to the list
294//
295Bool_t MImgCleanStd::PreProcess (MParList *pList)
296{
297 fCam = (MGeomCam*)pList->FindObject("MGeomCam");
298 if (!fCam)
299 {
300 *fLog << dbginf << "MGeomCam not found (no geometry information available)... aborting." << endl;
301 return kFALSE;
302 }
303
304 fEvt = (MCerPhotEvt*)pList->FindObject("MCerPhotEvt");
305 if (!fEvt)
306 {
307 *fLog << dbginf << "MCerPhotEvt not found... aborting." << endl;
308 return kFALSE;
309 }
310
311 return kTRUE;
312}
313
314
315// --------------------------------------------------------------------------
316//
317// Cleans the image.
318//
319Bool_t MImgCleanStd::Process()
320{
321 const Int_t max = CleanStep1();
322 CleanStep2(max);
323 CleanStep3();
324
325 return kTRUE;
326}
327
328// --------------------------------------------------------------------------
329//
330// Print descriptor and cleaning levels.
331//
332void MImgCleanStd::Print(Option_t *o) const
333{
334 *fLog << GetDescriptor() << " initialized with noise level ";
335 *fLog << fCleanLvl1 << " and " << fCleanLvl2 << endl;
336}
337
338// --------------------------------------------------------------------------
339//
340// Craete two text entry fields, one for each cleaning level and a
341// describing text line.
342//
343void MImgCleanStd::CreateGuiElements(MGGroupFrame *f)
344{
345 //
346 // Create a frame for line 3 and 4 to be able
347 // to align entry field and label in one line
348 //
349 TGHorizontalFrame *f1 = new TGHorizontalFrame(f, 0, 0);
350 TGHorizontalFrame *f2 = new TGHorizontalFrame(f, 0, 0);
351
352 /*
353 * --> use with root >=3.02 <--
354 *
355
356 TGNumberEntry *fNumEntry1 = new TGNumberEntry(frame, 3.0, 2, M_NENT_LVL1, kNESRealOne, kNEANonNegative);
357 TGNumberEntry *fNumEntry2 = new TGNumberEntry(frame, 2.5, 2, M_NENT_LVL1, kNESRealOne, kNEANonNegative);
358
359 */
360 TGTextEntry *entry1 = new TGTextEntry(f1, "****", kImgCleanLvl1);
361 TGTextEntry *entry2 = new TGTextEntry(f2, "****", kImgCleanLvl2);
362
363 // --- doesn't work like expected (until root 3.02?) --- fNumEntry1->SetAlignment(kTextRight);
364 // --- doesn't work like expected (until root 3.02?) --- fNumEntry2->SetAlignment(kTextRight);
365
366 entry1->SetText("3.0");
367 entry2->SetText("2.5");
368
369 entry1->Associate(f);
370 entry2->Associate(f);
371
372 TGLabel *l1 = new TGLabel(f1, "Cleaning Level 1");
373 TGLabel *l2 = new TGLabel(f2, "Cleaning Level 2");
374
375 l1->SetTextJustify(kTextLeft);
376 l2->SetTextJustify(kTextLeft);
377
378 //
379 // Align the text of the label centered, left in the row
380 // with a left padding of 10
381 //
382 TGLayoutHints *laylabel = new TGLayoutHints(kLHintsCenterY|kLHintsLeft, 10);
383 TGLayoutHints *layframe = new TGLayoutHints(kLHintsCenterY|kLHintsLeft, 5, 0, 10);
384
385 //
386 // Add one entry field and the corresponding label to each line
387 //
388 f1->AddFrame(entry1);
389 f2->AddFrame(entry2);
390
391 f1->AddFrame(l1, laylabel);
392 f2->AddFrame(l2, laylabel);
393
394 f->AddFrame(f1, layframe);
395 f->AddFrame(f2, layframe);
396
397 f->AddToList(entry1);
398 f->AddToList(entry2);
399 f->AddToList(l1);
400 f->AddToList(l2);
401 f->AddToList(laylabel);
402 f->AddToList(layframe);
403}
404
405// --------------------------------------------------------------------------
406//
407// Process the GUI Events comming from the two text entry fields.
408//
409Bool_t MImgCleanStd::ProcessMessage(Int_t msg, Int_t submsg, Long_t param1, Long_t param2)
410{
411 if (msg!=kC_TEXTENTRY || submsg!=kTE_ENTER)
412 return kTRUE;
413
414 TGTextEntry *txt = (TGTextEntry*)FindWidget(param1);
415
416 if (!txt)
417 return kTRUE;
418
419 Float_t lvl = atof(txt->GetText());
420
421 switch (param1)
422 {
423 case kImgCleanLvl1:
424 fCleanLvl1 = lvl;
425 *fLog << "Cleaning level 1 set to " << lvl << " sigma." << endl;
426 return kTRUE;
427
428 case kImgCleanLvl2:
429 fCleanLvl2 = lvl;
430 *fLog << "Cleaning level 2 set to " << lvl << " sigma." << endl;
431 return kTRUE;
432 }
433
434 return kTRUE;
435}
436
437// --------------------------------------------------------------------------
438//
439// Implementation of SavePrimitive. Used to write the call to a constructor
440// to a macro. In the original root implementation it is used to write
441// gui elements to a macro-file.
442//
443void MImgCleanStd::StreamPrimitive(ofstream &out) const
444{
445 out << " MImgCleanStd " << GetUniqueName() << "(";
446 out << fCleanLvl1 << ", " << fCleanLvl2;
447
448 if (fName!=gsDefName || fTitle!=gsDefTitle)
449 {
450 out << ", \"" << fName << "\"";
451 if (fTitle!=gsDefTitle)
452 out << ", \"" << fTitle << "\"";
453 }
454 out << ");" << endl;
455}
Note: See TracBrowser for help on using the repository browser.