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

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