3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ASV
6 #include "AliL3StandardIncludes.h"
11 #include <TClonesArray.h>
15 #include <AliSimDigits.h>
17 #include <AliTPCcluster.h>
18 #include <AliTPCClustersArray.h>
19 #include <AliTPCClustersRow.h>
20 #include <AliTPCParam.h>
21 #include <AliComplexCluster.h>
30 #include "AliL3Logging.h"
31 #include "AliL3Transform.h"
32 #include "AliL3SpacePointData.h"
33 #include "AliL3Track.h"
34 #include "AliL3FileHandler.h"
35 #include "AliL3TrackArray.h"
36 #include "AliL3Evaluate.h"
42 //_____________________________________________________________
45 // Evaluation class for tracking. Plots efficiencies etc..
49 ClassImp(AliL3Evaluate)
51 AliL3Evaluate::AliL3Evaluate()
62 AliL3Evaluate::AliL3Evaluate(Char_t *datapath,Int_t min_clusters,Int_t minhits,Double_t minpt,Int_t *slice)
75 fMaxFalseClusters = 0.1;
78 fMinPointsOnTrack = min_clusters;
79 fMinHitsFromParticle = minhits;
82 AliL3FileHandler *clusterfile[36][6];
83 for(Int_t s=fMinSlice; s<=fMaxSlice; s++)
85 for(Int_t p=0; p<AliL3Transform::GetNPatches(); p++)
88 clusterfile[s][p] = new AliL3FileHandler();
89 sprintf(fname,"%s/points_%d_%d.raw",datapath,s,p);
90 if(!clusterfile[s][p]->SetBinaryInput(fname))
92 LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open")
93 <<"Inputfile "<<fname<<" does not exist"<<ENDLOG;
94 delete clusterfile[s][p];
95 clusterfile[s][p] = 0;
98 fClusters[s][p] = (AliL3SpacePointData*)clusterfile[s][p]->Allocate();
99 clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]);
100 clusterfile[s][p]->CloseBinaryInput();
104 sprintf(fname,"%s/tracks.raw",datapath);
105 AliL3FileHandler *tfile = new AliL3FileHandler();
106 if(!tfile->SetBinaryInput(fname)){
107 LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open")
108 <<"Inputfile "<<fname<<" does not exist"<<ENDLOG;
111 fTracks = new AliL3TrackArray();
112 tfile->Binary2TrackArray(fTracks);
113 tfile->CloseBinaryInput();
118 AliL3Evaluate::~AliL3Evaluate()
120 if(fGoodTracks) delete fGoodTracks;
121 if(fDigitsTree) fDigitsTree->Delete();
122 if(fTracks) delete fTracks;
123 if(fPtRes) delete fPtRes;
124 if(fNGoodTracksPt) delete fNGoodTracksPt;
125 if(fNFoundTracksPt) delete fNFoundTracksPt;
126 if(fNFakeTracksPt) delete fNFakeTracksPt;
127 if(fTrackEffPt) delete fTrackEffPt;
128 if(fFakeTrackEffPt) delete fFakeTrackEffPt;
129 if(fNGoodTracksEta) delete fNGoodTracksEta;
130 if(fNFoundTracksEta) delete fNFoundTracksEta;
131 if(fNFakeTracksEta) delete fNFakeTracksEta;
132 if(fTrackEffEta) delete fTrackEffEta;
133 if(fFakeTrackEffEta) delete fFakeTrackEffEta;
134 if(fMcIndex) delete [] fMcIndex;
135 if(fMcId) delete [] fMcId;
136 if(fNtuppel) delete fNtuppel;
140 void AliL3Evaluate::AssignIDs()
142 //Assign MC id to the tracks.
144 cerr<<"AliL3Evaluate::AssignIDs() : You need to compile with the do_mc flag!"<<endl;
149 LOG(AliL3Log::kDebug,"AliL3Evaluate::AssignIDs","Track Loop")
150 <<"Assigning MC id to the found tracks...."<<ENDLOG;
151 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
153 AliL3Track *track = (AliL3Track*)fTracks->GetCheckedTrack(i);
155 if(track->GetNumberOfPoints() < fMinPointsOnTrack) break;
158 Int_t tID = GetMCTrackLabel(track);
161 cout<<"Found "<<fGoodFound<<" good tracks "<<endl;
165 struct S {Int_t lab; Int_t max;};
166 Int_t AliL3Evaluate::GetMCTrackLabel(AliL3Track *track){
167 //Returns the MCtrackID of the belonging clusters.
168 //If MCLabel < 0, means that track is fake.
169 //Fake track means that more than 10 percent of clusters are assigned incorrectly.
172 Int_t num_of_clusters = track->GetNumberOfPoints();
173 S *s=new S[num_of_clusters];
175 for (i=0; i<num_of_clusters; i++) s[i].lab=s[i].max=0;
176 UInt_t *hitnum = track->GetHitNumbers();
180 for (i=0; i<num_of_clusters; i++)
182 //Tricks to get the clusters belonging to this track:
184 Int_t slice = (id>>25) & 0x7f;
185 Int_t patch = (id>>22) & 0x7;
186 UInt_t pos = id&0x3fffff;
188 AliL3SpacePointData *points = fClusters[slice][patch];
189 if(!points) continue;
190 if(pos>=fNcl[slice][patch])
192 LOG(AliL3Log::kError,"AliL3Evaluate::GetMCTrackLabel","Clusterarray")
193 <<AliL3Log::kDec<<"ERROR"<<ENDLOG;
197 //Get the label of the cluster:
199 lab=abs(points[pos].fTrackID[0]);
201 cout<<"Track had negative id : "<<lab<<" padrow "<<(Int_t)points[pos].fPadRow<<" nhits "<<num_of_clusters<<" pt "<<track->GetPt()<<endl;
204 for (j=0; j<num_of_clusters; j++)
205 if (s[j].lab==lab || s[j].max==0) break;
211 for (i=0; i<num_of_clusters; i++)
212 if (s[i].max>max) {max=s[i].max; lab=s[i].lab;}
216 for (i=0; i<num_of_clusters; i++)
219 Int_t slice = (id>>25) & 0x7f;
220 Int_t patch = (id>>22) & 0x7;
221 UInt_t pos = id&0x3fffff;
223 AliL3SpacePointData *points = fClusters[slice][patch];
224 if(!points) continue;
225 if(pos>=fNcl[slice][patch])
227 LOG(AliL3Log::kError,"AliL3Evaluate::GetMCTrackLabel","Clusterarray")
228 <<AliL3Log::kDec<<"ERROR"<<ENDLOG;
232 if (abs(points[pos].fTrackID[1]) == lab ||
233 abs(points[pos].fTrackID[2]) == lab ) max++;
236 if (1.-Float_t(max)/num_of_clusters > fMaxFalseClusters)
242 #else //If we are running with mc_ids or not
248 void AliL3Evaluate::GetFastClusterIDs(Char_t *path)
250 //Get the MC id of space points in case of using the fast simulator.
252 sprintf(fname,"%s/point_mc.dat",path);
253 FILE *infile = fopen(fname,"r");
258 if(fscanf(infile,"%d %d",&hitid,&hitmc)==EOF) break;
261 fMcId = new Int_t[fNFastPoints];
262 fMcIndex = new UInt_t[fNFastPoints];
264 for(i=0; i<fNFastPoints; i++)
266 if(fscanf(infile,"%d %d",&hitid,&hitmc)==EOF) break;
273 void AliL3Evaluate::CreateHistos(Int_t nbin,Float_t xlow,Float_t xup)
275 //Create the histograms
277 LOG(AliL3Log::kInformational,"AliL3Evaluate::CreateHistos","Allocating")
278 <<"Creating histograms..."<<ENDLOG;
280 fNtuppel = new TNtuple("fNtuppel","Pt resolution","pt_gen:pt_found:nHits");
281 fNtuppel->SetDirectory(0);
282 fPtRes = new TH1F("fPtRes","Relative Pt resolution",30,-10.,10.);
283 fNGoodTracksPt = new TH1F("fNGoodTracksPt","Good tracks vs pt",nbin,xlow,xup);
284 fNFoundTracksPt = new TH1F("fNFoundTracksPt","Found tracks vs pt",nbin,xlow,xup);
285 fNFakeTracksPt = new TH1F("fNFakeTracksPt","Fake tracks vs pt",nbin,xlow,xup);
286 fTrackEffPt = new TH1F("fTrackEffPt","Tracking efficiency vs pt",nbin,xlow,xup);
287 fFakeTrackEffPt = new TH1F("fFakeTrackEffPt","Efficiency for fake tracks vs pt",nbin,xlow,xup);
289 fNGoodTracksEta = new TH1F("fNGoodTracksEta","Good tracks vs eta",20,-50,50);
290 fNFoundTracksEta = new TH1F("fNFoundTracksEta","Found tracks vs eta",20,-50,50);
291 fNFakeTracksEta = new TH1F("fNFakeTracksEta","Fake tracks vs eta",20,-50,50);
292 fTrackEffEta = new TH1F("fTrackEffEta","Tracking efficienct vs eta",20,-50,50);
293 fFakeTrackEffEta = new TH1F("fFakeTrackEffEta","Efficiency for fake tracks vs eta",20,-50,50);
297 void AliL3Evaluate::GetGoodParticles(Char_t *path,Bool_t sector)
299 //Read the good particles from file. This file should already have been
300 //generated by macro AliTPCComparison.C.
302 Char_t filename[1024];
304 sprintf(filename,"%s/good_tracks_tpc",path);
306 sprintf(filename,"%s/good_tracks_tpc_sector",path);//Sectorwise comparison.
307 ifstream in(filename);
310 cerr<<"AliL3Evaluate::GetGoodParticles : Problems opening file :"<<filename<<endl;
313 Int_t MaxTracks=20000;
314 fGoodTracks = new GoodTrack[MaxTracks];
316 while (in>>fGoodTracks[fGoodGen].label>>fGoodTracks[fGoodGen].code>>
317 fGoodTracks[fGoodGen].px>>fGoodTracks[fGoodGen].py>>fGoodTracks[fGoodGen].pz>>
318 fGoodTracks[fGoodGen].x>>fGoodTracks[fGoodGen].y >>fGoodTracks[fGoodGen].z>>fGoodTracks[fGoodGen].nhits>>fGoodTracks[fGoodGen].sector)
322 if (fGoodGen==MaxTracks)
324 cerr<<"AliL3Evaluate::GetGoodParticles : Too many good tracks !\n";
331 void AliL3Evaluate::FillEffHistos()
335 cerr<<"AliL3Evaluate::FillEffHistos : No good tracks"<<endl;
338 cout<<"Comparing "<<fGoodGen<<" good tracks ..."<<endl;
339 for(Int_t i=0; i<fGoodGen; i++)
341 //cout<<"Checking particle "<<i<<endl;
342 if(fGoodTracks[i].nhits < fMinHitsFromParticle) continue;
343 Float_t ptg = TMath::Sqrt(fGoodTracks[i].px*fGoodTracks[i].px + fGoodTracks[i].py*fGoodTracks[i].py);
344 if(ptg < fMinGoodPt) continue;
345 Float_t pzg=fGoodTracks[i].pz;
346 Float_t dipangle=TMath::ATan2(pzg,ptg)*180./TMath::Pi();
348 fNGoodTracksPt->Fill(ptg);
349 fNGoodTracksEta->Fill(dipangle);
352 for(Int_t k=0; k<fTracks->GetNTracks(); k++)
354 AliL3Track *track = fTracks->GetCheckedTrack(k);
356 Int_t nHits = track->GetNumberOfPoints();
357 if(nHits < fMinPointsOnTrack) break;
359 tracklabel = track->GetMCid();
361 if(TMath::Abs(tracklabel) != fGoodTracks[i].label) continue;
363 if(tracklabel == fGoodTracks[i].label) {fNFoundTracksPt->Fill(ptg); fNFoundTracksEta->Fill(dipangle);}
364 else {fNFakeTracksPt->Fill(ptg); fNFakeTracksEta->Fill(dipangle);}
365 Float_t pt=track->GetPt();
366 fPtRes->Fill((pt-ptg)/ptg*100.);
367 fNtuppel->Fill(ptg,pt,nHits);
372 cout<<"Track "<<fGoodTracks[i].label<<" was not found"<<endl;
376 void AliL3Evaluate::FillEffHistosNAIVE()
378 //Fill the efficiency histograms.
380 cout<<endl<<"Note: Doing NAIVE evaluation "<<endl;
381 for(Int_t i=0; i<fGoodGen; i++)
383 Double_t ptg=TMath::Sqrt(fGoodTracks[i].px*fGoodTracks[i].px + fGoodTracks[i].py*fGoodTracks[i].py);
384 Double_t pzg=fGoodTracks[i].pz;
385 Float_t dipangle=TMath::ATan2(pzg,ptg)*180./TMath::Pi();
386 //printf("filling particle with pt %f and dipangle %f\n",ptg,dipangle);
387 fNGoodTracksPt->Fill(ptg);
388 fNGoodTracksEta->Fill(dipangle);
392 for(Int_t k=0; k<fTracks->GetNTracks(); k++)
394 AliL3Track *track = fTracks->GetCheckedTrack(k);
396 Int_t nHits = track->GetNumberOfPoints();
397 if(nHits < fMinPointsOnTrack) break;
398 if(track->GetPt()<fMinGoodPt) continue;
399 if(fabs(track->GetPseudoRapidity())>0.9) continue;
401 fNFoundTracksPt->Fill(track->GetPt()); fNFoundTracksEta->Fill(track->GetPseudoRapidity());
402 //Float_t pt=track->GetPt();
403 //fPtRes->Fill((pt-ptg)/ptg*100.);
404 //fNtuppel->Fill(ptg,pt,nHits);
409 void AliL3Evaluate::CalcEffHistos(){
411 Stat_t ngood=fNGoodTracksPt->GetEntries();
412 Stat_t nfound=fNFoundTracksPt->GetEntries();
413 Stat_t nfake=fNFakeTracksPt->GetEntries();
415 LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency")
416 <<AliL3Log::kDec<<"There was "<<ngood<<" generated good tracks"<<ENDLOG;
417 LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency")
418 <<AliL3Log::kDec<<"Found "<<nfound<<" tracks"<<ENDLOG;
419 LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency")
420 <<AliL3Log::kDec<<"Integral efficiency is about "<<nfound/ngood*100<<ENDLOG;
421 LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency")
422 <<AliL3Log::kDec<<"Fake tracks relative is about "<<nfake/ngood*100<<ENDLOG;
424 LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency")
425 <<AliL3Log::kDec<<"Naive efficiency "<<(Double_t)fGoodFound/(Double_t)fGoodGen<<ENDLOG;
428 fNFoundTracksPt->Sumw2(); fNGoodTracksPt->Sumw2();
429 fTrackEffPt->Divide(fNFoundTracksPt,fNGoodTracksPt,1,1.,"b");
430 fFakeTrackEffPt->Divide(fNFakeTracksPt,fNGoodTracksPt,1,1.,"b");
431 fTrackEffPt->SetMaximum(1.4);
432 fTrackEffPt->SetXTitle("P_{T} [GeV]");
433 fTrackEffPt->SetLineWidth(2);
434 fFakeTrackEffPt->SetFillStyle(3013);
435 fTrackEffPt->SetLineColor(4);
436 fFakeTrackEffPt->SetFillColor(2);
438 fNFoundTracksEta->Sumw2(); fNGoodTracksEta->Sumw2();
439 fTrackEffEta->Divide(fNFoundTracksEta,fNGoodTracksEta,1,1.,"b");
440 fFakeTrackEffEta->Divide(fNFakeTracksEta,fNGoodTracksEta,1,1.,"b");
441 fTrackEffEta->SetMaximum(1.4);
442 fTrackEffEta->SetXTitle("#lambda [degrees]");
443 fTrackEffEta->SetLineWidth(2);
444 fFakeTrackEffEta->SetFillStyle(3013);
445 fTrackEffEta->SetLineColor(4);
446 fFakeTrackEffEta->SetFillColor(2);
450 void AliL3Evaluate::Write2File(Char_t *outputfile)
452 //Write histograms to file:
454 TFile *of = TFile::Open(outputfile,"RECREATE");
457 LOG(AliL3Log::kError,"AliL3Evaluate::Write2File","File Open")
458 <<"Problems opening rootfile"<<ENDLOG;
465 fNGoodTracksPt->Write();
466 fNFoundTracksPt->Write();
467 fNFakeTracksPt->Write();
468 fTrackEffPt->Write();
469 fFakeTrackEffPt->Write();
470 fNGoodTracksEta->Write();
471 fNFoundTracksEta->Write();
472 fNFakeTracksEta->Write();
473 fTrackEffEta->Write();
474 fFakeTrackEffEta->Write();
480 TNtupleD *AliL3Evaluate::CalculateResiduals(Char_t *datapath)
483 TNtupleD *ntuppel=new TNtupleD("ntuppel","Residuals","residual_trans:residual_long:zHit:pt:dipangle:beta:padrow:nHits");
484 ntuppel->SetDirectory(0);
486 for(int f=fMinSlice; f<=fMaxSlice; f++)
488 AliL3FileHandler *tfile = new AliL3FileHandler();
490 sprintf(fname,"%s/tracks_tr_%d_0.raw",datapath,f);
491 if(!tfile->SetBinaryInput(fname)){
492 LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open")
493 <<"Inputfile "<<fname<<" does not exist"<<ENDLOG;
496 fTracks = new AliL3TrackArray();
497 tfile->Binary2TrackArray(fTracks);
498 tfile->CloseBinaryInput();
500 printf("Looking in slice %d\n",f);
501 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
504 AliL3Track *track = (AliL3Track*)fTracks->GetCheckedTrack(i);
506 if(track->GetNHits() < fMinPointsOnTrack) continue;
508 track->CalculateHelix();
509 UInt_t *hitnum = track->GetHitNumbers();
514 for(Int_t j=0; j<track->GetNumberOfPoints()-1; j++)
517 Int_t slice = (id>>25) & 0x7f;
518 Int_t patch = (id>>22) & 0x7;
519 UInt_t pos = id&0x3fffff;
521 //if(slice!=1) continue;
523 AliL3SpacePointData *points = fClusters[slice][patch];
527 LOG(AliL3Log::kError,"AliL3Evaluate::CalculateResiduals","Clusterarray")
528 <<"No points at slice "<<slice<<" patch "<<patch<<" pos "<<pos<<ENDLOG;
531 if(pos>=fNcl[slice][patch])
533 LOG(AliL3Log::kError,"AliL3Evaluate::CalculateResiduals","Clusterarray")
534 <<AliL3Log::kDec<<"ERROR"<<ENDLOG;
538 xyz[0] = points[pos].fX;
539 xyz[1] = points[pos].fY;
540 xyz[2] = points[pos].fZ;
541 padrow = points[pos].fPadRow;
542 AliL3Transform::Global2Local(xyz,slice);
544 Float_t xyz_cross[3];
545 track->GetCrossingPoint(padrow,xyz_cross);
546 Double_t beta = track->GetCrossingAngle(padrow);
548 Double_t yres = xyz_cross[1] - xyz[1];
549 Double_t zres = xyz_cross[2] - xyz[2];
551 Double_t dipangle = atan(track->GetTgl());
552 ntuppel->Fill(yres,zres,xyz_cross[2],track->GetPt(),dipangle,beta,padrow,track->GetNumberOfPoints());
562 TNtuple *AliL3Evaluate::EvaluatePoints(Char_t *path)
564 //Compare points to the exact crossing points of track and padrows.
565 //The input file to this function, contains the exact clusters calculated
566 //in AliTPC::Hits2ExactClusters.
569 cerr<<"AliL3Evaluate::EvaluatePoints : Compile with do_mc flag!"<<endl;
572 cout<<"Evaluating points"<<endl;
573 TNtuple *ntuppel = new TNtuple("ntuppel","residuals","slice:padrow:resy:resz:zHit:pt");
574 ntuppel->SetDirectory(0);
576 Char_t filename[1024];
577 sprintf(filename,"%s/alirunfile.root",path);
578 TFile *exfile = TFile::Open(filename);
581 cerr<<"Error opening rootfile "<<filename<<endl;
584 gAlice = (AliRun*)exfile->Get("gAlice");
587 LOG(AliL3Log::kError,"AliL3Evaluate::InitMC","gAlice")
588 <<"AliRun object non existing on file"<<ENDLOG;
593 AliTPCParam *param = (AliTPCParam*)exfile->Get(AliL3Transform::GetParamName());
595 //Get the exact clusters from file:
596 AliTPCClustersArray *arr = new AliTPCClustersArray;
598 arr->SetClusterType("AliComplexCluster");
600 sprintf(treeName,"TreeCExact_%s",param->GetTitle());
601 Bool_t clusterok = arr->ConnectTree(treeName);//Segment Tree (for offline clusters)
602 if(!clusterok) {printf("AliL3Evaluate::EvaluatePoints : Error in clusterloading\n"); return 0;}
604 cout<<"Entering loop with "<<(Int_t)arr->GetTree()->GetEntries()<<endl;
605 for(Int_t i=0; i<arr->GetTree()->GetEntries(); i++)
607 //Get the exact clusters for this row:
609 AliSegmentID *s = arr->LoadEntry(i);
610 param->AdjustSectorRow(s->GetID(),cursec,currow);
612 AliTPCClustersRow *ro = (AliTPCClustersRow *)arr->GetRow(cursec,currow);
613 TClonesArray *clusters = ro->GetArray();
614 int num_of_offline=clusters->GetEntriesFast();
616 //Get the found clusters:
618 AliL3Transform::Sector2Slice(slice,padrow,cursec,currow);
619 if(slice<fMinSlice || slice>fMaxSlice) continue;
620 AliL3SpacePointData *points = fClusters[slice][0];
623 cerr<<"AliL3Evaluate::EvalutePoints : Error getting clusters "<<endl;
626 printf("Checking slice %d padrow %d with %d clusters\n",slice,padrow,num_of_offline);
627 cout<<"There are "<<fNcl[slice][0]<<" clusters here"<<endl;
628 for(UInt_t c=0; c<fNcl[slice][0]; c++)
630 if((Int_t)points[c].fPadRow!=padrow) continue;
631 Float_t xyz_cl[3] = {points[c].fX,points[c].fY,points[c].fZ};
633 AliL3Transform::Global2Local(xyz_cl,cursec);
635 for(Int_t m=0; m<num_of_offline; m++)
637 AliComplexCluster *cluster = (AliComplexCluster *)clusters->UncheckedAt(m);
638 Int_t mcId = cluster->fTracks[0];
640 if(mcId <0) continue;
641 TParticle *part = gAlice->Particle(mcId);
642 if(points[c].fTrackID[0]!=mcId &&
643 points[c].fTrackID[1]!=mcId &&
644 points[c].fTrackID[2]!=mcId)
647 AliL3Transform::Raw2Local(xyz_ex,cursec,currow,cluster->fY,cluster->fX);
649 //In function AliTPC::Hits2ExactClusters the time offset is not included,
650 //so we have to substract it again here.
651 xyz_ex[2]-=AliL3Transform::GetZOffset();
653 Float_t resy = xyz_cl[1] - xyz_ex[1];//cluster->GetY()
654 Float_t resz = xyz_cl[2] - xyz_ex[2];//cluster->GetZ()
656 ntuppel->Fill(slice,padrow,resy,resz,xyz_ex[2],part->Pt());
659 arr->ClearRow(cursec,currow);
666 void AliL3Evaluate::GetCFeff(Char_t *outfile)
669 TNtuple *ntuppel = new TNtuple("ntuppel","Cluster finder efficiency","row:ncrossings:nclusters");
671 AliTPC *TPC = (AliTPC*)gAlice->GetDetector("TPC");
673 TPC->SetParam(fParam);
675 Int_t ver = TPC->IsVersion();
676 LOG(AliL3Log::kInformational,"AliL3Evaluate::GetCFeff","TPC version")
677 <<"TPC version "<<ver<<" found on file"<<ENDLOG;
679 Int_t zero=TPC->GetParam()->GetZeroSup();
681 Int_t np = gAlice->GetNtrack();
684 Int_t *count = new Int_t[np]; //np number of particles.
687 for (i=0; i<np; i++) count[i]=0;
688 for(Int_t sl=fMinSlice; sl<=fMaxSlice; sl++)
690 for (i=0; i<=175; i++)
694 Int_t index = fRowid[sl][i];
695 if (!fDigitsTree->GetEvent(index)) continue;
697 fParam->AdjustSectorRow(fDigits->GetID(),sec,row);
700 Int_t it=fDigits->CurrentRow(), ip=fDigits->CurrentColumn();
701 Short_t dig = fDigits->GetDigit(it,ip);
703 if(dig<=fParam->GetZeroSup()) continue;
704 if(it < fParam->GetMaxTBin()-1 && it > 0)
705 if(fDigits->GetDigit(it+1,ip) <= fParam->GetZeroSup()
706 && fDigits->GetDigit(it-1,ip) <= fParam->GetZeroSup())
709 AliL3Transform::Raw2Local(xyz,sec,row,ip,it);
710 if(fParam->GetPadRowRadii(sec,row)<230./250.*fabs(xyz[2]))
714 Int_t idx0=fDigits->GetTrackID(it,ip,0);
715 Int_t idx1=fDigits->GetTrackID(it,ip,1);
716 Int_t idx2=fDigits->GetTrackID(it,ip,2);
718 if (idx0>=0 && dig>=zero) count[idx0]+=1;
719 if (idx1>=0 && dig>=zero) count[idx1]+=1;
720 if (idx2>=0 && dig>=zero) count[idx2]+=1;
721 } while (fDigits->Next());
723 for (Int_t j=0; j<np; j++)
725 if (count[j]>1) //at least two digits at this padrow
731 AliL3SpacePointData *points = fClusters[sl][0];
732 for(UInt_t k=0; k<fNcl[sl][0]; k++)
734 if(points[k].fPadRow!=i) continue;
737 ntuppel->Fill(i,crossed,recs);
743 TFile *file = TFile::Open(outfile,"RECREATE");