MAJOR UPGRADE: 1. all objects are counted from 0 2. new AliRICHRecon 3. calib off...
authorkir <kir@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 27 Oct 2006 14:02:41 +0000 (14:02 +0000)
committerkir <kir@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 27 Oct 2006 14:02:41 +0000 (14:02 +0000)
30 files changed:
RICH/AliRICH.cxx
RICH/AliRICH.h
RICH/AliRICHCluster.cxx
RICH/AliRICHCluster.h
RICH/AliRICHDigit.cxx
RICH/AliRICHDigit.h
RICH/AliRICHDigitizer.cxx
RICH/AliRICHDigitizer.h
RICH/AliRICHHelix.cxx
RICH/AliRICHHelix.h
RICH/AliRICHHit.cxx
RICH/AliRICHHit.h
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/AliRICHv1.cxx
RICH/AliRICHv1.h
RICH/RICHbaseLinkDef.h
RICH/RICHrecLinkDef.h
RICH/RichConfig.C
RICH/RichMake
RICH/RichMenu.C
RICH/api.txt
RICH/libRICHbase.pkg
RICH/libRICHrec.pkg

index bc594e8..054d130 100644 (file)
 //  **************************************************************************
 
 #include "AliRICH.h"
-#include "AliRICHParam.h"
-#include "AliRICHHelix.h" //ReadESD
-#include <TFile.h>
-#include <TObjArray.h>
-#include <TParticle.h>
-#include <AliStack.h>
-#include <AliRun.h>
+#include "AliRICHHit.h"   //OccupancyPrint(), HitQa()
+#include "AliRICHDigit.h" //OccupancyPrint()
+#include <TParticle.h>  //SummaryOfEvent(), HitQa()
+#include <TBenchmark.h>  //HitQA()
+#include <TPDGCode.h>    //HitQA()
+#include <AliStack.h>   //OccupancyPrint(), SummaryOfEvent(), HitQa()
+#include <AliRun.h>     //HitQa() 
 #include <AliMC.h>       //ctor
 #include <AliHeader.h>
 #include <AliGenEventHeader.h>
 #include <AliGenHijingEventHeader.h>
-#include <AliESD.h>
 #include <TH1F.h>        //HitQA()
-#include <TH2F.h>        //Display() 
-#include <TBenchmark.h>
-#include <AliLog.h>
-#include <TLatex.h>      //Display()
-#include <TCanvas.h>     //Display()
-#include <TGraph.h>      //Display()
-#include <TStyle.h>      //Display()
-#include <TMarker.h>     //Display()
+#include <AliLog.h>      //in many methods to print AliInfo 
 ClassImp(AliRICH)    
-//__________________________________________________________________________________________________
-// RICH manager class   
-//BEGIN_HTML
-/*
-  <img src="gif/alirich.gif">
-*/
-//END_HTML
-//__________________________________________________________________________________________________
-AliRICH::AliRICH():AliDetector(),fSdig(0),fSdigCnt(0),fDig(0),fClu(0),fCounters(0),fNcham(0) 
-{
-//Default ctor should not contain any new operators
-//AliDetector ctor deals with Hits and Digits  
-}//AliRICH::AliRICH()
-//__________________________________________________________________________________________________
-AliRICH::AliRICH(const char *name, const char *title):AliDetector(name,title),fSdig(0),fSdigCnt(0),fDig(0),fClu(0),fCounters(0),fNcham(0)
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+AliRICH::AliRICH(const char *name, const char *title):AliDetector(name,title),fSdi(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)
   HitCreate();          gAlice->GetMCApp()->AddHitList(fHits);
-  fNcham=7;
-  fCounters.ResizeTo(40); fCounters.Zero();
   AliDebug(1,"Stop.");
 }//AliRICH::AliRICH(const char *name, const char *title)
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 AliRICH::~AliRICH()
 {
 //dtor
@@ -68,84 +45,41 @@ AliRICH::~AliRICH()
 
   
   if(fHits)      delete fHits;
-  if(fSdig)      delete fSdig;
   if(fDigits)    delete fDigits;
+  if(fSdi)       delete fSdi;
   if(fDig)      {fDig->Delete();   delete fDig;}
   if(fClu)      {fClu->Delete();   delete fClu;}
   AliDebug(1,"Stop.");    
 }//AliRICH::~AliRICH()
-//__________________________________________________________________________________________________
-void AliRICH::BuildGeometry() 
-{
-//Builds a TNode geometry for event display
-  AliDebug(1,"Start.");
-  
-  AliDebug(1,"Stop.");    
-}//void AliRICH::BuildGeometry()
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICH::MakeBranch(Option_t* option)
 {
 //Create Tree branches for the RICH.
   AliDebug(1,Form("Start with option= %s.",option));
     
-  const Int_t kBufferSize = 4000;
+  const Int_t kBufSize = 4000;
       
   const char *cH = strstr(option,"H");
   const char *cD = strstr(option,"D");
   const char *cR = strstr(option,"R");
   const char *cS = strstr(option,"S");
 
-  if(cH&&TreeH()){//H
-    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  
-    SDigCreate();   MakeBranchInTree(fLoader->TreeS(),"RICH",&fSdig,kBufferSize,0) ;
-  }//S
-   
-  if(cD&&fLoader->TreeD()){//D
-    DigCreate();
-    for(Int_t i=0;i<fNcham;i++){ 
-      MakeBranchInTree(fLoader->TreeD(),Form("%s%d",GetName(),i+1),&((*fDig)[i]),kBufferSize,0);
-    }
-  }//D
+  if(cH&&         TreeH()){HitCreate();                       MakeBranchInTree(         TreeH(),     "RICH"     ,&fHits       ,kBufSize,0);}
+  if(cS&&fLoader->TreeS()){SdiCreate();                       MakeBranchInTree(fLoader->TreeS(),     "RICH"     ,&fSdi        ,kBufSize,0);}
+  if(cD&&fLoader->TreeD()){DigCreate();for(Int_t i=0;i<7;i++) MakeBranchInTree(fLoader->TreeD(),Form("RICH%d",i),&((*fDig)[i]),kBufSize,0);}
+  if(cR&&fLoader->TreeR()){CluCreate();for(Int_t i=0;i<7;i++) MakeBranchInTree(fLoader->TreeR(),Form("RICH%d",i),&((*fClu)[i]),kBufSize,0);}   
   
-  if(cR&&fLoader->TreeR()){//R
-    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)
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICH::SetTreeAddress()
 {
 //Set branch address for the Hits and Digits Tree.
   AliDebug(1,"Start.");
-      
-  TBranch *branch;
-    
-  if(fLoader->TreeH()){//H
-    AliDebug(1,"tree H is requested.");
-    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){SDigCreate();   branch->SetAddress(&fSdig);}
-  }//S
-    
-  if(fLoader->TreeD()){//D    
-    AliDebug(1,"tree D is requested.");
-    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<fNcham;i++){   branch=fLoader->TreeR()->GetBranch(Form("%sClusters%d" ,GetName(),i+1));  if(branch){CluCreate(); branch->SetAddress(&((*fClu)[i]));}}
-  }//R
+  if(fLoader->TreeH() && fLoader->TreeH()->GetBranch("RICH" )){HitCreate();                      fLoader->TreeH()->SetBranchAddress(     "RICH"     ,&fHits       );}
+  if(fLoader->TreeS() && fLoader->TreeS()->GetBranch("RICH" )){SdiCreate();                      fLoader->TreeS()->SetBranchAddress(     "RICH"     ,&fSdi        );}
+  if(fLoader->TreeD() && fLoader->TreeD()->GetBranch("RICH0")){DigCreate(); for(int i=0;i<7;i++) fLoader->TreeD()->SetBranchAddress(Form("RICH%d",i),&((*fDig)[i]));}
+  if(fLoader->TreeR() && fLoader->TreeR()->GetBranch("RICH0")){CluCreate(); for(int i=0;i<7;i++) fLoader->TreeR()->SetBranchAddress(Form("RICH%d",i),&((*fClu)[i]));}
   AliDebug(1,"Stop.");
 }//void AliRICH::SetTreeAddress()
 //__________________________________________________________________________________________________
@@ -180,38 +114,34 @@ void AliRICH::HitPrint(Int_t iEvtN)const
   GetLoader()->UnloadHits();
   AliInfo(Form("totally %i hits",iTotalHits));
 }
-//__________________________________________________________________________________________________
-void AliRICH::SDigPrint(Int_t iEvtN)const
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICH::SdiPrint(Int_t iEvt)const
 {
 //prints a list of RICH sdigits  for a given event
-  if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return;    
-  Info("PrintSDigits","List of RICH sdigits for event %i",iEvtN);
+  if(GetLoader()->GetRunLoader()->GetEvent(iEvt)) return;    
+  Info("PrintSDigits","List of RICH sdigits for event %i",iEvt);
   if(GetLoader()->LoadSDigits()) return;
   
   GetLoader()->TreeS()->GetEntry(0);
-  fSdig->Print();
+  SdiLst()->Print();
   GetLoader()->UnloadSDigits();
-  Printf("totally %i sdigits",fSdig->GetEntries());
+  Printf("totally %i sdigits",SdiLst()->GetEntries());
 }
-//__________________________________________________________________________________________________
-void AliRICH::DigPrint(Int_t iEvtN)const
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICH::DigPrint(Int_t iEvt)const
 {
 //prints a list of RICH digits  for a given event
-  if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return;    
-  Printf("List of RICH digits for event %i",iEvtN);
+  if(GetLoader()->GetRunLoader()->GetEvent(iEvt)) return;    
+  Printf("List of RICH digits for event %i",iEvt);
   if(GetLoader()->LoadDigits()) return;
   
-  Int_t iTotalDigits=0;
   GetLoader()->TreeD()->GetEntry(0);
-  if(!fDig) return;
-  for(Int_t iCham=0;iCham<fNcham;iCham++){
-    TClonesArray *pDigs=(TClonesArray*)fDig->At(iCham);    iTotalDigits+=pDigs->GetEntries();    pDigs->Print();
-  }
+  DigLst()->Print();
   GetLoader()->UnloadDigits();
-  Printf("totally %i Digits",iTotalDigits);
+  Printf("totally %i Digits",DigLst()->GetEntries());
 }
-//__________________________________________________________________________________________________
-void AliRICH::OccupancyPrint(Int_t iEvtNreq)const
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICH::OccupancyPrint(Int_t iEvtNreq)
 {
 //prints occupancy for each chamber in a given event
   Int_t iEvtNmin,iEvtNmax;
@@ -229,41 +159,44 @@ void AliRICH::OccupancyPrint(Int_t iEvtNreq)const
   if(GetLoader()->LoadHits()) return;
   if(GetLoader()->LoadDigits()) return;
 
-  Int_t totPadsPerChamber = AliRICHParam::NpadsX()*AliRICHParam::NpadsY();  
-
   
   for(Int_t iEvtN=iEvtNmin;iEvtN<iEvtNmax;iEvtN++){    
-    Int_t nDigCh[kNchambers]={0,0,0,0,0,0,0};  
-    Int_t iChHits[kNchambers]={0,0,0,0,0,0,0};
-    Int_t nPrim[kNchambers]={0,0,0,0,0,0,0};
-    Int_t nSec[kNchambers]={0,0,0,0,0,0,0};
+    Int_t nDigCh[7]={0,0,0,0,0,0,0};  
+    Int_t iChHits[7]={0,0,0,0,0,0,0};
+    Int_t nPrim[7]={0,0,0,0,0,0,0};
+    Int_t nSec[7]={0,0,0,0,0,0,0};
     AliInfo(Form("events processed %i",iEvtN));
     if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return;    
     AliStack *pStack = GetLoader()->GetRunLoader()->Stack();
     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(pHit->Eloss()>0){
-          iChHits[pHit->C()-1]++;
-          if(pStack->Particle(pHit->GetTrack())->Rho()<0.01) nPrim[pHit->C()-1]++;else nSec[pHit->C()-1]++;
+        AliRICHHit *pHit = (AliRICHHit*)Hits()->At(iHitN);
+        if(pHit->E()>0){
+          iChHits[pHit->Ch()]++;
+          if(pStack->Particle(pHit->GetTrack())->Rho()<0.01) nPrim[pHit->Ch()]++;else nSec[pHit->Ch()]++;
         }
       }
     }
+    
     GetLoader()->TreeD()->GetEntry(0);
-    for(Int_t iCh=0;iCh<fNcham;iCh++) {
-      nDigCh[iCh]= ((TClonesArray*)fDig->At(iCh))->GetEntries();
-      Double_t occupancy = (Double_t)nDigCh[iCh]/(Double_t)totPadsPerChamber;
-      Info("Occupancy","for chamber %i = %4.2f %% and charged prim tracks %i and sec. tracks %i with total %i",
-        iCh+1,occupancy*100.,nPrim[iCh],nSec[iCh],iChHits[iCh]);
-    }
-  }
+    for(Int_t iCh=0;iCh<7;iCh++){
+      for(Int_t iDig=0;iDig<DigLst(iCh)->GetEntries();iDig++){
+        AliRICHDigit *pDig=(AliRICHDigit*)DigLst(iCh)->At(iDig);
+        nDigCh[pDig->Ch()]++;
+      }
+      Printf("Occupancy for chamber %i = %4.2f %% and charged prim tracks %i and sec. tracks %i with total %i",
+        iCh,Float_t(nDigCh[iCh])*100/AliRICHDigit::kPadAll,nPrim[iCh],nSec[iCh],iChHits[iCh]);
+    }      
+    
+    
+  }//events loop
   GetLoader()->UnloadHits();
   GetLoader()->UnloadDigits();
   GetLoader()->GetRunLoader()->UnloadHeader();    
   GetLoader()->GetRunLoader()->UnloadKinematics();    
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICH::CluPrint(Int_t iEvtN)const
 {
 //prints a list of RICH clusters  for a given event
@@ -273,210 +206,13 @@ void AliRICH::CluPrint(Int_t iEvtN)const
   
   Int_t iCluCnt=0;
   GetLoader()->TreeR()->GetEntry(0);
-  for(Int_t iCham=0;iCham<fNcham;iCham++){
-    TClonesArray *pClus=(TClonesArray*)fClu->At(iCham);    iCluCnt+=pClus->GetEntries();    pClus->Print();
+  for(Int_t iCh=0;iCh<7;iCh++){
+    TClonesArray *pCluLst=(TClonesArray*)fClu->At(iCh);    iCluCnt+=pCluLst->GetEntries();    pCluLst->Print();
   }
   GetLoader()->UnloadRecPoints();
   Printf("totally %i clusters for event %i",iCluCnt,iEvtN);
 }
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICH::DisplayEvent(Int_t iEvtNmin,Int_t iEvtNmax)const
-{
-// Display digits, reconstructed tracks intersections and RICH rings if available 
-  TH2F *pH2[8];
-
-  GetLoader()->LoadDigits();
-  
-  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 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;
-
-  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(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());
-        pH2[pDig->C()]->Fill(x2.X(),x2.Y(),pDig->Qdc());
-      }//digits loop
-      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
-    pC->Update();
-    pC->Modified();
-
-    if(iEvt<iEvtNmax) {gPad->WaitPrimitive();pC->Clear();}
-  }//events loop
-}//ShowEvent()
-//__________________________________________________________________________________________________
-void AliRICH::Display()const
-{
-//Provides fast event display
-//For RICH only, full display is .x Display.C    
-  Bool_t isHits    =!GetLoader()->LoadHits();
-  Bool_t isDigits  =!GetLoader()->LoadDigits();
-  Bool_t isClusters=!GetLoader()->LoadRecPoints();
-  
-  if(!isHits && !isDigits && !isClusters){Error("Exec","No hits digits and clusters. Nothing to display.");return;}
-  
-  TCanvas *pCanvas = new TCanvas("Display","RICH Display",0,0,600,600);
-  
-  TH2F *pHitsH2=0,*pDigitsH2=0,*pClustersH2=0;
-  
-  if(isHits)     pHitsH2     = new TH2F("pHitsH2"  ,  "Event Display;x,cm;y,cm",165,0,AliRICHParam::PcSizeX(),
-                                                                                144,0,AliRICHParam::PcSizeY());
-  if(pHitsH2)    pHitsH2->SetStats(kFALSE);
-  
-  if(isDigits)   pDigitsH2   = new TH2F("pDigitsH2"  ,"Event Display",165,0,AliRICHParam::PcSizeX(),
-                                                                      144,0,AliRICHParam::PcSizeY());
-  if(isClusters) pClustersH2 = new TH2F("pClustersH2","Event Display",165,0,AliRICHParam::PcSizeX(),
-                                                                      144,0,AliRICHParam::PcSizeY());
-  
-  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 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 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",iEvt,iCh));
-      pHitsH2->SetMarkerColor(kRed); pHitsH2->SetMarkerStyle(29); pHitsH2->SetMarkerSize(0.4);
-      pHitsH2->Draw();
-      AliRICHParam::DrawSectors();
-      TLatex l; l.SetNDC(); l.SetTextSize(0.02);
-      if(!isHits)     {l.SetTextColor(kRed)  ;l.DrawLatex(0.1,0.01,"No Hits"    );}
-      if(!isDigits)   {l.SetTextColor(kGreen);l.DrawLatex(0.4,0.01,"No DIGITS"  );}
-      if(!isClusters) {l.SetTextColor(kBlue) ;l.DrawLatex(0.8,0.01,"No CLUSTERS");}
-      pCanvas->Update();        pCanvas->Modified();       gPad->WaitPrimitive();
-//deals with digits      
-      if(isDigits){
-        GetLoader()->TreeD()->GetEntry(0);
-        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");
-        pCanvas->Update();        pCanvas->Modified();       gPad->WaitPrimitive();
-      }//if(isDigits)      
-//deals with clusters      
-      if(isClusters){
-        GetLoader()->TreeR()->GetEntry(0);
-        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");
-        pCanvas->Update();        pCanvas->Modified();       gPad->WaitPrimitive();
-      }//if(isClusters)
-    }//chambers loop
-  }//events Loop
-  
-  delete pCanvas;
-  GetLoader()->UnloadHits();
-  if(isDigits)   GetLoader()->UnloadDigits();
-  if(isClusters) GetLoader()->UnloadRecPoints();
-}//Display()
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICH::ReadESD(Int_t iEventN, Int_t iChamber)const
-{
-//
-  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
-  
-                                                                 
-  AliESD *pESD=new AliESD;  pTree->SetBranchAddress("ESD", &pESD);
-  
-  pTree->GetEvent(iEventN);
-  
-  Int_t iNtracks=pESD->GetNumberOfTracks();    
-  
-  for(Int_t iTrackN=0;iTrackN<iNtracks;iTrackN++){//ESD tracks loop
-    AliESDtrack *pTrack = pESD->GetTrack(iTrackN);// get next reconstructed track
-    Double_t mom[3], pos[3];
-    pTrack->GetPxPyPz(mom); TVector3 mom3(mom[0],mom[1],mom[2]);
-    pTrack->GetXYZ(pos); TVector3 pos3(pos[0],pos[1],pos[2]);
-    AliRICHHelix helix(pos3,mom3,(Int_t)pTrack->GetSign(),-0.1*pESD->GetMagneticField());
-    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()/1000000;
-      if(iChamberRecon==iChamber) {
-        Double_t thetaCer = pTrack->GetRICHsignal();
-        if(thetaCer<0) continue;
-        TVector3 entrance(helix.PosRad().X(),helix.PosRad().Y(),0);
-        Float_t thetaTrack,phiTrack;
-        pTrack->GetRICHthetaPhi(thetaTrack,phiTrack);
-        TVector3 vectorTrack;
-        vectorTrack.SetMagThetaPhi(pTrack->GetP(),thetaTrack,phiTrack);
-        AliInfo(Form("Draw ring started for track %i on chamber %i",iTrackN,iChamber));
-        AliInfo(Form("ThetaCer %f TrackTheta %f TrackPhi %f Momentum %f",thetaCer,thetaTrack,phiTrack,pTrack->GetP()));
-        Float_t dx,dy;
-        pTrack->GetRICHdxdy(dx,dy);
-        DrawRing(entrance,vectorTrack,thetaCer);
-      }
-    }
-  }
-  delete pESD;  pFile->Close();//close AliESDs.root
-}
-//__________________________________________________________________________________________________
-void AliRICH::DrawRing(TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)const
-{
-  Double_t xGraph[100],yGraph[100];
-  Int_t nPointsToDraw = 0;
-  for(Int_t i=0;i<100;i++) {
-    Double_t phiCer = 2*TMath::Pi()*i/100;
-    TVector3 pos = AliRICHParam::Instance()->ForwardTracing(entrance,vectorTrack,thetaCer,phiCer);
-    if(pos.X()==-999) continue;
-    xGraph[nPointsToDraw] = pos.X();yGraph[nPointsToDraw] = pos.Y();nPointsToDraw++;
-  }
-//  AliInfo(Form("Npoints per ring %i",nPointsToDraw));
-  TGraph *gra = new TGraph(nPointsToDraw,xGraph,yGraph);
-  gra->Draw("C");  
-}
-//__________________________________________________________________________________________________
 void AliRICH::SummaryOfEvent(Int_t iEvtN) const
 {
 //prints a summary for a given event
@@ -501,159 +237,4 @@ void AliRICH::SummaryOfEvent(Int_t iEvtN) const
   GetLoader()->GetRunLoader()->UnloadHeader();
   GetLoader()->GetRunLoader()->UnloadKinematics();
 }
-//__________________________________________________________________________________________________
-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, 
-//            cetele (GeV) - the same for electrons-positrons
-//            cutR (cm)    - cut on production vertex radius (cylindrical system)        
-  gBenchmark->Start("HitsAna");
-  
-  Double_t cutPantiproton    =cut;
-  Double_t cutPkaonminus     =cut;
-  Double_t cutPpionminus     =cut;
-  Double_t cutPmuonminus     =cut;
-  Double_t cutPpositron      =cutele;
-                    
-  Double_t cutPelectron      =cutele;
-  Double_t cutPmuonplus      =cut;
-  Double_t cutPpionplus      =cut;
-  Double_t cutPkaonplus      =cut;
-  Double_t cutPproton        =cut;
-                       
-
-  TH2F *pEleHitRZ    =new TH2F("EleHitRZ"    ,Form("e^{+} e^{-} hit %s;z[cm];R[cm]" ,GetName())     , 400,-300,300 ,400,-500,500);   //R-z plot 0cm<R<550cm -300cm<z<300cm  
-  TH2F *pEleHitRP    =new TH2F("EleHitRP"    ,Form("e^{+} e^{-} hit %s;p[GeV];R[cm]",GetName())     ,1000,-1  ,1   ,400,   0,550);   //R-p plot 0cm<R<550cm -1GeV<p<1GeV 
-  TH1F *pEleAllP     =new TH1F("EleAllP"     ,     "e^{+} e^{-} all;p[GeV]"                         ,1000,-1  ,1                );  
-  TH1F *pEleHitP     =new TH1F("EleHitP"     ,Form("e^{+} e^{-} hit %s;p[GeV]"      ,GetName())     ,1000,-1  ,1                );   
-  TH1F *pMuoHitP     =new TH1F("MuoHitP"     ,Form("#mu^{-} #mu^{+} hit %s;p[GeV]"  ,GetName())     ,1000,-4  ,4                ); 
-  TH1F *pPioHitP     =new TH1F("PioHitP"     ,Form("#pi^{-} #pi^{+} hit %s;p[GeV]"  ,GetName())     ,1000,-4  ,4                ); 
-  TH1F *pKaoHitP     =new TH1F("KaoHitP"     ,Form("K^{-} K^{+} hit %s;p[GeV]"      ,GetName())     ,1000,-4  ,4                ); 
-  TH1F *pProHitP     =new TH1F("ProHitP"     ,Form("p^{-} p^{+} hit %s;p[GeV]"      ,GetName())     ,1000,-4  ,4                ); 
-  TH2F *pFlux        =new TH2F("flux"        ,Form("%s flux with Rvertex<%.1fcm"    ,GetName(),cutR),10  ,-5  ,5   , 10,0    ,10); //special text hist
-  TH2F *pVertex      =new TH2F("vertex"      ,Form("%s 2D vertex of RICH hit;x;y"   ,GetName())     ,120 ,0   ,600 ,120,0    ,600); //special text hist
-  TH1F *pRho         =new TH1F("rho"         ,Form("%s r of RICH hit"               ,GetName())     ,600 ,0   ,600); //special text hist
-  pFlux->SetStats(0);
-  pFlux->GetXaxis()->SetBinLabel(1 ,Form("p^{-}>%.3fGeV/c"   ,cutPantiproton));        
-  pFlux->GetXaxis()->SetBinLabel(2 ,Form("K^{-}>%.3fGeV/c"   ,cutPkaonminus ));        
-  pFlux->GetXaxis()->SetBinLabel(3 ,Form("#pi^{-}>%.3fGeV/c" ,cutPpionminus ));      
-  pFlux->GetXaxis()->SetBinLabel(4 ,Form("#mu^{-}>%.3fGeV/c" ,cutPmuonminus ));      
-  pFlux->GetXaxis()->SetBinLabel(5 ,Form("e^{+}>%.3fGeV/c"   ,cutPpositron  ));        
-  
-  pFlux->GetXaxis()->SetBinLabel(6 ,Form("e^{-}>%.3fGeV/c"   ,cutPelectron  ));        
-  pFlux->GetXaxis()->SetBinLabel(7 ,Form("#mu^{+}>%.3fGeV/c" ,cutPmuonplus  ));      
-  pFlux->GetXaxis()->SetBinLabel(8 ,Form("#pi^{+}>%.3fGeV/c" ,cutPpionplus  ));      
-  pFlux->GetXaxis()->SetBinLabel(9 ,Form("K^{+}>%.3fGeV/c"   ,cutPkaonplus  ));        
-  pFlux->GetXaxis()->SetBinLabel(10,Form("p^{+}>%.3fGeV/c"   ,cutPproton    ));        
-  
-  pFlux->GetYaxis()->SetBinLabel(1,"sum");  
-  pFlux->GetYaxis()->SetBinLabel(2,"ch1");  
-  pFlux->GetYaxis()->SetBinLabel(3,"ch2");  
-  pFlux->GetYaxis()->SetBinLabel(4,"ch3");  
-  pFlux->GetYaxis()->SetBinLabel(5,"ch4");  
-  pFlux->GetYaxis()->SetBinLabel(6,"ch5");  
-  pFlux->GetYaxis()->SetBinLabel(7,"ch6");  
-  pFlux->GetYaxis()->SetBinLabel(8,"ch7");  
-  pFlux->GetYaxis()->SetBinLabel(9,"prim"); 
-  pFlux->GetYaxis()->SetBinLabel(10,"tot");  
-  
-//end of hists definition
-   
-  Int_t iNevents=fLoader->GetRunLoader()->GetAliRun()->GetEventsPerRun(),iCntPrimParts=0,iCntTotParts=0;
-//load all needed trees   
-  fLoader->LoadHits(); 
-  fLoader->GetRunLoader()->LoadHeader(); 
-  fLoader->GetRunLoader()->LoadKinematics();  
-  
-  for(Int_t iEvtN=0;iEvtN < iNevents;iEvtN++){//events loop
-    fLoader->GetRunLoader()->GetEvent(iEvtN);
-    AliInfo(Form(" %i event processes",fLoader->GetRunLoader()->GetEventNumber()));
-    AliStack *pStack= fLoader->GetRunLoader()->Stack(); 
-    
-    for(Int_t iParticleN=0;iParticleN<pStack->GetNtrack();iParticleN++){//stack loop
-      TParticle *pPart=pStack->Particle(iParticleN);
-
-      if(iParticleN%10000==0) AliInfo(Form(" %i particles read",iParticleN));
-    
-      switch(pPart->GetPdgCode()){
-        case kProtonBar: pFlux->Fill(-4.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-4.5,8); break;
-        case kKMinus:    pFlux->Fill(-3.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-3.5,8); break;
-        case kPiMinus:   pFlux->Fill(-2.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-2.5,8); break;
-        case kMuonMinus: pFlux->Fill(-1.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-1.5,8); break;
-        case kPositron:  pFlux->Fill(-0.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-0.5,8); pEleAllP->Fill(-pPart->P()); break;
-      
-        case kElectron:  pFlux->Fill( 0.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 0.5,8); pEleAllP->Fill( pPart->P()); break;      
-        case kMuonPlus:  pFlux->Fill( 1.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 1.5,8); break;      
-        case kPiPlus:    pFlux->Fill( 2.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 2.5,8); break;      
-        case kKPlus:     pFlux->Fill( 3.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 3.5,8); break;      
-        case kProton:    pFlux->Fill( 4.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 4.5,8); break;            
-      }//switch
-    }//stack loop
-//now hits analiser        
-    for(Int_t iEntryN=0;iEntryN < fLoader->TreeH()->GetEntries();iEntryN++){//TreeH loop
-      fLoader->TreeH()->GetEntry(iEntryN);                                  //get current entry (prim)                
-      for(Int_t iHitN=0;iHitN < Hits()->GetEntries();iHitN++){//hits loop
-        AliRICHHit *pHit = (AliRICHHit*)Hits()->At(iHitN);            //get current hit
-        TParticle  *pPart=pStack->Particle(pHit->GetTrack());      //get stack particle which produced the current hit
-        
-        if(pPart->GetPDG()->Charge()!=0&&pPart->Rho()>0.1) pVertex->Fill(pPart->Vx(),pPart->Vy()); //safe margin for sec.
-        if(pPart->GetPDG()->Charge()!=0) pRho->Fill(pPart->Rho()); //safe margin for sec.
-        if(pPart->R()>cutR) continue;                                   //cut on production radius (cylindrical system) 
-      
-        switch(pPart->GetPdgCode()){
-          case kProtonBar: if(pPart->P()>cutPantiproton) {pProHitP->Fill(-pPart->P()); pFlux->Fill(-4.5,pHit->C());}break;
-          case kKMinus   : if(pPart->P()>cutPkaonminus)  {pKaoHitP->Fill(-pPart->P()); pFlux->Fill(-3.5,pHit->C());}break;
-          case kPiMinus  : if(pPart->P()>cutPpionminus)  {pPioHitP->Fill(-pPart->P()); pFlux->Fill(-2.5,pHit->C());}break;
-          case kMuonMinus: if(pPart->P()>cutPmuonminus)  {pMuoHitP->Fill(-pPart->P()); pFlux->Fill(-1.5,pHit->C());}break;        
-          case kPositron : if(pPart->P()>cutPpositron)   {pEleHitP->Fill(-pPart->P()); pFlux->Fill(-0.5,pHit->C()); 
-               pEleHitRP->Fill(-pPart->P(),pPart->R());  pEleHitRZ->Fill(pPart->Vz(),pPart->R()); }break;
-          
-          case kElectron : if(pPart->P()>cutPelectron)   {pEleHitP->Fill( pPart->P()); pFlux->Fill( 0.5,pHit->C()); 
-               pEleHitRP->Fill( pPart->P(),pPart->R());  pEleHitRZ->Fill(pPart->Vz(),pPart->R()); }break;
-          case kMuonPlus : if(pPart->P()>cutPmuonplus)   {pMuoHitP->Fill( pPart->P()); pFlux->Fill( 1.5,pHit->C());}break;                     
-          case kPiPlus   : if(pPart->P()>cutPpionplus)   {pPioHitP->Fill( pPart->P()); pFlux->Fill( 2.5,pHit->C());}break;           
-          case kKPlus    : if(pPart->P()>cutPkaonplus)   {pKaoHitP->Fill( pPart->P()); pFlux->Fill( 3.5,pHit->C());}break;           
-          case kProton   : if(pPart->P()>cutPproton)     {pProHitP->Fill( pPart->P()); pFlux->Fill( 4.5,pHit->C());}break;
-        }
-      }//hits loop      
-    }//TreeH loop
-    iCntPrimParts +=pStack->GetNprimary();
-    iCntTotParts  +=pStack->GetNtrack();
-  }//events loop                        
-//unload all loaded staff  
-  fLoader->UnloadHits();  
-  fLoader->GetRunLoader()->UnloadHeader(); 
-  fLoader->GetRunLoader()->UnloadKinematics();  
-//Calculater some sums
-  Stat_t sum=0;
-//sum row, sum over rows  
-  for(Int_t i=1;i<=pFlux->GetNbinsX();i++){
-    sum=0; for(Int_t j=2;j<=8;j++)    sum+=pFlux->GetBinContent(i,j);    
-    pFlux->SetBinContent(i,1,sum);
-  }
-    
-//display everything  
-  new TCanvas("canvas1",Form("Events %i Nprims=%i Nparticles=%i",iNevents,iCntPrimParts,iCntTotParts),1000,900); pFlux->Draw("text");  gPad->SetGrid();  
-//total prims and particles
-  TLatex latex; latex.SetTextSize(0.02);
-  sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,10);    latex.DrawLatex(5.1,9.5,Form("%.0f",sum));
-  sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,9);     latex.DrawLatex(5.1,8.5,Form("%.0f",sum));
-  for(Int_t iChN=1;iChN<=kNchambers;iChN++) {
-    sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,iChN+1);latex.DrawLatex(5.1,iChN+0.5,Form("%.0f",sum));
-  }  
-  sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,1);    latex.DrawLatex(5.1,0.5,Form("%.0f",sum));
-  
-  new TCanvas("cEleAllP"   ,"e" ,200,100); pEleAllP->Draw();
-  new TCanvas("cEleHitRP"  ,"e" ,200,100); pEleHitRP->Draw();
-  new TCanvas("cEleHitRZ"  ,"e" ,200,100); pEleHitRZ->Draw();
-  new TCanvas("cEleHitP"   ,"e" ,200,100); pEleHitP->Draw();
-  new TCanvas("cMuoHitP"   ,"mu",200,100); pMuoHitP->Draw();
-  new TCanvas("cPioHitP"   ,"pi",200,100); pPioHitP->Draw();
-  new TCanvas("cKaoHitP"   ,"K" ,200,100); pKaoHitP->Draw();
-  new TCanvas("cProHitP"   ,"p" ,200,100); pProHitP->Draw();
-  new TCanvas("cVertex"    ,"2d vertex" ,200,100); pVertex->Draw();
-  new TCanvas("cRho"    ,"Rho of sec" ,200,100); pRho->Draw();
-  
-  gBenchmark->Show("HitsPlots");
-}//HitsPlots()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index bde915c..19957fd 100644 (file)
  * See cxx source for full Copyright notice                               */
 
 #include <AliDetector.h>  //base class
-#include <TClonesArray.h>  
-#include <TObjArray.h>
-#include <TVector.h>
-#include <TVector3.h>
+#include <TClonesArray.h> //XxxCreate() 
+#include <TObjArray.h>    //fClu field
 
-#include "AliRICHCluster.h"
-#include "AliRICHHit.h"
 
-//__________________AliRICH_________________________________________________________________________
-class AliESD;
 
 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),fSdig(0),fSdigCnt(0),fDig(0),fClu(0),fCounters(0),fNcham(0) {;}  //copy ctor not implemented
+            AliRICH(const char *nm,const char *ttl);                                              //named ctor
+            AliRICH(                              ):AliDetector(    ),fSdi(0),fDig(0),fClu(0) {}  //default ctor          
+            AliRICH(const AliRICH &rich           ):AliDetector(rich),fSdi(0),fDig(0),fClu(0) {}  //copy ctor not implemented
   virtual  ~AliRICH();                                            
-          
-  AliRICH&  operator=(const AliRICH&)                 {return *this;}
+  AliRICH&  operator=(const AliRICH&)                 {return *this;}                             //not implemented
 //framework part  
