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

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