]>
Commit | Line | Data |
---|---|---|
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" | |
1c51a145 | 35 | #include "AliMUONGeometryModuleTransformer.h" |
6a518391 | 36 | #include "AliMUONSegmentation.h" |
1c51a145 | 37 | #include "AliMUONVGeometryDESegmentation.h" |
38 | #include "AliMpVSegmentation.h" | |
03ee5d34 | 39 | |
cc87ebcd | 40 | #include "AliRun.h" |
41 | #include "AliLog.h" | |
42 | ||
03ee5d34 | 43 | #include <TObjArray.h> |
44 | #include <TClonesArray.h> | |
1c51a145 | 45 | #include <TVector2.h> |
03ee5d34 | 46 | |
7945aae7 | 47 | /// \cond CLASSIMP |
cc87ebcd | 48 | ClassImp(AliMUONDetElement) // Class implementation in ROOT context |
7945aae7 | 49 | /// \endcond |
03ee5d34 | 50 | FILE *lun = 0x0; //fopen("hitmap.dat","w"); |
cc87ebcd | 51 | |
52 | //_________________________________________________________________________ | |
53 | AliMUONDetElement::AliMUONDetElement() | |
54d7ba50 | 54 | : TObject(), |
55 | fidDE(0), | |
56 | fIndex(0), | |
57 | fChamber(0), | |
58 | fZ(0.), | |
59 | fNHitsForRec(0), | |
60 | fRawClus(0x0), | |
61 | fHitsForRec(0x0), | |
62 | fRecModel(0x0) | |
cc87ebcd | 63 | { |
03ee5d34 | 64 | /// Default constructor |
cc87ebcd | 65 | for (Int_t i = 0; i < 2; i++) { |
66 | fHitMap[i] = NULL; | |
67 | fDigits[i] = NULL; | |
68 | fSeg[i] = NULL; | |
69 | } | |
cc87ebcd | 70 | } |
71 | ||
72 | //_________________________________________________________________________ | |
6a518391 | 73 | AliMUONDetElement::AliMUONDetElement(Int_t idDE, AliMUONDigit *dig, AliMUONClusterFinderAZ *recModel, |
74 | AliMUONSegmentation* segmentation) | |
54d7ba50 | 75 | : TObject(), |
76 | fidDE(idDE), | |
77 | fIndex(0), | |
78 | fChamber(idDE / 100 - 1), | |
79 | fZ(0.), | |
80 | fNHitsForRec(0), | |
1c51a145 | 81 | fRawClus(new TObjArray(10)), |
03ee5d34 | 82 | fHitsForRec(new TObjArray(10)), |
54d7ba50 | 83 | fRecModel(recModel) |
cc87ebcd | 84 | { |
03ee5d34 | 85 | /// Constructor |
1c51a145 | 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); | |
6a518391 | 92 | |
93 | // Segmentations | |
94 | fSeg[0] = segmentation->GetModuleSegmentationByDEId(idDE, 0); | |
95 | fSeg[1] = segmentation->GetModuleSegmentationByDEId(idDE, 1); | |
96 | ||
03ee5d34 | 97 | /* |
cc87ebcd | 98 | Float_t x, y, z; |
99 | fSeg[dig->Cathode()]->GetPadC(fidDE, dig->PadX(), dig->PadY(), x, y, z); | |
100 | fZ = z; | |
03ee5d34 | 101 | */ |
cc87ebcd | 102 | AddDigit(dig); |
103 | } | |
104 | ||
105 | //_________________________________________________________________________ | |
106 | AliMUONDetElement::~AliMUONDetElement() | |
107 | { | |
03ee5d34 | 108 | /// Destructor |
cc87ebcd | 109 | for (Int_t i = 0; i < 2; i++) { |
1c51a145 | 110 | delete fHitMap[i]; |
111 | delete fDigits[i]; | |
cc87ebcd | 112 | } |
1c51a145 | 113 | delete fRawClus; |
03ee5d34 | 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); | |
118 | } | |
1c51a145 | 119 | delete fHitsForRec; |
03ee5d34 | 120 | //fHitsForRec->SetOwner(kFALSE); |
121 | //fHitsForRec->Clear(); cout << " here " << fHitsForRec->GetEntriesFast() << endl; delete fHitsForRec; fHitsForRec = 0; | |
cc87ebcd | 122 | } |
123 | ||
cc87ebcd | 124 | //_________________________________________________________________________ |
125 | Int_t AliMUONDetElement::Compare(const TObject* detElem) const | |
126 | { | |
03ee5d34 | 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 | |
cc87ebcd | 130 | if (fZ > ((AliMUONDetElement*)detElem)->Z()) return(+1); |
131 | else if (fZ == ((AliMUONDetElement*)detElem)->Z()) return( 0); | |
132 | else return(-1); | |
133 | } | |
134 | ||
135 | //_________________________________________________________________________ | |
136 | void AliMUONDetElement::Fill(AliMUONData */*data*/) | |
137 | { | |
03ee5d34 | 138 | /// Fill hit maps |
cc87ebcd | 139 | fLeft[0] = fDigits[0]->GetEntriesFast(); |
140 | fLeft[1] = fDigits[1]->GetEntriesFast(); | |
141 | ||
4e92ede3 | 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]); | |
cc87ebcd | 145 | fHitMap[0]->FillHits(); |
4e92ede3 | 146 | |
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]); | |
cc87ebcd | 150 | fHitMap[1]->FillHits(); |
151 | ||
152 | // The part below is just for debugging (fill rec. points already found) | |
153 | /* | |
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 | |
164 | } | |
165 | cout << fHitsForRec->GetEntriesFast() << endl; | |
166 | rawClus->Compress(); | |
167 | */ | |
168 | } | |
169 | ||
170 | //_________________________________________________________________________ | |
171 | void AliMUONDetElement::AddDigit(AliMUONDigit *dig) | |
172 | { | |
03ee5d34 | 173 | /// Add digit |
cc87ebcd | 174 | |
03ee5d34 | 175 | //fDigits[dig->Cathode()]->Add(dig); |
176 | fDigits[dig->Cathode()]->Add(new AliMUONDigit(*dig)); | |
177 | Float_t x, y, z; | |
178 | fSeg[dig->Cathode()]->GetPadC(fidDE, dig->PadX(), dig->PadY(), x, y, z); | |
179 | fZ += z; | |
180 | /* | |
181 | Int_t ndig = fDigits[dig->Cathode()]->GetEntriesFast(); | |
182 | new((*fDigits[dig->Cathode()])[ndig]) AliMUONDigit(*dig); | |
183 | */ | |
cc87ebcd | 184 | } |
185 | ||
186 | //_________________________________________________________________________ | |
03ee5d34 | 187 | Bool_t AliMUONDetElement::Inside(Double_t x, Double_t y, Double_t z, Double_t dx, Double_t dy) const |
cc87ebcd | 188 | { |
03ee5d34 | 189 | /// Check if point is inside detection element |
cc87ebcd | 190 | |
03ee5d34 | 191 | dx = TMath::Max (dx, 1.); |
192 | dy = TMath::Max (dy, 1.); | |
cc87ebcd | 193 | Int_t ix, iy; |
03ee5d34 | 194 | ix = iy = 0; |
195 | Double_t xl, yl, zl; | |
cc87ebcd | 196 | for (Int_t i = 0; i < 2; i++) { |
197 | if (!fSeg[i]) continue; | |
03ee5d34 | 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; | |
203 | } | |
cc87ebcd | 204 | fSeg[i]->GetPadI(fidDE, x, y, z, ix, iy); |
03ee5d34 | 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; | |
cc87ebcd | 208 | } |
03ee5d34 | 209 | //Double_t xl, yl, zl; |
210 | //fSeg[0]->GetTransformer()->Global2Local(fidDE, x, y, z, xl, yl, zl); | |
211 | //cout << xl << " " << yl << " " << zl << endl; | |
212 | ||
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; | |
220 | ||
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 | |
225 | ||
226 | // Check for edge effect (extrapolated track "right outside" det. elem. boundaries | |
227 | // (+- dx * cath in X and Y) | |
228 | dx /= 2; | |
229 | dy /= 2; | |
cc87ebcd | 230 | for (Int_t i = 0; i < 2; i++) { |
231 | if (!fSeg[i]) continue; | |
232 | for (Int_t idx = -1; idx < 2; idx++) { | |
03ee5d34 | 233 | if (flagX && idx) continue; |
234 | Double_t x1 = x + dx * idx * (i + 1); | |
cc87ebcd | 235 | for (Int_t idy = -1; idy < 2; idy++) { |
236 | if (idx == 0 && idy == 0) continue; | |
03ee5d34 | 237 | if (flagY && idy) continue; |
238 | Double_t y1 = y + dy * idy * (i + 1); | |
cc87ebcd | 239 | fSeg[i]->GetPadI(fidDE, x1, y1, z, ix, iy); |
03ee5d34 | 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; | |
cc87ebcd | 243 | } |
244 | } | |
245 | } | |
246 | return kFALSE; | |
247 | } | |
248 | ||
249 | //_________________________________________________________________________ | |
03ee5d34 | 250 | void AliMUONDetElement::ClusterReco(Double_t xTrack, Double_t yTrack, Double_t dx, Double_t dy) |
cc87ebcd | 251 | { |
03ee5d34 | 252 | /// Run cluster reconstruction around point (x,y) inside window (dx,dy) |
cc87ebcd | 253 | |
254 | if (fLeft[0] == 0 && fLeft[1] == 0) return; // all digits have been used | |
cc87ebcd | 255 | AliMUONClusterInput::Instance()->SetDigits(fChamber, fidDE, |
256 | (TClonesArray*)fDigits[0], (TClonesArray*)fDigits[1]); | |
257 | ||
258 | // Mark used pads | |
259 | for (Int_t cath = 0; cath < 2; cath++) { | |
03ee5d34 | 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++) { | |
cc87ebcd | 264 | if (fLeft[cath] == 0) { fRecModel->SetUsed(cath,i); continue; } |
265 | AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(i); | |
03ee5d34 | 266 | //cout << i << " " << dig << " " /*<< dig->PadX() << " " << dig->PadY() << " " << fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) */<< endl; |
cc87ebcd | 267 | if (fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) == kUsed) fRecModel->SetUsed(cath,i); |
268 | else fRecModel->SetUnused(cath,i); | |
269 | } | |
270 | } | |
271 | ||
272 | fRecModel->ResetRawClusters(); | |
273 | ||
274 | for (Int_t cath = 0; cath < 2; cath++) { | |
03ee5d34 | 275 | Int_t ndig = fDigits[cath]->GetEntriesFast(); |
276 | if (ndig == 0) continue; // empty cathode | |
cc87ebcd | 277 | // Loop over pads |
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; | |
285 | ||
03ee5d34 | 286 | Int_t iOK = 0; |
cc87ebcd | 287 | // Set starting pad |
03ee5d34 | 288 | for (Int_t j = 0; j < ndig; j++) { |
cc87ebcd | 289 | AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(j); |
290 | if (dig->PadX() != fSeg[cath]->Ix() || dig->PadY() != fSeg[cath]->Iy()) continue; | |
03ee5d34 | 291 | //cout << fidDE << " " << j << " " << fDigits[cath]->GetEntriesFast() << " " << fSeg[cath]->Ix() << " " << fSeg[cath]->Iy() << endl; |
cc87ebcd | 292 | fRecModel->SetStart(cath, j); |
03ee5d34 | 293 | iOK = 1; |
cc87ebcd | 294 | break; |
295 | } | |
03ee5d34 | 296 | if (!iOK) continue; |
cc87ebcd | 297 | |
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; | |
305 | } | |
306 | // Mark used pads | |
307 | for (Int_t cath1 = 0; cath1 < 2; cath1++) { | |
03ee5d34 | 308 | Int_t ndig1 = fDigits[cath1]->GetEntriesFast(); |
309 | for (Int_t j = 0; j < ndig1; j++) { | |
cc87ebcd | 310 | if (fLeft[cath1] == 0) break; |
311 | AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath1]->UncheckedAt(j); | |
312 | Float_t x, y, z; | |
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()); | |
03ee5d34 | 318 | if (lun) fprintf(lun," %d %d %d %d \n", cath1, fidDE, dig->PadX(), dig->PadY()); |
cc87ebcd | 319 | fLeft[cath1]--; |
320 | } | |
321 | } | |
322 | } // for (fSeg[cath]->FirstPad(... | |
323 | } // for (Int_t cath = 0; | |
324 | } | |
325 | ||
326 | //_________________________________________________________________________ | |
327 | void AliMUONDetElement::AddHitForRec(AliMUONRawCluster *clus) | |
328 | { | |
03ee5d34 | 329 | /// Make HitForRec from raw cluster (rec. point) |
cc87ebcd | 330 | |
331 | fRawClus->Add(new AliMUONRawCluster(*clus)); | |
03ee5d34 | 332 | //AliMUONHitForRec *hitForRec = |
333 | //new ((*fHitsForRec)[fNHitsForRec++]) AliMUONHitForRec(clus); | |
334 | AliMUONHitForRec *hitForRec = new AliMUONHitForRec(clus); | |
335 | fHitsForRec->Add(hitForRec); | |
336 | fNHitsForRec++; | |
cc87ebcd | 337 | |
338 | // more information into HitForRec | |
339 | // resolution: info should be already in raw cluster and taken from it ???? | |
03ee5d34 | 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()); | |
cc87ebcd | 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 | |
350 | } | |
351 | ||
352 | /* | |
353 | //_________________________________________________________________________ | |
354 | Int_t AliMUONDetElement::GetMapElem(AliMUONDigit *digit) | |
355 | { | |
356 | Int_t cath = digit->Cathode(); | |
357 | return 0; | |
358 | ||
359 | } | |
360 | ||
361 | //_________________________________________________________________________ | |
362 | void AliMUONDetElement::SetMapElem(const AliMUONDigit *digit, Int_t flag) | |
363 | { | |
364 | Int_t cath = digit->Cathode(); | |
365 | } | |
366 | */ |