-          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    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* 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 
+          void  BuildGeometry   (                ) {}          //from AliModule invoked from AliMC::InitGeometry() to build geometry for old 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
+          void  SetTreeAddress  (                );            //from AliModule invoked from AliRun::GetEvent(), AliLoader::SetTAddrInDet()
+  virtual void  StepManager     (                )=0;          //from AliModule invoked from AliMC
+//private part +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+  void          HitCreate(         )     {if(fHits)return; fHits=new TClonesArray("AliRICHHit"); fNhits=0;      }//create hits list
+  void          HitPrint (Int_t evt)const;                                                                       //print hits list
+              
+  TClonesArray* SdiLst   (         )const{return fSdi;                                                          }//get sdigits list 
+  void          SdiCreate(         )     {if(fSdi)return; fSdi=new TClonesArray("AliRICHDigit");                }//create sdigits list
+  void          SdiReset (         )     {if(fSdi)  fSdi ->Clear();                                             }//clean sdigits list
+  void          SdiPrint (Int_t evt)const;                                                                       //print sdigits 
          
-         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
+  TObjArray*    DigLst   (         )const{return fDig;                                                          }//get digits list for all chambers
+  TClonesArray* DigLst   (Int_t c  )const{return fDig ? (TClonesArray *)fDig->At(c):0;                          }//get digits list for chamber
+  void          DigCreate(         )     {fDig=new TObjArray(7);for(Int_t i=0;i<7;i++)fDig->AddAt(new TClonesArray("AliRICHDigit"),i);}//create digits list
+  void          DigReset (         )     {if(fDig)for(int i=0;i<7;i++)fDig->At(i)->Clear();                     }//clean digits list 
+  void          DigPrint (Int_t evt)const;                                                                       //print digits
           
-         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
+  TClonesArray* CluLst   (Int_t c  )const{return fClu ? (TClonesArray *)fClu->At(c):0;                          }//get clusters list for chamber
+  inline void   CluCreate(         )     {fClu=new TObjArray(7); for(Int_t i=0;i<7;i++)fClu->AddAt(new TClonesArray("AliRICHCluster"),i);}//create clusters list
+         void   CluReset (         )     {if(fClu)for(int i=0;i<7;i++)fClu->At(i)->Clear();                     }//clean clusters list
+         void   CluPrint (Int_t evt)const;                                                                       //print clusters list
          
-         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;
+  void          OccupancyPrint(Int_t evt=-1);                    //print chambers occupancy 
+  void          SummaryOfEvent(Int_t evt=0)const;
 
 protected:  
-  TClonesArray         *fSdig;                    //! list of sdigits  
-  Int_t                 fSdigCnt;                 //! current number of sdigits
-  
+  TClonesArray         *fSdi;                     //! list of sdigits  
   TObjArray            *fDig;                     //! each chamber holds it's one list of digits
-  Int_t                 fDigCnt[7];               //! array of current numbers of digits
-  
   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() 
-  Int_t                 fNcham;                   // Number of RICH chambers during simulation
   
   ClassDef(AliRICH,11)                            //Main RICH class 
 };//class AliRICH  
-
-//__________________________________________________________________________________________________
-void AliRICH::SDigAdd(Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid) 
-{ 
-  Int_t cfm;  
-  switch(pid){
-    case 50000050: cfm=1000000;break;//cerenkov
-    case 50000051: cfm=1000;   break;//feedback
-    default:       cfm=1;      break;//mip
-  }   
-  new((*fSdig)[fSdigCnt++])AliRICHDigit(c,pad,q,cfm,tid,-1,-1);
-}
-//__________________________________________________________________________________________________
-void AliRICH::DigCreate()
-{
-  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::DigAdd(AliRICHDigit &dig)
-{
-//special for digit formed from raw  
-  TClonesArray &tmp=*((TClonesArray*)fDig->At(dig.C()-1));
-  new(tmp[fDigCnt[dig.C()-1]++])AliRICHDigit(dig);
-}    
-//__________________________________________________________________________________________________
-void AliRICH::DigAdd(int c,TVector pad,int q,int cfm,int *tid)
-{
-  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::CluCreate()
-{
-  if(fClu) return;
-  fClu = new TObjArray(fNcham);  
-  for(Int_t i=0;i<fNcham;i++) {fClu->AddAt(new TClonesArray("AliRICHCluster"), i); fCluCnt[i]=0;}
-}
-#endif//#ifndef AliRICH_h
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#endif
index e05c288..b9e5e18 100644 (file)
 
 #include "AliRICHCluster.h"  //class header
 #include <TMinuit.h>         //Solve()
-#include <AliStack.h>        //FindCfm(), Solve() 
-#include <TParticle.h>       //FindCfm()
-#include <TClonesArray.h>    //Solve() Test()
+#include <TClonesArray.h>    //Solve()
 
 ClassImp(AliRICHCluster)
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHCluster::CoG()
 {
 // Calculates naive cluster position as a center of gravity of its digits.
@@ -30,61 +28,65 @@ void AliRICHCluster::CoG()
   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
+    Float_t q=pDig->Q();                                //get QDC 
+    fX += pDig->LorsX()*q;fY +=pDig->LorsY()*q;         //add digit center weighted by QDC
   }//digits loop
-  fX/=fQdc;fY/=fQdc;                                    //final center of gravity
+  fX/=fQ;fY/=fQ;                                        //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;
+  CorrSin();
+  
+  fSt=kCoG;
 }//CoG()
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHCluster::CorrSin() 
+{
+// Correction of cluster x position due to sinoid, see HMPID TDR  page 30
+// Arguments: none
+//   Returns: none
+  AliRICHDigit dig(Ch(),100,1,fX,fY);                                               //tmp digit to get it center
+  Float_t x=fX-dig.LorsX();  
+  fX+=3.31267e-2*TMath::Sin(2*TMath::Pi()/0.8*x)-2.66575e-3*TMath::Sin(4*TMath::Pi()/0.8*x)+2.80553e-3*TMath::Sin(6*TMath::Pi()/0.8*x)+0.0070;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 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 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
+// For each pad of the cluster calculates the difference between actual pad charge and the charge induced to this pad by all Mathieson distributions 
+// Then the chi2 is calculated as the sum of this value squared for all pad in the cluster.  
 // 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;
+  Int_t iNshape = iNpars/3;
     
-  TVector2 curMathiesonPos;
   chi2 = 0;
-  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
+  for(Int_t i=0;i<pClu->Size();i++){                                       //loop on all pads of the cluster
+    Double_t dQpadMath = 0;                                                //pad charge collector  
+    for(Int_t j=0;j<iNshape;j++){                                          //Mathiesons loop as all of them may contribute to this pad
+      dQpadMath+=par[3*j+2]*pClu->Dig(i)->Mathieson(par[3*j],par[3*j+1]);  // par[3*j+2] is charge par[3*j] is x par[3*j+1] is y of current Mathieson
     }
-    chi2 += TMath::Power((dQpadMathieson-dQpadExp),2);                          //
+    chi2 +=TMath::Power((pClu->Dig(i)->Q()-dQpadMath),2);                  //
   }                                                                             //loop on all pads of the cluster     
 }//FitFunction()
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHCluster::Print(Option_t* opt)const
 {
 //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;
+  switch(fSt){
+    case      kFor: status="formed"     ;break;
+    case      kUnf: status="unfolded"   ;break;
+    case      kCoG: status="coged"      ;break;
+    case      kEmp: status="empty"      ;break;
   }
   Printf("%s cs=%2i, Size=%2i (x=%7.3f cm,y=%7.3f cm,Q=%4i qdc), %s",
-         opt,fCham,Size(),fX,fY,fQdc,status);
+         opt,Ch(),Size(),X(),Y(),Q(),status);
   for(Int_t i=0;i<Size();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
@@ -113,13 +115,12 @@ Int_t AliRICHCluster::Solve(TClonesArray *pCluLst,Bool_t isTryUnfold)
       AliRICHDigit *pDig2 = Dig(iDig2);                                                 //take second digit to compare with the first one
       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 dig2 is a neighbour of dig1
-         if(pDig2->Qdc()>=pDig1->Qdc()) iHowManyMoreCnt++;                              //count number of pads with Q more then Q of current pad
+         if(pDig2->Q()>=pDig1->Q()) iHowManyMoreCnt++;                                 //count number of pads with Q more then Q of current pad
     }//second digits loop
     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  ,Form("x%i",iLocMaxCnt),parStart=pDig1->LorsX(),parStep=0.01,parLow=0,parHigh=0,iErrFlg);
+        pMinuit->mnparm(3*iLocMaxCnt+1,Form("y%i",iLocMaxCnt),parStart=pDig1->LorsY(),parStep=0.01,parLow=0,parHigh=0,iErrFlg);
+        pMinuit->mnparm(3*iLocMaxCnt+2,Form("q%i",iLocMaxCnt),parStart=pDig1->Q()    ,parStep=0.01,parLow=0,parHigh=0,iErrFlg);
         iLocMaxCnt++;
     }//if this pad is local maximum
   }//first digits loop
@@ -133,13 +134,8 @@ Int_t AliRICHCluster::Solve(TClonesArray *pCluLst,Bool_t isTryUnfold)
        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);
-       if (TMath::Abs(fitQ)>2147483647.0) { 
-         //PH 2147483647 is the max. integer
-         //PH This apparently is a problem which needs investigation
-         AliWarning(Form("Too big or too small fitQ %f",fitQ));
-         fitQ = TMath::Sign((Double_t)2147483647,fitQ);
-       }
-       new ((*pCluLst)[iCluCnt++]) AliRICHCluster(C(),fitX,fitY,(Int_t)fitQ);      //add new unfolded clusters
+       if (TMath::Abs(fitQ)>2147483647.0) fitQ = TMath::Sign((Double_t)2147483647,fitQ);//???????????????
+       new ((*pCluLst)[iCluCnt++]) AliRICHCluster(Ch(),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 
@@ -149,47 +145,4 @@ Int_t AliRICHCluster::Solve(TClonesArray *pCluLst,Bool_t isTryUnfold)
   delete pMinuit;
   return iLocMaxCnt;
 }//Solve()
-//__________________________________________________________________________________________________
-void AliRICHCluster::Test(Double_t x,Double_t y,Double_t e,Bool_t isTryUnfold)
-{
-//This is to test all cluster functionality
-//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
-      clu.DigAdd(new AliRICHDigit(pad,dQpad));
-    }//affected pads loop 
-  }
-  clu.CoG();  clu.Print("Initial cluster:");
-  TClonesArray *pCluLst=new TClonesArray("AliRICHCluster",1);
-  clu.Solve(pCluLst,isTryUnfold);  
-  Printf("Initial hit    :  (%.2f,%.2f) Qtot=%i E=%.2f eV",x,y,iQtot,e*1e9);
-  ((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(AliRICHDigit::P2A(ch=1,padx=3,pady=3),qdc=101));
-  clu.DigAdd(new AliRICHDigit(AliRICHDigit::P2A(ch=1,padx=3,pady=4),qdc=202)); 
-  
-  clu.Print("Formed cluster:");
-  clu.Solve(pCluLst,kTRUE);  
-  pCluLst->Print();
-  delete pCluLst;
-}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index f4cd571..2c740d0 100644 (file)
@@ -3,97 +3,58 @@
 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
  * See cxx source for full Copyright notice                               */
 
-#include "AliRICHParam.h"    //DigAdd(), Dig()
+#include "AliRICHDigit.h"  //DigAdd()
+#include <TObjArray.h>     //DigAdd()      
+class TClonesArray;        //Solve()
 
 class AliRICHCluster :public TObject
 {
 public:
-  enum EClusterStatus {kFormed,kCoG,kUnfolded,kEmpty=-1}; 
-  AliRICHCluster():
-    TObject(),
-    fQdc(-1),
-    fCham(-1),
-    fX(-1),
-    fY(-1),
-    fStatus(kEmpty),
-    fDigs(0) {
-    // Default constructor
-  }
-  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(0x0) {
-    // Constructor
-  }
-  AliRICHCluster(const AliRICHCluster & src) :
-    TObject(src),
-    fQdc(src.fQdc),
-    fCham(src.fCham),
-    fX(src.fX),
-    fY(src.fY),
-    fStatus(src.fStatus),
-    fDigs(src.fDigs ? new TObjArray(*src.fDigs) : 0x0) {
-    // Copy constructor
-  }
-  AliRICHCluster & operator=(const AliRICHCluster & src) {
-    // Assigment operator  
-    if ( this == &src ) return *this;
-
-    // Base class assignment
-    TObject::operator=(src);
-
-    fQdc    = src.fQdc;
-    fCham   = src.fCham;
-    fX      = src.fX;
-    fY      = src.fY;
-    fStatus = src.fStatus;
-    fDigs = src.fDigs ? new TObjArray(*src.fDigs) : 0x0;
-    return *this;
-  }
-  virtual             ~AliRICHCluster(                                     )                                                                        {DigDel();}
+  enum EClusterStatus {kFor,kCoG,kUnf,kEmp=-1};      //status flags    
+  AliRICHCluster(                                   ):TObject( ),fSt(kEmp ),fCh(-1   ),fQ(-1  ),fX(-1  ),fY(-1  ),fDigs(0                                  ) {} 
+  AliRICHCluster(Int_t c,Float_t x,Float_t y,Int_t q):TObject( ),fSt(kUnf ),fCh(c    ),fQ(q   ),fX(x   ),fY(y   ),fDigs(0                                  ) {} 
+  AliRICHCluster(const AliRICHCluster &c            ):TObject(c),fSt(c.fSt),fCh(c.fCh),fQ(c.fQ),fX(c.fX),fY(c.fY),fDigs(c.fDigs ? new TObjArray(*c.fDigs):0) {}
+  AliRICHCluster &operator=(const AliRICHCluster &c) {
+    if(this == &c)return *this;TObject::operator=(c);            fSt=c.fSt; fCh=c.fCh; fQ=c.fQ; fX=c.fX; fY=c.fY; fDigs=c.fDigs ? new TObjArray(*c.fDigs):0; return *this;}
+    
+  virtual ~AliRICHCluster(                                     )                                                                        {DigDel();}
 //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
+         void          CorrSin  (                                         );                                                      //sinoidal correction   
+         Int_t         Ch       (                                         )const{return fCh;                                    } //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 (not 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
+         TObjArray*    DigLst   (                                         )const{return fDigs;                                  } //list of digits  
+         void          Reset    (                                         )     {DigDel();fQ=fCh=-1;fX=fY=-1;fSt=kEmp;          } //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
+         Int_t         Q        (                                         )const{return fQ;                                     } //cluster charge in QDC channels 
+         Float_t       X        (                                         )const{return fX;                                     } //cluster x position in LRS
+         Float_t       Y        (                                         )const{return fY;                                     } //cluster y position in LRS 
 protected:
-  Int_t         fQdc;         //QDC value
-  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   
+  Int_t         fSt;          //flag to mark the quality of the cluster   
+  Int_t         fCh;          //chamber number
+  Int_t         fQ;           //QDC value
+  Float_t       fX;           //local x postion, [cm] 
+  Float_t       fY;           //local y postion, [cm]  
   TObjArray    *fDigs;        //! list of digits forming this cluster
-  ClassDef(AliRICHCluster,3)  //RICH cluster class       
+  ClassDef(AliRICHCluster,5)  //RICH cluster class       
 };//class AliRICHCluster
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHCluster::DigAdd(AliRICHDigit *pDig)
 {
-// Adds a given digit to the list of digits belonging to this cluster    
-  if(!fDigs) {fQdc=0;fDigs = new TObjArray;}
+// Adds a given digit to the list of digits belonging to this cluster, cluster is not owner of digits
+// Arguments: pDig - pointer to digit to be added  
+//   Returns: none  
+  if(!fDigs) {fQ=0;fDigs = new TObjArray;}
   fDigs->Add(pDig);
-  fQdc+=(Int_t)pDig->Qdc(); 
-  fCham=pDig->C();
-  fStatus=kFormed;
+  fQ+=(Int_t)pDig->Q(); 
+  fCh=pDig->Ch();
+  fSt=kFor;
 }
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 #endif
index 28875ed..65807f6 100644 (file)
 //  * provided "as is" without express or implied warranty.                  *
 //  **************************************************************************
 
-#include "AliRICHDigit.h"//class header
-
+#include "AliRICHDigit.h" //class header
+#include "AliRICHHit.h"   //Hit2Sdi() 
+#include <TClonesArray.h> //Hit2Sdi() 
+#include <TCanvas.h>      //TestSeg()
+#include <TLine.h>        //TestSeg()
+#include <TLatex.h>       //TestSeg()
+#include <TPolyLine.h>    //DrawPc() 
+#include <TGStatusBar.h>  //Zoom()
+#include <TRootCanvas.h>  //Zoom() 
 ClassImp(AliRICHDigit)
 
 /*
@@ -28,7 +35,7 @@ For RICH the detector ID is 6 (reffered in the code as kRichRawId) while DDL ind
 
 Common header might be followed by the private one although  RICH has no any private header, just uses the common one.
 
-Single RICH D-RORC 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) 
+Single RICH D-RORC serves one half of a chamber i.e. 3 photocathodes even LDC for left part( PCs 0-2-4) and odd LDC for right part(1-3-5) 
 as it's seen from electronics side.
 
 So the LDC -chamber-ddl map is:
@@ -41,50 +48,151 @@ DDL index 10 -> ch 6 left -> DDL ID 0x60a          DDL index 11 -> ch 6 right ->
 DDL index 12 -> ch 7 left -> DDL ID 0x60c          DDL index 13 -> ch 7 right -> DDL ID 0x60d 
 
 RICH FEE as seen by single D-RORC 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.
+Each DILOGIC chip serves 48 channels for the 8x6 pads (reffered in the code as kDilX,kDilY). Channels counted from 0 to 47.
+
+The mapping inside DILOGIC chip has the following structure (see from electronics side):
 
-??????? Currently the exact mapping of DILOGIC addresses to pads is not known. So we invented horizontal zig-zag ???????  
+5  04 10 16 22 28 34 40 46
+4  02 08 14 20 26 32 38 44
+3  00 06 12 18 24 30 36 42
+2  01 07 13 19 25 31 37 43
+1  03 09 15 21 27 33 39 45
+0  05 11 17 23 29 35 41 47
+    
+    0  1  2  3  4  5  6  7  padx
 
-10 DILOGIC chips composes so called "row" in horizontal direction (reffered in the code as kNdilo), so the row is 80x6 pads structure. 
+10 DILOGIC chips composes so called "row" in horizontal direction (reffered in the code as kNdil), so the row is 80x6 pads structure. 
 DILOGIC chips in the row are counted from right to left as seen from electronics side, from 1 to 10.
-24 rows are piled up forming the whole FEE served by single D-RORC, so one DDL sees 80x144 pads separated in 3 photocathodes aka sectors.
-Rows are counted from 1 to 24 from top    to bottom for right  half of the chamber (sectors 2-4-6) as seen from electronics side, meaning even LDC number
-                          and from bottom to top    for left   half of the chamber (sectors 1-3-5) as seen from electronics side, meaning odd LDC number.
+24 rows are piled up forming the whole FEE served by single D-RORC, so one DDL sees 80x144 pads separated in 3 photocathodes.
+Rows are counted from 1 to 24 from top    to bottom for right  half of the chamber (PCs 1-3-5) as seen from electronics side, meaning even LDC number
+                          and from bottom to top    for left   half of the chamber (PCs 0-2-4) as seen from electronics side, meaning odd LDC number.
 
 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)
 */
-
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Float_t AliRICHDigit::Hit2Sdi(AliRICHHit *pHit,TClonesArray *pSdiLst)
+{
+// Creates a list of sdigits out of provided hit
+// Arguments: pHit- hit
+//   Returns: none
+  
+  Float_t  x=(pHit->LorsX() > SizePcX())? pHit->LorsX()-SizePcX()-SizeDead():pHit->LorsX();          //sagita is for PC (0-64) and not for chamber   
+  Float_t  qdcEle=34.06311+0.2337070*x+5.807476e-3*x*x-2.956471e-04*x*x*x+2.310001e-06*x*x*x*x;      //reparametrised from DiMauro
+  
+  Int_t iNele=Int_t(pHit->E()/26e-9);  if(iNele<1) iNele=1;                                          //number of electrons created by hit
+  Float_t qdcTot=0; for(Int_t i=1;i<=iNele;i++) qdcTot-=qdcEle*TMath::Log(gRandom->Rndm()+1e-6);     //total qdc fro hit, 1e-6 is a protection against 0 from rndm
+  
+  AliRICHDigit dd(1,1,1,pHit->LorsX(),pHit->LorsY());                                                //tmp digit to shift hit y to the nearest anod wire  
+  Float_t y=  (pHit->LorsY() > dd.LorsY()) ? dd.LorsY()+0.21 :  dd.LorsY()-0.21;
+  
+  Int_t iSdiCnt=pSdiLst->GetEntries();
+  for(Int_t i=0;i<9;i++){                                      //affected pads loop
+    AliRICHDigit dig(pHit->Ch(),qdcTot,pHit->Tid(),pHit->LorsX(),y,i); //c,q,tid,x,y   create tmp sdigit for pad i around hit position
+    if(dig.PadX()==-1) continue;
+    new((*pSdiLst)[iSdiCnt++]) AliRICHDigit(dig);
+  }
+  return qdcTot;
+}//Hit2Sdi()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHDigit::Print(Option_t*)const
 {
-//Print current digit  
-//Arguments: option string not used
-//  Returns: none    
-  Printf("pad=(%2i,%2i,%3i,%3i), QDC=%8.3f, cfm=%9i, TID=(%5i,%5i,%5i) raw r=%2i d=%2i a=%2i",
-               C(),Pad2Sec(PadX(),PadY()),PadX(),PadY() ,  Qdc(),    Cfm()  , fTracks[0],fTracks[1],fTracks[2], R(), D(), A());
+// Print current digit  
+// Arguments: option string not used
+//   Returns: none    
+  Printf("pad=(%2i,%2i,%3i,%3i),pos=(%7.2f,%7.2f) QDC=%8.3f, TID=(%5i,%5i,%5i) raw r=%2i d=%2i a=%2i",
+               Ch(),Pc(),PadX(),PadY(),LorsX(),LorsY(), Q(),  fTracks[0],fTracks[1],fTracks[2], Row(), Dilogic(), Addr());
 }
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICHDigit::Test()
+void AliRICHDigit::PrintSize()
 {
-  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));
+// Print all segmentaion related sizes
+// Arguments: none
+//   Returns: none    
+  Printf("-->pad    =(%6.2f,%6.2f) cm dead zone %.2f cm\n"
+         "-->PC     =(%6.2f,%6.2f) cm\n"
+         "-->all PCs=(%6.2f,%6.2f) cm",
+               SizePadX(),SizePadY(),SizeDead(),SizePcX(),SizePcY(),SizeAllX(),SizeAllY());
 }
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHDigit::TestSeg()
+{
+// Draws the picture of segmentation   
+// Arguments: none
+//   Returns: none     
+  TCanvas *pC=new TCanvas("pads","View from electronics side, IP is behind the picture.");pC->ToggleEventStatus();
+  gPad->AddExec("test","AliRICHDigit::Zoom()");
+  DrawPc();  
+}//TestSeg()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHDigit::Zoom()
+{
+// Show info about current cursur position in status bar of the canvas
+// Arguments: none
+//   Returns: none     
+  TCanvas *pC=(TCanvas*)gPad; 
+  TRootCanvas *pRC= (TRootCanvas*)pC->GetCanvasImp();
+  TGStatusBar *pBar=pRC->GetStatusBar();
+  pBar->SetParts(5);
+  Float_t x=gPad->AbsPixeltoX(gPad->GetEventX());
+  Float_t y=gPad->AbsPixeltoY(gPad->GetEventY());
+  AliRICHDigit dig(1,100,1,x,y);  
+  if(IsInDead(x,y))
+    pBar->SetText("Out of sensitive area",4);    
+  else
+    pBar->SetText(Form("p%i x%i y%i r%i d%i a%i (%.2f,%.2f)",dig.Pc(),dig.PadX(),dig.PadY(),dig.Row(),dig.Dilogic(),dig.Addr(),dig.LorsX(),dig.LorsY()),4);
+  if(gPad->GetEvent()==1){
+    new TCanvas("zoom",Form("Row %i DILOGIC %i",dig.Row(),dig.Dilogic()));  
+  }
+}//Zoom()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHDigit::DrawPc(Bool_t isFill) 
+{ 
+// Utility methode draws RICH chamber PCs on event display.
+// Arguments: none
+//   Returns: none      
+//  y6  ----------  ----------
+//      |        |  |        |
+//      |    4   |  |    5   |
+//  y5  ----------  ----------
+//
+//  y4  ----------  ----------
+//      |        |  |        |
+//      |    2   |  |    3   |   view from electronics side
+//  y3  ----------  ----------
+//          
+//  y2  ----------  ----------
+//      |        |  |        |
+//      |    0   |  |    1   |
+//  y1  ----------  ----------
+//      x1      x2  x3       x4
+  gPad->Range(-5,-5,SizeAllX()+5,SizeAllY()+5); 
+  Float_t x1=0,x2=SizePcX(),x3=SizePcX()+SizeDead(),                                                  x4=SizeAllX();
+  Float_t y1=0,y2=SizePcY(),y3=SizePcY()+SizeDead(),y4=2*SizePcY()+SizeDead(),y5=SizeAllY()-SizePcY(),y6=SizeAllY();
+
+  Float_t xL[5]={x1,x1,x2,x2,x1}; //clockwise
+  Float_t xR[5]={x3,x3,x4,x4,x3};  
+  Float_t yD[5]={y1,y2,y2,y1,y1};
+  Float_t yC[5]={y3,y4,y4,y3,y3};  
+  Float_t yU[5]={y5,y6,y6,y5,y5};
+    
+  TLatex t; t.SetTextSize(0.01); t.SetTextAlign(22);
+  Int_t iColLeft=29,iColRight=41;
+  TPolyLine *pc=0;  TLine *pL; Float_t x0=0,y0=0,wRow=kDilY*SizePadY(),wDil=kDilX*SizePadX();
+  for(Int_t iPc=0;iPc<kPcAll;iPc++){
+    if(iPc==4) {pc=new TPolyLine(5,xL,yU);t.DrawText(x1-3.5,y6-20,"PC4");x0=x1;y0=y5;} if(iPc==5) {pc=new TPolyLine(5,xR,yU);t.DrawText(x4+3.5,y6-20,"PC5");x0=x3;y0=y5;}
+    if(iPc==2) {pc=new TPolyLine(5,xL,yC);t.DrawText(x1-3.5,y4-20,"PC2");x0=x1;y0=y3;} if(iPc==3) {pc=new TPolyLine(5,xR,yC);t.DrawText(x4+3.5,y4-20,"PC3");x0=x3;y0=y3;}
+    if(iPc==0) {pc=new TPolyLine(5,xL,yD);t.DrawText(x1-3.5,y2-20,"PC0");x0=x1;y0=y1;} if(iPc==1) {pc=new TPolyLine(5,xR,yD);t.DrawText(x4+3.5,y2-20,"PC1");x0=x3;y0=y1;}    
+    (iPc%2)? pc->SetFillColor(iColLeft): pc->SetFillColor(iColRight);
+    if(isFill) pc->Draw("f"); else pc->Draw();
+    for(Int_t i=1;i<=8 ;i++){//draw row lines (horizontal)
+      Float_t y=y0+i*wRow;
+      Int_t row=i+iPc/2*8; if(iPc%2!=0) row=25-row; t.DrawText(x0-1,y -3,Form("r%i",row)); 
+      if(i==8) break;                                      //do not draw the last line of PC
+      pL=new TLine(x0,y,x0+SizePcX(),y);   pL->Draw(); 
+    }    
+    for(Int_t iDil=1;iDil<=10;iDil++){Float_t x=x0+iDil*wDil;t.DrawText(x -3,y0-1,Form("d%i",11-iDil));   if(iDil==10) break;    pL=new TLine(x,y0,x,y0+SizePcY());  pL->Draw();}  
+  }      
+}//DrawPc()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index 902a234..5a92fb5 100644 (file)
  * See cxx source for full Copyright notice                               */
 
 #include <AliDigit.h>      //base class  
-#include <AliBitPacking.h> //ToRaw(), FromRaw()
-#include <TVector.h>       //ctor
+#include <TMath.h>         //Mathieson()
+#include <TRandom.h>       //IsOverTh()  
+#include <AliBitPacking.h> //Raw()
 
