]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/AliCalcluster.cxx
SetCaller() calls added to identify the routine that calls stpping. (E. Futo)
[u/mrichter/AliRoot.git] / RALICE / AliCalcluster.cxx
CommitLineData
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
50ClassImp(AliCalcluster) // Class implementation to enable ROOT I/O
51
52AliCalcluster::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///////////////////////////////////////////////////////////////////////////
64AliCalcluster::~AliCalcluster()
65{
66// Destructor to delete dynamically allocated memory
67 if (fVetos)
68 {
d88f97cc 69 delete fVetos;
70 fVetos=0;
71 }
72}
73///////////////////////////////////////////////////////////////////////////
74AliCalcluster::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///////////////////////////////////////////////////////////////////////////
115Int_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///////////////////////////////////////////////////////////////////////////
128Int_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 141Int_t AliCalcluster::GetNmodules()
142{
143// Provide the number of modules in the cluster
144 return fNmods;
145}
146///////////////////////////////////////////////////////////////////////////
147Float_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///////////////////////////////////////////////////////////////////////////
161Float_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///////////////////////////////////////////////////////////////////////////
175void 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///////////////////////////////////////////////////////////////////////////
211void 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 266void 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///////////////////////////////////////////////////////////////////////////
350Int_t AliCalcluster::GetNvetos()
351{
352// Provide the number of veto signals associated to the cluster
353 return fNvetos;
354}
355///////////////////////////////////////////////////////////////////////////
356AliSignal* 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 380Float_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///////////////////////////////////////////////////////////////////////////
403Int_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///////////////////////////////////////////////////////////////////////////