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