+class AliRICHHit;          //Hit2Sdi()
+class TClonesArray;        //Hit2Sdi()
 class AliRICHDigit :public AliDigit //TObject-AliDigit-AliRICHDigit
 {
 public:
-  enum EAbsPad {kChamAbs=10000000,kSecAbs=1000000,kPadAbsX=1000,kPadAbsY=1};                            //absolute pad number structure
-  enum ERawData{kDiloX=8,kDiloY=6,kNdilo=10};                                                           //DILOGIC structure
-  enum EPadData{kFirstPad=1,kPadsSecX=80,kPadsSecY=48,kPadsChamX=160,kPadsChamY=144,kSecX=2,kSecY=3};   //Segmentation structure 
-  enum EDdlData{kNddls=14};                                                                             //DDL structure
+  enum EAbsPad {kChAbs=100000000,kPcAbs=1000000,kPadAbsX=1000,kPadAbsY=1};       //absolute pad number structure
+  enum ERawData{kDilX=8,kDilY=6,kNdil=10,kNrow=24,kNddls=14};                    //RAW data structure
+  enum EPadData{kPcX=2,kPcY=3,kPad1=0,kPadPcX=80,kPadPcY=48,kPadAllX=kPadPcX*kPcX,kPadAllY=kPadPcY*kPcY,kPcAll=kPcX*kPcY,kPadAll=kPadAllX*kPadAllY};   //Segmentation structure 
+  enum EPadShif{kC=0,kU=1,kUR=2,kR=3,kDR=4,kD=5,kDL=6,kL=7,kUL=8};                 
 //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() {;}
+           AliRICHDigit(                                                     ):AliDigit( ),fPad(Abs(-1,-1,-1,-1)),fQ(-1)  {}                //default ctor
+           AliRICHDigit(Int_t pad,Int_t q,Int_t *t                           ):AliDigit(t),fPad(pad             ),fQ(q )  {}                //digit ctor 
+  inline   AliRICHDigit(Int_t c,Float_t q,Int_t t,Float_t x,Float_t y,Int_t f=0);                                                               //sdigit ctor 
+  virtual ~AliRICHDigit()                                {} //dtor
 //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 *opt=""               )const;                                                                  //TObject::Print() overloaded
+         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() overloaded
 //private part  
-                Int_t    A           (                               )const{return   (PadY()-1)%kDiloY*kDiloX+(PadX()-1)%kDiloX;}             //DILOGIC address 0..47 invented ?????
-                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 
-                Int_t    D           (                               )const{return 1+(PadX()-1)/kDiloX;}                                      //DILOGIC chip number 1..10
-                Int_t    Ddl         (                               )const{return (PadX()<=kPadsSecX) ? 2*C()-2 : 2*C()-1;}                  //DDL number 0..13
-         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
-                Int_t    R           (                               )const{return 1+(PadY()-1)/kDiloY;}                                      //DILOGIC row number 1..24
-         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;  //chamber number
-  Int_t    fPadX;     //pad along X counts from kFirstPad to kPadsChamX 
-  Int_t    fPadY;     //pad along Y counts from kFirstPad to kPadsChamY 
-  Double_t fQdc;      //QDC value, fractions are permitted for summable procedure  
-  ClassDef(AliRICHDigit,3) //RICH digit class       
-};//class AliRICHDigit
+  static Int_t   Abs         (Int_t c,Int_t s,Int_t x,Int_t y)     {return c*kChAbs+s*kPcAbs+x*kPadAbsX+y*kPadAbsY; }                  //(ch,pc,padx,pady)-> abs pad
+  static Int_t   A2C         (Int_t pad                      )     {return pad/kChAbs;                              }                  //abs pad -> chamber
+  static Int_t   A2P         (Int_t pad                      )     {return pad%kChAbs/kPcAbs;                       }                  //abs pad -> pc
+  static Int_t   A2X         (Int_t pad                      )     {return pad%kPcAbs/kPadAbsX;                     }                  //abs pad -> pad X 
+  static Int_t   A2Y         (Int_t pad                      )     {return pad%kPadAbsX;                            }                  //abs pad -> pad Y 
+         Int_t   Addr        (                               )const{Int_t mapY2A[kDilY]={5,3,1,0,2,4}; return mapY2A[A2Y(fPad)%kDilY]+kDilY*(A2X(fPad)%kDilX);}//raw a=0..47
+         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   Ch          (                               )const{return A2C(fPad);                               }                  //chamber number
+         Int_t   Dilogic     (                               )const{return 10-PadX()/kDilX;                         }                  //raw d=1..10
+  static void    DrawPc      (Bool_t isFill=kTRUE            );                                                                        //draw PCs
+         Int_t   Ddl         (                               )const{return (PadX()<kPadPcX) ? 2*Ch()-2 : 2*Ch()-1;}                    //DDL number 0..13
+  static Float_t Hit2Sdi     (AliRICHHit *pHit,TClonesArray *);                                                                        //hit -> 9 sdigits, returns total QDC   
+  static Bool_t  IsOverTh    (Float_t q                      )     {return q > 6;                                                  }   //is digit over threshold????
+  static Bool_t  IsInside    (Float_t x,Float_t y            )     {return x>0&&y>0&&x<SizeAllX()&&y<SizeAllY();                   }   //is point inside pc boundary?
+  inline static Bool_t  IsInDead    (Float_t x,Float_t y            );                                                                 //is point in dead area?
+         Float_t LorsX       (                               )const{return (PadX()+0.5)*SizePadX()+(Pc()%2)*(SizePcX()+SizeDead());}   //center of the pad x, [cm]
+         Float_t LorsY       (                               )const{return (PadY()+0.5)*SizePadY()+(Pc()/2)*(SizePcY()+SizeDead());}   //center of the pad y, [cm]
+  inline Float_t Mathieson   (Float_t x,Float_t y            )const;                                                                   //Mathieson distribution 
+         Int_t   PadX        (                               )const{return A2X(fPad);}                                                 //x position of the pad
+         Int_t   PadY        (                               )const{return A2Y(fPad);}                                                 //y postion of the pad     
+         Int_t   Pad         (                               )const{return fPad;}                                                      //absolute id of this pad
+         Float_t Q           (                               )const{return fQ;}                                                        //charge, [QDC]
+         Int_t   Pc          (                               )const{return A2P(fPad);}                                                 //PC position number
+  static void    PrintSize   (                               );                                                                        //print all segmentation sizes      
+  inline Int_t   Raw         (UInt_t &w32                    )const;                                                                   //raw
+         Int_t   Row         (                               )const{Int_t r=1+Pc()/2*8+PadY()/kDilY; return (Pc()%2)?kNrow-r+1:r;}     //row r=1..24
+         void    Set         (Int_t c,Int_t s,Int_t x,Int_t y)     {fPad=Abs(c,s,x,y);}                                                //set new digit
+         void    ReadRaw     (Int_t ddl,Int_t r,Int_t d,Int_t a){Int_t mapA2Y[kDilY]={3,2,4,1,5,0};fPad=Abs(ddl/2,ddl%7,d*kDilX+a/kDilY,r*kDilY+mapA2Y[a%kDilY]);} //from raw
+  inline void    ReadRaw     (Int_t ddl,UInt_t w32           );                                                                        //read raw word
+  
+  static Float_t SizeAllX    (                               )     {return SizePadX()*kPadAllX+SizeDead();}                            //all PCs size x, [cm]        
+  static Float_t SizeAllY    (                               )     {return SizePadY()*kPadAllY+2*SizeDead();}                          //all PCs size y, [cm]    
+  static Float_t SizeArea    (                               )     {return SizePcX()*SizePcY()*kPcAll;}                                //sence area, [cm^2]  
+  static Float_t SizeDead    (                               )     {return 2.6;}                                                       //dead zone size x, [cm]         
+  static Float_t SizeGap     (                               )     {return 8;  }
+  static Float_t SizePadX    (                               )     {return 0.8;}                                                       //pad size x, [cm]  
+  static Float_t SizePadY    (                               )     {return 0.84;}                                                      //pad size y, [cm]  
+  static Float_t SizePcX     (                               )     {return SizePadX()*kPadPcX;}                                        //PC size x, [cm]        
+  static Float_t SizePcY     (                               )     {return SizePadY()*kPadPcY;}                                        //PC size y, [cm]    
+  static Float_t SizeWin     (                               )     {return 0.5;}
+  static Float_t SizeRad     (                               )     {return 1.5;}     
+  static void    TestSeg     (                               );                                                                        //test segmentation
+         void    Zoom        (                               ); 
+protected:                  //AliDigit has fTracks[3]
+  Int_t   fPad;             //absolute pad number is chamber*kCham
+  Float_t fQ;               //QDC value, fractions are permitted for summable procedure  
+  ClassDef(AliRICHDigit,4) //RICH digit class       
+};//class AliRICHDigitN
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+AliRICHDigit::AliRICHDigit(Int_t c,Float_t q,Int_t t,Float_t x,Float_t y,Int_t flag):AliDigit(),fPad(Abs(-1,-1,-1,-1)),fQ(-1)  
+{
+// Creation of sdigit  
+// Arguments: c- chamber 
+//            q- total QDC
+//            t -TID
+//            x,y - hit position, LORS        
+//   Returns: none    
+  Int_t pc,padx,pady;
+  if     (x>=          0          && x<=  SizePcX()            ) {pc=0; padx=Int_t( x                           / SizePadX());}//PC 0 or 2 or 4
+  else if(x>=SizePcX()+SizeDead() && x<=  SizeAllX()           ) {pc=1; padx=Int_t((x-  SizePcX()-  SizeDead()) / SizePadX());}//PC 2 or 4 or 6
+  else return;
+  if     (y>=          0          && y<=  SizePcY()            ) {      pady=Int_t( y                           / SizePadY());}//PC 0 or 1
+  else if(y>=SizePcY()+SizeDead() && y<=2*SizePcY()+SizeDead() ) {pc+=2;pady=Int_t((y-  SizePcY()-  SizeDead()) / SizePadY());}//PC 2 or 3
+  else if(y>=SizeAllY()-SizePcY() && y<=  SizeAllY()           ) {pc+=4;pady=Int_t((y-2*SizePcY()-2*SizeDead()) / SizePadY());}//PC 4 or 5
+  else return;
+  
+  switch(flag){
+    case kUL:padx--;pady++;break;    case kU:pady++;break;     case kUR:padx++; pady++;break;
+                                              
+    case kL: padx--;       break;    case kC:       break;     case kR:padx++;         break;
+                                                 
+    case kDL:padx--;pady--;break;    case kD:pady--;break;     case kDR:padx++; pady--;break;                                            
+  }
+  if(padx<0 || padx>=kPadPcX) return;
+  if(pady<0 || pady>=kPadPcY) return;
+  fPad=Abs(c,pc,padx,pady);
+  fQ=q*Mathieson(x,y);
+  fTracks[0]=t; 
+}    
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Int_t AliRICHDigit::Compare(const TObject *pObj) const
 {
@@ -65,57 +114,63 @@ Int_t AliRICHDigit::Compare(const TObject *pObj) const
 // 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     (fPad==((AliRICHDigit*)pObj)->Pad()) return  0;
+  else if(fPad >((AliRICHDigit*)pObj)->Pad()) return  1;
+  else                                        return -1;
 }
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICHDigit::Raw2Dig(Int_t ddl,UInt_t w32)
+Bool_t AliRICHDigit::IsInDead(Float_t x,Float_t y)
 {
-//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         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)    
+// Check is the current point is outside of sensitive area or in dead zones
+// Arguments: x,y -position
+//   Returns: 1 if not in sensitive zone           
+  if(x<0 || x>SizeAllX() || y<0 || y>SizeAllY()) return kTRUE; //out of pc 
   
-  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
-}  
+  if(x>SizePcX()  && x<SizePcX()+SizeDead())   return kTRUE; //in dead zone along x  
+  
+  if(y>SizePcY()                       && y<SizePcY()+SizeDead())      return kTRUE; //in first dead zone along y   
+  if(y>SizeAllY()-SizePcY()-SizeDead() && y<SizeAllY()-SizePcY())      return kTRUE; //in second dead zone along y   
+  return kFALSE;
+}
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-Int_t AliRICHDigit::Dig2Raw(UInt_t &w32)const
+Float_t AliRICHDigit::Mathieson(Float_t x,Float_t y)const
+{
+// This is the answer to electrostatic problem of charge distrubution in MWPC described elsewhere. (NIM A370(1988)602-603)
+// Arguments: x,y- position of the center of Mathieson distribution
+//  Returns: a charge fraction [0-1] imposed into the pad
+  const Float_t kSqrtK3=0.77459667,k2=0.962,k4=0.379;
+
+  Float_t ux1=kSqrtK3*TMath::TanH(k2*(x-LorsX()+0.5*SizePadX())/0.425);
+  Float_t ux2=kSqrtK3*TMath::TanH(k2*(x-LorsX()-0.5*SizePadX())/0.425);
+  Float_t uy1=kSqrtK3*TMath::TanH(k2*(y-LorsY()+0.5*SizePadY())/0.425);
+  Float_t uy2=kSqrtK3*TMath::TanH(k2*(y-LorsY()-0.5*SizePadY())/0.425);
+  return 4*k4*(TMath::ATan(ux2)-TMath::ATan(ux1))*k4*(TMath::ATan(uy2)-TMath::ATan(uy1));
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliRICHDigit::Raw(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
   w32=0;
-  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)  
+  AliBitPacking::PackWord((UInt_t)fQ        ,w32, 0,11);  // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq        Qdc               bits (00..11) counts (0..4095)
+  AliBitPacking::PackWord(         Addr()   ,w32,12,17);  // 3322 2222 2222 1111 1111 1000 0000 0000        DILOGIC address   bits (12..17) counts (0..47)
+  AliBitPacking::PackWord(         Dilogic(),w32,18,21);  // 1098 7654 3210 9876 5432 1098 7654 3210        DILOGIC number    bits (18..21) counts (1..10)
+  AliBitPacking::PackWord(         Row()    ,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)
+void AliRICHDigit::ReadRaw(Int_t ddl,UInt_t w32)
 {
-// Determines sector containing the given pad.
-// Arguments: padx,pady - pad number
-//   Returns: sector number    
-// y ^  5 6         sectors map as seen from outside (IP is behind the page)
-//   |  3 4
-//   |  1 2
-//   -------> x  
-  Int_t sector=-1;      
-  if     (padx >= kFirstPad && padx <=   kPadsSecX )    sector=1;
-  else if(padx >  kPadsSecX && padx <=   kPadsChamX)    sector=2; 
-  else                                                  return -1;//padx out of range     
-  if     (pady >= kFirstPad && 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()
+// Converts a given raw data word to a digit
+// Arguments: w32 - 32 bits raw data word
+//            ddl - DDL idx  0 1 2 3 4 ... 13
+//   Returns: none
+        fQ = 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)    
+  ReadRaw(ddl,r,d,a);    
+}
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 #endif
index 0129130..031fb18 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "AliRICHDigitizer.h"
 #include "AliRICH.h"
+#include "AliRICHDigit.h"
 #include <AliRun.h>
 #include <AliRunLoader.h>
 #include "AliRunDigitizer.h"
 
 ClassImp(AliRICHDigitizer)
 
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHDigitizer::Exec(Option_t*)
 {
-//This methode is responsible for merging sdigits to a list of digits
-//Disintegration leeds to the fact that one hit affected several neighbouring pads, which means that the same pad might be
-//affected by few hits.     
+// This methode is responsible for merging sdigits to a list of digits
+//Disintegration leeds to the fact that one hit affects several neighbouring pads, which means that the same pad might be affected by few hits.     
   AliDebug(1,Form("Start with %i input(s) for event %i",fManager->GetNinputs(),fManager->GetOutputEventNr()));
 //First we read all sdigits from all inputs  
   AliRunLoader *pInRunLoader=0;//in and out Run loaders
   AliLoader    *pInRichLoader=0;//in and out RICH loaders  
-  TClonesArray tmpCA("AliRICHDigit");//tmp storage for sdigits sum up from all input files
+  TClonesArray sdigs("AliRICHDigit");//tmp storage for sdigits sum up from all input files
   Int_t total=0;
   for(Int_t inFileN=0;inFileN<fManager->GetNinputs();inFileN++){//files loop
     pInRunLoader  = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inFileN));          //get run loader from current input 
@@ -42,41 +42,63 @@ 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->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
+    AliDebug(1,Form("input %i has %i sdigits",inFileN,pInRich->SdiLst()->GetEntries()));
+    for(Int_t i=0;i<pInRich->SdiLst()->GetEntries();i++){                                        //collect sdigits from current input
+      AliRICHDigit *pSDig=(AliRICHDigit*)pInRich->SdiLst()->At(i);
+      pSDig->AddTidOffset(fManager->GetMask(inFileN));                                          //apply TID shift since all inputs count tracks independently starting from 0
+      new(sdigs[total++]) AliRICHDigit(*pSDig);       
     }
-    pInRichLoader->UnloadSDigits();   pInRich->SDigReset(); //close current input and reset 
+    pInRichLoader->UnloadSDigits();   pInRich->SdiReset(); //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
+
+  if(sdigs.GetEntries()==0) return;                                                              //no sdigits collected, nothing to convert  
   
   AliRunLoader *pOutRunLoader  = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());    //open output stream (only 1 possible)
   AliLoader    *pOutRichLoader = pOutRunLoader->GetLoader("RICHLoader");                         //take output RICH loader
   AliRICH      *pOutRich       = (AliRICH*)pOutRunLoader->GetAliRun()->GetDetector("RICH");      //take output RICH
   pOutRichLoader->MakeTree("D");   pOutRich->MakeBranch("D");                                    //create TreeD in output stream
-  
-  TVector pad(2); pad[0]=0; pad[1]=0; Int_t iChamber=0,iCfm=0,aTids[3]={0,0,0},iId=-1; Double_t dQdc=0;//current pad info   
-  Int_t iNdigsPerPad=0;                   //how many sdigits for a given pad
-  for(Int_t i=0;i<tmpCA.GetEntries();i++){//sdigits loop (sorted)
-    AliRICHDigit *pSdig=(AliRICHDigit*)tmpCA.At(i);//get new sdigit
-    if(pSdig->PadAbs()==iId){//still the same pad
-      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(),-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->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->DigAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids);//add the last dig
+
+  Sdi2Dig(&sdigs,pOutRich->DigLst());
   
   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
+  sdigs.Clear();                      //remove all tmp sdigits
   pOutRichLoader->UnloadDigits();   pOutRich->DigReset();
 }//Exec()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHDigitizer::Sdi2Dig(TClonesArray *pSdiLst,TObjArray *pDigLst)
+{
+// Converts list of sdigits to 7 lists of digits, one per each chamber
+// Arguments: pSDigLst - list of all sdigits
+//            pDigLst  - list of 7 lists of digits        
+//   Returns: none  
+  
+  TClonesArray *pLst[7]; Int_t iCnt[7];
+  
+  for(Int_t i=0;i<7;i++){
+    pLst[i]=(TClonesArray*)(*pDigLst)[i];
+    iCnt[i]=pLst[i]->GetEntries();         //in principle those lists should be empty                                                                       
+  }
+  
+  pSdiLst->Sort();  
+                     
+  Int_t iPad=-1,iCh=-1,iNdigPad=-1,aTids[3]={-1,-1,-1}; Float_t q=-1;
+  for(Int_t i=0;i<pSdiLst->GetEntries();i++){                                                                  //sdigits loop (sorted)
+    AliRICHDigit *pSdig=(AliRICHDigit*)pSdiLst->At(i);                                                         //take current sdigit
+    if(pSdig->Pad()==iPad){                                                                                    //if the same pad 
+      q+=pSdig->Q();                                                                                           //sum up charge
+      iNdigPad++; if(iNdigPad<=3) aTids[iNdigPad-1]=pSdig->GetTrack(0);                                        //collect TID 
+      continue;
+    }
+    if(i!=0 && AliRICHDigit::IsOverTh(q))  new((*pLst[iCh])[iCnt[iCh]++]) AliRICHDigit(iPad,(Int_t)q,aTids);   //do not create digit for the very first sdigit 
+    iPad=pSdig->Pad(); iCh=AliRICHDigit::A2C(iPad);                                                            //new sdigit comes, reset collectors
+    iNdigPad=1;
+    aTids[0]=pSdig->GetTrack(0);aTids[1]=aTids[2]=-1; 
+    q=pSdig->Q();    
+  }//sdigits loop (sorted)
+  
+  if(AliRICHDigit::IsOverTh(q))  new((*pLst[iCh])[iCnt[iCh]++]) AliRICHDigit(iPad,(Int_t)q,aTids);             //add the last one, in case of empty sdigits list q=-1
+                                                                                                               //so digit is not created    
+}//Sdi2Dig()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index 8893185..70096b5 100644 (file)
@@ -6,6 +6,8 @@
 
 #include <AliDigitizer.h>
 class AliRunDigitizer;
+class TClonesArray;
+class TObjArray;
 
 class AliRICHDigitizer : public AliDigitizer //TObject-TNamed-TTask-AliDigitizer-AliRICHDigitizer
 {
@@ -14,6 +16,8 @@ public:
            AliRICHDigitizer(AliRunDigitizer *pRunDig):AliDigitizer(pRunDig)  {}
   virtual ~AliRICHDigitizer()                                                {}
   void     Exec(Option_t* option=0);                //virtual
+//   
+  static void    Sdi2Dig(TClonesArray *pSDigLst,TObjArray *pDigLst);
 protected:
   ClassDef(AliRICHDigitizer,0)
 };    
index 408b33a..2602a52 100644 (file)
@@ -3,41 +3,23 @@
 
 ClassImp(AliRICHHelix)
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-AliRICHHelix::AliRICHHelix(Double_t p,Double_t theta,Double_t phi,Double_t bz):TObject(),
-  fX0(TVector3(0,0,0)),
-  fP0(TVector3(0,0,0)),
-  fX(TVector3(0,0,0)),
-  fP(TVector3(0,0,0)),
-  fLen(0),
-  fQ(0),
-  fBz(bz),
-  fPosRad(TVector2(0,0)),
-  fPosPc(TVector2(0,0)),
-  fPloc(TVector3(0,0,0)) 
-{
-  fP0.SetMagThetaPhi(p,theta*TMath::DegToRad(),phi*TMath::DegToRad());     fP=fP0;
-}
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 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 
-  
+  TVector3 pos,mom;
   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());
+    Propagate(i,pos,mom);
+    pHelDraw->SetPoint(i,pos.X(),pos.Y(),pos.Z());
   }  
   pHelDraw->Draw();
 }
index 5288748..0139905 100644 (file)
 
 #include <TObject.h>              //base class
 #include <TVector3.h>             //used extensively
-#include "AliRICHParam.h"         //RichIntersect() 
 
 class AliRICHHelix: public TObject
 {
 public:
-  AliRICHHelix():TObject(),
-    fX0(TVector3(0,0,0)),
-    fP0(TVector3(0,0,0)),
-    fX(TVector3(0,0,0)),
-    fP(TVector3(0,0,0)),
-    fLen(0),
-    fQ(0),
-    fBz(0),
-    fPosRad(TVector2(0,0)),
-    fPosPc(TVector2(0,0)),
-    fPloc(TVector3(0,0,0))            {}
-  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),
-    fPosRad(TVector2(0,0)),
-    fPosPc(TVector2(0,0)),
-    fPloc(TVector3(0,0,0))            {}
+  AliRICHHelix(                                                            ):TObject(),fX0(TVector3(0,0,0)),fP0(TVector3(0,0,0)),fQ(0),fBz(0 )  {}
+  AliRICHHelix(const TVector3 &x0,const TVector3 &p0,Int_t q=1,Double_t b=2):TObject(),fX0(x0             ),fP0(p0             ),fQ(q),fBz(b )  {}
+  AliRICHHelix(Double_t p,Double_t theta,Double_t phi,Double_t bz=2        ):TObject(),fX0(TVector3(0,0,0)),fP0(TVector3(0,0,0)),fQ(0),fBz(bz)  
+                   {fP0.SetMagThetaPhi(p,theta*TMath::DegToRad(),phi*TMath::DegToRad());} //p [GeV], theta,phi [deg], Bz [Tesla];
   virtual ~AliRICHHelix()                                                                                                                   {}        
            
          void     Draw          (const Option_t *opt=""              );                              //from TObject, draw helix
-         void     Print         (const Option_t *opt=""              )const;                         //from TObject, print status
+         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;}
+  inline Bool_t   Intersect(            TVector3 &pnt,TVector3 &norm );          //intersection with plane given by point and normal vector
+  inline void     Propagate(Float_t len,TVector3 &x,  TVector3 &p    );          //propogate helix by given length along it            
 protected:
   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, [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]
+  Int_t    fQ;             //sign of track charge  
+  Float_t  fBz;            //magnetic field along z, [kGaus] 
   ClassDef(AliRICHHelix,0) //General helix
 };//class AliRICHHelix
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICHHelix::Propagate(Double_t len)
+void AliRICHHelix::Propagate(Float_t len,TVector3 &x,TVector3 &p)
 {
 // 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;   
+    x=fX0+fP0.Unit()*len;   
+    p=fP0;
   }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;
+    const Float_t c = 0.000299792458;//this speed of light value provides that coordinates are in [cm] momentum in [GeV/c] field in [kGaus]
+    Float_t a = -c*fBz*fQ;
+    Float_t rho = a/fP0.Mag();
+    x.SetX( fX0.X()+fP0.X()*TMath::Sin(rho*len)/a-fP0.Y()*(1-TMath::Cos(rho*len))/a  );
+    x.SetY( fX0.Y()+fP0.Y()*TMath::Sin(rho*len)/a+fP0.X()*(1-TMath::Cos(rho*len))/a  ); 
+    x.SetZ( fX0.Z()+fP0.Z()*len/fP0.Mag()                                            );
+    x.SetX( fP0.X()*TMath::Cos(rho*len)-fP0.Y()*TMath::Sin(rho*len)                  );
+    p.SetY( fP0.Y()*TMath::Cos(rho*len)+fP0.X()*TMath::Sin(rho*len)                  );
+    p.SetZ( fP0.Z()                                                                  );
   }
-}
+}//Propagate()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-Bool_t AliRICHHelix::Intersection(TVector3 planePoint,TVector3 planeNorm)
+Bool_t AliRICHHelix::Intersect(TVector3 &pnt,TVector3 &norm)
 {
 // 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
-
-  while(TMath::Abs(dist)>0.00001){
-    Propagate(s);                        //calculates helix at the distance s from x0 ALONG the helix
-    dist=(fX-planePoint)*planeNorm;      //distance between current helix position and plane
-    if(TMath::Abs(dist) >= TMath::Abs(distPrev)) { return kFALSE;}
+// Arguments: pnt  - arbitrary point of the plane, [cm] in MARS
+//            norm - vector, normal to the plane, [cm] in MARS
+//   Returns:      - kTrue if helix intersects the plane, kFALSE otherwise.
+//                 - pnt contains the point of intersection, [cm] in MARS  
+  TVector3 x,p;                                                    //current helix position and momentum
+  Double_t s=(pnt-fX0)*norm,dist=99999,distPrev=dist;              //estimates initial distance to plane
+  while(TMath::Abs(dist)>0.00001){                                 //loop while the distance is less then precision   
+    Propagate(s,x,p);                                              //calculates helix at the distance s from x0 ALONG the helix
+    dist=(x-pnt)*norm;                                             //distance between current helix position and plane
+    if(TMath::Abs(dist) >= TMath::Abs(distPrev)) { return kFALSE;} //if distance increases then no intersection 
     distPrev=dist;
     s-=dist;
-  }
+  }  
+  norm=p;
+  pnt=x;                                    
   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 radiator LORS (cm)    
-//         fPosPc  contains the same for photocathode  
-  for(Int_t iCh=1;iCh<=AliRICHParam::kNch;iCh++){//chambers loop
-    TVector3 norm =pParam->Lors2MarsVec(iCh,TVector3(0,0,1));
-    if(Intersection(pParam->Lors2Mars(iCh,0,0,AliRICHParam::kRad),norm)){//there is intersection with radiator plane
-      fPosRad=pParam->Mars2Lors(iCh,fX,AliRICHParam::kRad);//position on radiator plane
-      if(pParam->IsAccepted(fPosRad)){//intersection within radiator (even if in dead zone)
-        
-        if(Intersection(pParam->Lors2Mars(iCh,0,0,AliRICHParam::kPc),norm)){//there is intersection with photocathode
-          fPosPc=pParam->Mars2Lors(iCh,fX,AliRICHParam::kPc);//position on radiator plane
-          if(pParam->IsAccepted(fPosPc)){//intersection within pc (even if in dead zone)
-            
-            fPloc=pParam->Mars2LorsVec(iCh,fP);//trasform p to local system
-            return iCh;
-          }//if inside PC
-        }//if intersects PC
-        
-      }//if inside radiator
-    }//if for radiator       
-  }//chambers loop
-  return 0;
-}
+}//Intersect()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 #endif
index 2bd9c2b..b1b07b2 100644 (file)
 
 #include "AliRICHHit.h" //class header
 #include <TPDGCode.h>   //Print() 
+#include <TString.h>
  
 ClassImp(AliRICHHit)
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHHit::Print(Option_t*)const
 {
 //Print hit
-  char *sPart=Form("pid=%i",fPid);
-  switch(fPid){
+  char *sPart=Form("pid=%i",Pid());
+  switch(Pid()){
     case kProton:      sPart="p+  ";break;
-    case kProtonBar:   sPart="a-  ";break;
+    case kProtonBar:   sPart="p-  ";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 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);
+  Printf("%s Ch:%i TID:%6i,E:%9.3f eV, LORS:(%7.2f,%7.2f) MARS:(%7.2f,%7.2f,%7.2f)cm",sPart,Ch(),Tid(),E()*1e9,LorsX(),LorsY(),X(),Y(),Z());
 }
-//__________________________________________________________________________________________________
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index a75bb66..2ad6392 100644 (file)
@@ -3,49 +3,33 @@
 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
  * See cxx source for full Copyright notice                               */
 
-#include <AliHit.h>
-#include <TVector3.h>
+#include <AliHit.h>           //base class
+#include <TVector3.h>         //ctor
 
-//RICH hit container
-class AliRICHHit : public AliHit
+class AliRICHHit : public AliHit //   TObject-AliHit-AliRICHHit
 {
 public:
-  AliRICHHit():AliHit(),
-      fCham(-1) ,
-      fE(-1),
-      fPid(-1 ),
-      fInX3(TVector3(0,0,0)),
-      fOutX3(TVector3(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),
-      fInX3(TVector3(x,y,z)),
-      fOutX3(TVector3(x,y,z))  {fX=x;fY=y;fZ=z;}
-           
-  virtual ~AliRICHHit()                                                                                            {}
+  AliRICHHit(                                                                             ):AliHit(     ),fCh(-1),fPid(-1 ),fE(-1),fLorsX(-1),fLorsY(-1) {} //default ctor
+  AliRICHHit(Int_t c,Float_t e,Int_t pid,Int_t tid,Float_t xl,Float_t yl,const TVector3 &p):AliHit(0,tid),fCh(c ),fPid(pid),fE(e ),fLorsX(xl),fLorsY(yl) {fX=p.X();fY=p.Y();fZ=p.Z();}           
+  AliRICHHit(Int_t c,Float_t e,Int_t pid,Int_t tid,Float_t xl,Float_t yl                  ):              fCh(c ),fPid(pid),fE(e ),fLorsX(xl),fLorsY(yl) {fTrack=tid;}           
+  virtual ~AliRICHHit()                                                                                                {}
 //framework part
-  void     Print(Option_t *option="")const;                               //from TObject to print current status
+  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     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,3)                   //RICH hit class
+  Int_t   Ch    ()const{return fCh;                                    }       //Chamber
+  Float_t E     ()const{return fE;                                     }       //Eloss for MIP hit or Etot for photon hit, [GeV]
+  Float_t LorsX ()const{return fLorsX;                                 }       //hit X position in LORS, [cm]
+  Float_t LorsY ()const{return fLorsY;                                 }       //hit Y position in LORS, [cm]
+  Int_t   Pid   ()const{return fPid;                                   }       //PID
+  Int_t   Tid   ()const{return fTrack;                                 }       //TID
+         
+protected:                                                                     //AliHit has fTid,fX,fY,fZ 
+  Int_t    fCh;                                                                //Chamber
+  Int_t    fPid;                                                               //PID
+  Float_t  fE;                                                                 //Eloss for MIP or Etot for photon [GeV]
+  Float_t  fLorsX;                                                             //hit X position in chamber LORS, [cm]
+  Float_t  fLorsY;                                                             //hit Y position in chamber LORS, [cm]
+  ClassDef(AliRICHHit,4)                                                       //RICH hit class 
 };//class AliRICHhit
+    
 #endif
index 165709d..7b140ef 100644 (file)
 //  * about the suitability of this software for any purpose. It is          *
 //  * provided "as is" without express or implied warranty.                  *
 //  **************************************************************************
-#include "AliRICHParam.h" //class header
-#include "AliESD.h"
-#include <TCanvas.h>      //TestXXX() 
-#include <TLatex.h>
-#include <THStack.h>
-#include <TLegend.h>
-#include <TView.h>
-#include <TPolyMarker3D.h>
-#include <TPolyLine3D.h>
-#include <TPolyLine.h>
-#include <TSystem.h>
-#include <TVector2.h>
-#include <TVector3.h>
+#include "AliRICHParam.h"  //class header
+#include "AliRICHDigit.h"  //ctor
+#include <TCanvas.h>       //TestXXX() 
+#include <TLatex.h>        //TestTrans()  
+#include <TView.h>         //TestTrans()
+#include <TPolyMarker3D.h> //TestTrans()
 #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()
-#include <TLine.h>
-
-
 
 ClassImp(AliRICHParam)
-AliRICHParam * AliRICHParam::fgInstance             =0x0;     //singleton pointer               
+
+AliRICHParam* AliRICHParam::fgInstance=0x0;        //singleton pointer               
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 AliRICHParam::AliRICHParam():TNamed("RichParam","default version") 
 {
 // 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);
+  fX=0.5*AliRICHDigit::SizeAllX();
+  fY=0.5*AliRICHDigit::SizeAllY();
+  for(Int_t i=0;i<7;i++) fM[i]=(TGeoHMatrix*)gGeoManager->GetVolume("ALIC")->GetNode(Form("RICH_%i",i))->GetMatrix();
   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
-  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)                               
-  const Float_t kPn=kPressure/760.;
-  const Float_t kTn=kTemperature/273.16;
-  const Float_t kC0=-1.655279e-1;
-  const Float_t kC1= 6.307392e-2;
-  const Float_t kC2=-8.011441e-3;
-  const Float_t kC3= 3.392126e-4;
-               
-  Float_t crossSection=0;                        
-  if (eV<7.75) 
-    crossSection=0.06e-22;
-  else                 //------ METHANE CROSS SECTION cm-2 ASTROPH. J. 214, L47 (1978)                                               
-    crossSection=(kC0+kC1*eV+kC2*eV*eV+kC3*eV*eV*eV)*1.e-18;
-    
-    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(); 
-    if(!(AliCDBManager::Instance()->GetCacheFlag())) 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());
   
-  for(Int_t i=0;i<kNchambers;i++) fMatrix[i]->Print(opt);
+  for(Int_t i=0;i<7;i++) fM[i]->Print(opt);
 }//Print()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICHParam::TestSeg()
