// ************************************************************************** // * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * // * * // * Author: The ALICE Off-line Project. * // * Contributors are mentioned in the code where appropriate. * // * * // * Permission to use, copy, modify and distribute this software and its * // * documentation strictly for non-commercial purposes is hereby granted * // * without fee, provided that the above copyright notice appears in all * // * copies and that both the copyright notice and this permission notice * // * appear in the supporting documentation. The authors make no claims * // * about the suitability of this software for any purpose. It is * // * provided "as is" without express or implied warranty. * // ************************************************************************** //----------------------------------------------------------------------------------- // Jet finder based on Deterministic Annealing // For further informations about the DA working features see: // Phys.Lett. B601 (2004) 56-63 (http://arxiv.org/abs/hep-ph/0407214) // Author: Davide Perrino (davide.perrino@ba.infn.it, davide.perrino@cern.ch) //----------------------------------------------------------------------------------- #include #include #include #include "AliJetReader.h" #include "AliDAJetHeader.h" #include "AliDAJetFinder.h" ClassImp(AliDAJetFinder) //----------------------------------------------------------------------------------- AliDAJetFinder::AliDAJetFinder(): fAlpha(1.01), fDelta(1e-8), fAvDist(1e-6), fEps(1e-4), fEpsMax(1e-2), fNloopMax(100), fBeta(0.1), fNclustMax(0), fPyx(0x0), fY(0x0), fPx(0x0), fPy(0x0), fXEta(0x0), fXPhi(0x0), fNin(0) { // Constructor } //----------------------------------------------------------------------------------- AliDAJetFinder::~AliDAJetFinder() { // Destructor delete fPyx; delete fY; delete fPx; delete fPy; delete [] fXEta; delete [] fXPhi; } //----------------------------------------------------------------------------------- void AliDAJetFinder::FindJets() { // Find the jets in current event // Float_t betaStop=100.; Double_t dEtSum=0; InitDetAnn(dEtSum); if (!fNin) return; Int_t nc=1,nk; DoubleClusters(nc,nk); do{ //loop over beta fBeta*=fAlpha; Annealing(nk); NumCl(nc,nk); }while((fBetaGetMomentumArray(); fNin = lvArray->GetEntries(); fNclustMax= ((AliDAJetHeader*)fHeader)->GetFixedCl() ? ((AliDAJetHeader*)fHeader)->GetNclustMax() : TMath::Max((Int_t)TMath::Sqrt(fNin),5); fXEta=new Double_t[fNin]; fXPhi=new Double_t[fNin]; fPx = new TVectorD(fNin); for (Int_t iIn=0; iInAt(iIn); fXEta[iIn] = lv->Eta(); fXPhi[iIn] = lv->Phi()<0 ? lv->Phi() + 2*TMath::Pi() : lv->Phi(); (*fPx)(iIn)=lv->Pt(); dEtSum+=(*fPx)(iIn); } for (Int_t iIn=0; iInZero();fPyx->Zero();fPy->Zero(); (*fPy)(0)=1; TMatrixDColumn(*fPyx,0)=1; Double_t ypos=0,xpos=0; for (Int_t iIn=0; iIn0) ? atan2(ypos,xpos) : atan2(ypos,xpos)+2*TMath::Pi(); lvArray->Delete(); } //----------------------------------------------------------------------------------- void AliDAJetFinder::DoubleClusters(Int_t nc,Int_t &nk) { for(Int_t iClust=0; iClustGetEtaCut(),pi}; TVectorD vPart(2); Double_t *m = new Double_t[nk]; Double_t chi,chi1; do{ Int_t nloop=0; for (Int_t iClust=0; iClustRndm(24); ry->Randomize(-0.5,0.5,seed); for (Int_t i=0; i<2; i++){ for (Int_t iClust=0; iClustZero(); y->Zero(); //recalculate codevectors for (Int_t iClust=0; iClust0) ? atan2(ypos,xpos) : atan2(ypos,xpos)+2*pi; } //verify codevectors' stability chi=0; for (Int_t iClust=0; iClustchi) chi=chi1; } chi=TMath::Sqrt(chi); for (Int_t iClust=0; iClustfNloopMax){ if (chi500) break; } }while (chi>fEps); }while (chi>fEpsMax); for (Int_t iClust=0; iClust= fNclustMax) growcl=false; //recalculate the nc distinct codevectors TMatrixD *pyx = new TMatrixD(fNin,2*nc); TVectorD *py = new TVectorD(nk); TMatrixD *y1 = new TMatrixD(3,nk); for (Int_t iClust=0; iClust nk/2){ for (Int_t iClust=0; iClustZero(); fPyx->Zero(); fPy->Zero(); for (Int_t iIn=0; iIn0){ Double_t xpos=0,ypos=0,pxy; for (Int_t iIn=0; iIn0) ? atan2(ypos,xpos) : atan2(ypos,xpos)+2*TMath::Pi(); (*fY)(3,k)=(*fY)(3,iClust); k++; } } nk=k; } //----------------------------------------------------------------------------------- void AliDAJetFinder::StoreJets(Int_t nk,Int_t *xx) { //evaluate significant clusters properties const Double_t pi=TMath::Pi(); Double_t dMeanDist=TMath::Sqrt(4*((AliDAJetHeader*)fHeader)->GetEtaCut()*pi/fNin); Bool_t *isJet = new Bool_t[nk]; Double_t *etNoBg= new Double_t[nk]; Double_t *dDeltaEta=new Double_t[nk]; Double_t *dDeltaPhi=new Double_t[nk]; Double_t *surf = new Double_t[nk]; Double_t *etDens= new Double_t[nk]; for (Int_t iClust=0; iClust dEtaMax) dEtaMax=fXEta[iIn]; Double_t dPhi=fXPhi[iIn]-(*fY)(1,iClust); if (dPhi > pi ) dPhi-=2*pi; else if (dPhi < (-1)*pi) dPhi+=2*pi; if (dPhi < dPhiMin) dPhiMin=dPhi; else if (dPhi > dPhiMax) dPhiMax=dPhi; } dDeltaEta[iClust]=dEtaMax-dEtaMin+dMeanDist; dDeltaPhi[iClust]=dPhiMax-dPhiMin+dMeanDist; surf[iClust]=0.25*pi*dDeltaEta[iClust]*dDeltaPhi[iClust]; etDens[iClust]=(*fY)(3,iClust)/surf[iClust]; } if (((AliDAJetHeader*)fHeader)->GetSelJets()){ for (Int_t iClust=0; iClust (etDensMed+deltaEtDens)*surf[iClust]) isJet[iClust]=kTRUE; etNoBg[iClust]=(*fY)(3,iClust)-etDensMed*surf[iClust]; } } for (Int_t iClust=0; iClustGetEtaCut()*pi; for (Int_t iClust1=0; iClust1GetEtMin()){ isJet[iClust]=kFALSE; iClust=-1; } } } } else { for (Int_t iClust=0; iClustClassName(),"AliJetAODReader"); if (fromAod) refs = fReader->GetReferences(); for (Int_t iClust=0; iClustAt(iIn)); AddJet(jet); printf("jet %d, Eta: %f, Phi: %f, Et: %f\n",iClust,jet.Eta(),jet.Phi(),jet.Pt()); } } delete [] dDeltaEta; delete [] dDeltaPhi; delete [] etNoBg; delete [] isJet; delete [] inJet; } //----------------------------------------------------------------------------------- Double_t Dist(TVectorD x,TVectorD y) { // Squared distance const Double_t pi=TMath::Pi(); Double_t dphi=TMath::Abs(x(1)-y(1)); if (dphi > pi) dphi=2*pi-dphi; Double_t dist=pow(x(0)-y(0),2)+pow(dphi,2); return dist; }