Modifications of AliMath.cxx, AliMath.h, AliVertex.cxx, AliVertex.h
[u/mrichter/AliRoot.git] / RALICE / AliCalorimeter.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
16/*
17$Log$
f40f8fbd 18Revision 1.3 1999/11/03 14:23:17 fca
19New version of RALICE introduced
20
959fbac5 21Revision 1.2 1999/09/29 09:24:28 fca
22Introduction of the Copyright and cvs Log
23
4c039060 24*/
25
959fbac5 26///////////////////////////////////////////////////////////////////////////
27// Class AliCalorimeter
28// Description of a modular calorimeter system.
29// A matrix geometry is used in which a module is identified by (row,col).
30// Note : First module is identified as (1,1).
31//
32// This is the way to define and enter signals into a calorimeter :
33//
34// AliCalorimeter cal(10,15); // Calorimeter of 10x15 modules
35// // All module signals set to 0.
36// cal.AddSignal(5,7,85.4);
37// cal.AddSignal(5,7,25.9);
38// cal.AddSignal(3,5,1000);
39// cal.SetSignal(5,7,10.3);
40// cal.Reset(3,5); // Reset module (3,5) as being 'not fired'
41// // All module data are re-initialised.
42// cal.SetEdgeOn(1,1); // Declare module (1,1) as an 'edge module'
43// cal.SetDead(8,3);
44// cal.SetGain(2,8,3.2);
45//
46// Float_t vec[3]={6,1,20};
47// cal.SetPosition(2,8,vec,"car");
48//
49// Float_t loc[3]={-1,12,3};
50// cal.AddVetoSignal(loc,"car"); // Associate (extrapolated) position as a veto
51//
52// cal.Group(2); // Group 'fired' modules into clusters
53// // Perform grouping over 2 rings around the center
54// cal.Reset(); // Reset the complete calorimeter
55// // Normally to prepare for the next event data
56// // Note : Module gain, edge and dead flags remain
57//
58//--- Author: Nick van Eijndhoven 13-jun-1997 UU-SAP Utrecht
f40f8fbd 59//- Modified: NvE 03-mar-2000 UU-SAP Utrecht
959fbac5 60///////////////////////////////////////////////////////////////////////////
61
d88f97cc 62#include "AliCalorimeter.h"
959fbac5 63
d88f97cc 64ClassImp(AliCalorimeter) // Class implementation to enable ROOT I/O
65
66AliCalorimeter::AliCalorimeter()
67{
68// Default constructor, all parameters set to 0
69 fNrows=0;
70 fNcolumns=0;
71 fNsignals=0;
72 fNclusters=0;
73 fMatrix=0;
74 fClusters=0;
75 fModules=0;
76 fHmodules=0;
77 fHclusters=0;
78 fNvetos=0;
79 fVetos=0;
f40f8fbd 80 fAttributes=0;
81 fGains=0;
82 fPositions=0;
d88f97cc 83}
84///////////////////////////////////////////////////////////////////////////
85AliCalorimeter::~AliCalorimeter()
86{
f40f8fbd 87// Destructor to delete memory allocated to the various arrays and matrix
88 if (fModules)
d88f97cc 89 {
f40f8fbd 90 fModules->Delete();
91 delete fModules;
92 fModules=0;
d88f97cc 93 }
d88f97cc 94 if (fClusters)
95 {
96 fClusters->Delete();
97 delete fClusters;
98 fClusters=0;
99 }
d88f97cc 100 if (fVetos)
101 {
102 fVetos->Delete();
103 delete fVetos;
104 fVetos=0;
105 }
f40f8fbd 106 if (fHmodules)
107 {
108 delete fHmodules;
109 fHmodules=0;
110 }
111 if (fHclusters)
112 {
113 delete fHclusters;
114 fHclusters=0;
115 }
116 if (fMatrix || fPositions)
117 {
118 for (Int_t i=0; i<fNrows; i++)
119 {
120 for (Int_t j=0; j<fNcolumns; j++)
121 {
122 fMatrix[i][j]=0;
123 if (fPositions[i][j]) delete fPositions[i][j];
124 }
125 }
126 if (fMatrix)
127 {
128 delete [] fMatrix;
129 fMatrix=0;
130 }
131 if (fPositions)
132 {
133 delete [] fPositions;
134 fPositions=0;
135 }
136 }
137 if (fGains)
138 {
139 delete fGains;
140 fGains=0;
141 }
142 if (fAttributes)
143 {
144 delete fAttributes;
145 fAttributes=0;
146 }
d88f97cc 147}
148///////////////////////////////////////////////////////////////////////////
f40f8fbd 149AliCalorimeter::AliCalorimeter(Int_t nrow,Int_t ncol)
d88f97cc 150{
151// Create a calorimeter module matrix
152 fNrows=nrow;
153 fNcolumns=ncol;
154 fNsignals=0;
155 fNclusters=0;
156 fClusters=0;
f40f8fbd 157 fAttributes=new TMatrix(nrow,ncol);
158 fGains=new TMatrix(nrow,ncol);
159 fMatrix=new AliCalmodule**[nrow];
160 fPositions=new AliPosition**[nrow];
161 for (Int_t row=0; row<nrow; row++)
d88f97cc 162 {
f40f8fbd 163 fMatrix[row]=new AliCalmodule*[ncol];
164 fPositions[row]=new AliPosition*[ncol];
165 // Initialise the various matrices
166 for (Int_t col=0; col<ncol; col++)
167 {
168 fMatrix[row][col]=0;
169 fPositions[row][col]=0;
170 (*fGains)(row,col)=1;
171 (*fAttributes)(row,col)=0;
172 }
d88f97cc 173 }
f40f8fbd 174
d88f97cc 175 // Mark the edge modules
176 for (Int_t j=0; j<ncol; j++)
177 {
f40f8fbd 178 (*fAttributes)(0,j)=10;
179 (*fAttributes)(nrow-1,j)=10;
d88f97cc 180 }
f40f8fbd 181 for (Int_t i=0; i<nrow; i++)
d88f97cc 182 {
f40f8fbd 183 (*fAttributes)(i,0)=10;
184 (*fAttributes)(i,ncol-1)=10;
d88f97cc 185 }
186
187 fModules=new TObjArray(); // Default size, expanded automatically
188
189 fHmodules=0;
190 fHclusters=0;
191
192 fNvetos=0;
193 fVetos=0;
194}
195///////////////////////////////////////////////////////////////////////////
196Int_t AliCalorimeter::GetNrows()
197{
198// Provide the number of rows for the calorimeter module matrix
199 return fNrows;
200}
201///////////////////////////////////////////////////////////////////////////
202Int_t AliCalorimeter::GetNcolumns()
203{
204// Provide the number of columns for the calorimeter module matrix
205 return fNcolumns;
206}
207///////////////////////////////////////////////////////////////////////////
f40f8fbd 208void AliCalorimeter::SetSignal(Int_t row,Int_t col,Float_t sig)
d88f97cc 209{
210// Set the signal for a certain calorimeter module
211
212 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
213
214 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
215 {
f40f8fbd 216 AliCalmodule* m=fMatrix[row-1][col-1];
217 if (!m) // only count new modules
d88f97cc 218 {
219 fNsignals++;
f40f8fbd 220 m=new AliCalmodule;
221 AliPosition* r=fPositions[row-1][col-1];
222 if (r) m->SetPosition(*r);
223 fModules->Add(m);
224 fMatrix[row-1][col-1]=m;
d88f97cc 225 }
f40f8fbd 226 m->SetSignal(row,col,sig);
d88f97cc 227 }
228 else
229 {
230 cout << " *AliCalorimeter::SetSignal* row,col : " << row << "," << col
231 << " out of range." << endl;
232 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
233 }
234}
235///////////////////////////////////////////////////////////////////////////
236void AliCalorimeter::AddSignal(Int_t row, Int_t col, Float_t sig)
237{
238// Add the signal to a certain calorimeter module
239
240 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
241
242 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
243 {
f40f8fbd 244 AliCalmodule* m=fMatrix[row-1][col-1];
245 if (!m) // only count new modules
246 {
247 SetSignal(row,col,sig);
248 }
249 else
250 {
251 m->AddSignal(row,col,sig);
252 }
253 }
254 else
255 {
256 cout << " *AliCalorimeter::AddSignal* row,col : " << row << "," << col
257 << " out of range." << endl;
258 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
259 }
260}
261///////////////////////////////////////////////////////////////////////////
262void AliCalorimeter::AddSignal(AliCalmodule* mod)
263{
264// Add the signal of module mod to the current calorimeter data.
265// This enables mixing of calorimeter data of various events.
266
267 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
268
269 Int_t row=mod->GetRow();
270 Int_t col=mod->GetColumn();
271 Float_t sig=mod->GetSignal();
272 AliPosition r=mod->GetPosition();
273
274 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
275 {
276 AliCalmodule* m=fMatrix[row-1][col-1];
277 if (!m) // No module existed yet at this position
d88f97cc 278 {
279 fNsignals++;
f40f8fbd 280 m=new AliCalmodule;
281 fModules->Add(m);
282 fMatrix[row-1][col-1]=m;
283 m->SetPosition(r);
d88f97cc 284 }
f40f8fbd 285 m->AddSignal(row,col,sig);
286 if (!fPositions[row-1][col-1]) fPositions[row-1][col-1]=new AliPosition(r);
d88f97cc 287 }
288 else
289 {
290 cout << " *AliCalorimeter::AddSignal* row,col : " << row << "," << col
291 << " out of range." << endl;
292 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
293 }
294}
295///////////////////////////////////////////////////////////////////////////
f40f8fbd 296void AliCalorimeter::Reset(Int_t row,Int_t col)
d88f97cc 297{
298// Reset the signal for a certain calorimeter module
299
300 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
301
302 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
303 {
f40f8fbd 304 AliCalmodule* m=fMatrix[row-1][col-1];
959fbac5 305 if (m)
306 {
f40f8fbd 307 fModules->Remove(m);
959fbac5 308 fNsignals--;
309 fModules->Compress();
f40f8fbd 310 delete m;
311 fMatrix[row-1][col-1]=0;
959fbac5 312 }
d88f97cc 313 }
314 else
315 {
316 cout << " *AliCalorimeter::Reset* row,col : " << row << "," << col
317 << " out of range." << endl;
318 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
319 }
320}
321///////////////////////////////////////////////////////////////////////////
322void AliCalorimeter::Reset()
323{
324// Reset the signals for the complete calorimeter
325// Normally this is done to prepare for the data of the next event
326// Note : Module gains, edge and dead flags remain unchanged
327
328 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
329
330 fNsignals=0;
f40f8fbd 331 if (fModules) fModules->Delete();
d88f97cc 332 for (Int_t i=0; i<fNrows; i++)
333 {
334 for (Int_t j=0; j<fNcolumns; j++)
335 {
f40f8fbd 336 fMatrix[i][j]=0;
d88f97cc 337 }
338 }
d88f97cc 339
340 fNclusters=0;
341 if (fClusters)
342 {
343 fClusters->Delete();
344 delete fClusters;
345 fClusters=0;
346 }
347
348 fNvetos=0;
349 if (fVetos)
350 {
351 fVetos->Delete();
352 delete fVetos;
353 fVetos=0;
354 }
355}
356///////////////////////////////////////////////////////////////////////////
f40f8fbd 357Float_t AliCalorimeter::GetSignal(Int_t row,Int_t col)
d88f97cc 358{
959fbac5 359// Provide the signal of a certain calorimeter module.
360// In case the module was marked dead, 0 is returned.
d88f97cc 361
362 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
363
364 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
365 {
959fbac5 366 Float_t signal=0;
f40f8fbd 367 AliCalmodule* m=fMatrix[row-1][col-1];
368 if (m)
369 {
370 Int_t dead=m->GetDeadValue();
371 if (!dead) signal=m->GetSignal();
372 }
959fbac5 373 return signal;
d88f97cc 374 }
375 else
376 {
377 cout << " *AliCalorimeter::GetSignal* row,col : " << row << "," << col
378 << " out of range." << endl;
379 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
380 return 0;
381 }
382}
383///////////////////////////////////////////////////////////////////////////
f40f8fbd 384void AliCalorimeter::SetEdgeOn(Int_t row,Int_t col)
d88f97cc 385{
386// Indicate a certain calorimeter module as 'edge module'
387
388 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
389
390 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
391 {
f40f8fbd 392 Float_t word=(*fAttributes)(row-1,col-1);
393 Int_t iword=int(word+0.1);
394 Int_t dead=iword%10;
395 Int_t edge=1;
396 (*fAttributes)(row-1,col-1)=float(dead+10*edge);
d88f97cc 397 }
398 else
399 {
400 cout << " *AliCalorimeter::SetEdgeOn* row,col : " << row << "," << col
401 << " out of range." << endl;
402 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
403 }
404}
405///////////////////////////////////////////////////////////////////////////
f40f8fbd 406void AliCalorimeter::SetEdgeOff(Int_t row,Int_t col)
d88f97cc 407{
408// Indicate a certain calorimeter module as 'non-edge module'
409
410 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
411
412 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
413 {
f40f8fbd 414 Float_t word=(*fAttributes)(row-1,col-1);
415 Int_t iword=int(word+0.1);
416 Int_t dead=iword%10;
417 Int_t edge=0;
418 (*fAttributes)(row-1,col-1)=float(dead+10*edge);
d88f97cc 419 }
420 else
421 {
422 cout << " *AliCalorimeter::SetEdgeOff* row,col : " << row << "," << col
423 << " out of range." << endl;
424 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
425 }
426}
427///////////////////////////////////////////////////////////////////////////
f40f8fbd 428void AliCalorimeter::SetDead(Int_t row,Int_t col)
d88f97cc 429{
430// Indicate a certain calorimeter module as 'dead module'
431
432 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
433
434 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
435 {
f40f8fbd 436 Float_t word=(*fAttributes)(row-1,col-1);
437 Int_t iword=int(word+0.1);
438 Int_t edge=iword/10;
439 Int_t dead=1;
440 (*fAttributes)(row-1,col-1)=float(dead+10*edge);
441 if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetDead();
d88f97cc 442
443 // Increase the 'edge value' of surrounding modules
444 Int_t rlow=row-1;
445 Int_t rup=row+1;
446 Int_t clow=col-1;
447 Int_t cup=col+1;
448
449 if (rlow < 1) rlow=row;
450 if (rup > fNrows) rup=fNrows;
451 if (clow < 1) clow=col;
452 if (cup > fNcolumns) cup=fNcolumns;
453
454 for (Int_t i=rlow; i<=rup; i++)
455 {
456 for (Int_t j=clow; j<=cup; j++)
457 {
f40f8fbd 458 if (i!=row || j!=col) // No increase of edge value for the dead module itself
459 {
460 word=(*fAttributes)(i-1,j-1);
461 iword=int(word+0.1);
462 edge=iword/10;
463 dead=iword%10;
464 edge++;
465 (*fAttributes)(i-1,j-1)=float(dead+10*edge);
466 }
d88f97cc 467 }
468 }
d88f97cc 469 }
470 else
471 {
472 cout << " *AliCalorimeter::SetDead* row,col : " << row << "," << col
473 << " out of range." << endl;
474 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
475 }
476}
477///////////////////////////////////////////////////////////////////////////
f40f8fbd 478void AliCalorimeter::SetAlive(Int_t row,Int_t col)
d88f97cc 479{
480// Indicate a certain calorimeter module as 'active module'
481
482 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
483
484 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
485 {
f40f8fbd 486 Float_t word=(*fAttributes)(row-1,col-1);
487 Int_t iword=int(word+0.1);
488 Int_t edge=iword/10;
489 Int_t dead=0;
490 (*fAttributes)(row-1,col-1)=float(dead+10*edge);
491 if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetAlive();
d88f97cc 492
493 // Decrease the 'edge value' of surrounding modules
494 Int_t rlow=row-1;
495 Int_t rup=row+1;
496 Int_t clow=col-1;
497 Int_t cup=col+1;
498
499 if (rlow < 1) rlow=row;
500 if (rup > fNrows) rup=fNrows;
501 if (clow < 1) clow=col;
502 if (cup > fNcolumns) cup=fNcolumns;
503
504 for (Int_t i=rlow; i<=rup; i++)
505 {
506 for (Int_t j=clow; j<=cup; j++)
507 {
f40f8fbd 508 if (i!=row || j!=col) // No decrease of edge value for the dead module itself
509 {
510 word=(*fAttributes)(i-1,j-1);
511 iword=int(word+0.1);
512 edge=iword/10;
513 dead=iword%10;
514 if (edge>0) edge--;
515 (*fAttributes)(i-1,j-1)=float(dead+10*edge);
516 }
d88f97cc 517 }
518 }
d88f97cc 519 }
520 else
521 {
522 cout << " *AliCalorimeter::SetAlive* row,col : " << row << "," << col
523 << " out of range." << endl;
524 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
525 }
526}
527///////////////////////////////////////////////////////////////////////////
f40f8fbd 528void AliCalorimeter::SetGain(Int_t row,Int_t col,Float_t gain)
d88f97cc 529{
530// Set the gain value for a certain calorimeter module
531
532 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
533
534 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
535 {
f40f8fbd 536 (*fGains)(row-1,col-1)=gain;
537 if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetGain(gain);
d88f97cc 538 }
539 else
540 {
541 cout << " *AliCalorimeter::SetGain* row,col : " << row << "," << col
542 << " out of range." << endl;
543 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
544 }
545}
546///////////////////////////////////////////////////////////////////////////
547void AliCalorimeter::SetPosition(Int_t row,Int_t col,Float_t* vec,TString f)
548{
549// Set the position in user coordinates for a certain calorimeter module
550
551 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
552
553 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
554 {
f40f8fbd 555 if (!fPositions[row-1][col-1]) fPositions[row-1][col-1]=new AliPosition;
556 (fPositions[row-1][col-1])->SetVector(vec,f);
557 if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetPosition(vec,f);
d88f97cc 558 }
559 else
560 {
561 cout << " *AliCalorimeter::SetPosition* row,col : " << row << "," << col
562 << " out of range." << endl;
563 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
564 }
565}
566///////////////////////////////////////////////////////////////////////////
f40f8fbd 567void AliCalorimeter::SetPosition(Int_t row,Int_t col,Ali3Vector& r)
d88f97cc 568{
f40f8fbd 569// Set the position for a certain calorimeter module
d88f97cc 570
571 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
572
573 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
574 {
f40f8fbd 575 if (!fPositions[row-1][col-1]) fPositions[row-1][col-1]=new AliPosition;
576 (fPositions[row-1][col-1])->SetPosition(r);
577 if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetPosition(r);
578 }
579 else
580 {
581 cout << " *AliCalorimeter::SetPosition* row,col : " << row << "," << col
582 << " out of range." << endl;
583 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
584 }
585}
586///////////////////////////////////////////////////////////////////////////
587Int_t AliCalorimeter::GetEdgeValue(Int_t row,Int_t col)
588{
589// Provide the value of the edge flag of a certain module
590
591 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
592 {
593 Float_t word=(*fAttributes)(row-1,col-1);
594 Int_t iword=int(word+0.1);
595 Int_t edge=iword/10;
596 return edge;
d88f97cc 597 }
598 else
599 {
600 cout << " *AliCalorimeter::GetEdgeValue* row,col : " << row << "," << col
601 << " out of range." << endl;
602 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
603 return 0;
604 }
605}
606///////////////////////////////////////////////////////////////////////////
f40f8fbd 607Int_t AliCalorimeter::GetDeadValue(Int_t row,Int_t col)
d88f97cc 608{
609// Provide the value of the dead flag of a certain module
610
d88f97cc 611 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
612 {
f40f8fbd 613 Float_t word=(*fAttributes)(row-1,col-1);
614 Int_t iword=int(word+0.1);
615 Int_t dead=iword%10;
616 return dead;
d88f97cc 617 }
618 else
619 {
620 cout << " *AliCalorimeter::GetDeadValue* row,col : " << row << "," << col
621 << " out of range." << endl;
622 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
623 return 0;
624 }
625}
626///////////////////////////////////////////////////////////////////////////
f40f8fbd 627Float_t AliCalorimeter::GetGain(Int_t row,Int_t col)
d88f97cc 628{
629// Provide the gain value of a certain module
630
d88f97cc 631 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
632 {
f40f8fbd 633 return (*fGains)(row-1,col-1);
d88f97cc 634 }
635 else
636 {
637 cout << " *AliCalorimeter::GetGain* row,col : " << row << "," << col
638 << " out of range." << endl;
639 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
640 return 0;
641 }
642}
643///////////////////////////////////////////////////////////////////////////
644void AliCalorimeter::GetPosition(Int_t row,Int_t col,Float_t* vec,TString f)
645{
646// Return the position in user coordinates for a certain calorimeter module
647
648 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
649
650 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
651 {
f40f8fbd 652// if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->GetPosition(vec,f);
653 if (fPositions[row-1][col-1]) (fPositions[row-1][col-1])->GetVector(vec,f);
d88f97cc 654 }
655 else
656 {
657 cout << " *AliCalorimeter::GetPosition* row,col : " << row << "," << col
658 << " out of range." << endl;
659 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
660 }
661}
662///////////////////////////////////////////////////////////////////////////
f40f8fbd 663AliPosition* AliCalorimeter::GetPosition(Int_t row,Int_t col)
664{
665// Access to the position of a certain calorimeter module
666
667 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
668
669 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
670 {
671 return fPositions[row-1][col-1];
672 }
673 else
674 {
675 cout << " *AliCalorimeter::GetPosition* row,col : " << row << "," << col
676 << " out of range." << endl;
677 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
678 return 0;
679 }
680}
681///////////////////////////////////////////////////////////////////////////
682Float_t AliCalorimeter::GetClusteredSignal(Int_t row,Int_t col)
d88f97cc 683{
684// Provide the module signal after clustering
685
686 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
687
688 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
689 {
f40f8fbd 690 if (fMatrix[row-1][col-1])
691 {
692 return (fMatrix[row-1][col-1])->GetClusteredSignal();
693 }
694 else
695 {
696 return 0;
697 }
d88f97cc 698 }
699 else
700 {
701 cout << " *AliCalorimeter::GetClusteredSignal* row,col : " << row << "," << col
702 << " out of range." << endl;
703 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
704 return 0;
705 }
706}
707///////////////////////////////////////////////////////////////////////////
708Int_t AliCalorimeter::GetNsignals()
709{
710// Provide the number of modules that contain a signal
711// Note : The number of modules marked 'dead' but which had a signal
712// are included.
713 return fNsignals;
714}
715///////////////////////////////////////////////////////////////////////////
716void AliCalorimeter::Group(Int_t n)
717{
718// Group the individual modules into clusters
719// Module signals of n rings around the central module will be grouped
720
721 if (fNsignals > 0) // Directly return if no modules fired
722 {
723 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
724
725 if (fNclusters > 0) Ungroup(); // Restore unclustered situation if needed
726
727 // Order the modules with decreasing signal
959fbac5 728 AliCalmodule** ordered=new AliCalmodule*[fNsignals]; // temp. array for ordered modules
729 Int_t nord=0;
730 Sortm(ordered,nord);
d88f97cc 731
732 // Clustering of modules. Start with the highest signal.
733 if (fClusters)
734 {
735 fClusters->Delete();
736 delete fClusters;
737 fClusters=0;
738 }
739 fClusters=new TObjArray();
740 fNclusters=0;
741 Int_t row=0;
742 Int_t col=0;
743 AliCalcluster* c=0;
f40f8fbd 744 AliCalmodule* m=0;
959fbac5 745 for (Int_t i=0; i<nord; i++)
d88f97cc 746 {
959fbac5 747 row=ordered[i]->GetRow(); // row number of cluster center
748 col=ordered[i]->GetColumn(); // column number of cluster center
d88f97cc 749 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
750 {
f40f8fbd 751 m=fMatrix[row-1][col-1];
752 if (!m) continue;
753
d88f97cc 754 // only use modules not yet used in a cluster
f40f8fbd 755 if (m->GetClusteredSignal() > 0.)
d88f97cc 756 {
f40f8fbd 757 Int_t edge=GetEdgeValue(row,col);
d88f97cc 758 c=new AliCalcluster;
f40f8fbd 759 if (!edge) c->Start(*m); // module to start the cluster if not on edge
760 if (c->GetNmodules() > 0) // cluster started successfully (no edge)
d88f97cc 761 {
762 fClusters->Add(c);
763 fNclusters++; // update cluster counter
764 AddRing(row,col,n); // add signals of n rings around the center
765 }
766 else
767 {
768 if (c) delete c;
769 c=0;
770 }
771 }
772 }
773 }
774
775 // Delete the temp. array
959fbac5 776 if (ordered)
777 {
778 for (Int_t j=0; j<nord; j++)
779 {
780 ordered[j]=0;
781 }
782 delete [] ordered;
783 }
d88f97cc 784 }
785}
786///////////////////////////////////////////////////////////////////////////
959fbac5 787void AliCalorimeter::Sortm(AliCalmodule** ordered,Int_t& nord)
d88f97cc 788{
789// Order the modules with decreasing signal
790
959fbac5 791 nord=0;
d88f97cc 792 for (Int_t i=0; i<fNrows; i++) // loop over all modules of the matrix
793 {
794 for (Int_t ii=0; ii<fNcolumns; ii++)
795 {
959fbac5 796 if (GetSignal(i+1,ii+1) <= 0.) continue; // only take alive modules with a signal
d88f97cc 797
798 if (nord == 0) // store the first module with a signal at the first ordered position
799 {
800 nord++;
f40f8fbd 801 ordered[nord-1]=fMatrix[i][ii];
d88f97cc 802 continue;
803 }
804
805 for (Int_t j=0; j<=nord; j++) // put module in the right ordered position
806 {
807 if (j == nord) // module has smallest signal seen so far
808 {
809 nord++;
f40f8fbd 810 ordered[j]=fMatrix[i][ii]; // add module at the end
d88f97cc 811 break; // go for next matrix module
812 }
813
959fbac5 814 if (GetSignal(i+1,ii+1) < ordered[j]->GetSignal()) continue;
d88f97cc 815
816 nord++;
959fbac5 817 for (Int_t k=nord-1; k>j; k--) // create empty position
818 {
819 ordered[k]=ordered[k-1];
820 }
f40f8fbd 821 ordered[j]=fMatrix[i][ii]; // put module at empty position
d88f97cc 822 break; // go for next matrix module
823 }
824 }
825 }
826}
827///////////////////////////////////////////////////////////////////////////
828void AliCalorimeter::AddRing(Int_t row, Int_t col, Int_t n)
829{
830// Add module signals of 1 ring around (row,col) to current cluster
831// n denotes the maximum number of rings around cluster center
832// Note : This function is used recursively
833
834 if (n >= 1) // Check if any rings left for recursive calls
835 {
836 Float_t signal=GetSignal(row,col); // signal of (row,col) module
837
838 Int_t lrow=row-1; if (lrow < 1) lrow=1; // row lowerbound for ring
839 Int_t urow=row+1; if (urow > fNrows) urow=fNrows; // row upperbound for ring
840 Int_t lcol=col-1; if (lcol < 1) lcol=1; // col lowerbound for ring
841 Int_t ucol=col+1; if (ucol > fNcolumns) ucol=fNcolumns; // row upperbound for ring
842
843 for (Int_t i=lrow; i<=urow; i++)
844 {
845 for (Int_t j=lcol; j<=ucol; j++)
846 {
847 // add module(i,j) to cluster if the signal <= signal(row,col)
959fbac5 848 if (GetSignal(i,j) <= signal)
d88f97cc 849 {
f40f8fbd 850 AliCalmodule* m=fMatrix[i-1][j-1];
851 if (m) ((AliCalcluster*)fClusters->At(fNclusters-1))->Add(*m);
d88f97cc 852 }
853 AddRing(i,j,n-1); // Go for ring of modules around this (i,j) one
854 }
855 }
856 }
857}
858///////////////////////////////////////////////////////////////////////////
859Int_t AliCalorimeter::GetNclusters()
860{
861// Provide the number of clusters
862 return fNclusters;
863}
864///////////////////////////////////////////////////////////////////////////
865AliCalcluster* AliCalorimeter::GetCluster(Int_t j)
866{
867// Provide cluster number j
868// Note : j=1 denotes the first cluster
869 if ((j >= 1) && (j <= fNclusters))
870 {
871 return (AliCalcluster*)fClusters->At(j-1);
872 }
873 else
874 {
875 cout << " *AliCalorimeter::GetCluster* cluster number : " << j
876 << " out of range." << endl;
877 cout << " -- Cluster number 1 (if any) returned " << endl;
878 return (AliCalcluster*)fClusters->At(0);
879 }
880}
881///////////////////////////////////////////////////////////////////////////
882AliCalmodule* AliCalorimeter::GetModule(Int_t j)
883{
884// Provide 'fired' module number j
885// Note : j=1 denotes the first 'fired' module
886 if ((j >= 1) && (j <= fNsignals))
887 {
888 return (AliCalmodule*)fModules->At(j-1);
889 }
890 else
891 {
892 cout << " *AliCalorimeter::GetModule* module number : " << j
893 << " out of range." << endl;
894 cout << " -- Fired module number 1 (if any) returned " << endl;
895 return (AliCalmodule*)fModules->At(0);
896 }
897}
898///////////////////////////////////////////////////////////////////////////
959fbac5 899AliCalmodule* AliCalorimeter::GetModule(Int_t row,Int_t col)
900{
901// Provide access to module (row,col).
902// Note : first module is at (1,1).
903
904 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
905
906 if (row>=1 && row<=fNrows && col>=1 && col<=fNcolumns)
907 {
f40f8fbd 908 return fMatrix[row-1][col-1];
959fbac5 909 }
910 else
911 {
912 cout << " *AliCalorimeter::GetModule* row,col : " << row << ", " << col
913 << " out of range." << endl;
914 return 0;
915 }
916}
917///////////////////////////////////////////////////////////////////////////
d88f97cc 918TH2F* AliCalorimeter::DrawModules()
919{
920// Provide a lego plot of the module signals
921
922 if (fHmodules)
923 {
924 fHmodules->Reset();
925 }
926 else
927 {
928 fHmodules=new TH2F("fHmodules","Module signals",
929 fNcolumns,0.5,float(fNcolumns)+0.5,fNrows,0.5,float(fNrows)+0.5);
930
931 fHmodules->SetDirectory(0); // Suppress global character of histo pointer
932 }
933
934 AliCalmodule* m;
935 Float_t row,col,signal;
959fbac5 936 Int_t dead;
d88f97cc 937 for (Int_t i=0; i<fNsignals; i++)
938 {
939 m=(AliCalmodule*)fModules->At(i);
940 if (m)
941 {
942 row=float(m->GetRow());
943 col=float(m->GetColumn());
959fbac5 944 dead=m->GetDeadValue();
945 signal=0;
946 if (!dead) signal=m->GetSignal();
d88f97cc 947 if (signal>0.) fHmodules->Fill(col,row,signal);
948 }
949 }
950
951 fHmodules->Draw("lego");
952 return fHmodules;
953}
954///////////////////////////////////////////////////////////////////////////
955TH2F* AliCalorimeter::DrawClusters()
956{
957// Provide a lego plot of the cluster signals
958
959 if (fHclusters)
960 {
961 fHclusters->Reset();
962 }
963 else
964 {
965 fHclusters=new TH2F("fHclusters","Cluster signals",
966 fNcolumns,0.5,float(fNcolumns)+0.5,fNrows,0.5,float(fNrows)+0.5);
967
968 fHclusters->SetDirectory(0); // Suppress global character of histo pointer
969 }
970
971 AliCalcluster* c;
972 Float_t row,col,signal;
973 for (Int_t i=0; i<fNclusters; i++)
974 {
975 c=(AliCalcluster*)fClusters->At(i);
976 if (c)
977 {
978 row=float(c->GetRow());
979 col=float(c->GetColumn());
980 signal=c->GetSignal();
981 if (signal>0.) fHclusters->Fill(col,row,signal);
982 }
983 }
984
985 fHclusters->Draw("lego");
986 return fHclusters;
987}
988///////////////////////////////////////////////////////////////////////////
989void AliCalorimeter::LoadMatrix()
990{
991// Load the Calorimeter module matrix data back from the TObjArray
959fbac5 992
f40f8fbd 993 // Initialise the module matrix
994 if (!fMatrix)
d88f97cc 995 {
f40f8fbd 996 fMatrix=new AliCalmodule**[fNrows];
997 for (Int_t i=0; i<fNrows; i++)
d88f97cc 998 {
f40f8fbd 999 fMatrix[i]=new AliCalmodule*[fNcolumns];
d88f97cc 1000 }
d88f97cc 1001 }
f40f8fbd 1002
1003 // Initialise the position matrix
1004 if (!fPositions)
d88f97cc 1005 {
f40f8fbd 1006 fPositions=new AliPosition**[fNrows];
1007 for (Int_t j=0; j<fNrows; j++)
1008 {
1009 fPositions[j]=new AliPosition*[fNcolumns];
1010 }
1011 }
1012
1013 for (Int_t jrow=0; jrow<fNrows; jrow++)
1014 {
1015 for (Int_t jcol=0; jcol<fNcolumns; jcol++)
1016 {
1017 fMatrix[jrow][jcol]=0;
1018 fPositions[jrow][jcol]=0;
1019 }
d88f97cc 1020 }
1021
f40f8fbd 1022 // Copy the module pointers back into the matrix
959fbac5 1023 AliCalmodule* m=0;
1024 Int_t row=0;
1025 Int_t col=0;
1026 Int_t nsig=0;
f40f8fbd 1027 if (fModules) nsig=fModules->GetEntries();
959fbac5 1028 for (Int_t j=0; j<nsig; j++)
d88f97cc 1029 {
1030 m=(AliCalmodule*)fModules->At(j);
959fbac5 1031 if (m)
1032 {
1033 row=m->GetRow();
1034 col=m->GetColumn();
f40f8fbd 1035 AliPosition r=m->GetPosition();
1036 fMatrix[row-1][col-1]=m;
1037 fPositions[row-1][col-1]=new AliPosition(r);
959fbac5 1038 }
d88f97cc 1039 }
1040}
1041///////////////////////////////////////////////////////////////////////////
1042void AliCalorimeter::Ungroup()
1043{
1044// Set the module signals back to the non-clustered situation
1045
1046 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
1047
f40f8fbd 1048 Int_t nsig=0;
1049 if (fModules) nsig=fModules->GetEntries();
1050
d88f97cc 1051 Float_t signal=0;
f40f8fbd 1052 AliCalmodule* m=0;
1053 for (Int_t j=0; j<nsig; j++)
d88f97cc 1054 {
f40f8fbd 1055 m=(AliCalmodule*)fModules->At(j);
1056 if (m)
d88f97cc 1057 {
f40f8fbd 1058 signal=m->GetSignal();
1059 m->SetClusteredSignal(signal);
d88f97cc 1060 }
1061 }
1062}
1063///////////////////////////////////////////////////////////////////////////
1064void AliCalorimeter::AddVetoSignal(Float_t* r,TString f,Float_t s)
1065{
1066// Associate an (extrapolated) AliSignal at location r as veto to the cal.
1067// Note : The default signal value (s) is 0
1068 if (!fVetos)
1069 {
1070 fNvetos=0;
1071 fVetos=new TObjArray();
1072 }
1073
1074 fVetos->Add(new AliSignal);
1075 fNvetos++;
1076
1077 ((AliSignal*)fVetos->At(fNvetos-1))->SetPosition(r,f);
1078 ((AliSignal*)fVetos->At(fNvetos-1))->SetSignal(s);
1079}
1080///////////////////////////////////////////////////////////////////////////
1081Int_t AliCalorimeter::GetNvetos()
1082{
1083// Provide the number of veto signals associated to the calorimeter
1084 return fNvetos;
1085}
1086///////////////////////////////////////////////////////////////////////////
1087AliSignal* AliCalorimeter::GetVetoSignal(Int_t i)
1088{
1089// Provide access to the i-th veto signal of this calorimeter
1090// Note : The first hit corresponds to i=1
1091
1092 if (i>0 && i<=fNvetos)
1093 {
1094 return (AliSignal*)fVetos->At(i-1);
1095 }
1096 else
1097 {
1098 cout << " *AliCalorimeter::GetVetoSignal* Signal number " << i
1099 << " out of range." << endl;
1100 cout << " --- First signal (if any) returned." << endl;
1101 return (AliSignal*)fVetos->At(0);
1102 }
1103}
1104///////////////////////////////////////////////////////////////////////////