-{
-// Provides a set of pictures to test segementation currently in use.    
-// Arguments: none
-//   Returns: none    
-  new TCanvas("pads","View from electronics side, IP is behind the picture.");
-  gPad->Range(-5,-5,PcSizeX()+5,PcSizeY()+5);
-// list of corners:
-  DrawSectors(kTRUE);
-  TLatex t;
-  t.SetTextSize(0.02);  
-  t.SetTextColor(kRed)    ;t.SetTextAlign(11); t.DrawLatex(0         ,PcSizeY(),Form("Pad size %.2fx%.2fcm dead zone %.2fcm",PadSizeX(),PadSizeY(),DeadZone())); 
-  t.SetTextColor(kBlue)   ;t.SetTextAlign(21); t.DrawLatex(SecSizeX(),PcSizeY(),Form("Pc  size %.2fx%.2fcm %ix%i pads"      ,PcSizeX() ,PcSizeY() ,NpadsX()    ,NpadsY()));
-  t.SetTextColor(kMagenta);t.SetTextAlign(31); t.DrawLatex(PcSizeX() ,PcSizeY(),Form("Sec size %.2fx%.2fcm %ix%i pads"      ,SecSizeX(),SecSizeY(),NpadsXsec() ,NpadsYsec()));
-  
-
-//  TVector p(2);   TVector2 c;    TVector2 b;   //current: pad, pad center, pad boundary
-//  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();  
-  t.SetTextSize(0.015); t.SetTextColor(kBlue);
-
-//   b.Set(x0,y0);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x0,y1);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x0,y2);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x0,y3);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x0,y4);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x0,y5);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   
-//   b.Set(x1,y0);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x1,y1);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x1,y2);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x1,y3);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x1,y4);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x1,y5);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   
-//   b.Set(x2,y0);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x2,y1);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x2,y2);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x2,y3);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x2,y4);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x2,y5);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   
-//   b.Set(x3,y0);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x3,y1);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x3,y2);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x3,y3);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x3,y4);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-//   b.Set(x3,y5);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y()));
-
-//Now all chambers view    
-  TCanvas *pC=new TCanvas("cc","Chambers view from electronics side - IP is behind the picture"); pC->Divide(3,3);
-  t.SetTextSize(0.05);   
-  for(Int_t i=1;i<=7;i++){
-    if(i==1) pC->cd(9); if(i==2) pC->cd(8); if(i==3) pC->cd(6); if(i==4) pC->cd(5); if(i==5) pC->cd(4); if(i==6) pC->cd(2); if(i==7) pC->cd(1);   
-    gPad->Range(-5,-5,PcSizeX()+5,PcSizeY()+10); 
-    DrawSectors(kTRUE); 
-    t.SetTextColor(kBlack);   t.SetTextAlign(21); t.DrawText(SecSizeX(),PcSizeY(),Form("Cham %i",i)); 
-    t.SetTextColor(41);       t.SetTextAlign(11); t.DrawText(0         ,PcSizeY(),Form("DDL ID %i",1536+2*i-2)); //left half of chamber
-    t.SetTextColor(29);       t.SetTextAlign(31); t.DrawText(PcSizeX() ,PcSizeY(),Form("DDL ID %i",1536+2*i-1)); //right half of chamber
-  }
-}//TestSeg()
-//__________________________________________________________________________________________________
-void AliRICHParam::TestResp()
-{
-// 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);
-  
-  
-  const Int_t kNpoints=8;
-  THStack *pStackPhot=new THStack("StackPhot","photons");
-  THStack *pStackMip =new THStack("StackMip","mips");
-  TLegend *pLeg=new TLegend(0.6,0.2,0.9,0.5,"legend");    
-  TH1F *apHphot[kNpoints];
-  TH1F *apHmip[kNpoints];
-  
-  Double_t starty=0;
-  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-SecSizeY()/2));
-  }
-        
-  
-  TVector2 x2(0,0);  
-  for(Int_t i=0;i<10000;i++){//events loop
-    for(int j=0;j<kNpoints;j++){
-      x2.Set(10,starty+j*deltay);
-      apHphot[j]->Fill(TotQdc(x2,0));
-      apHmip[j]->Fill(TotQdc(x2,gRandom->Landau(600,150)*1e-9));
-    }
-  }
-  
-  pC->cd(1);  pStackMip->Draw("nostack");
-  pC->cd(2);  pStackPhot->Draw("nostack"); pLeg->Draw();
-}//TestResp()
-//__________________________________________________________________________________________________
-void AliRICHParam::TestTrans()
-{
-// Tests transformation methods
-// Arguments: none
-//   Returns: none    
-  
-  AliRICHParam *pParam=AliRICHParam::Instance();
-  Int_t iNpointsX=50,iNpointsY=50;  
-  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=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(iCham);
-    pChamber->Draw();  
-    helix.Draw();
-    t.SetNDC();t.SetTextColor(iCham); t.DrawText(0.1,iCham*0.1,Form("Chamber %i",iCham));    
-  }//chambers loop   
-}//TestTrans()
-//__________________________________________________________________________________________________
-void AliRICHParam::DrawAxis()
-{
-// 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();
-  TPolyLine3D *pZaxis=new TPolyLine3D(2,z);pZaxis->SetLineColor(kBlue);  pZaxis->Draw();  
-}
-//__________________________________________________________________________________________________
-void AliRICHParam::DrawSectors(Bool_t isInfo) 
-{ 
-// 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,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()};
-  
-  Int_t iColorLeft=29,iColorRight=41;
-  TPolyLine *sec[6];
-  
-  sec[0]= new TPolyLine(5,xLeft ,yDown);    
-  sec[1]= new TPolyLine(5,xRight,yDown);    
-  sec[2]= new TPolyLine(5,xLeft ,yCenter);  
-  sec[3]= new TPolyLine(5,xRight,yCenter);  
-  sec[4]= new TPolyLine(5,xLeft, yUp);      
-  sec[5]= new TPolyLine(5,xRight,yUp);      
-
-  for(Int_t iSec=0;iSec<6;iSec++){
-    if(isInfo){
-      (iSec%2)? sec[iSec]->SetFillColor(iColorLeft): sec[iSec]->SetFillColor(iColorRight);
-      sec[iSec]->Draw("f");
-    }else  
-      sec[iSec]->Draw();
-  }
-    
-  if(!isInfo) return;
-  
-  TText t; t.SetTextSize(0.02);
-  t.DrawText(32,20,"Sec 1");
-  t.DrawText(98,20,"Sec 2"); 
-  t.DrawText(32,65,"Sec 3");
-  t.DrawText(98,65,"Sec 4");
-  t.DrawText(32,106,"Sec 5");
-  t.DrawText(98,106,"Sec 6");
-  
-  Double_t x246=SecSizeX()+DeadZone();
-  Double_t y34=SecSizeY()+DeadZone();
-  Double_t y56=2*y34;
-  
-  for(Int_t iRow=1;iRow<=8;iRow++){//dilogic chip serves 8x6 pads
-    Double_t y=(iRow-1)*6*PadSizeY();
-    TLine *pL1=new TLine(0   ,y    ,SecSizeX(),y    ); pL1->Draw(); t.SetTextAlign(31); t.DrawText(0        ,y    ,Form("r%i",iRow)   );//sec1
-    TLine *pL2=new TLine(x246,y    ,PcSizeX() ,y    ); pL2->Draw(); t.SetTextAlign(11); t.DrawText(PcSizeX(),y    ,Form("r%i",25-iRow));//sec2
-    
-    TLine *pL3=new TLine(0   ,y+y34,SecSizeX(),y+y34); pL3->Draw(); t.SetTextAlign(31); t.DrawText(0        ,y+y34,Form("r%i",iRow+8) );//sec3
-    TLine *pL4=new TLine(x246,y+y34,PcSizeX() ,y+y34); pL4->Draw(); t.SetTextAlign(11); t.DrawText(PcSizeX(),y+y34,Form("r%i",17-iRow));//sec4
-    
-    TLine *pL5=new TLine(0   ,y+y56,SecSizeX(),y+y56); pL5->Draw(); t.SetTextAlign(31); t.DrawText(0        ,y+y56,Form("r%i",iRow+16));//sec5
-    TLine *pL6=new TLine(x246,y+y56,PcSizeX() ,y+y56); pL6->Draw(); t.SetTextAlign(11); t.DrawText(PcSizeX(),y+y56,Form("r%i",9-iRow) );//sec4
-  }  
-
-  for(Int_t iDilogic=1;iDilogic<=10;iDilogic++){
-    Double_t x=(iDilogic-1)*8*PadSizeX();
-    TLine *pL1=new TLine(x     ,0,x     ,SecSizeY()); pL1->Draw(); t.DrawText(x     ,0,Form("d%i",11-iDilogic));
-    TLine *pL2=new TLine(x+x246,0,x+x246,SecSizeY()); pL2->Draw(); t.DrawText(x+x246,0,Form("d%i",11-iDilogic));
-    
-    TLine *pL3=new TLine(x     ,y34,x     ,y34+SecSizeY()); pL3->Draw(); t.DrawText(x     ,y34,Form("d%i",11-iDilogic));
-    TLine *pL4=new TLine(x+x246,y34,x+x246,y34+SecSizeY()); pL4->Draw(); t.DrawText(x+x246,y34,Form("d%i",11-iDilogic));
-    
-    TLine *pL5=new TLine(x     ,y56,x     ,y56+SecSizeY()); pL5->Draw(); t.DrawText(x     ,y56,Form("d%i",11-iDilogic));
-    TLine *pL6=new TLine(x+x246,y56,x+x246,y56+SecSizeY()); pL6->Draw(); t.DrawText(x+x246,y56,Form("d%i",11-iDilogic));
-  }
-  
-  t.SetTextAlign(13); t.DrawText(0         ,0,"pad1");  t.DrawText(x246     ,0,"pad81");  
-  t.SetTextAlign(33); t.DrawText(SecSizeX(),0,"pad80"); t.DrawText(PcSizeX(),0,"pad160");  
-}//DrawSectors()
-//__________________________________________________________________________________________________
-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*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);
-  Double_t thetaout,phiout;
-  AnglesInDRS(vectorTrack.Theta(),vectorTrack.Phi(),thetaC,phiC,thetaout,phiout);
-  TVector3 vectorPhotonInC6F14;  
-  vectorPhotonInC6F14.SetMagThetaPhi(1,thetaout,phiout);
-  planeZposition=RadThick();
-  planePoint.SetXYZ(0,0,planeZposition);
-  TVector3 entranceToSiO2Point = PlaneIntersect(vectorPhotonInC6F14,emissionPoint,nPlane,planePoint);
-
-  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+=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(IdxSiO2(photonEn),IdxCH4(photonEn),vectorPhotonInSiO2.Theta());if(angleInCH4<0) return vBad;
-  TVector3 vectorPhotonInCH4;
-  vectorPhotonInCH4.SetMagThetaPhi(1,angleInCH4,phiout);
-//  planeZposition+=AliRICHParam::GapProx();
-  planeZposition+=Pc2Win();
-  planePoint.SetXYZ(0,0,planeZposition);
-  TVector3 impactToPC = PlaneIntersect(vectorPhotonInCH4,entranceToCH4,nPlane,planePoint);
-//  impactToPC.Dump();
-  return impactToPC;
-}//FowardTracing
-//__________________________________________________________________________________________________
-TVector3 AliRICHParam::PlaneIntersect(const TVector3 &lineDir,const TVector3 &linePoint,const TVector3 &planeNorm,const TVector3 &planePoint)
-{
-// 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)
-{
-// 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)
-{
-// Setup the rotation matrix of the track...
-
-  TRotation mtheta;
-  TRotation mphi;
-  TRotation minv;
-  TRotation mrot;
-  
-  mtheta.RotateY(trackTheta);
-  mphi.RotateZ(trackPhi);
-  
-  mrot = mphi * mtheta;
-    //  minv = mrot.Inverse();
-
-  TVector3 photonInRadiator(1,1,1);
-
-  photonInRadiator.SetTheta(thetaCerenkov);
-  photonInRadiator.SetPhi(phiCerenkov);
-  photonInRadiator = mrot * photonInRadiator;
-  tout=photonInRadiator.Theta();
-  pout=photonInRadiator.Phi();
-}//AnglesInDRS
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-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
index 3cab5b4..8af9dbb 100644 (file)
@@ -1,26 +1,10 @@
 #ifndef AliRICHParam_h
 #define AliRICHParam_h
 
-#include <TNamed.h>       //base class
-#include <TMath.h>        //QdcTot()  
-#include <TVector.h>      //old style
-#include <TVector2.h>
-#include <TVector3.h>
-#include <Riostream.h>     //---------to be deleted-------------
-#include <TRandom.h>
-#include <TClonesArray.h>  //Hit2SDigs()
-#include <AliLog.h>
-#include <TGeoMatrix.h>    //Mars2Lors() Lors2Mars() 
-#include <TF1.h>           //fields
-#include <TF2.h>           //fields
-#include "AliRICHDigit.h"  //Hit2Sdigs()
+#include <TNamed.h>        //base class
 #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
-static const int kNpadsY = 144;    //number of pads along Y in single chamber
-static const int kNsectors=6;      //number of sectors per chamber
-
+#include <TVector3.h>      //Lors2Mars() Mars2Lors()
 static const int kCerenkov=50000050;  //??? go to something more general like TPDGCode
 static const int kFeedback=50000051;  //??? go to something more general like TPDGCode
 
@@ -28,672 +12,46 @@ static const int kFeedback=50000051;  //??? go to something more general like TP
 // 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 TNamed  
 {
 public:
 //ctor&dtor    
-  virtual        ~AliRICHParam()                                    {delete fIdxC6F14;fgInstance=0;}
-//test methodes  
+  virtual        ~AliRICHParam()                                    {for(Int_t i=0;i<7;i++) delete fM[i]; delete fgInstance; fgInstance=0;}
          void     Print(Option_t *opt="") const;                                         //print current parametrization
-  static void     DrawAxis();
-  static void     DrawSectors(Bool_t isInfo=kFALSE);                     //draw sectors contour and print on top some info
-//flags staff         
   static inline AliRICHParam* Instance();                                //pointer to AliRICHParam singleton
+  
+                Double_t   MeanIdxRad              () {return 1.29204;}//???????????
+                Double_t   MeanIdxWin              () {return 1.57819;}//???????????
   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 Double_t   SigmaSinglePhotonFormula(Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta);
-//Geometrical properties  
-  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 TVector3   Lors2MarsVec  (Int_t c,const TVector3 &p                ); //LORS->MARS transform of vector for chamber c
-         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    
-         inline TVector3   Mars2LorsVec  (Int_t c,const TVector3 &p                ); //MARS->LORS transform of vector for chamber c
-  
-  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   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 
-  static        Int_t      Pad2PadY      (Int_t pad                      ){return pad%1000000%100;                   }//abs pad -> pad y
-  static        Int_t      PadAbs        (Int_t c,Int_t s,Int_t x,Int_t y){return 100000000*c+1000000*s+1000*x+y;    }//(c,s,x,y) -> abs pad
-  static inline TVector2   Pad2Loc       (Int_t pad                      );                                           //abs pad ->LORS
-  static inline TVector2   Pad2Loc       (TVector pad                    );                                           //pad  -> LORS returns center of the pad
-  static        TVector2   Pad2Loc       (Int_t x,Int_t y                ){TVector pad(2);pad[0]=x;pad[1]=y;return Pad2Loc(pad);}//return center of the pad (x,y)
-  static inline TVector    Loc2Area      (const TVector2 &x2             );                                           //pads area affected by hit x2. area is LeftDown-RightUp pad numbers
-  static inline Int_t      Loc2Sec       (const TVector2 &x2             );                                           //LORS -> sector
-  static        Int_t      Loc2Sec       (Double_t x,Double_t y          ){return Loc2Sec(TVector2(x,y));}            //LORS -> sector
-  static inline TVector    Loc2Pad       (const TVector2 &x2             );                                           //LORS -> pad
-  static        TVector    Loc2Pad       (Double_t x,Double_t y          ){return Loc2Pad(TVector2(x,y));}            //LORS -> pad
-  static inline Int_t      Pad2Sec       (const TVector &pad             );                                           //pad  -> sector
-  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        Float_t    EckovMean     (                               ){return 6.766e-9;}                          //mean Ckov energy according to the total trasmission curve
-  static        Float_t    EckovMin      (                               ){return 5.5e-9;}                            //min photon energy [GeV] defined in optical curves
-  static        Float_t    EckovMax      (                               ){return 8.5e-9;}                            //min photon energy [GeV] defined in optical curves
-  
-                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 TMath::Sqrt(1+46.411/(10.666*10.666-gev*gev*1e18)+228.71/(18.125*18.125-gev*gev*1e18));} //n=f(Eckov) [GeV] for SiO2 used as window TDR p.35
-  static        Float_t    IdxCH4        (Float_t gev                    ){return 1+0.12489e-6/(2.62e-4 - TMath::Power(1239.84e-9/gev,-2));}              //n=f(Eckov) [GeV] for CF4 
-  static        Float_t    AbsCH4        (Float_t gev                    );                                                                          //abs len=f(Eckov) [GeV] for CF4 
-  
-                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;}
-  static Int_t    HV(Int_t sector)           {if (sector>=1 && sector <=6) return 2050;  else return -1;} //high voltage for this sector
-//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 Gain(const TVector2 &x2,Bool_t isSag=kTRUE){//gives chamber gain in terms of QDC channels for given point in local ref system
-                          if(isSag) 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 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,Bool_t isSag=kTRUE                 ){return isSag?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 4;}                        //
-         static Float_t  SigmaThMean()                 {return 1.132;}                    //QDC electronic noise mean
-         static Float_t  SigmaThSpread()               {return 0.035;}                    //QDC electronic noise width
-                
-         static Double_t CogCorr(Double_t x) {return 3.31267e-2*TMath::Sin(2*TMath::Pi()/PadSizeX()*x) //correction of cluster CoG due to sinoidal
-                                                    -2.66575e-3*TMath::Sin(4*TMath::Pi()/PadSizeX()*x)
-                                                    +2.80553e-3*TMath::Sin(6*TMath::Pi()/PadSizeX()*x)+0.0070;}
-       
-         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
-
-  enum EPlaneId {kCenter,kPc,kRad,kAnod,kNch=7};            //4 planes in chamber and total number of chambers
+  void     Lors2Mars   (Int_t c,Float_t x,Float_t y,Double_t *m,Int_t pl=kPc)const{Double_t z=0; switch(pl){case kPc:z=8.0;break; case kAnod:z=7.806;break; case kRad:z=-1.25; break;}   Double_t l[3]={x-fX,y-fY,z};  fM[c]->LocalToMaster(l,m); }    
+  TVector3 Lors2Mars   (Int_t c,Float_t x,Float_t y,            Int_t pl=kPc)const{Double_t m[3];Lors2Mars(c,x,y,m,pl); return TVector3(m);    }//MRS->LRS  
+  void     Mars2Lors   (Int_t c,Double_t *m,Float_t &x,Float_t &y           )const{Double_t l[3];fM[c]->MasterToLocal(m,l);x=l[0]+fX;y=l[1]+fY;}//MRS->LRS
+  void     Mars2LorsVec(Int_t c,Double_t *m,Float_t &th,Float_t &ph         )const{Double_t l[3]; fM[c]->MasterToLocalVect(m,l); Float_t pt=TMath::Sqrt(l[0]*l[0]+l[1]*l[1]); th=TMath::ATan(l[3]/pt); ph=TMath::ATan(l[0]/pt);}    
+  TVector3 Norm        (Int_t c                                             )const{Double_t n[3]; Norm(c,n); return TVector3(n);               }//norm 
+  void     Norm        (Int_t c,Double_t *n                                 )const{Double_t l[3]={0,0,1};fM[c]->LocalToMasterVect(l,n);        }//norm
+
+  enum EPlaneId {kPc,kRad,kAnod};            //3 planes in chamber 
 protected:
          AliRICHParam();             //default ctor is protected to enforce it to be singleton
   static AliRICHParam *fgInstance;   //static pointer  to instance of AliRICHParam singleton
-  TF2         *fIdxC6F14;            //n=f(Ephot,T) [GeV] for radiator freon   C6F14
-  TGeoHMatrix *fMatrix[kNchambers];  //poiners to matrices defining RICH chambers rotations-translations
+  TGeoHMatrix *fM[7];                //poiners to matrices defining RICH chambers rotations-translations
+  Float_t fX;                        //x shift of LORS with respect to rotated MARS 
+  Float_t fY;                        //y shift of LORS with respect to rotated MARS   
   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");
+  if(!fgInstance)
+    if(gGeoManager) new AliRICHParam; 
+    else            Printf("AliRICHParam> Error:: No geometry defined!");
   return fgInstance;  
 }//Instance()    
-//__________________________________________________________________________________________________
-Int_t AliRICHParam::PadNeighbours(Int_t iPadX,Int_t iPadY,Int_t listX[4],Int_t listY[4])
-{
-//Determines all the neighbouring pads for the given one (iPadX,iPadY). Returns total number of these pads.
-//Dead zones are taken into account, meaning pads from different sector are not taken. 
-//   1  
-// 2   3
-//   4     
-  Int_t nPads=0;
-  if(iPadY!=NpadsY()&&iPadY!=2*NpadsYsec()&&iPadY!=NpadsYsec()){listX[nPads]=iPadX;   listY[nPads]=iPadY+1; nPads++;}       //1
-  if(iPadX!=1&&iPadX!=NpadsXsec()+1)                           {listX[nPads]=iPadX-1; listY[nPads]=iPadY;   nPads++;}       //2
-  if(iPadX!=NpadsXsec()&&iPadX!=NpadsX())                      {listX[nPads]=iPadX+1; listY[nPads]=iPadY;   nPads++;}       //3
-  if(iPadY!=1&&iPadY!=NpadsYsec()+1&&2*NpadsYsec()+1)          {listX[nPads]=iPadX;   listY[nPads]=iPadY-1; nPads++;}       //4
-
-  return nPads;
-}//Pad2ClosePads()
-//__________________________________________________________________________________________________
-Int_t AliRICHParam::Loc2Sec(const TVector2 &v2)
-{
-// 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;
-  else if(v2.X() >= x2 && v2.X() <= x3 )  sector=2;
-  else                                    return -1;
-  
-  if     (v2.Y() >= y0 && v2.Y() <= y1 )  ;                    //sectors 1 or 2 
-  else if(v2.Y() >= y2 && v2.Y() <= y3 )  sector+=2;           //sectors 3 or 4
-  else if(v2.Y() >= y4 && v2.Y() <= y5 )  sector+=4;           //sectors 5 or 6
-  else                                    return -1;
-  return sector;
-}//Loc2Sec(Double_t x, Double_t y)
-//__________________________________________________________________________________________________
-TVector AliRICHParam::Loc2Pad(const TVector2 &loc)
-{
-//Determines pad number TVector(padx,pady) containing the given point x2 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  
-  TVector pad(2);
-  Int_t sec=Loc2Sec(loc);//trasforms x2 to sector reference system
-  if(sec==-1) {pad[0]=pad[1]=-1; return pad;}
-//first we deal with x  
-  if(sec==1||sec==3||sec==5)    pad[0]=           Int_t(            loc.X()   / PadSizeX() )+1; //sector 1 or 3 or 5
-  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()-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.
-  Int_t sector=-1;      
-  if     (pad[0] >= 1           && pad[0] <=   NpadsXsec() )    {sector=1;}
-  else if(pad[0] >  NpadsXsec() && pad[0] <=   NpadsX()    )    {sector=2;} 
-  else                                                         AliDebugClass(1,Form("Wrong pad (%3.0f,%3.0f)",pad[0],pad[1]));
-    
-  if     (pad[1] >= 1             && pad[1] <=   NpadsYsec() )    {}
-  else if(pad[1] >  NpadsYsec()   && pad[1] <= 2*NpadsYsec() )    {sector+=2;}
-  else if(pad[1] >  2*NpadsYsec() && pad[1] <=   NpadsY()    )    {sector+=4;}
-  else                                                         AliDebugClass(1,Form("Wrong pad (%3.0f,%3.0f)",pad[0],pad[1]));
-
-  return sector;
-}//Pad2Sec()
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-TVector2 AliRICHParam::Pad2Loc(TVector pad)
-{
-//Returns position of the center of the given pad in local system of the chamber (cm)    
-// y ^  5 6
-//   |  3 4        sector numbers
-//   |  1 2
-//    -------> x  
-  Double_t x=-1,y=-1;
-  if(pad[0] > 0 && pad[0] <= NpadsXsec())//it's 1 or 3 or 5
-    x=(pad[0]-0.5)*PadSizeX();
-  else if(pad[0] > NpadsXsec() && pad[0] <= NpadsX())//it's 2 or 4 or 6
-    x=(pad[0]-0.5)*PadSizeX()+DeadZone();
-  else
-    AliDebugClass(1,Form("Wrong pad (%3.0f,%3.0f)",pad[0],pad[1]));
-  
-  if(pad[1] > 0 && pad[1] <= NpadsYsec())//it's 1 or 2
-    y=(pad[1]-0.5)*PadSizeY();
-  else if(pad[1] > NpadsYsec() && pad[1] <= 2*NpadsYsec())//it's 3 or 4
-    y=(pad[1]-0.5)*PadSizeY()+DeadZone();
-  else if(pad[1] > 2*NpadsYsec() && pad[1]<= NpadsY())//it's 5 or 6
-    y=(pad[1]-0.5)*PadSizeY()+2*DeadZone();
-  else
-    AliDebugClass(1,Form("Wrong pad (%3.0f,%3.0f)",pad[0],pad[1]));
-    
-  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  
-  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-=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;
-    case 2050: return 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 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;
-  }
-}
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-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()+1e-6);//1e-6 is a protection against 0 from 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).
-//Returns this change parametrised in QDC channels, or 0 if the hit in the dead zone.
-//eloss=0 means photon which produces 1 electron only eloss > 0 for Mip
-  if(Loc2Sec(x2)==-1) return 0; //hit in the dead zone     
-  Int_t iNelectrons=Int_t(eloss/IonisationPotential()); if(iNelectrons==0) iNelectrons=1;
-  Double_t qdc=0;
-  for(Int_t i=1;i<=iNelectrons;i++) qdc+=-Gain(x2)*TMath::Log(gRandom->Rndm()+1e-06);//ie-06 is a protection against 0 from 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.
-//Integrated Mathieson distribution is used.  
-  TVector2 center2=Pad2Loc(pad);//gives center of requested pad
-  Double_t normXmin=(x2.X()-center2.X()-PadSizeX()/2)  /Pc2Cath();//parametrise for Mathienson
-  Double_t normXmax=(x2.X()-center2.X()+PadSizeX()/2)  /Pc2Cath();
-  Double_t normYmin=(x2.Y()-center2.Y()-PadSizeY()/2)  /Pc2Cath();
-  Double_t normYmax=(x2.Y()-center2.Y()+PadSizeY()/2)  /Pc2Cath();
-//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 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;
-
-  Double_t ux1=kSqrtKx3*TMath::TanH(kX2*x1);
-  Double_t ux2=kSqrtKx3*TMath::TanH(kX2*x2);
-  Double_t uy1=kSqrtKy3*TMath::TanH(kY2*y1);
-  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.
-  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  
-  if(pad[0]!=1           && pad[0]!= NpadsXsec()+1                            ) area[0]--; //left down coner X
-  if(pad[1]!=1           && pad[1]!= NpadsYsec()+1 && pad[1]!= 2*NpadsYsec()+1) area[1]--; //left down coner Y 
-  if(pad[0]!=NpadsXsec() && pad[0]!= NpadsX()                                 ) area[2]++; //right up coner X
-  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 qdc)
-{
-// 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);
-}    
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-TVector3  AliRICHParam::Lors2MarsVec(Int_t iCh,const TVector3 &p)
-{
-  Double_t mars[3], lors[3]; p.GetXYZ(lors);  
-  fMatrix[iCh-1]->LocalToMasterVect(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::Mars2LorsVec(Int_t iCh,const TVector3 &p)
-{
-  Double_t mars[3], lors[3]; p.GetXYZ(mars);  
-  fMatrix[iCh-1]->MasterToLocalVect(mars,lors);
-  return TVector3(lors);
-}    
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-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::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
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-Double_t AliRICHParam::SigmaSinglePhotonFormula(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM)
-{
-// Analithical calculation of total error (as a sum of localization, geometrical and chromatic errors) on Cerenkov angle for a given Cerenkov photon 
-// created by a given MIP. Fromulae according to CERN-EP-2000-058 
-// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
-//            dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]        
-//            MIP beta
-//   Returns: absolute error on Cerenkov angle, [radians]    
-  
-  TVector3 v(-999,-999,-999);
-
-  v.SetX(ErrLoc (thetaC,phiC,thetaM,phiM,betaM));
-  v.SetY(ErrGeom(thetaC,phiC,thetaM,phiM,betaM));
-  v.SetZ(ErrCrom(thetaC,phiC,thetaM,phiM,betaM));
-
-  return v.Mag2();
-}
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-Double_t AliRICHParam::ErrLoc(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM)
-{
-// Analithical calculation of localization error (due to finite segmentation of PC) on Cerenkov angle for a given Cerenkov photon 
-// created by a given MIP. Fromulae according to CERN-EP-2000-058 
-// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
-//            dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]        
-//            MIP beta
-//   Returns: absolute error on Cerenkov angle, [radians]    
-  Double_t refC6F14m = 1.29337;
-  Double_t phiDelta = phiC - phiM;
-
-  Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM);
-  Double_t k = 1.-refC6F14m*refC6F14m+alpha*alpha/(betaM*betaM);
-  if (k<0) return 1e10;
-
-  Double_t mu =TMath::Sin(thetaM)*TMath::Sin(phiM)+TMath::Tan(thetaC)*(TMath::Cos(thetaM)*TMath::Cos(phiDelta)*TMath::Sin(phiM)+TMath::Sin(phiDelta)*TMath::Cos(phiM));
-  Double_t e  =TMath::Sin(thetaM)*TMath::Cos(phiM)+TMath::Tan(thetaC)*(TMath::Cos(thetaM)*TMath::Cos(phiDelta)*TMath::Cos(phiM)-TMath::Sin(phiDelta)*TMath::Sin(phiM));
-
-  Double_t kk = betaM*TMath::Sqrt(k)/(Pc2Win()*alpha);
-  Double_t dtdxc = kk*(k*(TMath::Cos(phiDelta)*TMath::Cos(phiM)-TMath::Cos(thetaM)*TMath::Sin(phiDelta)*TMath::Sin(phiM))-(alpha*mu/(betaM*betaM))*TMath::Sin(thetaM)*TMath::Sin(phiDelta));
-  Double_t dtdyc = kk*(k*(TMath::Cos(phiDelta)*TMath::Sin(phiM)+TMath::Cos(thetaM)*TMath::Sin(phiDelta)*TMath::Cos(phiM))+(alpha* e/(betaM*betaM))*TMath::Sin(thetaM)*TMath::Sin(phiDelta));
-
-  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 thetaM, Double_t phiM, Double_t betaM)
-{
-// Analithical calculation of chromatic error (due to lack of knowledge of Cerenkov photon energy) on Cerenkov angle for a given Cerenkov photon 
-// created by a given MIP. Fromulae according to CERN-EP-2000-058 
-// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
-//            dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]        
-//            MIP beta
-//   Returns: absolute error on Cerenkov angle, [radians]    
-  Double_t phiDelta = phiC - phiM;
-  Double_t refC6F14m = 1.29337;
-  Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM);
-
-  //cout << "alpha : "<<alpha<<"         thetaC : "<<thetaC<<endl;
-  Double_t dtdn = TMath::Cos(thetaM)*refC6F14m*betaM*betaM/(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 thetaM, Double_t phiM, Double_t betaM)
-{
-// Analithical calculation of geometric error (due to lack of knowledge of creation point in radiator) on Cerenkov angle for a given Cerenkov photon 
-// created by a given MIP. Fromulae according to CERN-EP-2000-058 
-// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
-//            dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]        
-//            MIP beta
-//   Returns: absolute error on Cerenkov angle, [radians]    
-
-  Double_t phiDelta = phiC - phiM;
-  Double_t refC6F14m = 1.29337;
-  Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM);
-
-  Double_t k = 1.-refC6F14m*refC6F14m+alpha*alpha/(betaM*betaM);
-  if (k<0) return 1e10;
-
-  Double_t eTr = 0.5*RadThick()*betaM*TMath::Sqrt(k)/(Pc2Win()*alpha);
-  Double_t lambda = 1.-TMath::Sin(thetaM)*TMath::Sin(thetaM)*TMath::Sin(phiC)*TMath::Sin(phiC);
-
-  Double_t c = 1./(1.+ eTr*k/(alpha*alpha*TMath::Cos(thetaC)*TMath::Cos(thetaC)));
-  Double_t i = betaM*TMath::Tan(thetaC)*lambda*TMath::Power(k,1.5);
-  Double_t ii = 1.+eTr*betaM*i;
-
-  Double_t err = c * (i/(alpha*alpha*Pc2Win()) +  ii*(1.-lambda) / ( alpha*alpha*Pc2Win()*betaM*(1.+eTr)) );
-  Double_t trErr = RadThick()/(TMath::Sqrt(12.)*TMath::Cos(thetaM));
-
-  return trErr*err;
-}//ErrGeom()
 
-#endif //AliRICHParam_h
+#endif
index 410b250..023de2b 100644 (file)
 //////////////////////////////////////////////////////////////////////////
 
 #include "AliRICHRecon.h"  //class header
-#include <TMath.h>
-#include <TRotation.h>
-#include <TVector3.h>
-#include <TH1F.h>
+#include "AliRICHCluster.h" //CkovAngle()
+#include <AliLog.h>        //AliInfo()
+#include <TMath.h>         //many 
+#include <TRotation.h>      //
+#include <TH1D.h>          //HoughResponse()
+#include <TClonesArray.h>  //CkovAngle()
 
-#include "AliRICHCluster.h" //ThetaCerenkov()
-#include "AliRICHParam.h"
-#include "AliRICHHelix.h"   //ThetaCerenkov()
-#include <AliLog.h>
+const Double_t AliRICHRecon::fkRadThick=1.5;
+const Double_t AliRICHRecon::fkWinThick=0.5;
+const Double_t AliRICHRecon::fkGapThick=8.0;
+const Double_t AliRICHRecon::fkRadIdx  =1.292;
+const Double_t AliRICHRecon::fkWinIdx  =1.5787;
+const Double_t AliRICHRecon::fkGapIdx  =1.0005;
 
-#define NPointsOfRing 201
 
-//__________________________________________________________________________________________________
-AliRICHRecon::AliRICHRecon():
-  TTask       ("RichRec","RichPat"),
-  fPhotonsNumber(0),
-  fPhotonIndex(0), // should we use -1?
-  fFittedHoughPhotons(0),
-  fMinNumPhots(3),
-  fTrackTheta(0),
-  fTrackPhi(0),
-  fMinDist(999),
-  fTrackBeta(0),
-  fXtoentr(999),
-  fYtoentr(999),
-  fThetaPhotonInTRS(0),
-  fPhiPhotonInTRS(0),
-  fThetaPhotonInDRS(0),
-  fPhiPhotonInDRS(0),
-  fThetaAtQuartz(0),
-  fXEmiss(-999),
-  fYEmiss(-999),
-  fXInner(-999),
-  fYInner(-999),
-  fXOuter(-999),
-  fYOuter(-999),
-  fInnerRadius(-999),
-  fOuterRadius(-999),
-  fEphot(0),
-  fLengthEmissionPoint(0),
-  fPhotonLimitX(999),
-  fPhotonLimitY(999),
-  fDistanceFromCluster(999),
-  fCerenkovAnglePad(999),
-  fThetaPhotonCerenkov(0),
-  fShiftX(0),
-  fShiftY(0),
-  fXcoord(999),
-  fYcoord(999),
-  fIntersectionX(999),
-  fIntersectionY(999),
-  fMassHypotesis(0.139567),
-  fThetaOfRing(0),
-  fAreaOfRing(0),
-  fPortionOfRing(0),
-  fHoughArea(0),
-  fHoughRMS(999),
-  fFittedTrackTheta(0),
-  fFittedTrackPhi(0),
-  fFittedThetaCerenkov(0),
-  fThetaMin(0.0),
-  fThetaMax(0.75),
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+AliRICHRecon::AliRICHRecon():TTask("RichRec","RichPat"),
+  fPhotCnt(-1),
+  fCkovSigma2(0),
   fIsWEIGHT(kFALSE),
-  fIsBACKGROUND(kFALSE),
   fDTheta(0.001),
   fWindowWidth(0.045),
-  fNumEtaPhotons(0),
-  fnPhotBKG(0),
-  fThetaCerenkov(0),
-  fWeightThetaCerenkov(0),
-  fThetaPeakPos(0),
-  fRingSigma2(0)
+  fTrkDir(TVector3(0,0,1)),fTrkPos(TVector2(30,40))  
 {
 // main ctor
   for (Int_t i=0; i<3000; i++) {
-    fPhotonFlag[i] = 0;
-    fPhiPoint[i] = -999;
-    fPhotonEta[i] = -999;
-    fPhotonWeight[i] = 0.0;
-    fEtaFlag[i] = 0;
-    fEtaPhotons[i] = 0;
-    fWeightPhotons[i] = 0;
+    fPhotFlag[i] =  0;
+    fPhotCkov[i] = -1;
+    fPhotPhi [i] = -1;
+    fPhotWei [i] =  0;
   }
 }
