]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/AliCalcluster.cxx
08-mar-2003 NvE Compiler option /GR introduced for MSVC++ in mklibs.bat to explicitly...
[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"
c72198f1 49#include "Riostream.h"
d88f97cc 50
51ClassImp(AliCalcluster) // Class implementation to enable ROOT I/O
52
c72198f1 53AliCalcluster::AliCalcluster() : AliSignal()
d88f97cc 54{
c72198f1 55// Default constructor, all data is set to 0
56 fRow=0;
57 fCol=0;
d88f97cc 58 fNmods=0;
d88f97cc 59 fRowdisp=0.;
60 fColdisp=0.;
61 fNvetos=0;
62 fVetos=0;
c72198f1 63 SetName("AliCalcluster [sig, sig11, sig33, sig55,...]");
d88f97cc 64}
65///////////////////////////////////////////////////////////////////////////
66AliCalcluster::~AliCalcluster()
67{
68// Destructor to delete dynamically allocated memory
69 if (fVetos)
70 {
d88f97cc 71 delete fVetos;
72 fVetos=0;
73 }
74}
75///////////////////////////////////////////////////////////////////////////
c72198f1 76AliCalcluster::AliCalcluster(AliCalcluster& c) : AliSignal(c)
77{
78// Copy constructor
79 fRow=c.fRow;
80 fCol=c.fCol;
81 fNmods=c.fNmods;
82 fRowdisp=c.fRowdisp;
83 fColdisp=c.fColdisp;
84 fNvetos=c.fNvetos;
85
86 fVetos=new TObjArray();
87 fVetos->SetOwner();
88
89 for (Int_t i=1; i<=fNvetos; i++)
90 {
91 AliSignal* sx=c.GetVetoSignal(i);
92 fVetos->Add(new AliSignal(*sx));
93 }
94}
95///////////////////////////////////////////////////////////////////////////
96AliCalcluster::AliCalcluster(AliCalmodule& m) : AliSignal()
d88f97cc 97{
98// Cluster constructor with module m as center.
f40f8fbd 99// Module data is only entered for a module which contains a signal,
100// has not been used in a cluster yet, and is not declared dead.
101//
102// Note :
103// It is advised NOT to start a cluster with modules situated at a detector edge.
104// This feature is automatically checked when using the built-in clustering
105// of AliCalorimeter.
d88f97cc 106
f40f8fbd 107 Ali3Vector r;
d88f97cc 108
dafe31a2 109 Float_t sig=m.GetClusteredSignal();
110
111 if (sig>0. && m.GetDeadValue()==0)
d88f97cc 112 {
c72198f1 113 fRow=m.GetRow();
114 fCol=m.GetColumn();
f40f8fbd 115 r=m.GetPosition();
116 SetPosition(r);
dafe31a2 117 SetSignal(sig);
d88f97cc 118 fNmods=1;
d88f97cc 119 fRowdisp=0.;
120 fColdisp=0.;
121 m.SetClusteredSignal(0.); // mark module as used in cluster
122 fNvetos=0;
123 fVetos=0;
124 }
125 else
126 {
c72198f1 127 fRow=0;
128 fCol=0;
f40f8fbd 129 SetPosition(r);
d88f97cc 130 fNmods=0;
d88f97cc 131 fRowdisp=0.;
132 fColdisp=0.;
133 fNvetos=0;
134 fVetos=0;
8e8e6c7f 135 }
c72198f1 136 SetName("AliCalcluster [sig, sig11, sig33, sig55,...]");
d88f97cc 137}
138///////////////////////////////////////////////////////////////////////////
139Int_t AliCalcluster::GetRow()
140{
141// Provide the row number of the cluster center
c72198f1 142 return fRow;
d88f97cc 143}
144///////////////////////////////////////////////////////////////////////////
145Int_t AliCalcluster::GetColumn()
146{
147// Provide the column number of the cluster center
c72198f1 148 return fCol;
d88f97cc 149}
150///////////////////////////////////////////////////////////////////////////
d88f97cc 151Int_t AliCalcluster::GetNmodules()
152{
153// Provide the number of modules in the cluster
154 return fNmods;
155}
156///////////////////////////////////////////////////////////////////////////
157Float_t AliCalcluster::GetRowDispersion()
158{
dafe31a2 159// Provide the normalised row dispersion of the cluster.
160 Float_t sig=GetSignal();
161 if (sig > 0.)
d88f97cc 162 {
dafe31a2 163 return fRowdisp/sig;
d88f97cc 164 }
165 else
166 {
167 return 0.;
168 }
169}
170///////////////////////////////////////////////////////////////////////////
171Float_t AliCalcluster::GetColumnDispersion()
172{
173// Provide the normalised column dispersion of the cluster
dafe31a2 174 Float_t sig=GetSignal();
175 if (sig > 0.)
d88f97cc 176 {
dafe31a2 177 return fColdisp/sig;
d88f97cc 178 }
179 else
180 {
181 return 0.;
182 }
183}
184///////////////////////////////////////////////////////////////////////////
185void AliCalcluster::Start(AliCalmodule& m)
186{
959fbac5 187// Reset cluster data and start with module m.
f40f8fbd 188// A module can only start a cluster when it contains a signal,
189// has not been used in a cluster yet, and is not declared dead.
190//
191// Note :
192// It is advised NOT to start a cluster with modules situated at a detector edge.
193// This feature is automatically checked when using the built-in clustering
194// of AliCalorimeter.
d88f97cc 195
dafe31a2 196 AliSignal::Reset();
197
f40f8fbd 198 Ali3Vector r;
d88f97cc 199
f40f8fbd 200 if (m.GetClusteredSignal()>0. && m.GetDeadValue()==0)
d88f97cc 201 {
c72198f1 202 fRow=m.GetRow();
203 fCol=m.GetColumn();
f40f8fbd 204 r=m.GetPosition();
205 SetPosition(r);
dafe31a2 206 SetSignal(m.GetSignal());
d88f97cc 207 fNmods=1;
d88f97cc 208 fRowdisp=0.;
209 fColdisp=0.;
210 m.SetClusteredSignal(0.); // mark module as used in cluster
211 }
212 else
213 {
c72198f1 214 fRow=0;
215 fCol=0;
f40f8fbd 216 SetPosition(r);
d88f97cc 217 fNmods=0;
d88f97cc 218 fRowdisp=0.;
219 fColdisp=0.;
220 }
221}
222///////////////////////////////////////////////////////////////////////////
223void AliCalcluster::Add(AliCalmodule& m)
224{
f40f8fbd 225// Add module data to the cluster.
226// Dead modules are NOT added to the cluster.
dafe31a2 227// According to the distance of the module w.r.t. the cluster center
228// the various signal values are updated.
229
230 if (fNmods)
231 {
232 Float_t sigm=m.GetClusteredSignal();
233
234 if (sigm>0. && m.GetDeadValue()==0) // only add unused modules
235 {
236 Int_t drow=int(fabs(double(GetRow()-m.GetRow()))); // row distance to center
237 Int_t dcol=int(fabs(double(GetColumn()-m.GetColumn()))); // column distance to center
238
239 // Determine the ring index for this module around the cluster center
240 Int_t jring=drow;
241 if (dcol>drow) jring=dcol;
242
243 Int_t nvalues=GetNvalues();
244
245 if ((jring+2)<=nvalues) // Module within existing ring(s) ==> Add module signal to the enclosing ring(s)
246 {
247 for (Int_t i=(jring+2); i<=nvalues; i++)
248 {
249 AddSignal(sigm,i);
250 }
251 }
252 else // Module outside all existing rings ==> Init. new ring signals with existing enclosed signal(s)
253 {
254 for (Int_t j=(nvalues+1); j<=(jring+2); j++)
255 {
256 SetSignal(GetSignal(j-1),j);
257 }
258 // Add current module signal to the signal value for the corresponding ring
259 AddSignal(sigm,(jring+2));
260 }
d88f97cc 261
dafe31a2 262 // Update total cluster signal
263 AddSignal(sigm);
d88f97cc 264
dafe31a2 265 fNmods+=1;
266 fRowdisp+=sigm*float(drow*drow);
267 fColdisp+=sigm*float(dcol*dcol);
268 m.SetClusteredSignal(0.); // mark module as used in cluster
269 }
270 }
271 else
d88f97cc 272 {
dafe31a2 273 cout << " *AliCalcluster::Add* No action. Cluster should be started first."
274 << endl;
d88f97cc 275 }
276}
277///////////////////////////////////////////////////////////////////////////
8e8e6c7f 278void AliCalcluster::AddVetoSignal(AliSignal& s,Int_t extr)
d88f97cc 279{
8e8e6c7f 280// Associate an (extrapolated) AliSignal as veto to the cluster.
281// By default a straight line extrapolation is performed which extrapolates
282// the signal position until the length of its position vector matches that
283// of the position vector of the cluster.
284// In this extrapolation procedure the error propagation is performed
285// automatically.
286// Based on the cluster and extrapolated veto signal (x,y) positions and
287// position errors the confidence level of association is calculated
288// and stored as an additional signal value.
289// By means of the GetVetoSignal memberfunction the confidence level of
290// association can always be updated by the user.
291// In case the user wants to invoke a more detailed extrapolation procedure,
292// the automatic extrapolation can be suppressed by setting the argument
293// extr=0. In this case it is assumed that the AliSignal as entered via
294// the argument contains already the extrapolated position vector and
295// corresponding errors.
296// Note : Three additional values are added to the original AliSignal
297// to hold the chi2, ndf and confidence level values of the association.
d88f97cc 298 if (!fVetos)
299 {
300 fNvetos=0;
301 fVetos=new TObjArray();
6516b62d 302 fVetos->SetOwner();
d88f97cc 303 }
304
8e8e6c7f 305 Int_t nvalues=s.GetNvalues();
c72198f1 306 AliSignal* sx=new AliSignal(s); // Additional values will be added
8e8e6c7f 307 TString name=s.GetName();
308 name.Append(" + additional chi2, ndf and CL values");
309 sx->SetName(name);
310
311 Double_t vecc[3],vecv[3];
c72198f1 312 if (extr)
8e8e6c7f 313 {
314 // Extrapolate the veto hit position
315 Double_t scale=1;
316 GetPosition(vecc,"sph");
317 s.GetPosition(vecv,"sph");
318 if (vecv[0]) scale=vecc[0]/vecv[0];
319 Ali3Vector r=s*scale;
320 sx->SetPosition(r);
321 }
d88f97cc 322
8e8e6c7f 323 // Calculate the confidence level of association
324 GetPosition(vecc,"car");
325 sx->GetPosition(vecv,"car");
326 Double_t dx=vecc[0]-vecv[0];
327 Double_t dy=vecc[1]-vecv[1];
328 GetPositionErrors(vecc,"car");
329 sx->GetPositionErrors(vecv,"car");
330 Double_t sxc2=vecc[0]*vecc[0];
331 Double_t syc2=vecc[1]*vecc[1];
332 Double_t sxv2=vecv[0]*vecv[0];
333 Double_t syv2=vecv[1]*vecv[1];
334 Double_t sumx2=sxc2+sxv2;
335 Double_t sumy2=syc2+syv2;
336 Double_t chi2=0;
337 if (sumx2>0 && sumy2>0) chi2=(dx*dx/sumx2)+(dy*dy/sumy2);
338 Int_t ndf=2;
339 AliMath m;
340 Double_t prob=m.Prob(chi2,ndf);
341 if (chi2>0) sx->SetSignal(chi2,nvalues+1);
342 if (ndf>0) sx->SetSignal(ndf,nvalues+2);
343 if (prob>0) sx->SetSignal(prob,nvalues+3);
344
345 fVetos->Add(sx);
346 fNvetos++;
d88f97cc 347}
348///////////////////////////////////////////////////////////////////////////
349Int_t AliCalcluster::GetNvetos()
350{
351// Provide the number of veto signals associated to the cluster
352 return fNvetos;
353}
354///////////////////////////////////////////////////////////////////////////
355AliSignal* AliCalcluster::GetVetoSignal(Int_t i)
356{
959fbac5 357// Provide access to the i-th veto signal of this cluster.
358// Note : The first hit corresponds to i=1.
6516b62d 359 if (!fVetos)
d88f97cc 360 {
6516b62d 361 cout << " *AliCalcluster::GetVetoSignal* No veto signals present." << endl;
362 return 0;
d88f97cc 363 }
364 else
365 {
6516b62d 366 if (i>0 && i<=fNvetos)
367 {
368 return (AliSignal*)fVetos->At(i-1);
369 }
370 else
371 {
372 cout << " *AliCalcluster::GetVetoSignal* Signal number " << i << " out of range."
373 << " Nvetos = " << fNvetos << endl;
374 return 0;
375 }
d88f97cc 376 }
377}
378///////////////////////////////////////////////////////////////////////////
959fbac5 379Float_t AliCalcluster::GetVetoLevel()
380{
381// Provide the confidence level of best associated veto signal.
382 Float_t cl=0;
383 Float_t clmax=0;
8e8e6c7f 384 AliSignal* s=0;
385 Int_t nvalues=0;
959fbac5 386 if (fVetos)
387 {
388 for (Int_t i=0; i<fNvetos; i++)
389 {
8e8e6c7f 390 s=((AliSignal*)fVetos->At(i));
391 if (s)
392 {
393 nvalues=s->GetNvalues();
394 cl=s->GetSignal(nvalues);
395 if (cl>clmax) clmax=cl;
396 }
959fbac5 397 }
398 }
399 return clmax;
400}
401///////////////////////////////////////////////////////////////////////////
402Int_t AliCalcluster::HasVetoHit(Double_t cl)
403{
404// Investigate if cluster has an associated veto hit with conf. level > cl.
405// Returns 1 if there is such an associated veto hit, otherwise returns 0.
406// Note : This function is faster than GetVetoLevel().
8e8e6c7f 407 AliSignal* s=0;
408 Int_t nvalues=0;
959fbac5 409 if (fVetos)
410 {
411 for (Int_t i=0; i<fNvetos; i++)
412 {
8e8e6c7f 413 s=((AliSignal*)fVetos->At(i));
414 if (s)
415 {
416 nvalues=s->GetNvalues();
417 if (s->GetSignal(nvalues) > cl) return 1;
418 }
959fbac5 419 }
420 }
421 return 0;
422}
423///////////////////////////////////////////////////////////////////////////