]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONDetElement.cxx
Additional protection in case of negative indexes. More investigation is needed
[u/mrichter/AliRoot.git] / MUON / AliMUONDetElement.cxx
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
18 #include <TObjArray.h>
19 #include <TClonesArray.h>
20 #include "AliMUONDetElement.h"
21 #include "AliMUON.h"
22 #include "AliMUONSegmentation.h"
23 #include "AliMUONDigit.h"
24 #include "AliMUONHitMapA1.h"
25 #include "AliMUONData.h"
26 #include "AliMUONRawCluster.h"
27 #include "AliMUONHitForRec.h"
28 #include "AliMUONClusterInput.h"
29 #include "AliMUONClusterFinderAZ.h"
30 #include "AliRun.h"
31 #include "AliLog.h"
32
33 ClassImp(AliMUONDetElement) // Class implementation in ROOT context
34   FILE *lun = 0x0; //fopen("hitmap.dat","w");
35
36 //_________________________________________________________________________
37 AliMUONDetElement::AliMUONDetElement()
38   : TObject()
39 {
40 // Default constructor
41   for (Int_t i = 0; i < 2; i++) {
42     fHitMap[i] = NULL;
43     fDigits[i] = NULL;
44     fSeg[i] = NULL;
45   }
46   fRawClus = fHitsForRec = NULL;
47   fRecModel = NULL;
48
49
50 //_________________________________________________________________________
51 AliMUONDetElement::AliMUONDetElement(Int_t idDE, AliMUONDigit *dig, AliMUONClusterFinderAZ *recModel) 
52   : TObject()
53 {
54   // Constructor
55   fidDE = idDE;
56   fChamber = fidDE / 100 - 1;
57   fDigits[0] = new TObjArray(10);
58   fDigits[1] = new TObjArray(10);
59   fRawClus = new TObjArray(10);
60   fHitsForRec = new TClonesArray("AliMUONHitForRec",10);
61   fNHitsForRec = 0;
62   fRecModel = recModel;
63   AliMUON *pMUON = (AliMUON*) gAlice->GetModule("MUON");
64   AliMUONSegmentation *pSegmentation = pMUON->GetSegmentation();
65   fSeg[0] = pSegmentation->GetModuleSegmentation(fChamber, 0);
66   fSeg[1] = pSegmentation->GetModuleSegmentation(fChamber, 1);
67   Float_t x, y, z;
68   fSeg[dig->Cathode()]->GetPadC(fidDE, dig->PadX(), dig->PadY(), x, y, z);
69   fZ = z;
70   AddDigit(dig);
71 }
72
73 //_________________________________________________________________________
74 AliMUONDetElement::~AliMUONDetElement()
75 {
76   // Destructor
77   for (Int_t i = 0; i < 2; i++) {
78     delete fHitMap[i]; fHitMap[i] = NULL; 
79     delete fDigits[i]; fDigits[i] = NULL; 
80   }
81   if (fRawClus) { fRawClus->Delete(); delete fRawClus; fRawClus = 0; }
82   //if (fRawClus) { delete fRawClus; fRawClus = 0; }
83   delete fHitsForRec; fHitsForRec = 0;
84 }
85
86 //_________________________________________________________________________
87 AliMUONDetElement::AliMUONDetElement (const AliMUONDetElement& rhs)
88   : TObject(rhs)
89 {
90 // Copy constructor
91
92   AliFatal("Not implemented.");
93 }
94
95 //________________________________________________________________________
96 AliMUONDetElement & AliMUONDetElement::operator = (const AliMUONDetElement& rhs)
97 {
98 // Assignement operator
99
100   if (this == &rhs) return *this;
101   AliFatal( "Not implemented.");
102   return *this;
103 }
104
105 //_________________________________________________________________________
106 Int_t AliMUONDetElement::Compare(const TObject* detElem) const
107 {
108   // "Compare" function to sort in Z (towards interaction point)
109   // Returns -1 (0, +1) if charge of current pixel
110   // is greater than (equal to, less than) charge of pixel
111   if (fZ > ((AliMUONDetElement*)detElem)->Z()) return(+1);
112   else if (fZ == ((AliMUONDetElement*)detElem)->Z()) return( 0);
113   else return(-1);
114 }
115
116 //_________________________________________________________________________
117 void AliMUONDetElement::Fill(AliMUONData */*data*/)
118 {
119   // Fill hit maps
120   fLeft[0] = fDigits[0]->GetEntriesFast();
121   fLeft[1] = fDigits[1]->GetEntriesFast();
122
123   Int_t  npx0  = fSeg[0]->Npx(fidDE)+1;
124   Int_t  npy0  = fSeg[0]->Npy(fidDE)+1;
125   fHitMap[0] = new AliMUONHitMapA1(npx0, npy0, fDigits[0]);
126   fHitMap[0]->FillHits();
127
128   Int_t  npx1  = fSeg[1]->Npx(fidDE)+1;
129   Int_t  npy1  = fSeg[1]->Npy(fidDE)+1;
130   fHitMap[1] = new AliMUONHitMapA1(npx1, npy1, fDigits[1]);
131   fHitMap[1]->FillHits();
132
133   // The part below is just for debugging (fill rec. points already found)
134   /*
135   fLeft[0] = fLeft[1] = 0;
136   TClonesArray *rawClus = data->RawClusters(fChamber);
137   cout << rawClus << " " << rawClus->GetEntriesFast() << endl;
138   for (Int_t i = 0; i < rawClus->GetEntriesFast(); i++) {
139     AliMUONRawCluster *recP = (AliMUONRawCluster*) rawClus->UncheckedAt(i);
140     cout << fChamber << " " << recP->GetZ(0) << " " << recP->GetZ(1) << " " << fZ << endl;
141     if (TMath::Abs(recP->GetZ(0)-fZ) > 0.5) continue;
142     if (!Inside(recP->GetX(0), recP->GetY(0), recP->GetZ(0))) continue;
143     AddHitForRec(recP); // add hit for rec.
144     rawClus->RemoveAt(i); // remove
145   }
146   cout << fHitsForRec->GetEntriesFast() << endl;
147   rawClus->Compress();
148   */
149 }
150
151 //_________________________________________________________________________
152 void AliMUONDetElement::AddDigit(AliMUONDigit *dig)
153 {
154   // Add digit
155
156   fDigits[dig->Cathode()]->Add(dig);
157 }
158
159 //_________________________________________________________________________
160 Bool_t AliMUONDetElement::Inside(Double_t x, Double_t y, Double_t z) const
161 {
162   // Check if point is inside detection element
163
164   Int_t ix, iy;
165   for (Int_t i = 0; i < 2; i++) {
166     if (!fSeg[i]) continue;
167     fSeg[i]->GetPadI(fidDE, x, y, z, ix, iy);
168     //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; 
169     if (ix > 0 && iy > 0 && ix <= fSeg[i]->Npx(fidDE) && iy <= fSeg[i]->Npy(fidDE)) return kTRUE;
170   }
171   // Check for edge effect (extrapolated track "right outside" det. elem. boundaries (+- 1cm in X and Y)
172   for (Int_t i = 0; i < 2; i++) {
173     if (!fSeg[i]) continue;
174     for (Int_t idx = -1; idx < 2; idx++) {
175       Double_t x1 = x + 1. * idx;
176       for (Int_t idy = -1; idy < 2; idy++) {
177         if (idx == 0 && idy == 0) continue;
178         Double_t y1 = y + 1. * idy;
179         fSeg[i]->GetPadI(fidDE, x1, y1, z, ix, iy);
180         //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; 
181         if (ix > 0 && iy > 0 && ix <= fSeg[i]->Npx(fidDE) && iy <= fSeg[i]->Npy(fidDE)) return kTRUE;
182       }
183     }
184   }
185   return kFALSE;
186 }
187
188 //_________________________________________________________________________
189 void AliMUONDetElement::ClusterReco(Double_t xTrack, Double_t yTrack)
190 {
191   // Run cluster reconstruction around point (x,y)
192
193   if (fLeft[0] == 0 && fLeft[1] == 0) return; // all digits have been used 
194   Float_t dx, dy;
195   dx = dy = 5; // 5 cm for now 
196   AliMUONClusterInput::Instance()->SetDigits(fChamber, fidDE, 
197              (TClonesArray*)fDigits[0], (TClonesArray*)fDigits[1]);
198
199   // Mark used pads
200   for (Int_t cath = 0; cath < 2; cath++) {
201     if (fDigits[cath]->GetEntriesFast() == 0) continue; // empty cathode
202     for (Int_t i = 0; i < fDigits[cath]->GetEntriesFast(); i++) {
203       if (fLeft[cath] == 0) { fRecModel->SetUsed(cath,i); continue; }
204       AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(i);
205       //cout << i << " " << dig->PadX() << " " << dig->PadY() << " " << fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) << endl;
206       if (fHitMap[cath]->TestHit(dig->PadX(), dig->PadY()) == kUsed) fRecModel->SetUsed(cath,i);
207       else fRecModel->SetUnused(cath,i);
208     }
209   }
210
211   fRecModel->ResetRawClusters();
212
213   for (Int_t cath = 0; cath < 2; cath++) {
214     if (fDigits[cath]->GetEntriesFast() == 0) continue; // empty cathode
215     // Loop over pads
216     for (fSeg[cath]->FirstPad(fidDE, xTrack, yTrack, fZ, dx, dy);
217          fSeg[cath]->MorePads(fidDE);
218          fSeg[cath]->NextPad(fidDE)) {
219       if (fLeft[cath] == 0) break;
220       //cout << cath << " " << fSeg[cath]->Ix() << " " << fSeg[cath]->Iy() << " " << fSeg[cath]->DetElemId() << " " << fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) << endl;
221       if (fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) == kEmpty ||
222           fHitMap[cath]->TestHit(fSeg[cath]->Ix(), fSeg[cath]->Iy()) == kUsed) continue;
223
224       // Set starting pad
225       for (Int_t j = 0; j < fDigits[cath]->GetEntriesFast(); j++) {
226         AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath]->UncheckedAt(j);
227         if (dig->PadX() != fSeg[cath]->Ix() || dig->PadY() != fSeg[cath]->Iy()) continue;
228         //cout << fidDE << " " << j << " " << fSeg[cath]->Ix() << " " << fSeg[cath]->Iy() << endl;
229         fRecModel->SetStart(cath, j);
230         break;
231       }
232
233       fRecModel->FindRawClusters();
234       Int_t nClusEnd = fRecModel->GetRawClusters()->GetEntriesFast();
235       //cout << " ***nclus: " << nClusEnd << endl;
236       for (Int_t i = 0; i < nClusEnd; i++) {
237         AliMUONRawCluster *clus = (AliMUONRawCluster*) fRecModel->GetRawClusters()->UncheckedAt(i);
238         AddHitForRec(clus); // add hit for rec.
239         //cout << clus->GetX(0) << " " << clus->GetY(0) << endl;
240       }
241       // Mark used pads
242       for (Int_t cath1 = 0; cath1 < 2; cath1++) {
243         for (Int_t j = 0; j < fDigits[cath1]->GetEntriesFast(); j++) {
244           if (fLeft[cath1] == 0) break;
245           AliMUONDigit *dig = (AliMUONDigit*) fDigits[cath1]->UncheckedAt(j);
246           Float_t x, y, z;
247           fSeg[cath1]->GetPadC(fidDE,dig->PadX(),dig->PadY(),x,y,z);
248           //cout << "clus " << cath1 << " " << fLeft[cath1] << " " << dig->PadX() << " " << dig->PadY() << " " << x << " " << y << " " << z << " " << fRecModel->GetUsed(cath1,j) << endl;
249           if (!fRecModel->GetUsed(cath1,j)) continue;
250           if (fHitMap[cath1]->TestHit(dig->PadX(), dig->PadY()) == kUsed) continue;
251           fHitMap[cath1]->FlagHit(dig->PadX(), dig->PadY());
252           if (lun) fprintf(lun," %d %d %d %d \n", cath1, fidDE, dig->PadX(), dig->PadY());
253           fLeft[cath1]--;
254         }
255       }
256     } // for (fSeg[cath]->FirstPad(...
257   } // for (Int_t cath = 0;
258 }
259
260 //_________________________________________________________________________
261 void AliMUONDetElement::AddHitForRec(AliMUONRawCluster *clus)
262 {
263   // Make HitForRec from raw cluster (rec. point)
264
265   fRawClus->Add(new AliMUONRawCluster(*clus));
266   AliMUONHitForRec *hitForRec = 
267     new ((*fHitsForRec)[fNHitsForRec++]) AliMUONHitForRec(clus);
268
269   // more information into HitForRec
270   //  resolution: info should be already in raw cluster and taken from it ????
271   hitForRec->SetBendingReso2(-1); //fBendingResolution * fBendingResolution);
272   hitForRec->SetNonBendingReso2(-1); //fNonBendingResolution * fNonBendingResolution);
273   //  original raw cluster
274   hitForRec->SetChamberNumber(fChamber);
275   hitForRec->SetZ(clus->GetZ(0));
276   //hitForRec->SetHitNumber(-(fIndex+1)*100000-fNHitsForRec+1);
277   hitForRec->SetHitNumber(-(fIndex+1)*100000-fRawClus->GetEntriesFast()+1);
278   //delete clus; // for now
279 }
280
281 /*
282 //_________________________________________________________________________
283 Int_t AliMUONDetElement::GetMapElem(AliMUONDigit *digit)
284 {
285   Int_t cath = digit->Cathode();
286   return 0;
287
288 }
289
290 //_________________________________________________________________________
291 void AliMUONDetElement::SetMapElem(const AliMUONDigit *digit, Int_t flag)
292 {
293   Int_t cath = digit->Cathode();
294 }
295 */