-//__________________________________________________________________________________________________
-Double_t AliRICHRecon::ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t &nphot)
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::CkovAngle(TClonesArray *pCluLst,Int_t &iNaccepted)
 {
 // 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 is the 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());
-  if(pClusters->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction
-  else                            fIsWEIGHT = kFALSE;
-
-
-
-  SetThetaCerenkov(-1);   
-
-  //
-  // Photon Flag:  Flag = 0 initial set; Flag = 1 good candidate (charge compatible with photon); Flag = 2 photon used for the ring;
-  //
+// Arguments: pCluLst  - list of clusters for this chamber   
+//   Returns:          - track ckov angle, [rad], 
   
-  for (Int_t iClu=0; iClu<pClusters->GetEntriesFast();iClu++){//clusters loop
-    if(iClu == nphot) continue; // do not consider MIP cluster as a photon candidate
-    SetPhotonIndex(iClu);
-    SetPhotonFlag(0);
-    SetPhotonEta(-999.);
-    SetPhotonWeight(0.);
-    AliRICHCluster *pClu=(AliRICHCluster*)pClusters->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();
-    SetPhotonFlag(1); 
-    FindThetaPhotonCerenkov();
-    Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov();
-    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);
-  }//clusters loop
+  if(pCluLst->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction
+  else                          fIsWEIGHT = kFALSE;
 
-  SetPhotonsNumber(pClusters->GetEntries());
-
-  if((nphot=FlagPhotons(HoughResponse()))<1) return -11; //flag photons according to individual theta ckov with respect to most probable track theta ckov
-
-
-//  Float_t thetaCerenkov = GetThetaCerenkov();  
-//  SetThetaOfRing(thetaCerenkov);
-//  FindAreaAndPortionOfRing();
-
-//  Float_t nPhotonHoughNorm = ((Float_t)nPhotonHough)/GetPortionOfRing();
-//  SetHoughPhotonsNorm(nPhotonHoughNorm);
-
-  // Calculate the area where the photon are accepted...
-/*
-  Float_t thetaInternal = thetaCerenkov - 0.5*fWindowWidth; 
-  SetThetaOfRing(thetaInternal);
-  FindAreaAndPortionOfRing();
-  Float_t internalArea = GetAreaOfRing();
-
-  Float_t thetaExternal = thetaCerenkov + 0.5*fWindowWidth; 
-  SetThetaOfRing(thetaExternal);
-  FindAreaAndPortionOfRing();
-  Float_t externalArea = GetAreaOfRing();
+  // Photon Flag:  Flag = 0 initial set; Flag = 1 good candidate (charge compatible with photon); Flag = 2 photon used for the ring;
 
-  Float_t houghArea = externalArea - internalArea;
+  fPhotCnt=0;                                                      
+  for (Int_t iClu=0; iClu<pCluLst->GetEntriesFast();iClu++){//clusters loop
+    AliRICHCluster *pClu=(AliRICHCluster*)pCluLst->UncheckedAt(iClu);                       //get pointer to current cluster    
+    if(pClu->Q()>100) continue;                                                             //avoid MIP clusters from bkg
+    
+    fPhotCkov[fPhotCnt]=FindPhotCkov(pClu->X(),pClu->Y());                                  //find ckov angle for this  photon candidate
+    fPhotCnt++;         //increment counter of photon candidates
+  }//clusters loop
 
-  SetHoughArea(houghArea);
-*/
-  FindThetaCerenkov(pClusters->GetEntries());
-  return GetThetaCerenkov();
+  iNaccepted=FlagPhot(HoughResponse()); //flag photons according to individual theta ckov with respect to most probable track theta ckov
+  if(iNaccepted<1) return -11; 
+  else             return FindRingCkov(pCluLst->GetEntries());  //find best Theta ckov for ring i.e. track
 }//ThetaCerenkov()
-//__________________________________________________________________________________________________
-Int_t AliRICHRecon::PhotonInBand()
-{
-// Define valid band for photon candidates. For that photons with ThetaMin and ThetaMax are traced up to photcathode
-
-  Float_t nfreon;
-
-  Float_t thetacer;
-
-  Float_t xtoentr = GetEntranceX();
-  Float_t ytoentr = GetEntranceY();
-
-  Float_t innerRadius;
-  Float_t outerRadius;
-
-  Float_t phpad = GetPhiPoint();
-
-
-  // inner radius //
-  SetEmissionPoint(AliRICHParam::RadThick() -0.0001);
-
-  nfreon = AliRICHParam::Instance()->IdxC6F14(AliRICHParam::Instance()->EckovMin());
-  thetacer = 0.;
-
-  AliDebug(1,Form("thetacer in photoninband min %f",thetacer));
-
-  FindThetaAtQuartz(thetacer);
-
-  if(thetacer == 999. || GetThetaAtQuartz() == 999.) {
-      innerRadius = -999.;
-      SetXInnerRing(-999.);
-      SetYInnerRing(-999.);
-      SetRadiusInnerRing(-999.);
-    }
-  else
-    {
-      SetThetaPhotonInDRS(GetThetaAtQuartz());
-      SetPhiPhotonInDRS(phpad);
-
-      innerRadius = FromEmissionToCathode();
-       if(innerRadius == 999.) innerRadius = -999.;
-      
-      SetXInnerRing(GetXPointOnCathode());
-      SetYInnerRing(GetYPointOnCathode());
-      SetRadiusInnerRing(innerRadius);
-    }
-  
-  // outer radius //
-  SetEmissionPoint(0.);
-//  SetMassHypotesis(0.139567);
-
-  nfreon = AliRICHParam::Instance()->IdxC6F14(AliRICHParam::Instance()->EckovMax());
-
-  thetacer = Cerenkovangle(nfreon,1);
-
-  //  thetacer = 0.75;
-
-  AliDebug(1,Form("thetacer in photoninband max %f",thetacer));
-
-  FindThetaAtQuartz(thetacer);
-
-  if(thetacer == 999. || GetThetaAtQuartz() == 999.)
-    {
-      outerRadius = 999.;
-      SetXOuterRing(999.);
-      SetYOuterRing(999.);
-      SetRadiusOuterRing(999.);
-    }
-  else
-    {
-      SetThetaPhotonInDRS(GetThetaAtQuartz());
-      SetPhiPhotonInDRS(phpad);
-
-      outerRadius = FromEmissionToCathode();
-//      cout << " outerRadius " << outerRadius << endl;
-      SetXOuterRing(GetXPointOnCathode());
-      SetYOuterRing(GetYPointOnCathode());
-      SetRadiusOuterRing(outerRadius);
-    }
-
-  Float_t padradius = sqrt(TMath::Power(xtoentr,2)+TMath::Power(ytoentr,2));
-  
-  AliDebug(1,Form("rmin %f r %f rmax %f",innerRadius,padradius,outerRadius));
-
-  if(padradius>=innerRadius && padradius<=outerRadius) return 1;
-  return 0;
-}//PhotonInBand()
-//__________________________________________________________________________________________________
-void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov)
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::FindPhotCkov(Double_t cluX,Double_t cluY)
 {
-// find the theta at the quartz plate
-
-  if(thetaCerenkov == 999.) { SetThetaAtQuartz(999.); return; }
-
-  Float_t thetaAtQuartz = 999.;
-
-  Float_t trackTheta = GetTrackTheta();
-
-  if(trackTheta == 0) {
-    thetaAtQuartz = thetaCerenkov;
-    SetThetaAtQuartz(thetaAtQuartz);
-    return;
-  }
-
-  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 b = TMath::Cos((Double_t)trackTheta)/den;
-  Double_t c = -TMath::Cos((Double_t)thetaCerenkov)/den;
-
-  Double_t underSqrt = 1 + b*b - c*c;
-
-  if(underSqrt < 0) {
-    SetThetaAtQuartz(999.);
-    return;
+// Finds Cerenkov angle  for this photon candidate
+// Arguments: cluX,cluY - position of cadidate's cluster  
+//   Returns: Cerenkov angle 
+
+  TVector2 pos(cluX,cluY); Double_t cluR=(pos-fTrkPos).Mod();  Double_t phi=FindPhotPhi(cluX,cluY);      
+  Printf("new dist %f phi %f",cluR,phi);
+  Double_t ckov1=0,ckov2=0.75;
+  const Double_t kTol=0.05; 
+  Int_t iIterCnt = 0;
+  while(1){
+    if(iIterCnt>=50) return -1;
+    Double_t ckov=0.5*(ckov1+ckov2);
+    Double_t dist=cluR-TracePhoton(ckov,phi,pos); iIterCnt++; //get distance between trial point and cluster position
+    Printf("New: phi %f ckov %f dist %f",phi,ckov,dist);
+    if     (dist> kTol) ckov1=ckov;                           //cluster @ larger ckov 
+    else if(dist<-kTol) ckov2=ckov;                           //cluster @ smaller ckov
+    else                return ckov;                          //precision achived         
   }
-
-  Double_t sol1 = (1+TMath::Sqrt(underSqrt))/(b-c);
-  Double_t sol2 = (1-TMath::Sqrt(underSqrt))/(b-c);
-
-  Double_t thetaSol1 = 2*TMath::ATan(sol1);
-  Double_t thetaSol2 = 2*TMath::ATan(sol2);
-
-  if(thetaSol1>0 && thetaSol1 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol1;
-  if(thetaSol2>0 && thetaSol2 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol2;
-
-//  AliDebug(1,Form(" Theta @ quartz window %f ",thetaAtQuartz));
-
-  SetThetaAtQuartz(thetaAtQuartz);
-}
-//__________________________________________________________________________________________________
-void AliRICHRecon::FindThetaPhotonCerenkov()
+}//FindPhotTheta()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::FindPhotPhi(Double_t cluX,Double_t cluY)
 {
-  //find theta cerenkov of ring
-
-  Float_t thetaCerMin = 0.;
-  Float_t thetaCerMax = 0.75;
-  Float_t thetaCerMean;
-
-  Float_t radiusMin, radiusMax, radiusMean;
-  Int_t nIteration = 0;
-
-  const Float_t kTollerance = 0.05;
-
-
-  Float_t phiPoint = GetPhiPoint();
-
-  SetEmissionPoint(AliRICHParam::RadThick()/2);
-
-  Float_t xPoint = GetEntranceX();
-  Float_t yPoint = GetEntranceY();
-  Float_t distPoint = TMath::Sqrt(xPoint*xPoint + yPoint*yPoint);
-
-//  AliDebug(1,Form(" DistPoint %f ",distPoint));
-
-  // Star minimization...
-
-  // First value...
-
-  FindThetaAtQuartz(thetaCerMin);
+// Finds phi angle og photon candidate by considering the cluster's position  of this candudate w.r.t track position
   
-  if(GetThetaAtQuartz() == 999.)
-    {
-      radiusMin = -999.;
-    }
-  else
-    {
-      SetThetaPhotonInDRS(GetThetaAtQuartz());
-      SetPhiPhotonInDRS(phiPoint);
-      
-      radiusMin = FromEmissionToCathode();
-    }
-
-  // Second value...
-
-  FindThetaAtQuartz(thetaCerMax);
-  if(GetThetaAtQuartz() == 999.)
-    {
-      radiusMax = 999.;
-    }
-  else
-    {
-      SetThetaPhotonInDRS(GetThetaAtQuartz());
-      SetPhiPhotonInDRS(phiPoint);
-      
-      radiusMax = FromEmissionToCathode();
-    }
-  // Mean value...
-
-  thetaCerMean = (thetaCerMax + thetaCerMin)/2;
-
-  FindThetaAtQuartz(thetaCerMean);
-  if(GetThetaAtQuartz() == 999.)
-    {
-      radiusMean = 999.;
-    }
-  else
-    {
-      SetThetaPhotonInDRS(GetThetaAtQuartz());
-      SetPhiPhotonInDRS(phiPoint);
-      
-      radiusMean = FromEmissionToCathode();
-    }
-
-//  AliDebug(1,Form(" r1 %f rmean %f r2 %f",radiusMin,radiusMean,radiusMax));
-
-  while (TMath::Abs(radiusMean-distPoint) > kTollerance)
-    {
-
-      if((radiusMin-distPoint)*(radiusMean-distPoint) < 0) thetaCerMax = thetaCerMean;
-      if((radiusMin-distPoint)*(radiusMean-distPoint) > 0) {
-
-       thetaCerMin = thetaCerMean;
-
-       FindThetaAtQuartz(thetaCerMin);
-       SetThetaPhotonInDRS(GetThetaAtQuartz());
-       SetPhiPhotonInDRS(phiPoint);
-
-       radiusMin =FromEmissionToCathode();
-      }
-
-      thetaCerMean = (thetaCerMax + thetaCerMin)/2;
-
-      FindThetaAtQuartz(thetaCerMean);
-      SetThetaPhotonInDRS(GetThetaAtQuartz());
-      SetPhiPhotonInDRS(phiPoint);
-
-      radiusMean = FromEmissionToCathode();
-
-      nIteration++;
-      if(nIteration>=50) {
-//     AliDebug(1,Form(" max iterations in FindPhotonCerenkov ",nIteration));
-       SetThetaPhotonCerenkov(999.);
-       return;
-      }
-    }
-
-//  AliDebug(1,Form(" distpoint %f radius %f ",distPoint,radiusMean));
-  SetThetaPhotonCerenkov(thetaCerMean);
-
+  Double_t emiss=0; 
+  return fPhotPhi[fPhotCnt]=TMath::ATan2(cluY-fTrkPos.Y()-emiss*TMath::Tan(fTrkDir.Theta())*TMath::Sin(fTrkDir.Phi()),
+                                         cluX-fTrkPos.X()-emiss*TMath::Tan(fTrkDir.Theta())*TMath::Cos(fTrkDir.Phi()));
 }
-//__________________________________________________________________________________________________
-void AliRICHRecon::FindAreaAndPortionOfRing()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::FindRingArea(Double_t ckovAng)const
 {
-  //find fraction of the ring accepted by the RICH
-
-  Float_t xPoint[NPointsOfRing], yPoint[NPointsOfRing];
-
-  //  Float_t xtoentr = GetEntranceX();
-  //  Float_t ytoentr = GetEntranceY();
-  Float_t shiftX = GetShiftX();
-  Float_t shiftY = GetShiftY();
-
-  Float_t xemiss = GetXCoordOfEmission(); 
-  Float_t yemiss = GetYCoordOfEmission(); 
-
-  Float_t x0 = xemiss + shiftX;
-  Float_t y0 = yemiss + shiftY;
-
-
-
-  SetEmissionPoint(AliRICHParam::RadThick()/2.);
-
-  Float_t theta = GetThetaOfRing();
+// Find area inside the cerenkov ring which lays inside PCs
+// Arguments: ckovThe - cernkov    
+//   Returns: area of the ring in cm^2 for given theta ckov
+   
   
-  Int_t nPoints = 0;
-  Int_t nPsiAccepted = 0;
-  Int_t nPsiTotal = 0;
-
-  for(Int_t i=0;i<NPointsOfRing-1;i++){
-      Float_t psi = 2*TMath::Pi()*i/NPointsOfRing;
-      
-      SetThetaPhotonInTRS(theta);
-      SetPhiPhotonInTRS(psi);
-      FindPhotonAnglesInDRS();
-      
-      Float_t radius = FromEmissionToCathode();
-      if (radius == 999.) continue;
-      
-      nPsiTotal++;
-
-      Float_t xPointRing = GetXPointOnCathode() + shiftX;
-      Float_t yPointRing = GetYPointOnCathode() + shiftY;
-      
-      SetDetectorWhereX(xPointRing);
-      SetDetectorWhereY(yPointRing);
+  TVector2 pos1,pos2;
+  
+  const Int_t kN=100;
+  Double_t area=0;
+  for(Int_t i=0;i<kN;i++){
+    TracePhoton(ckovAng,Double_t(TMath::TwoPi()*i    /kN),pos1);//trace this photon 
+    TracePhoton(ckovAng,Double_t(TMath::TwoPi()*(i+1)/kN),pos2);//trace this photon 
+    area+=(pos1-fTrkPos)*(pos2-fTrkPos);
       
-      Int_t zone = CheckDetectorAcceptance();
-
-       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++;
-           }
-      nPoints++;
   }
-
-  xPoint[nPoints] = xPoint[0];  yPoint[nPoints] = yPoint[0];
-  
-  // find area...
-
-  Float_t area = 0;
-
-  for (Int_t i = 0; i < nPoints; i++)
-    {
-      area += TMath::Abs((xPoint[i]-x0)*(yPoint[i+1]-y0) - (xPoint[i+1]-x0)*(yPoint[i]-y0));
-    }
-  
-  area *= 0.5;
-  
-  Float_t portionOfRing = 0;
-  if (nPsiTotal>0) 
-    portionOfRing = ((Float_t)nPsiAccepted)/((Float_t)(nPsiTotal));
-
-
-  SetAreaOfRing(area);
-  SetPortionOfRing(portionOfRing);
-}//FindAreaAndPortionOfRing()
-//__________________________________________________________________________________________________
-void AliRICHRecon::FindIntersectionWithDetector()
-{
-  // find ring intersection with CsI edges
-
-  Float_t xIntersect, yIntersect;
-  Float_t x1, x2, y1, y2;
-
-  Float_t shiftX = GetShiftX();
-  Float_t shiftY = GetShiftY();
-
-  Float_t xPoint = GetXPointOnCathode() + shiftX;
-  Float_t yPoint = GetYPointOnCathode() + shiftY;
-
-  Float_t xemiss = GetXCoordOfEmission(); 
-  Float_t yemiss = GetYCoordOfEmission(); 
-
-  Float_t phi = GetPhiPhotonInDRS();
-  Float_t m = tan(phi);
-
-  Float_t x0 = xemiss + shiftX;
-  Float_t y0 = yemiss + shiftY;
-
-  if(xPoint > x0)
-    {
-      x1 = x0;
-      x2 = xPoint;
-    }
-  else
-    {
-      x2 = x0;
-      x1 = xPoint;
-    }
-  if(yPoint > y0)
-    {
-      y1 = y0;
-      y2 = yPoint;
-    }
-  else
-    {
-      y2 = y0;
-      y1 = yPoint;
-    }
-  //
-  xIntersect = AliRICHParam::PcSizeX();
-  yIntersect = m*(xIntersect - x0) + y0;
-  if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2)
-    {
-      SetIntersectionX(xIntersect);
-      SetIntersectionY(yIntersect);
-      return;
-    }
-  //
-  xIntersect = 0;
-  yIntersect = m*(xIntersect - x0) + y0;
-  if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2)
-    {
-      SetIntersectionX(xIntersect);
-      SetIntersectionY(yIntersect);
-      return;
-    }
-  //
-  yIntersect = AliRICHParam::PcSizeY();
-  xIntersect = (yIntersect - y0)/m + x0;
-  if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2)
-    {
-      SetIntersectionX(xIntersect);
-      SetIntersectionY(yIntersect);
-      return;
-    }
-  //
-  yIntersect = 0;
-  xIntersect = (yIntersect - y0)/m + x0;
-  if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2)
-    {
-      SetIntersectionX(xIntersect);
-      SetIntersectionY(yIntersect);
-      return;
-    }
-}
-
-//__________________________________________________________________________________________________
-Int_t AliRICHRecon::CheckDetectorAcceptance() const
-{
-  // check for the acceptance
-
-  // crosses X -2.6 2.6 cm
-  // crosses Y -1 1 cm
-
-  Float_t xcoord = GetDetectorWhereX();
-  Float_t ycoord = GetDetectorWhereY();
-
-  if(xcoord > AliRICHParam::PcSizeX())
-    {
-      if(ycoord > AliRICHParam::PcSizeY()) return 2;
-      if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 3;
-      if(ycoord < 0) return 4;
-    }
-  if(xcoord < 0)
-    {
-      if(ycoord > AliRICHParam::PcSizeY()) return 8;
-      if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 7;
-      if(ycoord < 0) return 6;
-    }
-  if(xcoord > 0 && xcoord < AliRICHParam::PcSizeX())
-    {
-      if(ycoord > AliRICHParam::PcSizeY()) return 1;
-      if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 0;
-      if(ycoord < 0) return 5;
-    }
-  return 999;
-}
-//__________________________________________________________________________________________________
-void AliRICHRecon::FindPhotonAnglesInDRS()
+  return area;
+}//RingArea()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::TracePhoton(Double_t ckovThe,Double_t ckovPhi,TVector2 &pos)const
 {
-  // Setup the rotation matrix of the track...
-
-  TRotation mtheta;
-  TRotation mphi;
-  TRotation minv;
-  TRotation mrot;
+// Trace a single Ckov photon from emission point somewhere in radiator up to photocathode taking into account ref indexes of materials it travereses
+// Arguments: ckovThe,ckovPhi- photon ckov angles, [rad]  (warning: not photon theta and phi)     
+//   Returns: distance between photon point on PC and track projection  
+  TRotation mtheta;   mtheta.RotateY(fTrkDir.Theta());
+  TRotation mphi;       mphi.RotateZ(fTrkDir.Phi());  
+  TRotation mrot=mphi*mtheta;
   
-  Float_t trackTheta = GetTrackTheta();
-  Float_t trackPhi = GetTrackPhi();
-
-  mtheta.RotateY(trackTheta);
-  mphi.RotateZ(trackPhi);
+  TVector3  posCkov(fTrkPos.X(),fTrkPos.Y(),-0.5*fkRadThick-fkWinThick-fkGapThick);   //RAD: photon position is track position @ middle of RAD 
+  TVector3  dirCkov;   dirCkov.SetMagThetaPhi(1,ckovThe,ckovPhi);                     //initially photon is directed according to requested ckov angle
+                                               dirCkov=mrot*dirCkov;                  //now we know photon direction in LORS
+                       dirCkov.SetPhi(ckovPhi);   
+  if(dirCkov.Theta() > TMath::ASin(1./fkRadIdx)) return -999;//total refraction on WIN-GAP boundary
   
-  mrot = mphi * mtheta;
-  //  minv = mrot.Inverse();
-
-  TVector3 photonInRadiator(1,1,1);
-
-  Float_t thetaCerenkov = GetThetaPhotonInTRS();
-  Float_t phiCerenkov   = GetPhiPhotonInTRS();
-
-  photonInRadiator.SetTheta(thetaCerenkov);
-  photonInRadiator.SetPhi(phiCerenkov);
-  photonInRadiator = mrot * photonInRadiator;
-  Float_t theta = photonInRadiator.Theta();
-  Float_t phi = photonInRadiator.Phi();
-  SetThetaPhotonInDRS(theta);
-  SetPhiPhotonInDRS(phi);
-
-}
-//__________________________________________________________________________________________________
-Float_t AliRICHRecon::FromEmissionToCathode()
-{
-// Trace current photon from emission point somewhere in radiator to photocathode
-// Arguments: none
-//   Returns:    
-
-  Float_t nfreon, nquartz, ngas; 
-
-  nfreon  = AliRICHParam::Instance()->IdxC6F14(AliRICHParam::Instance()->EckovMean());
-  nquartz = AliRICHParam::Instance()->IdxSiO2(AliRICHParam::Instance()->EckovMean());
-  ngas    = AliRICHParam::Instance()->IdxCH4(AliRICHParam::Instance()->EckovMean());
-
-  Float_t trackTheta = GetTrackTheta();
-  Float_t trackPhi = GetTrackPhi();
-  Float_t lengthOfEmissionPoint = GetEmissionPoint();
-
-  Float_t theta = GetThetaPhotonInDRS();
-  Float_t phi   = GetPhiPhotonInDRS();
-
-  Float_t xemiss = lengthOfEmissionPoint*tan(trackTheta)*cos(trackPhi);
-  Float_t yemiss = lengthOfEmissionPoint*tan(trackTheta)*sin(trackPhi);
-
-  SetXCoordOfEmission(xemiss);
-  SetYCoordOfEmission(yemiss);
+  Propagate(dirCkov,posCkov,-fkWinThick-fkGapThick); //go to RAD-WIN boundary  remeber that z=0 is PC plane
+  Refract  (dirCkov,         fkRadIdx,fkWinIdx    ); //RAD-WIN refraction
+  Propagate(dirCkov,posCkov,-fkGapThick           ); //go to WIN-GAP boundary
+  Refract  (dirCkov,         fkWinIdx,fkGapIdx    ); //WIN-GAP refraction
+  Propagate(dirCkov,posCkov,0                     ); //go to PC
   
-  Float_t thetaquar = SnellAngle(nfreon, nquartz, theta);
-
-  if(thetaquar == 999.) 
-    {
-      SetXPointOnCathode(999.);
-      SetYPointOnCathode(999.);
-      return thetaquar;
-    }
-
-  Float_t thetagap  = SnellAngle( nquartz, ngas, thetaquar);
-
-  if(thetagap == 999.) 
-    {
-      SetXPointOnCathode(999.);
-      SetYPointOnCathode(999.);
-      return 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;
-  Float_t ytot = yemiss + yw + yq + yg;
-
-  SetXPointOnCathode(xtot);
-  SetYPointOnCathode(ytot);
-
-
-  Float_t distanceFromEntrance = TMath::Sqrt(TMath::Power(fPhotonLimitX,2)+TMath::Power(fPhotonLimitY,2)); 
-
-  return distanceFromEntrance;
-
-}
-//__________________________________________________________________________________________________
-void AliRICHRecon::FindPhiPoint()
-{
-  //find phi of generated point 
-
-  Float_t xtoentr = GetEntranceX();
-  Float_t ytoentr = GetEntranceY();
-
-  Float_t trackTheta = GetTrackTheta();
-  Float_t trackPhi = GetTrackPhi();
-
-  Float_t emissionPoint = GetEmissionPoint();
-
-  Float_t argY = ytoentr - emissionPoint*tan(trackTheta)*sin(trackPhi);
-  Float_t argX = xtoentr - emissionPoint*tan(trackTheta)*cos(trackPhi);
-  Float_t phi = atan2(argY,argX);
-
-  SetPhiPoint(phi);
-
-}
-//__________________________________________________________________________________________________
-Float_t AliRICHRecon::Cerenkovangle(Float_t n, Float_t beta)
-{
-  // cerenkov angle from n and beta
-
-// Compute the cerenkov angle
-
-  Float_t thetacer;
-
-  if((n*beta)<1.) {
-    thetacer = 999.;
-    //    cout << " warning in Cerenkoangle !!!!!! " << endl;
-    return thetacer;
-  }
-
-  thetacer = acos (1./(n*beta));
-  return thetacer;
-}
-//__________________________________________________________________________________________________
-Float_t AliRICHRecon::SnellAngle(Float_t n1, Float_t n2, Float_t theta1)
+  pos.Set(posCkov.X(),posCkov.Y());
+  return (pos-fTrkPos).Mod();
+}//TracePhoton()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHRecon::Propagate(const TVector3 &dir,TVector3 &pos,Double_t z)const
 {
-  // Snell law
-
-// Compute the Snell angle
-
-  Float_t sinrefractangle;
-  Float_t refractangle;
-
-  sinrefractangle = (n1/n2)*sin(theta1);
-
-  if(sinrefractangle>1.) {
-    //    cout << " PROBLEMS IN SNELL ANGLE !!!!! " << endl;
-    refractangle = 999.;
-    return refractangle;
-  }
+// Finds an intersection point between a line and XY plane shifted along Z.
+// Arguments:  dir,pos   - vector along the line and any point of the line
+//             z         - z coordinate of plain 
+//   Returns:  none
+//   On exit:  pos is the position if this intesection if any
+  static TVector3 nrm(0,0,1); 
+         TVector3 pnt(0,0,z);
   
-  refractangle = asin(sinrefractangle);  
-  return refractangle;
-}
-//__________________________________________________________________________________________________
+  TVector3 diff=pnt-pos;
+  Double_t sint=(nrm*diff)/(nrm*dir);
+  pos+=sint*dir;
+}//Propagate()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHRecon::Refract(TVector3 &dir,Double_t n1,Double_t n2)const
+{
+// Refract direction vector according to Snell law
+// Arguments: 
+//            n1 - ref idx of first substance
+//            n2 - ref idx of second substance
+//   Returns: none
+//   On exit: dir is new direction
+  Double_t sinref=(n1/n2)*TMath::Sin(dir.Theta());
+  if(sinref>1.)    dir.SetXYZ(-999,-999,-999);
+  else             dir.SetTheta(TMath::ASin(sinref));
+}//Refract()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 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 nBin = (Int_t)(fThetaMax/fDTheta);
+  Double_t kThetaMax=0.75;
+  Int_t nChannels = (Int_t)(kThetaMax/fDTheta+0.5);
+  TH1D *phots   = new TH1D("Rphot"  ,"phots"         ,nChannels,0,kThetaMax);
+  TH1D *photsw  = new TH1D("RphotWeighted" ,"photsw" ,nChannels,0,kThetaMax);
+  TH1D *resultw = new TH1D("resultw","resultw"       ,nChannels,0,kThetaMax);
+  Int_t nBin = (Int_t)(kThetaMax/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< GetPhotonsNumber(); kPhot++){
-    SetPhotonIndex(kPhot);
-    Double_t angle = GetPhotonEta();
-    if(angle<0||angle>fThetaMax) continue;
+  
+  for (Int_t i=0; i< fPhotCnt; i++){//photon cadidates loop
+    Double_t angle = fPhotCkov[i];  if(angle<0||angle>kThetaMax) continue;
     phots->Fill(angle);
     Int_t bin = (Int_t)(0.5+angle/(fDTheta));
     Double_t weight=1.;
     if(fIsWEIGHT){
-      Double_t lowerlimit = ((Float_t)bin)*fDTheta - 0.5*fDTheta;
-      SetThetaOfRing(lowerlimit);
-      FindAreaAndPortionOfRing();
-      Float_t area1 = GetAreaOfRing();
-      Double_t upperlimit = ((Float_t)bin)*fDTheta + 0.5*fDTheta;
-      SetThetaOfRing(upperlimit);
-      FindAreaAndPortionOfRing();
-      Float_t area2 = GetAreaOfRing();
-      AliDebug(1,Form("lowerlimit %f  area %f ; upperlimit %f area %f",lowerlimit,area1,upperlimit,area2));        
-      Float_t diffarea = area2 - area1;
-      if(diffarea>0){weight = 1./(area2-area1);}else{weight = 1.;}
+      Double_t lowerlimit = ((Double_t)bin)*fDTheta - 0.5*fDTheta;  Double_t upperlimit = ((Double_t)bin)*fDTheta + 0.5*fDTheta;   
+      Double_t diffArea = FindRingArea(upperlimit)-FindRingArea(lowerlimit);
+      if(diffArea>0) weight = 1./diffArea;
     }
-    AliDebug(1,Form("Calculated weight %f",weight));       
     photsw->Fill(angle,weight);
-    SetPhotonWeight(weight);
-  }  
+    fPhotWei[i]=weight;
+  }//photon candidates loop 
+   
   for (Int_t i=1; i<=nBin;i++){
     Int_t bin1= i-nCorrBand;
     Int_t bin2= i+nCorrBand;
     if(bin1<1) bin1=1;
     if(bin2>nBin)bin2=nBin;
     Double_t sumPhots=phots->Integral(bin1,bin2);
-    if(sumPhots<fMinNumPhots) continue; // cut on minimum n. of photons per ring
+    if(sumPhots<3) continue;                            // if less then 3 photons don't trust to this ring
     Double_t sumPhotsw=photsw->Integral(bin1,bin2);
-    resultw->Fill((Float_t)((i+0.5)*fDTheta),sumPhotsw);
+    resultw->Fill((Double_t)((i+0.5)*fDTheta),sumPhotsw);
   } 
 // evaluate the "BEST" theta ckov as the maximum value of histogramm
-  Float_t *pVec = resultw->GetArray();
+  Double_t *pVec = resultw->GetArray();
   Int_t locMax = TMath::LocMax(nBin,pVec);
   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(Int_t iNclus)
+}//HoughResponse()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::FindRingCkov(Int_t)
 {
 // Loops on all Ckov candidates and estimates the best Theta Ckov for a ring formed by those candidates. Also estimates an error for that Theat Ckov
 // collecting errors for all single Ckov candidates thetas. (Assuming they are independent)  
 // Arguments: iNclus- total number of clusters in chamber for background estimation
-//    Return: none    
+//    Return: best estimation of track Theta ckov
 
-  Float_t wei = 0.;
-  Float_t weightThetaCerenkov = 0.;
+  Double_t wei = 0.;
+  Double_t weightThetaCerenkov = 0.;
 
-  Double_t etaMin=9999.,etaMax=0.;
+  Double_t ckovMin=9999.,ckovMax=0.;
   Double_t sigma2 = 0;   //to collect error squared for this ring
   
-  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;      
-      //here comes sigma of the reconstructed ring
+  for(Int_t i=0;i<fPhotCnt;i++){//candidates loop
+    if(fPhotFlag[i] == 2){
+      if(fPhotCkov[i]<ckovMin) ckovMin=fPhotCkov[i];  //find max and min Theta ckov from all candidates within probable window
+      if(fPhotCkov[i]>ckovMax) ckovMax=fPhotCkov[i]; 
+      weightThetaCerenkov += fPhotCkov[i]*fPhotWei[i];   wei += fPhotWei[i];                 //collect weight as sum of all candidate weghts   
       
      //Double_t phiref=(GetPhiPoint()-GetTrackPhi());
-       if(GetPhotonEta()<=0) continue;//?????????????????Flag photos = 2 may imply CkovEta = 0?????????????? 
-                                      //???????????  Look at SetPhoton Flag method    
-      Double_t phiref=GetTrackPhi();
-  
-      Double_t beta = 1./(TMath::Cos(GetPhotonEta())*AliRICHParam::Instance()->IdxC6F14(AliRICHParam::EckovMean()));
-      sigma2 += 1./AliRICHParam::SigmaSinglePhotonFormula(GetPhotonEta(),GetPhiPoint(),GetTrackTheta(),phiref,beta);
+       if(fPhotCkov[i]<=0) continue;//?????????????????Flag photos = 2 may imply CkovEta = 0?????????????? 
+                                     
+      sigma2 += 1./Sigma2(fPhotCkov[i],fPhotPhi[i],fTrkDir.Theta(),fTrkDir.Phi());
     }
-  }
+  }//candidates loop
   
-  if(sigma2>0) SetRingSigma2(1./sigma2);
-  else         SetRingSigma2(1e10);  
+  if(sigma2>0) fCkovSigma2=1./sigma2;
+  else         fCkovSigma2=1e10;  
   
-  if(wei != 0.) weightThetaCerenkov /= wei; else weightThetaCerenkov = 0.;  
-  SetThetaCerenkov(weightThetaCerenkov);
-
-  // estimate of the n. of bkg photons
-  SetThetaOfRing(etaMin); FindAreaAndPortionOfRing(); Double_t internalArea = GetAreaOfRing();
-  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*iNclus;//????? is the division right?
-  if(nPhotBKG<0) nPhotBKG=0; //just protection from funny angles...
-  SetPhotBKG(nPhotBKG);
-  
-  AliDebug(1,Form(" thetac weighted -> %f",weightThetaCerenkov));
-}//FindThetaCerenkov()
+  if(wei != 0.) weightThetaCerenkov /= wei; else weightThetaCerenkov = 0.;  
+  return weightThetaCerenkov;
+}//FindCkovRing()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-Int_t AliRICHRecon::FlagPhotons(Double_t thetaCkovHough)
+Int_t AliRICHRecon::FlagPhot(Double_t ckov)
 {
-// 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()
+// Flag photon candidates if their individual ckov angle is inside the window around ckov angle returned by  HoughResponse()
+// Arguments: ckov- value of most probable ckov angle for track as returned by HoughResponse()
 //   Returns: number of photon candidates happened to be inside the window
 
-  Int_t steps = (Int_t)((thetaCkovHough - fThetaMin)/ fDTheta); //how many times we need to have fDTheta to fill the distance betwee fThetaMin and thetaCkovHough
+  
+  Int_t steps = (Int_t)((ckov )/ fDTheta); //how many times we need to have fDTheta to fill the distance between 0  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);
+  Double_t tmin = (Double_t)(steps - 1)*fDTheta;
+  Double_t tmax = (Double_t)(steps)*fDTheta;
+  Double_t tavg = 0.5*(tmin+tmax);
 
   tmin = tavg - 0.5*fWindowWidth;  tmax = tavg + 0.5*fWindowWidth;
 
-  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);          
+  Int_t iInsideCnt = 0; //count photons which Theta ckov inside the window
+  for(Int_t i=0;i<fPhotCnt;i++){//photon candidates loop
+    if(fPhotCkov[i] >= tmin && fPhotCkov[i] <= tmax)   { 
+      fPhotFlag[i]=2;    
       iInsideCnt++;
     }
   }
   return iInsideCnt;
-}//FlagPhotons
+}//FlagPhotons()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::Sigma2(Double_t ckovTh, Double_t ckovPh, Double_t trkTh, Double_t trkPh)const
+{
+// Analithical calculation of total error (as a sum of localization, geometrical and chromatic errors) on Cerenkov angle for a given Cerenkov photon 
+// created by a given MIP. Fromulae according to CERN-EP-2000-058 
+// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
+//            dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]        
+//            MIP beta
+//   Returns: absolute error on Cerenkov angle, [radians]    
+  
+  TVector3 v(-999,-999,-999);
+  Double_t trkBeta = 1./(TMath::Cos(ckovTh)*fkRadIdx);
+
+  v.SetX(SigLoc (ckovTh,ckovPh,trkTh,trkPh,trkBeta));
+  v.SetY(SigGeom(ckovTh,ckovPh,trkTh,trkPh,trkBeta));
+  v.SetZ(SigCrom(ckovTh,ckovPh,trkTh,trkPh,trkBeta));
+
+  return v.Mag2();
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::SigLoc(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM)const
+{
+// Analithical calculation of localization error (due to finite segmentation of PC) on Cerenkov angle for a given Cerenkov photon 
+// created by a given MIP. Fromulae according to CERN-EP-2000-058 
+// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
+//            dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]        
+//            MIP beta
+//   Returns: absolute error on Cerenkov angle, [radians]    
+  Double_t phiDelta = phiC - phiM;
+
+  Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM);
+  Double_t k = 1.-fkRadIdx*fkRadIdx+alpha*alpha/(betaM*betaM);
+  if (k<0) return 1e10;
+
+  Double_t mu =TMath::Sin(thetaM)*TMath::Sin(phiM)+TMath::Tan(thetaC)*(TMath::Cos(thetaM)*TMath::Cos(phiDelta)*TMath::Sin(phiM)+TMath::Sin(phiDelta)*TMath::Cos(phiM));
+  Double_t e  =TMath::Sin(thetaM)*TMath::Cos(phiM)+TMath::Tan(thetaC)*(TMath::Cos(thetaM)*TMath::Cos(phiDelta)*TMath::Cos(phiM)-TMath::Sin(phiDelta)*TMath::Sin(phiM));
+
+  Double_t kk = betaM*TMath::Sqrt(k)/(8*alpha);
+  Double_t dtdxc = kk*(k*(TMath::Cos(phiDelta)*TMath::Cos(phiM)-TMath::Cos(thetaM)*TMath::Sin(phiDelta)*TMath::Sin(phiM))-(alpha*mu/(betaM*betaM))*TMath::Sin(thetaM)*TMath::Sin(phiDelta));
+  Double_t dtdyc = kk*(k*(TMath::Cos(phiDelta)*TMath::Sin(phiM)+TMath::Cos(thetaM)*TMath::Sin(phiDelta)*TMath::Cos(phiM))+(alpha* e/(betaM*betaM))*TMath::Sin(thetaM)*TMath::Sin(phiDelta));
+
+  return  TMath::Sqrt(0.2*0.2*dtdxc*dtdxc + 0.25*0.25*dtdyc*dtdyc);
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::SigCrom(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM)const
+{
+// Analithical calculation of chromatic error (due to lack of knowledge of Cerenkov photon energy) on Cerenkov angle for a given Cerenkov photon 
+// created by a given MIP. Fromulae according to CERN-EP-2000-058 
+// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
+//            dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]        
+//            MIP beta
+//   Returns: absolute error on Cerenkov angle, [radians]    
+  Double_t phiDelta = phiC - phiM;
+  Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM);
+
+  Double_t dtdn = TMath::Cos(thetaM)*fkRadIdx*betaM*betaM/(alpha*TMath::Tan(thetaC));
+            
+  Double_t f = 0.00928*(7.75-5.635)/TMath::Sqrt(12.);
+
+  return f*dtdn;
+}//SigCrom()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Double_t AliRICHRecon::SigGeom(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM)const
+{
+// Analithical calculation of geometric error (due to lack of knowledge of creation point in radiator) on Cerenkov angle for a given Cerenkov photon 
+// created by a given MIP. Formulae according to CERN-EP-2000-058 
+// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
+//            dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]        
+//            MIP beta
+//   Returns: absolute error on Cerenkov angle, [radians]    
+
+  Double_t phiDelta = phiC - phiM;
+  Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM);
+
+  Double_t k = 1.-fkRadIdx*fkRadIdx+alpha*alpha/(betaM*betaM);
+  if (k<0) return 1e10;
+
+  Double_t eTr = 0.5*1.5*betaM*TMath::Sqrt(k)/(8*alpha);
+  Double_t lambda = 1.-TMath::Sin(thetaM)*TMath::Sin(thetaM)*TMath::Sin(phiC)*TMath::Sin(phiC);
+
+  Double_t c = 1./(1.+ eTr*k/(alpha*alpha*TMath::Cos(thetaC)*TMath::Cos(thetaC)));
+  Double_t i = betaM*TMath::Tan(thetaC)*lambda*TMath::Power(k,1.5);
+  Double_t ii = 1.+eTr*betaM*i;
+
+  Double_t err = c * (i/(alpha*alpha*8) +  ii*(1.-lambda) / ( alpha*alpha*8*betaM*(1.+eTr)) );
+  Double_t trErr = 1.5/(TMath::Sqrt(12.)*TMath::Cos(thetaM));
+
+  return trErr*err;
+}//SigGeom()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index 98dd42b..ea9bc20 100644 (file)
@@ -14,9 +14,8 @@
 
 
 #include <TTask.h> //base class
