1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 Revision 1.10 2001/02/27 15:21:58 jbarbosa
19 Transition to SDigits.
21 Revision 1.9 2001/01/26 20:00:27 hristov
22 Major upgrade of AliRoot code
24 Revision 1.8 2000/11/02 09:11:12 jbarbosa
25 Removed AliRICHRecHit.h from include.
27 Revision 1.7 2000/10/03 21:44:09 morsch
28 Use AliSegmentation and AliHit abstract base classes.
30 Revision 1.6 2000/10/02 21:28:12 fca
31 Removal of useless dependecies via forward declarations
33 Revision 1.5 2000/10/02 15:45:58 jbarbosa
34 Fixed forward declarations.
36 Revision 1.4 2000/06/12 19:01:29 morsch
37 Clean-up bug in Centered() corrected.
39 Revision 1.3 2000/06/12 15:49:44 jbarbosa
40 Removed verbose output.
42 Revision 1.2 2000/06/12 15:18:19 jbarbosa
45 Revision 1.1 2000/04/19 13:01:48 morsch
46 A cluster finder and hit reconstruction class for RICH (adapted from MUON).
47 Cluster Finders for MUON and RICH should derive from the same class in the
53 #include "AliRICHClusterFinder.h"
56 #include "AliRICHHit.h"
57 #include "AliRICHHitMapA1.h"
58 #include "AliRICHCerenkov.h"
59 #include "AliRICHSDigit.h"
60 #include "AliRICHDigit.h"
61 #include "AliRICHRawCluster.h"
69 #include <TPostScript.h>
72 //----------------------------------------------------------
73 static AliSegmentation* gSegmentation;
74 static AliRICHResponse* gResponse;
75 static Int_t gix[500];
76 static Int_t giy[500];
77 static Float_t gCharge[500];
79 static Int_t gFirst=kTRUE;
80 static TMinuit *gMyMinuit ;
81 void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
82 static Int_t gChargeTot;
84 ClassImp(AliRICHClusterFinder)
86 AliRICHClusterFinder::AliRICHClusterFinder
87 (AliSegmentation *segmentation, AliRICHResponse *response,
88 TClonesArray *digits, Int_t chamber)
91 // Constructor for Cluster Finder object
93 fSegmentation=segmentation;
97 fNdigits = fDigits->GetEntriesFast();
99 fRawClusters=new TClonesArray("AliRICHRawCluster",10000);
108 AliRICHClusterFinder::AliRICHClusterFinder()
111 // Default constructor
119 fRawClusters=new TClonesArray("AliRICHRawCluster",10000);
129 AliRICHClusterFinder::AliRICHClusterFinder(const AliRICHClusterFinder& ClusterFinder)
134 AliRICHClusterFinder::~AliRICHClusterFinder()
142 void AliRICHClusterFinder::AddRawCluster(const AliRICHRawCluster c)
145 // Add a raw cluster copy to the list
147 AliRICH *pRICH=(AliRICH*)gAlice->GetModule("RICH");
148 pRICH->AddRawCluster(fChamber,c);
154 void AliRICHClusterFinder::Decluster(AliRICHRawCluster *cluster)
158 // Decluster algorithm
160 Int_t mul = cluster->fMultiplicity;
161 // printf("Decluster - multiplicity %d \n",mul);
163 if (mul == 1 || mul ==2) {
165 // Nothing special for 1- and 2-clusters
167 cluster->fNcluster[0]=fNPeaks;
168 cluster->fNcluster[1]=0;
170 AddRawCluster(*cluster);
172 } else if (mul ==3) {
174 // 3-cluster, check topology
175 // printf("\n 3-cluster, check topology \n");
176 if (fDeclusterFlag) {
177 if (Centered(cluster)) {
178 // ok, cluster is centered
180 // cluster is not centered, split into 2+1
184 cluster->fNcluster[0]=fNPeaks;
185 cluster->fNcluster[1]=0;
187 AddRawCluster(*cluster);
192 // 4-and more-pad clusters
194 if (mul <= fClusterSize) {
195 if (fDeclusterFlag) {
196 SplitByLocalMaxima(cluster);
199 cluster->fNcluster[0]=fNPeaks;
200 cluster->fNcluster[1]=0;
202 AddRawCluster(*cluster);
210 Bool_t AliRICHClusterFinder::Centered(AliRICHRawCluster *cluster)
213 // Is the cluster centered?
216 dig= (AliRICHDigit*)fDigits->UncheckedAt(cluster->fIndexMap[0]);
217 Int_t ix=dig->PadX();
218 Int_t iy=dig->PadY();
220 Int_t x[kMaxNeighbours], y[kMaxNeighbours], xN[kMaxNeighbours], yN[kMaxNeighbours];
222 fSegmentation->Neighbours(ix,iy,&nn,x,y);
224 for (Int_t i=0; i<nn; i++) {
225 if (fHitMap->TestHit(x[i],y[i]) == kUsed) {
230 //printf("Getting: %d %d %d\n",i,x[i],y[i]);
235 // cluster is centered !
237 cluster->fNcluster[0]=fNPeaks;
238 cluster->fNcluster[1]=0;
241 AddRawCluster(*cluster);
246 // Highest signal on an edge, split cluster into 2+1
248 // who is the neighbour ?
250 //printf("Calling GetIndex with x:%d y:%d\n",xN[0], yN[0]);
252 Int_t nind=fHitMap->GetHitIndex(xN[0], yN[0]);
253 Int_t i1= (nind==cluster->fIndexMap[1]) ? 1:2;
254 Int_t i2= (nind==cluster->fIndexMap[1]) ? 2:1;
257 AliRICHRawCluster cnew;
259 cnew.fNcluster[0]=-1;
260 cnew.fNcluster[1]=fNRawClusters;
262 cnew.fNcluster[0]=fNPeaks;
265 cnew.fMultiplicity=2;
266 cnew.fIndexMap[0]=cluster->fIndexMap[0];
267 cnew.fIndexMap[1]=cluster->fIndexMap[i1];
269 cnew.fClusterType=cnew.PhysicsContribution();
274 cluster->fMultiplicity=1;
275 cluster->fIndexMap[0]=cluster->fIndexMap[i2];
276 cluster->fIndexMap[1]=0;
277 cluster->fIndexMap[2]=0;
278 FillCluster(cluster);
280 cluster->fNcluster[0]=fNPeaks;
281 cluster->fNcluster[1]=0;
283 cluster->fClusterType=cluster->PhysicsContribution();
284 AddRawCluster(*cluster);
288 printf("\n Completely screwed up %d !! \n",nd);
294 void AliRICHClusterFinder::SplitByLocalMaxima(AliRICHRawCluster *c)
298 // Split the cluster according to the number of maxima inside
301 AliRICHDigit* dig[100], *digt;
302 Int_t ix[100], iy[100], q[100];
303 Float_t x[100], y[100], zdum;
304 Int_t i; // loops over digits
305 Int_t j; // loops over local maxima
308 // Int_t threshold=500;
309 Int_t mul=c->fMultiplicity;
311 // dump digit information into arrays
313 for (i=0; i<mul; i++)
315 dig[i]= (AliRICHDigit*)fDigits->UncheckedAt(c->fIndexMap[i]);
316 ix[i]= dig[i]->PadX();
317 iy[i]= dig[i]->PadY();
318 q[i] = dig[i]->Signal();
319 fSegmentation->GetPadC(ix[i], iy[i], x[i], y[i], zdum);
326 Int_t associatePeak[100];
329 Int_t xNei[kMaxNeighbours], yNei[kMaxNeighbours];
330 for (i=0; i<mul; i++) {
331 fSegmentation->Neighbours(ix[i], iy[i], &nn, xNei, yNei);
333 for (j=0; j<nn; j++) {
334 if (fHitMap->TestHit(xNei[j], yNei[j])==kEmpty) continue;
335 digt=(AliRICHDigit*) fHitMap->GetHit(xNei[j], yNei[j]);
336 if (digt->Signal() > q[i]) {
340 // handle special case of neighbouring pads with equal signal
341 } else if (digt->Signal() == q[i]) {
343 for (Int_t k=0; k<nLocal; k++) {
344 if (xNei[j]==ix[indLocal[k]] && yNei[j]==iy[indLocal[k]]){
350 } // loop over next neighbours
351 // Maxima should not be on the edge
356 } // loop over all digits
357 // printf("Found %d local Maxima",nLocal);
359 // If only one local maximum found but multiplicity is high
360 // take global maximum from the list of digits.
361 if (nLocal==1 && mul>5) {
363 for (i=0; i<mul; i++) {
374 // If number of local maxima is 2 try to fit a double gaussian
377 // Initialise global variables for fit
379 gSegmentation=fSegmentation;
380 gResponse =fResponse;
383 for (i=0; i<mul; i++) {
386 gCharge[i]=Float_t(q[i]);
391 gMyMinuit = new TMinuit(5);
393 gMyMinuit->SetFCN(fcn);
394 gMyMinuit->mninit(5,10,7);
395 Double_t arglist[20];
398 // gMyMinuit->mnexcm("SET ERR",arglist,1,ierflag);
399 // Set starting values
400 static Double_t vstart[5];
401 vstart[0]=x[indLocal[0]];
402 vstart[1]=y[indLocal[0]];
403 vstart[2]=x[indLocal[1]];
404 vstart[3]=y[indLocal[1]];
405 vstart[4]=Float_t(q[indLocal[0]])/
406 Float_t(q[indLocal[0]]+q[indLocal[1]]);
407 // lower and upper limits
408 static Double_t lower[5], upper[5];
409 Int_t isec=fSegmentation->Sector(ix[indLocal[0]], iy[indLocal[0]]);
410 lower[0]=vstart[0]-fSegmentation->Dpx(isec)/2;
411 lower[1]=vstart[1]-fSegmentation->Dpy(isec)/2;
412 // lower[1]=vstart[1];
414 upper[0]=lower[0]+fSegmentation->Dpx(isec);
415 upper[1]=lower[1]+fSegmentation->Dpy(isec);
416 // upper[1]=vstart[1];
418 isec=fSegmentation->Sector(ix[indLocal[1]], iy[indLocal[1]]);
419 lower[2]=vstart[2]-fSegmentation->Dpx(isec)/2;
420 lower[3]=vstart[3]-fSegmentation->Dpy(isec)/2;
421 // lower[3]=vstart[3];
423 upper[2]=lower[2]+fSegmentation->Dpx(isec);
424 upper[3]=lower[3]+fSegmentation->Dpy(isec);
425 // upper[3]=vstart[3];
430 static Double_t step[5]={0.005, 0.03, 0.005, 0.03, 0.01};
432 gMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag);
433 gMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag);
434 gMyMinuit->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag);
435 gMyMinuit->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag);
436 gMyMinuit->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag);
437 // ready for minimisation
438 gMyMinuit->SetPrintLevel(-1);
439 gMyMinuit->mnexcm("SET OUT", arglist, 0, ierflag);
443 gMyMinuit->mnexcm("SET NOGR", arglist, 0, ierflag);
444 gMyMinuit->mnexcm("SCAN", arglist, 0, ierflag);
445 gMyMinuit->mnexcm("EXIT" , arglist, 0, ierflag);
447 // Double_t amin,edm,errdef;
448 // Int_t nvpar,nparx,icstat;
449 // gMyMinuit->mnstat(amin,edm,errdef,nvpar,nparx,icstat);
450 // gMyMinuit->mnprin(3,amin);
451 // Get fitted parameters
453 Double_t xrec[2], yrec[2], qfrac;
455 Double_t epxz, b1, b2;
457 gMyMinuit->mnpout(0, chname, xrec[0], epxz, b1, b2, ierflg);
458 gMyMinuit->mnpout(1, chname, yrec[0], epxz, b1, b2, ierflg);
459 gMyMinuit->mnpout(2, chname, xrec[1], epxz, b1, b2, ierflg);
460 gMyMinuit->mnpout(3, chname, yrec[1], epxz, b1, b2, ierflg);
461 gMyMinuit->mnpout(4, chname, qfrac, epxz, b1, b2, ierflg);
462 //printf("\n %f %f %f %f %f\n", xrec[0], yrec[0], xrec[1], yrec[1],qfrac);
467 // One cluster for each maximum
469 for (j=0; j<2; j++) {
470 AliRICHRawCluster cnew;
472 cnew.fNcluster[0]=-1;
473 cnew.fNcluster[1]=fNRawClusters;
475 cnew.fNcluster[0]=fNPeaks;
478 cnew.fMultiplicity=0;
479 cnew.fX=Float_t(xrec[j]);
480 cnew.fY=Float_t(yrec[j]);
482 cnew.fQ=Int_t(gChargeTot*qfrac);
484 cnew.fQ=Int_t(gChargeTot*(1-qfrac));
486 gSegmentation->SetHit(xrec[j],yrec[j],0);
487 for (i=0; i<mul; i++) {
488 cnew.fIndexMap[cnew.fMultiplicity]=c->fIndexMap[i];
489 gSegmentation->SetPad(gix[i], giy[i]);
490 Float_t q1=gResponse->IntXY(gSegmentation);
491 cnew.fContMap[cnew.fMultiplicity]=Float_t(q[i])/(q1*cnew.fQ);
492 cnew.fMultiplicity++;
494 FillCluster(&cnew,0);
495 //printf("\n x,y %f %f ", cnew.fX, cnew.fY);
496 cnew.fClusterType=cnew.PhysicsContribution();
504 if (nLocal !=-100 || !fitted) {
505 // Check if enough local clusters have been found,
506 // if not add global maxima to the list
512 printf("\n Warning, no local maximum found \n");
516 if (nPerMax > fNperMax) {
517 Int_t nGlob=mul/fNperMax-nLocal+1;
520 for (i=0; i<mul; i++) {
527 if (nnew==nGlob) break;
532 // Associate hits to peaks
534 for (i=0; i<mul; i++) {
537 if (isLocal[i]) continue;
538 for (j=0; j<nLocal; j++) {
539 Int_t il=indLocal[j];
540 Float_t d=TMath::Sqrt((x[i]-x[il])*(x[i]-x[il])
541 +(y[i]-y[il])*(y[i]-y[il]));
544 // Select nearest peak
550 } else if (d==dmin) {
552 // If more than one take highest peak
565 // One cluster for each maximum
567 for (j=0; j<nLocal; j++) {
568 AliRICHRawCluster cnew;
570 cnew.fNcluster[0]=-1;
571 cnew.fNcluster[1]=fNRawClusters;
573 cnew.fNcluster[0]=fNPeaks;
576 cnew.fIndexMap[0]=c->fIndexMap[indLocal[j]];
577 cnew.fMultiplicity=1;
578 for (i=0; i<mul; i++) {
579 if (isLocal[i]) continue;
580 if (associatePeak[i]==j) {
581 cnew.fIndexMap[cnew.fMultiplicity]=c->fIndexMap[i];
582 cnew.fMultiplicity++;
586 cnew.fClusterType=cnew.PhysicsContribution();
594 void AliRICHClusterFinder::FillCluster(AliRICHRawCluster* c, Int_t flag)
597 // Completes cluster information starting from list of digits
613 for (Int_t i=0; i<c->fMultiplicity; i++)
615 dig= (AliRICHDigit*)fDigits->UncheckedAt(c->fIndexMap[i]);
616 ix=dig->PadX()+c->fOffsetMap[i];
618 Int_t q=dig->Signal();
619 if (dig->Physics() >= dig->Signal()) {
621 } else if (dig->Physics() == 0) {
623 } else c->fPhysicsMap[i]=1;
626 // peak signal and track list
628 if (q>c->fPeakSignal) {
631 c->fTracks[0]=dig->Track(0);
632 c->fTracks[1]=dig->Track(1);
633 c->fTracks[2]=dig->Track(2);
635 //c->fTracks[0]=dig->fTrack;
636 c->fTracks[0]=dig->Hit();
637 c->fTracks[1]=dig->Track(0);
638 c->fTracks[2]=dig->Track(1);
641 if (c->fContMap[i] > frac) {
645 c->fTracks[0]=dig->Track(0);
646 c->fTracks[1]=dig->Track(1);
647 c->fTracks[2]=dig->Track(2);
649 //c->fTracks[0]=dig->fTrack;
650 c->fTracks[0]=dig->Hit();
651 c->fTracks[1]=dig->Track(0);
652 c->fTracks[2]=dig->Track(1);
657 fSegmentation->GetPadC(ix, iy, x, y, z);
663 } // loop over digits
668 c->fX=fSegmentation->GetAnod(c->fX);
671 // apply correction to the coordinate along the anode wire
675 fSegmentation->GetPadI(x, y, 0, ix, iy);
676 fSegmentation->GetPadC(ix, iy, x, y, z);
677 Int_t isec=fSegmentation->Sector(ix,iy);
678 TF1* cogCorr = fSegmentation->CorrFunc(isec-1);
681 Float_t yOnPad=(c->fY-y)/fSegmentation->Dpy(isec);
682 c->fY=c->fY-cogCorr->Eval(yOnPad, 0, 0);
688 void AliRICHClusterFinder::FindCluster(Int_t i, Int_t j, AliRICHRawCluster &c){
693 // Add i,j as element of the cluster
696 Int_t idx = fHitMap->GetHitIndex(i,j);
697 AliRICHDigit* dig = (AliRICHDigit*) fHitMap->GetHit(i,j);
698 Int_t q=dig->Signal();
699 if (q > TMath::Abs(c.fPeakSignal)) {
702 c.fTracks[0]=dig->fTracks[0];
703 c.fTracks[1]=dig->fTracks[1];
704 c.fTracks[2]=dig->fTracks[2];
706 //c.fTracks[0]=dig->fTrack;
707 c.fTracks[0]=dig->Hit();
708 c.fTracks[1]=dig->Track(0);
709 c.fTracks[2]=dig->Track(1);
712 // Make sure that list of digits is ordered
714 Int_t mu=c.fMultiplicity;
717 if (dig->Physics() >= dig->Signal()) {
719 } else if (dig->Physics() == 0) {
721 } else c.fPhysicsMap[mu]=1;
724 for (Int_t ind=mu-1; ind>=0; ind--) {
725 Int_t ist=(c.fIndexMap)[ind];
726 Int_t ql=((AliRICHDigit*)fDigits
727 ->UncheckedAt(ist))->Signal();
729 c.fIndexMap[ind]=idx;
730 c.fIndexMap[ind+1]=ist;
739 if (c.fMultiplicity >= 50 ) {
740 printf("FindCluster - multiplicity >50 %d \n",c.fMultiplicity);
744 // Prepare center of gravity calculation
746 fSegmentation->GetPadC(i, j, x, y, z);
751 fHitMap->FlagHit(i,j);
753 // Now look recursively for all neighbours
756 Int_t xList[kMaxNeighbours], yList[kMaxNeighbours];
757 fSegmentation->Neighbours(i,j,&nn,xList,yList);
758 for (Int_t in=0; in<nn; in++) {
761 if (fHitMap->TestHit(ix,iy)==kUnused) FindCluster(ix, iy, c);
765 //_____________________________________________________________________________
767 void AliRICHClusterFinder::FindRawClusters()
770 // simple RICH cluster finder from digits -- finds neighbours and
771 // fill the tree with raw clusters
773 if (!fNdigits) return;
775 fHitMap = new AliRICHHitMapA1(fSegmentation, fDigits);
779 //printf ("Now I'm here");
785 for (ndig=0; ndig<fNdigits; ndig++) {
786 dig = (AliRICHDigit*)fDigits->UncheckedAt(ndig);
789 if (fHitMap->TestHit(i,j)==kUsed ||fHitMap->TestHit(i,j)==kEmpty) {
795 c.fPeakSignal=dig->Signal();
797 c.fTracks[0]=dig->fTracks[0];
798 c.fTracks[1]=dig->fTracks[1];
799 c.fTracks[2]=dig->fTracks[2];
801 //c.fTracks[0]=dig->fTrack;
802 c.fTracks[0]=dig->Hit();
803 c.fTracks[1]=dig->Track(0);
804 c.fTracks[2]=dig->Track(1);
805 // tag the beginning of cluster list in a raw cluster
810 c.fX=fSegmentation->GetAnod(c.fX);
813 // apply correction to the coordinate along the anode wire
820 fSegmentation->GetPadI(x, y, 0, ix, iy);
821 fSegmentation->GetPadC(ix, iy, x, y, z);
822 Int_t isec=fSegmentation->Sector(ix,iy);
823 TF1* cogCorr=fSegmentation->CorrFunc(isec-1);
825 Float_t yOnPad=(c.fY-y)/fSegmentation->Dpy(isec);
826 c.fY=c.fY-cogCorr->Eval(yOnPad,0,0);
830 // Analyse cluster and decluster if necessary
833 c.fNcluster[1]=fNRawClusters;
834 c.fClusterType=c.PhysicsContribution();
840 // reset Cluster object
841 for (int k=0;k<c.fMultiplicity;k++) {
849 void AliRICHClusterFinder::
860 fSegmentation->GiveTestPoints(n, x, y);
861 for (i=0; i<n; i++) {
864 SinoidalFit(xtest, ytest, func);
865 fSegmentation->SetCorrFunc(i, new TF1(func));
871 void AliRICHClusterFinder::
872 SinoidalFit(Float_t x, Float_t y, TF1 &func)
877 static Int_t count=0;
882 sprintf(canvasname,"c%d",count);
885 Float_t xg[kNs], yg[kNs], xrg[kNs], yrg[kNs];
886 Float_t xsig[kNs], ysig[kNs];
888 AliSegmentation *segmentation=fSegmentation;
891 segmentation->GetPadI(x,y,0,ix,iy);
892 segmentation->GetPadC(ix,iy,x,y,z);
893 Int_t isec=segmentation->Sector(ix,iy);
895 Float_t xmin = x-segmentation->Dpx(isec)/2;
896 Float_t ymin = y-segmentation->Dpy(isec)/2;
898 // Integration Limits
899 Float_t dxI=fResponse->SigmaIntegration()*fResponse->ChargeSpreadX();
900 Float_t dyI=fResponse->SigmaIntegration()*fResponse->ChargeSpreadY();
910 Float_t dy=segmentation->Dpy(isec)/(kNs-1);
912 for (i=0; i<kNs; i++) {
918 segmentation->SigGenInit(x, yscan, 0);
920 for (segmentation->FirstPad(x, yscan,0, dxI, dyI);
921 segmentation->MorePads();
922 segmentation->NextPad())
924 qp=fResponse->IntXY(segmentation);
930 Int_t ixs=segmentation->Ix();
931 Int_t iys=segmentation->Iy();
933 segmentation->GetPadC(ixs,iys,xs,ys,zs);
937 Float_t ycog=sum/qcheck;
938 yg[i]=(yscan-y)/segmentation->Dpy(isec);
939 yrg[i]=(ycog-y)/segmentation->Dpy(isec);
946 Float_t dx=segmentation->Dpx(isec)/(kNs-1);
948 for (i=0; i<kNs; i++) {
954 segmentation->SigGenInit(xscan, y, 0);
956 for (segmentation->FirstPad(xscan, y, 0, dxI, dyI);
957 segmentation->MorePads();
958 segmentation->NextPad())
960 qp=fResponse->IntXY(segmentation);
966 Int_t ixs=segmentation->Ix();
967 Int_t iys=segmentation->Iy();
969 segmentation->GetPadC(ixs,iys,xs,ys,zs);
973 Float_t xcog=sum/qcheck;
974 xcog=segmentation->GetAnod(xcog);
976 xg[i]=(xscan-x)/segmentation->Dpx(isec);
977 xrg[i]=(xcog-x)/segmentation->Dpx(isec);
982 // Creates a Root function based on function sinoid above
983 // and perform the fit
985 // TGraph *graphx = new TGraph(kNs,xg ,xsig);
986 // TGraph *graphxr= new TGraph(kNs,xrg,xsig);
987 // TGraph *graphy = new TGraph(kNs,yg ,ysig);
988 TGraph *graphyr= new TGraph(kNs,yrg,ysig);
990 Double_t sinoid(Double_t *x, Double_t *par);
991 new TF1("sinoidf",sinoid,0.5,0.5,5);
992 graphyr->Fit("sinoidf","Q");
993 func = *((TF1*)((graphyr->GetListOfFunctions())->At(0)));
996 TCanvas *c1=new TCanvas(canvasname,canvasname,400,10,600,700);
997 TPad* pad11 = new TPad("pad11"," ",0.01,0.51,0.49,0.99);
998 TPad* pad12 = new TPad("pad12"," ",0.51,0.51,0.99,0.99);
999 TPad* pad13 = new TPad("pad13"," ",0.01,0.01,0.49,0.49);
1000 TPad* pad14 = new TPad("pad14"," ",0.51,0.01,0.99,0.49);
1001 pad11->SetFillColor(11);
1002 pad12->SetFillColor(11);
1003 pad13->SetFillColor(11);
1004 pad14->SetFillColor(11);
1012 graphx->SetFillColor(42);
1013 graphx->SetMarkerColor(4);
1014 graphx->SetMarkerStyle(21);
1016 graphx->GetHistogram()->SetXTitle("x on pad");
1017 graphx->GetHistogram()->SetYTitle("xcog-x");
1021 graphxr->SetFillColor(42);
1022 graphxr->SetMarkerColor(4);
1023 graphxr->SetMarkerStyle(21);
1024 graphxr->Draw("AP");
1025 graphxr->GetHistogram()->SetXTitle("xcog on pad");
1026 graphxr->GetHistogram()->SetYTitle("xcog-x");
1030 graphy->SetFillColor(42);
1031 graphy->SetMarkerColor(4);
1032 graphy->SetMarkerStyle(21);
1034 graphy->GetHistogram()->SetXTitle("y on pad");
1035 graphy->GetHistogram()->SetYTitle("ycog-y");
1040 graphyr->SetFillColor(42);
1041 graphyr->SetMarkerColor(4);
1042 graphyr->SetMarkerStyle(21);
1043 graphyr->Draw("AF");
1044 graphyr->GetHistogram()->SetXTitle("ycog on pad");
1045 graphyr->GetHistogram()->SetYTitle("ycog-y");
1051 Double_t sinoid(Double_t *x, Double_t *par)
1056 Double_t arg = -2*TMath::Pi()*x[0];
1057 Double_t fitval= par[0]*TMath::Sin(arg)+
1058 par[1]*TMath::Sin(2*arg)+
1059 par[2]*TMath::Sin(3*arg)+
1060 par[3]*TMath::Sin(4*arg)+
1061 par[4]*TMath::Sin(5*arg);
1066 Double_t DoubleGauss(Double_t *x, Double_t *par)
1069 // Doublr gaussian function
1071 Double_t arg1 = (x[0]-par[1])/0.18;
1072 Double_t arg2 = (x[0]-par[3])/0.18;
1073 Double_t fitval= par[0]*TMath::Exp(-arg1*arg1/2)
1074 +par[2]*TMath::Exp(-arg2*arg2/2);
1078 Float_t DiscrCharge(Int_t i,Double_t *par)
1080 // par[0] x-position of first cluster
1081 // par[1] y-position of first cluster
1082 // par[2] x-position of second cluster
1083 // par[3] y-position of second cluster
1084 // par[4] charge fraction of first cluster
1085 // 1-par[4] charge fraction of second cluster
1087 static Float_t qtot;
1090 for (Int_t jbin=0; jbin<gNbins; jbin++) {
1091 qtot+=gCharge[jbin];
1094 //printf("\n sum of charge from DiscrCharge %f\n", qtot);
1095 gChargeTot=Int_t(qtot);
1098 gSegmentation->SetPad(gix[i], giy[i]);
1100 gSegmentation->SetHit(par[0],par[1],0);
1101 Float_t q1=gResponse->IntXY(gSegmentation);
1104 gSegmentation->SetHit(par[2],par[3],0);
1105 Float_t q2=gResponse->IntXY(gSegmentation);
1107 Float_t value = qtot*(par[4]*q1+(1.-par[4])*q2);
1112 // Minimisation function
1113 void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
1121 for (i=0; i<gNbins; i++) {
1122 Float_t q0=gCharge[i];
1123 Float_t q1=DiscrCharge(i,par);
1124 delta=(q0-q1)/TMath::Sqrt(q0);
1129 chisq=chisq+=(qtot-qcont)*(qtot-qcont)*0.5;
1134 void AliRICHClusterFinder::SetDigits(TClonesArray *RICHdigits)
1137 // Get all the digits
1140 fNdigits = fDigits->GetEntriesFast();
1143 AliRICHClusterFinder& AliRICHClusterFinder::operator=(const AliRICHClusterFinder& rhs)
1145 // Assignment operator