source: trunk/Mars/mimage/MImgCleanTime.cc@ 20040

Last change on this file since 20040 was 18286, checked in by Daniela Dorner, 10 years ago
fixed bug (signle pixels were not ignored) and ignore unmapped pixels
File size: 7.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, 4/2014 <mailto:tbretz@phys.ethz.ch>
19!
20! Copyright: MAGIC Software Development, 2014
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MImgCleanTime
28//
29// Input Containers:
30// MGeomCam
31// MSignalCam
32//
33// Output Containers:
34// MSignalCam
35//
36/////////////////////////////////////////////////////////////////////////////
37#include "MImgCleanTime.h"
38
39#include <TEnv.h>
40
41#include "MLog.h"
42#include "MLogManip.h"
43
44#include "MParList.h"
45
46#include "MGeomPix.h"
47#include "MGeomCam.h"
48
49#include "MSignalPix.h"
50#include "MSignalCam.h"
51
52ClassImp(MImgCleanTime);
53
54using namespace std;
55
56// --------------------------------------------------------------------------
57//
58// Default constructor. Here you can specify the cleaning method and levels.
59// If you don't specify them the 'common standard' values 3.0 and 2.5 (sigma
60// above mean) are used.
61// Here you can also specify how many rings around the core pixels you want
62// to analyze (with the fixed lvl2). The default value for "rings" is 1.
63//
64MImgCleanTime::MImgCleanTime(const char *name, const char *title)
65 : fCam(0), fEvt(0), fMinCount(0), fMinSize(25), fDeltaT(2.5*17.5*0.1111),
66 fNameSignalCam("MSignalCam")
67{
68 fName = name ? name : "MImgCleanTime";
69 fTitle = title ? title : "Task to perform image cleaning";
70}
71
72// --------------------------------------------------------------------------
73//
74// Check if MEvtHeader exists in the Parameter list already.
75// if not create one and add them to the list
76//
77Int_t MImgCleanTime::PreProcess (MParList *pList)
78{
79 fCam = (MGeomCam*)pList->FindObject("MGeomCam");
80 if (!fCam)
81 {
82 *fLog << err << "MGeomCam not found (no geometry information available)... aborting." << endl;
83 return kFALSE;
84 }
85 fEvt = (MSignalCam*)pList->FindObject(fNameSignalCam, "MSignalCam");
86 if (!fEvt)
87 {
88 *fLog << err << fNameSignalCam << " [MSignalCam] not found... aborting." << endl;
89 return kFALSE;
90 }
91
92 return kTRUE;
93}
94
95Island MImgCleanTime::CalcIsland(MSignalPix &pix1, const MGeom &gpix1, const uint16_t &island1)
96{
97 pix1.SetIdxIsland(island1);
98
99 const Float_t time1 = pix1.GetArrivalTime();
100
101 if (pix1.IsPixelUnmapped())
102 return Island(0,time1);
103
104 Island island(pix1.GetNumPhotons(), time1);
105
106 for (UInt_t i=0; i<gpix1.GetNumNeighbors(); i++)
107 {
108 const Int_t idx2 = gpix1.GetNeighbor(i);
109
110 MSignalPix &pix2 = (*fEvt)[idx2];
111 if (pix2.IsPixelUnmapped())
112 continue;
113
114 const Int_t island2 = pix2.GetIdxIsland();
115 if (island2>=0)
116 {
117 if (island1==island2)
118 continue;
119
120 // The entries are sorted naturally, therefore
121 // there is no need to check the whole array
122 const auto it = fContacts.rbegin();
123 if (it==fContacts.rend() ||
124 (it->first!=island1 && it->second!=island2))
125 fContacts.emplace_back(island1, island2);
126
127 continue;
128 }
129
130 const Float_t time2 = pix2.GetArrivalTime();
131 if (fabs(time2-time1)<fDeltaT) // FIXME: Scale with distance?
132 island += CalcIsland(pix2, (*fCam)[idx2], island1);
133 }
134
135 return island;
136}
137
138// --------------------------------------------------------------------------
139//
140// Cleans the image.
141//
142Int_t MImgCleanTime::Process()
143{
144 // The assumption is that all mapped pixels contain valid data
145 const UInt_t npix = fEvt->GetNumPixels();
146 for (UInt_t i=0; i<npix; i++)
147 {
148 MSignalPix &pix = (*fEvt)[i];
149 if (!pix.IsPixelUnmapped())
150 pix.SetPixelUnused();
151 pix.SetPixelCore(kFALSE);
152 pix.SetIdxIsland(-1);
153 }
154
155 // Contains the id of the island for each pixel
156 fIslands.clear();
157 fContacts.clear();
158
159 // Start with island idx==0
160 UShort_t idx = 0;
161 for (UInt_t i=0; i<npix; i++)
162 {
163 MSignalPix &spix = (*fEvt)[i];
164
165 // The following might be much more efficient and faster
166 // if we omit small counted and sized islands already,
167 // but what is the disadvantage?
168 if (spix.GetIdxIsland()<0)
169 fIslands.emplace_back(CalcIsland(spix, (*fCam)[i], idx++));
170 }
171
172 fLut.resize(fIslands.size());
173 for (UInt_t i=0; i<fLut.size(); i++)
174 fLut[i] = i;
175
176 // Unify touching islands if their arrival time ranges overlap
177 for (auto it=fContacts.begin(); it!=fContacts.end(); it++)
178 {
179 const uint16_t &idx1 = fLut[it->first];
180 const uint16_t &idx2 = fLut[it->second];
181 if (idx1==idx2)
182 continue;
183
184 Island &I1 = fIslands[idx1];
185 const Island &I2 = fIslands[idx2];
186
187 // FIXME: Put a limit on count? Put a limit on size?
188 // The ideal cut would be to allow that a single
189 // pixel still can connect two clusters
190 if (I1.count==1 || I2.count==1)
191 continue;
192
193 if (I1.max<I2.min || I2.max<I1.min)
194 continue;
195
196 // Combine both islands
197 I1 += I2;
198
199 // Remove idx2 from the list
200 for (auto is=fLut.begin(); is!=fLut.end(); is++)
201 if (*is==idx2)
202 *is=idx1;
203
204 // Erase entry form contact list
205 fContacts.erase(it);
206
207 // Start over again
208 it = fContacts.begin();
209 }
210
211 uint16_t num_islands = 0;
212 double size_main = 0;
213 double size_tot = 0;
214
215 vector<bool> used(fIslands.size());
216 for (UInt_t i=0; i<npix; i++)
217 {
218 MSignalPix &pix = (*fEvt)[i];
219
220 // At the end every pixel has an island assigned
221 const Short_t ii = fLut[pix.GetIdxIsland()];
222
223 const Island &island = fIslands[ii];
224
225 if (island.count<=fMinCount || island.size<=fMinSize)
226 continue;
227
228 if (!used[ii])
229 {
230 used[ii] = true;
231 num_islands++;
232
233 size_tot += island.size;
234 if (island.size>size_main)
235 size_main = island.size;
236 }
237
238 pix.SetPixelUsed();
239 pix.SetPixelCore();
240 }
241
242 fEvt->SetIslandInfo(num_islands, size_main, size_tot-size_main);
243
244 return kTRUE;
245}
246
247// --------------------------------------------------------------------------
248//
249Int_t MImgCleanTime::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
250{
251 Bool_t rc = kFALSE;
252 if (IsEnvDefined(env, prefix, "MinSize", print))
253 {
254 rc = kTRUE;
255 SetMinSize(GetEnvValue(env, prefix, "MinSize", fMinSize));
256 }
257 if (IsEnvDefined(env, prefix, "MinCount", print))
258 {
259 rc = kTRUE;
260 SetMinSize(GetEnvValue(env, prefix, "MinCount", (Int_t)fMinCount));
261 }
262 if (IsEnvDefined(env, prefix, "DeltaT", print))
263 {
264 rc = kTRUE;
265 SetMinSize(GetEnvValue(env, prefix, "DeltaT", fDeltaT));
266 }
267
268 return rc;
269}
Note: See TracBrowser for help on using the repository browser.