+#include <TVector3.h>
 
-class AliRICHHelix;
-class AliRICHParam;
 class TClonesArray;
 class AliRICHRecon : public TTask 
 {
@@ -24,182 +23,46 @@ public :
              AliRICHRecon();
     virtual ~AliRICHRecon()                                                          {}
 
-  Double_t ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pCluLst,Int_t &iMipId);                  // it returns reconstructed Theta Cerenkov
-  void FindThetaPhotonCerenkov();             //
-  void FindAreaAndPortionOfRing();            //
-  void FindPhotonAnglesInDRS();               //
-  void FindPhiPoint();                        //
-  void FindThetaAtQuartz(Float_t ThetaCer);   //
-  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(Int_t iNclus);       //
-  void FindIntersectionWithDetector();        //
-  Float_t Cerenkovangle(Float_t n, Float_t b);//
-  Int_t   PhotonInBand();                     //
-  Int_t   CheckDetectorAcceptance() const;    //
-  Int_t   GetFittedHoughPhotons()                   const{ return fFittedHoughPhotons;}             //
-  Int_t   GetPhotonFlag()                           const{ return fPhotonFlag[fPhotonIndex];}       //
-  Int_t   GetPhotonsNumber()                        const{ return fPhotonsNumber;}                  //
-  Int_t   GetPhotonIndex()                          const{ return fPhotonIndex;}                    //
-  Float_t GetPhotonEnergy()                         const{ return fEphot;}                          //
-  Float_t GetEmissionPoint()                        const{ return fLengthEmissionPoint;}            //
-  Float_t GetMassHypotesis()                        const{ return fMassHypotesis;}                  //
-  Float_t GetBetaOfParticle()                       const{ return fTrackBeta;}                      //
-  Float_t GetEntranceX()                            const{ return fXtoentr;}                        //
-  Float_t GetEntranceY()                            const{ return fYtoentr;}                        //
-  Float_t GetThetaCerenkov()                        const{ return fThetaCerenkov;}                  //
-  Float_t GetThetaPhotonCerenkov()                  const{ return fThetaPhotonCerenkov;}            //
-  Float_t GetTrackTheta()                           const{ return fTrackTheta;}                     //
-  Float_t GetTrackPhi()                             const{ return fTrackPhi;}                       //
-  Float_t GetXPointOnCathode()                      const{ return fPhotonLimitX;}                   //
-  Float_t GetYPointOnCathode()                      const{ return fPhotonLimitY;}                   //
-  Float_t GetThetaPhotonInDRS()                     const{ return fThetaPhotonInDRS;}               //
-  Float_t GetPhiPhotonInDRS()                       const{ return fPhiPhotonInDRS;}                 //
-  Float_t GetThetaPhotonInTRS()                     const{ return fThetaPhotonInTRS;}               //
-  Float_t GetPhiPhotonInTRS()                       const{ return fPhiPhotonInTRS;}                 //
-  Float_t GetThetaAtQuartz()                        const{ return fThetaAtQuartz;}                  //
-  Float_t GetPhiPoint()                             const{ return fPhiPoint[fPhotonIndex];}         //
-  Float_t GetXCoordOfEmission()                     const{ return fXEmiss;}                         //
-  Float_t GetYCoordOfEmission()                     const{ return fYEmiss;}                         //
-  Float_t GetXInnerRing()                           const{ return fXInner;}                         //
-  Float_t GetYInnerRing()                           const{ return fYInner;}                         //
-  Float_t GetRadiusInnerRing()                      const{ return fInnerRadius;}                    //
-  Float_t GetXOuterRing()                           const{ return fXOuter;}                         //
-  Float_t GetYOuterRing()                           const{ return fYOuter;}                         //
-  Float_t GetRadiusOuterRing()                      const{ return fOuterRadius;}                    //
-  Float_t GetShiftX()                               const{ return fShiftX;}                         //
-  Float_t GetShiftY()                               const{ return fShiftY;}                         //
-  Float_t GetDetectorWhereX()                       const{ return fXcoord;}                         //
-  Float_t GetDetectorWhereY()                       const{ return fYcoord;}                         //
-  Float_t GetIntersectionX()                        const{ return fIntersectionX;}                  //
-  Float_t GetIntersectionY()                        const{ return fIntersectionY;}                  //
-  Float_t GetThetaOfRing()                          const{ return fThetaOfRing;}                    //
-  Float_t GetAreaOfRing()                           const{ return fAreaOfRing;}                     //
-  Float_t GetPortionOfRing()                        const{ return fPortionOfRing;}                  //
-  Float_t GetHoughArea()                            const{ return fHoughArea;}                      //
-  Float_t GetPhotonEta()                            const{ return fPhotonEta[fPhotonIndex];}        //
-  Float_t GetPhotonWeight()                         const{ return fPhotonWeight[fPhotonIndex];}     //
-  Float_t GetHoughRMS()                             const{ return fHoughRMS;}                       //
-  Double_t GetPhotBKG()                             const{ return fnPhotBKG;}                       //
-  Float_t GetFittedTrackTheta()                     const{ return fFittedTrackTheta;}               //
-  Float_t GetFittedTrackPhi()                       const{ return fFittedTrackPhi;}                 //
-  Float_t GetFittedThetaCerenkov()                  const{ return fFittedThetaCerenkov;}            //
-  Float_t GetRingSigma2()                           const{ return fRingSigma2;}                     //
-  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;}                                         //
-  void SetThetaPhotonInTRS(Float_t Theta) {fThetaPhotonInTRS = Theta;}                              //
-  void SetPhiPhotonInTRS(Float_t Phi) {fPhiPhotonInTRS = Phi;}                                      //
-  void SetThetaPhotonInDRS(Float_t Theta) {fThetaPhotonInDRS = Theta;}                              //
-  void SetPhiPhotonInDRS(Float_t Phi) {fPhiPhotonInDRS = Phi;}                                      //
-  void SetThetaAtQuartz(Float_t ThetaAtQuartz) {fThetaAtQuartz = ThetaAtQuartz;}                    //
-  void SetPhiPoint(Float_t PhiPoint){ fPhiPoint[fPhotonIndex] = PhiPoint;}                          //
-  void SetXCoordOfEmission(Float_t XEmiss) {fXEmiss = XEmiss;}                                      //
-  void SetYCoordOfEmission(Float_t YEmiss) {fYEmiss = YEmiss;}                                      //
-  void SetXPointOnCathode(Float_t PhotonLimitX) { fPhotonLimitX = PhotonLimitX;}                    //
-  void SetYPointOnCathode(Float_t PhotonLimitY) { fPhotonLimitY = PhotonLimitY;}                    //
-  void SetXInnerRing(Float_t XInner) {fXInner = XInner;}                                            //
-  void SetYInnerRing(Float_t YInner) {fYInner = YInner;}                                            //
-  void SetRadiusInnerRing(Float_t InnerRadius) {fInnerRadius = InnerRadius;}                        //
-  void SetXOuterRing(Float_t XOuter) {fXOuter = XOuter;}                                            //
-  void SetYOuterRing(Float_t YOuter) {fYOuter = YOuter;}                                            //
-  void SetRadiusOuterRing(Float_t OuterRadius) {fOuterRadius = OuterRadius;}                        //
-  void SetThetaCerenkov(Float_t ThetaCer) {fThetaCerenkov = ThetaCer;}                              //
-  void SetThetaPhotonCerenkov(Float_t ThetaPhotCer) {fThetaPhotonCerenkov = ThetaPhotCer;}          //
-  void SetTrackTheta(Float_t TrackTheta) { fTrackTheta = TrackTheta;}                               //
-  void SetTrackPhi(Float_t TrackPhi) { fTrackPhi = TrackPhi;}                                       //
-  void SetShiftX(Float_t ShiftX) { fShiftX = ShiftX;}                                               //
-  void SetShiftY(Float_t ShiftY) { fShiftY = ShiftY;}                                               //
-  void SetDetectorWhereX(Float_t Xcoord) { fXcoord = Xcoord;}                                       //
-  void SetDetectorWhereY(Float_t Ycoord) { fYcoord = Ycoord;}                                       //
-  void SetIntersectionX(Float_t IntersectionX) { fIntersectionX = IntersectionX;}                   //
-  void SetIntersectionY(Float_t IntersectionY) { fIntersectionY = IntersectionY;}                   //
-  void SetThetaOfRing(Float_t ThetaOfRing) { fThetaOfRing = ThetaOfRing;}                           //
-  void SetAreaOfRing(Float_t AreaOfRing) { fAreaOfRing = AreaOfRing;}                               //
-  void SetPortionOfRing(Float_t PortionOfRing) { fPortionOfRing = PortionOfRing;}                   //
-  void SetHoughArea(Float_t HoughArea) { fHoughArea = HoughArea;}                                   //
-  void SetPhotonsNumber(Int_t PhotonsNumber) { fPhotonsNumber = PhotonsNumber;}                     //
-  void SetPhotonIndex(Int_t PhotonIndex) { fPhotonIndex = PhotonIndex;}                             //
-  void SetPhotonEta(Float_t PhotonEta) { fPhotonEta[fPhotonIndex] = PhotonEta;}                     //
-  void SetPhotonFlag(Int_t PhotonFlag) { fPhotonFlag[fPhotonIndex] = PhotonFlag;}                   //
-  void SetPhotonWeight(Float_t PhotonWeight) { fPhotonWeight[fPhotonIndex] = PhotonWeight;}         //
-  void SetPhotBKG(Double_t nPhotBKG) {fnPhotBKG=nPhotBKG;}                                          //
-  void SetHoughRMS(Float_t HoughRMS) { fHoughRMS = HoughRMS;}                                       //
-  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 SetRingSigma2(Float_t RingSigma2) { fRingSigma2 = RingSigma2;} //
-  Float_t SnellAngle(Float_t n1, Float_t n2, Float_t theta1);                                       //
-  Float_t FromEmissionToCathode();                                                                  //
-
+  
+  Double_t CkovAngle    (TClonesArray *pCluLst,Int_t &iNaccepted);                                                         //reconstructed Theta Cerenkov
+  Double_t CkovSigma2   (                                                                     )const{ return fCkovSigma2;} //track ckov angle error squared
+  Double_t FindPhotCkov (Double_t cluX,Double_t cluY                                          );     //find ckov angle for single photon candidate
+  Double_t FindPhotPhi  (Double_t cluX,Double_t cluY                                          );     //find phi angle for single photon candidate
+  Double_t FindRingCkov (Int_t iNclus                                                         );     //best ckov for ring formed by found photon candidates
+  Double_t FindRingArea (Double_t ckov                                                        )const;//estimated area of ring in cm^2
+  Int_t    FlagPhot     (Double_t ckov                                                        );     //is photon ckov near most probable track ckov
+  Double_t HoughResponse(                                                                     );     //most probable track ckov angle
+  void     Propagate    (const TVector3 &dir,      TVector3 &pos,Double_t z                   )const;//propagate photon alogn the line  
+  void     Refract      (      TVector3 &dir,                    Double_t n1,    Double_t n2  )const;//refract photon on the boundary
+  Double_t TracePhoton  (Double_t ckovTh,Double_t ckovPh,TVector2 &pos                        )const;//trace photon created by track to PC
+  
+  Double_t SigLoc  (Double_t ckovTh,Double_t ckovPh,Double_t trkTh,Double_t trkPh,Double_t beta)const; //localization error
+  Double_t SigGeom (Double_t ckovTh,Double_t ckovPh,Double_t trkTh,Double_t trkPh,Double_t beta)const; //geometry error
+  Double_t SigCrom (Double_t ckovTh,Double_t ckovPh,Double_t trkTh,Double_t trkPh,Double_t beta)const; //cromasity error
+  Double_t Sigma2  (Double_t ckovTh,Double_t ckovPh,Double_t trkTh,Double_t trkPh              )const; //photon candidate sigma
+  void     SetTrack(Double_t th,Double_t ph,Double_t x,Double_t y){  fTrkDir.SetMagThetaPhi(1,th,ph);  fTrkPos.Set(x,y);}//set track info
+   
+  const static Double_t fkRadThick;                      //radiator thickness
+  const static Double_t fkWinThick;                      //window thickness
+  const static Double_t fkGapThick;                      //proximity gap thickness
+  const static Double_t fkRadIdx;                        //mean refractive index of RAD material (C6F14)
+  const static Double_t fkWinIdx;                        //mean refractive index of WIN material (SiO2) 
+  const static Double_t fkGapIdx;                        //mean refractive index of GAP material (CH4)
+  
 protected:
-  Int_t fPhotonsNumber;                       // Number of photons candidate
-  Int_t fPhotonIndex;                         // index of photons
-  Int_t fPhotonFlag[3000];                    // flag for photons
-  Int_t   fFittedHoughPhotons;                // n. photons after Hough and after minimization
-  Int_t fMinNumPhots;                         // minimum number of photons for a given ring
+  Int_t    fPhotCnt;                           // counter of photons candidate
+  Int_t    fPhotFlag[3000];                    // flags of photon candidates
+  Double_t fPhotCkov[3000];                    // Ckov angles of photon candidates, [rad]
+  Double_t fPhotPhi [3000];                    // phis of photons candidates, [rad]
+  Double_t fPhotWei [3000];                    // weigths of photon candidates
+  Double_t fCkovSigma2;                        // sigma2 of the reconstructed ring
 
-  Float_t fTrackTheta;                        // Theta of track at RICH
-  Float_t fTrackPhi;                          // Phi of track at RICH
-  Float_t fMinDist;                           // min distance between extrapolated track and MIP
-  Float_t fTrackBeta;                         // beta of the track
-  Float_t fXtoentr;                           // X entrance to RICH
-  Float_t fYtoentr;                           // Y entrance to RICH
-  Float_t fThetaPhotonInTRS;                  // Theta of photon in the Track Reference System (TRS)
-  Float_t fPhiPhotonInTRS;                    // Phi of photon in TRS
-  Float_t fThetaPhotonInDRS;                  // Theta of photon in Detector Reference System (DRS)
-  Float_t fPhiPhotonInDRS;                    // Phi of photon in DRS
-  Float_t fThetaAtQuartz;                     // Theta at the quartz entrance
-  Float_t fPhiPoint[3000];                    // array of phi of ring photons
-  Float_t fXEmiss;                            //  x emission
-  Float_t fYEmiss;                            //  y emission
-  Float_t fXInner;                            // X inner ring
-  Float_t fYInner;                            // Y inner ring
-  Float_t fXOuter;                            // X outer ring
-  Float_t fYOuter;                            // Y outer ring
-  Float_t fInnerRadius;                       // inner radius
-  Float_t fOuterRadius;                       // outer radius
-  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 
-  Float_t fDistanceFromCluster;               // distance from cluster
-  Float_t fCerenkovAnglePad;                  // cherenkov angle of pad
-  Float_t fThetaPhotonCerenkov;               // theta cerenkov for photon
-  Float_t fShiftX;                            // x shift to entrance in radiator
-  Float_t fShiftY;                            // y shift to entrance in radiator
-  Float_t fXcoord;                            // ..
-  Float_t fYcoord;                            // ..
-  Float_t fIntersectionX;                     // ..
-  Float_t fIntersectionY;                     // ..
-  Float_t fMassHypotesis;                     //
-  Float_t fThetaOfRing;                       // theta of ring
-  Float_t fAreaOfRing;                        // area of the ring
-  Float_t fPortionOfRing;                     // fraction of the accepted ring
-  Float_t fHoughArea;                         // area Hough
-  Float_t fPhotonEta[3000];                   // theta cerenkov of photon candidates
-  Float_t fPhotonWeight[3000];                // weigth
-  Float_t fHoughRMS;                          // rms Hough
-  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
   Bool_t  fIsWEIGHT;                          // flag to consider weight procedure
-  Bool_t  fIsBACKGROUND;                      // flag to simulate bkg
   Float_t fDTheta;                            // Step for sliding window
   Float_t fWindowWidth;                       // Hough width of sliding window
   
-  Int_t   fNumEtaPhotons;                     // Number of photons
-  Int_t   fEtaFlag[3000];                     // flag for good photons
-  Float_t fEtaPhotons[3000];                  // Cerenkov angle each photon
-  Float_t fWeightPhotons[3000];               // weight for each photon
-  Double_t fnPhotBKG;                         // # estimated BKG photons in the ring
-  Float_t fThetaCerenkov;                     // Theta angle for Hough
-  Float_t fWeightThetaCerenkov;               // Theta Cerenkov angle weighted
-  Float_t fThetaPeakPos;                      // Peak position
-  Float_t fRingSigma2;                        // sigma2 of the reconstructed ring
+  TVector3 fTrkDir;                           //track direction in LORS
+  TVector2 fTrkPos;                           //track positon in LORS at the middle of radiator
   ClassDef(AliRICHRecon,0)
 };
     
index 141ebb0..debb31a 100644 (file)
  **************************************************************************/
 
 #include "AliRICHReconstructor.h" //class header
-#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 <TFile.h>                //RichAna()
-#include <TParticle.h>            //RichAna()
+#include "AliRICH.h"              //Reconstruct() 
+#include "AliRICHCluster.h"       //CluQA() 
+#include "AliRICHParam.h"         //FillEsd() 
+#include <AliESD.h>               //FillEsd()
+#include <AliRunLoader.h>         //Reconstruct() for simulated digits
+#include <AliRawReader.h>         //Reconstruct() for raw digits
+#include <AliRun.h>               //Reconstruct()
 #include <TH1F.h>                 //CluQA() 
 #include <TH2F.h>                 //CluQA() 
 #include <TCanvas.h>              //CluQA() 
 #include <TNtupleD.h>             //CheckPR()
-#include <TPolyMarker.h>          //Test()
 ClassImp(AliRICHReconstructor)
 
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -44,31 +42,30 @@ void AliRICHReconstructor::CluQA(AliRunLoader *pAL)
   TH1::AddDirectory(kFALSE);
   
         
-  TH1F*    pQ=new TH1F("RichCluQdc"     ,"All QDC;q [QDC]"           ,4000 ,0  ,4000);// QDC hists
-  TH1F* pCerQ=new TH1F("RichCluCerQdc"  ,"Ckov QDC;q [QDC]"          ,4000 ,0  ,4000);
-  TH1F* pMipQ=new TH1F("RichCluMipQdc"  ,"MIP QDC;q [QDC]"           ,4000 ,0  ,4000);
+  TH1F*    pQ=new TH1F("RiAllQ"  ,"Charge All"           ,4000 ,0  ,4000);// Q hists
+  TH1F* pCerQ=new TH1F("RiCerQ"  ,"Charge Ckov"          ,4000 ,0  ,4000);
+  TH1F* pMipQ=new TH1F("RiMipQ"  ,"Charge MIP"           ,4000 ,0  ,4000);
   
   TH1F*    pS=new TH1F("RichCluSize"    ,"Cluster size;size"         ,100  ,0  ,100 );// size hists
   TH1F* pCerS=new TH1F("RichCluCerSize" ,"Ckov size;size"            ,100  ,0  ,100 );
   TH1F* pMipS=new TH1F("RichCluMipSize" ,"MIP size;size"             ,100  ,0  ,100 );
   
-  TH2F*    pM=new TH2F("RichCluMap"     ,"Cluster map;x [cm];y [cm]" ,1000 ,0  ,AliRICHParam::PcSizeX(),1000,0,AliRICHParam::PcSizeY()); // maps
-  TH2F* pMipM=new TH2F("RichCluMipMap"  ,"MIP map;x [cm];y [cm]"     ,1000 ,0  ,AliRICHParam::PcSizeX(),1000,0,AliRICHParam::PcSizeY());
-  TH2F* pCerM=new TH2F("RichCluCerMap"  ,"Ckov map;x [cm];y [cm]"    ,1000 ,0  ,AliRICHParam::PcSizeX(),1000,0,AliRICHParam::PcSizeY());
+  TH2F*    pM=new TH2F("RichCluMap"     ,"Cluster map;x [cm];y [cm]" ,1000 ,0  ,AliRICHDigit::SizePcX(),1000,0,AliRICHDigit::SizePcY()); // maps
+  TH2F* pMipM=new TH2F("RichCluMipMap"  ,"MIP map;x [cm];y [cm]"     ,1000 ,0  ,AliRICHDigit::SizePcX(),1000,0,AliRICHDigit::SizePcY());
+  TH2F* pCerM=new TH2F("RichCluCerMap"  ,"Ckov map;x [cm];y [cm]"    ,1000 ,0  ,AliRICHDigit::SizePcX(),1000,0,AliRICHDigit::SizePcY());
  
   
-  TClonesArray *pCluLst=new TClonesArray("AliRICHCluster");//tmp list of clusters
   
-  for(Int_t iEvtN=0; iEvtN<iNevt; iEvtN++){
-    pAL->GetEvent(iEvtN);               
+  for(Int_t iEvt=0;iEvt<iNevt;iEvt++){
+    pAL->GetEvent(iEvt);               
     pRL->TreeD()->GetEntry(0); 
-    for(Int_t iChN=1;iChN<=AliRICHParam::kNch;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
+    TClonesArray *pCluLst=new TClonesArray("AliRICHCluster");//tmp list of clusters for this event
+    
+    for(Int_t iCh=0;iCh<7;iCh++) Dig2Clu(pRich->DigLst(iCh),pCluLst,kFALSE);//cluster finder for all chamber if any digits present
     
-    for(Int_t iCluN=0 ; iCluN < pCluLst->GetEntriesFast() ; iCluN++){
-      AliRICHCluster *pClu = (AliRICHCluster*)pCluLst->At(iCluN);
-      Int_t cfm=0; for(Int_t iDig=0;iDig<pClu->Size();iDig++)  cfm+=pClu->Dig(iDig)->Cfm(); //collect ckov-fee-mip structure of current cluster
+    for(Int_t iClu=0;iClu<pCluLst->GetEntriesFast();iClu++){
+      AliRICHCluster *pClu = (AliRICHCluster*)pCluLst->At(iClu);
+      Int_t cfm=0; for(Int_t iDig=0;iDig<pClu->Size();iDig++)  cfm+=pClu->Dig(iDig)->Ch(); //collect ckov-fee-mip structure of current cluster ?????
       Int_t iNckov=cfm/1000000;      Int_t iNfee =cfm%1000000/1000;      Int_t iNmip =cfm%1000000%1000; 
 
                                              pQ   ->Fill(pClu->Q()) ; pS   ->Fill(pClu->Size()) ; pM    ->Fill(pClu->X(),pClu->Y()); //all clusters                                      
@@ -76,6 +73,7 @@ void AliRICHReconstructor::CluQA(AliRunLoader *pAL)
       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   
+    pCluLst->Clear();delete pCluLst;
   }//events loop
   
   pRL->UnloadDigits(); pAL->UnloadKinematics(); pAL->UnloadHeader();
@@ -85,68 +83,52 @@ void AliRICHReconstructor::CluQA(AliRunLoader *pAL)
   pC->cd(7); pCerM->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  
+// Finds all clusters for a given digits list provided not empty. Currently digits list is a list of all digits for a single chamber.
+// Puts all found clusters in separate lists, one per clusters. 
+// 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 index
+  TMatrixF digMap(AliRICHDigit::kPadAllX,AliRICHDigit::kPadAllY);  digMap=(Float_t)-1;     //digit map for single chamber reseted to -1
+  for(Int_t iDig=0;iDig<pDigLst->GetEntriesFast();iDig++){                                 //digits loop to fill digits map
+    AliRICHDigit *pDig= (AliRICHDigit*)pDigLst->At(iDig);                                  //get current digit
+    digMap( pDig->PadX(), pDig->PadY() )=iDig;                                             //fill the map, (padx,pady) cell takes digit index
   }                                                                                        //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
+  for(Int_t iDig=0;iDig<pDigLst->GetEntriesFast();iDig++){                                 //digits loop to form clusters list
+    AliRICHDigit *pDig=(AliRICHDigit*)pDigLst->At(iDig);                                   //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
+// 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++)
+  
+  Int_t iPadCnt=0;  Int_t iPadX=pDig->PadX(); Int_t iPadY=pDig->PadY();
+  if(iPadX != AliRICHDigit::kPad1)     {x[iPadCnt]=iPadX-1; y[iPadCnt]=iPadY;   iPadCnt++;}       //left
+  if(iPadX != AliRICHDigit::kPadPcX)   {x[iPadCnt]=iPadX+1; y[iPadCnt]=iPadY;   iPadCnt++;}       //right
+  if(iPadY != AliRICHDigit::kPad1)     {x[iPadCnt]=iPadX;   y[iPadCnt]=iPadY-1; iPadCnt++;}       //down
+  if(iPadY != AliRICHDigit::kPadPcY)   {x[iPadCnt]=iPadX;   y[iPadCnt]=iPadY+1; iPadCnt++;}       //up
+  
+  for (Int_t i=0;i<iPadCnt;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
@@ -161,9 +143,9 @@ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL)const
   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
+    
+    for(Int_t iCh=0;iCh<7;iCh++) Dig2Clu(pRich->DigLst(iCh),pRich->CluLst(iCh));//cluster finder 
+      
     pRL->TreeR()->Fill();            //fill tree for current event
     pRL->WriteRecPoints("OVERWRITE");//write out clusters for current event
     pRich->DigReset(); pRich->CluReset();
@@ -184,7 +166,6 @@ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const
   AliLoader *pRL=pAL->GetDetectorLoader("RICH");  AliRICH *pRich=(AliRICH*)pAL->GetAliRun()->GetDetector("RICH");//get pointers for RICH and RICH loader
   
   AliRICHDigit dig; //tmp digit, raw digit will be converted to it
-  TClonesArray *pDigList=new TClonesArray("AliRICHDigit"); Int_t iDigCnt=0; //tmp list of digits for single chamber only
   
   Int_t iEvtN=0;
   while(pRR->NextEvent()){//events loop
@@ -192,17 +173,18 @@ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const
     pRL->MakeTree("R");  pRich->MakeBranch("R");
     
     for(Int_t iChN=1;iChN<=7;iChN++){//chambers loop
+      TClonesArray *pDigLst=new TClonesArray("AliRICHDigit"); Int_t iDigCnt=0; //tmp list of digits for single chamber
       pRR->Select("RICH",2*iChN-2,2*iChN-1);//select only DDL files for the current chamber      
       UInt_t w32=0;
       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.C(),dig.S(),dig.PadX(),dig.PadY(),dig.Qdc()));
-        new((*pDigList)[iDigCnt++]) AliRICHDigit(dig); //add this digit to the tmp list
+        dig.ReadRaw(ddl,w32);  
+        AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iChN,ddl,w32,dig.Ch(),dig.Pc(),dig.PadX(),dig.PadY(),dig.Q()));
+        new((*pDigLst)[iDigCnt++]) AliRICHDigit(dig); //add this digit to the tmp list
       }//raw records loop
-      if(iDigCnt) Dig2Clu(pDigList,pRich->Clus(iChN));//cluster finder for the current chamber if any digits present
+      if(iDigCnt) Dig2Clu(pDigLst,pRich->CluLst(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
+      pDigLst->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
@@ -211,64 +193,6 @@ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const
   pRL->UnloadRecPoints();  
 }//Reconstruct raw data
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-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(AliRICHDigit::P2A(c=1,padx= 89,pady=13),qdc= 10);
-  new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 90,pady=13),qdc=  7);
-  new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 90,pady=12),qdc=  6);
-  new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 91,pady=12),qdc=  7);
-//mip cluster  
-  new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 99,pady=21),qdc=  9);
-  new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 99,pady=22),qdc= 26);
-  new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx=100,pady=21),qdc= 39);
-  new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx=100,pady=22),qdc=109);
-  new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx=100,pady=23),qdc=  7);
-  new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx=101,pady=22),qdc= 11);
-  
-  Printf("Initial digits (1 ckov cluster and 1 mip cluster):"); pDigTst->Print();
-  Dig2Clu(pDigTst,pCluTst,isTryUnfold);   
-  Printf("Resulting clusters (expecting to have 2):"); pCluTst->Print(); 
-  delete pDigTst; delete pCluTst;
-}//Test()
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICHReconstructor::Test(TClonesArray *pDigLst,Bool_t isTryUnfold)
-{
-// Test the cluster finding algorithm for given list of digits. Note that list of digits will not be deleted.
-// Arguments: pDigLst- list of digits
-//   Returns: none  
-  TClonesArray *pCluLst=new TClonesArray("AliRICHCluster");     
-  Dig2Clu(pDigLst,pCluLst,isTryUnfold);   
-  
-  Int_t iNdig=pDigLst->GetEntriesFast();
-  Int_t iNclu=pCluLst->GetEntriesFast();
-  
-  TH2F *pH2=new TH2F("RDH2",Form("Tst dig->clu Digs: %i Clus: %i;cm;cm",iNdig,iNclu),AliRICHParam::NpadsX(),0,AliRICHParam::PcSizeX(),AliRICHParam::NpadsY(),0,AliRICHParam::PcSizeY());
-  pH2->SetStats(kFALSE);
-  for(Int_t iDig=0;iDig < iNdig;iDig++) {//digits loop
-    AliRICHDigit *pDig = (AliRICHDigit*)pDigLst->At(iDig);
-    TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad());
-    pH2->Fill(x2.X(),x2.Y(),pDig->Qdc());
-  }//digits loop
-  
-  TPolyMarker *pCluMarker=new TPolyMarker(iNclu); pCluMarker->SetMarkerStyle(5); pCluMarker->SetMarkerColor(kBlue);
-  for(Int_t iClu=0;iClu < iNclu;iClu++) {//clusters loop
-    AliRICHCluster *pClu = (AliRICHCluster*)pCluLst->At(iClu);
-    pCluMarker->SetNextPoint(pClu->X(),pClu->Y());
-  }//digits loop
-  
-  pH2->Draw("col");
-  pCluMarker->Draw();  
-  AliRICHParam::DrawSectors();
-  delete pCluLst;
-}//Test()
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 void AliRICHReconstructor::FillESD(AliRunLoader *, AliESD *pESD) const
 {
@@ -278,36 +202,36 @@ void AliRICHReconstructor::FillESD(AliRunLoader *, AliESD *pESD) const
 
   AliPID ppp; //needed
   Double_t pid[AliPID::kSPECIES],h[AliPID::kSPECIES];
-  Double_t refIndex=AliRICHParam::Instance()->IdxC6F14(AliRICHParam::EckovMean());
    
   for(Int_t iTrk=0;iTrk<pESD->GetNumberOfTracks();iTrk++){//ESD tracks loop
-    AliESDtrack *pTrack = pESD->GetTrack(iTrk);// get next reconstructed track
-    if(pTrack->GetRICHsignal()<=0){//RICH does not find anything reasonable for this track, assign 0.2 for all species
+    AliESDtrack *pTrk = pESD->GetTrack(iTrk);// get next reconstructed track
+    if(pTrk->GetRICHsignal()<=0){//RICH does not find anything reasonable for this track, assign 0.2 for all species
       for(Int_t iPart=0;iPart<AliPID::kSPECIES;iPart++) pid[iPart]=1.0/AliPID::kSPECIES;
-      pTrack->SetRICHpid(pid);
+      pTrk->SetRICHpid(pid);
       continue;
     } 
-    Double_t pmod = pTrack->GetP();
+    Double_t pmod = pTrk->GetP();
     Double_t hTot=0;
     for(Int_t iPart=0;iPart<AliPID::kSPECIES;iPart++){
       Double_t mass = AliPID::ParticleMass(iPart);
-      Double_t cosThetaTh = TMath::Sqrt(mass*mass+pmod*pmod)/(refIndex*pmod);
+      Double_t cosThetaTh = TMath::Sqrt(mass*mass+pmod*pmod)/(AliRICHParam::Instance()->MeanIdxRad()*pmod);
       if(cosThetaTh<1) //calculate the height of theortical theta ckov on the gaus of experimental one
-        h[iPart] =TMath::Gaus(TMath::ACos(cosThetaTh),pTrack->GetRICHsignal(),TMath::Sqrt(pTrack->GetRICHchi2()),kTRUE);
+        h[iPart] =TMath::Gaus(TMath::ACos(cosThetaTh),pTrk->GetRICHsignal(),TMath::Sqrt(pTrk->GetRICHchi2()),kTRUE);
       
       else             //beta < 1/ref. idx. => no light at all  
         h[iPart] =0 ;       
       hTot    +=h[iPart]; //total height of all theoretical heights for normalization
     }//species loop
      
-    Double_t hMin=TMath::Gaus(pTrack->GetRICHsignal()-4*TMath::Sqrt(pTrack->GetRICHchi2()),pTrack->GetRICHsignal(),TMath::Sqrt(pTrack->GetRICHchi2()),kTRUE);//5 sigma protection
+    Double_t hMin=TMath::Gaus(pTrk->GetRICHsignal()-4*TMath::Sqrt(pTrk->GetRICHchi2()),pTrk->GetRICHsignal(),TMath::Sqrt(pTrk->GetRICHchi2()),kTRUE);//5 sigma protection
     
     for(Int_t iPart=0;iPart<AliPID::kSPECIES;iPart++)//species loop to assign probabilities
       if(hTot>hMin)  
         pid[iPart]=h[iPart]/hTot;
       else                               //all theoretical values are far away from experemental one
         pid[iPart]=1.0/AliPID::kSPECIES; 
-    pTrack->SetRICHpid(pid);
+    pTrk->SetRICHpid(pid);
   }//ESD tracks loop
   //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
 }//FillESD
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index 53bcf76..136ae34 100644 (file)
@@ -31,11 +31,8 @@ public:
   //private part  
   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          Test    (Bool_t isTryUnfold=kTRUE                                                       );//test digits->clusters  conversion
-  static        void          Test    (TClonesArray *pDigLst,Bool_t isTryUnfold=kTRUE                                 );//test digits->clusters  conversion
 
   protected:
   ClassDef(AliRICHReconstructor, 0)   //class for the RICH reconstruction
index b487660..c0912ec 100644 (file)
@@ -2,6 +2,7 @@
 #include "AliRICH.h"
 #include "AliRICHRecon.h"
 #include "AliRICHParam.h"
+#include "AliRICHCluster.h"
 #include <AliESD.h>
 #include <TGeoManager.h>     //EsdQA()
 #include <TVector3.h>
@@ -27,8 +28,6 @@ AliRICHTracker::AliRICHTracker():AliTracker()
 // 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
@@ -43,7 +42,7 @@ Bool_t AliRICHTracker::GetTrackPoint(Int_t idx, AliTrackPoint& point) const
   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
+  AliRICHCluster *pClu=(AliRICHCluster*)pRich->CluLst(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;
@@ -51,7 +50,7 @@ Bool_t AliRICHTracker::GetTrackPoint(Int_t idx, AliTrackPoint& point) const
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Int_t AliRICHTracker::LoadClusters(TTree *pCluTree)
 {
-// Interface callback methode invoked from AliReconstruction::RunTracking() to load RICH clusters for RICH
+// Interface callback methode invoked from AliReconstruction::RunTracking() to load RICH clusters before PropagateBack() gets control 
 // 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;
@@ -64,265 +63,63 @@ Int_t AliRICHTracker::PropagateBack(AliESD *pESD)
 //   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;
-  Int_t nphots =0;
+  AliRICHRecon recon;                                                        //instance of reconstruction class, nothing important in ctor
    
-  for(Int_t iTrk=0;iTrk<iNtracks;iTrk++){//ESD tracks loop
-    AliESDtrack *pTrk = pESD->GetTrack(iTrk);// get next reconstructed track    
-    Double_t mom[3], pos[3];
-    pTrk->GetPxPyPz(mom); TVector3 mom3(mom[0],mom[1],mom[2]);
-    pTrk->GetXYZ(pos);    TVector3 pos3(pos[0],pos[1],pos[2]);
-    AliRICHHelix helix(pos3,mom3,(Int_t)pTrk->GetSign(),-0.1*GetBz()); //construct helix out of track running parameters  
-     //Printf(" magnetic field %f charged %f\n",GetBz(),pTrack->GetSign()); 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 mipDr=9999,mipDx=9999,mipDy=9999,mipX=9999,mipY=9999; Int_t mipQ=0;           //nearest cluster parameters
-    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<mipDr){iMipId=iClu; mipDr=dR; mipDx=dX; mipDy=dY; mipX=pClu->X(); mipY=pClu->Y(); mipQ=pClu->Q();} //current cluster is closer, overwrite data for min cluster
-    }//clusters loop for intersected chamber
+  AliRICHParam *pParam=AliRICHParam::Instance();
 
-    pTrk->SetRICHthetaPhi(helix.Ploc().Theta(),helix.Ploc().Phi()); //store track impact angles with respect to RICH planes
-    pTrk->SetRICHdxdy(mipDx,mipDy);                                 //distance between track-PC intersection and closest cluster with Qdc>100
-    pTrk->SetRICHmipXY(mipX,mipY);                                  //position of that closest cluster with Qdc>100
-    pTrk->SetRICHnclusters(1000000*mipQ);                           //charge of that closest cluster with Qdc>100 
-    
-    if(iMipId==-1)                        {pTrk->SetRICHsignal(kMipQdcCut);  continue;} //no cluster with enough QDC found
-    if(mipDr>AliRICHParam::DmatchMIP())   {pTrk->SetRICHsignal(kMipDistCut); continue;} //closest cluster with enough carge is still too far 
-  
-    pTrk->SetRICHcluster(iMipId+1000000*iChamber);                                //set mip cluster index
-    pTrk->SetRICHsignal(recon.ThetaCerenkov(&helix,pRich->Clus(iChamber),nphots));//search for mean Cerenkov angle for this track
-    pTrk->SetRICHnclusters(1000000*mipQ+nphots);                                  //on return nphots is number of photon clusters accepted in reconstruction
-    pTrk->SetRICHchi2(recon.GetRingSigma2());
-
-    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(),            mipDx,mipDy,mipDr,     pTrk->GetRICHsignal()));
-    
-//here comes PID calculations    
-//    CalcProb(pTrack->GetRICHsignal(),pTrack->GetP(),sigmaPID,richPID);
-  }//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.
-// Arguments: hn- output ntuple where to store all variables
-//   Returns: none       
-  AliDebug(1,"Start.");  
-  AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH"));
-  
-//  pRich->GetLoader()->GetRunLoader()->LoadHeader();
-  if(!pRich->GetLoader()->GetRunLoader()->TreeK()) pRich->GetLoader()->GetRunLoader()->LoadKinematics();
-  AliStack *pStack =   pRich->GetLoader()->GetRunLoader()->Stack();
-  if(!pStack) {AliDebug(1,Form("No STACK found in AliRoot"));return;}
-  Int_t iNtracks=pStack->GetNtrack();
-  AliDebug(1,Form(" Start reconstruction with %i track(s) from Stack",iNtracks));
-  
-  Double_t hnvec[20];
-  
-  Double_t b=GetFieldMap()->SolenoidField()/10;// magnetic field in Tesla
-  AliDebug(1,Form("Start with simulated %i tracks in %f Tesla field",iNtracks,b));
-  TVector3 x0(0,0,0); TVector3 p0(0,0,0);//tmp storage for AliRICHHelix
-  
-
-  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;}
-    AliDebug(1,Form(" PDG code : %i",pParticle->GetPdgCode()));
-//
-// problem of PDG code of some extra particles to be solved!!!!!!!!!
-//
-// found problem! Look in TRD directory : codes from Fluka are :
-//
-//    if ((pdg_code == 10010020) ||
-//        (pdg_code == 10010030) ||
-//        (pdg_code == 50000050) ||
-//        (pdg_code == 50000051) ||
-//        (pdg_code == 10020040)) {
-//
-    if(pParticle->GetPdgCode()>=50000050||pParticle->GetPdgCode()==0||pParticle->GetPdgCode()>10000) {AliDebug(1,Form("A photon as track... Track skipped"));continue;}
-    if(!pParticle->GetPDG()) continue;
-//
-// to be updated for us!!
-//
-    AliDebug(1,Form("Track %i is a %s with charge %i and momentum %f",
-            iTrackN,pParticle->GetPDG()->GetName(),Int_t(pParticle->GetPDG()->Charge()),pParticle->P()));
-//    if(pParticle->GetMother(0)!=-1) continue; //consider only primaries
-    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());
-    AliRICHHelix helix(x0,p0,TMath::Sign(1,(Int_t)pParticle->GetPDG()->Charge()),b);   
-    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();
-    hnvec[4]=helix.PosPc().X();
-    hnvec[5]=helix.PosPc().Y();
-    
-    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 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 
+  for(Int_t iTrk=0;iTrk<iNtracks;iTrk++){                                                        //ESD tracks loop
+    AliESDtrack *pTrk = pESD->GetTrack(iTrk);                                                    //get next reconstructed track    
+        
+    Float_t xRa=0,yRa=0,xPc=0,yPc=0,th=0,ph=0;                                                   //track intersection point and angles, LORS  
+    Int_t iCh=-1;                                                                                //intersected chamber 
+    for(Int_t i=0;i<7;i++){                                                                      //chambers loop
+      Double_t p1[3],n1[3]; pParam->Norm(i,n1); pParam->Lors2Mars(i,0,0,p1,AliRICHParam::kRad);  //point & norm  for RAD
+      Double_t p2[3],n2[3]; pParam->Norm(i,n2); pParam->Lors2Mars(i,0,0,p2,AliRICHParam::kPc);   //point & norm  for PC
+      
+      if(pTrk->Intersect(p1,n1,-GetBz())==kFALSE) continue;                                      //try to intersect track with the middle of radiator
+      if(pTrk->Intersect(p2,n2,-GetBz())==kFALSE) continue;                                      //try to intersect track with PC
+      
+      pParam->Mars2LorsVec(i,n1,th,ph);                                                          //track angles
+      pParam->Mars2Lors   (i,p1,xRa,yRa);                                                        //TRKxRAD position
+      pParam->Mars2Lors   (i,p2,xPc,yPc);                                                        //TRKxPC position
       
-    }//clusters loop for intersected chamber
+      if(AliRICHDigit::IsInside(xPc,yPc)==kFALSE) continue;                                      //not in active area  
+      iCh=i;
+      break;
+    }//chambers loop      
     
