]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/TPCLib/Ref/AliHLTTPCClustFinderNew.cxx
Added a Makefile with rules for component libraries conforming to the
[u/mrichter/AliRoot.git] / HLT / TPCLib / Ref / AliHLTTPCClustFinderNew.cxx
CommitLineData
78001a73 1// @(#) $Id$
2
3// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>, Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
4//*-- Copyright &copy ALICE HLT Group
5
6#include "AliHLTTPCStandardIncludes.h"
7
8#include "AliHLTTPCLogging.h"
9#include "AliHLTTPCClustFinderNew.h"
10#include "AliHLTTPCDigitData.h"
11#include "AliHLTTPCTransform.h"
12#include "AliHLTTPCSpacePointData.h"
13#include "AliHLTTPCMemHandler.h"
14
15#if GCCVERSION == 3
16using namespace std;
17#endif
18
19/** \class AliHLTTPCClustFinderNew
20<pre>
21//_____________________________________________________________
22// AliHLTTPCClustFinderNew
23//
24// The current cluster finder for HLT
25// (Based on STAR L3)
26//
27// The cluster finder is initialized with the Init function,
28// providing the slice and patch information to work on.
29// The input is a AliHLTTPCDigitRowData structure using the
30// Read function. The resulting space points will be in the
31// array given by the SetOutputArray function.
32//
33// There are several setters which control the behaviour:
34//
35// - SetXYError(Float_t): set fixed error in XY direction
36// - SetZError(Float_t): set fixed error in Z direction
37// (used if errors are not calculated)
38// - SetDeconv(Bool_t): switch on/off deconvolution
39// - SetThreshold(UInt_t): set charge threshold for cluster
40// - SetMatchWidth(UInt_t): set the match distance in
41// time for sequences to be merged
42// - SetSTDOutput(Bool_t): switch on/off output about found clusters
43// - SetCalcErr(Bool_t): switch on/off calculation of
44// space point errors (or widths in raw system)
45// - SetRawSP(Bool_t): switch on/off convertion to raw system
46//
47//
48// Example Usage:
49//
50// AliHLTTPCFileHandler *file = new AliHLTTPCFileHandler();
51// file->SetAliInput(digitfile); //give some input file
52// for(int slice=0; slice<=35; slice++){
53// for(int patch=0; pat<6; pat++){
54// file->Init(slice,patch);
55// UInt_t ndigits=0;
56// UInt_t maxclusters=100000;
57// UInt_t pointsize = maxclusters*sizeof(AliHLTTPCSpacePointData);
58// AliHLTTPCSpacePointData *points = (AliHLTTPCSpacePointData*)memory->Allocate(pointsize);
59// AliHLTTPCDigitRowData *digits = (AliHLTTPCDigitRowData*)file->AliAltroDigits2Memory(ndigits,event);
60// AliHLTTPCClustFinderNew *cf = new AliHLTTPCClustFinderNew();
61// cf->SetMatchWidth(2);
62// cf->InitSlice(slice,patch,maxclusters);
63// cf->SetSTDOutput(kTRUE); //Some output to standard IO
64// cf->SetRawSP(kFALSE); //Convert space points to local system
65// cf->SetThreshold(5); //Threshold of cluster charge
66// cf->SetDeconv(kTRUE); //Deconv in pad and time direction
67// cf->SetCalcErr(kTRUE); //Calculate the errors of the spacepoints
68// cf->SetOutputArray(points); //Move the spacepoints to the array
69// cf->Read(ndigits,digits); //give the data to the cf
70// cf->ProcessDigits(); //process the rows given by init
71// Int_t npoints = cf->GetNumberOfClusters();
72// AliHLTTPCMemHandler *out= new AliHLTTPCMemHandler();
73// out->SetBinaryOutput(fname);
74// out->Memory2Binary(npoints,points); //store the spacepoints
75// out->CloseBinaryOutput();
76// delete out;
77// file->free();
78// delete cf;
79// }
80// }
81</pre>
82*/
83
84ClassImp(AliHLTTPCClustFinderNew)
85
86AliHLTTPCClustFinderNew::AliHLTTPCClustFinderNew()
87{
88 fMatch = 1;
89 fThreshold = 10;
90 fXYErr = 0.2;
91 fZErr = 0.3;
92 fDeconvPad = kTRUE;
93 fDeconvTime = kTRUE;
94 fStdout = kFALSE;
95 fCalcerr = kTRUE;
96 fRawSP = kFALSE;
97 fFirstRow=0;
98 fLastRow=0;
99}
100
101AliHLTTPCClustFinderNew::~AliHLTTPCClustFinderNew()
102{
103}
104
105void AliHLTTPCClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints)
106{
107 fNClusters = 0;
108 fMaxNClusters = nmaxpoints;
109 fCurrentSlice = slice;
110 fCurrentPatch = patch;
111 fFirstRow = firstrow;
112 fLastRow = lastrow;
113}
114
115void AliHLTTPCClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints)
116{
117 fNClusters = 0;
118 fMaxNClusters = nmaxpoints;
119 fCurrentSlice = slice;
120 fCurrentPatch = patch;
121 fFirstRow=AliHLTTPCTransform::GetFirstRow(patch);
122 fLastRow=AliHLTTPCTransform::GetLastRow(patch);
123}
124
125void AliHLTTPCClustFinderNew::SetOutputArray(AliHLTTPCSpacePointData *pt)
126{
127 fSpacePointData = pt;
128}
129
130void AliHLTTPCClustFinderNew::Read(UInt_t ndigits,AliHLTTPCDigitRowData *ptr)
131{
132 fNDigitRowData = ndigits;
133 fDigitRowData = ptr;
134}
135
136void AliHLTTPCClustFinderNew::ProcessDigits()
137{
138 //Loop over rows, and call processrow
139
140 AliHLTTPCDigitRowData *tempPt = (AliHLTTPCDigitRowData*)fDigitRowData;
141
142 for(Int_t i=fFirstRow; i<=fLastRow; i++)
143 {
144 fCurrentRow = i;
145 if((Int_t)tempPt->fRow!=fCurrentRow){
146 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCClustFinderNew::ProcessDigits","Digits")
147 <<"Row number should match! "<<tempPt->fRow<<" "<<fCurrentRow<<ENDLOG;
148 continue;
149 }
150#if 0
151 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCClustFinderNew::ProcessDigits","Digits")
152 << "Row " << AliHLTTPCLog::kDec << tempPt->fRow << " digits: "
153 << tempPt->fNDigit << " (Offset: " << ((unsigned long)tempPt) - ((unsigned long)fDigitRowData)
154 << ")." << ENDLOG;
155#endif
156 ProcessRow(tempPt);
157 Byte_t *tmp = (Byte_t*)tempPt;
158 Int_t size = sizeof(AliHLTTPCDigitRowData) + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
159 tmp += size;
160 tempPt = (AliHLTTPCDigitRowData*)tmp;
161 }
162 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCClustFinderNew::ProcessDigits","Space points")
163 <<"Cluster finder found "<<fNClusters<<" clusters in slice "<<fCurrentSlice
164 <<" patch "<<fCurrentPatch<<ENDLOG;
165}
166
167void AliHLTTPCClustFinderNew::ProcessRow(AliHLTTPCDigitRowData *tempPt)
168{
169
170 UInt_t last_pad = 123456789;
171
172 ClusterData *pad1[5000]; //2 lists for internal memory=2pads
173 ClusterData *pad2[5000]; //2 lists for internal memory=2pads
174 ClusterData clusterlist[10000]; //Clusterlist
175
176 ClusterData **currentPt; //List of pointers to the current pad
177 ClusterData **previousPt; //List of pointers to the previous pad
178 currentPt = pad2;
179 previousPt = pad1;
180 UInt_t n_previous=0,n_current=0,n_total=0;
181
182 //Loop over sequences of this row:
183 for(UInt_t bin=0; bin<tempPt->fNDigit; bin++)
184 {
185 AliHLTTPCDigitData *data = tempPt->fDigitData;
186#if 0
187 LOG( AliHLTTPCLog::kDebug, "AliHLTTPCClustFinderNew::ProcessRow", "Signal" )
188 << "Pad " << AliHLTTPCLog::kDec << data[bin].fPad
189 << " (" << bin << ")"
190 << " time " << data[bin].fTime << ": " << data[bin].fCharge
191 << " (Offset: " << ((unsigned long)(data+bin)) - ((unsigned long)fDigitRowData)
192 << ")." << ENDLOG;
193#ifdef do_mc
194 LOG( AliHLTTPCLog::kWarning, "AliHLTTPCClustFinderNew::ProcessRow", "Signal" )
195 << "Compiled with do_mc" << ENDLOG;
196#endif
197#endif
198 if(data[bin].fPad != last_pad)
199 {
200 //This is a new pad
201
202 //Switch the lists:
203 if(currentPt == pad2)
204 {
205 currentPt = pad1;
206 previousPt = pad2;
207 }
208 else
209 {
210 currentPt = pad2;
211 previousPt = pad1;
212 }
213 n_previous = n_current;
214 n_current = 0;
215 if(bin[data].fPad != last_pad+1)
216 {
217 //this happens if there is a pad with no signal.
218 n_previous = n_current = 0;
219 }
220 last_pad = data[bin].fPad;
221 }
222
223 Bool_t new_cluster = kTRUE;
224 UInt_t seq_charge=0,seq_average=0,seq_error=0;
225 UInt_t last_charge=0,last_was_falling=0;
226 Int_t new_bin=-1;
227
228 if(fDeconvTime)
229 {
230 redo: //This is a goto.
231 if(new_bin > -1)
232 {
233 bin = new_bin;
234 new_bin = -1;
235 }
236
237 last_charge=0;
238 last_was_falling = 0;
239 }
240
241 while(1) //Loop over current sequence
242 {
243 if(data[bin].fTime >= AliHLTTPCTransform::GetNTimeBins())
244 {
245 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClustFinderNew::ProcessRow","Digits")
246 <<"Timebin out of range "<<(Int_t)data[bin].fTime<<ENDLOG;
247 break;
248 }
249
250 //Get the current ADC-value
251 UInt_t charge = data[bin].fCharge;
252
253 if(fDeconvTime)
254 {
255 //Check if the last pixel in the sequence is smaller than this
256 if(charge > last_charge)
257 {
258 if(last_was_falling)
259 {
260 new_bin = bin;
261 break;
262 }
263 }
264 else last_was_falling = 1; //last pixel was larger than this
265 last_charge = charge;
266 }
267
268 //Sum the total charge of this sequence
269 seq_charge += charge;
270 seq_average += data[bin].fTime*charge;
271 seq_error += data[bin].fTime*data[bin].fTime*charge;
272
273 //Check where to stop:
274 if(bin >= tempPt->fNDigit - 1) //out of range
275 break;
276 if(data[bin+1].fPad != data[bin].fPad) //new pad
277 break;
278 if(data[bin+1].fTime != data[bin].fTime+1) //end of sequence
279 break;
280
281 bin++;
282 }//end loop over sequence
283
284 //Calculate mean of sequence:
285 Int_t seq_mean=0;
286 if(seq_charge)
287 seq_mean = seq_average/seq_charge;
288 else
289 {
290 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClustFinderNew::ProcessRow","Data")
291 <<"Error in data given to the cluster finder"<<ENDLOG;
292 seq_mean = 1;
293 seq_charge = 1;
294 }
295
296 //Calculate mean in pad direction:
297 Int_t pad_mean = seq_charge*data[bin].fPad;
298 Int_t pad_error = data[bin].fPad*pad_mean;
299
300 //Compare with results on previous pad:
301 for(UInt_t p=0; p<n_previous; p++)
302 {
303 //dont merge sequences on the same pad twice
304 if(previousPt[p]->fLastMergedPad==data[bin].fPad) continue;
305
306 Int_t difference = seq_mean - previousPt[p]->fMean;
307 if(difference < -fMatch) break;
308
309 if(difference <= fMatch) //There is a match here!!
310 {
311 ClusterData *local = previousPt[p];
312
313 if(fDeconvPad)
314 {
315 if(seq_charge > local->fLastCharge)
316 {
317 if(local->fChargeFalling) //The previous pad was falling
318 {
319 break; //create a new cluster
320 }
321 }
322 else
323 local->fChargeFalling = 1;
324 local->fLastCharge = seq_charge;
325 }
326
327 //Don't create a new cluster, because we found a match
328 new_cluster = kFALSE;
329
330 //Update cluster on current pad with the matching one:
331 local->fTotalCharge += seq_charge;
332 local->fPad += pad_mean;
333 local->fPad2 += pad_error;
334 local->fTime += seq_average;
335 local->fTime2 += seq_error;
336 local->fMean = seq_mean;
337 local->fFlags++; //means we have more than one pad
338 local->fLastMergedPad = data[bin].fPad;
339
340 currentPt[n_current] = local;
341 n_current++;
342
343 break;
344 } //Checking for match at previous pad
345 } //Loop over results on previous pad.
346
347 if(new_cluster)
348 {
349 //Start a new cluster. Add it to the clusterlist, and update
350 //the list of pointers to clusters in current pad.
351 //current pad will be previous pad on next pad.
352
353 //Add to the clusterlist:
354 ClusterData *tmp = &clusterlist[n_total];
355 tmp->fTotalCharge = seq_charge;
356 tmp->fPad = pad_mean;
357 tmp->fPad2 = pad_error;
358 tmp->fTime = seq_average;
359 tmp->fTime2 = seq_error;
360 tmp->fMean = seq_mean;
361 tmp->fFlags = 0; //flags for single pad clusters
362 tmp->fLastMergedPad = data[bin].fPad;
363
364 if(fDeconvPad)
365 {
366 tmp->fChargeFalling = 0;
367 tmp->fLastCharge = seq_charge;
368 }
369
370 //Update list of pointers to previous pad:
371 currentPt[n_current] = &clusterlist[n_total];
372 n_total++;
373 n_current++;
374 }
375
376 if(fDeconvTime)
377 if(new_bin >= 0) goto redo;
378 }//Loop over digits on this padrow
379
380 WriteClusters(n_total,clusterlist);
381}
382
383void AliHLTTPCClustFinderNew::WriteClusters(Int_t n_clusters,ClusterData *list)
384{
385 Int_t thisrow,thissector;
386 UInt_t counter = fNClusters;
387
388 for(int j=0; j<n_clusters; j++)
389 {
390 if(!list[j].fFlags) continue; //discard single pad clusters
391 if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
392
393 Float_t xyz[3];
394 Float_t fpad =(Float_t)list[j].fPad /(Float_t)list[j].fTotalCharge;
395 Float_t fpad2=fXYErr*fXYErr; //fixed given error
396 Float_t ftime =(Float_t)list[j].fTime /(Float_t)list[j].fTotalCharge;
397 Float_t ftime2=fZErr*fZErr; //fixed given error
398
399 if(fCalcerr) { //calc the errors, otherwice take the fixed error
400 Int_t patch = AliHLTTPCTransform::GetPatch(fCurrentRow);
401
402 Float_t sy2=(Float_t)list[j].fPad2/(Float_t)list[j].fTotalCharge - fpad*fpad;
403 if(sy2 < 0) {
404 LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinderNew::WriteClusters","Cluster width")
405 <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
406 continue;
407 } else {
408 if(!fRawSP){
409 fpad2 = (sy2 + 1./12)*AliHLTTPCTransform::GetPadPitchWidth(patch)*AliHLTTPCTransform::GetPadPitchWidth(patch);
410 if(sy2 != 0){
411 fpad2*=0.108; //constants are from offline studies
412 if(patch<2)
413 fpad2*=2.07;
414 }
415 } else fpad2=sy2; //take the width not the error
416 }
417 Float_t sz2=(Float_t)list[j].fTime2/(Float_t)list[j].fTotalCharge - ftime*ftime;
418 if(sz2 < 0){
419 LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinderNew::WriteClusters","Cluster width")
420 <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
421 continue;
422 } else {
423 if(!fRawSP){
424 ftime2 = (sz2 + 1./12)*AliHLTTPCTransform::GetZWidth()*AliHLTTPCTransform::GetZWidth();
425 if(sz2 != 0) {
426 ftime2 *= 0.169; //constants are from offline studies
427 if(patch<2)
428 ftime2 *= 1.77;
429 }
430 } else ftime2=sz2; //take the width, not the error
431 }
432 }
433 if(fStdout==kTRUE)
434 {
435#if 0
436 cout<<"WriteCluster: padrow "<<fCurrentRow<<" pad "<<fpad << " +- "<<fpad2<<" time "<<ftime<<" +- "<<ftime2<<" charge "<<list[j].fTotalCharge<<endl;
437#endif
438 }
439
440 if(!fRawSP){
441 AliHLTTPCTransform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
442 AliHLTTPCTransform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
443
444 if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
445 <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
446 if(fNClusters >= fMaxNClusters)
447 {
448 LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
449 <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
450 return;
451 }
452
453 fSpacePointData[counter].fX = xyz[0];
454 fSpacePointData[counter].fY = xyz[1];
455 fSpacePointData[counter].fZ = xyz[2];
456
457 } else {
458 fSpacePointData[counter].fX = fCurrentRow;
459 fSpacePointData[counter].fY = fpad;
460 fSpacePointData[counter].fZ = ftime;
461 }
462
463 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
464 fSpacePointData[counter].fPadRow = fCurrentRow;
465 fSpacePointData[counter].fSigmaY2 = fpad2;
466 fSpacePointData[counter].fSigmaZ2 = ftime2;
467
468 Int_t patch=fCurrentPatch;
469 if(patch==-1) patch=0; //never store negative patch number
470 fSpacePointData[counter].fID = counter
471 +((fCurrentSlice&0x7f)<<25)+((patch&0x7)<<22);//Uli
472#ifdef do_mc
473 Int_t trackID[3];
474 GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
475
476 fSpacePointData[counter].fTrackID[0] = trackID[0];
477 fSpacePointData[counter].fTrackID[1] = trackID[1];
478 fSpacePointData[counter].fTrackID[2] = trackID[2];
479
480 //cout<<"padrow "<<fCurrentRow<<" pad "<<(Int_t)rint(fpad)<<" time "<<(Int_t)rint(ftime)<<" Trackid "<<trackID[0]<<endl;
481#endif
482
483 fNClusters++;
484 counter++;
485 }
486}
487
488#ifdef do_mc
489void AliHLTTPCClustFinderNew::GetTrackID(Int_t pad,Int_t time,Int_t *trackID)
490{
491 AliHLTTPCDigitRowData *rowPt = (AliHLTTPCDigitRowData*)fDigitRowData;
492
493 trackID[0]=trackID[1]=trackID[2]=-2;
494 //cout<<"Looking for pad "<<pad<<" time "<<time<<endl;
495 for(Int_t i=fFirstRow; i<=fLastRow; i++){
496 if(rowPt->fRow < (UInt_t)fCurrentRow){
497 AliHLTTPCMemHandler::UpdateRowPointer(rowPt);
498 continue;
499 }
500 AliHLTTPCDigitData *digPt = (AliHLTTPCDigitData*)rowPt->fDigitData;
501 for(UInt_t j=0; j<rowPt->fNDigit; j++){
502 Int_t cpad = digPt[j].fPad;
503 Int_t ctime = digPt[j].fTime;
504 if(cpad != pad) continue;
505 if(ctime != time) continue;
506
507 trackID[0] = digPt[j].fTrackID[0];
508 trackID[1] = digPt[j].fTrackID[1];
509 trackID[2] = digPt[j].fTrackID[2];
510
511 //cout<<"Reading row "<<fCurrentRow<<" pad "<<cpad<<" time "<<ctime<<" trackID "<<digPt[j].fTrackID[0]<<endl;
512 break;
513 }
514 break;
515 }
516}
517#endif