]>
Commit | Line | Data |
---|---|---|
46fbeb8a | 1 | //Author: Anders Strand Vestbo |
2 | //Last Modified: 17.08.2001 | |
3 | ||
4 | #include <iostream.h> | |
5 | #include "AliL3Logging.h" | |
6 | #include "AliL3ClustFinderNew.h" | |
7 | #include "AliL3DigitData.h" | |
8 | #include "AliL3Transform.h" | |
9 | #include "AliL3SpacePointData.h" | |
10 | ||
11 | ClassImp(AliL3ClustFinderNew) | |
12 | ||
13 | AliL3ClustFinderNew::AliL3ClustFinderNew() | |
14 | { | |
15 | fMatch = 4; | |
16 | fThreshold =10; | |
99a6d5c9 | 17 | fDeconvPad = kTRUE; |
2bbf57d8 | 18 | fDeconvTime = kTRUE; |
46fbeb8a | 19 | } |
20 | ||
21 | AliL3ClustFinderNew::AliL3ClustFinderNew(AliL3Transform *transform) | |
22 | { | |
23 | fTransform = transform; | |
24 | fMatch = 4; | |
25 | fThreshold =10; | |
99a6d5c9 | 26 | fDeconvTime = kTRUE; |
27 | fDeconvPad = kTRUE; | |
46fbeb8a | 28 | } |
29 | ||
30 | AliL3ClustFinderNew::~AliL3ClustFinderNew() | |
31 | { | |
32 | ||
33 | ||
34 | } | |
35 | ||
36 | void AliL3ClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints) | |
37 | { | |
38 | fNClusters = 0; | |
39 | fMaxNClusters = nmaxpoints; | |
40 | fCurrentSlice = slice; | |
41 | fCurrentPatch = patch; | |
42 | fFirstRow = firstrow; | |
43 | fLastRow = lastrow; | |
99a6d5c9 | 44 | fDeconvTime = kTRUE; |
45 | fDeconvPad = kTRUE; | |
46fbeb8a | 46 | } |
47 | ||
48 | void AliL3ClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints) | |
49 | { | |
50 | fNClusters = 0; | |
51 | fMaxNClusters = nmaxpoints; | |
52 | fCurrentSlice = slice; | |
53 | fCurrentPatch = patch; | |
54 | } | |
55 | ||
56 | void AliL3ClustFinderNew::SetOutputArray(AliL3SpacePointData *pt) | |
57 | { | |
58 | ||
59 | fSpacePointData = pt; | |
60 | } | |
61 | ||
62 | ||
63 | void AliL3ClustFinderNew::Read(UInt_t ndigits,AliL3DigitRowData *ptr) | |
64 | { | |
65 | fNDigitRowData = ndigits; | |
66 | fDigitRowData = ptr; | |
67 | ||
68 | } | |
69 | ||
70 | void AliL3ClustFinderNew::ProcessDigits() | |
71 | { | |
72 | //Loop over rows, and call processrow | |
73 | ||
74 | ||
75 | AliL3DigitRowData *tempPt = (AliL3DigitRowData*)fDigitRowData; | |
76 | ||
77 | for(Int_t i=fFirstRow; i<=fLastRow; i++) | |
78 | { | |
79 | fCurrentRow = i; | |
80 | ProcessRow(tempPt); | |
81 | Byte_t *tmp = (Byte_t*)tempPt; | |
82 | Int_t size = sizeof(AliL3DigitRowData) + tempPt->fNDigit*sizeof(AliL3DigitData); | |
83 | tmp += size; | |
84 | tempPt = (AliL3DigitRowData*)tmp; | |
85 | } | |
86 | } | |
87 | ||
88 | ||
89 | ||
90 | void AliL3ClustFinderNew::ProcessRow(AliL3DigitRowData *tempPt) | |
91 | { | |
92 | ||
93 | UInt_t last_pad = 123456789; | |
94 | ||
95 | ClusterData *pad1[2500]; //2 lists for internal memory=2pads | |
96 | ClusterData *pad2[2500]; //2 lists for internal memory=2pads | |
97 | ClusterData clusterlist[5000]; //Clusterlist | |
98 | ||
99 | ClusterData **currentPt; //List of pointers to the current pad | |
100 | ClusterData **previousPt; //List of pointers to the previous pad | |
101 | currentPt = pad2; | |
102 | previousPt = pad1; | |
103 | UInt_t n_previous=0,n_current=0,n_total=0; | |
104 | ||
105 | //Loop over sequences of this row: | |
106 | for(UInt_t bin=0; bin<tempPt->fNDigit; bin++) | |
107 | { | |
108 | ||
109 | AliL3DigitData *data = tempPt->fDigitData; | |
110 | if(data[bin].fPad != last_pad) | |
111 | { | |
112 | //This is a new pad | |
46fbeb8a | 113 | |
114 | //Switch: | |
115 | if(currentPt == pad2) | |
116 | { | |
117 | currentPt = pad1; | |
118 | previousPt = pad2; | |
119 | ||
120 | } | |
121 | else | |
122 | { | |
123 | currentPt = pad2; | |
124 | previousPt = pad1; | |
125 | } | |
126 | n_previous = n_current; | |
127 | n_current = 0; | |
99a6d5c9 | 128 | if(bin[data].fPad != last_pad+1) |
129 | { | |
130 | //this happens if there is a pad with no signal. | |
131 | n_previous = n_current = 0; | |
132 | } | |
133 | last_pad = data[bin].fPad; | |
46fbeb8a | 134 | } |
135 | ||
136 | Bool_t new_cluster = kTRUE; | |
137 | ||
138 | UInt_t seq_charge=0,seq_average=0; | |
139 | ||
99a6d5c9 | 140 | UInt_t last_charge=0,last_was_falling=0; |
141 | Int_t new_bin=-1; | |
142 | if(fDeconvTime) | |
143 | { | |
144 | redo: //This is a goto. | |
145 | if(new_bin > -1) | |
146 | { | |
147 | bin = new_bin; | |
148 | new_bin = -1; | |
149 | } | |
150 | ||
151 | last_charge=0; | |
152 | last_was_falling = 0; | |
153 | } | |
154 | ||
155 | ||
46fbeb8a | 156 | while(1) //Loop over current sequence |
157 | { | |
158 | //Get the current ADC-value | |
159 | UInt_t charge = data[bin].fCharge; | |
99a6d5c9 | 160 | |
161 | if(fDeconvTime) | |
162 | { | |
163 | //Check if the last pixel in the sequence is smaller than this | |
164 | if(charge > last_charge) | |
165 | { | |
166 | if(last_was_falling) | |
167 | { | |
168 | new_bin = bin; | |
169 | break; | |
170 | } | |
171 | } | |
172 | else last_was_falling = 1; //last pixel was larger than this | |
173 | last_charge = charge; | |
174 | } | |
175 | ||
46fbeb8a | 176 | //Sum the total charge of this sequence |
177 | seq_charge += charge; | |
46fbeb8a | 178 | seq_average += data[bin].fTime*charge; |
179 | ||
180 | //Check where to stop: | |
181 | if(data[bin+1].fPad != data[bin].fPad) //new pad | |
182 | break; | |
183 | if(data[bin+1].fTime != data[bin].fTime+1) //end of sequence | |
184 | break; | |
185 | ||
186 | bin++; | |
187 | }//end loop over sequence | |
188 | ||
189 | //Calculate mean of sequence: | |
190 | Int_t seq_mean=0; | |
191 | if(seq_charge) | |
192 | seq_mean = seq_average/seq_charge; | |
193 | else | |
99a6d5c9 | 194 | { |
195 | printf("\nCF: Should not happen\n"); | |
196 | seq_mean = 1; | |
197 | seq_charge = 1; | |
198 | } | |
46fbeb8a | 199 | |
200 | //Calculate mean in pad direction: | |
201 | Int_t pad_mean = seq_charge*data[bin].fPad; | |
202 | ||
203 | //Compare with results on previous pad: | |
204 | for(UInt_t p=0; p<n_previous; p++) | |
205 | { | |
206 | Int_t difference = seq_mean - previousPt[p]->fMean; | |
207 | if(difference < -fMatch) | |
208 | break; | |
209 | ||
210 | if(difference <= fMatch)//There is a match here!! | |
211 | { | |
99a6d5c9 | 212 | |
213 | ClusterData *local = previousPt[p]; | |
214 | if(fDeconvPad) | |
215 | { | |
216 | if(seq_charge > local->fLastCharge) | |
217 | { | |
218 | if(local->fChargeFalling)//The previous pad was falling | |
219 | { | |
220 | break;//create a new cluster | |
221 | } | |
222 | } | |
223 | else | |
224 | local->fChargeFalling = 1; | |
225 | local->fLastCharge = seq_charge; | |
226 | } | |
227 | ||
46fbeb8a | 228 | //Don't create a new cluster, because we found a match |
229 | new_cluster = kFALSE; | |
230 | ||
231 | //Update cluster on current pad with the matching one: | |
99a6d5c9 | 232 | //currentPt[n_current] = previousPt[p]; |
233 | ||
234 | local->fTotalCharge += seq_charge; | |
235 | local->fPad += pad_mean; | |
236 | local->fTime += seq_average; | |
237 | local->fMean = seq_mean; | |
238 | local->fFlags++; //means we have more than one pad | |
239 | ||
240 | currentPt[n_current] = local; | |
46fbeb8a | 241 | n_current++; |
242 | ||
46fbeb8a | 243 | break; |
244 | }//Checking for match at previous pad | |
245 | }//Loop over results on previous pad. | |
246 | ||
247 | if(new_cluster) | |
248 | { | |
249 | //Start a new cluster. Add it to the clusterlist, and update | |
250 | //the list of pointers to clusters in current pad. | |
99a6d5c9 | 251 | //current pad will be previous pad on next pad. |
46fbeb8a | 252 | |
253 | //Add to the clusterlist: | |
254 | ClusterData *tmp = &clusterlist[n_total]; | |
255 | tmp->fTotalCharge = seq_charge; | |
256 | tmp->fPad = pad_mean; | |
257 | tmp->fTime = seq_average; | |
258 | tmp->fMean = seq_mean; | |
259 | tmp->fFlags = 0; //flags for 1 pad clusters | |
99a6d5c9 | 260 | if(fDeconvPad) |
261 | { | |
262 | tmp->fChargeFalling = 0; | |
263 | tmp->fLastCharge = seq_charge; | |
264 | } | |
265 | ||
46fbeb8a | 266 | //Update list of pointers to previous pad: |
267 | currentPt[n_current] = &clusterlist[n_total]; | |
268 | n_total++; | |
269 | n_current++; | |
270 | } | |
99a6d5c9 | 271 | if(fDeconvTime) |
272 | if(new_bin >= 0) goto redo; | |
273 | ||
46fbeb8a | 274 | }//Loop over digits on this padrow |
275 | ||
276 | WriteClusters(n_total,clusterlist); | |
277 | ||
278 | ||
279 | } | |
280 | ||
281 | void AliL3ClustFinderNew::WriteClusters(Int_t n_clusters,ClusterData *list) | |
282 | { | |
283 | Int_t thisrow,thissector; | |
284 | UInt_t counter = fNClusters; | |
285 | ||
286 | for(int j=0; j<n_clusters; j++) | |
287 | { | |
288 | if(!list[j].fFlags) continue; //discard 1 pad clusters | |
289 | if(list[j].fTotalCharge < fThreshold) continue; //noise cluster | |
290 | Float_t xyz[3]; | |
291 | ||
292 | Float_t fpad=(Float_t)list[j].fPad/(Float_t)list[j].fTotalCharge; | |
293 | Float_t ftime=(Float_t)list[j].fTime/(Float_t)list[j].fTotalCharge; | |
294 | //printf("padrow %d number of pads %d totalcharge %d\n",fCurrentRow,list[j].fFlags,list[j].fTotalCharge); | |
295 | fTransform->Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow); | |
296 | fTransform->Raw2Local(xyz,thissector,thisrow,fpad,ftime); | |
297 | if(xyz[0]==0) LOG(AliL3Log::kError,"AliL3ClustFinder","Cluster Finder") | |
298 | <<AliL3Log::kDec<<"Zero cluster"<<ENDLOG; | |
299 | if(fNClusters >= fMaxNClusters) | |
300 | { | |
301 | LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Finder") | |
302 | <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG; | |
303 | return; | |
304 | } | |
305 | fSpacePointData[counter].fX = xyz[0]; | |
306 | fSpacePointData[counter].fY = xyz[1]; | |
307 | fSpacePointData[counter].fZ = xyz[2]; | |
308 | fSpacePointData[counter].fPadRow = fCurrentRow; | |
309 | fSpacePointData[counter].fXYErr = fXYErr; | |
310 | fSpacePointData[counter].fZErr = fZErr; | |
311 | fSpacePointData[counter].fID = counter | |
312 | +((fCurrentSlice&0x7f)<<25)+((fCurrentPatch&0x7)<<22);//uli | |
313 | ||
46fbeb8a | 314 | fNClusters++; |
315 | counter++; | |
316 | ||
317 | } | |
318 | ||
319 | } |