+    if(iCh==-1) continue;                                                                  //no intersection at all, go after next track
     
-    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",hnvec[9]));
-  }//stack particles loop
-  
-  pRich->GetLoader()->UnloadRecPoints();
-  AliDebug(1,"Stop.");  
-}//RecWithStack
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICHTracker::EsdQA(Bool_t isPrint)
-{
-// Reads ESD file and print out or plot some information for QA
-// Arguments: isPrint is a flag to choose between printing (isPrint = kTRUE) and plotting (isPrint = kFALSE)
-//   Returns: none
+    TClonesArray *pCluLst=pRich->CluLst(iCh);                                              //get clusters list for intersected chamber
     
-  TFile *pFile=TFile::Open("AliESDs.root","read");              if(!pFile) {Printf("ERROR: AliESDs.root does not exist!");return;} 
-  TTree *pTr=(TTree*)pFile->Get("esdTree");                     if(!pTr)   {Printf("ERROR: AliESDs.root, no ESD tree inside!");return;} 
-  AliESD *pEsd=new AliESD;  pTr->SetBranchAddress("ESD", &pEsd); 
-  
-  TH1D     *pProbEl=0,*pProbMu=0,*pProbPi=0,*pProbKa=0,*pProbPr=0,*pMom=0,*pMipQ=0; 
-  TH2F     *pThP=0,*pDxDy=0; 
-  TProfile *pChiTh=0;
-  if(!isPrint){
-    TH1::AddDirectory(kFALSE);    
-    pProbEl=new TH1D("RiProbE" ,"Prob e"       ,101  ,0   ,1.05); pProbEl->SetLineColor(kGreen); 
-    pProbPi=new TH1D("RiProbPi","Prob #pi"     ,101  ,0   ,1.05); pProbPi->SetLineColor(kRed);
-    pProbMu=new TH1D("RiProbMu","Prob #mu"     ,101  ,0   ,1.05); pProbMu->SetLineColor(kBlue);
-    pProbKa=new TH1D("RiProbK" ,"Prob K"       ,101  ,0   ,1.05);
-    pProbPr=new TH1D("RiProbP" ,"Prob p"       ,101  ,0   ,1.05);
-    pMom   =new TH1D("pMom"    ,"Track P, GeV" ,200  ,0   ,20  );
-    pMipQ  =new TH1D("RiMipQ"  ,"Mip Q, ADC"   ,2000 ,0   ,4000);
-    pThP   =new TH2F("RiThP"   ,"#theta_{Ckov} radian;P GeV"              ,65 ,-0.5,6.0,75,0,0.75); pThP->SetStats(0);
-    pDxDy  =new TH2F("RiDxDy"  ,"distance between mip and track;cm",300,-2.5,2.5, 300,-2.5,2.5);
-    pChiTh =new TProfile("RiChiTh","#chi^{2};#theta_{C}"            ,80 ,0,0.8 , -2,2);
-  }
-  
-  Int_t iEvtCnt=0,iTrkCnt=0,iGoodCnt=0;   Float_t bz=0;
-  for(Int_t iEvt=0;iEvt<pTr->GetEntries();iEvt++){//ESD events loop
-    pTr->GetEvent(iEvt); iEvtCnt++; if(isPrint) Printf("");
-    bz=pEsd->GetMagneticField()/10.;
-    for(Int_t iTrk=0;iTrk<pEsd->GetNumberOfTracks();iTrk++){//ESD tracks loop
-      AliESDtrack *pTrk=pEsd->GetTrack(iTrk); iTrkCnt++;         //get next reconstructed track and increment total tracks counter
+    Double_t    dMin=999;                                                                  //distance between track-PC intersection point and current cluster
+    Int_t   iMip=-1;                                                                       //index of cluster nearest to intersection point
+    for(Int_t iClu=0;iClu<pCluLst->GetEntries();iClu++){                                   //clusters loop for intersected chamber
+      AliRICHCluster *pClu=(AliRICHCluster*)pCluLst->At(iClu);                             //get pointer to current cluster
+      if(pClu->Q()<100) continue;                                                          //QDC is incompartible with mip, go after another one
       
-      Float_t mom           =pTrk->GetP();                       //track momentum
-      Double_t sign         =pTrk->GetSign();                    //track sign 
-      Float_t ckov          =pTrk->GetRICHsignal();              //Theta ckov for this track, rad
-      Float_t chi2          =pTrk->GetRICHchi2();                //Theta ckov error for this track, rad^2 
-      Int_t   qdc           =pTrk->GetRICHnclusters()/1000000;   //Mip candidate charge, qdc 
-      Int_t   nphot         =pTrk->GetRICHnclusters()%1000000;   //number of photon candidates
-      Float_t dx,dy;         pTrk->GetRICHdxdy(dx,dy);           //distance between mip position and track instersection
-      Float_t theta,phi;     pTrk->GetRICHthetaPhi(theta,phi);   //track inclination angles in LORS
-      Double_t pid[5];       pTrk->GetRICHpid(pid);              //pid vector
+      Float_t dX=xPc-pClu->X();                                                         //distance between current cluster and intersection point
+      Float_t dY=yPc-pClu->Y();
+      Float_t d =TMath::Sqrt(dX*dX+dY*dY);
       
-      if(ckov>0) iGoodCnt++;
-      if(isPrint){
-        TString comment;
-        if(ckov>0)                         comment="OK";
-        else if(ckov==kMipQdcCut)          comment="small QDC";
-        else if(ckov==kMipDistCut)         comment="mip too far";
-        else if(ckov==-1)                  comment="no intersection";
-        Printf("Tr=%2i Q=%4.1f P=%.3f R=%4.2f Th=%6.3f MipQ= %4i Nph=%2i" " rad Prob : e=%.4f mu=%.4f pi=%.4f K=%.4f p=%.4f %s" ,
-                     iTrk,sign,mom,TMath::Sqrt(dx*dx+dy*dy),ckov,qdc,nphot,           pid[0],pid[1],pid[2],pid[3],pid[4], comment.Data());
-      }else{//collect hists
-                                 pMom->Fill(mom); 
-        pMipQ->Fill(qdc);
-                                 pDxDy->Fill(dx,dy);
-        pThP->Fill(mom,ckov); 
-                                 pChiTh->Fill(ckov,chi2);
-        pProbEl->Fill(pid[0]); 
-                                 pProbMu->Fill(pid[1]); 
-        pProbPi->Fill(pid[2]);  
-                                 pProbKa->Fill(pid[3]);  
-        pProbPr->Fill(pid[4]); 
-      }//if plot
-    }//ESD tracks loop
-  }//ESD events loop
-  delete pEsd;  pFile->Close();//close AliESDs.root
-  
-  TString summary=Form("Events: %i Tracks %i Good RICH: %i Mag Fld %.2f Tesla",iEvtCnt,iTrkCnt,iGoodCnt,bz);
-  if(isPrint){
-    Printf(summary.Data());
-  }else{  
-    TCanvas *pC=new TCanvas("c",summary.Data()); pC->Divide(2,2);
-    TF1 *pPion = new TF1("RITheor","acos(sqrt(x*x+[0]*[0])/(x*[1]))",1.2,6); pPion->SetLineWidth(1);
-                                                                    pPion->SetParameter(1,1.292);                                  //ref idx
-    AliPID ppp;                        pPion->SetLineColor(kRed);   pPion->SetParameter(0,AliPID::ParticleMass(AliPID::kPion));    //mass
-    TF1 *pKaon = (TF1*)pPion->Clone(); pKaon->SetLineColor(kGreen); pKaon->SetParameter(0,AliPID::ParticleMass(AliPID::kKaon)); 
-    TF1 *pProt = (TF1*)pPion->Clone(); pProt->SetLineColor(kBlue);  pProt->SetParameter(0,AliPID::ParticleMass(AliPID::kProton)); 
+      if( d < dMin) {iMip=iClu; dMin=d;}                                                   //current cluster is closer, overwrite data for min cluster
+    }//clusters loop for intersected chamber    
     
-    pC->cd(1);        pDxDy->Draw();                                                                     //distance between mip and track intersection 
-    pC->cd(2);        pMipQ->Draw();
-    pC->cd(3);        pThP->Draw();       pPion->Draw("same"); pKaon->Draw("same"); pProt->Draw("same"); //Theta Ckov versus p + theoretical curves
-    pC->cd(4);        pChiTh->Draw();                                                                    //Theta Ckov error versus theta Ckov
+//                   pTrk->SetRICHtrk      (xPc,yPc,th,ph);                                  //store track info
+//    if(iMip==-1)  {pTrk->SetRICHsignal   (kMipQdcCut);  continue;}                         //no clusters with QDC more the threshold at all
     
-    TCanvas *pC2=new TCanvas("c2",summary.Data()); pC2->Divide(2,2);
-    pC2->cd(1);        pProbPi->Draw(); pProbMu->Draw("same"); pProbEl->Draw("same");
-    pC2->cd(2);        pProbKa->Draw();
-    pC2->cd(3);        pProbPr->Draw();
-    pC2->cd(4);        pMom->Draw();
-  }
-}//EsdQA()
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICHTracker::MatrixPrint(Double_t probCut)
-{
-// Reads a set of 3  ESD files from current directory and prints out the matrix of probabilities to pion kaon or proton completely blindly withou nay assumption on the contents of files.
-// Normally it implies that those 3 ESDs contain only particles of the same sort namly pions, kaons and protons in that order.  
-// Arguments: probCut - cut on probability 
-//   Returns: none
-  for(Int_t iFile=0;iFile<3;iFile++){
-    TFile *pFile=TFile::Open(Form("Esd%1i.root",iFile+1),"read"); if(!pFile) {Printf("ERROR: Esd%1i.root does not exist!",iFile+1);return;} 
-    TTree *pTr=(TTree*)pFile->Get("esdTree");                     if(!pTr)   {Printf("ERROR: Esd%1i.root, no ESD tree inside!",iFile+1);return;} 
-    AliESD *pEsd=new AliESD;  pTr->SetBranchAddress("ESD", &pEsd); 
-    Int_t iProtCnt=0,iKaonCnt=0,iPionCnt=0,iUnreconCnt=0,iTrkCnt=0; //counters
+//    AliRICHCluster *pMipClu=(AliRICHCluster*)pCluLst->At(iMip);                                             //take mip cluster 
     
-    for(Int_t iEvt=0;iEvt<pTr->GetEntries();iEvt++){//ESD events loop
-      pTr->GetEvent(iEvt);
-      iTrkCnt+=pEsd->GetNumberOfTracks();
-      for(Int_t iTrk=0;iTrk<pEsd->GetNumberOfTracks();iTrk++){//ESD tracks loop
-        AliESDtrack *pTrack = pEsd->GetTrack(iTrk);// get next reconstructed track
-        Float_t dx,dy;         pTrack->GetRICHdxdy(dx,dy);
-        Float_t theta,phi;     pTrack->GetRICHthetaPhi(theta,phi);
-        Double_t prob[5];       pTrack->GetRICHpid(prob);
-        if(pTrack->GetRICHsignal()>0){
-          if(prob[4]>probCut)                         iProtCnt++; 
-          if(prob[3]>probCut)                         iKaonCnt++;
-          if((prob[0]+prob[1]+prob[2])>probCut)       iPionCnt++;
-        } else
-          iUnreconCnt++;       
-      }//ESD tracks loop
-      
-    }//ESD events loop
-    Printf("Bz=%5.2f Events=%i Total tracks=%i No recognized tracks=%i Pion=%i Kaon=%i Proton=%i ProbCut=%.2f",
-        0.1*pEsd->GetMagneticField(),pTr->GetEntries(),iTrkCnt,iUnreconCnt,iPionCnt,iKaonCnt,iProtCnt,probCut);
-    delete pEsd;  pFile->Close();//close AliESDs.root
-  }//files loop
-}
+//                   pTrk->SetRICHmip      (pMipClu->X(),pMipClu->Y(),pMipClu->Q());          //store mip info 
+    if(dMin>1)    {pTrk->SetRICHsignal   (kMipDistCut); continue;}                            //closest cluster with enough charge is still too far 
+//                   pTrk->SetRICHcluIdx   (iCh,iMip);                                        //set mip cluster index
+  recon.SetTrack(th,ph,xRa,yRa); Int_t iNphot=0;                                              //initialize track parameters  
+                   pTrk->SetRICHsignal   (recon.CkovAngle(pCluLst,iNphot));                   //search for Cerenkov angle for this track
+                   pTrk->SetRICHchi2     (recon.CkovSigma2());                                //error squared 
+//                   pTrk->SetRICHmip      (pMipClu->X(),pMipClu->Y(),pMipClu->Q(),iMip);     //info on mip cluster + n. phot.
+    Printf("Ch=%i MIP-TRK=%5.2f cm Th=%f+-%f", iCh, dMin,pTrk->GetRICHsignal(),pTrk->GetRICHchi2());
+ }//ESD tracks loop
+  AliDebug(1,"Stop pattern recognition");
+  return 0; // error code: 0=no error;
+}//PropagateBack()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index 730deae..eb786db 100644 (file)
@@ -17,14 +17,9 @@ public:
   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()
-  //void        FillESD        (AliESD *pESD               );                  //calculate pid for RICH
   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 EsdQA       (Bool_t isPrint=kFALSE                                            );   //print QA info
-  static void MatrixPrint (Double_t probCut=0.7                                             );   //print prob matrix with cut on probability    
-  Double_t fErrPar[5];                                                                       //Temporary stored for debug purpose
   enum ETrackingFlags {kMipDistCut=-9,kMipQdcCut=-5};
 protected:
   ClassDef(AliRICHTracker,0)
index 8f7c8c8..99d9e3c 100644 (file)
 
 
 #include "AliRICHv1.h"     //class header
-#include "AliRICHParam.h"
+#include "AliRICHParam.h"  //CreateMaterials()
+#include "AliRICHHit.h"    //Hits2SDigs(),StepManager()
+#include "AliRICHDigit.h"  //CreateMaterials()
+#include "AliRawReader.h"  //Raw2SDigits()
 #include <TParticle.h>     //Hits2SDigits()
 #include <TRandom.h> 
 #include <TVirtualMC.h>    //StepManager() for gMC
 #include <AliCDBEntry.h>      //CreateMaterials()
  
 ClassImp(AliRICHv1)    
