1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 //====================================================================================================================================================
18 // Class for finding and building the clusters of the ALICE Muon Forward Tracker
20 // Contact author: antonio.uras@cern.ch
22 //====================================================================================================================================================
25 #include "TObjArray.h"
26 #include "TClonesArray.h"
27 #include "AliMFTDigit.h"
28 #include "AliMFTCluster.h"
29 #include "AliMFTSegmentation.h"
32 #include "AliMFTClusterFinder.h"
34 ClassImp(AliMFTClusterFinder)
36 //====================================================================================================================================================
38 AliMFTClusterFinder::AliMFTClusterFinder() :
46 // Default constructor
48 for (Int_t iPlane=0; iPlane<fNMaxPlanes; iPlane++) fClustersPerPlane[iPlane] = NULL;
49 fDigitsInCluster = new TClonesArray("AliMFTDigit", fNMaxDigitsPerCluster);
53 //====================================================================================================================================================
55 AliMFTClusterFinder::~AliMFTClusterFinder() {
57 AliDebug(1, "Deleting AliMFTClusterFinder...");
59 for (Int_t iPlane=0; iPlane<fNMaxPlanes; iPlane++) delete fClustersPerPlane[iPlane];
61 AliDebug(1, "... done!");
65 //====================================================================================================================================================
67 void AliMFTClusterFinder::Init(const Char_t *nameGeomFile) {
69 fSegmentation = new AliMFTSegmentation(nameGeomFile);
70 fNPlanes = fSegmentation -> GetNPlanes();
74 //====================================================================================================================================================
76 void AliMFTClusterFinder::StartEvent() {
78 // Cleaning up and preparation for the clustering procedure
80 AliDebug(1, "Starting Event...");
82 for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
83 fClustersPerPlane[iPlane]->Clear();
86 AliDebug(1, "... done!");
90 //====================================================================================================================================================
92 void AliMFTClusterFinder::DigitsToClusters(const TObjArray *pDigitList) {
94 // where the clusterization is performed
96 AliInfo("Starting Clusterization for MFT");
97 AliDebug(1, Form("nPlanes = %d", fNPlanes));
101 for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
103 AliDebug(1, Form("Plane %02d", iPlane));
105 TClonesArray *myDigitList = (TClonesArray*) pDigitList->At(iPlane);
106 // myDigitList->Sort();
108 AliDebug(1, Form("myDigitList->GetEntries() = %d", myDigitList->GetEntries()));
110 while (myDigitList->GetEntries()) {
112 fDigitsInCluster->Clear();
114 Bool_t clusterUpdated=kTRUE;
116 //---------------------------------------------------------------------------------------------------------
118 while (clusterUpdated) { // repeat the loop on the digits until no new compatible digit is found
120 clusterUpdated = kFALSE;
122 for (Int_t iDig=0; iDig<myDigitList->GetEntries(); iDig++) {
123 fCurrentDig = (AliMFTDigit*) myDigitList->At(iDig);
124 if (fDigitsInCluster->GetEntries()<fNMaxDigitsPerCluster) {
125 if (fDigitsInCluster->GetEntries()==0) {
126 new ((*fDigitsInCluster)[fDigitsInCluster->GetEntries()]) AliMFTDigit(*fCurrentDig);
127 myDigitList->Remove(fCurrentDig);
128 clusterUpdated = kTRUE;
130 else if (IsCurrentDigitCompatible()) {
131 new ((*fDigitsInCluster)[fDigitsInCluster->GetEntries()]) AliMFTDigit(*fCurrentDig);
132 myDigitList->Remove(fCurrentDig);
133 clusterUpdated = kTRUE;
138 if (clusterUpdated) myDigitList->Compress();
142 //---------------------------------------------------------------------------------------------------------
144 AliDebug(1, "Building new cluster");
146 BuildNewCluster(iPlane); // here the new cluster is built
154 //====================================================================================================================================================
156 Bool_t AliMFTClusterFinder::IsCurrentDigitCompatible() {
158 // where it is decided if the current digit (fCurrentDig) is compatible with the current digits array (fDigitsInCluster)
160 for (Int_t iDigit=0; iDigit<fDigitsInCluster->GetEntries(); iDigit++) {
161 AliMFTDigit *tmpDig = (AliMFTDigit*) fDigitsInCluster->At(iDigit);
162 Int_t distX = TMath::Abs(tmpDig->GetPixelX() - fCurrentDig->GetPixelX());
163 Int_t distY = TMath::Abs(tmpDig->GetPixelY() - fCurrentDig->GetPixelY());
164 if (distX<=1 && distY<=1) return kTRUE;
171 //====================================================================================================================================================
173 void AliMFTClusterFinder::BuildNewCluster(Int_t plane) {
175 // where a new cluster is built, starting from the array of compatible digits (fDigitsInCluster)
177 AliDebug(1, Form("Starting cluster building from %d digits", fDigitsInCluster->GetEntries()));
179 AliMFTCluster *newCluster = new AliMFTCluster();
181 Double_t xCenters[fNMaxDigitsPerCluster] = {0};
182 Double_t yCenters[fNMaxDigitsPerCluster] = {0};
183 Double_t nElectrons = 0.;
185 for (Int_t iDigit=0; iDigit<fDigitsInCluster->GetEntries(); iDigit++) {
186 AliMFTDigit *tmpDig = (AliMFTDigit*) fDigitsInCluster->At(iDigit);
187 xCenters[iDigit] = tmpDig->GetPixelCenterX();
188 yCenters[iDigit] = tmpDig->GetPixelCenterY();
189 nElectrons += tmpDig->GetNElectrons();
190 for (Int_t iTrack=0; iTrack<tmpDig->GetNMCTracks(); iTrack++) newCluster->AddMCLabel(tmpDig->GetMCLabel(iTrack));
193 newCluster -> SetX(TMath::Mean(fDigitsInCluster->GetEntries(), xCenters));
194 newCluster -> SetY(TMath::Mean(fDigitsInCluster->GetEntries(), yCenters));
195 newCluster -> SetZ(((AliMFTDigit*) fDigitsInCluster->At(0))->GetPixelCenterZ());
197 Double_t minErrX = ((AliMFTDigit*) fDigitsInCluster->At(0))->GetPixelWidthX() / TMath::Sqrt(12.);
198 Double_t minErrY = ((AliMFTDigit*) fDigitsInCluster->At(0))->GetPixelWidthY() / TMath::Sqrt(12.);
199 Double_t minErrZ = ((AliMFTDigit*) fDigitsInCluster->At(0))->GetPixelWidthZ() / TMath::Sqrt(12.);
200 newCluster -> SetErrX( TMath::Max(TMath::RMS(fDigitsInCluster->GetEntries(), xCenters), minErrX) );
201 newCluster -> SetErrY( TMath::Max(TMath::RMS(fDigitsInCluster->GetEntries(), yCenters), minErrY) );
202 newCluster -> SetErrZ( minErrZ );
204 newCluster -> SetNElectrons(nElectrons);
205 newCluster -> SetPlane(plane);
207 newCluster -> SetSize(fDigitsInCluster->GetEntries());
209 AliDebug(1, Form("Adding cluster #%02d to tree (%f, %f, %f)",
210 fClustersPerPlane[plane]->GetEntries(), newCluster->GetX(), newCluster->GetY(), newCluster->GetZ()));
212 new ((*fClustersPerPlane[plane])[fClustersPerPlane[plane]->GetEntries()]) AliMFTCluster(*newCluster);
216 //====================================================================================================================================================
218 void AliMFTClusterFinder::MakeClusterBranch(TTree *treeCluster) {
220 // Creating the cluster branches, one for each plane (see AliMFTReconstructor::Reconstruct)
222 AliDebug(1, "Making Cluster Branch");
227 for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
228 AliDebug(1, Form("Setting Branch Plane_%02d for treeCluster",iPlane));
229 TBranch *branch = treeCluster->GetBranch(Form("Plane_%02d",iPlane));
230 if (branch) continue;
231 AliDebug(1, Form("Branch Plane_%02d does not exist, creating!",iPlane));
232 branch = treeCluster->Branch(Form("Plane_%02d",iPlane), &(fClustersPerPlane[iPlane]));
238 //====================================================================================================================================================
240 void AliMFTClusterFinder::SetClusterTreeAddress(TTree *treeCluster) {
242 // Addressing the cluster branches, one for each plane (see AliMFTReconstructor::Reconstruct)
244 if (treeCluster && treeCluster->GetBranch("Plane_00")) {
246 for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
247 if (treeCluster->GetBranch(Form("Plane_%02d",iPlane))) {
248 treeCluster->SetBranchAddress(Form("Plane_%02d",iPlane), &(fClustersPerPlane[iPlane]));
250 else AliError(Form("No branch available with name Plane_%02d", iPlane));
256 //====================================================================================================================================================
258 void AliMFTClusterFinder::CreateClusters() {
260 // create cluster list
262 AliDebug(1, Form("Creating clusters list: nPlanes = %d",fNPlanes));
264 if (fClustersPerPlane[0]) return;
266 for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
267 AliDebug(1, Form("plane %02d", iPlane));
268 fClustersPerPlane[iPlane] = new TClonesArray("AliMFTCluster");
273 //====================================================================================================================================================