Compliance with AliAlignObj
authorkir <kir@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 28 Mar 2006 14:27:54 +0000 (14:27 +0000)
committerkir <kir@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 28 Mar 2006 14:27:54 +0000 (14:27 +0000)
36 files changed:
RICH/AliRICH.cxx
RICH/AliRICH.h
RICH/AliRICHCluster.cxx
RICH/AliRICHCluster.h
RICH/AliRICHClusterFinder.cxx [deleted file]
RICH/AliRICHClusterFinder.h [deleted file]
RICH/AliRICHDigit.cxx
RICH/AliRICHDigit.h
RICH/AliRICHDigitizer.cxx
RICH/AliRICHHelix.cxx
RICH/AliRICHHelix.h
RICH/AliRICHHit.cxx
RICH/AliRICHHit.h
RICH/AliRICHMap.cxx [deleted file]
RICH/AliRICHMap.h [deleted file]
RICH/AliRICHParam.cxx
RICH/AliRICHParam.h
RICH/AliRICHRecon.cxx
RICH/AliRICHRecon.h
RICH/AliRICHReconstructor.cxx
RICH/AliRICHReconstructor.h
RICH/AliRICHTracker.cxx
RICH/AliRICHTracker.h
RICH/AliRICHv0.cxx
RICH/AliRICHv1.cxx
RICH/AliRICHv1.h
RICH/Opticals.h [deleted file]
RICH/RICHbaseLinkDef.h
RICH/RICHrecLinkDef.h
RICH/RichConfig.C
RICH/RichGeom.C
RICH/RichMake
RICH/RichMenu.C
RICH/api.txt
RICH/libRICHbase.pkg
RICH/libRICHrec.pkg

index 337234a..4f6ac7d 100644 (file)
 
 #include "AliRICH.h"
 #include "AliRICHParam.h"
-#include "AliRICHChamber.h"
-#include "AliRICHHelix.h"
-//#include <TArrayF.h>
-#include <TGeometry.h>
-#include <TBRIK.h>
-#include <TTUBE.h>
+#include "AliRICHHelix.h" //ReadESD
 #include <TFile.h>
-#include <TNode.h> 
 #include <TObjArray.h>
 #include <TParticle.h>
 #include <AliStack.h>
+#include <AliRun.h>
+#include <AliMC.h>       //ctor
 #include <AliHeader.h>
 #include <AliGenEventHeader.h>
 #include <AliGenHijingEventHeader.h>
-#include <AliMagF.h>
-#include <AliRun.h>
-#include <AliRunDigitizer.h>
-#include <AliMC.h>
 #include <AliESD.h>
-#include <TVirtualMC.h>
-#include <TH1F.h>
-#include <TH2F.h>
+#include <TH1F.h>        //HitQA()
+#include <TH2F.h>        //Display() 
 #include <TBenchmark.h>
 #include <AliLog.h>
-#include <TNtupleD.h>
-#include <AliTracker.h>
-#include <TLatex.h>   //Display()
-#include <TCanvas.h>  //Display()
-#include <TGraph.h>   //Display()
-#include <TStyle.h>   //Display()
-#include <TMarker.h>  //Display()
+#include <TLatex.h>      //Display()
+#include <TCanvas.h>     //Display()
+#include <TGraph.h>      //Display()
+#include <TStyle.h>      //Display()
+#include <TMarker.h>     //Display()
 ClassImp(AliRICH)    
 //__________________________________________________________________________________________________
 // RICH manager class   
@@ -56,23 +44,21 @@ ClassImp(AliRICH)
 */
 //END_HTML
 //__________________________________________________________________________________________________
-AliRICH::AliRICH():AliDetector(),fParam(0),  fSdigits(0),fNsdigits(0),fDigs(0),fClus(0) 
+AliRICH::AliRICH():AliDetector(),fSdig(0),fSdigCnt(0),fDig(0),fClu(0) 
 {
 //Default ctor should not contain any new operators
 //AliDetector ctor deals with Hits and Digits  
-  for(int i=0;i<kNchambers;i++) fNdigs[i]  =0;
-  for(int i=0;i<kNchambers;i++) fNclus[i]=0;
-//  fCounters.ResizeTo(20); fCounters.Zero();
 }//AliRICH::AliRICH()
 //__________________________________________________________________________________________________
 AliRICH::AliRICH(const char *name, const char *title)
-        :AliDetector(name,title),fParam(new AliRICHParam),fSdigits(0),fNsdigits(0),fDigs(0),fClus(0)
+        :AliDetector(name,title),fSdig(0),fSdigCnt(0),fDig(0),fClu(0)
 {
 //Named ctor
   AliDebug(1,"Start.");
 //AliDetector ctor deals with Hits and Digits (reset them to 0, does not create them)
-  HitsCreate();          gAlice->GetMCApp()->AddHitList(fHits);
-  fCounters.ResizeTo(20); fCounters.Zero();
+  HitCreate();          gAlice->GetMCApp()->AddHitList(fHits);
+  fNcham=7;
+  fCounters.ResizeTo(40); fCounters.Zero();
   AliDebug(1,"Stop.");
 }//AliRICH::AliRICH(const char *name, const char *title)
 //__________________________________________________________________________________________________
@@ -81,13 +67,12 @@ AliRICH::~AliRICH()
 //dtor
   AliDebug(1,"Start.");
 
-  if(fParam)     delete fParam;
   
   if(fHits)      delete fHits;
-  if(fSdigits)   delete fSdigits;
+  if(fSdig)      delete fSdig;
   if(fDigits)    delete fDigits;
-  if(fDigs)      {fDigs->Delete();   delete fDigs;}
-  if(fClus)      {fClus->Delete();   delete fClus;}
+  if(fDig)      {fDig->Delete();   delete fDig;}
+  if(fClu)      {fClu->Delete();   delete fClu;}
   AliDebug(1,"Stop.");    
 }//AliRICH::~AliRICH()
 //__________________________________________________________________________________________________
@@ -96,199 +81,9 @@ void AliRICH::BuildGeometry()
 //Builds a TNode geometry for event display
   AliDebug(1,"Start.");
   
-  TNode *node, *subnode, *top;
-  top=gAlice->GetGeometry()->GetNode("alice");
-
-  Float_t widx =P()->SectorSizeX();
-  Float_t leny =P()->SectorSizeY();
-  Float_t dz   =P()->Zfreon()+P()->Zwin()+P()->Pc2Win();
-  Float_t dead =P()->DeadZone();
-
-  new TBRIK("RICH","RICH","void",widx+dead/2,leny+leny/2+dead,dz+0.1); //RICH chamber
-  new TBRIK("RPC" ,"RPC" ,"void",widx/2,leny/2,0.01);                  //RICH sector 
-
-  for(int i=1;i<=P()->Nchambers();i++){
-    top->cd();
-    node = new TNode(Form("RICH%i",i),Form("RICH%i",i),"RICH",C(i)->Center().X(),C(i)->Center().Y(),C(i)->Center().Z(),C(i)->RotMatrixName());
-    node->SetLineColor(kRed);
-    node->cd();
-    subnode = new TNode("PHOTO1","PHOTO1","RPC",-widx/2-dead/2,-leny-dead/2,dz,"");
-    subnode->SetLineColor(kGreen);
-    fNodes->Add(subnode);
-    subnode = new TNode("PHOTO1","PHOTO1","RPC", widx/2+dead/2,-leny-dead/2,dz,"");
-    subnode->SetLineColor(kGreen);
-    fNodes->Add(subnode);
-    subnode = new TNode("PHOTO1","PHOTO1","RPC",-widx/2-dead/2,           0,dz,"");
-    subnode->SetLineColor(kGreen);
-    fNodes->Add(subnode);
-    subnode = new TNode("PHOTO1","PHOTO1","RPC", widx/2+dead/2,           0,dz,"");
-    subnode->SetLineColor(kGreen);
-    fNodes->Add(subnode);
-    subnode = new TNode("PHOTO1","PHOTO1","RPC",-widx/2-dead/2, leny+dead/2,dz,"");
-    subnode->SetLineColor(kGreen);
-    fNodes->Add(subnode);
-    subnode = new TNode("PHOTO1","PHOTO1","RPC", widx/2+dead/2, leny+dead/2,dz,"");
-    subnode->SetLineColor(kGreen);
-    fNodes->Add(subnode);
-    fNodes->Add(node);
-  }
-
   AliDebug(1,"Stop.");    
 }//void AliRICH::BuildGeometry()
 //__________________________________________________________________________________________________
-void AliRICH::CreateMaterials()
-{
-// Definition of available RICH materials  
-        
-  Int_t   material=0; //tmp material id number
-  Float_t a=0,z=0,den=0,radl=0,absl=0; //tmp material parameters
-  
-  Float_t tmaxfd=-10.0, deemax=-0.2, stemax=-0.1,epsil=0.001, stmin=-0.001; 
-  Int_t   isxfld = gAlice->Field()->Integ();
-  Float_t sxmgmx = gAlice->Field()->Max();
-    
-  Float_t aAir[4]={12,14,16,36};  Float_t zAir[4]={6,7,8,18}; Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};//total 0.9999999
-  AliMixture(++material, "RichAir",aAir,zAir,den=0.00120479,4,wAir);                                          //1 (Air) 0.01% C 75% N  23% O 1% Ar
-  AliMedium(kAir, "RichAir",material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  AliMixture(++material, "RichAerogel",aAir,zAir,den=P()->DenGel(),4,wAir);                     //Aerogel represented by Air
-  AliMedium(kGel, "RichAerogel",material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  AliMixture(++material, "RichAerogelReflector",aAir,zAir,den=P()->DenGel(),4,wAir);           //Aerogel reflector represented by Air
-  AliMedium(kReflector, "RichAerogelReflector",material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  AliMaterial(++material, "RichRohacell", a=12.01,z=6.0, den=0.1,     radl=18.8,   absl=0);                   //2 Rohacell 51 C-equiv radl rad cover
-  AliMedium(kRoha, "RichRohacell", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  Float_t  aQuartz[2]={28.09,16.0};  Float_t  zQuartz[2]={14.00, 8.0};  Float_t  wQuartz[2]={1,2};
-  AliMixture(++material, "RichSiO2",aQuartz,zQuartz,den=2.64,-2, wQuartz);                                    //3 Quarz (SiO2) -trasparent rad window
-  AliMedium(kSiO2, "RichSiO2",material, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  Float_t  aFreon[2]={12,19};  Float_t  zFreon[2]={6,9};  Float_t wmatFreon[2]={6,14};                        // C12-6 F19-9   
-  AliMixture(++material, "RichC6F14",aFreon,zFreon,den=1.68,-2,wmatFreon);                                    //4 Freon (C6F14) 
-  AliMedium(kC6F14, "RichC6F14",material, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  Float_t aMethane[2]={12.01,1}; Float_t zMethane[2]={6,1}; Float_t wMethane[2]={1,4};
-  AliMixture (++material, "RichCH4", aMethane, zMethane, den=7.17e-4,-2, wMethane);                        //5,9 methane (CH4) normal and for Gap    
-  AliMedium(kCH4, "RichCH4"   , material, 1, isxfld, sxmgmx, tmaxfd, stemax,  deemax, epsil,  stmin);  
-  AliMixture (++material, "RichCH4gap", aMethane, zMethane, den=7.17e-4,-2, wMethane);                      //5,9 methane (CH4) normal and for Gap    
-  AliMedium(kGap, "RichCH4gap", material, 1, isxfld, sxmgmx, tmaxfd, 0.1   , -deemax, epsil, -stmin);
-    
-  AliMaterial(++material, "RichCsI",      a=12.01,z=6.0, den=0.1,     radl=18.8,   absl=0);                   //6 CsI-radl equivalent
-  AliMedium(kCsI, "RichCsI", material, 1, isxfld, sxmgmx,tmaxfd, stemax, deemax, epsil, stmin);
-  
-  AliMaterial(++material, "RichGridCu",    a=63.54,z=29.0,den=8.96,    radl=1.43,   absl=0);                   //7 anode grid (Cu) 
-  AliMedium(kGridCu, "RichGridCu", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-    
-  AliMaterial(++material, "RichPcbCu",     a=63.54,z=29.0,den=8.96,    radl=1.4,    absl=0);                   //12 Cu
-  AliMedium(kCu, "RichPcbCu", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  AliMixture (++material, "RichOpSiO2",aQuartz, zQuartz, den=2.64, -2, wQuartz);                             //8 Quarz (SiO2) - opaque
-  AliMedium(kOpSiO2, "RichOpSiO2",material, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  AliMaterial(++material, "RichAl",     a=26.98,z=13.0,den=2.699,     radl=8.9,    absl=0);                 //10 aluminium sheet (Al)
-  AliMedium(kAl, "RichAl", material, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  Float_t aGlass[5]={12.01,28.09,16,10.8,23}; Float_t zGlass[5]={6,14,8,5,11};  Float_t wGlass[5]={0.5,0.105,0.355,0.03,0.01};
-  AliMixture(++material,"RichGlass",aGlass, zGlass, den=1.74, 5, wGlass);                                    //11 Glass 50%-C 10.5%-Si 35.5%-O 3%-B 1%-Na
-  AliMedium(kGlass, "RichGlass", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-
-  den=19.3;
-  AliMaterial(++material, "RichW",  a=183.84,z=74.0,den,    radl=0.35,    absl=185.0/den);              //13 W - anod wires
-  AliMedium(kW, "RichW", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-  
-  if(P()->IsRadioSrc()){
-    AliInfo("Special radioactive source materials");
-    den=7.87;
-    AliMaterial(++material, "RichSteel",  a=55.845,z=26.0,den,    radl=1.76,    absl=131.9/den);        //14 Steel (Fe)
-    AliMedium(kSteel, "RichSteel", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  
-    AliMaterial(++material, "RichPerpex",  a=63.54,z=29.0,den=8.96,    radl=1.4,    absl=0);                 //15 Perpex
-    AliMedium(kPerpex, "RichPerpex", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-    
-    AliMaterial(++material, "RichSr90",  a=87.62,z=38.0,den=2.54,    radl=4.24,    absl=0);                  //16 Sr90
-    AliMedium(kSr90, "RichSr90", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-    
-    Float_t aMylar[5]={12.01,1,16}; Float_t zMylar[5]={6,1,8};  Float_t wMylar[5]={5,4,5};                  //17 Mylar C5H4O5
-    AliMixture(++material,"RichMylar",aMylar, zMylar, den=1.39, -3, wMylar); 
-    AliMedium(kMylar, "RichMylar", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
-  }
-  
-//Optical properties:
-#include "Opticals.h"
-  gMC->SetCerenkov((*fIdtmed)[kAir]      , kNbins, aPckov, aAbsCH4    , aQeAll, aIdxCH4);       //1 Air
-  gMC->SetCerenkov((*fIdtmed)[kRoha]     , kNbins, aPckov, aAbsCH4    , aQeAll, aIdxCH4);       //2 Honeycomb  
-  gMC->SetCerenkov((*fIdtmed)[kSiO2]     , kNbins, aPckov, aAbsSiO2   , aQeAll, aIdxSiO2);      //3 Quartz SiO2 
-  gMC->SetCerenkov((*fIdtmed)[kC6F14]    , kNbins, aPckov, aAbsC6F14  , aQeAll, aIdxC6F14);     //4 Freon C6F14
-  gMC->SetCerenkov((*fIdtmed)[kCH4]      , kNbins, aPckov, aAbsCH4    , aQeAll, aIdxCH4);       //5 Methane CH4 
-  gMC->SetCerenkov((*fIdtmed)[kCsI]      , kNbins, aPckov, aAbsCsI    , aQeCsI, aIdxCH4);       //6 CsI
-  gMC->SetCerenkov((*fIdtmed)[kGridCu]   , kNbins, aPckov, aAbsGrid   , aQeAll, aIdxMetal);     //7 grid Cu
-  gMC->SetCerenkov((*fIdtmed)[kOpSiO2]   , kNbins, aPckov, aAbsOpSiO2 , aQeAll, aIdxMetal);     //8 Opaque quartz SiO2
-  gMC->SetCerenkov((*fIdtmed)[kGap]      , kNbins, aPckov, aAbsCH4    , aQeAll, aIdxCH4);       //9 Special methane gap
-  gMC->SetCerenkov((*fIdtmed)[kAl]       , kNbins, aPckov, aAbsGrid   , aQeAll, aIdxMetal);     //10 Aluminium
-  gMC->SetCerenkov((*fIdtmed)[kGlass]    , kNbins, aPckov, aAbsOpSiO2 , aQeAll, aIdxMetal);     //11 Glass    
-  gMC->SetCerenkov((*fIdtmed)[kGel]      , kNbins, aPckov, aAbsGel    , aQeAll, aIdxGel);       //12 Aerogel
-  gMC->SetCerenkov((*fIdtmed)[kReflector], kNbins, aPckov, aAbsRef    , aQeAll, aIdxMetal);     //13 Aerogel reflector
-}//void AliRICH::CreateMaterials()
-//__________________________________________________________________________________________________
-Float_t AliRICH::Fresnel(Float_t ene,Float_t pdoti, Bool_t pola)
-{
-
-    //ENE(EV), PDOTI=COS(INC.ANG.), PDOTR=COS(POL.PLANE ROT.ANG.)
-    
-    Float_t en[36] = {5.0,5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6.0,6.1,6.2,
-                     6.3,6.4,6.5,6.6,6.7,6.8,6.9,7.0,7.1,7.2,7.3,7.4,7.5,7.6,7.7,
-                     7.8,7.9,8.0,8.1,8.2,8.3,8.4,8.5};
-    Float_t csin[36] = {2.14,2.21,2.33,2.48,2.76,2.97,2.99,2.59,2.81,3.05,
-                       2.86,2.53,2.55,2.66,2.79,2.96,3.18,3.05,2.84,2.81,2.38,2.11,
-                       2.01,2.13,2.39,2.73,3.08,3.15,2.95,2.73,2.56,2.41,2.12,1.95,
-                       1.72,1.53};
-    Float_t csik[36] = {0.,0.,0.,0.,0.,0.196,0.408,0.208,0.118,0.49,0.784,0.543,
-                       0.424,0.404,0.371,0.514,0.922,1.102,1.139,1.376,1.461,1.253,0.878,
-                       0.69,0.612,0.649,0.824,1.347,1.571,1.678,1.763,1.857,1.824,1.824,
-                       1.714,1.498};
-    Float_t xe=ene;
-    Int_t  j=Int_t(xe*10)-49;
-    Float_t cn=csin[j]+((csin[j+1]-csin[j])/0.1)*(xe-en[j]);
-    Float_t ck=csik[j]+((csik[j+1]-csik[j])/0.1)*(xe-en[j]);
-
-    //FORMULAE FROM HANDBOOK OF OPTICS, 33.23 OR
-    //W.R. HUNTER, J.O.S.A. 54 (1964),15 , J.O.S.A. 55(1965),1197
-
-    Float_t sinin=TMath::Sqrt(1-pdoti*pdoti);
-    Float_t tanin=sinin/pdoti;
-
-    Float_t c1=cn*cn-ck*ck-sinin*sinin;
-    Float_t c2=4*cn*cn*ck*ck;
-    Float_t aO=TMath::Sqrt(0.5*(TMath::Sqrt(c1*c1+c2)+c1));
-    Float_t b2=0.5*(TMath::Sqrt(c1*c1+c2)-c1);
-    
-    Float_t rs=((aO-pdoti)*(aO-pdoti)+b2)/((aO+pdoti)*(aO+pdoti)+b2);
-    Float_t rp=rs*((aO-sinin*tanin)*(aO-sinin*tanin)+b2)/((aO+sinin*tanin)*(aO+sinin*tanin)+b2);
-    
-
-    //CORRECTION FACTOR FOR SURFACE ROUGHNESS
-    //B.J. STAGG  APPLIED OPTICS, 30(1991),4113
-
-    Float_t sigraf=18.;
-    Float_t lamb=1240/ene;
-    Float_t fresn;
-    Float_t  rO=TMath::Exp(-(4*TMath::Pi()*pdoti*sigraf/lamb)*(4*TMath::Pi()*pdoti*sigraf/lamb));
-
-    if(pola)
-    {
-       Float_t pdotr=0.8;                                 //DEGREE OF POLARIZATION : 1->P , -1->S
-       fresn=0.5*(rp*(1+pdotr)+rs*(1-pdotr));
-    }
-    else
-       fresn=0.5*(rp+rs);
-      
-    fresn = fresn*rO;
-    return(fresn);
-}//Fresnel()
-//__________________________________________________________________________________________________
 void AliRICH::MakeBranch(Option_t* option)
 {
 //Create Tree branches for the RICH.
@@ -302,25 +97,25 @@ void AliRICH::MakeBranch(Option_t* option)
   const char *cS = strstr(option,"S");
 
   if(cH&&TreeH()){//H
-    HitsCreate();      //branch will be created in AliDetector::MakeBranch
+    HitCreate();      //branch will be created in AliDetector::MakeBranch
   }//H     
   AliDetector::MakeBranch(option);//this is after cH because we need to guarantee that fHits array is created
       
   if(cS&&fLoader->TreeS()){//S  
-    SDigitsCreate();   MakeBranchInTree(fLoader->TreeS(),"RICH",&fSdigits,kBufferSize,0) ;
+    SDigCreate();   MakeBranchInTree(fLoader->TreeS(),"RICH",&fSdig,kBufferSize,0) ;
   }//S
    
   if(cD&&fLoader->TreeD()){//D
-    DigitsCreate();
-    for(Int_t i=0;i<kNchambers;i++){ 
-      MakeBranchInTree(fLoader->TreeD(),Form("%s%d",GetName(),i+1),&((*fDigs)[i]),kBufferSize,0);
+    DigCreate();
+    for(Int_t i=0;i<fNcham;i++){ 
+      MakeBranchInTree(fLoader->TreeD(),Form("%s%d",GetName(),i+1),&((*fDig)[i]),kBufferSize,0);
     }
   }//D
   
   if(cR&&fLoader->TreeR()){//R
-    ClustersCreate();
-    for(Int_t i=0;i<kNchambers;i++)
-      MakeBranchInTree(fLoader->TreeR(),Form("%sClusters%d",GetName(),i+1), &((*fClus)[i]), kBufferSize, 0);    
+    CluCreate();
+    for(Int_t i=0;i<fNcham;i++)
+      MakeBranchInTree(fLoader->TreeR(),Form("%sClusters%d",GetName(),i+1), &((*fClu)[i]), kBufferSize, 0);    
   }//R
   AliDebug(1,"Stop.");   
 }//void AliRICH::MakeBranch(Option_t* option)
@@ -334,223 +129,43 @@ void AliRICH::SetTreeAddress()
     
   if(fLoader->TreeH()){//H
     AliDebug(1,"tree H is requested.");
-    HitsCreate();//branch map will be in AliDetector::SetTreeAddress    
+    HitCreate();//branch map will be in AliDetector::SetTreeAddress    
   }//H
   AliDetector::SetTreeAddress();//this is after TreeH because we need to guarantee that fHits array is created
 
   if(fLoader->TreeS()){//S
     AliDebug(1,"tree S is requested.");
-    branch=fLoader->TreeS()->GetBranch(GetName());        if(branch){SDigitsCreate();   branch->SetAddress(&fSdigits);}
+    branch=fLoader->TreeS()->GetBranch(GetName());        if(branch){SDigCreate();   branch->SetAddress(&fSdig);}
   }//S
     
   if(fLoader->TreeD()){//D    
     AliDebug(1,"tree D is requested.");
-    for(int i=0;i<kNchambers;i++){      
-      branch=fLoader->TreeD()->GetBranch(Form("%s%d",GetName(),i+1)); 
-      if(branch){DigitsCreate(); branch->SetAddress(&((*fDigs)[i]));}
-    }
+    for(int i=0;i<fNcham;i++){   branch=fLoader->TreeD()->GetBranch(Form("%s%d",GetName(),i+1));  if(branch){DigCreate(); branch->SetAddress(&((*fDig)[i]));}}
   }//D
     
   if(fLoader->TreeR()){//R
     AliDebug(1,"tree R is requested.");
-    for(int i=0;i<kNchambers;i++){         
-      branch=fLoader->TreeR()->GetBranch(Form("%sClusters%d" ,GetName(),i+1));
-      if(branch){ClustersCreate(); branch->SetAddress(&((*fClus)[i]));}
-    }
+    for(int i=0;i<fNcham;i++){   branch=fLoader->TreeR()->GetBranch(Form("%sClusters%d" ,GetName(),i+1));  if(branch){CluCreate(); branch->SetAddress(&((*fClu)[i]));}}
   }//R
   AliDebug(1,"Stop.");
 }//void AliRICH::SetTreeAddress()
 //__________________________________________________________________________________________________
-void AliRICH::Print(Option_t *option)const
-{
-//Debug printout
-  TObject::Print(option);
-  P()->Print();
-  fCounters.Print();
-}//void AliRICH::Print(Option_t *option)const
-//__________________________________________________________________________________________________
-void AliRICH::ControlPlots()
-{ 
-//Creates a set of QA hists to control the results of simulation. Hists are in file $HOME/RCP.root     
-  TH1F             *pElecP=0 ,*pMuonP=0 ,*pPionP=0 ,*pKaonP=0 ,*pProtP=0,  //stack particles
-                   *pHxD=0,*pHyD=0,*pHxSd=0,*pHySd=0,      //diff hit position - digit sdigit position 
-                   *pNumClusH1=0,
-                   *pQdcH1=0,       *pSizeH1=0,
-                   *pPureMipQdcH1=0,*pPureMipSizeH1=0,
-                   *pPureCerQdcH1=0,*pPureCerSizeH1=0,
-                   *pPureFeeQdcH1=0,*pPureFeeSizeH1=0,
-                   *pMipQdcH1=0,    *pPhotQdcH1=0;  
-  TH2F *pMapH2=0,*pPureMipMapH2=0,*pPureCerMapH2=0,*pPureFeeMapH2=0;
-  TH1F *pelecRadius=0,*pprotRadius=0,*pprotbarRadius=0;
-//load all information  
-                 GetLoader()->GetRunLoader()->LoadHeader();  
-                 GetLoader()->GetRunLoader()->LoadKinematics();  
-                 GetLoader()->LoadHits();  
-  Bool_t isSdig=0;//!GetLoader()->LoadSDigits();
-  Bool_t isDig =0;//!GetLoader()->LoadDigits();
-  Bool_t isClus=!GetLoader()->LoadRecPoints();
-
-  gBenchmark->Start("ControlPlots");
-    
-  TFile *pFile = new TFile("$(HOME)/RCP.root","RECREATE");   
-  
-  pElecP=new TH1F("Pelec","Electrons made hit in RICH;p [GeV]",1000,-30,30); 
-  pMuonP=new TH1F("Pmuon","Muons made hit in RICH;p [GeV]",1000,-30,30); 
-  pPionP=new TH1F("Ppion","Pions made hit in RICH;p [GeV]",1000,-30,30); 
-  pKaonP=new TH1F("Pkaon","Kaon made hit in RICH;p [GeV]",1000,-30,30); 
-  pProtP=new TH1F("Pprot","Protons made hit in RICH;p [GeV]",1000,-30,30); 
-  pelecRadius=new TH1F("elecRadius","elec",600,0.,600.);  
-  pprotRadius=new TH1F("protRadius","elec",600,0.,600.);  
-  pprotbarRadius=new TH1F("protbarRadius","elec",600,0.,600.);
-    
-  if(isSdig){
-    AliInfo("SDigits available");
-    pHxSd=new TH1F("DiffHitSDigitX","Hit-SDigit diff X all chambers;diff [cm]",300,-10,10); 
-    pHySd=new TH1F("DiffHitSDigitY","Hit-SDigit diff Y all chambers;diff [cm]",300,-10,10); 
-  }//isSdig
-  
-  if(isDig){
-    AliInfo("Digits available");
-    pHxD=new TH1F("DiffHitDigitX","Hit-Digit diff X all chambers;diff [cm]",300,-10,10); 
-    pHyD=new TH1F("DiffHitDigitY","Hit-Digit diff Y all chambers;diff [cm]",300,-10,10); 
-  }//isDig
-  
-  if(isClus){ 
-    AliInfo("Clusters available");
-    pNumClusH1=new TH1F("NumClusPerEvent","Number of clusters per event;number",50,0,49);
-    
-    pQdcH1        =new TH1F("ClusQdc",   "Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc());
-    pSizeH1       =new TH1F("ClusSize",  "Cluster size all chambers;size [number of pads in cluster]",100,0,100);
-    pMapH2        =new TH2F("ClusMap",   "Cluster map;x [cm];y [cm]",1000,0,P()->PcSizeX(),1000,0,P()->PcSizeY());
-  
-    pMipQdcH1     =new TH1F("QdcMip"      ,"MIP Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc());
-    pPhotQdcH1    =new TH1F("QdcPhot"     ,"Cer+Fee Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc());
-        
-    pPureMipQdcH1 =new TH1F("QdcPureMip"  ,"MIP only Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc());
-    pPureMipSizeH1=new TH1F("SizePureMip" ,"MIP only Cluster size all chambers;size [number of pads in cluster]",100,0,100);
-    pPureMipMapH2 =new TH2F("MapPureMip"  ,"MIP only Cluster map;x [cm];y [cm]",1000,0,P()->PcSizeX(),1000,0,P()->PcSizeY());
-  
-    pPureCerQdcH1 =new TH1F("QdcPureCer"  ,"Cerenkov only Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc());
-    pPureCerSizeH1=new TH1F("SizePureCer" ,"Cernekov only Cluster size all chambers;size [number of pads in cluster]",100,0,100);
-    pPureCerMapH2 =new TH2F("MapPureCer"  ,"Cerenkov only Cluster map;x [cm];y [cm]",1000,0,P()->PcSizeX(),1000,0,P()->PcSizeY());
-    
-    pPureFeeQdcH1 =new TH1F("QdcPureFee"  ,"Feedback only Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc());
-    pPureFeeSizeH1=new TH1F("SizePureFee" ,"Feedback only Cluster size all chambers;size [number of pads in cluster]",100,0,100);
-    pPureFeeMapH2 =new TH2F("MapPureFee"  ,"Feedback only Cluster map;x [cm];y [cm]",1000,0,P()->PcSizeX(),1000,0,P()->PcSizeY());
-
-  }//isClus
-//end of hists booking  
-  for(Int_t iEvtN=0;iEvtN < GetLoader()->GetRunLoader()->GetAliRun()->GetEventsPerRun();iEvtN++){//events loop
-    GetLoader()->GetRunLoader()->GetEvent(iEvtN);    //get current event
-    
-    for(Int_t iPrimN=0;iPrimN < GetLoader()->TreeH()->GetEntries();iPrimN++){//hit tree loop
-      GetLoader()->TreeH()->GetEntry(iPrimN);      
-      for(Int_t j=0;j<Hits()->GetEntries();j++){//hits loop
-        AliRICHHit *pHit = (AliRICHHit*)Hits()->At(j);
-        TParticle *pParticle = GetLoader()->GetRunLoader()->Stack()->Particle(pHit->GetTrack());//get particle produced this hit
-        Double_t dRadius = TMath::Sqrt(pParticle->Vx()*pParticle->Vx()+pParticle->Vy()*pParticle->Vy()+pParticle->Vz()*pParticle->Vz());
-        switch(pParticle->GetPdgCode()){
-          case kPositron : pElecP->Fill( pParticle->P());pelecRadius->Fill(dRadius); break;
-          case kElectron : pElecP->Fill(-pParticle->P());pelecRadius->Fill(dRadius); break;
-          
-          case kMuonPlus : pMuonP->Fill( pParticle->P()); break;
-          case kMuonMinus: pMuonP->Fill(-pParticle->P()); break;
-                    
-          case kPiPlus   : pPionP->Fill( pParticle->P()); break;
-          case kPiMinus  : pPionP->Fill(-pParticle->P()); break;
-          
-          case kKPlus    : pKaonP->Fill( pParticle->P()); break;
-          case kKMinus   : pKaonP->Fill(-pParticle->P()); break;
-          
-          case kProton   : pProtP->Fill( pParticle->P()); pprotRadius->Fill(dRadius); break;
-          case kProtonBar: pProtP->Fill(-pParticle->P()); pprotbarRadius->Fill(dRadius); break;
-              
-        }//switch PdgCode
-            
-      }//hits loop
-    }//hit tree loop
-    
-    if(isSdig){
-      GetLoader()->TreeS()->GetEntry(0);  
-      for(Int_t iSdigN=0;iSdigN<SDigits()->GetEntries();iSdigN++){//sdigits loop 
-        AliRICHDigit *pSdig=(AliRICHDigit*)SDigits()->At(iSdigN); //get current sdigit pointer  
-        AliRICHHit   *pHit=Hit(pSdig->GetTrack(0));               //get hit of this sdigit (always one)
-        TVector2 hit2 =C(pHit->C())->Mrs2Pc(pHit->OutX3());       //this hit position  in local system
-        TVector2 sdig2=P()->Pad2Loc(pSdig->Pad());                //center of pad for this sdigit
-        pHxSd->Fill(hit2.X()-sdig2.X());        
-        pHySd->Fill(hit2.Y()-sdig2.Y());      
-      }//sdigits loop
-    }//if(isSdig)
-        
-    if(isDig)  GetLoader()->TreeD()->GetEntry(0);  
-    if(isClus) GetLoader()->TreeR()->GetEntry(0);
-    
-    for(Int_t iChamN=1;iChamN<=7;iChamN++){//chambers loop
-      if(isDig){
-        for(Int_t iDigN=0;iDigN<Digits(iChamN)->GetEntries();iDigN++){//digits loop
-          AliRICHDigit *pDig=(AliRICHDigit*)Digits(iChamN)->At(iDigN);
-          AliRICHHit   *pHit=Hit(pDig->GetTrack(0));           //get first hit of this digit
-          TVector2 hitV2=C(iChamN)->Mrs2Pc(pHit->OutX3()); 
-          TVector2 digV2=P()->Pad2Loc(pDig->Pad());            //center of pad for this digit
-          pHxD->Fill(hitV2.X()-digV2.X());        pHyD->Fill(hitV2.Y()-digV2.Y());
-        }//digits loop
-      }//isDig
-      if(isClus){
-        Int_t iNclusCham=Clusters(iChamN)->GetEntries(); if(iNclusCham) pNumClusH1->Fill(iNclusCham);//number of clusters per event
-        for(Int_t iClusN=0;iClusN<iNclusCham;iClusN++){//clusters loop
-          AliRICHCluster *pClus=(AliRICHCluster*)Clusters(iChamN)->At(iClusN);
-                                       pQdcH1        ->Fill(pClus->Q());   
-                                       pSizeH1       ->Fill(pClus->Size());  
-                                       pMapH2        ->Fill(pClus->X(),pClus->Y()); //common
-                                       
-           if(pClus->IsSingleMip())     {pPureMipQdcH1 ->Fill(pClus->Q());
-                                       pPureMipSizeH1->Fill(pClus->Size());
-                                       pPureMipMapH2 ->Fill(pClus->X(),pClus->Y());}//Pure Mips
-                                       
-           if(pClus->IsSingleCerenkov()){pPureCerQdcH1 ->Fill(pClus->Q());
-                                       pPureCerSizeH1->Fill(pClus->Size());
-                                       pPureCerMapH2 ->Fill(pClus->X(),pClus->Y());}//Pure Cerenkovs
-                                       
-           if(pClus->IsSingleFeedback()){pPureFeeQdcH1 ->Fill(pClus->Q());
-                                       pPureFeeSizeH1->Fill(pClus->Size());
-                                       pPureFeeMapH2 ->Fill(pClus->X(),pClus->Y());}//Pure Feedbacks
-           
-           if(pClus->IsMip()) {pMipQdcH1 ->Fill(pClus->Q());} //MIP+ other contributions
-           if(!pClus->IsPureMip())     pPhotQdcH1->Fill(pClus->Q());  //not MIP
-        }//clusters loop
-      }//isClus
-    }//chambers loop
-    Info("ControlPlots","Event %i processed.",iEvtN);
-  }//events loop 
-             GetLoader()->UnloadHits();
-  if(isSdig) GetLoader()->UnloadSDigits();
-  if(isDig)  GetLoader()->UnloadDigits();
-  if(isClus) GetLoader()->UnloadRecPoints();
-  
-  GetLoader()->GetRunLoader()->UnloadHeader();  
-  GetLoader()->GetRunLoader()->UnloadKinematics();  
-  
-  pFile->Write(); delete pFile;
-  
-  gBenchmark->Show("ControlPlots");
-}//ControlPlots()
-//__________________________________________________________________________________________________
-AliRICHHit* AliRICH::Hit(Int_t tid)const
-{
-//defines which hit provided by given tid for the currently loaded event
-  GetLoader()->LoadHits();
-  for(Int_t iPrimN=0;iPrimN<GetLoader()->TreeH()->GetEntries();iPrimN++){//prims loop      
-    GetLoader()->TreeH()->GetEntry(iPrimN);
-    for(Int_t iHitN=0;iHitN<Hits()->GetEntries();iHitN++){
-      AliRICHHit *pHit=(AliRICHHit*)Hits()->At(iHitN);
-      if(tid==pHit->Track()) {GetLoader()->UnloadHits();return pHit;}
-    }//hits
-  }//prims loop
-  GetLoader()->UnloadHits();
-  return 0;
-}
-//__________________________________________________________________________________________________
-void AliRICH::HitsPrint(Int_t iEvtN)const
+// AliRICHHit* AliRICH::Hit(Int_t tid)const
+// {
+// // Search for the first RICH hit belonging to the given tid
+//   GetLoader()->LoadHits();
+//   for(Int_t iPrimN=0;iPrimN<GetLoader()->TreeH()->GetEntries();iPrimN++){//prims loop      
+//     GetLoader()->TreeH()->GetEntry(iPrimN);
+//     for(Int_t iHitN=0;iHitN<Hits()->GetEntries();iHitN++){
+//       AliRICHHit *pHit=(AliRICHHit*)Hits()->At(iHitN);
+//       if(tid==pHit->Track()) {GetLoader()->UnloadHits();return pHit;}
+//     }//hits
+//   }//prims loop
+//   GetLoader()->UnloadHits();
+//   return 0;
+// }
+//__________________________________________________________________________________________________
+void AliRICH::HitPrint(Int_t iEvtN)const
 {
 //Prints a list of RICH hits for a given event. Default is event number 0.
   if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return;    
@@ -567,7 +182,7 @@ void AliRICH::HitsPrint(Int_t iEvtN)const
   AliInfo(Form("totally %i hits",iTotalHits));
 }
 //__________________________________________________________________________________________________
-void AliRICH::SDigitsPrint(Int_t iEvtN)const
+void AliRICH::SDigPrint(Int_t iEvtN)const
 {
 //prints a list of RICH sdigits  for a given event
   if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return;    
@@ -575,26 +190,26 @@ void AliRICH::SDigitsPrint(Int_t iEvtN)const
   if(GetLoader()->LoadSDigits()) return;
   
   GetLoader()->TreeS()->GetEntry(0);
-  SDigits()->Print();
+  fSdig->Print();
   GetLoader()->UnloadSDigits();
-  Info("PrintSDigits","totally %i sdigits",SDigits()->GetEntries());
+  Printf("totally %i sdigits",fSdig->GetEntries());
 }
 //__________________________________________________________________________________________________
-void AliRICH::DigitsPrint(Int_t iEvtN)const
+void AliRICH::DigPrint(Int_t iEvtN)const
 {
 //prints a list of RICH digits  for a given event
   if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return;    
-  Info("PrintDigits","List of RICH digits for event %i",iEvtN);
+  Printf("List of RICH digits for event %i",iEvtN);
   if(GetLoader()->LoadDigits()) return;
   
   Int_t iTotalDigits=0;
   GetLoader()->TreeD()->GetEntry(0);
-  for(Int_t iChamber=1;iChamber<=kNchambers;iChamber++){
-    Digits(iChamber)->Print();
-    iTotalDigits+=Digits(iChamber)->GetEntries();
+  if(!fDig) return;
+  for(Int_t iCham=0;iCham<fNcham;iCham++){
+    TClonesArray *pDigs=(TClonesArray*)fDig->At(iCham);    iTotalDigits+=pDigs->GetEntries();    pDigs->Print();
   }
   GetLoader()->UnloadDigits();
-  Info("PrintDigits","totally %i Digits",iTotalDigits);
+  Printf("totally %i Digits",iTotalDigits);
 }
 //__________________________________________________________________________________________________
 void AliRICH::OccupancyPrint(Int_t iEvtNreq)const
@@ -637,11 +252,11 @@ void AliRICH::OccupancyPrint(Int_t iEvtNreq)const
       }
     }
     GetLoader()->TreeD()->GetEntry(0);
-    for(Int_t iChamber=1;iChamber<=kNchambers;iChamber++) {
-      nDigCh[iChamber-1]= Digits(iChamber)->GetEntries();
-      Double_t occupancy = (Double_t)nDigCh[iChamber-1]/(Double_t)totPadsPerChamber;
+    for(Int_t iCh=0;iCh<fNcham;iCh++) {
+      nDigCh[iCh]= ((TClonesArray*)fDig->At(iCh))->GetEntries();
+      Double_t occupancy = (Double_t)nDigCh[iCh-1]/(Double_t)totPadsPerChamber;
       Info("Occupancy","for chamber %i = %4.2f %% and charged prim tracks %i and sec. tracks %i with total %i",
-        iChamber,occupancy*100.,nPrim[iChamber-1],nSec[iChamber-1],iChHits[iChamber-1]);
+        iCh+1,occupancy*100.,nPrim[iCh],nSec[iCh],iChHits[iCh]);
     }
   }
   GetLoader()->UnloadHits();
@@ -650,266 +265,72 @@ void AliRICH::OccupancyPrint(Int_t iEvtNreq)const
   GetLoader()->GetRunLoader()->UnloadKinematics();    
 }
 //__________________________________________________________________________________________________
-void AliRICH::ClustersPrint(Int_t iEvtN)const
+void AliRICH::CluPrint(Int_t iEvtN)const
 {
 //prints a list of RICH clusters  for a given event
-  AliInfo(Form("List of RICH clusters for event %i",iEvtN));
+  Printf("List of RICH clusters for event %i",iEvtN);
   GetLoader()->GetRunLoader()->GetEvent(iEvtN);    
   if(GetLoader()->LoadRecPoints()) return;
   
-  Int_t iTotalClusters=0;
+  Int_t iCluCnt=0;
   GetLoader()->TreeR()->GetEntry(0);
-  for(Int_t iChamber=1;iChamber<=kNchambers;iChamber++){
-    Clusters(iChamber)->Print();
-    iTotalClusters+=Clusters(iChamber)->GetEntries();
+  for(Int_t iCham=0;iCham<fNcham;iCham++){
+    TClonesArray *pClus=(TClonesArray*)fClu->At(iCham);    iCluCnt+=pClus->GetEntries();    pClus->Print();
   }
   GetLoader()->UnloadRecPoints();
-  AliInfo(Form("totally %i clusters for event %i",iTotalClusters,iEvtN));
+  Printf("totally %i clusters for event %i",iCluCnt,iEvtN);
 }
-//__________________________________________________________________________________________________
-void AliRICH::PrintTracks(Int_t iEvtN)
-{
-//prints a list of tracks (including secondary) for a given event
-  AliInfo(Form("List of all tracks for event %i",iEvtN));
-  GetLoader()->GetRunLoader()->GetEvent(iEvtN);    
-  if(GetLoader()->GetRunLoader()->LoadHeader()) return;
-  if(GetLoader()->GetRunLoader()->LoadKinematics()) return;
-  AliStack *pStack=GetLoader()->GetRunLoader()->Stack();
-  
-  for(Int_t i=0;i<pStack->GetNtrack();i++) pStack->Particle(i)->Print();
-  
-  AliInfo(Form("totally %i tracks including %i primaries for event %i",pStack->GetNtrack(),pStack->GetNprimary(),iEvtN));
-  GetLoader()->GetRunLoader()->UnloadHeader();
-  GetLoader()->GetRunLoader()->UnloadKinematics();
-}
-//__________________________________________________________________________________________________
-void AliRICH::GeomPadPanelFrame()const
-{
-//Pad Panel frame  6 sectors
-  Double_t cm=1,mm=0.1*cm;//default is cm
-  Float_t par[3];
-  
-  par[0]=648*mm/2;par[1]=  411*mm/2;par[2]=40  *mm/2;gMC->Gsvolu("RPPF","BOX ",(*fIdtmed)[kAl]  ,par,3);//PPF 2001P2 inner size of the slab by 1mm more
-  par[0]=181*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("PPFL","BOX ",(*fIdtmed)[kAir] ,par,3);//large whole
-  par[0]=114*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("PPFS","BOX ",(*fIdtmed)[kAir] ,par,3);//small whole
-  par[0]=644*mm/2;par[1]=  407*mm/2;par[2]= 1.7*mm/2;gMC->Gsvolu("RPC ","BOX ",(*fIdtmed)[kCsI] ,par,3);//by 0.2 mm more then actual size (PCB 2006P1)
-  
-  gMC->Gspos("RPPF",1,"RICH",    -335*mm,      -433*mm,  8*cm+20*mm,  0,"ONLY");//F1 2040P1 z p.84 TDR
-  gMC->Gspos("RPPF",2,"RICH",    +335*mm,      -433*mm,  8*cm+20*mm,  0,"ONLY");
-  gMC->Gspos("RPPF",3,"RICH",    -335*mm,         0*mm,  8*cm+20*mm,  0,"ONLY");
-  gMC->Gspos("RPPF",4,"RICH",    +335*mm,         0*mm,  8*cm+20*mm,  0,"ONLY");
-  gMC->Gspos("RPPF",5,"RICH",    -335*mm,      +433*mm,  8*cm+20*mm,  0,"ONLY");
-  gMC->Gspos("RPPF",6,"RICH",    +335*mm,      +433*mm,  8*cm+20*mm,  0,"ONLY");  
-    gMC->Gspos("RPC ",1,"RPPF",       0*mm,         0*mm,   -19.15*mm,  0,"ONLY");//PPF 2001P2 
-    gMC->Gspos("PPFL",1,"RPPF",  -224.5*mm,  -151.875*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFL",2,"RPPF",  -224.5*mm,  - 50.625*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFL",3,"RPPF",  -224.5*mm,  + 50.625*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFL",4,"RPPF",  -224.5*mm,  +151.875*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFS",1,"RPPF",  - 65.0*mm,  -151.875*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFS",2,"RPPF",  - 65.0*mm,  - 50.625*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFS",3,"RPPF",  - 65.0*mm,  + 50.625*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFS",4,"RPPF",  - 65.0*mm,  +151.875*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFS",5,"RPPF",  + 65.0*mm,  -151.875*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFS",6,"RPPF",  + 65.0*mm,  - 50.625*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFS",7,"RPPF",  + 65.0*mm,  + 50.625*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFS",8,"RPPF",  + 65.0*mm,  +151.875*mm,     0.85*mm,  0,"ONLY"); 
-    gMC->Gspos("PPFL",5,"RPPF",  +224.5*mm,  -151.875*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFL",6,"RPPF",  +224.5*mm,  - 50.625*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFL",7,"RPPF",  +224.5*mm,  + 50.625*mm,     0.85*mm,  0,"ONLY");
-    gMC->Gspos("PPFL",8,"RPPF",  +224.5*mm,  +151.875*mm,     0.85*mm,  0,"ONLY");
-}//GeomPadPanelFrame()
-//__________________________________________________________________________________________________
-void AliRICH::GeomAmpGap()const
-{
-//Gap - anod wires 6 copies to RICH
-  Double_t cm=1,mm=0.1*cm,mkm=0.001*mm;//default is cm
-  Int_t matrixIdReturn=0; //matrix id returned by AliMatrix
-  Float_t par[3];
-
-
-  par[0]=648*mm/2;par[1]=  411*mm/2 ;par[2]=4.45*mm/2;gMC->Gsvolu("RGAP","BOX ",(*fIdtmed)[kCH4] ,par,3);//xy as PPF 2001P2 z WP 2099P1
-  par[0]=  0*mm  ;par[1]=  20*mkm/2 ;par[2]= 648*mm/2;gMC->Gsvolu("RANO","TUBE",(*fIdtmed)[kW]   ,par,3);//WP 2099P1 z = gap x PPF 2001P2
-  AliMatrix(matrixIdReturn,180,0, 90,90, 90,0); //wires along x
-  
-  gMC->Gspos("RGAP",1,"RICH",    -335*mm,      -433*mm,8*cm-2.225*mm, 0,"ONLY"); //F1 2040P1 z WP 2099P1
-  gMC->Gspos("RGAP",2,"RICH",    +335*mm,      -433*mm,8*cm-2.225*mm, 0,"ONLY"); 
-  gMC->Gspos("RGAP",3,"RICH",    -335*mm,         0*mm,8*cm-2.225*mm, 0,"ONLY"); 
-  gMC->Gspos("RGAP",4,"RICH",    +335*mm,         0*mm,8*cm-2.225*mm, 0,"ONLY"); 
-  gMC->Gspos("RGAP",5,"RICH",    -335*mm,      +433*mm,8*cm-2.225*mm, 0,"ONLY"); 
-  gMC->Gspos("RGAP",6,"RICH",    +335*mm,      +433*mm,8*cm-2.225*mm, 0,"ONLY"); 
-  for(int i=1;i<=96;i++)
-    gMC->Gspos("RANO",i,"RGAP",     0*mm, -411/2*mm+i*4*mm, 0.185*mm, matrixIdReturn,"ONLY"); //WP 2099P1  
-}//GeomAmpGap()
-//__________________________________________________________________________________________________
-void AliRICH::GeomRadiators()const
-{
-//Defines radiators geometry  
-  Double_t mm=0.1;//default is cm
-  Float_t par[3];
-  par[0]=1330*mm/2 ;par[1]= 413*mm/2  ;par[2]=  24*mm/2;  gMC->Gsvolu("RRAD","BOX ",(*fIdtmed)[kC6F14]     ,par,3); // Rad 2011P1
-  par[0]=1330*mm/2 ;par[1]= 413*mm/2  ;par[2]=   4*mm/2;  gMC->Gsvolu("RRFR","BOX ",(*fIdtmed)[kRoha]      ,par,3); //front 
-  par[0]=1330*mm/2 ;par[1]= 413*mm/2  ;par[2]=   5*mm/2;  gMC->Gsvolu("RRWI","BOX ",(*fIdtmed)[kSiO2]      ,par,3); //window
-  par[0]=1330*mm/2 ;par[1]=   5*mm/2  ;par[2]=  15*mm/2;  gMC->Gsvolu("RRLO","BOX ",(*fIdtmed)[kRoha]      ,par,3); //long side  
-  par[0]=  10*mm/2 ;par[1]= 403*mm/2  ;par[2]=  15*mm/2;  gMC->Gsvolu("RRSH","BOX ",(*fIdtmed)[kRoha]      ,par,3); //short side 
-  par[0]=   0      ;par[1]=  10*mm/2  ;par[2]=  15*mm/2;  gMC->Gsvolu("RRSP","TUBE",(*fIdtmed)[kSiO2]      ,par,3); //spacer        
-    
-  gMC->Gspos("RRAD",1,"RICH",   0*mm,-434*mm,   -12*mm,  0,"ONLY"); //3 radiators to RICH
-  gMC->Gspos("RRAD",2,"RICH",   0*mm,   0*mm,   -12*mm,  0,"ONLY"); 
-  gMC->Gspos("RRAD",3,"RICH",   0*mm,+434*mm,   -12*mm,  0,"ONLY"); 
-    gMC->Gspos("RRFR",1,"RRAD",   0*mm,   0*mm, -10.0*mm,  0,"ONLY"); //front cover 
-    gMC->Gspos("RRWI",1,"RRAD",   0*mm,   0*mm,   9.5*mm,  0,"ONLY"); //quartz window (back cover)
-    gMC->Gspos("RRLO",1,"RRAD",   0*mm,-204*mm,  -0.5*mm,  0,"ONLY"); //long side
-    gMC->Gspos("RRLO",2,"RRAD",   0*mm,+204*mm,  -0.5*mm,  0,"ONLY"); //long side
-    gMC->Gspos("RRSH",1,"RRAD",-660*mm,   0*mm,  -0.5*mm,  0,"ONLY"); //short side
-    gMC->Gspos("RRSH",2,"RRAD",+660*mm,   0*mm,  -0.5*mm,  0,"ONLY"); //short side 
-    for(int i=0;i<3;i++)
-      for(int j=0;j<10;j++)
-        gMC->Gspos("RRSP",10*i+j,"RRAD",-1330*mm/2+116*mm+j*122*mm,(i-1)*105*mm,-0.5*mm,0,"ONLY");//spacers
-}//GeomRadiators()
-//__________________________________________________________________________________________________
-void AliRICH::GeomSandBox()const
-{
-//Defines SandBox geometry
-  Double_t mm=0.1;//default is cm
-  Float_t par[3];
-  par[0]=1419*mm/2 ;par[1]=1378*mm/2;par[2]=50.5*mm/2; gMC->Gsvolu("RSNB","BOX ",(*fIdtmed)[kAir]  ,par,3);  //2072P1   
-  par[0]=1419*mm/2 ;par[1]=1378*mm/2;par[2]= 0.5*mm/2; gMC->Gsvolu("RSCO","BOX ",(*fIdtmed)[kAl]   ,par,3);  //cover
-  par[0]=1359*mm/2 ;par[1]=1318*mm/2;par[2]=49.5*mm/2; gMC->Gsvolu("RSHO","BOX ",(*fIdtmed)[kRoha] ,par,3); //honeycomb structure 
-  
-  gMC->Gspos("RSNB",1,"RICH",   0*mm, 0*mm, -73.75*mm, 0,"ONLY"); //p.84 TDR sandbox to rich
-    gMC->Gspos("RSHO",1,"RSNB", 0*mm, 0*mm,      0*mm, 0,"ONLY"); //2072P1 honeycomv to sandbox
-    gMC->Gspos("RSCO",1,"RSNB", 0*mm, 0*mm,    +25*mm, 0,"ONLY"); //cover to sandbox
-    gMC->Gspos("RSCO",2,"RSNB", 0*mm, 0*mm,    -25*mm, 0,"ONLY"); //cover to sandbox
-}//GeomSandBox()
-//__________________________________________________________________________________________________
-void AliRICH::GeomRadioSrc()const
-{
-// Defines geometry for radioactive source  
-  Double_t cm=1,mm=0.1*cm,mkm=0.001*cm;
-  Float_t par[3];
-  
-  par[0]=0 ;par[1]= 70*mm/2  ;par[2]=  30*mm/2;      gMC->Gsvolu("RSRC","TUBE",(*fIdtmed)[kCH4]    ,par,3); //top src container
-    par[0]=0 ;par[1]= 38*mm/2  ;par[2]=  21.8*mm/2;  gMC->Gsvolu("RSAG","TUBE",(*fIdtmed)[kAl]     ,par,3); //Al glass
-      par[0]=0 ;par[1]= 34*mm/2  ;par[2]=  20*mm/2;  gMC->Gsvolu("RSPP","TUBE",(*fIdtmed)[kPerpex] ,par,3); //perpex plug
-        par[0]=0 ;par[1]= 5*mm/2  ;par[2]=  15*mm/2; gMC->Gsvolu("RSSC","TUBE",(*fIdtmed)[kSteel]  ,par,3); //steel screw in center of perpex
-        par[0]=0 ;par[1]= 2*mm/2  ;par[2]=  10*mm/2; gMC->Gsvolu("RSSS","TUBE",(*fIdtmed)[kSteel]  ,par,3); //Steel screw to support Sr90 
-          par[0]=0 ;par[1]= 1*mm/2  ;par[2]= 1*mm/2; gMC->Gsvolu("RSSR","TUBE",(*fIdtmed)[kSr90]   ,par,3); //Sr90 source
-        par[0]=0 ;par[1]= 4*mm/2  ;par[2]= 10*mm/2;  gMC->Gsvolu("RSWP","TUBE",(*fIdtmed)[kAir]    ,par,3); //Air hole in perpex plug      
-      par[0]=0 ;par[1]= 5*mm/2  ;par[2]= 1.8*mm/2;   gMC->Gsvolu("RSWA","TUBE",(*fIdtmed)[kAir]    ,par,3); //Air hole in Al glass bottom
-    par[0]=0 ;par[1]= 30*mm/2  ;par[2]= 50*mkm/2;    gMC->Gsvolu("RSMF","TUBE",(*fIdtmed)[kMylar]  ,par,3); //Mylar foil                
-    
-  gMC->Gspos("RSRC",1,"RICH",       30*cm,        0,     1*cm, 0,"ONLY"); //source to RICH
-    gMC->Gspos("RSMF",1,"RSRC",         0,        0,21.8*mm/2+50*mkm/2, 0,"ONLY");//mylar foil to top src volume
-    gMC->Gspos("RSAG",1,"RSRC",         0,        0,        0, 0,"ONLY");//Al glass to fake Src volume 
-      gMC->Gspos("RSWA",1,"RSAG",    6*mm,        0,   -10*mm, 0,"ONLY");//air whole in al glass bottom
-      gMC->Gspos("RSPP",1,"RSAG",       0,        0,   0.9*mm, 0,"ONLY");//perpex plug to Al glass
-        gMC->Gspos("RSWP",1,"RSPP",  6*mm,        0,    -5*mm, 0,"ONLY");//air whole in perpex plug
-        gMC->Gspos("RSSC",1,"RSPP",     0,        0,   2.5*mm, 0,"ONLY");//steel screw in center of perpex plug
-        gMC->Gspos("RSSS",1,"RSPP",  6*mm,        0,     5*mm, 0,"ONLY");//steel screw to support Sr90  in perpex plug
-          gMC->Gspos("RSSR",1,"RSSS",   0,        0,  -4.5*mm, 0,"ONLY");//Sr90  in support steel screw
-}//GeomSr90()
-//__________________________________________________________________________________________________
-void AliRICH::GeomAerogel()const
-{
-//Creates detailed geometry for aerogel study.
-  AliDebug(1,"Start.");
-  Double_t cm=1;
-  Float_t par[3]; //tmp array for volume dimentions
-       
-  par[0]=10.1*cm/2;par[1]=10.1*cm/2;par[2]=10.1*cm/2;
-  gMC->Gsvolu("RREF","BOX ",(*fIdtmed)[kReflector],par,3);//reflector box
-  gMC->Gspos("RREF",1,"RICH",0,0,0,0, "ONLY");            //put it to RICH volume
-  
-  par[0]=10*cm/2;par[1]=10*cm/2;par[2]=10*cm/2;
-  gMC->Gsvolu("RGEL","BOX ",(*fIdtmed)[kGel],par,3);//10x10x10 cm^3 cubic of aerogel
-  gMC->Gspos("RGEL",1,"RREF",0,0,0,0,"ONLY");//put gel cell to reflector
-  AliDebug(1,"Stop.");  
-}//GeomAerogel()
-//__________________________________________________________________________________________________
-void AliRICH::CreateGeometry()
-{
-//Creates detailed geometry simulation (currently GEANT volumes tree)         
-  AliDebug(1,"Start main.");
-  Double_t mm=0.1;//default is cm
-  Float_t par[3];
-  Int_t matrixIdReturn=0; //matrix id returned by AliMatrix
-       
-//place chambers into mother volume ALIC
-  par[0]=(6*mm+1681*mm+6*mm)/2;par[1]=(6*mm+1466*mm+6*mm)/2;par[2]=(80*mm+40*mm)*2/2;
-  gMC->Gsvolu("RICH","BOX ",(*fIdtmed)[kCH4],par,3);//2033P1  z p84 TDR
-  for(int i=1;i<=P()->Nchambers();i++){ //test configuration with single chamber is taken into account automaticaly in AliRICHParam
-    AliMatrix(matrixIdReturn,
-                   C(i)->ThetaXd(),C(i)->PhiXd(),  
-                   C(i)->ThetaYd(),C(i)->PhiYd(),  
-                   C(i)->ThetaZd(),C(i)->PhiZd());
-    gMC->Gspos("RICH",i,"ALIC",C(i)->Center().X(),
-                               C(i)->Center().Y(),
-                               C(i)->Center().Z(),matrixIdReturn, "ONLY");
-  }
-  
-  if(P()->IsAerogel()) 
-    GeomAerogel();
-  else{
-    GeomPadPanelFrame();
-    GeomAmpGap();
-    if(P()->IsRadioSrc())    GeomRadioSrc(); else GeomRadiators(); 
-    GeomSandBox();           
-  }
-  AliDebug(1,"Stop main.");  
-}//CreateGeometry()
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICH::DisplayEvent(Int_t iEvtNmin,Int_t iEvtNmax)const
 {
-  TH2F *pDigitsH2[8];
+// Display digits, reconstructed tracks intersections and RICH rings if available 
+  TH2F *pH2[8];
 
-  Bool_t isDigits  =!GetLoader()->LoadDigits();
-  if(!isDigits){Error("ShoEvent","No digits. Nothing to display.");return;}
+  GetLoader()->LoadDigits();
   
-  TCanvas *canvas = new TCanvas("RICHDisplay","RICH Display",0,0,1226,900);     
+  TLatex t;  t.SetTextSize(0.1);
+  TCanvas *pC = new TCanvas("RICHDisplay","RICH Display",0,0,1226,900);  pC->Divide(3,3);  pC->cd(9); t.DrawText(0.2,0.4,"View to IP");  
   gStyle->SetPalette(1);
 
   
-  for(Int_t iChamber=1;iChamber<=7;iChamber++) {
-    pDigitsH2[iChamber] = new TH2F(Form("pDigitsH2_%i",iChamber),Form("Chamber %i",iChamber),165,0,P()->PcSizeX(),144,0,P()->PcSizeY());
-    pDigitsH2[iChamber]->SetMarkerColor(kGreen); 
-    pDigitsH2[iChamber]->SetMarkerStyle(29); 
-    pDigitsH2[iChamber]->SetMarkerSize(0.4);
-    pDigitsH2[iChamber]->SetStats(kFALSE);
-    pDigitsH2[iChamber]->SetMaximum(300);
+  for(Int_t iCh=1;iCh<=fNcham;iCh++) {
+    pH2[iCh] = new TH2F(Form("RichDigH2_%i",iCh),Form("Chamber %i;cm;cm",iCh),165,0,AliRICHParam::PcSizeX(),144,0,AliRICHParam::PcSizeY());
+    pH2[iCh]->SetMarkerColor(kGreen); 
+    pH2[iCh]->SetMarkerStyle(29); 
+    pH2[iCh]->SetMarkerSize(0.4);
+    pH2[iCh]->SetStats(kFALSE);
+    pH2[iCh]->SetMaximum(300);
   }
   
   if(iEvtNmax>gAlice->GetEventsPerRun()||iEvtNmax==0) iEvtNmax=gAlice->GetEventsPerRun()-1;
 
-  TLatex t;  t.SetTextSize(0.1);
-  for(Int_t iEventN=iEvtNmin;iEventN<=iEvtNmax;iEventN++) {//events loop
-    canvas->Divide(3,3);    
-    canvas->cd(1);
-    t.DrawText(0.2,0.4,Form("Event Number %i",iEventN));        
+  for(Int_t iEvt=iEvtNmin;iEvt<=iEvtNmax;iEvt++) {//events loop
+    pC->cd(3);  t.DrawText(0.2,0.4,Form("Event %i",iEvt));        
 
-    GetLoader()->GetRunLoader()->GetEvent(iEventN); //get event
-    GetLoader()->TreeD()->GetEntry(0);              //get list of digits 
-    for(Int_t iChamber=1;iChamber<=7;iChamber++) {//chambers loop
-      pDigitsH2[iChamber]->Reset();    
-      for(Int_t j=0;j<Digits(iChamber)->GetEntries();j++) {//digits loop
-        AliRICHDigit *pDig = (AliRICHDigit*)Digits(iChamber)->At(j);
+    GetLoader()->GetRunLoader()->GetEvent(iEvt); //get event
+    GetLoader()->TreeD()->GetEntry(0);           //get list of digits 
+    for(Int_t iCh=1;iCh<=fNcham;iCh++) {//chambers loop
+      pH2[iCh]->Reset();    
+      for(Int_t iDig=0;iDig < Digs(iCh)->GetEntries();iDig++) {//digits loop
+        AliRICHDigit *pDig = (AliRICHDigit*)Digs(iCh)->At(iDig);
         TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad());
-        pDigitsH2[iChamber]->Fill(x2.X(),x2.Y(),pDig->Qdc());
+        pH2[pDig->C()]->Fill(x2.X(),x2.Y(),pDig->Qdc());
       }//digits loop
-      if(iChamber==1) canvas->cd(7);
-      if(iChamber==2) canvas->cd(8);
-      if(iChamber==3) canvas->cd(4);
-      if(iChamber==4) canvas->cd(5);
-      if(iChamber==5) canvas->cd(6);
-      if(iChamber==6) canvas->cd(2);
-      if(iChamber==7) canvas->cd(3);
-      pDigitsH2[iChamber]->Draw("col");
-      ReadESD(iEventN,iChamber);
+      if(iCh==1) pC->cd(9);
+      if(iCh==2) pC->cd(8);
+      if(iCh==3) pC->cd(6);
+      if(iCh==4) pC->cd(5);
+      if(iCh==5) pC->cd(4);
+      if(iCh==6) pC->cd(2);
+      if(iCh==7) pC->cd(1);
+      pH2[iCh]->Draw("col");
+      ReadESD(iEvt,iCh);
       AliRICHParam::DrawSectors();
     }//chambers loop
-    canvas->Update();
-    canvas->Modified();
+    pC->Update();
+    pC->Modified();
 
-    if(iEventN<iEvtNmax) {gPad->WaitPrimitive();canvas->Clear();}
+    if(iEvt<iEvtNmax) {gPad->WaitPrimitive();pC->Clear();}
   }//events loop
 }//ShowEvent()
 //__________________________________________________________________________________________________
@@ -936,30 +357,27 @@ void AliRICH::Display()const
   if(isClusters) pClustersH2 = new TH2F("pClustersH2","Event Display",165,0,AliRICHParam::PcSizeX(),
                                                                       144,0,AliRICHParam::PcSizeY());
   
-  for(Int_t iEventN=0;iEventN<gAlice->GetEventsPerRun();iEventN++){//events Loop
-    GetLoader()->GetRunLoader()->GetEvent(iEventN);  
+  for(Int_t iEvt=0;iEvt<GetLoader()->GetRunLoader()->GetNumberOfEvents();iEvt++){//events Loop
+    GetLoader()->GetRunLoader()->GetEvent(iEvt);  
 //display all the staff on chamber by chamber basis           
-    for(Int_t iChamber=1;iChamber<=7;iChamber++){//chambers loop       
+    for(Int_t iCh=1;iCh<=fNcham;iCh++){//chambers loop       
       if(isHits)     pHitsH2    ->Reset();     
       if(isDigits)   pDigitsH2  ->Reset();     
       if(isClusters) pClustersH2->Reset();
 //deals with hits
       for(Int_t i=0;i<GetLoader()->TreeH()->GetEntries();i++){//TreeH loop
         GetLoader()->TreeH()->GetEntry(i);
-        for(Int_t j=0;j<Hits()->GetEntries();j++){//hits loop
-          AliRICHHit *pHit = (AliRICHHit*)Hits()->At(j);
-          if(pHit->C()==iChamber){
-            TVector3 hitGlobX3= pHit->OutX3();
-            TVector2 hitLocX2 = C(iChamber)->Mrs2Pc(hitGlobX3);
+        for(Int_t iHit=0;iHit<Hits()->GetEntries();iHit++){//hits loop
+          AliRICHHit *pHit = (AliRICHHit*)Hits()->At(iHit);
+          if(pHit->C()==iCh){
+            TVector2 hitLocX2 = AliRICHParam::Instance()->Mars2Lors(iCh,pHit->OutX3());
             pHitsH2->Fill(hitLocX2.X(),hitLocX2.Y(),200);
           }//if
         }//hits loop         
       }//TreeH loop
-      pHitsH2->SetTitle(Form("event %i chamber %2i",iEventN,iChamber));
+      pHitsH2->SetTitle(Form("event %i chamber %2i",iEvt,iCh));
       pHitsH2->SetMarkerColor(kRed); pHitsH2->SetMarkerStyle(29); pHitsH2->SetMarkerSize(0.4);
-      ReadESD(iEventN,iChamber);
       pHitsH2->Draw();
-//      ReadESD(iEventN,iChamber);
       AliRICHParam::DrawSectors();
       TLatex l; l.SetNDC(); l.SetTextSize(0.02);
       if(!isHits)     {l.SetTextColor(kRed)  ;l.DrawLatex(0.1,0.01,"No Hits"    );}
@@ -969,10 +387,10 @@ void AliRICH::Display()const
 //deals with digits      
       if(isDigits){
         GetLoader()->TreeD()->GetEntry(0);
-        for(Int_t j=0;j<Digits(iChamber)->GetEntries();j++){//digits loop
-          AliRICHDigit *pDig = (AliRICHDigit*)Digits(iChamber)->At(j);
-         TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad());
-         pDigitsH2->Fill(x2.X(),x2.Y(),100);
+        for(Int_t iDig=0;iDig < Digs(iCh)->GetEntries();iDig++){//digits loop
+          AliRICHDigit *pDig = (AliRICHDigit*)Digs(iCh)->At(iDig);
+               TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad());
+               pDigitsH2->Fill(x2.X(),x2.Y(),100);
         }//digits loop
         pDigitsH2->SetMarkerColor(kGreen); pDigitsH2->SetMarkerStyle(29); pDigitsH2->SetMarkerSize(0.4);
         pDigitsH2->Draw("same");
@@ -981,9 +399,9 @@ void AliRICH::Display()const
 //deals with clusters      
       if(isClusters){
         GetLoader()->TreeR()->GetEntry(0);
-        for(Int_t j=0;j<Clusters(iChamber)->GetEntries();j++){//clusters loop
-          AliRICHCluster *pClus = (AliRICHCluster*)Clusters(iChamber)->At(j);
-          pClustersH2->Fill(pClus->X(),pClus->Y(),50);
+        for(Int_t iClu=0;iClu<Clus(iCh)->GetEntries();iClu++){//clusters loop
+          AliRICHCluster *pClu = (AliRICHCluster*)Clus(iCh)->At(iClu);
+          pClustersH2->Fill(pClu->X(),pClu->Y(),50);
         }//clusters loop
         pClustersH2->SetMarkerColor(kBlue); pClustersH2->SetMarkerStyle(29);  pClustersH2->SetMarkerSize(0.4);
         pClustersH2->Draw("same");
@@ -997,35 +415,15 @@ void AliRICH::Display()const
   if(isDigits)   GetLoader()->UnloadDigits();
   if(isClusters) GetLoader()->UnloadRecPoints();
 }//Display()
-//__________________________________________________________________________________________________
-Int_t AliRICH::Nparticles(Int_t iPartID,Int_t iEvtN,AliRunLoader *pRL)
-{
-//counts total number of particles of given type (including secondary) for a given event
-  pRL->GetEvent(iEvtN);    
-  if(pRL->LoadHeader()) return 0;
-  if(pRL->LoadKinematics()) return 0;
-  AliStack *pStack=pRL->Stack();
-  
-  Int_t iCounter=0;
-  for(Int_t i=0;i<pStack->GetNtrack();i++){
-    if(pStack->Particle(i)->GetPdgCode()==iPartID) iCounter++;
-  }
-  
-  pRL->UnloadHeader();
-  pRL->UnloadKinematics();
-  return iCounter;
-}
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICH::ReadESD(Int_t iEventN, Int_t iChamber)const
 {
 //
-  AliInfo("Start.");
   TFile *pFile=TFile::Open("AliESDs.root","read");
   if(!pFile || !pFile->IsOpen()) {AliInfo("ESD file not open.");return;}      //open AliESDs.root                                                                    
   TTree *pTree = (TTree*) pFile->Get("esdTree");
   if(!pTree){AliInfo("ESD not found.");return;}                               //get ESD tree
   
-  AliInfo("ESD found. Try to draw ring");
                                                                  
   AliESD *pESD=new AliESD;  pTree->SetBranchAddress("ESD", &pESD);
   
@@ -1039,14 +437,13 @@ void AliRICH::ReadESD(Int_t iEventN, Int_t iChamber)const
     AliESDtrack *pTrack = pESD->GetTrack(iTrackN);// get next reconstructed track
     Int_t charge = (Int_t)(-TMath::Sign(1.,pTrack->GetSign()*b));
     AliRICHHelix helix(pTrack->X3(),pTrack->P3(),charge,b);
-    Int_t iChamberOnRICH=helix.RichIntersect(P());        
+    Int_t iChamberOnRICH=helix.RichIntersect(AliRICHParam::Instance());        
     if(iChamberOnRICH==iChamber) {
-//
       TMarker *trackImpact = new TMarker(helix.PosPc().X(),helix.PosPc().Y(),kStar);
       trackImpact->SetMarkerColor(kRed);
       trackImpact->Draw();
 //
-      Int_t iChamberRecon = pTrack->GetRICHcluster()/100000;
+      Int_t iChamberRecon = pTrack->GetRICHcluster()/1000000;
       if(iChamberRecon==iChamber) {
         Double_t thetaCer = pTrack->GetRICHsignal();
         if(thetaCer<0) continue;
@@ -1059,13 +456,11 @@ void AliRICH::ReadESD(Int_t iEventN, Int_t iChamber)const
         AliInfo(Form("ThetaCer %f TrackTheta %f TrackPhi %f Momentum %f",thetaCer,thetaTrack,phiTrack,pTrack->GetP()));
         Double_t dx,dy;
         pTrack->GetRICHdxdy(dx,dy);
-        AliInfo(Form("dx %f dy %f ",dx,dy));
         DrawRing(entrance,vectorTrack,thetaCer);
       }
     }
   }
   delete pESD;  pFile->Close();//close AliESDs.root
-  AliInfo("Stop.");
 }
 //__________________________________________________________________________________________________
 void AliRICH::DrawRing(TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)const
@@ -1074,7 +469,7 @@ void AliRICH::DrawRing(TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)
   Int_t nPointsToDraw = 0;
   for(Int_t i=0;i<100;i++) {
     Double_t phiCer = 2*TMath::Pi()*i/100;
-    TVector3 pos = AliRICHParam::ForwardTracing(entrance,vectorTrack,thetaCer,phiCer);
+    TVector3 pos = AliRICHParam::Instance()->ForwardTracing(entrance,vectorTrack,thetaCer,phiCer);
     if(pos.X()==-999) continue;
     xGraph[nPointsToDraw] = pos.X();yGraph[nPointsToDraw] = pos.Y();nPointsToDraw++;
   }
@@ -1108,7 +503,7 @@ void AliRICH::SummaryOfEvent(Int_t iEvtN) const
   GetLoader()->GetRunLoader()->UnloadKinematics();
 }
 //__________________________________________________________________________________________________
-void AliRICH::HitsQA(Double_t cut,Double_t cutele,Double_t cutR)
+void AliRICH::HitQA(Double_t cut,Double_t cutele,Double_t cutR)
 {
 // Provides a set of control plots intended primarily for charged particle flux analisys
 // Arguments: cut (GeV)    - cut on momentum of any charged particles but electrons, 
index b353116..239a0c9 100644 (file)
 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
  * See cxx source for full Copyright notice                               */
 
-#include <AliDetector.h>  //inheritance
-#include <TClonesArray.h> 
+#include <AliDetector.h>  //base class
+#include <TClonesArray.h>  
 #include <TObjArray.h>
 #include <TVector.h>
 #include <TVector3.h>
 
-#include "AliRICHParam.h"
 #include "AliRICHCluster.h"
 #include "AliRICHHit.h"
 
 //__________________AliRICH_________________________________________________________________________
 class AliESD;
 
-class AliRICH : public AliDetector 
+class AliRICH : public AliDetector //TObject-TNamed-AliModule-AliDetector-AliRICH
 {
 public:
 //ctor & dtor    
             AliRICH();                                            
             AliRICH(const char *name, const char *title);
-            AliRICH(const AliRICH& RICH):AliDetector(RICH) {;}  //copy ctor 
+            AliRICH(const AliRICH& RICH                ):AliDetector(RICH) {;}  //copy ctor 
   virtual  ~AliRICH();                                            
           
   AliRICH&  operator=(const AliRICH&)                 {return *this;}
 //framework part  
-  virtual Int_t         IsVersion()                           const =0;                                  //interface from         
-  virtual void          StepManager()                               =0;                                  //interface from AliMC
-  virtual void          SetTreeAddress();                                                                //interface from AliLoader
-  virtual void          MakeBranch(Option_t *opt=" ");                                                   //interface from AliLoader
-  virtual void          CreateMaterials();                                                               //interface from AliMC
-  virtual void          CreateGeometry();                                                                //interface from AliMC
-  virtual void          BuildGeometry();                                                                 //interface 
-  virtual void          Print(Option_t *option="")               const;       //prints current RICH status
+          void  BuildGeometry   (                   );            //from AliModule invoked from AliMC::InitGeometry() to build geometry for event display
+  virtual void  CreateMaterials (                   )=0;          //from AliModule invoked from AliMC::ConstructGeometry() to define detector materials
+  virtual void  CreateGeometry  (                   )=0;          //from AliModule invoked from AliMC::ConstructGeometry() to build detector for simulation
+  virtual Int_t IsVersion       (                   )const=0;     //from AliModule not used        
+  virtual void  Init            (                   )=0;          //from AliModule invoked from AliMC::InitGeometry() after CreateGeometry() to do VolID initialization
+          void  MakeBranch      (Option_t *opt=""   );            //from AliModule invokde from AliRun::Tree2Tree() to make requested RICH branch
+//  virtual void  Print           (const Option_t *opt)const=0;     //from TObject
+  virtual void  StepManager     (                   )=0;          //from AliModule invoked from AliMC
+          void  SetTreeAddress  (                   );            //from AliModule invoked from AliRun::GetEvent(), AliLoader::SetTAddrInDet()
 //private part  
-          void          GeomPadPanelFrame()const;                                                        //defines PPF geometry
-          void          GeomAmpGap()       const;                                                        //defines gap geometry + anod wires
-          void          GeomRadiators()    const;                                                        //defines radiators geometry
-          void          GeomSandBox()      const;                                                        //defines sandbox geometry
-          void          GeomRadioSrc()     const;                                                        //defines radio source geometry
-          void          GeomAerogel()      const;                                                        //defines aerogel geometry
-  static  Float_t Fresnel(Float_t ene,Float_t pdoti, Bool_t pola);       //deals with Fresnel absorption
-  
-         AliRICHHit*   Hit           (Int_t tid                                              )const;                                                 //first hit of given TID 
-  inline void          HitAdd        (Int_t c,Int_t tid,TVector3 in,TVector3 out,Double_t e=0);                                                      //add new hit
-  inline void          HitsCreate    (                                                       );                                                      //create hits container
-         void          HitsPrint     (Int_t iEvent=0                                         )const;                                                 //prints hits
-         void          HitsQA        (Double_t cut=0,Double_t cutele=0,Double_t cutR=999);
+  void    HitAdd    (Int_t c,Int_t tid,Int_t pid,TVector3 in,TVector3 out,Double_t e=0        ){new((*fHits)[fNhits++])AliRICHHit(c,tid,in,out,e,pid);          } 
+  void    HitAdd    (Int_t tid,Double_t e,Int_t pad,Double_t x,Double_t y,Double_t z,Int_t pid){new((*fHits)[fNhits++])AliRICHHit(tid,e,pad,x,y,z,pid);         } 
+  void    HitCreate (                                                                         ){if(fHits)return; fHits=new TClonesArray("AliRICHHit"); fNhits=0;}
+  void    HitPrint  (Int_t iEvent=0                                                           )const;                                                 
+  void    HitQA     (Double_t cut=0,Double_t cutele=0,Double_t cutR=999                       );
             
-         TClonesArray* SDigits       (                                                       )const{return fSdigits;}                                //pointer to sdigits list 
-  inline void          SDigitAdd     (Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid     )     ;                                                 //add new sdigit
-  inline void          SDigitsCreate (                                                       )     ;                                                 //create sdigits container
-         void          SDigitsReset  (                                                       )     {fNsdigits=0;  if(fSdigits)  fSdigits ->Clear();} //clean a list of sdigits                                
-         void          SDigitsPrint  (Int_t iEvent=0                                         )const;                                                 //prints sdigits 
+  TClonesArray* SDigs         (                                                       )const{return fSdig;}                                  //pointer to sdigits list 
+  inline void          SDigAdd       (Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid     )     ;                                                 //add new sdigit
+  void   SDigCreate (                                                       )   {if(fSdig) return;  fSdig=new TClonesArray("AliRICHDigit"); fSdigCnt=0;}
+  void   SDigReset  (                                                       )   {fSdigCnt=0;  if(fSdig)  fSdig ->Clear();}     //clean a list of sdigits                                
+  void   SDigPrint  (Int_t iEvent=0                                         )const;                                                 //prints sdigits 
          
-    using AliDetector::Digits;  
-         TClonesArray* Digits        (Int_t iC                                               )const{return fDigs ? (TClonesArray *)fDigs->At(iC-1):0;}
-  inline void          DigitAdd      (Int_t c,TVector pad,int q,int cfm,int *tid             )     ;                                                 //add new digit
-  inline void          DigitAdd      (AliRICHDigit &dif                                      )     ;                                                 //add new digit
-  inline void          DigitsCreate  (                                                       )     ;                                                 //create digits
-         void          DigitsReset   (                                                       )     {if(fDigs)for(int i=0;i<kNchambers;i++){fDigs->At(i)->Clear();fNdigs[i]=0;}} //virtual
-         void          DigitsPrint   (Int_t iEvent=0                                         )const;                                                 //prints digits
+         TClonesArray* Digs          (Int_t iC                                               )const{return fDig ? (TClonesArray *)fDig->At(iC-1):0;}
+  inline void          DigAdd        (Int_t c,TVector pad,int q,int cfm,int *tid             )     ;                                                 //add new digit
+  inline void          DigAdd        (AliRICHDigit &dif                                      )     ;                                                 //add new digit
+  inline void          DigCreate     (                                                       )     ;                                                 //create digits
+         void          DigReset      (                                                       )     {if(fDig)for(int i=0;i<fNcham;i++){fDig->At(i)->Clear();fDigCnt[i]=0;}} 
+         void          DigPrint      (Int_t iEvent=0                                         )const;                                                 //prints digits
           
-         TClonesArray* Clusters      (Int_t iC                                               )const{if(fClus)  return (TClonesArray *)fClus->At(iC-1);else return 0;}
-  inline void          ClusterAdd    (AliRICHCluster &cl                                     )     ;                                                  //add new cluster                        
-  inline void          ClustersCreate(                                                       )     ;                                                  //create clusters container
-         void          ClustersReset (                                                       )     {if(fClus)for(int i=0;i<kNchambers;i++){fClus ->At(i)->Clear();fNclus[i]=0;}}
-         void          ClustersPrint (Int_t iEvent=0                                         )const;                        //prints a list of clusters for a given event
-
-         void          OccupancyPrint(Int_t iEvent=-1                                        )const;
-         void          SummaryOfEvent(Int_t iEvent=0                                         )const;
+         TClonesArray* Clus          (Int_t iC                                               )const{return fClu ? (TClonesArray *)fClu->At(iC-1):0;}
+  inline void          CluCreate     (                                                       )     ;                                                  //create clusters container
+         void          CluReset      (                                                       )     {if(fClu)for(int i=0;i<fNcham;i++){fClu->At(i)->Clear();fCluCnt[i]=0;}}
+         void          CluPrint      (Int_t iEvent=0                                         )const;                        //prints a list of clusters for a given event
          
-  AliRICHChamber* C(Int_t iC)           const{return fParam->C(iC);}   //provides pointer to a given chamber
-  AliRICHParam*   P()                   const{return fParam;}          //provides pointer to a RICH params
-  AliRICH*        R()                        {return this;}             //provides pointer to RICH main object
-  TVector         Counters()            const{return fCounters;}        //provides a set of counters
-  void            ControlPlots();                                       //creates ~/RCP.root with a set of QA plots
-  void            Display()const; //Display event
-  void            DisplayEvent(Int_t,Int_t)const; //Display event
-  static Int_t     Nparticles(Int_t iPid,Int_t iEventN,AliRunLoader *pRunLoader); //counts total number of particle with iPid
-  void            PrintTracks  (Int_t iEvent=0);                        //prints a list of tracks for a given event
-  void            ReadESD(Int_t iEventN, Int_t iChamber)const;
-  void            DrawRing(TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)const;
+         void     Display      (                                                        )const;                    //Display event
+         void     DisplayEvent (Int_t,Int_t                                             )const;                    //Display event
+         void     DrawRing     (TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)const;
+         void     OccupancyPrint(Int_t iEvent=-1                                        )const;                    //print chambers occupancy 
+         void     ReadESD      (Int_t iEventN, Int_t iChamber                           )const;                    
+         void     SummaryOfEvent(Int_t iEvent=0                                         )const;
 
 protected:  
-  enum                  EMedia {kAir=1,kRoha,kSiO2,kC6F14,kCH4,kCsI,kGridCu,kOpSiO2,kGap,kAl,kGlass,kCu,kW,kSteel,kPerpex,kSr90,kMylar,kGel,kReflector};
-  enum                  ECounters {kStepManager=0,kCerProdTot,kCerProdRad,kCerKillTot,kCerKillRad,kCerKillRef,kEleProdTot};
-  AliRICHParam         *fParam;                    //main RICH parametrization     
-                                                   //fHits and fDigits belong to AliDetector
-  TClonesArray         *fSdigits;                  //! list of sdigits  
-  Int_t                 fNsdigits;                 //! current number of sdigits
+  TClonesArray         *fSdig;                    //! list of sdigits  
+  Int_t                 fSdigCnt;                 //! current number of sdigits
   
-  TObjArray            *fDigs;                     //! each chamber holds it's one lists of digits
-  Int_t                 fNdigs[7];                 //! array of current numbers of digits
+  TObjArray            *fDig;                     //! each chamber holds it's one list of digits
+  Int_t                 fDigCnt[7];               //! array of current numbers of digits
   
-  TObjArray            *fClus;                     //! each chamber holds it's one lists of clusters 
-  Int_t                 fNclus[7];                 //! array of current numbers of raw clusters
+  TObjArray            *fClu;                     //! each chamber holds it's one list of clusters 
+  Int_t                 fCluCnt[7];               //! array of current numbers of raw clusters
   
-  TVector               fCounters;                 //Particle history counters, explanation in StepManager() 
+  TVector               fCounters;                // Particle history counters, explanation in StepManager() 
+  Int_t                 fNcham;                   // Number of RICH chambers during simulation
   
-  ClassDef(AliRICH,9)                              //Main RICH class 
+  ClassDef(AliRICH,11)                            //Main RICH class 
 };//class AliRICH  
 
 //__________________________________________________________________________________________________
-void AliRICH::HitsCreate()
-{
-  if(fHits) return;
-  AliDebug(1,"creating hits container.");
-  fHits=new TClonesArray("AliRICHHit",10000);   fNhits=0;
-}
-//__________________________________________________________________________________________________
-void AliRICH::HitAdd(Int_t c,Int_t tid,TVector3 i3,TVector3 o3,Double_t eloss)
-{
-//add new RICH hit to the list of hits  
-  TClonesArray &tmp=*fHits;
-  new(tmp[fNhits++])AliRICHHit(c,tid,i3,o3,eloss);
-}//AddHit()
-//__________________________________________________________________________________________________
-void AliRICH::SDigitsCreate()
-{
-  if(fSdigits) return;
-  AliDebug(1,"creating sdigits container.");
-  fSdigits=new TClonesArray("AliRICHDigit",10000); fNsdigits=0;
-}
-//__________________________________________________________________________________________________
-void AliRICH::SDigitAdd(Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid) 
+void AliRICH::SDigAdd(Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid) 
 { 
   Int_t cfm;  
   switch(pid){
@@ -134,42 +92,33 @@ void AliRICH::SDigitAdd(Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid)
     case 50000051: cfm=1000;   break;//feedback
     default:       cfm=1;      break;//mip
   }   
-  TClonesArray &tmp=*fSdigits; new(tmp[fNsdigits++])AliRICHDigit(c,pad,q,cfm,tid,-1,-1);
+  new((*fSdig)[fSdigCnt++])AliRICHDigit(c,pad,q,cfm,tid,-1,-1);
 }
 //__________________________________________________________________________________________________
-void AliRICH::DigitsCreate()
+void AliRICH::DigCreate()
 {
-  if(fDigs) return;
-  AliDebug(1,"creating digits containers.");
-  fDigs = new TObjArray(kNchambers);  
-  for(Int_t i=0;i<kNchambers;i++) {fDigs->AddAt(new TClonesArray("AliRICHDigit",10000), i); fNdigs[i]=0;}
+  if(fDig) return;
+  fDig = new TObjArray(fNcham);  
+  for(Int_t i=0;i<fNcham;i++) {fDig->AddAt(new TClonesArray("AliRICHDigit"), i); fDigCnt[i]=0;}
 }
 //__________________________________________________________________________________________________
-void AliRICH::DigitAdd(AliRICHDigit &dig)
+void AliRICH::DigAdd(AliRICHDigit &dig)
 {
 //special for digit formed from raw  
-  TClonesArray &tmp=*((TClonesArray*)fDigs->At(dig.Chamber()-1));
-  new(tmp[fNdigs[dig.Chamber()-1]++])AliRICHDigit(dig);
+  TClonesArray &tmp=*((TClonesArray*)fDig->At(dig.C()-1));
+  new(tmp[fDigCnt[dig.C()-1]++])AliRICHDigit(dig);
 }    
 //__________________________________________________________________________________________________
-void AliRICH::DigitAdd(int c,TVector pad,int q,int cfm,int *tid)
+void AliRICH::DigAdd(int c,TVector pad,int q,int cfm,int *tid)
 {
-  TClonesArray &tmp=*((TClonesArray*)fDigs->At(c-1));
-  new(tmp[fNdigs[c-1]++])AliRICHDigit(c,pad,q,cfm,tid[0],tid[1],tid[2]);
+  TClonesArray &tmp=*((TClonesArray*)fDig->At(c-1));
+  new(tmp[fDigCnt[c-1]++])AliRICHDigit(c,pad,q,cfm,tid[0],tid[1],tid[2]);
 }    
 //__________________________________________________________________________________________________
-void AliRICH::ClustersCreate()
+void AliRICH::CluCreate()
 {
-  if(fClus) return;
-  AliDebug(1,"creating clusters containers.");
-  fClus = new TObjArray(kNchambers);  
-  for(Int_t i=0;i<kNchambers;i++) {fClus->AddAt(new TClonesArray("AliRICHCluster",10000), i); fNclus[i]=0;}
+  if(fClu) return;
+  fClu = new TObjArray(fNcham);  
+  for(Int_t i=0;i<fNcham;i++) {fClu->AddAt(new TClonesArray("AliRICHCluster"), i); fCluCnt[i]=0;}
 }
-//__________________________________________________________________________________________________
-void AliRICH::ClusterAdd(AliRICHCluster &cl)                     
-{
-  Int_t c=cl.C()-1;TClonesArray &tmp=*((TClonesArray*)fClus->At(c));
-  new(tmp[fNclus[c]++])AliRICHCluster(cl);
-}
-//__________________________________________________________________________________________________
 #endif//#ifndef AliRICH_h
index 6e73674..3f91dd8 100644 (file)
 //  * provided "as is" without express or implied warranty.                  *
 //  **************************************************************************
 
-#include "AliRICHCluster.h"
-#include <TMinuit.h>  //Solve()
+#include "AliRICHCluster.h"  //class header
+#include <TMinuit.h>         //Solve()
+#include <AliStack.h>        //FindCfm(), Solve() 
+#include <TParticle.h>       //FindCfm()
+#include <TClonesArray.h>    //Solve() Test()
+
 ClassImp(AliRICHCluster)
 //__________________________________________________________________________________________________
-void AliRICHCluster::Print(Option_t*)const
+void AliRICHCluster::CoG()
 {
-//Print current cluster  
-  const char *status=0;
-  switch(fStatus){
-    case      kFormed: status="formed"     ;break;
-    case    kUnfolded: status="unfolded"   ;break;
-    case         kCoG: status="CoGed"      ;break;
-    case       kEmpty: status="empty"      ;break;
-  }
-  Int_t iNdigs=0;  if(fDigits) iNdigs=fDigits->GetEntriesFast();
-    
-  Printf("cfm=%10i, cs=%2i, Size=%2i Maxima=%2i, Shape=%5i, pos=(%7.3f,%7.3f) Q=%6i, %s",
-            fCFM,fChamber,Size(),Nlocmax(),fShape,fX,fY,fQdc,status,iNdigs);
-  for(Int_t i=0;i<iNdigs;i++) Digit(i)->Print();    
-}//Print()
+// Calculates naive cluster position as a center of gravity of its digits.
+// Arguments: none 
+//   Returns: shape of the cluster i.e. the box which fully contains the cluster      
+  if(fDigs==0) return;                                  //no digits in this cluster
+  fX=fY=0;                                              //set cluster position to (0,0) to start to collect contributions
+  for(Int_t iDig=0;iDig<fDigs->GetEntriesFast();iDig++){//digits loop
+    AliRICHDigit *pDig=(AliRICHDigit*)fDigs->At(iDig);  //get pointer to next digit
+    TVector pad=pDig->Pad(); Double_t q=pDig->Qdc();    //get pad adn QDC of this digit 
+    TVector2 x2=AliRICHParam::Pad2Loc(pad);             //calculate center of the pad in LORS
+    fX += x2.X()*q;fY +=x2.Y()*q;                       //sum up digit centers weighted by QDC
+  }//digits loop
+  fX/=fQdc;fY/=fQdc;                                    //final center of gravity
 
+  TVector2 center = AliRICHParam::Pad2Loc(AliRICHParam::Loc2Pad(TVector2(fX,fY)));//center of the pad containing calculated cluster position
+  fX += AliRICHParam::CogCorr(fX-center.X());                                     //correct cluster position for sinoid
 
+  fStatus=kCoG;
+}//CoG()
 //__________________________________________________________________________________________________
-TMinuit* AliRICHCluster::Solve()
-{
-//At this point, cluster contains a list of digits, cluster charge is precalculated as a sum of digits charges (in AddDigit()),
-//position is preset to (-1,-1) (in ctor), status is preset to kFormed in (AddDigit()), chamber-sector info is preseted to actual value (in AddDigit())
-//Here we decide what to do with this cluster: unfold or just calculate center of gravity
-//Arguments: none
-//  Returns: pointer to fitter or 0 if no unfolding decided 
-  TMinuit *pMinuit=0;
-  if(Size()>=2 && AliRICHParam::IsResolveClusters())
-    pMinuit=Unfold();
-  else
-    CoG(0);
-  return pMinuit;
-}//Solve()
-//__________________________________________________________________________________________________
-void AliRICHCluster::FitFunc(Int_t &iNpars, Double_t *, Double_t &chi2, Double_t *aPar, Int_t )
+void AliRICHCluster::FitFunc(Int_t &iNpars, Double_t *, Double_t &chi2, Double_t *par, Int_t )
 {
-//Cluster fit function 
-//par[0]=x par[1]=y par[2]=q for the first Mathieson shape
-//par[3]=x par[4]=y par[5]=q for the second Mathieson shape and so on up to iNpars/3 Mathieson shapes
-//We need to calculate Qpad - Qpadmath summup over all pads of the cluster
-//Here Qpad is a actual charge of the pad, Qpadmath is calculated charge of the pad induced by all Mathiesons
-//Arguments: iNpars - number of parameters which is number of local maxima of cluster * 3
-//           chi2   - function result to be minimised 
-//           aPar   - parametrs array of size iNpars            
-//  Returns: none  
+// Cluster fit function 
+// par[0]=x par[1]=y par[2]=q for the first Mathieson shape
+// par[3]=x par[4]=y par[5]=q for the second Mathieson shape and so on up to iNpars/3 Mathieson shapes
+// We need to calculate QpadExp - QpadMathieson summup over all pads of the cluster
+// Here QpadExp is a actual charge of the pad, QpadMathieson is calculated charge of the pad induced by all Mathiesons
+// Arguments: iNpars - number of parameters which is number of local maxima of cluster * 3
+//            chi2   - function result to be minimised 
+//            par   - parameters array of size iNpars            
+//   Returns: none  
   AliRICHCluster *pClu=(AliRICHCluster*)gMinuit->GetObjectFit();
   Int_t iNmathiesons = iNpars/3;
     
   TVector2 curMathiesonPos;
   chi2 = 0;
-  for(Int_t i=0;i<pClu->Size();i++){//digits loop
-    TVector    pad     = pClu->Digit(i)->Pad();
-    Double_t dQpad     = pClu->Digit(i)->Qdc();
-    Double_t dQpadmath = 0;
-    for(Int_t j=0;j<iNmathiesons;j++){//all Mathiesons may contribute to this pad
-      curMathiesonPos.Set(aPar[3*j],aPar[3*j+1]);//get current position for current Mathieson
-      dQpadmath += aPar[3*j+2]*AliRICHParam::FracQdc(curMathiesonPos,pad);//sums up contributions to the current pad from all Mathiesons
+  for(Int_t i=0;i<pClu->Size();i++){                                            //loop on all pads of the cluster
+    TVector    pad          = pClu->Dig(i)->Pad();
+    Double_t dQpadExp       = pClu->Dig(i)->Qdc();
+    Double_t dQpadMathieson = 0;
+    for(Int_t j=0;j<iNmathiesons;j++){                                          //Mathiesons loop as all of them may contribute to this pad
+      curMathiesonPos.Set(par[3*j],par[3*j+1]);                                 //get position of current Mathieson
+      dQpadMathieson += par[3*j+2]*AliRICHParam::FracQdc(curMathiesonPos,pad);  //sums up contributions to the current pad from all Mathiesons
     }
-    chi2 += TMath::Power((dQpadmath-dQpad),2);
-  }//digits loop     
-}//RichClusterFitFunction()
+    chi2 += TMath::Power((dQpadMathieson-dQpadExp),2);                          //
+  }                                                                             //loop on all pads of the cluster     
+}//FitFunction()
 //__________________________________________________________________________________________________
-TMinuit* AliRICHCluster::Unfold()
+void AliRICHCluster::Print(Option_t* opt)const
 {
-//This methode is invoked from Solve() when decided to unfold this cluster
-//Method first finds number of local maxima and if it's more then one tries to unfold this cluster into local maxima number of clusters
-//Arguments: none
-//  Returns: pointer to fitter for retriving parameters
+//Print current cluster  
+  const char *status=0;
+  switch(fStatus){
+    case      kFormed: status="formed"     ;break;
+    case    kUnfolded: status="unfolded"   ;break;
+    case         kCoG: status="coged"      ;break;
+    case       kEmpty: status="empty"      ;break;
+  }
+  Int_t iNdigs=0;  if(fDigs) iNdigs=fDigs->GetEntriesFast();
     
-  TMinuit *pMinuit = new TMinuit(15); //init MINUIT with max 15 parameters (maxim 5 mathiesons, 3 params per matheson )
-  pMinuit->SetObjectFit((TObject*)this);
-  pMinuit->SetFCN(AliRICHCluster::FitFunc);//set fit function
-  Double_t aArg=-1,parStart,parStep,parLow,parHigh; Int_t iErrFlg; //tmp for MINUIT parameters definitions
-  pMinuit->mnexcm("SET PRI" ,&aArg,1,iErrFlg); //suspend all printout from TMinuit 
-  
+  Printf("%s cs=%2i, Size=%2i (x=%7.3f cm,y=%7.3f cm,Q=%4i qdc), %s",
+         opt,fCham,iNdigs,fX,fY,fQdc,status);
+  for(Int_t i=0;i<iNdigs;i++) Dig(i)->Print();    
+}//Print()
+//__________________________________________________________________________________________________
+Int_t AliRICHCluster::Solve(TClonesArray *pCluLst,Bool_t isTryUnfold)
+{
+//This methode is invoked when the cluster is formed to solve it. Solve the cluster means to try to unfold the cluster
+//into the local maxima number of clusters. This methode is invoked by AliRICHRconstructor::Dig2Clu() on cluster by cluster basis.  
+//At this point, cluster contains a list of digits, cluster charge and size is precalculated in AddDigit(), position is preset to (-1,-1) in ctor,
+//status is preset to kFormed in AddDigit(), chamber-sector info is preseted to actual values in AddDigit()
+//Method first finds number of local maxima and if it's more then one tries to unfold this cluster into local maxima number of clusters
+//Arguments: pCluLst     - cluster list pointer where to add new cluster(s)
+//           isTryUnfold - flag to switch on/off unfolding   
+//  Returns: number of local maxima of original cluster
+
+//Phase 0. Initialise TMinuit  
+  const Int_t kMaxLocMax=6;                                                            //max allowed number of loc max for fitting
+  TMinuit *pMinuit = new TMinuit(3*kMaxLocMax);                                        //init MINUIT with this number of parameters (3 params per mathieson)
+  pMinuit->SetObjectFit((TObject*)this);  pMinuit->SetFCN(AliRICHCluster::FitFunc);    //set fit function
+  Double_t aArg=-1,parStart,parStep,parLow,parHigh;     Int_t iErrFlg;                 //tmp vars for TMinuit
+  pMinuit->mnexcm("SET PRI",&aArg,1,iErrFlg);                                          //suspend all printout from TMinuit 
+  pMinuit->mnexcm("SET NOW",&aArg,0,iErrFlg);                                          //suspend all warning printout from TMinuit
+//Phase 1. Find number of local maxima. Strategy is to check if the current pad has QDC more then all neigbours   
   Int_t iLocMaxCnt=0;
-//Strategy is to check if the current pad has QDC more then all neigbours 
-  for(Int_t iDig1=0;iDig1<Size();iDig1++) {//first digits loop
-    AliRICHDigit *pDig1 = Digit(iDig1);//take the current digit
-    Int_t iHowManyMoreCnt = 0;//counts how many neighbouring pads has QDC more then current one
-    for(Int_t iDig2=0;iDig2<Size();iDig2++) {//loop on all digits again
-      AliRICHDigit *pDig2 = Digit(iDig2);
-      if(iDig1==iDig2) continue;             //no need to compare 
+  for(Int_t iDig1=0;iDig1<Size();iDig1++) {                                             //first digits loop
+    AliRICHDigit *pDig1 = Dig(iDig1);                                                   //take next digit
+    Int_t iHowManyMoreCnt = 0;                                                          //counts how many neighbouring pads has QDC more then current one
+    for(Int_t iDig2=0;iDig2<Size();iDig2++) {                                           //loop on all digits again
+      AliRICHDigit *pDig2 = Dig(iDig2);                                                 //take second digit to compare with the first one
+      if(iDig1==iDig2) continue;                                                        //the same digit, no need to compare 
       Int_t dist = TMath::Sign(Int_t(pDig1->PadX()-pDig2->PadX()),1)+TMath::Sign(Int_t(pDig1->PadY()-pDig2->PadY()),1);//distance between pads
-      if(dist==1)//means pads are neighbours
-         if(pDig2->Qdc()>=pDig1->Qdc()) iHowManyMoreCnt++;//count number of pads with Q more then Q of current pad
+      if(dist==1)                                                                       //means dig2 is a neighbour of dig1
+         if(pDig2->Qdc()>=pDig1->Qdc()) iHowManyMoreCnt++;                              //count number of pads with Q more then Q of current pad
     }//second digits loop
-    if(iHowManyMoreCnt==0&&iLocMaxCnt<6){//this pad has Q more then any neighbour so it's local maximum
-        TVector2 x2=AliRICHParam::Pad2Loc(pDig1->Pad());//take pad center position and use it as parameter for current Mathienson shape
+    if(iHowManyMoreCnt==0&&iLocMaxCnt<=kMaxLocMax){                                     //this pad has Q more then any neighbour so it's local maximum
+        TVector2 x2=AliRICHParam::Pad2Loc(pDig1->Pad());                                //take pad center position and use it as parameter for current Mathienson shape
         pMinuit->mnparm(3*iLocMaxCnt  ,Form("x%i",iLocMaxCnt),parStart=x2.X()      ,parStep=0.01,parLow=0,parHigh=0,iErrFlg);
         pMinuit->mnparm(3*iLocMaxCnt+1,Form("y%i",iLocMaxCnt),parStart=x2.Y()      ,parStep=0.01,parLow=0,parHigh=0,iErrFlg);
-        pMinuit->mnparm(3*iLocMaxCnt+2,Form("q%i",iLocMaxCnt),parStart=pDig1->Qdc(),parStep=0.01,parLow=0,parHigh=0,iErrFlg);//
+        pMinuit->mnparm(3*iLocMaxCnt+2,Form("q%i",iLocMaxCnt),parStart=pDig1->Qdc(),parStep=0.01,parLow=0,parHigh=0,iErrFlg);
         iLocMaxCnt++;
     }//if this pad is local maximum
   }//first digits loop
-  
-  fSize+=iLocMaxCnt;
-  if(iLocMaxCnt>0&&iLocMaxCnt<6){ //resonable number of local maxima to fit
-    Double_t aArg=0;
-    pMinuit->mnexcm("MIGRAD",&aArg,0,iErrFlg);//start fitting
-    fStatus=kUnfolded;
-  }else{
-    delete pMinuit;
-    pMinuit=0;
-    CoG(0);
+//Phase 2. Fit loc max number of Mathiesons or add this current cluster to the list
+  Int_t iCluCnt=pCluLst->GetEntriesFast();                                          //get current number of clusters already stored in the list by previous operations
+  if(isTryUnfold==kTRUE && iLocMaxCnt<=kMaxLocMax){                                        //resonable number of local maxima to fit and user requested it
+    pMinuit->mnexcm("MIGRAD" ,&aArg,0,iErrFlg);                                     //start fitting
+    Double_t fitX,fitY,fitQ,d1,d2,d3; TString sName;                                //vars to get results from TMinuit
+    for(Int_t i=0;i<iLocMaxCnt;i++){//local maxima loop
+      pMinuit->mnpout(3*i   ,sName,  fitX, d1 , d2, d3, iErrFlg);
+      pMinuit->mnpout(3*i+1 ,sName,  fitY, d1 , d2, d3, iErrFlg);
+      pMinuit->mnpout(3*i+2 ,sName,  fitQ, d1 , d2, d3, iErrFlg);
+      new ((*pCluLst)[iCluCnt++]) AliRICHCluster(C(),fitX,fitY,(Int_t)fitQ);        //add new unfolded clusters
+    }//local maxima loop
+  }else{//do not unfold since number of loc max is unresonably high or user's baned unfolding 
+    CoG();
+    new ((*pCluLst)[iCluCnt++]) AliRICHCluster(*this);  //add this raw cluster 
   }
-  return pMinuit;  
-}//Unfold()
-//__________________________________________________________________________________________________
-void AliRICHCluster::CoG(Int_t nLocals)
-{
-//Calculates naive cluster position as a center of gravity of its digits.
-//Also determines the box fully contaning this cluster
-//Arguments:     
-  Float_t xmin=999,ymin=999,xmax=0,ymax=0;
-  fX=fY=0;
-  for(Int_t iDig=0;iDig<Size();iDig++) {
-    AliRICHDigit *pDig=Digit(iDig);
-    TVector pad=pDig->Pad(); Double_t q=pDig->Qdc();
-    TVector2 x2=AliRICHParam::Pad2Loc(pad);
-    fX += x2.X()*q;fY +=x2.Y()*q;
-    if(pad[0]<xmin)xmin=pad[0];if(pad[0]>xmax)xmax=pad[0];if(pad[1]<ymin)ymin=pad[1];if(pad[1]>ymax)ymax=pad[1];
-   }
-   fX/=fQdc;fY/=fQdc;//Center of Gravity
-
-   TVector2 center = AliRICHParam::Pad2Loc(AliRICHParam::Loc2Pad(TVector2(fX,fY)));
-   fX += AliRICHParam::CogCorr(fX-center.X());//correct cluster position for sinoid
-
-   fShape=Int_t(100*(xmax-xmin+1)+ymax-ymin+1);//find box containing cluster
-   fSize+=nLocals;
-   fStatus=kCoG;
-}//CoG()
+  delete pMinuit;
+  return iLocMaxCnt;
+}//Solve()
 //__________________________________________________________________________________________________
-void AliRICHCluster::Test(const TVector2 &hitX2,Double_t dEloss)
+void AliRICHCluster::Test(Double_t x,Double_t y,Double_t e,Bool_t isTryUnfold)
 {
 //This is to test all cluster functionality
-//Method uses AddDigit() to add a predifined pad structure and then calls Solve   
-  Int_t iQtot=AliRICHParam::TotQdc(hitX2,dEloss);
+//Uses AddDigit() to add a predifined pad structure and then calls Solve   
+  TVector2 hitX2(x,y);
+  Int_t iQtot=AliRICHParam::TotQdc(hitX2,e);
   if(iQtot==0){
     Printf("Provided hit position out of sensitive area");
     return;
   }
   TVector area=AliRICHParam::Loc2Area(hitX2);
   TVector pad(2);
+  AliRICHCluster clu;
   for(pad[1]=area[1];pad[1]<=area[3];pad[1]++){//affected pads loop first y
     for(pad[0]=area[0];pad[0]<=area[2];pad[0]++){//then x               
       Double_t dQpad=iQtot*AliRICHParam::FracQdc(hitX2,pad);//charge fraction from Mathieson centered at x to pad
-      AddDigit(new AliRICHDigit(3,(Int_t)pad[0],(Int_t)pad[1],dQpad));
+      clu.DigAdd(new AliRICHDigit(3,(Int_t)pad[0],(Int_t)pad[1],dQpad));
     }//affected pads loop 
   }
-  TMinuit *pMinuit=Solve();
-  Print();
-  Printf("Initial hit (%.2f,%.2f) Qtot=%i Eloss=%.2f",hitX2.X(),hitX2.Y(),iQtot,dEloss);
-  Double_t d1,d2,d3; Int_t iErrFlg;TString sName; //tmp vars for TMinuit
-  Double_t x,y,q;
-  for(Int_t i=0;i<Nlocmax();i++){//retrive fitting results
-    pMinuit->mnpout(3*i   ,sName,  x, d1 , d2, d3, iErrFlg);
-    pMinuit->mnpout(3*i+1 ,sName,  y, d1 , d2, d3, iErrFlg);
-    pMinuit->mnpout(3*i+2 ,sName,  q, d1 , d2, d3, iErrFlg);
-  }
-  Printf(" Fitted hit (%.2f,%.2f) Qfit=%.0f",x,y,q);
-  delete pMinuit; pMinuit=0;  Reset();
+     Printf("Initial hit    :  (%.2f,%.2f) Qtot=%i E=%.2f eV",hitX2.X(),hitX2.Y(),iQtot,e*1e9);
+  clu.Print("Initial cluster:");
+  TClonesArray *pCluLst=new TClonesArray("AliRICHCluster",1);
+  clu.Solve(pCluLst,isTryUnfold);  
+  ((AliRICHCluster *)pCluLst->At(0))->Print("Solved cluster:");
+  
+  delete pCluLst; clu.Reset();
 }//Test()
+//__________________________________________________________________________________________________
+void AliRICHCluster::Test()
+{
+//Test cluster builder by a number of predefined digit patterns
+//Arguments: none
+//  Returns: none
+  AliRICHCluster clu; Int_t ch,padx,pady,qdc; TClonesArray *pCluLst=new TClonesArray("AliRICHCluster",10);
+  Printf("2 digits vertical cluster");
+  clu.DigAdd(new AliRICHDigit(ch=1,padx=3,pady=3,qdc=101));
+  clu.DigAdd(new AliRICHDigit(ch=1,padx=3,pady=4,qdc=202)); clu.Print("Formed cluster:");
+  clu.Solve(pCluLst,kTRUE);  pCluLst->Print();
+  delete pCluLst;
+}
index 74117eb..b5b6292 100644 (file)
@@ -3,90 +3,54 @@
 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
  * See cxx source for full Copyright notice                               */
 
-#include <TObject.h>         //base class
-#include <TVector2.h>        //DistTo
-#include "AliRICHDigit.h"
-class TMinuit;
+#include "AliRICHParam.h"    //DigAdd(), Dig()
 
 class AliRICHCluster :public TObject
 {
 public:
-  enum EClusterStatus {kFormed,kCoG,kUnfolded,kEmpty}; 
-  AliRICHCluster()                                               :TObject(),fCFM(-1),fSize(-1),fShape(-1),fQdc(-1),fChamber(-1),fX(-1),fY(-1),fStatus(kEmpty),fDigits(0) {}  //default ctor  
-  AliRICHCluster(Int_t cs,Double_t x,Double_t y,Int_t q,Int_t sm):TObject(),fCFM(-1),fSize(sm),fShape(-1),fQdc(q ),fChamber(cs),fX(x ),fY(y ),fStatus(kEmpty),fDigits(0) {}  //default ctor  
-  virtual          ~AliRICHCluster()                 {}                                                  //dtor
-                   // AliRICHcluster(const AliRICHcluster& clus):TObject(clus)                                                         {}  //copy ctor 
-  AliRICHCluster&  operator=(const AliRICHCluster&)                 {return *this;}                                                     //copy operator
-                   
-         void      Print(Option_t *option="")const;                                                       //
-  
-  
-         void       Reset()                          {DeleteDigits();fCFM=fSize=fShape=fQdc=fChamber=-1;fX=fY=-1;fStatus=kEmpty;} //cleans the cluster
-         void       DeleteDigits()                   {if(fDigits) {delete fDigits;} fDigits=0;}           //deletes the list of digits  
-         Int_t      Nlocmax()                   const{return fSize-10000*(fSize/10000);}                //number of local maximums
-         Int_t      Size()                      const{return fSize/10000;}                              //number of digits in cluster
-         Int_t      Fsize()                     const{return fSize;}                                    //
-         Int_t      Shape()                     const{return fShape;}                                   //cluster shape rectangulare
-         Int_t      C()                         const{return fChamber/10;}                              //chamber number
-         Int_t      S()                         const{return fChamber-(fChamber/10)*10;}                //sector number
-         Int_t      Fchamber()                  const{return fChamber;}                                 //
-         Int_t      Q()                         const{return fQdc;}                                     //cluster charge in QDC channels 
-         Double_t   X()                         const{return fX;}                                       //cluster x position in LRS
-         Double_t   Y()                         const{return fY;}                                       //cluster y position in LRS 
-         Int_t      Status()                    const{return fStatus;}                                  //
-         void       SetStatus(Int_t status)         {fStatus=status;}                                     //
-         Int_t      Nmips()                     const{return fCFM-1000000*Ncerenkovs()-1000*Nfeedbacks();} //
-         Int_t      Ncerenkovs()                const{return fCFM/1000000;}                                //
-         Int_t      Nfeedbacks()                const{return (fCFM-1000000*Ncerenkovs())/1000;}            //
-         Bool_t     IsPureMip()                 const{return fCFM<1000;}                                   //
-         Bool_t     IsPureCerenkov()            const{return Nmips()==0&&Nfeedbacks()==0;}                 //
-         Bool_t     IsPureFeedback()            const{return Nmips()==0&&Ncerenkovs()==0;}                 //
-         Bool_t     IsSingleMip()               const{return Nmips()==1&&Ncerenkovs()==0&&Nfeedbacks()==0;}  //
-         Bool_t     IsSingleCerenkov()          const{return Nmips()==0&&Ncerenkovs()==1&&Nfeedbacks()==0;}  //
-         Bool_t     IsSingleFeedback()          const{return Nmips()==0&&Ncerenkovs()==0&&Nfeedbacks()==1;}  //
-         Bool_t     IsMip()                     const{return Nmips()!=0;}                                  //
-         Bool_t     IsCerenkov()                const{return Ncerenkovs()!=0;}                             //
-         Bool_t     IsFeedback()                const{return Nfeedbacks()!=0;}                             //
-         Int_t      CombiPid()                  const{return fCFM;}                                        //
-         void       CFM(Int_t c,Int_t f,Int_t m)     {fCFM=1000000*c+1000*f+m;}                            //cluster contributors
-         TObjArray*    Digits()                    const{return fDigits;}                                     //  
-         
-  inline void          AddDigit(AliRICHDigit *pDig);                                                          //add new digit ot the cluster
-         AliRICHDigit* Digit  (Int_t i                      )const{return (AliRICHDigit*)fDigits->At(i); }//get pointer to i-th digit without existence check 
-         TMinuit*      Solve  (                             );                                            //calculates cluster position
-         TMinuit*      Unfold (                             );                                            //decompose cluster n. loc max clusters
-         void          Set    (Double_t x,Double_t y,Int_t q)     {fX=x;fY=y,fQdc=q;                     }//set some cluster properties
-  static void          FitFunc(Int_t &iNpars, Double_t *, Double_t &chi2, Double_t *aPar, Int_t);         //fit function to be used by MINUIT
-          
-         void      CoG(Int_t iNlocmax);                                                                   //calculates center of gravity
-          void      Fill(AliRICHCluster *pRaw,Double_t x,Double_t y,Double_t q,Int_t cfm)              //form new resolved cluster from raw one
-                    {fCFM=cfm;fChamber=pRaw->Fchamber();fSize=pRaw->Fsize();fQdc=(Int_t)(q*pRaw->Q());fX=x;fY=y;fStatus=kUnfolded;} 
-         Double_t   DistTo(TVector2 x)          const{return TMath::Sqrt((x.X()-fX)*(x.X()-fX)+(x.Y()-fY)*(x.Y()-fY));} //distance to given point 
-         Double_t   DistX(TVector2 x)           const{return (x.X()-fX);} //distance in x to given point 
-         Double_t   DistY(TVector2 x)           const{return (x.Y()-fY);} //distance to given point 
-         void       Test(const TVector2 &x,Double_t dEloss=0);            //test cluster fuctionality by provided hit with energy in eV
+  enum EClusterStatus {kFormed,kCoG,kUnfolded,kEmpty=-1}; 
+                       AliRICHCluster(                                     ):TObject(),fQdc(-1),fCham(-1),fX(-1),fY(-1),fStatus(kEmpty   ),fDigs(0) {}
+                       AliRICHCluster(Int_t c,Double_t x,Double_t y,Int_t q):TObject(),fQdc(q ),fCham(c) ,fX(x ),fY(y ),fStatus(kUnfolded),fDigs(0) {}
+  virtual             ~AliRICHCluster(                                     )                                                                        {if(fDigs) delete fDigs;}
+//framework part                   
+         void          Print  (Option_t *opt=""                                  )const;                  //overloaded TObject::Print() to print cluster info
+  static void          FitFunc(Int_t &, Double_t *, Double_t &, Double_t *, Int_t);                       //fit function to be used by MINUIT
+//private part  
+         void          CoG      (                                         );                                                      //calculates center of gravity
+         Int_t         C        (                                         )const{return fCham;                                  } //chamber number
+  inline void          DigAdd   (AliRICHDigit *pDig                       );                                                      //add new digit ot the cluster
+         void          DigDel   (                                         )     {if(fDigs) {delete fDigs;} fDigs=0;             } //deletes the list of digits  
+         void          DistXY   (const TVector2 &p,Double_t &x,Double_t &y)const{ x=p.X()-fX; y=p.Y()-fY;                       } //distance in x to given point 
+         AliRICHDigit* Dig      (Int_t i                                  )const{return (AliRICHDigit*)fDigs->At(i);            } //pointer to i-th digit
+         TObjArray*    Digits   (                                         )const{return fDigs;                                  } //list of digits  
+         TVector3      Lors2Mars()                            const{return AliRICHParam::Instance()->Lors2Mars(fCham,fX,fY);     } //cluster position in MARS
+         void          Reset    (                                         )     {DigDel();fQdc=fCham=-1;fX=fY=-1;fStatus=kEmpty;} //cleans the cluster
+         Int_t         Solve    (TClonesArray *pCluLst,Bool_t isUnfold    );                                                      //solve cluster: MINUIT fit or CoG
+         Int_t         Size     (                                         )const{return (fDigs)?fDigs->GetEntriesFast():0;      } //number of pads in cluster
+         Int_t         Q        (                                         )const{return fQdc;                                   } //cluster charge in QDC channels 
+         Double_t      X        (                                         )const{return fX;                                     } //cluster x position in LRS
+         Double_t      Y        (                                         )const{return fY;                                     } //cluster y position in LRS 
+//test part         
+  static void          Test     (Double_t x,Double_t y,Double_t e=0,Bool_t isUnfold=kTRUE);                                        //test by hit (x [cm] , y [cm] , e [GeV])
+  static void          Test     (                                                        );                                        //test by predifined patterns
 protected:
-  Int_t         fCFM;         //1000000*Ncerenkovs+1000*Nfeedbacks+Nmips  
-  Int_t         fSize;        //10000*(N digits) + N maxima     
-  Int_t         fShape;       //100*xdim+ydim box containing the cluster
   Int_t         fQdc;         //QDC value
-  Int_t         fChamber;     //10*chamber number+sector number 
-  Double_t      fX;           //local x postion 
-  Double_t      fY;           //local y postion  
+  Int_t         fCham;        //10*chamber number+sector number 
+  Double_t      fX;           //local x postion, cm 
+  Double_t      fY;           //local y postion, cm  
   Int_t         fStatus;      //flag to mark the quality of the cluster   
-  TObjArray    *fDigits;      //! list of digits forming this cluster
-  ClassDef(AliRICHCluster,2)  //RICH cluster class       
+  TObjArray    *fDigs;        //! list of digits forming this cluster
+  ClassDef(AliRICHCluster,3)  //RICH cluster class       
 };//class AliRICHCluster
-//__________________________________________________________________________________________________
-void AliRICHCluster::AddDigit(AliRICHDigit *pDig)
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHCluster::DigAdd(AliRICHDigit *pDig)
 {
 // Adds a given digit to the list of digits belonging to this cluster    
-  if(!fDigits) {fQdc=fSize=0;fDigits = new TObjArray;}
-  fDigits->Add(pDig);
+  if(!fDigs) {fQdc=0;fDigs = new TObjArray;}
+  fDigs->Add(pDig);
   fQdc+=(Int_t)pDig->Qdc(); 
-  fChamber=10*pDig->Chamber()+pDig->Sector();
-  fSize+=10000;
+  fCham=pDig->C();
   fStatus=kFormed;
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 #endif
diff --git a/RICH/AliRICHClusterFinder.cxx b/RICH/AliRICHClusterFinder.cxx
deleted file mode 100644 (file)
index 26e3004..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/**************************************************************************
- * 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.                  *
- **************************************************************************/
-
-
-#include "AliRICHClusterFinder.h"
-#include "AliRICHMap.h"
-#include <TMinuit.h>
-#include <TParticle.h>
-#include <TVector3.h>
-#include <AliLoader.h>
-#include <AliStack.h>
-#include <AliRun.h>
-#include "AliRICHParam.h"
-
-void RICHMinMathieson(Int_t &npar, Double_t *gin, Double_t &chi2, Double_t *par, Int_t iflag);
-
-ClassImp(AliRICHClusterFinder)
-//__________________________________________________________________________________________________
-AliRICHClusterFinder::AliRICHClusterFinder(AliRunLoader *pRunLoader)   
-{//main ctor
-  fRICH = (AliRICH*) pRunLoader->GetAliRun()->GetDetector("RICH");
-
-  AliDebug(1,"main ctor Start.");
-  
-  fDigitMap = 0;
-  fRawCluster.Reset();
-  fResolvedCluster.Reset();
-  AliDebug(1,"main ctor Stop.");
-}//main ctor
-//__________________________________________________________________________________________________
-void AliRICHClusterFinder::Exec(const Option_t *)
-{
-//Main method of cluster finder. Loops on  events and chambers, everything else is done in FindClusters()  
-  AliDebug(1,"Exec Start.");
-    
-  R()->GetLoader()                ->LoadDigits();   
-//  R()->GetLoader()->GetRunLoader()->LoadHeader(); 
-  if(!R()->GetLoader()->GetRunLoader()->TreeK()) R()->GetLoader()->GetRunLoader()->LoadKinematics();
-
-  for(Int_t iEventN=0;iEventN<gAlice->GetEventsPerRun();iEventN++){//events loop
-    AliDebug(1,Form("Processing event %i...",iEventN));
-    R()->GetLoader()->GetRunLoader()->GetEvent(iEventN);
-    
-    R()->GetLoader()->MakeTree("R");  R()->MakeBranch("R");
-    R()->DigitsReset();               R()->ClustersReset();
-    
-    R()->GetLoader()->TreeD()->GetEntry(0);
-    for(Int_t iChamber=1;iChamber<=kNchambers;iChamber++){//chambers loop
-      FindClusters(iChamber);
-    }//chambers loop
-    R()->GetLoader()->TreeR()->Fill();  R()->GetLoader()->WriteRecPoints("OVERWRITE");//write out clusters for current event
-  }//events loop  
-  
-  R()->DigitsReset();//reset and unload everything
-  R()->ClustersReset();
-  R()->GetLoader()                ->UnloadDigits(); 
-  R()->GetLoader()                ->UnloadRecPoints();  
-//  R()->GetLoader()->GetRunLoader()->UnloadHeader();
-  R()->GetLoader()->GetRunLoader()->UnloadKinematics();
-
-  AliDebug(1,"Stop.");      
-}//Exec()
-//__________________________________________________________________________________________________
-void AliRICHClusterFinder::FindClusters(Int_t iChamber)
-{
-//Loops on digits for a given chamber, forms raw clusters, then tries to resolve them if requested
-  Int_t iNdigits=R()->Digits(iChamber)->GetEntriesFast();
-  AliDebug(1,Form("Start for chamber %i with %i digits.",iChamber,iNdigits));  
-  
-  if(iNdigits==0)return;//no digits for a given chamber, nothing to do
-
-  fDigitMap=new AliRICHMap(R()->Digits(iChamber));//create digit map for the given chamber
-
-  for(Int_t iDigN=0;iDigN<iNdigits;iDigN++){//digits loop for a given chamber    
-    AliRICHDigit *dig=(AliRICHDigit*)R()->Digits(iChamber)->At(iDigN);
-    Int_t i=dig->PadX();   Int_t j=dig->PadY();
-    if(fDigitMap->TestHit(i,j)==kUsed) continue;//this digit is already taken, go after next digit
-       
-    FormRawCluster(i,j);//form raw cluster starting from (i,j) pad 
-    AliDebug(1,"After FormRawCluster:");ToAliDebug(1,fRawCluster.Print());  
-    FindLocalMaxima();  //find number of local maxima and initial center of gravity
-    AliDebug(1,"After FindLocalMaxima:");ToAliDebug(1,fRawCluster.Print());  
-    
-    if(AliRICHParam::IsResolveClusters()&&fNlocals<=6&&fRawCluster.Size()>1){
-      FitCoG(); //serialization of resolved clusters will happen inside
-    }else{//cluster size=1 or resolving is switched off
-      WriteRawCluster();//simply output the formed raw cluster without deconvolution
-    }
-    fRawCluster.Reset(); fResolvedCluster.Reset();
-  }//digits loop for a given chamber
-
-  delete fDigitMap;
-  
-  AliDebug(1,"Stop.");  
-}//FindClusters()
-//__________________________________________________________________________________________________
-void AliRICHClusterFinder::FindClusterContribs(AliRICHCluster *pCluster)
-{
-//Finds cerenkov-feedback-mip mixture for a given cluster
-  AliDebug(1,"Start.");ToAliDebug(1,pCluster->Print());
-
-//  R()->GetLoader()->GetRunLoader()->LoadHeader(); //...message from AliRunLoader...hopefully will disappear in future...
-  // sometimes no stack found if the above line is commented out!!
-  AliStack *pStack = R()->GetLoader()->GetRunLoader()->Stack();
-  if(!pStack)
-  {AliInfo("No Stack found!!! No contrib to cluster found.");return;}
-  
-  TObjArray *pDigits = pCluster->Digits();
-  if(!pDigits) return; //??????????
-  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;iDigN<pCluster->Size();iDigN++) {//loop on digits of a given cluster
-    contribs[3*iDigN]  =((AliRICHDigit*)pDigits->At(iDigN))->GetTrack(0);
-    if (contribs[3*iDigN] >= 10000000) contribs[3*iDigN] = 0;
-    contribs[3*iDigN+1]=((AliRICHDigit*)pDigits->At(iDigN))->GetTrack(1);
-    if (contribs[3*iDigN+1] >= 10000000) contribs[3*iDigN+1] = 0;
-    contribs[3*iDigN+2]=((AliRICHDigit*)pDigits->At(iDigN))->GetTrack(2);
-    if (contribs[3*iDigN+2] >= 10000000) contribs[3*iDigN+2] = 0;
-  }//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 tids
-    AliDebug(1,Form("%4i for digit n. %4i",contribs[pindex[iDigN]],iDigN));
-    if(contribs[pindex[iDigN]]!=contribs[pindex[iDigN+1]]) {
-      Int_t thecontrib = contribs[pindex[iDigN]];
-      if (thecontrib>=pStack->GetNtrack()) continue;//PH this should not happen 
-      TParticle* particle = pStack->Particle(thecontrib);
-      if (!particle) continue;//PH this should not happen
-      Int_t code   = particle->GetPdgCode();
-      Double_t charge = 0;
-      if(particle->GetPDG()) charge=particle->GetPDG()->Charge();
-      AliDebug(1,Form(" charge of particle %f",charge));
-
-      if(code==50000050) iNckovs++;
-      if(code==50000051) iNfeeds++;
-      if(charge!=0) iNmips++;
-    }
-  }//loop on digits to sort Tid
-  
-  if (contribs[pindex[3*pCluster->Size()-1]]!=-1) {
-     Int_t thecontrib = contribs[pindex[3*pCluster->Size()-1]];
-     if (thecontrib<pStack->GetNtrack()){
-       //PH the opposite should not happen 
-
-       TParticle* particle = pStack->Particle(thecontrib);
-       if (particle) {
-        //PH the opposite should not happen
-        Int_t code   = particle->GetPdgCode();
-        Double_t charge = 0;
-        if(particle->GetPDG()) charge=particle->GetPDG()->Charge();
-        AliDebug(1,Form(" charge of particle %f",charge));
-        if(code==50000050) iNckovs++;
-        if(code==50000051) iNfeeds++;
-        if(charge!=0) iNmips++;
-       }
-     }
-  }
-    
-  pCluster->CFM(iNckovs,iNfeeds,iNmips);
-//  
-  delete [] pindex; 
-  ToAliDebug(1,pCluster->Print());
-  AliDebug(1,"Stop.");
-}//FindClusterContribs()
-//__________________________________________________________________________________________________
-void  AliRICHClusterFinder::FormRawCluster(Int_t i, Int_t j)
-{
-//Builds the raw cluster (before deconvolution). Starts from the first pad (i,j) then calls itself recursevly  for all neighbours.
-  AliDebug(1,Form("Start with digit(%i,%i) Q=%f",i,j,((AliRICHDigit*)fDigitMap->GetHit(i,j))->Qdc()));
-  
-  fRawCluster.AddDigit((AliRICHDigit*) fDigitMap->GetHit(i,j));//take this pad in cluster
-  fDigitMap->FlagHit(i,j);//flag this pad as taken  
-
-  Int_t listX[4], listY[4];    //  Now look recursively for all neighbours
-  for (Int_t iNei=0;iNei<R()->P()->PadNeighbours(i,j,listX,listY);iNei++)
-    if(fDigitMap->TestHit(listX[iNei],listY[iNei])==kUnused) FormRawCluster(listX[iNei],listY[iNei]);    
-}//FormRawCluster()
-//__________________________________________________________________________________________________
-void AliRICHClusterFinder::FindLocalMaxima()
-{
-//find number of local maxima in the current raw cluster and then calculates initial center of gravity
-  fNlocals=0;
-  AliDebug(1,Form("Cluster size of the Raw cluster ---> %i",fRawCluster.Size()));
-  for(Int_t iDig1=0;iDig1<fRawCluster.Size();iDig1++) {
-    Int_t iNotMax = 0;
-    AliRICHDigit *pDig1 = (AliRICHDigit *)fRawCluster.Digits()->At(iDig1);
-    if(!pDig1) {fNlocals=0;return;}
-    TVector pad1 = pDig1->Pad();
-    Int_t padQ1 = (Int_t)(pDig1->Qdc()+0.1);
-    Int_t padC1 = pDig1->Cfm();
-    for(Int_t iDig2=0;iDig2<fRawCluster.Size();iDig2++) {
-      AliRICHDigit *pDig2 = (AliRICHDigit *)fRawCluster.Digits()->At(iDig2);
-      if(!pDig2) {fNlocals=0;return;}
-      TVector pad2 = pDig2->Pad();
-      Int_t padQ2 = (Int_t)(pDig2->Qdc()+0.1);
-      if(iDig1==iDig2) continue;
-      Int_t diffx = TMath::Sign(Int_t(pad1[0]-pad2[0]),1);
-      Int_t diffy = TMath::Sign(Int_t(pad1[1]-pad2[1]),1);
-      if((diffx+diffy)<=1) {
-         if(padQ2>=padQ1) iNotMax++;
-      }
-    }
-    if(iNotMax==0) {
-      if (fNlocals<100) {
-       TVector2 x2=AliRICHParam::Pad2Loc(pad1);
-       fLocalX[fNlocals]=x2.X();fLocalY[fNlocals]=x2.Y();
-       fLocalQ[fNlocals] = (Double_t)padQ1;
-       fLocalC[fNlocals] = padC1;
-       fNlocals++;
-      }
-    }
-  }
-  AliDebug(1,Form("Number of local maxima found ---> %i",fNlocals));
-  fRawCluster.CoG(fNlocals); //first initial approximation of the CoG...to start minimization.
-}//FindLocalMaxima()
-//__________________________________________________________________________________________________
-void AliRICHClusterFinder::WriteRawCluster()
-{
-//Add the current raw cluster to the list of clusters
-  AliDebug(1,"Start.");
-  
-  FindClusterContribs(&fRawCluster);  
-  R()->ClusterAdd(fRawCluster);
-  
-  ToAliDebug(1,fRawCluster.Print()); AliDebug(1,"Stop."); 
-}//WriteRawCluster()
-//__________________________________________________________________________________________________
-void AliRICHClusterFinder::WriteResolvedCluster()
-{
-//Add the current resolved cluster to the list of clusters
-  AliDebug(1,"Start.");
-  
-  FindClusterContribs(&fResolvedCluster);
-  R()->ClusterAdd(fResolvedCluster);
-  
-  ToAliDebug(1,fResolvedCluster.Print()); AliDebug(1,"Stop.");  
-}//WriteResolvedCluster()
-//__________________________________________________________________________________________________
-void AliRICHClusterFinder::FitCoG()
-{
-//Fits cluster of size  by the corresponding number of Mathieson shapes.
-//This methode is only invoked in case everything is ok to start deconvolution  
-  AliDebug(1,"Start with:"); ToAliDebug(1,fRawCluster.Print());
-  
-  Double_t arglist;
-  Int_t ierflag = 0;
-
-  AliDebug(1,Form("MINUIT Started with %i parameters and %i local maxima",3*fNlocals-1,fNlocals));
-
-//  TMinuit *pMinuit = new TMinuit(3*fNlocals-1);
-  TMinuit *pMinuit = new TMinuit(100);
-  pMinuit->mninit(5,10,7);
-  
-  arglist = -1;
-  pMinuit->mnexcm("SET PRI",&arglist, 1, ierflag);
-  pMinuit->mnexcm("SET NOW",&arglist, 0, ierflag);
-  
-  TString chname;
-  Int_t ierflg;
-  
-  pMinuit->SetObjectFit((TObject*)this);
-  pMinuit->SetFCN(RICHMinMathieson);
-  
-  Double_t vstart,lower, upper;
-  Double_t stepX= 0.01;
-  Double_t stepY= 0.01;
-  Double_t stepQ= 0.01;
-  
-  for(Int_t i=0;i<fNlocals;i++) {
-    AliDebug(1,Form(" local minimum n. %i with Xstart %f and Ystart %f",i,fLocalX[i],fLocalY[i]));
-    vstart   = fLocalX[i];
-    lower    = vstart - 2*AliRICHParam::PadSizeX();
-    upper    = vstart + 2*AliRICHParam::PadSizeX();
-    pMinuit->mnparm(3*i  ,Form("xCoG  %i",i),vstart,stepX,lower,upper,ierflag);
-    AliDebug(1,Form("xCoG %i vstart %f lower %f upper %f ",i,vstart,lower,upper));
-
-    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);
-    AliDebug(1,Form("yCoG %i vstart %f lower %f upper %f ",i,vstart,lower,upper));
-    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);
-    AliDebug(1,Form("qfrac %i vstart %f lower %f upper %f ",i,vstart,lower,upper));
-  }
-  
-  arglist = -1;  pMinuit->mnexcm("SET NOGR",&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);
-  
-  Double_t xCoG[50],yCoG[50],qfracCoG[50];
-  Double_t eps, b1, b2;
-
-  Double_t qfraclast=0;  
-  for(Int_t i=0;i<fNlocals;i++) {
-    pMinuit->mnpout(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(Int_t i=0;i<fNlocals;i++){//resolved positions loop
-    fResolvedCluster.Fill(&fRawCluster,xCoG[i],yCoG[i],qfracCoG[i],fLocalC[i]);
-    WriteResolvedCluster();
-  }
-
-  AliDebug(1,"Stop.");
-
-}//FitCoG()
-//__________________________________________________________________________________________________
-void RICHMinMathieson(Int_t &npar, Double_t *, Double_t &chi2, Double_t *par, Int_t )
-{
-//Mathieson minimization function 
-  
-  AliRICHCluster *pRawCluster = ((AliRICHClusterFinder*)gMinuit->GetObjectFit())->GetRawCluster();
-
-  TVector2 centroid[50];
-  Double_t q[50];
-  Int_t nFunctions = (npar+1)/3;
-  Double_t qfract = 0;
-  for(Int_t i=0;i<nFunctions;i++) {
-    centroid[i].Set(par[3*i],par[3*i+1]);
-    if(i==nFunctions-1) break;
-    q[i]=par[3*i+2];
-    qfract+=q[i];
-  }
-  q[nFunctions-1] = 1 - qfract;
-    
-  chi2 = 0;
-  Int_t qtot = pRawCluster->Q();
-  for(Int_t i=0;i<pRawCluster->Size();i++) {
-    TVector  pad=((AliRICHDigit *)pRawCluster->Digits()->At(i))->Pad();
-    Double_t padQ = ((AliRICHDigit *)pRawCluster->Digits()->At(i))->Qdc();
-    Double_t qfracpar=0;
-    for(Int_t j=0;j<nFunctions;j++) {
-      qfracpar += q[j]*AliRICHParam::FracQdc(centroid[j],pad);
-    }
-    chi2 += TMath::Power((qtot*qfracpar-padQ),2)/padQ;
-  }     
-}//RICHMinMathieson()
-//__________________________________________________________________________________________________
diff --git a/RICH/AliRICHClusterFinder.h b/RICH/AliRICHClusterFinder.h
deleted file mode 100644 (file)
index f8900c8..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef AliRICHClusterFinder_h
-#define AliRICHClusterFinder_h
-
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice                               */
-
-#include "TTask.h"
-
-#include "AliRICH.h"
-class AliHitMap;
-
-class AliRICHClusterFinder : public TTask
-{
-public:    
-           AliRICHClusterFinder(AliRunLoader *pRunLoader);
-  virtual ~AliRICHClusterFinder()                                          {;}
-  
-  AliRICH        *R()                                              {return fRICH;}   //returns pointer to RICH  
-  void            Exec(const Option_t *option="");                                   //loop on events and chambers  
-  void            FindClusters(Int_t iChamber);                                      //find all clusters for a given chamber
-  void            FindClusterContribs(AliRICHCluster *pCluster);                     //find CFM for the current cluster
-  void            FormRawCluster(Int_t i, Int_t j);                                  //form a raw cluster
-  void            FindLocalMaxima();                                                 //find local maxima in a cluster
-  void            FitCoG();                                                          //evaluate the CoG as the best 
-  void            WriteRawCluster();                                                 //write in the list of cluster  
-  void            WriteResolvedCluster();                                            //write in the list of cluster  
-  AliRICHCluster *GetRawCluster()                           {return &fRawCluster;}   //returns pointer to the current raw cluster
-protected:
-  AliRICH                *fRICH;                         //pointer to RICH
-  AliHitMap              *fDigitMap;                     //map of digits positions
-  AliRICHCluster         fRawCluster;                    //current raw cluster before deconvolution
-  AliRICHCluster         fResolvedCluster;               //current cluster after deconvolution
-  Int_t                  fNlocals;                       //number of local maxima
-  Double_t               fLocalX[100],fLocalY[100];      //list of locals X,Y
-  Double_t               fLocalQ[100];                   //list of locals charge Q
-  Int_t                  fLocalC[100];                   //list of locals CombiPid
-  ClassDef(AliRICHClusterFinder,0) //finds raw clusters, trasfers them to resolved clusters through declustering.
-};
-#endif
index 01c18cf..91a8e3c 100644 (file)
@@ -23,10 +23,28 @@ void AliRICHDigit::Print(Option_t*)const
 //Print current digit  
 //Arguments: option string not used
 //  Returns: none    
-  Printf("pad=(%2i,%2i,%3i,%3i), q=%8.3f, cfm=%9i, TID=(%5i,%5i,%5i)",
-               Chamber(),Sector(),PadX(),PadY() ,  Qdc(),    Cfm()  , fTracks[0],fTracks[1],fTracks[2]);
+  Printf("pad=(%2i,%2i,%3i,%3i), QDC=%8.3f, cfm=%9i, TID=(%5i,%5i,%5i)",
+               C(),Pad2Sec(PadX(),PadY()),PadX(),PadY() ,  Qdc(),    Cfm()  , fTracks[0],fTracks[1],fTracks[2]);
 }
 //__________________________________________________________________________________________________
 void AliRICHDigit::Test()
 {
+  Printf("Test of Pad2Sec:");
+  Int_t x1=kFirstPad, x2=kPadsSecX, x3=kPadsSecX+1, x4=kPadsChamX;//all possible padx for corners
+  Int_t y;
+  
+  y=kPadsChamY;
+  Printf("Sector5:(%3i,%3i)->%i (%3i,%3i)->%i  Sector6:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y));
+  y=2*kPadsSecY+1;
+  Printf("Sector5:(%3i,%3i)->%i (%3i,%3i)->%i  Sector6:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y));
+  Printf("");
+  y=2*kPadsSecY;
+  Printf("Sector3:(%3i,%3i)->%i (%3i,%3i)->%i  Sector4:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y));
+  y=kPadsSecY+1;
+  Printf("Sector3:(%3i,%3i)->%i (%3i,%3i)->%i  Sector4:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y));
+  Printf("");
+  y=kPadsSecY;
+  Printf("Sector1:(%3i,%3i)->%i (%3i,%3i)->%i  Sector2:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y));
+  y=kFirstPad;
+  Printf("Sector1:(%3i,%3i)->%i (%3i,%3i)->%i  Sector2:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y));
 }
index 8063624..df37f55 100644 (file)
@@ -4,65 +4,93 @@
  * See cxx source for full Copyright notice                               */
 
 #include <AliDigit.h>      //base class  
-#include <AliBitPacking.h> //Dig2Raw()
-#include "AliRICHParam.h"
+#include <AliBitPacking.h> //ToRaw(), FromRaw()
+#include <TVector.h>       //ctor
+/*
+Any given LDC collects data from all FEE connected to the LDC by DDL. This data is stored in name.ddl file.
+Name of this file is composed by detector name plus some value for example RICH1793.ddl
+That value is calculated as sequensial number of detector LDC plus some predifined offset, unique for a given detector.
+The value is expected to be within a given range assigned to detector.
+For RICH, the offset number is 0x700 hex or 1792 decimal (reffered in the code as kDdlOffset). 
+The range assigned for RICH is 0x700-0x714 hex or 1792-1812 decimal. It is 20 ddl files or 20 LDCs.
+RICH actually uses 14 LDCs hence DAQ writes for RICH 14 ddl files (reffered in the code as kNddls).
+RICH FEE is connected to LDC in the following way:
+Single LDC serves one half of a chamber i.e. 3 photocathodes aka sectors,  even LDC for left part( sectors 1-3-5) and odd LDC for right part(2-4-6) 
+So the LDC -chamber-ddl file name map is:
+LDC  0 -> ch 1L -> file name value 0x700 1792          LDC  1 -> ch 1R -> file name value 0x701 1793
+LDC  2 -> ch 2L -> file name value 0x702 1794          LDC  3 -> ch 2R -> file name value 0x703 1795
+LDC  4 -> ch 3L -> file name value 0x704 1796          LDC  5 -> ch 3R -> file name value 0x705 1797
+LDC  6 -> ch 4L -> file name value 0x706 1798          LDC  7 -> ch 4R -> file name value 0x707 1799
+LDC  8 -> ch 5L -> file name value 0x708 1800          LDC  9 -> ch 5R -> file name value 0x709 1801
+LDC 10 -> ch 6L -> file name value 0x70a 1802          LDC 11 -> ch 6R -> file name value 0x70b 1803
+LDC 12 -> ch 7L -> file name value 0x70c 1804          LDC 13 -> ch 7R -> file name value 0x70d 1805
 
-//RICH DDL ID allowed range is [0x700,0x714] or in decimal notation [1792,1812]. 20 DDL files are reserved. (kDdlOffset)
-//RICH actually uses 14 DDLs (kNddls), 2 per chamber, even number for left part(1-3-5) odd number for right part(2-4-6) 
-//So the chamber-DDL map is:
-//N  0 1L=0x700 1792          N  1 1R=0x701 1793
-//N  2 2L=0x702 1794          N  3 2R=0x703 1795
-//N  4 3L=0x704 1796          N  5 3R=0x705 1797
-//N  6 4L=0x706 1798          N  7 4R=0x707 1799
-//N  8 5L=0x708 1800          N  9 5R=0x709 1801
-//N 10 6L=0x70a 1802          N 11 6R=0x70b 1803
-//N 12 7L=0x70c 1804          N 13 7R=0x70d 1805
-//RICH has no any propriate header just uses the common one
-//RICH chamber is divide on 2 halves vertically 
-//Half chamber is divided by 24 rows counted from 1 to 24 (8 raws per sector) from top to bottom for left half chamber (sectors 1-3-5) 
-//                                                                         and from bottom to top for right half chamber (sectors 2-4-6) as seen from MARS (0,0,0)
-//Raw is composed from 10 DILOGIC chips (kNchips) counted from left to right from 1 to 10  as seen from MARS (0,0,0)
-//So each DILOGIC chip serves 48 channels for the 8x6 pads box (kChipX,kChipY). Channels counted from 0 to 47.
-//??????? Currently the exact mapping of DILOGIC addresses to pads is not known. So we invented horizontal zig-zag ???????  
-//So RICH raw word is  32 bits word with structure:   
-// 00000        rrrrr                      dddd                               aaaaaa                          qqqqqqqqqqqq 
-// 5 bits zero  5 bits raw number (1..24)  4 bits DILOGIC chip number (1..10) 6 bits DILOGIC address (0..47)  12 bits QDC value (0..4095)
+Programmatically, operations with ddl files are interfaced by class AliRawReader. In order to select some ddl files for detector,
+one needs to provide a reserved id number of detector. For RICH, this number is 7 (reffered in the code as kRichRawId).
+
+DDL file starts with common header described in AliRawDataHeader, which can be followed by private header.
+RICH has no any private header, just uses the common one.
+
+RICH FEE as seen by single LDC is composed from a number of DILOGIC chips organized in vertical stack of rows. 
+Each DILOGIC chip serves 48 channels for the 8x6 pads (reffered in the code as kDiloX,kDiloY). Channels counted from 0 to 47.
+
+??????? Currently the exact mapping of DILOGIC addresses to pads is not known. So we invented horizontal zig-zag ???????  
+
+10 DILOGIC chips composes so called "row" in horizontal direction (reffered in the code as kNdilo), so the row is 80x6 pads structure. 
+DILOGIC chips in the row are counted from left to right as seen from MARS (0,0,0), from 1 to 10.
+24 rows are piled up forming the whole FEE served by single LDC, so one LDC sees 80x144 pads separated in 3 photocathodes aka sectors.
+Rows are counted from 1 to 24 from top    to bottom for left  half chamber (sectors 1-3-5) as seen from MARS (0,0,0), meaning even LDC number
+                          and from bottom to top    for right half chamber (sectors 2-4-6) as seen from MARS (0,0,0), meaning odd LDC number.
+
+So RICH raw word is 32 bits with the structure:   
+   00000             rrrrr                      dddd                               aaaaaa                          qqqqqqqqqqqq 
+ 5 bits zero  5 bits row number (1..24)  4 bits DILOGIC chip number (1..10) 6 bits DILOGIC address (0..47)  12 bits QDC value (0..4095)
+*/
 
 class AliRICHDigit :public AliDigit
 {
 public:
-  enum EAbsPad {kChamber=10000000,kPadX=1000};                           //absolute pad number structure
-  enum ERawProp{kChipX=8,kChipY=6,kNchips=10,kNddls=14,kRichRawId=7,kDdlOffset=0x700};//DILOGIC is 8x6 pads
-  AliRICHDigit()                                  :AliDigit(),fCFM(-1),fChamber(-1  )  ,fPadX(-1)    ,fPadY(-1)    ,fQdc(-1) {}
-  AliRICHDigit(Int_t c,Int_t x,Int_t y,Double_t q):AliDigit(),fCFM(-1),fChamber(10*c)  ,fPadX(x )    ,fPadY(y )    ,fQdc(q ) {}
-  AliRICHDigit(Int_t c,TVector pad,Double_t q,Int_t cfm,Int_t tid0,Int_t tid1,Int_t tid2):fCFM(cfm)  
-       {fPadX=(Int_t)pad[0];fPadY=(Int_t)pad[1];fQdc=q;fChamber=10*c+AliRICHParam::Pad2Sec(pad);fTracks[0]=tid0;fTracks[1]=tid1;fTracks[2]=tid2;}
+  enum EAbsPad {kChamAbs=10000000,kSecAbs=1000000,kPadAbsX=1000,kPadAbsY=1};                //absolute pad number structure
+  enum ERawData{kDiloX=8,kDiloY=6,kNdilo=10};                                               //DILOGIC structure, see description above 
+  enum EPadData{kFirstPad=1,kPadsSecX=80,kPadsSecY=48,kPadsChamX=160,kPadsChamY=144,kSecX=2,kSecY=3};   //Segmentation structure 
+  enum EDdlData{kNddls=14,kDdlOffset=0x700,kRichRawId=7};                                   //Common DDL structure, see description above
+//ctor&dtor    
+  AliRICHDigit()                                                :AliDigit(),fCFM(-1) ,fChamber(-1  )     ,fPadX(-1)      ,fPadY(-1)      ,fQdc(-1)  {}
+  AliRICHDigit(Int_t pad,Double_t qdc,Int_t cfm=-1,Int_t tid=-1):AliDigit(),fCFM(cfm),fChamber(P2C(pad)) ,fPadX(P2X(pad)),fPadY(P2Y(pad)),fQdc(qdc) {fTracks[0]=tid;}
+  AliRICHDigit(TVector pad,Double_t q                          ):AliDigit(),fCFM(-1) ,fChamber(-1)       ,fPadX((Int_t)pad[0])  ,fPadY((Int_t)pad[1])  ,fQdc(q)   {}
+  AliRICHDigit(Int_t c,TVector pad,Double_t q,Int_t cfm,Int_t tid0,Int_t tid1,Int_t tid2):fCFM(cfm),fChamber(c)  
+       {fPadX=(Int_t)pad[0];fPadY=(Int_t)pad[1];fQdc=q;fTracks[0]=tid0;fTracks[1]=tid1;fTracks[2]=tid2;}
   virtual ~AliRICHDigit() {;}
 //framework part    
-         Bool_t   IsSortable  (                   )const{return kTRUE;}                                                    //provision to use TObject::Sort()
-  inline Int_t    Compare     (const TObject *pObj)const;                                                                  //provision to use TObject::Sort()
-         void     Print       (Option_t *option="")const;                                                                  //TObject Print() overload
+                Bool_t   IsSortable  (                               )const{return kTRUE;}                                                    //provision to use TObject::Sort()
+         inline Int_t    Compare     (const TObject *pObj            )const;                                                                  //provision to use TObject::Sort()
+                void     Print       (Option_t *opt=""               )const;                                                                  //TObject Print() overload
 //private part  
-         void     AddTidOffset(Int_t offset     )     {for (Int_t i=0; i<3; i++) if (fTracks[i]>0) fTracks[i]+=offset;}; //needed for merging
-         Int_t    Cfm         (                 )const{return fCFM;}                                                     //particle mixture for this digit
-         Int_t    Chamber     (                 )const{return fChamber/10;}                                              //chamber number
-         Int_t    Sector      (                 )const{return fChamber%10;}                                              //sector number
-         Int_t    PadX        (                 )const{return fPadX;}                                                    //x position of the pad
-         Int_t    PadY        (                 )const{return fPadY;}                                                    //y postion of the pad     
-         TVector  Pad         (                 )const{Float_t v[2]={fPadX,fPadY}; return TVector(2,v);}
-         Int_t    PadAbs      (                 )const{return fChamber*kChamber+fPadX*kPadX+fPadY;}                      //absolute id of this pad
-         Double_t Qdc         (                 )const{return fQdc;}                                                     //charge in terms of ADC channels
-  inline Int_t    Dig2Raw     (        UInt_t &w)const;                                                                  //returns DDL ID and fill raw 32 bits word
-  inline void     Raw2Dig     (Int_t d,UInt_t  w);                                                                       //(DDL,word32)->(ch,sec,padx,pady,QDC)
-  static Int_t    P2C         (Int_t pad        )     {return pad/kChamber;}                                             //abs pad number-> chamber number
-  static Int_t    P2X         (Int_t pad        )     {return pad%kChamber/kPadX;}                                       //abs pad number-> pad X number
-  static Int_t    P2Y         (Int_t pad        )     {return pad%kChamber%kPadX;}                                       //abs pad number-> pad Y number
-         void     Test        (                 );                                                                       //used to test all possible digit manipulations
+                void     AddTidOffset(Int_t offset                   )     {for (Int_t i=0; i<3; i++) if (fTracks[i]>0) fTracks[i]+=offset;}; //needed for merging
+                Int_t    Cfm         (                               )const{return fCFM;}                                                     //ckov-feed-mip mixture
+                Int_t    Chamber     (                               )const{return fChamber;}                                                 //chamber number
+                Int_t    C           (                               )const{return fChamber;}                                                 //chamber number 
+         inline Int_t    Dig2Raw     (        UInt_t &w              )const;                                                                  //returns DDL ID and fill raw word
+                Int_t    PadX        (                               )const{return fPadX;}                                                    //x position of the pad
+                Int_t    PadY        (                               )const{return fPadY;}                                                    //y postion of the pad     
+                TVector  Pad         (                               )const{Float_t v[2]={fPadX,fPadY}; return TVector(2,v);}
+                Int_t    PadAbs      (                               )const{return fChamber*kChamAbs+fPadX*kPadAbsX+fPadY;}                   //absolute id of this pad
+  static inline Int_t    Pad2Sec     (Int_t x,Int_t y                );                                   
+  static        Int_t    P2A         (Int_t c,        Int_t x,Int_t y)     {Int_t s=Pad2Sec(x,y);return c*kChamAbs+s*kSecAbs+x*kPadAbsX+y;}   //(cham,padx,pady)-> abs pad
+  static        Int_t    P2A         (Int_t c,Int_t s,Int_t x,Int_t y)     {return Pad2Sec(x,y)==s?c*kChamAbs+s*kSecAbs+x*kPadAbsX+y:-1;}     //(cham,sec,padx,pady)-> abs pad
+  static        Int_t    P2C         (Int_t pad                      )     {return pad/kChamAbs;}                                             //abs pad -> chamber
+  static        Int_t    P2S         (Int_t pad                      )     {return pad%kChamAbs/kSecAbs;}                                     //abs pad -> sector 
+  static        Int_t    P2X         (Int_t pad                      )     {return pad%kSecAbs/kPadAbsX;}                                     //abs pad -> pad X 
+  static        Int_t    P2Y         (Int_t pad                      )     {return pad%kPadAbsX;}                                             //abs pad number-> pad Y 
+                Double_t Qdc         (                               )const{return fQdc;}                                                     //charge, QDC
+         inline void     Raw2Dig     (Int_t ddl,UInt_t  w32          );                                                                       //(DDL,w32)->(ch,sec,x,y,QDC)
+                Int_t    S           (                               )const{return -1;}                                                       //sector number  ?????
+  static        void     Test        (                               );                                                                       //test raw-digit manipulations
 protected:
-  Int_t    fCFM;  //1000000*Ncerenkovs+1000*Nfeedbacks+Nmips  
-  Int_t    fChamber;  //10*chamber number+ sector number 
-  Int_t    fPadX;     //pad number along X
-  Int_t    fPadY;     //pad number along Y
+  Int_t    fCFM;      //1000000*Ncerenkovs+1000*Nfeedbacks+Nmips  
+  Int_t    fChamber;  //chamber
+  Int_t    fPadX;     //pad along X
+  Int_t    fPadY;     //pad along Y
   Double_t fQdc;      //QDC value, fractions are permitted for summable procedure  
   ClassDef(AliRICHDigit,3) //RICH digit class       
 };//class AliRICHDigit
@@ -70,32 +98,28 @@ protected:
 Int_t AliRICHDigit::Compare(const TObject *pObj) const
 {
 //Used in Sort() method to compare to objects. Note that abs pad structure is first x then y, hence will be sorted on column basis.
-//This feature is used in digitizer to facilitate finding of sdigits for the same pad as they will be together after sorting.
+//This feature is used in digitizer to facilitate finding of sdigits for the same pad since they all will come together after sorting.
 //Arguments: pObj - pointer to object to compare with
 //  Retunrs: -1 if AbsPad less then in pObj, 1 if more and 0 if they are the same      
-  if(PadAbs()==((AliRICHDigit*)pObj)->PadAbs())
-    return 0;
-  else if(PadAbs()>((AliRICHDigit*)pObj)->PadAbs())
-    return 1;
-  else 
-    return -1;
+  if     (PadAbs()==((AliRICHDigit*)pObj)->PadAbs()) return  0;
+  else if(PadAbs() >((AliRICHDigit*)pObj)->PadAbs()) return  1;
+  else                                               return -1;
 }
 //__________________________________________________________________________________________________
 void AliRICHDigit::Raw2Dig(Int_t ddl,UInt_t w32)
 {
-//Reads next raw word from raw data stream and convert     
-//Arguments: w32 - 32 bits word as in raw data stream
+//Converts a given raw data word to a digit
+//Arguments: w32 - 32 bits raw data word
 //           ddl - DDL file number  0 1 2 3 4 ... 13
 //  Returns: none
-      fQdc = AliBitPacking::UnpackWord(w32, 0,11);  // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq 
-  UInt_t a = AliBitPacking::UnpackWord(w32,12,17);  // 3322 2222 2222 1111 1111 1000 0000 0000 
-  UInt_t d = AliBitPacking::UnpackWord(w32,18,21);  // 1098 7654 3210 9876 5432 1098 7654 3210 
-  UInt_t r = AliBitPacking::UnpackWord(w32,22,26);  // r- iRawN d- iChiN a- iChiC              
+      fQdc = AliBitPacking::UnpackWord(w32, 0,11);  // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq         Qdc               bits (00..11) counts (0..4095)   
+  UInt_t a = AliBitPacking::UnpackWord(w32,12,17);  // 3322 2222 2222 1111 1111 1000 0000 0000         DILOGIC address   bits (12..17) counts (0..47)
+  UInt_t d = AliBitPacking::UnpackWord(w32,18,21);  // 1098 7654 3210 9876 5432 1098 7654 3210         DILOGIC number    bits (18..21) counts (1..10)
+  UInt_t r = AliBitPacking::UnpackWord(w32,22,26);  //                                                 Row number        bits (22..26) counts (1..24)    
   
-  fPadY    = (r-1)*kChipY+a/kChipX+1;
-  fPadX    = (d-1)*kChipX+a%kChipX+1;      fPadX+=(ddl%2)*kChipX*kNchips;//if ddl is odd then right half of the chamber
-  TVector pad(2); pad[0]=fPadX;pad[1]=fPadY;
-  fChamber = ((ddl+2)/2)*10+AliRICHParam::Pad2Sec(pad);  // ddl 0..13 to chamber 1..7
+  fPadY    = (r-1)*kDiloY+a/kDiloX+1;
+  fPadX    = (d-1)*kDiloX+a%kDiloX+1;      fPadX+=(ddl%2)*kDiloX*kNdilo;//if ddl is odd then right half of the chamber
+  fChamber = (ddl+2)/2;  // ddl 0..13 to chamber 1..7
 }  
 //__________________________________________________________________________________________________
 Int_t AliRICHDigit::Dig2Raw(UInt_t &w32)const
@@ -103,21 +127,40 @@ Int_t AliRICHDigit::Dig2Raw(UInt_t &w32)const
 //Convert digit structure to raw word format
 //Arguments: 32 bits raw word to fill
 //  Returns: DDL ID where to write this digit
-  Int_t ddl=2*Chamber()-1;              //chamber 1..7 -> DDL 0..13, this idDdl is for right half (sectors 2 4 6), to be decremented if d < kNchips
-  UInt_t a =  (PadY()-1)%kChipY*kChipX+(PadX()-1)%kChipX;          //invented to be horizontal zig-zag
-  UInt_t r =1+(PadY()-1)/kChipY;      
-  UInt_t d =1+(PadX()-1)/kChipX;    
-  if(d>kNchips)
-    d-=kNchips;              //chip number more then kNchips means right half of chamber, goes to this ddl
+  Int_t ddl=2*C()-1;                                         //chamber 1..7 -> DDL 0..13, this idDdl is for right half (sectors 2 4 6), to be decremented if d < kNchips
+  UInt_t a =  (PadY()-1)%kDiloY*kDiloX+(PadX()-1)%kDiloX;    //invented to be horizontal zig-zag
+  UInt_t r =1+(PadY()-1)/kDiloY;                             //Row number depends only on y and we have (1..24) rows per (1..144) pads
+  UInt_t d =1+(PadX()-1)/kDiloX;                             //DILOGIC number depends only on x we have (1..10) chips per (1..80) pads
+  if(d>kNdilo)
+    d-=kNdilo;              //chip number more then kNdilo means right half of chamber, goes to this ddl
   else
-    ddl--;                   //chip number less then kNchips means left half of the chamber, goes to ddl-1 
+    ddl--;                  //chip number less then kNdilo means left half of the chamber, goes to ddl-1 
   
   w32=0;
-  AliBitPacking::PackWord((UInt_t)fQdc,w32, 0,11);  // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq
-  AliBitPacking::PackWord(           a,w32,12,17);  // 3322 2222 2222 1111 1111 1000 0000 0000
-  AliBitPacking::PackWord(           d,w32,18,21);  // 1098 7654 3210 9876 5432 1098 7654 3210 
-  AliBitPacking::PackWord(           r,w32,22,26);  
+  AliBitPacking::PackWord((UInt_t)fQdc,w32, 0,11);  // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq        Qdc               bits (00..11) counts (0..4095)
+  AliBitPacking::PackWord(           a,w32,12,17);  // 3322 2222 2222 1111 1111 1000 0000 0000        DILOGIC address   bits (12..17) counts (0..47)
+  AliBitPacking::PackWord(           d,w32,18,21);  // 1098 7654 3210 9876 5432 1098 7654 3210        DILOGIC number    bits (18..21) counts (1..10)
+  AliBitPacking::PackWord(           r,w32,22,26);  //                                                Row number        bits (22..26) counts (1..24)  
   return ddl; //ddl 0..13 where to write this digit 
 }
-
+//__________________________________________________________________________________________________
+Int_t AliRICHDigit::Pad2Sec(Int_t padx,Int_t pady)
+{
+//Determines sector containing the given pad.
+//Arguments: padx,pady - pad number
+//  Returns: sector number    
+//y ^  5 6         sectors map as seen from IP
+//  |  3 4
+//  |  1 2
+//   -------> x  
+  Int_t sector;      
+  if     (padx >=     1      && padx <=   kPadsSecX )    sector=1;
+  else if(padx >  kPadsSecX  && padx <=   kPadsChamX)    sector=2; 
+  else                                                   return -1;//padx out of range     
+  if     (pady >=     1      && pady <=   kPadsSecY )    return sector;
+  else if(pady >   kPadsSecY && pady <= 2*kPadsSecY )    return sector+2;
+  else if(pady > 2*kPadsSecY && pady <=   kPadsChamY)    return sector+4;
+  else                                                   return -1; //pady out of range
+}//Pad2Sec()
+//__________________________________________________________________________________________________
 #endif
index c95af38..0129130 100644 (file)
@@ -42,12 +42,12 @@ void AliRICHDigitizer::Exec(Option_t*)
     if (!pInRunLoader->GetAliRun()) pInRunLoader->LoadgAlice();
     AliRICH* pInRich=(AliRICH*)pInRunLoader->GetAliRun()->GetDetector("RICH");                  //take RICH from current input
     pInRichLoader->LoadSDigits(); pInRichLoader->TreeS()->GetEntry(0);                          //take list of RICH sdigits from current input 
-    AliDebug(1,Form("input %i has %i sdigits",inFileN,pInRich->SDigits()->GetEntries()));
-    for(Int_t i=0;i<pInRich->SDigits()->GetEntries();i++){//collect sdigits from current input to tmpCA
-      new(tmpCA[total++]) AliRICHDigit(*(AliRICHDigit*)pInRich->SDigits()->At(i)); 
+    AliDebug(1,Form("input %i has %i sdigits",inFileN,pInRich->SDigs()->GetEntries()));
+    for(Int_t i=0;i<pInRich->SDigs()->GetEntries();i++){//collect sdigits from current input to tmpCA
+      new(tmpCA[total++]) AliRICHDigit(*(AliRICHDigit*)pInRich->SDigs()->At(i)); 
       ((AliRICHDigit*)tmpCA[total-1])->AddTidOffset(fManager->GetMask(inFileN));//apply TID shift since all inputs count tracks independently starting from 0
     }
-    pInRichLoader->UnloadSDigits();   pInRich->SDigitsReset(); //close current input and reset 
+    pInRichLoader->UnloadSDigits();   pInRich->SDigReset(); //close current input and reset 
   }//files loop
   
   tmpCA.Sort();                     //at this point we have a list of all sdigits from all inputs, now sort them according to fPad field
@@ -65,18 +65,18 @@ void AliRICHDigitizer::Exec(Option_t*)
       iNdigsPerPad++;         dQdc+=pSdig->Qdc();      iCfm+=pSdig->Cfm();//sum up charge and cfm
       if(pSdig->Cfm()==1) aTids[0] = pSdig->GetTrack(0); // force the first tid to be mip's tid if it exists in the current pad
       if(iNdigsPerPad<=3)        aTids[iNdigsPerPad-1]=pSdig->GetTrack(0);
-      else                         AliDebug(1,Form("More then 3 sdigits in (%d,%d,%f,%f) with Q= %f",pSdig->Chamber(),pSdig->Sector(),pSdig->Pad()(0),pSdig->Pad()(1),pSdig->Qdc()));
+      else                         AliDebug(1,Form("More then 3 sdigits in (%d,%d,%f,%f) with Q= %f",pSdig->Chamber(),-1,pSdig->Pad()(0),pSdig->Pad()(1),pSdig->Qdc()));
     }else{//new pad, add the pevious one
-        if(iId!=-1 && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigitAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids); //add newly created dig
+        if(iId!=-1 && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids); //add newly created dig
         iChamber=pSdig->Chamber(); pad=pSdig->Pad(); iCfm=pSdig->Cfm(); dQdc=pSdig->Qdc();  iId=pSdig->PadAbs();                    //init all values by current sdig
         iNdigsPerPad=1; aTids[0]=pSdig->GetTrack(0); aTids[1]=aTids[2]=-1;
       }
   }//sdigits loop (sorted)
-  if(tmpCA.GetEntries() && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigitAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids);//add the last dig
+  if(tmpCA.GetEntries() && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids);//add the last dig
   
   pOutRichLoader->TreeD()->Fill();              //fill the output tree with the list of digits
   pOutRichLoader->WriteDigits("OVERWRITE");     //serialize them to file
   
   tmpCA.Clear();                      //remove all tmp sdigits
-  pOutRichLoader->UnloadDigits();   pOutRich->DigitsReset();
+  pOutRichLoader->UnloadDigits();   pOutRich->DigReset();
 }//Exec()
index 92b67f6..e97e95c 100644 (file)
@@ -1,16 +1,35 @@
-#include "AliRICHHelix.h"
-#include <AliLog.h>
+#include "AliRICHHelix.h" //class header
+#include <TPolyLine3D.h>  //Draw()
 
 ClassImp(AliRICHHelix)
-
-void  AliRICHHelix::Print(Option_t *) const
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+AliRICHHelix::AliRICHHelix(Double_t p,Double_t theta,Double_t phi,Double_t bz):TObject() 
 {
-//Debug printout
-  AliInfo(Form("Q=%i, in B(0,0,%5.2f) x0=(%5.2f,%5.2f,%5.2f) p0=(%5.2f,%5.2f,%5.2f)",fQ,fBz,
-                            fX0.X(),fX0.Y(),fX0.Z(),
-                            fP0.X(),fP0.Y(),fP0.Z()  ));
-  AliInfo(Form("At length %7.2f gives x=(%5.2f,%5.2f,%5.2f) p=(%5.2f,%5.2f,%5.2f)",fLen,
-                            fX.X(),fX.Y(),fX.Z(),
-                            fP.X(),fP.Y(),fP.Z()  ));
-
+  fX0.SetXYZ(0,0,0);                                                       fX=fX0;
+  fP0.SetMagThetaPhi(p,theta*TMath::DegToRad(),phi*TMath::DegToRad());     fP=fP0;
+  fLen=0; fQ=1;fBz=bz;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void  AliRICHHelix::Print(Option_t *opt) const
+{
+// Debug printout
+  Printf("%s helix for Q=%i in B=(0,0,%.2f) tesla",opt,fQ,fBz);
+  Printf("Helix parametrised  @ x0=(%6.2f,%6.2f,%6.2f) cm p0=(%6.2f,%6.2f,%6.2f) GeV  P=%.2f GeV Theta=%.2f Phi=%.2f degrees", 
+                                fX0.X(),fX0.Y(),fX0.Z(),    fP0.Px(),fP0.Py(),fP0.Pz(), fP0.Mag(),fP0.Theta()*TMath::RadToDeg(),fP0.Phi()*TMath::RadToDeg());
+  Printf("@ %7.2f cm           x=(%6.2f,%6.2f,%6.2f) cm  p=(%6.2f,%6.2f,%6.2f) GeV  P=%.2f GeV Theta=%.2f Phi=%.2f degrees",
+           fLen,              fX.X(), fX.Y(), fX.Z(),       fP.Px(),fP.Py(),fP.Pz(), fP.Mag(), fP.Theta()*TMath::RadToDeg(),fP.Phi()*TMath::RadToDeg());
+  Printf("             in LORS   rad=(%5.2f,%5.2f)  pc=(%5.2f,%5.2f)",fPosRad.X(), fPosRad.Y(),fPosPc.X(),fPosPc.Y());
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHHelix::Draw(const Option_t *)
+{
+// Draw helix by a set of points seperated by 1 cm distance 
+  
+  const Int_t kNpoints=500;
+  TPolyLine3D *pHelDraw = new TPolyLine3D(kNpoints); pHelDraw->SetLineColor(kGreen);
+  for(Int_t i=0;i<kNpoints;i++) {
+    Propagate(i);
+    pHelDraw->SetPoint(i,fX.X(),fX.Y(),fX.Z());
+  }  
+  pHelDraw->Draw();
 }
index f3112cf..a769f1c 100644 (file)
@@ -1,66 +1,69 @@
 #ifndef AliRICHHelix_h
 #define AliRICHHelix_h
 
-#include <TObject.h>
-#include <TVector3.h>
-#include "AliRICHParam.h"
-#include "AliRICHChamber.h"
+#include <TObject.h>              //base class
+#include <TVector3.h>             //used extensively
+#include "AliRICHParam.h"         //RichIntersect() 
 
 class AliRICHHelix: public TObject
 {
 public:
-  AliRICHHelix():TObject()                                                                                                          {;}
-  AliRICHHelix(const TVector3 &x0,const TVector3 &p0,Int_t q=1,Double_t b=0.2):TObject(),fX0(x0),fP0(p0),fX(x0),fP(p0),
-                                                                                         fLen(0),fQ(q),fBz(b)                       {;}
-  virtual ~AliRICHHelix()                                                                                                           {;}        
+  AliRICHHelix():TObject()                                                                                                                  {}
+  AliRICHHelix(Double_t p,Double_t theta,Double_t phi,Double_t bz=0.2);//p [GeV], theta,phi [deg], Bz [Tesla];
+  AliRICHHelix(const TVector3 &x0,const TVector3 &p0,Int_t q=1,Double_t b=0.2):TObject(),fX0(x0),fP0(p0),fX(x0),fP(p0),fLen(0),fQ(q),fBz(b) {}
+  virtual ~AliRICHHelix()                                                                                                                   {}        
            
-  inline void     Propagate(Double_t len);                                          //propogate helix by length len along it
-  inline Int_t    RichIntersect(AliRICHParam *pParam);                              //search intersection with any RICH chamber 
-  inline Bool_t   Intersection(TVector3 planePnt,TVector3 planeNorm);               //intersection with plane given by point and normal vector
-         Bool_t   Intersection(TVector3 pl)    {return Intersection(pl,pl.Unit());} // special plane given by point only
-         TVector2 PosRad()                const{return fPosRad;}          //returns position of intersection with radiator (local system)
-         TVector2 PosAnod()               const{return fPosAnod;}         //returns position of intersection with anod wires plane (local system)
-         TVector2 PosPc()                 const{return fPosPc;}           //returns position of intersection with PC (local system)
-         TVector3 Ploc()                  const{return fPloc;}            //returns momentum at the position of intersection with radiator   
-         Double_t Length()                const{return fLen;}             //returns length of the track from initial point to RICH
-         void     Print(Option_t *sOption)const; //virtual interface from TObject
+         void     Draw          (const Option_t *opt=""              );                              //from TObject, draw helix
+         void     Print         (const Option_t *opt=""              )const;                         //from TObject, print status
+//private part++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  inline Bool_t   Intersection  (TVector3 planePnt,TVector3 planeNorm);                              //intersection with plane given by point and normal vector
+  inline void     Propagate     (Double_t len                        );                              //propogate helix by given length along it
+  inline Int_t    RichIntersect (AliRICHParam *pParam                );                              //search intersection with any RICH chamber 
+         TVector2 PosRad        (                                    )const{return fPosRad;}         //intersection with radiator LORS
+         TVector2 PosPc         (                                    )const{return fPosPc;}          //returns position of intersection with PC (local system)
+         TVector3 Ploc          (                                    )const{return fPloc;}           //returns momentum at the position of intersection with radiator   
+//         Double_t Length        ()                const{return fLen;}             //returns length of the track from initial point to RICH
+         TVector3 X             (                                    )const{return fX;}
 protected:
-  TVector3 fX0;            //helix position in parametrised point, cm    in MRS
-  TVector3 fP0;            //helix momentum in parametrised point, GeV/c in MRS
-  TVector3 fX;             //helix position in point of interest,  cm    in MRS
-  TVector3 fP;             //helix momentum in point of interest,  GeV/c in MRS
-  Double_t fLen;           //helix length in point of interest    
+  TVector3 fX0;            //helix position in point of definition, [cm]    in MARS
+  TVector3 fP0;            //helix momentum in point of definition, [GeV/c] in MARS
+  TVector3 fX;             //helix position in point of interest,  [cm]    in MARS
+  TVector3 fP;             //helix momentum in point of interest,  [GeV/c] in MARS
+  Double_t fLen;           //helix length from point of definition to point of interest, [cm]    
   Int_t    fQ;             //sign of track charge (value not provided by current ESD)  
-  Double_t fBz;            //magnetic field along z value in Tesla under assumption of uniformity 
-  TVector2 fPosRad;        //track intersection with radiator (local system)
-  TVector2 fPosAnod;       //track intersection with anod wires plane (local system)
-  TVector2 fPosPc;         //track intersection with PC (local system)
-  TVector3 fPloc;          //momentum in local system
+  Double_t fBz;            //magnetic field along z, [Tesla] 
+  TVector2 fPosRad;        //helix intersection with radiator entrance, LORS [cm]
+  TVector2 fPosPc;         //helix intersection with PC, LORS [cm]
+  TVector3 fPloc;          //helix momentum, LORS [GeV/c]
   ClassDef(AliRICHHelix,0) //General helix
 };//class AliRICHHelix
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHHelix::Propagate(Double_t len)
 {
-// Propogates the helix to the position of interest defined by helix length s  
-// Assumes uniform magnetic field along z direction.  
-  const Double_t c = 0.00299792458;//this value provides that coordinates are in cm momentum in GeV/c
-  Double_t a = -c*fBz*fQ;
-  Double_t rho = a/fP0.Mag();
-  fX.SetX( fX0.X()+fP0.X()*TMath::Sin(rho*len)/a-fP0.Y()*(1-TMath::Cos(rho*len))/a  );
-  fX.SetY( fX0.Y()+fP0.Y()*TMath::Sin(rho*len)/a+fP0.X()*(1-TMath::Cos(rho*len))/a  ); 
-  fX.SetZ( fX0.Z()+fP0.Z()*len/fP0.Mag()                                            );
-  fP.SetX( fP0.X()*TMath::Cos(rho*len)-fP0.Y()*TMath::Sin(rho*len)                  );
-  fP.SetY( fP0.Y()*TMath::Cos(rho*len)+fP0.X()*TMath::Sin(rho*len)                  );
-  fP.SetZ( fP0.Z()                                                                  );
-  fLen=len;
+// Propogates the helix from inintial point by a given distance along helix. Assumes uniform magnetic field along z direction.  
+// Arguments: len - distance to propagate by, [cm]
+//   Returns: none    
+  if(fBz==0){//no magnetic field->straight line
+    fX=fX0+fP0.Unit()*len;   
+  }else{
+    const Double_t c = 0.00299792458;//this speed of light value provides that coordinates are in cm momentum in GeV/c
+    Double_t a = -c*fBz*fQ;
+     Double_t rho = a/fP0.Mag();
+    fX.SetX( fX0.X()+fP0.X()*TMath::Sin(rho*len)/a-fP0.Y()*(1-TMath::Cos(rho*len))/a  );
+    fX.SetY( fX0.Y()+fP0.Y()*TMath::Sin(rho*len)/a+fP0.X()*(1-TMath::Cos(rho*len))/a  ); 
+    fX.SetZ( fX0.Z()+fP0.Z()*len/fP0.Mag()                                            );
+    fP.SetX( fP0.X()*TMath::Cos(rho*len)-fP0.Y()*TMath::Sin(rho*len)                  );
+    fP.SetY( fP0.Y()*TMath::Cos(rho*len)+fP0.X()*TMath::Sin(rho*len)                  );
+    fP.SetZ( fP0.Z()                                                                  );
+    fLen=len;
+  }
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Bool_t AliRICHHelix::Intersection(TVector3 planePoint,TVector3 planeNorm)
 {
-// Finds point of intersection (if exists) of the helix to the plane given by point and normal vector.
-// Returns kTrue if helix intersects the plane, kFALSE otherwise.
-// Stores result in current helix fields fX and fP.   
+// Finds point of intersection (if exists) of the helix with the plane. Stores result in fX and fP.   
+// Arguments: planePoint,planeNorm - the plane defined by any plane's point and vector, normal to the plane
+//   Returns: kTrue if helix intersects the plane, kFALSE otherwise.
   
   Double_t s=(planePoint-fX0)*planeNorm,dist=99999,distPrev=dist;//estimates initial distance to plane
 
@@ -73,26 +76,23 @@ Bool_t AliRICHHelix::Intersection(TVector3 planePoint,TVector3 planeNorm)
   }
   return kTRUE;
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Int_t AliRICHHelix::RichIntersect(AliRICHParam *pParam)
 {
 // Searchs for intersection of this helix with all RICH chambers, returns chamber number or 0 if no intersection
-// On exit fPosRad contain position of intersection in Local System with radiator     
+// On exit fPosRad contain position of intersection in radiator LORS (cm)    
 //         fPosPc  contains the same for photocathode  
-  for(Int_t iChamberN=1;iChamberN<=kNchambers;iChamberN++){//chamber loop
-    if(Intersection(pParam->C(iChamberN)->Rad())){//there is intersection with radiator plane
-      fPosRad=pParam->C(iChamberN)->Mrs2Rad(fX);//position on radiator plane
+  for(Int_t iChamN=1;iChamN<=AliRICHParam::kNch;iChamN++){//chamber loop
+    if(Intersection(pParam->Center(iChamN,AliRICHParam::kRad),pParam->Norm(iChamN))){//there is intersection with radiator plane
+      fPosRad=pParam->Mars2Lors(iChamN,fX,AliRICHParam::kRad);//position on radiator plane
       if(pParam->IsAccepted(fPosRad)){//intersection within radiator (even if in dead zone)
         
-        if(Intersection(pParam->C(iChamberN)->Pc())){//there is intersection with photocathode
-          fPosPc=pParam->C(iChamberN)->Mrs2Pc(fX);//position on photcathode plane
+        if(Intersection(pParam->Center(iChamN,AliRICHParam::kPc),pParam->Norm(iChamN))){//there is intersection with photocathode
+          fPosPc=pParam->Mars2Lors(iChamN,fX,AliRICHParam::kPc);//position on radiator plane
           if(pParam->IsAccepted(fPosPc)){//intersection within pc (even if in dead zone)
             
-            Intersection(pParam->C(iChamberN)->Anod()); //search for anod intersection position
-            fPosAnod=pParam->C(iChamberN)->Mrs2Anod(fX);
-            
-            fPloc=pParam->C(iChamberN)->PMrs2Loc(fP);//trasform p to local system
-            return iChamberN;
+            fPloc=pParam->Mars2LorsVec(iChamN,fP);//trasform p to local system
+            return iChamN;
           }//if inside PC
         }//if intersects PC
         
@@ -101,5 +101,5 @@ Int_t AliRICHHelix::RichIntersect(AliRICHParam *pParam)
   }//chamber loop
   return 0;
 }
-//__________________________________________________________________________________________________    
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 #endif
index 3cd4d37..2bd9c2b 100644 (file)
 //  * provided "as is" without express or implied warranty.                  *
 //  **************************************************************************
 
-#include "AliRICHHit.h"
-#include <AliLog.h>
+#include "AliRICHHit.h" //class header
+#include <TPDGCode.h>   //Print() 
  
 ClassImp(AliRICHHit)
 //__________________________________________________________________________________________________
 void AliRICHHit::Print(Option_t*)const
 {
 //Print hit
-  AliInfo(Form("Ch=%1i,TID=%6i,Elos=%9.3f eV,IN(%6.2f,%6.2f,%6.2f)-OUT(%6.2f,%6.2f,%6.2f)=%9.4f"
-      ,fChamber,fTrack,fEloss*1e9,fInX3.X() ,fInX3.Y() ,fInX3.Z(),
-                                  fOutX3.X(),fOutX3.Y(),fOutX3.Z(),Length()));
+  char *sPart=Form("pid=%i",fPid);
+  switch(fPid){
+    case kProton:      sPart="p+  ";break;
+    case kProtonBar:   sPart="a-  ";break;
+    case kKPlus:       sPart="K+  ";break;
+    case kKMinus:      sPart="K-  ";break;
+    case kPiPlus:      sPart="pi+ ";break;
+    case kPiMinus:     sPart="pi- ";break;
+    case kMuonPlus:    sPart="mu+ ";break;
+    case kMuonMinus:   sPart="mu- ";break;
+    case kElectron:    sPart="e-  ";break;
+    case kPositron:    sPart="e+  ";break;
+    case 50000050:     sPart="ckov";break;
+    case 50000051:     sPart="feed";break;
+  }
+
+  Printf("%s TID=%6i,Ch=(%2i),E=%9.3f eV, pos=(%7.2f,%7.2f,%7.2f)cm",sPart,Track(),C(),fE*1e9,fX,fY,fZ);
 }
 //__________________________________________________________________________________________________
index 646931f..a0210cd 100644 (file)
 class AliRICHHit : public AliHit
 {
 public:
-           AliRICHHit()                                                     :AliHit(     ),fChamber(-1),fEloss(-1) {fInX3.SetXYZ(0,0,0);fOutX3.SetXYZ(0,0,0);}
-           AliRICHHit(Int_t c,Int_t tid,TVector3 in,TVector3 out,Double_t e):AliHit(0,tid),fChamber(c ),fEloss(e ) {fInX3=in; fOutX3=out; fX=out.X();fY=out.Y();fZ=out.Z();}
+  AliRICHHit()                                                                         :AliHit(     ),fCham(-1) ,fE(-1),fPid(-1 ){fInX3.SetXYZ(0,0,0);fOutX3.SetXYZ(0,0,0);}
+  AliRICHHit(Int_t c,Int_t tid,TVector3 in,TVector3 out,Double_t e,Int_t pid)          :AliHit(0,tid),fCham(c ) ,fE(e) ,fPid(pid){fInX3=in; fOutX3=out; fX=out.X();fY=out.Y();fZ=out.Z();}
+  AliRICHHit(Int_t tid,Double_t e,Int_t pad,Double_t x,Double_t y,Double_t z,Int_t pid):AliHit(0,tid),fCham(pad),fE(e) ,fPid(pid){fX=x;fY=y;fZ=z;}
+           
   virtual ~AliRICHHit()                                                                                            {}
-
-  Int_t    C()                       const{return fChamber;}              //chamber number 
-  Int_t    Chamber()                 const{return fChamber;}              //chamber number 
-  Float_t  Eloss()                   const{return fEloss;}                //energy lost by track inside amplification gap  
-  TVector3 InX3()                    const{return fInX3;}                 //track position at the faceplane of the gap 
-  TVector3 OutX3()                   const{return fOutX3;}                //track position at the backplane of the gap 
-  Double_t Length()                  const{return (fOutX3-fInX3).Mag();}  //track length inside the amplification gap
-  void     Print(Option_t *option="")const;                               //virtual
+//framework part
+  void     Print(Option_t *option="")const;                               //from TObject to print current status
+//private part  
+  Int_t    C      ()const{return fCham;}                //chamber number 
+  Int_t    Chamber()const{return fCham;}                //chamber number 
+  Int_t    Pad    ()const{return fCham;}                //absolute pad number, definition in AliRICHParam
+  Float_t  Eloss  ()const{return fE;   }                //Eloss for MIP hit or Etot for photon hit
+  TVector3 InX3   ()const{return fInX3;}                //track position at the faceplane of the gap 
+  TVector3 OutX3  ()const{return fOutX3;}               //track position at the backplane of the gap 
+  Double_t Length ()const{return (fOutX3-fInX3).Mag();} //track length inside the amplification gap
 protected:
-  Int_t     fChamber;                      //chamber number
-  Double_t  fEloss;                        //ionisation energy lost in GAP
+  Int_t     fCham;                         //chamber number or in future absolute pad number
+  Double_t  fE;                            //Eloss for MIP or Etot for photon [GeV]
+  Int_t     fPid;                          //PID of particle created this hit
   TVector3  fInX3;                         //position at the entrance of the GAP   
   TVector3  fOutX3;                        //position at the exit of the GAP
-  ClassDef(AliRICHHit,2)                   //RICH hit class
+  ClassDef(AliRICHHit,3)                   //RICH hit class
 };//class AliRICHhit
 #endif
diff --git a/RICH/AliRICHMap.cxx b/RICH/AliRICHMap.cxx
deleted file mode 100644 (file)
index 1236fc0..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/**************************************************************************
- * 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.                  *
- **************************************************************************/
-
-#include "AliRICHMap.h"
-#include "AliRICH.h"
-
-ClassImp(AliRICHMap)
-
-AliRICHMap::AliRICHMap(TClonesArray *pDig)
-{
-// main ctor
-  fDigits=pDig;
-  fNdigits=fDigits->GetEntries();
-  fMap=new TMatrix(1,AliRICHParam::NpadsX(),1,AliRICHParam::NpadsY());
-  Clear("");
-  FillHits();
-}
-//__________________________________________________________________________________________________   
-void  AliRICHMap::FillHits()
-{
-// Loops over the list of digits filling the "pad fired by digits" structure
-  if(!fNdigits) return;    
-  for(Int_t iDigN=0;iDigN<fNdigits;iDigN++){
-    AliRICHDigit *pDig= (AliRICHDigit*)fDigits->At(iDigN);
-    SetHit(pDig->PadX(),pDig->PadY(),iDigN);
-  }
-}
-//__________________________________________________________________________________________________
diff --git a/RICH/AliRICHMap.h b/RICH/AliRICHMap.h
deleted file mode 100644 (file)
index d57edb4..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef AliRICHMap_h
-#define AliRICHMap_h
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice                               */
-
-#include "AliHitMap.h"
-#include <TMatrix.h>
-#include <TMath.h>
-#include <TClonesArray.h>
-
-class AliRICHMap : public AliHitMap 
-{    
-public:
-           AliRICHMap(TClonesArray *pDig);
-  virtual ~AliRICHMap()                          {delete fMap;}
-  void     FillHits();                                                                                             //virtual
-  void     Clear(const char *)                   {fMap->Zero();}                                                   //virtual  
-  void     DeleteHit(Int_t ix,Int_t iy)          {(*fMap)(ix,iy)=0;}                                               //virtual
-  void     SetHit(Int_t ix,Int_t iy,Int_t idigit){(*fMap)(ix,iy)=idigit+1;}                                        //virtual  
-  Int_t    GetHitIndex(Int_t ix,Int_t iy)   const{return (Int_t)TMath::Abs((*fMap)(ix, iy))-1;}                    //virtual
-  TObject* GetHit(Int_t ix,Int_t iy)        const{Int_t idx=GetHitIndex(ix,iy);return(idx <0)?0:fDigits->At(idx);} //virtual
-  void     FlagHit(Int_t ix,Int_t iy)            {(*fMap)(ix, iy)=-TMath::Abs((*fMap)(ix,iy));}                    //virtual
-  Bool_t   ValidateHit(Int_t,Int_t)              {return 1;}                                                       //virtual
-  inline   FlagType TestHit(Int_t ix,Int_t iy);                                                                    //virtual
-  void     Print(const Option_t *)          const{fMap->Print();}                                                  
-protected:
-  TClonesArray *fDigits;                                 //List of digits
-  Int_t         fNdigits;                                //Number of digits
-  TMatrix      *fMap;                                    //hit map
-  ClassDef(AliRICHMap,0)                                 //Implements map as TMatrix
-};
-//__________________________________________________________________________________________________
-FlagType AliRICHMap::TestHit(Int_t padx,Int_t pady)
-{
-//Is there a hit for given pad?
-  Int_t inf=(Int_t)(*fMap)(padx,pady);
-  if(inf<0){//flaged as used
-    return kUsed;
-  }else if(inf==0){//no hit 
-    return kEmpty;
-  }else{//index of not yet used hit
-    return kUnused;
-  }
-}//TestHit()  
-#endif 
index bc62a72..f55c604 100644 (file)
 //  * about the suitability of this software for any purpose. It is          *
 //  * provided "as is" without express or implied warranty.                  *
 //  **************************************************************************
-#include "AliRICHParam.h"
+#include "AliRICHParam.h" //class header
 #include "AliESD.h"
-#include "AliRICHChamber.h"
-#include <TCanvas.h>
+#include <TCanvas.h>      //TestXXX() 
 #include <TLatex.h>
 #include <THStack.h>
 #include <TLegend.h>
 #include <TVector2.h>
 #include <TVector3.h>
 #include <TRotation.h>
-
+#include <AliCDBManager.h> //CdbRead()
+#include <AliCDBStorage.h> //CdbRead()
+#include <AliCDBEntry.h>   //CdbRead()
+#include <AliRunLoader.h>  //Stack()
+#include <AliStack.h>      //Stack()
+#include <TParticle.h>     //Stack()    
+#include "AliRICHHelix.h"  //TestTrans()
 
 ClassImp(AliRICHParam)
-Bool_t   AliRICHParam::fgIsWireSag            =kTRUE;   //take ware sagita into account?
-Bool_t   AliRICHParam::fgIsResolveClusters    =kTRUE;   //do cluster resolving?
-Bool_t   AliRICHParam::fgIsFeedback           =kTRUE;   //generate feedback photons?
-Bool_t   AliRICHParam::fgIsRadioSrc           =kFALSE;  //put radioactive source instead of radiators?
-Bool_t   AliRICHParam::fgIsAerogel            =kFALSE;  //special aerogel configuration
-Bool_t   AliRICHParam::fgIsTestBeam           =kFALSE;  //special test beam configuration
+AliRICHParam * AliRICHParam::fgInstance             =0x0;     //singleton pointer               
+Bool_t         AliRICHParam::fgIsWireSag            =kTRUE;   //take ware sagita into account?
+Bool_t         AliRICHParam::fgIsResolveClusters    =kTRUE;   //do cluster resolving?
+Bool_t         AliRICHParam::fgIsFeedback           =kTRUE;   //generate feedback photons?
+Bool_t         AliRICHParam::fgIsTestBeam           =kFALSE;  //special test beam configuration
 
 Int_t    AliRICHParam::fgHV[kNsectors]        ={2050,2050,2050,2050,2050,2050};
 Int_t    AliRICHParam::fgNsigmaTh             =4;
@@ -46,33 +50,45 @@ Double_t AliRICHParam::fgErrGeom[4][330];                        //
 Double_t AliRICHParam::fgErrLoc[4][330];                         //Chromatic, Geometric and Localization array to parametrize SigmaCerenkov
 Double_t AliRICHParam::fgMass[5]              ={0.00051,0.10566,0.13957,0.49360,0.93828};  
 
-//__________________________________________________________________________________________________
-void AliRICHParam::Print(Option_t*) const
-{
-//print some usefull (hopefully) info on some internal guts of RICH parametrisation 
-  AliInfo(Form("Pads in chamber (%3i,%3i) in sector (%2i,%2i) pad size (%4.2f,%4.2f)",NpadsX(),NpadsY(),NpadsXsec(),NpadsYsec(),PadSizeX(),PadSizeY()));
-  AliInfo(Form("Resolve clusters %i sagita %i Radio source %i Aerogel %i TestBeam %i",
-                IsResolveClusters(),IsWireSag(),IsRadioSrc(),IsAerogel(),IsTestBeam())); 
-  fpChambers->Print();
-}//Print()
-//__________________________________________________________________________________________________
-void AliRICHParam::CreateChambers()
+
+Double_t AliRICHParam::fEckovMin=5.5e-9; //GeV
+Double_t AliRICHParam::fEckovMax=8.5e-9; //GeV
+TF1 AliRICHParam::fgAbsC6F14("RabsC4F14","6512.39*(x<=7.75e-9)+(x>7.75e-9)*0.039/(-0.166+0.063e9*x-8.01e7*x^2+3.39e5*x^3)" ,fEckovMin,fEckovMin); 
+TF1 AliRICHParam::fgAbsSiO2 ("RabsSiO2" ,"333"                                                                             ,fEckovMin,fEckovMin); 
+TF1 AliRICHParam::fgAbsCH4  ("RabsCH4"  ,"6512.39*(x<=7.75e-9)+(x>7.75e-9)*0.039/(-0.166+0.063e9*x-8.01e7*x^2+3.39e5*x^3)" ,fEckovMin,fEckovMin);
+TF1 AliRICHParam::fgAbsAir  ("RabsAir"  ,"500"                                                                             ,fEckovMin,fEckovMin);  //len ???
+TF1 AliRICHParam::fgAbsCF4  ("RabsCF4"  ,"6512.39*(x<=7.75e-9)+(x>7.75e-9)*0.039/(-0.166+0.063e9*x-8.01e7*x^2+3.39e5*x^3)" ,fEckovMin,fEckovMin);
+TF1 AliRICHParam::fgAbsC4F10("RabsC4F10","1+0.25324e-6/(1.84e-4 - (1239.84e-9/x)^-2)"                                      ,fEckovMin,fEckovMin);  //Olav preprint
+TF1 AliRICHParam::fgAbsGel  ("RabsGel"  ,"400"                                                                             ,fEckovMin,fEckovMin);  //len ???
+
+TF1 AliRICHParam::fgIdxAir  ("RidxAir"  ,"1+1e-8*(8342.13 + 2406030/(130-(1.23984e-9/x)^2)+15597/(38.9-(1.23984e-9/x)^2))" ,fEckovMin,fEckovMin);  //???
+TF1 AliRICHParam::fgIdxSiO2 ("RidxSiO2" ,"sqrt(1+46.411/(10.666*10.666-x*x*1e18)+228.71/(18.125*18.125-x*x*1e18))"         ,fEckovMin,fEckovMin);  //TDR p.35
+TF1 AliRICHParam::fgIdxCH4  ("RidxCH4"  ,"1+0.12489e-6/(2.62e-4 - (1239.84e-9/x)^-2)"                                      ,fEckovMin,fEckovMin);  //Olav preprint
+TF1 AliRICHParam::fgIdxG30  ("RidxGel30","1.030"                                                                           ,fEckovMin,fEckovMin);  //???
+TF1 AliRICHParam::fgIdxG28  ("RidxGel28","1.028"                                                                           ,fEckovMin,fEckovMin);  //???
+TF1 AliRICHParam::fgIdxG26  ("RidxGel26","1.026"                                                                           ,fEckovMin,fEckovMin);  //???
+TF1 AliRICHParam::fgIdxG24  ("RidxGel24","1.024"                                                                           ,fEckovMin,fEckovMin);  //???
+TF1 AliRICHParam::fgIdxC4F10("RidxC4F10","1+0.25324e-6/(1.84e-4 - (1239.84e-9/x)^-2)"                                      ,fEckovMin,fEckovMin);  //Olav preprint
+TF1 AliRICHParam::fgIdxCF4  ("RidxCF4"  ,"1+0.12489e-6/(2.62e-4 - (1239.84e-9/x)^-2)"                                      ,fEckovMin,fEckovMin);  //Olav preprint
+
+TF1 AliRICHParam::fgQeApd("QeApd"    ,"0+(x>6e-9)*0.27*(1-exp(-(1e9*x-6)/0.3))"                                            ,fEckovMin,fEckovMin);  //???
+TF1 AliRICHParam::fgQeCsI("AbsApd"   ,"0.03"                                                                               ,fEckovMin,fEckovMin);  //prob
+
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+AliRICHParam::AliRICHParam():TNamed("RichParam","default version") 
 {
-//Create all RICH Chambers on each call. Previous chambers deleted.
-  if(fpChambers) delete fpChambers;
-  if(fgIsTestBeam){ 
-    fpChambers=new TObjArray(1);//test beam configuration 1 chamber
-    fpChambers->AddAt(new AliRICHChamber(0),0);  
-  }else{ 
-    fpChambers=new TObjArray(kNchambers);//normal configuration 7 chambers
-    for(int iChamberN=0;iChamberN<kNchambers;iChamberN++)  fpChambers->AddAt(new AliRICHChamber(iChamberN+1),iChamberN);  
-  }
-  fpChambers->SetOwner();
-}//CreateChambers()
-//__________________________________________________________________________________________________
+// Here all the intitializition is taken place when AliRICHParam::Instance() is invoked for the first time.
+// In particulare, matrices to be used for LORS<->MARS trasnformations are initialized from TGeo structure.    
+// Note that TGeoManager should be already initialized from geometry.root file  
+  for(Int_t iCh=0;iCh<kNchambers;iCh++) fMatrix[iCh]=(TGeoHMatrix*)gGeoManager->GetVolume("ALIC")->GetNode(Form("RICH_%i",iCh+1))->GetMatrix();
+  CdbRead(0,0);
+  fgInstance=this; 
+}//ctor
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Float_t AliRICHParam::AbsCH4(Float_t eV)
 {
-//Evaluate the absorbtion lenght of CH4 for a photon of energy eV in electron-volts
+// Evaluate the absorbtion lenght of CH4 for a photon of energy eV in electron-volts
   const Float_t kLoschmidt=2.686763e19;                                      // LOSCHMIDT NUMBER IN CM-3
   const Float_t kPressure=750.0;          //mm of Hg
   const Float_t kTemperature=283.0;       //K (10 grad C)                               
@@ -92,16 +108,44 @@ Float_t AliRICHParam::AbsCH4(Float_t eV)
     Float_t density=kLoschmidt*kPn/kTn; //CH4 molecular concentration (cm^-3)
     return 1.0/(density*crossSection);
 }//AbsoCH4()
-//__________________________________________________________________________________________________
+//__________________________________________________________________________________________________sss
+void AliRICHParam::CdbRead(Int_t run,Int_t version)
+{
+// This methode read all the calibration information and initialise corresponding fields for requested run number
+// Arguments: run - run number for which to retrieve calibration
+//            version- version number   
+//   Returns: none      
+
+  AliCDBEntry *pEntry=AliCDBManager::Instance()->Get("RICH/RICHConfig/RefIdxC6F14",run,0,version); //try to get from common local storage  
+  if(pEntry){
+    fIdxC6F14=(TF2*)pEntry->GetObject(); delete pEntry;
+  }else{
+    AliWarning("No valid calibarion, the hardcoded will be used!");
+    fIdxC6F14=new TF2("RidxC4F14","sqrt(1+0.554*(1239.84e-9/x)^2/((1239.84e-9/x)^2-5796)-0.0005*(y-20))",5.5e-9,8.5e-9,0,50); //DiMauro mail
+    fIdxC6F14->SetUniqueID(20);//T=20 deg C
+  }
+}//CdbRead()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHParam::Print(Option_t* opt) const
+{
+// print some usefull (hopefully) info on some internal guts of RICH parametrisation 
+  Printf("Pads in chamber (%3i,%3i) in sector (%2i,%2i) pad size (%4.2f,%4.2f)",NpadsX(),NpadsY(),NpadsXsec(),NpadsYsec(),PadSizeX(),PadSizeY());
+  Printf("Resolve clusters %i sagita %i",IsResolveClusters(),IsWireSag()); 
+  
+  for(Int_t i=0;i<kNchambers;i++) fMatrix[i]->Print(opt);
+}//Print()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHParam::TestSeg()
 {
-//Provides a set of pictures to test segementation currently in use.    
+// Provides a set of pictures to test segementation currently in use.    
+// Arguments: none
+//   Returns: none    
   new TCanvas("pads","PC segmentation - pads display",700,600);
   gPad->Range(-5,-5,PcSizeX()+5,PcSizeY()+15);
   TVector p(2);   TVector2 c;    TVector2 b;   //current: pad, pad center, pad boundary
 // list of corners:
-  Double_t x0=0,x1=SectorSizeX(),x2=SectorSizeX()+DeadZone(),                                                                 x3=PcSizeX();  
-  Double_t y0=0,y1=SectorSizeY(),y2=SectorSizeY()+DeadZone(),y3=2*SectorSizeY()+DeadZone(),y4=PcSizeY()-SectorSizeY(),y5=PcSizeY();  
+  Double_t x0=0,x1=SecSizeX(),x2=SecSizeX()+DeadZone()                                                      ,x3=PcSizeX();  
+  Double_t y0=0,y1=SecSizeY(),y2=SecSizeY()+DeadZone(),y3=2*SecSizeY()+DeadZone(),y4=PcSizeY()-SecSizeY(),y5=PcSizeY();  
   DrawSectors();
 //header 
   TLatex t;
@@ -109,7 +153,7 @@ void AliRICHParam::TestSeg()
   t.DrawLatex(0,PcSizeY()+10,Form("IP in front of this page. pad size %.2fx%.2fcm   dead zone %.2fcm",PadSizeX(),PadSizeY(),DeadZone()));
   t.DrawLatex(0,PcSizeY()+ 5,Form("Pc  %.2fx%.2f cm %ix%i pads               Sec %.2fx%.2f cm %ix%i pads",
                                          PcSizeX()     , PcSizeY()     , NpadsX()    , NpadsY()                                 ,
-                                         SectorSizeX() , SectorSizeY() , NpadsXsec() , NpadsYsec()                              ));
+                                         SecSizeX() , SecSizeY() , NpadsXsec() , NpadsYsec()                              ));
 //sectors  
   t.SetTextSize(0.015); t.SetTextColor(kRed); t.SetTextAlign(22);
   c=Pad2Loc( 40, 24); t.DrawText(c.X(),c.Y(),Form("sec 1 (%.2f,%.2f)",c.X(),c.Y()  ));  
@@ -152,7 +196,9 @@ void AliRICHParam::TestSeg()
 //__________________________________________________________________________________________________
 void AliRICHParam::TestResp()
 {
-//Provides a set of plot to check the response parametrisation currently in use.  
+// Provides a set of plot to check the response parametrisation currently in use.  
+// Arguments: none
+//   Returns: none    
   TCanvas *pC=new TCanvas("c","Amplification test",900,800);
   pC->Divide(1,2);
   
@@ -165,13 +211,13 @@ void AliRICHParam::TestResp()
   TH1F *apHmip[kNpoints];
   
   Double_t starty=0;
-  Double_t deltay=AliRICHParam::SectorSizeY()/kNpoints;
+  Double_t deltay=AliRICHParam::SecSizeY()/kNpoints;
   
   for(int i=0;i<kNpoints;i++){
     apHphot[i]=new TH1F(Form("hphot%i",i),"Qdc for Photon;QDC;Counts",500,0,500); apHphot[i]->SetLineColor(i);pStackPhot->Add(apHphot[i]);                 
     apHmip[i] =new TH1F(Form("hmip%i",i),"Qdc for Mip;QDC;Counts",4000,0,4000);   apHmip[i]->SetLineColor(i);pStackMip->Add(apHmip[i]);                 
     
-    pLeg->AddEntry(apHphot[i],Form("@(10,%5.2f->%5.2f)",starty+i*deltay,starty+i*deltay-SectorSizeY()/2));
+    pLeg->AddEntry(apHphot[i],Form("@(10,%5.2f->%5.2f)",starty+i*deltay,starty+i*deltay-SecSizeY()/2));
   }
         
   
@@ -190,34 +236,41 @@ void AliRICHParam::TestResp()
 //__________________________________________________________________________________________________
 void AliRICHParam::TestTrans()
 {
-//Provides a set of plots to test transformation methods
-  new TCanvas("trasform","Test LRS-MRS transform");
-  TLatex t; t.SetTextSize(0.02);
+// Tests transformation methods
+// Arguments: none
+//   Returns: none    
   
-  TView *pView=new TView(1);
-  pView->SetRange(-600,-600,-600,600,600,600);
-  DrawAxis();  
-//Draw PC for all chambers by trasfering Pc plane using Pc2Mrs methode  
+  AliRICHParam *pParam=AliRICHParam::Instance();
   Int_t iNpointsX=50,iNpointsY=50;  
-  for(Int_t iChamberN=1;iChamberN<=7;iChamberN++){//chamber loop
+  new TCanvas("trasform","Test LORS-MARS transform"); TLatex t; t.SetTextSize(0.02);
+  
+  TView *pView=new TView(1);  pView->SetRange(-400,-400,-400,400,400,400);
+  DrawAxis();  
+  for(Int_t iCham=1;iCham<=7;iCham++){//chamber loop
+    AliRICHHelix helix(2.5,Norm(iCham).Theta()*TMath::RadToDeg(),Norm(iCham).Phi()*TMath::RadToDeg());
+    helix.RichIntersect(AliRICHParam::Instance());
     TPolyMarker3D *pChamber=new TPolyMarker3D(iNpointsX*iNpointsY);
     Int_t i=0;
     for(Double_t x=0;x<PcSizeX();x+=PcSizeX()/iNpointsX)
       for(Double_t y=0;y<PcSizeY();y+=PcSizeY()/iNpointsY){//step loop
-        TVector3 v3=C(iChamberN)->Pc2Mrs(TVector2(x,y));//from regular grid of local PC points to MRS presentation
-        pChamber->SetPoint(i++,v3.X(),v3.Y(),v3.Z());//Pc plane poing in MRS
+        TVector3 v3=pParam->Lors2Mars(iCham,x,y,kPc); TVector2 v2=pParam->Mars2Lors(iCham,v3,kPc);//LORS->MARS->LORS
+        Double_t dx=v2.X()-x , dy=v2.Y()-y; 
+        if(dx>0.000001 || dy>0.000001) Printf("Problem in MARS<->LORS transformations dx=%f dy=%f!!!",dx,dy);
+        pChamber->SetPoint(i++,v3.X(),v3.Y(),v3.Z());//Pc plane point in MARS
       }//step loop
     pChamber->SetMarkerSize(1);
-    pChamber->SetMarkerColor(iChamberN);
+    pChamber->SetMarkerColor(iCham);
     pChamber->Draw();  
-    t.SetNDC();t.SetTextColor(iChamberN); t.DrawText(0.1,iChamberN*0.1,Form("Chamber %i",iChamberN));    
-  }//chamber loop   
-//  gPad->GetView()->RotateView(94,45);
+    helix.Draw();
+    t.SetNDC();t.SetTextColor(iCham); t.DrawText(0.1,iCham*0.1,Form("Chamber %i",iCham));    
+  }//chambers loop   
 }//TestTrans()
 //__________________________________________________________________________________________________
 void AliRICHParam::DrawAxis()
 {
-//Utility: draws axis on geometry scene  
+// This utility methode draws axis on geometry scene  
+// Arguments: none
+//   Returns: none    
   Double_t x[6]={0,0,0,300,0,0};  Double_t y[6]={0,0,0,0,300,0};  Double_t z[6]={0,0,0,0,0,300};  
   TPolyLine3D *pXaxis=new TPolyLine3D(2,x);pXaxis->SetLineColor(kRed);   pXaxis->Draw();
   TPolyLine3D *pYaxis=new TPolyLine3D(2,y);pYaxis->SetLineColor(kGreen); pYaxis->Draw();
@@ -226,14 +279,16 @@ void AliRICHParam::DrawAxis()
 //__________________________________________________________________________________________________
 void AliRICHParam::DrawSectors() 
 { 
-//Utility: draws RICH chamber sectors on event display.
-  Double_t xLeft[5]  = {0,0,SectorSizeX(),SectorSizeX(),0};
-  Double_t xRight[5] = {SectorSizeX()+DeadZone(),SectorSizeX()+DeadZone(),PcSizeX(),PcSizeX(),SectorSizeX()+DeadZone()};
+// Utility methode draws RICH chamber sectors on event display.
+// Arguments: none
+//   Returns: none      
+  Double_t xLeft[5]  = {0,0,SecSizeX(),SecSizeX(),0};
+  Double_t xRight[5] = {SecSizeX()+DeadZone(),SecSizeX()+DeadZone(),PcSizeX(),PcSizeX(),SecSizeX()+DeadZone()};
   
-  Double_t yDown[5]   = {0,SectorSizeY(),SectorSizeY(),0,0};
-  Double_t yCenter[5] = {  SectorSizeY()+DeadZone(),2*SectorSizeY()+DeadZone(),2*SectorSizeY()+DeadZone(),
-                           SectorSizeY()+DeadZone(),SectorSizeY()+DeadZone()};  
-  Double_t yUp[5]     = {2*SectorSizeY()+2*DeadZone(),PcSizeY(),PcSizeY(),2*SectorSizeY()+2*DeadZone(),2*SectorSizeY()+2*DeadZone()};
+  Double_t yDown[5]   = {0,SecSizeY(),SecSizeY(),0,0};
+  Double_t yCenter[5] = {  SecSizeY()+DeadZone(),2*SecSizeY()+DeadZone(),2*SecSizeY()+DeadZone(),
+                           SecSizeY()+DeadZone(),SecSizeY()+DeadZone()};  
+  Double_t yUp[5]     = {2*SecSizeY()+2*DeadZone(),PcSizeY(),PcSizeY(),2*SecSizeY()+2*DeadZone(),2*SecSizeY()+2*DeadZone()};
   
   TPolyLine *sec1 = new TPolyLine(5,xLeft ,yDown);    sec1->SetLineColor(21);  sec1->Draw();
   TPolyLine *sec2 = new TPolyLine(5,xRight,yDown);    sec2->SetLineColor(21);  sec2->Draw();
@@ -245,8 +300,9 @@ void AliRICHParam::DrawSectors()
 //__________________________________________________________________________________________________
 void AliRICHParam::ReadErrFiles()
 {
-// Read the three files corresponding to Chrom,Geom and Loc
-// They are parameters of a polynomial of 6th order...
+// Read the three files corresponding to Chrom,Geom and Loc They are parameters of a polynomial of 6th order...  ????????? go to CDB?
+// Arguments: none
+//   Returns: none    
   
   static Bool_t count = kFALSE;
   
@@ -301,7 +357,7 @@ TVector3 AliRICHParam::SigmaSinglePhoton(Int_t partID, Double_t mom, Double_t th
   Double_t massRef = fgMass[4]; // all the files are calculated for protons...so mass ref is proton mass
   pmom = mom*massRef/mass; // normalized momentum respect to proton...
   if(pmom>PmodMax()) pmom = PmodMax();
-  Double_t oneOverRefIndex = 1/RefIdxC6F14(MeanCkovEnergy());
+  Double_t oneOverRefIndex = 1/IdxC6F14(EckovMean());
   Double_t pmin = mass*oneOverRefIndex/TMath::Sqrt(1-oneOverRefIndex*oneOverRefIndex);
   if(pmom<pmin) return v;
   Double_t Theta = theta*TMath::RadToDeg();
@@ -326,7 +382,7 @@ TVector3 AliRICHParam::SigmaSinglePhoton(Double_t thetaCer, Double_t theta, Doub
 
   ReadErrFiles();
   Double_t massRef = fgMass[4]; // all the files are calculated for protons...so mass ref is proton mass
-  Double_t beta=1./(RefIdxC6F14(MeanCkovEnergy())*TMath::Cos(thetaCer));
+  Double_t beta=1./(IdxC6F14(EckovMean())*TMath::Cos(thetaCer));
   if(beta>=1) {
     pmom=6.5; // above physical limi the error is calculated at the saturation...
   } else {
@@ -334,7 +390,7 @@ TVector3 AliRICHParam::SigmaSinglePhoton(Double_t thetaCer, Double_t theta, Doub
     pmom = beta*gamma*massRef; // normalized momentum respect to proton...
   }
   if(pmom>PmodMax()) pmom = PmodMax();
-  Double_t oneOverRefIndex = 1/RefIdxC6F14(MeanCkovEnergy());
+  Double_t oneOverRefIndex = 1/IdxC6F14(EckovMean());
   Double_t pmin = massRef*oneOverRefIndex/TMath::Sqrt(1-oneOverRefIndex*oneOverRefIndex);
   if(pmom<pmin) return v;
   Double_t Theta = theta*TMath::RadToDeg();
@@ -380,37 +436,32 @@ Double_t AliRICHParam::Interpolate(Double_t par[4][330], Double_t x, Double_t y,
 //__________________________________________________________________________________________________
 TVector3 AliRICHParam::ForwardTracing(TVector3 entranceTrackPoint, TVector3 vectorTrack, Double_t thetaC, Double_t phiC)
 {
-//
+// Trace a single Ckov photon from a given emission point up to photocathode taking into account ref indexes of materials it travereses
   TVector3 vBad(-999,-999,-999);
   TVector3 nPlane(0,0,1);
-  Double_t planeZposition = 0.5*Zfreon();
-  TVector3 planePoint(0,0,planeZposition);
+  Double_t planeZposition = 0.5*RadThick();
+  TVector3 planePoint(0,0,0.5*RadThick()); //this is plane parallel to window which contains emission point 
   TVector3 emissionPoint = PlaneIntersect(vectorTrack,entranceTrackPoint,nPlane,planePoint);
-//  emissionPoint.Dump();
   Double_t thetaout,phiout;
   AnglesInDRS(vectorTrack.Theta(),vectorTrack.Phi(),thetaC,phiC,thetaout,phiout);
-//  cout << "thetaout "<<thetaout << " phiout " << phiout << endl;
   TVector3 vectorPhotonInC6F14;  
   vectorPhotonInC6F14.SetMagThetaPhi(1,thetaout,phiout);
-//  vectorPhotonInC6F14.Dump();
-//  planeZposition=AliRICHParam::C6F14Thickness();
-  planeZposition=Zfreon();
+  planeZposition=RadThick();
   planePoint.SetXYZ(0,0,planeZposition);
   TVector3 entranceToSiO2Point = PlaneIntersect(vectorPhotonInC6F14,emissionPoint,nPlane,planePoint);
-//  entranceToSiO2Point.Dump();
 
-  Double_t photonEn = MeanCkovEnergy();
-  Double_t angleInSiO2 = SnellAngle(RefIdxC6F14(photonEn),RefIdxSiO2(photonEn),vectorPhotonInC6F14.Theta());if(angleInSiO2<0) return vBad;
+  Double_t photonEn = EckovMean();
+  Double_t angleInSiO2 = SnellAngle(IdxC6F14(EckovMean()),IdxSiO2(EckovMean()),vectorPhotonInC6F14.Theta());if(angleInSiO2<0) return vBad;
   TVector3 vectorPhotonInSiO2;
   vectorPhotonInSiO2.SetMagThetaPhi(1,angleInSiO2,phiout);
 //  planeZposition+=AliRICHParam::SiO2Thickness();
-  planeZposition+=Zwin();
+  planeZposition+=WinThick();
   planePoint.SetXYZ(0,0,planeZposition);
   TVector3 entranceToCH4 = PlaneIntersect(vectorPhotonInSiO2,entranceToSiO2Point,nPlane,planePoint);
 //  entranceToCH4.Dump();
 
   //  Double_t angleInCH4 = SnellAngle(AliRICHParam::IndOfRefSiO2(6.755),AliRICHParam::IndOfRefCH4,angleInSiO2);
-  Double_t angleInCH4 = SnellAngle(RefIdxSiO2(photonEn),RefIdxCH4(photonEn),vectorPhotonInSiO2.Theta());if(angleInCH4<0) return vBad;
+  Double_t angleInCH4 = SnellAngle(IdxSiO2(photonEn),IdxCH4(photonEn),vectorPhotonInSiO2.Theta());if(angleInCH4<0) return vBad;
   TVector3 vectorPhotonInCH4;
   vectorPhotonInCH4.SetMagThetaPhi(1,angleInCH4,phiout);
 //  planeZposition+=AliRICHParam::GapProx();
@@ -421,39 +472,28 @@ TVector3 AliRICHParam::ForwardTracing(TVector3 entranceTrackPoint, TVector3 vect
   return impactToPC;
 }//FowardTracing
 //__________________________________________________________________________________________________
-TVector3 AliRICHParam::PlaneIntersect(TVector3 vstart,TVector3 p0,TVector3 n,TVector3 v0)
+TVector3 AliRICHParam::PlaneIntersect(const TVector3 &lineDir,const TVector3 &linePoint,const TVector3 &planeNorm,const TVector3 &planePoint)
 {
-//
-  TVector3 parallel(-999,-999,-999);
-  // vstart = given vector
-  // p0 = origin of the given vector
-  // n = normal to a given plane
-  // v0 = point of the given plane
-//  cout << " n*vstart = " << n*vstart << endl;
-  if(n*vstart==0) return parallel;
-  TVector3 diff=v0-p0;
-  Double_t sint=(n*diff)/(n*vstart);
-  return p0+sint*vstart;
+// Finds an intersection point between a line and plane.
+// Arguments:  lineDir,linePoint    - vector along the line and any point of the line
+//             planeNorm,planePoint - vector normal to the plane and any point of the plane
+//   Returns:  point of intersection if any
+  if(planeNorm*lineDir==0) return   TVector3(-999,-999,-999);
+  TVector3 diff=planePoint-linePoint;
+  Double_t sint=(planeNorm*diff)/(planeNorm*lineDir);
+  return linePoint+sint*lineDir;
 }//PlaneIntersect
 //__________________________________________________________________________________________________ 
 Double_t AliRICHParam::SnellAngle(Float_t n1, Float_t n2, Float_t theta1)
 {
-// Snell law
-// Compute the Snell angle
-
-  Double_t sinrefractangle;
-  Double_t refractangle;
-
-  sinrefractangle = (n1/n2)*sin(theta1);
-
-  if(sinrefractangle>1.) {
-    //    cout << " PROBLEMS IN SNELL ANGLE !!!!! " << endl;
-    refractangle = -999.;
-    return refractangle;
-  }
-
-  refractangle = asin(sinrefractangle);
-  return refractangle;
+// Compute the angle of refraction out of Snell law
+// Arguments: n1 - ref idx of first substance  
+//            n2 - ref idx of second substance  
+//            n1 - photon impact angle in the first substance i.e. angle between the photon direction and vector normal to the surface (radians)
+//   Returns: photon refraction angle, i.e. angle in the second substance (radians)
+  Double_t sinref=(n1/n2)*TMath::Sin(theta1);
+  if(sinref>1.)    return -999;  
+  else             return TMath::ASin(sinref);
 }//SnellAngle
 //__________________________________________________________________________________________________
 void AliRICHParam::AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t thetaCerenkov,Double_t phiCerenkov,Double_t &tout,Double_t &pout)
@@ -479,10 +519,6 @@ void AliRICHParam::AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t th
   tout=photonInRadiator.Theta();
   pout=photonInRadiator.Phi();
 }//AnglesInDRS
-//__________________________________________________________________________________________________
-
-//__________________________________________________________________________________________________
-//__________________________________________________________________________________________________
 /*
 void DrawRing()
 {
@@ -532,3 +568,73 @@ void DrawRing()
 }
 //__________________________________________________________________________________________________
 */
+void AliRICHParam::TestHit2SDigs(Double_t x,Double_t y,Double_t e,Bool_t isNew)
+{
+//Test  hit->sdigits procedures
+//Arguments: isNew - if true use new (abs pad) procedure else use old one (TVector)
+//  Returns: none
+  TClonesArray *pSDigLst=new TClonesArray("AliRICHDigit");
+  Int_t iQtot=-1;
+  if(isNew){
+    iQtot=Hit2SDigs(10101,e,pSDigLst);        //new technique
+  }else{
+    iQtot=Hit2SDigs(TVector2(x,y),e,pSDigLst);//old technique
+  }
+  pSDigLst->Print();
+  Double_t dQsum=0;
+  for(Int_t i=0;i<pSDigLst->GetEntriesFast();i++)
+    dQsum+=((AliRICHDigit*)pSDigLst->At(i))->Qdc();
+  Printf("Qtot=%i Qsum=%.2f ",iQtot,dQsum);
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHParam::Stack(Int_t evt,Int_t tid)
+{
+// Prints some usefull info from stack
+// Arguments: evt - event number. if not -1 print info only for that event
+//            tid - track id. if not -1 then print it and all it's mothers if any   
+//   Returns: mother tid of the given tid if any
+  AliRunLoader *pAL=AliRunLoader::Open(); 
+  if(pAL->LoadHeader()) return -1;
+  if(pAL->LoadKinematics()) return -1;
+  
+  Int_t mtid=-1;
+  Int_t iNevt=pAL->GetNumberOfEvents();     Printf("This session contains %i event(s)",iNevt);
+  
+  for(Int_t iEvt=0;iEvt<iNevt;iEvt++){//events loop
+    if(evt!=-1 && evt!=iEvt) continue; //in case one needs to print the requested event, ignore all others
+    pAL->GetEvent(iEvt);    
+    AliStack *pStack=pAL->Stack();  
+    if(tid==-1){                        //print all tids for this event
+      for(Int_t i=0;i<pStack->GetNtrack();i++) pStack->Particle(i)->Print();
+      Printf("totally %i tracks including %i primaries for event %i out of %i event(s)",pStack->GetNtrack(),pStack->GetNprimary(),iEvt,iNevt);
+    }else{                              //print only this tid and it;s mothers
+      if(tid<0 || tid>pStack->GetNtrack()) {Printf("Wrong tid, valid tid range for event %i is 0-%i",iEvt,pStack->GetNtrack());break;}
+      TParticle *pTrack=pStack->Particle(tid); mtid=pTrack->GetFirstMother();
+      TString str=pTrack->GetName();
+      while((tid=pTrack->GetFirstMother()) >= 0){
+        pTrack=pStack->Particle(tid);
+        str+=" from ";str+=pTrack->GetName();
+      } 
+      Printf("%s",str.Data());       
+    }//if(tid==-1)      
+  }//events loop
+  pAL->UnloadHeader();  pAL->UnloadKinematics();
+  return mtid;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHParam::StackCount(Int_t pid,Int_t evt)
+{
+// Counts total number of particles of given sort (including secondary) for a given event
+  AliRunLoader *pAL=AliRunLoader::Open(); 
+  pAL->GetEvent(evt);    
+  if(pAL->LoadHeader()) return 0;
+  if(pAL->LoadKinematics()) return 0;
+  AliStack *pStack=pAL->Stack();
+  
+  Int_t iCnt=0;
+  for(Int_t i=0;i<pStack->GetNtrack();i++) if(pStack->Particle(i)->GetPdgCode()==pid) iCnt++;
+  
+  pAL->UnloadHeader();  pAL->UnloadKinematics();
+  return iCnt;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index 02d7c5e..90ef9a7 100644 (file)
@@ -1,20 +1,19 @@
 #ifndef AliRICHParam_h
 #define AliRICHParam_h
 
-#include <TError.h>
-#include <TMath.h>
-#include <TObjArray.h>
-#include <TObject.h>
-#include <TMath.h>
-#include <TRandom.h>
-#include <TVector.h>
+#include <TNamed.h>       //base class
+#include <TMath.h>        //QdcTot()  
+#include <TVector.h>      //old style
 #include <TVector2.h>
 #include <TVector3.h>
 #include <TRandom.h>
-#include <TError.h>
-#include <TObjArray.h>
+#include <TClonesArray.h>  //Hit2SDigs()
 #include <AliLog.h>
-#include <TClass.h>
+#include <TGeoMatrix.h>    //Mars2Lors() Lors2Mars() 
+#include <TF1.h>           //fields
+#include <TF2.h>           //fields
+#include "AliRICHDigit.h"  //Hit2Sdigs()
+#include <TGeoManager.h>   //Instance()
 
 static const int kNchambers=7;     //number of RICH chambers 
 static const int kNpadsX = 160;    //number of pads along X in single chamber
@@ -24,65 +23,68 @@ static const int kNsectors=6;      //number of sectors per chamber
 static const int kCerenkov=50000050;  //??? go to something more general like TPDGCode
 static const int kFeedback=50000051;  //??? go to something more general like TPDGCode
 
-class AliRICHChamber;
-
 // Class providing all the needed parametrised information
 // to construct the geometry, to define segmentation and to provide response model
 // In future will also provide all the staff needed for alignment and calibration
 
 
-class AliRICHParam :public TObject  
+class AliRICHParam :public TNamed  
 {
 public:
 //ctor&dtor    
-                  AliRICHParam():TObject(),fpChambers(0)  {CreateChambers();}
-  virtual        ~AliRICHParam()                          {delete fpChambers;}
+  virtual        ~AliRICHParam()                                    {delete fIdxC6F14;fgInstance=0;}
 //test methodes  
          void     Print(Option_t *opt="") const;                                         //print current parametrization
-         void     Test()                            {TestSeg();TestTrans();TestResp();}  //test all groups of methodes
-         void     TestResp();                                                            //test the response group of methodes
-         void     TestSeg();                                                             //test the segmentation group of methodes
-         void     TestTrans();                                                           //test the transform group of methodes
   static void     DrawAxis();
   static void     DrawSectors();
 //flags staff         
-  static           void     SetAerogel(Bool_t a)                   {fgIsAerogel=a;}
-  static           Bool_t   IsAerogel()                            {return fgIsAerogel;}
-  static           void     SetRadioSrc(Bool_t a)                   {fgIsRadioSrc=a;}
-  static           Bool_t   IsRadioSrc()                            {return fgIsRadioSrc;}
-  static              void     SetTestBeam(Bool_t a)                {fgIsTestBeam=a;}
-  static              Bool_t   IsTestBeam()                         {return fgIsTestBeam;}
+  static inline AliRICHParam* Instance();                                //pointer to AliRICHParam singleton
   static                void     SetWireSag(Bool_t a)               {fgIsWireSag=a;}
   static                Bool_t   IsWireSag()                        {return fgIsWireSag;}
   static                   void     SetResolveClusters(Bool_t a)    {fgIsResolveClusters=a;}
   static                   Bool_t   IsResolveClusters()             {return fgIsResolveClusters;}
-//Chambers manipulation  methodes 
-  void            CreateChambers();                                                      //form chamber structure  
-  AliRICHChamber* C(Int_t i)                 {return (AliRICHChamber*)fpChambers->UncheckedAt(i-1);}      //returns pointer to chamber i
-  Int_t           Nchambers()                {return fpChambers->GetEntriesFast();}      //returns number of chambers 
+  static        Int_t      Stack(Int_t evt=-1,Int_t tid=-1);              //Print stack info for event and tid
+  static        Int_t      StackCount(Int_t pid,Int_t evt);               //Counts stack particles of given sort in given event  
+  static inline Double_t   ErrLoc                  (Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta);
+  static inline Double_t   ErrGeom                 (Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta);
+  static inline Double_t   ErrCrom                 (Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta);
+  static inline TVector3   SigmaSinglePhotonFormula(Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta);
 //Geometrical properties  
-  static        Int_t      NpadsX()                   {return kNpadsX;}                           //pads along X in chamber
-  static        Int_t      NpadsY()                   {return kNpadsY;}                           //pads along Y in chamber
-  static        Int_t      NpadsXsec()                {return NpadsX()/2;}                        //pads along X in sector
-  static        Int_t      NpadsYsec()                {return NpadsY()/3;}                        //pads along Y in sector
-  static        Double_t   DeadZone()                 {return 2.6;}                               //dead zone size in cm  
-  static        Double_t   SectorSizeX()              {return NpadsX()*PadSizeX()/2;}             //sector size x, cm
-  static        Double_t   SectorSizeY()              {return NpadsY()*PadSizeY()/3;}             //sector size y, cm 
-  static        Double_t   PcSizeX()                  {return NpadsX()*PadSizeX()+DeadZone();}    //PC size x, cm
-  static        Double_t   PcSizeY()                  {return NpadsY()*PadSizeY()+2*DeadZone();}  //PC size y, cm
-  static        Double_t   Zfreon()                   {return 1.5;}                               //freon thinkness, cm
-  static        Double_t   Zwin()                     {return 0.5;}                               //radiator quartz window, cm   
-  static        Double_t   Pc2Win()                   {return 8.0;}                               //cm between CsI PC and radiator quartz window
-  static        Double_t   Pc2Coll()                  {return 7.0;}                               //cm between CsI PC and third wire grid (collection wires)     
-  static        Double_t   Pc2Anod()                  {return 0.204;}                             //cm between CsI PC and first wire grid (anod wires)     
-  static        Double_t   Pc2Cath()                  {return 0.445;}                             //cm between CsI PC and second wire grid (cathode wires)
-  static        Double_t   Freon2Pc()                 {return Zfreon()+Zwin()+Pc2Win();}          //cm between CsI PC and entrance to freon
-  static        Double_t   PitchAnod()                {return PadSizeY()/2;}                      //cm between anode wires
-  static        Double_t   PitchCath()                {return PadSizeY()/4;}                      //cm between cathode wires
-  static        Double_t   PitchColl()                {return 0.5;}                               //cm between collection wires
-  static        Double_t   PadSizeX()                 {return 0.8;}                               //pad size x, cm 
-  static        Double_t   PadSizeY      (                               ){return 0.84;}                              //pad size y, cm   
+  static        Int_t      NpadsX      ()   {return kNpadsX;}                           //number of pads along X in chamber
+  static        Int_t      NpadsY      ()   {return kNpadsY;}                           //number of pads along Y in chamber
+  static        Int_t      NpadsXsec   ()   {return NpadsX()/2;}                        //number of pads along X in sector
+  static        Int_t      NpadsYsec   ()   {return NpadsY()/3;}                        //number of pads along Y in sector
+  
+  static        Double_t   AnodPitch   ()   {return PadSizeY()/2;}                      //cm between anode wires
+  static        Double_t   AnodZ       ()   {return 7.806;}                             //Z positon of anod plane in LORS of the chamber, [cm]
+  static        Double_t   CathPitch   ()   {return PadSizeY()/4;}                      //dist between cathode wires [cm]
+  static        Double_t   CollPitch   ()   {return 0.5;}                               //dist between collection wires [cm]
+  static        Double_t   DeadZone    ()   {return 2.6;}                               //dead zone thickness [cm]  
+  static        Double_t   PadSizeX    ()   {return 0.8;}                               //pad size x [cm] 
+  static        Double_t   PadSizeY    ()   {return 0.84;}                              //pad size y [cm]   
+  static        Double_t   PcSizeX     ()   {return NpadsX()*PadSizeX()+DeadZone();}    //PC size x [cm]
+  static        Double_t   PcSizeY     ()   {return NpadsY()*PadSizeY()+2*DeadZone();}  //PC size y [cm]
+  static        Double_t   Pc2Cath     ()   {return 0.445;}                             //dist between PC entrance plane and cathode wires plane [cm]
+  static        Double_t   Pc2Win      ()   {return PcZ();}                             //dist between PC entrance plane and window exit plane [cm]
+  static        Double_t   PcZ         ()   {return 8.0;  }                             //Z positon of PC entrance plane in LORS of the chamber [cm]
+  static        Double_t   RadThick    ()   {return 1.5;}                               //radiator thickness [cm]
+  static        Double_t   RadZ        ()   {return -2.0; }                             //Z positon of radiator entrance plane in LORS of the chamber [cm]
+  static        Double_t   SecSizeX    ()   {return NpadsX()*PadSizeX()/2;}             //sector size x [cm]
+  static        Double_t   SecSizeY    ()   {return NpadsY()*PadSizeY()/3;}             //sector size y [cm ]
+  static        Double_t   WinThick    ()   {return 0.5;}                               //radiator window thickness [cm]   
+  
+  
 //trasformation methodes
+         inline TVector3   Lors2Mars     (Int_t c,Double_t x,Double_t y,Int_t p=kPc); //LORS->MARS transform of point [cm] for chamber c and plane p
+         inline TVector2   Mars2Lors     (Int_t c,const TVector3 &x    ,Int_t p=kPc); //MARS->LORS transform of point [cm] for chamber c and plane p    
+  
+  static inline TVector3   Lors2MarsOld  (Int_t c,Double_t x,Double_t y,Int_t p); //LORS->MARS transform of position (cm) for chamber c and plane p
+  static inline TVector2   Mars2LorsOld  (Int_t c,const TVector3 &x,Int_t p    ); //MARS->LORS transform of position (cm) for chamber c and plane p    
+  static inline TVector3   Mars2LorsVec  (Int_t c,const TVector3 &p            ); //MARS->LORS transform of vector for chamber c
+  static inline TVector3   Center        (Int_t c,Int_t p                      ); //Center of plane p of chamber c in MARS (cm)
+  static inline TVector3   Norm          (Int_t c                              ); //Norm vector to the chamber c in MARS (cm)
+  static inline TGeoMatrix*Matrix        (Int_t iCh, Int_t iPlane              ); //TGeoMatrix for the given chamber plain
+  
   static        Int_t      Pad2Cha       (Int_t pad                      ){return pad/100000000;                     }//abs pad -> chamber
   static        Int_t      Pad2Sec       (Int_t pad                      ){return pad%100000000/1000000;             }//abs pad -> sector
   static        Int_t      Pad2PadX      (Int_t pad                      ){return pad%1000000/1000;                  }//abs pad -> pad x 
@@ -100,21 +102,34 @@ public:
   static inline Int_t      PadNeighbours (Int_t iPadX,Int_t iPadY,Int_t aListX[4],Int_t aListY[4]);                   //pad -> list of it neighbours
   static        Bool_t     IsAccepted    (const TVector2 &x2             ){return ( x2.X()>=0 && x2.X()<=PcSizeX() && x2.Y()>=0 && x2.Y()<=PcSizeY() ) ? kTRUE:kFALSE;}
 //optical properties methodes  
-  static        Double_t   MeanCkovEnergy(                               ){return 6.766;}                 //mean Ckov energy according to the total trasmission curve
-  static        Float_t    PhotonEnergy  (Int_t i                        ){return 0.1*i+5.5;}                         //photon energy (eV) for i-th point
-  static        Float_t    AbsCH4        (Float_t ev                     );                                           //CH4 abs len (cm) 
-  static        Float_t    AbsGel        (Float_t                        ){return 500;}                               //Aerogel abs len (cm)
-  static        Float_t    RefIdxC6F14   (Float_t eV                     ){return eV*0.0172+1.177;}                   //Freon ref idx
-  static        Float_t    RefIdxCH4     (Float_t                        ){return 1.000444;}                          //Methane ref idx 
-  static        Float_t    RefIdxSiO2    (Float_t eV                     ){Float_t e1=10.666,e2=18.125,f1=46.411,f2= 228.71; return TMath::Sqrt(1.+f1/(e1*e1-eV*eV)+f2/(e2*e2-eV*eV));}//Quartz window ref index from TDR p.35
-  static        Float_t    RefIdxGel     (Float_t                        ){return 1.05;}                              //aerogel ref index 
-  static        Float_t    DenGel        (                               ){return (RefIdxGel(0)-1)/0.21;}             //aerogel density gr/cm^3 parametrization by E.Nappi
-
+  static        Float_t    EckovMean     (                               ){return 6.766e-9;}                          //mean Ckov energy according to the total trasmission curve
+  static        Float_t    EckovMin      (                               ){return fEckovMin;}                         //min photon energy [GeV] defined in optical curves
+  static        Float_t    EckovMax      (                               ){return fEckovMax;}                         //min photon energy [GeV] defined in optical curves
+  
+  static        Float_t    AbsCH4        (Float_t gev                    );                                           //AbsLen [cm]=f(Eckov) [GeV] for CH4 used as amp gas
+  static        Float_t    AbsGel        (Float_t gev                    ){return fgAbsGel.Eval(gev);}                //AbsLen [cm]=f(Eckov) [GeV] for aerogel
+  static        Float_t    AbsAir        (Float_t gev                    ){return fgAbsAir.Eval(gev);}                //AbsLen [cm]=f(Eckov) [GeV] for air
+  
+                Float_t    IdxC6F14      (Float_t gev                    ){return fIdxC6F14->Eval(gev,fIdxC6F14->GetUniqueID());}  //n=f(Eckov) [GeV] for C6H14 used as radiator
+  static        Float_t    IdxSiO2       (Float_t gev                    ){return fgIdxSiO2 .Eval(gev);}              //n=f(Eckov) [GeV] for SiO2 used as window TDR p.35
+  static        Float_t    IdxCH4        (Float_t gev                    ){return fgIdxCH4  .Eval(gev);}              //n=f(Eckov) [GeV] for CF4 
+  static        Float_t    IdxG24        (Float_t gev                    ){return fgIdxG24  .Eval(gev);}              //n=f(Eckov) [GeV] for aerogel @1.024
+  static        Float_t    IdxG26        (Float_t gev                    ){return fgIdxG26  .Eval(gev);}              //n=f(Eckov) [GeV] for aerogel @1.026
+  static        Float_t    IdxG28        (Float_t gev                    ){return fgIdxG28  .Eval(gev);}              //n=f(Eckov) [GeV] for aerogel @1.028
+  static        Float_t    IdxG30        (Float_t gev                    ){return fgIdxG30  .Eval(gev);}              //n=f(Eckov) [GeV] for aerogel @1.030
+  static        Float_t    IdxAir        (Float_t gev                    ){return fgIdxAir  .Eval(gev);}              //n=f(Eckov) [GeV] for air
+  static        Float_t    IdxCF4        (Float_t gev                    ){return fgIdxCF4  .Eval(gev);}              //n=f(Eckov) [GeV] for CF4 
+  
+  static        Float_t    QeApd         (Float_t gev                    ){return fgQeApd  .Eval(gev);}               //Q.E.=f(Eckov) [GeV] for APD
+  static        Float_t    QeCsI         (Float_t gev                    ){return fgQeCsI  .Eval(gev);}               //Q.E.=f(Eckov) [GeV] for CsI
+  
+                void       CdbRead   (Int_t run,Int_t version           );                                           //read all calibration information for requested run
   
   static Double_t IonisationPotential()      {return 26.0e-9;}                            //for CH4 in GeV taken from ????
   static TVector2 MathiesonDelta()           {return TVector2(5*0.18,5*0.18);}            //area of 5 sigmas of Mathieson distribution (cm)
   static Int_t    MaxQdc()                   {return 4095;}                               //QDC number of channels          
 
+  
   static Int_t    QthMIP()                   {return 100;}
   static Double_t DmatchMIP()                {return 1.;}
   static Double_t PmodMax()                  {return 6.5;}
@@ -122,15 +137,26 @@ public:
   static void     SetHV(Int_t sector,Int_t hv){fgHV[sector-1]=hv;}  
 //charge response methodes  
   inline static Double_t Mathieson(Double_t x1,Double_t x2,Double_t y1,Double_t y2);               //Mathienson integral over given limits
+  
   inline static Double_t GainSag(Double_t x,Int_t sector);                                         //gain variations in %
-         static Double_t QdcSlope(Int_t sec){switch(sec){case -1: return 0;  default:   return 33;}} //weight of electon in QDC channels
          static Double_t Gain(const TVector2 &x2){//gives chamber gain in terms of QDC channels for given point in local ref system
                           if(fgIsWireSag) return QdcSlope(Loc2Sec(x2))*(1+GainSag(x2.X(),Loc2Sec(x2))/100);
                           else            return QdcSlope(Loc2Sec(x2));}
   inline static Double_t FracQdc(const TVector2 &x2,const TVector &pad);                           //charge fraction to pad from hit
-  inline static Int_t    TotQdc(TVector2 x2,Double_t eloss);                                       //total charge for Eloss (GeV) 0 for photons
+  inline static Int_t    TotQdc(TVector2 x2,Double_t e    );                                       //total charge for Eloss (GeV) 0 for photons
+         static Double_t QdcSlope(Int_t sec){switch(sec){case -1: return 0;  default:   return 33;}} //weight of electon in QDC channels
+  
+  static inline Int_t    Lors2Pad      (Double_t x,Double_t y                         );                                            //LORS (x,y) [cm] -> abs pad number        
+  static        Double_t IonPot        (                                              ){return 26.0e-9;}                            //for CH4 in GeV taken from ????
+  static inline Int_t    QdcTot        (Int_t iPad,Double_t e                         );                                            //total QDC generated by Eloss or Etot [GeV]
+  static inline Double_t QdcSag        (Int_t iPad                                    );                                            //mean QDC variation due to sagita [0,1]
+  static        Double_t QdcEle        (Int_t iPad                                    ){return fgIsWireSag?33*(1+QdcSag(iPad)):33;} //mean QDC per electron
+  static inline Int_t    Hit2SDigs     (Int_t iPad,  Double_t e,TClonesArray* pSDigLst);                                            //hit->sdigits, returns Qtot
+  static inline Int_t    Hit2SDigs     (TVector2 hit,Double_t e,TClonesArray* pSDigLst);                                            //hit->sdigits, returns Qtot, old style
+  static        void     TestHit2SDigs (Double_t x,Double_t y,Double_t e,Bool_t isNew=kFALSE);                                      //test hit->sdigits
+  
   inline static Bool_t   IsOverTh(Int_t c,TVector pad,Double_t q);                                 //is QDC of the pad registered by FEE  
-         static Int_t    NsigmaTh()                    {return fgNsigmaTh;}                        //
+           static Int_t    NsigmaTh()                    {return fgNsigmaTh;}                        //
          static Float_t  SigmaThMean()                 {return fgSigmaThMean;}                     //QDC electronic noise mean
          static Float_t  SigmaThSpread()               {return fgSigmaThSpread;}                   //QDC electronic noise width
                 
@@ -138,37 +164,78 @@ public:
                                                     -2.66575e-3*TMath::Sin(4*TMath::Pi()/PadSizeX()*x)
                                                     +2.80553e-3*TMath::Sin(6*TMath::Pi()/PadSizeX()*x)+0.0070;}
          static void     ReadErrFiles();                                                                  //Read Err file parameters
-         static TVector3 SigmaSinglePhoton(Int_t Npart, Double_t mom, Double_t theta, Double_t phi);      //Find Sigma for single photon from momentum and particle id
-         static TVector3 SigmaSinglePhoton(Double_t thetaCer, Double_t theta, Double_t phi);              //Fing sigma for single photon from thetacer
-         static Double_t Interpolate(Double_t par[4][330],Double_t x, Double_t y, Double_t phi);          //Find the error value from interpolation
-         
-         static TVector3 ForwardTracing(TVector3 entranceTrackPoint,TVector3 vectorTrack, Double_t thetaC, Double_t phiC); //it traces foward a photon from Emission Point to PC
-         static TVector3 PlaneIntersect(TVector3 vstart,TVector3 p0,TVector3 n,TVector3 v0);              //it finds intersection between straight track and plane
-         static Double_t SnellAngle(Float_t n1, Float_t n2, Float_t theta1);                              // Snell law
-         static void     AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t thetaCerenkov,Double_t phiCerenkov,Double_t &tout,Double_t &pout);//It finds photon angles in 
-                                                                                                                                                      //Detector Reference System
-
-  static Bool_t     fgIsAerogel;                            //aerogel geometry instead of normal RICH flag
+         TVector3 SigmaSinglePhoton(Int_t Npart, Double_t mom, Double_t theta, Double_t phi);      //Find Sigma for single photon from momentum and particle id
+         TVector3 SigmaSinglePhoton(Double_t thetaCer, Double_t theta, Double_t phi);              //Fing sigma for single photon from thetacer
+  static Double_t Interpolate(Double_t par[4][330],Double_t x, Double_t y, Double_t phi);          //Find the error value from interpolation
+       
+         TVector3 ForwardTracing(TVector3 entranceTrackPoint,TVector3 vectorTrack, Double_t thetaC, Double_t phiC); //it traces foward a photon from Emission Point to PC
+  static TVector3 PlaneIntersect(const TVector3 &lineDir,const TVector3 &linePoint,const TVector3 &planeNorm,const TVector3 &planePoint); //intersection between line and plane
+  static Double_t SnellAngle(Float_t n1, Float_t n2, Float_t theta1);                              // Snell law
+  static void     AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t thetaCerenkov,Double_t phiCerenkov,Double_t &tout,Double_t &pout);//It finds photon angles in 
+  static        Double_t AlphaFeedback(Int_t c,Int_t s) {c++;s++; return 0.02;} //for sector s of chamber c
+//test part  
+  static void     Test()                            {TestSeg();TestTrans();TestResp();}  //test all groups of methodes
+  static void     TestResp();                                                            //test the response group of methodes
+  static void     TestSeg();                                                             //test the segmentation group of methodes
+  static void     TestTrans();                                                           //test the transform group of methodes
+
   static Double_t fgMass[5];                                // mass array
-protected:
-  static Bool_t     fgIsRadioSrc;                           //radioactive source instead of radiators flag
   static Bool_t     fgIsTestBeam;                           //test beam geometry instead of normal RICH flag
-  static Bool_t     fgIsWireSag;                            //wire sagitta ON/OFF flag
-  static Bool_t     fgIsResolveClusters;                    //declustering ON/OFF flag
-  static Bool_t     fgIsFeedback;                           //generate feedback photon?
-
-         TObjArray *fpChambers;                             //list of chambers    
-  static Int_t      fgHV[6];                                //HV applied to anod wires
-  static Int_t      fgNsigmaTh;                             //n. of sigmas to cut for zero suppression
-  static Float_t    fgSigmaThMean;                          //sigma threshold value
-  static Float_t    fgSigmaThSpread;                        //spread of sigma
+  enum EPlaneId {kCenter,kPc,kRad,kAnod,kNch=7};            //4 planes in chamber and total number of chambers
+protected:
+         AliRICHParam();             //default ctor is protected to enforce it to be singleton
+  static AliRICHParam *fgInstance;   //static pointer  to instance of AliRICHParam singleton
+//optical curves
+  static Double_t fEckovMin;         //min Eckov
+  static Double_t fEckovMax;         //max Eckov
+      
+         TF2*  fIdxC6F14;            //n=f(Ephot,T) [GeV] for radiator freon   C6F14
+  static TF1   fgIdxSiO2;            //n=f(Ephot) [GeV] for window   quartz  SiO2 
+  static TF1   fgIdxCH4;             //n=f(Ephot) [GeV] for MWPC     amp gas CF4  
+  static TF1   fgIdxAir;             //n=f(Ephot) [GeV] for          air
+  static TF1   fgIdxC4F10;           //n=f(Ephot) [GeV] for radiator C4F10   
+  static TF1   fgIdxCF4;             //n=f(Ephot) [GeV] for radiator CF4 
+  static TF1   fgIdxG30;             //n=f(Ephot) [GeV] for radiator aerogel @1.030
+  static TF1   fgIdxG28;             //n=f(Ephot) [GeV] for radiator aerogel @1.028
+  static TF1   fgIdxG26;             //n=f(Ephot) [GeV] for radiator aerogel @1.026
+  static TF1   fgIdxG24;             //n=f(Ephot) [GeV] for radiator aerogel @1.024
   
-  static Double_t fgErrChrom[4][330];                       //
-  static Double_t fgErrGeom[4][330];                        //
-  static Double_t fgErrLoc[4][330];                         //Chromatic, Geometric and Localization array to parametrize SigmaCerenkov
+  static TF1   fgAbsC6F14;           //abs len curve for radiator freon   C6F14, cm   versus GeV
+  static TF1   fgAbsSiO2;            //abs len curve for window   quartz  SiO2 , cm   versus GeV  
+  static TF1   fgAbsCH4;             //abs len curve for MWPC     methane CF4  , cm   versus GeV
+  static TF1   fgAbsAir;             //abs len curve for air, cm versus GeV
+  static TF1   fgAbsC4F10;           //abs len curve for radiator C4F10    
+  static TF1   fgAbsCF4;             //abs len curve for radiator CF4 
+  static TF1   fgAbsGel;             //abs len curve for gel, cm versus GeV
   
-  ClassDef(AliRICHParam,6)                                  //RICH main parameters class
+  static TF1   fgQeCsI;              //QE=f(Ephot) [GeV] for MWPC PC CsI
+  static TF1   fgQeApd;              //QE=f(Ephot) [GeV] for APD
+  
+  static Bool_t     fgIsWireSag;            //wire sagitta ON/OFF flag
+  static Bool_t     fgIsResolveClusters;    //declustering ON/OFF flag
+  static Bool_t     fgIsFeedback;           //generate feedback photon?
+
+  static Int_t      fgHV[6];                //HV applied to anod wires
+  static Int_t      fgNsigmaTh;             //n. of sigmas to cut for zero suppression
+  static Float_t    fgSigmaThMean;          //sigma threshold value
+  static Float_t    fgSigmaThSpread;        //spread of sigma
+
+  static Double_t     fgErrChrom[4][330];                       //
+  static Double_t     fgErrGeom[4][330];                        //
+  static Double_t     fgErrLoc[4][330];                         //Chromatic, Geometric and Localization array to parametrize SigmaCerenkov
+         TGeoHMatrix *fMatrix[kNchambers];                      //poiners to matrices defining RICH chambers rotations-translations
+  ClassDef(AliRICHParam,0)                                      //RICH main parameters class
 };
+
+AliRICHParam* AliRICHParam::Instance()
+{
+// Return pointer to the AliRICHParam singleton. 
+// Arguments: none
+//   Returns: pointer to the instance of AliRICHParam or 0 if no geometry       
+  if(!fgInstance&&gGeoManager) new AliRICHParam; 
+  else if(!gGeoManager)                        Printf("No geometry imported");
+  return fgInstance;  
+}//Instance()    
 //__________________________________________________________________________________________________
 Int_t AliRICHParam::PadNeighbours(Int_t iPadX,Int_t iPadY,Int_t listX[4],Int_t listY[4])
 {
@@ -188,15 +255,15 @@ Int_t AliRICHParam::PadNeighbours(Int_t iPadX,Int_t iPadY,Int_t listX[4],Int_t l
 //__________________________________________________________________________________________________
 Int_t AliRICHParam::Loc2Sec(const TVector2 &v2)
 {
-//Determines sector containing the given point.
-//Returns sector code:                       
-//y ^  5 6
-//  |  3 4
-//  |  1 2
-//   -------> x  
-  Double_t x0=0; Double_t x1=SectorSizeX(); Double_t x2=SectorSizeX()+DeadZone(); Double_t x3=PcSizeX();
-  Double_t y0=0; Double_t y1=SectorSizeY(); Double_t y2=SectorSizeY()+DeadZone(); Double_t y3=2*SectorSizeY()+DeadZone(); 
-  Double_t y4=PcSizeY()-SectorSizeY();      Double_t y5=PcSizeY();
+// Determines sector containing the given point. y ^  5 6
+//                                                 |  3 4
+//                                                 |  1 2
+//                                                  -------> x 
+// Arguments: v2- LORS position [cm]
+//   Returns: sector code
+  Double_t x0=0; Double_t x1=SecSizeX(); Double_t x2=SecSizeX()+DeadZone(); Double_t x3=PcSizeX();
+  Double_t y0=0; Double_t y1=SecSizeY(); Double_t y2=SecSizeY()+DeadZone(); Double_t y3=2*SecSizeY()+DeadZone(); 
+  Double_t y4=PcSizeY()-SecSizeY();      Double_t y5=PcSizeY();
   
   Int_t sector=-1;  
   if     (v2.X() >= x0 && v2.X() <= x1 )  sector=1;
@@ -226,11 +293,33 @@ TVector AliRICHParam::Loc2Pad(const TVector2 &loc)
   else                          pad[0]=NpadsX() - Int_t( (PcSizeX()-loc.X())  / PadSizeX() )  ; //sector 2 or 4 or 6
 //second deal with y
        if(sec==1||sec==2)       pad[1]=Int_t(             loc.Y()                / PadSizeY())+1;               //sector 1 or 2 
-  else if(sec==3||sec==4)       pad[1]=Int_t( (loc.Y()-SectorSizeY()-DeadZone()) / PadSizeY())+NpadsYsec()+1;  //sector 3 or 4    
+  else if(sec==3||sec==4)       pad[1]=Int_t( (loc.Y()-SecSizeY()-DeadZone()) / PadSizeY())+NpadsYsec()+1;  //sector 3 or 4    
   else                          pad[1]=NpadsY() - Int_t( (PcSizeY()-loc.Y())     / PadSizeY());                //sector 5 or 6        
   return pad;
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHParam::Lors2Pad(Double_t x,Double_t y)
+{
+// Determines abs pad number containing the given point (x,y) defined in the chamber RS.
+// Pad count starts in lower left corner from 1,1 to 144,160 in upper right corner of a chamber.
+// y ^  5 6
+//   |  3 4
+//   |  1 2
+//    -------> x
+  Int_t padx,pady;
+  if     (x>=          0           && x<=  SecSizeX()            )  padx=  1              + Int_t(            x /PadSizeX() ); //sector 1 or 3 or 5
+  else if(x>=SecSizeX()+DeadZone() && x<=  PcSizeX()             )  padx=     NpadsX()    - Int_t( (PcSizeX()-x)/PadSizeX() ); //sector 2 or 4 or 6
+  else                                                              return -1;                                             //dead zone or out of chamber
+
+
+  if     (y>=          0           && y<=  SecSizeY()            )  pady= 1 +               Int_t(            y /PadSizeY()              ); //sector 1 or 2
+  else if(y>=SecSizeY()+DeadZone() && y<=2*SecSizeY()+DeadZone() )  pady= 1 + NpadsYsec() + Int_t( (y-SecSizeY()-DeadZone()) / PadSizeY()); //sector 3 or 4
+  else if(y>= PcSizeY()-SecSizeY() && y<=  PcSizeY()             )  pady=     NpadsY()    - Int_t( (PcSizeY()-y)/PadSizeY()              ); //sector 5 or 6
+  else                                                              return -1;                                               //dead zone or out of chamber
+
+  return AliRICHDigit::P2A(0,padx,pady);
+}//Lors2Pad()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Int_t AliRICHParam::Pad2Sec(const TVector &pad)
 {
 //Determines sector containing the given pad.
@@ -246,7 +335,7 @@ Int_t AliRICHParam::Pad2Sec(const TVector &pad)
 
   return sector;
 }//Pad2Sec()
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 TVector2 AliRICHParam::Pad2Loc(TVector pad)
 {
 //Returns position of the center of the given pad in local system of the chamber (cm)    
@@ -273,25 +362,25 @@ TVector2 AliRICHParam::Pad2Loc(TVector pad)
     
   return TVector2(x,y);
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 TVector2 AliRICHParam::Pad2Loc(Int_t pad)
 {
-//Converts absolute pad number to local position in LORS
-//LORS is a chamber  reference system with origin in left-down coner looking from IP
-//Arguments: pad- absolute pad number
-//  Returns: pad center position as TVector2 in PCRS  
+// Converts absolute pad number to local position in LORS
+// LORS is a chamber  reference system with origin in left-down coner looking from IP
+// Arguments: pad- absolute pad number
+//   Returns: pad center position as TVector2 in PCRS  
   TVector2 pos;
   pos.Set((Pad2PadX(pad)-0.5)*PadSizeX() , (Pad2PadY(pad)-0.5)*PadSizeY());//set to sector LORS
   return pos;
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Double_t AliRICHParam::GainSag(Double_t x,Int_t sector)
 {
 //Returns % of gain variation due to wire sagita.
 //All curves are parametrized as per sector basis, so x must be apriory transformed to the Sector RS.    
 //Here x is a distance along wires.  
-  x-=SectorSizeX()/2;
-  if(x>SectorSizeX()) x-=SectorSizeX(); 
+  x-=SecSizeX()/2;
+  if(x>SecSizeX()) x-=SecSizeX(); 
   switch(HV(sector)){
     case 2150: return 9e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0316*TMath::Power(x,2)-3e-4*x+25.367;//%
     case 2100: return 8e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0283*TMath::Power(x,2)-2e-4*x+23.015;
@@ -300,7 +389,38 @@ Double_t AliRICHParam::GainSag(Double_t x,Int_t sector)
     default:   return 0;
   }
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHParam::QdcSag(Int_t iPad)
+{
+// It was observed at BNL that wires are affected by gravitation field providing a significant sagita leading to the local electric field variation
+// which means that different pads produce different signals.
+// Arguments:  iPad- absolute pad number
+//   Returns:  gain variation due to wire sagita 0 < QdcSag < 1.
+// Curves are parametrised in terms of distance x (cm) along wires having 0 on the left edge of the photocathode
+  Double_t x=AliRICHDigit::P2X(iPad)*PadSizeX()-0.5*PadSizeX(); //center of the padx (count from 1)
+  switch(HV(iPad)){
+    case 2150: return 0.01*(9e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0316*TMath::Power(x,2)-3e-4*x+25.367);//function is a fit in % so multiply by 0.01
+    case 2100: return 0.01*(8e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0283*TMath::Power(x,2)-2e-4*x+23.015);
+    case 2050: return 0.01*(7e-6*TMath::Power(x,4)+1e-7*TMath::Power(x,3)-0.0254*TMath::Power(x,2)-2e-4*x+20.888);
+    case 2000: return 0.01*(6e-6*TMath::Power(x,4)+8e-8*TMath::Power(x,3)-0.0227*TMath::Power(x,2)-1e-4*x+18.961);
+    default:   return 0;
+  }
+}//QdcSag()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHParam::QdcTot(Int_t iPad,Double_t e)
+{
+// Calculates the total charge produced by the hit. Method: 
+// 1. number of electrons is calculated as energy lost in amp gas divided by ionisation potential (for photon only one electron as Etot is always less then ionization potential)
+// 2. each electron imposes a charge distributed as Poisson with QdcEle() mean. Different pads produce different means. See QdcEle().
+// Arguments:  iPad- absolute pad number contaning the hit;
+//                e- Eloss for mip in amplification gas or Etot for photon
+//   Returns:  charge parametrised in QDC channels.
+  Int_t iNele=Int_t(e/IonPot()); if(iNele==0) iNele=1;//e < ion. pot. means it's photoelectron
+  Double_t dQdc=0;
+  for(Int_t i=1;i<=iNele;i++) dQdc+=-QdcEle(iPad)*TMath::Log(gRandom->Rndm());
+  return Int_t(dQdc);
+}//QdcTot()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Int_t AliRICHParam::TotQdc(TVector2 x2,Double_t eloss)
 {
 //Calculates the total charge produced by the eloss in point x2 (Chamber RS).
@@ -312,7 +432,7 @@ Int_t AliRICHParam::TotQdc(TVector2 x2,Double_t eloss)
   for(Int_t i=1;i<=iNelectrons;i++) qdc+=-Gain(x2)*TMath::Log(gRandom->Rndm());
   return Int_t(qdc);
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Double_t AliRICHParam::FracQdc(const TVector2 &x2,const TVector &pad)
 {
 //Calculates the charge fraction induced to given pad by the hit from the given point.
@@ -326,13 +446,15 @@ Double_t AliRICHParam::FracQdc(const TVector2 &x2,const TVector &pad)
 //requested pad might not belong to the sector of the given hit position, hence the check:
   return (Loc2Sec(x2)!=Pad2Sec(pad)) ? 0:Mathieson(normXmin, normYmin, normXmax, normYmax);
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Double_t AliRICHParam::Mathieson(Double_t x1,Double_t y1,Double_t x2,Double_t y2)
 {
-//This is the answer to electrostatic problem of charge distrubution in MWPC described elsewhere. (NIM A370(1988)602-603)
-//Arguments: x1- diff between center of distribution and left margin of interested pad divided by anod-cathode distance
-//           x2,y1,y2- analogically  
-//  Returns: a charge fraction [0-1].
+// This is the answer to electrostatic problem of charge distrubution in MWPC described elsewhere. (NIM A370(1988)602-603)
+// Arguments: x1- diff between center of distribution which is a hit position and left edge of interested pad divided by anod-cathode distance
+//            x2- right edge of the pad
+//            y1- up edge of the pad
+//            y2- bottom edge of the pad
+//  Returns: a charge fraction [0-1] imposed into the pad
   const Double_t kSqrtKx3=0.77459667;const Double_t kX2=0.962;const Double_t kX4=0.379;
   const Double_t kSqrtKy3=0.77459667;const Double_t kY2=0.962;const Double_t kY4=0.379;
 
@@ -342,11 +464,11 @@ Double_t AliRICHParam::Mathieson(Double_t x1,Double_t y1,Double_t x2,Double_t y2
   Double_t uy2=kSqrtKy3*TMath::TanH(kY2*y2);
   return 4*kX4*(TMath::ATan(ux2)-TMath::ATan(ux1))*kY4*(TMath::ATan(uy2)-TMath::ATan(uy1));
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 TVector AliRICHParam::Loc2Area(const TVector2 &x2)
 {
-//Calculates the area of disintegration for a given point. It's assumed here that this points lays on anode wire.
-//Area is a rectangulare set of pads defined by its left-down and right-up coners.
+// Calculates the area of disintegration for a given point. It's assumed here that this points lays on anode wire.
+// Area is a rectangulare set of pads defined by its left-down and right-up coners.
   TVector area(4);
   TVector pad=Loc2Pad(x2); 
   area[0]=area[2]=pad[0]; area[1]=area[3]=pad[1];//area is just a pad fired  
@@ -356,11 +478,259 @@ TVector AliRICHParam::Loc2Area(const TVector2 &x2)
   if(pad[1]!=NpadsYsec() && pad[1]!= 2*NpadsYsec() && pad[1]!= NpadsY()       ) area[3]++; //right up coner Y
   return area;          
 }
-//__________________________________________________________________________________________________
-Bool_t AliRICHParam::IsOverTh(Int_t ,TVector ,Double_t q)
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliRICHParam::IsOverTh(Int_t ,TVector ,Double_t qdc)
 {
-//Checks if the current q is over threshold and FEE will save this value to data concentrator.
-  return (q>NsigmaTh()*(SigmaThMean()+(1.-2*gRandom->Rndm())*SigmaThSpread()));
+// Checks if the current QDC is over threshold and FEE will save this value to data concentrator.
+// This is done on pad by pad level, so the pad pedestal map is to be used. ??????????????  
+// Arguments: 
+//   Returns:  true if QDC over treshold 
+  return (qdc>NsigmaTh()*(SigmaThMean()+(1.-2*gRandom->Rndm())*SigmaThSpread())); //??????????? to be change to real values
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TGeoMatrix* AliRICHParam::Matrix(Int_t iChamN,Int_t iPlane)
+{
+  TGeoHMatrix *pMatrix=new TGeoHMatrix;
+        
+  const Double_t kAngHor=19.5; //  horizontal angle between chambers  19.5 grad
+  const Double_t kAngVer=20;   //  vertical angle between chambers    20   grad     
+  const Double_t kAngCom=30;   //  common RICH rotation with respect to x axis  30   grad     
+  
+  pMatrix->RotateY(90);        //rotate around y since initial position is in XY plane -> now in YZ plane
+  Double_t trans[3]={490,0,0}; //center of the chamber is on window-gap surface
+    
+  switch(iPlane){
+    case kCenter:                          break; 
+    case kPc    :   trans[0]+=PcZ();       break; 
+    case kRad   :   trans[0]+=RadZ();      break; 
+    case kAnod  :   trans[0]+=AnodZ();     break;      
+    default:               return 0;       break; 
+  }
+  pMatrix->SetTranslation(trans); //now plane in YZ is shifted along x 
+  
+  switch(iChamN){
+    case 1:                pMatrix->RotateY(kAngHor);  pMatrix->RotateZ(-kAngVer);  break; //right and down 
+    case 2:                                            pMatrix->RotateZ(-kAngVer);  break; //down              
+    case 3:                pMatrix->RotateY(kAngHor);                               break; //right 
+    case 4:                                                                         break; //no rotation
+    case 5:                pMatrix->RotateY(-kAngHor);                              break; //left   
+    case 6:                                            pMatrix->RotateZ(kAngVer);   break; //up
+    case 7:                pMatrix->RotateY(-kAngHor); pMatrix->RotateZ(kAngVer);   break; //left and up 
+    default:               return 0;                                  break;
+  }//switch(iChamber)
+  pMatrix->RotateZ(kAngCom);     //apply common rotation  in XY plane
+  return pMatrix;
+}//Matrix()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TVector3  AliRICHParam::Lors2Mars(Int_t iChId,Double_t x,Double_t y,Int_t iPlnId)
+{
+// Trasform from LORS to MARS
+// Arguments: iChId  - chamber code 1..7
+//            x,y    - point in LORS 
+//            iPlnN  - chamber plane code  might be kPc kRad kCenter kAnod    
+  Double_t z=0;
+  switch(iPlnId){
+    case kPc    : z=PcZ()  ; break;
+    case kAnod  : z=AnodZ(); break;
+    case kCenter: z=0      ; break;
+    case kRad   : z=RadZ() ; break;
+  }
+  Double_t lors[3]={x-0.5*PcSizeX(),y-0.5*PcSizeY(),z},  mars[3]; 
+  fMatrix[iChId-1]->LocalToMaster(lors,mars);
+  return TVector3(mars);
+}    
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TVector2  AliRICHParam::Mars2Lors(Int_t iChId,const TVector3 &x,Int_t iPlnId)
+{
+// Trasform from MARS to LORS
+// Arguments: iChId  - chamber code 1..7
+//            mars   - point in MARS 
+//            iPlnN  - chamber plane code  might be kPc kRad kCenter kAnod    
+  Double_t z=0;
+  switch(iPlnId){
+    case kPc    : z=PcZ()  ; break;
+    case kAnod  : z=AnodZ(); break;
+    case kCenter: z=0      ; break;
+    case kRad   : z=RadZ() ; break;
+  }
+  Double_t lors[3],mars[3]; 
+  x.GetXYZ(mars);
+  fMatrix[iChId-1]->MasterToLocal(mars,lors);
+  return TVector2(lors[0]+0.5*PcSizeX(),lors[1]+0.5*PcSizeY());
+}    
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TVector3  AliRICHParam::Lors2MarsOld(Int_t iChId,Double_t x,Double_t y,Int_t iPlnId)
+{
+// Trasform from LORS to MARS
+// Arguments: iChId  - chamber code 0..6
+//            x,y    - point in LORS 
+//            iPlnN  - chamber plane code  might be kPc kRad kCenter kAnod    
+  TGeoMatrix *pMatrix=Matrix(iChId,iPlnId);
+  Double_t lors[3]={x-0.5*PcSizeX(),y-0.5*PcSizeY(),0},  mars[3];  pMatrix->LocalToMaster(lors,mars);  delete pMatrix;
+  return TVector3(mars);
+}    
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TVector2  AliRICHParam::Mars2LorsOld(Int_t iChamN,const TVector3 &x,Int_t iPlaneN)
+{
+  TGeoMatrix *pMatrix=Matrix(iChamN,iPlaneN);
+  Double_t mars[3]={x.X(),x.Y(),x.Z()}  , lors[3];  pMatrix->MasterToLocal(mars,lors);  delete pMatrix;
+  return TVector2(lors[0]+0.5*PcSizeX(),lors[1]+0.5*PcSizeY());
+}    
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TVector3  AliRICHParam::Mars2LorsVec(Int_t iChamN,const TVector3 &x)
+{
+  TGeoMatrix *pMatrix=Matrix(iChamN,kPc);
+  Double_t mars[3]={x.X(),x.Y(),x.Z()}  , lors[3];  pMatrix->MasterToLocalVect(mars,lors);  delete pMatrix;
+  return TVector3(lors);
+}    
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TVector3  AliRICHParam::Center(Int_t iChamN,Int_t iPlaneN)
+{
+  TGeoMatrix *pMatrix=Matrix(iChamN,iPlaneN);
+  Double_t mars[3]  , lors[3]={0,0,0};  pMatrix->LocalToMaster(lors,mars);  delete pMatrix;
+  return TVector3(mars);
+}    
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TVector3  AliRICHParam::Norm(Int_t iChamN)
+{
+  TGeoMatrix *pMatrix=Matrix(iChamN,kPc);
+  Double_t mars[3] , lors[3]={0,0,1};  pMatrix->LocalToMasterVect(lors,mars);  delete pMatrix;
+  return TVector3(mars);
+}    
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHParam::Hit2SDigs(Int_t iHitPad,Double_t e,TClonesArray *pSDigLst)
+{
+// Determines a number of pads affected by the hit and calculates the charge induced to each pad.
+// Integrated Mathieson distribution is used. Invoked from AliRICHvX::Hits2SDigits()
+// Arguments: iHitPad  - hit pad absolute number
+//            e        - energy (GeV) of this hit (Eloss for mip or Etot for photon)
+//            pSDigLst - pointer to clones array to store in calculated sdigits
+//   Returns:          total QDC for this hit
+  Int_t iQtot=QdcTot(iHitPad,e);                    //total QDC value collected for this hit
+  Int_t a=1;                                        //analise current pad +- a pads in both directions
+  Int_t iLeftX=0,iBotY=0,iRightX=0,iTopY=0;         //area of disintegration for cluster formation, shifts to hit pad, not pad numbers
+  if(AliRICHDigit::P2X(iHitPad) >                         a) iLeftX =-a;//determine area of disintegration as hit pad +- parametrised number
+  if(AliRICHDigit::P2X(iHitPad) < AliRICHDigit::kPadsSecX-a) iRightX= a;//of pads. this number is determined by5 sigmas of Mathieson shape
+  if(AliRICHDigit::P2Y(iHitPad) >                         a) iBotY  =-a;//see RICH TDR page 29
+  if(AliRICHDigit::P2Y(iHitPad) < AliRICHDigit::kPadsSecY-a) iTopY  = a;//also boundary conditions are checked (edge of sector aka PC)
+  Int_t iPadsCnt=0;
+  for(Int_t iShiftX=iLeftX;iShiftX<=iRightX;iShiftX++){//affected pads loop iShiftX is a distance (in pads) between hit pad and pad under analisys
+    for(Int_t iShiftY=iBotY;iShiftY<=iTopY;iShiftY++){//affected pads loop
+      iHitPad+=AliRICHDigit::kPadAbsX*iShiftX+iShiftY;
+      Double_t x1=PadSizeX()/Pc2Cath()*(iShiftX-0.5);//parametrise for Mathienson
+      Double_t x2=PadSizeX()/Pc2Cath()*(iShiftX+0.5);//parametrise for Mathienson
+      Double_t y1=PadSizeY()/Pc2Cath()*(iShiftY-0.5);//parametrise for Mathienson
+      Double_t y2=PadSizeY()/Pc2Cath()*(iShiftY+0.5);//parametrise for Mathienson
+      (*pSDigLst)[iPadsCnt++]= new AliRICHDigit(iHitPad,iQtot*Mathieson(x1,y1,x2,y2));
+    }//Y loop
+  }//X loop
+  return iQtot;
+}//Hit2SDigs() for abs pad 
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHParam::Hit2SDigs(TVector2 hitX2,Double_t e,TClonesArray *pSDigLst)
+{
+// Determines a number of pads affected by the hit and calculates the charge induced to each pad.
+// Integrated Mathieson distribution is used. Invoked from AliRICHvX::Hits2SDigits()
+// Arguments: hitX2    - hit position in LORS, cm
+//            e        - energy (GeV) of this hit (Eloss for mip or Etot for photon)
+//            pSDigLst - pointer to clones array to store in calculated sdigits
+//   Returns:          total QDC for this hit
+  Int_t iQtot=TotQdc(hitX2,e);//total charge produced by hit, 0 if hit in dead zone
+  if(iQtot==0) return 0;
+
+  TVector  hitPad=Loc2Pad(hitX2);  TVector2 padCenterX2=Pad2Loc(hitPad);     //shift the hit position to the nearest anod wire
+  TVector2 anod;
+  if((hitX2.Y()-padCenterX2.Y())>0) anod.Set(hitX2.X(),padCenterX2.Y()+AnodPitch()/2); //upper part of the pad: shift to upper anod wire
+  else                              anod.Set(hitX2.X(),padCenterX2.Y()-AnodPitch()/2); //lower part of the pad: shift to lower anod wire
+
+  TVector area=Loc2Area(anod);//determine affected pads, dead zones analysed inside
+  TVector pad(2); //current pad
+  Int_t iPadsCnt=0;
+  for(pad[1]=area[1];pad[1]<=area[3];pad[1]++){//affected pads loop
+    for(pad[0]=area[0];pad[0]<=area[2];pad[0]++){
+      Double_t dQpad=iQtot*FracQdc(anod,pad);
+      if(dQpad>0.1) (*pSDigLst)[iPadsCnt++]= new AliRICHDigit(pad,dQpad);//make sdigit if Qpad is large enough, meaning after merging there is a chance to go above threshold
+    }//X loop
+  }//Y loop
+  return iQtot;
+}//Hit2SDigs() for TVector2
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+TVector3 AliRICHParam::SigmaSinglePhotonFormula(Double_t thetaCer, Double_t phiCer, Double_t theta, Double_t phi, Double_t beta)
+{
+  TVector3 v(-999,-999,-999);
+
+  v.SetX(AliRICHParam::ErrLoc(thetaCer,phiCer,theta,phi,beta));
+  v.SetY(AliRICHParam::ErrGeom(thetaCer,phiCer,theta,phi,beta));
+  v.SetZ(AliRICHParam::ErrCrom(thetaCer,phiCer,theta,phi,beta));
+
+  return v;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHParam::ErrLoc(Double_t thetaC, Double_t phiC, Double_t Ptheta, Double_t Pphi, Double_t beta)
+{
+//par->RefIdxC6F14(par->MeanCkovEnergy())
+//(Float_t)1.29337525367736816e+00
+Double_t RefC6F14m = 1.29337;
+  Double_t Hgap = Pc2Win();
+  Double_t dphi = phiC - Pphi;
+
+  Double_t alpha =TMath::Cos(Ptheta)-TMath::Tan(thetaC)*TMath::Cos(dphi)*TMath::Sin(Ptheta);
+  Double_t k = 1.-RefC6F14m*RefC6F14m+alpha*alpha/(beta*beta);
+
+  Double_t mu = TMath::Sin(Ptheta)*TMath::Sin(Pphi) + TMath::Tan(thetaC)*(TMath::Cos(Ptheta)*TMath::Cos(dphi)*TMath::Sin(Pphi)
++ TMath::Sin(dphi)*TMath::Cos(Pphi));
+
+  Double_t e = TMath::Sin(Ptheta)*TMath::Cos(Pphi)+TMath::Tan(thetaC)*(TMath::Cos(Ptheta)*TMath::Cos(dphi)*TMath::Cos(Pphi) -TMath::Sin(dphi)*TMath::Sin(Pphi));
+
+  Double_t kk = beta*TMath::Sqrt(k)/(Hgap*alpha);
+  Double_t dtdxc = kk*(k*(TMath::Cos(dphi)*TMath::Cos(Pphi) - TMath::Cos(Ptheta)*TMath::Sin(dphi)*TMath::Sin(Pphi)) - ( alpha*
+  mu/(beta*beta) )*TMath::Sin(Ptheta)*TMath::Sin(dphi));
+
+  Double_t dtdyc = kk*(k*(TMath::Cos(dphi)*TMath::Sin(Pphi) + TMath::Cos(Ptheta)*TMath::Sin(dphi)*TMath::Cos(Pphi)) + ( alpha*
+  e/(beta*beta) )* TMath::Sin(Ptheta)*TMath::Sin(dphi));
+
+  return  TMath::Sqrt(0.2*0.2*dtdxc*dtdxc + 0.25*0.25*dtdyc*dtdyc);
+}
+
+Double_t AliRICHParam::ErrCrom(Double_t thetaC, Double_t phiC, Double_t Ptheta, Double_t Pphi, Double_t beta)
+{
+  Double_t dphi = phiC - Pphi;
+  Double_t RefC6F14m = 1.29337;
+  Double_t alpha =TMath::Cos(Ptheta)-TMath::Tan(thetaC)*TMath::Cos(dphi)*TMath::Sin(Ptheta);
+
+  Double_t dtdn = TMath::Cos(Ptheta)*RefC6F14m*beta*beta/(alpha*TMath::Tan(thetaC));
+            
+  Double_t f = 0.00928*(7.75-5.635)/TMath::Sqrt(12.);
+
+  return f*dtdn;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHParam::ErrGeom(Double_t thetaC, Double_t phiC, Double_t Ptheta, Double_t Pphi, Double_t beta )
+{
+
+  Double_t Tr = RadThick();
+  Double_t Xep = 0.5*Tr;
+
+  Double_t dphi = phiC - Pphi;
+  Double_t RefC6F14m = 1.29337;
+  Double_t alpha =TMath::Cos(Ptheta)-TMath::Tan(thetaC)*TMath::Cos(dphi)*TMath::Sin(Ptheta);
+
+  Double_t k = 1.-RefC6F14m*RefC6F14m+alpha*alpha/(beta*beta);
+
+  Double_t Hgap = Pc2Win();
+
+
+  Double_t eTr = (Tr - Xep)*beta*TMath::Sqrt(k)/(Hgap*alpha);
+  Double_t lambda = 1.-TMath::Sin(Ptheta)*TMath::Sin(Ptheta)*TMath::Sin(phiC)*TMath::Sin(phiC);
+
+  Double_t c = 1./(1.+ eTr*k/(alpha*alpha*TMath::Cos(thetaC)*TMath::Cos(thetaC)));
+  Double_t I = beta*TMath::Tan(thetaC)*lambda*TMath::Power(k,1.5);
+  Double_t II = 1.+eTr*beta*I;
+
+  Double_t err = c * (I/(alpha*alpha*Hgap) +  II* (1.-lambda) / ( alpha*alpha*Hgap*beta*(1.+eTr)) );
+  Double_t TrErr = Tr/(TMath::Sqrt(12.)*TMath::Cos(Ptheta));
+
+  return TrErr*err;
+}//ErrGeom()
+
 #endif //AliRICHParam_h
index b24acf0..e4c3e42 100644 (file)
 // AliRICHRecon                                                         //
 //                                                                      //
 // RICH class to perfom pattern recognition based on Hough transfrom    //
-//                                                                      //
+// for single chamber                                                   //
 //////////////////////////////////////////////////////////////////////////
 
-#include <Riostream.h>
+#include "AliRICHRecon.h"  //class header
 #include <TMath.h>
 #include <TRotation.h>
 #include <TVector3.h>
 #include <TH1F.h>
-#include <TROOT.h>
 
-#include "AliRICH.h"
+#include "AliRICHCluster.h" //ThetaCerenkov()
 #include "AliRICHParam.h"
-#include "AliRICHRecon.h"
-#include "AliRICHHelix.h"
+#include "AliRICHHelix.h"   //ThetaCerenkov()
 #include <AliLog.h>
 
 #define NPointsOfRing 201
 
 //__________________________________________________________________________________________________
-AliRICHRecon::AliRICHRecon(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t iMipId)
-             :TTask("RichRec","RichPat")
+AliRICHRecon::AliRICHRecon()
+             :TTask       ("RichRec","RichPat")
 {
 // main ctor
-  SetFreonScaleFactor(1);
-  fIsWEIGHT = kFALSE;
-  if(pClusters->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction
-//  fIsWEIGHT = kTRUE;
   fThetaMin = 0.0; fThetaMax = 0.75; 
   fDTheta       = 0.001;   fWindowWidth  = 0.045;
   fMinNumPhots = 3;
-  fRadiatorWidth = AliRICHParam::Zfreon();
-  fQuartzWidth   = AliRICHParam::Zwin();
-  fGapWidth      = AliRICHParam::Freon2Pc() - fRadiatorWidth - fQuartzWidth;
-  fXmin         = 0.;
-  fXmax         =  AliRICHParam::PcSizeX();
-  fYmin         = 0.;
-  fYmax         =  AliRICHParam::PcSizeY(); 
-  SetTrackTheta(pHelix->Ploc().Theta());
-  SetTrackPhi(pHelix->Ploc().Phi());
-  SetMipIndex(iMipId);
-  SetShiftX(pHelix->PosRad().X());
-  SetShiftY(pHelix->PosRad().Y());
-  fpClusters = pClusters;
+  fParam=AliRICHParam::Instance(); //get the pointer to AliRICHParam
 }
 //__________________________________________________________________________________________________
-Double_t AliRICHRecon::ThetaCerenkov()
+Double_t AliRICHRecon::ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t &iMipId)
 {
 // Pattern recognition method based on Hough transform
 // Return theta Cerenkov for a given track and list of clusters which are set in ctor  
+// Remeber that list of clusters must contain more then 1 cluster. This considiration implies that normally we have 1 mip cluster and few photon clusters per track.  
+// Argume
+//   Returns: Track theta ckov in rad, nPhot contains number of photon candidates accepted for reconstruction track theta ckov   
+  SetTrackTheta(pHelix->Ploc().Theta());  SetTrackPhi(pHelix->Ploc().Phi());
+  SetShiftX(pHelix->PosRad().X());        SetShiftY(pHelix->PosRad().Y());
+  fClusters = pClusters;
+  if(pClusters->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction
+  else                            fIsWEIGHT = kFALSE;
 
-  if(fpClusters->GetEntries()==0) return -10;//no clusters at all for a given track
-  Bool_t kPatRec = kFALSE;  
-    
-  AliDebug(1,Form("---Track Parameters--- Theta: %f , Phi: %f ",GetTrackTheta()*TMath::RadToDeg(),GetTrackPhi()*TMath::RadToDeg()));
 
-  Int_t candidatePhotons = 0;
 
-  SetThetaCerenkov(-1);
-  SetHoughPhotons(0);
-  SetHoughPhotonsNorm(0);
+  SetThetaCerenkov(-1);   
 
-  for (Int_t j=0; j < fpClusters->GetEntries(); j++){//clusters loop
-    SetPhotonIndex(j);
+  for (Int_t iClu=0; iClu<fClusters->GetEntriesFast();iClu++){//clusters loop
+    if(iClu == iMipId) continue; // do not consider MIP cluster as a photon candidate
+    SetPhotonIndex(iClu);
     SetPhotonFlag(0);
     SetPhotonEta(-999.);
     SetPhotonWeight(0.);
-    if (j == GetMipIndex()) continue; // do not consider MIP cluster as a candidate photon
-//    if(((AliRICHCluster*)fpClusters->UncheckedAt(j))->Q()>AliRICHParam::QthMIP()) continue; // avoid MIP clusters from bkg
-    Float_t xtoentr = ((AliRICHCluster*)fpClusters->UncheckedAt(j))->X() - GetShiftX();
-    Float_t ytoentr = ((AliRICHCluster*)fpClusters->UncheckedAt(j))->Y() - GetShiftY();
-    SetEntranceX(xtoentr);
-    SetEntranceY(ytoentr);
+    AliRICHCluster *pClu=(AliRICHCluster*)fClusters->UncheckedAt(iClu);                      //get pointer to current cluster
+//    if(pClu->Q()>AliRICHParam::QthMIP()) continue;                                         //avoid MIP clusters from bkg
+    SetEntranceX(pClu->X() - GetShiftX());    SetEntranceY(pClu->Y() - GetShiftY());         //cluster position with respect to track intersection
     FindPhiPoint();
-//      Int_t photonStatus = PhotonInBand();
-//      if(photonStatus == 0) continue;
+//      if(PhotonInBand()==0) continue;  ????????????
     SetPhotonFlag(1);
     FindThetaPhotonCerenkov();
     Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov();
-    AliDebug(1,Form("THETA CERENKOV ---> %f",thetaPhotonCerenkov));
+    AliDebug(1,Form("Track Theta=%5.2f deg, Phi=%5.2f deg Photon clus=%2i ThetaCkov=%5.2f rad",GetTrackTheta()*TMath::RadToDeg(),GetTrackPhi()*TMath::RadToDeg()
+                                                                                              ,iClu,thetaPhotonCerenkov ));
     SetPhotonEta(thetaPhotonCerenkov);
-    candidatePhotons++;
   }//clusters loop
 
-  if(candidatePhotons >= 1) kPatRec = kTRUE;
-
-  if(!kPatRec) return -1;
+  SetPhotonsNumber(fClusters->GetEntries());
 
-  SetPhotonsNumber(fpClusters->GetEntries());
+  if((iMipId=FlagPhotons(HoughResponse()))<1) return -11; //flag photons according to individual theta ckov with respect to most probable track theta ckov
 
-  HoughResponse();
-  
-  fNrings++;
-
-  FlagPhotons();
-  Int_t nPhotonHough = GetHoughPhotons();
-  if(nPhotonHough < 1) 
-    {
-      SetThetaCerenkov(-1);
-      SetHoughPhotonsNorm(0);
-      return -1;
-    }
 
-  FindThetaCerenkov();
-
-  AliDebug(1,Form("Number of clusters accepted --->  %i",nPhotonHough));
-  
 //  Float_t thetaCerenkov = GetThetaCerenkov();  
 //  SetThetaOfRing(thetaCerenkov);
 //  FindAreaAndPortionOfRing();
@@ -148,35 +109,14 @@ Double_t AliRICHRecon::ThetaCerenkov()
 
   SetHoughArea(houghArea);
 */
+  FindThetaCerenkov();
   return GetThetaCerenkov();
-
 }//ThetaCerenkov()
 //__________________________________________________________________________________________________
-void AliRICHRecon::FindEmissionPoint()
-{
-  //estimate the emission point in radiator
-
-// Find emission point
-
-  Float_t absorbtionLenght=7.83*fRadiatorWidth; //absorption length in the freon (cm)
-  // 7.83 = -1/ln(T0) where 
-  // T0->Trasmission freon at 180nm = 0.88 (Eph=6.85eV)
-  Float_t photonLenght, photonLenghtMin, photonLenghtMax;
-
-  photonLenght=exp(-fRadiatorWidth/(absorbtionLenght*cos(fCerenkovAnglePad)));
-  photonLenghtMin=fRadiatorWidth*photonLenght/(1.-photonLenght);
-  photonLenghtMax=absorbtionLenght*cos(fCerenkovAnglePad);
-  Float_t emissionPoint = fRadiatorWidth + photonLenghtMin - photonLenghtMax;
-
-  SetEmissionPoint(emissionPoint);
-  SetEmissionPoint(fRadiatorWidth/2); // tune the emission point
-}
-//__________________________________________________________________________________________________
 Int_t AliRICHRecon::PhotonInBand()
 {
-  //search band fro photon candidates
+// Define valid band for photon candidates. For that photons with ThetaMin and ThetaMax are traced up to photcathode
 
-  //  Float_t massOfParticle;
   Float_t nfreon;
 
   Float_t thetacer;
@@ -191,19 +131,16 @@ Int_t AliRICHRecon::PhotonInBand()
 
 
   // inner radius //
-  SetPhotonEnergy(5.6);
-  SetEmissionPoint(fRadiatorWidth -0.0001);
-  SetFreonRefractiveIndex();
+  SetEmissionPoint(AliRICHParam::RadThick() -0.0001);
 
-  nfreon = GetFreonRefractiveIndex();
+  nfreon = fParam->IdxC6F14(fParam->EckovMin());
   thetacer = 0.;
 
   AliDebug(1,Form("thetacer in photoninband min %f",thetacer));
 
   FindThetaAtQuartz(thetacer);
 
-  if(thetacer == 999. || GetThetaAtQuartz() == 999.)
-    {
+  if(thetacer == 999. || GetThetaAtQuartz() == 999.) {
       innerRadius = -999.;
       SetXInnerRing(-999.);
       SetYInnerRing(-999.);
@@ -223,12 +160,10 @@ Int_t AliRICHRecon::PhotonInBand()
     }
   
   // outer radius //
-  SetPhotonEnergy(7.7);
   SetEmissionPoint(0.);
 //  SetMassHypotesis(0.139567);
-  SetFreonRefractiveIndex();
 
-  nfreon = GetFreonRefractiveIndex();
+  nfreon = fParam->IdxC6F14(fParam->EckovMax());
 
   thetacer = Cerenkovangle(nfreon,1);
 
@@ -263,24 +198,19 @@ Int_t AliRICHRecon::PhotonInBand()
 
   if(padradius>=innerRadius && padradius<=outerRadius) return 1;
   return 0;
-}
+}//PhotonInBand()
 //__________________________________________________________________________________________________
 void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov)
 {
-  //find the theta at the quartz plate
+// find the theta at the quartz plate
 
-  if(thetaCerenkov == 999.) 
-    {
-      SetThetaAtQuartz(999.);
-      return;
-    }
+  if(thetaCerenkov == 999.) { SetThetaAtQuartz(999.); return; }
 
   Float_t thetaAtQuartz = 999.;
 
   Float_t trackTheta = GetTrackTheta();
 
   if(trackTheta == 0) {
-
     thetaAtQuartz = thetaCerenkov;
     SetThetaAtQuartz(thetaAtQuartz);
     return;
@@ -289,12 +219,8 @@ void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov)
   Float_t trackPhi   = GetTrackPhi();
   Float_t phiPoint = GetPhiPoint();
 
-  Double_t den = TMath::Sin((Double_t)trackTheta)
-    *TMath::Cos((Double_t)trackPhi)
-    *TMath::Cos((Double_t)phiPoint) +
-    TMath::Sin((Double_t)trackTheta)
-    *TMath::Sin((Double_t)trackPhi)
-    *TMath::Sin((Double_t)phiPoint); 
+  Double_t den = TMath::Sin((Double_t)trackTheta)*TMath::Cos((Double_t)trackPhi)*TMath::Cos((Double_t)phiPoint) +
+    TMath::Sin((Double_t)trackTheta)*TMath::Sin((Double_t)trackPhi)*TMath::Sin((Double_t)phiPoint); 
   Double_t b = TMath::Cos((Double_t)trackTheta)/den;
   Double_t c = -TMath::Cos((Double_t)thetaCerenkov)/den;
 
@@ -335,8 +261,7 @@ void AliRICHRecon::FindThetaPhotonCerenkov()
 
   Float_t phiPoint = GetPhiPoint();
 
-  SetPhotonEnergy(AliRICHParam::MeanCkovEnergy());
-  SetEmissionPoint(fRadiatorWidth/2);
+  SetEmissionPoint(AliRICHParam::RadThick()/2);
 
   Float_t xPoint = GetEntranceX();
   Float_t yPoint = GetEntranceY();
@@ -449,10 +374,8 @@ void AliRICHRecon::FindAreaAndPortionOfRing()
   Float_t y0 = yemiss + shiftY;
 
 
-  SetPhotonEnergy(AliRICHParam::MeanCkovEnergy());
-  SetFreonRefractiveIndex();
 
-  SetEmissionPoint(fRadiatorWidth/2.);
+  SetEmissionPoint(AliRICHParam::RadThick()/2.);
 
   Float_t theta = GetThetaOfRing();
   
@@ -460,9 +383,7 @@ void AliRICHRecon::FindAreaAndPortionOfRing()
   Int_t nPsiAccepted = 0;
   Int_t nPsiTotal = 0;
 
-  for(Int_t i=0;i<NPointsOfRing-1;i++)
-    {
-
+  for(Int_t i=0;i<NPointsOfRing-1;i++){
       Float_t psi = 2*TMath::Pi()*i/NPointsOfRing;
       
       SetThetaPhotonInTRS(theta);
@@ -484,25 +405,17 @@ void AliRICHRecon::FindAreaAndPortionOfRing()
 
        AliDebug(1,Form("acceptance to detector zone -> %d",zone));         
 
-      if (zone != 0) 
-       {
-         FindIntersectionWithDetector();
-         xPoint[nPoints] = GetIntersectionX();
-         yPoint[nPoints] = GetIntersectionY();
-       }
-      else
-       {
-         xPoint[nPoints] = xPointRing;
-         yPoint[nPoints] = yPointRing;
-         nPsiAccepted++;
-       }
-
+      if (zone != 0){
+             FindIntersectionWithDetector();
+             xPoint[nPoints] = GetIntersectionX();       yPoint[nPoints] = GetIntersectionY();
+       }else{
+             xPoint[nPoints] = xPointRing;           yPoint[nPoints] = yPointRing;
+             nPsiAccepted++;
+           }
       nPoints++;
+  }
 
-    }
-
-  xPoint[nPoints] = xPoint[0];
-  yPoint[nPoints] = yPoint[0];
+  xPoint[nPoints] = xPoint[0];  yPoint[nPoints] = yPoint[0];
   
   // find area...
 
@@ -522,7 +435,7 @@ void AliRICHRecon::FindAreaAndPortionOfRing()
 
   SetAreaOfRing(area);
   SetPortionOfRing(portionOfRing);
-}
+}//FindAreaAndPortionOfRing()
 //__________________________________________________________________________________________________
 void AliRICHRecon::FindIntersectionWithDetector()
 {
@@ -567,45 +480,43 @@ void AliRICHRecon::FindIntersectionWithDetector()
       y1 = yPoint;
     }
   //
-  xIntersect = fXmax;
+  xIntersect = AliRICHParam::PcSizeX();
   yIntersect = m*(xIntersect - x0) + y0;
-  if (yIntersect >= fYmin && yIntersect <= fYmax && xIntersect >= x1 && xIntersect <= x2)
+  if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2)
     {
       SetIntersectionX(xIntersect);
       SetIntersectionY(yIntersect);
       return;
     }
   //
-  xIntersect = fXmin;
+  xIntersect = 0;
   yIntersect = m*(xIntersect - x0) + y0;
-  if (yIntersect >= fYmin && yIntersect <= fYmax && xIntersect >= x1 && xIntersect <= x2)
+  if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2)
     {
       SetIntersectionX(xIntersect);
       SetIntersectionY(yIntersect);
       return;
     }
   //
-  yIntersect = fYmax;
+  yIntersect = AliRICHParam::PcSizeY();
   xIntersect = (yIntersect - y0)/m + x0;
-  if (xIntersect >= fXmin && xIntersect <= fXmax && yIntersect >= y1 && yIntersect <= y2)
+  if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2)
     {
       SetIntersectionX(xIntersect);
       SetIntersectionY(yIntersect);
       return;
     }
   //
-  yIntersect = fYmin;
+  yIntersect = 0;
   xIntersect = (yIntersect - y0)/m + x0;
-  if (xIntersect >= fXmin && xIntersect <= fXmax && yIntersect >= y1 && yIntersect <= y2)
+  if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2)
     {
       SetIntersectionX(xIntersect);
       SetIntersectionY(yIntersect);
       return;
     }
-  
-  cout << " sono fuori!!!!!!" << endl;
-  
 }
+
 //__________________________________________________________________________________________________
 Int_t AliRICHRecon::CheckDetectorAcceptance() const
 {
@@ -617,23 +528,23 @@ Int_t AliRICHRecon::CheckDetectorAcceptance() const
   Float_t xcoord = GetDetectorWhereX();
   Float_t ycoord = GetDetectorWhereY();
 
-  if(xcoord > fXmax)
+  if(xcoord > AliRICHParam::PcSizeX())
     {
-      if(ycoord > fYmax) return 2;
-      if(ycoord > fYmin && ycoord < fYmax) return 3;
-      if(ycoord < fYmin) return 4;
+      if(ycoord > AliRICHParam::PcSizeY()) return 2;
+      if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 3;
+      if(ycoord < 0) return 4;
     }
-  if(xcoord < fXmin)
+  if(xcoord < 0)
     {
-      if(ycoord > fYmax) return 8;
-      if(ycoord > fYmin && ycoord < fYmax) return 7;
-      if(ycoord < fYmin) return 6;
+      if(ycoord > AliRICHParam::PcSizeY()) return 8;
+      if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 7;
+      if(ycoord < 0) return 6;
     }
-  if(xcoord > fXmin && xcoord < fXmax)
+  if(xcoord > 0 && xcoord < AliRICHParam::PcSizeX())
     {
-      if(ycoord > fYmax) return 1;
-      if(ycoord > fYmin && ycoord < fYmax) return 0;
-      if(ycoord < fYmin) return 5;
+      if(ycoord > AliRICHParam::PcSizeY()) return 1;
+      if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 0;
+      if(ycoord < 0) return 5;
     }
   return 999;
 }
@@ -673,17 +584,16 @@ void AliRICHRecon::FindPhotonAnglesInDRS()
 //__________________________________________________________________________________________________
 Float_t AliRICHRecon::FromEmissionToCathode()
 {
-  // trace from emission point to cathode
+// Trace current photon from emission point somewhere in radiator to photocathode
+// Arguments: none
+//   Returns:    
 
   Float_t nfreon, nquartz, ngas; 
 
-  SetFreonRefractiveIndex();
-  SetQuartzRefractiveIndex();
-  SetGasRefractiveIndex();
 
-  nfreon  = GetFreonRefractiveIndex();
-  nquartz = GetQuartzRefractiveIndex();
-  ngas    = GetGasRefractiveIndex();
+  nfreon  = fParam->IdxC6F14(fParam->EckovMean());
+  nquartz = fParam->IdxSiO2(fParam->EckovMean());
+  ngas    = fParam->IdxCH4(fParam->EckovMean());
 
   Float_t trackTheta = GetTrackTheta();
   Float_t trackPhi = GetTrackPhi();
@@ -692,8 +602,6 @@ Float_t AliRICHRecon::FromEmissionToCathode()
   Float_t theta = GetThetaPhotonInDRS();
   Float_t phi   = GetPhiPhotonInDRS();
 
-//   cout << " Theta " << Theta << " Phi " << Phi << endl;
-
   Float_t xemiss = lengthOfEmissionPoint*tan(trackTheta)*cos(trackPhi);
   Float_t yemiss = lengthOfEmissionPoint*tan(trackTheta)*sin(trackPhi);
 
@@ -718,12 +626,12 @@ Float_t AliRICHRecon::FromEmissionToCathode()
       return thetagap;
     }
 
-  Float_t xw = (fRadiatorWidth - lengthOfEmissionPoint)*cos(phi)*tan(theta);
-  Float_t xq = fQuartzWidth*cos(phi)*tan(thetaquar);
-  Float_t xg = fGapWidth*cos(phi)*tan(thetagap);
-  Float_t yw = (fRadiatorWidth - lengthOfEmissionPoint)*sin(phi)*tan(theta);
-  Float_t yq = fQuartzWidth*sin(phi)*tan(thetaquar);
-  Float_t yg = fGapWidth*sin(phi)*tan(thetagap);
+  Float_t xw = (AliRICHParam::RadThick() - lengthOfEmissionPoint)*cos(phi)*tan(theta);
+  Float_t xq = AliRICHParam::WinThick()*cos(phi)*tan(thetaquar);
+  Float_t xg = AliRICHParam::Pc2Win()*cos(phi)*tan(thetagap);
+  Float_t yw = (AliRICHParam::RadThick() - lengthOfEmissionPoint)*sin(phi)*tan(theta);
+  Float_t yq = AliRICHParam::WinThick()*sin(phi)*tan(thetaquar);
+  Float_t yg = AliRICHParam::Pc2Win()*sin(phi)*tan(thetagap);
 
 
   Float_t xtot = xemiss + xw + xq + xg;
@@ -733,8 +641,7 @@ Float_t AliRICHRecon::FromEmissionToCathode()
   SetYPointOnCathode(ytot);
 
 
-  Float_t distanceFromEntrance = sqrt(TMath::Power(fPhotonLimitX,2)
-                                   +TMath::Power(fPhotonLimitY,2)); 
+  Float_t distanceFromEntrance = TMath::Sqrt(TMath::Power(fPhotonLimitX,2)+TMath::Power(fPhotonLimitY,2)); 
 
   return distanceFromEntrance;
 
@@ -799,17 +706,19 @@ Float_t AliRICHRecon::SnellAngle(Float_t n1, Float_t n2, Float_t theta1)
   return refractangle;
 }
 //__________________________________________________________________________________________________
-void AliRICHRecon::HoughResponse()
+Double_t AliRICHRecon::HoughResponse()
 {
+//
+//
+//       
   Int_t nChannels = (Int_t)(fThetaMax/fDTheta+0.5);
-  TH1F *phots = new TH1F("phots","phots",nChannels,0.,fThetaMax);
-  TH1F *photsw = new TH1F("photsw","photsw",nChannels,0.,fThetaMax);
-  TH1F *resultw = new TH1F("resultw","resultw",nChannels,0.,fThetaMax);
-  Int_t nPhotons = GetPhotonsNumber();
+  TH1F *phots   = new TH1F("phots"  ,"phots"  ,nChannels,0,fThetaMax);
+  TH1F *photsw  = new TH1F("photsw" ,"photsw" ,nChannels,0,fThetaMax);
+  TH1F *resultw = new TH1F("resultw","resultw",nChannels,0,fThetaMax);
   Int_t nBin = (Int_t)(fThetaMax/fDTheta);
   Int_t nCorrBand = (Int_t)(fWindowWidth/(2*fDTheta));
   AliDebug(1,Form("Ring reconstruction for track with theta %f",GetTrackTheta()*TMath::RadToDeg()));         
-  for (Int_t kPhot=0; kPhot< nPhotons; kPhot++){
+  for (Int_t kPhot=0; kPhot< GetPhotonsNumber(); kPhot++){
     SetPhotonIndex(kPhot);
     Double_t angle = GetPhotonEta();
     if(angle<0||angle>fThetaMax) continue;
@@ -842,14 +751,13 @@ void AliRICHRecon::HoughResponse()
     if(sumPhots<fMinNumPhots) continue; // cut on minimum n. of photons per ring
     Double_t sumPhotsw=photsw->Integral(bin1,bin2);
     resultw->Fill((Float_t)((i+0.5)*fDTheta),sumPhotsw);
-} 
-// evaluate the "BEST" thetacerenkov....
+  } 
+// evaluate the "BEST" theta ckov as the maximum value of histogramm
   Float_t *pVec = resultw->GetArray();
   Int_t locMax = TMath::LocMax(nBin,pVec);
-  SetThetaCerenkov((Double_t)(locMax*fDTheta+0.5*fDTheta));
-   
-// Reset and delete objects
-  phots->Delete();photsw->Delete();resultw->Delete(); 
+  phots->Delete();photsw->Delete();resultw->Delete(); // Reset and delete objects
+  
+  return (Double_t)(locMax*fDTheta+0.5*fDTheta); //final most probable track theta ckov   
 }//HoughResponse
 //__________________________________________________________________________________________________
 void AliRICHRecon::FindThetaCerenkov()
@@ -859,22 +767,18 @@ void AliRICHRecon::FindThetaCerenkov()
   Float_t wei = 0.;
   Float_t weightThetaCerenkov = 0.;
 
-  Int_t nPhotons = GetPhotonsNumber();
   Double_t etaMin=9999.,etaMax=0.;
-  for(Int_t i=0;i<nPhotons;i++)
-    {
-      SetPhotonIndex(i);
-
-      if(GetPhotonFlag() == 2)
-       {
-         Float_t photonEta = GetPhotonEta();
-          if(photonEta<etaMin) etaMin=photonEta;
-          if(photonEta>etaMax) etaMax=photonEta;
-         Float_t photonWeight = GetPhotonWeight();
-         weightThetaCerenkov += photonEta*photonWeight;
-         wei += photonWeight;
-       }
-    }
+  for(Int_t i=0;i<GetPhotonsNumber();i++){
+    SetPhotonIndex(i);
+    if(GetPhotonFlag() == 2){
+         Float_t photonEta = GetPhotonEta();
+      if(photonEta<etaMin) etaMin=photonEta;
+      if(photonEta>etaMax) etaMax=photonEta;
+           Float_t photonWeight = GetPhotonWeight();
+           weightThetaCerenkov += photonEta*photonWeight;
+           wei += photonWeight;
+         }
+  }
 
   if(wei != 0.) weightThetaCerenkov /= wei; else weightThetaCerenkov = 0.;  
   SetThetaCerenkov(weightThetaCerenkov);
@@ -884,57 +788,33 @@ void AliRICHRecon::FindThetaCerenkov()
   SetThetaOfRing(etaMax); FindAreaAndPortionOfRing(); Double_t externalArea = GetAreaOfRing();
 
   Double_t effArea = (AliRICHParam::PcSizeX()-AliRICHParam::DeadZone())*(AliRICHParam::PcSizeY()-2*AliRICHParam::DeadZone());
-  Double_t nPhotBKG = (externalArea-internalArea)/effArea*fpClusters->GetEntries();
+  Double_t nPhotBKG = (externalArea-internalArea)/effArea*fClusters->GetEntries();
   if(nPhotBKG<0) nPhotBKG=0; //just protection from funny angles...
   SetPhotBKG(nPhotBKG);
   //
   
   AliDebug(1,Form(" thetac weighted -> %f",weightThetaCerenkov));
 }
-//__________________________________________________________________________________________________
-void AliRICHRecon::FlagPhotons()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHRecon::FlagPhotons(Double_t thetaCkovHough)
 {
-  // flag photons
+// flag photon candidates if their individual theta ckov inside the window  around theta ckov of Hough transform 
+// Arguments: thetaCkovHough- value of most probable theta ckov for track as returned by HoughResponse()
+//   Returns: number of photon candidates happened to be inside the window
 
-  Int_t nPhotonHough = 0;
-
-  Float_t thetaCerenkov = GetThetaCerenkov();
-  AliDebug(1,Form(" fThetaCerenkov %f ",thetaCerenkov));
-
-  Float_t thetaDist= thetaCerenkov - fThetaMin;
-  Int_t steps = (Int_t)(thetaDist / fDTheta);
+  Int_t steps = (Int_t)((thetaCkovHough - fThetaMin)/ fDTheta); //how many times we need to have fDTheta to fill the distance betwee fThetaMin and thetaCkovHough
 
   Float_t tmin = fThetaMin + (Float_t)(steps - 1)*fDTheta;
   Float_t tmax = fThetaMin + (Float_t)(steps)*fDTheta;
   Float_t tavg = 0.5*(tmin+tmax);
 
-  tmin = tavg - 0.5*fWindowWidth;
-  tmax = tavg + 0.5*fWindowWidth;
-
-  //  Int_t candidatePhotonsNumber = GetCandidatePhotonsNumber();
-
-  Int_t nPhotons = GetPhotonsNumber();
-
-  //  for(Int_t i=0;i<candidatePhotonsNumber;i++)
-
-//  TH1F* h1_phots = (TH1F*)gROOT->FindObjectAny("h1_phots");
-  
-//  cout << "h1_phots " << h1_phots << endl;
-  
-  for(Int_t i=0;i<nPhotons;i++)
-    {
-      SetPhotonIndex(i);
-
-      Float_t photonEta = GetPhotonEta();
-
-      if(photonEta == -999.) continue;
+  tmin = tavg - 0.5*fWindowWidth;  tmax = tavg + 0.5*fWindowWidth;
 
-      if(photonEta >= tmin && photonEta <= tmax)
-       {
-         SetPhotonFlag(2);
-         nPhotonHough++;
-//          if(h1_phots)h1_phots->Fill(photonEta);
-       }
-    }
-  SetHoughPhotons(nPhotonHough);
-}
+  Int_t iInsideCnt = 0; //count photons which theta inside prdefined window
+  for(Int_t i=0;i<GetPhotonsNumber();i++){//photon candidates loop
+    SetPhotonIndex(i);  Float_t photonEta = GetPhotonEta();
+    if(photonEta == -999.) continue;
+    if(photonEta >= tmin && photonEta <= tmax) { SetPhotonFlag(2);       iInsideCnt++;}
+  }
+  return iInsideCnt;
+}//FlagPhotons
index d402540..50048cb 100644 (file)
 //////////////////////////////////////////////////////////////////////////
 
 
-#include <TTask.h>
+#include <TTask.h> //base class
 
 class AliRICHHelix;
-
+class AliRICHParam;
+class TClonesArray;
 class AliRICHRecon : public TTask 
 {
 public : 
-    AliRICHRecon(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t iMipId);
-    virtual ~AliRICHRecon(){;}
+             AliRICHRecon();
+    virtual ~AliRICHRecon()                                                          {}
 
-  Double_t ThetaCerenkov();                   // it returns reconstructed Theta Cerenkov
+  Double_t ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pCluLst,Int_t &iMipId);                  // it returns reconstructed Theta Cerenkov
   void FindThetaPhotonCerenkov();             //
   void FindAreaAndPortionOfRing();            //
-  void FindEmissionPoint();                   //
   void FindPhotonAnglesInDRS();               //
   void FindPhiPoint();                        //
   void FindThetaAtQuartz(Float_t ThetaCer);   //
-  void HoughResponse();                       //
-  void FlagPhotons();                         //
+  Double_t HoughResponse (              );                   //most probable track theta ckov out of all photon candidate thetas 
+  Int_t    FlagPhotons   (Double_t theta);                   //n. of photon candidates which thetas are inside a window around most probable track theta ckov
   void FindThetaCerenkov();                   //
   void FindIntersectionWithDetector();        //
   Float_t Cerenkovangle(Float_t n, Float_t b);//
@@ -39,17 +39,9 @@ public :
   Int_t   CheckDetectorAcceptance() const;    //
   Int_t   GetFittedHoughPhotons()                   const{ return fFittedHoughPhotons;}             //
   Int_t   GetPhotonFlag()                           const{ return fPhotonFlag[fPhotonIndex];}       //
-  Int_t   GetTrackCharge()                          const{ return fTrackCharge;}                    //
   Int_t   GetPhotonsNumber()                        const{ return fPhotonsNumber;}                  //
   Int_t   GetPhotonIndex()                          const{ return fPhotonIndex;}                    //
-  Int_t   GetMipIndex()                             const{ return fMipIndex;}                       //
-  Int_t   GetTrackIndex()                           const{ return fTrackIndex;}                     //
-  Int_t   GetCandidatePhotonsNumber()               const{ return fCandidatePhotonsNumber;}         //
-  Int_t   GetHoughPhotons()                         const{ return fHoughPhotons;}                   //
-  Float_t GetPhotonEnergy()                         const{ return fPhotonEnergy;}                   //
-  Float_t GetFreonRefractiveIndex()                 const{ return fFreonRefractiveIndex;}           //
-  Float_t GetQuartzRefractiveIndex()                const{ return fQuartzRefractiveIndex;}          //
-  Float_t GetGasRefractiveIndex()                   const{ return fGasRefractiveIndex;}             //
+  Float_t GetPhotonEnergy()                         const{ return fEphot;}                          //
   Float_t GetEmissionPoint()                        const{ return fLengthEmissionPoint;}            //
   Float_t GetMassHypotesis()                        const{ return fMassHypotesis;}                  //
   Float_t GetBetaOfParticle()                       const{ return fTrackBeta;}                      //
@@ -92,11 +84,7 @@ public :
   Float_t GetFittedTrackTheta()                     const{ return fFittedTrackTheta;}               //
   Float_t GetFittedTrackPhi()                       const{ return fFittedTrackPhi;}                 //
   Float_t GetFittedThetaCerenkov()                  const{ return fFittedThetaCerenkov;}            //
-  void SetPhotonEnergy(Float_t PhotonEnergy) { fPhotonEnergy = PhotonEnergy;}                       //
-  void SetFreonRefractiveIndex() {fFreonRefractiveIndex = fFreonScaleFactor*(1.177+0.0172*fPhotonEnergy);}//
-  void SetQuartzRefractiveIndex() {fQuartzRefractiveIndex = sqrt(1+(46.411/(113.763556-TMath::Power(fPhotonEnergy,2)))+(228.71/(328.51563-TMath::Power(fPhotonEnergy,2))));}//
-  void SetGasRefractiveIndex() { fGasRefractiveIndex = 1.;}                                         //
-  void SetFreonScaleFactor(Float_t FreonScaleFactor) {fFreonScaleFactor = FreonScaleFactor;}        //
+  void    SetPhotonEnergy(Float_t e)                     { fEphot = e;}                       //
   void SetEmissionPoint(Float_t LengthEmissionPoint) { fLengthEmissionPoint = LengthEmissionPoint;} //
   void SetEntranceX(Float_t Xtoentr) { fXtoentr = Xtoentr;}                                         //
   void SetEntranceY(Float_t Ytoentr) { fYtoentr = Ytoentr;}                                         //
@@ -120,7 +108,6 @@ public :
   void SetThetaPhotonCerenkov(Float_t ThetaPhotCer) {fThetaPhotonCerenkov = ThetaPhotCer;}          //
   void SetTrackTheta(Float_t TrackTheta) { fTrackTheta = TrackTheta;}                               //
   void SetTrackPhi(Float_t TrackPhi) { fTrackPhi = TrackPhi;}                                       //
-  void SetTrackCharge(Int_t TrackCharge) { fTrackCharge = TrackCharge;}                             //
   void SetShiftX(Float_t ShiftX) { fShiftX = ShiftX;}                                               //
   void SetShiftY(Float_t ShiftY) { fShiftY = ShiftY;}                                               //
   void SetDetectorWhereX(Float_t Xcoord) { fXcoord = Xcoord;}                                       //
@@ -138,28 +125,19 @@ public :
   void SetPhotonWeight(Float_t PhotonWeight) { fPhotonWeight[fPhotonIndex] = PhotonWeight;}         //
   void SetPhotBKG(Double_t nPhotBKG) {fnPhotBKG=nPhotBKG;}                                          //
   void SetHoughRMS(Float_t HoughRMS) { fHoughRMS = HoughRMS;}                                       //
-  void SetMipIndex(Int_t MipIndex) { fMipIndex = MipIndex;}                                         //
-  void SetTrackIndex(Int_t TrackIndex) { fTrackIndex = TrackIndex;}                                 //
-  void SetHoughPhotons(Int_t HoughPhotons) { fHoughPhotons = HoughPhotons;}                         //
-  void SetHoughPhotonsNorm(Float_t HoughPhotonsNorm) { fHoughPhotonsNorm = HoughPhotonsNorm;}       //
   void SetFittedTrackTheta(Float_t FittedTrackTheta)    { fFittedTrackTheta = FittedTrackTheta;}    //
   void SetFittedTrackPhi(Float_t FittedTrackPhi)    { fFittedTrackPhi = FittedTrackPhi;}            //
   void SetFittedThetaCerenkov(Float_t FittedThetaCerenkov) { fFittedThetaCerenkov = FittedThetaCerenkov;}//
   void SetFittedHoughPhotons(Int_t FittedHoughPhotons) { fFittedHoughPhotons = FittedHoughPhotons;} //
-  void FindBetaFromTheta(Float_t ThetaCerenkov) {fTrackBeta = 1/(fFreonRefractiveIndex*cos(ThetaCerenkov));}//
   Float_t SnellAngle(Float_t n1, Float_t n2, Float_t theta1);                                       //
   Float_t FromEmissionToCathode();                                                                  //
 
 protected:
-  TClonesArray *fpClusters;                   // poiter to clusters
-  Int_t   fTrackCharge;                       // charge track
-  Int_t fMipIndex;                            // index for Mip
-  Int_t fTrackIndex;                          // index for track
+  TClonesArray *fClusters;                    //tmp pointer to list of clusters
+  AliRICHParam *fParam;                       //tmp pointer to AliRICHParam instance containing all the parameters needed for proccessing
   Int_t fPhotonsNumber;                       // Number of photons candidate
   Int_t fPhotonIndex;                         // index of photons
   Int_t fPhotonFlag[3000];                    // flag for photons
-  Int_t fCandidatePhotonsNumber;              // number of candidate photons
-  Int_t fHoughPhotons;                        // n. photons after Hough
   Int_t   fFittedHoughPhotons;                // n. photons after Hough and after minimization
   Int_t fMinNumPhots;                         // minimum number of photons for a given ring
 
@@ -183,11 +161,7 @@ protected:
   Float_t fYOuter;                            // Y outer ring
   Float_t fInnerRadius;                       // inner radius
   Float_t fOuterRadius;                       // outer radius
-  Float_t fPhotonEnergy;                      // photon energy
-  Float_t fFreonRefractiveIndex;              // n freon
-  Float_t fQuartzRefractiveIndex;             // n quartz
-  Float_t fGasRefractiveIndex;                // n gas
-  Float_t fFreonScaleFactor;                  // scale factor for n freon
+  Float_t fEphot;                             // photon energy
   Float_t fLengthEmissionPoint;               // lenght of emmission point
   Float_t fPhotonLimitX;                      // X phys limit for photon
   Float_t fPhotonLimitY;                      // Y phys limit for photon 
@@ -210,18 +184,12 @@ protected:
   Float_t fHoughRMS;                          // rms Hough
   Float_t* fCandidatePhotonX;                 // x photon candidates
   Float_t* fCandidatePhotonY;                 // y photon candidates
-  Float_t fHoughPhotonsNorm;                  // n. photons norm.
   Float_t fFittedTrackTheta;                  // theta track after minim.
   Float_t fFittedTrackPhi;                    // phi track after minim.
   Float_t fFittedThetaCerenkov;               // thetacerenkov after minim.
   Float_t fThetaMin,fThetaMax;                // min max
-  Float_t fXmin,fXmax,fYmin,fYmax;            // xy min max
-  Int_t   fNrings;                            //current number of reconstructed rings
   Bool_t  fIsWEIGHT;                          // flag to consider weight procedure
   Bool_t  fIsBACKGROUND;                      // flag to simulate bkg
-  Float_t fRadiatorWidth;                     // radiator width
-  Float_t fQuartzWidth;                       // quartz width
-  Float_t fGapWidth;                          // gap width
   Float_t fDTheta;                            // Step for sliding window
   Float_t fWindowWidth;                       // Hough width of sliding window
   
@@ -234,7 +202,6 @@ protected:
   Float_t fWeightThetaCerenkov;               // Theta Cerenkov angle weighted
   Float_t fThetaPeakPos;                      // Peak position
 
-
   ClassDef(AliRICHRecon,0)
 };
     
index f5198be..eef4594 100644 (file)
 #include "AliRICH.h"              //Reconstruct(...) 
 #include <AliRawReader.h>         //Reconstruct(...)
 #include <AliRun.h>               //ConvertDigits uses gAlice
-#include <AliESD.h>            //RichAna()
-#include <AliStack.h>          //RichAna()
-#include <TFile.h>             //RichAna()
-#include <TMinuit.h>              //Dig2Clu()
-#include <TParticle.h>            //TParticle()
+#include <AliESD.h>               //RichAna()
+#include <AliStack.h>             //RichAna()
+#include <TFile.h>                //RichAna()
+#include <TFile.h>                //RichAna()
+#include <TParticle.h>            //RichAna()
+#include <TH1F.h>                 //CluQA() 
+#include <TH2F.h>                 //CluQA() 
+#include <TCanvas.h>              //CluQA() 
+#include <TNtupleD.h>             //CheckPR()
 ClassImp(AliRICHReconstructor)
 
+//__________________________________________________________________________________________________
+void AliRICHReconstructor::CluQA(AliRunLoader *pAL)
+{
+// Quality assesment plots for clusters. 
+// This methode takes list of digits and form list of clusters again in order to 
+// calculate cluster shape and cluster particle mixture    
+  AliLoader *pRL=pAL->GetDetectorLoader("RICH");  AliRICH *pRich=(AliRICH*)pAL->GetAliRun()->GetDetector("RICH");//get pointers for RICH and RICH loader
+  Int_t iNevt=pAL->GetNumberOfEvents();  if(iNevt==0)             {AliInfoClass("No events");return;}   
+                                         if(pRL->LoadDigits())    {AliInfoClass("No digits file");return;}
+                                            pAL->LoadHeader();
+                                            pAL->LoadKinematics(); 
+//                                            AliStack *pStack=pAL->Stack();
+  TH1::AddDirectory(kFALSE);
+  
+  TH1F *pN   =new TH1F("RichCluPerEvt"  ,"Number of clusters per event;number" ,100                    ,0  ,99                                                        );
+  TH1F* pQ   =new TH1F("RichCluQdc"     ,"Cluster QDC;q [QDC]"                 ,4000 ,0  ,4000                                    );
+  TH1F* pS   =new TH1F("RichCluSize"    ,"Cluster size;size"                   ,100                    ,0  ,100                                                       );
+  TH2F* pM   =new TH2F("RichCluMap"     ,"Cluster map;x [cm];y [cm]"           ,1000                   ,0  ,AliRICHParam::PcSizeX()   ,1000,0,AliRICHParam::PcSizeY() );
+        
+  TH1F* pMipQ=new TH1F("RichCluMipQdc"  ,"MIP QDC;q [QDC]"                     ,4000 ,0  ,4000                                    );
+  TH1F* pMipS=new TH1F("RichCluMipSize" ,"MIP size;size"                       ,100                    ,0  ,100                                                       );
+  TH2F* pMipM=new TH2F("RichCluMipMap"  ,"MIP map;x [cm];y [cm]"               ,1000                   ,0  ,AliRICHParam::PcSizeX()   ,1000,0,AliRICHParam::PcSizeY() );
+  
+  TH1F* pCerQ=new TH1F("RichCluCerQdc"  ,"Ckov QDC;q [QDC]"                    ,4000 ,0  ,4000                                    );
+  TH1F* pCerS=new TH1F("RichCluCerSize" ,"Ckov size;size"                      ,100                    ,0  ,100                                                       );
+  TH2F* pCerM=new TH2F("RichCluCerMap"  ,"Ckov map;x [cm];y [cm]"              ,1000                   ,0  ,AliRICHParam::PcSizeX()   ,1000,0,AliRICHParam::PcSizeY() );
+    
+  TH1F* pFeeQ=new TH1F("RichCluFeeQdc"  ,"Fee QDC;q [QDC]"                     ,4000 ,0  ,4000);
+  TH1F* pFeeS=new TH1F("RichCluFeeSize" ,"Fee size;size"                       ,100                    ,0  ,100                                                       );
+  TH2F* pFeeM=new TH2F("RichCluFeeMap"  ,"Fee map;x [cm];y [cm]"               ,1000                   ,0  ,AliRICHParam::PcSizeX()   ,1000,0,AliRICHParam::PcSizeY() );
+  
+  TClonesArray *pCluLst=new TClonesArray("AliRICHCluster");//tmp list of clusters
+  
+  for(Int_t iEvtN=0; iEvtN<iNevt; iEvtN++){
+    pAL->GetEvent(iEvtN);               
+    pRL->TreeD()->GetEntry(0); 
+    for(Int_t iChN=1;iChN<=7;iChN++){//chambers loop
+      if(pRich->Digs(iChN)->GetEntriesFast()>0) Dig2Clu(pRich->Digs(iChN),pCluLst,kFALSE);//cluster finder for the current chamber if any digits present
+    }//chambers loop
+    
+    pCluLst->Print();
+    for(Int_t iCluN=0 ; iCluN < pCluLst->GetEntriesFast() ; iCluN++){
+      AliRICHCluster *pClu = (AliRICHCluster*)pCluLst->At(iCluN);
+      Int_t iNckov=0,iNfee=0,iNmip=0; 
+                                             pQ   ->Fill(pClu->Q()) ; pS   ->Fill(pClu->Size()) ; pM    ->Fill(pClu->X(),pClu->Y()); //all clusters                                      
+      if(iNckov!=0 && iNfee==0 && iNmip==0) {pCerQ->Fill(pClu->Q()) ; pCerS->Fill(pClu->Size()) ; pCerM ->Fill(pClu->X(),pClu->Y());}//ckov only cluster
+      if(iNckov==0 && iNfee!=0 && iNmip==0) {pFeeQ->Fill(pClu->Q()) ; pFeeS->Fill(pClu->Size()) ; pFeeM ->Fill(pClu->X(),pClu->Y());}//feed only cluster
+      if(iNckov==0 && iNfee==0 && iNmip!=0) {pMipQ->Fill(pClu->Q()) ; pMipS->Fill(pClu->Size()) ; pMipM ->Fill(pClu->X(),pClu->Y());}//mip only cluster
+                                       
+    }//clusters loop   
+  }//events loop
+  
+  pRL->UnloadDigits(); pAL->UnloadKinematics(); pAL->UnloadHeader();
+  TCanvas *pC=new TCanvas("RichCluQA",Form("QA for cluster from %i events",iNevt),1000,900); pC->Divide(3,3);
+  pC->cd(1); pN->Draw();          pC->cd(2); pQ->Draw();          pC->cd(3); pS->Draw();        
+  pC->cd(4); pN->Draw();          pC->cd(5); pMipQ->Draw();       pC->cd(6); pMipS->Draw();        
+  pC->cd(7); pN->Draw();          pC->cd(8); pCerQ->Draw();       pC->cd(9); pCerS->Draw();        
+}//CluQA()
+//__________________________________________________________________________________________________
+void AliRICHReconstructor::CheckPR()
+{
+//Pattern recognition with stack particles
+  TFile *pFile = new TFile("$(HOME)/RPR.root","RECREATE","RICH Pattern Recognition");
+  TNtupleD *hn = new TNtupleD("hn","ntuple","Pmod:Charge:TrackTheta:TrackPhi:TrackX:TrackY:MinX:MinY:ChargeMIP:ThetaCerenkov:NPhotons:MipIndex:Chamber:Particle");
+//  printf("\n\n");
+//  printf("Pattern Recognition done for event %5i",0);
+  AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH"));
+  AliMagF * magf = gAlice->Field();
+  AliTracker::SetFieldMap(magf,kTRUE);
+  for(Int_t iEvtN=0;iEvtN<pRich->GetLoader()->GetRunLoader()->GetNumberOfEvents();iEvtN++) {
+    pRich->GetLoader()->GetRunLoader()->GetEvent(iEvtN);
+    AliRICHTracker *tr = new AliRICHTracker();
+    tr->RecWithStack(hn);
+    AliInfoClass(Form("Pattern Recognition done for event %i \b",iEvtN));
+//    printf("\b\b\b\b\b%5i",iEvtN+1);
+  }
+  printf("\n\n");
+  pFile->Write();pFile->Close();
+}
+//__________________________________________________________________________________________________
+void AliRICHReconstructor::Dig2Clu(TClonesArray *pDigLst,TClonesArray *pCluLst,Bool_t isTryUnfold)
+{
+//Finds all clusters for a given digits list provided not empty. Currently digits list is a list of all digits for a single chamber.
+//If pStack not 0 then also finds Ckov-Fee-Mip composition for formed clusters.  
+//Puts all found clusters in the given clusters list. 
+//Arguments: pDigLst     - list of digits provided not empty
+//           pCluLst     - list of clusters, provided empty     
+//           isTryUnfold - flag to choose between CoG and Mathieson fitting  
+//  Returns: none    
+  TMatrixF digMap(1,AliRICHParam::NpadsX(),1,AliRICHParam::NpadsY());  digMap=(Float_t)-1; //digit map for one chamber reseted to -1
+  for(Int_t iDigN=0 ; iDigN < pDigLst->GetEntriesFast() ; iDigN++){                        //digits loop to fill digits map
+    AliRICHDigit *pDig= (AliRICHDigit*)pDigLst->At(iDigN);                                   //get current digit
+    digMap( pDig->PadX(), pDig->PadY() )=iDigN;                                              //fill the map, (padx,pady) cell takes digit number
+  }                                                                                        //digits loop to fill digits map 
+  
+  AliRICHCluster clu;                                                                      //tmp cluster to be used as current
+  
+  for(Int_t iDigN=0;iDigN<pDigLst->GetEntriesFast();iDigN++){                              //digits loop to form clusters list
+    AliRICHDigit *pDig=(AliRICHDigit*)pDigLst->At(iDigN);                                  //take current digit
+    if(!(pDig=UseDig(pDig->PadX(),pDig->PadY(),pDigLst,&digMap))) continue;                //this digit is already taken in FormClu(), go after next digit
+    FormClu(&clu,pDig,pDigLst,&digMap);                                                    //form cluster starting from this digit by recursion
+    clu.Solve(pCluLst,isTryUnfold);                                                        //solve this cluster and add all unfolded clusters to provided list  
+    clu.Reset();                                                                           //empty current cluster
+  }                                                                                        //digits loop to form clusters list
+}//Dig2Clu()
+//__________________________________________________________________________________________________
+void  AliRICHReconstructor::FormClu(AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigLst,TMatrixF *pDigMap)
+{
+//Forms the initial cluster as a sum of all adjascent digits. Starts from the given digit
+//then calls itself recursevly  for all neighbours.
+//Arguments: pClu - pointer to cluster being formed
+//  Returns: none
+  pClu->DigAdd(pDig);//take this digit in cluster
+
+  Int_t x[4],y[4];
+  
+  Int_t iNnei=AliRICHParam::PadNeighbours(pDig->PadX(),pDig->PadY(),x,y);//returns in x,y all possible neighbours of the given padx,pady
+  for (Int_t i=0;i<iNnei;i++)
+    if((pDig=UseDig(x[i],y[i],pDigLst,pDigMap))) FormClu(pClu,pDig,pDigLst,pDigMap);   //check if this neighbour hit and mark it as taken  
+}//FormClu()
+//__________________________________________________________________________________________________
+void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL)const
+{
+//Invoked  by AliReconstruction to convert digits to clusters i.e. reconstruct simulated data
+//Arguments: pAL - ALICE run loader pointer
+//  Returns: none    
+  AliDebug(1,"Start.");
+  AliLoader *pRL=pAL->GetDetectorLoader("RICH");  AliRICH *pRich=(AliRICH*)pAL->GetAliRun()->GetDetector("RICH");//get pointers for RICH and RICH loader
+  pRL->LoadDigits();   
+  
+  for(Int_t iEvtN=0;iEvtN<pAL->GetNumberOfEvents();iEvtN++){//events loop
+    pAL->GetEvent(iEvtN++); AliDebug(1,Form("Processing event %i...",iEvtN)); //switch current directory to next event    
+    pRL->TreeD()->GetEntry(0);  pRL->MakeTree("R");  pRich->MakeBranch("R");  //load digits to memory  and create branches for clusters              
+    for(Int_t iChN=1;iChN<=7;iChN++){//chambers loop
+      if(pRich->Digs(iChN)->GetEntriesFast()>0) Dig2Clu(pRich->Digs(iChN),pRich->Clus(iChN));//cluster finder for the current chamber if any digits present
+    }//chambers loop
+    pRL->TreeR()->Fill();            //fill tree for current event
+    pRL->WriteRecPoints("OVERWRITE");//write out clusters for current event
+    pRich->DigReset(); pRich->CluReset();
+  }//events loop  
+
+  pRL->UnloadDigits(); 
+  pRL->UnloadRecPoints();  
+    
+  AliDebug(1,"Stop.");      
+}//Reconstruct(for simulated digits)
+//__________________________________________________________________________________________________
 void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const
 {
 //Invoked  by AliReconstruction to convert raw digits from DDL files to clusters
@@ -46,92 +198,20 @@ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const
       while(pRR->ReadNextInt(w32)){//raw records loop (in selected DDL files)
         UInt_t ddl=pRR->GetDDLID(); //returns 0,1,2 ... 13
         dig.Raw2Dig(ddl,w32);  
-        AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iChN,ddl,w32,dig.Chamber(),dig.Sector(),dig.PadX(),dig.PadY(),dig.Qdc()));
+        AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iChN,ddl,w32,dig.C(),dig.S(),dig.PadX(),dig.PadY(),dig.Qdc()));
         new((*pDigList)[iDigCnt++]) AliRICHDigit(dig); //add this digit to the tmp list
       }//raw records loop
-      if(iDigCnt) Dig2Clu(pDigList,pRich->Clusters(iChN));//cluster finder for the current chamber if any digits present
+      if(iDigCnt) Dig2Clu(pDigList,pRich->Clus(iChN));//cluster finder for the current chamber if any digits present
       pRR->Reset();        
       pDigList->Delete();  iDigCnt=0;//clean up list of digits for the current chamber
     }//chambers loop
     pRL->TreeR()->Fill();            //fill tree for current event
     pRL->WriteRecPoints("OVERWRITE");//write out clusters for current event
-    pRich->ClustersReset();
+    pRich->CluReset();
   }//events loop  
   pRL->UnloadRecPoints();  
 }//Reconstruct raw data
 //__________________________________________________________________________________________________
-void AliRICHReconstructor::Dig2Clu(TClonesArray *pDigList,TClonesArray *pCluList)const
-{
-//Finds all clusters for a given digits list provided not empty. Currently digits list provided is a list of all digits for a single chamber.
-//Puts all found clusters in the given clusters list. 
-//Arguments: pDigList - list of digits provided not empty
-//  Returns: none    
-  TMatrixF digMap(1,AliRICHParam::NpadsX(),1,AliRICHParam::NpadsY());  digMap=(Float_t)-1; //digit map for one chamber reseted to -1
-  for(Int_t iDigN=0 ; iDigN < pDigList->GetEntriesFast() ; iDigN++){ //digits loop to fill digits map
-    AliRICHDigit *pDig= (AliRICHDigit*)pDigList->At(iDigN);
-    digMap( pDig->PadX(), pDig->PadY() )=iDigN;                     //(padx,pady) cell takes digit number
-  }
-  
-  AliRICHCluster clu; Int_t iCluCnt=0; //tmp cluster and cluster counter
-  
-  for(Int_t iDigN=0;iDigN<pDigList->GetEntriesFast();iDigN++){//digits loop    
-    AliRICHDigit *pDig=(AliRICHDigit*)pDigList->At(iDigN);
-    if(!(pDig=UseDig(pDig->PadX(),pDig->PadY(),pDigList,&digMap))) continue;  //this digit is already taken in FormCluster(), go after next digit
-    FormCluster(&clu,pDig,pDigList,&digMap);                            //form cluster starting from this digit
-    TMinuit *pMinuit=clu.Solve();                              //solve this cluster
-    
-    if(pMinuit){//means cluster is solved into local maxima number of clusters, so add all of them in loop
-      Double_t x=-1,y=-1,q=-1;TString str; Double_t b1,b2,b3; Int_t iErrFlg;//tmp to withdraw resulting parameters
-      for(Int_t i=0;i<clu.Nlocmax();i++){//take resulting parameters 
-        pMinuit->mnpout(3*i  ,str, x, b1, b2, b3, iErrFlg);
-        pMinuit->mnpout(3*i+1,str, y, b1, b2, b3, iErrFlg);
-        pMinuit->mnpout(3*i+2,str, q, b1, b2, b3, iErrFlg);
-        clu.Set(x,y,(Int_t)q);
-        new((*pCluList)[iCluCnt++]) AliRICHCluster(clu);
-      }
-      delete pMinuit;
-    }else//means cluster is solved as simple center of gravity cluster, add it
-      new((*pCluList)[iCluCnt++]) AliRICHCluster(clu); 
-    clu.Reset();//make current cluster empty
-  }//digits loop
-}//Dig2Clu()
-//__________________________________________________________________________________________________
-void  AliRICHReconstructor::FormCluster(AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigList,TMatrixF *pDigMap)const
-{
-//Forms the initial cluster as a sum of all adjascent digits. Starts from the given digit
-//then calls itself recursevly  for all neighbours.
-//Arguments: pClu - pointer to cluster being formed
-//  Returns: none
-  pClu->AddDigit(pDig);//take this digit in cluster and mark it as taken
-
-  Int_t x[4],y[4];
-  
-  Int_t iNnei=AliRICHParam::PadNeighbours(pDig->PadX(),pDig->PadY(),x,y);//returns in x,y all possible neighbours of the given one
-  for (Int_t i=0;i<iNnei;i++)
-    if((pDig=UseDig(x[i],y[i],pDigList,pDigMap))) FormCluster(pClu,pDig,pDigList,pDigMap);    
-}//FormCluster()
-//__________________________________________________________________________________________________
-void AliRICHReconstructor::CheckPR()
-{
-//Pattern recognition with stack particles
-  TFile *pFile = new TFile("$(HOME)/RPR.root","RECREATE","RICH Pattern Recognition");
-  TNtupleD *hn = new TNtupleD("hn","ntuple","Pmod:Charge:TrackTheta:TrackPhi:TrackX:TrackY:MinX:MinY:ChargeMIP:ThetaCerenkov:NPhotons:MipIndex:Chamber:Particle");
-//  printf("\n\n");
-//  printf("Pattern Recognition done for event %5i",0);
-  AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH"));
-  AliMagF * magf = gAlice->Field();
-  AliTracker::SetFieldMap(magf,kTRUE);
-  for(Int_t iEvtN=0;iEvtN<pRich->GetLoader()->GetRunLoader()->GetNumberOfEvents();iEvtN++) {
-    pRich->GetLoader()->GetRunLoader()->GetEvent(iEvtN);
-    AliRICHTracker *tr = new AliRICHTracker();
-    tr->RecWithStack(hn);
-    AliInfoClass(Form("Pattern Recognition done for event %i \b",iEvtN));
-//    printf("\b\b\b\b\b%5i",iEvtN+1);
-  }
-  printf("\n\n");
-  pFile->Write();pFile->Close();
-}
-//__________________________________________________________________________________________________
 void AliRICHReconstructor::RichAna(Int_t iNevMin,Int_t iNevMax,Bool_t askPatRec)
 {
   TFile *pFile=TFile::Open("AliESDs.root","read");
@@ -175,7 +255,7 @@ void AliRICHReconstructor::RichAna(Int_t iNevMin,Int_t iNevMax,Bool_t askPatRec)
       for(Int_t iTrackN=0;iTrackN<iNtracks;iTrackN++){//ESD tracks loop
         if(iTrackN%100==0)AliInfoClass(Form("Track %i to be processed",iTrackN));
         AliRICHTracker *pTrRich = new AliRICHTracker();
-        if(askPatRec==kTRUE) pTrRich->RecWithESD(pESD,pRich,iTrackN);
+        if(askPatRec==kTRUE) pTrRich->PropagateBack(pESD);
         AliESDtrack *pTrack = pESD->GetTrack(iTrackN);// get next reconstructed track
         
         Int_t lab=TMath::Abs(pTrack->GetLabel());
@@ -205,13 +285,13 @@ void AliRICHReconstructor::RichAna(Int_t iNevMin,Int_t iNevMax,Bool_t askPatRec)
         hnvec[17]=pTrRich->fErrPar[4];
         for(Int_t i=0;i<3;i++) {
           Double_t mass = AliRICHParam::fgMass[i+2];
-          Double_t refIndex=AliRICHParam::RefIdxC6F14(AliRICHParam::MeanCkovEnergy());
+          Double_t refIndex=AliRICHParam::Instance()->IdxC6F14(AliRICHParam::EckovMean());
           Double_t cosThetaTh = TMath::Sqrt(mass*mass+pTrack->GetP()*pTrack->GetP())/(refIndex*pTrack->GetP());
           hnvec[18+i]=0;
           if(cosThetaTh>=1) continue;
           hnvec[18+i]= TMath::ACos(cosThetaTh);
         }
-        if(askPatRec==kTRUE) hnvec[21]=pTrRich->fnPhotBKG; else hnvec[21]=0;
+//        if(askPatRec==kTRUE) hnvec[21]=pTrRich->fnPhotBKG; else hnvec[21]=0;
         hnvec[22]=code;
         hn->Fill(hnvec);
       }
@@ -220,5 +300,32 @@ void AliRICHReconstructor::RichAna(Int_t iNevMin,Int_t iNevMax,Bool_t askPatRec)
   }
   pFileRA->Write();pFileRA->Close();// close RichAna.root
   delete pESD;  pFile->Close();//close AliESDs.root
-}
+}//RichAna()
+//__________________________________________________________________________________________________
+void AliRICHReconstructor::Test(Bool_t isTryUnfold)
+{
+// Test the cluster finding algorithm by providing predifined set of digits
+// Arguments: none
+//   Returns: none  
+  TClonesArray *pDigTst=new TClonesArray("AliRICHDigit");       TClonesArray *pCluTst=new TClonesArray("AliRICHCluster");     
+  Int_t iDigCnt=0;
+  Int_t c,padx,pady,qdc;
+//ckov cluster  
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 89,pady=13,qdc= 10);
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 90,pady=13,qdc=  7);
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 90,pady=12,qdc=  6);
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 91,pady=12,qdc=  7);
+//mip cluster  
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 99,pady=21,qdc=  9);
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 99,pady=22,qdc= 26);
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx=100,pady=21,qdc= 39);
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx=100,pady=22,qdc=109);
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx=100,pady=23,qdc=  7);
+  new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx=101,pady=22,qdc= 11);
+  
+  pDigTst->Print("","Initial digit:");
+  Dig2Clu(pDigTst,pCluTst,isTryUnfold);   
+  pCluTst->Print("","Solved cluster:"); 
+  delete pDigTst; delete pCluTst;
+}//Test()
 //__________________________________________________________________________________________________
index 608669b..db8f9c3 100644 (file)
@@ -5,10 +5,11 @@
 
 #include <AliReconstructor.h>       //base class
 #include "AliRICHTracker.h"         //CreateTracker()
-#include "AliRICHClusterFinder.h"   //Reconstruct()
-
-class AliRawReader;
-class TTree;
+#include <TMatrixF.h>               //UseDig()
+#include <TClonesArray.h>           //UseDig()
+class AliRawReader;                 //Reconstruct() with raw data   
+class AliRICHDigit;                 //Dig2Clu(), UseDig()
+class AliRICHCluster;               //Dig2Clu()
 
 class AliRICHReconstructor: public AliReconstructor 
 {
@@ -16,34 +17,33 @@ public:
            AliRICHReconstructor(): AliReconstructor()              {}//default ctor
   virtual ~AliRICHReconstructor()                                  {}//dtor  
 //framework part  
-  AliTracker*  CreateTracker         (AliRunLoader*                      )const{return new AliRICHTracker;}                 //interface from AliReconstructor
-  void         Reconstruct           (AliRunLoader* pAL                  )const{AliRICHClusterFinder cf(pAL);    cf.Exec();}//from AliReconstruction for digits->clusters
-  void         Reconstruct           (AliRunLoader* pAL,AliRawReader *pRR)const;                                            //from AliReconstruction for raw->clusters
-  using AliReconstructor::Reconstruct;                                                                            //to get rid of virtual hidden warning 
+  AliTracker*  CreateTracker         (AliRunLoader*                      )const{return new AliRICHTracker;}            //from AliReconstructor for clusters->PID
+  void         Reconstruct           (AliRunLoader* pAL                  )const;                                       //from AliReconstruction for digits->clusters
+  void         Reconstruct           (AliRunLoader* pAL,AliRawReader *pRR)const;                                       //from AliReconstruction for raws->clusters
+  using AliReconstructor::Reconstruct;                                                                                 //to get rid of virtual hidden warning 
 //private part  
-         void          Dig2Clu    (TClonesArray*pDigList,TClonesArray *pCluList                                    )const;//form clusters out of provided digits list
-         void          FormCluster(AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigList,TMatrixF *pDigMap)const;//form cluster recursive algorithm
-  inline AliRICHDigit *UseDig     (Int_t padX,Int_t padY,TClonesArray *pDigList,TMatrixF *pDigMap                  )const;//use this pad's digit to form a cluster
-  static void          CheckPR    (                                                                                );     //utility-> run staff for stack
-  static void          RichAna    (Int_t iNevMin=0, Int_t iNevMax=99999,Bool_t isPatRec=kFALSE                                      );     //utility-> create ntuples for analysis
-  
+  static        void          Dig2Clu (TClonesArray*pDigLst,TClonesArray *pCluLst,Bool_t isTryUnfold=kTRUE            );//digits list -> clusters list
+  static        void          CluQA   (AliRunLoader* pAL                                                              );//QA for clusters
+  static        void          CheckPR (                                                                               );//utility-> run staff for stack
+  static        void          FormClu (AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigLst,TMatrixF *pDigMap);//cluster formation recursive algorithm
+  static inline AliRICHDigit* UseDig  (Int_t padX,Int_t padY,TClonesArray *pDigList,TMatrixF *pDigMap                 );//use this pad's digit to form a cluster
+  static        void          RichAna (Int_t iNevMin=0,Int_t iNevMax=99999,Bool_t isPatRec=kFALSE                     );//utility-> create ntuples for analysis  
+  static        void          Test    (Bool_t isTryUnfold=kTRUE                                                       );//test digits->clusters  conversion
 protected:
   ClassDef(AliRICHReconstructor, 0)   //class for the RICH reconstruction
 };
 //__________________________________________________________________________________________________
-AliRICHDigit* AliRICHReconstructor::UseDig(Int_t padX,Int_t padY,TClonesArray *pDigList,TMatrixF *pDigMap)const
+AliRICHDigit* AliRICHReconstructor::UseDig(Int_t padX,Int_t padY,TClonesArray *pDigLst,TMatrixF *pDigMap)
 {
 //Digit map contains a matrix if digit numbers.
 //Main operation in forming initial cluster is done here. Requested digit pointer is returned and this digit marked as taken.
 //Arguments: padX,padY - pad number
-//           pDigList  - list of digits for one sector
+//           pDigLst   - list of digits for one sector
 //           pDigMap   - map of those digits
 //  Returns: pointer to digit if not yet used or 0 if used
   Int_t iDig=(Int_t)(*pDigMap)(padX,padY);(*pDigMap)(padX,padY)=-1;//take digit number from the map and reset this map cell to -1
-  if(iDig!=-1)
-    return (AliRICHDigit*)pDigList->At(iDig);    //digit pointer
-  else      
-    return 0;
+  if(iDig!=-1)    return (AliRICHDigit*)pDigLst->At(iDig);         //digit pointer
+  else            return 0;
 }
 
 #endif
index bdb1dec..3370fb0 100644 (file)
-#include "AliRICHTracker.h"
+#include "AliRICHTracker.h" //class header
+#include "AliRICH.h"
+#include "AliRICHRecon.h"
 #include <AliESD.h>
 #include <TVector3.h>
-#include <TTree.h>
-#include "AliRICH.h"
+#include <TTree.h>          //EsdPrint() 
+#include <TFile.h>          //EsdPrint()    
 #include "AliRICHHelix.h"
 #include <AliMagF.h>
-#include "AliRICHRecon.h"
 #include <AliStack.h>
 #include <TParticle.h>
 #include <TMath.h>
 #include <AliRun.h>
+#include <TNtupleD.h>            //RecWithStack();
+#include <AliTrackPointArray.h>  //GetTrackPoint()
+#include <AliAlignObj.h>         //GetTrackPoint()
 ClassImp(AliRICHTracker)
-//__________________________________________________________________________________________________
-Int_t AliRICHTracker::PropagateBack(AliESD *pESD)
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+AliRICHTracker::AliRICHTracker():AliTracker()
 {
-// Interface callback methode invoked by AliRecontruction during tracking after TOF
-// It steers to different way to provide the final reconstructed information sutable for analisys:
-// 1. AliESD  - reconstructed tracks are used     
-// 2. RICH private ntuple for debug- stack particles used instead of reconstructed tracks     
-  AliDebug(1,"Start pattern recognition");
-  if(pESD->GetNumberOfTracks()) {
-    Int_t iNtracks=pESD->GetNumberOfTracks();
-    AliDebug(1,Form("Start with %i tracks",iNtracks));
-    AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH"));  
-    for(Int_t iTrackN=0;iTrackN<iNtracks;iTrackN++){//ESD tracks loop
-      RecWithESD(pESD,pRich,iTrackN);
-    }
-  }
-  else RecWithStack(0);
-  AliDebug(1,"Stop pattern recognition");
-  return 0; // error code: 0=no error;
-}//PropagateBack()
-//__________________________________________________________________________________________________
-void AliRICHTracker::RecWithESD(AliESD *pESD,AliRICH *pRich,Int_t iTrackN)
+// AliRICHTracker is created from AliReconstraction::Run() which invokes AliReconstraction::CreateTrackers() 
+// which in turn invokes AliRICHReconstructor::CreateTracker(). 
+// Note that this is done just once per session before AliReconstruction::Run() goes to events loop.
+  AliRICHParam::Instance()->CdbRead(0,0); 
+  for(Int_t i=0;i<5;i++)fErrPar[i]=0;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    
+Bool_t AliRICHTracker::GetTrackPoint(Int_t idx, AliTrackPoint& point) const
 {
-//recontruction from ESD- primary way to reconstruct particle ID signal from tracks provided by core detectors
-    fnPhotBKG = 0;
-
-    Double_t fField=GetFieldMap()->SolenoidField()/10;// magnetic field in Tesla
-    AliESDtrack *pTrack = pESD->GetTrack(iTrackN);// get next reconstructed track
-//  if((pTrack->GetStatus()&AliESDtrack::kTOFout)==0) continue; //ignore tracks not recontructed by TOF
-//    pTrack->GetXYZ(xb); 
-//    pTrack->GetPxPyPz(pb); 
-    Int_t status=pTrack->GetStatus()&AliESDtrack::kTOFout;//get running track parameters
-    Int_t charge = (Int_t)(-TMath::Sign(1.,pTrack->GetSign()*fField));
-    AliDebug(1,Form("Track %i pmod=%f charge=%i stat=%i",iTrackN,pTrack->GetP(),charge,status));
-    AliRICHHelix helix(pTrack->X3(),pTrack->P3(),charge,fField);   
-    Int_t iChamber=helix.RichIntersect(pRich->P());        
-    AliDebug(1,Form("intersection with %i chamber found",iChamber));
-    if(!iChamber) {
-      pTrack->SetRICHsignal(-999); //to be improved by flags...
-      return;//intersection with no chamber found
-    }
-//find MIP cluster candidate (cluster which is closest to track intersection point)
-    Double_t distMip=9999,distX=0,distY=0; //min distance between clusters and track position on PC 
-    Int_t iMipId=0; //index of that min distance cluster
-    Double_t chargeMip=0; //charge of the MIP
-    Bool_t kFound = kFALSE;
-    for(Int_t iClusN=0;iClusN<pRich->Clusters(iChamber)->GetEntries();iClusN++){//clusters loop for intersected chamber
-      AliRICHCluster *pClus=(AliRICHCluster*)pRich->Clusters(iChamber)->UncheckedAt(iClusN);//get pointer to current cluster
-      if(pClus->Q()<AliRICHParam::QthMIP()) continue;
-      Double_t distCurrent=pClus->DistTo(helix.PosPc());//distance between current cluster and helix intersection with PC
-      if(distCurrent<distMip){
-        kFound = kTRUE;
-        distMip=distCurrent;
-        iMipId=iClusN;
-        distX=pClus->DistX(helix.PosPc());
-        distY=pClus->DistY(helix.PosPc());
-        chargeMip=pClus->Q();
-      }//find cluster nearest to the track       
-      AliDebug(1,Form("Ploc (%f,%f,%f) dist= %f",helix.Ploc().Mag(),helix.Ploc().Theta()*TMath::RadToDeg(),
-                                       helix.Ploc().Phi()*TMath::RadToDeg(),pClus->DistTo(helix.PosPc())));
+// Interface callback methode invoked from AliReconstruction::WriteAlignmentData() to get position of MIP cluster in MARS associated to a current track.
+// MIP cluster is reffered by index which is stored in AliESDtrack  ???????
+// Arguments: idx- cluster index which is stored by RICH in AliESDtrack
+//            point- reference to the object where to store the point     
+//   Returns: status of operation  if FALSE then AliReconstruction::WriteAlignmentData() do not store this point to array of points for current track. 
+  if(idx<0) return kFALSE; //no MIP cluster assigned to this track in PropagateBack()
+  Int_t iCham=idx/1000000;
+  Int_t iClu=idx%1000000;
+  point.SetVolumeID(AliAlignObj::LayerToVolUID(AliAlignObj::kRICH,iCham-1));//layer and chamber number
+  AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH"));  
+  AliRICHCluster *pClu=(AliRICHCluster*)pRich->Clus(iCham)->UncheckedAt(iClu);//get pointer to cluster
+  TVector3 mars=AliRICHParam::Instance()->Lors2Mars(iCham,pClu->X(),pClu->Y());
+  point.SetXYZ(mars.X(),mars.Y(),mars.Z());
+  return kTRUE;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHTracker::LoadClusters(TTree *pCluTree)
+{
+// Interface callback methode invoked from AliReconstruction::RunTracking() to load RICH clusters for RICH
+// Arguments: pCluTree- pointer to clusters tree got by AliRICHLoader::LoadRecPoints("read") then AliRICHLoader::TreeR()
+//   Returns: error code (currently ignored in AliReconstruction::RunTraking())    
+  AliDebug(1,"Start.");  pCluTree->GetEntry(0);  AliDebug(1,"Stop."); return 0;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHTracker::PropagateBack(AliESD *pESD)
+{
+// Interface callback methode invoked by AliRecontruction::RunTracking() during tracking after TOF. It's done just once per event
+// Arguments: pESD - pointer to Event Summary Data class instance which contains a list of tracks
+//   Returns: error code, 0 if no errors   
+  Int_t iNtracks=pESD->GetNumberOfTracks();
+  AliDebug(1,Form("Start with %i tracks",iNtracks));
+  AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH"));  
+  AliRICHRecon recon;
+   
+  for(Int_t iTrk=0;iTrk<iNtracks;iTrk++){//ESD tracks loop
+    AliESDtrack *pTrack = pESD->GetTrack(iTrk);// get next reconstructed track    
+    AliRICHHelix helix(pTrack->X3(),pTrack->P3(),(Int_t)pTrack->GetSign(),GetBz()/10); //construct helix out of track running parameters  
+    helix.Print("Track");
+    Int_t iChamber=helix.RichIntersect(AliRICHParam::Instance());    
+    if(!iChamber) continue;                                         //no intersection with chambers, ignore this track go after the next one
+  
+    //find MIP cluster candidate (closest to track intersection point cluster with large enough QDC)
+    Double_t    dR=9999,   dX=9999,   dY=9999; //distance between track-PC intersection point and current cluster
+    Double_t dRmip=9999,dXmip=9999,dYmip=9999; //distance between track-PC intersection point and nearest cluster
+    Int_t   iMipId=-1;                         //index of this nearest cluster
+    for(Int_t iClu=0;iClu<pRich->Clus(iChamber)->GetEntries();iClu++){//clusters loop for intersected chamber
+      AliRICHCluster *pClu=(AliRICHCluster*)pRich->Clus(iChamber)->UncheckedAt(iClu);//get pointer to current cluster
+      if(pClu->Q()<AliRICHParam::QthMIP()) continue; //to low QDC, go after another one
+      pClu->DistXY(helix.PosPc(),dX,dY); dR=TMath::Sqrt(dX*dX+dY*dY); //get distance for current cluster
+      if(dR<dRmip){iMipId=iClu; dRmip=dR; dXmip=dX; dYmip=dY; }       //current cluster is closer, overwrite data for min cluster
     }//clusters loop for intersected chamber
 
-    if(!kFound) {
-      pTrack->SetRICHsignal(-999);
-      return;
-    }
-    AliDebug(1,Form("Min distance cluster: %i dist is %f",iMipId,distMip));
-    pTrack->SetRICHcluster(((Int_t)chargeMip)+1000000*iChamber);
-    pTrack->SetRICHdxdy(distX,distY);
-    pTrack->SetRICHthetaPhi(helix.Ploc().Theta(),helix.Ploc().Phi());
-//
-// HERE CUTS ON GOLD RINGS....
-//
-    if(distMip>AliRICHParam::DmatchMIP()) {
-      //track not accepted for pattern recognition
-      pTrack->SetRICHsignal(-990); //to be improved by flags...
-      return;
-    }
-//
-    AliRICHRecon recon(&helix,pRich->Clusters(iChamber),iMipId); //actual job is done there
-
-    Double_t thetaCerenkov=recon.ThetaCerenkov(); //search for mean Cerenkov angle for this track
+    pTrack->SetRICHthetaPhi(helix.Ploc().Theta(),helix.Ploc().Phi()); //store track impact angles with respect to RICH planes
+    pTrack->SetRICHdxdy(dXmip,dYmip);                                 //distance between track-PC intersection and closest cluster with Qdc>100
     
-    pTrack->SetRICHsignal(thetaCerenkov);
-    pTrack->SetRICHnclusters(recon.GetHoughPhotons());
+    if(iMipId==-1)                        {pTrack->SetRICHsignal(kMipQdcCut);  continue;} //no cluster with enough QDC found
+    if(dRmip>AliRICHParam::DmatchMIP())   {pTrack->SetRICHsignal(kMipDistCut); continue;} //closest cluster with enough carge is still too far 
+  
+    pTrack->SetRICHcluster(iMipId+1000000*iChamber);                                //set mip cluster index
+    pTrack->SetRICHsignal(recon.ThetaCerenkov(&helix,pRich->Clus(iChamber),iMipId));//search for mean Cerenkov angle for this track
+    pTrack->SetRICHnclusters(iMipId);                                               //on return iMipId is number of photon clusters accepted in reconstruction
 
-    fnPhotBKG = recon.GetPhotBKG();
-        
-    AliDebug(1,Form("FINAL Theta Cerenkov=%f",pTrack->GetRICHsignal()));
-//
+    AliDebug(1,Form("Ch=%i PC Intersection=(%5.2f,%5.2f) cm MIP cluster dist=(%5.2f,%5.2f)=%5.2f cm ThetaCkov=%f",
+                     iChamber,helix.PosPc().X(),helix.PosPc().Y(),            dXmip,dYmip,dRmip,     pTrack->GetRICHsignal()));
+    
+//here comes PID calculations    
     if(pTrack->GetRICHsignal()>0) {
       AliDebug(1,Form("Start to assign the probabilities"));
       Double_t sigmaPID[AliPID::kSPECIES];
@@ -108,33 +100,36 @@ void AliRICHTracker::RecWithESD(AliESD *pESD,AliRICH *pRich,Int_t iTrackN)
       for (Int_t iPart=0;iPart<AliPID::kSPECIES;iPart++) {
         sigmaPID[iPart] = 0;
         fErrPar[iPart] = 0;
-        for(Int_t iphot=0;iphot<pRich->Clusters(iChamber)->GetEntries();iphot++) {
+        for(Int_t iphot=0;iphot<pRich->Clus(iChamber)->GetEntries();iphot++) {
           recon.SetPhotonIndex(iphot);
           if(recon.GetPhotonFlag() == 2) {
             Double_t theta_g=recon.GetTrackTheta();
             Double_t phi_g=(recon.GetPhiPoint()-recon.GetTrackPhi());
-            Double_t sigma2 = AliRICHParam::SigmaSinglePhoton(iPart,pTrack->GetP(),theta_g,phi_g).Mag2(); 
+            Double_t sigma2 = AliRICHParam::Instance()->SigmaSinglePhoton(iPart,pTrack->GetP(),theta_g,phi_g).Mag2(); 
             if(sigma2>0) sigmaPID[iPart] += 1/sigma2;
           }
         }
-       if (sigmaPID[iPart]>0)
-          sigmaPID[iPart] *= (Double_t)(recon.GetHoughPhotons()-fnPhotBKG)/(Double_t)(recon.GetHoughPhotons()); // n total phots, m are background...the sigma are scaled..
-         if(sigmaPID[iPart]>0) sigmaPID[iPart] = 1/TMath::Sqrt(sigmaPID[iPart])*0.001; // sigma from parametrization are in mrad...
+        if (sigmaPID[iPart]>0)
+          sigmaPID[iPart] *= (Double_t)(iMipId-recon.GetPhotBKG())/(Double_t)(iMipId); // n total phots, m are background...the sigma are scaled..
+          if(sigmaPID[iPart]>0) sigmaPID[iPart] = 1/TMath::Sqrt(sigmaPID[iPart])*0.001; // sigma from parametrization are in mrad...
           else                  sigmaPID[iPart] = 0;
           fErrPar[iPart]=sigmaPID[iPart];
         AliDebug(1,Form("sigma for %s is %f rad",AliPID::ParticleName(iPart),sigmaPID[iPart]));
       }
-      CalcProb(thetaCerenkov,pTrack->GetP(),sigmaPID,richPID);
+      CalcProb(pTrack->GetRICHsignal(),pTrack->GetP(),sigmaPID,richPID);
       pTrack->SetRICHpid(richPID);         
       AliDebug(1,Form("PROBABILITIES ---> %f - %f - %f - %f - %f",richPID[0],richPID[1],richPID[2],richPID[3],richPID[4]));
     }    
-  AliDebug(1,"Stop.");  
-} //RecWithESD
-//__________________________________________________________________________________________________
+  }//ESD tracks loop
+  AliDebug(1,"Stop pattern recognition");
+  return 0; // error code: 0=no error;
+}//PropagateBack()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHTracker::RecWithStack(TNtupleD *hn)
 {
-//Reconstruction for particles from STACK. This methode is to be used for RICH standalone when no other detectors are switched on,
-//so normal tracking is not available   
+// Reconstruction for particles from STACK. This methode is to be used for RICH standalone when no other detectors are switched on, so normal tracking is not available.
+// Arguments: hn- output ntuple where to store all variables
+//   Returns: none       
   AliDebug(1,"Start.");  
   AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH"));
   
@@ -155,6 +150,7 @@ void AliRICHTracker::RecWithStack(TNtupleD *hn)
   if(pRich->GetLoader()->LoadRecPoints()) {AliDebug(1,Form("No clusters found in RICH"));return;}
   pRich->GetLoader()->TreeR()->GetEntry(0);
 
+  AliRICHRecon recon;
   for(Int_t iTrackN=0;iTrackN<iNtracks;iTrackN++){//stack particles loop
     TParticle *pParticle = pStack->Particle(iTrackN);
     if(!pParticle) {AliDebug(1,Form("Not a valid TParticle pointer. Track skipped"));continue;}
@@ -181,56 +177,41 @@ void AliRICHTracker::RecWithStack(TNtupleD *hn)
     if(pParticle->GetPDG()->Charge()==0||TMath::Abs(Int_t(pParticle->GetPDG()->Charge()))!=3) continue; //to avoid photons from stack...
     hnvec[0]=pParticle->P();
     hnvec[1]=pParticle->GetPDG()->Charge();
-    p0.SetMagThetaPhi(pParticle->P(),pParticle->Theta(),pParticle->Phi());
-    x0.SetXYZ(pParticle->Vx(),pParticle->Vy(),pParticle->Vz());
+    
+    p0.SetMagThetaPhi(pParticle->P(),pParticle->Theta(),pParticle->Phi());   x0.SetXYZ(pParticle->Vx(),pParticle->Vy(),pParticle->Vz());
     AliRICHHelix helix(x0,p0,TMath::Sign(1,(Int_t)pParticle->GetPDG()->Charge()),b);   
-    Int_t iChamber=helix.RichIntersect(pRich->P());        
+    Int_t iChamber=helix.RichIntersect(AliRICHParam::Instance());        
+    if(!iChamber) continue;// no intersection with RICH found
+    
     hnvec[2]=helix.Ploc().Theta();
     hnvec[3]=helix.Ploc().Phi();
-    AliDebug(1,Form("intersection with %i chamber found",iChamber));
-    if(!iChamber) continue;// no intersection with RICH found
     hnvec[4]=helix.PosPc().X();
     hnvec[5]=helix.PosPc().Y();
-    Double_t distMip=9999;   //min distance between clusters and track position on PC 
-    Double_t mipX=-1;      //min distance between clusters and track position on PC 
-    Double_t mipY=-1;      //min distance between clusters and track position on PC 
-    Double_t chargeMip=-1; // charge MIP to find
+    
+    Double_t dX,dY,dR,dRmip=9999;      //min distance between clusters and track position on PC 
     Int_t iMipId=-1;       //index of that min distance cluster 
-    for(Int_t iClusN=0;iClusN<pRich->Clusters(iChamber)->GetEntries();iClusN++){//clusters loop for intersected chamber
-      AliRICHCluster *pClus=(AliRICHCluster*)pRich->Clusters(iChamber)->UncheckedAt(iClusN);//get pointer to current cluster
-      Double_t distCurrent=pClus->DistTo(helix.PosPc());//ditance between current cluster and helix intersection with PC
-      if(distCurrent<distMip){distMip=distCurrent;mipX=pClus->X();
-                                                  mipY=pClus->Y();
-                                                  chargeMip=pClus->Q();iMipId=1000000*iChamber+iClusN;}//find cluster nearest to the track 
+    for(Int_t iClu=0;iClu<pRich->Clus(iChamber)->GetEntries();iClu++){//clusters loop for intersected chamber
+      AliRICHCluster *pClu=(AliRICHCluster*)pRich->Clus(iChamber)->UncheckedAt(iClu);//get pointer to current cluster
+      pClu->DistXY(helix.PosPc(),dX,dY); dR=TMath::Sqrt(dX*dX+dY*dY);//ditance between current cluster and helix intersection with PC
+      if(dR<dRmip){dRmip=dR; hnvec[6]=pClu->X();hnvec[7]=pClu->Y();hnvec[8]=pClu->Q();
+                                                  iMipId=1000000*iChamber+iClu;}//find cluster nearest to the track 
       
-      AliDebug(1,Form("Ploc (%f,%f,%f) dist= %f",helix.Ploc().Mag(),helix.Ploc().Theta()*TMath::RadToDeg(),
-                                                                    helix.Ploc().Phi()*TMath::RadToDeg(),pClus->DistTo(helix.PosPc())));
     }//clusters loop for intersected chamber
     
-    AliDebug(1,Form("Min distance cluster: %i dist is %f",iMipId,distMip));
-    hnvec[6]=mipX;hnvec[7]=mipY;
-    hnvec[8]=chargeMip;
-    AliRICHRecon recon(&helix,pRich->Clusters(iChamber),iMipId);
-    Double_t thetaCerenkov=recon.ThetaCerenkov(); //search for mean Cerenkov angle for this track
-    hnvec[9]=thetaCerenkov;
-    hnvec[10]=recon.GetHoughPhotons();
+    
+    hnvec[9]=recon.ThetaCerenkov(&helix,pRich->Clus(iChamber),iMipId); //search for mean Cerenkov angle for this track
+    hnvec[10]=iMipId;//on return from ThetaCerenkov() contains number of photon candidates accepted
     hnvec[11]=(Double_t)iMipId;
     hnvec[12]=(Double_t)iChamber;
     hnvec[13]=(Double_t)pParticle->GetPdgCode();
     if(hn) hn->Fill(hnvec);
-    AliDebug(1,Form("FINAL Theta Cerenkov=%f",thetaCerenkov));
+    AliDebug(1,Form("FINAL Theta Cerenkov=%f",hnvec[9]));
   }//stack particles loop
   
   pRich->GetLoader()->UnloadRecPoints();
   AliDebug(1,"Stop.");  
 }//RecWithStack
-//__________________________________________________________________________________________________
-Int_t AliRICHTracker::LoadClusters(TTree *pTree)
-{
-// Load clusters for RICH
-  AliDebug(1,"Start.");  pTree->GetEntry(0);  AliDebug(1,"Stop."); return 0;
-}
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHTracker::CalcProb(Double_t thetaCer,Double_t pmod, Double_t *sigmaPID, Double_t *richPID)
 {
 // Calculates probability to be a electron-muon-pion-kaon-proton
@@ -241,7 +222,7 @@ void AliRICHTracker::CalcProb(Double_t thetaCer,Double_t pmod, Double_t *sigmaPI
   for(Int_t iPart=0;iPart<AliPID::kSPECIES;iPart++){
     height[iPart]=0;
     Double_t mass = AliRICHParam::fgMass[iPart];
-    Double_t refIndex=AliRICHParam::RefIdxC6F14(AliRICHParam::MeanCkovEnergy());
+    Double_t refIndex=AliRICHParam::Instance()->IdxC6F14(AliRICHParam::EckovMean());
     Double_t cosThetaTh = TMath::Sqrt(mass*mass+pmod*pmod)/(refIndex*pmod);
     thetaTh[iPart]=0;
     if(cosThetaTh>=1) continue;
@@ -252,8 +233,8 @@ void AliRICHTracker::CalcProb(Double_t thetaCer,Double_t pmod, Double_t *sigmaPI
     if(sigmaPID[iPart]>0) height[iPart] = TMath::Gaus(thetaCer,thetaTh[iPart],sigmaPID[iPart],kTRUE);
     else                  height[iPart] = 0;
     totalHeight +=height[iPart];
-    AliDebug(1,Form(" Particle %s with mass %f with height %f and thetaTH %f",AliPID::ParticleName(iPart),mass,height[iPart],thetaTh[iPart]));
-    AliDebug(1,Form(" partial height %15.14f total height %15.14f",height[iPart],totalHeight));
+    AliDebugClass(1,Form(" Particle %s with mass %f with height %f and thetaTH %f",AliPID::ParticleName(iPart),mass,height[iPart],thetaTh[iPart]));
+    AliDebugClass(1,Form(" partial height %15.14f total height %15.14f",height[iPart],totalHeight));
   }
   if(totalHeight<1e-5) {for(Int_t iPart=0;iPart<AliPID::kSPECIES;iPart++)richPID[iPart]=1.0/AliPID::kSPECIES;return;}
   for(Int_t iPart=0;iPart<AliPID::kSPECIES;iPart++) richPID[iPart] = height[iPart]/totalHeight;
@@ -262,4 +243,25 @@ void AliRICHTracker::CalcProb(Double_t thetaCer,Double_t pmod, Double_t *sigmaPI
   //last line is to check if the nearest thetacerenkov to the teorethical one is within 5 sigma, otherwise no response (equal prob to every particle
 
 }//CalcProb
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHTracker::EsdPrint()
+{
+  TFile *pFile=TFile::Open("AliESDs.root","read"); if(!pFile) {Printf("ERROR: No AliESDs.root in current directory!");return;}
+  TTree *pEsdTr = (TTree*)pFile->Get("esdTree");   if(!pEsdTr){Printf("ERROR: Bad AliESDs.root, no ESD tree inside!");return;} 
+  AliESD *pESD=new AliESD;  pEsdTr->SetBranchAddress("ESD", &pESD);
+  
+  Int_t iNevt=pEsdTr->GetEntries();  Printf("This ESD contains %i events",iNevt);
+  for(Int_t iEvt=0;iEvt<iNevt;iEvt++){//ESD events loop
+    pEsdTr->GetEvent(iEvt);
+    Int_t iNtracks=pESD->GetNumberOfTracks(); Printf("ESD contains %i tracks created in Bz=%.2f Tesla",iNtracks,pESD->GetMagneticField()/10.);
+    for(Int_t iTrk=0;iTrk<iNtracks;iTrk++){//ESD tracks loop
+      AliESDtrack *pTrack = pESD->GetTrack(iTrk);// get next reconstructed track
+      Double_t dx,dy;         pTrack->GetRICHdxdy(dx,dy);
+      Double_t theta,phi;     pTrack->GetRICHthetaPhi(theta,phi);
+      Printf("Track %2i Q=%4.1f P=%.3f GeV RICH: ChamberCluster %7i Track-Mip=(%7.2f,%7.2f)=%5.2f cm ThetaCer %7.1f rad",iTrk,pTrack->GetSign(),pTrack->GetP(),
+                   pTrack->GetRICHcluster(),dx,dy,TMath::Sqrt(dx*dx+dy*dy),pTrack->GetRICHsignal());
+    }//ESD tracks loop
+  }//ESD events loop
+  delete pESD;  pFile->Close();//close AliESDs.root
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index 9a6d159..a8df01a 100644 (file)
@@ -1,35 +1,31 @@
 #ifndef AliRICHTracker_h
 #define AliRICHTracker_h
 
-#include <AliTracker.h>
-#include <AliLog.h>
-#include "TNtupleD.h"
+#include <AliTracker.h> //base class
 
-class AliCluster;
-class AliESD;
-class AliRICH;
-class TTree;
+class TNtupleD;         //RecWithStack()   
+class AliESD;           //Clusters2Tracks(), RefitInward(), PropagateBack(), RecWithESD()
 
 class AliRICHTracker : public AliTracker
 {
 public:
-           AliRICHTracker() :AliTracker()      {for(Int_t i=0;i<5;i++)fErrPar[i]=0;AliDebug(1,"Start.");}
-  virtual ~AliRICHTracker()                    {AliDebug(1,"Stop.");}
-  Int_t Clusters2Tracks(AliESD *)              {AliDebug(1,"Start.");return 0;} //pure virtual from AliTracker 
-  Int_t RefitInward(AliESD *)                  {AliDebug(1,"Start.");return 0;} //pure virtual from AliTracker 
-  void UnloadClusters()                        {AliDebug(1,"Start.");}          //pure virtual from AliTracker 
-  AliCluster *GetCluster(Int_t )const          {AliDebug(1,"Start.");return 0;} //pure virtual from AliTracker 
-  Int_t PropagateBack(AliESD *);                                                //pure virtual from AliTracker 
-  void RecWithESD(AliESD *,AliRICH *,Int_t iTrackN);                            //recon with ESD
-  void RecWithStack(TNtupleD *hn);                                              //recon from Stack in case ESD empty
-  void CalcProb(Double_t thetaCer,Double_t pmod,Double_t *sigmaPID, Double_t *richPID);             // calculate pid for RICH
-  Int_t LoadClusters(TTree *);                                                  //pure virtual from AliTracker 
-  Double_t fnPhotBKG;                                                           //Temporary stored for debug purpose
-  Double_t fErrPar[5];                                                          //Temporary stored for debug purpose
+           AliRICHTracker(); 
+  virtual ~AliRICHTracker()                    {}
+//framework part  
+  AliCluster *GetCluster     (Int_t                      )const  {return 0;} //pure virtual from AliTracker 
+  Bool_t      GetTrackPoint  (Int_t idx,AliTrackPoint &pt)const;             //             from AliTracker  
+  Int_t       Clusters2Tracks(AliESD *                   )       {return 0;} //pure virtual from AliTracker 
+  Int_t       LoadClusters   (TTree *pCluTr              );                  //pure virtual from AliTracker   
+  Int_t       PropagateBack  (AliESD *                   );                  //pure virtual from AliTracker invoked from AliReconstruction::RunTracking()
+  Int_t       RefitInward    (AliESD *                   )       {return 0;} //pure virtual from AliTracker 
+  void        UnloadClusters (                           )       {         } //pure virtual from AliTracker 
+//private part  
+         void RecWithStack(TNtupleD *hn                                                     );   //recon from Stack in case ESD empty
+  static void CalcProb    (Double_t thetaCer,Double_t pmod,Double_t *pidsigma, Double_t *pid);   //calculate pid for RICH
+  static void EsdPrint    (                                                                 );   //print ESD status    
+  Double_t fErrPar[5];                                                                       //Temporary stored for debug purpose
+  enum ETrackingFlags {kMipDistCut=-990,kMipQdcCut=-999};
 protected:
-
-  Double_t fField; // magnetic field stored
-
   ClassDef(AliRICHTracker,0)
 };//class AliRICHTracker
 
index e5a57c6..50268c6 100644 (file)
 //**************************************************************************
 
 #include "AliRICHv0.h"
-#include "AliRICHChamber.h" 
-#include <AliRun.h>
-#include <AliMC.h>
-#include <TVirtualMC.h>
-#include <TPDGCode.h>
-#include <TLorentzVector.h>
-#include <TMath.h>
 
 #include <TGeoManager.h>
 
@@ -29,92 +22,5 @@ ClassImp(AliRICHv0)
 void AliRICHv0::StepManager()
 {
 //This StepManager is a provision for different test-learn activities on the current MC layer  
-  static Int_t iStepN;
-  const char *sParticle;
-  switch(gMC->TrackPid()){
-    case kProton:      sParticle="proton"    ;break;
-    case kNeutron:     sParticle="neutron"   ;break;
-    case kGamma:       sParticle="gamma"     ;break;
-    case kCerenkov:    sParticle="photon"    ;break;
-    case kPi0:         sParticle="Pi0"       ;break;  
-    case kPiPlus:      sParticle="Pi+"       ;break;  
-    case kPiMinus:     sParticle="Pi-"       ;break;  
-    case kElectron:    sParticle="electron"  ;break;  
-    default:           sParticle="not known" ;break;
-  }
-
-  Info(Form("Step %i",iStepN),"event=%i hunt=%i tid=%i pid=%i(%s) m=%f q=%3.1f dEdX=%9.3f",
-                            gMC->CurrentEvent(),
-                            fIshunt,
-                            gAlice->GetMCApp()->GetCurrentTrackNumber(),
-                            gMC->TrackPid(),
-                            sParticle,
-                            gMC->TrackMass(),
-                            gMC->TrackCharge(),
-                            gMC->Edep()*1e9);
-  Info("Flags","alive(%i) disap(%i) enter(%i) exit(%i) inside(%i) out(%i) stop(%i) new(%i)",
-                            gMC->IsTrackAlive(),
-                            gMC->IsTrackDisappeared(),
-                            gMC->IsTrackEntering(),
-                            gMC->IsTrackExiting(),
-                            gMC->IsTrackInside(),
-                            gMC->IsTrackOut(),
-                            gMC->IsTrackStop(),
-                            gMC->IsNewTrack());
-  Int_t copy0=0,copy1=0,copy2=0,copy3=0;
-  Int_t vid0=gMC->CurrentVolID(copy0);
-  Int_t vid1=gMC->CurrentVolOffID(1,copy1);
-  Int_t vid2=gMC->CurrentVolOffID(2,copy2);
-  Int_t vid3=gMC->CurrentVolOffID(3,copy3);
-  Info("Volumes","vid0=%i(%s)c%i vid1=%i(%s)c%i vid2=%i(%s)c%i vid3=%i(%s)c%i   %s-%s-%s-%s",
-                      vid0,gMC->VolName(vid0),copy0, 
-                      vid1,gMC->VolName(vid1),copy1, 
-                      vid2,gMC->VolName(vid2),copy2, 
-                      vid3,gMC->VolName(vid3),copy3, 
-                      gMC->CurrentVolName(),
-                      gMC->CurrentVolOffName(1),
-                      gMC->CurrentVolOffName(2),
-                      gMC->CurrentVolOffName(3));
-  
-  Float_t a,z,den,rad,abs; a=z=den=rad=abs=-1;
-  Int_t mid=gMC->CurrentMaterial(a,z,den,rad,abs);
-  Info("Material","id=%i a=%7.2f z=%7.2f den=%9.4f rad=%9.2f abs=%9.2f",mid,a,z,den,rad,abs);
-  
-  Int_t iTmedId=gMC->CurrentMedium();
-  const char *sTmed;
-  switch(iTmedId){
-    case kAir:        sTmed="Air"      ;break;
-    case kRoha:       sTmed="Rohacell" ;break;
-    case kSiO2:       sTmed="SiO2"     ;break;
-    case kC6F14:      sTmed="C6F14"    ;break;
-    case kGridCu:     sTmed="GridCu"   ;break;
-    case kOpSiO2:     sTmed="OpSiO2"   ;break;
-    case kGap:        sTmed="Gap"      ;break;
-    case kGlass:      sTmed="Glass"    ;break;
-    case kCu:         sTmed="Cu"       ;break;
-    case kSteel:      sTmed="Steel"    ;break;
-    case kPerpex:     sTmed="Perpex"   ;break;
-    case kCH4:        sTmed="CH4"      ;break;
-    case kCsI:        sTmed="CsI"      ;break;
-    case kAl:         sTmed="Al"       ;break;
-    case kW:          sTmed="W"        ;break;
-    default:          sTmed="not known";break;
-  }
-  Info("Medium","id=%i (%s)",iTmedId,sTmed);
   
-  TLorentzVector x4; gMC->TrackPosition(x4);
-  Float_t glo[3],loc[3];
-  glo[0]=x4.X();glo[1]=x4.Y();glo[2]=x4.Z();  
-  gMC->Gmtod(glo,loc,1);
-  Info("X4 glo","(x,y,z)=(%+8.3f,%+8.3f,%+8.3f) (r,theta,phi)=(%8.3f,%8.3f,%8.3f)",
-                      glo[0],glo[1],glo[2],x4.Rho(),x4.Theta()*TMath::RadToDeg(),x4.Phi()*TMath::RadToDeg());  
-  Info("X4 loc","(x,y,z)=(%+8.3f,%+8.3f,%8.3f) by gMC->Gmtod()",loc[0],loc[1],loc[2]);  
-  static Int_t idGAP = gMC->VolId("GAP ");
-  if(idGAP==gMC->CurrentVolID(copy0)){
-    Int_t iChamber;
-    gMC->CurrentVolOffID(2,iChamber);
-    TVector2 x2=C(iChamber)->Mrs2Pc(x4);
-    Info("X4 loc","(%+8.3f,%+8.3f) by Mrs2Pc",      x2.X(),x2.Y());  
-  }
-  Info(Form("Step %i",iStepN++),"end of current step\n");
 }//StepManager()
index cfe2ed6..d680bea 100644 (file)
 
 #include "AliRICHv1.h"     //class header
 #include "AliRICHParam.h"
-#include "AliRICHChamber.h"
-#include <TParticle.h> 
+#include <TParticle.h>     //Hits2SDigits()
 #include <TRandom.h> 
-#include <TVirtualMC.h>
-#include <TPDGCode.h>
-#include <AliStack.h>      //Hits2SDigits()
+#include <TVirtualMC.h>    //StepManager() for gMC
+#include <TPDGCode.h>      //StepHistory() 
+#include <AliStack.h>      //StepManager(),Hits2SDigits()
+#include <AliLoader.h>        //Hits2SDigits()
+#include <AliRunLoader.h>     //Hits2SDigits()
 #include <AliConst.h>
 #include <AliPDG.h>
-#include <AliRun.h>
-#include <AliMC.h>
+#include <AliMC.h>            //StepManager()      
 #include <AliRawDataHeader.h> //Digits2Raw()
-
+#include <AliRun.h>           //CreateMaterials()    
+#include <AliMagF.h>          //CreateMaterials()
+#include <TGeoManager.h>      //CreateGeometry()
+#include <TMultiGraph.h>      //Optics() 
+#include <TGraph.h>           //Optics() 
+#include <TLegend.h>          //Optics() 
+#include <TCanvas.h>          //Optics() 
+#include <TF2.h>              //CreateMaterials()
+#include <AliCDBManager.h>    //CreateMaterials()
+#include <AliCDBEntry.h>      //CreateMaterials()