-
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHv1::AddAlignableVolumes()const
+{
+// Associates the symbolic volume name with the corresponding volume path. Interface methode from AliModule ivoked from AliMC
+// Arguments: none
+//   Returns: none   
+  for(Int_t i=0;i<7;i++)
+    gGeoManager->SetAlignableEntry(Form("/RICH/CH%i",i),Form("ALIC_1/RICH_%i",i));
+}
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHv1::CreateMaterials()
 {
@@ -49,50 +60,34 @@ void AliRICHv1::CreateMaterials()
 //   Returns: none    
   AliDebug(1,"Start v1 RICH.");
   
-  const Int_t kNbins=30;       //number of photon energy points
+  Float_t emin=5.5,emax=8.5;         //Photon energy range,[eV]
+
+  TF2 *pRaIF=new TF2("RidxRad","sqrt(1+0.554*(1239.84/x)^2/((1239.84/x)^2-5796)-0.0005*(y-20))"                                       ,emin,emax,0,50); //DiMauro mail temp 0-50 degrees C
+  TF1 *pWiIF=new TF1("RidxWin","sqrt(1+46.411/(10.666*10.666-x*x)+228.71/(18.125*18.125-x*x))"                                        ,emin,emax);      //SiO2 idx TDR p.35
+  TF1 *pGaIF=new TF1("RidxGap","1+0.12489e-6/(2.62e-4 - x*x/1239.84/1239.84)"                                                         ,emin,emax);      //?????? from where  
+
+  TF1 *pRaAF=new TF1("RabsRad","(x<7.8)*(gaus+gaus(3))+(x>=7.8)*0.0001"                                                               ,emin,emax);  //fit from DiMauro data 28.10.03 
+  pRaAF->SetParameters(3.20491e16,-0.00917890,0.742402,3035.37,4.81171,0.626309);
+  TF1 *pWiAF=new TF1("RabsWin","(x<8.2)*(818.8638-301.0436*x+36.89642*x*x-1.507555*x*x*x)+(x>=8.2)*0.0001"                            ,emin,emax);  //fit from DiMauro data 28.10.03 
+  TF1 *pGaAF=new TF1("RabsGap","(x<7.75)*6512.399+(x>=7.75)*3.90743e-2/(-1.655279e-1+6.307392e-2*x-8.011441e-3*x*x+3.392126e-4*x*x*x)",emin,emax);  //????? from where  
   
-  Float_t aAbsC6F14[kNbins]={//New values from A.DiMauro 28.10.03 total 30
-    32701.4219, 17996.1141, 10039.7281, 1799.1230, 1799.1231, 1799.1231, 1241.4091, 179.0987, 179.0986, 179.0987,
-      179.0987,   118.9800,    39.5058,   23.7244,   11.1283,    7.1573,    3.6249,   2.1236,   0.7362,   0.5348,
-        0.3387,     0.3074,     0.3050,    0.0001,    0.0001,    0.0001,    0.0001,   0.0001,   0.0001,   0.0001};    
-    
-  Float_t aAbsSiO2[kNbins]={//New values from A.DiMauro 28.10.03 total 30
-       34.4338, 30.5424, 30.2584, 31.4928, 31.7868, 17.8397, 9.3410, 6.4492, 6.1128, 5.8128,
-        5.5589,  5.2877,  5.0162,  4.7999,  4.5734,  4.2135, 3.7471, 2.6033, 1.5223, 0.9658,
-        0.4242,  0.2500,  0.1426,  0.0863,  0.0793,  0.0724, 0.0655, 0.0587, 0.0001, 0.0001};
-    
-  Float_t aQeCsI[kNbins] = {//New values from A.DiMauro 28.10.03 total 31 the last one cut to provide 30
-                            0.0002, 0.0006, 0.0007, 0.0010, 0.0049, 0.0073, 0.0104, 0.0519, 0.0936, 0.1299,
-                            0.1560, 0.1768, 0.1872, 0.1976, 0.2142, 0.2288, 0.2434, 0.2599, 0.2673, 0.2808,
-                            0.2859, 0.2954, 0.3016, 0.3120, 0.3172, 0.3224, 0.3266, 0.3328, 0.3359, 0.3390}; //0.3431};
-                              
-  Float_t aQeCsIold[kNbins]={//previous values 26 in total added 0.0001 to the 30
-    0.0002, 0.0006, 0.0007, 0.0050, 0.0075, 0.0101, 0.0243, 0.0405, 0.0689, 0.1053, 
-    0.1215, 0.1417, 0.1579, 0.1620, 0.1661, 0.1677, 0.1743, 0.1768, 0.1793, 0.1826,
-    0.1859, 0.1876, 0.1892, 0.1909, 0.2075, 0.2158, 0.0001, 0.0001, 0.0001, 0.0001 };      
-                            
-//         radiator            window             gas               metal 
-  Float_t aIdxC6F14[kNbins] , aIdxSiO2[kNbins] , aIdxCH4[kNbins] , aIdx0[kNbins]   , aIdx1[kNbins] ; 
-  Float_t                                        aAbsCH4[kNbins] , aAbsMet[kNbins]                 ;
-  Float_t                                                                            aQe1[kNbins]  ;    //QE for all but PC
-  Float_t aEckov[kNbins];  //Ckov energy in GeV
+  TF1 *pQeF =new TF1("Qe"    ,"0+(x>6.07267)*0.344811*(1-exp(-1.29730*(x-6.07267)))"                                                  ,emin,emax);  //fit from DiMauro data 28.10.03  
+
+  const Int_t kNbins=30;       //number of photon energy points
+  Float_t aEckov [kNbins]; 
+  Float_t aAbsRad[kNbins], aAbsWin[kNbins], aAbsGap[kNbins], aAbsMet[kNbins],               ;
+  Float_t aIdxRad[kNbins], aIdxWin[kNbins], aIdxGap[kNbins], aIdxMet[kNbins], aIdxPc[kNbins]; 
+  Float_t                                                    aQeAll [kNbins], aQePc [kNbins];
                             
-  
-  Double_t eCkovMin=5.5e-9,eCkovMax=8.5e-9; //in GeV
-  TF2 idxC6F14("RidxC4F14","sqrt(1+0.554*(1239.84e-9/x)^2/((1239.84e-9/x)^2-5796)-0.0005*(y-20))"   ,eCkovMin,eCkovMax,0,50); //DiMauro mail temp 0-50 degrees C
-  TF1 idxSiO2( "RidxSiO2" ,"sqrt(1+46.411/(10.666*10.666-x*x*1e18)+228.71/(18.125*18.125-x*x*1e18))",eCkovMin,eCkovMax);  //TDR p.35
-  
-  
   for(Int_t i=0;i<kNbins;i++){
-    aEckov     [i] =eCkovMin+0.1e-9*i;//Ckov energy in GeV
-    
-    aIdxC6F14  [i] =idxC6F14.Eval(aEckov[i],20);      //Simulation for 20 degress C       
-    aIdxSiO2   [i] =idxSiO2 .Eval(aEckov[i]);
-    aIdxCH4    [i] =AliRICHParam::IdxCH4   (aEckov[i]); aAbsCH4 [i]  =AliRICHParam::AbsCH4     (aEckov[i]); 
-    aAbsMet    [i] =0.0001;                              //metal has absorption probability
-    aIdx0      [i] =0;                                   //metal ref idx must be 0 in order to reflect photon
-    aIdx1      [i] =1;                                   //metal ref idx must be 1 in order to apply photon to QE conversion 
-    aQe1       [i] =1;                                   //QE for all other materials except for PC must be 1.
+    Float_t eV=emin+0.1*i;  //Ckov energy in eV
+    aEckov [i] =1e-9*eV;    //Ckov energy in GeV
+    aAbsRad[i]=pRaAF->Eval(eV); aIdxRad[i]=1.292;//pRaIF->Eval(eV,20);      //Simulation for 20 degress C       
+    aAbsWin[i]=pWiAF->Eval(eV); aIdxWin[i]=1.5787;//pWiIF->Eval(eV);
+    aAbsGap[i]=pGaAF->Eval(eV); aIdxGap[i]=1.0005;//pGaIF->Eval(eV);    aQeAll[i] =1;                     //QE for all other materials except for PC must be 1.  
+    aAbsMet[i] =0.0001;                aIdxMet[i]=0;                                             //metal ref idx must be 0 in order to reflect photon
+                                       aIdxPc [i]=1;           aQePc [i]=pQeF->Eval(eV);         //PC ref idx must be 1 in order to apply photon to QE conversion 
+                                       
   }
   
 //data from PDG booklet 2002     density [gr/cm^3] rad len [cm] abs len [cm]    
@@ -105,93 +100,82 @@ void AliRICHv1::CreateMaterials()
   Float_t       aCu= 63.55 ,                 zCu= 29 ,                                dCu=  8.96 ,   radCu=  1.43 ,   absCu= 134.9/dCu  ;
   Float_t        aW=183.84 ,                  zW= 74 ,                                 dW= 19.30 ,    radW=  0.35 ,    absW= 185.0/dW   ;
   Float_t       aAl= 26.98 ,                 zAl= 13 ,                                dAl=  2.70 ,   radAl=  8.90 ,   absAl= 106.4/dAl  ;
-    
-  Int_t   matId=0;                           //tmp material id number
-  Int_t   unsens =  0, sens=1;               //sensitive or unsensitive medium
-  Int_t   itgfld = gAlice->Field()->Integ(); //type of field intergration 0 no field -1 user in guswim 1 Runge Kutta 2 helix 3 const field along z
-  Float_t maxfld = gAlice->Field()->Max();   //max field value
-  Float_t tmaxfd = -10.0;                    //max deflection angle due to magnetic field in one step
-  Float_t deemax = - 0.2;                    //max fractional energy loss in one step   
-  Float_t stemax = - 0.1;                    //mas step allowed [cm]
-  Float_t epsil  =   0.001;                  //abs tracking precision [cm]   
-  Float_t stmin  = - 0.001;                  //min step size [cm] in continius process transport, negative value: choose it automatically
-  AliMixture(++matId,"Air"  ,aAir  ,zAir  ,dAir  ,nAir  ,wAir  ); AliMedium(kAir  ,"Air"  ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
-  AliMixture(++matId,"C6F14",aC6F14,zC6F14,dC6F14,nC6F14,wC6F14); AliMedium(kC6F14,"C6F14",matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);      
-  AliMixture(++matId,"SiO2" ,aSiO2 ,zSiO2 ,dSiO2 ,nSiO2 ,wSiO2 ); AliMedium(kSiO2 ,"SiO2" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);    
-  AliMixture(++matId,"CH4"  ,aCH4  ,zCH4  ,dCH4  ,nCH4  ,wCH4  ); AliMedium(kCH4  ,"CH4"  ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);  
-  AliMixture(++matId,"CsI"  ,aCsI  ,zCsI  ,dCsI  ,nCsI  ,wCsI  ); AliMedium(kCsI  ,"CsI"  ,matId,   sens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);//sensitive
   
-  AliMaterial(++matId,"Roha",aRoha,zRoha,dRoha,radRoha,absRoha);  AliMedium(kRoha,"Roha", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
-  AliMaterial(++matId,"Cu"  ,aCu  ,zCu  ,dCu  ,radCu  ,absCu  );  AliMedium(kCu  ,"Cu"  , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
-  AliMaterial(++matId,"W"   ,aW   ,zW   ,dW   ,radW   ,absW   );  AliMedium(kW   ,"W"   , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
-  AliMaterial(++matId,"Al"  ,aAl  ,zAl  ,dAl  ,radAl  ,absAl  );  AliMedium(kAl  ,"Al"  , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
+    Int_t   matId=0;                           //tmp material id number
+    Int_t   unsens =  0, sens=1;               //sensitive or unsensitive medium
+    Int_t   itgfld = gAlice->Field()->Integ(); //type of field intergration 0 no field -1 user in guswim 1 Runge Kutta 2 helix 3 const field along z
+    Float_t maxfld = gAlice->Field()->Max();   //max field value
+    Float_t tmaxfd = -10.0;                    //max deflection angle due to magnetic field in one step
+    Float_t deemax = - 0.2;                    //max fractional energy loss in one step   
+    Float_t stemax = - 0.1;                    //mas step allowed [cm]
+    Float_t epsil  =   0.001;                  //abs tracking precision [cm]   
+    Float_t stmin  = - 0.001;                  //min step size [cm] in continius process transport, negative value: choose it automatically
+    AliMixture(++matId,"Air"  ,aAir  ,zAir  ,dAir  ,nAir  ,wAir  ); AliMedium(kAir  ,"Air"  ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
+    AliMixture(++matId,"C6F14",aC6F14,zC6F14,dC6F14,nC6F14,wC6F14); AliMedium(kC6F14,"C6F14",matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);      
+    AliMixture(++matId,"SiO2" ,aSiO2 ,zSiO2 ,dSiO2 ,nSiO2 ,wSiO2 ); AliMedium(kSiO2 ,"SiO2" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);    
+    AliMixture(++matId,"CH4"  ,aCH4  ,zCH4  ,dCH4  ,nCH4  ,wCH4  ); AliMedium(kCH4  ,"CH4"  ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);  
+    AliMixture(++matId,"CsI"  ,aCsI  ,zCsI  ,dCsI  ,nCsI  ,wCsI  ); AliMedium(kCsI  ,"CsI"  ,matId,   sens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);//sensitive
   
-  gMC->SetCerenkov((*fIdtmed)[kC6F14]    , kNbins, aEckov, aAbsC6F14  , aQe1  , aIdxC6F14 );    
-  gMC->SetCerenkov((*fIdtmed)[kSiO2]     , kNbins, aEckov, aAbsSiO2   , aQe1  , aIdxSiO2  );    
-  gMC->SetCerenkov((*fIdtmed)[kCH4]      , kNbins, aEckov, aAbsCH4    , aQe1  , aIdxCH4   );    
-  gMC->SetCerenkov((*fIdtmed)[kCu]       , kNbins, aEckov, aAbsMet    , aQe1  , aIdx0     );    
-  gMC->SetCerenkov((*fIdtmed)[kW]        , kNbins, aEckov, aAbsMet    , aQe1  , aIdx0     ); //n=0 means reflect photons       
-  gMC->SetCerenkov((*fIdtmed)[kCsI]      , kNbins, aEckov, aAbsMet    , aQeCsI, aIdx1     ); //n=1 means convert photons    
-  gMC->SetCerenkov((*fIdtmed)[kAl]       , kNbins, aEckov, aAbsMet    , aQe1  , aIdx0     );    
+    AliMaterial(++matId,"Roha",aRoha,zRoha,dRoha,radRoha,absRoha);  AliMedium(kRoha,"Roha", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
+    AliMaterial(++matId,"Cu"  ,aCu  ,zCu  ,dCu  ,radCu  ,absCu  );  AliMedium(kCu  ,"Cu"  , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
+    AliMaterial(++matId,"W"   ,aW   ,zW   ,dW   ,radW   ,absW   );  AliMedium(kW   ,"W"   , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
+    AliMaterial(++matId,"Al"  ,aAl  ,zAl  ,dAl  ,radAl  ,absAl  );  AliMedium(kAl  ,"Al"  , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
   
-  AliDebug(1,"Stop v1 RICH.");
-  TString ttl=GetTitle();
-  if(!ttl.Contains("ShowOptics")) return; //do not plot optical curves
-  {
-  const Double_t kWidth=0.25,kHeight=0.2;  
-  const Int_t kC6F14Marker=24 , kC6F14Color=kRed;  
-  const Int_t kCH4Marker  =25 , kCH4Color  =kGreen;  
-  const Int_t kSiO2M      =26 , kSiO2Color =kBlue;  
-  const Int_t kCsIMarker  = 2 , kCsIColor  =kMagenta;  
+    gMC->SetCerenkov((*fIdtmed)[kC6F14]    , kNbins, aEckov, aAbsRad  , aQeAll , aIdxRad );    
+    gMC->SetCerenkov((*fIdtmed)[kSiO2]     , kNbins, aEckov, aAbsWin  , aQeAll , aIdxWin );    
+    gMC->SetCerenkov((*fIdtmed)[kCH4]      , kNbins, aEckov, aAbsGap  , aQeAll , aIdxGap );    
+    gMC->SetCerenkov((*fIdtmed)[kCu]       , kNbins, aEckov, aAbsMet  , aQeAll , aIdxMet );    
+    gMC->SetCerenkov((*fIdtmed)[kW]        , kNbins, aEckov, aAbsMet  , aQeAll , aIdxMet ); //n=0 means reflect photons       
+    gMC->SetCerenkov((*fIdtmed)[kCsI]      , kNbins, aEckov, aAbsMet  , aQePc  , aIdxPc  ); //n=1 means convert photons    
+    gMC->SetCerenkov((*fIdtmed)[kAl]       , kNbins, aEckov, aAbsMet  , aQeAll , aIdxMet );    
+  
+  delete pRaAF;delete pWiAF;delete pGaAF; delete pRaIF; delete pWiIF; delete pGaIF; delete pQeF;
+    AliDebug(1,"Stop v1 RICH.");
+
+  TString ttl=GetTitle(); if(!ttl.Contains("ShowOptics")) return;              //user didn't aks to plot optical curves
   
-//Ref index           
-  TGraph *pIdxC6F14=new TGraph(kNbins,aEckov,aIdxC6F14);pIdxC6F14->SetMarkerStyle(kC6F14Marker);pIdxC6F14->SetMarkerColor(kC6F14Color);
-  TGraph *pIdxSiO2 =new TGraph(kNbins,aEckov,aIdxSiO2); pIdxSiO2 ->SetMarkerStyle(kSiO2M)      ;pIdxSiO2 ->SetMarkerColor(kSiO2Color);  
-  TGraph *pIdxCH4  =new TGraph(kNbins,aEckov,aIdxCH4);  pIdxCH4  ->SetMarkerStyle(kCH4Marker)  ;pIdxCH4  ->SetMarkerColor(kCH4Color);
-  TMultiGraph *pIdxMG=new TMultiGraph("refidx","Ref index;E_{#check{C}} [GeV]");  TLegend *pIdxLe=new TLegend(0.5,0.21,0.5+kWidth,0.21+kHeight);
-  pIdxMG->Add(pIdxC6F14); pIdxLe->AddEntry(pIdxC6F14,"C6F14"  ,"p");            
-  pIdxMG->Add(pIdxSiO2) ; pIdxLe->AddEntry(pIdxSiO2 ,"SiO2"   ,"p");          
-  pIdxMG->Add(pIdxCH4)  ; pIdxLe->AddEntry(pIdxCH4  ,"CH4"    ,"p");          
-//Absorbtion
-  TGraph *pAbsC6F14=new TGraph(kNbins,aEckov,aAbsC6F14);pAbsC6F14->SetMarkerStyle(kC6F14Marker); pAbsC6F14->SetMarkerColor(kC6F14Color);
-  TGraph *pAbsSiO2 =new TGraph(kNbins,aEckov,aAbsSiO2) ;pAbsSiO2 ->SetMarkerStyle(kSiO2M)      ; pAbsSiO2 ->SetMarkerColor(kSiO2Color);
-  TGraph *pAbsCH4  =new TGraph(kNbins,aEckov,aAbsCH4)  ;pAbsCH4  ->SetMarkerStyle(kCH4Marker)  ; pAbsCH4  ->SetMarkerColor(kCH4Color);
+  const Double_t kWidth=0.25,kHeight=0.2;  
+  const Int_t kRadM=24 , kRadC=kRed;  
+  const Int_t kWinM=26 , kWinC=kBlue;  
+  const Int_t kGapM=25 , kGapC=kGreen;  
+  const Int_t kPcM = 2 , kPcC =kMagenta;  
   
-  TMultiGraph *pAbsMG=new TMultiGraph("abs","Absorption [cm];E_{#check{C}} [GeV]");  TLegend *pAbsLe=new TLegend(0.2,0.15,0.2+kWidth,0.15+kHeight);
-  pAbsMG->Add(pAbsC6F14);      pAbsLe->AddEntry(pAbsC6F14,  "C6F14"    ,"p"); 
-  pAbsMG->Add(pAbsSiO2);       pAbsLe->AddEntry(pAbsSiO2 ,  "SiO2"     ,"p"); 
-  pAbsMG->Add(pAbsCH4);        pAbsLe->AddEntry(pAbsCH4  ,  "CH4"      ,"p"); 
-//QE new and old
-  TGraph *pQeCsI   =new TGraph(kNbins,aEckov,aQeCsI);    pQeCsI   ->SetMarkerStyle(kCsIMarker);  pQeCsI   ->SetMarkerColor(kCsIColor);
-  TGraph *pQeCsIold=new TGraph(kNbins,aEckov,aQeCsIold); pQeCsIold->SetMarkerStyle(kC6F14Marker);pQeCsIold->SetMarkerColor(kC6F14Color);    
-  TMultiGraph *pCompMG=new TMultiGraph("qe","QE;E_{#check{C}} [GeV]");  TLegend *pCompLe=new TLegend(0.2,0.6,0.2+kWidth,0.6+kHeight);
-  pCompMG->Add(pQeCsI);       pCompLe->AddEntry(pQeCsI,    "QE new 30.10.03", "p");  
-  pCompMG->Add(pQeCsIold);    pCompLe->AddEntry(pQeCsIold, "QE old 01.01.02", "p");
-//transmission  
-  Float_t aTrC6F14[kNbins],aTrSiO2[kNbins],aTrCH4[kNbins],aTrTotal[kNbins];
+  Float_t aTraRad[kNbins],aTraWin[kNbins],aTraGap[kNbins],aTraTot[kNbins];
   for(Int_t i=0;i<kNbins;i++){//calculate probability for photon to survive during transversing a volume of material with absorption length  
-    aTrC6F14[i] =TMath::Exp(-AliRICHParam::RadThick() / (aAbsC6F14[i]+0.0001)); //radiator
-    aTrSiO2[i]  =TMath::Exp(-AliRICHParam::WinThick() / (aAbsSiO2[i] +0.0001)); //window
-    aTrCH4[i]   =TMath::Exp(-AliRICHParam::Pc2Win()   / (aAbsCH4[i]  +0.0001)); //from window to PC   
-    aTrTotal[i] =aTrC6F14[i]*aTrSiO2[i]*aTrCH4[i]*aQeCsI[i];
+    aTraRad[i]=TMath::Exp(-AliRICHDigit::SizeRad()/ (aAbsRad[i]+0.0001)); //radiator
+    aTraWin[i]=TMath::Exp(-AliRICHDigit::SizeWin()/ (aAbsWin[i] +0.0001)); //window
+    aTraGap[i]=TMath::Exp(-AliRICHDigit::SizeGap()/ (aAbsGap[i]  +0.0001)); //from window to PC   
+    aTraTot[i]=aTraRad[i]*aTraWin[i]*aTraGap[i]*aQePc[i];
   }
-  TGraph *pTrC6F14=new TGraph(kNbins,aEckov,aTrC6F14)  ;pTrC6F14->SetMarkerStyle(kC6F14Marker);pTrC6F14->SetMarkerColor(kC6F14Color);  
-  TGraph *pTrSiO2 =new TGraph(kNbins,aEckov,aTrSiO2)   ;pTrSiO2 ->SetMarkerStyle(kSiO2M)      ;pTrSiO2 ->SetMarkerColor(kSiO2Color);  
-  TGraph *pTrCH4  =new TGraph(kNbins,aEckov,aTrCH4)    ;pTrCH4  ->SetMarkerStyle(kCH4Marker)  ;pTrCH4  ->SetMarkerColor(kCH4Color);   
-  TGraph *pTrTotal=new TGraph(kNbins,aEckov,aTrTotal)  ;pTrTotal->SetMarkerStyle(30)          ;pTrTotal->SetMarkerColor(kYellow);  
-  TMultiGraph *pTrMG=new TMultiGraph("trans","Transmission;E_{#check{C}} [GeV]");  TLegend *pTrLe=new TLegend(0.2,0.4,0.2+kWidth,0.4+kHeight);
-  pTrMG->Add(pQeCsI);       pTrLe->AddEntry(pQeCsI,   "CsI QE", "p");  
-  pTrMG->Add(pTrC6F14);     pTrLe->AddEntry(pTrC6F14, "C6F14" , "p");  
-  pTrMG->Add(pTrSiO2);      pTrLe->AddEntry(pTrSiO2,  "SiO2"  , "p");          
-  pTrMG->Add(pTrCH4);       pTrLe->AddEntry(pTrCH4,   "CH4"   , "p");          
-  pTrMG->Add(pTrTotal);     pTrLe->AddEntry(pTrTotal, "total" , "p");          
   
+  TGraph *pRaAG=new TGraph(kNbins,aEckov,aAbsRad);pRaAG->SetMarkerStyle(kRadM);pRaAG->SetMarkerColor(kRadC);
+  TGraph *pRaIG=new TGraph(kNbins,aEckov,aIdxRad);pRaIG->SetMarkerStyle(kRadM);pRaIG->SetMarkerColor(kRadC);
+  TGraph *pRaTG=new TGraph(kNbins,aEckov,aTraRad);pRaTG->SetMarkerStyle(kRadM);pRaTG->SetMarkerColor(kRadC);  
+  
+  TGraph *pWiAG=new TGraph(kNbins,aEckov,aAbsWin);pWiAG->SetMarkerStyle(kWinM);pWiAG->SetMarkerColor(kWinC);
+  TGraph *pWiIG=new TGraph(kNbins,aEckov,aIdxWin);pWiIG->SetMarkerStyle(kWinM);pWiIG->SetMarkerColor(kWinC);  
+  TGraph *pWiTG=new TGraph(kNbins,aEckov,aTraWin);pWiTG->SetMarkerStyle(kWinM);pWiTG->SetMarkerColor(kWinC);  
+  
+  TGraph *pGaAG=new TGraph(kNbins,aEckov,aAbsGap);pGaAG->SetMarkerStyle(kGapM);pGaAG->SetMarkerColor(kGapC);
+  TGraph *pGaIG=new TGraph(kNbins,aEckov,aIdxGap);pGaIG->SetMarkerStyle(kGapM);pGaIG->SetMarkerColor(kGapC);
+  TGraph *pGaTG=new TGraph(kNbins,aEckov,aTraGap);pGaTG->SetMarkerStyle(kGapM);pGaTG->SetMarkerColor(kGapC);   
+  
+  TGraph *pQeG =new TGraph(kNbins,aEckov,aQePc);  pQeG  ->SetMarkerStyle(kPcM );pQeG->SetMarkerColor(kPcC);
+  TGraph *pToG =new TGraph(kNbins,aEckov,aTraTot);pToG  ->SetMarkerStyle(30)   ;pToG->SetMarkerColor(kYellow);  
+  
+  TMultiGraph *pIdxMG=new TMultiGraph("idx","Ref index;E_{#check{C}} [GeV]");       
+  TMultiGraph *pAbsMG=new TMultiGraph("abs","Absorption [cm];E_{#check{C}} [GeV]"); 
+  TMultiGraph *pTraMG=new TMultiGraph("tra","Transmission;E_{#check{C}} [GeV]");    TLegend *pTraLe=new TLegend(0.2,0.4,0.2+kWidth,0.4+kHeight);
+  pAbsMG->Add(pRaAG);  pIdxMG->Add(pRaIG);     pTraMG->Add(pRaTG);     pTraLe->AddEntry(pRaTG, "Rad", "p");           
+  pAbsMG->Add(pWiAG);  pIdxMG->Add(pWiIG);     pTraMG->Add(pWiTG);     pTraLe->AddEntry(pWiTG, "Win", "p");               
+  pAbsMG->Add(pGaAG);  pIdxMG->Add(pGaIG);     pTraMG->Add(pGaTG);     pTraLe->AddEntry(pGaTG, "Gap", "p");               
+                                               pTraMG->Add(pToG);      pTraLe->AddEntry(pToG,  "Tot", "p");          
+                                               pTraMG->Add(pQeG);      pTraLe->AddEntry(pQeG,   "QE" , "p");  
   TCanvas *pC=new TCanvas("c1","RICH optics to check",1100,900);  pC->Divide(2,2);           
-  pC->cd(1);                    pIdxMG ->Draw("AP");  pIdxLe ->Draw();      //ref idx       
-  pC->cd(2);  gPad->SetLogy();  pAbsMG ->Draw("AP");  pAbsLe ->Draw();      //absorption
-  pC->cd(3);                    pCompMG->Draw("AP");  pCompLe->Draw();      //QE      
-  pC->cd(4);                    pTrMG  ->Draw("AP");  pTrLe  ->Draw();      //transmission
-  }
+  pC->cd(1);                    pIdxMG->Draw("AP"); 
+  pC->cd(2);  gPad->SetLogy();  pAbsMG->Draw("AP"); 
+  pC->cd(3);                    pTraLe->Draw();    
+  pC->cd(4);                    pTraMG->Draw("AP");
 }//void AliRICH::CreateMaterials()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHv1::CreateGeometry()
@@ -209,18 +193,18 @@ void AliRICHv1::CreateGeometry()
   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     
   const Double_t trans[3]={490,0,0}; //center of the chamber is on window-gap surface
-  for(Int_t iCh=1;iCh<=7;iCh++){//place 7 chambers
+  for(Int_t iCh=0;iCh<7;iCh++){//place 7 chambers
     TGeoHMatrix *pMatrix=new TGeoHMatrix;
     pMatrix->RotateY(90);           //rotate around y since initial position is in XY plane -> now in YZ plane
     pMatrix->SetTranslation(trans); //now plane in YZ is shifted along x 
     switch(iCh){
-      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 
+      case 0:                pMatrix->RotateY(kAngHor);  pMatrix->RotateZ(-kAngVer);  break; //right and down 
+      case 1:                                            pMatrix->RotateZ(-kAngVer);  break; //down              
+      case 2:                pMatrix->RotateY(kAngHor);                               break; //right 
+      case 3:                                                                         break; //no rotation
+      case 4:                pMatrix->RotateY(-kAngHor);                              break; //left   
+      case 5:                                            pMatrix->RotateZ(kAngVer);   break; //up
+      case 6:                pMatrix->RotateY(-kAngHor); pMatrix->RotateZ(kAngVer);   break; //left and up 
     }
     pMatrix->RotateZ(kAngCom);     //apply common rotation  in XY plane    
     gGeoManager->GetVolume("ALIC")->AddNode(pRich,iCh,pMatrix);
@@ -234,12 +218,12 @@ void AliRICHv1::CreateGeometry()
   par[0]=114*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("RppfSmall","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("Rppf",0,"RICH",    -335*mm,      -433*mm,  8*cm+20*mm,  0,"ONLY");//F1 2040P1 z p.84 TDR
+  gMC->Gspos("Rppf",1,"RICH",    +335*mm,      -433*mm,  8*cm+20*mm,  0,"ONLY");
+  gMC->Gspos("Rppf",2,"RICH",    -335*mm,         0*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,      +433*mm,  8*cm+20*mm,  0,"ONLY");
+  gMC->Gspos("Rppf",5,"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("RppfLarge",1,"Rppf",  -224.5*mm,  -151.875*mm,     0.85*mm,  0,"ONLY");
     gMC->Gspos("RppfLarge",2,"Rppf",  -224.5*mm,  - 50.625*mm,     0.85*mm,  0,"ONLY");
@@ -262,12 +246,12 @@ void AliRICHv1::CreateGeometry()
   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"); 
+  gMC->Gspos("Rgap",0,"RICH",    -335*mm,      -433*mm,8*cm-2.225*mm, 0,"ONLY"); //F1 2040P1 z WP 2099P1
+  gMC->Gspos("Rgap",1,"RICH",    +335*mm,      -433*mm,8*cm-2.225*mm, 0,"ONLY"); 
+  gMC->Gspos("Rgap",2,"RICH",    -335*mm,         0*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,      +433*mm,8*cm-2.225*mm, 0,"ONLY"); 
+  gMC->Gspos("Rgap",5,"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  
 //Defines radiators geometry  
@@ -334,18 +318,13 @@ Bool_t AliRICHv1::IsLostByFresnel()
     return kFALSE;
 }//IsLostByFresnel()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-void AliRICHv1::GenFee(Int_t iChamber,Float_t eloss)
+void AliRICHv1::GenFee(Int_t iCh,Float_t eloss)
 {
 // Generate FeedBack photons for the current particle. To be invoked from StepManager().
 // eloss=0 means photon so only pulse height distribution is to be analysed. This one is done in AliRICHParam::TotQdc()
-  
   TLorentzVector x4;
-  gMC->TrackPosition(x4);  
-  TVector2 x2=AliRICHParam::Instance()->Mars2Lors(iChamber,x4.Vect(),AliRICHParam::kPc);//hit position on photocathode plane
-  TVector2 xspe=x2;
-  Int_t sector=AliRICHParam::Loc2Sec(xspe);  if(sector==-1) return; //hit in dead zone, nothing to produce
-  Int_t iTotQdc=AliRICHParam::TotQdc(x2,eloss);
-  Int_t iNphotons=gMC->GetRandom()->Poisson(AliRICHParam::AlphaFeedback(iChamber,sector)*iTotQdc);    
+  gMC->TrackPosition(x4); 
+  Int_t iNphotons=gMC->GetRandom()->Poisson(0.02*200); eloss++; iCh++;   //??????????????????????
   AliDebug(1,Form("N photons=%i",iNphotons));
   Int_t j;
   Float_t cthf, phif, enfp = 0, sthf, e1[3], e2[3], e3[3], vmod, uswop,dir[3], phi,pol[3], mom[4];
@@ -413,57 +392,50 @@ void AliRICHv1::GenFee(Int_t iChamber,Float_t eloss)
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHv1::Hits2SDigits()
 {
-// Create a list of sdigits corresponding to list of hits. Every hit generates one or more sdigits.
+// Interface methode ivoked from AliSimulation to create a list of sdigits corresponding to list of hits. Every hit generates one or more sdigits.
+// Arguments: none
+//   Returns: none   
   AliDebug(1,"Start.");
-  for(Int_t iEventN=0;iEventN<GetLoader()->GetRunLoader()->GetAliRun()->GetEventsPerRun();iEventN++){//events loop
-    GetLoader()->GetRunLoader()->GetEvent(iEventN);//get next event
+  for(Int_t iEvt=0;iEvt < GetLoader()->GetRunLoader()->GetNumberOfEvents();iEvt++){                //events loop
+    GetLoader()->GetRunLoader()->GetEvent(iEvt);                          //get next event
   
-    if(!GetLoader()->TreeH()) GetLoader()->LoadHits();    GetLoader()->GetRunLoader()->LoadHeader(); 
-    if(!GetLoader()->GetRunLoader()->TreeK())             GetLoader()->GetRunLoader()->LoadKinematics();//from
-    if(!GetLoader()->TreeS()) GetLoader()->MakeTree("S"); MakeBranch("S");//to
+    if(!GetLoader()->TreeH()) {GetLoader()->LoadHits();                    }
+    if(!GetLoader()->TreeS()) {GetLoader()->MakeTree("S"); MakeBranch("S");}//to
           
     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++){//hits loop 
-        AliRICHHit *pHit=(AliRICHHit*)Hits()->At(iHitN);//get current hit                
-        TVector2 x2 = AliRICHParam::Instance()->Mars2Lors(pHit->C(),0.5*(pHit->InX3()+pHit->OutX3()),AliRICHParam::kAnod);//hit position in the anod plane
-        Int_t iTotQdc=AliRICHParam::TotQdc(x2,pHit->Eloss());//total charge produced by hit, 0 if hit in dead zone
-        if(iTotQdc==0) continue;
-        //
-        //need to quantize the anod....
-        TVector padHit=AliRICHParam::Loc2Pad(x2);
-        TVector2 padHitXY=AliRICHParam::Pad2Loc(padHit);
-        TVector2 anod;
-        if((x2.Y()-padHitXY.Y())>0) anod.Set(x2.X(),padHitXY.Y()+AliRICHParam::AnodPitch()/2);
-        else anod.Set(x2.X(),padHitXY.Y()-AliRICHParam::AnodPitch()/2);
-        //end to quantize anod
-        //
-        TVector area=AliRICHParam::Loc2Area(anod);//determine affected pads, dead zones analysed inside
-        AliDebug(1,Form("hitanod(%6.2f,%6.2f)->area(%3.0f,%3.0f)-(%3.0f,%3.0f) QDC=%4i",anod.X(),anod.Y(),area[0],area[1],area[2],area[3],iTotQdc));
-        TVector pad(2);
-        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 padQdc=iTotQdc*AliRICHParam::FracQdc(anod,pad);
-            AliDebug(1,Form("current pad(%3.0f,%3.0f) with QDC  =%6.2f",pad[0],pad[1],padQdc));
-            if(padQdc>0.1) SDigAdd(pHit->C(),pad,padQdc,GetLoader()->GetRunLoader()->Stack()->Particle(pHit->GetTrack())->GetPdgCode(),pHit->GetTrack());
-          }//affected pads loop 
-      }//hits loop
+      Hit2Sdi(Hits(),SdiLst());
     }//prims loop
     GetLoader()->TreeS()->Fill();
     GetLoader()->WriteSDigits("OVERWRITE");
-    SDigReset();
+    SdiReset();
   }//events loop  
-  GetLoader()->UnloadHits(); GetLoader()->GetRunLoader()->UnloadHeader(); GetLoader()->GetRunLoader()->UnloadKinematics();
+  GetLoader()->UnloadHits();
   GetLoader()->UnloadSDigits();  
   AliDebug(1,"Stop.");
 }//Hits2SDigits()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliRICHv1::Hit2Sdi(TClonesArray *pHitLst,TClonesArray *pSdiLst)
+{
+// Converts list of hits to list of sdigits.  For each hit in a loop the following steps are done:
+// - calcultion of the total charge induced by the hit
+// - determination of the pad contaning the hit and shifting hit y position to the nearest anod wire y
+// - defining a set of pads affected (up to 9 including the hitted pad)    
+// - calculating charge induced to all those pads using integrated Mathieson distribution and creating sdigit  
+// Arguments: pHitLst  - list of hits provided not empty
+//            pSDigLst - list of sdigits where to store the results
+//   Returns: none         
+  for(Int_t iHit=0;iHit<pHitLst->GetEntries();iHit++){         //hits loop
+    AliRICHHit *pHit=(AliRICHHit*)pHitLst->At(iHit);           //get pointer to current hit   
+    AliRICHDigit::Hit2Sdi(pHit,pSdiLst);                       //convert this hit to list of sdigits     
+  }//hits loop loop
+}//Hits2SDigs() for TVector2
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHv1::Digits2Raw()
 {
-//Creates raw data files in DDL format. Invoked by AliSimulation
-//loop over events is done outside in AliSimulation
-//Arguments: none
-//  Returns: none    
+// Creates raw data files in DDL format. Invoked by AliSimulation where loop over events is done
+// Arguments: none
+//   Returns: none    
   AliDebug(1,"Start.");
   GetLoader()->LoadDigits();
   GetLoader()->TreeD()->GetEntry(0);
@@ -473,22 +445,22 @@ void AliRICHv1::Digits2Raw()
   AliRawDataHeader header; //empty DDL header
   UInt_t w32=0;            //32 bits data word 
   
-  for(Int_t i=0;i<AliRICHDigit::kNddls;i++){//open all 14 DDL in parallel
-    file[i].open(AliDAQ::DdlFileName("RICH",i));
-    file[i].write((char*)&header,sizeof(header));                //write dummy header as place holder, actual will be written later when total size of DDL is known
-    cnt[i]=0; //reset counters
+  for(Int_t i=0;i<AliRICHDigit::kNddls;i++){        
+    file[i].open(AliDAQ::DdlFileName(GetName(),i)); //open all 14 DDL in parallel
+    file[i].write((char*)&header,sizeof(header));   //write dummy header as place holder, actual will be written later when total size of DDL is known
+    cnt[i]=0;                                       //reset counters
   }
   
-  for(Int_t iCh=0;iCh<fNcham;iCh++){ //digits are stored on chamber by chamber basis   
-    TClonesArray *pDigs=(TClonesArray*)fDig->UncheckedAt(iCh);
-    for(Int_t iDig=0;iDig<pDigs->GetEntriesFast();iDig++){//digits loop for a given chamber
-      AliRICHDigit *pDig=(AliRICHDigit*)pDigs->At(iDig);
-      Int_t ddl=pDig->Dig2Raw(w32);  //ddl is 0..13 
+  for(Int_t iCh=0;iCh<7;iCh++)
+    for(Int_t iDig=0;iDig<DigLst(iCh)->GetEntriesFast();iDig++){//digits loop for a given chamber
+      AliRICHDigit *pDig=(AliRICHDigit*)DigLst(iCh)->At(iDig);
+      Int_t ddl=pDig->Raw(w32);                             //ddl is 0..13 
       file[ddl].write((char*)&w32,sizeof(w32));  cnt[ddl]++;//write formated digit to the propriate file (as decided in Dig2Raw) and increment corresponding counter
-    }//digits loop for a given chamber
-  }//chambers loop    
+    }//digits 
+    
+    
   for(Int_t i=0;i<AliRICHDigit::kNddls;i++){
-    header.fSize=sizeof(header)+cnt[i]*sizeof(w32); //now calculate total number of bytes for each DDL file  
+    header.fSize=sizeof(header)+cnt[i]*sizeof(w32);                //now calculate total number of bytes for each DDL file  
     header.SetAttribute(0); 
     file[i].seekp(0); file[i].write((char*)&header,sizeof(header));//rewrite DDL header with fSize field properly set
     file[i].close();                                               //close DDL file
@@ -559,28 +531,33 @@ void AliRICHv1::Print(Option_t *option)const
 {
 // Debug printout
   TObject::Print(option);
-  Printf("Total number of MIP reached radiator        %9i",fCounters(kMipEnterRad));
-  Printf("Total number of Ckov created                %9i",fCounters(kCkovNew));
-  Printf("number of Ckov created in radiator          %9i",fCounters(kCkovNewRad));
-  Printf("number of Ckov created in window            %9i",fCounters(kCkovNewWin));
-  Printf("number of Ckov created in proximity gap     %9i",fCounters(kCkovNewProxGap));
-  Printf("number of Ckov created in amplification gap %9i",fCounters(kCkovNewAmpGap));
-  Printf("number of Ckov reached PC                   %9i",fCounters(kCkovEnterPc));
-  Printf("number of photelectrons                     %9i",fCounters(kPhotoEle));
 }//void AliRICH::Print(Option_t *option)const
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliRICHv1::Raw2SDigits(AliRawReader *pRR)
+{
+// Interface methode ivoked from AliSimulation to create a list of sdigits from raw digits. Events loop is done in AliSimulation
+// Arguments: pRR- raw reader 
+//   Returns: kTRUE on success (currently ignored in AliSimulation::ConvertRaw2SDigits())      
+  AliRICHDigit sdi; //tmp sdigit, raw digit will be converted to it
+  
+  if(!GetLoader()->TreeS()) {MakeTree("S");  MakeBranch("S");}
+    
+  TClonesArray *pSdiLst=SdiLst(); Int_t iSdiCnt=0; //tmp list of sdigits for all chambers
+  pRR->Select("RICH",0,13);//select all RICH DDL files
+  UInt_t w32=0;
+  while(pRR->ReadNextInt(w32)){//raw records loop (in selected DDL files)
+    UInt_t ddl=pRR->GetDDLID(); //returns 0,1,2 ... 13
+    sdi.ReadRaw(ddl,w32);  
+    new((*pSdiLst)[iSdiCnt++]) AliRICHDigit(sdi); //add this digit to the tmp list
+  }//raw records loop
+  GetLoader()->TreeS()->Fill(); GetLoader()->WriteSDigits("OVERWRITE");//write out sdigits
+  SdiReset();
+  return kTRUE;
+}//Raw2SDigits
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHv1::StepCount()
 {
 // Count number of ckovs created  
-  Int_t copy;
-  if(gMC->TrackCharge()        &&gMC->CurrentVolID(copy)==fIdRad    &&gMC->IsTrackEntering()                ) fCounters(kMipEnterRad)++;  
-  if(gMC->TrackPid()==kCerenkov                                     &&gMC->IsNewTrack()                     ) fCounters(kCkovNew)++;      
-  if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdRad    &&gMC->IsNewTrack()                     ) fCounters(kCkovNewRad)++;   
-  if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdWin    &&gMC->IsNewTrack()                     ) fCounters(kCkovNewWin)++;   
-  if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdProxGap&&gMC->IsNewTrack()                     ) fCounters(kCkovNewProxGap)++;
-  if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdAmpGap &&gMC->IsNewTrack()                     ) fCounters(kCkovNewAmpGap)++;
-  if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdPc     &&gMC->IsTrackEntering()                ) fCounters(kCkovEnterPc)++;  
-  if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdPc     &&gMC->IsTrackEntering() &&gMC->Edep()>0) fCounters(kPhotoEle)++;       
 }
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 void AliRICHv1::StepHistory()
@@ -634,34 +611,42 @@ void AliRICHv1::StepManager()
 //  StepHistory(); return; //uncomment to print tracks history
 //  StepCount(); return;     //uncomment to count photons
   
-  Int_t          copy; //volume copy aka node
-  static Int_t   iCham;
+  Int_t   copy; //volume copy aka node
+  
 //Treat photons    
-  static TLorentzVector cerX4;
-  if((gMC->TrackPid()==kCerenkov||gMC->TrackPid()==kFeedback)&&gMC->CurrentVolID(copy)==fIdPc){//photon in PC
-    if(gMC->Edep()>0){//photon survided QE test i.e. produces electron
-      if(IsLostByFresnel()){ gMC->StopTrack(); return;} //photon lost due to fersnel reflection        
-      gMC->TrackPosition(cerX4); gMC->CurrentVolOffID(2,iCham);//RICH-Rppf-Rpc
-      HitAdd(iCham,gMC->GetStack()->GetCurrentTrackNumber(),gMC->TrackPid(),cerX4.Vect(),cerX4.Vect());//HIT for PHOTON in conditions CF+CSI+DE
-      GenFee(iCham);
-    }//photon in PC and DE >0 
-  }//photon in PC
+  if((gMC->TrackPid()==kCerenkov||gMC->TrackPid()==kFeedback)&&gMC->CurrentVolID(copy)==fIdPc){  //photon (Ckov or feedback) hit PC (fIdPc)
+    if(gMC->Edep()>0){                                                                           //photon survided QE test i.e. produces electron
+      if(IsLostByFresnel()){ gMC->StopTrack(); return;}                                          //photon lost due to fersnel reflection on PC       
+                       gMC->CurrentVolOffID(2,copy);                                             //current chamber since geomtry tree is RICH-Rppf-Rpc
+      Int_t   tid=     gMC->GetStack()->GetCurrentTrackNumber();                                 //take TID
+      Int_t   pid=     gMC->TrackPid();                                                          //take PID
+      Float_t etot=    gMC->Etot();                                                              //total hpoton energy, [GeV] 
+      Double_t x[3];   gMC->TrackPosition(x[0],x[1],x[2]);                                       //take MARS position at entrance to PC
+      Float_t xl,yl;   AliRICHParam::Instance()->Mars2Lors(copy,x,xl,yl);                        //take LORS position
+      new((*fHits)[fNhits++])AliRICHHit(copy,etot,pid,tid,xl,yl,x);                              //HIT for photon, position at PC
+      GenFee(copy);                                                                              //generate feedback photons
+    }//photon hit PC and DE >0 
+  }//photon hit PC
   
 //Treat charged particles  
-  static Float_t eloss;
-  static TLorentzVector mipInX4,mipOutX4;
-  if(gMC->TrackCharge() && gMC->CurrentVolID(copy)==fIdAmpGap){//MIP in amplification gap
-    gMC->CurrentVolOffID(1,iCham);//RICH-Rgap
-    if(gMC->IsTrackEntering()||gMC->IsNewTrack()) {//MIP in GAP entering or newly created
-      eloss=0;                                                           
-      gMC->TrackPosition(mipInX4);
-    }else if(gMC->IsTrackExiting()||gMC->IsTrackStop()||gMC->IsTrackDisappeared()){//MIP in GAP exiting or disappeared
-      eloss+=gMC->Edep();//take into account last step dEdX
-      gMC->TrackPosition(mipOutX4);  
-      HitAdd(iCham,gMC->GetStack()->GetCurrentTrackNumber(),gMC->TrackPid(),mipInX4.Vect(),mipOutX4.Vect(),eloss);//HIT for MIP: MIP in GAP Exiting
-      GenFee(iCham,eloss);//MIP+GAP+Exit
-    }else//MIP in GAP going inside
-      eloss   += gMC->Edep();
+  static Double_t dEdX;                                                                           //need to store mip parameters between different steps    
+  static Double_t in[3];
+  if(gMC->TrackCharge() && gMC->CurrentVolID(copy)==fIdAmpGap){                                   //charged particle in amplification gap (fIdAmpGap)
+    if(gMC->IsTrackEntering()||gMC->IsNewTrack()) {                                               //entering or newly created
+      dEdX=0;                                                                                     //reset dEdX collector                         
+      gMC->TrackPosition(in[0],in[1],in[2]);                                                      //take position at the entrance
+    }else if(gMC->IsTrackExiting()||gMC->IsTrackStop()||gMC->IsTrackDisappeared()){               //exiting or disappeared
+      dEdX              +=gMC->Edep();                                                            //take into account last step dEdX
+                          gMC->CurrentVolOffID(1,copy);                                           //take current chamber since geometry tree is RICH-Rgap
+      Int_t tid=          gMC->GetStack()->GetCurrentTrackNumber();                               //take TID
+      Int_t pid=          gMC->TrackPid();                                                        //take PID
+      Double_t out[3];    gMC->TrackPosition(out[0],out[1],out[2]);                               //take MARS position at exit
+      out[0]=0.5*(out[0]+in[0]); out[1]=0.5*(out[1]+in[1]); out[1]=0.5*(out[1]+in[1]);            //take hit position at the anod plane
+      Float_t xl,yl;AliRICHParam::Instance()->Mars2Lors(copy,out,xl,yl);                          //take LORS position
+      new((*fHits)[fNhits++])AliRICHHit(copy,dEdX,pid,tid,xl,yl,out);                             //HIT for MIP, position near anod plane 
+      GenFee(copy,dEdX);                                                                          //generate feedback photons
+    }else                                                                                         //just going inside
+      dEdX          += gMC->Edep();                                                               //collect this step dEdX 
   }//MIP in GAP
 }//StepManager()
 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index 1ad850b..ded555d 100644 (file)
@@ -14,21 +14,24 @@ public:
                  AliRICHv1(const char *name, const char *title):AliRICH(name,title),fIdRad(-1),fIdWin(-1),fIdProxGap(-1),fIdAmpGap(-1),fIdPc(-1),fIdAnod(-1),fIdCath(-1),fIdColl(-1) {;}          //named ctor
   virtual       ~AliRICHv1()                                                         {;}          //dtor
 //framework part++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++