3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ALICE HLT Group
6 #include "AliL3StandardIncludes.h"
8 #include <AliTPCParamSR.h>
9 #include <AliTPCClustersArray.h>
10 #include <AliTPCcluster.h>
11 #include <AliTPCClustersRow.h>
14 #include <AliTPCcluster.h>
15 #include <AliTPCtracker.h>
16 #include <AliTPCclusterMI.h>
17 #include <AliTPCtrackerMI.h>
18 #include <AliKalmanTrack.h>
24 #include <TDirectory.h>
28 #include "AliL3Transform.h"
29 #include "AliL3ModelTrack.h"
30 #include "AliL3Compress.h"
31 #include "AliL3TrackArray.h"
34 #include "AliL3OfflineDataCompressor.h"
40 //_____________________________________________________________
42 // AliL3OfflineDataCompression
46 ClassImp(AliL3OfflineDataCompressor)
48 AliL3OfflineDataCompressor::AliL3OfflineDataCompressor()
54 AliL3OfflineDataCompressor::AliL3OfflineDataCompressor(Char_t *path,Bool_t keep,Bool_t writeshape,Bool_t MI)
55 : AliL3DataCompressor(path,keep,writeshape)
61 AliL3OfflineDataCompressor::~AliL3OfflineDataCompressor()
65 fTracker->UnloadClusters();
71 void AliL3OfflineDataCompressor::LoadData(Int_t event,Bool_t sp)
73 //Take offline reconstructed tracks as an input.
74 //In this case, no remaining clusters are written.
78 fTracker->UnloadClusters();
86 AliKalmanTrack::SetConvConst(1000/0.299792458/AliL3Transform::GetSolenoidField());
88 sprintf(filename,"%s/offline/AliTPCclusters.root",fPath);
90 sprintf(filename,"%s/offline/AliTPCclustersMI.root",fPath);
95 cout<<"AliL3OfflineDataCompressor::LoadData : Taking compressed offline files!!"<<endl;
96 sprintf(filename,"%s/comp/offline/AliTPCclusters.root",fPath);
98 TFile *in = TFile::Open(filename);
99 AliTPCParam *param=(AliTPCParam*)in->Get("75x40_100x60_150x60");
102 fTracker = new AliTPCtracker(param);
104 fTracker = new AliTPCtrackerMI(param);
105 fTracker->SetEventNumber(event);
107 fTracker->LoadClusters();
112 AliTPCtrackerMI *mitracker = (AliTPCtrackerMI*)fTracker;
113 mitracker->LoadInnerSectors();
114 mitracker->LoadOuterSectors();
118 const Int_t MAX=20000;
119 Int_t nentr=0,i=0; TObjArray tarray(MAX);
121 sprintf(filename,"%s/offline/AliTPCtracks.root",fPath);
123 sprintf(filename,"%s/offline/AliTPCtracksMI.root",fPath);
126 sprintf(filename,"%s/comp/offline/AliTPCtracks.root",fPath);
128 TFile *tf=TFile::Open(filename);
130 char tname[100]; sprintf(tname,"TreeT_TPC_%d",event);
131 TTree *tracktree=(TTree*)tf->Get(tname);
133 TBranch *tbranch=tracktree->GetBranch("tracks");
134 nentr=(Int_t)tracktree->GetEntries();
135 AliTPCtrack *iotrack=0;
137 for (i=0; i<nentr; i++) {
138 iotrack=new AliTPCtrack;
139 tbranch->SetAddress(&iotrack);
140 tracktree->GetEvent(i);
141 tarray.AddLast(iotrack);
146 AliL3TrackArray *comptracks = new AliL3TrackArray("AliL3ModelTrack");
147 cout<<"Loaded "<<nentr<<" offline tracks"<<endl;
151 for(i=0; i<nentr; i++)
154 AliTPCtrack *track=(AliTPCtrack*)tarray.UncheckedAt(i);
155 Int_t nhits = track->GetNumberOfClusters();
156 Int_t idx = track->GetClusterIndex(nhits-1);
157 Int_t sec=(idx&0xff000000)>>24, row=(idx&0x00ff0000)>>16;
160 TPC sector numbering within the AliTPCtracker class:
161 There are in total 18 inner sectors and 18 outer sectors.
162 This means that one sector includes _both_ sides of the TPC.
163 Example: sec=0 -> sector 0 and 18.
164 sec=18 -> sector 36 and 54
171 AliL3Transform::Sector2Slice(slice,padrow,sec,row);
172 Double_t par[5],xk=AliL3Transform::Row2X(padrow);
173 track->PropagateTo(xk);
174 track->GetExternalParameters(xk,par);
175 Double_t psi = TMath::ASin(par[2]) + track->GetAlpha();
176 if (psi<-TMath::Pi()) psi+=2*TMath::Pi();
177 if (psi>=TMath::Pi()) psi-=2*TMath::Pi();
178 Float_t pt_1=TMath::Abs(par[4]);
186 fcl= fTracker->GetCluster(idx);
189 AliTPCtrackerMI *mitracker = (AliTPCtrackerMI*)fTracker;
190 fcl = mitracker->GetClusterMI(idx);
196 AliL3Transform::Local2Global(first,slice);
198 AliL3ModelTrack *outtrack = (AliL3ModelTrack*)comptracks->NextTrack();
199 outtrack->SetNHits(nhits);
200 outtrack->SetFirstPoint(first[0],first[1],first[2]);
201 outtrack->SetPt(1/pt_1);
202 outtrack->SetPsi(psi);
203 outtrack->SetTgl(par[3]);
204 outtrack->SetCharge(charge);
205 outtrack->CalculateHelix();
206 outtrack->Init(0,-1);
208 //cout<<"Loading track with "<<nhits<<" hits"<<endl;
209 for(int j=nhits-1; j>=0; j--)
212 Int_t index = track->GetClusterIndex(j);
217 Int_t clustercharge =0;
219 //AliTPCcluster *cluster = (AliTPCcluster*)tracker->GetCluster(index);
220 AliCluster *cluster=0;
223 cluster = fTracker->GetCluster(index);
226 AliTPCtrackerMI *mitracker = (AliTPCtrackerMI*)fTracker;
227 cluster = mitracker->GetClusterMI(index);
230 xyz[1] = cluster->GetY();
231 xyz[2] = cluster->GetZ();
234 AliTPCcluster *cl = (AliTPCcluster*)cluster;
235 clustercharge = (Int_t)cl->GetQ();
239 AliTPCclusterMI *cl = (AliTPCclusterMI*)cluster;
240 clustercharge = (Int_t)cl->GetQ();
245 sec=(index&0xff000000)>>24; row=(index&0x00ff0000)>>16;
256 //cout<<"sector "<<sec<<" row "<<row<<endl;
257 if(!AliL3Transform::Sector2Slice(slice,padrow,sec,row))
259 xyz[0] = AliL3Transform::Row2X(padrow);
261 //cout<<"Hit in slice "<<slice<<" padrow "<<padrow<<" index "<<index<<" y "<<cluster->GetY()<<" z "<<cluster->GetZ()<<endl;
262 AliL3Transform::Local2Raw(xyz,sec,row);
263 //cout<<"slice "<<slice<<" padrow "<<padrow<<" pad "<<xyz[1]<<" time "<<xyz[2]<<endl;
265 if(xyz[1] < -1 || xyz[1] > AliL3Transform::GetNPads(padrow) ||
266 xyz[2] < -1 || xyz[2] > AliL3Transform::GetNTimeBins())
268 cerr<<"AliL3DataCompressor::FillOfflineData : Wrong time "<<xyz[2]<<" in slice "
269 <<slice<<" padrow "<<padrow<<endl;
270 cout<<"sector "<<sec<<" row "<<row<<endl;
271 //cout<<"Hit in slice "<<slice<<" padrow "<<padrow<<" y "<<cluster->GetY()<<" z "<<cluster->GetZ()<<endl;
272 cout<<"Track hit "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
277 AliL3Transform::Local2GlobalAngle(&angle,slice);
278 if(!outtrack->CalculateReferencePoint(angle,AliL3Transform::Row2X(padrow)))
280 cerr<<"AliL3DataCompressor::FillOfflineData : Error in crossing point calc on slice "
281 <<slice<<" row "<<padrow<<endl;
285 Float_t xyz_cross[3] = {outtrack->GetPointX(),outtrack->GetPointY(),outtrack->GetPointZ()};
286 AliL3Transform::Global2Raw(xyz_cross,sec,row);
288 if(fabs(xyz_cross[1] - xyz[1]) > 10 ||
289 fabs(xyz_cross[2] - xyz[2]) > 10)
291 cout<<"AliL3DataCompressor::FillOfflineData : Wrong crossing slice "<<slice<<" padrow "
292 <<padrow<<" pad "<<xyz[1]<<" padhit "<<xyz_cross[1]<<" time "<<xyz[2]<<" timehit "<<xyz_cross[2]<<endl;
297 //cout<<" crossing "<<xyz_cross[0]<<" "<<xyz_cross[1]<<" "<<xyz_cross[2]<<endl;
298 outtrack->SetPadHit(padrow,xyz_cross[1]);
299 outtrack->SetTimeHit(padrow,xyz_cross[2]);
301 if(fWriteClusterShape)
303 Float_t angle = outtrack->GetCrossingAngle(padrow,slice);
304 outtrack->SetCrossingAngleLUT(padrow,angle);
305 outtrack->CalculateClusterWidths(padrow,kTRUE);
306 Int_t patch = AliL3Transform::GetPatch(padrow);
307 Float_t sigmaY2 = cluster->GetSigmaY2() / pow(AliL3Transform::GetPadPitchWidth(patch),2);
308 Float_t sigmaZ2 = cluster->GetSigmaZ2() / pow(AliL3Transform::GetZWidth(),2);
309 outtrack->SetCluster(padrow,xyz[1],xyz[2],clustercharge,sigmaY2,sigmaZ2,3);
312 outtrack->SetCluster(padrow,xyz[1],xyz[2],clustercharge,0,0,3);
314 outtrack->GetClusterModel(padrow)->fSlice = slice;
319 cout<<"AliL3DataCompressor::FillOfflineData : Wrote "<<totcounter<<" clusters"<<endl;
320 //Write tracks to file
321 AliL3Compress *comp = new AliL3Compress(-1,-1,fPath,fWriteClusterShape,fEvent);
322 comp->WriteFile(comptracks);
328 void AliL3OfflineDataCompressor::WriteRemaining(Bool_t select)
330 //Write remaining clusters (not assigned to any tracks) to file
336 SelectRemainingClusters();
338 Char_t filename[1024];
342 cerr<<"AliL3OfflineDataCompressor::WriteRemaining : You have to modify this function when not running singlepatch"<<endl;
349 sprintf(filename,"%s/comp/remains_ids.txt",fPath);
350 idfile.open(filename);
353 cout<<"Writing remaining clusters "<<endl;
354 Int_t nrows = AliL3Transform::GetNRows(),sector,row,sec;
356 AliTPCtracker *tracker = (AliTPCtracker*)fTracker;
358 for(Int_t slice=0; slice<=35; slice++)
360 sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,slice,-1);
361 BIT_FILE *output = OpenOutputBitFile(filename);
364 cerr<<"AliL3OfflineDataCompressor::WriteRemaining : Cannot open file "<<filename<<endl;
368 //Write number of padrows with clusters
369 OutputBits(output,nrows,8);
371 for(Int_t padrow=0; padrow < nrows; padrow++)
373 AliL3Transform::Slice2Sector(slice,padrow,sector,row);
376 if(fMarian == kFALSE)
383 //cout<<"Getting clusters in sector "<<sec<<" row "<<row<<endl;
386 ncl = tracker->GetNClusters(sec,row);
393 AliTPCcluster *cluster = 0;
395 cluster=(AliTPCcluster*)tracker->GetCluster(sec,row,j);
397 if(cluster->GetZ() < 0 && slice < 18) continue;
398 if(cluster->GetZ() > 0 && slice > 17) continue;
399 if(cluster->IsUsed())
404 OutputBits(output,padrow,8);//Write padrow #
405 OutputBits(output,counter,10);//Write number of clusters on this padrow
407 //cout<<"Found "<<counter<<" unused out of "<<ncl<<" clusters on slice "<<slice<<" padrow "<<padrow<<endl;
410 AliTPCcluster *cluster = 0;
412 cluster=(AliTPCcluster*)tracker->GetCluster(sec,row,j);
414 if(cluster->GetZ() < 0 && slice < 18) continue;
415 if(cluster->GetZ() > 0 && slice > 17) continue;
416 if(cluster->IsUsed())
420 idfile << cluster->GetLabel(0)<<' ';
422 Float_t xyz[3] = {AliL3Transform::Row2X(padrow),cluster->GetY(),cluster->GetZ()};
423 AliL3Transform::Local2Raw(xyz,sector,row);
425 Int_t patch = AliL3Transform::GetPatch(padrow);
426 Float_t padw = cluster->GetSigmaY2()/pow(AliL3Transform::GetPadPitchWidth(patch),2);
427 Float_t timew = cluster->GetSigmaZ2()/pow(AliL3Transform::GetZWidth(),2);
431 buff = (Int_t)rint(xyz[1]*10);
434 cerr<<"AliL3OfflineDataCompressor:WriteRemaining : Wrong pad value "<<buff<<endl;
437 OutputBits(output,buff,11);
440 buff = (Int_t)rint(xyz[2]*10);
443 cerr<<"AliL3OfflineDataCompressor:WriteRemaining : Wrong time value "<<buff<<endl;
446 OutputBits(output,buff,13);
449 buff = (Int_t)rint(padw*100);
450 OutputBits(output,buff,8);
451 buff = (Int_t)rint(timew*100);
452 OutputBits(output,buff,8);
455 buff = (Int_t)cluster->GetQ();
458 OutputBits(output,buff,14);
463 CloseOutputBitFile(output);
472 void AliL3OfflineDataCompressor::SelectRemainingClusters()
475 cout<<"Cleaning up clusters"<<endl;
476 Int_t nrows = AliL3Transform::GetNRows();
477 Int_t gap=(Int_t)(0.125*nrows), shift=(Int_t)(0.5*gap);
479 Int_t sector,row,sec;
482 AliTPCtracker *tracker = (AliTPCtracker*)fTracker;
484 for(Int_t slice=0; slice<36; slice++)
486 for(Int_t padrow=0; padrow < nrows; padrow++)
489 AliL3Transform::Slice2Sector(slice,padrow,sector,row);
492 if(fMarian == kFALSE)
501 ncl=tracker->GetNClusters(sec,row);
503 for(Int_t j=0; j<ncl; j++)
505 AliTPCcluster *cluster = 0;
507 cluster = (AliTPCcluster*)tracker->GetCluster(sec,row,j);
509 if(cluster->IsUsed())
512 //Check the widths (errors) of the cluster, and remove big bastards:
513 Float_t xyw = cluster->GetSigmaY2() / pow(AliL3Transform::GetPadPitchWidth(AliL3Transform::GetPatch(padrow)),2);
514 Float_t zw = cluster->GetSigmaZ2() / pow(AliL3Transform::GetZWidth(),2);
515 if(xyw >= 2.55 || zw >= 2.55)//Because we use 1 byte to store
521 //if(padrow >= nrows-1-gap-shift) continue;//save all the clusters in this region
523 if(padrow == nrows - 1 || padrow == nrows - 1 - gap || //First seeding
524 padrow == nrows - 1 - shift || padrow == nrows - 1 - gap - shift) //Second seeding
527 if(cluster->GetZ() < 0 && slice < 18) continue;
528 if(cluster->GetZ() > 0 && slice > 17) continue;
529 if(cluster->IsUsed())