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