]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/comp/AliHLTDataCompressor.cxx
L3 becomes HLT
[u/mrichter/AliRoot.git] / HLT / comp / AliHLTDataCompressor.cxx
CommitLineData
3e87ef69 1// @(#) $Id$
5b3f37f6 2
3// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
3e87ef69 4//*-- Copyright &copy ALICE HLT Group
b4686276 5//_____________________________________________________________
6//
4aa41877 7// AliHLTDataCompression
b4686276 8//
9// Interface class; binary <-> AliROOT handling of TPC data compression classes.
10//
11
5b3f37f6 12
4aa41877 13#include "AliHLTStandardIncludes.h"
3e87ef69 14
4aa41877 15#include "AliHLTLogging.h"
16#include "AliHLTRootTypes.h"
17#include "AliHLTTransform.h"
18#include "AliHLTMemHandler.h"
19#include "AliHLTSpacePointData.h"
20#include "AliHLTCompressAC.h"
21#include "AliHLTTrackArray.h"
22#include "AliHLTModelTrack.h"
23#include "AliHLTBenchmark.h"
24#include "AliHLTClusterFitter.h"
3e87ef69 25
26#ifdef use_aliroot
4aa41877 27#include "AliHLTFileHandler.h"
3e87ef69 28#include <AliTPCcluster.h>
5b3f37f6 29#include <AliTPCParamSR.h>
30#include <AliTPCDigitsArray.h>
31#include <AliTPCClustersArray.h>
5b3f37f6 32#include <AliTPCClustersRow.h>
33#include <AliSimDigits.h>
34#include <AliTPC.h>
35#include <AliTPCv2.h>
36#include <AliRun.h>
3e87ef69 37#endif
5b3f37f6 38
3e87ef69 39#ifdef use_root
5b3f37f6 40#include <TFile.h>
5b3f37f6 41#include <TDirectory.h>
42#include <TSystem.h>
3e87ef69 43#include <TH2F.h>
44#endif
45
4aa41877 46#include "AliHLTDataCompressorHelper.h"
47#include "AliHLTDataCompressor.h"
de3c3890 48#include <math.h>
3e87ef69 49
0bd0c1ef 50#if __GNUC__ == 3
3e87ef69 51using namespace std;
52#endif
53
5b3f37f6 54
4aa41877 55ClassImp(AliHLTDataCompressor)
5b3f37f6 56
4aa41877 57AliHLTDataCompressor::AliHLTDataCompressor()
5b3f37f6 58{
b4686276 59 // default constructor
bd53cfb7 60 fBenchmark=0;
3e87ef69 61 fInputTracks=0;
62 fKeepRemaining=kTRUE;
5a31e9df 63 fNoCompression=kFALSE;
3e87ef69 64 fEvent=0;
65 fWriteClusterShape=kFALSE;
66 fOutputFile=0;
67 fCompRatioFile=0;
b2a02bce 68 fNusedClusters=0;
69 fNunusedClusters=0;
4aa41877 70 memset(fClusters,0,36*6*sizeof(AliHLTSpacePointData*));
5b3f37f6 71}
72
4aa41877 73AliHLTDataCompressor::AliHLTDataCompressor(Char_t *path,Bool_t keep,Bool_t writeshape)
5b3f37f6 74{
b4686276 75 // constructor
5b3f37f6 76 strcpy(fPath,path);
4aa41877 77 fBenchmark = new AliHLTBenchmark();
3e87ef69 78 fInputTracks=0;
79 fKeepRemaining=keep;
80 fWriteClusterShape = writeshape;
81 fEvent=0;
82 fOutputFile=0;
b2a02bce 83 fNusedClusters=0;
84 fNunusedClusters=0;
5a31e9df 85 fNoCompression=kFALSE;
4aa41877 86 memset(fClusters,0,36*6*sizeof(AliHLTSpacePointData*));
3e87ef69 87#ifdef use_root
88 Char_t name[1024];
89 sprintf(name,"rm -f %s/comp/*",path);//Clean the directory
90 gSystem->Exec(name);
91#endif
92 OpenOutputFile();
5b3f37f6 93}
94
4aa41877 95AliHLTDataCompressor::~AliHLTDataCompressor()
5b3f37f6 96{
b4686276 97 // destructor
3e87ef69 98 if(fInputTracks)
99 delete fInputTracks;
bd53cfb7 100 if(fBenchmark)
101 delete fBenchmark;
3e87ef69 102 if(fClusters)
103 {
104 for(Int_t i=0; i<36; i++)
105 for(Int_t j=0; j<6; j++)
106 if(fClusters[i][j])
107 delete fClusters[i][j];
108 }
109 CloseOutputFile();
bd53cfb7 110}
111
4aa41877 112void AliHLTDataCompressor::DoBench(Char_t *fname)
bd53cfb7 113{
b4686276 114 // does benchmarking
bd53cfb7 115 fBenchmark->Analyze(fname);
5b3f37f6 116}
117
4aa41877 118void AliHLTDataCompressor::OpenOutputFile()
5b3f37f6 119{
b4686276 120 // opens the output file
3e87ef69 121#ifndef use_aliroot
4aa41877 122 LOG(AliHLTLog::kError,"AliHLTDataCompressor::OpenOutputFile","Version")
3e87ef69 123 <<"You have to compile with use_aliroot flag in order to use this function"<<ENDLOG;
124#else
125 Char_t filename[1024];
5b3f37f6 126
3e87ef69 127 sprintf(filename,"%s/comp/comprates.txt",fPath);
128 fCompRatioFile = new ofstream(filename);
129
130 if(fOutputFile)
131 if(fOutputFile->IsOpen())
132 fOutputFile->Close();
133
134 sprintf(filename,"%s/alirunfile.root",fPath);
135 TFile *f = TFile::Open(filename);
4aa41877 136 AliTPCParam *param = (AliTPCParam*)f->Get(AliHLTTransform::GetParamName());
3e87ef69 137 sprintf(filename,"%s/comp/AliTPCclusters.root",fPath);
138 fOutputFile = TFile::Open(filename,"RECREATE");
139 param->Write(param->GetTitle());
140 f->Close();
141#endif
142}
143
4aa41877 144void AliHLTDataCompressor::CloseOutputFile()
3e87ef69 145{
b4686276 146 // closes the output file
3e87ef69 147 if(fCompRatioFile)
5b3f37f6 148 {
3e87ef69 149 fCompRatioFile->close();
150 delete fCompRatioFile;
151 }
152
153 if(!fOutputFile)
154 return;
155#ifdef use_root
156 if(!fOutputFile->IsOpen())
157 return;
158 fOutputFile->Close();
159#else
160 fclose(fOutputFile);
161#endif
162 fOutputFile=0;
163}
5b3f37f6 164
4aa41877 165void AliHLTDataCompressor::LoadData(Int_t event,Bool_t sp)
3e87ef69 166{
b4686276 167 // Loads data
3e87ef69 168 fSinglePatch=sp;
169 fEvent=event;
4aa41877 170 AliHLTMemHandler *clusterfile[36][6];
3e87ef69 171 Char_t fname[1024];
172 for(Int_t s=0; s<=35; s++)
173 {
174 for(Int_t p=0; p<6; p++)
175 {
176 if(fClusters[s][p])
177 delete fClusters[s][p];
178 fClusters[s][p] = 0;
4aa41877 179 clusterfile[s][p] = new AliHLTMemHandler();
3e87ef69 180 if(fSinglePatch)
181 sprintf(fname,"%s/cf/points_%d_%d_%d.raw",fPath,fEvent,s,-1);
182 else
183 sprintf(fname,"%s/cf/points_%d_%d_%d.raw",fPath,fEvent,s,p);
184 clusterfile[s][p]->SetBinaryInput(fname);
5b3f37f6 185
4aa41877 186 fClusters[s][p] = (AliHLTSpacePointData*)clusterfile[s][p]->Allocate();
3e87ef69 187 clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]);
188 clusterfile[s][p]->CloseBinaryInput();
5b3f37f6 189
3e87ef69 190 if(fSinglePatch)
191 break;
5b3f37f6 192 }
193 }
194
5a31e9df 195 //cout<<endl<<"Reading from offlinecf"<<endl<<endl;
3e87ef69 196 sprintf(fname,"%s/cf/tracks_%d.raw",fPath,fEvent);
4aa41877 197 AliHLTMemHandler *tfile = new AliHLTMemHandler();
3e87ef69 198 tfile->SetBinaryInput(fname);
199
200 if(fInputTracks)
201 delete fInputTracks;
4aa41877 202 fInputTracks = new AliHLTTrackArray();
3e87ef69 203 tfile->Binary2TrackArray(fInputTracks);
204 tfile->CloseBinaryInput();
205 delete tfile;
5b3f37f6 206}
207
4aa41877 208void AliHLTDataCompressor::FillData(Int_t minHits,Bool_t expand)
5b3f37f6 209{
5b3f37f6 210
3e87ef69 211 //Fill the track data into track and cluster structures, and write to file.
212 //Preparation for compressing it.
213
214 cout<<"Filling data; "<<fInputTracks->GetNTracks()<<" tracks"<<endl;
4aa41877 215 AliHLTTrackArray *comptracks = new AliHLTTrackArray("AliHLTModelTrack");
3e87ef69 216 fInputTracks->QSort();
217 for(Int_t i=0; i<fInputTracks->GetNTracks(); i++)
5b3f37f6 218 {
4aa41877 219 AliHLTTrack *intrack = fInputTracks->GetCheckedTrack(i);
3e87ef69 220 if(!intrack) continue;
221
b4686276 222 if(intrack->GetNHits()<minHits) break;
1f1942b8 223 if(intrack->GetPt()<0.1) continue;
224
3e87ef69 225 intrack->CalculateHelix();
226
4aa41877 227 AliHLTModelTrack *outtrack = (AliHLTModelTrack*)comptracks->NextTrack();
3e87ef69 228 outtrack->SetNHits(intrack->GetNHits());
229 outtrack->SetRowRange(intrack->GetFirstRow(),intrack->GetLastRow());
230 outtrack->SetFirstPoint(intrack->GetFirstPointX(),intrack->GetFirstPointY(),intrack->GetFirstPointZ());
231 outtrack->SetLastPoint(intrack->GetLastPointX(),intrack->GetLastPointY(),intrack->GetLastPointZ());
232 outtrack->SetPt(intrack->GetPt());
233 outtrack->SetPsi(intrack->GetPsi());
234 outtrack->SetTgl(intrack->GetTgl());
235 outtrack->SetCharge(intrack->GetCharge());
236 outtrack->CalculateHelix();
237 Int_t nhits = intrack->GetNHits();
238 UInt_t *hitids = intrack->GetHitNumbers();
239 Int_t origslice = (hitids[nhits-1]>>25)&0x7f;
240 outtrack->Init(origslice,-1);
1f1942b8 241
3e87ef69 242 for(Int_t j=nhits-1; j>=0; j--)
5b3f37f6 243 {
3e87ef69 244 UInt_t id=hitids[j];
245 Int_t slice = (id>>25)&0x7f;
246 Int_t patch = (id>>22)&0x7;
247 UInt_t pos = id&0x3fffff;
248
249 //UInt_t size;
4aa41877 250 AliHLTSpacePointData *points = fClusters[slice][patch];//->GetDataPointer(size);
3e87ef69 251 Float_t xyz[3] = {points[pos].fX,points[pos].fY,points[pos].fZ};
252 Int_t padrow = points[pos].fPadRow;
5b3f37f6 253
3e87ef69 254 //Calculate the crossing point between track and padrow
255 Float_t angle = 0; //Perpendicular to padrow in local coordinates
4aa41877 256 AliHLTTransform::Local2GlobalAngle(&angle,slice);
257 if(!intrack->CalculateReferencePoint(angle,AliHLTTransform::Row2X(padrow)))
3e87ef69 258 {
4aa41877 259 cerr<<"AliHLTDataCompressor::FillData : Error in crossing point calc on slice "<<slice<<" row "<<padrow<<endl;
0a86fbb7 260 break;
261 //outtrack->Print(kFALSE);
262 //exit(5);
3e87ef69 263 }
264
b4686276 265 Float_t xyzCross[3] = {intrack->GetPointX(),intrack->GetPointY(),intrack->GetPointZ()};
1f1942b8 266
3e87ef69 267 Int_t sector,row;
4aa41877 268 AliHLTTransform::Slice2Sector(slice,padrow,sector,row);
269 AliHLTTransform::Global2Raw(xyzCross,sector,row);
270 AliHLTTransform::Global2Raw(xyz,sector,row);
3e87ef69 271
b4686276 272 outtrack->SetPadHit(padrow,xyzCross[1]);
273 outtrack->SetTimeHit(padrow,xyzCross[2]);
1f1942b8 274
6f388e0d 275 outtrack->SetCrossingAngleLUT(padrow,intrack->GetCrossingAngle(padrow,slice));
276 outtrack->CalculateClusterWidths(padrow,kTRUE);
1f1942b8 277
3e87ef69 278 if(fWriteClusterShape)
279 {
4aa41877 280 Int_t patch = AliHLTTransform::GetPatch(padrow);
281 Float_t sigmaY2 = points[pos].fSigmaY2 / pow(AliHLTTransform::GetPadPitchWidth(patch),2);
282 Float_t sigmaZ2 = points[pos].fSigmaZ2 / pow(AliHLTTransform::GetZWidth(),2);
3e87ef69 283 outtrack->SetCluster(padrow,xyz[1],xyz[2],points[pos].fCharge,sigmaY2,sigmaZ2,3);
284 }
285 else
286 outtrack->SetCluster(padrow,xyz[1],xyz[2],points[pos].fCharge,0,0,3);
5b3f37f6 287
4aa41877 288 //IMPORTANT: Set the slice in which cluster is, you need it in AliHLTModelTrack::FillTrack!
3e87ef69 289 outtrack->GetClusterModel(padrow)->fSlice=slice;
290 points[pos].fCharge = 0;//Mark this cluster as used.
b2a02bce 291 fNusedClusters++;
5b3f37f6 292 }
3e87ef69 293 if(!expand)
4aa41877 294 outtrack->SetNClusters(AliHLTTransform::GetNRows(-1));
5b3f37f6 295 }
3e87ef69 296 if(expand)
297 ExpandTrackData(comptracks);
298
299 cout<<"Writing "<<comptracks->GetNTracks()<<" tracks to file"<<endl;
4aa41877 300 AliHLTCompress *comp = new AliHLTCompress(-1,-1,fPath,fWriteClusterShape,fEvent);
3e87ef69 301 comp->WriteFile(comptracks);
302 delete comp;
303 delete comptracks;
304
5b3f37f6 305}
306
4aa41877 307void AliHLTDataCompressor::ExpandTrackData(AliHLTTrackArray *tracks)
5b3f37f6 308{
3e87ef69 309 //Loop over tracks and try to assign unused clusters.
310 //Only clusters which are closer than the max. residual are taken.
5b3f37f6 311
3e87ef69 312 cout<<"Expanding "<<tracks->GetNTracks()<<" tracks"<<endl;
313 for(Int_t i=0; i<tracks->GetNTracks(); i++)
5b3f37f6 314 {
4aa41877 315 AliHLTModelTrack *track = (AliHLTModelTrack*)tracks->GetCheckedTrack(i);
3e87ef69 316 if(!track) continue;
4aa41877 317 if(track->GetNHits() == AliHLTTransform::GetNRows()) continue;
3e87ef69 318
319 Int_t nhits = track->GetNHits();
320 //cout<<"Expanding track with "<<nhits<<" clusters"<<endl;
321
b4686276 322 Int_t lastSlice=-1;
4aa41877 323 for(Int_t padrow=AliHLTTransform::GetNRows()-1; padrow>=0; padrow--)
5b3f37f6 324 {
3e87ef69 325 if(track->IsPresent(padrow))
326 {
b4686276 327 lastSlice = track->GetClusterModel(padrow)->fSlice;
3e87ef69 328 continue;
329 }
330
b4686276 331 if(lastSlice < 0) //the outer cluster is missing, so skip it - it will be written anyhow.
3e87ef69 332 continue;
333
334 //Check the slice of the next padrow:
b4686276 335 Int_t nextPadrow = padrow-1;
336 Int_t nextSlice = -1;
337 while(nextPadrow >=0)
3e87ef69 338 {
b4686276 339 if(track->IsPresent(nextPadrow))
3e87ef69 340 {
b4686276 341 nextSlice = track->GetClusterModel(nextPadrow)->fSlice;
3e87ef69 342 break;
343 }
b4686276 344 nextPadrow--;
3e87ef69 345 }
b4686276 346 if(nextSlice>=0)
347 if(nextSlice != lastSlice)//The track crosses a slice boundary here
3e87ef69 348 continue;
349
350 //UInt_t size;
4aa41877 351 AliHLTSpacePointData *points = fClusters[lastSlice][0];//->GetDataPointer(size);
3e87ef69 352
353 Float_t angle = 0;
4aa41877 354 AliHLTTransform::Local2GlobalAngle(&angle,lastSlice);
355 if(!track->CalculateReferencePoint(angle,AliHLTTransform::Row2X(padrow)))
3e87ef69 356 continue;
b4686276 357 Float_t xyzCross[3] = {track->GetPointX(),track->GetPointY(),track->GetPointZ()};
4aa41877 358 AliHLTTransform::Global2LocHLT(xyzCross,lastSlice);
3e87ef69 359 Float_t mindist = 123456789;
4aa41877 360 AliHLTSpacePointData *closest=0;
b4686276 361 for(UInt_t j=0; j<fNcl[lastSlice][0]; j++)
3e87ef69 362 {
363 if(points[j].fCharge == 0) continue;// || points[j].fPadRow != padrow) continue;
364 if(points[j].fPadRow < padrow) continue;
365 if(points[j].fPadRow > padrow) break;
366 Float_t xyz[3] = {points[j].fX,points[j].fY,points[j].fZ};
4aa41877 367 AliHLTTransform::Global2LocHLT(xyz,lastSlice);
3e87ef69 368
369 //Check for overflow:
4aa41877 370 Int_t temp = (Int_t)rint((xyzCross[1]-xyz[1])/AliHLTDataCompressorHelper::GetXYResidualStep(padrow));
371 if( abs(temp) > 1<<(AliHLTDataCompressorHelper::GetNPadBits()-1))
3e87ef69 372 continue;
373
4aa41877 374 temp = (Int_t)rint((xyzCross[2]-xyz[2])/AliHLTDataCompressorHelper::GetZResidualStep(padrow));
375 if( abs(temp) > 1<<(AliHLTDataCompressorHelper::GetNTimeBits()-1))
3e87ef69 376 continue;
377
b4686276 378 Float_t dist = sqrt( pow(xyzCross[1]-xyz[1],2) + pow(xyzCross[2]-xyz[2],2) );
3e87ef69 379 if(dist < mindist)
380 {
381 closest = &points[j];
382 mindist = dist;
383 }
384 }
385 if(closest) //there was a cluster assigned
386 {
387 Int_t sector,row;
388 Float_t xyz[3] = {closest->fX,closest->fY,closest->fZ};
4aa41877 389 AliHLTTransform::Slice2Sector(lastSlice,padrow,sector,row);
390 AliHLTTransform::Local2Raw(xyzCross,sector,row);
391 AliHLTTransform::Global2Raw(xyz,sector,row);
3e87ef69 392
b4686276 393 track->SetPadHit(padrow,xyzCross[1]);
394 track->SetTimeHit(padrow,xyzCross[2]);
3e87ef69 395
396 if(fWriteClusterShape)
397 {
b4686276 398 Float_t angle = track->GetCrossingAngle(padrow,lastSlice);
3e87ef69 399 track->SetCrossingAngleLUT(padrow,angle);
400 track->CalculateClusterWidths(padrow,kTRUE);
4aa41877 401 Int_t patch = AliHLTTransform::GetPatch(padrow);
402 Float_t sigmaY2 = closest->fSigmaY2 / pow(AliHLTTransform::GetPadPitchWidth(patch),2);
403 Float_t sigmaZ2 = closest->fSigmaZ2 / pow(AliHLTTransform::GetZWidth(),2);
3e87ef69 404 track->SetCluster(padrow,xyz[1],xyz[2],closest->fCharge,sigmaY2,sigmaZ2,3);
405 }
406 else
407 track->SetCluster(padrow,xyz[1],xyz[2],closest->fCharge,0,0,3);
408 nhits++;
409
4aa41877 410 //IMPORTANT: Set the slice in which cluster is, you need it in AliHLTModelTrack::FillTrack!
b4686276 411 track->GetClusterModel(padrow)->fSlice=lastSlice;
3e87ef69 412 closest->fCharge = 0;//Mark this cluster as used.
413 }
5b3f37f6 414 }
4aa41877 415 track->SetNClusters(AliHLTTransform::GetNRows());
3e87ef69 416 //cout<<"Track was assigned "<<nhits<<" clusters"<<endl;
5b3f37f6 417 }
418
419}
420
de3c3890 421
422
4aa41877 423void AliHLTDataCompressor::DetermineMinBits()
1f1942b8 424{
425 //Make a pass through the modelled data (after FillData has been done) to determine
426 //how many bits is needed to encode the residuals _without_ overflows.
427
4aa41877 428 AliHLTCompress *comp = new AliHLTCompress(-1,-1,fPath,fWriteClusterShape,fEvent);
1f1942b8 429 comp->ReadFile('m');
4aa41877 430 AliHLTTrackArray *tracks = comp->GetTracks();
1f1942b8 431 if(tracks->GetNTracks()==0)
432 {
433 delete comp;
434 return;
435 }
436
437 Int_t maxtime=0,maxpad=0,maxsigma=0,maxcharge=0;
438 Int_t dpad,dtime,charge,dsigmaY,dsigmaZ,npadbits,ntimebits,nchargebits,nshapebits=0;
439 for(Int_t i=0; i<tracks->GetNTracks(); i++)
440 {
4aa41877 441 AliHLTModelTrack *track = (AliHLTModelTrack*)tracks->GetCheckedTrack(i);
1f1942b8 442 if(!track) continue;
4aa41877 443 for(Int_t padrow=0; padrow<AliHLTTransform::GetNRows(); padrow++)
1f1942b8 444 {
445 if(!track->IsPresent(padrow)) continue;
4aa41877 446 dpad = AliHLTDataCompressorHelper::Abs(AliHLTDataCompressorHelper::Nint(track->GetClusterModel(padrow)->fDPad));
447 dtime = AliHLTDataCompressorHelper::Abs(AliHLTDataCompressorHelper::Nint(track->GetClusterModel(padrow)->fDTime));
448 charge = AliHLTDataCompressorHelper::Abs((Int_t)track->GetClusterModel(padrow)->fDCharge);
449 dsigmaY = AliHLTDataCompressorHelper::Abs(AliHLTDataCompressorHelper::Nint(track->GetClusterModel(padrow)->fDSigmaY));
450 dsigmaZ = AliHLTDataCompressorHelper::Abs(AliHLTDataCompressorHelper::Nint(track->GetClusterModel(padrow)->fDSigmaZ));
1f1942b8 451 if(dpad > maxpad)
452 maxpad=dpad;
453 if(dtime > maxtime)
454 maxtime=dtime;
455 if(charge > maxcharge)
456 maxcharge=charge;
457 if(dsigmaY > maxsigma)
458 maxsigma=dsigmaY;
459 if(dsigmaZ > maxsigma)
460 maxsigma=dsigmaZ;
461 }
462 }
463 cout<<"maxpad "<<maxpad<<" maxtime "<<maxtime<<" maxcharge "<<maxcharge<<endl;
de3c3890 464 npadbits = (Int_t)ceil(log(Double_t(maxpad))/log(2.)) + 1; //need 1 extra bit to encode the sign
465 ntimebits = (Int_t)ceil(log(Double_t(maxtime))/log(2.)) + 1;
466 nchargebits = (Int_t)ceil(log(Double_t(maxcharge))/log(2.)); //Store as a absolute value
1f1942b8 467 if(fWriteClusterShape)
de3c3890 468 nshapebits = (Int_t)ceil(log(Double_t(maxsigma))/log(2.)) + 1;
1f1942b8 469
4aa41877 470 nchargebits = AliHLTDataCompressorHelper::GetNChargeBits();
1f1942b8 471 cout<<"Updating bitnumbers; pad "<<npadbits<<" time "<<ntimebits<<" charge "<<nchargebits<<" shape "<<nshapebits<<endl;
4aa41877 472 AliHLTDataCompressorHelper::SetBitNumbers(npadbits,ntimebits,nchargebits,nshapebits);
1f1942b8 473}
474
4aa41877 475void AliHLTDataCompressor::WriteRemaining(Bool_t select)
5b3f37f6 476{
3e87ef69 477 //Write remaining clusters (not assigned to any tracks) to file
5b3f37f6 478
5b3f37f6 479
3e87ef69 480 if(!fKeepRemaining)
481 return;
5b3f37f6 482
3e87ef69 483 if(select)
484 SelectRemainingClusters();
485
3e87ef69 486 if(!fSinglePatch)
5b3f37f6 487 {
4aa41877 488 cerr<<"AliHLTCompressor::WriteRemaining : You have to modify this function when not running singlepatch"<<endl;
5b3f37f6 489 return;
3e87ef69 490 }
5a31e9df 491 if(!fNoCompression)
492 {
493 cout<<"Compressing remaining clusters "<<endl;
4aa41877 494 AliHLTCompress *comp = new AliHLTCompress(-1,-1,fPath,fWriteClusterShape,fEvent);
5a31e9df 495 comp->CompressRemaining(fClusters,fNcl);
496 delete comp;
497 return;
498 }
499 else
500 {
501 cout<<"Writing remaining clusters"<<endl;
4aa41877 502 Int_t nrows = AliHLTTransform::GetNRows();
5a31e9df 503 Int_t *npoints = new Int_t[nrows];
504 Char_t filename[1024];
505 for(Int_t i=0; i<=35; i++)
506 {
507 for(Int_t patch=0; patch < 1; patch++)
508 {
509 sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,i,-1);
510 FILE *outfile = fopen(filename,"w");
511 if(!outfile)
512 {
4aa41877 513 cerr<<"AliHLTDataCompressor::WriteRemaining : Cannot open file "<<filename<<endl;
5a31e9df 514 exit(5);
515 }
516
4aa41877 517 AliHLTSpacePointData *points = fClusters[i][patch];
5a31e9df 518
519 memset(npoints,0,nrows*sizeof(Int_t));
520
521 for(UInt_t j=0; j<fNcl[i][patch]; j++)
522 {
523 if(points[j].fCharge == 0) continue; //has been used
524 npoints[points[j].fPadRow]++;
525 }
526 Int_t size =0;
527 Byte_t *data = 0;
4aa41877 528 AliHLTRemainingRow *tempPt=0;
5a31e9df 529
b4686276 530 Int_t lastRow = -2;
5a31e9df 531 Int_t localcounter=0;
532
533 for(UInt_t j=0; j<fNcl[i][patch]; j++)
534 {
535 if(points[j].fCharge == 0) continue; //has been used
536
537 Int_t padrow = points[j].fPadRow;
b4686276 538 if(padrow != lastRow)
5a31e9df 539 {
b4686276 540 if(lastRow != -2)
5a31e9df 541 {
542 if(!tempPt)
543 {
4aa41877 544 cerr<<"AliHLTDataCompressor::WriteRemaining : Zero row pointer "<<endl;
5a31e9df 545 exit(5);
546 }
547 if(localcounter != tempPt->fNClusters)
548 {
4aa41877 549 cerr<<"AliHLTDataCompressor::WriteRemaining : Mismatching clustercounter "<<localcounter<<" "
5a31e9df 550 <<(Int_t)tempPt->fNClusters<<endl;
551 exit(5);
552 }
553 //cout<<"Writing row "<<(int)tempPt->fPadRow<<" with "<<(int)tempPt->fNClusters<<" clusters"<<endl;
554 fwrite(tempPt,size,1,outfile);
555 }
556 if(data)
557 delete [] data;
4aa41877 558 size = sizeof(AliHLTRemainingRow) + npoints[padrow]*sizeof(AliHLTRemainingCluster);
5a31e9df 559 data = new Byte_t[size];
4aa41877 560 tempPt = (AliHLTRemainingRow*)data;
5a31e9df 561
562 localcounter=0;
563 tempPt->fPadRow = padrow;
564 tempPt->fNClusters = npoints[padrow];
b4686276 565 lastRow = padrow;
5a31e9df 566 }
567 if(localcounter >= npoints[padrow])
568 {
4aa41877 569 cerr<<"AliHLTDataCompressor::WriteRemaining : Cluster counter out of range: "
5a31e9df 570 <<localcounter<<" "<<npoints[padrow]<<endl;
571 exit(5);
572 }
573
574 Float_t xyz[3] = {points[j].fX,points[j].fY,points[j].fZ};
575 Int_t sector,row;
4aa41877 576 AliHLTTransform::Slice2Sector(i,padrow,sector,row);
577 AliHLTTransform::Global2Raw(xyz,sector,row);
5a31e9df 578
4aa41877 579 Float_t padw = points[j].fSigmaY2 / pow(AliHLTTransform::GetPadPitchWidth(AliHLTTransform::GetPatch(padrow)),2);
580 Float_t timew = points[j].fSigmaZ2 / pow(AliHLTTransform::GetZWidth(),2);
5a31e9df 581 tempPt->fClusters[localcounter].fPad = xyz[1];
582 tempPt->fClusters[localcounter].fTime = xyz[2];
583 tempPt->fClusters[localcounter].fCharge = points[j].fCharge;
584 tempPt->fClusters[localcounter].fSigmaY2 = padw;
585 tempPt->fClusters[localcounter].fSigmaZ2 = timew;
586 localcounter++;
587 fNunusedClusters++;
588 }
589
590 //Write the last row:
591 fwrite(tempPt,size,1,outfile);
592 if(data)
593 delete [] data;
594 fclose(outfile);
595 }
596 }
597 delete [] npoints;
598 }
3e87ef69 599}
600
4aa41877 601void AliHLTDataCompressor::SelectRemainingClusters()
3e87ef69 602{
603 //Select which remaining clusters to write in addition to the compressed data.
0a86fbb7 604 //In particular one can here make sure that "important" clusters are not missed:
605 //The offline track finder perform seed finding in the outer padrows;
606 //the first seeding is using pair of points on outermost padrow and
607 //0.125*nrows more rows towards the vertex. The second seeding uses pair
608 //of points on the outermost padrow-0.5*0.125*nrows and 0.125*nrows + 0.5*0.125*nrows
609 //more rows towards the vertex. In order to evaluate the seeds, the track offline
610 //track finder checks whether a certain amount of possible clusters (padrows) is
611 //attached to the track, and then the kalman filtering starts.
612 //To ensure a minimal loss off efficiency, all clusters in this region should be
613 //intact.....
614
3e87ef69 615 cout<<"Cleaning up clusters"<<endl;
4aa41877 616 Int_t nrows = AliHLTTransform::GetNRows();
3e87ef69 617 Int_t gap=(Int_t)(0.125*nrows), shift=(Int_t)(0.5*gap);
5b3f37f6 618
3e87ef69 619 for(Int_t slice=0; slice<36; slice++)
620 {
4aa41877 621 AliHLTSpacePointData *points = fClusters[slice][0];
3e87ef69 622 for(UInt_t i=0; i<fNcl[slice][0]; i++)
623 {
624 if(points[i].fCharge == 0) continue; //Already removed
625 Int_t padrow = (Int_t)points[i].fPadRow;
626
6f388e0d 627 //Check the widths (errors) of the cluster, and remove big bastards:
4aa41877 628 Float_t padw = sqrt(points[i].fSigmaY2) / AliHLTTransform::GetPadPitchWidth(AliHLTTransform::GetPatch(padrow));
629 Float_t timew = sqrt(points[i].fSigmaZ2) / AliHLTTransform::GetZWidth();
1f1942b8 630 if(padw >= 2.55 || timew >= 2.55)//Because we use 1 byte to store
6f388e0d 631 {
632 points[i].fCharge = 0;
633 continue;
634 }
635
3e87ef69 636 Float_t xyz[3] = {points[i].fX,points[i].fY,points[i].fZ};
637 Int_t sector,row;
4aa41877 638 AliHLTTransform::Slice2Sector(slice,padrow,sector,row);
639 AliHLTTransform::Global2Raw(xyz,sector,row);
3e87ef69 640
0a86fbb7 641 if(padrow >= nrows-1-gap-shift) continue;//save all the clusters in this region
642
3e87ef69 643 //if(padrow >= nrows-1-shift) continue;
644
645 //Save the clusters at the borders:
4aa41877 646 //if(xyz[1] < 3 || xyz[1] >= AliHLTTransform::GetNPads(padrow)-4)
0a86fbb7 647 // continue;
3e87ef69 648
649 //Save clusters on padrows used for offline seeding:
650 if(padrow == nrows - 1 || padrow == nrows - 1 - gap || //First seeding
651 padrow == nrows - 1 - shift || padrow == nrows - 1 - gap - shift) //Second seeding
652 continue;
653
654 //Cluster did not meet any of the above criteria, so disregard it:
655 points[i].fCharge = 0;
656 }
657 }
5b3f37f6 658
5b3f37f6 659}
660
4aa41877 661void AliHLTDataCompressor::CompressAndExpand(Bool_t arithmeticCoding)
3e87ef69 662{
663 //Read tracks/clusters from file, compress data and uncompress it. Write compression rates to file.
5a31e9df 664 if(fNoCompression)
665 return;
666
3e87ef69 667 cout<<"Compressing and expanding data"<<endl;
4aa41877 668 AliHLTCompress *comp = 0;
b4686276 669 if(arithmeticCoding)
4aa41877 670 comp = new AliHLTCompressAC(-1,-1,fPath,fWriteClusterShape,fEvent);
de3c3890 671 else
4aa41877 672 comp = new AliHLTCompress(-1,-1,fPath,fWriteClusterShape,fEvent);
3e87ef69 673 comp->CompressFile();
674 comp->ExpandFile();
675 comp->PrintCompRatio(fCompRatioFile);
676 delete comp;
b2a02bce 677
b2a02bce 678 ofstream &out = *fCompRatioFile;
4aa41877 679 out<<AliHLTDataCompressorHelper::GetNPadBits()<<' '<<AliHLTDataCompressorHelper::GetNTimeBits()<<' '
680 <<AliHLTDataCompressorHelper::GetNChargeBits()<<' '<<AliHLTDataCompressorHelper::GetNShapeBits()<<' '
681 <<AliHLTDataCompressorHelper::GetNPadBitsRemaining()<<' '<<AliHLTDataCompressorHelper::GetNTimeBitsRemaining()<<' '
682 <<AliHLTDataCompressorHelper::GetNShapeBitsRemaining()<<endl;
1f1942b8 683 /*
684 //Write the ratio between used and unused clusters to comp file:
b2a02bce 685 out<<fNusedClusters<<' '<<fNunusedClusters<<endl;
1f1942b8 686 */
3e87ef69 687}
688
689
4aa41877 690void AliHLTDataCompressor::RestoreData(Bool_t remainingOnly)
5b3f37f6 691{
692 //Restore the uncompressed data together with the remaining clusters,
693 //and write to a final cluster file which serves as an input to the
3e87ef69 694 //final offline tracker.
5b3f37f6 695
3e87ef69 696#ifndef use_aliroot
4aa41877 697 LOG(AliHLTLog::kError,"AliHLTDataCompressor::RestoreData","Version")
3e87ef69 698 <<"You have to compile with use_aliroot flag in order to use this function"<<ENDLOG;
699#else
700
701 cout<<"Restoring data"<<endl;
702
b4686276 703 const Int_t kmaxpoints=500000;
3e87ef69 704 TempCluster **clusters = new TempCluster*[36];
705 Int_t *ncl = new Int_t[36];
706 for(Int_t i=0; i<36; i++)
707 {
708 ncl[i]=0;
b4686276 709 clusters[i] = new TempCluster[kmaxpoints];
3e87ef69 710 }
711
b4686276 712 if(!remainingOnly)
713 ReadUncompressedData(clusters,ncl,kmaxpoints);
de3c3890 714
3e87ef69 715 if(fKeepRemaining)
b4686276 716 ReadRemaining(clusters,ncl,kmaxpoints);
bd53cfb7 717
3e87ef69 718 Char_t filename[1024];
5b3f37f6 719 sprintf(filename,"%s/digitfile.root",fPath);
720 TFile *rootfile = TFile::Open(filename);
721 rootfile->cd();
4aa41877 722 AliTPCParam *param = (AliTPCParam*)rootfile->Get(AliHLTTransform::GetParamName());
3e87ef69 723
5b3f37f6 724 AliTPCDigitsArray *darray = new AliTPCDigitsArray();
725 darray->Setup(param);
726 darray->SetClass("AliSimDigits");
4aa41877 727 sprintf(filename,"TreeD_%s_%d",AliHLTTransform::GetParamName(),fEvent);
5b3f37f6 728 Bool_t ok = darray->ConnectTree(filename);
729 if(!ok)
730 {
4aa41877 731 cerr<<"AliHLTDataCompressor::RestoreData : Problems connecting tree"<<endl;
5b3f37f6 732 return;
733 }
3e87ef69 734
735 fOutputFile->cd();
736
737 AliTPCClustersArray *carray = new AliTPCClustersArray();
738 carray->Setup(param);
739 carray->SetClusterType("AliTPCcluster");
740 carray->MakeTree();
5b3f37f6 741
3e87ef69 742 Int_t totcounter=0;
743 for(Int_t slice=0; slice<=35; slice++)
5b3f37f6 744 {
b4686276 745 TempCluster **clPt = new TempCluster*[kmaxpoints];
3e87ef69 746 cout<<"Sorting "<<ncl[slice]<<" clusters in slice "<<slice<<endl;
747 for(Int_t i=0; i<ncl[slice]; i++)
748 clPt[i] = &clusters[slice][i];
749
5a31e9df 750 if(fNusedClusters)
751 QSort(clPt,0,ncl[slice]);
3e87ef69 752
b4686276 753 //cout<<"padrow "<<clPt[i]->fPadrow<<" pad "<<clPt[i]->fPad<<" time "<<clPt[i]->fTime<<endl;
3e87ef69 754
755 Int_t falseid=0;
756 Int_t counter=0;
4aa41877 757 for(Int_t padrow=AliHLTTransform::GetFirstRow(-1); padrow<=AliHLTTransform::GetLastRow(-1); padrow++)
5b3f37f6 758 {
3e87ef69 759 Int_t sec,row;
4aa41877 760 AliHLTTransform::Slice2Sector(slice,padrow,sec,row);
3e87ef69 761 AliTPCClustersRow *clrow=carray->CreateRow(sec,row);
762 AliSimDigits *digits = (AliSimDigits*)darray->LoadRow(sec,row);
763 digits->ExpandBuffer();
764 digits->ExpandTrackBuffer();
4aa41877 765 Int_t patch = AliHLTTransform::GetPatch(padrow);
b4686276 766 while(counter < ncl[slice] && clPt[counter]->fPadrow == padrow)
5b3f37f6 767 {
3e87ef69 768 Float_t temp[3];
4aa41877 769 AliHLTTransform::Raw2Local(temp,sec,row,clPt[counter]->fPad,clPt[counter]->fTime);
3e87ef69 770
771 AliTPCcluster *c = new AliTPCcluster();
772 c->SetY(temp[1]);
773 c->SetZ(temp[2]);
b4686276 774 c->SetQ(clPt[counter]->fCharge);
3e87ef69 775
4aa41877 776 c->SetSigmaY2(clPt[counter]->fSigmaY2*pow(AliHLTTransform::GetPadPitchWidth(patch),2));
777 c->SetSigmaZ2(clPt[counter]->fSigmaZ2*pow(AliHLTTransform::GetZWidth(),2));
778 Int_t pad = AliHLTDataCompressorHelper::Nint(clPt[counter]->fPad);
779 Int_t time = AliHLTDataCompressorHelper::Nint(clPt[counter]->fTime);
5b3f37f6 780
3e87ef69 781 if(pad < 0)
782 pad=0;
4aa41877 783 if(pad >= AliHLTTransform::GetNPads(padrow))
784 pad = AliHLTTransform::GetNPads(padrow)-1;
785 if(time < 0 || time >= AliHLTTransform::GetNTimeBins())
3e87ef69 786 cerr<<"row "<<padrow<<" pad "<<pad<<" time "<<time<<endl;
bd53cfb7 787
3e87ef69 788 for(Int_t lab=0; lab<3; lab++)
bd53cfb7 789 {
3e87ef69 790 Int_t label = digits->GetTrackIDFast(time,pad,lab);
791 if(label > 1)
792 c->SetLabel(label-2,lab);
793 else if(label==0)
794 c->SetLabel(-2,lab);
795 else
796 c->SetLabel(-1,lab);
797 if(lab==0 && c->GetLabel(0) < 0)
bd53cfb7 798 {
3e87ef69 799 falseid++;
4aa41877 800 //AliHLTTransform::Local2Global(temp,slice);
3e87ef69 801 //cout<<"slice "<<slice<<" padrow "<<padrow<<" y "<<temp[1]<<" z "<<temp[2]<<" label "<<c->GetLabel(0)<<endl;
bd53cfb7 802 }
bd53cfb7 803 }
b4686276 804 //cout<<"row "<<padrow<<" pad "<<clPt[counter]->fPad<<" time "<<clPt[counter]->fTime<<" sigmaY2 "<<c->GetSigmaY2()<<" sigmaZ2 "<<c->GetSigmaZ2()<<endl;
3e87ef69 805 clrow->InsertCluster(c);
806 delete c;
807 counter++;
808 totcounter++;
809 }
810 carray->StoreRow(sec,row);
811 carray->ClearRow(sec,row);
812 darray->ClearRow(sec,row);
813 }
814 //cerr<<"Slice "<<slice<<" nclusters "<<counter<<" falseones "<<falseid<<endl;
815 if(counter != ncl[slice])
816 cerr<<"AliLDataCompressor::RestoreData : Mismatching cluster count :"<<counter<<" "<<ncl[slice]<<endl;
817 delete [] clPt;
818 }
819
820 cout<<"Writing "<<totcounter<<" clusters to rootfile "<<endl;
821
822 sprintf(filename,"TreeC_TPC_%d",fEvent);
823 carray->GetTree()->SetName(filename);
824 carray->GetTree()->Write();
825 delete carray;
826 delete darray;
827 rootfile->Close();
828
829 for(Int_t i=0; i<36; i++)
830 delete [] clusters[i];
831 delete [] clusters;
832 delete [] ncl;
833#endif
834}
835
4aa41877 836void AliHLTDataCompressor::ReadUncompressedData(TempCluster **clusters,Int_t *ncl,const Int_t kmaxpoints)
3e87ef69 837{
b4686276 838 // Reads uncompressed data
4aa41877 839 AliHLTCompress *comp = new AliHLTCompress(-1,-1,fPath,fWriteClusterShape,fEvent);
5a31e9df 840 if(fNoCompression)
841 {
842 cout<<endl<<"Reading unmodified data, no compression has been done here!!!!"<<endl<<endl;
843 comp->ReadFile('m');//Read the unmodified data (no compression has been done).
844 }
845 else
846 {
847 cout<<"Reading uncompressed tracks "<<endl;
848 comp->ReadFile('u');
849 }
3e87ef69 850
4aa41877 851 AliHLTTrackArray *tracks = comp->GetTracks();
3e87ef69 852
de3c3890 853 //Float_t totcounter=0,pcounter=0,tcounter=0;
3e87ef69 854 Int_t charge;
855 Float_t pad,time,sigmaY2,sigmaZ2;
856 for(Int_t i=0; i<tracks->GetNTracks(); i++)
857 {
4aa41877 858 AliHLTModelTrack *track = (AliHLTModelTrack*)tracks->GetCheckedTrack(i);
3e87ef69 859 if(!track) continue;
4aa41877 860 for(Int_t padrow=0; padrow < AliHLTTransform::GetNRows(-1); padrow++)
3e87ef69 861 {
862 if(!track->IsPresent(padrow)) continue;
863 track->GetPad(padrow,pad);
864 track->GetTime(padrow,time);
865 track->GetClusterCharge(padrow,charge);
1f1942b8 866 track->GetSigmaY2(padrow,sigmaY2);
867 track->GetSigmaZ2(padrow,sigmaZ2);
3e87ef69 868 Int_t slice = track->GetClusterModel(padrow)->fSlice;
869 /*
4aa41877 870 if(pad < -1 || pad > AliHLTTransform::GetNPads(padrow) || time < -1 || time > AliHLTTransform::GetNTimeBins())
3e87ef69 871 {
4aa41877 872 cerr<<"AliHLTDataCompressor::ReadUncompressData : Wrong pad "<<pad<<" or time "<<time<<" on row "<<padrow<<" track index "<<i<<endl;
3e87ef69 873 track->Print();
874 exit(5);
875 }
876 */
b4686276 877 if(ncl[slice] >= kmaxpoints)
3e87ef69 878 {
4aa41877 879 cerr<<"AliHLTDataCompressor::ReadUncompressedData : Too many clusters"<<endl;
3e87ef69 880 exit(5);
881 }
b4686276 882 clusters[slice][ncl[slice]].fPad = pad;
883 clusters[slice][ncl[slice]].fTime = time;
884 clusters[slice][ncl[slice]].fCharge = charge;
885 clusters[slice][ncl[slice]].fSigmaY2 = sigmaY2;
886 clusters[slice][ncl[slice]].fSigmaZ2 = sigmaZ2;
887 clusters[slice][ncl[slice]].fPadrow = padrow;
3e87ef69 888 //cout<<"row "<<padrow<<" pad "<<pad<<" time "<<time<<" charge "<<charge<<" sigmas "<<sigmaY2<<" "<<sigmaZ2<<endl;
889 ncl[slice]++;
890 }
891 }
3e87ef69 892 delete comp;
893}
894
4aa41877 895void AliHLTDataCompressor::ReadRemaining(TempCluster **clusters,Int_t *ncl,const Int_t kmaxpoints)
3e87ef69 896{
b4686276 897 // reads remaining clusters
3e87ef69 898 cout<<"Reading remaining clusters "<<endl;
5a31e9df 899 if(!fNoCompression)
900 {
4aa41877 901 AliHLTCompress *comp = new AliHLTCompress(-1,-1,fPath,fWriteClusterShape,fEvent);
b4686276 902 comp->ExpandRemaining(clusters,ncl,kmaxpoints);
5a31e9df 903 delete comp;
904 return;
905 }
906 else
907 {
4aa41877 908 AliHLTMemHandler mem;
5a31e9df 909 Char_t filename[1024];
910 for(Int_t slice=0; slice<=35; slice++)
911 {
912 for(Int_t p=0; p<1; p++)
913 {
914 sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,slice,-1);
915
916 mem.SetBinaryInput(filename);
4aa41877 917 AliHLTRemainingRow *tempPt = (AliHLTRemainingRow*)mem.Allocate();
5a31e9df 918
919 Int_t nrows=0;
920 FILE *infile = mem.GetFilePointer();
921 while(!feof(infile))
922 {
923 Byte_t *dPt = (Byte_t*)tempPt;
4aa41877 924 if(fread(tempPt,sizeof(AliHLTRemainingRow),1,infile)!=1) break;
5a31e9df 925
4aa41877 926 dPt += sizeof(AliHLTRemainingRow);
5a31e9df 927
4aa41877 928 Int_t size = sizeof(AliHLTRemainingCluster)*tempPt->fNClusters;
5a31e9df 929
930 fread(dPt,size,1,infile);
931 dPt += size;
4aa41877 932 tempPt = (AliHLTRemainingRow*)dPt;
5a31e9df 933 nrows++;
934 }
935
936 mem.CloseBinaryInput();
937 UInt_t dummy;
4aa41877 938 tempPt = (AliHLTRemainingRow*)mem.GetDataPointer(dummy);
5a31e9df 939
940 for(Int_t i=0; i<nrows; i++)
941 {
4aa41877 942 AliHLTRemainingCluster *points = tempPt->fClusters;
5a31e9df 943 Int_t padrow = (Int_t)tempPt->fPadRow;
944 //Int_t sector,row;
4aa41877 945 //AliHLTTransform::Slice2Sector(slice,padrow,sector,row);
5a31e9df 946 //cout<<"Loading slice "<<slice<<" row "<<padrow<<" with "<<(Int_t)tempPt->fNClusters<<" clusters "<<endl;
947 for(Int_t j=0; j<tempPt->fNClusters; j++)
948 {
949
4aa41877 950 //Float_t xyz[3] = {AliHLTTransform::Row2X(padrow),points[j].fY,points[j].fZ};
951 //AliHLTTransform::Local2Raw(xyz,sector,row);
5a31e9df 952
b4686276 953 if(ncl[slice] >= kmaxpoints)
5a31e9df 954 {
4aa41877 955 cerr<<"AliHLTDataCompressor::ReadRemaining : Too many clusters"<<endl;
5a31e9df 956 exit(5);
957 }
958 //cout<<"slice "<<slice<<" padrow "<<padrow<<" pad "<<xyz[1]<<" time "<<xyz[2]<<endl;
b4686276 959 clusters[slice][ncl[slice]].fPad = points[j].fPad;
960 clusters[slice][ncl[slice]].fTime = points[j].fTime;
961 clusters[slice][ncl[slice]].fCharge = points[j].fCharge;
962 clusters[slice][ncl[slice]].fSigmaY2 = points[j].fSigmaY2;
963 clusters[slice][ncl[slice]].fSigmaZ2 = points[j].fSigmaZ2;
964 clusters[slice][ncl[slice]].fPadrow = padrow;
965 //cout<<"padrow "<<padrow<<" pad "<<clusters[slice][ncl[slice]].fPad<<" time "<<clusters[slice][ncl[slice]].fTime<<" charge "<<clusters[slice][ncl[slice]].fCharge<<" widths "<<clusters[slice][ncl[slice]].fSigmaY2<<" "<<clusters[slice][ncl[slice]].fSigmaZ2<<endl;
5a31e9df 966 ncl[slice]++;
967 }
968 Byte_t *dPt = (Byte_t*)tempPt;
4aa41877 969 Int_t size = sizeof(AliHLTRemainingRow) + tempPt->fNClusters*sizeof(AliHLTRemainingCluster);
5a31e9df 970 dPt += size;
4aa41877 971 tempPt = (AliHLTRemainingRow*)dPt;
5a31e9df 972 }
973
974 mem.Free();
975 }
976 }
977 }
3e87ef69 978}
979
4aa41877 980void AliHLTDataCompressor::QSort(TempCluster **a, Int_t first, Int_t last)
3e87ef69 981{
b4686276 982 // Implementation of quick sort
3e87ef69 983 static TempCluster *tmp;
984 static int i; // "static" to save stack space
985 int j;
986
987 while (last - first > 1) {
988 i = first;
989 j = last;
990 for (;;) {
991 while (++i < last && Compare(a[i], a[first]) < 0)
992 ;
993 while (--j > first && Compare(a[j], a[first]) > 0)
994 ;
995 if (i >= j)
996 break;
997
998 tmp = a[i];
999 a[i] = a[j];
1000 a[j] = tmp;
1001 }
1002 if (j == first) {
1003 ++first;
1004 continue;
1005 }
1006 tmp = a[first];
1007 a[first] = a[j];
1008 a[j] = tmp;
1009 if (j - first < last - (j + 1)) {
1010 QSort(a, first, j);
1011 first = j + 1; // QSort(j + 1, last);
1012 } else {
1013 QSort(a, j + 1, last);
1014 last = j; // QSort(first, j);
1015 }
1016 }
1017}
1018
4aa41877 1019Int_t AliHLTDataCompressor::Compare(TempCluster *a,TempCluster *b)
3e87ef69 1020{
b4686276 1021 // compares two clusters
1022 if(a->fPadrow < b->fPadrow) return -1;
1023 if(a->fPadrow > b->fPadrow) return 1;
3e87ef69 1024
b4686276 1025 if(rint(a->fPad) == rint(b->fPad) && rint(a->fTime) == rint(b->fTime)) return 0;
5b3f37f6 1026
b4686276 1027 if(rint(a->fPad) < rint(b->fPad)) return -1;
1028 if(rint(a->fPad) == rint(b->fPad) && rint(a->fTime) < rint(b->fTime)) return -1;
5b3f37f6 1029
3e87ef69 1030 return 1;
5b3f37f6 1031}
1032