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 the MUON arm
23 // Author: Alexander Zinchenko, JINR Dubna
25 #include "AliMUONDetElement.h"
27 #include "AliMUONSegmentation.h"
28 #include "AliMUONDigit.h"
29 #include "AliMUONHitMapA1.h"
30 #include "AliMUONData.h"
31 #include "AliMUONRawCluster.h"
32 #include "AliMUONHitForRec.h"
33 #include "AliMUONClusterInput.h"
34 #include "AliMUONClusterFinderAZ.h"
35 #include "AliMUONGeometryModuleTransformer.h"
36 #include "AliMUONSegmentation.h"
37 #include "AliMUONVGeometryDESegmentation.h"
38 #include "AliMpVSegmentation.h"
43 #include <TObjArray.h>
44 #include <TClonesArray.h>
48 ClassImp(AliMUONDetElement) // Class implementation in ROOT context
50 FILE *lun = 0x0; //fopen("hitmap.dat","w");
52 //_________________________________________________________________________
53 AliMUONDetElement::AliMUONDetElement()
64 /// Default constructor
65 for (Int_t i = 0; i < 2; i++) {
72 //_________________________________________________________________________
73 AliMUONDetElement::AliMUONDetElement(Int_t idDE, AliMUONDigit *dig, AliMUONClusterFinderAZ *recModel,
74 AliMUONSegmentation* segmentation)
78 fChamber(idDE / 100 - 1),
81 fRawClus(new TObjArray(10)),
82 fHitsForRec(new TObjArray(10)),
86 fRawClus->SetOwner(kTRUE);
87 fHitsForRec->SetOwner(kTRUE);
88 fDigits[0] = new TObjArray(20);
89 fDigits[1] = new TObjArray(20);
90 fDigits[0]->SetOwner(kTRUE);
91 fDigits[1]->SetOwner(kTRUE);
94 fSeg[0] = segmentation->GetModuleSegmentationByDEId(idDE, 0);
95 fSeg[1] = segmentation->GetModuleSegmentationByDEId(idDE, 1);
99 fSeg[dig->Cathode()]->GetPadC(fidDE, dig->PadX(), dig->PadY(), x, y, z);
105 //_________________________________________________________________________
106 AliMUONDetElement::~AliMUONDetElement()
109 for (Int_t i = 0; i < 2; i++) {
114 for (Int_t i = 0; i < fNHitsForRec; i++) {
115 Int_t ntracks = ((AliMUONHitForRec*)fHitsForRec->UncheckedAt(i))->GetNTrackHits();
116 //cout << ntracks << endl;
117 if (ntracks) fHitsForRec->RemoveAt(i);
120 //fHitsForRec->SetOwner(kFALSE);
121 //fHitsForRec->Clear(); cout << " here " << fHitsForRec->GetEntriesFast() << endl; delete fHitsForRec; fHitsForRec = 0;
124 //_________________________________________________________________________
125 Int_t AliMUONDetElement::Compare(const TObject* detElem) const
127 /// "Compare" function to sort in Z (towards interaction point)
128 /// Returns -1 (0, +1) if charge of current pixel
129 /// is greater than (equal to, less than) charge of pixel
130 if (fZ > ((AliMUONDetElement*)detElem)->Z()) return(+1);
131 else if (fZ == ((AliMUONDetElement*)detElem)->Z()) return( 0);
135 //_________________________________________________________________________
136 void AliMUONDetElement::Fill(AliMUONData */*data*/)
139 fLeft[0] = fDigits[0]->GetEntriesFast();
140 fLeft[1] = fDigits[1]->GetEntriesFast();
142 Int_t npx0 = fSeg[0]->Npx(fidDE)+1;
143 Int_t npy0 = fSeg[0]->Npy(fidDE)+1;
144 fHitMap[0] = new AliMUONHitMapA1(npx0, npy0, fDigits[0]);
145 fHitMap[0]->FillHits();
147 Int_t npx1 = fSeg[1]->Npx(fidDE)+1;
148 Int_t npy1 = fSeg[1]->Npy(fidDE)+1;
149 fHitMap[1] = new AliMUONHitMapA1(npx1, npy1, fDigits[1]);
150 fHitMap[1]->FillHits();
152 // The part below is just for debugging (fill rec. points already found)
154 fLeft[0] = fLeft[1] = 0;
155 TClonesArray *rawClus = data->RawClusters(fChamber);
156 cout << rawClus << " " << rawClus->GetEntriesFast() << endl;
157 for (Int_t i = 0; i < rawClus->GetEntriesFast(); i++) {
158 AliMUONRawCluster *recP = (AliMUONRawCluster*) rawClus->UncheckedAt(i);
159 cout << fChamber << " " << recP->GetZ(0) << " " << recP->GetZ(1) << " " << fZ << endl;
160 if (TMath::Abs(recP->GetZ(0)-fZ) > 0.5) continue;
161 if (!Inside(recP->GetX(0), recP->GetY(0), recP->GetZ(0))) continue;
162 AddHitForRec(recP); // add hit for rec.
163 rawClus->RemoveAt(i); // remove
165 cout << fHitsForRec->GetEntriesFast() << endl;
170 //_________________________________________________________________________
171 void AliMUONDetElement::AddDigit(AliMUONDigit *dig)
175 //fDigits[dig->Cathode()]->Add(dig);
176 fDigits[dig->Cathode()]->Add(new AliMUONDigit(*dig));
178 fSeg[dig->Cathode()]->GetPadC(fidDE, dig->PadX(), dig->PadY(), x, y, z);
181 Int_t ndig = fDigits[dig->Cathode()]->GetEntriesFast();
182 new((*fDigits[dig->Cathode()])[ndig]) AliMUONDigit(*dig);
186 //_________________________________________________________________________
187 Bool_t AliMUONDetElement::Inside(Double_t x, Double_t y, Double_t z, Double_t dx, Double_t dy) const
189 /// Check if point is inside detection element
191 dx = TMath::Max (dx, 1.);
192 dy = TMath::Max (dy, 1.);
196 for (Int_t i = 0; i < 2; i++) {
197 if (!fSeg[i]) continue;
198 if (i == 0 || fSeg[0] == 0x0) {
199 fSeg[i]->GetTransformer()->Global2Local(fidDE, x, y, z, xl, yl, zl);
200 //cout << xl << " " << yl << " " << zl << endl;
201 if (TMath::Abs (zl) > 0.5) return kFALSE;
202 //if (fChamber < 4 && (xl < 0 || yl < 0)) return kFALSE;
204 fSeg[i]->GetPadI(fidDE, x, y, z, ix, iy);
205 //cout << x << " " << y << " " << z << " " << fChamber << " " << ix << " " << iy << " " << fSeg[i]->Npx(fidDE) << " " << fSeg[i]->Npy(fidDE) /*<< " " << fSeg[i]->GetPadI(fidDE, x, y, z, ix, iy)*/ << " " << fSeg[i]->HasPad(fidDE, (Float_t)x, (Float_t)y, (Float_t)z) << endl;
206 //if (ix > 0 && iy > 0 && ix <= fSeg[i]->Npx(fidDE) && iy <= fSeg[i]->Npy(fidDE)) return kTRUE;
207 if (fSeg[i]->HasPad(fidDE, (Float_t)x, (Float_t)y, (Float_t)z)) return kTRUE;
209 //Double_t xl, yl, zl;
210 //fSeg[0]->GetTransformer()->Global2Local(fidDE, x, y, z, xl, yl, zl);
211 //cout << xl << " " << yl << " " << zl << endl;
213 Int_t cath = fSeg[0] ? 0 : 1;
214 const AliMpVSegmentation *mpSeg = fSeg[cath]->GetDESegmentation(fidDE)->GetMpSegmentation();
215 TVector2 dim = mpSeg->Dimensions();
216 if (fChamber < 4) dim *= 2.; // quadrants
217 //cout << fChamber << " " << dim.X() << " " << dim.Y() << endl;
218 if (TMath::Abs (xl) - dim.X() > dx) return kFALSE;
219 if (TMath::Abs (yl) - dim.Y() > dy) return kFALSE;
221 Int_t flagX = 0, flagY = 0;
222 if (TMath::Abs (xl) - dim.X() < -2) flagX = 1;
223 if (TMath::Abs (yl) - dim.Y() < -2) flagY = 1;
224 if (flagX && flagY) flagX = flagY = 0; // both coordinates "inside" det. elem. limits
226 // Check for edge effect (extrapolated track "right outside" det. elem. boundaries
227 // (+- dx * cath in X and Y)
230 for (Int_t i = 0; i < 2; i++) {
231 if (!fSeg[i]) continue;
232 for (Int_t idx = -1; idx < 2; idx++) {
233 if (flagX && idx) continue;
234 Double_t x1 = x + dx * idx * (i + 1);
235 for (Int_t idy = -1; idy < 2; idy++) {
236 if (idx == 0 && idy == 0) continue;
237 if (flagY && idy) continue;
238 Double_t y1 = y + dy * idy * (i + 1);
239 fSeg[i]->GetPadI(fidDE, x1, y1, z, ix, iy);
240 //cout << x1 << " " << y1 << " " << z << " " << fChamber << " " << ix << " " << iy << " " << fSeg[i]->Npx(fidDE) << " " << fSeg[i]->Npy(fidDE) /*<< " " << fSeg[i]->GetPadI(fidDE, x, y, z, ix, iy)*/ << " " << fSeg[i]->HasPad(fidDE, (Float_t)x1, (Float_t)y1, (Float_t)z) << endl;
241 //if (ix > 0 && iy > 0 && ix <= fSeg[i]->Npx(fidDE) && iy <= fSeg[i]->Npy(fidDE)) return kTRUE;
242 if (fSeg[i]->HasPad(fidDE, (Float_t)x1, (Float_t)y1, (Float_t)z)) return kTRUE;
249 //_________________________________________________________________________
250 void AliMUONDetElement::ClusterReco(Double_t xTrack, Double_t yTrack, Double_t dx, Double_t dy)
252 /// Run cluster reconstruction around point (x,y) inside window (dx,dy)
254 if (fLeft[0] == 0 && fLeft[1] == 0) return; // all digits have been used
255 AliMUONClusterInput::Instance()->SetDigits(fChamber, fidDE,
256 (TClonesArray*)fDigits[0], (TClonesArray*)fDigits[1]);
259 for (Int_t cath = 0; cath < 2; cath++) {
260 Int_t ndig = fDigits[cath]->GetEntriesFast();
261 if (ndig == 0) continue; // empty cathode
262 //cout << fidDE << " " << cath << " " << ndig << endl;
263 for (Int_t i = 0; i < ndig; i++) {
264 if (fLeft[cath] == 0) { fRecModel->SetUsed(cath,i); continue; }
265 AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(i);
266 //cout << i << " " << dig << " " /*<< dig->PadX() << " " << dig->PadY() << " " << fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) */<< endl;
267 if (fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) == kUsed) fRecModel->SetUsed(cath,i);
268 else fRecModel->SetUnused(cath,i);
272 fRecModel->ResetRawClusters();
274 for (Int_t cath = 0; cath < 2; cath++) {
275 Int_t ndig = fDigits[cath]->GetEntriesFast();
276 if (ndig == 0) continue; // empty cathode
278 for (fSeg[cath]->FirstPad(fidDE, xTrack, yTrack, fZ, dx, dy);
279 fSeg[cath]->MorePads(fidDE);
280 fSeg[cath]->NextPad(fidDE)) {
281 if (fLeft[cath] == 0) break;
282 //cout << cath << " " << fSeg[cath]->Ix() << " " << fSeg[cath]->Iy() << " " << fSeg[cath]->DetElemId() << " " << fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) << endl;
283 if (fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) == kEmpty ||
284 fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) == kUsed) continue;
288 for (Int_t j = 0; j < ndig; j++) {
289 AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(j);
290 if (dig->PadX() != fSeg[cath]->Ix() || dig->PadY() != fSeg[cath]->Iy()) continue;
291 //cout << fidDE << " " << j << " " << fDigits[cath]->GetEntriesFast() << " " << fSeg[cath]->Ix() << " " << fSeg[cath]->Iy() << endl;
292 fRecModel->SetStart(cath, j);
298 fRecModel->FindRawClusters();
299 Int_t nClusEnd = fRecModel->GetRawClusters()->GetEntriesFast();
300 //cout << " ***nclus: " << nClusEnd << endl;
301 for (Int_t i = 0; i < nClusEnd; i++) {
302 AliMUONRawCluster *clus = (AliMUONRawCluster*) fRecModel->GetRawClusters()->UncheckedAt(i);
303 AddHitForRec(clus); // add hit for rec.
304 //cout << clus->GetX(0) << " " << clus->GetY(0) << endl;
307 for (Int_t cath1 = 0; cath1 < 2; cath1++) {
308 Int_t ndig1 = fDigits[cath1]->GetEntriesFast();
309 for (Int_t j = 0; j < ndig1; j++) {
310 if (fLeft[cath1] == 0) break;
311 AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath1]->UncheckedAt(j);
313 fSeg[cath1]->GetPadC(fidDE,dig->PadX(),dig->PadY(),x,y,z);
314 //cout << "clus " << cath1 << " " << fLeft[cath1] << " " << dig->PadX() << " " << dig->PadY() << " " << x << " " << y << " " << z << " " << fRecModel->GetUsed(cath1,j) << endl;
315 if (!fRecModel->GetUsed(cath1,j)) continue;
316 if (fHitMap[cath1]->TestHit(dig->PadX(), dig->PadY()) == kUsed) continue;
317 fHitMap[cath1]->FlagHit(dig->PadX(), dig->PadY());
318 if (lun) fprintf(lun," %d %d %d %d \n", cath1, fidDE, dig->PadX(), dig->PadY());
322 } // for (fSeg[cath]->FirstPad(...
323 } // for (Int_t cath = 0;
326 //_________________________________________________________________________
327 void AliMUONDetElement::AddHitForRec(AliMUONRawCluster *clus)
329 /// Make HitForRec from raw cluster (rec. point)
331 fRawClus->Add(new AliMUONRawCluster(*clus));
332 //AliMUONHitForRec *hitForRec =
333 //new ((*fHitsForRec)[fNHitsForRec++]) AliMUONHitForRec(clus);
334 AliMUONHitForRec *hitForRec = new AliMUONHitForRec(clus);
335 fHitsForRec->Add(hitForRec);
338 // more information into HitForRec
339 // resolution: info should be already in raw cluster and taken from it ????
340 //hitForRec->SetBendingReso2(-1); //fBendingResolution * fBendingResolution);
341 //hitForRec->SetNonBendingReso2(-1); //fNonBendingResolution * fNonBendingResolution);
342 hitForRec->SetBendingReso2(clus->GetErrY() * clus->GetErrY());
343 hitForRec->SetNonBendingReso2(clus->GetErrX() * clus->GetErrX());
344 // original raw cluster
345 hitForRec->SetChamberNumber(fChamber);
346 hitForRec->SetZ(clus->GetZ(0));
347 //hitForRec->SetHitNumber(-(fIndex+1)*100000-fNHitsForRec+1);
348 hitForRec->SetHitNumber(-(fIndex+1)*100000-fRawClus->GetEntriesFast()+1);
349 //delete clus; // for now
353 //_________________________________________________________________________
354 Int_t AliMUONDetElement::GetMapElem(AliMUONDigit *digit)
356 Int_t cath = digit->Cathode();
361 //_________________________________________________________________________
362 void AliMUONDetElement::SetMapElem(const AliMUONDigit *digit, Int_t flag)
364 Int_t cath = digit->Cathode();