+ TNamed::Copy(c);
+}
+
+//_____________________________________________________________________________
+Long64_t AliESDtrackCuts::Merge(TCollection* list) {
+ // Merge a list of AliESDtrackCuts objects with this (needed for PROOF)
+ // Returns the number of merged objects (including this)
+
+ if (!list)
+ return 0;
+
+ if (list->IsEmpty())
+ return 1;
+
+ if (!fHistogramsOn)
+ return 0;
+
+ TIterator* iter = list->MakeIterator();
+ TObject* obj;
+
+
+ // collection of measured and generated histograms
+ Int_t count = 0;
+ while ((obj = iter->Next())) {
+
+ AliESDtrackCuts* entry = dynamic_cast<AliESDtrackCuts*>(obj);
+ if (entry == 0)
+ continue;
+
+ if (!entry->fHistogramsOn)
+ continue;
+
+ for (Int_t i=0; i<2; i++) {
+
+ fhNClustersITS[i] ->Add(entry->fhNClustersITS[i] );
+ fhNClustersTPC[i] ->Add(entry->fhNClustersTPC[i] );
+
+ fhChi2PerClusterITS[i] ->Add(entry->fhChi2PerClusterITS[i]);
+ fhChi2PerClusterTPC[i] ->Add(entry->fhChi2PerClusterTPC[i]);
+
+ fhC11[i] ->Add(entry->fhC11[i] );
+ fhC22[i] ->Add(entry->fhC22[i] );
+ fhC33[i] ->Add(entry->fhC33[i] );
+ fhC44[i] ->Add(entry->fhC44[i] );
+ fhC55[i] ->Add(entry->fhC55[i] );
+
+ fhDXY[i] ->Add(entry->fhDXY[i] );
+ fhDZ[i] ->Add(entry->fhDZ[i] );
+ fhDXYvsDZ[i] ->Add(entry->fhDXYvsDZ[i] );
+
+ fhDXYNormalized[i] ->Add(entry->fhDXYNormalized[i] );
+ fhDZNormalized[i] ->Add(entry->fhDZNormalized[i] );
+ fhDXYvsDZNormalized[i] ->Add(entry->fhDXYvsDZNormalized[i]);
+ fhNSigmaToVertex[i] ->Add(entry->fhNSigmaToVertex[i]);
+
+ }
+
+ fhCutStatistics ->Add(entry->fhCutStatistics);
+ fhCutCorrelation ->Add(entry->fhCutCorrelation);
+
+ count++;
+ }
+
+ return count+1;
+}
+
+
+//____________________________________________________________________
+Float_t AliESDtrackCuts::GetSigmaToVertex(AliESDtrack* esdTrack)
+{
+ // Calculates the number of sigma to the vertex.
+
+ Float_t b[2];
+ Float_t bRes[2];
+ Float_t bCov[3];
+ esdTrack->GetImpactParameters(b,bCov);
+ if (bCov[0]<=0 || bCov[2]<=0) {
+ AliDebug(1, "Estimated b resolution lower or equal zero!");
+ bCov[0]=0; bCov[2]=0;
+ }
+ bRes[0] = TMath::Sqrt(bCov[0]);
+ bRes[1] = TMath::Sqrt(bCov[2]);
+
+ // -----------------------------------
+ // How to get to a n-sigma cut?
+ //
+ // The accumulated statistics from 0 to d is
+ //
+ // -> Erf(d/Sqrt(2)) for a 1-dim gauss (d = n_sigma)
+ // -> 1 - Exp(-d**2) for a 2-dim gauss (d*d = dx*dx + dy*dy != n_sigma)
+ //
+ // It means that for a 2-dim gauss: n_sigma(d) = Sqrt(2)*ErfInv(1 - Exp((-x**2)/2)
+ // Can this be expressed in a different way?
+
+ if (bRes[0] == 0 || bRes[1] ==0)
+ return -1;
+
+ Float_t d = TMath::Sqrt(TMath::Power(b[0]/bRes[0],2) + TMath::Power(b[1]/bRes[1],2));
+
+ // stupid rounding problem screws up everything:
+ // if d is too big, TMath::Exp(...) gets 0, and TMath::ErfInverse(1) that should be infinite, gets 0 :(
+ if (TMath::Exp(-d * d / 2) < 1e-10)
+ return 1000;
+
+ d = TMath::ErfInverse(1 - TMath::Exp(-d * d / 2)) * TMath::Sqrt(2);
+ return d;
+}
+
+void AliESDtrackCuts::EnableNeededBranches(TTree* tree)
+{
+ // enables the branches needed by AcceptTrack, for a list see comment of AcceptTrack
+
+ tree->SetBranchStatus("fTracks.fFlags", 1);
+ tree->SetBranchStatus("fTracks.fITSncls", 1);
+ tree->SetBranchStatus("fTracks.fTPCncls", 1);
+ tree->SetBranchStatus("fTracks.fITSchi2", 1);
+ tree->SetBranchStatus("fTracks.fTPCchi2", 1);
+ tree->SetBranchStatus("fTracks.fC*", 1);
+ tree->SetBranchStatus("fTracks.fD", 1);
+ tree->SetBranchStatus("fTracks.fZ", 1);
+ tree->SetBranchStatus("fTracks.fCdd", 1);
+ tree->SetBranchStatus("fTracks.fCdz", 1);
+ tree->SetBranchStatus("fTracks.fCzz", 1);
+ tree->SetBranchStatus("fTracks.fP*", 1);
+ tree->SetBranchStatus("fTracks.fR*", 1);
+ tree->SetBranchStatus("fTracks.fKinkIndexes*", 1);