]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/TPCLib/AliHLTTPCClusterFinder.cxx
Coding rule violations
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCClusterFinder.cxx
CommitLineData
a38a7850 1// @(#) $Id$
4aa41877 2// Original: AliHLTClustFinderNew.cxx,v 1.29 2005/06/14 10:55:21 cvetan Exp
a38a7850 3
600e6a1b 4/**************************************************************************
9be2600f 5 * This file is property of and copyright by the ALICE HLT Project *
6 * ALICE Experiment at CERN, All rights reserved. *
600e6a1b 7 * *
01f43166 8 * Primary Authors: Anders Vestbo, Constantin Loizides, Jochen Thaeder *
9 * Kenneth Aamodt <kenneth.aamodt@student.uib.no> *
10 * for The ALICE HLT Project. *
600e6a1b 11 * *
12 * Permission to use, copy, modify and distribute this software and its *
13 * documentation strictly for non-commercial purposes is hereby granted *
14 * without fee, provided that the above copyright notice appears in all *
15 * copies and that both the copyright notice and this permission notice *
16 * appear in the supporting documentation. The authors make no claims *
17 * about the suitability of this software for any purpose. It is *
18 * provided "as is" without express or implied warranty. *
19 **************************************************************************/
a38a7850 20
600e6a1b 21/** @file AliHLTTPCClusterFinder.cxx
01f43166 22 @author Anders Vestbo, Constantin Loizides, Jochen Thaeder
23 Kenneth Aamodt kenneth.aamodt@student.uib.no
600e6a1b 24 @date
25 @brief Cluster Finder for the TPC
26*/
a38a7850 27
28#include "AliHLTTPCDigitReader.h"
a38a7850 29#include "AliHLTTPCRootTypes.h"
30#include "AliHLTTPCLogging.h"
31#include "AliHLTTPCClusterFinder.h"
32#include "AliHLTTPCDigitData.h"
33#include "AliHLTTPCTransform.h"
34#include "AliHLTTPCSpacePointData.h"
35#include "AliHLTTPCMemHandler.h"
46b33a24 36#include "AliHLTTPCPad.h"
01f43166 37#include "AliHLTTPCPadArray.h"
a38a7850 38
39#if __GNUC__ >= 3
40using namespace std;
41#endif
42
43/** \class AliHLTTPCClusterFinder
a38a7850 44//
45// The current cluster finder for HLT
46// (Based on STAR L3)
01f43166 47//
48//Basically we have two versions for the cluster finder now.
49//The default version, reads the data pad by pad, and find the
50//clusters as it reads the data. The other version has now been
51//developed to cope with unsorted data. New methods for the unsorted
52//version can be found at the end of the default one i the source file.
53//Currently the new version is only build to manage zero-suppressed data.
54//More functionality will be added later.
55//
a38a7850 56// The cluster finder is initialized with the Init function,
57// providing the slice and patch information to work on.
58//
59// The input is a provided by the AliHLTTPCDigitReader class,
60// using the init() funktion, and the next() funktion in order
61// to get the next bin. Either packed or unpacked data can be
62// processed, dependent if one uses AliHLTTPCDigitReaderPacked
63// class or AliHLTTPCDigitReaderUnpacked class in the
64// Clusterfinder Component.
65// The resulting space points will be in the
66// array given by the SetOutputArray function.
67//
68// There are several setters which control the behaviour:
69//
70// - SetXYError(Float_t): set fixed error in XY direction
71// - SetZError(Float_t): set fixed error in Z direction
72// (used if errors are not calculated)
73// - SetDeconv(Bool_t): switch on/off deconvolution
74// - SetThreshold(UInt_t): set charge threshold for cluster
75// - SetMatchWidth(UInt_t): set the match distance in
76// time for sequences to be merged
77// - SetSTDOutput(Bool_t): switch on/off output about found clusters
78// - SetCalcErr(Bool_t): switch on/off calculation of
79// space point errors (or widths in raw system)
80// - SetRawSP(Bool_t): switch on/off convertion to raw system
81//
82//
83// Example Usage:
84//
85// AliHLTTPCFileHandler *file = new AliHLTTPCFileHandler();
86// file->SetAliInput(digitfile); //give some input file
87// for(int slice=0; slice<=35; slice++){
88// for(int patch=0; pat<6; pat++){
89// file->Init(slice,patch);
90// UInt_t ndigits=0;
91// UInt_t maxclusters=100000;
92// UInt_t pointsize = maxclusters*sizeof(AliHLTTPCSpacePointData);
93// AliHLTTPCSpacePointData *points = (AliHLTTPCSpacePointData*)memory->Allocate(pointsize);
94// AliHLTTPCDigitRowData *digits = (AliHLTTPCDigitRowData*)file->AliAltroDigits2Memory(ndigits,event);
95// AliHLTTPCClusterFinder *cf = new AliHLTTPCClusterFinder();
96// cf->SetMatchWidth(2);
97// cf->InitSlice( slice, patch, row[0], row[1], maxPoints );
98// cf->SetSTDOutput(kTRUE); //Some output to standard IO
99// cf->SetRawSP(kFALSE); //Convert space points to local system
100// cf->SetThreshold(5); //Threshold of cluster charge
101// cf->SetDeconv(kTRUE); //Deconv in pad and time direction
102// cf->SetCalcErr(kTRUE); //Calculate the errors of the spacepoints
103// cf->SetOutputArray(points); //Move the spacepoints to the array
104// cf->Read(iter->fPtr, iter->fSize ); //give the data to the cf
105// cf->ProcessDigits(); //process the rows given by init
106// Int_t npoints = cf->GetNumberOfClusters();
107// AliHLTTPCMemHandler *out= new AliHLTTPCMemHandler();
108// out->SetBinaryOutput(fname);
109// out->Memory2Binary(npoints,points); //store the spacepoints
110// out->CloseBinaryOutput();
111// delete out;
112// file->free();
113// delete cf;
114// }
115// }
a38a7850 116*/
117
118ClassImp(AliHLTTPCClusterFinder)
119
120AliHLTTPCClusterFinder::AliHLTTPCClusterFinder()
46b33a24 121 :
2a083ac4 122 fSpacePointData(NULL),
123 fDigitReader(NULL),
124 fPtr(NULL),
125 fSize(0),
46b33a24 126 fDeconvTime(kTRUE),
2a083ac4 127 fDeconvPad(kTRUE),
46b33a24 128 fStdout(kFALSE),
129 fCalcerr(kTRUE),
130 fRawSP(kFALSE),
131 fFirstRow(0),
132 fLastRow(0),
2a083ac4 133 fCurrentRow(0),
134 fCurrentSlice(0),
135 fCurrentPatch(0),
136 fMatch(1),
137 fThreshold(10),
138 fSignalThreshold(-1),
139 fNClusters(0),
140 fMaxNClusters(0),
141 fXYErr(0.2),
142 fZErr(0.3),
01f43166 143 fOccupancyLimit(1.0),
144 fPadArray(NULL)
a38a7850 145{
146 //constructor
46b33a24 147}
a38a7850 148
a38a7850 149AliHLTTPCClusterFinder::~AliHLTTPCClusterFinder()
150{
151 //destructor
152}
153
154void AliHLTTPCClusterFinder::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints)
155{
156 //init slice
157 fNClusters = 0;
158 fMaxNClusters = nmaxpoints;
159 fCurrentSlice = slice;
160 fCurrentPatch = patch;
161 fFirstRow = firstrow;
162 fLastRow = lastrow;
163}
164
165void AliHLTTPCClusterFinder::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints)
166{
167 //init slice
168 fNClusters = 0;
169 fMaxNClusters = nmaxpoints;
170 fCurrentSlice = slice;
171 fCurrentPatch = patch;
172 fFirstRow=AliHLTTPCTransform::GetFirstRow(patch);
173 fLastRow=AliHLTTPCTransform::GetLastRow(patch);
174}
175
176void AliHLTTPCClusterFinder::SetOutputArray(AliHLTTPCSpacePointData *pt)
177{
178 //set pointer to output
179 fSpacePointData = pt;
180}
181
182void AliHLTTPCClusterFinder::Read(void* ptr,unsigned long size){
183 //set input pointer
184 fPtr = (UChar_t*)ptr;
185 fSize = size;
186}
187
188void AliHLTTPCClusterFinder::ProcessDigits()
189{
6b0fdc0e 190 int iResult=0;
a38a7850 191 bool readValue = true;
192 Int_t newRow = 0;
193 Int_t rowOffset = 0;
46b33a24 194 UShort_t time=0,newTime=0;
195 UInt_t pad=0,newPad=0;
196 AliHLTTPCSignal_t charge=0;
a38a7850 197
198 fNClusters = 0;
199
200 // initialize block for reading packed data
db16520a 201 fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice);
a38a7850 202 readValue = fDigitReader->Next();
203
5235c3e9 204 // Matthias 08.11.2006 the following return would cause termination without writing the
6c1a9d9e 205 // ClusterData and thus would block the component. I just want to have the commented line
5235c3e9 206 // here for information
207 //if (!readValue)return;
db16520a 208
a38a7850 209 pad = fDigitReader->GetPad();
210 time = fDigitReader->GetTime();
211 fCurrentRow = fDigitReader->GetRow();
212
213 if ( fCurrentPatch >= 2 ) // Outer sector, patches 2, 3, 4, 5
214 rowOffset = AliHLTTPCTransform::GetFirstRow( 2 );
215
216 fCurrentRow += rowOffset;
217
218 UInt_t lastpad = 123456789;
2a083ac4 219 const UInt_t kPadArraySize=5000;
220 const UInt_t kClusterListSize=10000;
84645eb0 221 AliClusterData *pad1[kPadArraySize]; //2 lists for internal memory=2pads
222 AliClusterData *pad2[kPadArraySize]; //2 lists for internal memory=2pads
223 AliClusterData clusterlist[kClusterListSize]; //Clusterlist
a38a7850 224
225 AliClusterData **currentPt; //List of pointers to the current pad
226 AliClusterData **previousPt; //List of pointers to the previous pad
227 currentPt = pad2;
228 previousPt = pad1;
229 UInt_t nprevious=0,ncurrent=0,ntotal=0;
230
46b33a24 231 /* quick implementation of baseline calculation and zero suppression
232 open a pad object for each pad and delete it after processing.
233 later a list of pad objects with base line history can be used
234 The whole thing only works if we really get unprocessed raw data, if
235 the data is already zero suppressed, there might be gaps in the time
236 bins.
237 */
238 Int_t gatingGridOffset=50;
239 AliHLTTPCPad baseline(gatingGridOffset, AliHLTTPCTransform::GetNTimeBins());
240 // just to make later conversion to a list of objects easier
84645eb0 241 AliHLTTPCPad* pCurrentPad=NULL;
242 if (fSignalThreshold>=0) {
243 pCurrentPad=&baseline;
244 baseline.SetThreshold(fSignalThreshold);
245 }
46b33a24 246
6b0fdc0e 247 while ( readValue!=0 && iResult>=0){ // Reads through all digits in block
248 iResult=0;
a38a7850 249
250 if(pad != lastpad){
251 //This is a new pad
252
253 //Switch the lists:
254 if(currentPt == pad2){
255 currentPt = pad1;
256 previousPt = pad2;
257 }
258 else {
259 currentPt = pad2;
260 previousPt = pad1;
261 }
262 nprevious = ncurrent;
263 ncurrent = 0;
264 if(pad != lastpad+1){
265 //this happens if there is a pad with no signal.
266 nprevious = ncurrent = 0;
267 }
268 lastpad = pad;
269 }
270
271 Bool_t newcluster = kTRUE;
272 UInt_t seqcharge=0,seqaverage=0,seqerror=0;
2a083ac4 273 AliHLTTPCSignal_t lastcharge=0;
274 UInt_t bLastWasFalling=0;
a38a7850 275 Int_t newbin=-1;
276
277
278 if(fDeconvTime){
279 redo: //This is a goto.
280
281 if(newbin > -1){
282 //bin = newbin;
283 newbin = -1;
284 }
285
286 lastcharge=0;
2a083ac4 287 bLastWasFalling = 0;
a38a7850 288 }
289
6b0fdc0e 290 while(iResult>=0){ //Loop over time bins of current pad
46b33a24 291 // read all the values for one pad at once to calculate the base line
292 if (pCurrentPad) {
293 if (!pCurrentPad->IsStarted()) {
294 //HLTDebug("reading data for pad %d, padrow %d", fDigitReader->GetPad(), fDigitReader->GetRow()+rowOffset);
295 pCurrentPad->SetID(fDigitReader->GetRow()+rowOffset,fDigitReader->GetPad());
296 if ((pCurrentPad->StartEvent())>=0) {
297 do {
298 if ((fDigitReader->GetRow()+rowOffset)!=pCurrentPad->GetRowNumber()) break;
299 if (fDigitReader->GetPad()!=pCurrentPad->GetPadNumber()) break;
300 pCurrentPad->SetRawData(fDigitReader->GetTime(), fDigitReader->GetSignal());
301 //HLTDebug("set raw data to pad: bin %d charge %d", fDigitReader->GetTime(), fDigitReader->GetSignal());
302 } while ((readValue = fDigitReader->Next())!=0);
303 }
304 pCurrentPad->CalculateBaseLine(AliHLTTPCTransform::GetNTimeBins()/2);
305 if (pCurrentPad->Next(kTRUE/*do zero suppression*/)==0) {
84645eb0 306 //HLTDebug("no data available after zero suppression");
46b33a24 307 pCurrentPad->StopEvent();
308 pCurrentPad->ResetHistory();
309 break;
310 }
311 time=pCurrentPad->GetCurrentPosition();
312 if (time>pCurrentPad->GetSize()) {
313 HLTError("invalid time bin for pad");
314 break;
315 }
316 }
317 }
a38a7850 318
46b33a24 319 if (pCurrentPad) {
5235c3e9 320 Float_t occupancy=pCurrentPad->GetOccupancy();
321 //HLTDebug("pad %d occupancy level: %f", pCurrentPad->GetPadNumber(), occupancy);
322 if ( occupancy < fOccupancyLimit ) {
323 charge = pCurrentPad->GetCorrectedData();
324 } else {
325 charge = 0;
326 //HLTDebug("ignoring pad %d with occupancy level %f", pCurrentPad->GetPadNumber(), occupancy);
327 }
46b33a24 328 } else {
5235c3e9 329 charge = fDigitReader->GetSignal();
46b33a24 330 }
331 //HLTDebug("get next charge value: position %d charge %d", time, charge);
a38a7850 332
738c049f 333
334 // CHARGE DEBUG
335 if (fDigitReader->GetRow() == 90){
336///// LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::Row","row90") << "PAD=" << fDigitReader->GetPad() << " TIME=" << fDigitReader->GetTime()
337 // << " SIGNAL=" << fDigitReader->GetSignal() << ENDLOG;
338
339 }
340
a38a7850 341 if(time >= AliHLTTPCTransform::GetNTimeBins()){
6b0fdc0e 342 HLTWarning("Pad %d: Timebin (%d) out of range (%d)", pad, time, AliHLTTPCTransform::GetNTimeBins());
343 iResult=-ERANGE;
a38a7850 344 }
46b33a24 345
346
a38a7850 347 //Get the current ADC-value
348 if(fDeconvTime){
349
350 //Check if the last pixel in the sequence is smaller than this
351 if(charge > lastcharge){
2a083ac4 352 if(bLastWasFalling){
a38a7850 353 newbin = 1;
354 break;
355 }
356 }
2a083ac4 357 else bLastWasFalling = 1; //last pixel was larger than this
a38a7850 358 lastcharge = charge;
359 }
360
361 //Sum the total charge of this sequence
362 seqcharge += charge;
363 seqaverage += time*charge;
364 seqerror += time*time*charge;
365
46b33a24 366 if (pCurrentPad) {
367
368 if((pCurrentPad->Next(kTRUE/*do zero suppression*/))==0) {
369 pCurrentPad->StopEvent();
370 pCurrentPad->ResetHistory();
371 if(readValue) {
372 newPad = fDigitReader->GetPad();
373 newTime = fDigitReader->GetTime();
374 newRow = fDigitReader->GetRow() + rowOffset;
375 }
376 break;
377 }
378
379 newPad=pCurrentPad->GetPadNumber();
380 newTime=pCurrentPad->GetCurrentPosition();
381 newRow=pCurrentPad->GetRowNumber();
382 } else {
a38a7850 383 readValue = fDigitReader->Next();
a38a7850 384 //Check where to stop:
385 if(!readValue) break; //No more value
386
387 newPad = fDigitReader->GetPad();
388 newTime = fDigitReader->GetTime();
389 newRow = fDigitReader->GetRow() + rowOffset;
46b33a24 390 }
a38a7850 391
392 if(newPad != pad)break; //new pad
393 if(newTime != time+1) break; //end of sequence
6b0fdc0e 394 if(iResult<0) break;
a38a7850 395
396 // pad = newpad; is equal
397 time = newTime;
398
399 }//end loop over sequence
400
46b33a24 401 //HLTDebug("ended time bin sequence loop: seqcharge=%d readValue=%d", seqcharge, readValue);
402 //HLTDebug("pad=%d newpad=%d current row=%d newrow=%d", pad, newPad, fCurrentRow, newRow);
403 if (seqcharge<=0) {
404 // with active zero suppression zero values are possible
405 continue;
406 }
a38a7850 407
408 //Calculate mean of sequence:
409 Int_t seqmean=0;
410 if(seqcharge)
411 seqmean = seqaverage/seqcharge;
412 else{
413 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::ProcessRow","Data")
414 <<"Error in data given to the cluster finder"<<ENDLOG;
415 seqmean = 1;
416 seqcharge = 1;
417 }
418
419 //Calculate mean in pad direction:
420 Int_t padmean = seqcharge*pad;
421 Int_t paderror = pad*padmean;
422
a38a7850 423 //Compare with results on previous pad:
84645eb0 424 for(UInt_t p=0; p<nprevious && p<kPadArraySize && ncurrent<kPadArraySize; p++){
a38a7850 425
426 //dont merge sequences on the same pad twice
427 if(previousPt[p]->fLastMergedPad==pad) continue;
428
429 Int_t difference = seqmean - previousPt[p]->fMean;
430 if(difference < -fMatch) break;
431
432 if(difference <= fMatch){ //There is a match here!!
433 AliClusterData *local = previousPt[p];
434
435 if(fDeconvPad){
436 if(seqcharge > local->fLastCharge){
437 if(local->fChargeFalling){ //The previous pad was falling
438 break; //create a new cluster
439 }
440 }
441 else local->fChargeFalling = 1;
442 local->fLastCharge = seqcharge;
443 }
444
445 //Don't create a new cluster, because we found a match
446 newcluster = kFALSE;
447
448 //Update cluster on current pad with the matching one:
449 local->fTotalCharge += seqcharge;
450 local->fPad += padmean;
451 local->fPad2 += paderror;
452 local->fTime += seqaverage;
453 local->fTime2 += seqerror;
454 local->fMean = seqmean;
455 local->fFlags++; //means we have more than one pad
456 local->fLastMergedPad = pad;
457
458 currentPt[ncurrent] = local;
459 ncurrent++;
460
461 break;
462 } //Checking for match at previous pad
463 } //Loop over results on previous pad.
464
84645eb0 465 if(newcluster && ncurrent<kPadArraySize){
a38a7850 466 //Start a new cluster. Add it to the clusterlist, and update
467 //the list of pointers to clusters in current pad.
468 //current pad will be previous pad on next pad.
469
470 //Add to the clusterlist:
471 AliClusterData *tmp = &clusterlist[ntotal];
472 tmp->fTotalCharge = seqcharge;
473 tmp->fPad = padmean;
474 tmp->fPad2 = paderror;
475 tmp->fTime = seqaverage;
476 tmp->fTime2 = seqerror;
477 tmp->fMean = seqmean;
478 tmp->fFlags = 0; //flags for single pad clusters
479 tmp->fLastMergedPad = pad;
480
481 if(fDeconvPad){
482 tmp->fChargeFalling = 0;
483 tmp->fLastCharge = seqcharge;
484 }
485
486 //Update list of pointers to previous pad:
487 currentPt[ncurrent] = &clusterlist[ntotal];
488 ntotal++;
489 ncurrent++;
490 }
491
492 if(fDeconvTime)
493 if(newbin >= 0) goto redo;
494
495 // to prevent endless loop
496 if(time >= AliHLTTPCTransform::GetNTimeBins()){
46b33a24 497 HLTWarning("Timebin (%d) out of range (%d)", time, AliHLTTPCTransform::GetNTimeBins());
a38a7850 498 break;
499 }
500
501
502 if(!readValue) break; //No more value
84645eb0 503
504 if (ntotal>=kClusterListSize || ncurrent>=kPadArraySize) {
505 HLTWarning("pad array size exceeded ntotal=%d ncurrent=%d, skip rest of the data", ntotal, ncurrent);
506 break;
507 }
a38a7850 508
509 if(fCurrentRow != newRow){
510 WriteClusters(ntotal,clusterlist);
511
512 lastpad = 123456789;
513
514 currentPt = pad2;
515 previousPt = pad1;
516 nprevious=0;
517 ncurrent=0;
518 ntotal=0;
519
520 fCurrentRow = newRow;
521 }
522
523 pad = newPad;
524 time = newTime;
db16520a 525
a38a7850 526 } // END while(readValue)
527
528 WriteClusters(ntotal,clusterlist);
529
46b33a24 530 HLTInfo("ClusterFinder found %d clusters in slice %d patch %d", fNClusters, fCurrentSlice, fCurrentPatch);
a38a7850 531
532} // ENDEND
533
534void AliHLTTPCClusterFinder::WriteClusters(Int_t nclusters,AliClusterData *list)
535{
536 //write cluster to output pointer
8f8bf0af 537 Int_t thisrow=-1,thissector=-1;
a38a7850 538 UInt_t counter = fNClusters;
539
540 for(int j=0; j<nclusters; j++)
541 {
d8b2f74a 542
543
544
a38a7850 545 if(!list[j].fFlags) continue; //discard single pad clusters
546 if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
547
548 Float_t xyz[3];
549 Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
550 Float_t fpad2=fXYErr*fXYErr; //fixed given error
551 Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
552 Float_t ftime2=fZErr*fZErr; //fixed given error
553
738c049f 554
d8b2f74a 555#if UNSORTED
556 fCurrentRow=list[j].fRow;
557#endif
738c049f 558
a38a7850 559 if(fCalcerr) { //calc the errors, otherwice take the fixed error
560 Int_t patch = AliHLTTPCTransform::GetPatch(fCurrentRow);
561 UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
562 Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
563 sy2/=q2;
564 if(sy2 < 0) {
565 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
566 <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
567 continue;
568 } else {
569 if(!fRawSP){
570 fpad2 = (sy2 + 1./12)*AliHLTTPCTransform::GetPadPitchWidth(patch)*AliHLTTPCTransform::GetPadPitchWidth(patch);
571 if(sy2 != 0){
572 fpad2*=0.108; //constants are from offline studies
573 if(patch<2)
574 fpad2*=2.07;
575 }
576 } else fpad2=sy2; //take the width not the error
577 }
578 Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
579 sz2/=q2;
580 if(sz2 < 0){
581 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
582 <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
583 continue;
584 } else {
585 if(!fRawSP){
586 ftime2 = (sz2 + 1./12)*AliHLTTPCTransform::GetZWidth()*AliHLTTPCTransform::GetZWidth();
587 if(sz2 != 0) {
588 ftime2 *= 0.169; //constants are from offline studies
589 if(patch<2)
590 ftime2 *= 1.77;
591 }
592 } else ftime2=sz2; //take the width, not the error
593 }
594 }
595 if(fStdout==kTRUE)
596 cout<<"WriteCluster: padrow "<<fCurrentRow<<" pad "<<fpad << " +- "<<fpad2<<" time "<<ftime<<" +- "<<ftime2<<" charge "<<list[j].fTotalCharge<<endl;
597
598 if(!fRawSP){
599 AliHLTTPCTransform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
600 AliHLTTPCTransform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
601
602 if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
603 <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
604 if(fNClusters >= fMaxNClusters)
605 {
606 LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
607 <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
608 return;
609 }
610
611 fSpacePointData[counter].fX = xyz[0];
612 fSpacePointData[counter].fY = xyz[1];
613 fSpacePointData[counter].fZ = xyz[2];
614
615 } else {
616 fSpacePointData[counter].fX = fCurrentRow;
617 fSpacePointData[counter].fY = fpad;
618 fSpacePointData[counter].fZ = ftime;
619 }
620
621 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
622 fSpacePointData[counter].fPadRow = fCurrentRow;
623 fSpacePointData[counter].fSigmaY2 = fpad2;
624 fSpacePointData[counter].fSigmaZ2 = ftime2;
625
44be0fde 626 fSpacePointData[counter].fUsed = kFALSE; // only used / set in AliHLTTPCDisplay
738c049f 627 fSpacePointData[counter].fTrackN = -1; // only used / set in AliHLTTPCDisplay
44be0fde 628
a38a7850 629 Int_t patch=fCurrentPatch;
630 if(patch==-1) patch=0; //never store negative patch number
631 fSpacePointData[counter].fID = counter
632 +((fCurrentSlice&0x7f)<<25)+((patch&0x7)<<22);//Uli
633
634#ifdef do_mc
635 Int_t trackID[3];
636 GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
637
638 fSpacePointData[counter].fTrackID[0] = trackID[0];
639 fSpacePointData[counter].fTrackID[1] = trackID[1];
640 fSpacePointData[counter].fTrackID[2] = trackID[2];
641
642 //cout<<"padrow "<<fCurrentRow<<" pad "<<(Int_t)rint(fpad)<<" time "<<(Int_t)rint(ftime)<<" Trackid "<<trackID[0]<<endl;
643#endif
644
645 fNClusters++;
646 counter++;
647 }
648}
649
650// STILL TO FIX ----------------------------------------------------------------------------
651
652#ifdef do_mc
653void AliHLTTPCClusterFinder::GetTrackID(Int_t pad,Int_t time,Int_t *trackID)
654{
655 //get mc id
656 AliHLTTPCDigitRowData *rowPt = (AliHLTTPCDigitRowData*)fDigitRowData;
657
658 trackID[0]=trackID[1]=trackID[2]=-2;
659 //cout<<"Looking for pad "<<pad<<" time "<<time<<endl;
660 for(Int_t i=fFirstRow; i<=fLastRow; i++){
661 if(rowPt->fRow < (UInt_t)fCurrentRow){
662 AliHLTTPCMemHandler::UpdateRowPointer(rowPt);
663 continue;
664 }
665 AliHLTTPCDigitData *digPt = (AliHLTTPCDigitData*)rowPt->fDigitData;
666 for(UInt_t j=0; j<rowPt->fNDigit; j++){
667 Int_t cpad = digPt[j].fPad;
668 Int_t ctime = digPt[j].fTime;
669 if(cpad != pad) continue;
670 if(ctime != time) continue;
671
672 trackID[0] = digPt[j].fTrackID[0];
673 trackID[1] = digPt[j].fTrackID[1];
674 trackID[2] = digPt[j].fTrackID[2];
675
676 //cout<<"Reading row "<<fCurrentRow<<" pad "<<cpad<<" time "<<ctime<<" trackID "<<digPt[j].fTrackID[0]<<endl;
677 break;
678 }
679 break;
680 }
681}
682#endif
01f43166 683
684//----------------------------------Methods for the new unsorted way of reading the data --------------------------------
685
686void AliHLTTPCClusterFinder::SetPadArray(AliHLTTPCPadArray * padArray){
687 fPadArray=padArray;
688}
689
690void AliHLTTPCClusterFinder::ReadDataUnsorted(void* ptr,unsigned long size){
691 //set input pointer
692 fPtr = (UChar_t*)ptr;
693 fSize = size;
694
695 fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice);
696
697 fPadArray->SetDigitReader(fDigitReader);
698 fPadArray->ReadData();
699}
700void AliHLTTPCClusterFinder::FindClusters(){
701 fPadArray->FindClusterCandidates();
702 fPadArray->FindClusters(fMatch);
d8b2f74a 703
704 AliClusterData * clusterlist = new AliClusterData[fPadArray->fClusters.size()]; //Clusterlist
a1dbf058 705 for(unsigned int i=0;i<fPadArray->fClusters.size();i++){
d8b2f74a 706 clusterlist[i].fTotalCharge = fPadArray->fClusters[i].fTotalCharge;
707 clusterlist[i].fPad = fPadArray->fClusters[i].fPad;
708 clusterlist[i].fPad2 = fPadArray->fClusters[i].fPad2;
709 clusterlist[i].fTime = fPadArray->fClusters[i].fTime;
710 clusterlist[i].fTime2 = fPadArray->fClusters[i].fTime2;
711 clusterlist[i].fMean = fPadArray->fClusters[i].fMean;
712 clusterlist[i].fFlags = fPadArray->fClusters[i].fFlags;
713 clusterlist[i].fChargeFalling = fPadArray->fClusters[i].fChargeFalling;
714 clusterlist[i].fLastCharge = fPadArray->fClusters[i].fLastCharge;
715 clusterlist[i].fLastMergedPad = fPadArray->fClusters[i].fLastMergedPad;
716 clusterlist[i].fRow = fPadArray->fClusters[i].fRowNumber;
01f43166 717 }
718 WriteClusters(fPadArray->fClusters.size(),clusterlist);
e83e889b 719 delete [] clusterlist;
6be21538 720 fPadArray->DataToDefault();
01f43166 721}
722void AliHLTTPCClusterFinder::WriteClusters(Int_t nclusters,AliHLTTPCClusters *list)//This is used when using the AliHLTTPCClusters class for cluster data
723{
724 //write cluster to output pointer
725 Int_t thisrow,thissector;
726 UInt_t counter = fNClusters;
727
728 for(int j=0; j<nclusters; j++)
729 {
730 if(!list[j].fFlags) continue; //discard single pad clusters
731 if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
732
733 Float_t xyz[3];
734 Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
735 Float_t fpad2=fXYErr*fXYErr; //fixed given error
736 Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
737 Float_t ftime2=fZErr*fZErr; //fixed given error
738
d8b2f74a 739
01f43166 740 if(fCalcerr) { //calc the errors, otherwice take the fixed error
741 Int_t patch = AliHLTTPCTransform::GetPatch(fCurrentRow);
742 UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
743 Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
744 sy2/=q2;
745 if(sy2 < 0) {
746 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
747 <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
748 continue;
749 } else {
750 if(!fRawSP){
751 fpad2 = (sy2 + 1./12)*AliHLTTPCTransform::GetPadPitchWidth(patch)*AliHLTTPCTransform::GetPadPitchWidth(patch);
752 if(sy2 != 0){
753 fpad2*=0.108; //constants are from offline studies
754 if(patch<2)
755 fpad2*=2.07;
756 }
757 } else fpad2=sy2; //take the width not the error
758 }
759 Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
760 sz2/=q2;
761 if(sz2 < 0){
762 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
763 <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
764 continue;
765 } else {
766 if(!fRawSP){
767 ftime2 = (sz2 + 1./12)*AliHLTTPCTransform::GetZWidth()*AliHLTTPCTransform::GetZWidth();
768 if(sz2 != 0) {
769 ftime2 *= 0.169; //constants are from offline studies
770 if(patch<2)
771 ftime2 *= 1.77;
772 }
773 } else ftime2=sz2; //take the width, not the error
774 }
775 }
776 if(fStdout==kTRUE)
777 cout<<"WriteCluster: padrow "<<fCurrentRow<<" pad "<<fpad << " +- "<<fpad2<<" time "<<ftime<<" +- "<<ftime2<<" charge "<<list[j].fTotalCharge<<endl;
778
779 if(!fRawSP){
780 AliHLTTPCTransform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
781 AliHLTTPCTransform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
782
783 if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
784 <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
785 if(fNClusters >= fMaxNClusters)
786 {
787 LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
788 <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
789 return;
790 }
791
792 fSpacePointData[counter].fX = xyz[0];
793 fSpacePointData[counter].fY = xyz[1];
794 fSpacePointData[counter].fZ = xyz[2];
795
796 } else {
797 fSpacePointData[counter].fX = fCurrentRow;
798 fSpacePointData[counter].fY = fpad;
799 fSpacePointData[counter].fZ = ftime;
800 }
801
802 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
803 fSpacePointData[counter].fPadRow = fCurrentRow;
804 fSpacePointData[counter].fSigmaY2 = fpad2;
805 fSpacePointData[counter].fSigmaZ2 = ftime2;
806
807 fSpacePointData[counter].fUsed = kFALSE; // only used / set in AliHLTTPCDisplay
808 fSpacePointData[counter].fTrackN = -1; // only used / set in AliHLTTPCDisplay
809
810 Int_t patch=fCurrentPatch;
811 if(patch==-1) patch=0; //never store negative patch number
812 fSpacePointData[counter].fID = counter
813 +((fCurrentSlice&0x7f)<<25)+((patch&0x7)<<22);//Uli
814
815#ifdef do_mc
816 Int_t trackID[3];
817 GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
818
819 fSpacePointData[counter].fTrackID[0] = trackID[0];
820 fSpacePointData[counter].fTrackID[1] = trackID[1];
821 fSpacePointData[counter].fTrackID[2] = trackID[2];
822
823 //cout<<"padrow "<<fCurrentRow<<" pad "<<(Int_t)rint(fpad)<<" time "<<(Int_t)rint(ftime)<<" Trackid "<<trackID[0]<<endl;
824#endif
825
826 fNClusters++;
827 counter++;
828 }
829}