]>
Commit | Line | Data |
---|---|---|
4c039060 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
f531a546 | 16 | // $Id$ |
4c039060 | 17 | |
959fbac5 | 18 | /////////////////////////////////////////////////////////////////////////// |
19 | // Class AliCalcluster | |
20 | // Description of a cluster of calorimeter modules. | |
dafe31a2 | 21 | // A 2D (matrix) geometry is assumed in which a cluster center is identified |
22 | // by two integer indices (i,j), e.g. row and column indicators. | |
23 | // | |
24 | // The 1st signal value is the signal of the complete cluster. | |
25 | // This is the signal which is provided as default by invoking GetSignal(). | |
26 | // | |
27 | // In case clustering/grouping of module signals was performed over several | |
28 | // rings around the center (see e.g. AliCalorimeter::Group), the following | |
29 | // additional information is provided by the various signal values : | |
30 | // | |
31 | // The 2nd signal value is the original signal of the central module. | |
32 | // The 3rd signal value is the total signal within the 1st (i.e. 3x3) ring of | |
33 | // modules around the cluster center. | |
34 | // The 4th signal value is the total signal within the 2nd (i.e. 5x5) ring of | |
35 | // modules around the cluster center. | |
36 | // Etc.... | |
37 | // | |
38 | // Note : In case the cluster consists of only 1 module, then only the | |
39 | // 1st signal value will be present (for obvious reasons). | |
40 | // | |
41 | // Some dispersion info about cluster topology is provided in order | |
959fbac5 | 42 | // to enable EM or hadronic cluster identification. |
43 | // | |
44 | //--- Author: Nick van Eijndhoven 13-jun-1997 UU-SAP Utrecht | |
f531a546 | 45 | //- Modified: NvE $Date$ UU-SAP Utrecht |
959fbac5 | 46 | /////////////////////////////////////////////////////////////////////////// |
47 | ||
d88f97cc | 48 | #include "AliCalcluster.h" |
49 | ||
50 | ClassImp(AliCalcluster) // Class implementation to enable ROOT I/O | |
51 | ||
52 | AliCalcluster::AliCalcluster() | |
53 | { | |
54 | // Default constructer, all data is set to 0 | |
55 | fCenter=0; | |
d88f97cc | 56 | fNmods=0; |
d88f97cc | 57 | fRowdisp=0.; |
58 | fColdisp=0.; | |
59 | fNvetos=0; | |
60 | fVetos=0; | |
dafe31a2 | 61 | SetName("AliCalcluster [sig, sig11, sig33, sig55, ...]"); |
d88f97cc | 62 | } |
63 | /////////////////////////////////////////////////////////////////////////// | |
64 | AliCalcluster::~AliCalcluster() | |
65 | { | |
66 | // Destructor to delete dynamically allocated memory | |
67 | if (fVetos) | |
68 | { | |
d88f97cc | 69 | delete fVetos; |
70 | fVetos=0; | |
71 | } | |
72 | } | |
73 | /////////////////////////////////////////////////////////////////////////// | |
74 | AliCalcluster::AliCalcluster(AliCalmodule& m) | |
75 | { | |
76 | // Cluster constructor with module m as center. | |
f40f8fbd | 77 | // Module data is only entered for a module which contains a signal, |
78 | // has not been used in a cluster yet, and is not declared dead. | |
79 | // | |
80 | // Note : | |
81 | // It is advised NOT to start a cluster with modules situated at a detector edge. | |
82 | // This feature is automatically checked when using the built-in clustering | |
83 | // of AliCalorimeter. | |
d88f97cc | 84 | |
f40f8fbd | 85 | Ali3Vector r; |
d88f97cc | 86 | |
dafe31a2 | 87 | Float_t sig=m.GetClusteredSignal(); |
88 | ||
89 | if (sig>0. && m.GetDeadValue()==0) | |
d88f97cc | 90 | { |
91 | fCenter=&m; | |
f40f8fbd | 92 | r=m.GetPosition(); |
93 | SetPosition(r); | |
dafe31a2 | 94 | SetSignal(sig); |
d88f97cc | 95 | fNmods=1; |
d88f97cc | 96 | fRowdisp=0.; |
97 | fColdisp=0.; | |
98 | m.SetClusteredSignal(0.); // mark module as used in cluster | |
99 | fNvetos=0; | |
100 | fVetos=0; | |
101 | } | |
102 | else | |
103 | { | |
104 | fCenter=0; | |
f40f8fbd | 105 | SetPosition(r); |
d88f97cc | 106 | fNmods=0; |
d88f97cc | 107 | fRowdisp=0.; |
108 | fColdisp=0.; | |
109 | fNvetos=0; | |
110 | fVetos=0; | |
8e8e6c7f | 111 | } |
dafe31a2 | 112 | SetName("AliCalcluster [sig, sig11, sig33, sig55, ...]"); |
d88f97cc | 113 | } |
114 | /////////////////////////////////////////////////////////////////////////// | |
115 | Int_t AliCalcluster::GetRow() | |
116 | { | |
117 | // Provide the row number of the cluster center | |
118 | if (fCenter) | |
119 | { | |
120 | return fCenter->GetRow(); | |
121 | } | |
122 | else | |
123 | { | |
124 | return 0; | |
125 | } | |
126 | } | |
127 | /////////////////////////////////////////////////////////////////////////// | |
128 | Int_t AliCalcluster::GetColumn() | |
129 | { | |
130 | // Provide the column number of the cluster center | |
131 | if (fCenter) | |
132 | { | |
133 | return fCenter->GetColumn(); | |
134 | } | |
135 | else | |
136 | { | |
137 | return 0; | |
138 | } | |
139 | } | |
140 | /////////////////////////////////////////////////////////////////////////// | |
d88f97cc | 141 | Int_t AliCalcluster::GetNmodules() |
142 | { | |
143 | // Provide the number of modules in the cluster | |
144 | return fNmods; | |
145 | } | |
146 | /////////////////////////////////////////////////////////////////////////// | |
147 | Float_t AliCalcluster::GetRowDispersion() | |
148 | { | |
dafe31a2 | 149 | // Provide the normalised row dispersion of the cluster. |
150 | Float_t sig=GetSignal(); | |
151 | if (sig > 0.) | |
d88f97cc | 152 | { |
dafe31a2 | 153 | return fRowdisp/sig; |
d88f97cc | 154 | } |
155 | else | |
156 | { | |
157 | return 0.; | |
158 | } | |
159 | } | |
160 | /////////////////////////////////////////////////////////////////////////// | |
161 | Float_t AliCalcluster::GetColumnDispersion() | |
162 | { | |
163 | // Provide the normalised column dispersion of the cluster | |
dafe31a2 | 164 | Float_t sig=GetSignal(); |
165 | if (sig > 0.) | |
d88f97cc | 166 | { |
dafe31a2 | 167 | return fColdisp/sig; |
d88f97cc | 168 | } |
169 | else | |
170 | { | |
171 | return 0.; | |
172 | } | |
173 | } | |
174 | /////////////////////////////////////////////////////////////////////////// | |
175 | void AliCalcluster::Start(AliCalmodule& m) | |
176 | { | |
959fbac5 | 177 | // Reset cluster data and start with module m. |
f40f8fbd | 178 | // A module can only start a cluster when it contains a signal, |
179 | // has not been used in a cluster yet, and is not declared dead. | |
180 | // | |
181 | // Note : | |
182 | // It is advised NOT to start a cluster with modules situated at a detector edge. | |
183 | // This feature is automatically checked when using the built-in clustering | |
184 | // of AliCalorimeter. | |
d88f97cc | 185 | |
dafe31a2 | 186 | AliSignal::Reset(); |
187 | ||
f40f8fbd | 188 | Ali3Vector r; |
d88f97cc | 189 | |
f40f8fbd | 190 | if (m.GetClusteredSignal()>0. && m.GetDeadValue()==0) |
d88f97cc | 191 | { |
192 | fCenter=&m; | |
f40f8fbd | 193 | r=m.GetPosition(); |
194 | SetPosition(r); | |
dafe31a2 | 195 | SetSignal(m.GetSignal()); |
d88f97cc | 196 | fNmods=1; |
d88f97cc | 197 | fRowdisp=0.; |
198 | fColdisp=0.; | |
199 | m.SetClusteredSignal(0.); // mark module as used in cluster | |
200 | } | |
201 | else | |
202 | { | |
203 | fCenter=0; | |
f40f8fbd | 204 | SetPosition(r); |
d88f97cc | 205 | fNmods=0; |
d88f97cc | 206 | fRowdisp=0.; |
207 | fColdisp=0.; | |
208 | } | |
209 | } | |
210 | /////////////////////////////////////////////////////////////////////////// | |
211 | void AliCalcluster::Add(AliCalmodule& m) | |
212 | { | |
f40f8fbd | 213 | // Add module data to the cluster. |
214 | // Dead modules are NOT added to the cluster. | |
dafe31a2 | 215 | // According to the distance of the module w.r.t. the cluster center |
216 | // the various signal values are updated. | |
217 | ||
218 | if (fNmods) | |
219 | { | |
220 | Float_t sigm=m.GetClusteredSignal(); | |
221 | ||
222 | if (sigm>0. && m.GetDeadValue()==0) // only add unused modules | |
223 | { | |
224 | Int_t drow=int(fabs(double(GetRow()-m.GetRow()))); // row distance to center | |
225 | Int_t dcol=int(fabs(double(GetColumn()-m.GetColumn()))); // column distance to center | |
226 | ||
227 | // Determine the ring index for this module around the cluster center | |
228 | Int_t jring=drow; | |
229 | if (dcol>drow) jring=dcol; | |
230 | ||
231 | Int_t nvalues=GetNvalues(); | |
232 | ||
233 | if ((jring+2)<=nvalues) // Module within existing ring(s) ==> Add module signal to the enclosing ring(s) | |
234 | { | |
235 | for (Int_t i=(jring+2); i<=nvalues; i++) | |
236 | { | |
237 | AddSignal(sigm,i); | |
238 | } | |
239 | } | |
240 | else // Module outside all existing rings ==> Init. new ring signals with existing enclosed signal(s) | |
241 | { | |
242 | for (Int_t j=(nvalues+1); j<=(jring+2); j++) | |
243 | { | |
244 | SetSignal(GetSignal(j-1),j); | |
245 | } | |
246 | // Add current module signal to the signal value for the corresponding ring | |
247 | AddSignal(sigm,(jring+2)); | |
248 | } | |
d88f97cc | 249 | |
dafe31a2 | 250 | // Update total cluster signal |
251 | AddSignal(sigm); | |
d88f97cc | 252 | |
dafe31a2 | 253 | fNmods+=1; |
254 | fRowdisp+=sigm*float(drow*drow); | |
255 | fColdisp+=sigm*float(dcol*dcol); | |
256 | m.SetClusteredSignal(0.); // mark module as used in cluster | |
257 | } | |
258 | } | |
259 | else | |
d88f97cc | 260 | { |
dafe31a2 | 261 | cout << " *AliCalcluster::Add* No action. Cluster should be started first." |
262 | << endl; | |
d88f97cc | 263 | } |
264 | } | |
265 | /////////////////////////////////////////////////////////////////////////// | |
8e8e6c7f | 266 | void AliCalcluster::AddVetoSignal(AliSignal& s,Int_t extr) |
d88f97cc | 267 | { |
8e8e6c7f | 268 | // Associate an (extrapolated) AliSignal as veto to the cluster. |
269 | // By default a straight line extrapolation is performed which extrapolates | |
270 | // the signal position until the length of its position vector matches that | |
271 | // of the position vector of the cluster. | |
272 | // In this extrapolation procedure the error propagation is performed | |
273 | // automatically. | |
274 | // Based on the cluster and extrapolated veto signal (x,y) positions and | |
275 | // position errors the confidence level of association is calculated | |
276 | // and stored as an additional signal value. | |
277 | // By means of the GetVetoSignal memberfunction the confidence level of | |
278 | // association can always be updated by the user. | |
279 | // In case the user wants to invoke a more detailed extrapolation procedure, | |
280 | // the automatic extrapolation can be suppressed by setting the argument | |
281 | // extr=0. In this case it is assumed that the AliSignal as entered via | |
282 | // the argument contains already the extrapolated position vector and | |
283 | // corresponding errors. | |
284 | // Note : Three additional values are added to the original AliSignal | |
285 | // to hold the chi2, ndf and confidence level values of the association. | |
d88f97cc | 286 | if (!fVetos) |
287 | { | |
288 | fNvetos=0; | |
289 | fVetos=new TObjArray(); | |
6516b62d | 290 | fVetos->SetOwner(); |
d88f97cc | 291 | } |
292 | ||
8e8e6c7f | 293 | Int_t nvalues=s.GetNvalues(); |
294 | AliSignal* sx=new AliSignal(nvalues+3); // Additional value added | |
295 | TString name=s.GetName(); | |
296 | name.Append(" + additional chi2, ndf and CL values"); | |
297 | sx->SetName(name); | |
298 | ||
299 | Double_t vecc[3],vecv[3]; | |
300 | if (!extr) | |
301 | { | |
302 | sx->SetPosition((Ali3Vector&)s); | |
303 | } | |
304 | else | |
305 | { | |
306 | // Extrapolate the veto hit position | |
307 | Double_t scale=1; | |
308 | GetPosition(vecc,"sph"); | |
309 | s.GetPosition(vecv,"sph"); | |
310 | if (vecv[0]) scale=vecc[0]/vecv[0]; | |
311 | Ali3Vector r=s*scale; | |
312 | sx->SetPosition(r); | |
313 | } | |
d88f97cc | 314 | |
8e8e6c7f | 315 | Double_t sig,err; |
316 | for (Int_t i=1; i<=nvalues; i++) | |
317 | { | |
318 | sig=s.GetSignal(i); | |
319 | err=s.GetSignalError(i); | |
320 | sx->SetSignal(sig,i); | |
321 | sx->SetSignalError(err,i); | |
322 | } | |
323 | ||
324 | // Calculate the confidence level of association | |
325 | GetPosition(vecc,"car"); | |
326 | sx->GetPosition(vecv,"car"); | |
327 | Double_t dx=vecc[0]-vecv[0]; | |
328 | Double_t dy=vecc[1]-vecv[1]; | |
329 | GetPositionErrors(vecc,"car"); | |
330 | sx->GetPositionErrors(vecv,"car"); | |
331 | Double_t sxc2=vecc[0]*vecc[0]; | |
332 | Double_t syc2=vecc[1]*vecc[1]; | |
333 | Double_t sxv2=vecv[0]*vecv[0]; | |
334 | Double_t syv2=vecv[1]*vecv[1]; | |
335 | Double_t sumx2=sxc2+sxv2; | |
336 | Double_t sumy2=syc2+syv2; | |
337 | Double_t chi2=0; | |
338 | if (sumx2>0 && sumy2>0) chi2=(dx*dx/sumx2)+(dy*dy/sumy2); | |
339 | Int_t ndf=2; | |
340 | AliMath m; | |
341 | Double_t prob=m.Prob(chi2,ndf); | |
342 | if (chi2>0) sx->SetSignal(chi2,nvalues+1); | |
343 | if (ndf>0) sx->SetSignal(ndf,nvalues+2); | |
344 | if (prob>0) sx->SetSignal(prob,nvalues+3); | |
345 | ||
346 | fVetos->Add(sx); | |
347 | fNvetos++; | |
d88f97cc | 348 | } |
349 | /////////////////////////////////////////////////////////////////////////// | |
350 | Int_t AliCalcluster::GetNvetos() | |
351 | { | |
352 | // Provide the number of veto signals associated to the cluster | |
353 | return fNvetos; | |
354 | } | |
355 | /////////////////////////////////////////////////////////////////////////// | |
356 | AliSignal* AliCalcluster::GetVetoSignal(Int_t i) | |
357 | { | |
959fbac5 | 358 | // Provide access to the i-th veto signal of this cluster. |
359 | // Note : The first hit corresponds to i=1. | |
6516b62d | 360 | if (!fVetos) |
d88f97cc | 361 | { |
6516b62d | 362 | cout << " *AliCalcluster::GetVetoSignal* No veto signals present." << endl; |
363 | return 0; | |
d88f97cc | 364 | } |
365 | else | |
366 | { | |
6516b62d | 367 | if (i>0 && i<=fNvetos) |
368 | { | |
369 | return (AliSignal*)fVetos->At(i-1); | |
370 | } | |
371 | else | |
372 | { | |
373 | cout << " *AliCalcluster::GetVetoSignal* Signal number " << i << " out of range." | |
374 | << " Nvetos = " << fNvetos << endl; | |
375 | return 0; | |
376 | } | |
d88f97cc | 377 | } |
378 | } | |
379 | /////////////////////////////////////////////////////////////////////////// | |
959fbac5 | 380 | Float_t AliCalcluster::GetVetoLevel() |
381 | { | |
382 | // Provide the confidence level of best associated veto signal. | |
383 | Float_t cl=0; | |
384 | Float_t clmax=0; | |
8e8e6c7f | 385 | AliSignal* s=0; |
386 | Int_t nvalues=0; | |
959fbac5 | 387 | if (fVetos) |
388 | { | |
389 | for (Int_t i=0; i<fNvetos; i++) | |
390 | { | |
8e8e6c7f | 391 | s=((AliSignal*)fVetos->At(i)); |
392 | if (s) | |
393 | { | |
394 | nvalues=s->GetNvalues(); | |
395 | cl=s->GetSignal(nvalues); | |
396 | if (cl>clmax) clmax=cl; | |
397 | } | |
959fbac5 | 398 | } |
399 | } | |
400 | return clmax; | |
401 | } | |
402 | /////////////////////////////////////////////////////////////////////////// | |
403 | Int_t AliCalcluster::HasVetoHit(Double_t cl) | |
404 | { | |
405 | // Investigate if cluster has an associated veto hit with conf. level > cl. | |
406 | // Returns 1 if there is such an associated veto hit, otherwise returns 0. | |
407 | // Note : This function is faster than GetVetoLevel(). | |
8e8e6c7f | 408 | AliSignal* s=0; |
409 | Int_t nvalues=0; | |
959fbac5 | 410 | if (fVetos) |
411 | { | |
412 | for (Int_t i=0; i<fNvetos; i++) | |
413 | { | |
8e8e6c7f | 414 | s=((AliSignal*)fVetos->At(i)); |
415 | if (s) | |
416 | { | |
417 | nvalues=s->GetNvalues(); | |
418 | if (s->GetSignal(nvalues) > cl) return 1; | |
419 | } | |
959fbac5 | 420 | } |
421 | } | |
422 | return 0; | |
423 | } | |
424 | /////////////////////////////////////////////////////////////////////////// |