]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONDetElement.cxx
Bug fixes
[u/mrichter/AliRoot.git] / MUON / AliMUONDetElement.cxx
CommitLineData
cc87ebcd 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
d19b6003 18// --------------------------
19// Class AliMUONDetElement
20// --------------------------
21// Detection element object containing information for combined
03ee5d34 22// cluster / track finder in the MUON arm
d19b6003 23// Author: Alexander Zinchenko, JINR Dubna
24
cc87ebcd 25#include "AliMUONDetElement.h"
26#include "AliMUON.h"
27#include "AliMUONSegmentation.h"
28#include "AliMUONDigit.h"
29#include "AliMUONHitMapA1.h"
03ee5d34 30#include "AliMUONData.h"
cc87ebcd 31#include "AliMUONRawCluster.h"
32#include "AliMUONHitForRec.h"
33#include "AliMUONClusterInput.h"
34#include "AliMUONClusterFinderAZ.h"
03ee5d34 35#include "AliMUONGeometryModuleTransformer.h" //AZ
36#include "AliMUONVGeometryDESegmentation.h" //AZ
37#include "AliMpVSegmentation.h" //AZ
38
cc87ebcd 39#include "AliRun.h"
40#include "AliLog.h"
41
03ee5d34 42#include <TObjArray.h>
43#include <TClonesArray.h>
44#include <TVector2.h> //AZ
45
7945aae7 46/// \cond CLASSIMP
cc87ebcd 47ClassImp(AliMUONDetElement) // Class implementation in ROOT context
7945aae7 48/// \endcond
03ee5d34 49 FILE *lun = 0x0; //fopen("hitmap.dat","w");
cc87ebcd 50
51//_________________________________________________________________________
52AliMUONDetElement::AliMUONDetElement()
54d7ba50 53 : TObject(),
54 fidDE(0),
55 fIndex(0),
56 fChamber(0),
57 fZ(0.),
58 fNHitsForRec(0),
59 fRawClus(0x0),
60 fHitsForRec(0x0),
61 fRecModel(0x0)
cc87ebcd 62{
03ee5d34 63 /// Default constructor
cc87ebcd 64 for (Int_t i = 0; i < 2; i++) {
65 fHitMap[i] = NULL;
66 fDigits[i] = NULL;
67 fSeg[i] = NULL;
68 }
cc87ebcd 69}
70
71//_________________________________________________________________________
72AliMUONDetElement::AliMUONDetElement(Int_t idDE, AliMUONDigit *dig, AliMUONClusterFinderAZ *recModel)
54d7ba50 73 : TObject(),
74 fidDE(idDE),
75 fIndex(0),
76 fChamber(idDE / 100 - 1),
77 fZ(0.),
78 fNHitsForRec(0),
79 fRawClus(0x0),
03ee5d34 80 fHitsForRec(new TObjArray(10)),
54d7ba50 81 fRecModel(recModel)
cc87ebcd 82{
03ee5d34 83 /// Constructor
cc87ebcd 84 fDigits[0] = new TObjArray(10);
85 fDigits[1] = new TObjArray(10);
86 fRawClus = new TObjArray(10);
cc87ebcd 87 AliMUON *pMUON = (AliMUON*) gAlice->GetModule("MUON");
88 AliMUONSegmentation *pSegmentation = pMUON->GetSegmentation();
03ee5d34 89 fSeg[0] = pSegmentation->GetModuleSegmentationByDEId(idDE, 0);
90 fSeg[1] = pSegmentation->GetModuleSegmentationByDEId(idDE, 1);
91 /*
cc87ebcd 92 Float_t x, y, z;
93 fSeg[dig->Cathode()]->GetPadC(fidDE, dig->PadX(), dig->PadY(), x, y, z);
94 fZ = z;
03ee5d34 95 */
cc87ebcd 96 AddDigit(dig);
97}
98
99//_________________________________________________________________________
100AliMUONDetElement::~AliMUONDetElement()
101{
03ee5d34 102 /// Destructor
103
cc87ebcd 104 for (Int_t i = 0; i < 2; i++) {
105 delete fHitMap[i]; fHitMap[i] = NULL;
106 delete fDigits[i]; fDigits[i] = NULL;
03ee5d34 107 //fDigits[i]->Delete(); delete fDigits[i]; fDigits[i] = NULL;
cc87ebcd 108 }
03ee5d34 109 //fHitsForRec->Clear(); delete fHitsForRec; fHitsForRec = 0;
cc87ebcd 110 if (fRawClus) { fRawClus->Delete(); delete fRawClus; fRawClus = 0; }
111 //if (fRawClus) { delete fRawClus; fRawClus = 0; }
03ee5d34 112 for (Int_t i = 0; i < fNHitsForRec; i++) {
113 Int_t ntracks = ((AliMUONHitForRec*)fHitsForRec->UncheckedAt(i))->GetNTrackHits();
114 //cout << ntracks << endl;
115 if (ntracks) fHitsForRec->RemoveAt(i);
116 }
117 //fHitsForRec->Delete();
cc87ebcd 118 delete fHitsForRec; fHitsForRec = 0;
03ee5d34 119 //fHitsForRec->SetOwner(kFALSE);
120 //fHitsForRec->Clear(); cout << " here " << fHitsForRec->GetEntriesFast() << endl; delete fHitsForRec; fHitsForRec = 0;
cc87ebcd 121}
122
cc87ebcd 123//_________________________________________________________________________
124Int_t AliMUONDetElement::Compare(const TObject* detElem) const
125{
03ee5d34 126 /// "Compare" function to sort in Z (towards interaction point)
127 /// Returns -1 (0, +1) if charge of current pixel
128 /// is greater than (equal to, less than) charge of pixel
cc87ebcd 129 if (fZ > ((AliMUONDetElement*)detElem)->Z()) return(+1);
130 else if (fZ == ((AliMUONDetElement*)detElem)->Z()) return( 0);
131 else return(-1);
132}
133
134//_________________________________________________________________________
135void AliMUONDetElement::Fill(AliMUONData */*data*/)
136{
03ee5d34 137 /// Fill hit maps
cc87ebcd 138 fLeft[0] = fDigits[0]->GetEntriesFast();
139 fLeft[1] = fDigits[1]->GetEntriesFast();
140
4e92ede3 141 Int_t npx0 = fSeg[0]->Npx(fidDE)+1;
142 Int_t npy0 = fSeg[0]->Npy(fidDE)+1;
143 fHitMap[0] = new AliMUONHitMapA1(npx0, npy0, fDigits[0]);
cc87ebcd 144 fHitMap[0]->FillHits();
4e92ede3 145
146 Int_t npx1 = fSeg[1]->Npx(fidDE)+1;
147 Int_t npy1 = fSeg[1]->Npy(fidDE)+1;
148 fHitMap[1] = new AliMUONHitMapA1(npx1, npy1, fDigits[1]);
cc87ebcd 149 fHitMap[1]->FillHits();
150
151 // The part below is just for debugging (fill rec. points already found)
152 /*
153 fLeft[0] = fLeft[1] = 0;
154 TClonesArray *rawClus = data->RawClusters(fChamber);
155 cout << rawClus << " " << rawClus->GetEntriesFast() << endl;
156 for (Int_t i = 0; i < rawClus->GetEntriesFast(); i++) {
157 AliMUONRawCluster *recP = (AliMUONRawCluster*) rawClus->UncheckedAt(i);
158 cout << fChamber << " " << recP->GetZ(0) << " " << recP->GetZ(1) << " " << fZ << endl;
159 if (TMath::Abs(recP->GetZ(0)-fZ) > 0.5) continue;
160 if (!Inside(recP->GetX(0), recP->GetY(0), recP->GetZ(0))) continue;
161 AddHitForRec(recP); // add hit for rec.
162 rawClus->RemoveAt(i); // remove
163 }
164 cout << fHitsForRec->GetEntriesFast() << endl;
165 rawClus->Compress();
166 */
167}
168
169//_________________________________________________________________________
170void AliMUONDetElement::AddDigit(AliMUONDigit *dig)
171{
03ee5d34 172 /// Add digit
cc87ebcd 173
03ee5d34 174 //fDigits[dig->Cathode()]->Add(dig);
175 fDigits[dig->Cathode()]->Add(new AliMUONDigit(*dig));
176 Float_t x, y, z;
177 fSeg[dig->Cathode()]->GetPadC(fidDE, dig->PadX(), dig->PadY(), x, y, z);
178 fZ += z;
179 /*
180 Int_t ndig = fDigits[dig->Cathode()]->GetEntriesFast();
181 new((*fDigits[dig->Cathode()])[ndig]) AliMUONDigit(*dig);
182 */
cc87ebcd 183}
184
185//_________________________________________________________________________
03ee5d34 186Bool_t AliMUONDetElement::Inside(Double_t x, Double_t y, Double_t z, Double_t dx, Double_t dy) const
cc87ebcd 187{
03ee5d34 188 /// Check if point is inside detection element
cc87ebcd 189
03ee5d34 190 dx = TMath::Max (dx, 1.);
191 dy = TMath::Max (dy, 1.);
cc87ebcd 192 Int_t ix, iy;
03ee5d34 193 ix = iy = 0;
194 Double_t xl, yl, zl;
cc87ebcd 195 for (Int_t i = 0; i < 2; i++) {
196 if (!fSeg[i]) continue;
03ee5d34 197 if (i == 0 || fSeg[0] == 0x0) {
198 fSeg[i]->GetTransformer()->Global2Local(fidDE, x, y, z, xl, yl, zl);
199 //cout << xl << " " << yl << " " << zl << endl;
200 if (TMath::Abs (zl) > 0.5) return kFALSE;
201 //if (fChamber < 4 && (xl < 0 || yl < 0)) return kFALSE;
202 }
cc87ebcd 203 fSeg[i]->GetPadI(fidDE, x, y, z, ix, iy);
03ee5d34 204 //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;
205 //if (ix > 0 && iy > 0 && ix <= fSeg[i]->Npx(fidDE) && iy <= fSeg[i]->Npy(fidDE)) return kTRUE;
206 if (fSeg[i]->HasPad(fidDE, (Float_t)x, (Float_t)y, (Float_t)z)) return kTRUE;
cc87ebcd 207 }
03ee5d34 208 //Double_t xl, yl, zl;
209 //fSeg[0]->GetTransformer()->Global2Local(fidDE, x, y, z, xl, yl, zl);
210 //cout << xl << " " << yl << " " << zl << endl;
211
212 Int_t cath = fSeg[0] ? 0 : 1;
213 const AliMpVSegmentation *mpSeg = fSeg[cath]->GetDESegmentation(fidDE)->GetMpSegmentation();
214 TVector2 dim = mpSeg->Dimensions();
215 if (fChamber < 4) dim *= 2.; // quadrants
216 //cout << fChamber << " " << dim.X() << " " << dim.Y() << endl;
217 if (TMath::Abs (xl) - dim.X() > dx) return kFALSE;
218 if (TMath::Abs (yl) - dim.Y() > dy) return kFALSE;
219
220 Int_t flagX = 0, flagY = 0;
221 if (TMath::Abs (xl) - dim.X() < -2) flagX = 1;
222 if (TMath::Abs (yl) - dim.Y() < -2) flagY = 1;
223 if (flagX && flagY) flagX = flagY = 0; // both coordinates "inside" det. elem. limits
224
225 // Check for edge effect (extrapolated track "right outside" det. elem. boundaries
226 // (+- dx * cath in X and Y)
227 dx /= 2;
228 dy /= 2;
cc87ebcd 229 for (Int_t i = 0; i < 2; i++) {
230 if (!fSeg[i]) continue;
231 for (Int_t idx = -1; idx < 2; idx++) {
03ee5d34 232 if (flagX && idx) continue;
233 Double_t x1 = x + dx * idx * (i + 1);
cc87ebcd 234 for (Int_t idy = -1; idy < 2; idy++) {
235 if (idx == 0 && idy == 0) continue;
03ee5d34 236 if (flagY && idy) continue;
237 Double_t y1 = y + dy * idy * (i + 1);
cc87ebcd 238 fSeg[i]->GetPadI(fidDE, x1, y1, z, ix, iy);
03ee5d34 239 //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;
240 //if (ix > 0 && iy > 0 && ix <= fSeg[i]->Npx(fidDE) && iy <= fSeg[i]->Npy(fidDE)) return kTRUE;
241 if (fSeg[i]->HasPad(fidDE, (Float_t)x1, (Float_t)y1, (Float_t)z)) return kTRUE;
cc87ebcd 242 }
243 }
244 }
245 return kFALSE;
246}
247
248//_________________________________________________________________________
03ee5d34 249void AliMUONDetElement::ClusterReco(Double_t xTrack, Double_t yTrack, Double_t dx, Double_t dy)
cc87ebcd 250{
03ee5d34 251 /// Run cluster reconstruction around point (x,y) inside window (dx,dy)
cc87ebcd 252
253 if (fLeft[0] == 0 && fLeft[1] == 0) return; // all digits have been used
cc87ebcd 254 AliMUONClusterInput::Instance()->SetDigits(fChamber, fidDE,
255 (TClonesArray*)fDigits[0], (TClonesArray*)fDigits[1]);
256
257 // Mark used pads
258 for (Int_t cath = 0; cath < 2; cath++) {
03ee5d34 259 Int_t ndig = fDigits[cath]->GetEntriesFast();
260 if (ndig == 0) continue; // empty cathode
261 //cout << fidDE << " " << cath << " " << ndig << endl;
262 for (Int_t i = 0; i < ndig; i++) {
cc87ebcd 263 if (fLeft[cath] == 0) { fRecModel->SetUsed(cath,i); continue; }
264 AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(i);
03ee5d34 265 //cout << i << " " << dig << " " /*<< dig->PadX() << " " << dig->PadY() << " " << fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) */<< endl;
cc87ebcd 266 if (fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) == kUsed) fRecModel->SetUsed(cath,i);
267 else fRecModel->SetUnused(cath,i);
268 }
269 }
270
271 fRecModel->ResetRawClusters();
272
273 for (Int_t cath = 0; cath < 2; cath++) {
03ee5d34 274 Int_t ndig = fDigits[cath]->GetEntriesFast();
275 if (ndig == 0) continue; // empty cathode
cc87ebcd 276 // Loop over pads
277 for (fSeg[cath]->FirstPad(fidDE, xTrack, yTrack, fZ, dx, dy);
278 fSeg[cath]->MorePads(fidDE);
279 fSeg[cath]->NextPad(fidDE)) {
280 if (fLeft[cath] == 0) break;
281 //cout << cath << " " << fSeg[cath]->Ix() << " " << fSeg[cath]->Iy() << " " << fSeg[cath]->DetElemId() << " " << fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) << endl;
282 if (fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) == kEmpty ||
283 fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) == kUsed) continue;
284
03ee5d34 285 Int_t iOK = 0;
cc87ebcd 286 // Set starting pad
03ee5d34 287 for (Int_t j = 0; j < ndig; j++) {
cc87ebcd 288 AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(j);
289 if (dig->PadX() != fSeg[cath]->Ix() || dig->PadY() != fSeg[cath]->Iy()) continue;
03ee5d34 290 //cout << fidDE << " " << j << " " << fDigits[cath]->GetEntriesFast() << " " << fSeg[cath]->Ix() << " " << fSeg[cath]->Iy() << endl;
cc87ebcd 291 fRecModel->SetStart(cath, j);
03ee5d34 292 iOK = 1;
cc87ebcd 293 break;
294 }
03ee5d34 295 if (!iOK) continue;
cc87ebcd 296
297 fRecModel->FindRawClusters();
298 Int_t nClusEnd = fRecModel->GetRawClusters()->GetEntriesFast();
299 //cout << " ***nclus: " << nClusEnd << endl;
300 for (Int_t i = 0; i < nClusEnd; i++) {
301 AliMUONRawCluster *clus = (AliMUONRawCluster*) fRecModel->GetRawClusters()->UncheckedAt(i);
302 AddHitForRec(clus); // add hit for rec.
303 //cout << clus->GetX(0) << " " << clus->GetY(0) << endl;
304 }
305 // Mark used pads
306 for (Int_t cath1 = 0; cath1 < 2; cath1++) {
03ee5d34 307 Int_t ndig1 = fDigits[cath1]->GetEntriesFast();
308 for (Int_t j = 0; j < ndig1; j++) {
cc87ebcd 309 if (fLeft[cath1] == 0) break;
310 AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath1]->UncheckedAt(j);
311 Float_t x, y, z;
312 fSeg[cath1]->GetPadC(fidDE,dig->PadX(),dig->PadY(),x,y,z);
313 //cout << "clus " << cath1 << " " << fLeft[cath1] << " " << dig->PadX() << " " << dig->PadY() << " " << x << " " << y << " " << z << " " << fRecModel->GetUsed(cath1,j) << endl;
314 if (!fRecModel->GetUsed(cath1,j)) continue;
315 if (fHitMap[cath1]->TestHit(dig->PadX(), dig->PadY()) == kUsed) continue;
316 fHitMap[cath1]->FlagHit(dig->PadX(), dig->PadY());
03ee5d34 317 if (lun) fprintf(lun," %d %d %d %d \n", cath1, fidDE, dig->PadX(), dig->PadY());
cc87ebcd 318 fLeft[cath1]--;
319 }
320 }
321 } // for (fSeg[cath]->FirstPad(...
322 } // for (Int_t cath = 0;
323}
324
325//_________________________________________________________________________
326void AliMUONDetElement::AddHitForRec(AliMUONRawCluster *clus)
327{
03ee5d34 328 /// Make HitForRec from raw cluster (rec. point)
cc87ebcd 329
330 fRawClus->Add(new AliMUONRawCluster(*clus));
03ee5d34 331 //AliMUONHitForRec *hitForRec =
332 //new ((*fHitsForRec)[fNHitsForRec++]) AliMUONHitForRec(clus);
333 AliMUONHitForRec *hitForRec = new AliMUONHitForRec(clus);
334 fHitsForRec->Add(hitForRec);
335 fNHitsForRec++;
cc87ebcd 336
337 // more information into HitForRec
338 // resolution: info should be already in raw cluster and taken from it ????
03ee5d34 339 //hitForRec->SetBendingReso2(-1); //fBendingResolution * fBendingResolution);
340 //hitForRec->SetNonBendingReso2(-1); //fNonBendingResolution * fNonBendingResolution);
341 hitForRec->SetBendingReso2(clus->GetErrY() * clus->GetErrY());
342 hitForRec->SetNonBendingReso2(clus->GetErrX() * clus->GetErrX());
cc87ebcd 343 // original raw cluster
344 hitForRec->SetChamberNumber(fChamber);
345 hitForRec->SetZ(clus->GetZ(0));
346 //hitForRec->SetHitNumber(-(fIndex+1)*100000-fNHitsForRec+1);
347 hitForRec->SetHitNumber(-(fIndex+1)*100000-fRawClus->GetEntriesFast()+1);
348 //delete clus; // for now
349}
350
351/*
352//_________________________________________________________________________
353Int_t AliMUONDetElement::GetMapElem(AliMUONDigit *digit)
354{
355 Int_t cath = digit->Cathode();
356 return 0;
357
358}
359
360//_________________________________________________________________________
361void AliMUONDetElement::SetMapElem(const AliMUONDigit *digit, Int_t flag)
362{
363 Int_t cath = digit->Cathode();
364}
365*/