1 #include "AliCalorimeter.h"
3 ClassImp(AliCalorimeter) // Class implementation to enable ROOT I/O
5 AliCalorimeter::AliCalorimeter()
7 // Default constructor, all parameters set to 0
20 ///////////////////////////////////////////////////////////////////////////
21 AliCalorimeter::~AliCalorimeter()
23 // Destructor to delete memory allocated for matrix and cluster array
26 for (Int_t i=0; i<fNrows; i++)
33 if (fModules) delete fModules;
41 if (fHmodules) delete fHmodules;
43 if (fHclusters) delete fHclusters;
52 ///////////////////////////////////////////////////////////////////////////
53 AliCalorimeter::AliCalorimeter(Int_t nrow, Int_t ncol)
55 // Create a calorimeter module matrix
61 fMatrix=new AliCalmodule*[nrow];
62 for (Int_t i=0; i<nrow; i++)
64 fMatrix[i]=new AliCalmodule[ncol];
66 // Mark the edge modules
67 for (Int_t j=0; j<ncol; j++)
69 fMatrix[0][j].SetEdgeOn();
70 fMatrix[nrow-1][j].SetEdgeOn();
72 for (Int_t k=0; k<nrow; k++)
74 fMatrix[k][0].SetEdgeOn();
75 fMatrix[k][ncol-1].SetEdgeOn();
78 fModules=new TObjArray(); // Default size, expanded automatically
86 ///////////////////////////////////////////////////////////////////////////
87 Int_t AliCalorimeter::GetNrows()
89 // Provide the number of rows for the calorimeter module matrix
92 ///////////////////////////////////////////////////////////////////////////
93 Int_t AliCalorimeter::GetNcolumns()
95 // Provide the number of columns for the calorimeter module matrix
98 ///////////////////////////////////////////////////////////////////////////
99 void AliCalorimeter::SetSignal(Int_t row, Int_t col, Float_t sig)
101 // Set the signal for a certain calorimeter module
103 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
105 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
107 if (fMatrix[row-1][col-1].GetSignal() <= 0.) // only count new modules
110 fModules->Add(&(fMatrix[row-1][col-1]));
112 fMatrix[row-1][col-1].SetSignal(row,col,sig);
116 cout << " *AliCalorimeter::SetSignal* row,col : " << row << "," << col
117 << " out of range." << endl;
118 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
121 ///////////////////////////////////////////////////////////////////////////
122 void AliCalorimeter::AddSignal(Int_t row, Int_t col, Float_t sig)
124 // Add the signal to a certain calorimeter module
126 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
128 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
130 if (fMatrix[row-1][col-1].GetSignal() <= 0.) // only count new modules
133 fModules->Add(&(fMatrix[row-1][col-1]));
135 fMatrix[row-1][col-1].AddSignal(row,col,sig);
139 cout << " *AliCalorimeter::AddSignal* row,col : " << row << "," << col
140 << " out of range." << endl;
141 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
144 ///////////////////////////////////////////////////////////////////////////
145 void AliCalorimeter::Reset(Int_t row, Int_t col)
147 // Reset the signal for a certain calorimeter module
149 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
151 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
153 fMatrix[row-1][col-1].SetSignal(row,col,0);
155 fModules->Remove(&(fMatrix[row-1][col-1]));
159 cout << " *AliCalorimeter::Reset* row,col : " << row << "," << col
160 << " out of range." << endl;
161 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
164 ///////////////////////////////////////////////////////////////////////////
165 void AliCalorimeter::Reset()
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
171 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
174 for (Int_t i=0; i<fNrows; i++)
176 for (Int_t j=0; j<fNcolumns; j++)
178 fMatrix[i][j].SetSignal(i+1,j+1,0);
181 if (fModules) fModules->Clear();
199 ///////////////////////////////////////////////////////////////////////////
200 Float_t AliCalorimeter::GetSignal(Int_t row, Int_t col)
202 // Provide the signal of a certain calorimeter module
204 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
206 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
208 return fMatrix[row-1][col-1].GetSignal();
212 cout << " *AliCalorimeter::GetSignal* row,col : " << row << "," << col
213 << " out of range." << endl;
214 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
218 ///////////////////////////////////////////////////////////////////////////
219 void AliCalorimeter::SetEdgeOn(Int_t row, Int_t col)
221 // Indicate a certain calorimeter module as 'edge module'
223 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
225 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
227 fMatrix[row-1][col-1].SetEdgeOn();
231 cout << " *AliCalorimeter::SetEdgeOn* row,col : " << row << "," << col
232 << " out of range." << endl;
233 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
236 ///////////////////////////////////////////////////////////////////////////
237 void AliCalorimeter::SetEdgeOff(Int_t row, Int_t col)
239 // Indicate a certain calorimeter module as 'non-edge module'
241 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
243 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
245 fMatrix[row-1][col-1].SetEdgeOff();
249 cout << " *AliCalorimeter::SetEdgeOff* row,col : " << row << "," << col
250 << " out of range." << endl;
251 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
254 ///////////////////////////////////////////////////////////////////////////
255 void AliCalorimeter::SetDead(Int_t row, Int_t col)
257 // Indicate a certain calorimeter module as 'dead module'
259 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
261 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
263 fMatrix[row-1][col-1].SetDead();
265 // Increase the 'edge value' of surrounding modules
271 if (rlow < 1) rlow=row;
272 if (rup > fNrows) rup=fNrows;
273 if (clow < 1) clow=col;
274 if (cup > fNcolumns) cup=fNcolumns;
276 for (Int_t i=rlow; i<=rup; i++)
278 for (Int_t j=clow; j<=cup; j++)
280 fMatrix[i-1][j-1].EdgeUp();
284 // Correct the 'edge value' for the dead module itself
285 fMatrix[row-1][col-1].EdgeDown();
289 cout << " *AliCalorimeter::SetDead* row,col : " << row << "," << col
290 << " out of range." << endl;
291 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
294 ///////////////////////////////////////////////////////////////////////////
295 void AliCalorimeter::SetAlive(Int_t row, Int_t col)
297 // Indicate a certain calorimeter module as 'active module'
299 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
301 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
303 fMatrix[row-1][col-1].SetAlive();
305 // Decrease the 'edge value' of surrounding modules
311 if (rlow < 1) rlow=row;
312 if (rup > fNrows) rup=fNrows;
313 if (clow < 1) clow=col;
314 if (cup > fNcolumns) cup=fNcolumns;
316 for (Int_t i=rlow; i<=rup; i++)
318 for (Int_t j=clow; j<=cup; j++)
320 fMatrix[i-1][j-1].EdgeDown();
324 // Correct the 'edge value' for the dead module itself
325 fMatrix[row-1][col-1].EdgeUp();
329 cout << " *AliCalorimeter::SetAlive* row,col : " << row << "," << col
330 << " out of range." << endl;
331 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
334 ///////////////////////////////////////////////////////////////////////////
335 void AliCalorimeter::SetGain(Int_t row, Int_t col, Float_t gain)
337 // Set the gain value for a certain calorimeter module
339 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
341 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
343 fMatrix[row-1][col-1].SetGain(gain);
347 cout << " *AliCalorimeter::SetGain* row,col : " << row << "," << col
348 << " out of range." << endl;
349 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
352 ///////////////////////////////////////////////////////////////////////////
353 void AliCalorimeter::SetPosition(Int_t row,Int_t col,Float_t* vec,TString f)
355 // Set the position in user coordinates for a certain calorimeter module
357 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
359 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
361 fMatrix[row-1][col-1].SetPosition(vec,f);
365 cout << " *AliCalorimeter::SetPosition* row,col : " << row << "," << col
366 << " out of range." << endl;
367 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
370 ///////////////////////////////////////////////////////////////////////////
371 Int_t AliCalorimeter::GetEdgeValue(Int_t row, Int_t col)
373 // Provide the value of the edge flag of a certain module
375 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
377 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
379 return fMatrix[row-1][col-1].GetEdgeValue();
383 cout << " *AliCalorimeter::GetEdgeValue* row,col : " << row << "," << col
384 << " out of range." << endl;
385 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
389 ///////////////////////////////////////////////////////////////////////////
390 Int_t AliCalorimeter::GetDeadValue(Int_t row, Int_t col)
392 // Provide the value of the dead flag of a certain module
394 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
396 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
398 return fMatrix[row-1][col-1].GetDeadValue();
402 cout << " *AliCalorimeter::GetDeadValue* row,col : " << row << "," << col
403 << " out of range." << endl;
404 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
408 ///////////////////////////////////////////////////////////////////////////
409 Float_t AliCalorimeter::GetGain(Int_t row, Int_t col)
411 // Provide the gain value of a certain module
413 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
415 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
417 return fMatrix[row-1][col-1].GetGain();
421 cout << " *AliCalorimeter::GetGain* row,col : " << row << "," << col
422 << " out of range." << endl;
423 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
427 ///////////////////////////////////////////////////////////////////////////
428 void AliCalorimeter::GetPosition(Int_t row,Int_t col,Float_t* vec,TString f)
430 // Return the position in user coordinates for a certain calorimeter module
432 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
434 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
436 fMatrix[row-1][col-1].GetPosition(vec,f);
440 cout << " *AliCalorimeter::GetPosition* row,col : " << row << "," << col
441 << " out of range." << endl;
442 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
445 ///////////////////////////////////////////////////////////////////////////
446 Float_t AliCalorimeter::GetClusteredSignal(Int_t row, Int_t col)
448 // Provide the module signal after clustering
450 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
452 if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
454 return fMatrix[row-1][col-1].GetClusteredSignal();
458 cout << " *AliCalorimeter::GetClusteredSignal* row,col : " << row << "," << col
459 << " out of range." << endl;
460 cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
464 ///////////////////////////////////////////////////////////////////////////
465 Int_t AliCalorimeter::GetNsignals()
467 // Provide the number of modules that contain a signal
468 // Note : The number of modules marked 'dead' but which had a signal
472 ///////////////////////////////////////////////////////////////////////////
473 void AliCalorimeter::Group(Int_t n)
475 // Group the individual modules into clusters
476 // Module signals of n rings around the central module will be grouped
478 if (fNsignals > 0) // Directly return if no modules fired
480 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
482 if (fNclusters > 0) Ungroup(); // Restore unclustered situation if needed
484 // Order the modules with decreasing signal
485 AliCalmodule* ordered=new AliCalmodule[fNsignals]; // temp. array for ordered modules
488 // Clustering of modules. Start with the highest signal.
495 fClusters=new TObjArray();
500 for (Int_t i=0; i<fNsignals; i++)
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)
506 // only use modules not yet used in a cluster
507 if (fMatrix[row-1][col-1].GetClusteredSignal() > 0.)
510 c->Start(fMatrix[row-1][col-1]); // module to start the cluster
511 if (c->GetNmodules() > 0) // cluster started successfully (no edge)
514 fNclusters++; // update cluster counter
515 AddRing(row,col,n); // add signals of n rings around the center
526 // Delete the temp. array
530 ///////////////////////////////////////////////////////////////////////////
531 void AliCalorimeter::Sortm(AliCalmodule* ordered)
533 // Order the modules with decreasing signal
536 for (Int_t i=0; i<fNrows; i++) // loop over all modules of the matrix
538 for (Int_t ii=0; ii<fNcolumns; ii++)
540 if (fMatrix[i][ii].GetSignal() <= 0.) continue; // only take modules with a signal
542 if (nord == 0) // store the first module with a signal at the first ordered position
545 ordered[nord-1]=fMatrix[i][ii];
549 for (Int_t j=0; j<=nord; j++) // put module in the right ordered position
551 if (j == nord) // module has smallest signal seen so far
554 ordered[j]=fMatrix[i][ii]; // add module at the end
555 break; // go for next matrix module
558 if (fMatrix[i][ii].GetSignal() < ordered[j].GetSignal()) continue;
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
568 ///////////////////////////////////////////////////////////////////////////
569 void AliCalorimeter::AddRing(Int_t row, Int_t col, Int_t n)
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
575 if (n >= 1) // Check if any rings left for recursive calls
577 Float_t signal=GetSignal(row,col); // signal of (row,col) module
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
584 for (Int_t i=lrow; i<=urow; i++)
586 for (Int_t j=lcol; j<=ucol; j++)
588 // add module(i,j) to cluster if the signal <= signal(row,col)
589 if (fMatrix[i-1][j-1].GetSignal() <= signal)
591 ((AliCalcluster*)fClusters->At(fNclusters-1))->Add(fMatrix[i-1][j-1]);
593 AddRing(i,j,n-1); // Go for ring of modules around this (i,j) one
598 ///////////////////////////////////////////////////////////////////////////
599 Int_t AliCalorimeter::GetNclusters()
601 // Provide the number of clusters
604 ///////////////////////////////////////////////////////////////////////////
605 AliCalcluster* AliCalorimeter::GetCluster(Int_t j)
607 // Provide cluster number j
608 // Note : j=1 denotes the first cluster
609 if ((j >= 1) && (j <= fNclusters))
611 return (AliCalcluster*)fClusters->At(j-1);
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);
621 ///////////////////////////////////////////////////////////////////////////
622 AliCalmodule* AliCalorimeter::GetModule(Int_t j)
624 // Provide 'fired' module number j
625 // Note : j=1 denotes the first 'fired' module
626 if ((j >= 1) && (j <= fNsignals))
628 return (AliCalmodule*)fModules->At(j-1);
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);
638 ///////////////////////////////////////////////////////////////////////////
639 TH2F* AliCalorimeter::DrawModules()
641 // Provide a lego plot of the module signals
649 fHmodules=new TH2F("fHmodules","Module signals",
650 fNcolumns,0.5,float(fNcolumns)+0.5,fNrows,0.5,float(fNrows)+0.5);
652 fHmodules->SetDirectory(0); // Suppress global character of histo pointer
656 Float_t row,col,signal;
657 for (Int_t i=0; i<fNsignals; i++)
659 m=(AliCalmodule*)fModules->At(i);
662 row=float(m->GetRow());
663 col=float(m->GetColumn());
664 signal=m->GetSignal();
665 if (signal>0.) fHmodules->Fill(col,row,signal);
669 fHmodules->Draw("lego");
672 ///////////////////////////////////////////////////////////////////////////
673 TH2F* AliCalorimeter::DrawClusters()
675 // Provide a lego plot of the cluster signals
683 fHclusters=new TH2F("fHclusters","Cluster signals",
684 fNcolumns,0.5,float(fNcolumns)+0.5,fNrows,0.5,float(fNrows)+0.5);
686 fHclusters->SetDirectory(0); // Suppress global character of histo pointer
690 Float_t row,col,signal;
691 for (Int_t i=0; i<fNclusters; i++)
693 c=(AliCalcluster*)fClusters->At(i);
696 row=float(c->GetRow());
697 col=float(c->GetColumn());
698 signal=c->GetSignal();
699 if (signal>0.) fHclusters->Fill(col,row,signal);
703 fHclusters->Draw("lego");
706 ///////////////////////////////////////////////////////////////////////////
707 void AliCalorimeter::LoadMatrix()
709 // Load the Calorimeter module matrix data back from the TObjArray
711 // Create the module matrix space
714 for (Int_t k=0; k<fNrows; k++)
716 delete [] fMatrix[k];
720 fMatrix=new AliCalmodule*[fNrows];
721 for (Int_t i=0; i<fNrows; i++)
723 fMatrix[i]=new AliCalmodule[fNcolumns];
726 // Copy the module data back into the matrix
730 for (Int_t j=0; j<fNsignals; j++)
732 m=(AliCalmodule*)fModules->At(j);
735 fMatrix[row-1][col-1]=*m;
736 fModules->AddAt(&(fMatrix[row-1][col-1]),j); // Store new pointer
739 ///////////////////////////////////////////////////////////////////////////
740 void AliCalorimeter::Ungroup()
742 // Set the module signals back to the non-clustered situation
744 if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
747 for (Int_t i=0; i<fNrows; i++)
749 for (Int_t j=0; j<fNcolumns; j++)
751 signal=fMatrix[i][j].GetSignal();
752 fMatrix[i][j].SetClusteredSignal(signal);
756 ///////////////////////////////////////////////////////////////////////////
757 void AliCalorimeter::AddVetoSignal(Float_t* r,TString f,Float_t s)
759 // Associate an (extrapolated) AliSignal at location r as veto to the cal.
760 // Note : The default signal value (s) is 0
764 fVetos=new TObjArray();
767 fVetos->Add(new AliSignal);
770 ((AliSignal*)fVetos->At(fNvetos-1))->SetPosition(r,f);
771 ((AliSignal*)fVetos->At(fNvetos-1))->SetSignal(s);
773 ///////////////////////////////////////////////////////////////////////////
774 Int_t AliCalorimeter::GetNvetos()
776 // Provide the number of veto signals associated to the calorimeter
779 ///////////////////////////////////////////////////////////////////////////
780 AliSignal* AliCalorimeter::GetVetoSignal(Int_t i)
782 // Provide access to the i-th veto signal of this calorimeter
783 // Note : The first hit corresponds to i=1
785 if (i>0 && i<=fNvetos)
787 return (AliSignal*)fVetos->At(i-1);
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);
797 ///////////////////////////////////////////////////////////////////////////