This commit was generated by cvs2svn to compensate for changes in r165,
[u/mrichter/AliRoot.git] / RALICE / AliCalorimeter.cxx
1 #include "AliCalorimeter.h"
2  
3 ClassImp(AliCalorimeter) // Class implementation to enable ROOT I/O
4  
5 AliCalorimeter::AliCalorimeter()
6 {
7 // Default constructor, all parameters set to 0
8  fNrows=0;
9  fNcolumns=0;
10  fNsignals=0;
11  fNclusters=0;
12  fMatrix=0;
13  fClusters=0;
14  fModules=0;
15  fHmodules=0;
16  fHclusters=0;
17  fNvetos=0;
18  fVetos=0;
19 }
20 ///////////////////////////////////////////////////////////////////////////
21 AliCalorimeter::~AliCalorimeter()
22 {
23 // Destructor to delete memory allocated for matrix and cluster array
24  if (fMatrix)
25  {
26   for (Int_t i=0; i<fNrows; i++)
27   {
28    delete [] fMatrix[i];
29   }
30    delete [] fMatrix;
31  }
32  fMatrix=0;
33  if (fModules) delete fModules;
34  fModules=0;
35  if (fClusters)
36  {
37   fClusters->Delete();
38   delete fClusters;
39   fClusters=0;
40  }
41  if (fHmodules) delete fHmodules;
42  fHmodules=0;
43  if (fHclusters) delete fHclusters;
44  fHclusters=0;
45  if (fVetos)
46  {
47   fVetos->Delete();
48   delete fVetos;
49   fVetos=0;
50  }
51 }
52 ///////////////////////////////////////////////////////////////////////////
53 AliCalorimeter::AliCalorimeter(Int_t nrow, Int_t ncol)
54 {
55 // Create a calorimeter module matrix
56  fNrows=nrow;
57  fNcolumns=ncol;
58  fNsignals=0;
59  fNclusters=0;
60  fClusters=0;
61  fMatrix=new AliCalmodule*[nrow];
62  for (Int_t i=0; i<nrow; i++)
63  {
64   fMatrix[i]=new AliCalmodule[ncol];
65  }
66  // Mark the edge modules
67  for (Int_t j=0; j<ncol; j++)
68  {
69   fMatrix[0][j].SetEdgeOn();
70   fMatrix[nrow-1][j].SetEdgeOn();
71  }
72  for (Int_t k=0; k<nrow; k++)
73  {
74   fMatrix[k][0].SetEdgeOn();
75   fMatrix[k][ncol-1].SetEdgeOn();
76  }
77  
78  fModules=new TObjArray();  // Default size, expanded automatically
79  
80  fHmodules=0;
81  fHclusters=0;
82
83  fNvetos=0;
84  fVetos=0;
85 }
86 ///////////////////////////////////////////////////////////////////////////
87 Int_t AliCalorimeter::GetNrows()
88 {
89 // Provide the number of rows for the calorimeter module matrix
90  return fNrows;
91 }
92 ///////////////////////////////////////////////////////////////////////////
93 Int_t AliCalorimeter::GetNcolumns()
94 {
95 // Provide the number of columns for the calorimeter module matrix
96  return fNcolumns;
97 }
98 ///////////////////////////////////////////////////////////////////////////
99 void AliCalorimeter::SetSignal(Int_t row, Int_t col, Float_t sig)
100 {
101 // Set the signal for a certain calorimeter module
102  
103  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
104  
105  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
106  {
107   if (fMatrix[row-1][col-1].GetSignal() <= 0.) // only count new modules
108   {
109    fNsignals++;
110    fModules->Add(&(fMatrix[row-1][col-1]));
111   }
112   fMatrix[row-1][col-1].SetSignal(row,col,sig);
113  }
114  else
115  {
116   cout << " *AliCalorimeter::SetSignal* row,col : " << row << "," << col
117        << " out of range." << endl;
118   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
119  }
120 }
121 ///////////////////////////////////////////////////////////////////////////
122 void AliCalorimeter::AddSignal(Int_t row, Int_t col, Float_t sig)
123 {
124 // Add the signal to a certain calorimeter module
125  
126  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
127  
128  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
129  {
130   if (fMatrix[row-1][col-1].GetSignal() <= 0.) // only count new modules
131   {
132    fNsignals++;
133    fModules->Add(&(fMatrix[row-1][col-1]));
134   }
135   fMatrix[row-1][col-1].AddSignal(row,col,sig);
136  }
137  else
138  {
139   cout << " *AliCalorimeter::AddSignal* row,col : " << row << "," << col
140        << " out of range." << endl;
141   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
142  }
143 }
144 ///////////////////////////////////////////////////////////////////////////
145 void AliCalorimeter::Reset(Int_t row, Int_t col)
146 {
147 // Reset the signal for a certain calorimeter module
148  
149  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
150  
151  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
152  {
153   fMatrix[row-1][col-1].SetSignal(row,col,0);
154   fNsignals--;
155   fModules->Remove(&(fMatrix[row-1][col-1]));
156  }
157  else
158  {
159   cout << " *AliCalorimeter::Reset* row,col : " << row << "," << col
160        << " out of range." << endl;
161   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
162  }
163 }
164 ///////////////////////////////////////////////////////////////////////////
165 void AliCalorimeter::Reset()
166 {
167 // Reset the signals for the complete calorimeter
168 // Normally this is done to prepare for the data of the next event
169 // Note : Module gains, edge and dead flags remain unchanged
170  
171  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
172  
173  fNsignals=0;
174  for (Int_t i=0; i<fNrows; i++)
175  {
176   for (Int_t j=0; j<fNcolumns; j++)
177   {
178    fMatrix[i][j].SetSignal(i+1,j+1,0);
179   }
180  }
181  if (fModules) fModules->Clear();
182
183  fNclusters=0;
184  if (fClusters)
185  {
186   fClusters->Delete();
187   delete fClusters;
188   fClusters=0;
189  }
190
191  fNvetos=0;
192  if (fVetos)
193  {
194   fVetos->Delete();
195   delete fVetos;
196   fVetos=0;
197  }
198 }
199 ///////////////////////////////////////////////////////////////////////////
200 Float_t AliCalorimeter::GetSignal(Int_t row, Int_t col)
201 {
202 // Provide the signal of 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  {
208   return fMatrix[row-1][col-1].GetSignal();
209  }
210  else
211  {
212   cout << " *AliCalorimeter::GetSignal* row,col : " << row << "," << col
213        << " out of range." << endl;
214   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
215   return 0;
216  }
217 }
218 ///////////////////////////////////////////////////////////////////////////
219 void AliCalorimeter::SetEdgeOn(Int_t row, Int_t col)
220 {
221 // Indicate a certain calorimeter module as 'edge module'
222  
223  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
224  
225  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
226  {
227   fMatrix[row-1][col-1].SetEdgeOn();
228  }
229  else
230  {
231   cout << " *AliCalorimeter::SetEdgeOn* row,col : " << row << "," << col
232        << " out of range." << endl;
233   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
234  }
235 }
236 ///////////////////////////////////////////////////////////////////////////
237 void AliCalorimeter::SetEdgeOff(Int_t row, Int_t col)
238 {
239 // Indicate a certain calorimeter module as 'non-edge module'
240  
241  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
242  
243  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
244  {
245   fMatrix[row-1][col-1].SetEdgeOff();
246  }
247  else
248  {
249   cout << " *AliCalorimeter::SetEdgeOff* row,col : " << row << "," << col
250        << " out of range." << endl;
251   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
252  }
253 }
254 ///////////////////////////////////////////////////////////////////////////
255 void AliCalorimeter::SetDead(Int_t row, Int_t col)
256 {
257 // Indicate a certain calorimeter module as 'dead module'
258  
259  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
260  
261  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
262  {
263   fMatrix[row-1][col-1].SetDead();
264  
265   // Increase the 'edge value' of surrounding modules
266   Int_t rlow=row-1;
267   Int_t rup=row+1;
268   Int_t clow=col-1;
269   Int_t cup=col+1;
270  
271   if (rlow < 1) rlow=row;
272   if (rup > fNrows) rup=fNrows;
273   if (clow < 1) clow=col;
274   if (cup > fNcolumns) cup=fNcolumns;
275  
276   for (Int_t i=rlow; i<=rup; i++)
277   {
278    for (Int_t j=clow; j<=cup; j++)
279    {
280     fMatrix[i-1][j-1].EdgeUp();
281    }
282   }
283  
284   // Correct the 'edge value' for the dead module itself
285   fMatrix[row-1][col-1].EdgeDown();
286  }
287  else
288  {
289   cout << " *AliCalorimeter::SetDead* row,col : " << row << "," << col
290        << " out of range." << endl;
291   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
292  }
293 }
294 ///////////////////////////////////////////////////////////////////////////
295 void AliCalorimeter::SetAlive(Int_t row, Int_t col)
296 {
297 // Indicate a certain calorimeter module as 'active module'
298  
299  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
300  
301  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
302  {
303   fMatrix[row-1][col-1].SetAlive();
304  
305   // Decrease the 'edge value' of surrounding modules
306   Int_t rlow=row-1;
307   Int_t rup=row+1;
308   Int_t clow=col-1;
309   Int_t cup=col+1;
310  
311   if (rlow < 1) rlow=row;
312   if (rup > fNrows) rup=fNrows;
313   if (clow < 1) clow=col;
314   if (cup > fNcolumns) cup=fNcolumns;
315  
316   for (Int_t i=rlow; i<=rup; i++)
317   {
318    for (Int_t j=clow; j<=cup; j++)
319    {
320     fMatrix[i-1][j-1].EdgeDown();
321    }
322   }
323  
324   // Correct the 'edge value' for the dead module itself
325   fMatrix[row-1][col-1].EdgeUp();
326  }
327  else
328  {
329   cout << " *AliCalorimeter::SetAlive* row,col : " << row << "," << col
330        << " out of range." << endl;
331   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
332  }
333 }
334 ///////////////////////////////////////////////////////////////////////////
335 void AliCalorimeter::SetGain(Int_t row, Int_t col, Float_t gain)
336 {
337 // Set the gain value for a certain calorimeter module
338  
339  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
340  
341  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
342  {
343   fMatrix[row-1][col-1].SetGain(gain);
344  }
345  else
346  {
347   cout << " *AliCalorimeter::SetGain* row,col : " << row << "," << col
348        << " out of range." << endl;
349   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
350  }
351 }
352 ///////////////////////////////////////////////////////////////////////////
353 void AliCalorimeter::SetPosition(Int_t row,Int_t col,Float_t* vec,TString f)
354 {
355 // Set the position in user coordinates for a certain calorimeter module
356  
357  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
358  
359  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
360  {
361   fMatrix[row-1][col-1].SetPosition(vec,f);
362  }
363  else
364  {
365   cout << " *AliCalorimeter::SetPosition* row,col : " << row << "," << col
366        << " out of range." << endl;
367   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
368  }
369 }
370 ///////////////////////////////////////////////////////////////////////////
371 Int_t AliCalorimeter::GetEdgeValue(Int_t row, Int_t col)
372 {
373 // Provide the value of the edge flag of a certain module
374  
375  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
376  
377  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
378  {
379   return fMatrix[row-1][col-1].GetEdgeValue();
380  }
381  else
382  {
383   cout << " *AliCalorimeter::GetEdgeValue* row,col : " << row << "," << col
384        << " out of range." << endl;
385   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
386   return 0;
387  }
388 }
389 ///////////////////////////////////////////////////////////////////////////
390 Int_t AliCalorimeter::GetDeadValue(Int_t row, Int_t col)
391 {
392 // Provide the value of the dead flag of a certain module
393  
394  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
395  
396  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
397  {
398   return fMatrix[row-1][col-1].GetDeadValue();
399  }
400  else
401  {
402   cout << " *AliCalorimeter::GetDeadValue* row,col : " << row << "," << col
403        << " out of range." << endl;
404   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
405   return 0;
406  }
407 }
408 ///////////////////////////////////////////////////////////////////////////
409 Float_t AliCalorimeter::GetGain(Int_t row, Int_t col)
410 {
411 // Provide the gain value of a certain module
412  
413  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
414  
415  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
416  {
417   return fMatrix[row-1][col-1].GetGain();
418  }
419  else
420  {
421   cout << " *AliCalorimeter::GetGain* row,col : " << row << "," << col
422        << " out of range." << endl;
423   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
424   return 0;
425  }
426 }
427 ///////////////////////////////////////////////////////////////////////////
428 void AliCalorimeter::GetPosition(Int_t row,Int_t col,Float_t* vec,TString f)
429 {
430 // Return the position in user coordinates for a certain calorimeter 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  {
436   fMatrix[row-1][col-1].GetPosition(vec,f);
437  }
438  else
439  {
440   cout << " *AliCalorimeter::GetPosition* row,col : " << row << "," << col
441        << " out of range." << endl;
442   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
443  }
444 }
445 ///////////////////////////////////////////////////////////////////////////
446 Float_t AliCalorimeter::GetClusteredSignal(Int_t row, Int_t col)
447 {
448 // Provide the module signal after clustering
449  
450  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
451  
452  if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
453  {
454   return fMatrix[row-1][col-1].GetClusteredSignal();
455  }
456  else
457  {
458   cout << " *AliCalorimeter::GetClusteredSignal* row,col : " << row << "," << col
459        << " out of range." << endl;
460   cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
461   return 0;
462  }
463 }
464 ///////////////////////////////////////////////////////////////////////////
465 Int_t AliCalorimeter::GetNsignals()
466 {
467 // Provide the number of modules that contain a signal
468 // Note : The number of modules marked 'dead' but which had a signal
469 //        are included.
470  return fNsignals;
471 }
472 ///////////////////////////////////////////////////////////////////////////
473 void AliCalorimeter::Group(Int_t n)
474 {
475 // Group the individual modules into clusters
476 // Module signals of n rings around the central module will be grouped
477  
478  if (fNsignals > 0) // Directly return if no modules fired
479  {
480   if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
481  
482   if (fNclusters > 0) Ungroup(); // Restore unclustered situation if needed
483  
484   // Order the modules with decreasing signal
485   AliCalmodule* ordered=new AliCalmodule[fNsignals]; // temp. array for ordered modules
486   Sortm(ordered);
487  
488   // Clustering of modules. Start with the highest signal.
489   if (fClusters)
490   {
491    fClusters->Delete();
492    delete fClusters;
493    fClusters=0;
494   }
495   fClusters=new TObjArray();
496   fNclusters=0;
497   Int_t row=0;
498   Int_t col=0;
499   AliCalcluster* c=0;
500   for (Int_t i=0; i<fNsignals; i++)
501   {
502    row=ordered[i].GetRow();    // row number of cluster center
503    col=ordered[i].GetColumn(); // column number of cluster center
504    if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
505    {
506     // only use modules not yet used in a cluster
507     if (fMatrix[row-1][col-1].GetClusteredSignal() > 0.)
508     {
509      c=new AliCalcluster;
510      c->Start(fMatrix[row-1][col-1]); // module to start the cluster
511      if (c->GetNmodules() > 0)        // cluster started successfully (no edge)
512      {
513       fClusters->Add(c);
514       fNclusters++;       // update cluster counter
515       AddRing(row,col,n); // add signals of n rings around the center
516      }
517      else
518      {
519       if (c) delete c;
520       c=0;
521      }
522     }
523    }
524   }
525  
526   // Delete the temp. array
527   delete [] ordered;
528  }
529 }
530 ///////////////////////////////////////////////////////////////////////////
531 void AliCalorimeter::Sortm(AliCalmodule* ordered)
532 {
533 // Order the modules with decreasing signal
534  
535  Int_t nord=0;
536  for (Int_t i=0; i<fNrows; i++) // loop over all modules of the matrix
537  {
538   for (Int_t ii=0; ii<fNcolumns; ii++)
539   {
540    if (fMatrix[i][ii].GetSignal() <= 0.) continue; // only take modules with a signal
541  
542    if (nord == 0) // store the first module with a signal at the first ordered position
543    {
544     nord++;
545     ordered[nord-1]=fMatrix[i][ii];
546     continue;
547    }
548  
549    for (Int_t j=0; j<=nord; j++) // put module in the right ordered position
550    {
551     if (j == nord) // module has smallest signal seen so far
552     {
553      nord++;
554      ordered[j]=fMatrix[i][ii]; // add module at the end
555      break; // go for next matrix module
556     }
557  
558     if (fMatrix[i][ii].GetSignal() < ordered[j].GetSignal()) continue;
559  
560     nord++;
561     for (Int_t k=nord-1; k>j; k--) {ordered[k]=ordered[k-1];} // create empty position
562     ordered[j]=fMatrix[i][ii]; // put module at empty position
563     break; // go for next matrix module
564    }
565   }
566  }
567 }
568 ///////////////////////////////////////////////////////////////////////////
569 void AliCalorimeter::AddRing(Int_t row, Int_t col, Int_t n)
570 {
571 // Add module signals of 1 ring around (row,col) to current cluster
572 // n denotes the maximum number of rings around cluster center
573 // Note : This function is used recursively
574  
575  if (n >= 1) // Check if any rings left for recursive calls
576  {
577   Float_t signal=GetSignal(row,col); // signal of (row,col) module
578  
579   Int_t lrow=row-1; if (lrow < 1) lrow=1;                 // row lowerbound for ring
580   Int_t urow=row+1; if (urow > fNrows) urow=fNrows;       // row upperbound for ring
581   Int_t lcol=col-1; if (lcol < 1) lcol=1;                 // col lowerbound for ring
582   Int_t ucol=col+1; if (ucol > fNcolumns) ucol=fNcolumns; // row upperbound for ring
583  
584   for (Int_t i=lrow; i<=urow; i++)
585   {
586    for (Int_t j=lcol; j<=ucol; j++)
587    {
588     // add module(i,j) to cluster if the signal <= signal(row,col)
589     if (fMatrix[i-1][j-1].GetSignal() <= signal)
590     {
591      ((AliCalcluster*)fClusters->At(fNclusters-1))->Add(fMatrix[i-1][j-1]);
592     }
593     AddRing(i,j,n-1); // Go for ring of modules around this (i,j) one
594    }
595   }
596  }
597 }
598 ///////////////////////////////////////////////////////////////////////////
599 Int_t AliCalorimeter::GetNclusters()
600 {
601 // Provide the number of clusters
602  return fNclusters;
603 }
604 ///////////////////////////////////////////////////////////////////////////
605 AliCalcluster* AliCalorimeter::GetCluster(Int_t j)
606 {
607 // Provide cluster number j
608 // Note : j=1 denotes the first cluster
609  if ((j >= 1) && (j <= fNclusters))
610  {
611   return (AliCalcluster*)fClusters->At(j-1);
612  }
613  else
614  {
615   cout << " *AliCalorimeter::GetCluster* cluster number : " << j
616        << " out of range." << endl;
617   cout << " -- Cluster number 1 (if any) returned " << endl;
618   return (AliCalcluster*)fClusters->At(0);
619  }
620 }
621 ///////////////////////////////////////////////////////////////////////////
622 AliCalmodule* AliCalorimeter::GetModule(Int_t j)
623 {
624 // Provide 'fired' module number j
625 // Note : j=1 denotes the first 'fired' module
626  if ((j >= 1) && (j <= fNsignals))
627  {
628   return (AliCalmodule*)fModules->At(j-1);
629  }
630  else
631  {
632   cout << " *AliCalorimeter::GetModule* module number : " << j
633        << " out of range." << endl;
634   cout << " -- Fired module number 1 (if any) returned " << endl;
635   return (AliCalmodule*)fModules->At(0);
636  }
637 }
638 ///////////////////////////////////////////////////////////////////////////
639 TH2F* AliCalorimeter::DrawModules()
640 {
641 // Provide a lego plot of the module signals
642  
643  if (fHmodules)
644  {
645   fHmodules->Reset();
646  }
647  else
648  {
649   fHmodules=new TH2F("fHmodules","Module signals",
650             fNcolumns,0.5,float(fNcolumns)+0.5,fNrows,0.5,float(fNrows)+0.5);
651  
652   fHmodules->SetDirectory(0); // Suppress global character of histo pointer
653  }
654  
655  AliCalmodule* m;
656  Float_t row,col,signal;
657  for (Int_t i=0; i<fNsignals; i++)
658  {
659   m=(AliCalmodule*)fModules->At(i);
660   if (m)
661   {
662    row=float(m->GetRow());
663    col=float(m->GetColumn());
664    signal=m->GetSignal();
665    if (signal>0.) fHmodules->Fill(col,row,signal);
666   }
667  }
668  
669  fHmodules->Draw("lego");
670  return fHmodules;
671 }
672 ///////////////////////////////////////////////////////////////////////////
673 TH2F* AliCalorimeter::DrawClusters()
674 {
675 // Provide a lego plot of the cluster signals
676  
677  if (fHclusters)
678  {
679   fHclusters->Reset();
680  }
681  else
682  {
683   fHclusters=new TH2F("fHclusters","Cluster signals",
684             fNcolumns,0.5,float(fNcolumns)+0.5,fNrows,0.5,float(fNrows)+0.5);
685  
686   fHclusters->SetDirectory(0); // Suppress global character of histo pointer
687  }
688  
689  AliCalcluster* c;
690  Float_t row,col,signal;
691  for (Int_t i=0; i<fNclusters; i++)
692  {
693   c=(AliCalcluster*)fClusters->At(i);
694   if (c)
695   {
696    row=float(c->GetRow());
697    col=float(c->GetColumn());
698    signal=c->GetSignal();
699    if (signal>0.) fHclusters->Fill(col,row,signal);
700   }
701  }
702  
703  fHclusters->Draw("lego");
704  return fHclusters;
705 }
706 ///////////////////////////////////////////////////////////////////////////
707 void AliCalorimeter::LoadMatrix()
708 {
709 // Load the Calorimeter module matrix data back from the TObjArray
710  
711  // Create the module matrix space
712  if (fMatrix)
713  {
714   for (Int_t k=0; k<fNrows; k++)
715   {
716    delete [] fMatrix[k];
717   }
718    delete [] fMatrix;
719  }
720  fMatrix=new AliCalmodule*[fNrows];
721  for (Int_t i=0; i<fNrows; i++)
722  {
723   fMatrix[i]=new AliCalmodule[fNcolumns];
724  }
725  
726  // Copy the module data back into the matrix
727  AliCalmodule* m;
728  Int_t row;
729  Int_t col;
730  for (Int_t j=0; j<fNsignals; j++)
731  {
732   m=(AliCalmodule*)fModules->At(j);
733   row=m->GetRow();
734   col=m->GetColumn();
735   fMatrix[row-1][col-1]=*m;
736   fModules->AddAt(&(fMatrix[row-1][col-1]),j); // Store new pointer
737  }
738 }
739 ///////////////////////////////////////////////////////////////////////////
740 void AliCalorimeter::Ungroup()
741 {
742 // Set the module signals back to the non-clustered situation
743  
744  if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
745  
746  Float_t signal=0;
747  for (Int_t i=0; i<fNrows; i++)
748  {
749   for (Int_t j=0; j<fNcolumns; j++)
750   {
751    signal=fMatrix[i][j].GetSignal();
752    fMatrix[i][j].SetClusteredSignal(signal);
753   }
754  }
755 }
756 ///////////////////////////////////////////////////////////////////////////
757 void AliCalorimeter::AddVetoSignal(Float_t* r,TString f,Float_t s)
758 {
759 // Associate an (extrapolated) AliSignal at location r as veto to the cal.
760 // Note : The default signal value (s) is 0
761  if (!fVetos)
762  {
763   fNvetos=0;
764   fVetos=new TObjArray();
765  } 
766
767  fVetos->Add(new AliSignal);
768  fNvetos++;
769
770  ((AliSignal*)fVetos->At(fNvetos-1))->SetPosition(r,f);
771  ((AliSignal*)fVetos->At(fNvetos-1))->SetSignal(s);
772 }
773 ///////////////////////////////////////////////////////////////////////////
774 Int_t AliCalorimeter::GetNvetos()
775 {
776 // Provide the number of veto signals associated to the calorimeter
777  return fNvetos;
778 }
779 ///////////////////////////////////////////////////////////////////////////
780 AliSignal* AliCalorimeter::GetVetoSignal(Int_t i)
781 {
782 // Provide access to the i-th veto signal of this calorimeter
783 // Note : The first hit corresponds to i=1
784
785  if (i>0 && i<=fNvetos)
786  {
787   return (AliSignal*)fVetos->At(i-1);
788  }
789  else
790  {
791   cout << " *AliCalorimeter::GetVetoSignal* Signal number " << i
792        << " out of range." << endl;
793   cout << " --- First signal (if any) returned." << endl;
794   return (AliSignal*)fVetos->At(0);
795  }
796 }
797 ///////////////////////////////////////////////////////////////////////////