// @(#) $Id$ // Author: Anders Vestbo //*-- Copyright © ALICE HLT Group #include "AliL3StandardIncludes.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if __GNUC__ == 3 #include #include #else #include #endif #include "AliL3Logging.h" #include "AliL3Transform.h" #include "AliL3SpacePointData.h" #include "AliL3Track.h" #include "AliL3FileHandler.h" #include "AliL3TrackArray.h" #include "AliL3Evaluate.h" #if __GNUC__ == 3 using namespace std; #endif /** \class AliL3Evaluate
//_____________________________________________________________
// AliL3Evaluate
//
// Evaluation class for tracking. Plots efficiencies etc..
//
*/ ClassImp(AliL3Evaluate) AliL3Evaluate::AliL3Evaluate() { fTracks = 0; fNFastPoints = 0; fMcIndex = 0; fMcId = 0; fMinSlice=0; fMaxSlice=0; fGoodTracks=0; fNtupleRes=0; fDigitsTree=0; fPtRes=0; fNGoodTracksPt=0; fNFoundTracksPt=0; fNFakeTracksPt=0; fTrackEffPt=0; fFakeTrackEffPt=0; fNGoodTracksEta=0; fNFoundTracksEta=0; fNFakeTracksEta=0; fTrackEffEta=0; fFakeTrackEffEta=0; fMcIndex=0; fMcId=0; fNtuppel=0; fStandardComparison=kTRUE; } AliL3Evaluate::AliL3Evaluate(Char_t *datapath,Int_t min_clusters,Int_t minhits,Double_t minpt,Double_t maxpt,Int_t *slice) { if(slice) { fMinSlice=slice[0]; fMaxSlice=slice[1]; } else { fMinSlice=0; fMaxSlice=35; } sprintf(fPath,"%s",datapath); fMaxFalseClusters = 0.1; fGoodFound = 0; fGoodGen = 0; fMinPointsOnTrack = min_clusters; fMinHitsFromParticle = minhits; fMinGoodPt = minpt; fMaxGoodPt = maxpt; memset(fClusters,0,36*6*sizeof(AliL3SpacePointData*)); fTracks=0; fGoodTracks=0; fNtupleRes=0; fDigitsTree=0; fPtRes=0; fNGoodTracksPt=0; fNFoundTracksPt=0; fNFakeTracksPt=0; fTrackEffPt=0; fFakeTrackEffPt=0; fNGoodTracksEta=0; fNFoundTracksEta=0; fNFakeTracksEta=0; fTrackEffEta=0; fFakeTrackEffEta=0; fMcIndex=0; fMcId=0; fNtuppel=0; fStandardComparison=kTRUE; } void AliL3Evaluate::LoadData(Int_t event,Bool_t sp) { Char_t fname[1024]; AliL3FileHandler *clusterfile[36][6]; for(Int_t s=fMinSlice; s<=fMaxSlice; s++) { for(Int_t p=0; pSetBinaryInput(fname)) { LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open") <<"Inputfile "<Allocate(); clusterfile[s][p]->Binary2Memory(fNcl[s][p],fClusters[s][p]); clusterfile[s][p]->CloseBinaryInput(); if(sp==kTRUE) break; } } sprintf(fname,"%s/tracks_%d.raw",fPath,event); AliL3FileHandler *tfile = new AliL3FileHandler(); if(!tfile->SetBinaryInput(fname)){ LOG(AliL3Log::kError,"AliL3Evaluation::Setup","File Open") <<"Inputfile "<Binary2TrackArray(fTracks); tfile->CloseBinaryInput(); delete tfile; fTracks->QSort(); } AliL3Evaluate::~AliL3Evaluate() { if(fGoodTracks) delete fGoodTracks; if(fDigitsTree) fDigitsTree->Delete(); if(fTracks) delete fTracks; if(fPtRes) delete fPtRes; if(fNGoodTracksPt) delete fNGoodTracksPt; if(fNFoundTracksPt) delete fNFoundTracksPt; if(fNFakeTracksPt) delete fNFakeTracksPt; if(fTrackEffPt) delete fTrackEffPt; if(fFakeTrackEffPt) delete fFakeTrackEffPt; if(fNGoodTracksEta) delete fNGoodTracksEta; if(fNFoundTracksEta) delete fNFoundTracksEta; if(fNFakeTracksEta) delete fNFakeTracksEta; if(fTrackEffEta) delete fTrackEffEta; if(fFakeTrackEffEta) delete fFakeTrackEffEta; if(fMcIndex) delete [] fMcIndex; if(fMcId) delete [] fMcId; if(fNtuppel) delete fNtuppel; if(fNtupleRes) delete fNtupleRes; } void AliL3Evaluate::AssignIDs() { //Assign MC id to the tracks. #ifndef do_mc cerr<<"AliL3Evaluate::AssignIDs() : You need to compile with the do_mc flag!"<QSort(); LOG(AliL3Log::kDebug,"AliL3Evaluate::AssignIDs","Track Loop") <<"Assigning MC id to the found tracks...."<GetNTracks(); i++) { AliL3Track *track = (AliL3Track*)fTracks->GetCheckedTrack(i); if(!track) continue; if(track->GetNumberOfPoints() < fMinPointsOnTrack) break; fGoodFound++; Int_t tID = GetMCTrackLabel(track); track->SetMCid(tID); } //cout<<"Found "<GetNumberOfPoints(); S *s=new S[num_of_clusters]; Int_t i; for (i=0; iGetHitNumbers(); UInt_t id; Int_t lab=123456789; for (i=0; i>25) & 0x7f; Int_t patch = (id>>22) & 0x7; UInt_t pos = id&0x3fffff; AliL3SpacePointData *points = fClusters[slice][patch]; if(!points) continue; if(pos>=fNcl[slice][patch]) { LOG(AliL3Log::kError,"AliL3Evaluate::GetMCTrackLabel","Clusterarray") <max) {max=s[i].max; lab=s[i].lab;} if(lab == -1) return -1; //If most clusters is -1, this is a noise track. if(lab < 0) cerr<<"AliL3Evaluate::GetMCTrackLabel : Track label negative :"<>25) & 0x7f; Int_t patch = (id>>22) & 0x7; UInt_t pos = id&0x3fffff; AliL3SpacePointData *points = fClusters[slice][patch]; if(!points) continue; if(pos>=fNcl[slice][patch]) { LOG(AliL3Log::kError,"AliL3Evaluate::GetMCTrackLabel","Clusterarray") < fMaxFalseClusters) { return -lab; } else //Check if at least half of the 10% innermost clusters are assigned correctly. { Int_t tail=Int_t(0.10*num_of_clusters); max=0; for (i=1; i<=tail; i++) { id = hitnum[num_of_clusters - i]; Int_t slice = (id>>25) & 0x7f; Int_t patch = (id>>22) & 0x7; UInt_t pos = id&0x3fffff; AliL3SpacePointData *points = fClusters[slice][patch]; if(lab == abs(points[pos].fTrackID[0]) || lab == abs(points[pos].fTrackID[1]) || lab == abs(points[pos].fTrackID[2])) max++; } if (max < Int_t(0.5*tail)) return -lab; } return lab; #else //If we are running with mc_ids or not return 0; #endif } void AliL3Evaluate::GetFastClusterIDs(Char_t *path) { //Get the MC id of space points in case of using the fast simulator. char fname[256]; sprintf(fname,"%s/point_mc.dat",path); FILE *infile = fopen(fname,"r"); if(!infile) return; Int_t hitid,hitmc,i; for(i=0; ; i++) if(fscanf(infile,"%d %d",&hitid,&hitmc)==EOF) break; rewind(infile); fNFastPoints = i; fMcId = new Int_t[fNFastPoints]; fMcIndex = new UInt_t[fNFastPoints]; for(i=0; iSetDirectory(0); fPtRes = new TH1F("fPtRes","Relative Pt resolution",30,-10.,10.); fNGoodTracksPt = new TH1F("fNGoodTracksPt","Good tracks vs pt",nbin,xlow,xup); fNFoundTracksPt = new TH1F("fNFoundTracksPt","Found tracks vs pt",nbin,xlow,xup); fNFakeTracksPt = new TH1F("fNFakeTracksPt","Fake tracks vs pt",nbin,xlow,xup); fTrackEffPt = new TH1F("fTrackEffPt","Tracking efficiency vs pt",nbin,xlow,xup); fFakeTrackEffPt = new TH1F("fFakeTrackEffPt","Efficiency for fake tracks vs pt",nbin,xlow,xup); fNGoodTracksEta = new TH1F("fNGoodTracksEta","Good tracks vs eta",20,-50,50); fNFoundTracksEta = new TH1F("fNFoundTracksEta","Found tracks vs eta",20,-50,50); fNFakeTracksEta = new TH1F("fNFakeTracksEta","Fake tracks vs eta",20,-50,50); fTrackEffEta = new TH1F("fTrackEffEta","Tracking efficienct vs eta",20,-50,50); fFakeTrackEffEta = new TH1F("fFakeTrackEffEta","Efficiency for fake tracks vs eta",20,-50,50); } void AliL3Evaluate::GetGoodParticles(Char_t *path,Int_t event,Int_t *padrowrange) { //Read the good particles from file. This file should already have been //generated by macro AliTPCComparison.C. Char_t filename[1024]; if(event<0 && !padrowrange) sprintf(filename,"%s/good_tracks_tpc",path); else if(event>=0 && !padrowrange) sprintf(filename,"%s/good_tracks_tpc_%d",path,event); else sprintf(filename,"%s/good_tracks_tpc_%d_%d_%d",path,event,padrowrange[0],padrowrange[1]); ifstream in(filename); if(!in) { cerr<<"AliL3Evaluate::GetGoodParticles : Problems opening file :"<>fGoodTracks[fGoodGen].label>>fGoodTracks[fGoodGen].code>> fGoodTracks[fGoodGen].px>>fGoodTracks[fGoodGen].py>>fGoodTracks[fGoodGen].pz>> fGoodTracks[fGoodGen].x>>fGoodTracks[fGoodGen].y>>fGoodTracks[fGoodGen].z) { fGoodTracks[fGoodGen].nhits=-1; fGoodTracks[fGoodGen].sector=-1; fGoodGen++; if (fGoodGen==MaxTracks) { cerr<<"AliL3Evaluate::GetGoodParticles : Too many good tracks !\n"; break; } } } else { while (in>>fGoodTracks[fGoodGen].label>>fGoodTracks[fGoodGen].code>> fGoodTracks[fGoodGen].px>>fGoodTracks[fGoodGen].py>>fGoodTracks[fGoodGen].pz>> fGoodTracks[fGoodGen].x>>fGoodTracks[fGoodGen].y >>fGoodTracks[fGoodGen].z>>fGoodTracks[fGoodGen].nhits>>fGoodTracks[fGoodGen].sector) { fGoodGen++; if (fGoodGen==MaxTracks) { cerr<<"AliL3Evaluate::GetGoodParticles : Too many good tracks !\n"; break; } } } } //has to be modified for fakes. void AliL3Evaluate::FillEffHistos() { if(!fGoodTracks) { cerr<<"AliL3Evaluate::FillEffHistos : No good tracks"< fMaxGoodPt) continue; Float_t pzg=fGoodTracks[i].pz; Float_t dipangle=TMath::ATan2(pzg,ptg)*180./TMath::Pi(); //If we are only considering tracks on one side of the TPC: if(fMaxSlice <= 17) if(dipangle < 0) continue; fNGoodTracksPt->Fill(ptg); fNGoodTracksEta->Fill(dipangle); Int_t found = 0; for(Int_t k=0; kGetNTracks(); k++) { AliL3Track *track = fTracks->GetCheckedTrack(k); if(!track) continue; Int_t nHits = track->GetNumberOfPoints(); if(nHits < fMinPointsOnTrack) break; Int_t tracklabel; tracklabel = track->GetMCid(); if(TMath::Abs(tracklabel) != fGoodTracks[i].label) continue; found=1; Float_t pt=track->GetPt(); if(tracklabel == fGoodTracks[i].label) { fNFoundTracksPt->Fill(ptg); fNFoundTracksEta->Fill(dipangle); fNtuppel->Fill(ptg,pt,nHits); fPtRes->Fill((pt-ptg)/ptg*100.); } else { fNFakeTracksPt->Fill(ptg); fNFakeTracksEta->Fill(dipangle); } //fPtRes->Fill((pt-ptg)/ptg*100.); //fNtuppel->Fill(ptg,pt,nHits); break; } //if(!found) //cout<<"Track "< fMaxGoodPt) continue; Double_t pzg=fGoodTracks[i].pz; Float_t dipangle=TMath::ATan2(pzg,ptg)*180./TMath::Pi(); //printf("filling particle with pt %f and dipangle %f\n",ptg,dipangle); fNGoodTracksPt->Fill(ptg); fNGoodTracksEta->Fill(dipangle); } for(Int_t k=0; kGetNTracks(); k++) { AliL3Track *track = fTracks->GetCheckedTrack(k); if(!track) continue; Int_t nHits = track->GetNumberOfPoints(); if(nHits < fMinPointsOnTrack) break; if(track->GetPt()GetPt() > fMaxGoodPt) continue; if(fabs(track->GetPseudoRapidity())>0.9) continue; fNFoundTracksPt->Fill(track->GetPt()); fNFoundTracksEta->Fill(track->GetPseudoRapidity()); //Float_t pt=track->GetPt(); //fPtRes->Fill((pt-ptg)/ptg*100.); //fNtuppel->Fill(ptg,pt,nHits); } } void AliL3Evaluate::CalcEffHistos() { Stat_t ngood=fNGoodTracksPt->GetEntries(); Stat_t nfound=fNFoundTracksPt->GetEntries(); Stat_t nfake=fNFakeTracksPt->GetEntries(); LOG(AliL3Log::kInformational,"AliL3Evaluate::FillEffHistos","Efficiency") <Sumw2(); fNGoodTracksPt->Sumw2(); fTrackEffPt->Divide(fNFoundTracksPt,fNGoodTracksPt,1,1.,"b"); fFakeTrackEffPt->Divide(fNFakeTracksPt,fNGoodTracksPt,1,1.,"b"); fTrackEffPt->SetMaximum(1.4); fTrackEffPt->SetXTitle("P_{T} [GeV]"); fTrackEffPt->SetLineWidth(2); fFakeTrackEffPt->SetFillStyle(3013); fTrackEffPt->SetLineColor(4); fFakeTrackEffPt->SetFillColor(2); fNFoundTracksEta->Sumw2(); fNGoodTracksEta->Sumw2(); fTrackEffEta->Divide(fNFoundTracksEta,fNGoodTracksEta,1,1.,"b"); fFakeTrackEffEta->Divide(fNFakeTracksEta,fNGoodTracksEta,1,1.,"b"); fTrackEffEta->SetMaximum(1.4); fTrackEffEta->SetXTitle("#lambda [degrees]"); fTrackEffEta->SetLineWidth(2); fFakeTrackEffEta->SetFillStyle(3013); fTrackEffEta->SetLineColor(4); fFakeTrackEffEta->SetFillColor(2); } void AliL3Evaluate::Write2File(Char_t *outputfile) { //Write histograms to file: TFile *of = TFile::Open(outputfile,"RECREATE"); if(!of->IsOpen()) { LOG(AliL3Log::kError,"AliL3Evaluate::Write2File","File Open") <<"Problems opening rootfile"<cd(); fNtuppel->Write(); fPtRes->Write(); fNGoodTracksPt->Write(); fNFoundTracksPt->Write(); fNFakeTracksPt->Write(); fTrackEffPt->Write(); fFakeTrackEffPt->Write(); fNGoodTracksEta->Write(); fNFoundTracksEta->Write(); fNFakeTracksEta->Write(); fTrackEffEta->Write(); fFakeTrackEffEta->Write(); of->Close(); } TNtuple *AliL3Evaluate::GetNtuple() { if(!fNtupleRes) { fNtupleRes = new TNtuple("ntuppel","Residuals","residual_trans:residual_long:zHit:pt:dipangle:beta:padrow:nHits"); fNtupleRes->SetDirectory(0);//Bug in older version of root. } return fNtupleRes; } void AliL3Evaluate::CalculateResiduals() { TNtuple *ntuppel = GetNtuple(); for(Int_t i=0; iGetNTracks(); i++) { AliL3Track *track = (AliL3Track*)fTracks->GetCheckedTrack(i); if(!track) continue; if(track->GetNHits() < fMinPointsOnTrack) break; track->CalculateHelix(); UInt_t *hitnum = track->GetHitNumbers(); UInt_t id; Float_t xyz[3]; Int_t padrow; for(Int_t j=0; jGetNumberOfPoints()-1; j++) { id = hitnum[j]; Int_t slice = (id>>25) & 0x7f; Int_t patch = (id>>22) & 0x7; UInt_t pos = id&0x3fffff; //if(slice<18) continue; AliL3SpacePointData *points = fClusters[slice][patch]; if(!points) { LOG(AliL3Log::kError,"AliL3Evaluate::CalculateResiduals","Clusterarray") <<"No points at slice "<=fNcl[slice][patch]) { LOG(AliL3Log::kError,"AliL3Evaluate::CalculateResiduals","Clusterarray") <CalculateReferencePoint(angle,AliL3Transform::Row2X(padrow))) { LOG(AliL3Log::kError,"AliL3Evaluate::CalculateResiduals","Crossing point") <<"Track does not crossing padrow "<GetPointX(),track->GetPointY(),track->GetPointZ()}; //AliL3Transform::Global2Local(xyz_cross,slice,kTRUE); AliL3Transform::Global2LocHLT(xyz_cross,slice); Double_t beta = track->GetCrossingAngle(padrow,slice); Double_t yres = xyz_cross[1] - xyz[1]; Double_t zres = xyz_cross[2] - xyz[2]; Double_t dipangle = atan(track->GetTgl()); ntuppel->Fill(yres,zres,xyz_cross[2],track->GetPt(),dipangle,beta,padrow,track->GetNumberOfPoints()); } } } enum tagprimary {kPrimaryCharged = 0x4000}; void AliL3Evaluate::EvaluatePoints(Char_t *rootfile,Char_t *exactfile,Char_t *tofile,Int_t nevent,Bool_t offline,Bool_t sp) { //Compare points to the exact crossing points of track and padrows. //The input file to this function, contains the exact clusters calculated //in AliTPC::Hits2ExactClusters. #ifndef do_mc cerr<<"AliL3Evaluate::EvaluatePoints : Compile with do_mc flag!"<SetDirectory(0); TNtuple *ntuppel2 = new TNtuple("ntuppel_eff","Efficiency","slice:padrow:nfound:ngen"); ntuppel2->SetDirectory(0); TFile *exfile = TFile::Open(rootfile); if(!exfile) { cerr<<"Error opening rootfile "<Get("gAlice"); if (!gAlice) { LOG(AliL3Log::kError,"AliL3Evaluate::InitMC","gAlice") <<"AliRun object non existing on file"<Get(AliL3Transform::GetParamName()); TFile *exact = TFile::Open(exactfile); if(!exact) { cerr<<"AliL3Evaluate::EvaluatePoints : Problems opening file :"<Stack(); AliTPCClustersArray *arr=0; for(Int_t event=0; eventcd(); if(arr) delete arr; Int_t nparticles = gAlice->GetEvent(event); Int_t nprimaries = 0;//FindPrimaries(nparticles); cout<<"Event "<cd(); //Get the exact clusters from file: AliTPCClustersArray *arr = new AliTPCClustersArray; arr->Setup(param); arr->SetClusterType("AliComplexCluster"); char treeName[500]; sprintf(treeName,"TreeCExact_%s_%d",param->GetTitle(),event); Bool_t clusterok = arr->ConnectTree(treeName);//Segment Tree (for offline clusters) if(!clusterok) {printf("AliL3Evaluate::EvaluatePoints : Error in clusterloading\n"); return;} //cout<<"Entering loop with "<<(Int_t)arr->GetTree()->GetEntries()<GetTree()->GetEntries(); i++) { //Get the exact clusters for this row: Int_t cursec,currow; AliSegmentID *s = arr->LoadEntry(i); param->AdjustSectorRow(s->GetID(),cursec,currow); AliTPCClustersRow *ro = (AliTPCClustersRow *)arr->GetRow(cursec,currow); TClonesArray *clusters = ro->GetArray(); int num_of_offline=clusters->GetEntriesFast(); //Get the found clusters: Int_t slice,padrow; AliL3Transform::Sector2Slice(slice,padrow,cursec,currow); if(slice < fMinSlice) continue; if(slice > fMaxSlice) break; Int_t patch = AliL3Transform::GetPatch(padrow); if(sp) patch=0; AliL3SpacePointData *points = fClusters[slice][patch]; if(!points) continue; //cout<<"Slice "<UncheckedAt(m); #ifdef use_newio Int_t mcId = cluster->GetTrack(0); #else Int_t mcId = cluster->fTracks[0]; #endif if(mcId <0) continue; #ifdef use_newio if(cluster->GetY() < 1 || cluster->GetY() > AliL3Transform::GetNPads(padrow) - 2 || cluster->GetX() < 1 || cluster->GetX() > AliL3Transform::GetNTimeBins() - 2) continue; #else if(cluster->fY < 1 || cluster->fY > AliL3Transform::GetNPads(padrow) - 2 || cluster->fX < 1 || cluster->fX > AliL3Transform::GetNTimeBins() - 2) continue; #endif Float_t xyz_ex[3]; #ifdef use_newio AliL3Transform::Raw2Local(xyz_ex,cursec,currow,cluster->GetY(),cluster->GetX()); #else AliL3Transform::Raw2Local(xyz_ex,cursec,currow,cluster->fY,cluster->fX); #endif //In function AliTPC::Hits2ExactClusters the time offset is not included, //so we have to substract it again here. if(slice<18) xyz_ex[2]-=AliL3Transform::GetZOffset(); else xyz_ex[2]+=AliL3Transform::GetZOffset(); //Outside our cone: if(param->GetPadRowRadii(cursec,currow)<230./250.*fabs(xyz_ex[2])) continue; TParticle *part = astack->Particle(mcId); crosscount++; if(part->Pt() < fMinGoodPt) continue; //Dont take secondaries, because in width calculation we assume primaries: //if(!(part->TestBit(kPrimaryCharged))) continue; if(part->GetFirstMother()>=0) continue; Int_t tempcount=0; for(UInt_t c=0; cFill(slice,padrow,charge,resy,resz,xyz_ex[2],part->Pt(),beta,sigmaY2,sigmaZ2,psigmaY2,psigmaZ2); } clustercount=tempcount; } ntuppel2->Fill(slice,padrow,clustercount,crosscount); arr->ClearRow(cursec,currow); } } exfile->Close(); exact->Close(); TFile *ofile = TFile::Open(tofile,"RECREATE"); ntuppel->Write(); ntuppel2->Write(); ofile->Close(); #endif } void AliL3Evaluate::GetCFeff(Char_t *path,Char_t *outfile,Int_t nevent,Bool_t sp) { //Evaluate the cluster finder efficiency. #ifndef do_mc cerr<<"AliL3Evaluate::GetCFeff : Compile with do_mc flag"<SetDirectory(0); Char_t filename[1024]; sprintf(filename,"%s/alirunfile.root",path); TFile *rfile = TFile::Open(filename); gAlice = (AliRun*)rfile->Get("gAlice"); AliStack *astack=gAlice->Stack(); AliTPCParam *param = (AliTPCParam*)rfile->Get(AliL3Transform::GetParamName()); Int_t zero=param->GetZeroSup(); sprintf(filename,"%s/digitfile.root",path); TFile *dfile = TFile::Open(filename); for(Int_t event=0; eventcd(); gAlice->GetEvent(event); Int_t np = astack->GetNtrack(); cout<<"Processing event "<cd(); sprintf(filename,"TreeD_75x40_100x60_150x60_%d",event); TTree *TD=(TTree*)gDirectory->Get(filename); AliSimDigits da, *digits=&da; TD->GetBranch("Segment")->SetAddress(&digits); Int_t crossed=0,recs=0; Int_t *count = new Int_t[np]; //np number of particles. Int_t i; Float_t xyz[3]; for (i=0; iGetEntries(); i++) { crossed=recs=0; if (!TD->GetEvent(i)) continue; param->AdjustSectorRow(digits->GetID(),sec,row); AliL3Transform::Sector2Slice(sl,sr,sec,row); if(sl < fMinSlice) continue; if(sl > fMaxSlice) break; cout<<"Processing slice "<First(); do { Int_t it=digits->CurrentRow(), ip=digits->CurrentColumn(); Short_t dig = digits->GetDigit(it,ip); if(dig<=param->GetZeroSup()) continue; AliL3Transform::Raw2Local(xyz,sec,row,ip,it); if(param->GetPadRowRadii(sec,row)<230./250.*fabs(xyz[2])) continue; Int_t idx0=digits->GetTrackID(it,ip,0); Int_t idx1=digits->GetTrackID(it,ip,1); Int_t idx2=digits->GetTrackID(it,ip,2); if (idx0>=0 && dig>=zero) count[idx0]+=1; if (idx1>=0 && dig>=zero) count[idx1]+=1; if (idx2>=0 && dig>=zero) count[idx2]+=1; } while (digits->Next()); for (Int_t j=0; jParticle(j); if(part->Pt() < fMinGoodPt) continue; if(part->GetFirstMother() >= 0) continue; if (count[j]>1) //at least two digits at this padrow { crossed++; count[j]=0; } } Int_t patch = AliL3Transform::GetPatch(sr); if(sp==kTRUE) patch=0; AliL3SpacePointData *points = fClusters[sl][patch]; if(!points) continue; for(UInt_t k=0; kFill(sl,sr,crossed,recs); } TD->Delete(); delete[] count; } TFile *file = TFile::Open(outfile,"RECREATE"); ntuppel->Write(); file->Close(); rfile->Close(); dfile->Close(); #endif } Float_t AliL3Evaluate::GetCrossingAngle(TParticle *part,Int_t slice,Int_t padrow,Float_t *xyz) { //Calculate the padrow crossing angle of the particle Double_t kappa = AliL3Transform::GetBField()*AliL3Transform::GetBFact()/part->Pt(); Double_t radius = 1/fabs(kappa); if(part->GetPdgCode() > 0) kappa = -kappa; Float_t angl[1] = {part->Phi()}; AliL3Transform::Global2LocalAngle(angl,slice); Double_t charge = -1.*kappa; Double_t trackPhi0 = angl[0] + charge*0.5*AliL3Transform::Pi()/fabs(charge); Double_t x0=0; Double_t y0=0; Double_t xc = x0 - radius * cos(trackPhi0); Double_t yc = y0 - radius * sin(trackPhi0); Double_t tangent[2]; tangent[0] = -1.*(xyz[1] - yc)/radius; tangent[1] = (xyz[0] - xc)/radius; Double_t perp_padrow[2] = {1,0}; //locally in slice Double_t cos_beta = fabs(tangent[0]*perp_padrow[0] + tangent[1]*perp_padrow[1]); if(cos_beta > 1) cos_beta=1; return acos(cos_beta); } Int_t AliL3Evaluate::FindPrimaries(Int_t nparticles) { // cuts: Double_t vertcut = 0.001; Double_t decacut = 3.; Double_t timecut = 0.; Int_t nprch1=0; AliStack *astack=gAlice->Stack(); TParticle * part = astack->Particle(0); Double_t xori = part->Vx(); Double_t yori = part->Vy(); Double_t zori = part->Vz(); for(Int_t iprim = 0; iprimParticle(iprim); const char * xxx=strstr(part->GetName(),"XXX"); if(xxx)continue; TParticlePDG *ppdg = part->GetPDG(); if(TMath::Abs(ppdg->Charge())!=3)continue; // only charged (no quarks) Double_t dist=TMath::Sqrt((part->Vx()-xori)*(part->Vx()-xori)+(part->Vy()-yori)*(part->Vy()-yori)+(part->Vz()-zori)*(part->Vz()-zori)); if(dist>vertcut)continue; // cut on the vertex if(part->T()>timecut)continue; Double_t ptot=TMath::Sqrt(part->Px()*part->Px()+part->Py()*part->Py()+part->Pz()*part->Pz()); if(ptot==(TMath::Abs(part->Pz())))continue; // no beam particles Bool_t prmch = kTRUE; // candidate primary track Int_t fidau=part->GetFirstDaughter(); // cut on daughters Int_t lasdau=0; Int_t ndau=0; if(fidau>=0){ lasdau=part->GetLastDaughter(); ndau=lasdau-fidau+1; } if(ndau>0){ for(Int_t j=fidau;j<=lasdau;j++){ TParticle *dau=astack->Particle(j); Double_t distd=TMath::Sqrt((dau->Vx()-xori)*(dau->Vx()-xori)+(dau->Vy()-yori)*(dau->Vy()-yori)+(dau->Vz()-zori)*(dau->Vz()-zori)); if(distdSetBit(kPrimaryCharged); } } return nprch1; }