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 **************************************************************************/
18 // --------------------------
19 // Class AliMUONDetElement
20 // --------------------------
21 // Detection element object containing information for combined
22 // cluster / track finder in MUON arm
23 // Author: Alexander Zinchenko, JINR Dubna
26 #include <TObjArray.h>
27 #include <TClonesArray.h>
28 #include "AliMUONDetElement.h"
30 #include "AliMUONSegmentation.h"
31 #include "AliMUONDigit.h"
32 #include "AliMUONHitMapA1.h"
33 #include "AliMUONRawCluster.h"
34 #include "AliMUONHitForRec.h"
35 #include "AliMUONClusterInput.h"
36 #include "AliMUONClusterFinderAZ.h"
40 ClassImp(AliMUONDetElement) // Class implementation in ROOT context
42 //_________________________________________________________________________
43 AliMUONDetElement::AliMUONDetElement()
46 /// Default constructor
47 for (Int_t i = 0; i < 2; i++) {
52 fRawClus = fHitsForRec = NULL;
56 //_________________________________________________________________________
57 AliMUONDetElement::AliMUONDetElement(Int_t idDE, AliMUONDigit *dig, AliMUONClusterFinderAZ *recModel)
62 fChamber = fidDE / 100 - 1;
63 fDigits[0] = new TObjArray(10);
64 fDigits[1] = new TObjArray(10);
65 fRawClus = new TObjArray(10);
66 fHitsForRec = new TClonesArray("AliMUONHitForRec",10);
69 AliMUON *pMUON = (AliMUON*) gAlice->GetModule("MUON");
70 AliMUONSegmentation *pSegmentation = pMUON->GetSegmentation();
71 fSeg[0] = pSegmentation->GetModuleSegmentation(fChamber, 0);
72 fSeg[1] = pSegmentation->GetModuleSegmentation(fChamber, 1);
74 fSeg[dig->Cathode()]->GetPadC(fidDE, dig->PadX(), dig->PadY(), x, y, z);
79 //_________________________________________________________________________
80 AliMUONDetElement::~AliMUONDetElement()
83 for (Int_t i = 0; i < 2; i++) {
84 delete fHitMap[i]; fHitMap[i] = NULL;
85 delete fDigits[i]; fDigits[i] = NULL;
87 if (fRawClus) { fRawClus->Delete(); delete fRawClus; fRawClus = 0; }
88 //if (fRawClus) { delete fRawClus; fRawClus = 0; }
89 delete fHitsForRec; fHitsForRec = 0;
92 //_________________________________________________________________________
93 AliMUONDetElement::AliMUONDetElement (const AliMUONDetElement& rhs)
98 AliFatal("Not implemented.");
101 //________________________________________________________________________
102 AliMUONDetElement & AliMUONDetElement::operator = (const AliMUONDetElement& rhs)
104 /// Assignement operator
106 if (this == &rhs) return *this;
107 AliFatal( "Not implemented.");
111 //_________________________________________________________________________
112 Int_t AliMUONDetElement::Compare(const TObject* detElem) const
114 /// "Compare" function to sort in Z (towards interaction point)
115 /// Returns -1 (0, +1) if charge of current pixel
116 /// is greater than (equal to, less than) charge of pixel
117 if (fZ > ((AliMUONDetElement*)detElem)->Z()) return(+1);
118 else if (fZ == ((AliMUONDetElement*)detElem)->Z()) return( 0);
122 //_________________________________________________________________________
123 void AliMUONDetElement::Fill(AliMUONData */*data*/)
126 fLeft[0] = fDigits[0]->GetEntriesFast();
127 fLeft[1] = fDigits[1]->GetEntriesFast();
129 Int_t npx0 = fSeg[0]->Npx(fidDE)+1;
130 Int_t npy0 = fSeg[0]->Npy(fidDE)+1;
131 fHitMap[0] = new AliMUONHitMapA1(npx0, npy0, fDigits[0]);
132 fHitMap[0]->FillHits();
134 Int_t npx1 = fSeg[1]->Npx(fidDE)+1;
135 Int_t npy1 = fSeg[1]->Npy(fidDE)+1;
136 fHitMap[1] = new AliMUONHitMapA1(npx1, npy1, fDigits[1]);
137 fHitMap[1]->FillHits();
139 // The part below is just for debugging (fill rec. points already found)
141 fLeft[0] = fLeft[1] = 0;
142 TClonesArray *rawClus = data->RawClusters(fChamber);
143 cout << rawClus << " " << rawClus->GetEntriesFast() << endl;
144 for (Int_t i = 0; i < rawClus->GetEntriesFast(); i++) {
145 AliMUONRawCluster *recP = (AliMUONRawCluster*) rawClus->UncheckedAt(i);
146 cout << fChamber << " " << recP->GetZ(0) << " " << recP->GetZ(1) << " " << fZ << endl;
147 if (TMath::Abs(recP->GetZ(0)-fZ) > 0.5) continue;
148 if (!Inside(recP->GetX(0), recP->GetY(0), recP->GetZ(0))) continue;
149 AddHitForRec(recP); // add hit for rec.
150 rawClus->RemoveAt(i); // remove
152 cout << fHitsForRec->GetEntriesFast() << endl;
157 //_________________________________________________________________________
158 void AliMUONDetElement::AddDigit(AliMUONDigit *dig)
162 fDigits[dig->Cathode()]->Add(dig);
165 //_________________________________________________________________________
166 Bool_t AliMUONDetElement::Inside(Double_t x, Double_t y, Double_t z) const
168 /// Check if point is inside detection element
171 for (Int_t i = 0; i < 2; i++) {
172 if (!fSeg[i]) continue;
173 fSeg[i]->GetPadI(fidDE, x, y, z, ix, iy);
174 //cout << x << " " << y << " " << z << " " << fChamber << " " << ix << " " << iy << " " << fSeg[i]->Npx(fidDE) << " " << fSeg[i]->Npy(fidDE) /*<< " " << fSeg[i]->GetPadI(fidDE, x, y, z, ix, iy)*/ << endl;
175 if (ix > 0 && iy > 0 && ix <= fSeg[i]->Npx(fidDE) && iy <= fSeg[i]->Npy(fidDE)) return kTRUE;
177 // Check for edge effect (extrapolated track "right outside" det. elem. boundaries (+- 1cm in X and Y)
178 for (Int_t i = 0; i < 2; i++) {
179 if (!fSeg[i]) continue;
180 for (Int_t idx = -1; idx < 2; idx++) {
181 Double_t x1 = x + 1. * idx;
182 for (Int_t idy = -1; idy < 2; idy++) {
183 if (idx == 0 && idy == 0) continue;
184 Double_t y1 = y + 1. * idy;
185 fSeg[i]->GetPadI(fidDE, x1, y1, z, ix, iy);
186 //cout << x1 << " " << y1 << " " << z << " " << fChamber << " " << ix << " " << iy << " " << fSeg[i]->Npx(fidDE) << " " << fSeg[i]->Npy(fidDE) /*<< " " << fSeg[i]->GetPadI(fidDE, x, y, z, ix, iy)*/ << endl;
187 if (ix > 0 && iy > 0 && ix <= fSeg[i]->Npx(fidDE) && iy <= fSeg[i]->Npy(fidDE)) return kTRUE;
194 //_________________________________________________________________________
195 void AliMUONDetElement::ClusterReco(Double_t xTrack, Double_t yTrack)
197 /// Run cluster reconstruction around point (x,y)
199 if (fLeft[0] == 0 && fLeft[1] == 0) return; // all digits have been used
201 dx = dy = 5; // 5 cm for now
202 AliMUONClusterInput::Instance()->SetDigits(fChamber, fidDE,
203 (TClonesArray*)fDigits[0], (TClonesArray*)fDigits[1]);
206 for (Int_t cath = 0; cath < 2; cath++) {
207 if (fDigits[cath]->GetEntriesFast() == 0) continue; // empty cathode
208 for (Int_t i = 0; i < fDigits[cath]->GetEntriesFast(); i++) {
209 if (fLeft[cath] == 0) { fRecModel->SetUsed(cath,i); continue; }
210 AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(i);
211 //cout << i << " " << dig->PadX() << " " << dig->PadY() << " " << fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) << endl;
212 if (fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) == kUsed) fRecModel->SetUsed(cath,i);
213 else fRecModel->SetUnused(cath,i);
217 fRecModel->ResetRawClusters();
219 for (Int_t cath = 0; cath < 2; cath++) {
220 if (fDigits[cath]->GetEntriesFast() == 0) continue; // empty cathode
222 for (fSeg[cath]->FirstPad(fidDE, xTrack, yTrack, fZ, dx, dy);
223 fSeg[cath]->MorePads(fidDE);
224 fSeg[cath]->NextPad(fidDE)) {
225 if (fLeft[cath] == 0) break;
226 //cout << cath << " " << fSeg[cath]->Ix() << " " << fSeg[cath]->Iy() << " " << fSeg[cath]->DetElemId() << " " << fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) << endl;
227 if (fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) == kEmpty ||
228 fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) == kUsed) continue;
231 for (Int_t j = 0; j < fDigits[cath]->GetEntriesFast(); j++) {
232 AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(j);
233 if (dig->PadX() != fSeg[cath]->Ix() || dig->PadY() != fSeg[cath]->Iy()) continue;
234 //cout << fidDE << " " << j << " " << fSeg[cath]->Ix() << " " << fSeg[cath]->Iy() << endl;
235 fRecModel->SetStart(cath, j);
239 fRecModel->FindRawClusters();
240 Int_t nClusEnd = fRecModel->GetRawClusters()->GetEntriesFast();
241 //cout << " ***nclus: " << nClusEnd << endl;
242 for (Int_t i = 0; i < nClusEnd; i++) {
243 AliMUONRawCluster *clus = (AliMUONRawCluster*) fRecModel->GetRawClusters()->UncheckedAt(i);
244 AddHitForRec(clus); // add hit for rec.
245 //cout << clus->GetX(0) << " " << clus->GetY(0) << endl;
248 for (Int_t cath1 = 0; cath1 < 2; cath1++) {
249 for (Int_t j = 0; j < fDigits[cath1]->GetEntriesFast(); j++) {
250 if (fLeft[cath1] == 0) break;
251 AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath1]->UncheckedAt(j);
253 fSeg[cath1]->GetPadC(fidDE,dig->PadX(),dig->PadY(),x,y,z);
254 //cout << "clus " << cath1 << " " << fLeft[cath1] << " " << dig->PadX() << " " << dig->PadY() << " " << x << " " << y << " " << z << " " << fRecModel->GetUsed(cath1,j) << endl;
255 if (!fRecModel->GetUsed(cath1,j)) continue;
256 if (fHitMap[cath1]->TestHit(dig->PadX(), dig->PadY()) == kUsed) continue;
257 fHitMap[cath1]->FlagHit(dig->PadX(), dig->PadY());
258 AliDebug(10,Form(" %d %d %d %d \n", cath1, fidDE, dig->PadX(), dig->PadY()));
262 } // for (fSeg[cath]->FirstPad(...
263 } // for (Int_t cath = 0;
266 //_________________________________________________________________________
267 void AliMUONDetElement::AddHitForRec(AliMUONRawCluster *clus)
269 /// Make HitForRec from raw cluster (rec. point)
271 fRawClus->Add(new AliMUONRawCluster(*clus));
272 AliMUONHitForRec *hitForRec =
273 new ((*fHitsForRec)[fNHitsForRec++]) AliMUONHitForRec(clus);
275 // more information into HitForRec
276 // resolution: info should be already in raw cluster and taken from it ????
277 hitForRec->SetBendingReso2(-1); //fBendingResolution * fBendingResolution);
278 hitForRec->SetNonBendingReso2(-1); //fNonBendingResolution * fNonBendingResolution);
279 // original raw cluster
280 hitForRec->SetChamberNumber(fChamber);
281 hitForRec->SetZ(clus->GetZ(0));
282 //hitForRec->SetHitNumber(-(fIndex+1)*100000-fNHitsForRec+1);
283 hitForRec->SetHitNumber(-(fIndex+1)*100000-fRawClus->GetEntriesFast()+1);
284 //delete clus; // for now
288 //_________________________________________________________________________
289 Int_t AliMUONDetElement::GetMapElem(AliMUONDigit *digit)
291 Int_t cath = digit->Cathode();
296 //_________________________________________________________________________
297 void AliMUONDetElement::SetMapElem(const AliMUONDigit *digit, Int_t flag)
299 Int_t cath = digit->Cathode();