X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=RICH%2FAliRICHClusterFinder.cxx;h=823bea20e9d98391171e6aedb2d8179f749817a9;hb=2b8f978a74051298b8ca140ec579d32ed7ff8bfd;hp=da7fe36220ff1c1ea18c978d3a14fe9a07007d0c;hpb=c712cb2f4fb2f464fc616e692d6a72ce3fabe10a;p=u%2Fmrichter%2FAliRoot.git diff --git a/RICH/AliRICHClusterFinder.cxx b/RICH/AliRICHClusterFinder.cxx index da7fe36220f..823bea20e9d 100644 --- a/RICH/AliRICHClusterFinder.cxx +++ b/RICH/AliRICHClusterFinder.cxx @@ -15,762 +15,330 @@ #include "AliRICHClusterFinder.h" -#include "AliRun.h" -#include "AliRICH.h" #include "AliRICHMap.h" -#include "AliRICHSDigit.h" -#include "AliRICHDigit.h" -#include "AliRICHRawCluster.h" -#include "AliRICHParam.h" -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include -static AliSegmentation *gSegmentation; -static AliRICHResponse* gResponse; -static Int_t gix[500]; -static Int_t giy[500]; -static Float_t gCharge[500]; -static Int_t gNbins; -static Bool_t gFirst=kTRUE; -static TMinuit *gMyMinuit ; -void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t); -static Int_t gChargeTot; +void RICHMinMathieson(Int_t &npar, Double_t *gin, Double_t &chi2, Double_t *par, Int_t iflag); ClassImp(AliRICHClusterFinder) //__________________________________________________________________________________________________ AliRICHClusterFinder::AliRICHClusterFinder(AliRICH *pRICH) {//main ctor - Info("main ctor","Start."); +// Info("main ctor","Start."); - fRICH=pRICH; + fRICH = pRICH; - fSegmentation=Rich()->C(1)->GetSegmentationModel(); - fResponse =Rich()->C(1)->GetResponseModel(); - - fDigits=0; fNdigits=0; - fChamber=0; - fHitMap=0; + fHitMap = 0; + fRawCluster.Reset(); + fResolvedCluster.Reset(); - fCogCorr = 0; - SetNperMax(); - SetClusterSize(); - fNPeaks=-1; }//main ctor //__________________________________________________________________________________________________ -void AliRICHClusterFinder::Decluster(AliRICHRawCluster *cluster) -{// Decluster algorithm - Info("Decluster","Start."); - if(cluster->fMultiplicity==1||cluster->fMultiplicity==2){//Nothing special for 1- and 2-clusters - if(fNPeaks != 0) {cluster->fNcluster[0]=fNPeaks; cluster->fNcluster[1]=0;} - AddRawCluster(*cluster); - fNPeaks++; - }else if(cluster->fMultiplicity==3){// 3-cluster, check topology - Centered(cluster);// ok, cluster is centered and added in Centered() - }else{//4-and more-pad clusters - if(cluster->fMultiplicity<= fMaxClusterSize){ - SplitByLocalMaxima(cluster); - }//if <= fClusterSize - }//if multiplicity -}//Decluster() +void AliRICHClusterFinder::FindLocalMaxima() +{ +// Find number of local maxima in the cluster +// Info("FindLocalMaxima","Start."); + + fNlocals = 0; + for(Int_t iDig1=0;iDig1At(iDig1); + Int_t padX1 = pDig1->X(); + Int_t padY1 = pDig1->Y(); + Int_t padQ1 = (Int_t)(pDig1->Q()+0.1); + Int_t padC1 = pDig1->CombiPid(); + for(Int_t iDig2=0;iDig2At(iDig2); + Int_t padX2 = pDig2->X(); + Int_t padY2 = pDig2->Y(); + Int_t padQ2 = (Int_t)(pDig2->Q()+0.1); + if(iDig1==iDig2) continue; + Int_t diffx = TMath::Sign(padX1-padX2,1); + Int_t diffy = TMath::Sign(padY1-padY2,1); + if((diffx+diffy)<=1) { + if(padQ2>=padQ1) iNotMax++; + } + } + if(iNotMax==0) { + TVector2 x2=AliRICHParam::Pad2Loc(padX1,padY1); + fLocalX[fNlocals]=x2.X();fLocalY[fNlocals]=x2.Y(); + fLocalQ[fNlocals] = (Double_t)padQ1; + fLocalC[fNlocals] = padC1; + fNlocals++; + } + } +}//FindLocalMaxima() //__________________________________________________________________________________________________ -Bool_t AliRICHClusterFinder::Centered(AliRICHRawCluster *cluster) -{//Is the cluster centered? +void AliRICHClusterFinder::Exec() +{ + Info("Exec","Start."); + + + Rich()->GetLoader()->LoadDigits(); + + Rich()->GetLoader()->GetRunLoader()->LoadHeader(); + Rich()->GetLoader()->GetRunLoader()->LoadKinematics(); - AliRICHDigit* dig; - dig= (AliRICHDigit*)fDigits->UncheckedAt(cluster->fIndexMap[0]); - Int_t x[kMaxNeighbours], y[kMaxNeighbours], xN[kMaxNeighbours], yN[kMaxNeighbours]; - Int_t nn=Rich()->Param()->PadNeighbours(dig->PadX(),dig->PadY(),x,y); + for(Int_t iEventN=0;iEventNGetEventsPerRun();iEventN++){//events loop + Info("Exec","Event %i processed.",iEventN+1); +// gAlice->GetRunLoader()->GetEvent(iEventN); + Rich()->GetLoader()->GetRunLoader()->GetEvent(iEventN); - - Int_t nd=0; - for (Int_t i=0; iTestHit(x[i],y[i]) == kUsed){ - xN[nd]=x[i]; - yN[nd]=y[i]; - nd++; - } - }//neighbours loop + Rich()->GetLoader()->MakeTree("R"); Rich()->MakeBranch("R"); + Rich()->ResetDigits(); Rich()->ResetClusters(); - if(nd==2){// cluster is centered ! - if (fNPeaks != 0) { - cluster->fNcluster[0]=fNPeaks; - cluster->fNcluster[1]=0; - } - cluster->fCtype=0; - AddRawCluster(*cluster); - fNPeaks++; - return kTRUE; - } else if (nd ==1) { -// Highest signal on an edge, split cluster into 2+1 -// who is the neighbour ? - Int_t nind=fHitMap->GetHitIndex(xN[0], yN[0]); - Int_t i1= (nind==cluster->fIndexMap[1]) ? 1:2; - Int_t i2= (nind==cluster->fIndexMap[1]) ? 2:1; -// 2-cluster - AliRICHRawCluster cnew; - if (fNPeaks == 0) { - cnew.fNcluster[0]=-1; - cnew.fNcluster[1]=fNRawClusters; - } else { - cnew.fNcluster[0]=fNPeaks; - cnew.fNcluster[1]=0; - } - cnew.fMultiplicity=2; - cnew.fIndexMap[0]=cluster->fIndexMap[0]; - cnew.fIndexMap[1]=cluster->fIndexMap[i1]; - FillCluster(&cnew); - cnew.fClusterType=cnew.PhysicsContribution(); - AddRawCluster(cnew); - fNPeaks++; -// 1-cluster - cluster->fMultiplicity=1; - cluster->fIndexMap[0]=cluster->fIndexMap[i2]; - cluster->fIndexMap[1]=0; - cluster->fIndexMap[2]=0; - FillCluster(cluster); - if (fNPeaks != 0) { - cluster->fNcluster[0]=fNPeaks; - cluster->fNcluster[1]=0; - } - cluster->fClusterType=cluster->PhysicsContribution(); - AddRawCluster(*cluster); - fNPeaks++; - return kFALSE; - } else { - Warning("Centered","\n Completely screwed up %d !! \n",nd); - - } - return kFALSE; -}//Centered() -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::SplitByLocalMaxima(AliRICHRawCluster *c) -{// Split the cluster according to the number of maxima inside - Info("SplitbyLocalMaxima","Start."); + Rich()->GetLoader()->TreeD()->GetEntry(0); + for(Int_t iChamber=1;iChamber<=kNCH;iChamber++){//chambers loop + FindClusters(iChamber); + }//chambers loop + Rich()->GetLoader()->TreeR()->Fill(); + Rich()->GetLoader()->WriteRecPoints("OVERWRITE"); + }//events loop + Rich()->GetLoader()->UnloadDigits(); Rich()->GetLoader()->UnloadRecPoints(); + Rich()->ResetDigits(); Rich()->ResetClusters(); - AliRICHDigit* dig[100], *digt; - Int_t ix[100], iy[100], q[100]; - Double_t x[100], y[100]; - Int_t i; // loops over digits - Int_t j; // loops over local maxima - Int_t mul=c->fMultiplicity; -// dump digit information into arrays - for (i=0; iUncheckedAt(c->fIndexMap[i]); - ix[i]= dig[i]->PadX(); - iy[i]= dig[i]->PadY(); - q[i] = dig[i]->Signal(); - AliRICHParam::Pad2Loc(ix[i], iy[i], x[i], y[i]); - } -// Find local maxima - Bool_t isLocal[100]; - Int_t nLocal=0; - Int_t associatePeak[100]; - Int_t indLocal[100]; - Int_t nn; - Int_t xNei[kMaxNeighbours], yNei[kMaxNeighbours]; - for (i=0; iNeighbours(ix[i], iy[i], &nn, xNei, yNei); - isLocal[i]=kTRUE; - for (j=0; jTestHit(xNei[j], yNei[j])==kEmpty) continue; - digt=(AliRICHDigit*) fHitMap->GetHit(xNei[j], yNei[j]); - if (digt->Signal() > q[i]) { - isLocal[i]=kFALSE; - break; -// handle special case of neighbouring pads with equal signal - } else if (digt->Signal() == q[i]) { - if (nLocal >0) { - for (Int_t k=0; k5) { - Int_t nnew=0; - for (i=0; iGetLoader()->GetRunLoader()->UnloadHeader(); + Rich()->GetLoader()->GetRunLoader()->UnloadKinematics(); -// Initialise global variables for fit - gFirst=kTRUE; - gSegmentation=fSegmentation; - gResponse =fResponse; - gNbins=mul; - - for (i=0; iSetFCN(fcn); - gMyMinuit->mninit(5,10,7); - Double_t arglist[20]; - arglist[0]=1; -// Set starting values - static Double_t vstart[5]; - vstart[0]=x[indLocal[0]]; - vstart[1]=y[indLocal[0]]; - vstart[2]=x[indLocal[1]]; - vstart[3]=y[indLocal[1]]; - vstart[4]=Float_t(q[indLocal[0]])/Float_t(q[indLocal[0]]+q[indLocal[1]]); -// lower and upper limits - static Double_t lower[5], upper[5]; - lower[0]=vstart[0]-AliRICHParam::PadSizeX()/2; - lower[1]=vstart[1]-AliRICHParam::PadSizeY()/2; - - upper[0]=vstart[0]+AliRICHParam::PadSizeX()/2; - upper[1]=vstart[1]+AliRICHParam::PadSizeY()/2; - - lower[2]=vstart[2]-AliRICHParam::PadSizeX()/2; - lower[3]=vstart[3]-AliRICHParam::PadSizeY()/2; - - upper[2]=vstart[2]+AliRICHParam::PadSizeX()/2; - upper[3]=vstart[3]+AliRICHParam::PadSizeY()/2; - - lower[4]=0.; - upper[4]=1.; -// step sizes - static Double_t step[5]={0.005, 0.03, 0.005, 0.03, 0.01}; - Int_t iErr; - - gMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],iErr); - gMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],iErr); - gMyMinuit->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],iErr); - gMyMinuit->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],iErr); - gMyMinuit->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],iErr); -// ready for minimisation - gMyMinuit->SetPrintLevel(-1); - gMyMinuit->mnexcm("SET OUT", arglist, 0, iErr); - arglist[0]= -1; - arglist[1]= 0; - - gMyMinuit->mnexcm("SET NOGR", arglist, 0, iErr); - gMyMinuit->mnexcm("SIMPLEX", arglist, 0, iErr); - gMyMinuit->mnexcm("MIGRAD", arglist, 0, iErr); - gMyMinuit->mnexcm("EXIT" , arglist, 0, iErr); + Info("Exec","Stop."); +}//Exec() +//__________________________________________________________________________________________________ +void AliRICHClusterFinder::FindClusters(Int_t iChamber) +{ + //finds neighbours and fill the tree with raw clusters + Int_t nDigits=Rich()->Digits(iChamber)->GetEntriesFast(); +// Info("FindClusters","Start for Chamber %i with %i digits.",iChamber,nDigits); + if(nDigits==0)return; - Double_t xrec[2], yrec[2], qfrac; - TString chname; - Double_t epxz, b1, b2; - gMyMinuit->mnpout(0, chname, xrec[0], epxz, b1, b2, iErr); - gMyMinuit->mnpout(1, chname, yrec[0], epxz, b1, b2, iErr); - gMyMinuit->mnpout(2, chname, xrec[1], epxz, b1, b2, iErr); - gMyMinuit->mnpout(3, chname, yrec[1], epxz, b1, b2, iErr); - gMyMinuit->mnpout(4, chname, qfrac, epxz, b1, b2, iErr); - - cout<<"xrex[0]="<fIndexMap[i]; - TVector3 x3(xrec[j],yrec[j],0); - cnew.fContMap[cnew.fMultiplicity]=AliRICHParam::Loc2PadFrac(x3,gix[i], giy[i]); - cnew.fMultiplicity++; - } - FillCluster(&cnew,0); - cnew.fClusterType=cnew.PhysicsContribution(); - AddRawCluster(cnew); - fNPeaks++; - } - }//if 2 maximum in cluster - Bool_t fitted=kTRUE; + fHitMap=new AliRICHMap(Rich()->Digits(iChamber));//create digit map for the given chamber - if (nLocal >2 || !fitted) { - // Check if enough local clusters have been found, if not add global maxima to the list - Int_t nPerMax; - if (nLocal!=0) { - nPerMax=mul/nLocal; - } else { - Warning("SplitByLocalMaxima","no local maximum found"); - nPerMax=fNperMax+1; - } + for(Int_t iDig=0;iDigDigits(iChamber)->At(iDig); + Int_t i=dig->X(); Int_t j=dig->Y(); + if(fHitMap->TestHit(i,j)==kUsed) continue; - if (nPerMax > fNperMax) { - Int_t nGlob=mul/fNperMax-nLocal+1; - if (nGlob > 0) { - Int_t nnew=0; - for (i=0; iqmax) { - dmin=d; - qmax=ql; - associatePeak[i]=j; - } - } - } - } - // One cluster for each maximum - for (j=0; jfIndexMap[indLocal[j]]; - cnew.fMultiplicity=1; - for (i=0; ifIndexMap[i]; - cnew.fMultiplicity++; - } - } - FillCluster(&cnew); - cnew.fClusterType=cnew.PhysicsContribution(); - AddRawCluster(cnew); - fNPeaks++; - } - } -}//SplitByLocalMaxima(AliRICHRawCluster *c) -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::FillCluster(AliRICHRawCluster* c, Int_t flag) -{// Completes cluster information starting from list of digits - AliRICHDigit* dig; - Double_t x, y; - Int_t ix, iy; - Float_t fraction=0; + FormRawCluster(i,j); + FindLocalMaxima(); +// cout << " fNlocals in FindCluster " << fNlocals << endl; + fRawCluster.CoG(fNlocals); // first initial approxmation of the CoG...to start minimization. - c->fPeakSignal=0; - if (flag) { - c->fX=0; - c->fY=0; - c->fQ=0; + if(AliRICHParam::IsResolveClusters()) { + ResolveCluster(); // ResolveCluster serialization will happen inside + } else { + WriteRawCluster(); // simply output of the RawCluster found without deconvolution } - - - for (Int_t i=0; ifMultiplicity; i++){ - dig= (AliRICHDigit*)fDigits->UncheckedAt(c->fIndexMap[i]); - ix=dig->PadX(); - iy=dig->PadY(); - Int_t q=dig->Signal(); - if (dig->Physics() >= dig->Signal()) { - c->fPhysicsMap[i]=2; - } else if (dig->Physics() == 0) { - c->fPhysicsMap[i]=0; - } else c->fPhysicsMap[i]=1; -// peak signal and track list - if (flag) { - if (q>c->fPeakSignal) { - c->fPeakSignal=q; - c->fTracks[0]=dig->Hit(); - c->fTracks[1]=dig->Track(0); - c->fTracks[2]=dig->Track(1); - } - } else { - if (c->fContMap[i] > fraction) { - fraction=c->fContMap[i]; - c->fPeakSignal=q; - c->fTracks[0]=dig->Hit(); - c->fTracks[1]=dig->Track(0); - c->fTracks[2]=dig->Track(1); - } - } - if (flag) { - AliRICHParam::Pad2Loc(ix,iy,x,y); - c->fX += q*x; - c->fY += q*y; - c->fQ += q; - } - - } // loop over digits + fRawCluster.Reset(); + fResolvedCluster.Reset(); + }//digits loop - if (flag) { - - c->fX/=c->fQ; - c->fX=fSegmentation->GetAnod(c->fX); - c->fY/=c->fQ; -// apply correction to the coordinate along the anode wire - x=c->fX; - y=c->fY; - AliRICHParam::Loc2Pad(x,y,ix,iy); - AliRICHParam::Pad2Loc(ix,iy,x,y); - Int_t isec=fSegmentation->Sector(ix,iy); - TF1* cogCorr = fSegmentation->CorrFunc(isec-1); - - if (cogCorr) { - Float_t yOnPad=(c->fY-y)/fSegmentation->Dpy(isec); - c->fY=c->fY-cogCorr->Eval(yOnPad, 0, 0); - } - } -}//FillCluster() + delete fHitMap; +// Info("FindClusters","Stop."); + +}//FindClusters() //__________________________________________________________________________________________________ -void AliRICHClusterFinder::AddDigit2Cluster(Int_t i, Int_t j, AliRICHRawCluster &c) -{//Find clusters Add i,j as element of the cluster - Info("AddDigit2Cluster","Start with digit(%i,%i)",i,j); +void AliRICHClusterFinder::FindClusterContribs(AliRICHcluster *pCluster) +{ +// finds CombiPid for a given cluster +// Info("FindClusterContribs","Start"); - Int_t idx = fHitMap->GetHitIndex(i,j); - AliRICHDigit* dig = (AliRICHDigit*) fHitMap->GetHit(i,j); - Int_t q=dig->Signal(); - if(q>TMath::Abs(c.fPeakSignal)){ - c.fPeakSignal=q; - c.fTracks[0]=dig->Hit(); - c.fTracks[1]=dig->Track(0); - c.fTracks[2]=dig->Track(1); - } -// Make sure that list of digits is ordered - Int_t mu=c.fMultiplicity; - c.fIndexMap[mu]=idx; - - if (dig->Physics() >= dig->Signal()) { - c.fPhysicsMap[mu]=2; - } else if (dig->Physics() == 0) { - c.fPhysicsMap[mu]=0; - } else c.fPhysicsMap[mu]=1; + TObjArray *pDigits = pCluster->Digits(); + Int_t iNmips=0,iNckovs=0,iNfeeds=0; + TArrayI contribs(3*pCluster->Size()); + Int_t *pindex = new Int_t[3*pCluster->Size()]; + for(Int_t iDigN=0;iDigNSize();iDigN++) {//loop on digits of a given cluster + contribs[3*iDigN] =((AliRICHdigit*)pDigits->At(iDigN))->Tid(0); + contribs[3*iDigN+1]=((AliRICHdigit*)pDigits->At(iDigN))->Tid(1); + contribs[3*iDigN+2]=((AliRICHdigit*)pDigits->At(iDigN))->Tid(2); + }//loop on digits of a given cluster + TMath::Sort(contribs.GetSize(),contribs.GetArray(),pindex); + for(Int_t iDigN=0;iDigN<3*pCluster->Size()-1;iDigN++) {//loop on digits to sort Tid + if(contribs[pindex[iDigN]]!=contribs[pindex[iDigN+1]]) { + Int_t code = Rich()->GetLoader()->GetRunLoader()->Stack()->Particle(contribs[pindex[iDigN]])->GetPdgCode(); + Double_t charge = Rich()->GetLoader()->GetRunLoader()->Stack()->Particle(contribs[pindex[iDigN]])->GetPDG()->Charge(); - if (mu > 0) { - for (Int_t ind=mu-1; ind>=0; ind--) { - Int_t ist=(c.fIndexMap)[ind]; - Int_t ql=((AliRICHDigit*)fDigits->UncheckedAt(ist))->Signal(); - if (q>ql) { - c.fIndexMap[ind]=idx; - c.fIndexMap[ind+1]=ist; - } else { - break; - } - } + if(code==50000050) iNckovs++; + else if(code==50000051) iNfeeds++; + else if(charge!=0) iNmips++; + if (contribs[pindex[iDigN+1]]==kBad) break; } - - c.fMultiplicity++; - if (c.fMultiplicity >= 50 ) { - Info("AddDigit2CLuster","multiplicity >50 %d \n",c.fMultiplicity); - c.fMultiplicity=49; - } - Double_t x,y;// Prepare center of gravity calculation - AliRICHParam::Pad2Loc(i,j,x,y); - c.fX+=q*x; c.fY+=q*y; c.fQ += q; + }//loop on digits to sort Tid + pCluster->SetCombiPid(iNckovs,iNfeeds,iNmips); +// pCluster->Print(); + delete [] pindex; +}//FindClusterContribs() +//__________________________________________________________________________________________________ +void AliRICHClusterFinder::FormRawCluster(Int_t i, Int_t j) +{ +// Builder of the final Raw Cluster (before deconvolution) + if(GetDebug()) Info("FormRawCluster","Start with digit(%i,%i)",i,j); + + fRawCluster.AddDigit((AliRICHdigit*) fHitMap->GetHit(i,j)); fHitMap->FlagHit(i,j);// Flag hit as taken - - Int_t xList[4], yList[4]; // Now look recursively for all neighbours - for (Int_t iNei=0;iNeiParam()->PadNeighbours(i,j,xList,yList);iNei++) - if(fHitMap->TestHit(xList[iNei],yList[iNei])==kUnused) AddDigit2Cluster(xList[iNei],yList[iNei],c); -}//AddDigit2Cluster() + Int_t listX[4], listY[4]; // Now look recursively for all neighbours + for (Int_t iNeighbour=0;iNeighbourParam()->PadNeighbours(i,j,listX,listY);iNeighbour++) + if(fHitMap->TestHit(listX[iNeighbour],listY[iNeighbour])==kUnused) + FormRawCluster(listX[iNeighbour],listY[iNeighbour]); +}//FormRawCluster() //__________________________________________________________________________________________________ -void AliRICHClusterFinder::FindRawClusters() -{//finds neighbours and fill the tree with raw clusters - Info("FindRawClusters","Start for Chamber %i.",fChamber); +void AliRICHClusterFinder::ResolveCluster() +{// Decluster algorithm + if(GetDebug()) {Info("ResolveCluster","Start."); fRawCluster.Print();} - if(!fNdigits)return; - - fHitMap=new AliRICHMap(fDigits); - - for(Int_t iDigN=0;iDigNUncheckedAt(iDigN); - Int_t i=dig->PadX(); Int_t j=dig->PadY(); - if(fHitMap->TestHit(i,j)==kUsed||fHitMap->TestHit(i,j)==kEmpty) continue; - - AliRICHRawCluster c; - c.fMultiplicity=0; c.fPeakSignal=dig->Signal(); - c.fTracks[0]=dig->Hit();c.fTracks[1]=dig->Track(0);c.fTracks[2]=dig->Track(1); - c.fNcluster[0]=-1;// tag the beginning of cluster list in a raw cluster - - AddDigit2Cluster(i,j,c);//form initial cluster - - c.fX /= c.fQ; // center of gravity - //c.fX=fSegmentation->GetAnod(c.fX); - c.fY /= c.fQ; - //AddRawCluster(c); - -// Int_t ix,iy;// apply correction to the coordinate along the anode wire -// Float_t x=c.fX, y=c.fY; -// Rich()->Param()->Loc2Pad(x,y,ix,iy); -// Rich()->Param()->Pad2Loc(ix,iy,x,y); -// Int_t isec=fSegmentation->Sector(ix,iy); -// TF1* cogCorr=fSegmentation->CorrFunc(isec-1); -// if(cogCorr){ -// Float_t yOnPad=(c.fY-y)/fSegmentation->Dpy(isec); -// c.fY=c.fY-cogCorr->Eval(yOnPad,0,0); -// } - - c.fNcluster[1]=fNRawClusters; c.fClusterType=c.PhysicsContribution(); - - Decluster(&c); - - fNPeaks=0; - - c.fMultiplicity=0; for(int k=0;k 1: if=2 FitCoG; if>2 Resolve and FitCoG + FitCoG();break; + } +}//ResolveCluster() //__________________________________________________________________________________________________ -void AliRICHClusterFinder::CalibrateCOG() -{// Calibration - - Float_t x[5]; - Float_t y[5]; - Int_t n, i; - if (fSegmentation) { - TF1 *func; - fSegmentation->GiveTestPoints(n, x, y); - for (i=0; iSetCorrFunc(i, new TF1(*func)); - } - } -}//CalibrateCOG() +void AliRICHClusterFinder::WriteRawCluster() +{ +// out the current raw cluster +// Info("WriteRawCluster","Start."); + + FindClusterContribs(&fRawCluster); + Rich()->AddCluster(fRawCluster); +// fRawCluster.Print(); +}//WriteRawCluster() //__________________________________________________________________________________________________ -void AliRICHClusterFinder::SinoidalFit(Double_t x, Double_t y, TF1 *func) -{//Sinoidal fit - static Int_t count=0; - - count++; +void AliRICHClusterFinder::WriteResolvedCluster() +{ +// out the current resolved cluster +// Info("WriteResolvedCluster","Start."); + +// FindClusterContribs(&fResolvedCluster); + Rich()->AddCluster(fResolvedCluster); + +}//WriteResolvedCluster() +//__________________________________________________________________________________________________ +void AliRICHClusterFinder::FitCoG() +{// Fit cluster size 2 by single Mathieson + Info("FitCoG","Start with size %3i and local maxima %3i",fRawCluster.Size(),fNlocals); + + Double_t arglist; + Int_t ierflag = 0; - const Int_t kNs=101; - Float_t xg[kNs], yg[kNs], xrg[kNs], yrg[kNs]; - Float_t xsig[kNs], ysig[kNs]; - - Int_t ix,iy; - AliRICHParam::Loc2Pad(x,y,ix,iy); - AliRICHParam::Pad2Loc(ix,iy,x,y); - Int_t isec=fSegmentation->Sector(ix,iy); -// Pad Limits - Float_t xmin = x-Rich()->Param()->PadSizeX()/2; - Float_t ymin = y-Rich()->Param()->PadSizeY()/2; -// -// Integration Limits - Float_t dxI=Rich()->Param()->MathiensonDeltaX(); - Float_t dyI=Rich()->Param()->MathiensonDeltaY(); +// fRawCluster.Print(); + if(fNlocals==0) fRawCluster.Print(); + if(fNlocals==0||fNlocals>3) {WriteRawCluster();return;} + + TMinuit *pMinuit = new TMinuit(3*fNlocals-1); + pMinuit->mninit(5,10,7); + + arglist = -1; + pMinuit->mnexcm("SET PRI",&arglist, 1, ierflag); + + TString chname; + Int_t ierflg; + + pMinuit->SetObjectFit((TObject*)this); + pMinuit->SetFCN(RICHMinMathieson); + + Double_t vstart,lower, upper; + Double_t stepX= 0.001; + Double_t stepY= 0.001; + Double_t stepQ= 0.0001; + + for(Int_t i=0;imnparm(3*i ,Form("xCoG %i",i),vstart,stepX,lower,upper,ierflag); +// cout << Form("xCoG %i",i) << "start " << vstart << "lower " << lower << "upper " << upper << endl; + vstart = fLocalY[i]; + lower = vstart - 2*AliRICHParam::PadSizeY(); + upper = vstart + 2*AliRICHParam::PadSizeY(); + pMinuit->mnparm(3*i+1,Form("yCoG %i",i),vstart,stepY,lower,upper,ierflag); +// cout << Form("yCoG %i",i) << "start " << vstart << "lower " << lower << "upper " << upper << endl; + if(i==fNlocals-1) break; // last parameter is constrained + vstart = fLocalQ[i]/fRawCluster.Q(); + lower = 0; + upper = 1; + pMinuit->mnparm(3*i+2,Form("qfrac %i",i),vstart,stepQ,lower,upper,ierflag); +// cout << Form("qCoG %i",i) << "start " << vstart << "lower " << lower << "upper " << upper << endl; -// -// Scanning -// - Int_t i; - Float_t qp=0; + } + + arglist = -1; + + pMinuit->mnexcm("SET NOGR",&arglist, 1, ierflag); + pMinuit->mnexcm("SET NOW",&arglist, 1, ierflag); + arglist = 1; + pMinuit->mnexcm("SET ERR", &arglist, 1,ierflg); + arglist = -1; + pMinuit->mnexcm("SIMPLEX",&arglist, 0, ierflag); + pMinuit->mnexcm("MIGRAD",&arglist, 0, ierflag); + pMinuit->mnexcm("EXIT" ,&arglist, 0, ierflag); -// y-position - Float_t yscan=ymin; - Float_t dy=Rich()->Param()->PadSizeY()/(kNs-1); + Double_t xCoG[50],yCoG[50],qfracCoG[50]; + Double_t eps, b1, b2; - for (i=0; iSigGenInit(x, yscan, 0); - - for (fSegmentation->FirstPad(x, yscan,0, dxI, dyI); - fSegmentation->MorePads(); - fSegmentation->NextPad()) - { - qp=fResponse->IntXY(fSegmentation); - qp=TMath::Abs(qp); - if (qp > 1.e-4) { - qcheck+=qp; - Int_t ixs=fSegmentation->Ix(); - Int_t iys=fSegmentation->Iy(); - Double_t xs,ys; - AliRICHParam::Pad2Loc(ixs,iys,xs,ys); - sum+=qp*ys; - } - } // Pad loop - Float_t ycog=sum/qcheck; - yg[i]=(yscan-y)/fSegmentation->Dpy(isec); - yrg[i]=(ycog-y)/fSegmentation->Dpy(isec); - ysig[i]=ycog-yscan; - yscan+=dy; - } // scan loop -// x-position - Float_t xscan=xmin; - Float_t dx=fSegmentation->Dpx(isec)/(kNs-1); + Double_t qfraclast=0; + for(Int_t i=0;imnpout(3*i ,chname, xCoG[i], eps , b1, b2, ierflg); + pMinuit->mnpout(3*i+1,chname, yCoG[i], eps , b1, b2, ierflg); + if(i==fNlocals-1) break; + pMinuit->mnpout(3*i+2,chname, qfracCoG[i], eps , b1, b2, ierflg); + qfraclast+=qfracCoG[i]; + } + qfracCoG[fNlocals-1] = 1 - qfraclast; + delete pMinuit; - for (i=0; iSigGenInit(xscan, y, 0); - - for (fSegmentation->FirstPad(xscan, y, 0, dxI, dyI); - fSegmentation->MorePads(); - fSegmentation->NextPad()) - { - qp=fResponse->IntXY(fSegmentation); - qp=TMath::Abs(qp); - if (qp > 1.e-2) { - qcheck+=qp; - Int_t ixs=fSegmentation->Ix(); - Int_t iys=fSegmentation->Iy(); - Double_t xs,ys; - AliRICHParam::Pad2Loc(ixs,iys,xs,ys); - sum+=qp*xs; - } - } // Pad loop - Float_t xcog=sum/qcheck; - xcog=fSegmentation->GetAnod(xcog); - - xg[i]=(xscan-x)/fSegmentation->Dpx(isec); - xrg[i]=(xcog-x)/fSegmentation->Dpx(isec); - xsig[i]=xcog-xscan; - xscan+=dx; - } -// Creates a Root function based on function sinoid above and perform the fit - TGraph *graphyr= new TGraph(kNs,yrg,ysig); - Double_t sinoid(Double_t *x, Double_t *par); - new TF1("sinoidf",sinoid,0.5,0.5,5); - graphyr->Fit("sinoidf","Q"); - func = (TF1*)graphyr->GetListOfFunctions()->At(0); -}//SinoidalFit() -//__________________________________________________________________________________________________ -Double_t sinoid(Double_t *x, Double_t *par) -{// Sinoid function + for(Int_t i=0;iGetObjectFit())->GetRawCluster(); - static Float_t qtot; - if (gFirst) { - qtot=0; - for (Int_t jbin=0; jbinGetLoader()->LoadDigits(); - - for(Int_t iEventN=0;iEventNGetEventsPerRun();iEventN++){//events loop - gAlice->GetRunLoader()->GetEvent(iEventN); - - Rich()->GetLoader()->MakeTree("R"); Rich()->MakeBranch("R"); - Rich()->ResetDigitsOld(); Rich()->ResetRawClusters(); - - Rich()->GetLoader()->TreeD()->GetEntry(0); - for(fChamber=1;fChamber<=kNCH;fChamber++){//chambers loop - fDigits=Rich()->DigitsOld(fChamber); fNdigits=fDigits->GetEntries(); - - FindRawClusters(); - - }//chambers loop - - Rich()->GetLoader()->TreeR()->Fill(); - Rich()->GetLoader()->WriteRecPoints("OVERWRITE"); - }//events loop - Rich()->GetLoader()->UnloadDigits(); Rich()->GetLoader()->UnloadRecPoints(); - Rich()->ResetDigitsOld(); Rich()->ResetRawClusters(); - Info("Exec","Stop."); -}//Exec() -//__________________________________________________________________________________________________ + chi2 += TMath::Power((qtot*qfracpar-padQ),2)/padQ; +// cout << " chi2 " << chi2 << " pad n. " << i << " qfracpar " << qfracpar << endl; + } +// if(iflag==3) { +// cout << " chi2 final " << chi2 << endl; +// } +}//RICHMinMathieson()