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

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