From db910db956d944a2e4c784e8718daa5d3150c87c Mon Sep 17 00:00:00 2001 From: kir Date: Tue, 28 Mar 2006 14:27:54 +0000 Subject: [PATCH] Compliance with AliAlignObj --- RICH/AliRICH.cxx | 843 +++++----------------------------- RICH/AliRICH.h | 179 +++----- RICH/AliRICHCluster.cxx | 259 +++++------ RICH/AliRICHCluster.h | 110 ++--- RICH/AliRICHClusterFinder.cxx | 363 --------------- RICH/AliRICHClusterFinder.h | 39 -- RICH/AliRICHDigit.cxx | 22 +- RICH/AliRICHDigit.h | 201 ++++---- RICH/AliRICHDigitizer.cxx | 16 +- RICH/AliRICHHelix.cxx | 43 +- RICH/AliRICHHelix.h | 118 ++--- RICH/AliRICHHit.cxx | 24 +- RICH/AliRICHHit.h | 31 +- RICH/AliRICHMap.cxx | 40 -- RICH/AliRICHMap.h | 45 -- RICH/AliRICHParam.cxx | 334 +++++++++----- RICH/AliRICHParam.h | 618 ++++++++++++++++++++----- RICH/AliRICHRecon.cxx | 372 +++++---------- RICH/AliRICHRecon.h | 59 +-- RICH/AliRICHReconstructor.cxx | 275 +++++++---- RICH/AliRICHReconstructor.h | 40 +- RICH/AliRICHTracker.cxx | 272 +++++------ RICH/AliRICHTracker.h | 42 +- RICH/AliRICHv0.cxx | 94 ---- RICH/AliRICHv1.cxx | 575 +++++++++++++++++++---- RICH/AliRICHv1.h | 35 +- RICH/Opticals.h | 252 ---------- RICH/RICHbaseLinkDef.h | 1 - RICH/RICHrecLinkDef.h | 2 - RICH/RichConfig.C | 166 +++---- RICH/RichGeom.C | 505 +++++++++++++------- RICH/RichMake | 4 +- RICH/RichMenu.C | 144 ++---- RICH/api.txt | 143 +++++- RICH/libRICHbase.pkg | 2 +- RICH/libRICHrec.pkg | 2 +- 36 files changed, 2969 insertions(+), 3301 deletions(-) delete mode 100644 RICH/AliRICHClusterFinder.cxx delete mode 100644 RICH/AliRICHClusterFinder.h delete mode 100644 RICH/AliRICHMap.cxx delete mode 100644 RICH/AliRICHMap.h delete mode 100644 RICH/Opticals.h diff --git a/RICH/AliRICH.cxx b/RICH/AliRICH.cxx index 337234a7757..4f6ac7d537d 100644 --- a/RICH/AliRICH.cxx +++ b/RICH/AliRICH.cxx @@ -15,38 +15,26 @@ #include "AliRICH.h" #include "AliRICHParam.h" -#include "AliRICHChamber.h" -#include "AliRICHHelix.h" -//#include -#include -#include -#include +#include "AliRICHHelix.h" //ReadESD #include -#include #include #include #include +#include +#include //ctor #include #include #include -#include -#include -#include -#include #include -#include -#include -#include +#include //HitQA() +#include //Display() #include #include -#include -#include -#include //Display() -#include //Display() -#include //Display() -#include //Display() -#include //Display() - +#include //Display() +#include //Display() +#include //Display() +#include //Display() +#include //Display() ClassImp(AliRICH) //__________________________________________________________________________________________________ // RICH manager class @@ -56,23 +44,21 @@ ClassImp(AliRICH) */ //END_HTML //__________________________________________________________________________________________________ -AliRICH::AliRICH():AliDetector(),fParam(0), fSdigits(0),fNsdigits(0),fDigs(0),fClus(0) +AliRICH::AliRICH():AliDetector(),fSdig(0),fSdigCnt(0),fDig(0),fClu(0) { //Default ctor should not contain any new operators //AliDetector ctor deals with Hits and Digits - for(int i=0;iGetMCApp()->AddHitList(fHits); - fCounters.ResizeTo(20); fCounters.Zero(); + HitCreate(); gAlice->GetMCApp()->AddHitList(fHits); + fNcham=7; + fCounters.ResizeTo(40); fCounters.Zero(); AliDebug(1,"Stop."); }//AliRICH::AliRICH(const char *name, const char *title) //__________________________________________________________________________________________________ @@ -81,13 +67,12 @@ AliRICH::~AliRICH() //dtor AliDebug(1,"Start."); - if(fParam) delete fParam; if(fHits) delete fHits; - if(fSdigits) delete fSdigits; + if(fSdig) delete fSdig; if(fDigits) delete fDigits; - if(fDigs) {fDigs->Delete(); delete fDigs;} - if(fClus) {fClus->Delete(); delete fClus;} + if(fDig) {fDig->Delete(); delete fDig;} + if(fClu) {fClu->Delete(); delete fClu;} AliDebug(1,"Stop."); }//AliRICH::~AliRICH() //__________________________________________________________________________________________________ @@ -96,199 +81,9 @@ void AliRICH::BuildGeometry() //Builds a TNode geometry for event display AliDebug(1,"Start."); - TNode *node, *subnode, *top; - top=gAlice->GetGeometry()->GetNode("alice"); - - Float_t widx =P()->SectorSizeX(); - Float_t leny =P()->SectorSizeY(); - Float_t dz =P()->Zfreon()+P()->Zwin()+P()->Pc2Win(); - Float_t dead =P()->DeadZone(); - - new TBRIK("RICH","RICH","void",widx+dead/2,leny+leny/2+dead,dz+0.1); //RICH chamber - new TBRIK("RPC" ,"RPC" ,"void",widx/2,leny/2,0.01); //RICH sector - - for(int i=1;i<=P()->Nchambers();i++){ - top->cd(); - node = new TNode(Form("RICH%i",i),Form("RICH%i",i),"RICH",C(i)->Center().X(),C(i)->Center().Y(),C(i)->Center().Z(),C(i)->RotMatrixName()); - node->SetLineColor(kRed); - node->cd(); - subnode = new TNode("PHOTO1","PHOTO1","RPC",-widx/2-dead/2,-leny-dead/2,dz,""); - subnode->SetLineColor(kGreen); - fNodes->Add(subnode); - subnode = new TNode("PHOTO1","PHOTO1","RPC", widx/2+dead/2,-leny-dead/2,dz,""); - subnode->SetLineColor(kGreen); - fNodes->Add(subnode); - subnode = new TNode("PHOTO1","PHOTO1","RPC",-widx/2-dead/2, 0,dz,""); - subnode->SetLineColor(kGreen); - fNodes->Add(subnode); - subnode = new TNode("PHOTO1","PHOTO1","RPC", widx/2+dead/2, 0,dz,""); - subnode->SetLineColor(kGreen); - fNodes->Add(subnode); - subnode = new TNode("PHOTO1","PHOTO1","RPC",-widx/2-dead/2, leny+dead/2,dz,""); - subnode->SetLineColor(kGreen); - fNodes->Add(subnode); - subnode = new TNode("PHOTO1","PHOTO1","RPC", widx/2+dead/2, leny+dead/2,dz,""); - subnode->SetLineColor(kGreen); - fNodes->Add(subnode); - fNodes->Add(node); - } - AliDebug(1,"Stop."); }//void AliRICH::BuildGeometry() //__________________________________________________________________________________________________ -void AliRICH::CreateMaterials() -{ -// Definition of available RICH materials - - Int_t material=0; //tmp material id number - Float_t a=0,z=0,den=0,radl=0,absl=0; //tmp material parameters - - Float_t tmaxfd=-10.0, deemax=-0.2, stemax=-0.1,epsil=0.001, stmin=-0.001; - Int_t isxfld = gAlice->Field()->Integ(); - Float_t sxmgmx = gAlice->Field()->Max(); - - Float_t aAir[4]={12,14,16,36}; Float_t zAir[4]={6,7,8,18}; Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};//total 0.9999999 - AliMixture(++material, "RichAir",aAir,zAir,den=0.00120479,4,wAir); //1 (Air) 0.01% C 75% N 23% O 1% Ar - AliMedium(kAir, "RichAir",material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - AliMixture(++material, "RichAerogel",aAir,zAir,den=P()->DenGel(),4,wAir); //Aerogel represented by Air - AliMedium(kGel, "RichAerogel",material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - AliMixture(++material, "RichAerogelReflector",aAir,zAir,den=P()->DenGel(),4,wAir); //Aerogel reflector represented by Air - AliMedium(kReflector, "RichAerogelReflector",material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - AliMaterial(++material, "RichRohacell", a=12.01,z=6.0, den=0.1, radl=18.8, absl=0); //2 Rohacell 51 C-equiv radl rad cover - AliMedium(kRoha, "RichRohacell", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - Float_t aQuartz[2]={28.09,16.0}; Float_t zQuartz[2]={14.00, 8.0}; Float_t wQuartz[2]={1,2}; - AliMixture(++material, "RichSiO2",aQuartz,zQuartz,den=2.64,-2, wQuartz); //3 Quarz (SiO2) -trasparent rad window - AliMedium(kSiO2, "RichSiO2",material, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - Float_t aFreon[2]={12,19}; Float_t zFreon[2]={6,9}; Float_t wmatFreon[2]={6,14}; // C12-6 F19-9 - AliMixture(++material, "RichC6F14",aFreon,zFreon,den=1.68,-2,wmatFreon); //4 Freon (C6F14) - AliMedium(kC6F14, "RichC6F14",material, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - Float_t aMethane[2]={12.01,1}; Float_t zMethane[2]={6,1}; Float_t wMethane[2]={1,4}; - AliMixture (++material, "RichCH4", aMethane, zMethane, den=7.17e-4,-2, wMethane); //5,9 methane (CH4) normal and for Gap - AliMedium(kCH4, "RichCH4" , material, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - AliMixture (++material, "RichCH4gap", aMethane, zMethane, den=7.17e-4,-2, wMethane); //5,9 methane (CH4) normal and for Gap - AliMedium(kGap, "RichCH4gap", material, 1, isxfld, sxmgmx, tmaxfd, 0.1 , -deemax, epsil, -stmin); - - AliMaterial(++material, "RichCsI", a=12.01,z=6.0, den=0.1, radl=18.8, absl=0); //6 CsI-radl equivalent - AliMedium(kCsI, "RichCsI", material, 1, isxfld, sxmgmx,tmaxfd, stemax, deemax, epsil, stmin); - - AliMaterial(++material, "RichGridCu", a=63.54,z=29.0,den=8.96, radl=1.43, absl=0); //7 anode grid (Cu) - AliMedium(kGridCu, "RichGridCu", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - AliMaterial(++material, "RichPcbCu", a=63.54,z=29.0,den=8.96, radl=1.4, absl=0); //12 Cu - AliMedium(kCu, "RichPcbCu", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - AliMixture (++material, "RichOpSiO2",aQuartz, zQuartz, den=2.64, -2, wQuartz); //8 Quarz (SiO2) - opaque - AliMedium(kOpSiO2, "RichOpSiO2",material, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - AliMaterial(++material, "RichAl", a=26.98,z=13.0,den=2.699, radl=8.9, absl=0); //10 aluminium sheet (Al) - AliMedium(kAl, "RichAl", material, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - Float_t aGlass[5]={12.01,28.09,16,10.8,23}; Float_t zGlass[5]={6,14,8,5,11}; Float_t wGlass[5]={0.5,0.105,0.355,0.03,0.01}; - AliMixture(++material,"RichGlass",aGlass, zGlass, den=1.74, 5, wGlass); //11 Glass 50%-C 10.5%-Si 35.5%-O 3%-B 1%-Na - AliMedium(kGlass, "RichGlass", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - den=19.3; - AliMaterial(++material, "RichW", a=183.84,z=74.0,den, radl=0.35, absl=185.0/den); //13 W - anod wires - AliMedium(kW, "RichW", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - - if(P()->IsRadioSrc()){ - AliInfo("Special radioactive source materials"); - den=7.87; - AliMaterial(++material, "RichSteel", a=55.845,z=26.0,den, radl=1.76, absl=131.9/den); //14 Steel (Fe) - AliMedium(kSteel, "RichSteel", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - AliMaterial(++material, "RichPerpex", a=63.54,z=29.0,den=8.96, radl=1.4, absl=0); //15 Perpex - AliMedium(kPerpex, "RichPerpex", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - AliMaterial(++material, "RichSr90", a=87.62,z=38.0,den=2.54, radl=4.24, absl=0); //16 Sr90 - AliMedium(kSr90, "RichSr90", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - - Float_t aMylar[5]={12.01,1,16}; Float_t zMylar[5]={6,1,8}; Float_t wMylar[5]={5,4,5}; //17 Mylar C5H4O5 - AliMixture(++material,"RichMylar",aMylar, zMylar, den=1.39, -3, wMylar); - AliMedium(kMylar, "RichMylar", material, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); - } - -//Optical properties: -#include "Opticals.h" - gMC->SetCerenkov((*fIdtmed)[kAir] , kNbins, aPckov, aAbsCH4 , aQeAll, aIdxCH4); //1 Air - gMC->SetCerenkov((*fIdtmed)[kRoha] , kNbins, aPckov, aAbsCH4 , aQeAll, aIdxCH4); //2 Honeycomb - gMC->SetCerenkov((*fIdtmed)[kSiO2] , kNbins, aPckov, aAbsSiO2 , aQeAll, aIdxSiO2); //3 Quartz SiO2 - gMC->SetCerenkov((*fIdtmed)[kC6F14] , kNbins, aPckov, aAbsC6F14 , aQeAll, aIdxC6F14); //4 Freon C6F14 - gMC->SetCerenkov((*fIdtmed)[kCH4] , kNbins, aPckov, aAbsCH4 , aQeAll, aIdxCH4); //5 Methane CH4 - gMC->SetCerenkov((*fIdtmed)[kCsI] , kNbins, aPckov, aAbsCsI , aQeCsI, aIdxCH4); //6 CsI - gMC->SetCerenkov((*fIdtmed)[kGridCu] , kNbins, aPckov, aAbsGrid , aQeAll, aIdxMetal); //7 grid Cu - gMC->SetCerenkov((*fIdtmed)[kOpSiO2] , kNbins, aPckov, aAbsOpSiO2 , aQeAll, aIdxMetal); //8 Opaque quartz SiO2 - gMC->SetCerenkov((*fIdtmed)[kGap] , kNbins, aPckov, aAbsCH4 , aQeAll, aIdxCH4); //9 Special methane gap - gMC->SetCerenkov((*fIdtmed)[kAl] , kNbins, aPckov, aAbsGrid , aQeAll, aIdxMetal); //10 Aluminium - gMC->SetCerenkov((*fIdtmed)[kGlass] , kNbins, aPckov, aAbsOpSiO2 , aQeAll, aIdxMetal); //11 Glass - gMC->SetCerenkov((*fIdtmed)[kGel] , kNbins, aPckov, aAbsGel , aQeAll, aIdxGel); //12 Aerogel - gMC->SetCerenkov((*fIdtmed)[kReflector], kNbins, aPckov, aAbsRef , aQeAll, aIdxMetal); //13 Aerogel reflector -}//void AliRICH::CreateMaterials() -//__________________________________________________________________________________________________ -Float_t AliRICH::Fresnel(Float_t ene,Float_t pdoti, Bool_t pola) -{ - - //ENE(EV), PDOTI=COS(INC.ANG.), PDOTR=COS(POL.PLANE ROT.ANG.) - - Float_t en[36] = {5.0,5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6.0,6.1,6.2, - 6.3,6.4,6.5,6.6,6.7,6.8,6.9,7.0,7.1,7.2,7.3,7.4,7.5,7.6,7.7, - 7.8,7.9,8.0,8.1,8.2,8.3,8.4,8.5}; - Float_t csin[36] = {2.14,2.21,2.33,2.48,2.76,2.97,2.99,2.59,2.81,3.05, - 2.86,2.53,2.55,2.66,2.79,2.96,3.18,3.05,2.84,2.81,2.38,2.11, - 2.01,2.13,2.39,2.73,3.08,3.15,2.95,2.73,2.56,2.41,2.12,1.95, - 1.72,1.53}; - Float_t csik[36] = {0.,0.,0.,0.,0.,0.196,0.408,0.208,0.118,0.49,0.784,0.543, - 0.424,0.404,0.371,0.514,0.922,1.102,1.139,1.376,1.461,1.253,0.878, - 0.69,0.612,0.649,0.824,1.347,1.571,1.678,1.763,1.857,1.824,1.824, - 1.714,1.498}; - Float_t xe=ene; - Int_t j=Int_t(xe*10)-49; - Float_t cn=csin[j]+((csin[j+1]-csin[j])/0.1)*(xe-en[j]); - Float_t ck=csik[j]+((csik[j+1]-csik[j])/0.1)*(xe-en[j]); - - //FORMULAE FROM HANDBOOK OF OPTICS, 33.23 OR - //W.R. HUNTER, J.O.S.A. 54 (1964),15 , J.O.S.A. 55(1965),1197 - - Float_t sinin=TMath::Sqrt(1-pdoti*pdoti); - Float_t tanin=sinin/pdoti; - - Float_t c1=cn*cn-ck*ck-sinin*sinin; - Float_t c2=4*cn*cn*ck*ck; - Float_t aO=TMath::Sqrt(0.5*(TMath::Sqrt(c1*c1+c2)+c1)); - Float_t b2=0.5*(TMath::Sqrt(c1*c1+c2)-c1); - - Float_t rs=((aO-pdoti)*(aO-pdoti)+b2)/((aO+pdoti)*(aO+pdoti)+b2); - Float_t rp=rs*((aO-sinin*tanin)*(aO-sinin*tanin)+b2)/((aO+sinin*tanin)*(aO+sinin*tanin)+b2); - - - //CORRECTION FACTOR FOR SURFACE ROUGHNESS - //B.J. STAGG APPLIED OPTICS, 30(1991),4113 - - Float_t sigraf=18.; - Float_t lamb=1240/ene; - Float_t fresn; - - Float_t rO=TMath::Exp(-(4*TMath::Pi()*pdoti*sigraf/lamb)*(4*TMath::Pi()*pdoti*sigraf/lamb)); - - if(pola) - { - Float_t pdotr=0.8; //DEGREE OF POLARIZATION : 1->P , -1->S - fresn=0.5*(rp*(1+pdotr)+rs*(1-pdotr)); - } - else - fresn=0.5*(rp+rs); - - fresn = fresn*rO; - return(fresn); -}//Fresnel() -//__________________________________________________________________________________________________ void AliRICH::MakeBranch(Option_t* option) { //Create Tree branches for the RICH. @@ -302,25 +97,25 @@ void AliRICH::MakeBranch(Option_t* option) const char *cS = strstr(option,"S"); if(cH&&TreeH()){//H - HitsCreate(); //branch will be created in AliDetector::MakeBranch + HitCreate(); //branch will be created in AliDetector::MakeBranch }//H AliDetector::MakeBranch(option);//this is after cH because we need to guarantee that fHits array is created if(cS&&fLoader->TreeS()){//S - SDigitsCreate(); MakeBranchInTree(fLoader->TreeS(),"RICH",&fSdigits,kBufferSize,0) ; + SDigCreate(); MakeBranchInTree(fLoader->TreeS(),"RICH",&fSdig,kBufferSize,0) ; }//S if(cD&&fLoader->TreeD()){//D - DigitsCreate(); - for(Int_t i=0;iTreeD(),Form("%s%d",GetName(),i+1),&((*fDigs)[i]),kBufferSize,0); + DigCreate(); + for(Int_t i=0;iTreeD(),Form("%s%d",GetName(),i+1),&((*fDig)[i]),kBufferSize,0); } }//D if(cR&&fLoader->TreeR()){//R - ClustersCreate(); - for(Int_t i=0;iTreeR(),Form("%sClusters%d",GetName(),i+1), &((*fClus)[i]), kBufferSize, 0); + CluCreate(); + for(Int_t i=0;iTreeR(),Form("%sClusters%d",GetName(),i+1), &((*fClu)[i]), kBufferSize, 0); }//R AliDebug(1,"Stop."); }//void AliRICH::MakeBranch(Option_t* option) @@ -334,223 +129,43 @@ void AliRICH::SetTreeAddress() if(fLoader->TreeH()){//H AliDebug(1,"tree H is requested."); - HitsCreate();//branch map will be in AliDetector::SetTreeAddress + HitCreate();//branch map will be in AliDetector::SetTreeAddress }//H AliDetector::SetTreeAddress();//this is after TreeH because we need to guarantee that fHits array is created if(fLoader->TreeS()){//S AliDebug(1,"tree S is requested."); - branch=fLoader->TreeS()->GetBranch(GetName()); if(branch){SDigitsCreate(); branch->SetAddress(&fSdigits);} + branch=fLoader->TreeS()->GetBranch(GetName()); if(branch){SDigCreate(); branch->SetAddress(&fSdig);} }//S if(fLoader->TreeD()){//D AliDebug(1,"tree D is requested."); - for(int i=0;iTreeD()->GetBranch(Form("%s%d",GetName(),i+1)); - if(branch){DigitsCreate(); branch->SetAddress(&((*fDigs)[i]));} - } + for(int i=0;iTreeD()->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;iTreeR()->GetBranch(Form("%sClusters%d" ,GetName(),i+1)); - if(branch){ClustersCreate(); branch->SetAddress(&((*fClus)[i]));} - } + for(int i=0;iTreeR()->GetBranch(Form("%sClusters%d" ,GetName(),i+1)); if(branch){CluCreate(); branch->SetAddress(&((*fClu)[i]));}} }//R AliDebug(1,"Stop."); }//void AliRICH::SetTreeAddress() //__________________________________________________________________________________________________ -void AliRICH::Print(Option_t *option)const -{ -//Debug printout - TObject::Print(option); - P()->Print(); - fCounters.Print(); -}//void AliRICH::Print(Option_t *option)const -//__________________________________________________________________________________________________ -void AliRICH::ControlPlots() -{ -//Creates a set of QA hists to control the results of simulation. Hists are in file $HOME/RCP.root - TH1F *pElecP=0 ,*pMuonP=0 ,*pPionP=0 ,*pKaonP=0 ,*pProtP=0, //stack particles - *pHxD=0,*pHyD=0,*pHxSd=0,*pHySd=0, //diff hit position - digit sdigit position - *pNumClusH1=0, - *pQdcH1=0, *pSizeH1=0, - *pPureMipQdcH1=0,*pPureMipSizeH1=0, - *pPureCerQdcH1=0,*pPureCerSizeH1=0, - *pPureFeeQdcH1=0,*pPureFeeSizeH1=0, - *pMipQdcH1=0, *pPhotQdcH1=0; - TH2F *pMapH2=0,*pPureMipMapH2=0,*pPureCerMapH2=0,*pPureFeeMapH2=0; - TH1F *pelecRadius=0,*pprotRadius=0,*pprotbarRadius=0; -//load all information - GetLoader()->GetRunLoader()->LoadHeader(); - GetLoader()->GetRunLoader()->LoadKinematics(); - GetLoader()->LoadHits(); - Bool_t isSdig=0;//!GetLoader()->LoadSDigits(); - Bool_t isDig =0;//!GetLoader()->LoadDigits(); - Bool_t isClus=!GetLoader()->LoadRecPoints(); - - gBenchmark->Start("ControlPlots"); - - TFile *pFile = new TFile("$(HOME)/RCP.root","RECREATE"); - - pElecP=new TH1F("Pelec","Electrons made hit in RICH;p [GeV]",1000,-30,30); - pMuonP=new TH1F("Pmuon","Muons made hit in RICH;p [GeV]",1000,-30,30); - pPionP=new TH1F("Ppion","Pions made hit in RICH;p [GeV]",1000,-30,30); - pKaonP=new TH1F("Pkaon","Kaon made hit in RICH;p [GeV]",1000,-30,30); - pProtP=new TH1F("Pprot","Protons made hit in RICH;p [GeV]",1000,-30,30); - pelecRadius=new TH1F("elecRadius","elec",600,0.,600.); - pprotRadius=new TH1F("protRadius","elec",600,0.,600.); - pprotbarRadius=new TH1F("protbarRadius","elec",600,0.,600.); - - if(isSdig){ - AliInfo("SDigits available"); - pHxSd=new TH1F("DiffHitSDigitX","Hit-SDigit diff X all chambers;diff [cm]",300,-10,10); - pHySd=new TH1F("DiffHitSDigitY","Hit-SDigit diff Y all chambers;diff [cm]",300,-10,10); - }//isSdig - - if(isDig){ - AliInfo("Digits available"); - pHxD=new TH1F("DiffHitDigitX","Hit-Digit diff X all chambers;diff [cm]",300,-10,10); - pHyD=new TH1F("DiffHitDigitY","Hit-Digit diff Y all chambers;diff [cm]",300,-10,10); - }//isDig - - if(isClus){ - AliInfo("Clusters available"); - pNumClusH1=new TH1F("NumClusPerEvent","Number of clusters per event;number",50,0,49); - - pQdcH1 =new TH1F("ClusQdc", "Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc()); - pSizeH1 =new TH1F("ClusSize", "Cluster size all chambers;size [number of pads in cluster]",100,0,100); - pMapH2 =new TH2F("ClusMap", "Cluster map;x [cm];y [cm]",1000,0,P()->PcSizeX(),1000,0,P()->PcSizeY()); - - pMipQdcH1 =new TH1F("QdcMip" ,"MIP Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc()); - pPhotQdcH1 =new TH1F("QdcPhot" ,"Cer+Fee Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc()); - - pPureMipQdcH1 =new TH1F("QdcPureMip" ,"MIP only Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc()); - pPureMipSizeH1=new TH1F("SizePureMip" ,"MIP only Cluster size all chambers;size [number of pads in cluster]",100,0,100); - pPureMipMapH2 =new TH2F("MapPureMip" ,"MIP only Cluster map;x [cm];y [cm]",1000,0,P()->PcSizeX(),1000,0,P()->PcSizeY()); - - pPureCerQdcH1 =new TH1F("QdcPureCer" ,"Cerenkov only Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc()); - pPureCerSizeH1=new TH1F("SizePureCer" ,"Cernekov only Cluster size all chambers;size [number of pads in cluster]",100,0,100); - pPureCerMapH2 =new TH2F("MapPureCer" ,"Cerenkov only Cluster map;x [cm];y [cm]",1000,0,P()->PcSizeX(),1000,0,P()->PcSizeY()); - - pPureFeeQdcH1 =new TH1F("QdcPureFee" ,"Feedback only Cluster Charge all chambers;q [QDC]",P()->MaxQdc(),0,P()->MaxQdc()); - pPureFeeSizeH1=new TH1F("SizePureFee" ,"Feedback only Cluster size all chambers;size [number of pads in cluster]",100,0,100); - pPureFeeMapH2 =new TH2F("MapPureFee" ,"Feedback only Cluster map;x [cm];y [cm]",1000,0,P()->PcSizeX(),1000,0,P()->PcSizeY()); - - }//isClus -//end of hists booking - for(Int_t iEvtN=0;iEvtN < GetLoader()->GetRunLoader()->GetAliRun()->GetEventsPerRun();iEvtN++){//events loop - GetLoader()->GetRunLoader()->GetEvent(iEvtN); //get current event - - for(Int_t iPrimN=0;iPrimN < GetLoader()->TreeH()->GetEntries();iPrimN++){//hit tree loop - GetLoader()->TreeH()->GetEntry(iPrimN); - for(Int_t j=0;jGetEntries();j++){//hits loop - AliRICHHit *pHit = (AliRICHHit*)Hits()->At(j); - TParticle *pParticle = GetLoader()->GetRunLoader()->Stack()->Particle(pHit->GetTrack());//get particle produced this hit - Double_t dRadius = TMath::Sqrt(pParticle->Vx()*pParticle->Vx()+pParticle->Vy()*pParticle->Vy()+pParticle->Vz()*pParticle->Vz()); - switch(pParticle->GetPdgCode()){ - case kPositron : pElecP->Fill( pParticle->P());pelecRadius->Fill(dRadius); break; - case kElectron : pElecP->Fill(-pParticle->P());pelecRadius->Fill(dRadius); break; - - case kMuonPlus : pMuonP->Fill( pParticle->P()); break; - case kMuonMinus: pMuonP->Fill(-pParticle->P()); break; - - case kPiPlus : pPionP->Fill( pParticle->P()); break; - case kPiMinus : pPionP->Fill(-pParticle->P()); break; - - case kKPlus : pKaonP->Fill( pParticle->P()); break; - case kKMinus : pKaonP->Fill(-pParticle->P()); break; - - case kProton : pProtP->Fill( pParticle->P()); pprotRadius->Fill(dRadius); break; - case kProtonBar: pProtP->Fill(-pParticle->P()); pprotbarRadius->Fill(dRadius); break; - - }//switch PdgCode - - }//hits loop - }//hit tree loop - - if(isSdig){ - GetLoader()->TreeS()->GetEntry(0); - for(Int_t iSdigN=0;iSdigNGetEntries();iSdigN++){//sdigits loop - AliRICHDigit *pSdig=(AliRICHDigit*)SDigits()->At(iSdigN); //get current sdigit pointer - AliRICHHit *pHit=Hit(pSdig->GetTrack(0)); //get hit of this sdigit (always one) - TVector2 hit2 =C(pHit->C())->Mrs2Pc(pHit->OutX3()); //this hit position in local system - TVector2 sdig2=P()->Pad2Loc(pSdig->Pad()); //center of pad for this sdigit - pHxSd->Fill(hit2.X()-sdig2.X()); - pHySd->Fill(hit2.Y()-sdig2.Y()); - }//sdigits loop - }//if(isSdig) - - if(isDig) GetLoader()->TreeD()->GetEntry(0); - if(isClus) GetLoader()->TreeR()->GetEntry(0); - - for(Int_t iChamN=1;iChamN<=7;iChamN++){//chambers loop - if(isDig){ - for(Int_t iDigN=0;iDigNGetEntries();iDigN++){//digits loop - AliRICHDigit *pDig=(AliRICHDigit*)Digits(iChamN)->At(iDigN); - AliRICHHit *pHit=Hit(pDig->GetTrack(0)); //get first hit of this digit - TVector2 hitV2=C(iChamN)->Mrs2Pc(pHit->OutX3()); - TVector2 digV2=P()->Pad2Loc(pDig->Pad()); //center of pad for this digit - pHxD->Fill(hitV2.X()-digV2.X()); pHyD->Fill(hitV2.Y()-digV2.Y()); - }//digits loop - }//isDig - if(isClus){ - Int_t iNclusCham=Clusters(iChamN)->GetEntries(); if(iNclusCham) pNumClusH1->Fill(iNclusCham);//number of clusters per event - for(Int_t iClusN=0;iClusNAt(iClusN); - pQdcH1 ->Fill(pClus->Q()); - pSizeH1 ->Fill(pClus->Size()); - pMapH2 ->Fill(pClus->X(),pClus->Y()); //common - - if(pClus->IsSingleMip()) {pPureMipQdcH1 ->Fill(pClus->Q()); - pPureMipSizeH1->Fill(pClus->Size()); - pPureMipMapH2 ->Fill(pClus->X(),pClus->Y());}//Pure Mips - - if(pClus->IsSingleCerenkov()){pPureCerQdcH1 ->Fill(pClus->Q()); - pPureCerSizeH1->Fill(pClus->Size()); - pPureCerMapH2 ->Fill(pClus->X(),pClus->Y());}//Pure Cerenkovs - - if(pClus->IsSingleFeedback()){pPureFeeQdcH1 ->Fill(pClus->Q()); - pPureFeeSizeH1->Fill(pClus->Size()); - pPureFeeMapH2 ->Fill(pClus->X(),pClus->Y());}//Pure Feedbacks - - if(pClus->IsMip()) {pMipQdcH1 ->Fill(pClus->Q());} //MIP+ other contributions - if(!pClus->IsPureMip()) pPhotQdcH1->Fill(pClus->Q()); //not MIP - }//clusters loop - }//isClus - }//chambers loop - Info("ControlPlots","Event %i processed.",iEvtN); - }//events loop - GetLoader()->UnloadHits(); - if(isSdig) GetLoader()->UnloadSDigits(); - if(isDig) GetLoader()->UnloadDigits(); - if(isClus) GetLoader()->UnloadRecPoints(); - - GetLoader()->GetRunLoader()->UnloadHeader(); - GetLoader()->GetRunLoader()->UnloadKinematics(); - - pFile->Write(); delete pFile; - - gBenchmark->Show("ControlPlots"); -}//ControlPlots() -//__________________________________________________________________________________________________ -AliRICHHit* AliRICH::Hit(Int_t tid)const -{ -//defines which hit provided by given tid for the currently loaded event - GetLoader()->LoadHits(); - for(Int_t iPrimN=0;iPrimNTreeH()->GetEntries();iPrimN++){//prims loop - GetLoader()->TreeH()->GetEntry(iPrimN); - for(Int_t iHitN=0;iHitNGetEntries();iHitN++){ - AliRICHHit *pHit=(AliRICHHit*)Hits()->At(iHitN); - if(tid==pHit->Track()) {GetLoader()->UnloadHits();return pHit;} - }//hits - }//prims loop - GetLoader()->UnloadHits(); - return 0; -} -//__________________________________________________________________________________________________ -void AliRICH::HitsPrint(Int_t iEvtN)const +// AliRICHHit* AliRICH::Hit(Int_t tid)const +// { +// // Search for the first RICH hit belonging to the given tid +// GetLoader()->LoadHits(); +// for(Int_t iPrimN=0;iPrimNTreeH()->GetEntries();iPrimN++){//prims loop +// GetLoader()->TreeH()->GetEntry(iPrimN); +// for(Int_t iHitN=0;iHitNGetEntries();iHitN++){ +// AliRICHHit *pHit=(AliRICHHit*)Hits()->At(iHitN); +// if(tid==pHit->Track()) {GetLoader()->UnloadHits();return pHit;} +// }//hits +// }//prims loop +// GetLoader()->UnloadHits(); +// return 0; +// } +//__________________________________________________________________________________________________ +void AliRICH::HitPrint(Int_t iEvtN)const { //Prints a list of RICH hits for a given event. Default is event number 0. if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return; @@ -567,7 +182,7 @@ void AliRICH::HitsPrint(Int_t iEvtN)const AliInfo(Form("totally %i hits",iTotalHits)); } //__________________________________________________________________________________________________ -void AliRICH::SDigitsPrint(Int_t iEvtN)const +void AliRICH::SDigPrint(Int_t iEvtN)const { //prints a list of RICH sdigits for a given event if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return; @@ -575,26 +190,26 @@ void AliRICH::SDigitsPrint(Int_t iEvtN)const if(GetLoader()->LoadSDigits()) return; GetLoader()->TreeS()->GetEntry(0); - SDigits()->Print(); + fSdig->Print(); GetLoader()->UnloadSDigits(); - Info("PrintSDigits","totally %i sdigits",SDigits()->GetEntries()); + Printf("totally %i sdigits",fSdig->GetEntries()); } //__________________________________________________________________________________________________ -void AliRICH::DigitsPrint(Int_t iEvtN)const +void AliRICH::DigPrint(Int_t iEvtN)const { //prints a list of RICH digits for a given event if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return; - Info("PrintDigits","List of RICH digits for event %i",iEvtN); + Printf("List of RICH digits for event %i",iEvtN); if(GetLoader()->LoadDigits()) return; Int_t iTotalDigits=0; GetLoader()->TreeD()->GetEntry(0); - for(Int_t iChamber=1;iChamber<=kNchambers;iChamber++){ - Digits(iChamber)->Print(); - iTotalDigits+=Digits(iChamber)->GetEntries(); + if(!fDig) return; + for(Int_t iCham=0;iChamAt(iCham); iTotalDigits+=pDigs->GetEntries(); pDigs->Print(); } GetLoader()->UnloadDigits(); - Info("PrintDigits","totally %i Digits",iTotalDigits); + Printf("totally %i Digits",iTotalDigits); } //__________________________________________________________________________________________________ void AliRICH::OccupancyPrint(Int_t iEvtNreq)const @@ -637,11 +252,11 @@ void AliRICH::OccupancyPrint(Int_t iEvtNreq)const } } GetLoader()->TreeD()->GetEntry(0); - for(Int_t iChamber=1;iChamber<=kNchambers;iChamber++) { - nDigCh[iChamber-1]= Digits(iChamber)->GetEntries(); - Double_t occupancy = (Double_t)nDigCh[iChamber-1]/(Double_t)totPadsPerChamber; + for(Int_t iCh=0;iChAt(iCh))->GetEntries(); + Double_t occupancy = (Double_t)nDigCh[iCh-1]/(Double_t)totPadsPerChamber; Info("Occupancy","for chamber %i = %4.2f %% and charged prim tracks %i and sec. tracks %i with total %i", - iChamber,occupancy*100.,nPrim[iChamber-1],nSec[iChamber-1],iChHits[iChamber-1]); + iCh+1,occupancy*100.,nPrim[iCh],nSec[iCh],iChHits[iCh]); } } GetLoader()->UnloadHits(); @@ -650,266 +265,72 @@ void AliRICH::OccupancyPrint(Int_t iEvtNreq)const GetLoader()->GetRunLoader()->UnloadKinematics(); } //__________________________________________________________________________________________________ -void AliRICH::ClustersPrint(Int_t iEvtN)const +void AliRICH::CluPrint(Int_t iEvtN)const { //prints a list of RICH clusters for a given event - AliInfo(Form("List of RICH clusters for event %i",iEvtN)); + Printf("List of RICH clusters for event %i",iEvtN); GetLoader()->GetRunLoader()->GetEvent(iEvtN); if(GetLoader()->LoadRecPoints()) return; - Int_t iTotalClusters=0; + Int_t iCluCnt=0; GetLoader()->TreeR()->GetEntry(0); - for(Int_t iChamber=1;iChamber<=kNchambers;iChamber++){ - Clusters(iChamber)->Print(); - iTotalClusters+=Clusters(iChamber)->GetEntries(); + for(Int_t iCham=0;iChamAt(iCham); iCluCnt+=pClus->GetEntries(); pClus->Print(); } GetLoader()->UnloadRecPoints(); - AliInfo(Form("totally %i clusters for event %i",iTotalClusters,iEvtN)); + Printf("totally %i clusters for event %i",iCluCnt,iEvtN); } -//__________________________________________________________________________________________________ -void AliRICH::PrintTracks(Int_t iEvtN) -{ -//prints a list of tracks (including secondary) for a given event - AliInfo(Form("List of all tracks for event %i",iEvtN)); - GetLoader()->GetRunLoader()->GetEvent(iEvtN); - if(GetLoader()->GetRunLoader()->LoadHeader()) return; - if(GetLoader()->GetRunLoader()->LoadKinematics()) return; - AliStack *pStack=GetLoader()->GetRunLoader()->Stack(); - - for(Int_t i=0;iGetNtrack();i++) pStack->Particle(i)->Print(); - - AliInfo(Form("totally %i tracks including %i primaries for event %i",pStack->GetNtrack(),pStack->GetNprimary(),iEvtN)); - GetLoader()->GetRunLoader()->UnloadHeader(); - GetLoader()->GetRunLoader()->UnloadKinematics(); -} -//__________________________________________________________________________________________________ -void AliRICH::GeomPadPanelFrame()const -{ -//Pad Panel frame 6 sectors - Double_t cm=1,mm=0.1*cm;//default is cm - Float_t par[3]; - - par[0]=648*mm/2;par[1]= 411*mm/2;par[2]=40 *mm/2;gMC->Gsvolu("RPPF","BOX ",(*fIdtmed)[kAl] ,par,3);//PPF 2001P2 inner size of the slab by 1mm more - par[0]=181*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("PPFL","BOX ",(*fIdtmed)[kAir] ,par,3);//large whole - par[0]=114*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("PPFS","BOX ",(*fIdtmed)[kAir] ,par,3);//small whole - par[0]=644*mm/2;par[1]= 407*mm/2;par[2]= 1.7*mm/2;gMC->Gsvolu("RPC ","BOX ",(*fIdtmed)[kCsI] ,par,3);//by 0.2 mm more then actual size (PCB 2006P1) - - gMC->Gspos("RPPF",1,"RICH", -335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY");//F1 2040P1 z p.84 TDR - gMC->Gspos("RPPF",2,"RICH", +335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY"); - gMC->Gspos("RPPF",3,"RICH", -335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); - gMC->Gspos("RPPF",4,"RICH", +335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); - gMC->Gspos("RPPF",5,"RICH", -335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); - gMC->Gspos("RPPF",6,"RICH", +335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); - gMC->Gspos("RPC ",1,"RPPF", 0*mm, 0*mm, -19.15*mm, 0,"ONLY");//PPF 2001P2 - gMC->Gspos("PPFL",1,"RPPF", -224.5*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFL",2,"RPPF", -224.5*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFL",3,"RPPF", -224.5*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFL",4,"RPPF", -224.5*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFS",1,"RPPF", - 65.0*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFS",2,"RPPF", - 65.0*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFS",3,"RPPF", - 65.0*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFS",4,"RPPF", - 65.0*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFS",5,"RPPF", + 65.0*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFS",6,"RPPF", + 65.0*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFS",7,"RPPF", + 65.0*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFS",8,"RPPF", + 65.0*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFL",5,"RPPF", +224.5*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFL",6,"RPPF", +224.5*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFL",7,"RPPF", +224.5*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); - gMC->Gspos("PPFL",8,"RPPF", +224.5*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); -}//GeomPadPanelFrame() -//__________________________________________________________________________________________________ -void AliRICH::GeomAmpGap()const -{ -//Gap - anod wires 6 copies to RICH - Double_t cm=1,mm=0.1*cm,mkm=0.001*mm;//default is cm - Int_t matrixIdReturn=0; //matrix id returned by AliMatrix - Float_t par[3]; - - - par[0]=648*mm/2;par[1]= 411*mm/2 ;par[2]=4.45*mm/2;gMC->Gsvolu("RGAP","BOX ",(*fIdtmed)[kCH4] ,par,3);//xy as PPF 2001P2 z WP 2099P1 - par[0]= 0*mm ;par[1]= 20*mkm/2 ;par[2]= 648*mm/2;gMC->Gsvolu("RANO","TUBE",(*fIdtmed)[kW] ,par,3);//WP 2099P1 z = gap x PPF 2001P2 - AliMatrix(matrixIdReturn,180,0, 90,90, 90,0); //wires along x - - gMC->Gspos("RGAP",1,"RICH", -335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); //F1 2040P1 z WP 2099P1 - gMC->Gspos("RGAP",2,"RICH", +335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); - gMC->Gspos("RGAP",3,"RICH", -335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); - gMC->Gspos("RGAP",4,"RICH", +335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); - gMC->Gspos("RGAP",5,"RICH", -335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); - gMC->Gspos("RGAP",6,"RICH", +335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); - for(int i=1;i<=96;i++) - gMC->Gspos("RANO",i,"RGAP", 0*mm, -411/2*mm+i*4*mm, 0.185*mm, matrixIdReturn,"ONLY"); //WP 2099P1 -}//GeomAmpGap() -//__________________________________________________________________________________________________ -void AliRICH::GeomRadiators()const -{ -//Defines radiators geometry - Double_t mm=0.1;//default is cm - Float_t par[3]; - par[0]=1330*mm/2 ;par[1]= 413*mm/2 ;par[2]= 24*mm/2; gMC->Gsvolu("RRAD","BOX ",(*fIdtmed)[kC6F14] ,par,3); // Rad 2011P1 - par[0]=1330*mm/2 ;par[1]= 413*mm/2 ;par[2]= 4*mm/2; gMC->Gsvolu("RRFR","BOX ",(*fIdtmed)[kRoha] ,par,3); //front - par[0]=1330*mm/2 ;par[1]= 413*mm/2 ;par[2]= 5*mm/2; gMC->Gsvolu("RRWI","BOX ",(*fIdtmed)[kSiO2] ,par,3); //window - par[0]=1330*mm/2 ;par[1]= 5*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RRLO","BOX ",(*fIdtmed)[kRoha] ,par,3); //long side - par[0]= 10*mm/2 ;par[1]= 403*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RRSH","BOX ",(*fIdtmed)[kRoha] ,par,3); //short side - par[0]= 0 ;par[1]= 10*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RRSP","TUBE",(*fIdtmed)[kSiO2] ,par,3); //spacer - - gMC->Gspos("RRAD",1,"RICH", 0*mm,-434*mm, -12*mm, 0,"ONLY"); //3 radiators to RICH - gMC->Gspos("RRAD",2,"RICH", 0*mm, 0*mm, -12*mm, 0,"ONLY"); - gMC->Gspos("RRAD",3,"RICH", 0*mm,+434*mm, -12*mm, 0,"ONLY"); - gMC->Gspos("RRFR",1,"RRAD", 0*mm, 0*mm, -10.0*mm, 0,"ONLY"); //front cover - gMC->Gspos("RRWI",1,"RRAD", 0*mm, 0*mm, 9.5*mm, 0,"ONLY"); //quartz window (back cover) - gMC->Gspos("RRLO",1,"RRAD", 0*mm,-204*mm, -0.5*mm, 0,"ONLY"); //long side - gMC->Gspos("RRLO",2,"RRAD", 0*mm,+204*mm, -0.5*mm, 0,"ONLY"); //long side - gMC->Gspos("RRSH",1,"RRAD",-660*mm, 0*mm, -0.5*mm, 0,"ONLY"); //short side - gMC->Gspos("RRSH",2,"RRAD",+660*mm, 0*mm, -0.5*mm, 0,"ONLY"); //short side - for(int i=0;i<3;i++) - for(int j=0;j<10;j++) - gMC->Gspos("RRSP",10*i+j,"RRAD",-1330*mm/2+116*mm+j*122*mm,(i-1)*105*mm,-0.5*mm,0,"ONLY");//spacers -}//GeomRadiators() -//__________________________________________________________________________________________________ -void AliRICH::GeomSandBox()const -{ -//Defines SandBox geometry - Double_t mm=0.1;//default is cm - Float_t par[3]; - par[0]=1419*mm/2 ;par[1]=1378*mm/2;par[2]=50.5*mm/2; gMC->Gsvolu("RSNB","BOX ",(*fIdtmed)[kAir] ,par,3); //2072P1 - par[0]=1419*mm/2 ;par[1]=1378*mm/2;par[2]= 0.5*mm/2; gMC->Gsvolu("RSCO","BOX ",(*fIdtmed)[kAl] ,par,3); //cover - par[0]=1359*mm/2 ;par[1]=1318*mm/2;par[2]=49.5*mm/2; gMC->Gsvolu("RSHO","BOX ",(*fIdtmed)[kRoha] ,par,3); //honeycomb structure - - gMC->Gspos("RSNB",1,"RICH", 0*mm, 0*mm, -73.75*mm, 0,"ONLY"); //p.84 TDR sandbox to rich - gMC->Gspos("RSHO",1,"RSNB", 0*mm, 0*mm, 0*mm, 0,"ONLY"); //2072P1 honeycomv to sandbox - gMC->Gspos("RSCO",1,"RSNB", 0*mm, 0*mm, +25*mm, 0,"ONLY"); //cover to sandbox - gMC->Gspos("RSCO",2,"RSNB", 0*mm, 0*mm, -25*mm, 0,"ONLY"); //cover to sandbox -}//GeomSandBox() -//__________________________________________________________________________________________________ -void AliRICH::GeomRadioSrc()const -{ -// Defines geometry for radioactive source - Double_t cm=1,mm=0.1*cm,mkm=0.001*cm; - Float_t par[3]; - - par[0]=0 ;par[1]= 70*mm/2 ;par[2]= 30*mm/2; gMC->Gsvolu("RSRC","TUBE",(*fIdtmed)[kCH4] ,par,3); //top src container - par[0]=0 ;par[1]= 38*mm/2 ;par[2]= 21.8*mm/2; gMC->Gsvolu("RSAG","TUBE",(*fIdtmed)[kAl] ,par,3); //Al glass - par[0]=0 ;par[1]= 34*mm/2 ;par[2]= 20*mm/2; gMC->Gsvolu("RSPP","TUBE",(*fIdtmed)[kPerpex] ,par,3); //perpex plug - par[0]=0 ;par[1]= 5*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RSSC","TUBE",(*fIdtmed)[kSteel] ,par,3); //steel screw in center of perpex - par[0]=0 ;par[1]= 2*mm/2 ;par[2]= 10*mm/2; gMC->Gsvolu("RSSS","TUBE",(*fIdtmed)[kSteel] ,par,3); //Steel screw to support Sr90 - par[0]=0 ;par[1]= 1*mm/2 ;par[2]= 1*mm/2; gMC->Gsvolu("RSSR","TUBE",(*fIdtmed)[kSr90] ,par,3); //Sr90 source - par[0]=0 ;par[1]= 4*mm/2 ;par[2]= 10*mm/2; gMC->Gsvolu("RSWP","TUBE",(*fIdtmed)[kAir] ,par,3); //Air hole in perpex plug - par[0]=0 ;par[1]= 5*mm/2 ;par[2]= 1.8*mm/2; gMC->Gsvolu("RSWA","TUBE",(*fIdtmed)[kAir] ,par,3); //Air hole in Al glass bottom - par[0]=0 ;par[1]= 30*mm/2 ;par[2]= 50*mkm/2; gMC->Gsvolu("RSMF","TUBE",(*fIdtmed)[kMylar] ,par,3); //Mylar foil - - gMC->Gspos("RSRC",1,"RICH", 30*cm, 0, 1*cm, 0,"ONLY"); //source to RICH - gMC->Gspos("RSMF",1,"RSRC", 0, 0,21.8*mm/2+50*mkm/2, 0,"ONLY");//mylar foil to top src volume - gMC->Gspos("RSAG",1,"RSRC", 0, 0, 0, 0,"ONLY");//Al glass to fake Src volume - gMC->Gspos("RSWA",1,"RSAG", 6*mm, 0, -10*mm, 0,"ONLY");//air whole in al glass bottom - gMC->Gspos("RSPP",1,"RSAG", 0, 0, 0.9*mm, 0,"ONLY");//perpex plug to Al glass - gMC->Gspos("RSWP",1,"RSPP", 6*mm, 0, -5*mm, 0,"ONLY");//air whole in perpex plug - gMC->Gspos("RSSC",1,"RSPP", 0, 0, 2.5*mm, 0,"ONLY");//steel screw in center of perpex plug - gMC->Gspos("RSSS",1,"RSPP", 6*mm, 0, 5*mm, 0,"ONLY");//steel screw to support Sr90 in perpex plug - gMC->Gspos("RSSR",1,"RSSS", 0, 0, -4.5*mm, 0,"ONLY");//Sr90 in support steel screw -}//GeomSr90() -//__________________________________________________________________________________________________ -void AliRICH::GeomAerogel()const -{ -//Creates detailed geometry for aerogel study. - AliDebug(1,"Start."); - Double_t cm=1; - Float_t par[3]; //tmp array for volume dimentions - - par[0]=10.1*cm/2;par[1]=10.1*cm/2;par[2]=10.1*cm/2; - gMC->Gsvolu("RREF","BOX ",(*fIdtmed)[kReflector],par,3);//reflector box - gMC->Gspos("RREF",1,"RICH",0,0,0,0, "ONLY"); //put it to RICH volume - - par[0]=10*cm/2;par[1]=10*cm/2;par[2]=10*cm/2; - gMC->Gsvolu("RGEL","BOX ",(*fIdtmed)[kGel],par,3);//10x10x10 cm^3 cubic of aerogel - gMC->Gspos("RGEL",1,"RREF",0,0,0,0,"ONLY");//put gel cell to reflector - AliDebug(1,"Stop."); -}//GeomAerogel() -//__________________________________________________________________________________________________ -void AliRICH::CreateGeometry() -{ -//Creates detailed geometry simulation (currently GEANT volumes tree) - AliDebug(1,"Start main."); - Double_t mm=0.1;//default is cm - Float_t par[3]; - Int_t matrixIdReturn=0; //matrix id returned by AliMatrix - -//place chambers into mother volume ALIC - par[0]=(6*mm+1681*mm+6*mm)/2;par[1]=(6*mm+1466*mm+6*mm)/2;par[2]=(80*mm+40*mm)*2/2; - gMC->Gsvolu("RICH","BOX ",(*fIdtmed)[kCH4],par,3);//2033P1 z p84 TDR - for(int i=1;i<=P()->Nchambers();i++){ //test configuration with single chamber is taken into account automaticaly in AliRICHParam - AliMatrix(matrixIdReturn, - C(i)->ThetaXd(),C(i)->PhiXd(), - C(i)->ThetaYd(),C(i)->PhiYd(), - C(i)->ThetaZd(),C(i)->PhiZd()); - gMC->Gspos("RICH",i,"ALIC",C(i)->Center().X(), - C(i)->Center().Y(), - C(i)->Center().Z(),matrixIdReturn, "ONLY"); - } - - if(P()->IsAerogel()) - GeomAerogel(); - else{ - GeomPadPanelFrame(); - GeomAmpGap(); - if(P()->IsRadioSrc()) GeomRadioSrc(); else GeomRadiators(); - GeomSandBox(); - } - AliDebug(1,"Stop main."); -}//CreateGeometry() -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICH::DisplayEvent(Int_t iEvtNmin,Int_t iEvtNmax)const { - TH2F *pDigitsH2[8]; +// Display digits, reconstructed tracks intersections and RICH rings if available + TH2F *pH2[8]; - Bool_t isDigits =!GetLoader()->LoadDigits(); - if(!isDigits){Error("ShoEvent","No digits. Nothing to display.");return;} + GetLoader()->LoadDigits(); - TCanvas *canvas = new TCanvas("RICHDisplay","RICH Display",0,0,1226,900); + TLatex t; t.SetTextSize(0.1); + TCanvas *pC = new TCanvas("RICHDisplay","RICH Display",0,0,1226,900); pC->Divide(3,3); pC->cd(9); t.DrawText(0.2,0.4,"View to IP"); gStyle->SetPalette(1); - for(Int_t iChamber=1;iChamber<=7;iChamber++) { - pDigitsH2[iChamber] = new TH2F(Form("pDigitsH2_%i",iChamber),Form("Chamber %i",iChamber),165,0,P()->PcSizeX(),144,0,P()->PcSizeY()); - pDigitsH2[iChamber]->SetMarkerColor(kGreen); - pDigitsH2[iChamber]->SetMarkerStyle(29); - pDigitsH2[iChamber]->SetMarkerSize(0.4); - pDigitsH2[iChamber]->SetStats(kFALSE); - pDigitsH2[iChamber]->SetMaximum(300); + for(Int_t iCh=1;iCh<=fNcham;iCh++) { + pH2[iCh] = new TH2F(Form("RichDigH2_%i",iCh),Form("Chamber %i;cm;cm",iCh),165,0,AliRICHParam::PcSizeX(),144,0,AliRICHParam::PcSizeY()); + pH2[iCh]->SetMarkerColor(kGreen); + pH2[iCh]->SetMarkerStyle(29); + pH2[iCh]->SetMarkerSize(0.4); + pH2[iCh]->SetStats(kFALSE); + pH2[iCh]->SetMaximum(300); } if(iEvtNmax>gAlice->GetEventsPerRun()||iEvtNmax==0) iEvtNmax=gAlice->GetEventsPerRun()-1; - TLatex t; t.SetTextSize(0.1); - for(Int_t iEventN=iEvtNmin;iEventN<=iEvtNmax;iEventN++) {//events loop - canvas->Divide(3,3); - canvas->cd(1); - t.DrawText(0.2,0.4,Form("Event Number %i",iEventN)); + for(Int_t iEvt=iEvtNmin;iEvt<=iEvtNmax;iEvt++) {//events loop + pC->cd(3); t.DrawText(0.2,0.4,Form("Event %i",iEvt)); - GetLoader()->GetRunLoader()->GetEvent(iEventN); //get event - GetLoader()->TreeD()->GetEntry(0); //get list of digits - for(Int_t iChamber=1;iChamber<=7;iChamber++) {//chambers loop - pDigitsH2[iChamber]->Reset(); - for(Int_t j=0;jGetEntries();j++) {//digits loop - AliRICHDigit *pDig = (AliRICHDigit*)Digits(iChamber)->At(j); + GetLoader()->GetRunLoader()->GetEvent(iEvt); //get event + GetLoader()->TreeD()->GetEntry(0); //get list of digits + for(Int_t iCh=1;iCh<=fNcham;iCh++) {//chambers loop + pH2[iCh]->Reset(); + for(Int_t iDig=0;iDig < Digs(iCh)->GetEntries();iDig++) {//digits loop + AliRICHDigit *pDig = (AliRICHDigit*)Digs(iCh)->At(iDig); TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad()); - pDigitsH2[iChamber]->Fill(x2.X(),x2.Y(),pDig->Qdc()); + pH2[pDig->C()]->Fill(x2.X(),x2.Y(),pDig->Qdc()); }//digits loop - if(iChamber==1) canvas->cd(7); - if(iChamber==2) canvas->cd(8); - if(iChamber==3) canvas->cd(4); - if(iChamber==4) canvas->cd(5); - if(iChamber==5) canvas->cd(6); - if(iChamber==6) canvas->cd(2); - if(iChamber==7) canvas->cd(3); - pDigitsH2[iChamber]->Draw("col"); - ReadESD(iEventN,iChamber); + if(iCh==1) pC->cd(9); + if(iCh==2) pC->cd(8); + if(iCh==3) pC->cd(6); + if(iCh==4) pC->cd(5); + if(iCh==5) pC->cd(4); + if(iCh==6) pC->cd(2); + if(iCh==7) pC->cd(1); + pH2[iCh]->Draw("col"); + ReadESD(iEvt,iCh); AliRICHParam::DrawSectors(); }//chambers loop - canvas->Update(); - canvas->Modified(); + pC->Update(); + pC->Modified(); - if(iEventNWaitPrimitive();canvas->Clear();} + if(iEvtWaitPrimitive();pC->Clear();} }//events loop }//ShowEvent() //__________________________________________________________________________________________________ @@ -936,30 +357,27 @@ void AliRICH::Display()const if(isClusters) pClustersH2 = new TH2F("pClustersH2","Event Display",165,0,AliRICHParam::PcSizeX(), 144,0,AliRICHParam::PcSizeY()); - for(Int_t iEventN=0;iEventNGetEventsPerRun();iEventN++){//events Loop - GetLoader()->GetRunLoader()->GetEvent(iEventN); + for(Int_t iEvt=0;iEvtGetRunLoader()->GetNumberOfEvents();iEvt++){//events Loop + GetLoader()->GetRunLoader()->GetEvent(iEvt); //display all the staff on chamber by chamber basis - for(Int_t iChamber=1;iChamber<=7;iChamber++){//chambers loop + for(Int_t iCh=1;iCh<=fNcham;iCh++){//chambers loop if(isHits) pHitsH2 ->Reset(); if(isDigits) pDigitsH2 ->Reset(); if(isClusters) pClustersH2->Reset(); //deals with hits for(Int_t i=0;iTreeH()->GetEntries();i++){//TreeH loop GetLoader()->TreeH()->GetEntry(i); - for(Int_t j=0;jGetEntries();j++){//hits loop - AliRICHHit *pHit = (AliRICHHit*)Hits()->At(j); - if(pHit->C()==iChamber){ - TVector3 hitGlobX3= pHit->OutX3(); - TVector2 hitLocX2 = C(iChamber)->Mrs2Pc(hitGlobX3); + for(Int_t iHit=0;iHitGetEntries();iHit++){//hits loop + AliRICHHit *pHit = (AliRICHHit*)Hits()->At(iHit); + if(pHit->C()==iCh){ + TVector2 hitLocX2 = AliRICHParam::Instance()->Mars2Lors(iCh,pHit->OutX3()); pHitsH2->Fill(hitLocX2.X(),hitLocX2.Y(),200); }//if }//hits loop }//TreeH loop - pHitsH2->SetTitle(Form("event %i chamber %2i",iEventN,iChamber)); + pHitsH2->SetTitle(Form("event %i chamber %2i",iEvt,iCh)); pHitsH2->SetMarkerColor(kRed); pHitsH2->SetMarkerStyle(29); pHitsH2->SetMarkerSize(0.4); - ReadESD(iEventN,iChamber); pHitsH2->Draw(); -// ReadESD(iEventN,iChamber); AliRICHParam::DrawSectors(); TLatex l; l.SetNDC(); l.SetTextSize(0.02); if(!isHits) {l.SetTextColor(kRed) ;l.DrawLatex(0.1,0.01,"No Hits" );} @@ -969,10 +387,10 @@ void AliRICH::Display()const //deals with digits if(isDigits){ GetLoader()->TreeD()->GetEntry(0); - for(Int_t j=0;jGetEntries();j++){//digits loop - AliRICHDigit *pDig = (AliRICHDigit*)Digits(iChamber)->At(j); - TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad()); - pDigitsH2->Fill(x2.X(),x2.Y(),100); + for(Int_t iDig=0;iDig < Digs(iCh)->GetEntries();iDig++){//digits loop + AliRICHDigit *pDig = (AliRICHDigit*)Digs(iCh)->At(iDig); + TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad()); + pDigitsH2->Fill(x2.X(),x2.Y(),100); }//digits loop pDigitsH2->SetMarkerColor(kGreen); pDigitsH2->SetMarkerStyle(29); pDigitsH2->SetMarkerSize(0.4); pDigitsH2->Draw("same"); @@ -981,9 +399,9 @@ void AliRICH::Display()const //deals with clusters if(isClusters){ GetLoader()->TreeR()->GetEntry(0); - for(Int_t j=0;jGetEntries();j++){//clusters loop - AliRICHCluster *pClus = (AliRICHCluster*)Clusters(iChamber)->At(j); - pClustersH2->Fill(pClus->X(),pClus->Y(),50); + for(Int_t iClu=0;iCluGetEntries();iClu++){//clusters loop + AliRICHCluster *pClu = (AliRICHCluster*)Clus(iCh)->At(iClu); + pClustersH2->Fill(pClu->X(),pClu->Y(),50); }//clusters loop pClustersH2->SetMarkerColor(kBlue); pClustersH2->SetMarkerStyle(29); pClustersH2->SetMarkerSize(0.4); pClustersH2->Draw("same"); @@ -997,35 +415,15 @@ void AliRICH::Display()const if(isDigits) GetLoader()->UnloadDigits(); if(isClusters) GetLoader()->UnloadRecPoints(); }//Display() -//__________________________________________________________________________________________________ -Int_t AliRICH::Nparticles(Int_t iPartID,Int_t iEvtN,AliRunLoader *pRL) -{ -//counts total number of particles of given type (including secondary) for a given event - pRL->GetEvent(iEvtN); - if(pRL->LoadHeader()) return 0; - if(pRL->LoadKinematics()) return 0; - AliStack *pStack=pRL->Stack(); - - Int_t iCounter=0; - for(Int_t i=0;iGetNtrack();i++){ - if(pStack->Particle(i)->GetPdgCode()==iPartID) iCounter++; - } - - pRL->UnloadHeader(); - pRL->UnloadKinematics(); - return iCounter; -} -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICH::ReadESD(Int_t iEventN, Int_t iChamber)const { // - AliInfo("Start."); TFile *pFile=TFile::Open("AliESDs.root","read"); if(!pFile || !pFile->IsOpen()) {AliInfo("ESD file not open.");return;} //open AliESDs.root TTree *pTree = (TTree*) pFile->Get("esdTree"); if(!pTree){AliInfo("ESD not found.");return;} //get ESD tree - AliInfo("ESD found. Try to draw ring"); AliESD *pESD=new AliESD; pTree->SetBranchAddress("ESD", &pESD); @@ -1039,14 +437,13 @@ void AliRICH::ReadESD(Int_t iEventN, Int_t iChamber)const AliESDtrack *pTrack = pESD->GetTrack(iTrackN);// get next reconstructed track Int_t charge = (Int_t)(-TMath::Sign(1.,pTrack->GetSign()*b)); AliRICHHelix helix(pTrack->X3(),pTrack->P3(),charge,b); - Int_t iChamberOnRICH=helix.RichIntersect(P()); + Int_t iChamberOnRICH=helix.RichIntersect(AliRICHParam::Instance()); if(iChamberOnRICH==iChamber) { -// TMarker *trackImpact = new TMarker(helix.PosPc().X(),helix.PosPc().Y(),kStar); trackImpact->SetMarkerColor(kRed); trackImpact->Draw(); // - Int_t iChamberRecon = pTrack->GetRICHcluster()/100000; + Int_t iChamberRecon = pTrack->GetRICHcluster()/1000000; if(iChamberRecon==iChamber) { Double_t thetaCer = pTrack->GetRICHsignal(); if(thetaCer<0) continue; @@ -1059,13 +456,11 @@ void AliRICH::ReadESD(Int_t iEventN, Int_t iChamber)const AliInfo(Form("ThetaCer %f TrackTheta %f TrackPhi %f Momentum %f",thetaCer,thetaTrack,phiTrack,pTrack->GetP())); Double_t dx,dy; pTrack->GetRICHdxdy(dx,dy); - AliInfo(Form("dx %f dy %f ",dx,dy)); DrawRing(entrance,vectorTrack,thetaCer); } } } delete pESD; pFile->Close();//close AliESDs.root - AliInfo("Stop."); } //__________________________________________________________________________________________________ void AliRICH::DrawRing(TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)const @@ -1074,7 +469,7 @@ void AliRICH::DrawRing(TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer) Int_t nPointsToDraw = 0; for(Int_t i=0;i<100;i++) { Double_t phiCer = 2*TMath::Pi()*i/100; - TVector3 pos = AliRICHParam::ForwardTracing(entrance,vectorTrack,thetaCer,phiCer); + TVector3 pos = AliRICHParam::Instance()->ForwardTracing(entrance,vectorTrack,thetaCer,phiCer); if(pos.X()==-999) continue; xGraph[nPointsToDraw] = pos.X();yGraph[nPointsToDraw] = pos.Y();nPointsToDraw++; } @@ -1108,7 +503,7 @@ void AliRICH::SummaryOfEvent(Int_t iEvtN) const GetLoader()->GetRunLoader()->UnloadKinematics(); } //__________________________________________________________________________________________________ -void AliRICH::HitsQA(Double_t cut,Double_t cutele,Double_t cutR) +void AliRICH::HitQA(Double_t cut,Double_t cutele,Double_t cutR) { // Provides a set of control plots intended primarily for charged particle flux analisys // Arguments: cut (GeV) - cut on momentum of any charged particles but electrons, diff --git a/RICH/AliRICH.h b/RICH/AliRICH.h index b353116f7f7..239a0c99c74 100644 --- a/RICH/AliRICH.h +++ b/RICH/AliRICH.h @@ -3,130 +3,88 @@ /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ -#include //inheritance -#include +#include //base class +#include #include #include #include -#include "AliRICHParam.h" #include "AliRICHCluster.h" #include "AliRICHHit.h" //__________________AliRICH_________________________________________________________________________ class AliESD; -class AliRICH : public AliDetector +class AliRICH : public AliDetector //TObject-TNamed-AliModule-AliDetector-AliRICH { public: //ctor & dtor AliRICH(); AliRICH(const char *name, const char *title); - AliRICH(const AliRICH& RICH):AliDetector(RICH) {;} //copy ctor + AliRICH(const AliRICH& RICH ):AliDetector(RICH) {;} //copy ctor virtual ~AliRICH(); AliRICH& operator=(const AliRICH&) {return *this;} //framework part - virtual Int_t IsVersion() const =0; //interface from - virtual void StepManager() =0; //interface from AliMC - virtual void SetTreeAddress(); //interface from AliLoader - virtual void MakeBranch(Option_t *opt=" "); //interface from AliLoader - virtual void CreateMaterials(); //interface from AliMC - virtual void CreateGeometry(); //interface from AliMC - virtual void BuildGeometry(); //interface - virtual void Print(Option_t *option="") const; //prints current RICH status + void BuildGeometry ( ); //from AliModule invoked from AliMC::InitGeometry() to build geometry for event display + virtual void CreateMaterials ( )=0; //from AliModule invoked from AliMC::ConstructGeometry() to define detector materials + virtual void CreateGeometry ( )=0; //from AliModule invoked from AliMC::ConstructGeometry() to build detector for simulation + virtual Int_t IsVersion ( )const=0; //from AliModule not used + virtual void Init ( )=0; //from AliModule invoked from AliMC::InitGeometry() after CreateGeometry() to do VolID initialization + void MakeBranch (Option_t *opt="" ); //from AliModule invokde from AliRun::Tree2Tree() to make requested RICH branch +// virtual void Print (const Option_t *opt)const=0; //from TObject + virtual void StepManager ( )=0; //from AliModule invoked from AliMC + void SetTreeAddress ( ); //from AliModule invoked from AliRun::GetEvent(), AliLoader::SetTAddrInDet() //private part - void GeomPadPanelFrame()const; //defines PPF geometry - void GeomAmpGap() const; //defines gap geometry + anod wires - void GeomRadiators() const; //defines radiators geometry - void GeomSandBox() const; //defines sandbox geometry - void GeomRadioSrc() const; //defines radio source geometry - void GeomAerogel() const; //defines aerogel geometry - static Float_t Fresnel(Float_t ene,Float_t pdoti, Bool_t pola); //deals with Fresnel absorption - - AliRICHHit* Hit (Int_t tid )const; //first hit of given TID - inline void HitAdd (Int_t c,Int_t tid,TVector3 in,TVector3 out,Double_t e=0); //add new hit - inline void HitsCreate ( ); //create hits container - void HitsPrint (Int_t iEvent=0 )const; //prints hits - void HitsQA (Double_t cut=0,Double_t cutele=0,Double_t cutR=999); + void HitAdd (Int_t c,Int_t tid,Int_t pid,TVector3 in,TVector3 out,Double_t e=0 ){new((*fHits)[fNhits++])AliRICHHit(c,tid,in,out,e,pid); } + void HitAdd (Int_t tid,Double_t e,Int_t pad,Double_t x,Double_t y,Double_t z,Int_t pid){new((*fHits)[fNhits++])AliRICHHit(tid,e,pad,x,y,z,pid); } + void HitCreate ( ){if(fHits)return; fHits=new TClonesArray("AliRICHHit"); fNhits=0;} + void HitPrint (Int_t iEvent=0 )const; + void HitQA (Double_t cut=0,Double_t cutele=0,Double_t cutR=999 ); - TClonesArray* SDigits ( )const{return fSdigits;} //pointer to sdigits list - inline void SDigitAdd (Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid ) ; //add new sdigit - inline void SDigitsCreate ( ) ; //create sdigits container - void SDigitsReset ( ) {fNsdigits=0; if(fSdigits) fSdigits ->Clear();} //clean a list of sdigits - void SDigitsPrint (Int_t iEvent=0 )const; //prints sdigits + TClonesArray* SDigs ( )const{return fSdig;} //pointer to sdigits list + inline void SDigAdd (Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid ) ; //add new sdigit + void SDigCreate ( ) {if(fSdig) return; fSdig=new TClonesArray("AliRICHDigit"); fSdigCnt=0;} + void SDigReset ( ) {fSdigCnt=0; if(fSdig) fSdig ->Clear();} //clean a list of sdigits + void SDigPrint (Int_t iEvent=0 )const; //prints sdigits - using AliDetector::Digits; - TClonesArray* Digits (Int_t iC )const{return fDigs ? (TClonesArray *)fDigs->At(iC-1):0;} - inline void DigitAdd (Int_t c,TVector pad,int q,int cfm,int *tid ) ; //add new digit - inline void DigitAdd (AliRICHDigit &dif ) ; //add new digit - inline void DigitsCreate ( ) ; //create digits - void DigitsReset ( ) {if(fDigs)for(int i=0;iAt(i)->Clear();fNdigs[i]=0;}} //virtual - void DigitsPrint (Int_t iEvent=0 )const; //prints digits + TClonesArray* Digs (Int_t iC )const{return fDig ? (TClonesArray *)fDig->At(iC-1):0;} + inline void DigAdd (Int_t c,TVector pad,int q,int cfm,int *tid ) ; //add new digit + inline void DigAdd (AliRICHDigit &dif ) ; //add new digit + inline void DigCreate ( ) ; //create digits + void DigReset ( ) {if(fDig)for(int i=0;iAt(i)->Clear();fDigCnt[i]=0;}} + void DigPrint (Int_t iEvent=0 )const; //prints digits - TClonesArray* Clusters (Int_t iC )const{if(fClus) return (TClonesArray *)fClus->At(iC-1);else return 0;} - inline void ClusterAdd (AliRICHCluster &cl ) ; //add new cluster - inline void ClustersCreate( ) ; //create clusters container - void ClustersReset ( ) {if(fClus)for(int i=0;iAt(i)->Clear();fNclus[i]=0;}} - void ClustersPrint (Int_t iEvent=0 )const; //prints a list of clusters for a given event - - void OccupancyPrint(Int_t iEvent=-1 )const; - void SummaryOfEvent(Int_t iEvent=0 )const; + TClonesArray* Clus (Int_t iC )const{return fClu ? (TClonesArray *)fClu->At(iC-1):0;} + inline void CluCreate ( ) ; //create clusters container + void CluReset ( ) {if(fClu)for(int i=0;iAt(i)->Clear();fCluCnt[i]=0;}} + void CluPrint (Int_t iEvent=0 )const; //prints a list of clusters for a given event - AliRICHChamber* C(Int_t iC) const{return fParam->C(iC);} //provides pointer to a given chamber - AliRICHParam* P() const{return fParam;} //provides pointer to a RICH params - AliRICH* R() {return this;} //provides pointer to RICH main object - TVector Counters() const{return fCounters;} //provides a set of counters - void ControlPlots(); //creates ~/RCP.root with a set of QA plots - void Display()const; //Display event - void DisplayEvent(Int_t,Int_t)const; //Display event - static Int_t Nparticles(Int_t iPid,Int_t iEventN,AliRunLoader *pRunLoader); //counts total number of particle with iPid - void PrintTracks (Int_t iEvent=0); //prints a list of tracks for a given event - void ReadESD(Int_t iEventN, Int_t iChamber)const; - void DrawRing(TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)const; + void Display ( )const; //Display event + void DisplayEvent (Int_t,Int_t )const; //Display event + void DrawRing (TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)const; + void OccupancyPrint(Int_t iEvent=-1 )const; //print chambers occupancy + void ReadESD (Int_t iEventN, Int_t iChamber )const; + void SummaryOfEvent(Int_t iEvent=0 )const; protected: - enum EMedia {kAir=1,kRoha,kSiO2,kC6F14,kCH4,kCsI,kGridCu,kOpSiO2,kGap,kAl,kGlass,kCu,kW,kSteel,kPerpex,kSr90,kMylar,kGel,kReflector}; - enum ECounters {kStepManager=0,kCerProdTot,kCerProdRad,kCerKillTot,kCerKillRad,kCerKillRef,kEleProdTot}; - AliRICHParam *fParam; //main RICH parametrization - //fHits and fDigits belong to AliDetector - TClonesArray *fSdigits; //! list of sdigits - Int_t fNsdigits; //! current number of sdigits + TClonesArray *fSdig; //! list of sdigits + Int_t fSdigCnt; //! current number of sdigits - TObjArray *fDigs; //! each chamber holds it's one lists of digits - Int_t fNdigs[7]; //! array of current numbers of digits + TObjArray *fDig; //! each chamber holds it's one list of digits + Int_t fDigCnt[7]; //! array of current numbers of digits - TObjArray *fClus; //! each chamber holds it's one lists of clusters - Int_t fNclus[7]; //! array of current numbers of raw clusters + TObjArray *fClu; //! each chamber holds it's one list of clusters + Int_t fCluCnt[7]; //! array of current numbers of raw clusters - TVector fCounters; //Particle history counters, explanation in StepManager() + TVector fCounters; // Particle history counters, explanation in StepManager() + Int_t fNcham; // Number of RICH chambers during simulation - ClassDef(AliRICH,9) //Main RICH class + ClassDef(AliRICH,11) //Main RICH class };//class AliRICH //__________________________________________________________________________________________________ -void AliRICH::HitsCreate() -{ - if(fHits) return; - AliDebug(1,"creating hits container."); - fHits=new TClonesArray("AliRICHHit",10000); fNhits=0; -} -//__________________________________________________________________________________________________ -void AliRICH::HitAdd(Int_t c,Int_t tid,TVector3 i3,TVector3 o3,Double_t eloss) -{ -//add new RICH hit to the list of hits - TClonesArray &tmp=*fHits; - new(tmp[fNhits++])AliRICHHit(c,tid,i3,o3,eloss); -}//AddHit() -//__________________________________________________________________________________________________ -void AliRICH::SDigitsCreate() -{ - if(fSdigits) return; - AliDebug(1,"creating sdigits container."); - fSdigits=new TClonesArray("AliRICHDigit",10000); fNsdigits=0; -} -//__________________________________________________________________________________________________ -void AliRICH::SDigitAdd(Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid) +void AliRICH::SDigAdd(Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid) { Int_t cfm; switch(pid){ @@ -134,42 +92,33 @@ void AliRICH::SDigitAdd(Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid) case 50000051: cfm=1000; break;//feedback default: cfm=1; break;//mip } - TClonesArray &tmp=*fSdigits; new(tmp[fNsdigits++])AliRICHDigit(c,pad,q,cfm,tid,-1,-1); + new((*fSdig)[fSdigCnt++])AliRICHDigit(c,pad,q,cfm,tid,-1,-1); } //__________________________________________________________________________________________________ -void AliRICH::DigitsCreate() +void AliRICH::DigCreate() { - if(fDigs) return; - AliDebug(1,"creating digits containers."); - fDigs = new TObjArray(kNchambers); - for(Int_t i=0;iAddAt(new TClonesArray("AliRICHDigit",10000), i); fNdigs[i]=0;} + if(fDig) return; + fDig = new TObjArray(fNcham); + for(Int_t i=0;iAddAt(new TClonesArray("AliRICHDigit"), i); fDigCnt[i]=0;} } //__________________________________________________________________________________________________ -void AliRICH::DigitAdd(AliRICHDigit &dig) +void AliRICH::DigAdd(AliRICHDigit &dig) { //special for digit formed from raw - TClonesArray &tmp=*((TClonesArray*)fDigs->At(dig.Chamber()-1)); - new(tmp[fNdigs[dig.Chamber()-1]++])AliRICHDigit(dig); + TClonesArray &tmp=*((TClonesArray*)fDig->At(dig.C()-1)); + new(tmp[fDigCnt[dig.C()-1]++])AliRICHDigit(dig); } //__________________________________________________________________________________________________ -void AliRICH::DigitAdd(int c,TVector pad,int q,int cfm,int *tid) +void AliRICH::DigAdd(int c,TVector pad,int q,int cfm,int *tid) { - TClonesArray &tmp=*((TClonesArray*)fDigs->At(c-1)); - new(tmp[fNdigs[c-1]++])AliRICHDigit(c,pad,q,cfm,tid[0],tid[1],tid[2]); + TClonesArray &tmp=*((TClonesArray*)fDig->At(c-1)); + new(tmp[fDigCnt[c-1]++])AliRICHDigit(c,pad,q,cfm,tid[0],tid[1],tid[2]); } //__________________________________________________________________________________________________ -void AliRICH::ClustersCreate() +void AliRICH::CluCreate() { - if(fClus) return; - AliDebug(1,"creating clusters containers."); - fClus = new TObjArray(kNchambers); - for(Int_t i=0;iAddAt(new TClonesArray("AliRICHCluster",10000), i); fNclus[i]=0;} + if(fClu) return; + fClu = new TObjArray(fNcham); + for(Int_t i=0;iAddAt(new TClonesArray("AliRICHCluster"), i); fCluCnt[i]=0;} } -//__________________________________________________________________________________________________ -void AliRICH::ClusterAdd(AliRICHCluster &cl) -{ - Int_t c=cl.C()-1;TClonesArray &tmp=*((TClonesArray*)fClus->At(c)); - new(tmp[fNclus[c]++])AliRICHCluster(cl); -} -//__________________________________________________________________________________________________ #endif//#ifndef AliRICH_h diff --git a/RICH/AliRICHCluster.cxx b/RICH/AliRICHCluster.cxx index 6e73674dc0d..3f91dd80fe0 100644 --- a/RICH/AliRICHCluster.cxx +++ b/RICH/AliRICHCluster.cxx @@ -13,171 +13,174 @@ // * provided "as is" without express or implied warranty. * // ************************************************************************** -#include "AliRICHCluster.h" -#include //Solve() - +#include "AliRICHCluster.h" //class header +#include //Solve() +#include //FindCfm(), Solve() +#include //FindCfm() +#include //Solve() Test() + ClassImp(AliRICHCluster) //__________________________________________________________________________________________________ -void AliRICHCluster::Print(Option_t*)const +void AliRICHCluster::CoG() { -//Print current cluster - const char *status=0; - switch(fStatus){ - case kFormed: status="formed" ;break; - case kUnfolded: status="unfolded" ;break; - case kCoG: status="CoGed" ;break; - case kEmpty: status="empty" ;break; - } - Int_t iNdigs=0; if(fDigits) iNdigs=fDigits->GetEntriesFast(); - - Printf("cfm=%10i, cs=%2i, Size=%2i Maxima=%2i, Shape=%5i, pos=(%7.3f,%7.3f) Q=%6i, %s", - fCFM,fChamber,Size(),Nlocmax(),fShape,fX,fY,fQdc,status,iNdigs); - for(Int_t i=0;iPrint(); -}//Print() +// Calculates naive cluster position as a center of gravity of its digits. +// Arguments: none +// Returns: shape of the cluster i.e. the box which fully contains the cluster + if(fDigs==0) return; //no digits in this cluster + fX=fY=0; //set cluster position to (0,0) to start to collect contributions + for(Int_t iDig=0;iDigGetEntriesFast();iDig++){//digits loop + AliRICHDigit *pDig=(AliRICHDigit*)fDigs->At(iDig); //get pointer to next digit + TVector pad=pDig->Pad(); Double_t q=pDig->Qdc(); //get pad adn QDC of this digit + TVector2 x2=AliRICHParam::Pad2Loc(pad); //calculate center of the pad in LORS + fX += x2.X()*q;fY +=x2.Y()*q; //sum up digit centers weighted by QDC + }//digits loop + fX/=fQdc;fY/=fQdc; //final center of gravity + TVector2 center = AliRICHParam::Pad2Loc(AliRICHParam::Loc2Pad(TVector2(fX,fY)));//center of the pad containing calculated cluster position + fX += AliRICHParam::CogCorr(fX-center.X()); //correct cluster position for sinoid + fStatus=kCoG; +}//CoG() //__________________________________________________________________________________________________ -TMinuit* AliRICHCluster::Solve() -{ -//At this point, cluster contains a list of digits, cluster charge is precalculated as a sum of digits charges (in AddDigit()), -//position is preset to (-1,-1) (in ctor), status is preset to kFormed in (AddDigit()), chamber-sector info is preseted to actual value (in AddDigit()) -//Here we decide what to do with this cluster: unfold or just calculate center of gravity -//Arguments: none -// Returns: pointer to fitter or 0 if no unfolding decided - TMinuit *pMinuit=0; - if(Size()>=2 && AliRICHParam::IsResolveClusters()) - pMinuit=Unfold(); - else - CoG(0); - return pMinuit; -}//Solve() -//__________________________________________________________________________________________________ -void AliRICHCluster::FitFunc(Int_t &iNpars, Double_t *, Double_t &chi2, Double_t *aPar, Int_t ) +void AliRICHCluster::FitFunc(Int_t &iNpars, Double_t *, Double_t &chi2, Double_t *par, Int_t ) { -//Cluster fit function -//par[0]=x par[1]=y par[2]=q for the first Mathieson shape -//par[3]=x par[4]=y par[5]=q for the second Mathieson shape and so on up to iNpars/3 Mathieson shapes -//We need to calculate Qpad - Qpadmath summup over all pads of the cluster -//Here Qpad is a actual charge of the pad, Qpadmath is calculated charge of the pad induced by all Mathiesons -//Arguments: iNpars - number of parameters which is number of local maxima of cluster * 3 -// chi2 - function result to be minimised -// aPar - parametrs array of size iNpars -// Returns: none +// Cluster fit function +// par[0]=x par[1]=y par[2]=q for the first Mathieson shape +// par[3]=x par[4]=y par[5]=q for the second Mathieson shape and so on up to iNpars/3 Mathieson shapes +// We need to calculate QpadExp - QpadMathieson summup over all pads of the cluster +// Here QpadExp is a actual charge of the pad, QpadMathieson is calculated charge of the pad induced by all Mathiesons +// Arguments: iNpars - number of parameters which is number of local maxima of cluster * 3 +// chi2 - function result to be minimised +// par - parameters array of size iNpars +// Returns: none AliRICHCluster *pClu=(AliRICHCluster*)gMinuit->GetObjectFit(); Int_t iNmathiesons = iNpars/3; TVector2 curMathiesonPos; chi2 = 0; - for(Int_t i=0;iSize();i++){//digits loop - TVector pad = pClu->Digit(i)->Pad(); - Double_t dQpad = pClu->Digit(i)->Qdc(); - Double_t dQpadmath = 0; - for(Int_t j=0;jSize();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;jGetEntriesFast(); - TMinuit *pMinuit = new TMinuit(15); //init MINUIT with max 15 parameters (maxim 5 mathiesons, 3 params per matheson ) - pMinuit->SetObjectFit((TObject*)this); - pMinuit->SetFCN(AliRICHCluster::FitFunc);//set fit function - Double_t aArg=-1,parStart,parStep,parLow,parHigh; Int_t iErrFlg; //tmp for MINUIT parameters definitions - pMinuit->mnexcm("SET PRI" ,&aArg,1,iErrFlg); //suspend all printout from TMinuit - + Printf("%s cs=%2i, Size=%2i (x=%7.3f cm,y=%7.3f cm,Q=%4i qdc), %s", + opt,fCham,iNdigs,fX,fY,fQdc,status); + for(Int_t i=0;iPrint(); +}//Print() +//__________________________________________________________________________________________________ +Int_t AliRICHCluster::Solve(TClonesArray *pCluLst,Bool_t isTryUnfold) +{ +//This methode is invoked when the cluster is formed to solve it. Solve the cluster means to try to unfold the cluster +//into the local maxima number of clusters. This methode is invoked by AliRICHRconstructor::Dig2Clu() on cluster by cluster basis. +//At this point, cluster contains a list of digits, cluster charge and size is precalculated in AddDigit(), position is preset to (-1,-1) in ctor, +//status is preset to kFormed in AddDigit(), chamber-sector info is preseted to actual values in AddDigit() +//Method first finds number of local maxima and if it's more then one tries to unfold this cluster into local maxima number of clusters +//Arguments: pCluLst - cluster list pointer where to add new cluster(s) +// isTryUnfold - flag to switch on/off unfolding +// Returns: number of local maxima of original cluster + +//Phase 0. Initialise TMinuit + const Int_t kMaxLocMax=6; //max allowed number of loc max for fitting + TMinuit *pMinuit = new TMinuit(3*kMaxLocMax); //init MINUIT with this number of parameters (3 params per mathieson) + pMinuit->SetObjectFit((TObject*)this); pMinuit->SetFCN(AliRICHCluster::FitFunc); //set fit function + Double_t aArg=-1,parStart,parStep,parLow,parHigh; Int_t iErrFlg; //tmp vars for TMinuit + pMinuit->mnexcm("SET PRI",&aArg,1,iErrFlg); //suspend all printout from TMinuit + pMinuit->mnexcm("SET NOW",&aArg,0,iErrFlg); //suspend all warning printout from TMinuit +//Phase 1. Find number of local maxima. Strategy is to check if the current pad has QDC more then all neigbours Int_t iLocMaxCnt=0; -//Strategy is to check if the current pad has QDC more then all neigbours - for(Int_t iDig1=0;iDig1PadX()-pDig2->PadX()),1)+TMath::Sign(Int_t(pDig1->PadY()-pDig2->PadY()),1);//distance between pads - if(dist==1)//means pads are neighbours - if(pDig2->Qdc()>=pDig1->Qdc()) iHowManyMoreCnt++;//count number of pads with Q more then Q of current pad + if(dist==1) //means dig2 is a neighbour of dig1 + if(pDig2->Qdc()>=pDig1->Qdc()) iHowManyMoreCnt++; //count number of pads with Q more then Q of current pad }//second digits loop - if(iHowManyMoreCnt==0&&iLocMaxCnt<6){//this pad has Q more then any neighbour so it's local maximum - TVector2 x2=AliRICHParam::Pad2Loc(pDig1->Pad());//take pad center position and use it as parameter for current Mathienson shape + if(iHowManyMoreCnt==0&&iLocMaxCnt<=kMaxLocMax){ //this pad has Q more then any neighbour so it's local maximum + TVector2 x2=AliRICHParam::Pad2Loc(pDig1->Pad()); //take pad center position and use it as parameter for current Mathienson shape pMinuit->mnparm(3*iLocMaxCnt ,Form("x%i",iLocMaxCnt),parStart=x2.X() ,parStep=0.01,parLow=0,parHigh=0,iErrFlg); pMinuit->mnparm(3*iLocMaxCnt+1,Form("y%i",iLocMaxCnt),parStart=x2.Y() ,parStep=0.01,parLow=0,parHigh=0,iErrFlg); - pMinuit->mnparm(3*iLocMaxCnt+2,Form("q%i",iLocMaxCnt),parStart=pDig1->Qdc(),parStep=0.01,parLow=0,parHigh=0,iErrFlg);// + pMinuit->mnparm(3*iLocMaxCnt+2,Form("q%i",iLocMaxCnt),parStart=pDig1->Qdc(),parStep=0.01,parLow=0,parHigh=0,iErrFlg); iLocMaxCnt++; }//if this pad is local maximum }//first digits loop - - fSize+=iLocMaxCnt; - if(iLocMaxCnt>0&&iLocMaxCnt<6){ //resonable number of local maxima to fit - Double_t aArg=0; - pMinuit->mnexcm("MIGRAD",&aArg,0,iErrFlg);//start fitting - fStatus=kUnfolded; - }else{ - delete pMinuit; - pMinuit=0; - CoG(0); +//Phase 2. Fit loc max number of Mathiesons or add this current cluster to the list + Int_t iCluCnt=pCluLst->GetEntriesFast(); //get current number of clusters already stored in the list by previous operations + if(isTryUnfold==kTRUE && iLocMaxCnt<=kMaxLocMax){ //resonable number of local maxima to fit and user requested it + pMinuit->mnexcm("MIGRAD" ,&aArg,0,iErrFlg); //start fitting + Double_t fitX,fitY,fitQ,d1,d2,d3; TString sName; //vars to get results from TMinuit + for(Int_t i=0;imnpout(3*i ,sName, fitX, d1 , d2, d3, iErrFlg); + pMinuit->mnpout(3*i+1 ,sName, fitY, d1 , d2, d3, iErrFlg); + pMinuit->mnpout(3*i+2 ,sName, fitQ, d1 , d2, d3, iErrFlg); + new ((*pCluLst)[iCluCnt++]) AliRICHCluster(C(),fitX,fitY,(Int_t)fitQ); //add new unfolded clusters + }//local maxima loop + }else{//do not unfold since number of loc max is unresonably high or user's baned unfolding + CoG(); + new ((*pCluLst)[iCluCnt++]) AliRICHCluster(*this); //add this raw cluster } - return pMinuit; -}//Unfold() -//__________________________________________________________________________________________________ -void AliRICHCluster::CoG(Int_t nLocals) -{ -//Calculates naive cluster position as a center of gravity of its digits. -//Also determines the box fully contaning this cluster -//Arguments: - Float_t xmin=999,ymin=999,xmax=0,ymax=0; - fX=fY=0; - for(Int_t iDig=0;iDigPad(); Double_t q=pDig->Qdc(); - TVector2 x2=AliRICHParam::Pad2Loc(pad); - fX += x2.X()*q;fY +=x2.Y()*q; - if(pad[0]xmax)xmax=pad[0];if(pad[1]ymax)ymax=pad[1]; - } - fX/=fQdc;fY/=fQdc;//Center of Gravity - - TVector2 center = AliRICHParam::Pad2Loc(AliRICHParam::Loc2Pad(TVector2(fX,fY))); - fX += AliRICHParam::CogCorr(fX-center.X());//correct cluster position for sinoid - - fShape=Int_t(100*(xmax-xmin+1)+ymax-ymin+1);//find box containing cluster - fSize+=nLocals; - fStatus=kCoG; -}//CoG() + delete pMinuit; + return iLocMaxCnt; +}//Solve() //__________________________________________________________________________________________________ -void AliRICHCluster::Test(const TVector2 &hitX2,Double_t dEloss) +void AliRICHCluster::Test(Double_t x,Double_t y,Double_t e,Bool_t isTryUnfold) { //This is to test all cluster functionality -//Method uses AddDigit() to add a predifined pad structure and then calls Solve - Int_t iQtot=AliRICHParam::TotQdc(hitX2,dEloss); +//Uses AddDigit() to add a predifined pad structure and then calls Solve + TVector2 hitX2(x,y); + Int_t iQtot=AliRICHParam::TotQdc(hitX2,e); if(iQtot==0){ Printf("Provided hit position out of sensitive area"); return; } TVector area=AliRICHParam::Loc2Area(hitX2); TVector pad(2); + AliRICHCluster clu; for(pad[1]=area[1];pad[1]<=area[3];pad[1]++){//affected pads loop first y for(pad[0]=area[0];pad[0]<=area[2];pad[0]++){//then x Double_t dQpad=iQtot*AliRICHParam::FracQdc(hitX2,pad);//charge fraction from Mathieson centered at x to pad - AddDigit(new AliRICHDigit(3,(Int_t)pad[0],(Int_t)pad[1],dQpad)); + clu.DigAdd(new AliRICHDigit(3,(Int_t)pad[0],(Int_t)pad[1],dQpad)); }//affected pads loop } - TMinuit *pMinuit=Solve(); - Print(); - Printf("Initial hit (%.2f,%.2f) Qtot=%i Eloss=%.2f",hitX2.X(),hitX2.Y(),iQtot,dEloss); - Double_t d1,d2,d3; Int_t iErrFlg;TString sName; //tmp vars for TMinuit - Double_t x,y,q; - for(Int_t i=0;imnpout(3*i ,sName, x, d1 , d2, d3, iErrFlg); - pMinuit->mnpout(3*i+1 ,sName, y, d1 , d2, d3, iErrFlg); - pMinuit->mnpout(3*i+2 ,sName, q, d1 , d2, d3, iErrFlg); - } - Printf(" Fitted hit (%.2f,%.2f) Qfit=%.0f",x,y,q); - delete pMinuit; pMinuit=0; Reset(); + Printf("Initial hit : (%.2f,%.2f) Qtot=%i E=%.2f eV",hitX2.X(),hitX2.Y(),iQtot,e*1e9); + clu.Print("Initial cluster:"); + TClonesArray *pCluLst=new TClonesArray("AliRICHCluster",1); + clu.Solve(pCluLst,isTryUnfold); + ((AliRICHCluster *)pCluLst->At(0))->Print("Solved cluster:"); + + delete pCluLst; clu.Reset(); }//Test() +//__________________________________________________________________________________________________ +void AliRICHCluster::Test() +{ +//Test cluster builder by a number of predefined digit patterns +//Arguments: none +// Returns: none + AliRICHCluster clu; Int_t ch,padx,pady,qdc; TClonesArray *pCluLst=new TClonesArray("AliRICHCluster",10); + Printf("2 digits vertical cluster"); + clu.DigAdd(new AliRICHDigit(ch=1,padx=3,pady=3,qdc=101)); + clu.DigAdd(new AliRICHDigit(ch=1,padx=3,pady=4,qdc=202)); clu.Print("Formed cluster:"); + clu.Solve(pCluLst,kTRUE); pCluLst->Print(); + delete pCluLst; +} diff --git a/RICH/AliRICHCluster.h b/RICH/AliRICHCluster.h index 74117ebe8c9..b5b62926a0e 100644 --- a/RICH/AliRICHCluster.h +++ b/RICH/AliRICHCluster.h @@ -3,90 +3,54 @@ /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ -#include //base class -#include //DistTo -#include "AliRICHDigit.h" -class TMinuit; +#include "AliRICHParam.h" //DigAdd(), Dig() class AliRICHCluster :public TObject { public: - enum EClusterStatus {kFormed,kCoG,kUnfolded,kEmpty}; - AliRICHCluster() :TObject(),fCFM(-1),fSize(-1),fShape(-1),fQdc(-1),fChamber(-1),fX(-1),fY(-1),fStatus(kEmpty),fDigits(0) {} //default ctor - AliRICHCluster(Int_t cs,Double_t x,Double_t y,Int_t q,Int_t sm):TObject(),fCFM(-1),fSize(sm),fShape(-1),fQdc(q ),fChamber(cs),fX(x ),fY(y ),fStatus(kEmpty),fDigits(0) {} //default ctor - virtual ~AliRICHCluster() {} //dtor - // AliRICHcluster(const AliRICHcluster& clus):TObject(clus) {} //copy ctor - AliRICHCluster& operator=(const AliRICHCluster&) {return *this;} //copy operator - - void Print(Option_t *option="")const; // - - - void Reset() {DeleteDigits();fCFM=fSize=fShape=fQdc=fChamber=-1;fX=fY=-1;fStatus=kEmpty;} //cleans the cluster - void DeleteDigits() {if(fDigits) {delete fDigits;} fDigits=0;} //deletes the list of digits - Int_t Nlocmax() const{return fSize-10000*(fSize/10000);} //number of local maximums - Int_t Size() const{return fSize/10000;} //number of digits in cluster - Int_t Fsize() const{return fSize;} // - Int_t Shape() const{return fShape;} //cluster shape rectangulare - Int_t C() const{return fChamber/10;} //chamber number - Int_t S() const{return fChamber-(fChamber/10)*10;} //sector number - Int_t Fchamber() const{return fChamber;} // - Int_t Q() const{return fQdc;} //cluster charge in QDC channels - Double_t X() const{return fX;} //cluster x position in LRS - Double_t Y() const{return fY;} //cluster y position in LRS - Int_t Status() const{return fStatus;} // - void SetStatus(Int_t status) {fStatus=status;} // - Int_t Nmips() const{return fCFM-1000000*Ncerenkovs()-1000*Nfeedbacks();} // - Int_t Ncerenkovs() const{return fCFM/1000000;} // - Int_t Nfeedbacks() const{return (fCFM-1000000*Ncerenkovs())/1000;} // - Bool_t IsPureMip() const{return fCFM<1000;} // - Bool_t IsPureCerenkov() const{return Nmips()==0&&Nfeedbacks()==0;} // - Bool_t IsPureFeedback() const{return Nmips()==0&&Ncerenkovs()==0;} // - Bool_t IsSingleMip() const{return Nmips()==1&&Ncerenkovs()==0&&Nfeedbacks()==0;} // - Bool_t IsSingleCerenkov() const{return Nmips()==0&&Ncerenkovs()==1&&Nfeedbacks()==0;} // - Bool_t IsSingleFeedback() const{return Nmips()==0&&Ncerenkovs()==0&&Nfeedbacks()==1;} // - Bool_t IsMip() const{return Nmips()!=0;} // - Bool_t IsCerenkov() const{return Ncerenkovs()!=0;} // - Bool_t IsFeedback() const{return Nfeedbacks()!=0;} // - Int_t CombiPid() const{return fCFM;} // - void CFM(Int_t c,Int_t f,Int_t m) {fCFM=1000000*c+1000*f+m;} //cluster contributors - TObjArray* Digits() const{return fDigits;} // - - inline void AddDigit(AliRICHDigit *pDig); //add new digit ot the cluster - AliRICHDigit* Digit (Int_t i )const{return (AliRICHDigit*)fDigits->At(i); }//get pointer to i-th digit without existence check - TMinuit* Solve ( ); //calculates cluster position - TMinuit* Unfold ( ); //decompose cluster n. loc max clusters - void Set (Double_t x,Double_t y,Int_t q) {fX=x;fY=y,fQdc=q; }//set some cluster properties - static void FitFunc(Int_t &iNpars, Double_t *, Double_t &chi2, Double_t *aPar, Int_t); //fit function to be used by MINUIT - - void CoG(Int_t iNlocmax); //calculates center of gravity - void Fill(AliRICHCluster *pRaw,Double_t x,Double_t y,Double_t q,Int_t cfm) //form new resolved cluster from raw one - {fCFM=cfm;fChamber=pRaw->Fchamber();fSize=pRaw->Fsize();fQdc=(Int_t)(q*pRaw->Q());fX=x;fY=y;fStatus=kUnfolded;} - Double_t DistTo(TVector2 x) const{return TMath::Sqrt((x.X()-fX)*(x.X()-fX)+(x.Y()-fY)*(x.Y()-fY));} //distance to given point - Double_t DistX(TVector2 x) const{return (x.X()-fX);} //distance in x to given point - Double_t DistY(TVector2 x) const{return (x.Y()-fY);} //distance to given point - void Test(const TVector2 &x,Double_t dEloss=0); //test cluster fuctionality by provided hit with energy in eV + enum EClusterStatus {kFormed,kCoG,kUnfolded,kEmpty=-1}; + AliRICHCluster( ):TObject(),fQdc(-1),fCham(-1),fX(-1),fY(-1),fStatus(kEmpty ),fDigs(0) {} + AliRICHCluster(Int_t c,Double_t x,Double_t y,Int_t q):TObject(),fQdc(q ),fCham(c) ,fX(x ),fY(y ),fStatus(kUnfolded),fDigs(0) {} + virtual ~AliRICHCluster( ) {if(fDigs) delete fDigs;} +//framework part + void Print (Option_t *opt="" )const; //overloaded TObject::Print() to print cluster info + static void FitFunc(Int_t &, Double_t *, Double_t &, Double_t *, Int_t); //fit function to be used by MINUIT +//private part + void CoG ( ); //calculates center of gravity + Int_t C ( )const{return fCham; } //chamber number + inline void DigAdd (AliRICHDigit *pDig ); //add new digit ot the cluster + void DigDel ( ) {if(fDigs) {delete fDigs;} fDigs=0; } //deletes the list of digits + void DistXY (const TVector2 &p,Double_t &x,Double_t &y)const{ x=p.X()-fX; y=p.Y()-fY; } //distance in x to given point + AliRICHDigit* Dig (Int_t i )const{return (AliRICHDigit*)fDigs->At(i); } //pointer to i-th digit + TObjArray* Digits ( )const{return fDigs; } //list of digits + TVector3 Lors2Mars() const{return AliRICHParam::Instance()->Lors2Mars(fCham,fX,fY); } //cluster position in MARS + void Reset ( ) {DigDel();fQdc=fCham=-1;fX=fY=-1;fStatus=kEmpty;} //cleans the cluster + Int_t Solve (TClonesArray *pCluLst,Bool_t isUnfold ); //solve cluster: MINUIT fit or CoG + Int_t Size ( )const{return (fDigs)?fDigs->GetEntriesFast():0; } //number of pads in cluster + Int_t Q ( )const{return fQdc; } //cluster charge in QDC channels + Double_t X ( )const{return fX; } //cluster x position in LRS + Double_t Y ( )const{return fY; } //cluster y position in LRS +//test part + static void Test (Double_t x,Double_t y,Double_t e=0,Bool_t isUnfold=kTRUE); //test by hit (x [cm] , y [cm] , e [GeV]) + static void Test ( ); //test by predifined patterns protected: - Int_t fCFM; //1000000*Ncerenkovs+1000*Nfeedbacks+Nmips - Int_t fSize; //10000*(N digits) + N maxima - Int_t fShape; //100*xdim+ydim box containing the cluster Int_t fQdc; //QDC value - Int_t fChamber; //10*chamber number+sector number - Double_t fX; //local x postion - Double_t fY; //local y postion + Int_t fCham; //10*chamber number+sector number + Double_t fX; //local x postion, cm + Double_t fY; //local y postion, cm Int_t fStatus; //flag to mark the quality of the cluster - TObjArray *fDigits; //! list of digits forming this cluster - ClassDef(AliRICHCluster,2) //RICH cluster class + TObjArray *fDigs; //! list of digits forming this cluster + ClassDef(AliRICHCluster,3) //RICH cluster class };//class AliRICHCluster -//__________________________________________________________________________________________________ -void AliRICHCluster::AddDigit(AliRICHDigit *pDig) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHCluster::DigAdd(AliRICHDigit *pDig) { // Adds a given digit to the list of digits belonging to this cluster - if(!fDigits) {fQdc=fSize=0;fDigits = new TObjArray;} - fDigits->Add(pDig); + if(!fDigs) {fQdc=0;fDigs = new TObjArray;} + fDigs->Add(pDig); fQdc+=(Int_t)pDig->Qdc(); - fChamber=10*pDig->Chamber()+pDig->Sector(); - fSize+=10000; + fCham=pDig->C(); fStatus=kFormed; } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #endif diff --git a/RICH/AliRICHClusterFinder.cxx b/RICH/AliRICHClusterFinder.cxx deleted file mode 100644 index 26e3004e221..00000000000 --- a/RICH/AliRICHClusterFinder.cxx +++ /dev/null @@ -1,363 +0,0 @@ -/************************************************************************** - * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * * - * Author: The ALICE Off-line Project. * - * Contributors are mentioned in the code where appropriate. * - * * - * Permission to use, copy, modify and distribute this software and its * - * documentation strictly for non-commercial purposes is hereby granted * - * without fee, provided that the above copyright notice appears in all * - * copies and that both the copyright notice and this permission notice * - * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * - * provided "as is" without express or implied warranty. * - **************************************************************************/ - - -#include "AliRICHClusterFinder.h" -#include "AliRICHMap.h" -#include -#include -#include -#include -#include -#include -#include "AliRICHParam.h" - -void RICHMinMathieson(Int_t &npar, Double_t *gin, Double_t &chi2, Double_t *par, Int_t iflag); - -ClassImp(AliRICHClusterFinder) -//__________________________________________________________________________________________________ -AliRICHClusterFinder::AliRICHClusterFinder(AliRunLoader *pRunLoader) -{//main ctor - fRICH = (AliRICH*) pRunLoader->GetAliRun()->GetDetector("RICH"); - - AliDebug(1,"main ctor Start."); - - fDigitMap = 0; - fRawCluster.Reset(); - fResolvedCluster.Reset(); - AliDebug(1,"main ctor Stop."); -}//main ctor -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::Exec(const Option_t *) -{ -//Main method of cluster finder. Loops on events and chambers, everything else is done in FindClusters() - AliDebug(1,"Exec Start."); - - R()->GetLoader() ->LoadDigits(); -// R()->GetLoader()->GetRunLoader()->LoadHeader(); - if(!R()->GetLoader()->GetRunLoader()->TreeK()) R()->GetLoader()->GetRunLoader()->LoadKinematics(); - - for(Int_t iEventN=0;iEventNGetEventsPerRun();iEventN++){//events loop - AliDebug(1,Form("Processing event %i...",iEventN)); - R()->GetLoader()->GetRunLoader()->GetEvent(iEventN); - - R()->GetLoader()->MakeTree("R"); R()->MakeBranch("R"); - R()->DigitsReset(); R()->ClustersReset(); - - R()->GetLoader()->TreeD()->GetEntry(0); - for(Int_t iChamber=1;iChamber<=kNchambers;iChamber++){//chambers loop - FindClusters(iChamber); - }//chambers loop - R()->GetLoader()->TreeR()->Fill(); R()->GetLoader()->WriteRecPoints("OVERWRITE");//write out clusters for current event - }//events loop - - R()->DigitsReset();//reset and unload everything - R()->ClustersReset(); - R()->GetLoader() ->UnloadDigits(); - R()->GetLoader() ->UnloadRecPoints(); -// R()->GetLoader()->GetRunLoader()->UnloadHeader(); - R()->GetLoader()->GetRunLoader()->UnloadKinematics(); - - AliDebug(1,"Stop."); -}//Exec() -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::FindClusters(Int_t iChamber) -{ -//Loops on digits for a given chamber, forms raw clusters, then tries to resolve them if requested - Int_t iNdigits=R()->Digits(iChamber)->GetEntriesFast(); - AliDebug(1,Form("Start for chamber %i with %i digits.",iChamber,iNdigits)); - - if(iNdigits==0)return;//no digits for a given chamber, nothing to do - - fDigitMap=new AliRICHMap(R()->Digits(iChamber));//create digit map for the given chamber - - for(Int_t iDigN=0;iDigNDigits(iChamber)->At(iDigN); - Int_t i=dig->PadX(); Int_t j=dig->PadY(); - if(fDigitMap->TestHit(i,j)==kUsed) continue;//this digit is already taken, go after next digit - - FormRawCluster(i,j);//form raw cluster starting from (i,j) pad - AliDebug(1,"After FormRawCluster:");ToAliDebug(1,fRawCluster.Print()); - FindLocalMaxima(); //find number of local maxima and initial center of gravity - AliDebug(1,"After FindLocalMaxima:");ToAliDebug(1,fRawCluster.Print()); - - if(AliRICHParam::IsResolveClusters()&&fNlocals<=6&&fRawCluster.Size()>1){ - FitCoG(); //serialization of resolved clusters will happen inside - }else{//cluster size=1 or resolving is switched off - WriteRawCluster();//simply output the formed raw cluster without deconvolution - } - fRawCluster.Reset(); fResolvedCluster.Reset(); - }//digits loop for a given chamber - - delete fDigitMap; - - AliDebug(1,"Stop."); -}//FindClusters() -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::FindClusterContribs(AliRICHCluster *pCluster) -{ -//Finds cerenkov-feedback-mip mixture for a given cluster - AliDebug(1,"Start.");ToAliDebug(1,pCluster->Print()); - -// R()->GetLoader()->GetRunLoader()->LoadHeader(); //...message from AliRunLoader...hopefully will disappear in future... - // sometimes no stack found if the above line is commented out!! - AliStack *pStack = R()->GetLoader()->GetRunLoader()->Stack(); - if(!pStack) - {AliInfo("No Stack found!!! No contrib to cluster found.");return;} - - TObjArray *pDigits = pCluster->Digits(); - if(!pDigits) return; //?????????? - Int_t iNmips=0,iNckovs=0,iNfeeds=0; - TArrayI contribs(3*pCluster->Size()); - Int_t *pindex = new Int_t[3*pCluster->Size()]; - for(Int_t iDigN=0;iDigNSize();iDigN++) {//loop on digits of a given cluster - contribs[3*iDigN] =((AliRICHDigit*)pDigits->At(iDigN))->GetTrack(0); - if (contribs[3*iDigN] >= 10000000) contribs[3*iDigN] = 0; - contribs[3*iDigN+1]=((AliRICHDigit*)pDigits->At(iDigN))->GetTrack(1); - if (contribs[3*iDigN+1] >= 10000000) contribs[3*iDigN+1] = 0; - contribs[3*iDigN+2]=((AliRICHDigit*)pDigits->At(iDigN))->GetTrack(2); - if (contribs[3*iDigN+2] >= 10000000) contribs[3*iDigN+2] = 0; - }//loop on digits of a given cluster - TMath::Sort(contribs.GetSize(),contribs.GetArray(),pindex); - for(Int_t iDigN=0;iDigN<3*pCluster->Size()-1;iDigN++) {//loop on digits to sort tids - AliDebug(1,Form("%4i for digit n. %4i",contribs[pindex[iDigN]],iDigN)); - if(contribs[pindex[iDigN]]!=contribs[pindex[iDigN+1]]) { - Int_t thecontrib = contribs[pindex[iDigN]]; - if (thecontrib>=pStack->GetNtrack()) continue;//PH this should not happen - TParticle* particle = pStack->Particle(thecontrib); - if (!particle) continue;//PH this should not happen - Int_t code = particle->GetPdgCode(); - Double_t charge = 0; - if(particle->GetPDG()) charge=particle->GetPDG()->Charge(); - AliDebug(1,Form(" charge of particle %f",charge)); - - if(code==50000050) iNckovs++; - if(code==50000051) iNfeeds++; - if(charge!=0) iNmips++; - } - }//loop on digits to sort Tid - - if (contribs[pindex[3*pCluster->Size()-1]]!=-1) { - Int_t thecontrib = contribs[pindex[3*pCluster->Size()-1]]; - if (thecontribGetNtrack()){ - //PH the opposite should not happen - - TParticle* particle = pStack->Particle(thecontrib); - if (particle) { - //PH the opposite should not happen - Int_t code = particle->GetPdgCode(); - Double_t charge = 0; - if(particle->GetPDG()) charge=particle->GetPDG()->Charge(); - AliDebug(1,Form(" charge of particle %f",charge)); - if(code==50000050) iNckovs++; - if(code==50000051) iNfeeds++; - if(charge!=0) iNmips++; - } - } - } - - pCluster->CFM(iNckovs,iNfeeds,iNmips); -// - delete [] pindex; - ToAliDebug(1,pCluster->Print()); - AliDebug(1,"Stop."); -}//FindClusterContribs() -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::FormRawCluster(Int_t i, Int_t j) -{ -//Builds the raw cluster (before deconvolution). Starts from the first pad (i,j) then calls itself recursevly for all neighbours. - AliDebug(1,Form("Start with digit(%i,%i) Q=%f",i,j,((AliRICHDigit*)fDigitMap->GetHit(i,j))->Qdc())); - - fRawCluster.AddDigit((AliRICHDigit*) fDigitMap->GetHit(i,j));//take this pad in cluster - fDigitMap->FlagHit(i,j);//flag this pad as taken - - Int_t listX[4], listY[4]; // Now look recursively for all neighbours - for (Int_t iNei=0;iNeiP()->PadNeighbours(i,j,listX,listY);iNei++) - if(fDigitMap->TestHit(listX[iNei],listY[iNei])==kUnused) FormRawCluster(listX[iNei],listY[iNei]); -}//FormRawCluster() -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::FindLocalMaxima() -{ -//find number of local maxima in the current raw cluster and then calculates initial center of gravity - fNlocals=0; - AliDebug(1,Form("Cluster size of the Raw cluster ---> %i",fRawCluster.Size())); - for(Int_t iDig1=0;iDig1At(iDig1); - if(!pDig1) {fNlocals=0;return;} - TVector pad1 = pDig1->Pad(); - Int_t padQ1 = (Int_t)(pDig1->Qdc()+0.1); - Int_t padC1 = pDig1->Cfm(); - for(Int_t iDig2=0;iDig2At(iDig2); - if(!pDig2) {fNlocals=0;return;} - TVector pad2 = pDig2->Pad(); - Int_t padQ2 = (Int_t)(pDig2->Qdc()+0.1); - if(iDig1==iDig2) continue; - Int_t diffx = TMath::Sign(Int_t(pad1[0]-pad2[0]),1); - Int_t diffy = TMath::Sign(Int_t(pad1[1]-pad2[1]),1); - if((diffx+diffy)<=1) { - if(padQ2>=padQ1) iNotMax++; - } - } - if(iNotMax==0) { - if (fNlocals<100) { - TVector2 x2=AliRICHParam::Pad2Loc(pad1); - fLocalX[fNlocals]=x2.X();fLocalY[fNlocals]=x2.Y(); - fLocalQ[fNlocals] = (Double_t)padQ1; - fLocalC[fNlocals] = padC1; - fNlocals++; - } - } - } - AliDebug(1,Form("Number of local maxima found ---> %i",fNlocals)); - fRawCluster.CoG(fNlocals); //first initial approximation of the CoG...to start minimization. -}//FindLocalMaxima() -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::WriteRawCluster() -{ -//Add the current raw cluster to the list of clusters - AliDebug(1,"Start."); - - FindClusterContribs(&fRawCluster); - R()->ClusterAdd(fRawCluster); - - ToAliDebug(1,fRawCluster.Print()); AliDebug(1,"Stop."); -}//WriteRawCluster() -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::WriteResolvedCluster() -{ -//Add the current resolved cluster to the list of clusters - AliDebug(1,"Start."); - - FindClusterContribs(&fResolvedCluster); - R()->ClusterAdd(fResolvedCluster); - - ToAliDebug(1,fResolvedCluster.Print()); AliDebug(1,"Stop."); -}//WriteResolvedCluster() -//__________________________________________________________________________________________________ -void AliRICHClusterFinder::FitCoG() -{ -//Fits cluster of size by the corresponding number of Mathieson shapes. -//This methode is only invoked in case everything is ok to start deconvolution - AliDebug(1,"Start with:"); ToAliDebug(1,fRawCluster.Print()); - - Double_t arglist; - Int_t ierflag = 0; - - AliDebug(1,Form("MINUIT Started with %i parameters and %i local maxima",3*fNlocals-1,fNlocals)); - -// TMinuit *pMinuit = new TMinuit(3*fNlocals-1); - TMinuit *pMinuit = new TMinuit(100); - pMinuit->mninit(5,10,7); - - arglist = -1; - pMinuit->mnexcm("SET PRI",&arglist, 1, ierflag); - pMinuit->mnexcm("SET NOW",&arglist, 0, ierflag); - - TString chname; - Int_t ierflg; - - pMinuit->SetObjectFit((TObject*)this); - pMinuit->SetFCN(RICHMinMathieson); - - Double_t vstart,lower, upper; - Double_t stepX= 0.01; - Double_t stepY= 0.01; - Double_t stepQ= 0.01; - - for(Int_t i=0;imnparm(3*i ,Form("xCoG %i",i),vstart,stepX,lower,upper,ierflag); - AliDebug(1,Form("xCoG %i vstart %f lower %f upper %f ",i,vstart,lower,upper)); - - vstart = fLocalY[i]; - lower = vstart - 2*AliRICHParam::PadSizeY(); - upper = vstart + 2*AliRICHParam::PadSizeY(); - pMinuit->mnparm(3*i+1,Form("yCoG %i",i),vstart,stepY,lower,upper,ierflag); - AliDebug(1,Form("yCoG %i vstart %f lower %f upper %f ",i,vstart,lower,upper)); - if(i==fNlocals-1) break; // last parameter is constrained - vstart = fLocalQ[i]/fRawCluster.Q(); - lower = 0; - upper = 1; - pMinuit->mnparm(3*i+2,Form("qfrac %i",i),vstart,stepQ,lower,upper,ierflag); - AliDebug(1,Form("qfrac %i vstart %f lower %f upper %f ",i,vstart,lower,upper)); - } - - arglist = -1; pMinuit->mnexcm("SET NOGR",&arglist, 1,ierflag); - arglist = 1; pMinuit->mnexcm("SET ERR" ,&arglist, 1,ierflg); - arglist = -1; pMinuit->mnexcm("SIMPLEX" ,&arglist, 0,ierflag); - pMinuit->mnexcm("MIGRAD",&arglist, 0, ierflag); -// pMinuit->mnexcm("EXIT" ,&arglist, 0, ierflag); - - Double_t xCoG[50],yCoG[50],qfracCoG[50]; - Double_t eps, b1, b2; - - Double_t qfraclast=0; - for(Int_t i=0;imnpout(3*i ,chname, xCoG[i], eps , b1, b2, ierflg); - pMinuit->mnpout(3*i+1,chname, yCoG[i], eps , b1, b2, ierflg); - if(i==fNlocals-1) break; - pMinuit->mnpout(3*i+2,chname, qfracCoG[i], eps , b1, b2, ierflg); - qfraclast+=qfracCoG[i]; - } - qfracCoG[fNlocals-1] = 1 - qfraclast; - - delete pMinuit; - - for(Int_t i=0;iGetObjectFit())->GetRawCluster(); - - TVector2 centroid[50]; - Double_t q[50]; - Int_t nFunctions = (npar+1)/3; - Double_t qfract = 0; - for(Int_t i=0;iQ(); - for(Int_t i=0;iSize();i++) { - TVector pad=((AliRICHDigit *)pRawCluster->Digits()->At(i))->Pad(); - Double_t padQ = ((AliRICHDigit *)pRawCluster->Digits()->At(i))->Qdc(); - Double_t qfracpar=0; - for(Int_t j=0;j%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)); } diff --git a/RICH/AliRICHDigit.h b/RICH/AliRICHDigit.h index 80636244d3b..df37f55325d 100644 --- a/RICH/AliRICHDigit.h +++ b/RICH/AliRICHDigit.h @@ -4,65 +4,93 @@ * See cxx source for full Copyright notice */ #include //base class -#include //Dig2Raw() -#include "AliRICHParam.h" +#include //ToRaw(), FromRaw() +#include //ctor +/* +Any given LDC collects data from all FEE connected to the LDC by DDL. This data is stored in name.ddl file. +Name of this file is composed by detector name plus some value for example RICH1793.ddl +That value is calculated as sequensial number of detector LDC plus some predifined offset, unique for a given detector. +The value is expected to be within a given range assigned to detector. +For RICH, the offset number is 0x700 hex or 1792 decimal (reffered in the code as kDdlOffset). +The range assigned for RICH is 0x700-0x714 hex or 1792-1812 decimal. It is 20 ddl files or 20 LDCs. +RICH actually uses 14 LDCs hence DAQ writes for RICH 14 ddl files (reffered in the code as kNddls). +RICH FEE is connected to LDC in the following way: +Single LDC serves one half of a chamber i.e. 3 photocathodes aka sectors, even LDC for left part( sectors 1-3-5) and odd LDC for right part(2-4-6) +So the LDC -chamber-ddl file name map is: +LDC 0 -> ch 1L -> file name value 0x700 1792 LDC 1 -> ch 1R -> file name value 0x701 1793 +LDC 2 -> ch 2L -> file name value 0x702 1794 LDC 3 -> ch 2R -> file name value 0x703 1795 +LDC 4 -> ch 3L -> file name value 0x704 1796 LDC 5 -> ch 3R -> file name value 0x705 1797 +LDC 6 -> ch 4L -> file name value 0x706 1798 LDC 7 -> ch 4R -> file name value 0x707 1799 +LDC 8 -> ch 5L -> file name value 0x708 1800 LDC 9 -> ch 5R -> file name value 0x709 1801 +LDC 10 -> ch 6L -> file name value 0x70a 1802 LDC 11 -> ch 6R -> file name value 0x70b 1803 +LDC 12 -> ch 7L -> file name value 0x70c 1804 LDC 13 -> ch 7R -> file name value 0x70d 1805 -//RICH DDL ID allowed range is [0x700,0x714] or in decimal notation [1792,1812]. 20 DDL files are reserved. (kDdlOffset) -//RICH actually uses 14 DDLs (kNddls), 2 per chamber, even number for left part(1-3-5) odd number for right part(2-4-6) -//So the chamber-DDL map is: -//N 0 1L=0x700 1792 N 1 1R=0x701 1793 -//N 2 2L=0x702 1794 N 3 2R=0x703 1795 -//N 4 3L=0x704 1796 N 5 3R=0x705 1797 -//N 6 4L=0x706 1798 N 7 4R=0x707 1799 -//N 8 5L=0x708 1800 N 9 5R=0x709 1801 -//N 10 6L=0x70a 1802 N 11 6R=0x70b 1803 -//N 12 7L=0x70c 1804 N 13 7R=0x70d 1805 -//RICH has no any propriate header just uses the common one -//RICH chamber is divide on 2 halves vertically -//Half chamber is divided by 24 rows counted from 1 to 24 (8 raws per sector) from top to bottom for left half chamber (sectors 1-3-5) -// and from bottom to top for right half chamber (sectors 2-4-6) as seen from MARS (0,0,0) -//Raw is composed from 10 DILOGIC chips (kNchips) counted from left to right from 1 to 10 as seen from MARS (0,0,0) -//So each DILOGIC chip serves 48 channels for the 8x6 pads box (kChipX,kChipY). Channels counted from 0 to 47. -//??????? Currently the exact mapping of DILOGIC addresses to pads is not known. So we invented horizontal zig-zag ??????? -//So RICH raw word is 32 bits word with structure: -// 00000 rrrrr dddd aaaaaa qqqqqqqqqqqq -// 5 bits zero 5 bits raw number (1..24) 4 bits DILOGIC chip number (1..10) 6 bits DILOGIC address (0..47) 12 bits QDC value (0..4095) +Programmatically, operations with ddl files are interfaced by class AliRawReader. In order to select some ddl files for detector, +one needs to provide a reserved id number of detector. For RICH, this number is 7 (reffered in the code as kRichRawId). + +DDL file starts with common header described in AliRawDataHeader, which can be followed by private header. +RICH has no any private header, just uses the common one. + +RICH FEE as seen by single LDC is composed from a number of DILOGIC chips organized in vertical stack of rows. +Each DILOGIC chip serves 48 channels for the 8x6 pads (reffered in the code as kDiloX,kDiloY). Channels counted from 0 to 47. + +??????? Currently the exact mapping of DILOGIC addresses to pads is not known. So we invented horizontal zig-zag ??????? + +10 DILOGIC chips composes so called "row" in horizontal direction (reffered in the code as kNdilo), so the row is 80x6 pads structure. +DILOGIC chips in the row are counted from left to right as seen from MARS (0,0,0), from 1 to 10. +24 rows are piled up forming the whole FEE served by single LDC, so one LDC sees 80x144 pads separated in 3 photocathodes aka sectors. +Rows are counted from 1 to 24 from top to bottom for left half chamber (sectors 1-3-5) as seen from MARS (0,0,0), meaning even LDC number + and from bottom to top for right half chamber (sectors 2-4-6) as seen from MARS (0,0,0), meaning odd LDC number. + +So RICH raw word is 32 bits with the structure: + 00000 rrrrr dddd aaaaaa qqqqqqqqqqqq + 5 bits zero 5 bits row number (1..24) 4 bits DILOGIC chip number (1..10) 6 bits DILOGIC address (0..47) 12 bits QDC value (0..4095) +*/ class AliRICHDigit :public AliDigit { public: - enum EAbsPad {kChamber=10000000,kPadX=1000}; //absolute pad number structure - enum ERawProp{kChipX=8,kChipY=6,kNchips=10,kNddls=14,kRichRawId=7,kDdlOffset=0x700};//DILOGIC is 8x6 pads - AliRICHDigit() :AliDigit(),fCFM(-1),fChamber(-1 ) ,fPadX(-1) ,fPadY(-1) ,fQdc(-1) {} - AliRICHDigit(Int_t c,Int_t x,Int_t y,Double_t q):AliDigit(),fCFM(-1),fChamber(10*c) ,fPadX(x ) ,fPadY(y ) ,fQdc(q ) {} - AliRICHDigit(Int_t c,TVector pad,Double_t q,Int_t cfm,Int_t tid0,Int_t tid1,Int_t tid2):fCFM(cfm) - {fPadX=(Int_t)pad[0];fPadY=(Int_t)pad[1];fQdc=q;fChamber=10*c+AliRICHParam::Pad2Sec(pad);fTracks[0]=tid0;fTracks[1]=tid1;fTracks[2]=tid2;} + enum EAbsPad {kChamAbs=10000000,kSecAbs=1000000,kPadAbsX=1000,kPadAbsY=1}; //absolute pad number structure + enum ERawData{kDiloX=8,kDiloY=6,kNdilo=10}; //DILOGIC structure, see description above + enum EPadData{kFirstPad=1,kPadsSecX=80,kPadsSecY=48,kPadsChamX=160,kPadsChamY=144,kSecX=2,kSecY=3}; //Segmentation structure + enum EDdlData{kNddls=14,kDdlOffset=0x700,kRichRawId=7}; //Common DDL structure, see description above +//ctor&dtor + AliRICHDigit() :AliDigit(),fCFM(-1) ,fChamber(-1 ) ,fPadX(-1) ,fPadY(-1) ,fQdc(-1) {} + AliRICHDigit(Int_t pad,Double_t qdc,Int_t cfm=-1,Int_t tid=-1):AliDigit(),fCFM(cfm),fChamber(P2C(pad)) ,fPadX(P2X(pad)),fPadY(P2Y(pad)),fQdc(qdc) {fTracks[0]=tid;} + AliRICHDigit(TVector pad,Double_t q ):AliDigit(),fCFM(-1) ,fChamber(-1) ,fPadX((Int_t)pad[0]) ,fPadY((Int_t)pad[1]) ,fQdc(q) {} + AliRICHDigit(Int_t c,TVector pad,Double_t q,Int_t cfm,Int_t tid0,Int_t tid1,Int_t tid2):fCFM(cfm),fChamber(c) + {fPadX=(Int_t)pad[0];fPadY=(Int_t)pad[1];fQdc=q;fTracks[0]=tid0;fTracks[1]=tid1;fTracks[2]=tid2;} virtual ~AliRICHDigit() {;} //framework part - Bool_t IsSortable ( )const{return kTRUE;} //provision to use TObject::Sort() - inline Int_t Compare (const TObject *pObj)const; //provision to use TObject::Sort() - void Print (Option_t *option="")const; //TObject Print() overload + Bool_t IsSortable ( )const{return kTRUE;} //provision to use TObject::Sort() + inline Int_t Compare (const TObject *pObj )const; //provision to use TObject::Sort() + void Print (Option_t *opt="" )const; //TObject Print() overload //private part - void AddTidOffset(Int_t offset ) {for (Int_t i=0; i<3; i++) if (fTracks[i]>0) fTracks[i]+=offset;}; //needed for merging - Int_t Cfm ( )const{return fCFM;} //particle mixture for this digit - Int_t Chamber ( )const{return fChamber/10;} //chamber number - Int_t Sector ( )const{return fChamber%10;} //sector number - Int_t PadX ( )const{return fPadX;} //x position of the pad - Int_t PadY ( )const{return fPadY;} //y postion of the pad - TVector Pad ( )const{Float_t v[2]={fPadX,fPadY}; return TVector(2,v);} - Int_t PadAbs ( )const{return fChamber*kChamber+fPadX*kPadX+fPadY;} //absolute id of this pad - Double_t Qdc ( )const{return fQdc;} //charge in terms of ADC channels - inline Int_t Dig2Raw ( UInt_t &w)const; //returns DDL ID and fill raw 32 bits word - inline void Raw2Dig (Int_t d,UInt_t w); //(DDL,word32)->(ch,sec,padx,pady,QDC) - static Int_t P2C (Int_t pad ) {return pad/kChamber;} //abs pad number-> chamber number - static Int_t P2X (Int_t pad ) {return pad%kChamber/kPadX;} //abs pad number-> pad X number - static Int_t P2Y (Int_t pad ) {return pad%kChamber%kPadX;} //abs pad number-> pad Y number - void Test ( ); //used to test all possible digit manipulations + void AddTidOffset(Int_t offset ) {for (Int_t i=0; i<3; i++) if (fTracks[i]>0) fTracks[i]+=offset;}; //needed for merging + Int_t Cfm ( )const{return fCFM;} //ckov-feed-mip mixture + Int_t Chamber ( )const{return fChamber;} //chamber number + Int_t C ( )const{return fChamber;} //chamber number + inline Int_t Dig2Raw ( UInt_t &w )const; //returns DDL ID and fill raw word + Int_t PadX ( )const{return fPadX;} //x position of the pad + Int_t PadY ( )const{return fPadY;} //y postion of the pad + TVector Pad ( )const{Float_t v[2]={fPadX,fPadY}; return TVector(2,v);} + Int_t PadAbs ( )const{return fChamber*kChamAbs+fPadX*kPadAbsX+fPadY;} //absolute id of this pad + static inline Int_t Pad2Sec (Int_t x,Int_t y ); + static Int_t P2A (Int_t c, Int_t x,Int_t y) {Int_t s=Pad2Sec(x,y);return c*kChamAbs+s*kSecAbs+x*kPadAbsX+y;} //(cham,padx,pady)-> abs pad + static Int_t P2A (Int_t c,Int_t s,Int_t x,Int_t y) {return Pad2Sec(x,y)==s?c*kChamAbs+s*kSecAbs+x*kPadAbsX+y:-1;} //(cham,sec,padx,pady)-> abs pad + static Int_t P2C (Int_t pad ) {return pad/kChamAbs;} //abs pad -> chamber + static Int_t P2S (Int_t pad ) {return pad%kChamAbs/kSecAbs;} //abs pad -> sector + static Int_t P2X (Int_t pad ) {return pad%kSecAbs/kPadAbsX;} //abs pad -> pad X + static Int_t P2Y (Int_t pad ) {return pad%kPadAbsX;} //abs pad number-> pad Y + Double_t Qdc ( )const{return fQdc;} //charge, QDC + inline void Raw2Dig (Int_t ddl,UInt_t w32 ); //(DDL,w32)->(ch,sec,x,y,QDC) + Int_t S ( )const{return -1;} //sector number ????? + static void Test ( ); //test raw-digit manipulations protected: - Int_t fCFM; //1000000*Ncerenkovs+1000*Nfeedbacks+Nmips - Int_t fChamber; //10*chamber number+ sector number - Int_t fPadX; //pad number along X - Int_t fPadY; //pad number along Y + Int_t fCFM; //1000000*Ncerenkovs+1000*Nfeedbacks+Nmips + Int_t fChamber; //chamber + Int_t fPadX; //pad along X + Int_t fPadY; //pad along Y Double_t fQdc; //QDC value, fractions are permitted for summable procedure ClassDef(AliRICHDigit,3) //RICH digit class };//class AliRICHDigit @@ -70,32 +98,28 @@ protected: Int_t AliRICHDigit::Compare(const TObject *pObj) const { //Used in Sort() method to compare to objects. Note that abs pad structure is first x then y, hence will be sorted on column basis. -//This feature is used in digitizer to facilitate finding of sdigits for the same pad as they will be together after sorting. +//This feature is used in digitizer to facilitate finding of sdigits for the same pad since they all will come together after sorting. //Arguments: pObj - pointer to object to compare with // Retunrs: -1 if AbsPad less then in pObj, 1 if more and 0 if they are the same - if(PadAbs()==((AliRICHDigit*)pObj)->PadAbs()) - return 0; - else if(PadAbs()>((AliRICHDigit*)pObj)->PadAbs()) - return 1; - else - return -1; + if (PadAbs()==((AliRICHDigit*)pObj)->PadAbs()) return 0; + else if(PadAbs() >((AliRICHDigit*)pObj)->PadAbs()) return 1; + else return -1; } //__________________________________________________________________________________________________ void AliRICHDigit::Raw2Dig(Int_t ddl,UInt_t w32) { -//Reads next raw word from raw data stream and convert -//Arguments: w32 - 32 bits word as in raw data stream +//Converts a given raw data word to a digit +//Arguments: w32 - 32 bits raw data word // ddl - DDL file number 0 1 2 3 4 ... 13 // Returns: none - fQdc = AliBitPacking::UnpackWord(w32, 0,11); // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq - UInt_t a = AliBitPacking::UnpackWord(w32,12,17); // 3322 2222 2222 1111 1111 1000 0000 0000 - UInt_t d = AliBitPacking::UnpackWord(w32,18,21); // 1098 7654 3210 9876 5432 1098 7654 3210 - UInt_t r = AliBitPacking::UnpackWord(w32,22,26); // r- iRawN d- iChiN a- iChiC + fQdc = AliBitPacking::UnpackWord(w32, 0,11); // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq Qdc bits (00..11) counts (0..4095) + UInt_t a = AliBitPacking::UnpackWord(w32,12,17); // 3322 2222 2222 1111 1111 1000 0000 0000 DILOGIC address bits (12..17) counts (0..47) + UInt_t d = AliBitPacking::UnpackWord(w32,18,21); // 1098 7654 3210 9876 5432 1098 7654 3210 DILOGIC number bits (18..21) counts (1..10) + UInt_t r = AliBitPacking::UnpackWord(w32,22,26); // Row number bits (22..26) counts (1..24) - fPadY = (r-1)*kChipY+a/kChipX+1; - fPadX = (d-1)*kChipX+a%kChipX+1; fPadX+=(ddl%2)*kChipX*kNchips;//if ddl is odd then right half of the chamber - TVector pad(2); pad[0]=fPadX;pad[1]=fPadY; - fChamber = ((ddl+2)/2)*10+AliRICHParam::Pad2Sec(pad); // ddl 0..13 to chamber 1..7 + fPadY = (r-1)*kDiloY+a/kDiloX+1; + fPadX = (d-1)*kDiloX+a%kDiloX+1; fPadX+=(ddl%2)*kDiloX*kNdilo;//if ddl is odd then right half of the chamber + fChamber = (ddl+2)/2; // ddl 0..13 to chamber 1..7 } //__________________________________________________________________________________________________ Int_t AliRICHDigit::Dig2Raw(UInt_t &w32)const @@ -103,21 +127,40 @@ Int_t AliRICHDigit::Dig2Raw(UInt_t &w32)const //Convert digit structure to raw word format //Arguments: 32 bits raw word to fill // Returns: DDL ID where to write this digit - Int_t ddl=2*Chamber()-1; //chamber 1..7 -> DDL 0..13, this idDdl is for right half (sectors 2 4 6), to be decremented if d < kNchips - UInt_t a = (PadY()-1)%kChipY*kChipX+(PadX()-1)%kChipX; //invented to be horizontal zig-zag - UInt_t r =1+(PadY()-1)/kChipY; - UInt_t d =1+(PadX()-1)/kChipX; - if(d>kNchips) - d-=kNchips; //chip number more then kNchips means right half of chamber, goes to this ddl + Int_t ddl=2*C()-1; //chamber 1..7 -> DDL 0..13, this idDdl is for right half (sectors 2 4 6), to be decremented if d < kNchips + UInt_t a = (PadY()-1)%kDiloY*kDiloX+(PadX()-1)%kDiloX; //invented to be horizontal zig-zag + UInt_t r =1+(PadY()-1)/kDiloY; //Row number depends only on y and we have (1..24) rows per (1..144) pads + UInt_t d =1+(PadX()-1)/kDiloX; //DILOGIC number depends only on x we have (1..10) chips per (1..80) pads + if(d>kNdilo) + d-=kNdilo; //chip number more then kNdilo means right half of chamber, goes to this ddl else - ddl--; //chip number less then kNchips means left half of the chamber, goes to ddl-1 + ddl--; //chip number less then kNdilo means left half of the chamber, goes to ddl-1 w32=0; - AliBitPacking::PackWord((UInt_t)fQdc,w32, 0,11); // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq - AliBitPacking::PackWord( a,w32,12,17); // 3322 2222 2222 1111 1111 1000 0000 0000 - AliBitPacking::PackWord( d,w32,18,21); // 1098 7654 3210 9876 5432 1098 7654 3210 - AliBitPacking::PackWord( r,w32,22,26); + AliBitPacking::PackWord((UInt_t)fQdc,w32, 0,11); // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq Qdc bits (00..11) counts (0..4095) + AliBitPacking::PackWord( a,w32,12,17); // 3322 2222 2222 1111 1111 1000 0000 0000 DILOGIC address bits (12..17) counts (0..47) + AliBitPacking::PackWord( d,w32,18,21); // 1098 7654 3210 9876 5432 1098 7654 3210 DILOGIC number bits (18..21) counts (1..10) + AliBitPacking::PackWord( r,w32,22,26); // Row number bits (22..26) counts (1..24) return ddl; //ddl 0..13 where to write this digit } - +//__________________________________________________________________________________________________ +Int_t AliRICHDigit::Pad2Sec(Int_t padx,Int_t pady) +{ +//Determines sector containing the given pad. +//Arguments: padx,pady - pad number +// Returns: sector number +//y ^ 5 6 sectors map as seen from IP +// | 3 4 +// | 1 2 +// -------> x + Int_t sector; + if (padx >= 1 && padx <= kPadsSecX ) sector=1; + else if(padx > kPadsSecX && padx <= kPadsChamX) sector=2; + else return -1;//padx out of range + if (pady >= 1 && pady <= kPadsSecY ) return sector; + else if(pady > kPadsSecY && pady <= 2*kPadsSecY ) return sector+2; + else if(pady > 2*kPadsSecY && pady <= kPadsChamY) return sector+4; + else return -1; //pady out of range +}//Pad2Sec() +//__________________________________________________________________________________________________ #endif diff --git a/RICH/AliRICHDigitizer.cxx b/RICH/AliRICHDigitizer.cxx index c95af38e2f8..0129130f9cc 100644 --- a/RICH/AliRICHDigitizer.cxx +++ b/RICH/AliRICHDigitizer.cxx @@ -42,12 +42,12 @@ void AliRICHDigitizer::Exec(Option_t*) if (!pInRunLoader->GetAliRun()) pInRunLoader->LoadgAlice(); AliRICH* pInRich=(AliRICH*)pInRunLoader->GetAliRun()->GetDetector("RICH"); //take RICH from current input pInRichLoader->LoadSDigits(); pInRichLoader->TreeS()->GetEntry(0); //take list of RICH sdigits from current input - AliDebug(1,Form("input %i has %i sdigits",inFileN,pInRich->SDigits()->GetEntries())); - for(Int_t i=0;iSDigits()->GetEntries();i++){//collect sdigits from current input to tmpCA - new(tmpCA[total++]) AliRICHDigit(*(AliRICHDigit*)pInRich->SDigits()->At(i)); + AliDebug(1,Form("input %i has %i sdigits",inFileN,pInRich->SDigs()->GetEntries())); + for(Int_t i=0;iSDigs()->GetEntries();i++){//collect sdigits from current input to tmpCA + new(tmpCA[total++]) AliRICHDigit(*(AliRICHDigit*)pInRich->SDigs()->At(i)); ((AliRICHDigit*)tmpCA[total-1])->AddTidOffset(fManager->GetMask(inFileN));//apply TID shift since all inputs count tracks independently starting from 0 } - pInRichLoader->UnloadSDigits(); pInRich->SDigitsReset(); //close current input and reset + pInRichLoader->UnloadSDigits(); pInRich->SDigReset(); //close current input and reset }//files loop tmpCA.Sort(); //at this point we have a list of all sdigits from all inputs, now sort them according to fPad field @@ -65,18 +65,18 @@ void AliRICHDigitizer::Exec(Option_t*) iNdigsPerPad++; dQdc+=pSdig->Qdc(); iCfm+=pSdig->Cfm();//sum up charge and cfm if(pSdig->Cfm()==1) aTids[0] = pSdig->GetTrack(0); // force the first tid to be mip's tid if it exists in the current pad if(iNdigsPerPad<=3) aTids[iNdigsPerPad-1]=pSdig->GetTrack(0); - else AliDebug(1,Form("More then 3 sdigits in (%d,%d,%f,%f) with Q= %f",pSdig->Chamber(),pSdig->Sector(),pSdig->Pad()(0),pSdig->Pad()(1),pSdig->Qdc())); + else AliDebug(1,Form("More then 3 sdigits in (%d,%d,%f,%f) with Q= %f",pSdig->Chamber(),-1,pSdig->Pad()(0),pSdig->Pad()(1),pSdig->Qdc())); }else{//new pad, add the pevious one - if(iId!=-1 && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigitAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids); //add newly created dig + if(iId!=-1 && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids); //add newly created dig iChamber=pSdig->Chamber(); pad=pSdig->Pad(); iCfm=pSdig->Cfm(); dQdc=pSdig->Qdc(); iId=pSdig->PadAbs(); //init all values by current sdig iNdigsPerPad=1; aTids[0]=pSdig->GetTrack(0); aTids[1]=aTids[2]=-1; } }//sdigits loop (sorted) - if(tmpCA.GetEntries() && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigitAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids);//add the last dig + if(tmpCA.GetEntries() && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids);//add the last dig pOutRichLoader->TreeD()->Fill(); //fill the output tree with the list of digits pOutRichLoader->WriteDigits("OVERWRITE"); //serialize them to file tmpCA.Clear(); //remove all tmp sdigits - pOutRichLoader->UnloadDigits(); pOutRich->DigitsReset(); + pOutRichLoader->UnloadDigits(); pOutRich->DigReset(); }//Exec() diff --git a/RICH/AliRICHHelix.cxx b/RICH/AliRICHHelix.cxx index 92b67f626d7..e97e95cf6b5 100644 --- a/RICH/AliRICHHelix.cxx +++ b/RICH/AliRICHHelix.cxx @@ -1,16 +1,35 @@ -#include "AliRICHHelix.h" -#include +#include "AliRICHHelix.h" //class header +#include //Draw() ClassImp(AliRICHHelix) - -void AliRICHHelix::Print(Option_t *) const +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliRICHHelix::AliRICHHelix(Double_t p,Double_t theta,Double_t phi,Double_t bz):TObject() { -//Debug printout - AliInfo(Form("Q=%i, in B(0,0,%5.2f) x0=(%5.2f,%5.2f,%5.2f) p0=(%5.2f,%5.2f,%5.2f)",fQ,fBz, - fX0.X(),fX0.Y(),fX0.Z(), - fP0.X(),fP0.Y(),fP0.Z() )); - AliInfo(Form("At length %7.2f gives x=(%5.2f,%5.2f,%5.2f) p=(%5.2f,%5.2f,%5.2f)",fLen, - fX.X(),fX.Y(),fX.Z(), - fP.X(),fP.Y(),fP.Z() )); - + fX0.SetXYZ(0,0,0); fX=fX0; + fP0.SetMagThetaPhi(p,theta*TMath::DegToRad(),phi*TMath::DegToRad()); fP=fP0; + fLen=0; fQ=1;fBz=bz; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHHelix::Print(Option_t *opt) const +{ +// Debug printout + Printf("%s helix for Q=%i in B=(0,0,%.2f) tesla",opt,fQ,fBz); + Printf("Helix parametrised @ x0=(%6.2f,%6.2f,%6.2f) cm p0=(%6.2f,%6.2f,%6.2f) GeV P=%.2f GeV Theta=%.2f Phi=%.2f degrees", + fX0.X(),fX0.Y(),fX0.Z(), fP0.Px(),fP0.Py(),fP0.Pz(), fP0.Mag(),fP0.Theta()*TMath::RadToDeg(),fP0.Phi()*TMath::RadToDeg()); + Printf("@ %7.2f cm x=(%6.2f,%6.2f,%6.2f) cm p=(%6.2f,%6.2f,%6.2f) GeV P=%.2f GeV Theta=%.2f Phi=%.2f degrees", + fLen, fX.X(), fX.Y(), fX.Z(), fP.Px(),fP.Py(),fP.Pz(), fP.Mag(), fP.Theta()*TMath::RadToDeg(),fP.Phi()*TMath::RadToDeg()); + Printf(" in LORS rad=(%5.2f,%5.2f) pc=(%5.2f,%5.2f)",fPosRad.X(), fPosRad.Y(),fPosPc.X(),fPosPc.Y()); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHHelix::Draw(const Option_t *) +{ +// Draw helix by a set of points seperated by 1 cm distance + + const Int_t kNpoints=500; + TPolyLine3D *pHelDraw = new TPolyLine3D(kNpoints); pHelDraw->SetLineColor(kGreen); + for(Int_t i=0;iSetPoint(i,fX.X(),fX.Y(),fX.Z()); + } + pHelDraw->Draw(); } diff --git a/RICH/AliRICHHelix.h b/RICH/AliRICHHelix.h index f3112cf2840..a769f1c0f30 100644 --- a/RICH/AliRICHHelix.h +++ b/RICH/AliRICHHelix.h @@ -1,66 +1,69 @@ #ifndef AliRICHHelix_h #define AliRICHHelix_h -#include -#include -#include "AliRICHParam.h" -#include "AliRICHChamber.h" +#include //base class +#include //used extensively +#include "AliRICHParam.h" //RichIntersect() class AliRICHHelix: public TObject { public: - AliRICHHelix():TObject() {;} - AliRICHHelix(const TVector3 &x0,const TVector3 &p0,Int_t q=1,Double_t b=0.2):TObject(),fX0(x0),fP0(p0),fX(x0),fP(p0), - fLen(0),fQ(q),fBz(b) {;} - virtual ~AliRICHHelix() {;} + AliRICHHelix():TObject() {} + AliRICHHelix(Double_t p,Double_t theta,Double_t phi,Double_t bz=0.2);//p [GeV], theta,phi [deg], Bz [Tesla]; + AliRICHHelix(const TVector3 &x0,const TVector3 &p0,Int_t q=1,Double_t b=0.2):TObject(),fX0(x0),fP0(p0),fX(x0),fP(p0),fLen(0),fQ(q),fBz(b) {} + virtual ~AliRICHHelix() {} - inline void Propagate(Double_t len); //propogate helix by length len along it - inline Int_t RichIntersect(AliRICHParam *pParam); //search intersection with any RICH chamber - inline Bool_t Intersection(TVector3 planePnt,TVector3 planeNorm); //intersection with plane given by point and normal vector - Bool_t Intersection(TVector3 pl) {return Intersection(pl,pl.Unit());} // special plane given by point only - TVector2 PosRad() const{return fPosRad;} //returns position of intersection with radiator (local system) - TVector2 PosAnod() const{return fPosAnod;} //returns position of intersection with anod wires plane (local system) - TVector2 PosPc() const{return fPosPc;} //returns position of intersection with PC (local system) - TVector3 Ploc() const{return fPloc;} //returns momentum at the position of intersection with radiator - Double_t Length() const{return fLen;} //returns length of the track from initial point to RICH - void Print(Option_t *sOption)const; //virtual interface from TObject + void Draw (const Option_t *opt="" ); //from TObject, draw helix + void Print (const Option_t *opt="" )const; //from TObject, print status +//private part++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + inline Bool_t Intersection (TVector3 planePnt,TVector3 planeNorm); //intersection with plane given by point and normal vector + inline void Propagate (Double_t len ); //propogate helix by given length along it + inline Int_t RichIntersect (AliRICHParam *pParam ); //search intersection with any RICH chamber + TVector2 PosRad ( )const{return fPosRad;} //intersection with radiator LORS + TVector2 PosPc ( )const{return fPosPc;} //returns position of intersection with PC (local system) + TVector3 Ploc ( )const{return fPloc;} //returns momentum at the position of intersection with radiator +// Double_t Length () const{return fLen;} //returns length of the track from initial point to RICH + TVector3 X ( )const{return fX;} protected: - TVector3 fX0; //helix position in parametrised point, cm in MRS - TVector3 fP0; //helix momentum in parametrised point, GeV/c in MRS - TVector3 fX; //helix position in point of interest, cm in MRS - TVector3 fP; //helix momentum in point of interest, GeV/c in MRS - Double_t fLen; //helix length in point of interest + TVector3 fX0; //helix position in point of definition, [cm] in MARS + TVector3 fP0; //helix momentum in point of definition, [GeV/c] in MARS + TVector3 fX; //helix position in point of interest, [cm] in MARS + TVector3 fP; //helix momentum in point of interest, [GeV/c] in MARS + Double_t fLen; //helix length from point of definition to point of interest, [cm] Int_t fQ; //sign of track charge (value not provided by current ESD) - Double_t fBz; //magnetic field along z value in Tesla under assumption of uniformity - TVector2 fPosRad; //track intersection with radiator (local system) - TVector2 fPosAnod; //track intersection with anod wires plane (local system) - TVector2 fPosPc; //track intersection with PC (local system) - TVector3 fPloc; //momentum in local system + Double_t fBz; //magnetic field along z, [Tesla] + TVector2 fPosRad; //helix intersection with radiator entrance, LORS [cm] + TVector2 fPosPc; //helix intersection with PC, LORS [cm] + TVector3 fPloc; //helix momentum, LORS [GeV/c] ClassDef(AliRICHHelix,0) //General helix };//class AliRICHHelix -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHHelix::Propagate(Double_t len) { -// Propogates the helix to the position of interest defined by helix length s -// Assumes uniform magnetic field along z direction. - const Double_t c = 0.00299792458;//this value provides that coordinates are in cm momentum in GeV/c - Double_t a = -c*fBz*fQ; - - Double_t rho = a/fP0.Mag(); - fX.SetX( fX0.X()+fP0.X()*TMath::Sin(rho*len)/a-fP0.Y()*(1-TMath::Cos(rho*len))/a ); - fX.SetY( fX0.Y()+fP0.Y()*TMath::Sin(rho*len)/a+fP0.X()*(1-TMath::Cos(rho*len))/a ); - fX.SetZ( fX0.Z()+fP0.Z()*len/fP0.Mag() ); - fP.SetX( fP0.X()*TMath::Cos(rho*len)-fP0.Y()*TMath::Sin(rho*len) ); - fP.SetY( fP0.Y()*TMath::Cos(rho*len)+fP0.X()*TMath::Sin(rho*len) ); - fP.SetZ( fP0.Z() ); - fLen=len; +// Propogates the helix from inintial point by a given distance along helix. Assumes uniform magnetic field along z direction. +// Arguments: len - distance to propagate by, [cm] +// Returns: none + if(fBz==0){//no magnetic field->straight line + fX=fX0+fP0.Unit()*len; + }else{ + const Double_t c = 0.00299792458;//this speed of light value provides that coordinates are in cm momentum in GeV/c + Double_t a = -c*fBz*fQ; + Double_t rho = a/fP0.Mag(); + fX.SetX( fX0.X()+fP0.X()*TMath::Sin(rho*len)/a-fP0.Y()*(1-TMath::Cos(rho*len))/a ); + fX.SetY( fX0.Y()+fP0.Y()*TMath::Sin(rho*len)/a+fP0.X()*(1-TMath::Cos(rho*len))/a ); + fX.SetZ( fX0.Z()+fP0.Z()*len/fP0.Mag() ); + fP.SetX( fP0.X()*TMath::Cos(rho*len)-fP0.Y()*TMath::Sin(rho*len) ); + fP.SetY( fP0.Y()*TMath::Cos(rho*len)+fP0.X()*TMath::Sin(rho*len) ); + fP.SetZ( fP0.Z() ); + fLen=len; + } } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Bool_t AliRICHHelix::Intersection(TVector3 planePoint,TVector3 planeNorm) { -// Finds point of intersection (if exists) of the helix to the plane given by point and normal vector. -// Returns kTrue if helix intersects the plane, kFALSE otherwise. -// Stores result in current helix fields fX and fP. +// Finds point of intersection (if exists) of the helix with the plane. Stores result in fX and fP. +// Arguments: planePoint,planeNorm - the plane defined by any plane's point and vector, normal to the plane +// Returns: kTrue if helix intersects the plane, kFALSE otherwise. Double_t s=(planePoint-fX0)*planeNorm,dist=99999,distPrev=dist;//estimates initial distance to plane @@ -73,26 +76,23 @@ Bool_t AliRICHHelix::Intersection(TVector3 planePoint,TVector3 planeNorm) } return kTRUE; } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Int_t AliRICHHelix::RichIntersect(AliRICHParam *pParam) { // Searchs for intersection of this helix with all RICH chambers, returns chamber number or 0 if no intersection -// On exit fPosRad contain position of intersection in Local System with radiator +// On exit fPosRad contain position of intersection in radiator LORS (cm) // fPosPc contains the same for photocathode - for(Int_t iChamberN=1;iChamberN<=kNchambers;iChamberN++){//chamber loop - if(Intersection(pParam->C(iChamberN)->Rad())){//there is intersection with radiator plane - fPosRad=pParam->C(iChamberN)->Mrs2Rad(fX);//position on radiator plane + for(Int_t iChamN=1;iChamN<=AliRICHParam::kNch;iChamN++){//chamber loop + if(Intersection(pParam->Center(iChamN,AliRICHParam::kRad),pParam->Norm(iChamN))){//there is intersection with radiator plane + fPosRad=pParam->Mars2Lors(iChamN,fX,AliRICHParam::kRad);//position on radiator plane if(pParam->IsAccepted(fPosRad)){//intersection within radiator (even if in dead zone) - if(Intersection(pParam->C(iChamberN)->Pc())){//there is intersection with photocathode - fPosPc=pParam->C(iChamberN)->Mrs2Pc(fX);//position on photcathode plane + if(Intersection(pParam->Center(iChamN,AliRICHParam::kPc),pParam->Norm(iChamN))){//there is intersection with photocathode + fPosPc=pParam->Mars2Lors(iChamN,fX,AliRICHParam::kPc);//position on radiator plane if(pParam->IsAccepted(fPosPc)){//intersection within pc (even if in dead zone) - Intersection(pParam->C(iChamberN)->Anod()); //search for anod intersection position - fPosAnod=pParam->C(iChamberN)->Mrs2Anod(fX); - - fPloc=pParam->C(iChamberN)->PMrs2Loc(fP);//trasform p to local system - return iChamberN; + fPloc=pParam->Mars2LorsVec(iChamN,fP);//trasform p to local system + return iChamN; }//if inside PC }//if intersects PC @@ -101,5 +101,5 @@ Int_t AliRICHHelix::RichIntersect(AliRICHParam *pParam) }//chamber loop return 0; } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #endif diff --git a/RICH/AliRICHHit.cxx b/RICH/AliRICHHit.cxx index 3cd4d37c85b..2bd9c2b00d9 100644 --- a/RICH/AliRICHHit.cxx +++ b/RICH/AliRICHHit.cxx @@ -13,16 +13,30 @@ // * provided "as is" without express or implied warranty. * // ************************************************************************** -#include "AliRICHHit.h" -#include +#include "AliRICHHit.h" //class header +#include //Print() ClassImp(AliRICHHit) //__________________________________________________________________________________________________ void AliRICHHit::Print(Option_t*)const { //Print hit - AliInfo(Form("Ch=%1i,TID=%6i,Elos=%9.3f eV,IN(%6.2f,%6.2f,%6.2f)-OUT(%6.2f,%6.2f,%6.2f)=%9.4f" - ,fChamber,fTrack,fEloss*1e9,fInX3.X() ,fInX3.Y() ,fInX3.Z(), - fOutX3.X(),fOutX3.Y(),fOutX3.Z(),Length())); + char *sPart=Form("pid=%i",fPid); + switch(fPid){ + case kProton: sPart="p+ ";break; + case kProtonBar: sPart="a- ";break; + case kKPlus: sPart="K+ ";break; + case kKMinus: sPart="K- ";break; + case kPiPlus: sPart="pi+ ";break; + case kPiMinus: sPart="pi- ";break; + case kMuonPlus: sPart="mu+ ";break; + case kMuonMinus: sPart="mu- ";break; + case kElectron: sPart="e- ";break; + case kPositron: sPart="e+ ";break; + case 50000050: sPart="ckov";break; + case 50000051: sPart="feed";break; + } + + Printf("%s TID=%6i,Ch=(%2i),E=%9.3f eV, pos=(%7.2f,%7.2f,%7.2f)cm",sPart,Track(),C(),fE*1e9,fX,fY,fZ); } //__________________________________________________________________________________________________ diff --git a/RICH/AliRICHHit.h b/RICH/AliRICHHit.h index 646931fed9e..a0210cd18db 100644 --- a/RICH/AliRICHHit.h +++ b/RICH/AliRICHHit.h @@ -10,22 +10,27 @@ class AliRICHHit : public AliHit { public: - AliRICHHit() :AliHit( ),fChamber(-1),fEloss(-1) {fInX3.SetXYZ(0,0,0);fOutX3.SetXYZ(0,0,0);} - AliRICHHit(Int_t c,Int_t tid,TVector3 in,TVector3 out,Double_t e):AliHit(0,tid),fChamber(c ),fEloss(e ) {fInX3=in; fOutX3=out; fX=out.X();fY=out.Y();fZ=out.Z();} + AliRICHHit() :AliHit( ),fCham(-1) ,fE(-1),fPid(-1 ){fInX3.SetXYZ(0,0,0);fOutX3.SetXYZ(0,0,0);} + AliRICHHit(Int_t c,Int_t tid,TVector3 in,TVector3 out,Double_t e,Int_t pid) :AliHit(0,tid),fCham(c ) ,fE(e) ,fPid(pid){fInX3=in; fOutX3=out; fX=out.X();fY=out.Y();fZ=out.Z();} + AliRICHHit(Int_t tid,Double_t e,Int_t pad,Double_t x,Double_t y,Double_t z,Int_t pid):AliHit(0,tid),fCham(pad),fE(e) ,fPid(pid){fX=x;fY=y;fZ=z;} + virtual ~AliRICHHit() {} - - Int_t C() const{return fChamber;} //chamber number - Int_t Chamber() const{return fChamber;} //chamber number - Float_t Eloss() const{return fEloss;} //energy lost by track inside amplification gap - TVector3 InX3() const{return fInX3;} //track position at the faceplane of the gap - TVector3 OutX3() const{return fOutX3;} //track position at the backplane of the gap - Double_t Length() const{return (fOutX3-fInX3).Mag();} //track length inside the amplification gap - void Print(Option_t *option="")const; //virtual +//framework part + void Print(Option_t *option="")const; //from TObject to print current status +//private part + Int_t C ()const{return fCham;} //chamber number + Int_t Chamber()const{return fCham;} //chamber number + Int_t Pad ()const{return fCham;} //absolute pad number, definition in AliRICHParam + Float_t Eloss ()const{return fE; } //Eloss for MIP hit or Etot for photon hit + TVector3 InX3 ()const{return fInX3;} //track position at the faceplane of the gap + TVector3 OutX3 ()const{return fOutX3;} //track position at the backplane of the gap + Double_t Length ()const{return (fOutX3-fInX3).Mag();} //track length inside the amplification gap protected: - Int_t fChamber; //chamber number - Double_t fEloss; //ionisation energy lost in GAP + Int_t fCham; //chamber number or in future absolute pad number + Double_t fE; //Eloss for MIP or Etot for photon [GeV] + Int_t fPid; //PID of particle created this hit TVector3 fInX3; //position at the entrance of the GAP TVector3 fOutX3; //position at the exit of the GAP - ClassDef(AliRICHHit,2) //RICH hit class + ClassDef(AliRICHHit,3) //RICH hit class };//class AliRICHhit #endif diff --git a/RICH/AliRICHMap.cxx b/RICH/AliRICHMap.cxx deleted file mode 100644 index 1236fc0dff9..00000000000 --- a/RICH/AliRICHMap.cxx +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************** - * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * * - * Author: The ALICE Off-line Project. * - * Contributors are mentioned in the code where appropriate. * - * * - * Permission to use, copy, modify and distribute this software and its * - * documentation strictly for non-commercial purposes is hereby granted * - * without fee, provided that the above copyright notice appears in all * - * copies and that both the copyright notice and this permission notice * - * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * - * provided "as is" without express or implied warranty. * - **************************************************************************/ - -#include "AliRICHMap.h" -#include "AliRICH.h" - -ClassImp(AliRICHMap) - -AliRICHMap::AliRICHMap(TClonesArray *pDig) -{ -// main ctor - fDigits=pDig; - fNdigits=fDigits->GetEntries(); - fMap=new TMatrix(1,AliRICHParam::NpadsX(),1,AliRICHParam::NpadsY()); - Clear(""); - FillHits(); -} -//__________________________________________________________________________________________________ -void AliRICHMap::FillHits() -{ -// Loops over the list of digits filling the "pad fired by digits" structure - if(!fNdigits) return; - for(Int_t iDigN=0;iDigNAt(iDigN); - SetHit(pDig->PadX(),pDig->PadY(),iDigN); - } -} -//__________________________________________________________________________________________________ diff --git a/RICH/AliRICHMap.h b/RICH/AliRICHMap.h deleted file mode 100644 index d57edb4f7b2..00000000000 --- a/RICH/AliRICHMap.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef AliRICHMap_h -#define AliRICHMap_h -/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * See cxx source for full Copyright notice */ - -#include "AliHitMap.h" -#include -#include -#include - -class AliRICHMap : public AliHitMap -{ -public: - AliRICHMap(TClonesArray *pDig); - virtual ~AliRICHMap() {delete fMap;} - void FillHits(); //virtual - void Clear(const char *) {fMap->Zero();} //virtual - void DeleteHit(Int_t ix,Int_t iy) {(*fMap)(ix,iy)=0;} //virtual - void SetHit(Int_t ix,Int_t iy,Int_t idigit){(*fMap)(ix,iy)=idigit+1;} //virtual - Int_t GetHitIndex(Int_t ix,Int_t iy) const{return (Int_t)TMath::Abs((*fMap)(ix, iy))-1;} //virtual - TObject* GetHit(Int_t ix,Int_t iy) const{Int_t idx=GetHitIndex(ix,iy);return(idx <0)?0:fDigits->At(idx);} //virtual - void FlagHit(Int_t ix,Int_t iy) {(*fMap)(ix, iy)=-TMath::Abs((*fMap)(ix,iy));} //virtual - Bool_t ValidateHit(Int_t,Int_t) {return 1;} //virtual - inline FlagType TestHit(Int_t ix,Int_t iy); //virtual - void Print(const Option_t *) const{fMap->Print();} -protected: - TClonesArray *fDigits; //List of digits - Int_t fNdigits; //Number of digits - TMatrix *fMap; //hit map - ClassDef(AliRICHMap,0) //Implements map as TMatrix -}; -//__________________________________________________________________________________________________ -FlagType AliRICHMap::TestHit(Int_t padx,Int_t pady) -{ -//Is there a hit for given pad? - Int_t inf=(Int_t)(*fMap)(padx,pady); - if(inf<0){//flaged as used - return kUsed; - }else if(inf==0){//no hit - return kEmpty; - }else{//index of not yet used hit - return kUnused; - } -}//TestHit() -#endif diff --git a/RICH/AliRICHParam.cxx b/RICH/AliRICHParam.cxx index bc62a72307b..f55c6049e5a 100644 --- a/RICH/AliRICHParam.cxx +++ b/RICH/AliRICHParam.cxx @@ -12,10 +12,9 @@ // * about the suitability of this software for any purpose. It is * // * provided "as is" without express or implied warranty. * // ************************************************************************** -#include "AliRICHParam.h" +#include "AliRICHParam.h" //class header #include "AliESD.h" -#include "AliRICHChamber.h" -#include +#include //TestXXX() #include #include #include @@ -27,15 +26,20 @@ #include #include #include - +#include //CdbRead() +#include //CdbRead() +#include //CdbRead() +#include //Stack() +#include //Stack() +#include //Stack() +#include "AliRICHHelix.h" //TestTrans() ClassImp(AliRICHParam) -Bool_t AliRICHParam::fgIsWireSag =kTRUE; //take ware sagita into account? -Bool_t AliRICHParam::fgIsResolveClusters =kTRUE; //do cluster resolving? -Bool_t AliRICHParam::fgIsFeedback =kTRUE; //generate feedback photons? -Bool_t AliRICHParam::fgIsRadioSrc =kFALSE; //put radioactive source instead of radiators? -Bool_t AliRICHParam::fgIsAerogel =kFALSE; //special aerogel configuration -Bool_t AliRICHParam::fgIsTestBeam =kFALSE; //special test beam configuration +AliRICHParam * AliRICHParam::fgInstance =0x0; //singleton pointer +Bool_t AliRICHParam::fgIsWireSag =kTRUE; //take ware sagita into account? +Bool_t AliRICHParam::fgIsResolveClusters =kTRUE; //do cluster resolving? +Bool_t AliRICHParam::fgIsFeedback =kTRUE; //generate feedback photons? +Bool_t AliRICHParam::fgIsTestBeam =kFALSE; //special test beam configuration Int_t AliRICHParam::fgHV[kNsectors] ={2050,2050,2050,2050,2050,2050}; Int_t AliRICHParam::fgNsigmaTh =4; @@ -46,33 +50,45 @@ Double_t AliRICHParam::fgErrGeom[4][330]; // Double_t AliRICHParam::fgErrLoc[4][330]; //Chromatic, Geometric and Localization array to parametrize SigmaCerenkov Double_t AliRICHParam::fgMass[5] ={0.00051,0.10566,0.13957,0.49360,0.93828}; -//__________________________________________________________________________________________________ -void AliRICHParam::Print(Option_t*) const -{ -//print some usefull (hopefully) info on some internal guts of RICH parametrisation - AliInfo(Form("Pads in chamber (%3i,%3i) in sector (%2i,%2i) pad size (%4.2f,%4.2f)",NpadsX(),NpadsY(),NpadsXsec(),NpadsYsec(),PadSizeX(),PadSizeY())); - AliInfo(Form("Resolve clusters %i sagita %i Radio source %i Aerogel %i TestBeam %i", - IsResolveClusters(),IsWireSag(),IsRadioSrc(),IsAerogel(),IsTestBeam())); - fpChambers->Print(); -}//Print() -//__________________________________________________________________________________________________ -void AliRICHParam::CreateChambers() + +Double_t AliRICHParam::fEckovMin=5.5e-9; //GeV +Double_t AliRICHParam::fEckovMax=8.5e-9; //GeV +TF1 AliRICHParam::fgAbsC6F14("RabsC4F14","6512.39*(x<=7.75e-9)+(x>7.75e-9)*0.039/(-0.166+0.063e9*x-8.01e7*x^2+3.39e5*x^3)" ,fEckovMin,fEckovMin); +TF1 AliRICHParam::fgAbsSiO2 ("RabsSiO2" ,"333" ,fEckovMin,fEckovMin); +TF1 AliRICHParam::fgAbsCH4 ("RabsCH4" ,"6512.39*(x<=7.75e-9)+(x>7.75e-9)*0.039/(-0.166+0.063e9*x-8.01e7*x^2+3.39e5*x^3)" ,fEckovMin,fEckovMin); +TF1 AliRICHParam::fgAbsAir ("RabsAir" ,"500" ,fEckovMin,fEckovMin); //len ??? +TF1 AliRICHParam::fgAbsCF4 ("RabsCF4" ,"6512.39*(x<=7.75e-9)+(x>7.75e-9)*0.039/(-0.166+0.063e9*x-8.01e7*x^2+3.39e5*x^3)" ,fEckovMin,fEckovMin); +TF1 AliRICHParam::fgAbsC4F10("RabsC4F10","1+0.25324e-6/(1.84e-4 - (1239.84e-9/x)^-2)" ,fEckovMin,fEckovMin); //Olav preprint +TF1 AliRICHParam::fgAbsGel ("RabsGel" ,"400" ,fEckovMin,fEckovMin); //len ??? + +TF1 AliRICHParam::fgIdxAir ("RidxAir" ,"1+1e-8*(8342.13 + 2406030/(130-(1.23984e-9/x)^2)+15597/(38.9-(1.23984e-9/x)^2))" ,fEckovMin,fEckovMin); //??? +TF1 AliRICHParam::fgIdxSiO2 ("RidxSiO2" ,"sqrt(1+46.411/(10.666*10.666-x*x*1e18)+228.71/(18.125*18.125-x*x*1e18))" ,fEckovMin,fEckovMin); //TDR p.35 +TF1 AliRICHParam::fgIdxCH4 ("RidxCH4" ,"1+0.12489e-6/(2.62e-4 - (1239.84e-9/x)^-2)" ,fEckovMin,fEckovMin); //Olav preprint +TF1 AliRICHParam::fgIdxG30 ("RidxGel30","1.030" ,fEckovMin,fEckovMin); //??? +TF1 AliRICHParam::fgIdxG28 ("RidxGel28","1.028" ,fEckovMin,fEckovMin); //??? +TF1 AliRICHParam::fgIdxG26 ("RidxGel26","1.026" ,fEckovMin,fEckovMin); //??? +TF1 AliRICHParam::fgIdxG24 ("RidxGel24","1.024" ,fEckovMin,fEckovMin); //??? +TF1 AliRICHParam::fgIdxC4F10("RidxC4F10","1+0.25324e-6/(1.84e-4 - (1239.84e-9/x)^-2)" ,fEckovMin,fEckovMin); //Olav preprint +TF1 AliRICHParam::fgIdxCF4 ("RidxCF4" ,"1+0.12489e-6/(2.62e-4 - (1239.84e-9/x)^-2)" ,fEckovMin,fEckovMin); //Olav preprint + +TF1 AliRICHParam::fgQeApd("QeApd" ,"0+(x>6e-9)*0.27*(1-exp(-(1e9*x-6)/0.3))" ,fEckovMin,fEckovMin); //??? +TF1 AliRICHParam::fgQeCsI("AbsApd" ,"0.03" ,fEckovMin,fEckovMin); //prob + + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliRICHParam::AliRICHParam():TNamed("RichParam","default version") { -//Create all RICH Chambers on each call. Previous chambers deleted. - if(fpChambers) delete fpChambers; - if(fgIsTestBeam){ - fpChambers=new TObjArray(1);//test beam configuration 1 chamber - fpChambers->AddAt(new AliRICHChamber(0),0); - }else{ - fpChambers=new TObjArray(kNchambers);//normal configuration 7 chambers - for(int iChamberN=0;iChamberNAddAt(new AliRICHChamber(iChamberN+1),iChamberN); - } - fpChambers->SetOwner(); -}//CreateChambers() -//__________________________________________________________________________________________________ +// Here all the intitializition is taken place when AliRICHParam::Instance() is invoked for the first time. +// In particulare, matrices to be used for LORS<->MARS trasnformations are initialized from TGeo structure. +// Note that TGeoManager should be already initialized from geometry.root file + for(Int_t iCh=0;iChGetVolume("ALIC")->GetNode(Form("RICH_%i",iCh+1))->GetMatrix(); + CdbRead(0,0); + fgInstance=this; +}//ctor +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Float_t AliRICHParam::AbsCH4(Float_t eV) { -//Evaluate the absorbtion lenght of CH4 for a photon of energy eV in electron-volts +// Evaluate the absorbtion lenght of CH4 for a photon of energy eV in electron-volts const Float_t kLoschmidt=2.686763e19; // LOSCHMIDT NUMBER IN CM-3 const Float_t kPressure=750.0; //mm of Hg const Float_t kTemperature=283.0; //K (10 grad C) @@ -92,16 +108,44 @@ Float_t AliRICHParam::AbsCH4(Float_t eV) Float_t density=kLoschmidt*kPn/kTn; //CH4 molecular concentration (cm^-3) return 1.0/(density*crossSection); }//AbsoCH4() -//__________________________________________________________________________________________________ +//__________________________________________________________________________________________________sss +void AliRICHParam::CdbRead(Int_t run,Int_t version) +{ +// This methode read all the calibration information and initialise corresponding fields for requested run number +// Arguments: run - run number for which to retrieve calibration +// version- version number +// Returns: none + + AliCDBEntry *pEntry=AliCDBManager::Instance()->Get("RICH/RICHConfig/RefIdxC6F14",run,0,version); //try to get from common local storage + if(pEntry){ + fIdxC6F14=(TF2*)pEntry->GetObject(); delete pEntry; + }else{ + AliWarning("No valid calibarion, the hardcoded will be used!"); + fIdxC6F14=new TF2("RidxC4F14","sqrt(1+0.554*(1239.84e-9/x)^2/((1239.84e-9/x)^2-5796)-0.0005*(y-20))",5.5e-9,8.5e-9,0,50); //DiMauro mail + fIdxC6F14->SetUniqueID(20);//T=20 deg C + } +}//CdbRead() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHParam::Print(Option_t* opt) const +{ +// print some usefull (hopefully) info on some internal guts of RICH parametrisation + Printf("Pads in chamber (%3i,%3i) in sector (%2i,%2i) pad size (%4.2f,%4.2f)",NpadsX(),NpadsY(),NpadsXsec(),NpadsYsec(),PadSizeX(),PadSizeY()); + Printf("Resolve clusters %i sagita %i",IsResolveClusters(),IsWireSag()); + + for(Int_t i=0;iPrint(opt); +}//Print() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHParam::TestSeg() { -//Provides a set of pictures to test segementation currently in use. +// Provides a set of pictures to test segementation currently in use. +// Arguments: none +// Returns: none new TCanvas("pads","PC segmentation - pads display",700,600); gPad->Range(-5,-5,PcSizeX()+5,PcSizeY()+15); TVector p(2); TVector2 c; TVector2 b; //current: pad, pad center, pad boundary // list of corners: - Double_t x0=0,x1=SectorSizeX(),x2=SectorSizeX()+DeadZone(), x3=PcSizeX(); - Double_t y0=0,y1=SectorSizeY(),y2=SectorSizeY()+DeadZone(),y3=2*SectorSizeY()+DeadZone(),y4=PcSizeY()-SectorSizeY(),y5=PcSizeY(); + Double_t x0=0,x1=SecSizeX(),x2=SecSizeX()+DeadZone() ,x3=PcSizeX(); + Double_t y0=0,y1=SecSizeY(),y2=SecSizeY()+DeadZone(),y3=2*SecSizeY()+DeadZone(),y4=PcSizeY()-SecSizeY(),y5=PcSizeY(); DrawSectors(); //header TLatex t; @@ -109,7 +153,7 @@ void AliRICHParam::TestSeg() t.DrawLatex(0,PcSizeY()+10,Form("IP in front of this page. pad size %.2fx%.2fcm dead zone %.2fcm",PadSizeX(),PadSizeY(),DeadZone())); t.DrawLatex(0,PcSizeY()+ 5,Form("Pc %.2fx%.2f cm %ix%i pads Sec %.2fx%.2f cm %ix%i pads", PcSizeX() , PcSizeY() , NpadsX() , NpadsY() , - SectorSizeX() , SectorSizeY() , NpadsXsec() , NpadsYsec() )); + SecSizeX() , SecSizeY() , NpadsXsec() , NpadsYsec() )); //sectors t.SetTextSize(0.015); t.SetTextColor(kRed); t.SetTextAlign(22); c=Pad2Loc( 40, 24); t.DrawText(c.X(),c.Y(),Form("sec 1 (%.2f,%.2f)",c.X(),c.Y() )); @@ -152,7 +196,9 @@ void AliRICHParam::TestSeg() //__________________________________________________________________________________________________ void AliRICHParam::TestResp() { -//Provides a set of plot to check the response parametrisation currently in use. +// Provides a set of plot to check the response parametrisation currently in use. +// Arguments: none +// Returns: none TCanvas *pC=new TCanvas("c","Amplification test",900,800); pC->Divide(1,2); @@ -165,13 +211,13 @@ void AliRICHParam::TestResp() TH1F *apHmip[kNpoints]; Double_t starty=0; - Double_t deltay=AliRICHParam::SectorSizeY()/kNpoints; + Double_t deltay=AliRICHParam::SecSizeY()/kNpoints; for(int i=0;iSetLineColor(i);pStackPhot->Add(apHphot[i]); apHmip[i] =new TH1F(Form("hmip%i",i),"Qdc for Mip;QDC;Counts",4000,0,4000); apHmip[i]->SetLineColor(i);pStackMip->Add(apHmip[i]); - pLeg->AddEntry(apHphot[i],Form("@(10,%5.2f->%5.2f)",starty+i*deltay,starty+i*deltay-SectorSizeY()/2)); + pLeg->AddEntry(apHphot[i],Form("@(10,%5.2f->%5.2f)",starty+i*deltay,starty+i*deltay-SecSizeY()/2)); } @@ -190,34 +236,41 @@ void AliRICHParam::TestResp() //__________________________________________________________________________________________________ void AliRICHParam::TestTrans() { -//Provides a set of plots to test transformation methods - new TCanvas("trasform","Test LRS-MRS transform"); - TLatex t; t.SetTextSize(0.02); +// Tests transformation methods +// Arguments: none +// Returns: none - TView *pView=new TView(1); - pView->SetRange(-600,-600,-600,600,600,600); - DrawAxis(); -//Draw PC for all chambers by trasfering Pc plane using Pc2Mrs methode + AliRICHParam *pParam=AliRICHParam::Instance(); Int_t iNpointsX=50,iNpointsY=50; - for(Int_t iChamberN=1;iChamberN<=7;iChamberN++){//chamber loop + new TCanvas("trasform","Test LORS-MARS transform"); TLatex t; t.SetTextSize(0.02); + + TView *pView=new TView(1); pView->SetRange(-400,-400,-400,400,400,400); + DrawAxis(); + for(Int_t iCham=1;iCham<=7;iCham++){//chamber loop + AliRICHHelix helix(2.5,Norm(iCham).Theta()*TMath::RadToDeg(),Norm(iCham).Phi()*TMath::RadToDeg()); + helix.RichIntersect(AliRICHParam::Instance()); TPolyMarker3D *pChamber=new TPolyMarker3D(iNpointsX*iNpointsY); Int_t i=0; for(Double_t x=0;xPc2Mrs(TVector2(x,y));//from regular grid of local PC points to MRS presentation - pChamber->SetPoint(i++,v3.X(),v3.Y(),v3.Z());//Pc plane poing in MRS + TVector3 v3=pParam->Lors2Mars(iCham,x,y,kPc); TVector2 v2=pParam->Mars2Lors(iCham,v3,kPc);//LORS->MARS->LORS + Double_t dx=v2.X()-x , dy=v2.Y()-y; + if(dx>0.000001 || dy>0.000001) Printf("Problem in MARS<->LORS transformations dx=%f dy=%f!!!",dx,dy); + pChamber->SetPoint(i++,v3.X(),v3.Y(),v3.Z());//Pc plane point in MARS }//step loop pChamber->SetMarkerSize(1); - pChamber->SetMarkerColor(iChamberN); + pChamber->SetMarkerColor(iCham); pChamber->Draw(); - t.SetNDC();t.SetTextColor(iChamberN); t.DrawText(0.1,iChamberN*0.1,Form("Chamber %i",iChamberN)); - }//chamber loop -// gPad->GetView()->RotateView(94,45); + helix.Draw(); + t.SetNDC();t.SetTextColor(iCham); t.DrawText(0.1,iCham*0.1,Form("Chamber %i",iCham)); + }//chambers loop }//TestTrans() //__________________________________________________________________________________________________ void AliRICHParam::DrawAxis() { -//Utility: draws axis on geometry scene +// This utility methode draws axis on geometry scene +// Arguments: none +// Returns: none Double_t x[6]={0,0,0,300,0,0}; Double_t y[6]={0,0,0,0,300,0}; Double_t z[6]={0,0,0,0,0,300}; TPolyLine3D *pXaxis=new TPolyLine3D(2,x);pXaxis->SetLineColor(kRed); pXaxis->Draw(); TPolyLine3D *pYaxis=new TPolyLine3D(2,y);pYaxis->SetLineColor(kGreen); pYaxis->Draw(); @@ -226,14 +279,16 @@ void AliRICHParam::DrawAxis() //__________________________________________________________________________________________________ void AliRICHParam::DrawSectors() { -//Utility: draws RICH chamber sectors on event display. - Double_t xLeft[5] = {0,0,SectorSizeX(),SectorSizeX(),0}; - Double_t xRight[5] = {SectorSizeX()+DeadZone(),SectorSizeX()+DeadZone(),PcSizeX(),PcSizeX(),SectorSizeX()+DeadZone()}; +// Utility methode draws RICH chamber sectors on event display. +// Arguments: none +// Returns: none + Double_t xLeft[5] = {0,0,SecSizeX(),SecSizeX(),0}; + Double_t xRight[5] = {SecSizeX()+DeadZone(),SecSizeX()+DeadZone(),PcSizeX(),PcSizeX(),SecSizeX()+DeadZone()}; - Double_t yDown[5] = {0,SectorSizeY(),SectorSizeY(),0,0}; - Double_t yCenter[5] = { SectorSizeY()+DeadZone(),2*SectorSizeY()+DeadZone(),2*SectorSizeY()+DeadZone(), - SectorSizeY()+DeadZone(),SectorSizeY()+DeadZone()}; - Double_t yUp[5] = {2*SectorSizeY()+2*DeadZone(),PcSizeY(),PcSizeY(),2*SectorSizeY()+2*DeadZone(),2*SectorSizeY()+2*DeadZone()}; + Double_t yDown[5] = {0,SecSizeY(),SecSizeY(),0,0}; + Double_t yCenter[5] = { SecSizeY()+DeadZone(),2*SecSizeY()+DeadZone(),2*SecSizeY()+DeadZone(), + SecSizeY()+DeadZone(),SecSizeY()+DeadZone()}; + Double_t yUp[5] = {2*SecSizeY()+2*DeadZone(),PcSizeY(),PcSizeY(),2*SecSizeY()+2*DeadZone(),2*SecSizeY()+2*DeadZone()}; TPolyLine *sec1 = new TPolyLine(5,xLeft ,yDown); sec1->SetLineColor(21); sec1->Draw(); TPolyLine *sec2 = new TPolyLine(5,xRight,yDown); sec2->SetLineColor(21); sec2->Draw(); @@ -245,8 +300,9 @@ void AliRICHParam::DrawSectors() //__________________________________________________________________________________________________ void AliRICHParam::ReadErrFiles() { -// Read the three files corresponding to Chrom,Geom and Loc -// They are parameters of a polynomial of 6th order... +// Read the three files corresponding to Chrom,Geom and Loc They are parameters of a polynomial of 6th order... ????????? go to CDB? +// Arguments: none +// Returns: none static Bool_t count = kFALSE; @@ -301,7 +357,7 @@ TVector3 AliRICHParam::SigmaSinglePhoton(Int_t partID, Double_t mom, Double_t th Double_t massRef = fgMass[4]; // all the files are calculated for protons...so mass ref is proton mass pmom = mom*massRef/mass; // normalized momentum respect to proton... if(pmom>PmodMax()) pmom = PmodMax(); - Double_t oneOverRefIndex = 1/RefIdxC6F14(MeanCkovEnergy()); + Double_t oneOverRefIndex = 1/IdxC6F14(EckovMean()); Double_t pmin = mass*oneOverRefIndex/TMath::Sqrt(1-oneOverRefIndex*oneOverRefIndex); if(pmom=1) { pmom=6.5; // above physical limi the error is calculated at the saturation... } else { @@ -334,7 +390,7 @@ TVector3 AliRICHParam::SigmaSinglePhoton(Double_t thetaCer, Double_t theta, Doub pmom = beta*gamma*massRef; // normalized momentum respect to proton... } if(pmom>PmodMax()) pmom = PmodMax(); - Double_t oneOverRefIndex = 1/RefIdxC6F14(MeanCkovEnergy()); + Double_t oneOverRefIndex = 1/IdxC6F14(EckovMean()); Double_t pmin = massRef*oneOverRefIndex/TMath::Sqrt(1-oneOverRefIndex*oneOverRefIndex); if(pmom1.) return -999; + else return TMath::ASin(sinref); }//SnellAngle //__________________________________________________________________________________________________ void AliRICHParam::AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t thetaCerenkov,Double_t phiCerenkov,Double_t &tout,Double_t &pout) @@ -479,10 +519,6 @@ void AliRICHParam::AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t th tout=photonInRadiator.Theta(); pout=photonInRadiator.Phi(); }//AnglesInDRS -//__________________________________________________________________________________________________ - -//__________________________________________________________________________________________________ -//__________________________________________________________________________________________________ /* void DrawRing() { @@ -532,3 +568,73 @@ void DrawRing() } //__________________________________________________________________________________________________ */ +void AliRICHParam::TestHit2SDigs(Double_t x,Double_t y,Double_t e,Bool_t isNew) +{ +//Test hit->sdigits procedures +//Arguments: isNew - if true use new (abs pad) procedure else use old one (TVector) +// Returns: none + TClonesArray *pSDigLst=new TClonesArray("AliRICHDigit"); + Int_t iQtot=-1; + if(isNew){ + iQtot=Hit2SDigs(10101,e,pSDigLst); //new technique + }else{ + iQtot=Hit2SDigs(TVector2(x,y),e,pSDigLst);//old technique + } + pSDigLst->Print(); + Double_t dQsum=0; + for(Int_t i=0;iGetEntriesFast();i++) + dQsum+=((AliRICHDigit*)pSDigLst->At(i))->Qdc(); + Printf("Qtot=%i Qsum=%.2f ",iQtot,dQsum); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliRICHParam::Stack(Int_t evt,Int_t tid) +{ +// Prints some usefull info from stack +// Arguments: evt - event number. if not -1 print info only for that event +// tid - track id. if not -1 then print it and all it's mothers if any +// Returns: mother tid of the given tid if any + AliRunLoader *pAL=AliRunLoader::Open(); + if(pAL->LoadHeader()) return -1; + if(pAL->LoadKinematics()) return -1; + + Int_t mtid=-1; + Int_t iNevt=pAL->GetNumberOfEvents(); Printf("This session contains %i event(s)",iNevt); + + for(Int_t iEvt=0;iEvtGetEvent(iEvt); + AliStack *pStack=pAL->Stack(); + if(tid==-1){ //print all tids for this event + for(Int_t i=0;iGetNtrack();i++) pStack->Particle(i)->Print(); + Printf("totally %i tracks including %i primaries for event %i out of %i event(s)",pStack->GetNtrack(),pStack->GetNprimary(),iEvt,iNevt); + }else{ //print only this tid and it;s mothers + if(tid<0 || tid>pStack->GetNtrack()) {Printf("Wrong tid, valid tid range for event %i is 0-%i",iEvt,pStack->GetNtrack());break;} + TParticle *pTrack=pStack->Particle(tid); mtid=pTrack->GetFirstMother(); + TString str=pTrack->GetName(); + while((tid=pTrack->GetFirstMother()) >= 0){ + pTrack=pStack->Particle(tid); + str+=" from ";str+=pTrack->GetName(); + } + Printf("%s",str.Data()); + }//if(tid==-1) + }//events loop + pAL->UnloadHeader(); pAL->UnloadKinematics(); + return mtid; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliRICHParam::StackCount(Int_t pid,Int_t evt) +{ +// Counts total number of particles of given sort (including secondary) for a given event + AliRunLoader *pAL=AliRunLoader::Open(); + pAL->GetEvent(evt); + if(pAL->LoadHeader()) return 0; + if(pAL->LoadKinematics()) return 0; + AliStack *pStack=pAL->Stack(); + + Int_t iCnt=0; + for(Int_t i=0;iGetNtrack();i++) if(pStack->Particle(i)->GetPdgCode()==pid) iCnt++; + + pAL->UnloadHeader(); pAL->UnloadKinematics(); + return iCnt; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHParam.h b/RICH/AliRICHParam.h index 02d7c5e41e1..90ef9a7a5dc 100644 --- a/RICH/AliRICHParam.h +++ b/RICH/AliRICHParam.h @@ -1,20 +1,19 @@ #ifndef AliRICHParam_h #define AliRICHParam_h -#include -#include -#include -#include -#include -#include -#include +#include //base class +#include //QdcTot() +#include //old style #include #include #include -#include -#include +#include //Hit2SDigs() #include -#include +#include //Mars2Lors() Lors2Mars() +#include //fields +#include //fields +#include "AliRICHDigit.h" //Hit2Sdigs() +#include //Instance() static const int kNchambers=7; //number of RICH chambers static const int kNpadsX = 160; //number of pads along X in single chamber @@ -24,65 +23,68 @@ static const int kNsectors=6; //number of sectors per chamber static const int kCerenkov=50000050; //??? go to something more general like TPDGCode static const int kFeedback=50000051; //??? go to something more general like TPDGCode -class AliRICHChamber; - // Class providing all the needed parametrised information // to construct the geometry, to define segmentation and to provide response model // In future will also provide all the staff needed for alignment and calibration -class AliRICHParam :public TObject +class AliRICHParam :public TNamed { public: //ctor&dtor - AliRICHParam():TObject(),fpChambers(0) {CreateChambers();} - virtual ~AliRICHParam() {delete fpChambers;} + virtual ~AliRICHParam() {delete fIdxC6F14;fgInstance=0;} //test methodes void Print(Option_t *opt="") const; //print current parametrization - void Test() {TestSeg();TestTrans();TestResp();} //test all groups of methodes - void TestResp(); //test the response group of methodes - void TestSeg(); //test the segmentation group of methodes - void TestTrans(); //test the transform group of methodes static void DrawAxis(); static void DrawSectors(); //flags staff - static void SetAerogel(Bool_t a) {fgIsAerogel=a;} - static Bool_t IsAerogel() {return fgIsAerogel;} - static void SetRadioSrc(Bool_t a) {fgIsRadioSrc=a;} - static Bool_t IsRadioSrc() {return fgIsRadioSrc;} - static void SetTestBeam(Bool_t a) {fgIsTestBeam=a;} - static Bool_t IsTestBeam() {return fgIsTestBeam;} + static inline AliRICHParam* Instance(); //pointer to AliRICHParam singleton static void SetWireSag(Bool_t a) {fgIsWireSag=a;} static Bool_t IsWireSag() {return fgIsWireSag;} static void SetResolveClusters(Bool_t a) {fgIsResolveClusters=a;} static Bool_t IsResolveClusters() {return fgIsResolveClusters;} -//Chambers manipulation methodes - void CreateChambers(); //form chamber structure - AliRICHChamber* C(Int_t i) {return (AliRICHChamber*)fpChambers->UncheckedAt(i-1);} //returns pointer to chamber i - Int_t Nchambers() {return fpChambers->GetEntriesFast();} //returns number of chambers + static Int_t Stack(Int_t evt=-1,Int_t tid=-1); //Print stack info for event and tid + static Int_t StackCount(Int_t pid,Int_t evt); //Counts stack particles of given sort in given event + static inline Double_t ErrLoc (Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta); + static inline Double_t ErrGeom (Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta); + static inline Double_t ErrCrom (Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta); + static inline TVector3 SigmaSinglePhotonFormula(Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta); //Geometrical properties - static Int_t NpadsX() {return kNpadsX;} //pads along X in chamber - static Int_t NpadsY() {return kNpadsY;} //pads along Y in chamber - static Int_t NpadsXsec() {return NpadsX()/2;} //pads along X in sector - static Int_t NpadsYsec() {return NpadsY()/3;} //pads along Y in sector - static Double_t DeadZone() {return 2.6;} //dead zone size in cm - static Double_t SectorSizeX() {return NpadsX()*PadSizeX()/2;} //sector size x, cm - static Double_t SectorSizeY() {return NpadsY()*PadSizeY()/3;} //sector size y, cm - static Double_t PcSizeX() {return NpadsX()*PadSizeX()+DeadZone();} //PC size x, cm - static Double_t PcSizeY() {return NpadsY()*PadSizeY()+2*DeadZone();} //PC size y, cm - static Double_t Zfreon() {return 1.5;} //freon thinkness, cm - static Double_t Zwin() {return 0.5;} //radiator quartz window, cm - static Double_t Pc2Win() {return 8.0;} //cm between CsI PC and radiator quartz window - static Double_t Pc2Coll() {return 7.0;} //cm between CsI PC and third wire grid (collection wires) - static Double_t Pc2Anod() {return 0.204;} //cm between CsI PC and first wire grid (anod wires) - static Double_t Pc2Cath() {return 0.445;} //cm between CsI PC and second wire grid (cathode wires) - static Double_t Freon2Pc() {return Zfreon()+Zwin()+Pc2Win();} //cm between CsI PC and entrance to freon - static Double_t PitchAnod() {return PadSizeY()/2;} //cm between anode wires - static Double_t PitchCath() {return PadSizeY()/4;} //cm between cathode wires - static Double_t PitchColl() {return 0.5;} //cm between collection wires - static Double_t PadSizeX() {return 0.8;} //pad size x, cm - static Double_t PadSizeY ( ){return 0.84;} //pad size y, cm + static Int_t NpadsX () {return kNpadsX;} //number of pads along X in chamber + static Int_t NpadsY () {return kNpadsY;} //number of pads along Y in chamber + static Int_t NpadsXsec () {return NpadsX()/2;} //number of pads along X in sector + static Int_t NpadsYsec () {return NpadsY()/3;} //number of pads along Y in sector + + static Double_t AnodPitch () {return PadSizeY()/2;} //cm between anode wires + static Double_t AnodZ () {return 7.806;} //Z positon of anod plane in LORS of the chamber, [cm] + static Double_t CathPitch () {return PadSizeY()/4;} //dist between cathode wires [cm] + static Double_t CollPitch () {return 0.5;} //dist between collection wires [cm] + static Double_t DeadZone () {return 2.6;} //dead zone thickness [cm] + static Double_t PadSizeX () {return 0.8;} //pad size x [cm] + static Double_t PadSizeY () {return 0.84;} //pad size y [cm] + static Double_t PcSizeX () {return NpadsX()*PadSizeX()+DeadZone();} //PC size x [cm] + static Double_t PcSizeY () {return NpadsY()*PadSizeY()+2*DeadZone();} //PC size y [cm] + static Double_t Pc2Cath () {return 0.445;} //dist between PC entrance plane and cathode wires plane [cm] + static Double_t Pc2Win () {return PcZ();} //dist between PC entrance plane and window exit plane [cm] + static Double_t PcZ () {return 8.0; } //Z positon of PC entrance plane in LORS of the chamber [cm] + static Double_t RadThick () {return 1.5;} //radiator thickness [cm] + static Double_t RadZ () {return -2.0; } //Z positon of radiator entrance plane in LORS of the chamber [cm] + static Double_t SecSizeX () {return NpadsX()*PadSizeX()/2;} //sector size x [cm] + static Double_t SecSizeY () {return NpadsY()*PadSizeY()/3;} //sector size y [cm ] + static Double_t WinThick () {return 0.5;} //radiator window thickness [cm] + + //trasformation methodes + inline TVector3 Lors2Mars (Int_t c,Double_t x,Double_t y,Int_t p=kPc); //LORS->MARS transform of point [cm] for chamber c and plane p + inline TVector2 Mars2Lors (Int_t c,const TVector3 &x ,Int_t p=kPc); //MARS->LORS transform of point [cm] for chamber c and plane p + + static inline TVector3 Lors2MarsOld (Int_t c,Double_t x,Double_t y,Int_t p); //LORS->MARS transform of position (cm) for chamber c and plane p + static inline TVector2 Mars2LorsOld (Int_t c,const TVector3 &x,Int_t p ); //MARS->LORS transform of position (cm) for chamber c and plane p + static inline TVector3 Mars2LorsVec (Int_t c,const TVector3 &p ); //MARS->LORS transform of vector for chamber c + static inline TVector3 Center (Int_t c,Int_t p ); //Center of plane p of chamber c in MARS (cm) + static inline TVector3 Norm (Int_t c ); //Norm vector to the chamber c in MARS (cm) + static inline TGeoMatrix*Matrix (Int_t iCh, Int_t iPlane ); //TGeoMatrix for the given chamber plain + static Int_t Pad2Cha (Int_t pad ){return pad/100000000; }//abs pad -> chamber static Int_t Pad2Sec (Int_t pad ){return pad%100000000/1000000; }//abs pad -> sector static Int_t Pad2PadX (Int_t pad ){return pad%1000000/1000; }//abs pad -> pad x @@ -100,21 +102,34 @@ public: static inline Int_t PadNeighbours (Int_t iPadX,Int_t iPadY,Int_t aListX[4],Int_t aListY[4]); //pad -> list of it neighbours static Bool_t IsAccepted (const TVector2 &x2 ){return ( x2.X()>=0 && x2.X()<=PcSizeX() && x2.Y()>=0 && x2.Y()<=PcSizeY() ) ? kTRUE:kFALSE;} //optical properties methodes - static Double_t MeanCkovEnergy( ){return 6.766;} //mean Ckov energy according to the total trasmission curve - static Float_t PhotonEnergy (Int_t i ){return 0.1*i+5.5;} //photon energy (eV) for i-th point - static Float_t AbsCH4 (Float_t ev ); //CH4 abs len (cm) - static Float_t AbsGel (Float_t ){return 500;} //Aerogel abs len (cm) - static Float_t RefIdxC6F14 (Float_t eV ){return eV*0.0172+1.177;} //Freon ref idx - static Float_t RefIdxCH4 (Float_t ){return 1.000444;} //Methane ref idx - static Float_t RefIdxSiO2 (Float_t eV ){Float_t e1=10.666,e2=18.125,f1=46.411,f2= 228.71; return TMath::Sqrt(1.+f1/(e1*e1-eV*eV)+f2/(e2*e2-eV*eV));}//Quartz window ref index from TDR p.35 - static Float_t RefIdxGel (Float_t ){return 1.05;} //aerogel ref index - static Float_t DenGel ( ){return (RefIdxGel(0)-1)/0.21;} //aerogel density gr/cm^3 parametrization by E.Nappi - + static Float_t EckovMean ( ){return 6.766e-9;} //mean Ckov energy according to the total trasmission curve + static Float_t EckovMin ( ){return fEckovMin;} //min photon energy [GeV] defined in optical curves + static Float_t EckovMax ( ){return fEckovMax;} //min photon energy [GeV] defined in optical curves + + static Float_t AbsCH4 (Float_t gev ); //AbsLen [cm]=f(Eckov) [GeV] for CH4 used as amp gas + static Float_t AbsGel (Float_t gev ){return fgAbsGel.Eval(gev);} //AbsLen [cm]=f(Eckov) [GeV] for aerogel + static Float_t AbsAir (Float_t gev ){return fgAbsAir.Eval(gev);} //AbsLen [cm]=f(Eckov) [GeV] for air + + Float_t IdxC6F14 (Float_t gev ){return fIdxC6F14->Eval(gev,fIdxC6F14->GetUniqueID());} //n=f(Eckov) [GeV] for C6H14 used as radiator + static Float_t IdxSiO2 (Float_t gev ){return fgIdxSiO2 .Eval(gev);} //n=f(Eckov) [GeV] for SiO2 used as window TDR p.35 + static Float_t IdxCH4 (Float_t gev ){return fgIdxCH4 .Eval(gev);} //n=f(Eckov) [GeV] for CF4 + static Float_t IdxG24 (Float_t gev ){return fgIdxG24 .Eval(gev);} //n=f(Eckov) [GeV] for aerogel @1.024 + static Float_t IdxG26 (Float_t gev ){return fgIdxG26 .Eval(gev);} //n=f(Eckov) [GeV] for aerogel @1.026 + static Float_t IdxG28 (Float_t gev ){return fgIdxG28 .Eval(gev);} //n=f(Eckov) [GeV] for aerogel @1.028 + static Float_t IdxG30 (Float_t gev ){return fgIdxG30 .Eval(gev);} //n=f(Eckov) [GeV] for aerogel @1.030 + static Float_t IdxAir (Float_t gev ){return fgIdxAir .Eval(gev);} //n=f(Eckov) [GeV] for air + static Float_t IdxCF4 (Float_t gev ){return fgIdxCF4 .Eval(gev);} //n=f(Eckov) [GeV] for CF4 + + static Float_t QeApd (Float_t gev ){return fgQeApd .Eval(gev);} //Q.E.=f(Eckov) [GeV] for APD + static Float_t QeCsI (Float_t gev ){return fgQeCsI .Eval(gev);} //Q.E.=f(Eckov) [GeV] for CsI + + void CdbRead (Int_t run,Int_t version ); //read all calibration information for requested run static Double_t IonisationPotential() {return 26.0e-9;} //for CH4 in GeV taken from ???? static TVector2 MathiesonDelta() {return TVector2(5*0.18,5*0.18);} //area of 5 sigmas of Mathieson distribution (cm) static Int_t MaxQdc() {return 4095;} //QDC number of channels + static Int_t QthMIP() {return 100;} static Double_t DmatchMIP() {return 1.;} static Double_t PmodMax() {return 6.5;} @@ -122,15 +137,26 @@ public: static void SetHV(Int_t sector,Int_t hv){fgHV[sector-1]=hv;} //charge response methodes inline static Double_t Mathieson(Double_t x1,Double_t x2,Double_t y1,Double_t y2); //Mathienson integral over given limits + inline static Double_t GainSag(Double_t x,Int_t sector); //gain variations in % - static Double_t QdcSlope(Int_t sec){switch(sec){case -1: return 0; default: return 33;}} //weight of electon in QDC channels static Double_t Gain(const TVector2 &x2){//gives chamber gain in terms of QDC channels for given point in local ref system if(fgIsWireSag) return QdcSlope(Loc2Sec(x2))*(1+GainSag(x2.X(),Loc2Sec(x2))/100); else return QdcSlope(Loc2Sec(x2));} inline static Double_t FracQdc(const TVector2 &x2,const TVector &pad); //charge fraction to pad from hit - inline static Int_t TotQdc(TVector2 x2,Double_t eloss); //total charge for Eloss (GeV) 0 for photons + inline static Int_t TotQdc(TVector2 x2,Double_t e ); //total charge for Eloss (GeV) 0 for photons + static Double_t QdcSlope(Int_t sec){switch(sec){case -1: return 0; default: return 33;}} //weight of electon in QDC channels + + static inline Int_t Lors2Pad (Double_t x,Double_t y ); //LORS (x,y) [cm] -> abs pad number + static Double_t IonPot ( ){return 26.0e-9;} //for CH4 in GeV taken from ???? + static inline Int_t QdcTot (Int_t iPad,Double_t e ); //total QDC generated by Eloss or Etot [GeV] + static inline Double_t QdcSag (Int_t iPad ); //mean QDC variation due to sagita [0,1] + static Double_t QdcEle (Int_t iPad ){return fgIsWireSag?33*(1+QdcSag(iPad)):33;} //mean QDC per electron + static inline Int_t Hit2SDigs (Int_t iPad, Double_t e,TClonesArray* pSDigLst); //hit->sdigits, returns Qtot + static inline Int_t Hit2SDigs (TVector2 hit,Double_t e,TClonesArray* pSDigLst); //hit->sdigits, returns Qtot, old style + static void TestHit2SDigs (Double_t x,Double_t y,Double_t e,Bool_t isNew=kFALSE); //test hit->sdigits + inline static Bool_t IsOverTh(Int_t c,TVector pad,Double_t q); //is QDC of the pad registered by FEE - static Int_t NsigmaTh() {return fgNsigmaTh;} // + static Int_t NsigmaTh() {return fgNsigmaTh;} // static Float_t SigmaThMean() {return fgSigmaThMean;} //QDC electronic noise mean static Float_t SigmaThSpread() {return fgSigmaThSpread;} //QDC electronic noise width @@ -138,37 +164,78 @@ public: -2.66575e-3*TMath::Sin(4*TMath::Pi()/PadSizeX()*x) +2.80553e-3*TMath::Sin(6*TMath::Pi()/PadSizeX()*x)+0.0070;} static void ReadErrFiles(); //Read Err file parameters - static TVector3 SigmaSinglePhoton(Int_t Npart, Double_t mom, Double_t theta, Double_t phi); //Find Sigma for single photon from momentum and particle id - static TVector3 SigmaSinglePhoton(Double_t thetaCer, Double_t theta, Double_t phi); //Fing sigma for single photon from thetacer - static Double_t Interpolate(Double_t par[4][330],Double_t x, Double_t y, Double_t phi); //Find the error value from interpolation - - static TVector3 ForwardTracing(TVector3 entranceTrackPoint,TVector3 vectorTrack, Double_t thetaC, Double_t phiC); //it traces foward a photon from Emission Point to PC - static TVector3 PlaneIntersect(TVector3 vstart,TVector3 p0,TVector3 n,TVector3 v0); //it finds intersection between straight track and plane - static Double_t SnellAngle(Float_t n1, Float_t n2, Float_t theta1); // Snell law - static void AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t thetaCerenkov,Double_t phiCerenkov,Double_t &tout,Double_t &pout);//It finds photon angles in - //Detector Reference System - - static Bool_t fgIsAerogel; //aerogel geometry instead of normal RICH flag + TVector3 SigmaSinglePhoton(Int_t Npart, Double_t mom, Double_t theta, Double_t phi); //Find Sigma for single photon from momentum and particle id + TVector3 SigmaSinglePhoton(Double_t thetaCer, Double_t theta, Double_t phi); //Fing sigma for single photon from thetacer + static Double_t Interpolate(Double_t par[4][330],Double_t x, Double_t y, Double_t phi); //Find the error value from interpolation + + TVector3 ForwardTracing(TVector3 entranceTrackPoint,TVector3 vectorTrack, Double_t thetaC, Double_t phiC); //it traces foward a photon from Emission Point to PC + static TVector3 PlaneIntersect(const TVector3 &lineDir,const TVector3 &linePoint,const TVector3 &planeNorm,const TVector3 &planePoint); //intersection between line and plane + static Double_t SnellAngle(Float_t n1, Float_t n2, Float_t theta1); // Snell law + static void AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t thetaCerenkov,Double_t phiCerenkov,Double_t &tout,Double_t &pout);//It finds photon angles in + static Double_t AlphaFeedback(Int_t c,Int_t s) {c++;s++; return 0.02;} //for sector s of chamber c +//test part + static void Test() {TestSeg();TestTrans();TestResp();} //test all groups of methodes + static void TestResp(); //test the response group of methodes + static void TestSeg(); //test the segmentation group of methodes + static void TestTrans(); //test the transform group of methodes + static Double_t fgMass[5]; // mass array -protected: - static Bool_t fgIsRadioSrc; //radioactive source instead of radiators flag static Bool_t fgIsTestBeam; //test beam geometry instead of normal RICH flag - static Bool_t fgIsWireSag; //wire sagitta ON/OFF flag - static Bool_t fgIsResolveClusters; //declustering ON/OFF flag - static Bool_t fgIsFeedback; //generate feedback photon? - - TObjArray *fpChambers; //list of chambers - static Int_t fgHV[6]; //HV applied to anod wires - static Int_t fgNsigmaTh; //n. of sigmas to cut for zero suppression - static Float_t fgSigmaThMean; //sigma threshold value - static Float_t fgSigmaThSpread; //spread of sigma + enum EPlaneId {kCenter,kPc,kRad,kAnod,kNch=7}; //4 planes in chamber and total number of chambers +protected: + AliRICHParam(); //default ctor is protected to enforce it to be singleton + static AliRICHParam *fgInstance; //static pointer to instance of AliRICHParam singleton +//optical curves + static Double_t fEckovMin; //min Eckov + static Double_t fEckovMax; //max Eckov + + TF2* fIdxC6F14; //n=f(Ephot,T) [GeV] for radiator freon C6F14 + static TF1 fgIdxSiO2; //n=f(Ephot) [GeV] for window quartz SiO2 + static TF1 fgIdxCH4; //n=f(Ephot) [GeV] for MWPC amp gas CF4 + static TF1 fgIdxAir; //n=f(Ephot) [GeV] for air + static TF1 fgIdxC4F10; //n=f(Ephot) [GeV] for radiator C4F10 + static TF1 fgIdxCF4; //n=f(Ephot) [GeV] for radiator CF4 + static TF1 fgIdxG30; //n=f(Ephot) [GeV] for radiator aerogel @1.030 + static TF1 fgIdxG28; //n=f(Ephot) [GeV] for radiator aerogel @1.028 + static TF1 fgIdxG26; //n=f(Ephot) [GeV] for radiator aerogel @1.026 + static TF1 fgIdxG24; //n=f(Ephot) [GeV] for radiator aerogel @1.024 - static Double_t fgErrChrom[4][330]; // - static Double_t fgErrGeom[4][330]; // - static Double_t fgErrLoc[4][330]; //Chromatic, Geometric and Localization array to parametrize SigmaCerenkov + static TF1 fgAbsC6F14; //abs len curve for radiator freon C6F14, cm versus GeV + static TF1 fgAbsSiO2; //abs len curve for window quartz SiO2 , cm versus GeV + static TF1 fgAbsCH4; //abs len curve for MWPC methane CF4 , cm versus GeV + static TF1 fgAbsAir; //abs len curve for air, cm versus GeV + static TF1 fgAbsC4F10; //abs len curve for radiator C4F10 + static TF1 fgAbsCF4; //abs len curve for radiator CF4 + static TF1 fgAbsGel; //abs len curve for gel, cm versus GeV - ClassDef(AliRICHParam,6) //RICH main parameters class + static TF1 fgQeCsI; //QE=f(Ephot) [GeV] for MWPC PC CsI + static TF1 fgQeApd; //QE=f(Ephot) [GeV] for APD + + static Bool_t fgIsWireSag; //wire sagitta ON/OFF flag + static Bool_t fgIsResolveClusters; //declustering ON/OFF flag + static Bool_t fgIsFeedback; //generate feedback photon? + + static Int_t fgHV[6]; //HV applied to anod wires + static Int_t fgNsigmaTh; //n. of sigmas to cut for zero suppression + static Float_t fgSigmaThMean; //sigma threshold value + static Float_t fgSigmaThSpread; //spread of sigma + + static Double_t fgErrChrom[4][330]; // + static Double_t fgErrGeom[4][330]; // + static Double_t fgErrLoc[4][330]; //Chromatic, Geometric and Localization array to parametrize SigmaCerenkov + TGeoHMatrix *fMatrix[kNchambers]; //poiners to matrices defining RICH chambers rotations-translations + ClassDef(AliRICHParam,0) //RICH main parameters class }; + +AliRICHParam* AliRICHParam::Instance() +{ +// Return pointer to the AliRICHParam singleton. +// Arguments: none +// Returns: pointer to the instance of AliRICHParam or 0 if no geometry + if(!fgInstance&&gGeoManager) new AliRICHParam; + else if(!gGeoManager) Printf("No geometry imported"); + return fgInstance; +}//Instance() //__________________________________________________________________________________________________ Int_t AliRICHParam::PadNeighbours(Int_t iPadX,Int_t iPadY,Int_t listX[4],Int_t listY[4]) { @@ -188,15 +255,15 @@ Int_t AliRICHParam::PadNeighbours(Int_t iPadX,Int_t iPadY,Int_t listX[4],Int_t l //__________________________________________________________________________________________________ Int_t AliRICHParam::Loc2Sec(const TVector2 &v2) { -//Determines sector containing the given point. -//Returns sector code: -//y ^ 5 6 -// | 3 4 -// | 1 2 -// -------> x - Double_t x0=0; Double_t x1=SectorSizeX(); Double_t x2=SectorSizeX()+DeadZone(); Double_t x3=PcSizeX(); - Double_t y0=0; Double_t y1=SectorSizeY(); Double_t y2=SectorSizeY()+DeadZone(); Double_t y3=2*SectorSizeY()+DeadZone(); - Double_t y4=PcSizeY()-SectorSizeY(); Double_t y5=PcSizeY(); +// Determines sector containing the given point. y ^ 5 6 +// | 3 4 +// | 1 2 +// -------> x +// Arguments: v2- LORS position [cm] +// Returns: sector code + Double_t x0=0; Double_t x1=SecSizeX(); Double_t x2=SecSizeX()+DeadZone(); Double_t x3=PcSizeX(); + Double_t y0=0; Double_t y1=SecSizeY(); Double_t y2=SecSizeY()+DeadZone(); Double_t y3=2*SecSizeY()+DeadZone(); + Double_t y4=PcSizeY()-SecSizeY(); Double_t y5=PcSizeY(); Int_t sector=-1; if (v2.X() >= x0 && v2.X() <= x1 ) sector=1; @@ -226,11 +293,33 @@ TVector AliRICHParam::Loc2Pad(const TVector2 &loc) else pad[0]=NpadsX() - Int_t( (PcSizeX()-loc.X()) / PadSizeX() ) ; //sector 2 or 4 or 6 //second deal with y if(sec==1||sec==2) pad[1]=Int_t( loc.Y() / PadSizeY())+1; //sector 1 or 2 - else if(sec==3||sec==4) pad[1]=Int_t( (loc.Y()-SectorSizeY()-DeadZone()) / PadSizeY())+NpadsYsec()+1; //sector 3 or 4 + else if(sec==3||sec==4) pad[1]=Int_t( (loc.Y()-SecSizeY()-DeadZone()) / PadSizeY())+NpadsYsec()+1; //sector 3 or 4 else pad[1]=NpadsY() - Int_t( (PcSizeY()-loc.Y()) / PadSizeY()); //sector 5 or 6 return pad; } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliRICHParam::Lors2Pad(Double_t x,Double_t y) +{ +// Determines abs pad number containing the given point (x,y) defined in the chamber RS. +// Pad count starts in lower left corner from 1,1 to 144,160 in upper right corner of a chamber. +// y ^ 5 6 +// | 3 4 +// | 1 2 +// -------> x + Int_t padx,pady; + if (x>= 0 && x<= SecSizeX() ) padx= 1 + Int_t( x /PadSizeX() ); //sector 1 or 3 or 5 + else if(x>=SecSizeX()+DeadZone() && x<= PcSizeX() ) padx= NpadsX() - Int_t( (PcSizeX()-x)/PadSizeX() ); //sector 2 or 4 or 6 + else return -1; //dead zone or out of chamber + + + if (y>= 0 && y<= SecSizeY() ) pady= 1 + Int_t( y /PadSizeY() ); //sector 1 or 2 + else if(y>=SecSizeY()+DeadZone() && y<=2*SecSizeY()+DeadZone() ) pady= 1 + NpadsYsec() + Int_t( (y-SecSizeY()-DeadZone()) / PadSizeY()); //sector 3 or 4 + else if(y>= PcSizeY()-SecSizeY() && y<= PcSizeY() ) pady= NpadsY() - Int_t( (PcSizeY()-y)/PadSizeY() ); //sector 5 or 6 + else return -1; //dead zone or out of chamber + + return AliRICHDigit::P2A(0,padx,pady); +}//Lors2Pad() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Int_t AliRICHParam::Pad2Sec(const TVector &pad) { //Determines sector containing the given pad. @@ -246,7 +335,7 @@ Int_t AliRICHParam::Pad2Sec(const TVector &pad) return sector; }//Pad2Sec() -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TVector2 AliRICHParam::Pad2Loc(TVector pad) { //Returns position of the center of the given pad in local system of the chamber (cm) @@ -273,25 +362,25 @@ TVector2 AliRICHParam::Pad2Loc(TVector pad) return TVector2(x,y); } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TVector2 AliRICHParam::Pad2Loc(Int_t pad) { -//Converts absolute pad number to local position in LORS -//LORS is a chamber reference system with origin in left-down coner looking from IP -//Arguments: pad- absolute pad number -// Returns: pad center position as TVector2 in PCRS +// Converts absolute pad number to local position in LORS +// LORS is a chamber reference system with origin in left-down coner looking from IP +// Arguments: pad- absolute pad number +// Returns: pad center position as TVector2 in PCRS TVector2 pos; pos.Set((Pad2PadX(pad)-0.5)*PadSizeX() , (Pad2PadY(pad)-0.5)*PadSizeY());//set to sector LORS return pos; } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Double_t AliRICHParam::GainSag(Double_t x,Int_t sector) { //Returns % of gain variation due to wire sagita. //All curves are parametrized as per sector basis, so x must be apriory transformed to the Sector RS. //Here x is a distance along wires. - x-=SectorSizeX()/2; - if(x>SectorSizeX()) x-=SectorSizeX(); + x-=SecSizeX()/2; + if(x>SecSizeX()) x-=SecSizeX(); switch(HV(sector)){ case 2150: return 9e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0316*TMath::Power(x,2)-3e-4*x+25.367;//% case 2100: return 8e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0283*TMath::Power(x,2)-2e-4*x+23.015; @@ -300,7 +389,38 @@ Double_t AliRICHParam::GainSag(Double_t x,Int_t sector) default: return 0; } } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHParam::QdcSag(Int_t iPad) +{ +// It was observed at BNL that wires are affected by gravitation field providing a significant sagita leading to the local electric field variation +// which means that different pads produce different signals. +// Arguments: iPad- absolute pad number +// Returns: gain variation due to wire sagita 0 < QdcSag < 1. +// Curves are parametrised in terms of distance x (cm) along wires having 0 on the left edge of the photocathode + Double_t x=AliRICHDigit::P2X(iPad)*PadSizeX()-0.5*PadSizeX(); //center of the padx (count from 1) + switch(HV(iPad)){ + case 2150: return 0.01*(9e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0316*TMath::Power(x,2)-3e-4*x+25.367);//function is a fit in % so multiply by 0.01 + case 2100: return 0.01*(8e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0283*TMath::Power(x,2)-2e-4*x+23.015); + case 2050: return 0.01*(7e-6*TMath::Power(x,4)+1e-7*TMath::Power(x,3)-0.0254*TMath::Power(x,2)-2e-4*x+20.888); + case 2000: return 0.01*(6e-6*TMath::Power(x,4)+8e-8*TMath::Power(x,3)-0.0227*TMath::Power(x,2)-1e-4*x+18.961); + default: return 0; + } +}//QdcSag() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliRICHParam::QdcTot(Int_t iPad,Double_t e) +{ +// Calculates the total charge produced by the hit. Method: +// 1. number of electrons is calculated as energy lost in amp gas divided by ionisation potential (for photon only one electron as Etot is always less then ionization potential) +// 2. each electron imposes a charge distributed as Poisson with QdcEle() mean. Different pads produce different means. See QdcEle(). +// Arguments: iPad- absolute pad number contaning the hit; +// e- Eloss for mip in amplification gas or Etot for photon +// Returns: charge parametrised in QDC channels. + Int_t iNele=Int_t(e/IonPot()); if(iNele==0) iNele=1;//e < ion. pot. means it's photoelectron + Double_t dQdc=0; + for(Int_t i=1;i<=iNele;i++) dQdc+=-QdcEle(iPad)*TMath::Log(gRandom->Rndm()); + return Int_t(dQdc); +}//QdcTot() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Int_t AliRICHParam::TotQdc(TVector2 x2,Double_t eloss) { //Calculates the total charge produced by the eloss in point x2 (Chamber RS). @@ -312,7 +432,7 @@ Int_t AliRICHParam::TotQdc(TVector2 x2,Double_t eloss) for(Int_t i=1;i<=iNelectrons;i++) qdc+=-Gain(x2)*TMath::Log(gRandom->Rndm()); return Int_t(qdc); } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Double_t AliRICHParam::FracQdc(const TVector2 &x2,const TVector &pad) { //Calculates the charge fraction induced to given pad by the hit from the given point. @@ -326,13 +446,15 @@ Double_t AliRICHParam::FracQdc(const TVector2 &x2,const TVector &pad) //requested pad might not belong to the sector of the given hit position, hence the check: return (Loc2Sec(x2)!=Pad2Sec(pad)) ? 0:Mathieson(normXmin, normYmin, normXmax, normYmax); } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Double_t AliRICHParam::Mathieson(Double_t x1,Double_t y1,Double_t x2,Double_t y2) { -//This is the answer to electrostatic problem of charge distrubution in MWPC described elsewhere. (NIM A370(1988)602-603) -//Arguments: x1- diff between center of distribution and left margin of interested pad divided by anod-cathode distance -// x2,y1,y2- analogically -// Returns: a charge fraction [0-1]. +// This is the answer to electrostatic problem of charge distrubution in MWPC described elsewhere. (NIM A370(1988)602-603) +// Arguments: x1- diff between center of distribution which is a hit position and left edge of interested pad divided by anod-cathode distance +// x2- right edge of the pad +// y1- up edge of the pad +// y2- bottom edge of the pad +// Returns: a charge fraction [0-1] imposed into the pad const Double_t kSqrtKx3=0.77459667;const Double_t kX2=0.962;const Double_t kX4=0.379; const Double_t kSqrtKy3=0.77459667;const Double_t kY2=0.962;const Double_t kY4=0.379; @@ -342,11 +464,11 @@ Double_t AliRICHParam::Mathieson(Double_t x1,Double_t y1,Double_t x2,Double_t y2 Double_t uy2=kSqrtKy3*TMath::TanH(kY2*y2); return 4*kX4*(TMath::ATan(ux2)-TMath::ATan(ux1))*kY4*(TMath::ATan(uy2)-TMath::ATan(uy1)); } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TVector AliRICHParam::Loc2Area(const TVector2 &x2) { -//Calculates the area of disintegration for a given point. It's assumed here that this points lays on anode wire. -//Area is a rectangulare set of pads defined by its left-down and right-up coners. +// Calculates the area of disintegration for a given point. It's assumed here that this points lays on anode wire. +// Area is a rectangulare set of pads defined by its left-down and right-up coners. TVector area(4); TVector pad=Loc2Pad(x2); area[0]=area[2]=pad[0]; area[1]=area[3]=pad[1];//area is just a pad fired @@ -356,11 +478,259 @@ TVector AliRICHParam::Loc2Area(const TVector2 &x2) if(pad[1]!=NpadsYsec() && pad[1]!= 2*NpadsYsec() && pad[1]!= NpadsY() ) area[3]++; //right up coner Y return area; } -//__________________________________________________________________________________________________ -Bool_t AliRICHParam::IsOverTh(Int_t ,TVector ,Double_t q) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Bool_t AliRICHParam::IsOverTh(Int_t ,TVector ,Double_t qdc) { -//Checks if the current q is over threshold and FEE will save this value to data concentrator. - return (q>NsigmaTh()*(SigmaThMean()+(1.-2*gRandom->Rndm())*SigmaThSpread())); +// Checks if the current QDC is over threshold and FEE will save this value to data concentrator. +// This is done on pad by pad level, so the pad pedestal map is to be used. ?????????????? +// Arguments: +// Returns: true if QDC over treshold + return (qdc>NsigmaTh()*(SigmaThMean()+(1.-2*gRandom->Rndm())*SigmaThSpread())); //??????????? to be change to real values } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TGeoMatrix* AliRICHParam::Matrix(Int_t iChamN,Int_t iPlane) +{ + TGeoHMatrix *pMatrix=new TGeoHMatrix; + + const Double_t kAngHor=19.5; // horizontal angle between chambers 19.5 grad + const Double_t kAngVer=20; // vertical angle between chambers 20 grad + const Double_t kAngCom=30; // common RICH rotation with respect to x axis 30 grad + + pMatrix->RotateY(90); //rotate around y since initial position is in XY plane -> now in YZ plane + Double_t trans[3]={490,0,0}; //center of the chamber is on window-gap surface + + switch(iPlane){ + case kCenter: break; + case kPc : trans[0]+=PcZ(); break; + case kRad : trans[0]+=RadZ(); break; + case kAnod : trans[0]+=AnodZ(); break; + default: return 0; break; + } + pMatrix->SetTranslation(trans); //now plane in YZ is shifted along x + + switch(iChamN){ + case 1: pMatrix->RotateY(kAngHor); pMatrix->RotateZ(-kAngVer); break; //right and down + case 2: pMatrix->RotateZ(-kAngVer); break; //down + case 3: pMatrix->RotateY(kAngHor); break; //right + case 4: break; //no rotation + case 5: pMatrix->RotateY(-kAngHor); break; //left + case 6: pMatrix->RotateZ(kAngVer); break; //up + case 7: pMatrix->RotateY(-kAngHor); pMatrix->RotateZ(kAngVer); break; //left and up + default: return 0; break; + }//switch(iChamber) + pMatrix->RotateZ(kAngCom); //apply common rotation in XY plane + return pMatrix; +}//Matrix() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TVector3 AliRICHParam::Lors2Mars(Int_t iChId,Double_t x,Double_t y,Int_t iPlnId) +{ +// Trasform from LORS to MARS +// Arguments: iChId - chamber code 1..7 +// x,y - point in LORS +// iPlnN - chamber plane code might be kPc kRad kCenter kAnod + Double_t z=0; + switch(iPlnId){ + case kPc : z=PcZ() ; break; + case kAnod : z=AnodZ(); break; + case kCenter: z=0 ; break; + case kRad : z=RadZ() ; break; + } + Double_t lors[3]={x-0.5*PcSizeX(),y-0.5*PcSizeY(),z}, mars[3]; + fMatrix[iChId-1]->LocalToMaster(lors,mars); + return TVector3(mars); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TVector2 AliRICHParam::Mars2Lors(Int_t iChId,const TVector3 &x,Int_t iPlnId) +{ +// Trasform from MARS to LORS +// Arguments: iChId - chamber code 1..7 +// mars - point in MARS +// iPlnN - chamber plane code might be kPc kRad kCenter kAnod + Double_t z=0; + switch(iPlnId){ + case kPc : z=PcZ() ; break; + case kAnod : z=AnodZ(); break; + case kCenter: z=0 ; break; + case kRad : z=RadZ() ; break; + } + Double_t lors[3],mars[3]; + x.GetXYZ(mars); + fMatrix[iChId-1]->MasterToLocal(mars,lors); + return TVector2(lors[0]+0.5*PcSizeX(),lors[1]+0.5*PcSizeY()); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TVector3 AliRICHParam::Lors2MarsOld(Int_t iChId,Double_t x,Double_t y,Int_t iPlnId) +{ +// Trasform from LORS to MARS +// Arguments: iChId - chamber code 0..6 +// x,y - point in LORS +// iPlnN - chamber plane code might be kPc kRad kCenter kAnod + TGeoMatrix *pMatrix=Matrix(iChId,iPlnId); + Double_t lors[3]={x-0.5*PcSizeX(),y-0.5*PcSizeY(),0}, mars[3]; pMatrix->LocalToMaster(lors,mars); delete pMatrix; + return TVector3(mars); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TVector2 AliRICHParam::Mars2LorsOld(Int_t iChamN,const TVector3 &x,Int_t iPlaneN) +{ + TGeoMatrix *pMatrix=Matrix(iChamN,iPlaneN); + Double_t mars[3]={x.X(),x.Y(),x.Z()} , lors[3]; pMatrix->MasterToLocal(mars,lors); delete pMatrix; + return TVector2(lors[0]+0.5*PcSizeX(),lors[1]+0.5*PcSizeY()); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TVector3 AliRICHParam::Mars2LorsVec(Int_t iChamN,const TVector3 &x) +{ + TGeoMatrix *pMatrix=Matrix(iChamN,kPc); + Double_t mars[3]={x.X(),x.Y(),x.Z()} , lors[3]; pMatrix->MasterToLocalVect(mars,lors); delete pMatrix; + return TVector3(lors); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TVector3 AliRICHParam::Center(Int_t iChamN,Int_t iPlaneN) +{ + TGeoMatrix *pMatrix=Matrix(iChamN,iPlaneN); + Double_t mars[3] , lors[3]={0,0,0}; pMatrix->LocalToMaster(lors,mars); delete pMatrix; + return TVector3(mars); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TVector3 AliRICHParam::Norm(Int_t iChamN) +{ + TGeoMatrix *pMatrix=Matrix(iChamN,kPc); + Double_t mars[3] , lors[3]={0,0,1}; pMatrix->LocalToMasterVect(lors,mars); delete pMatrix; + return TVector3(mars); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliRICHParam::Hit2SDigs(Int_t iHitPad,Double_t e,TClonesArray *pSDigLst) +{ +// Determines a number of pads affected by the hit and calculates the charge induced to each pad. +// Integrated Mathieson distribution is used. Invoked from AliRICHvX::Hits2SDigits() +// Arguments: iHitPad - hit pad absolute number +// e - energy (GeV) of this hit (Eloss for mip or Etot for photon) +// pSDigLst - pointer to clones array to store in calculated sdigits +// Returns: total QDC for this hit + Int_t iQtot=QdcTot(iHitPad,e); //total QDC value collected for this hit + Int_t a=1; //analise current pad +- a pads in both directions + Int_t iLeftX=0,iBotY=0,iRightX=0,iTopY=0; //area of disintegration for cluster formation, shifts to hit pad, not pad numbers + if(AliRICHDigit::P2X(iHitPad) > a) iLeftX =-a;//determine area of disintegration as hit pad +- parametrised number + if(AliRICHDigit::P2X(iHitPad) < AliRICHDigit::kPadsSecX-a) iRightX= a;//of pads. this number is determined by5 sigmas of Mathieson shape + if(AliRICHDigit::P2Y(iHitPad) > a) iBotY =-a;//see RICH TDR page 29 + if(AliRICHDigit::P2Y(iHitPad) < AliRICHDigit::kPadsSecY-a) iTopY = a;//also boundary conditions are checked (edge of sector aka PC) + Int_t iPadsCnt=0; + for(Int_t iShiftX=iLeftX;iShiftX<=iRightX;iShiftX++){//affected pads loop iShiftX is a distance (in pads) between hit pad and pad under analisys + for(Int_t iShiftY=iBotY;iShiftY<=iTopY;iShiftY++){//affected pads loop + iHitPad+=AliRICHDigit::kPadAbsX*iShiftX+iShiftY; + Double_t x1=PadSizeX()/Pc2Cath()*(iShiftX-0.5);//parametrise for Mathienson + Double_t x2=PadSizeX()/Pc2Cath()*(iShiftX+0.5);//parametrise for Mathienson + Double_t y1=PadSizeY()/Pc2Cath()*(iShiftY-0.5);//parametrise for Mathienson + Double_t y2=PadSizeY()/Pc2Cath()*(iShiftY+0.5);//parametrise for Mathienson + (*pSDigLst)[iPadsCnt++]= new AliRICHDigit(iHitPad,iQtot*Mathieson(x1,y1,x2,y2)); + }//Y loop + }//X loop + return iQtot; +}//Hit2SDigs() for abs pad +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliRICHParam::Hit2SDigs(TVector2 hitX2,Double_t e,TClonesArray *pSDigLst) +{ +// Determines a number of pads affected by the hit and calculates the charge induced to each pad. +// Integrated Mathieson distribution is used. Invoked from AliRICHvX::Hits2SDigits() +// Arguments: hitX2 - hit position in LORS, cm +// e - energy (GeV) of this hit (Eloss for mip or Etot for photon) +// pSDigLst - pointer to clones array to store in calculated sdigits +// Returns: total QDC for this hit + Int_t iQtot=TotQdc(hitX2,e);//total charge produced by hit, 0 if hit in dead zone + if(iQtot==0) return 0; + + TVector hitPad=Loc2Pad(hitX2); TVector2 padCenterX2=Pad2Loc(hitPad); //shift the hit position to the nearest anod wire + TVector2 anod; + if((hitX2.Y()-padCenterX2.Y())>0) anod.Set(hitX2.X(),padCenterX2.Y()+AnodPitch()/2); //upper part of the pad: shift to upper anod wire + else anod.Set(hitX2.X(),padCenterX2.Y()-AnodPitch()/2); //lower part of the pad: shift to lower anod wire + + TVector area=Loc2Area(anod);//determine affected pads, dead zones analysed inside + TVector pad(2); //current pad + Int_t iPadsCnt=0; + for(pad[1]=area[1];pad[1]<=area[3];pad[1]++){//affected pads loop + for(pad[0]=area[0];pad[0]<=area[2];pad[0]++){ + Double_t dQpad=iQtot*FracQdc(anod,pad); + if(dQpad>0.1) (*pSDigLst)[iPadsCnt++]= new AliRICHDigit(pad,dQpad);//make sdigit if Qpad is large enough, meaning after merging there is a chance to go above threshold + }//X loop + }//Y loop + return iQtot; +}//Hit2SDigs() for TVector2 +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TVector3 AliRICHParam::SigmaSinglePhotonFormula(Double_t thetaCer, Double_t phiCer, Double_t theta, Double_t phi, Double_t beta) +{ + TVector3 v(-999,-999,-999); + + v.SetX(AliRICHParam::ErrLoc(thetaCer,phiCer,theta,phi,beta)); + v.SetY(AliRICHParam::ErrGeom(thetaCer,phiCer,theta,phi,beta)); + v.SetZ(AliRICHParam::ErrCrom(thetaCer,phiCer,theta,phi,beta)); + + return v; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHParam::ErrLoc(Double_t thetaC, Double_t phiC, Double_t Ptheta, Double_t Pphi, Double_t beta) +{ +//par->RefIdxC6F14(par->MeanCkovEnergy()) +//(Float_t)1.29337525367736816e+00 +Double_t RefC6F14m = 1.29337; + Double_t Hgap = Pc2Win(); + Double_t dphi = phiC - Pphi; + + Double_t alpha =TMath::Cos(Ptheta)-TMath::Tan(thetaC)*TMath::Cos(dphi)*TMath::Sin(Ptheta); + Double_t k = 1.-RefC6F14m*RefC6F14m+alpha*alpha/(beta*beta); + + Double_t mu = TMath::Sin(Ptheta)*TMath::Sin(Pphi) + TMath::Tan(thetaC)*(TMath::Cos(Ptheta)*TMath::Cos(dphi)*TMath::Sin(Pphi) ++ TMath::Sin(dphi)*TMath::Cos(Pphi)); + + Double_t e = TMath::Sin(Ptheta)*TMath::Cos(Pphi)+TMath::Tan(thetaC)*(TMath::Cos(Ptheta)*TMath::Cos(dphi)*TMath::Cos(Pphi) -TMath::Sin(dphi)*TMath::Sin(Pphi)); + + Double_t kk = beta*TMath::Sqrt(k)/(Hgap*alpha); + Double_t dtdxc = kk*(k*(TMath::Cos(dphi)*TMath::Cos(Pphi) - TMath::Cos(Ptheta)*TMath::Sin(dphi)*TMath::Sin(Pphi)) - ( alpha* + mu/(beta*beta) )*TMath::Sin(Ptheta)*TMath::Sin(dphi)); + + Double_t dtdyc = kk*(k*(TMath::Cos(dphi)*TMath::Sin(Pphi) + TMath::Cos(Ptheta)*TMath::Sin(dphi)*TMath::Cos(Pphi)) + ( alpha* + e/(beta*beta) )* TMath::Sin(Ptheta)*TMath::Sin(dphi)); + + return TMath::Sqrt(0.2*0.2*dtdxc*dtdxc + 0.25*0.25*dtdyc*dtdyc); +} + +Double_t AliRICHParam::ErrCrom(Double_t thetaC, Double_t phiC, Double_t Ptheta, Double_t Pphi, Double_t beta) +{ + Double_t dphi = phiC - Pphi; + Double_t RefC6F14m = 1.29337; + Double_t alpha =TMath::Cos(Ptheta)-TMath::Tan(thetaC)*TMath::Cos(dphi)*TMath::Sin(Ptheta); + + Double_t dtdn = TMath::Cos(Ptheta)*RefC6F14m*beta*beta/(alpha*TMath::Tan(thetaC)); + + Double_t f = 0.00928*(7.75-5.635)/TMath::Sqrt(12.); + + return f*dtdn; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHParam::ErrGeom(Double_t thetaC, Double_t phiC, Double_t Ptheta, Double_t Pphi, Double_t beta ) +{ + + Double_t Tr = RadThick(); + Double_t Xep = 0.5*Tr; + + Double_t dphi = phiC - Pphi; + Double_t RefC6F14m = 1.29337; + Double_t alpha =TMath::Cos(Ptheta)-TMath::Tan(thetaC)*TMath::Cos(dphi)*TMath::Sin(Ptheta); + + Double_t k = 1.-RefC6F14m*RefC6F14m+alpha*alpha/(beta*beta); + + Double_t Hgap = Pc2Win(); + + + Double_t eTr = (Tr - Xep)*beta*TMath::Sqrt(k)/(Hgap*alpha); + Double_t lambda = 1.-TMath::Sin(Ptheta)*TMath::Sin(Ptheta)*TMath::Sin(phiC)*TMath::Sin(phiC); + + Double_t c = 1./(1.+ eTr*k/(alpha*alpha*TMath::Cos(thetaC)*TMath::Cos(thetaC))); + Double_t I = beta*TMath::Tan(thetaC)*lambda*TMath::Power(k,1.5); + Double_t II = 1.+eTr*beta*I; + + Double_t err = c * (I/(alpha*alpha*Hgap) + II* (1.-lambda) / ( alpha*alpha*Hgap*beta*(1.+eTr)) ); + Double_t TrErr = Tr/(TMath::Sqrt(12.)*TMath::Cos(Ptheta)); + + return TrErr*err; +}//ErrGeom() + #endif //AliRICHParam_h diff --git a/RICH/AliRICHRecon.cxx b/RICH/AliRICHRecon.cxx index b24acf0c037..e4c3e42aa43 100644 --- a/RICH/AliRICHRecon.cxx +++ b/RICH/AliRICHRecon.cxx @@ -18,113 +18,74 @@ // AliRICHRecon // // // // RICH class to perfom pattern recognition based on Hough transfrom // -// // +// for single chamber // ////////////////////////////////////////////////////////////////////////// -#include +#include "AliRICHRecon.h" //class header #include #include #include #include -#include -#include "AliRICH.h" +#include "AliRICHCluster.h" //ThetaCerenkov() #include "AliRICHParam.h" -#include "AliRICHRecon.h" -#include "AliRICHHelix.h" +#include "AliRICHHelix.h" //ThetaCerenkov() #include #define NPointsOfRing 201 //__________________________________________________________________________________________________ -AliRICHRecon::AliRICHRecon(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t iMipId) - :TTask("RichRec","RichPat") +AliRICHRecon::AliRICHRecon() + :TTask ("RichRec","RichPat") { // main ctor - SetFreonScaleFactor(1); - fIsWEIGHT = kFALSE; - if(pClusters->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction -// fIsWEIGHT = kTRUE; fThetaMin = 0.0; fThetaMax = 0.75; fDTheta = 0.001; fWindowWidth = 0.045; fMinNumPhots = 3; - fRadiatorWidth = AliRICHParam::Zfreon(); - fQuartzWidth = AliRICHParam::Zwin(); - fGapWidth = AliRICHParam::Freon2Pc() - fRadiatorWidth - fQuartzWidth; - fXmin = 0.; - fXmax = AliRICHParam::PcSizeX(); - fYmin = 0.; - fYmax = AliRICHParam::PcSizeY(); - SetTrackTheta(pHelix->Ploc().Theta()); - SetTrackPhi(pHelix->Ploc().Phi()); - SetMipIndex(iMipId); - SetShiftX(pHelix->PosRad().X()); - SetShiftY(pHelix->PosRad().Y()); - fpClusters = pClusters; + fParam=AliRICHParam::Instance(); //get the pointer to AliRICHParam } //__________________________________________________________________________________________________ -Double_t AliRICHRecon::ThetaCerenkov() +Double_t AliRICHRecon::ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t &iMipId) { // Pattern recognition method based on Hough transform // Return theta Cerenkov for a given track and list of clusters which are set in ctor +// Remeber that list of clusters must contain more then 1 cluster. This considiration implies that normally we have 1 mip cluster and few photon clusters per track. +// Argume +// Returns: Track theta ckov in rad, nPhot contains number of photon candidates accepted for reconstruction track theta ckov + SetTrackTheta(pHelix->Ploc().Theta()); SetTrackPhi(pHelix->Ploc().Phi()); + SetShiftX(pHelix->PosRad().X()); SetShiftY(pHelix->PosRad().Y()); + fClusters = pClusters; + if(pClusters->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction + else fIsWEIGHT = kFALSE; - if(fpClusters->GetEntries()==0) return -10;//no clusters at all for a given track - Bool_t kPatRec = kFALSE; - - AliDebug(1,Form("---Track Parameters--- Theta: %f , Phi: %f ",GetTrackTheta()*TMath::RadToDeg(),GetTrackPhi()*TMath::RadToDeg())); - Int_t candidatePhotons = 0; - SetThetaCerenkov(-1); - SetHoughPhotons(0); - SetHoughPhotonsNorm(0); + SetThetaCerenkov(-1); - for (Int_t j=0; j < fpClusters->GetEntries(); j++){//clusters loop - SetPhotonIndex(j); + for (Int_t iClu=0; iCluGetEntriesFast();iClu++){//clusters loop + if(iClu == iMipId) continue; // do not consider MIP cluster as a photon candidate + SetPhotonIndex(iClu); SetPhotonFlag(0); SetPhotonEta(-999.); SetPhotonWeight(0.); - if (j == GetMipIndex()) continue; // do not consider MIP cluster as a candidate photon -// if(((AliRICHCluster*)fpClusters->UncheckedAt(j))->Q()>AliRICHParam::QthMIP()) continue; // avoid MIP clusters from bkg - Float_t xtoentr = ((AliRICHCluster*)fpClusters->UncheckedAt(j))->X() - GetShiftX(); - Float_t ytoentr = ((AliRICHCluster*)fpClusters->UncheckedAt(j))->Y() - GetShiftY(); - SetEntranceX(xtoentr); - SetEntranceY(ytoentr); + AliRICHCluster *pClu=(AliRICHCluster*)fClusters->UncheckedAt(iClu); //get pointer to current cluster +// if(pClu->Q()>AliRICHParam::QthMIP()) continue; //avoid MIP clusters from bkg + SetEntranceX(pClu->X() - GetShiftX()); SetEntranceY(pClu->Y() - GetShiftY()); //cluster position with respect to track intersection FindPhiPoint(); -// Int_t photonStatus = PhotonInBand(); -// if(photonStatus == 0) continue; +// if(PhotonInBand()==0) continue; ???????????? SetPhotonFlag(1); FindThetaPhotonCerenkov(); Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov(); - AliDebug(1,Form("THETA CERENKOV ---> %f",thetaPhotonCerenkov)); + AliDebug(1,Form("Track Theta=%5.2f deg, Phi=%5.2f deg Photon clus=%2i ThetaCkov=%5.2f rad",GetTrackTheta()*TMath::RadToDeg(),GetTrackPhi()*TMath::RadToDeg() + ,iClu,thetaPhotonCerenkov )); SetPhotonEta(thetaPhotonCerenkov); - candidatePhotons++; }//clusters loop - if(candidatePhotons >= 1) kPatRec = kTRUE; - - if(!kPatRec) return -1; + SetPhotonsNumber(fClusters->GetEntries()); - SetPhotonsNumber(fpClusters->GetEntries()); + if((iMipId=FlagPhotons(HoughResponse()))<1) return -11; //flag photons according to individual theta ckov with respect to most probable track theta ckov - HoughResponse(); - - fNrings++; - - FlagPhotons(); - Int_t nPhotonHough = GetHoughPhotons(); - - if(nPhotonHough < 1) - { - SetThetaCerenkov(-1); - SetHoughPhotonsNorm(0); - return -1; - } - FindThetaCerenkov(); - - AliDebug(1,Form("Number of clusters accepted ---> %i",nPhotonHough)); - // Float_t thetaCerenkov = GetThetaCerenkov(); // SetThetaOfRing(thetaCerenkov); // FindAreaAndPortionOfRing(); @@ -148,35 +109,14 @@ Double_t AliRICHRecon::ThetaCerenkov() SetHoughArea(houghArea); */ + FindThetaCerenkov(); return GetThetaCerenkov(); - }//ThetaCerenkov() //__________________________________________________________________________________________________ -void AliRICHRecon::FindEmissionPoint() -{ - //estimate the emission point in radiator - -// Find emission point - - Float_t absorbtionLenght=7.83*fRadiatorWidth; //absorption length in the freon (cm) - // 7.83 = -1/ln(T0) where - // T0->Trasmission freon at 180nm = 0.88 (Eph=6.85eV) - Float_t photonLenght, photonLenghtMin, photonLenghtMax; - - photonLenght=exp(-fRadiatorWidth/(absorbtionLenght*cos(fCerenkovAnglePad))); - photonLenghtMin=fRadiatorWidth*photonLenght/(1.-photonLenght); - photonLenghtMax=absorbtionLenght*cos(fCerenkovAnglePad); - Float_t emissionPoint = fRadiatorWidth + photonLenghtMin - photonLenghtMax; - - SetEmissionPoint(emissionPoint); - SetEmissionPoint(fRadiatorWidth/2); // tune the emission point -} -//__________________________________________________________________________________________________ Int_t AliRICHRecon::PhotonInBand() { - //search band fro photon candidates +// Define valid band for photon candidates. For that photons with ThetaMin and ThetaMax are traced up to photcathode - // Float_t massOfParticle; Float_t nfreon; Float_t thetacer; @@ -191,19 +131,16 @@ Int_t AliRICHRecon::PhotonInBand() // inner radius // - SetPhotonEnergy(5.6); - SetEmissionPoint(fRadiatorWidth -0.0001); - SetFreonRefractiveIndex(); + SetEmissionPoint(AliRICHParam::RadThick() -0.0001); - nfreon = GetFreonRefractiveIndex(); + nfreon = fParam->IdxC6F14(fParam->EckovMin()); thetacer = 0.; AliDebug(1,Form("thetacer in photoninband min %f",thetacer)); FindThetaAtQuartz(thetacer); - if(thetacer == 999. || GetThetaAtQuartz() == 999.) - { + if(thetacer == 999. || GetThetaAtQuartz() == 999.) { innerRadius = -999.; SetXInnerRing(-999.); SetYInnerRing(-999.); @@ -223,12 +160,10 @@ Int_t AliRICHRecon::PhotonInBand() } // outer radius // - SetPhotonEnergy(7.7); SetEmissionPoint(0.); // SetMassHypotesis(0.139567); - SetFreonRefractiveIndex(); - nfreon = GetFreonRefractiveIndex(); + nfreon = fParam->IdxC6F14(fParam->EckovMax()); thetacer = Cerenkovangle(nfreon,1); @@ -263,24 +198,19 @@ Int_t AliRICHRecon::PhotonInBand() if(padradius>=innerRadius && padradius<=outerRadius) return 1; return 0; -} +}//PhotonInBand() //__________________________________________________________________________________________________ void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov) { - //find the theta at the quartz plate +// find the theta at the quartz plate - if(thetaCerenkov == 999.) - { - SetThetaAtQuartz(999.); - return; - } + if(thetaCerenkov == 999.) { SetThetaAtQuartz(999.); return; } Float_t thetaAtQuartz = 999.; Float_t trackTheta = GetTrackTheta(); if(trackTheta == 0) { - thetaAtQuartz = thetaCerenkov; SetThetaAtQuartz(thetaAtQuartz); return; @@ -289,12 +219,8 @@ void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov) Float_t trackPhi = GetTrackPhi(); Float_t phiPoint = GetPhiPoint(); - Double_t den = TMath::Sin((Double_t)trackTheta) - *TMath::Cos((Double_t)trackPhi) - *TMath::Cos((Double_t)phiPoint) + - TMath::Sin((Double_t)trackTheta) - *TMath::Sin((Double_t)trackPhi) - *TMath::Sin((Double_t)phiPoint); + Double_t den = TMath::Sin((Double_t)trackTheta)*TMath::Cos((Double_t)trackPhi)*TMath::Cos((Double_t)phiPoint) + + TMath::Sin((Double_t)trackTheta)*TMath::Sin((Double_t)trackPhi)*TMath::Sin((Double_t)phiPoint); Double_t b = TMath::Cos((Double_t)trackTheta)/den; Double_t c = -TMath::Cos((Double_t)thetaCerenkov)/den; @@ -335,8 +261,7 @@ void AliRICHRecon::FindThetaPhotonCerenkov() Float_t phiPoint = GetPhiPoint(); - SetPhotonEnergy(AliRICHParam::MeanCkovEnergy()); - SetEmissionPoint(fRadiatorWidth/2); + SetEmissionPoint(AliRICHParam::RadThick()/2); Float_t xPoint = GetEntranceX(); Float_t yPoint = GetEntranceY(); @@ -449,10 +374,8 @@ void AliRICHRecon::FindAreaAndPortionOfRing() Float_t y0 = yemiss + shiftY; - SetPhotonEnergy(AliRICHParam::MeanCkovEnergy()); - SetFreonRefractiveIndex(); - SetEmissionPoint(fRadiatorWidth/2.); + SetEmissionPoint(AliRICHParam::RadThick()/2.); Float_t theta = GetThetaOfRing(); @@ -460,9 +383,7 @@ void AliRICHRecon::FindAreaAndPortionOfRing() Int_t nPsiAccepted = 0; Int_t nPsiTotal = 0; - for(Int_t i=0;i %d",zone)); - if (zone != 0) - { - FindIntersectionWithDetector(); - xPoint[nPoints] = GetIntersectionX(); - yPoint[nPoints] = GetIntersectionY(); - } - else - { - xPoint[nPoints] = xPointRing; - yPoint[nPoints] = yPointRing; - nPsiAccepted++; - } - + if (zone != 0){ + FindIntersectionWithDetector(); + xPoint[nPoints] = GetIntersectionX(); yPoint[nPoints] = GetIntersectionY(); + }else{ + xPoint[nPoints] = xPointRing; yPoint[nPoints] = yPointRing; + nPsiAccepted++; + } nPoints++; + } - } - - xPoint[nPoints] = xPoint[0]; - yPoint[nPoints] = yPoint[0]; + xPoint[nPoints] = xPoint[0]; yPoint[nPoints] = yPoint[0]; // find area... @@ -522,7 +435,7 @@ void AliRICHRecon::FindAreaAndPortionOfRing() SetAreaOfRing(area); SetPortionOfRing(portionOfRing); -} +}//FindAreaAndPortionOfRing() //__________________________________________________________________________________________________ void AliRICHRecon::FindIntersectionWithDetector() { @@ -567,45 +480,43 @@ void AliRICHRecon::FindIntersectionWithDetector() y1 = yPoint; } // - xIntersect = fXmax; + xIntersect = AliRICHParam::PcSizeX(); yIntersect = m*(xIntersect - x0) + y0; - if (yIntersect >= fYmin && yIntersect <= fYmax && xIntersect >= x1 && xIntersect <= x2) + if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2) { SetIntersectionX(xIntersect); SetIntersectionY(yIntersect); return; } // - xIntersect = fXmin; + xIntersect = 0; yIntersect = m*(xIntersect - x0) + y0; - if (yIntersect >= fYmin && yIntersect <= fYmax && xIntersect >= x1 && xIntersect <= x2) + if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2) { SetIntersectionX(xIntersect); SetIntersectionY(yIntersect); return; } // - yIntersect = fYmax; + yIntersect = AliRICHParam::PcSizeY(); xIntersect = (yIntersect - y0)/m + x0; - if (xIntersect >= fXmin && xIntersect <= fXmax && yIntersect >= y1 && yIntersect <= y2) + if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2) { SetIntersectionX(xIntersect); SetIntersectionY(yIntersect); return; } // - yIntersect = fYmin; + yIntersect = 0; xIntersect = (yIntersect - y0)/m + x0; - if (xIntersect >= fXmin && xIntersect <= fXmax && yIntersect >= y1 && yIntersect <= y2) + if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2) { SetIntersectionX(xIntersect); SetIntersectionY(yIntersect); return; } - - cout << " sono fuori!!!!!!" << endl; - } + //__________________________________________________________________________________________________ Int_t AliRICHRecon::CheckDetectorAcceptance() const { @@ -617,23 +528,23 @@ Int_t AliRICHRecon::CheckDetectorAcceptance() const Float_t xcoord = GetDetectorWhereX(); Float_t ycoord = GetDetectorWhereY(); - if(xcoord > fXmax) + if(xcoord > AliRICHParam::PcSizeX()) { - if(ycoord > fYmax) return 2; - if(ycoord > fYmin && ycoord < fYmax) return 3; - if(ycoord < fYmin) return 4; + if(ycoord > AliRICHParam::PcSizeY()) return 2; + if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 3; + if(ycoord < 0) return 4; } - if(xcoord < fXmin) + if(xcoord < 0) { - if(ycoord > fYmax) return 8; - if(ycoord > fYmin && ycoord < fYmax) return 7; - if(ycoord < fYmin) return 6; + if(ycoord > AliRICHParam::PcSizeY()) return 8; + if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 7; + if(ycoord < 0) return 6; } - if(xcoord > fXmin && xcoord < fXmax) + if(xcoord > 0 && xcoord < AliRICHParam::PcSizeX()) { - if(ycoord > fYmax) return 1; - if(ycoord > fYmin && ycoord < fYmax) return 0; - if(ycoord < fYmin) return 5; + if(ycoord > AliRICHParam::PcSizeY()) return 1; + if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 0; + if(ycoord < 0) return 5; } return 999; } @@ -673,17 +584,16 @@ void AliRICHRecon::FindPhotonAnglesInDRS() //__________________________________________________________________________________________________ Float_t AliRICHRecon::FromEmissionToCathode() { - // trace from emission point to cathode +// Trace current photon from emission point somewhere in radiator to photocathode +// Arguments: none +// Returns: Float_t nfreon, nquartz, ngas; - SetFreonRefractiveIndex(); - SetQuartzRefractiveIndex(); - SetGasRefractiveIndex(); - nfreon = GetFreonRefractiveIndex(); - nquartz = GetQuartzRefractiveIndex(); - ngas = GetGasRefractiveIndex(); + nfreon = fParam->IdxC6F14(fParam->EckovMean()); + nquartz = fParam->IdxSiO2(fParam->EckovMean()); + ngas = fParam->IdxCH4(fParam->EckovMean()); Float_t trackTheta = GetTrackTheta(); Float_t trackPhi = GetTrackPhi(); @@ -692,8 +602,6 @@ Float_t AliRICHRecon::FromEmissionToCathode() Float_t theta = GetThetaPhotonInDRS(); Float_t phi = GetPhiPhotonInDRS(); -// cout << " Theta " << Theta << " Phi " << Phi << endl; - Float_t xemiss = lengthOfEmissionPoint*tan(trackTheta)*cos(trackPhi); Float_t yemiss = lengthOfEmissionPoint*tan(trackTheta)*sin(trackPhi); @@ -718,12 +626,12 @@ Float_t AliRICHRecon::FromEmissionToCathode() return thetagap; } - Float_t xw = (fRadiatorWidth - lengthOfEmissionPoint)*cos(phi)*tan(theta); - Float_t xq = fQuartzWidth*cos(phi)*tan(thetaquar); - Float_t xg = fGapWidth*cos(phi)*tan(thetagap); - Float_t yw = (fRadiatorWidth - lengthOfEmissionPoint)*sin(phi)*tan(theta); - Float_t yq = fQuartzWidth*sin(phi)*tan(thetaquar); - Float_t yg = fGapWidth*sin(phi)*tan(thetagap); + Float_t xw = (AliRICHParam::RadThick() - lengthOfEmissionPoint)*cos(phi)*tan(theta); + Float_t xq = AliRICHParam::WinThick()*cos(phi)*tan(thetaquar); + Float_t xg = AliRICHParam::Pc2Win()*cos(phi)*tan(thetagap); + Float_t yw = (AliRICHParam::RadThick() - lengthOfEmissionPoint)*sin(phi)*tan(theta); + Float_t yq = AliRICHParam::WinThick()*sin(phi)*tan(thetaquar); + Float_t yg = AliRICHParam::Pc2Win()*sin(phi)*tan(thetagap); Float_t xtot = xemiss + xw + xq + xg; @@ -733,8 +641,7 @@ Float_t AliRICHRecon::FromEmissionToCathode() SetYPointOnCathode(ytot); - Float_t distanceFromEntrance = sqrt(TMath::Power(fPhotonLimitX,2) - +TMath::Power(fPhotonLimitY,2)); + Float_t distanceFromEntrance = TMath::Sqrt(TMath::Power(fPhotonLimitX,2)+TMath::Power(fPhotonLimitY,2)); return distanceFromEntrance; @@ -799,17 +706,19 @@ Float_t AliRICHRecon::SnellAngle(Float_t n1, Float_t n2, Float_t theta1) return refractangle; } //__________________________________________________________________________________________________ -void AliRICHRecon::HoughResponse() +Double_t AliRICHRecon::HoughResponse() { +// +// +// Int_t nChannels = (Int_t)(fThetaMax/fDTheta+0.5); - TH1F *phots = new TH1F("phots","phots",nChannels,0.,fThetaMax); - TH1F *photsw = new TH1F("photsw","photsw",nChannels,0.,fThetaMax); - TH1F *resultw = new TH1F("resultw","resultw",nChannels,0.,fThetaMax); - Int_t nPhotons = GetPhotonsNumber(); + TH1F *phots = new TH1F("phots" ,"phots" ,nChannels,0,fThetaMax); + TH1F *photsw = new TH1F("photsw" ,"photsw" ,nChannels,0,fThetaMax); + TH1F *resultw = new TH1F("resultw","resultw",nChannels,0,fThetaMax); Int_t nBin = (Int_t)(fThetaMax/fDTheta); Int_t nCorrBand = (Int_t)(fWindowWidth/(2*fDTheta)); AliDebug(1,Form("Ring reconstruction for track with theta %f",GetTrackTheta()*TMath::RadToDeg())); - for (Int_t kPhot=0; kPhot< nPhotons; kPhot++){ + for (Int_t kPhot=0; kPhot< GetPhotonsNumber(); kPhot++){ SetPhotonIndex(kPhot); Double_t angle = GetPhotonEta(); if(angle<0||angle>fThetaMax) continue; @@ -842,14 +751,13 @@ void AliRICHRecon::HoughResponse() if(sumPhotsIntegral(bin1,bin2); resultw->Fill((Float_t)((i+0.5)*fDTheta),sumPhotsw); -} -// evaluate the "BEST" thetacerenkov.... + } +// evaluate the "BEST" theta ckov as the maximum value of histogramm Float_t *pVec = resultw->GetArray(); Int_t locMax = TMath::LocMax(nBin,pVec); - SetThetaCerenkov((Double_t)(locMax*fDTheta+0.5*fDTheta)); - -// Reset and delete objects - phots->Delete();photsw->Delete();resultw->Delete(); + phots->Delete();photsw->Delete();resultw->Delete(); // Reset and delete objects + + return (Double_t)(locMax*fDTheta+0.5*fDTheta); //final most probable track theta ckov }//HoughResponse //__________________________________________________________________________________________________ void AliRICHRecon::FindThetaCerenkov() @@ -859,22 +767,18 @@ void AliRICHRecon::FindThetaCerenkov() Float_t wei = 0.; Float_t weightThetaCerenkov = 0.; - Int_t nPhotons = GetPhotonsNumber(); Double_t etaMin=9999.,etaMax=0.; - for(Int_t i=0;ietaMax) etaMax=photonEta; - Float_t photonWeight = GetPhotonWeight(); - weightThetaCerenkov += photonEta*photonWeight; - wei += photonWeight; - } - } + for(Int_t i=0;ietaMax) etaMax=photonEta; + Float_t photonWeight = GetPhotonWeight(); + weightThetaCerenkov += photonEta*photonWeight; + wei += photonWeight; + } + } if(wei != 0.) weightThetaCerenkov /= wei; else weightThetaCerenkov = 0.; SetThetaCerenkov(weightThetaCerenkov); @@ -884,57 +788,33 @@ void AliRICHRecon::FindThetaCerenkov() SetThetaOfRing(etaMax); FindAreaAndPortionOfRing(); Double_t externalArea = GetAreaOfRing(); Double_t effArea = (AliRICHParam::PcSizeX()-AliRICHParam::DeadZone())*(AliRICHParam::PcSizeY()-2*AliRICHParam::DeadZone()); - Double_t nPhotBKG = (externalArea-internalArea)/effArea*fpClusters->GetEntries(); + Double_t nPhotBKG = (externalArea-internalArea)/effArea*fClusters->GetEntries(); if(nPhotBKG<0) nPhotBKG=0; //just protection from funny angles... SetPhotBKG(nPhotBKG); // AliDebug(1,Form(" thetac weighted -> %f",weightThetaCerenkov)); } -//__________________________________________________________________________________________________ -void AliRICHRecon::FlagPhotons() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliRICHRecon::FlagPhotons(Double_t thetaCkovHough) { - // flag photons +// flag photon candidates if their individual theta ckov inside the window around theta ckov of Hough transform +// Arguments: thetaCkovHough- value of most probable theta ckov for track as returned by HoughResponse() +// Returns: number of photon candidates happened to be inside the window - Int_t nPhotonHough = 0; - - Float_t thetaCerenkov = GetThetaCerenkov(); - AliDebug(1,Form(" fThetaCerenkov %f ",thetaCerenkov)); - - Float_t thetaDist= thetaCerenkov - fThetaMin; - Int_t steps = (Int_t)(thetaDist / fDTheta); + Int_t steps = (Int_t)((thetaCkovHough - fThetaMin)/ fDTheta); //how many times we need to have fDTheta to fill the distance betwee fThetaMin and thetaCkovHough Float_t tmin = fThetaMin + (Float_t)(steps - 1)*fDTheta; Float_t tmax = fThetaMin + (Float_t)(steps)*fDTheta; Float_t tavg = 0.5*(tmin+tmax); - tmin = tavg - 0.5*fWindowWidth; - tmax = tavg + 0.5*fWindowWidth; - - // Int_t candidatePhotonsNumber = GetCandidatePhotonsNumber(); - - Int_t nPhotons = GetPhotonsNumber(); - - // for(Int_t i=0;iFindObjectAny("h1_phots"); - -// cout << "h1_phots " << h1_phots << endl; - - for(Int_t i=0;i= tmin && photonEta <= tmax) - { - SetPhotonFlag(2); - nPhotonHough++; -// if(h1_phots)h1_phots->Fill(photonEta); - } - } - SetHoughPhotons(nPhotonHough); -} + Int_t iInsideCnt = 0; //count photons which theta inside prdefined window + for(Int_t i=0;i= tmin && photonEta <= tmax) { SetPhotonFlag(2); iInsideCnt++;} + } + return iInsideCnt; +}//FlagPhotons diff --git a/RICH/AliRICHRecon.h b/RICH/AliRICHRecon.h index d4025402c22..50048cbfebe 100644 --- a/RICH/AliRICHRecon.h +++ b/RICH/AliRICHRecon.h @@ -13,25 +13,25 @@ ////////////////////////////////////////////////////////////////////////// -#include +#include //base class class AliRICHHelix; - +class AliRICHParam; +class TClonesArray; class AliRICHRecon : public TTask { public : - AliRICHRecon(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t iMipId); - virtual ~AliRICHRecon(){;} + AliRICHRecon(); + virtual ~AliRICHRecon() {} - Double_t ThetaCerenkov(); // it returns reconstructed Theta Cerenkov + Double_t ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pCluLst,Int_t &iMipId); // it returns reconstructed Theta Cerenkov void FindThetaPhotonCerenkov(); // void FindAreaAndPortionOfRing(); // - void FindEmissionPoint(); // void FindPhotonAnglesInDRS(); // void FindPhiPoint(); // void FindThetaAtQuartz(Float_t ThetaCer); // - void HoughResponse(); // - void FlagPhotons(); // + Double_t HoughResponse ( ); //most probable track theta ckov out of all photon candidate thetas + Int_t FlagPhotons (Double_t theta); //n. of photon candidates which thetas are inside a window around most probable track theta ckov void FindThetaCerenkov(); // void FindIntersectionWithDetector(); // Float_t Cerenkovangle(Float_t n, Float_t b);// @@ -39,17 +39,9 @@ public : Int_t CheckDetectorAcceptance() const; // Int_t GetFittedHoughPhotons() const{ return fFittedHoughPhotons;} // Int_t GetPhotonFlag() const{ return fPhotonFlag[fPhotonIndex];} // - Int_t GetTrackCharge() const{ return fTrackCharge;} // Int_t GetPhotonsNumber() const{ return fPhotonsNumber;} // Int_t GetPhotonIndex() const{ return fPhotonIndex;} // - Int_t GetMipIndex() const{ return fMipIndex;} // - Int_t GetTrackIndex() const{ return fTrackIndex;} // - Int_t GetCandidatePhotonsNumber() const{ return fCandidatePhotonsNumber;} // - Int_t GetHoughPhotons() const{ return fHoughPhotons;} // - Float_t GetPhotonEnergy() const{ return fPhotonEnergy;} // - Float_t GetFreonRefractiveIndex() const{ return fFreonRefractiveIndex;} // - Float_t GetQuartzRefractiveIndex() const{ return fQuartzRefractiveIndex;} // - Float_t GetGasRefractiveIndex() const{ return fGasRefractiveIndex;} // + Float_t GetPhotonEnergy() const{ return fEphot;} // Float_t GetEmissionPoint() const{ return fLengthEmissionPoint;} // Float_t GetMassHypotesis() const{ return fMassHypotesis;} // Float_t GetBetaOfParticle() const{ return fTrackBeta;} // @@ -92,11 +84,7 @@ public : Float_t GetFittedTrackTheta() const{ return fFittedTrackTheta;} // Float_t GetFittedTrackPhi() const{ return fFittedTrackPhi;} // Float_t GetFittedThetaCerenkov() const{ return fFittedThetaCerenkov;} // - void SetPhotonEnergy(Float_t PhotonEnergy) { fPhotonEnergy = PhotonEnergy;} // - void SetFreonRefractiveIndex() {fFreonRefractiveIndex = fFreonScaleFactor*(1.177+0.0172*fPhotonEnergy);}// - void SetQuartzRefractiveIndex() {fQuartzRefractiveIndex = sqrt(1+(46.411/(113.763556-TMath::Power(fPhotonEnergy,2)))+(228.71/(328.51563-TMath::Power(fPhotonEnergy,2))));}// - void SetGasRefractiveIndex() { fGasRefractiveIndex = 1.;} // - void SetFreonScaleFactor(Float_t FreonScaleFactor) {fFreonScaleFactor = FreonScaleFactor;} // + void SetPhotonEnergy(Float_t e) { fEphot = e;} // void SetEmissionPoint(Float_t LengthEmissionPoint) { fLengthEmissionPoint = LengthEmissionPoint;} // void SetEntranceX(Float_t Xtoentr) { fXtoentr = Xtoentr;} // void SetEntranceY(Float_t Ytoentr) { fYtoentr = Ytoentr;} // @@ -120,7 +108,6 @@ public : void SetThetaPhotonCerenkov(Float_t ThetaPhotCer) {fThetaPhotonCerenkov = ThetaPhotCer;} // void SetTrackTheta(Float_t TrackTheta) { fTrackTheta = TrackTheta;} // void SetTrackPhi(Float_t TrackPhi) { fTrackPhi = TrackPhi;} // - void SetTrackCharge(Int_t TrackCharge) { fTrackCharge = TrackCharge;} // void SetShiftX(Float_t ShiftX) { fShiftX = ShiftX;} // void SetShiftY(Float_t ShiftY) { fShiftY = ShiftY;} // void SetDetectorWhereX(Float_t Xcoord) { fXcoord = Xcoord;} // @@ -138,28 +125,19 @@ public : void SetPhotonWeight(Float_t PhotonWeight) { fPhotonWeight[fPhotonIndex] = PhotonWeight;} // void SetPhotBKG(Double_t nPhotBKG) {fnPhotBKG=nPhotBKG;} // void SetHoughRMS(Float_t HoughRMS) { fHoughRMS = HoughRMS;} // - void SetMipIndex(Int_t MipIndex) { fMipIndex = MipIndex;} // - void SetTrackIndex(Int_t TrackIndex) { fTrackIndex = TrackIndex;} // - void SetHoughPhotons(Int_t HoughPhotons) { fHoughPhotons = HoughPhotons;} // - void SetHoughPhotonsNorm(Float_t HoughPhotonsNorm) { fHoughPhotonsNorm = HoughPhotonsNorm;} // void SetFittedTrackTheta(Float_t FittedTrackTheta) { fFittedTrackTheta = FittedTrackTheta;} // void SetFittedTrackPhi(Float_t FittedTrackPhi) { fFittedTrackPhi = FittedTrackPhi;} // void SetFittedThetaCerenkov(Float_t FittedThetaCerenkov) { fFittedThetaCerenkov = FittedThetaCerenkov;}// void SetFittedHoughPhotons(Int_t FittedHoughPhotons) { fFittedHoughPhotons = FittedHoughPhotons;} // - void FindBetaFromTheta(Float_t ThetaCerenkov) {fTrackBeta = 1/(fFreonRefractiveIndex*cos(ThetaCerenkov));}// Float_t SnellAngle(Float_t n1, Float_t n2, Float_t theta1); // Float_t FromEmissionToCathode(); // protected: - TClonesArray *fpClusters; // poiter to clusters - Int_t fTrackCharge; // charge track - Int_t fMipIndex; // index for Mip - Int_t fTrackIndex; // index for track + TClonesArray *fClusters; //tmp pointer to list of clusters + AliRICHParam *fParam; //tmp pointer to AliRICHParam instance containing all the parameters needed for proccessing Int_t fPhotonsNumber; // Number of photons candidate Int_t fPhotonIndex; // index of photons Int_t fPhotonFlag[3000]; // flag for photons - Int_t fCandidatePhotonsNumber; // number of candidate photons - Int_t fHoughPhotons; // n. photons after Hough Int_t fFittedHoughPhotons; // n. photons after Hough and after minimization Int_t fMinNumPhots; // minimum number of photons for a given ring @@ -183,11 +161,7 @@ protected: Float_t fYOuter; // Y outer ring Float_t fInnerRadius; // inner radius Float_t fOuterRadius; // outer radius - Float_t fPhotonEnergy; // photon energy - Float_t fFreonRefractiveIndex; // n freon - Float_t fQuartzRefractiveIndex; // n quartz - Float_t fGasRefractiveIndex; // n gas - Float_t fFreonScaleFactor; // scale factor for n freon + Float_t fEphot; // photon energy Float_t fLengthEmissionPoint; // lenght of emmission point Float_t fPhotonLimitX; // X phys limit for photon Float_t fPhotonLimitY; // Y phys limit for photon @@ -210,18 +184,12 @@ protected: Float_t fHoughRMS; // rms Hough Float_t* fCandidatePhotonX; // x photon candidates Float_t* fCandidatePhotonY; // y photon candidates - Float_t fHoughPhotonsNorm; // n. photons norm. Float_t fFittedTrackTheta; // theta track after minim. Float_t fFittedTrackPhi; // phi track after minim. Float_t fFittedThetaCerenkov; // thetacerenkov after minim. Float_t fThetaMin,fThetaMax; // min max - Float_t fXmin,fXmax,fYmin,fYmax; // xy min max - Int_t fNrings; //current number of reconstructed rings Bool_t fIsWEIGHT; // flag to consider weight procedure Bool_t fIsBACKGROUND; // flag to simulate bkg - Float_t fRadiatorWidth; // radiator width - Float_t fQuartzWidth; // quartz width - Float_t fGapWidth; // gap width Float_t fDTheta; // Step for sliding window Float_t fWindowWidth; // Hough width of sliding window @@ -234,7 +202,6 @@ protected: Float_t fWeightThetaCerenkov; // Theta Cerenkov angle weighted Float_t fThetaPeakPos; // Peak position - ClassDef(AliRICHRecon,0) }; diff --git a/RICH/AliRICHReconstructor.cxx b/RICH/AliRICHReconstructor.cxx index f5198be08da..eef4594cb19 100644 --- a/RICH/AliRICHReconstructor.cxx +++ b/RICH/AliRICHReconstructor.cxx @@ -17,13 +17,165 @@ #include "AliRICH.h" //Reconstruct(...) #include //Reconstruct(...) #include //ConvertDigits uses gAlice -#include //RichAna() -#include //RichAna() -#include //RichAna() -#include //Dig2Clu() -#include //TParticle() +#include //RichAna() +#include //RichAna() +#include //RichAna() +#include //RichAna() +#include //RichAna() +#include //CluQA() +#include //CluQA() +#include //CluQA() +#include //CheckPR() ClassImp(AliRICHReconstructor) +//__________________________________________________________________________________________________ +void AliRICHReconstructor::CluQA(AliRunLoader *pAL) +{ +// Quality assesment plots for clusters. +// This methode takes list of digits and form list of clusters again in order to +// calculate cluster shape and cluster particle mixture + AliLoader *pRL=pAL->GetDetectorLoader("RICH"); AliRICH *pRich=(AliRICH*)pAL->GetAliRun()->GetDetector("RICH");//get pointers for RICH and RICH loader + Int_t iNevt=pAL->GetNumberOfEvents(); if(iNevt==0) {AliInfoClass("No events");return;} + if(pRL->LoadDigits()) {AliInfoClass("No digits file");return;} + pAL->LoadHeader(); + pAL->LoadKinematics(); +// AliStack *pStack=pAL->Stack(); + TH1::AddDirectory(kFALSE); + + TH1F *pN =new TH1F("RichCluPerEvt" ,"Number of clusters per event;number" ,100 ,0 ,99 ); + TH1F* pQ =new TH1F("RichCluQdc" ,"Cluster QDC;q [QDC]" ,4000 ,0 ,4000 ); + TH1F* pS =new TH1F("RichCluSize" ,"Cluster size;size" ,100 ,0 ,100 ); + TH2F* pM =new TH2F("RichCluMap" ,"Cluster map;x [cm];y [cm]" ,1000 ,0 ,AliRICHParam::PcSizeX() ,1000,0,AliRICHParam::PcSizeY() ); + + TH1F* pMipQ=new TH1F("RichCluMipQdc" ,"MIP QDC;q [QDC]" ,4000 ,0 ,4000 ); + TH1F* pMipS=new TH1F("RichCluMipSize" ,"MIP size;size" ,100 ,0 ,100 ); + TH2F* pMipM=new TH2F("RichCluMipMap" ,"MIP map;x [cm];y [cm]" ,1000 ,0 ,AliRICHParam::PcSizeX() ,1000,0,AliRICHParam::PcSizeY() ); + + TH1F* pCerQ=new TH1F("RichCluCerQdc" ,"Ckov QDC;q [QDC]" ,4000 ,0 ,4000 ); + TH1F* pCerS=new TH1F("RichCluCerSize" ,"Ckov size;size" ,100 ,0 ,100 ); + TH2F* pCerM=new TH2F("RichCluCerMap" ,"Ckov map;x [cm];y [cm]" ,1000 ,0 ,AliRICHParam::PcSizeX() ,1000,0,AliRICHParam::PcSizeY() ); + + TH1F* pFeeQ=new TH1F("RichCluFeeQdc" ,"Fee QDC;q [QDC]" ,4000 ,0 ,4000); + TH1F* pFeeS=new TH1F("RichCluFeeSize" ,"Fee size;size" ,100 ,0 ,100 ); + TH2F* pFeeM=new TH2F("RichCluFeeMap" ,"Fee map;x [cm];y [cm]" ,1000 ,0 ,AliRICHParam::PcSizeX() ,1000,0,AliRICHParam::PcSizeY() ); + + + TClonesArray *pCluLst=new TClonesArray("AliRICHCluster");//tmp list of clusters + + for(Int_t iEvtN=0; iEvtNGetEvent(iEvtN); + pRL->TreeD()->GetEntry(0); + for(Int_t iChN=1;iChN<=7;iChN++){//chambers loop + if(pRich->Digs(iChN)->GetEntriesFast()>0) Dig2Clu(pRich->Digs(iChN),pCluLst,kFALSE);//cluster finder for the current chamber if any digits present + }//chambers loop + + pCluLst->Print(); + for(Int_t iCluN=0 ; iCluN < pCluLst->GetEntriesFast() ; iCluN++){ + AliRICHCluster *pClu = (AliRICHCluster*)pCluLst->At(iCluN); + Int_t iNckov=0,iNfee=0,iNmip=0; + pQ ->Fill(pClu->Q()) ; pS ->Fill(pClu->Size()) ; pM ->Fill(pClu->X(),pClu->Y()); //all clusters + if(iNckov!=0 && iNfee==0 && iNmip==0) {pCerQ->Fill(pClu->Q()) ; pCerS->Fill(pClu->Size()) ; pCerM ->Fill(pClu->X(),pClu->Y());}//ckov only cluster + if(iNckov==0 && iNfee!=0 && iNmip==0) {pFeeQ->Fill(pClu->Q()) ; pFeeS->Fill(pClu->Size()) ; pFeeM ->Fill(pClu->X(),pClu->Y());}//feed only cluster + if(iNckov==0 && iNfee==0 && iNmip!=0) {pMipQ->Fill(pClu->Q()) ; pMipS->Fill(pClu->Size()) ; pMipM ->Fill(pClu->X(),pClu->Y());}//mip only cluster + + }//clusters loop + }//events loop + + pRL->UnloadDigits(); pAL->UnloadKinematics(); pAL->UnloadHeader(); + TCanvas *pC=new TCanvas("RichCluQA",Form("QA for cluster from %i events",iNevt),1000,900); pC->Divide(3,3); + pC->cd(1); pN->Draw(); pC->cd(2); pQ->Draw(); pC->cd(3); pS->Draw(); + pC->cd(4); pN->Draw(); pC->cd(5); pMipQ->Draw(); pC->cd(6); pMipS->Draw(); + pC->cd(7); pN->Draw(); pC->cd(8); pCerQ->Draw(); pC->cd(9); pCerS->Draw(); +}//CluQA() +//__________________________________________________________________________________________________ +void AliRICHReconstructor::CheckPR() +{ +//Pattern recognition with stack particles + TFile *pFile = new TFile("$(HOME)/RPR.root","RECREATE","RICH Pattern Recognition"); + TNtupleD *hn = new TNtupleD("hn","ntuple","Pmod:Charge:TrackTheta:TrackPhi:TrackX:TrackY:MinX:MinY:ChargeMIP:ThetaCerenkov:NPhotons:MipIndex:Chamber:Particle"); +// printf("\n\n"); +// printf("Pattern Recognition done for event %5i",0); + AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH")); + AliMagF * magf = gAlice->Field(); + AliTracker::SetFieldMap(magf,kTRUE); + for(Int_t iEvtN=0;iEvtNGetLoader()->GetRunLoader()->GetNumberOfEvents();iEvtN++) { + pRich->GetLoader()->GetRunLoader()->GetEvent(iEvtN); + AliRICHTracker *tr = new AliRICHTracker(); + tr->RecWithStack(hn); + AliInfoClass(Form("Pattern Recognition done for event %i \b",iEvtN)); +// printf("\b\b\b\b\b%5i",iEvtN+1); + } + printf("\n\n"); + pFile->Write();pFile->Close(); +} +//__________________________________________________________________________________________________ +void AliRICHReconstructor::Dig2Clu(TClonesArray *pDigLst,TClonesArray *pCluLst,Bool_t isTryUnfold) +{ +//Finds all clusters for a given digits list provided not empty. Currently digits list is a list of all digits for a single chamber. +//If pStack not 0 then also finds Ckov-Fee-Mip composition for formed clusters. +//Puts all found clusters in the given clusters list. +//Arguments: pDigLst - list of digits provided not empty +// pCluLst - list of clusters, provided empty +// isTryUnfold - flag to choose between CoG and Mathieson fitting +// Returns: none + TMatrixF digMap(1,AliRICHParam::NpadsX(),1,AliRICHParam::NpadsY()); digMap=(Float_t)-1; //digit map for one chamber reseted to -1 + for(Int_t iDigN=0 ; iDigN < pDigLst->GetEntriesFast() ; iDigN++){ //digits loop to fill digits map + AliRICHDigit *pDig= (AliRICHDigit*)pDigLst->At(iDigN); //get current digit + digMap( pDig->PadX(), pDig->PadY() )=iDigN; //fill the map, (padx,pady) cell takes digit number + } //digits loop to fill digits map + + AliRICHCluster clu; //tmp cluster to be used as current + + for(Int_t iDigN=0;iDigNGetEntriesFast();iDigN++){ //digits loop to form clusters list + AliRICHDigit *pDig=(AliRICHDigit*)pDigLst->At(iDigN); //take current digit + if(!(pDig=UseDig(pDig->PadX(),pDig->PadY(),pDigLst,&digMap))) continue; //this digit is already taken in FormClu(), go after next digit + FormClu(&clu,pDig,pDigLst,&digMap); //form cluster starting from this digit by recursion + clu.Solve(pCluLst,isTryUnfold); //solve this cluster and add all unfolded clusters to provided list + clu.Reset(); //empty current cluster + } //digits loop to form clusters list +}//Dig2Clu() +//__________________________________________________________________________________________________ +void AliRICHReconstructor::FormClu(AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigLst,TMatrixF *pDigMap) +{ +//Forms the initial cluster as a sum of all adjascent digits. Starts from the given digit +//then calls itself recursevly for all neighbours. +//Arguments: pClu - pointer to cluster being formed +// Returns: none + pClu->DigAdd(pDig);//take this digit in cluster + + Int_t x[4],y[4]; + + Int_t iNnei=AliRICHParam::PadNeighbours(pDig->PadX(),pDig->PadY(),x,y);//returns in x,y all possible neighbours of the given padx,pady + for (Int_t i=0;iGetDetectorLoader("RICH"); AliRICH *pRich=(AliRICH*)pAL->GetAliRun()->GetDetector("RICH");//get pointers for RICH and RICH loader + pRL->LoadDigits(); + + for(Int_t iEvtN=0;iEvtNGetNumberOfEvents();iEvtN++){//events loop + pAL->GetEvent(iEvtN++); AliDebug(1,Form("Processing event %i...",iEvtN)); //switch current directory to next event + pRL->TreeD()->GetEntry(0); pRL->MakeTree("R"); pRich->MakeBranch("R"); //load digits to memory and create branches for clusters + for(Int_t iChN=1;iChN<=7;iChN++){//chambers loop + if(pRich->Digs(iChN)->GetEntriesFast()>0) Dig2Clu(pRich->Digs(iChN),pRich->Clus(iChN));//cluster finder for the current chamber if any digits present + }//chambers loop + pRL->TreeR()->Fill(); //fill tree for current event + pRL->WriteRecPoints("OVERWRITE");//write out clusters for current event + pRich->DigReset(); pRich->CluReset(); + }//events loop + + pRL->UnloadDigits(); + pRL->UnloadRecPoints(); + + AliDebug(1,"Stop."); +}//Reconstruct(for simulated digits) +//__________________________________________________________________________________________________ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const { //Invoked by AliReconstruction to convert raw digits from DDL files to clusters @@ -46,92 +198,20 @@ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const while(pRR->ReadNextInt(w32)){//raw records loop (in selected DDL files) UInt_t ddl=pRR->GetDDLID(); //returns 0,1,2 ... 13 dig.Raw2Dig(ddl,w32); - AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iChN,ddl,w32,dig.Chamber(),dig.Sector(),dig.PadX(),dig.PadY(),dig.Qdc())); + AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iChN,ddl,w32,dig.C(),dig.S(),dig.PadX(),dig.PadY(),dig.Qdc())); new((*pDigList)[iDigCnt++]) AliRICHDigit(dig); //add this digit to the tmp list }//raw records loop - if(iDigCnt) Dig2Clu(pDigList,pRich->Clusters(iChN));//cluster finder for the current chamber if any digits present + if(iDigCnt) Dig2Clu(pDigList,pRich->Clus(iChN));//cluster finder for the current chamber if any digits present pRR->Reset(); pDigList->Delete(); iDigCnt=0;//clean up list of digits for the current chamber }//chambers loop pRL->TreeR()->Fill(); //fill tree for current event pRL->WriteRecPoints("OVERWRITE");//write out clusters for current event - pRich->ClustersReset(); + pRich->CluReset(); }//events loop pRL->UnloadRecPoints(); }//Reconstruct raw data //__________________________________________________________________________________________________ -void AliRICHReconstructor::Dig2Clu(TClonesArray *pDigList,TClonesArray *pCluList)const -{ -//Finds all clusters for a given digits list provided not empty. Currently digits list provided is a list of all digits for a single chamber. -//Puts all found clusters in the given clusters list. -//Arguments: pDigList - list of digits provided not empty -// Returns: none - TMatrixF digMap(1,AliRICHParam::NpadsX(),1,AliRICHParam::NpadsY()); digMap=(Float_t)-1; //digit map for one chamber reseted to -1 - for(Int_t iDigN=0 ; iDigN < pDigList->GetEntriesFast() ; iDigN++){ //digits loop to fill digits map - AliRICHDigit *pDig= (AliRICHDigit*)pDigList->At(iDigN); - digMap( pDig->PadX(), pDig->PadY() )=iDigN; //(padx,pady) cell takes digit number - } - - AliRICHCluster clu; Int_t iCluCnt=0; //tmp cluster and cluster counter - - for(Int_t iDigN=0;iDigNGetEntriesFast();iDigN++){//digits loop - AliRICHDigit *pDig=(AliRICHDigit*)pDigList->At(iDigN); - if(!(pDig=UseDig(pDig->PadX(),pDig->PadY(),pDigList,&digMap))) continue; //this digit is already taken in FormCluster(), go after next digit - FormCluster(&clu,pDig,pDigList,&digMap); //form cluster starting from this digit - TMinuit *pMinuit=clu.Solve(); //solve this cluster - - if(pMinuit){//means cluster is solved into local maxima number of clusters, so add all of them in loop - Double_t x=-1,y=-1,q=-1;TString str; Double_t b1,b2,b3; Int_t iErrFlg;//tmp to withdraw resulting parameters - for(Int_t i=0;imnpout(3*i ,str, x, b1, b2, b3, iErrFlg); - pMinuit->mnpout(3*i+1,str, y, b1, b2, b3, iErrFlg); - pMinuit->mnpout(3*i+2,str, q, b1, b2, b3, iErrFlg); - clu.Set(x,y,(Int_t)q); - new((*pCluList)[iCluCnt++]) AliRICHCluster(clu); - } - delete pMinuit; - }else//means cluster is solved as simple center of gravity cluster, add it - new((*pCluList)[iCluCnt++]) AliRICHCluster(clu); - clu.Reset();//make current cluster empty - }//digits loop -}//Dig2Clu() -//__________________________________________________________________________________________________ -void AliRICHReconstructor::FormCluster(AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigList,TMatrixF *pDigMap)const -{ -//Forms the initial cluster as a sum of all adjascent digits. Starts from the given digit -//then calls itself recursevly for all neighbours. -//Arguments: pClu - pointer to cluster being formed -// Returns: none - pClu->AddDigit(pDig);//take this digit in cluster and mark it as taken - - Int_t x[4],y[4]; - - Int_t iNnei=AliRICHParam::PadNeighbours(pDig->PadX(),pDig->PadY(),x,y);//returns in x,y all possible neighbours of the given one - for (Int_t i=0;iGetDetector("RICH")); - AliMagF * magf = gAlice->Field(); - AliTracker::SetFieldMap(magf,kTRUE); - for(Int_t iEvtN=0;iEvtNGetLoader()->GetRunLoader()->GetNumberOfEvents();iEvtN++) { - pRich->GetLoader()->GetRunLoader()->GetEvent(iEvtN); - AliRICHTracker *tr = new AliRICHTracker(); - tr->RecWithStack(hn); - AliInfoClass(Form("Pattern Recognition done for event %i \b",iEvtN)); -// printf("\b\b\b\b\b%5i",iEvtN+1); - } - printf("\n\n"); - pFile->Write();pFile->Close(); -} -//__________________________________________________________________________________________________ void AliRICHReconstructor::RichAna(Int_t iNevMin,Int_t iNevMax,Bool_t askPatRec) { TFile *pFile=TFile::Open("AliESDs.root","read"); @@ -175,7 +255,7 @@ void AliRICHReconstructor::RichAna(Int_t iNevMin,Int_t iNevMax,Bool_t askPatRec) for(Int_t iTrackN=0;iTrackNRecWithESD(pESD,pRich,iTrackN); + if(askPatRec==kTRUE) pTrRich->PropagateBack(pESD); AliESDtrack *pTrack = pESD->GetTrack(iTrackN);// get next reconstructed track Int_t lab=TMath::Abs(pTrack->GetLabel()); @@ -205,13 +285,13 @@ void AliRICHReconstructor::RichAna(Int_t iNevMin,Int_t iNevMax,Bool_t askPatRec) hnvec[17]=pTrRich->fErrPar[4]; for(Int_t i=0;i<3;i++) { Double_t mass = AliRICHParam::fgMass[i+2]; - Double_t refIndex=AliRICHParam::RefIdxC6F14(AliRICHParam::MeanCkovEnergy()); + Double_t refIndex=AliRICHParam::Instance()->IdxC6F14(AliRICHParam::EckovMean()); Double_t cosThetaTh = TMath::Sqrt(mass*mass+pTrack->GetP()*pTrack->GetP())/(refIndex*pTrack->GetP()); hnvec[18+i]=0; if(cosThetaTh>=1) continue; hnvec[18+i]= TMath::ACos(cosThetaTh); } - if(askPatRec==kTRUE) hnvec[21]=pTrRich->fnPhotBKG; else hnvec[21]=0; +// if(askPatRec==kTRUE) hnvec[21]=pTrRich->fnPhotBKG; else hnvec[21]=0; hnvec[22]=code; hn->Fill(hnvec); } @@ -220,5 +300,32 @@ void AliRICHReconstructor::RichAna(Int_t iNevMin,Int_t iNevMax,Bool_t askPatRec) } pFileRA->Write();pFileRA->Close();// close RichAna.root delete pESD; pFile->Close();//close AliESDs.root -} +}//RichAna() +//__________________________________________________________________________________________________ +void AliRICHReconstructor::Test(Bool_t isTryUnfold) +{ +// Test the cluster finding algorithm by providing predifined set of digits +// Arguments: none +// Returns: none + TClonesArray *pDigTst=new TClonesArray("AliRICHDigit"); TClonesArray *pCluTst=new TClonesArray("AliRICHCluster"); + Int_t iDigCnt=0; + Int_t c,padx,pady,qdc; +//ckov cluster + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 89,pady=13,qdc= 10); + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 90,pady=13,qdc= 7); + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 90,pady=12,qdc= 6); + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 91,pady=12,qdc= 7); +//mip cluster + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 99,pady=21,qdc= 9); + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx= 99,pady=22,qdc= 26); + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx=100,pady=21,qdc= 39); + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx=100,pady=22,qdc=109); + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx=100,pady=23,qdc= 7); + new((*pDigTst)[iDigCnt++]) AliRICHDigit(c=1,padx=101,pady=22,qdc= 11); + + pDigTst->Print("","Initial digit:"); + Dig2Clu(pDigTst,pCluTst,isTryUnfold); + pCluTst->Print("","Solved cluster:"); + delete pDigTst; delete pCluTst; +}//Test() //__________________________________________________________________________________________________ diff --git a/RICH/AliRICHReconstructor.h b/RICH/AliRICHReconstructor.h index 608669b63d9..db8f9c3c5a1 100644 --- a/RICH/AliRICHReconstructor.h +++ b/RICH/AliRICHReconstructor.h @@ -5,10 +5,11 @@ #include //base class #include "AliRICHTracker.h" //CreateTracker() -#include "AliRICHClusterFinder.h" //Reconstruct() - -class AliRawReader; -class TTree; +#include //UseDig() +#include //UseDig() +class AliRawReader; //Reconstruct() with raw data +class AliRICHDigit; //Dig2Clu(), UseDig() +class AliRICHCluster; //Dig2Clu() class AliRICHReconstructor: public AliReconstructor { @@ -16,34 +17,33 @@ public: AliRICHReconstructor(): AliReconstructor() {}//default ctor virtual ~AliRICHReconstructor() {}//dtor //framework part - AliTracker* CreateTracker (AliRunLoader* )const{return new AliRICHTracker;} //interface from AliReconstructor - void Reconstruct (AliRunLoader* pAL )const{AliRICHClusterFinder cf(pAL); cf.Exec();}//from AliReconstruction for digits->clusters - void Reconstruct (AliRunLoader* pAL,AliRawReader *pRR)const; //from AliReconstruction for raw->clusters - using AliReconstructor::Reconstruct; //to get rid of virtual hidden warning + AliTracker* CreateTracker (AliRunLoader* )const{return new AliRICHTracker;} //from AliReconstructor for clusters->PID + void Reconstruct (AliRunLoader* pAL )const; //from AliReconstruction for digits->clusters + void Reconstruct (AliRunLoader* pAL,AliRawReader *pRR)const; //from AliReconstruction for raws->clusters + using AliReconstructor::Reconstruct; //to get rid of virtual hidden warning //private part - void Dig2Clu (TClonesArray*pDigList,TClonesArray *pCluList )const;//form clusters out of provided digits list - void FormCluster(AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigList,TMatrixF *pDigMap)const;//form cluster recursive algorithm - inline AliRICHDigit *UseDig (Int_t padX,Int_t padY,TClonesArray *pDigList,TMatrixF *pDigMap )const;//use this pad's digit to form a cluster - static void CheckPR ( ); //utility-> run staff for stack - static void RichAna (Int_t iNevMin=0, Int_t iNevMax=99999,Bool_t isPatRec=kFALSE ); //utility-> create ntuples for analysis - + static void Dig2Clu (TClonesArray*pDigLst,TClonesArray *pCluLst,Bool_t isTryUnfold=kTRUE );//digits list -> clusters list + static void CluQA (AliRunLoader* pAL );//QA for clusters + static void CheckPR ( );//utility-> run staff for stack + static void FormClu (AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigLst,TMatrixF *pDigMap);//cluster formation recursive algorithm + static inline AliRICHDigit* UseDig (Int_t padX,Int_t padY,TClonesArray *pDigList,TMatrixF *pDigMap );//use this pad's digit to form a cluster + static void RichAna (Int_t iNevMin=0,Int_t iNevMax=99999,Bool_t isPatRec=kFALSE );//utility-> create ntuples for analysis + static void Test (Bool_t isTryUnfold=kTRUE );//test digits->clusters conversion protected: ClassDef(AliRICHReconstructor, 0) //class for the RICH reconstruction }; //__________________________________________________________________________________________________ -AliRICHDigit* AliRICHReconstructor::UseDig(Int_t padX,Int_t padY,TClonesArray *pDigList,TMatrixF *pDigMap)const +AliRICHDigit* AliRICHReconstructor::UseDig(Int_t padX,Int_t padY,TClonesArray *pDigLst,TMatrixF *pDigMap) { //Digit map contains a matrix if digit numbers. //Main operation in forming initial cluster is done here. Requested digit pointer is returned and this digit marked as taken. //Arguments: padX,padY - pad number -// pDigList - list of digits for one sector +// pDigLst - list of digits for one sector // pDigMap - map of those digits // Returns: pointer to digit if not yet used or 0 if used Int_t iDig=(Int_t)(*pDigMap)(padX,padY);(*pDigMap)(padX,padY)=-1;//take digit number from the map and reset this map cell to -1 - if(iDig!=-1) - return (AliRICHDigit*)pDigList->At(iDig); //digit pointer - else - return 0; + if(iDig!=-1) return (AliRICHDigit*)pDigLst->At(iDig); //digit pointer + else return 0; } #endif diff --git a/RICH/AliRICHTracker.cxx b/RICH/AliRICHTracker.cxx index bdb1decc2ad..3370fb0b3d7 100644 --- a/RICH/AliRICHTracker.cxx +++ b/RICH/AliRICHTracker.cxx @@ -1,106 +1,98 @@ -#include "AliRICHTracker.h" +#include "AliRICHTracker.h" //class header +#include "AliRICH.h" +#include "AliRICHRecon.h" #include #include -#include -#include "AliRICH.h" +#include //EsdPrint() +#include //EsdPrint() #include "AliRICHHelix.h" #include -#include "AliRICHRecon.h" #include #include #include #include +#include //RecWithStack(); +#include //GetTrackPoint() +#include //GetTrackPoint() ClassImp(AliRICHTracker) -//__________________________________________________________________________________________________ -Int_t AliRICHTracker::PropagateBack(AliESD *pESD) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliRICHTracker::AliRICHTracker():AliTracker() { -// Interface callback methode invoked by AliRecontruction during tracking after TOF -// It steers to different way to provide the final reconstructed information sutable for analisys: -// 1. AliESD - reconstructed tracks are used -// 2. RICH private ntuple for debug- stack particles used instead of reconstructed tracks - AliDebug(1,"Start pattern recognition"); - if(pESD->GetNumberOfTracks()) { - Int_t iNtracks=pESD->GetNumberOfTracks(); - AliDebug(1,Form("Start with %i tracks",iNtracks)); - AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH")); - for(Int_t iTrackN=0;iTrackNCdbRead(0,0); + for(Int_t i=0;i<5;i++)fErrPar[i]=0; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Bool_t AliRICHTracker::GetTrackPoint(Int_t idx, AliTrackPoint& point) const { -//recontruction from ESD- primary way to reconstruct particle ID signal from tracks provided by core detectors - fnPhotBKG = 0; - - Double_t fField=GetFieldMap()->SolenoidField()/10;// magnetic field in Tesla - AliESDtrack *pTrack = pESD->GetTrack(iTrackN);// get next reconstructed track -// if((pTrack->GetStatus()&AliESDtrack::kTOFout)==0) continue; //ignore tracks not recontructed by TOF -// pTrack->GetXYZ(xb); -// pTrack->GetPxPyPz(pb); - Int_t status=pTrack->GetStatus()&AliESDtrack::kTOFout;//get running track parameters - Int_t charge = (Int_t)(-TMath::Sign(1.,pTrack->GetSign()*fField)); - AliDebug(1,Form("Track %i pmod=%f charge=%i stat=%i",iTrackN,pTrack->GetP(),charge,status)); - AliRICHHelix helix(pTrack->X3(),pTrack->P3(),charge,fField); - Int_t iChamber=helix.RichIntersect(pRich->P()); - AliDebug(1,Form("intersection with %i chamber found",iChamber)); - if(!iChamber) { - pTrack->SetRICHsignal(-999); //to be improved by flags... - return;//intersection with no chamber found - } -//find MIP cluster candidate (cluster which is closest to track intersection point) - Double_t distMip=9999,distX=0,distY=0; //min distance between clusters and track position on PC - Int_t iMipId=0; //index of that min distance cluster - Double_t chargeMip=0; //charge of the MIP - Bool_t kFound = kFALSE; - for(Int_t iClusN=0;iClusNClusters(iChamber)->GetEntries();iClusN++){//clusters loop for intersected chamber - AliRICHCluster *pClus=(AliRICHCluster*)pRich->Clusters(iChamber)->UncheckedAt(iClusN);//get pointer to current cluster - if(pClus->Q()DistTo(helix.PosPc());//distance between current cluster and helix intersection with PC - if(distCurrentDistX(helix.PosPc()); - distY=pClus->DistY(helix.PosPc()); - chargeMip=pClus->Q(); - }//find cluster nearest to the track - AliDebug(1,Form("Ploc (%f,%f,%f) dist= %f",helix.Ploc().Mag(),helix.Ploc().Theta()*TMath::RadToDeg(), - helix.Ploc().Phi()*TMath::RadToDeg(),pClus->DistTo(helix.PosPc()))); +// Interface callback methode invoked from AliReconstruction::WriteAlignmentData() to get position of MIP cluster in MARS associated to a current track. +// MIP cluster is reffered by index which is stored in AliESDtrack ??????? +// Arguments: idx- cluster index which is stored by RICH in AliESDtrack +// point- reference to the object where to store the point +// Returns: status of operation if FALSE then AliReconstruction::WriteAlignmentData() do not store this point to array of points for current track. + if(idx<0) return kFALSE; //no MIP cluster assigned to this track in PropagateBack() + Int_t iCham=idx/1000000; + Int_t iClu=idx%1000000; + point.SetVolumeID(AliAlignObj::LayerToVolUID(AliAlignObj::kRICH,iCham-1));//layer and chamber number + AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH")); + AliRICHCluster *pClu=(AliRICHCluster*)pRich->Clus(iCham)->UncheckedAt(iClu);//get pointer to cluster + TVector3 mars=AliRICHParam::Instance()->Lors2Mars(iCham,pClu->X(),pClu->Y()); + point.SetXYZ(mars.X(),mars.Y(),mars.Z()); + return kTRUE; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliRICHTracker::LoadClusters(TTree *pCluTree) +{ +// Interface callback methode invoked from AliReconstruction::RunTracking() to load RICH clusters for RICH +// Arguments: pCluTree- pointer to clusters tree got by AliRICHLoader::LoadRecPoints("read") then AliRICHLoader::TreeR() +// Returns: error code (currently ignored in AliReconstruction::RunTraking()) + AliDebug(1,"Start."); pCluTree->GetEntry(0); AliDebug(1,"Stop."); return 0; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliRICHTracker::PropagateBack(AliESD *pESD) +{ +// Interface callback methode invoked by AliRecontruction::RunTracking() during tracking after TOF. It's done just once per event +// Arguments: pESD - pointer to Event Summary Data class instance which contains a list of tracks +// Returns: error code, 0 if no errors + Int_t iNtracks=pESD->GetNumberOfTracks(); + AliDebug(1,Form("Start with %i tracks",iNtracks)); + AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH")); + AliRICHRecon recon; + + for(Int_t iTrk=0;iTrkGetTrack(iTrk);// get next reconstructed track + AliRICHHelix helix(pTrack->X3(),pTrack->P3(),(Int_t)pTrack->GetSign(),GetBz()/10); //construct helix out of track running parameters + helix.Print("Track"); + Int_t iChamber=helix.RichIntersect(AliRICHParam::Instance()); + if(!iChamber) continue; //no intersection with chambers, ignore this track go after the next one + + //find MIP cluster candidate (closest to track intersection point cluster with large enough QDC) + Double_t dR=9999, dX=9999, dY=9999; //distance between track-PC intersection point and current cluster + Double_t dRmip=9999,dXmip=9999,dYmip=9999; //distance between track-PC intersection point and nearest cluster + Int_t iMipId=-1; //index of this nearest cluster + for(Int_t iClu=0;iCluClus(iChamber)->GetEntries();iClu++){//clusters loop for intersected chamber + AliRICHCluster *pClu=(AliRICHCluster*)pRich->Clus(iChamber)->UncheckedAt(iClu);//get pointer to current cluster + if(pClu->Q()DistXY(helix.PosPc(),dX,dY); dR=TMath::Sqrt(dX*dX+dY*dY); //get distance for current cluster + if(dRSetRICHsignal(-999); - return; - } - AliDebug(1,Form("Min distance cluster: %i dist is %f",iMipId,distMip)); - pTrack->SetRICHcluster(((Int_t)chargeMip)+1000000*iChamber); - pTrack->SetRICHdxdy(distX,distY); - pTrack->SetRICHthetaPhi(helix.Ploc().Theta(),helix.Ploc().Phi()); -// -// HERE CUTS ON GOLD RINGS.... -// - if(distMip>AliRICHParam::DmatchMIP()) { - //track not accepted for pattern recognition - pTrack->SetRICHsignal(-990); //to be improved by flags... - return; - } -// - AliRICHRecon recon(&helix,pRich->Clusters(iChamber),iMipId); //actual job is done there - - Double_t thetaCerenkov=recon.ThetaCerenkov(); //search for mean Cerenkov angle for this track + pTrack->SetRICHthetaPhi(helix.Ploc().Theta(),helix.Ploc().Phi()); //store track impact angles with respect to RICH planes + pTrack->SetRICHdxdy(dXmip,dYmip); //distance between track-PC intersection and closest cluster with Qdc>100 - pTrack->SetRICHsignal(thetaCerenkov); - pTrack->SetRICHnclusters(recon.GetHoughPhotons()); + if(iMipId==-1) {pTrack->SetRICHsignal(kMipQdcCut); continue;} //no cluster with enough QDC found + if(dRmip>AliRICHParam::DmatchMIP()) {pTrack->SetRICHsignal(kMipDistCut); continue;} //closest cluster with enough carge is still too far + + pTrack->SetRICHcluster(iMipId+1000000*iChamber); //set mip cluster index + pTrack->SetRICHsignal(recon.ThetaCerenkov(&helix,pRich->Clus(iChamber),iMipId));//search for mean Cerenkov angle for this track + pTrack->SetRICHnclusters(iMipId); //on return iMipId is number of photon clusters accepted in reconstruction - fnPhotBKG = recon.GetPhotBKG(); - - AliDebug(1,Form("FINAL Theta Cerenkov=%f",pTrack->GetRICHsignal())); -// + AliDebug(1,Form("Ch=%i PC Intersection=(%5.2f,%5.2f) cm MIP cluster dist=(%5.2f,%5.2f)=%5.2f cm ThetaCkov=%f", + iChamber,helix.PosPc().X(),helix.PosPc().Y(), dXmip,dYmip,dRmip, pTrack->GetRICHsignal())); + +//here comes PID calculations if(pTrack->GetRICHsignal()>0) { AliDebug(1,Form("Start to assign the probabilities")); Double_t sigmaPID[AliPID::kSPECIES]; @@ -108,33 +100,36 @@ void AliRICHTracker::RecWithESD(AliESD *pESD,AliRICH *pRich,Int_t iTrackN) for (Int_t iPart=0;iPartClusters(iChamber)->GetEntries();iphot++) { + for(Int_t iphot=0;iphotClus(iChamber)->GetEntries();iphot++) { recon.SetPhotonIndex(iphot); if(recon.GetPhotonFlag() == 2) { Double_t theta_g=recon.GetTrackTheta(); Double_t phi_g=(recon.GetPhiPoint()-recon.GetTrackPhi()); - Double_t sigma2 = AliRICHParam::SigmaSinglePhoton(iPart,pTrack->GetP(),theta_g,phi_g).Mag2(); + Double_t sigma2 = AliRICHParam::Instance()->SigmaSinglePhoton(iPart,pTrack->GetP(),theta_g,phi_g).Mag2(); if(sigma2>0) sigmaPID[iPart] += 1/sigma2; } } - if (sigmaPID[iPart]>0) - sigmaPID[iPart] *= (Double_t)(recon.GetHoughPhotons()-fnPhotBKG)/(Double_t)(recon.GetHoughPhotons()); // n total phots, m are background...the sigma are scaled.. - if(sigmaPID[iPart]>0) sigmaPID[iPart] = 1/TMath::Sqrt(sigmaPID[iPart])*0.001; // sigma from parametrization are in mrad... + if (sigmaPID[iPart]>0) + sigmaPID[iPart] *= (Double_t)(iMipId-recon.GetPhotBKG())/(Double_t)(iMipId); // n total phots, m are background...the sigma are scaled.. + if(sigmaPID[iPart]>0) sigmaPID[iPart] = 1/TMath::Sqrt(sigmaPID[iPart])*0.001; // sigma from parametrization are in mrad... else sigmaPID[iPart] = 0; fErrPar[iPart]=sigmaPID[iPart]; AliDebug(1,Form("sigma for %s is %f rad",AliPID::ParticleName(iPart),sigmaPID[iPart])); } - CalcProb(thetaCerenkov,pTrack->GetP(),sigmaPID,richPID); + CalcProb(pTrack->GetRICHsignal(),pTrack->GetP(),sigmaPID,richPID); pTrack->SetRICHpid(richPID); AliDebug(1,Form("PROBABILITIES ---> %f - %f - %f - %f - %f",richPID[0],richPID[1],richPID[2],richPID[3],richPID[4])); } - AliDebug(1,"Stop."); -} //RecWithESD -//__________________________________________________________________________________________________ + }//ESD tracks loop + AliDebug(1,"Stop pattern recognition"); + return 0; // error code: 0=no error; +}//PropagateBack() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHTracker::RecWithStack(TNtupleD *hn) { -//Reconstruction for particles from STACK. This methode is to be used for RICH standalone when no other detectors are switched on, -//so normal tracking is not available +// Reconstruction for particles from STACK. This methode is to be used for RICH standalone when no other detectors are switched on, so normal tracking is not available. +// Arguments: hn- output ntuple where to store all variables +// Returns: none AliDebug(1,"Start."); AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH")); @@ -155,6 +150,7 @@ void AliRICHTracker::RecWithStack(TNtupleD *hn) if(pRich->GetLoader()->LoadRecPoints()) {AliDebug(1,Form("No clusters found in RICH"));return;} pRich->GetLoader()->TreeR()->GetEntry(0); + AliRICHRecon recon; for(Int_t iTrackN=0;iTrackNParticle(iTrackN); if(!pParticle) {AliDebug(1,Form("Not a valid TParticle pointer. Track skipped"));continue;} @@ -181,56 +177,41 @@ void AliRICHTracker::RecWithStack(TNtupleD *hn) if(pParticle->GetPDG()->Charge()==0||TMath::Abs(Int_t(pParticle->GetPDG()->Charge()))!=3) continue; //to avoid photons from stack... hnvec[0]=pParticle->P(); hnvec[1]=pParticle->GetPDG()->Charge(); - p0.SetMagThetaPhi(pParticle->P(),pParticle->Theta(),pParticle->Phi()); - x0.SetXYZ(pParticle->Vx(),pParticle->Vy(),pParticle->Vz()); + + p0.SetMagThetaPhi(pParticle->P(),pParticle->Theta(),pParticle->Phi()); x0.SetXYZ(pParticle->Vx(),pParticle->Vy(),pParticle->Vz()); AliRICHHelix helix(x0,p0,TMath::Sign(1,(Int_t)pParticle->GetPDG()->Charge()),b); - Int_t iChamber=helix.RichIntersect(pRich->P()); + Int_t iChamber=helix.RichIntersect(AliRICHParam::Instance()); + if(!iChamber) continue;// no intersection with RICH found + hnvec[2]=helix.Ploc().Theta(); hnvec[3]=helix.Ploc().Phi(); - AliDebug(1,Form("intersection with %i chamber found",iChamber)); - if(!iChamber) continue;// no intersection with RICH found hnvec[4]=helix.PosPc().X(); hnvec[5]=helix.PosPc().Y(); - Double_t distMip=9999; //min distance between clusters and track position on PC - Double_t mipX=-1; //min distance between clusters and track position on PC - Double_t mipY=-1; //min distance between clusters and track position on PC - Double_t chargeMip=-1; // charge MIP to find + + Double_t dX,dY,dR,dRmip=9999; //min distance between clusters and track position on PC Int_t iMipId=-1; //index of that min distance cluster - for(Int_t iClusN=0;iClusNClusters(iChamber)->GetEntries();iClusN++){//clusters loop for intersected chamber - AliRICHCluster *pClus=(AliRICHCluster*)pRich->Clusters(iChamber)->UncheckedAt(iClusN);//get pointer to current cluster - Double_t distCurrent=pClus->DistTo(helix.PosPc());//ditance between current cluster and helix intersection with PC - if(distCurrentX(); - mipY=pClus->Y(); - chargeMip=pClus->Q();iMipId=1000000*iChamber+iClusN;}//find cluster nearest to the track + for(Int_t iClu=0;iCluClus(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(dRX();hnvec[7]=pClu->Y();hnvec[8]=pClu->Q(); + iMipId=1000000*iChamber+iClu;}//find cluster nearest to the track - AliDebug(1,Form("Ploc (%f,%f,%f) dist= %f",helix.Ploc().Mag(),helix.Ploc().Theta()*TMath::RadToDeg(), - helix.Ploc().Phi()*TMath::RadToDeg(),pClus->DistTo(helix.PosPc()))); }//clusters loop for intersected chamber - AliDebug(1,Form("Min distance cluster: %i dist is %f",iMipId,distMip)); - hnvec[6]=mipX;hnvec[7]=mipY; - hnvec[8]=chargeMip; - AliRICHRecon recon(&helix,pRich->Clusters(iChamber),iMipId); - Double_t thetaCerenkov=recon.ThetaCerenkov(); //search for mean Cerenkov angle for this track - hnvec[9]=thetaCerenkov; - hnvec[10]=recon.GetHoughPhotons(); + + hnvec[9]=recon.ThetaCerenkov(&helix,pRich->Clus(iChamber),iMipId); //search for mean Cerenkov angle for this track + hnvec[10]=iMipId;//on return from ThetaCerenkov() contains number of photon candidates accepted hnvec[11]=(Double_t)iMipId; hnvec[12]=(Double_t)iChamber; hnvec[13]=(Double_t)pParticle->GetPdgCode(); if(hn) hn->Fill(hnvec); - AliDebug(1,Form("FINAL Theta Cerenkov=%f",thetaCerenkov)); + AliDebug(1,Form("FINAL Theta Cerenkov=%f",hnvec[9])); }//stack particles loop pRich->GetLoader()->UnloadRecPoints(); AliDebug(1,"Stop."); }//RecWithStack -//__________________________________________________________________________________________________ -Int_t AliRICHTracker::LoadClusters(TTree *pTree) -{ -// Load clusters for RICH - AliDebug(1,"Start."); pTree->GetEntry(0); AliDebug(1,"Stop."); return 0; -} -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHTracker::CalcProb(Double_t thetaCer,Double_t pmod, Double_t *sigmaPID, Double_t *richPID) { // Calculates probability to be a electron-muon-pion-kaon-proton @@ -241,7 +222,7 @@ void AliRICHTracker::CalcProb(Double_t thetaCer,Double_t pmod, Double_t *sigmaPI for(Int_t iPart=0;iPartIdxC6F14(AliRICHParam::EckovMean()); Double_t cosThetaTh = TMath::Sqrt(mass*mass+pmod*pmod)/(refIndex*pmod); thetaTh[iPart]=0; if(cosThetaTh>=1) continue; @@ -252,8 +233,8 @@ void AliRICHTracker::CalcProb(Double_t thetaCer,Double_t pmod, Double_t *sigmaPI if(sigmaPID[iPart]>0) height[iPart] = TMath::Gaus(thetaCer,thetaTh[iPart],sigmaPID[iPart],kTRUE); else height[iPart] = 0; totalHeight +=height[iPart]; - AliDebug(1,Form(" Particle %s with mass %f with height %f and thetaTH %f",AliPID::ParticleName(iPart),mass,height[iPart],thetaTh[iPart])); - AliDebug(1,Form(" partial height %15.14f total height %15.14f",height[iPart],totalHeight)); + AliDebugClass(1,Form(" Particle %s with mass %f with height %f and thetaTH %f",AliPID::ParticleName(iPart),mass,height[iPart],thetaTh[iPart])); + AliDebugClass(1,Form(" partial height %15.14f total height %15.14f",height[iPart],totalHeight)); } if(totalHeight<1e-5) {for(Int_t iPart=0;iPartGet("esdTree"); if(!pEsdTr){Printf("ERROR: Bad AliESDs.root, no ESD tree inside!");return;} + AliESD *pESD=new AliESD; pEsdTr->SetBranchAddress("ESD", &pESD); + + Int_t iNevt=pEsdTr->GetEntries(); Printf("This ESD contains %i events",iNevt); + for(Int_t iEvt=0;iEvtGetEvent(iEvt); + Int_t iNtracks=pESD->GetNumberOfTracks(); Printf("ESD contains %i tracks created in Bz=%.2f Tesla",iNtracks,pESD->GetMagneticField()/10.); + for(Int_t iTrk=0;iTrkGetTrack(iTrk);// get next reconstructed track + Double_t dx,dy; pTrack->GetRICHdxdy(dx,dy); + Double_t theta,phi; pTrack->GetRICHthetaPhi(theta,phi); + Printf("Track %2i Q=%4.1f P=%.3f GeV RICH: ChamberCluster %7i Track-Mip=(%7.2f,%7.2f)=%5.2f cm ThetaCer %7.1f rad",iTrk,pTrack->GetSign(),pTrack->GetP(), + pTrack->GetRICHcluster(),dx,dy,TMath::Sqrt(dx*dx+dy*dy),pTrack->GetRICHsignal()); + }//ESD tracks loop + }//ESD events loop + delete pESD; pFile->Close();//close AliESDs.root +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHTracker.h b/RICH/AliRICHTracker.h index 9a6d159c958..a8df01a5339 100644 --- a/RICH/AliRICHTracker.h +++ b/RICH/AliRICHTracker.h @@ -1,35 +1,31 @@ #ifndef AliRICHTracker_h #define AliRICHTracker_h -#include -#include -#include "TNtupleD.h" +#include //base class -class AliCluster; -class AliESD; -class AliRICH; -class TTree; +class TNtupleD; //RecWithStack() +class AliESD; //Clusters2Tracks(), RefitInward(), PropagateBack(), RecWithESD() class AliRICHTracker : public AliTracker { public: - AliRICHTracker() :AliTracker() {for(Int_t i=0;i<5;i++)fErrPar[i]=0;AliDebug(1,"Start.");} - virtual ~AliRICHTracker() {AliDebug(1,"Stop.");} - Int_t Clusters2Tracks(AliESD *) {AliDebug(1,"Start.");return 0;} //pure virtual from AliTracker - Int_t RefitInward(AliESD *) {AliDebug(1,"Start.");return 0;} //pure virtual from AliTracker - void UnloadClusters() {AliDebug(1,"Start.");} //pure virtual from AliTracker - AliCluster *GetCluster(Int_t )const {AliDebug(1,"Start.");return 0;} //pure virtual from AliTracker - Int_t PropagateBack(AliESD *); //pure virtual from AliTracker - void RecWithESD(AliESD *,AliRICH *,Int_t iTrackN); //recon with ESD - void RecWithStack(TNtupleD *hn); //recon from Stack in case ESD empty - void CalcProb(Double_t thetaCer,Double_t pmod,Double_t *sigmaPID, Double_t *richPID); // calculate pid for RICH - Int_t LoadClusters(TTree *); //pure virtual from AliTracker - Double_t fnPhotBKG; //Temporary stored for debug purpose - Double_t fErrPar[5]; //Temporary stored for debug purpose + AliRICHTracker(); + virtual ~AliRICHTracker() {} +//framework part + AliCluster *GetCluster (Int_t )const {return 0;} //pure virtual from AliTracker + Bool_t GetTrackPoint (Int_t idx,AliTrackPoint &pt)const; // from AliTracker + Int_t Clusters2Tracks(AliESD * ) {return 0;} //pure virtual from AliTracker + Int_t LoadClusters (TTree *pCluTr ); //pure virtual from AliTracker + Int_t PropagateBack (AliESD * ); //pure virtual from AliTracker invoked from AliReconstruction::RunTracking() + Int_t RefitInward (AliESD * ) {return 0;} //pure virtual from AliTracker + void UnloadClusters ( ) { } //pure virtual from AliTracker +//private part + void RecWithStack(TNtupleD *hn ); //recon from Stack in case ESD empty + static void CalcProb (Double_t thetaCer,Double_t pmod,Double_t *pidsigma, Double_t *pid); //calculate pid for RICH + static void EsdPrint ( ); //print ESD status + Double_t fErrPar[5]; //Temporary stored for debug purpose + enum ETrackingFlags {kMipDistCut=-990,kMipQdcCut=-999}; protected: - - Double_t fField; // magnetic field stored - ClassDef(AliRICHTracker,0) };//class AliRICHTracker diff --git a/RICH/AliRICHv0.cxx b/RICH/AliRICHv0.cxx index e5a57c6ac8d..50268c6b97c 100644 --- a/RICH/AliRICHv0.cxx +++ b/RICH/AliRICHv0.cxx @@ -14,13 +14,6 @@ //************************************************************************** #include "AliRICHv0.h" -#include "AliRICHChamber.h" -#include -#include -#include -#include -#include -#include #include @@ -29,92 +22,5 @@ ClassImp(AliRICHv0) void AliRICHv0::StepManager() { //This StepManager is a provision for different test-learn activities on the current MC layer - static Int_t iStepN; - const char *sParticle; - switch(gMC->TrackPid()){ - case kProton: sParticle="proton" ;break; - case kNeutron: sParticle="neutron" ;break; - case kGamma: sParticle="gamma" ;break; - case kCerenkov: sParticle="photon" ;break; - case kPi0: sParticle="Pi0" ;break; - case kPiPlus: sParticle="Pi+" ;break; - case kPiMinus: sParticle="Pi-" ;break; - case kElectron: sParticle="electron" ;break; - default: sParticle="not known" ;break; - } - - Info(Form("Step %i",iStepN),"event=%i hunt=%i tid=%i pid=%i(%s) m=%f q=%3.1f dEdX=%9.3f", - gMC->CurrentEvent(), - fIshunt, - gAlice->GetMCApp()->GetCurrentTrackNumber(), - gMC->TrackPid(), - sParticle, - gMC->TrackMass(), - gMC->TrackCharge(), - gMC->Edep()*1e9); - Info("Flags","alive(%i) disap(%i) enter(%i) exit(%i) inside(%i) out(%i) stop(%i) new(%i)", - gMC->IsTrackAlive(), - gMC->IsTrackDisappeared(), - gMC->IsTrackEntering(), - gMC->IsTrackExiting(), - gMC->IsTrackInside(), - gMC->IsTrackOut(), - gMC->IsTrackStop(), - gMC->IsNewTrack()); - Int_t copy0=0,copy1=0,copy2=0,copy3=0; - Int_t vid0=gMC->CurrentVolID(copy0); - Int_t vid1=gMC->CurrentVolOffID(1,copy1); - Int_t vid2=gMC->CurrentVolOffID(2,copy2); - Int_t vid3=gMC->CurrentVolOffID(3,copy3); - Info("Volumes","vid0=%i(%s)c%i vid1=%i(%s)c%i vid2=%i(%s)c%i vid3=%i(%s)c%i %s-%s-%s-%s", - vid0,gMC->VolName(vid0),copy0, - vid1,gMC->VolName(vid1),copy1, - vid2,gMC->VolName(vid2),copy2, - vid3,gMC->VolName(vid3),copy3, - gMC->CurrentVolName(), - gMC->CurrentVolOffName(1), - gMC->CurrentVolOffName(2), - gMC->CurrentVolOffName(3)); - - Float_t a,z,den,rad,abs; a=z=den=rad=abs=-1; - Int_t mid=gMC->CurrentMaterial(a,z,den,rad,abs); - Info("Material","id=%i a=%7.2f z=%7.2f den=%9.4f rad=%9.2f abs=%9.2f",mid,a,z,den,rad,abs); - - Int_t iTmedId=gMC->CurrentMedium(); - const char *sTmed; - switch(iTmedId){ - case kAir: sTmed="Air" ;break; - case kRoha: sTmed="Rohacell" ;break; - case kSiO2: sTmed="SiO2" ;break; - case kC6F14: sTmed="C6F14" ;break; - case kGridCu: sTmed="GridCu" ;break; - case kOpSiO2: sTmed="OpSiO2" ;break; - case kGap: sTmed="Gap" ;break; - case kGlass: sTmed="Glass" ;break; - case kCu: sTmed="Cu" ;break; - case kSteel: sTmed="Steel" ;break; - case kPerpex: sTmed="Perpex" ;break; - case kCH4: sTmed="CH4" ;break; - case kCsI: sTmed="CsI" ;break; - case kAl: sTmed="Al" ;break; - case kW: sTmed="W" ;break; - default: sTmed="not known";break; - } - Info("Medium","id=%i (%s)",iTmedId,sTmed); - TLorentzVector x4; gMC->TrackPosition(x4); - Float_t glo[3],loc[3]; - glo[0]=x4.X();glo[1]=x4.Y();glo[2]=x4.Z(); - gMC->Gmtod(glo,loc,1); - Info("X4 glo","(x,y,z)=(%+8.3f,%+8.3f,%+8.3f) (r,theta,phi)=(%8.3f,%8.3f,%8.3f)", - glo[0],glo[1],glo[2],x4.Rho(),x4.Theta()*TMath::RadToDeg(),x4.Phi()*TMath::RadToDeg()); - Info("X4 loc","(x,y,z)=(%+8.3f,%+8.3f,%8.3f) by gMC->Gmtod()",loc[0],loc[1],loc[2]); - static Int_t idGAP = gMC->VolId("GAP "); - if(idGAP==gMC->CurrentVolID(copy0)){ - Int_t iChamber; - gMC->CurrentVolOffID(2,iChamber); - TVector2 x2=C(iChamber)->Mrs2Pc(x4); - Info("X4 loc","(%+8.3f,%+8.3f) by Mrs2Pc", x2.X(),x2.Y()); - } - Info(Form("Step %i",iStepN++),"end of current step\n"); }//StepManager() diff --git a/RICH/AliRICHv1.cxx b/RICH/AliRICHv1.cxx index cfe2ed6db61..d680bea65bd 100644 --- a/RICH/AliRICHv1.cxx +++ b/RICH/AliRICHv1.cxx @@ -16,76 +16,312 @@ #include "AliRICHv1.h" //class header #include "AliRICHParam.h" -#include "AliRICHChamber.h" -#include +#include //Hits2SDigits() #include -#include -#include -#include //Hits2SDigits() +#include //StepManager() for gMC +#include //StepHistory() +#include //StepManager(),Hits2SDigits() +#include //Hits2SDigits() +#include //Hits2SDigits() #include #include -#include -#include +#include //StepManager() #include //Digits2Raw() - +#include //CreateMaterials() +#include //CreateMaterials() +#include //CreateGeometry() +#include //Optics() +#include //Optics() +#include //Optics() +#include //Optics() +#include //CreateMaterials() +#include //CreateMaterials() +#include //CreateMaterials() + ClassImp(AliRICHv1) + +void AliRICHv1::CreateMaterials() +{ +// Definition of available RICH materials +// Arguments: none +// Returns: none + AliDebug(1,"Start v1 RICH."); + + const Int_t kNbins=30; //number of photon energy points + + 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 + +//Read all the staff from CDB + TF2 *pIdxC6F14; + AliCDBEntry *pEntry=AliCDBManager::Instance()->Get("RICH/RICHConfig/RefIdxC6F14",0,0,0); //0-0-0 is for simulation + if(pEntry){ + pIdxC6F14=(TF2*)pEntry->GetObject(); delete pEntry; + }else{ + AliWarning("No valid calibarion, the hardcoded will be used!"); + pIdxC6F14=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 + } + + Double_t eCkovMin=5.5e-9,eCkovMax=8.5e-9; //in GeV + 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;iEval(aEckov[i],pIdxC6F14->GetUniqueID()); + 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 +// aQeCsI[i] /= (1.0-Fresnel(aEckov[i]*1e9,1.0,0)) ; //FRESNEL LOSS CORRECTION ????????????? + aQe1 [i] =1 ; //QE for all other materials except for PC must be 1. + } + +//data from PDG booklet 2002 density [gr/cm^3] rad len [cm] abs len [cm] + Float_t aAir[4]={12,14,16,36} , zAir[4]={6,7,8,18} , wAir[4]={0.000124,0.755267,0.231781,0.012827} , dAir=0.00120479; Int_t nAir=4;//mixture 0.9999999 + Float_t aC6F14[2]={ 12.01 , 18.99} , zC6F14[2]={ 6 , 9} , wC6F14[2]={6 , 14} , dC6F14=1.68 ; Int_t nC6F14=-2; + Float_t aSiO2[2]={ 28.09 , 15.99} , zSiO2[2]={14 , 8} , wSiO2[2]={1 , 2} , dSiO2=2.64 ; Int_t nSiO2=-2; + Float_t aCH4[2]={ 12.01 , 1.01} , zCH4[2]={ 6 , 1} , wCH4[2]={1 , 4} , dCH4=7.17e-4 ; Int_t nCH4=-2; + Float_t aCsI[2]={132.90 ,126.90} , zCsI[2]={55 ,53} , wCsI[2]={1 , 1} , dCsI=0.1 ; Int_t nCsI=-2; + Float_t aRoha= 12.01 , zRoha= 6 , dRoha= 0.10 , radRoha= 18.80 , absRoha= 86.3/dRoha; //special material- quazi carbon + 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); + + 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 ); + + 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; + +//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); + + 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]; + for(Int_t i=0;iSetMarkerStyle(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"); + + 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 + } +}//void AliRICH::CreateMaterials() //__________________________________________________________________________________________________ -void AliRICHv1::StepManager() +void AliRICHv1::CreateGeometry() { -// Full Step Manager. -// 3- Ckovs absorbed on Collection electrods -// 5- Ckovs absorbed on Cathode wires -// 6- Ckovs absorbed on Anod wires - - Int_t copy; - static Int_t iCurrentChamber; - static Int_t idRRAD = gMC->VolId("RRAD"); - static Int_t idRRWI = gMC->VolId("RRWI"); - static Int_t idRICH = gMC->VolId("RICH"); - static Int_t idRPC = gMC->VolId("RPC "); - static Int_t idRGAP = gMC->VolId("RGAP"); -//history of Cerenkovs - if(gMC->TrackPid()==kCerenkov){ - if( gMC->IsNewTrack() && gMC->CurrentVolID(copy)==idRRAD) fCounters(0)++;// 0- Ckovs produced in radiator - if(!gMC->IsTrackAlive() && gMC->CurrentVolID(copy)==idRRAD) fCounters(1)++;// 1- Ckovs absorbed in radiator - if(!gMC->IsTrackAlive() && gMC->CurrentVolID(copy)==idRRWI) fCounters(2)++;// 2- Ckovs absorbed in radiator window - if(!gMC->IsTrackAlive() && gMC->CurrentVolID(copy)==idRICH) fCounters(4)++;// 4- Ckovs absorbed in CH4 +//Creates detailed geometry simulation (currently GEANT volumes tree) + AliDebug(1,"Start main."); + if(!gMC->IsRootGeometrySupported()) return; + + Double_t cm=1,mm=0.1*cm,mkm=0.001*mm,dx,dy,dz;//default is cm + + TGeoVolume *pRich=gGeoManager->MakeBox("RICH",gGeoManager->GetMedium("RICH_CH4"),dx=(6*mm+1681*mm+6*mm)/2, //main RICH volume + dy=(6*mm+1466*mm+6*mm)/2, + dz=(80*mm+40*mm)*2/2); //x,y taken from 2033P1 z from p84 TDR + 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 + 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 + 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 + } + pMatrix->RotateZ(kAngCom); //apply common rotation in XY plane + gGeoManager->GetVolume("ALIC")->AddNode(pRich,iCh,pMatrix); } - -//Treat photons - static TLorentzVector cerX4; - if((gMC->TrackPid()==kCerenkov||gMC->TrackPid()==kFeedback)&&gMC->CurrentVolID(copy)==idRPC){//photon in PC - if(gMC->Edep()>0){//photon in PC +DE - if(IsLostByFresnel()){ - if(gMC->TrackPid()==kCerenkov) fCounters(7)++;// 7- Ckovs reflected from CsI - gMC->StopTrack(); - return; - } - gMC->TrackPosition(cerX4); gMC->CurrentVolOffID(2,iCurrentChamber);//RICH-RPPF-RPC - - HitAdd(iCurrentChamber,gAlice->GetMCApp()->GetCurrentTrackNumber(),cerX4.Vect(),cerX4.Vect());//HIT for PHOTON in conditions CF+CSI+DE - fCounters(8)++;//4- Ckovs converted to electron on CsI - GenerateFeedbacks(iCurrentChamber); - }//photon in PC and DE >0 - }//photon in PC + + Float_t par[3]; + Int_t matrixIdReturn=0; //matrix id returned by AliMatrix +//Pad Panel frame 6 sectors + par[0]=648*mm/2;par[1]= 411*mm/2;par[2]=40 *mm/2;gMC->Gsvolu("Rppf" ,"BOX ",(*fIdtmed)[kAl] ,par,3);//PPF 2001P2 inner size of the slab by 1mm more + par[0]=181*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("RppfLarge","BOX ",(*fIdtmed)[kAir] ,par,3);//large whole + par[0]=114*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("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) -//Treat charged particles - static Float_t eloss; - static TLorentzVector mipInX4,mipOutX4; - if(gMC->TrackCharge() && gMC->CurrentVolID(copy)==idRGAP){//MIP in GAP - gMC->CurrentVolOffID(1,iCurrentChamber);//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(iCurrentChamber,gAlice->GetMCApp()->GetCurrentTrackNumber(),mipInX4.Vect(),mipOutX4.Vect(),eloss);//HIT for MIP: MIP in GAP Exiting - GenerateFeedbacks(iCurrentChamber,eloss);//MIP+GAP+Exit - }else//MIP in GAP going inside - eloss += gMC->Edep(); - }//MIP in GAP -}//StepManager() + gMC->Gspos("Rppf",1,"RICH", -335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY");//F1 2040P1 z p.84 TDR + gMC->Gspos("Rppf",2,"RICH", +335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",3,"RICH", -335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",4,"RICH", +335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",5,"RICH", -335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",6,"RICH", +335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rpc" ,1,"Rppf", 0*mm, 0*mm, -19.15*mm, 0,"ONLY");//PPF 2001P2 + gMC->Gspos("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"); + gMC->Gspos("RppfLarge",3,"Rppf", -224.5*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",4,"Rppf", -224.5*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",1,"Rppf", - 65.0*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",2,"Rppf", - 65.0*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",3,"Rppf", - 65.0*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",4,"Rppf", - 65.0*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",5,"Rppf", + 65.0*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",6,"Rppf", + 65.0*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",7,"Rppf", + 65.0*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",8,"Rppf", + 65.0*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",5,"Rppf", +224.5*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",6,"Rppf", +224.5*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",7,"Rppf", +224.5*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",8,"Rppf", +224.5*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); +//Gap - anod wires 6 copies to RICH + par[0]=648*mm/2;par[1]= 411*mm/2 ;par[2]=4.45*mm/2;gMC->Gsvolu("Rgap","BOX ",(*fIdtmed)[kCH4] ,par,3);//xy as PPF 2001P2 z WP 2099P1 + par[0]= 0*mm ;par[1]= 20*mkm/2 ;par[2]= 648*mm/2;gMC->Gsvolu("Rano","TUBE",(*fIdtmed)[kW] ,par,3);//WP 2099P1 z = gap x PPF 2001P2 + AliMatrix(matrixIdReturn,180,0, 90,90, 90,0); //wires along x + + gMC->Gspos("Rgap",1,"RICH", -335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); //F1 2040P1 z WP 2099P1 + gMC->Gspos("Rgap",2,"RICH", +335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",3,"RICH", -335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",4,"RICH", +335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",5,"RICH", -335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",6,"RICH", +335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); + for(int i=1;i<=96;i++) + gMC->Gspos("Rano",i,"Rgap", 0*mm, -411/2*mm+i*4*mm, 0.185*mm, matrixIdReturn,"ONLY"); //WP 2099P1 +//Defines radiators geometry + par[0]=1330*mm/2 ;par[1]= 413*mm/2 ;par[2]= 24*mm/2; gMC->Gsvolu("Rrad" ,"BOX ",(*fIdtmed)[kC6F14] ,par,3); // Rad 2011P1 + par[0]=1330*mm/2 ;par[1]= 413*mm/2 ;par[2]= 4*mm/2; gMC->Gsvolu("RradFront" ,"BOX ",(*fIdtmed)[kRoha] ,par,3); //front + par[0]=1330*mm/2 ;par[1]= 413*mm/2 ;par[2]= 5*mm/2; gMC->Gsvolu("RradWin" ,"BOX ",(*fIdtmed)[kSiO2] ,par,3); //window + par[0]=1330*mm/2 ;par[1]= 5*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RradLong" ,"BOX ",(*fIdtmed)[kRoha] ,par,3); //long side + par[0]= 10*mm/2 ;par[1]= 403*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RradShort" ,"BOX ",(*fIdtmed)[kRoha] ,par,3); //short side + par[0]= 0 ;par[1]= 10*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RradSpacer","TUBE",(*fIdtmed)[kSiO2] ,par,3); //spacer + + gMC->Gspos("Rrad",1,"RICH", 0*mm,-434*mm, -12*mm, 0,"ONLY"); //3 radiators to RICH + gMC->Gspos("Rrad",2,"RICH", 0*mm, 0*mm, -12*mm, 0,"ONLY"); + gMC->Gspos("Rrad",3,"RICH", 0*mm,+434*mm, -12*mm, 0,"ONLY"); + gMC->Gspos("RradFront",1,"Rrad", 0*mm, 0*mm, -10.0*mm, 0,"ONLY"); //front cover + gMC->Gspos("RradWin" ,1,"Rrad", 0*mm, 0*mm, 9.5*mm, 0,"ONLY"); //quartz window (back cover) + gMC->Gspos("RradLong" ,1,"Rrad", 0*mm,-204*mm, -0.5*mm, 0,"ONLY"); //long side + gMC->Gspos("RradLong" ,2,"Rrad", 0*mm,+204*mm, -0.5*mm, 0,"ONLY"); //long side + gMC->Gspos("RradShort",1,"Rrad",-660*mm, 0*mm, -0.5*mm, 0,"ONLY"); //short side + gMC->Gspos("RradShort",2,"Rrad",+660*mm, 0*mm, -0.5*mm, 0,"ONLY"); //short side + for(int i=0;i<3;i++) + for(int j=0;j<10;j++) + gMC->Gspos("RradSpacer",10*i+j,"Rrad",-1330*mm/2+116*mm+j*122*mm,(i-1)*105*mm,-0.5*mm,0,"ONLY");//spacers +//Defines SandBox geometry + par[0]=1419*mm/2 ;par[1]=1378*mm/2;par[2]=50.5*mm/2; gMC->Gsvolu("Rsb" ,"BOX ",(*fIdtmed)[kAir] ,par,3); //2072P1 + par[0]=1419*mm/2 ;par[1]=1378*mm/2;par[2]= 0.5*mm/2; gMC->Gsvolu("RsbCover","BOX ",(*fIdtmed)[kAl] ,par,3); //cover + par[0]=1359*mm/2 ;par[1]=1318*mm/2;par[2]=49.5*mm/2; gMC->Gsvolu("RsbComb" ,"BOX ",(*fIdtmed)[kRoha] ,par,3); //honeycomb structure + + gMC->Gspos("Rsb",1,"RICH", 0*mm, 0*mm, -73.75*mm, 0,"ONLY"); //p.84 TDR sandbox to rich + gMC->Gspos("RsbComb" ,1,"Rsb", 0*mm, 0*mm, 0*mm, 0,"ONLY"); //2072P1 honeycomv to sandbox + gMC->Gspos("RsbCover",1,"Rsb", 0*mm, 0*mm, +25*mm, 0,"ONLY"); //cover to sandbox + gMC->Gspos("RsbCover",2,"Rsb", 0*mm, 0*mm, -25*mm, 0,"ONLY"); //cover to sandbox + AliDebug(1,"Stop v1. HMPID option"); +}//CreateGeometry() +//__________________________________________________________________________________________________ +void AliRICHv1::Init() +{ +// This methode defines ID for sensitive volumes, i.e. such geometry volumes for which there are if(gMC->CurrentVolID()==XXX) statements in StepManager() +// Arguments: none +// Returns: none + AliDebug(1,"Start v1 HMPID."); + fIdRad = gMC->VolId("Rrad"); + fIdWin = gMC->VolId("RradWin"); + fIdPc = gMC->VolId("Rpc"); + fIdAmpGap = gMC->VolId("Rgap"); + fIdProxGap = gMC->VolId("Rgap"); + AliDebug(1,"Stop v1 HMPID."); +} //__________________________________________________________________________________________________ Bool_t AliRICHv1::IsLostByFresnel() { @@ -105,18 +341,18 @@ Bool_t AliRICHv1::IsLostByFresnel() return kFALSE; }//IsLostByFresnel() //__________________________________________________________________________________________________ -void AliRICHv1::GenerateFeedbacks(Int_t iChamber,Float_t eloss) +void AliRICHv1::GenFee(Int_t iChamber,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=C(iChamber)->Mrs2Pc(x4);//hit position on photocathode plane + TVector2 x2=AliRICHParam::Instance()->Mars2Lors(iChamber,x4.Vect(),AliRICHParam::kPc);//hit position on photocathode plane TVector2 xspe=x2; - Int_t sector=P()->Loc2Sec(xspe); if(sector==-1) return; //hit in dead zone, nothing to produce - Int_t iTotQdc=P()->TotQdc(x2,eloss); - Int_t iNphotons=gMC->GetRandom()->Poisson(P()->C(iChamber)->AlphaFeedback(sector)*iTotQdc); + 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); 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]; @@ -169,15 +405,15 @@ void AliRICHv1::GenerateFeedbacks(Int_t iChamber,Float_t eloss) for(j=0;j<3;j++) pol[j]=e1[j]*TMath::Sin(phi)+e2[j]*TMath::Cos(phi); gMC->Gdtom(pol, pol, 2); Int_t outputNtracksStored; - gAlice->GetMCApp()->PushTrack(1, //do not transport + gAlice->GetMCApp()->PushTrack(1, //transport gAlice->GetMCApp()->GetCurrentTrackNumber(),//parent track - kFeedback, //PID - mom[0],mom[1],mom[2],mom[3], //track momentum - x4.X(),x4.Y(),x4.Z(),x4.T(), //track origin - pol[0],pol[1],pol[2], //polarization - kPFeedBackPhoton, - outputNtracksStored, - 1.0); + kFeedback, //PID + mom[0],mom[1],mom[2],mom[3], //track momentum + x4.X(),x4.Y(),x4.Z(),x4.T(), //track origin + pol[0],pol[1],pol[2], //polarization + kPFeedBackPhoton, //process ID + outputNtracksStored, //on return how many new photons stored on stack + 1.0); //weight }//feedbacks loop AliDebug(1,"Stop."); }//GenerateFeedbacks() @@ -197,32 +433,32 @@ void AliRICHv1::Hits2SDigits() GetLoader()->TreeH()->GetEntry(iPrimN); for(Int_t iHitN=0;iHitNGetEntries();iHitN++){//hits loop AliRICHHit *pHit=(AliRICHHit*)Hits()->At(iHitN);//get current hit - TVector2 x2 = C(pHit->C())->Mrs2Anod(0.5*(pHit->InX3()+pHit->OutX3()));//hit position in the anod plane - Int_t iTotQdc=P()->TotQdc(x2,pHit->Eloss());//total charge produced by hit, 0 if hit in dead zone + 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::PitchAnod()/2); - else anod.Set(x2.X(),padHitXY.Y()-AliRICHParam::PitchAnod()/2); + 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=P()->Loc2Area(anod);//determine affected pads, dead zones analysed inside + 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*P()->FracQdc(anod,pad); + 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) SDigitAdd(pHit->C(),pad,padQdc,GetLoader()->GetRunLoader()->Stack()->Particle(pHit->GetTrack())->GetPdgCode(),pHit->GetTrack()); + if(padQdc>0.1) SDigAdd(pHit->C(),pad,padQdc,GetLoader()->GetRunLoader()->Stack()->Particle(pHit->GetTrack())->GetPdgCode(),pHit->GetTrack()); }//affected pads loop }//hits loop }//prims loop GetLoader()->TreeS()->Fill(); GetLoader()->WriteSDigits("OVERWRITE"); - SDigitsReset(); + SDigReset(); }//events loop GetLoader()->UnloadHits(); GetLoader()->GetRunLoader()->UnloadHeader(); GetLoader()->GetRunLoader()->UnloadKinematics(); GetLoader()->UnloadSDigits(); @@ -250,9 +486,10 @@ void AliRICHv1::Digits2Raw() cnt[i]=0; //reset counters } - for(Int_t iChN=1;iChN<=kNchambers;iChN++){ //digits are stored on chamber by chamber basis - for(Int_t iDigN=0;iDigNGetEntriesFast();iDigN++){//digits loop for a given chamber - AliRICHDigit *pDig=(AliRICHDigit*)Digits(iChN)->At(iDigN); + for(Int_t iCh=0;iChUncheckedAt(iCh); + for(Int_t iDig=0;iDigGetEntriesFast();iDig++){//digits loop for a given chamber + AliRICHDigit *pDig=(AliRICHDigit*)pDigs->At(iDig); Int_t ddl=pDig->Dig2Raw(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 @@ -267,3 +504,171 @@ void AliRICHv1::Digits2Raw() AliDebug(1,"Stop."); }//Digits2Raw() //__________________________________________________________________________________________________ +Float_t AliRICHv1::Fresnel(Float_t ene,Float_t pdoti, Bool_t pola) +{ +// Correction for Fresnel ??????????? +// Arguments: ene - photon energy [GeV], +// PDOTI=COS(INC.ANG.), PDOTR=COS(POL.PLANE ROT.ANG.) +// Returns: + Float_t en[36] = {5.0,5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6.0,6.1,6.2, + 6.3,6.4,6.5,6.6,6.7,6.8,6.9,7.0,7.1,7.2,7.3,7.4,7.5,7.6,7.7, + 7.8,7.9,8.0,8.1,8.2,8.3,8.4,8.5}; + Float_t csin[36] = {2.14,2.21,2.33,2.48,2.76,2.97,2.99,2.59,2.81,3.05, + 2.86,2.53,2.55,2.66,2.79,2.96,3.18,3.05,2.84,2.81,2.38,2.11, + 2.01,2.13,2.39,2.73,3.08,3.15,2.95,2.73,2.56,2.41,2.12,1.95, + 1.72,1.53}; + Float_t csik[36] = {0.,0.,0.,0.,0.,0.196,0.408,0.208,0.118,0.49,0.784,0.543, + 0.424,0.404,0.371,0.514,0.922,1.102,1.139,1.376,1.461,1.253,0.878, + 0.69,0.612,0.649,0.824,1.347,1.571,1.678,1.763,1.857,1.824,1.824, + 1.714,1.498}; + Float_t xe=ene; + Int_t j=Int_t(xe*10)-49; + Float_t cn=csin[j]+((csin[j+1]-csin[j])/0.1)*(xe-en[j]); + Float_t ck=csik[j]+((csik[j+1]-csik[j])/0.1)*(xe-en[j]); + + //FORMULAE FROM HANDBOOK OF OPTICS, 33.23 OR + //W.R. HUNTER, J.O.S.A. 54 (1964),15 , J.O.S.A. 55(1965),1197 + + Float_t sinin=TMath::Sqrt(1-pdoti*pdoti); + Float_t tanin=sinin/pdoti; + + Float_t c1=cn*cn-ck*ck-sinin*sinin; + Float_t c2=4*cn*cn*ck*ck; + Float_t aO=TMath::Sqrt(0.5*(TMath::Sqrt(c1*c1+c2)+c1)); + Float_t b2=0.5*(TMath::Sqrt(c1*c1+c2)-c1); + + Float_t rs=((aO-pdoti)*(aO-pdoti)+b2)/((aO+pdoti)*(aO+pdoti)+b2); + Float_t rp=rs*((aO-sinin*tanin)*(aO-sinin*tanin)+b2)/((aO+sinin*tanin)*(aO+sinin*tanin)+b2); + + + //CORRECTION FACTOR FOR SURFACE ROUGHNESS + //B.J. STAGG APPLIED OPTICS, 30(1991),4113 + + Float_t sigraf=18.; + Float_t lamb=1240/ene; + Float_t fresn; + + Float_t rO=TMath::Exp(-(4*TMath::Pi()*pdoti*sigraf/lamb)*(4*TMath::Pi()*pdoti*sigraf/lamb)); + + if(pola) + { + Float_t pdotr=0.8; //DEGREE OF POLARIZATION : 1->P , -1->S + fresn=0.5*(rp*(1+pdotr)+rs*(1-pdotr)); + } + else + fresn=0.5*(rp+rs); + + fresn = fresn*rO; + return fresn; +}//Fresnel() +//__________________________________________________________________________________________________ +void 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 +//__________________________________________________________________________________________________ +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() +{ +// This methode is invoked from StepManager() in order to print out + static Int_t iStepN; + const char *sParticle; + switch(gMC->TrackPid()){ + case kProton: sParticle="PROTON" ;break; + case kNeutron: sParticle="neutron" ;break; + case kGamma: sParticle="gamma" ;break; + case kCerenkov: sParticle="CKOV" ;break; + case kPi0: sParticle="Pi0" ;break; + case kPiPlus: sParticle="Pi+" ;break; + case kPiMinus: sParticle="Pi-" ;break; + case kElectron: sParticle="electron" ;break; + default: sParticle="not known" ;break; + } + + TString flag="fanny combination"; + if(gMC->IsTrackAlive()) + if(gMC->IsTrackEntering()) flag="enters to"; + else if(gMC->IsTrackExiting()) flag="exits from"; + else if(gMC->IsTrackInside()) flag="inside"; + else + if(gMC->IsTrackStop()) flag="stoped in"; + + Int_t vid=0,copy=0; + TString path=gMC->CurrentVolName(); path.Prepend("-");path.Prepend(gMC->CurrentVolOffName(1));//current volume and his mother are always there + vid=gMC->CurrentVolOffID(2,copy); if(vid) {path.Prepend("-");path.Prepend(gMC->VolName(vid));} + vid=gMC->CurrentVolOffID(3,copy); if(vid) {path.Prepend("-");path.Prepend(gMC->VolName(vid));} + + Printf("Step %i: %s (%i) %s %s m=%.6f GeV q=%.1f dEdX=%.4f",iStepN,sParticle,gMC->TrackPid(),flag.Data(),path.Data(),gMC->TrackMass(),gMC->TrackCharge(),gMC->Edep()*1e9); + + Printf("Step %i: tid=%i flags alive=%i disap=%i enter=%i exit=%i inside=%i out=%i stop=%i new=%i", + iStepN, gAlice->GetMCApp()->GetCurrentTrackNumber(), + gMC->IsTrackAlive(), gMC->IsTrackDisappeared(),gMC->IsTrackEntering(), gMC->IsTrackExiting(), + gMC->IsTrackInside(),gMC->IsTrackOut(), gMC->IsTrackStop(), gMC->IsNewTrack()); + + Float_t a,z,den,rad,abs; a=z=den=rad=abs=-1; + Int_t mid=gMC->CurrentMaterial(a,z,den,rad,abs); + Printf("Step %i: id=%i a=%7.2f z=%7.2f den=%9.4f rad=%9.2f abs=%9.2f\n\n",iStepN,mid,a,z,den,rad,abs); + iStepN++; +}//StepHistory() +//__________________________________________________________________________________________________ +void AliRICHv1::StepManager() +{ +// Full Step Manager. +// Arguments: none +// Returns: none +// StepHistory(); return; //uncomment to print tracks history +// StepCount(); return; //uncomment to count photons + + Int_t copy; //volume copy aka node + static Int_t iCham; +//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 + +//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(); + }//MIP in GAP +}//StepManager() +//__________________________________________________________________________________________________ diff --git a/RICH/AliRICHv1.h b/RICH/AliRICHv1.h index 8065a36cca9..50bf46e3da5 100644 --- a/RICH/AliRICHv1.h +++ b/RICH/AliRICHv1.h @@ -5,26 +5,35 @@ * See cxx source for full Copyright notice */ #include "AliRICH.h" //base class -#include "AliRICHDigitizer.h" //CreateDigitizer() +#include "AliRICHDigitizer.h" //CreateDigitizer() -class AliRICHv1 : public AliRICH +class AliRICHv1 : public AliRICH //TObject-TNamed-AliModule-AliDetector-AliRICH-AliRICHv0 { public: AliRICHv1():AliRICH() {;} //default ctor AliRICHv1(const char *name, const char *title):AliRICH(name,title) {;} //named ctor virtual ~AliRICHv1() {;} //dtor -//framework part - void Init() {;} - Int_t IsVersion ( )const{return 1;} - void StepManager ( ); //called from AliSimulation or AliRun when transport particles - void Hits2SDigits ( ); //called from AliSimulation for Hits->SDigits - AliDigitizer* CreateDigitizer (AliRunDigitizer *pMan )const{return new AliRICHDigitizer(pMan);} //called from AliSimulation for SDigits->Digits - void Digits2Raw ( ); //called from AliSimulation for Digits->Raw -//private part - Bool_t IsLostByFresnel (); //checks if the photon lost on Fresnel reflection - void GenerateFeedbacks(Int_t iChamber,Float_t eloss=0); //generates feedback photons; eloss=0 for photon +//framework part++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + void CreateMaterials ( ); //from AliModule invoked from AliMC::ConstructGeometry() + void CreateGeometry ( ); //from AliModule invoked from AliMC::ConstructGeometry() + AliDigitizer* CreateDigitizer (AliRunDigitizer *m )const{return new AliRICHDigitizer(m);} //from AliModule invoked from AliSimulation::RunDigitization() + void Digits2Raw ( ); //from AliModule invoked from AliSimulation::WriteRawFiles() + void Hits2SDigits ( ); //from AliModule invoked from AliSimulation::RunSDigitization() + void Init ( ); //from AliModule invoked from AliMC::InitGeometry() + Int_t IsVersion ( )const{return 1; } //from AliModule not used + void Print (const Option_t *opt="" )const; //from TObject + void StepManager ( ); //from AliModule invoked from AliMC::Stepping() +//private part++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + void GenFee (Int_t iCh,Float_t eloss=0 ); //generates feedback photons; eloss=0 for photon + static Float_t Fresnel (Float_t geV,Float_t p, Bool_t pl); //deals with Fresnel absorption on PC + Bool_t IsLostByFresnel ( ); //checks if the photon lost on Fresnel reflection + void StepCount ( ); //counts particles in StepManager() + void StepHistory ( ); //prints history of tracking in StepManager() protected: - ClassDef(AliRICHv1,1) //RICH full version for simulation + enum EMedia {kAir=1,kRoha=2,kSiO2=3,kC6F14=4,kCH4=5,kCsI=6,kAl=7,kCu=8,kW=9}; //media ids, used for geometry creation + enum Ecounters {kMipEnterRad=1,kCkovNew,kCkovNewRad,kCkovNewWin,kCkovNewProxGap,kCkovNewAmpGap,kCkovEnterPc,kPhotoEle}; //counters id's + Int_t fIdRad,fIdWin,fIdProxGap,fIdAmpGap,fIdPc,fIdAnod,fIdCath,fIdColl; //! volumes ID's used in StepManager() and Count() + ClassDef(AliRICHv1,2) //RICH full version for simulation }; #endif diff --git a/RICH/Opticals.h b/RICH/Opticals.h deleted file mode 100644 index ede72012764..00000000000 --- a/RICH/Opticals.h +++ /dev/null @@ -1,252 +0,0 @@ -#ifdef __CINT__ -void Opticals() -{ - gROOT->Reset(); -#endif - int i; - const Int_t kNbins=30;//number of photon energy points - - Float_t aPckov[kNbins]; for(i=0;iDivide(3,2); -//Ref index - pC->cd(1); - TGraph *pIdxC6F14=new TGraph(kNbins,aPckov,aIdxC6F14);pIdxC6F14->SetMarkerStyle(kC6F14Marker);pIdxC6F14->SetMarkerColor(kC6F14Color); - TGraph *pIdxSiO2 =new TGraph(kNbins,aPckov,aIdxSiO2); pIdxSiO2 ->SetMarkerStyle(kSiO2M) ;pIdxSiO2 ->SetMarkerColor(kSiO2Color); - TGraph *pIdxCH4 =new TGraph(kNbins,aPckov,aIdxCH4); pIdxCH4 ->SetMarkerStyle(kCH4Marker) ;pIdxCH4 ->SetMarkerColor(kCH4Color); - TGraph *pIdxGel =new TGraph(kNbins,aPckov,aIdxGel); pIdxGel ->SetMarkerStyle(kGelMarker) ;pIdxGel ->SetMarkerColor(kGelColor); - - TMultiGraph *pIdxMG=new TMultiGraph(); 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"); - pIdxMG->Add(pIdxGel) ; pIdxLe->AddEntry(pIdxGel ,"Aerogel","p"); - pIdxMG->Draw("APL"); - pIdxMG->SetTitle("Refractive index"); pIdxMG->GetXaxis()->SetTitle("energy, GeV"); - pIdxMG->Draw("APL"); - pIdxLe->Draw(); -//Absorbtion - pC->cd(2); - gPad->SetLogy(); - TGraph *pAbsC6F14=new TGraph(kNbins,aPckov,aAbsC6F14);pAbsC6F14->SetMarkerStyle(kC6F14Marker); pAbsC6F14->SetMarkerColor(kC6F14Color); - TGraph *pAbsSiO2 =new TGraph(kNbins,aPckov,aAbsSiO2) ;pAbsSiO2 ->SetMarkerStyle(kSiO2M) ; pAbsSiO2 ->SetMarkerColor(kSiO2Color); - TGraph *pAbsCH4 =new TGraph(kNbins,aPckov,aAbsCH4) ;pAbsCH4 ->SetMarkerStyle(kCH4Marker) ; pAbsCH4 ->SetMarkerColor(kCH4Color); - TGraph *pAbsGel =new TGraph(kNbins,aPckov,aAbsGel) ;pAbsGel ->SetMarkerStyle(kGelMarker) ; pAbsGel ->SetMarkerColor(kGelColor); - TGraph *pAbsRef =new TGraph(kNbins,aPckov,aAbsRef) ;pAbsRef ->SetMarkerStyle(kRefMarker) ; pAbsRef ->SetMarkerColor(kRefColor); - - TMultiGraph *pAbsMG=new TMultiGraph(); 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"); - pAbsMG->Add(pAbsGel); pAbsLe->AddEntry(pAbsGel , "Aerogel" ,"p"); - pAbsMG->Add(pAbsRef); pAbsLe->AddEntry(pAbsRef , "Reflector","p"); - pAbsMG->Draw("APL"); - pAbsMG->SetTitle("Absorbtion length,cm"); pAbsMG->GetXaxis()->SetTitle("energy, GeV"); - pAbsMG->Draw("APL"); - pAbsLe->Draw(); -//QE - pC->cd(4); - TGraph *pQeCsI=new TGraph(kNbins,aPckov,aQeCsI); pQeCsI->SetMarkerStyle(kCsIMarker); pQeCsI->SetMarkerColor(kCsIColor); - pQeCsI->Draw("APL"); - pQeCsI->SetTitle("QE"); pQeCsI->GetXaxis()->SetTitle("energy, GeV"); - pQeCsI->Draw("APL"); -//transmission - pC->cd(5); - Float_t mm =0.1;Float_t cm=1.; - Float_t aTrC6F14[kNbins],aTrSiO2[kNbins],aTrCH4[kNbins]; - Float_t aTotTr[kNbins]; - for(Int_t i=0;iSetMarkerStyle(kC6F14Marker);pTrC6F14->SetMarkerColor(kC6F14Color); - TGraph *pTrSiO2 =new TGraph(kNbins,aPckov,aTrSiO2) ;pTrSiO2 ->SetMarkerStyle(kSiO2M) ;pTrSiO2 ->SetMarkerColor(kSiO2Color); - TGraph *pTrCH4 =new TGraph(kNbins,aPckov,aTrCH4) ;pTrCH4 ->SetMarkerStyle(kCH4Marker) ;pTrCH4 ->SetMarkerColor(kCH4Color); - TGraph *pTotTr =new TGraph(kNbins,aPckov,aTotTr) ;pTotTr ->SetMarkerStyle(30) ;pTotTr ->SetMarkerColor(kYellow); - - TMultiGraph *pTrMG=new TMultiGraph(); 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(pTotTr); pTrLe->AddEntry(pTotTr, "total", "p"); - pTrMG->Draw("APL"); - pTrMG->SetTitle("Transmission"); pTrMG->GetXaxis()->SetTitle("energy, GeV"); - pTrMG->Draw("APL"); - pTrLe->Draw(); -//comparison of new and old staff - pC->cd(6); - TGraph *pQeCsIold=new TGraph(kNbins,aPckov,aQeCsIold); pQeCsIold->SetMarkerStyle(kC6F14Marker);pQeCsIold->SetMarkerColor(kC6F14Color); - - TMultiGraph *pCompMG=new TMultiGraph; 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"); - pCompMG->Draw("APL"); - pCompMG->SetTitle("Comparison of new and old staff"); - pCompMG->GetXaxis()->SetTitle("energy, GeV"); - pCompMG->Draw("APL"); - pCompLe->Draw(); - - return; - TCanvas *pQeC=new TCanvas("pQeC","CsI QE currently all the same",800,900); - pQeC->Divide(2,4); - for(int i=1;i<=7;i++){ - pQeC->cd(i); - switch(i){ - case 1: TGraph *pQeCsIGr=new TGraph(kNbins,aPckov,aQeCsI);pQeCsIGr->SetTitle("Module 1");break; - case 2: TGraph *pQeCsIGr=new TGraph(kNbins,aPckov,aQeCsI);pQeCsIGr->SetTitle("Module 2");break; - case 3: TGraph *pQeCsIGr=new TGraph(kNbins,aPckov,aQeCsI);pQeCsIGr->SetTitle("Module 3");break; - case 4: TGraph *pQeCsIGr=new TGraph(kNbins,aPckov,aQeCsI);pQeCsIGr->SetTitle("Module 4");break; - case 5: TGraph *pQeCsIGr=new TGraph(kNbins,aPckov,aQeCsI);pQeCsIGr->SetTitle("Module 5");break; - case 6: TGraph *pQeCsIGr=new TGraph(kNbins,aPckov,aQeCsI);pQeCsIGr->SetTitle("Module 6");break; - case 7: TGraph *pQeCsIGr=new TGraph(kNbins,aPckov,aQeCsI);pQeCsIGr->SetTitle("Module 7");break; - } - pQeCsIGr->SetMarkerStyle(kCsIMarker); pQeCsIGr->SetMarkerColor(kCsIColor); - pQeCsIGr->Draw("APL"); - pQeCsIGr->GetXaxis()->SetTitle("energy, GeV"); - pQeCsIGr->Draw("APL"); - } -}//main -//__________________________________________________________________________________________________ -Float_t Fresnel(Float_t ene,Float_t pdoti, Bool_t pola) -{//ENE(EV), PDOTI=COS(INC.ANG.), PDOTR=COS(POL.PLANE ROT.ANG.) - - Float_t en[36] = {5.0,5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6.0,6.1,6.2, - 6.3,6.4,6.5,6.6,6.7,6.8,6.9,7.0,7.1,7.2,7.3,7.4,7.5,7.6,7.7, - 7.8,7.9,8.0,8.1,8.2,8.3,8.4,8.5}; - - - Float_t csin[36] = {2.14,2.21,2.33,2.48,2.76,2.97,2.99,2.59,2.81,3.05, - 2.86,2.53,2.55,2.66,2.79,2.96,3.18,3.05,2.84,2.81,2.38,2.11, - 2.01,2.13,2.39,2.73,3.08,3.15,2.95,2.73,2.56,2.41,2.12,1.95, - 1.72,1.53}; - - Float_t csik[36] = {0.,0.,0.,0.,0.,0.196,0.408,0.208,0.118,0.49,0.784,0.543, - 0.424,0.404,0.371,0.514,0.922,1.102,1.139,1.376,1.461,1.253,0.878, - 0.69,0.612,0.649,0.824,1.347,1.571,1.678,1.763,1.857,1.824,1.824, - 1.714,1.498}; - Float_t xe=ene; - Int_t j=Int_t(xe*10)-49; - Float_t cn=csin[j]+((csin[j+1]-csin[j])/0.1)*(xe-en[j]); - Float_t ck=csik[j]+((csik[j+1]-csik[j])/0.1)*(xe-en[j]); - - //FORMULAE FROM HANDBOOK OF OPTICS, 33.23 OR - //W.R. HUNTER, J.O.S.A. 54 (1964),15 , J.O.S.A. 55(1965),1197 - - Float_t sinin=TMath::Sqrt(1-pdoti*pdoti); - Float_t tanin=sinin/pdoti; - - Float_t c1=cn*cn-ck*ck-sinin*sinin; - Float_t c2=4*cn*cn*ck*ck; - Float_t aO=TMath::Sqrt(0.5*(TMath::Sqrt(c1*c1+c2)+c1)); - Float_t b2=0.5*(TMath::Sqrt(c1*c1+c2)-c1); - - Float_t rs=((aO-pdoti)*(aO-pdoti)+b2)/((aO+pdoti)*(aO+pdoti)+b2); - Float_t rp=rs*((aO-sinin*tanin)*(aO-sinin*tanin)+b2)/((aO+sinin*tanin)*(aO+sinin*tanin)+b2); - - - //CORRECTION FACTOR FOR SURFACE ROUGHNESS - //B.J. STAGG APPLIED OPTICS, 30(1991),4113 - - Float_t sigraf=18.; - Float_t lamb=1240/ene; - Float_t fresn; - - Float_t rO=TMath::Exp(-(4*TMath::Pi()*pdoti*sigraf/lamb)*(4*TMath::Pi()*pdoti*sigraf/lamb)); - - if(pola) - { - Float_t pdotr=0.8; //DEGREE OF POLARIZATION : 1->P , -1->S - fresn=0.5*(rp*(1+pdotr)+rs*(1-pdotr)); - } - else - fresn=0.5*(rp+rs); - - fresn = fresn*rO; - return(fresn); -}//Fresnel() -#endif diff --git a/RICH/RICHbaseLinkDef.h b/RICH/RICHbaseLinkDef.h index 9f1d4a6d9d1..0938cffe02e 100644 --- a/RICH/RICHbaseLinkDef.h +++ b/RICH/RICHbaseLinkDef.h @@ -3,7 +3,6 @@ #pragma link off all classes; #pragma link off all functions; #pragma link C++ class AliRICHParam+; -#pragma link C++ class AliRICHChamber+; #pragma link C++ class AliRICH+; #pragma link C++ class AliRICHHit+; #pragma link C++ class AliRICHDigit+; diff --git a/RICH/RICHrecLinkDef.h b/RICH/RICHrecLinkDef.h index 6b02a320e9b..0147b149ad5 100644 --- a/RICH/RICHrecLinkDef.h +++ b/RICH/RICHrecLinkDef.h @@ -2,9 +2,7 @@ #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class AliRICHMap+; #pragma link C++ class AliRICHReconstructor+; -#pragma link C++ class AliRICHClusterFinder+; #pragma link C++ class AliRICHTracker+; #pragma link C++ class AliRICHRecon+; #endif diff --git a/RICH/RichConfig.C b/RICH/RichConfig.C index 2d7ac1ffcef..0cd2adb3278 100644 --- a/RICH/RichConfig.C +++ b/RICH/RichConfig.C @@ -8,7 +8,7 @@ public: ~RichConfig() {Info("ctor","");Cleanup();} enum EVersOpts {kNo=101,kVer0,kVer1,kVer2,kTest, kDeclust=301,kSagita,kFeedback,kSecRad,kQe0=400,kQeNorm,kOptics}; - enum EGenTypes {kGunZ=1,kGun1,kGun7,kBox1,kBox7,kHijing,kHijingPara,kPythia,kRichLib,kNotUsed=999}; + enum EGenTypes {kGunZ=1,kGun1,kGun7,kBox,kHijing,kHijingPara,kPythia,kRichLib,kNotUsed=999}; enum EDetectors {kPIPE=1,kITS,kTPC,kTRD,kTOF,kFRAME,kMAG,kCRT,kHALL,kPHOS,kSTART,kFMD,kABSO,kPMD,kDIPO,kEMCAL,kVZERO,kMUON,kZDC,kSHILD}; enum EProcesses {kDCAY=1,kPAIR,kCOMP,kPHOT,kPFIS,kDRAY,kANNI,kBREM,kMUNU,kCKOV,kHADR,kLOSS,kMULS,kRAYL,kALL}; @@ -183,8 +183,7 @@ void RichConfig::GuiGen(TGCompositeFrame *pMainF) new TGCheckButton(fGenBG,"gun along z" ,kGunZ); new TGCheckButton(fGenBG,"gun to 1 chamber" ,kGun1); new TGCheckButton(fGenBG,"gun to 7 chambers" ,kGun7); - new TGCheckButton(fGenBG,"box to 1 chamber" ,kBox1); - new TGCheckButton(fGenBG,"box to 7 chambers" ,kBox7); + new TGCheckButton(fGenBG,"box RICH phase space" ,kBox ); new TGCheckButton(fGenBG,"HIJING" ,kHijing); new TGCheckButton(fGenBG,"HIJING para" ,kHijingPara); new TGCheckButton(fGenBG,"Pythia" ,kPythia); @@ -195,7 +194,10 @@ void RichConfig::GuiGen(TGCompositeFrame *pMainF) fGenNprimCO->AddEntry("N prim=1" ,1); fGenNprimCO->AddEntry("N prim=2" ,2); fGenNprimCO->AddEntry("N prim=5" ,5); + fGenNprimCO->AddEntry("N prim=100" ,100); fGenNprimCO->AddEntry("N prim=500" ,500); + fGenNprimCO->AddEntry("N prim=1000" ,1000); + fGenNprimCO->AddEntry("N prim=10000",10000); fGenNprimCO->AddEntry("N prim=80000",80000); fGenNprimCO->Resize(160,20); fGenNprimCO->Select(kNotUsed); //PID fGenF->AddFrame(fGenPidCO=new TGComboBox(fGenF,100)); //add pid combo to generator vertical frame @@ -230,32 +232,23 @@ void RichConfig::GenAddSlot(Int_t id) if(id==kGunZ){ fGenBG->GetButton(kGun1)->SetEnabled(kFALSE); fGenF->HideFrame(fGenNprimCO); fGenBG->GetButton(kGun7)->SetEnabled(kFALSE); fGenPidCO->Select(kProton); - fGenBG->GetButton(kBox1)->SetEnabled(kFALSE); fGenF->HideFrame(fGenPmaxCO); fGenPminCO->Select(25); - fGenBG->GetButton(kBox7)->SetEnabled(kFALSE); fGenF->HideFrame(fGenChamCO); + fGenBG->GetButton(kBox )->SetEnabled(kFALSE); fGenF->HideFrame(fGenPmaxCO); fGenPminCO->Select(25); } if(id==kGun1){ fGenBG->GetButton(kGunZ)->SetEnabled(kFALSE); fGenF->HideFrame(fGenNprimCO); fGenBG->GetButton(kGun7)->SetEnabled(kFALSE); fGenF->HideFrame(fGenPmaxCO); - fGenBG->GetButton(kBox1)->SetEnabled(kFALSE); - fGenBG->GetButton(kBox7)->SetEnabled(kFALSE); fGenPidCO->Select(kProton); fGenPminCO->Select(25); fGenChamCO->Select(4); + fGenBG->GetButton(kBox )->SetEnabled(kFALSE); } if(id==kGun7){ fGenBG->GetButton(kGunZ)->SetEnabled(kFALSE); fGenF->HideFrame(fGenNprimCO); fGenBG->GetButton(kGun1)->SetEnabled(kFALSE); fGenPidCO->Select(kProton); - fGenBG->GetButton(kBox1)->SetEnabled(kFALSE); fGenF->HideFrame(fGenPmaxCO); fGenPminCO->Select(25); - fGenBG->GetButton(kBox7)->SetEnabled(kFALSE); fGenF->HideFrame(fGenChamCO); + fGenBG->GetButton(kBox )->SetEnabled(kFALSE); fGenF->HideFrame(fGenPmaxCO); fGenPminCO->Select(25); + fGenF->HideFrame(fGenChamCO); } - if(id==kBox1){ - fGenBG->GetButton(kGunZ)->SetEnabled(kFALSE); fGenNprimCO->Select(1); + if(id==kBox){ + fGenBG->GetButton(kGunZ)->SetEnabled(kFALSE); fGenNprimCO->Select(500); fGenBG->GetButton(kGun1)->SetEnabled(kFALSE); fGenPidCO ->Select(kProton); - fGenBG->GetButton(kGun7)->SetEnabled(kFALSE); fGenPminCO ->Select(5); fGenPmaxCO->Select(25); - fGenBG->GetButton(kBox7)->SetEnabled(kFALSE); fGenChamCO ->Select(4); - } - if(id==kBox7){ - fGenBG->GetButton(kGunZ)->SetEnabled(kFALSE); fGenNprimCO->Select(1); - fGenBG->GetButton(kGun1)->SetEnabled(kFALSE); fGenPidCO ->Select(kProton); - fGenBG->GetButton(kGun1)->SetEnabled(kFALSE); fGenPminCO ->Select(5); fGenPmaxCO->Select(25); - fGenBG->GetButton(kBox1)->SetEnabled(kFALSE); fGenF->HideFrame(fGenChamCO); + fGenBG->GetButton(kGun7)->SetEnabled(kFALSE); fGenPminCO ->Select(15); fGenPmaxCO->Select(15); } if(id==kHijing){ fGenBG->GetButton(kHijing)->ChangeBackground(0xff0000); @@ -277,32 +270,24 @@ void RichConfig::GenRemSlot(Int_t id) if(id==kGunZ){ fGenBG->GetButton(kGun1)->SetEnabled(); fGenF->ShowFrame(fGenNprimCO); fGenBG->GetButton(kGun7)->SetEnabled(); fGenPidCO ->Select(kNotUsed); - fGenBG->GetButton(kBox1)->SetEnabled(); fGenF->ShowFrame(fGenPmaxCO); fGenPminCO ->Select(kNotUsed); - fGenBG->GetButton(kBox7)->SetEnabled(); fGenF->ShowFrame(fGenChamCO); + fGenBG->GetButton(kBox )->SetEnabled(); fGenF->ShowFrame(fGenPmaxCO); fGenPminCO ->Select(kNotUsed); } if(id==kGun1){ fGenBG->GetButton(kGunZ)->SetEnabled(); fGenF->ShowFrame(fGenNprimCO); fGenBG->GetButton(kGun7)->SetEnabled(); fGenPidCO ->Select(kNotUsed); - fGenBG->GetButton(kBox1)->SetEnabled(); fGenF->ShowFrame(fGenPmaxCO); fGenPminCO ->Select(kNotUsed); - fGenBG->GetButton(kBox7)->SetEnabled(); fGenChamCO ->Select(kNotUsed); + fGenBG->GetButton(kBox )->SetEnabled(); fGenF->ShowFrame(fGenPmaxCO); fGenPminCO ->Select(kNotUsed); } if(id==kGun7){ fGenBG->GetButton(kGunZ)->SetEnabled(); fGenF->ShowFrame(fGenNprimCO); fGenBG->GetButton(kGun1)->SetEnabled(); fGenPidCO ->Select(kNotUsed); - fGenBG->GetButton(kBox1)->SetEnabled(); fGenF->ShowFrame(fGenPmaxCO); fGenPminCO ->Select(kNotUsed); - fGenBG->GetButton(kBox7)->SetEnabled(); fGenF->ShowFrame(fGenChamCO); + fGenBG->GetButton(kBox )->SetEnabled(); fGenF->ShowFrame(fGenPmaxCO); fGenPminCO ->Select(kNotUsed); + fGenF->ShowFrame(fGenChamCO); } - if(id==kBox1){ + if(id==kBox){ fGenBG->GetButton(kGunZ)->SetEnabled(); fGenNprimCO->Select(kNotUsed); fGenBG->GetButton(kGun1)->SetEnabled(); fGenPidCO ->Select(kNotUsed); fGenBG->GetButton(kGun7)->SetEnabled(); fGenPminCO ->Select(kNotUsed); fGenPmaxCO->Select(kNotUsed); - fGenBG->GetButton(kBox7)->SetEnabled(); fGenChamCO ->Select(kNotUsed); - } - if(id==kBox7){ - fGenBG->GetButton(kGunZ)->SetEnabled(); fGenNprimCO->Select(kNotUsed); - fGenBG->GetButton(kGun1)->SetEnabled(); fGenPidCO ->Select(kNotUsed); - fGenBG->GetButton(kGun1)->SetEnabled(); fGenPminCO ->Select(kNotUsed); fGenPmaxCO->Select(kNotUsed); - fGenBG->GetButton(kBox1)->SetEnabled(); fGenF->ShowFrame(fGenChamCO); + fGenChamCO ->Select(kNotUsed); } if(id==kHijing){ fGenBG->GetButton(kHijing)->ChangeBackground(0xbebebe); @@ -321,61 +306,78 @@ void RichConfig::GenRemSlot(Int_t id) //__________________________________________________________________________________________________ void RichConfig::WriteGen(FILE *pF) { - fprintf(pF," AliGenCocktail *pCocktail=new AliGenCocktail();\n\n"); - if(fGenBG->GetButton(kGunZ)->GetState()==kButtonDown){//1 particle along Z axis - fprintf(pF," AliGenFixed *pGunZ=new AliGenFixed(1);\n"); - fprintf(pF," pGunZ->SetPart(%i); pGunZ->SetMomentum(%.1f); pGunZ->SetOrigin(0,0,-200);\n",fGenPidCO->GetSelected(),float(fGenPminCO->GetSelected())/10); - fprintf(pF," pCocktail->AddGenerator(pGunZ,\"gunZ\",1);\n\n"); - } + Int_t pid=fGenPidCO->GetSelected(); + Float_t pmin=0.1*fGenPminCO->GetSelected(); //particle momentum, GeV + Float_t pmax=0.1*fGenPmaxCO->GetSelected(); //particle momentum, GeV + + fprintf(pF," AliGenCocktail *pG=new AliGenCocktail();\n\n"); + + if(fGenBG->GetButton(kGunZ)->GetState()==kButtonDown)//1 particle along Z axis + fprintf(pF," AliGenFixed *pGz=new AliGenFixed(1); pGz->SetPart(%i); pGz->SetMomentum(%.1f); pGz->SetOrigin(0,0,-200); pG->AddGenerator(pGz,\"Gz\",1);\n",pid,p); + if(fGenBG->GetButton(kGun1)->GetState()==kButtonDown){//1 gun towards 1 RICH chamber - fprintf(pF," AliGenFixed *pGun1=new AliGenFixed(1);\n"); - fprintf(pF," pGun1->SetPart(%i); pGun1->SetMomentum(%.1f);\n",fGenPidCO->GetSelected(),float(fGenPminCO->GetSelected())/10); - fprintf(pF," pGun1->SetTheta(AliRICHParam::Norm(%i).Theta()*TMath::RadToDeg()-2);\n",fGenChamCO->GetSelected()); - fprintf(pF," pGun1->SetPhi(AliRICHParam::Norm(%i).Phi()*TMath::RadToDeg()-2);\n" ,fGenChamCO->GetSelected()); - fprintf(pF," pCocktail->AddGenerator(pGun1,\"gun1\",1);\n\n"); + switch(fGenChamCO->GetSelected()){ + case 1: fprintf(pF," AliGenFixed *pG1=new AliGenFixed(1); pG1->SetPart(%i); pG1->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG1->SetTheta(109.5); pG1->SetPhi(10); pG->AddGenerator(pG1,\"g1\",1);\n"); break; + case 2: fprintf(pF," AliGenFixed *pG2=new AliGenFixed(1); pG2->SetPart(%i); pG2->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG2->SetTheta( 90.0); pG2->SetPhi(10); pG->AddGenerator(pG2,\"g2\",1);\n"); break; + case 3: fprintf(pF," AliGenFixed *pG3=new AliGenFixed(1); pG3->SetPart(%i); pG3->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG3->SetTheta(109.5); pG3->SetPhi(30); pG->AddGenerator(pG3,\"g3\",1);\n"); break; + case 4: fprintf(pF," AliGenFixed *pG4=new AliGenFixed(1); pG4->SetPart(%i); pG4->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG4->SetTheta( 90.0); pG4->SetPhi(30); pG->AddGenerator(pG4,\"g4\",1);\n"); break; + case 5: fprintf(pF," AliGenFixed *pG5=new AliGenFixed(1); pG5->SetPart(%i); pG5->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG5->SetTheta( 70.5); pG5->SetPhi(30); pG->AddGenerator(pG5,\"g5\",1);\n"); break; + case 6: fprintf(pF," AliGenFixed *pG6=new AliGenFixed(1); pG6->SetPart(%i); pG6->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG6->SetTheta( 90.0); pG6->SetPhi(50); pG->AddGenerator(pG6,\"g6\",1);\n"); break; + case 7: fprintf(pF," AliGenFixed *pG7=new AliGenFixed(1); pG7->SetPart(%i); pG7->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG7->SetTheta( 70.5); pG7->SetPhi(50); pG->AddGenerator(pG7,\"g7\",1);\n"); break; + } } + if(fGenBG->GetButton(kGun7)->GetState()==kButtonDown){//7 guns towards 7 RICH chambers - fprintf(pF," for(int i=1;i<=7;i++){\n"); - fprintf(pF," AliGenFixed *pGun7=new AliGenFixed(1);\n"); - fprintf(pF," pGun7->SetPart(%i); pGun7->SetMomentum(1.0+i*0.5);\n",fGenPidCO->GetSelected()); - fprintf(pF," pGun7->SetTheta(AliRICHParam::Norm(i).Theta()*TMath::RadToDeg()); pGun7->SetPhi(AliRICHParam::Norm(i).Phi()*TMath::RadToDeg()); \n"); - fprintf(pF," pCocktail->AddGenerator(pGun7,Form(\"gun7-%%i\",i),1);\n }\n\n"); - } - if(fGenBG->GetButton(kBox1)->GetState()==kButtonDown){//1 box towards 1 RICH chamber - fprintf(pF," AliGenBox *pBox1=new AliGenBox(1);\n"); - fprintf(pF," pBox1->SetPart(%i); pBox1->SetMomentumRange(%.1f,%.1f);\n",fGenPidCO->GetSelected(),float(fGenPminCO->GetSelected())/10,float(fGenPmaxCO->GetSelected())/10); - fprintf(pF," pBox1->SetThetaRange(pRICH->C(%i)->ThetaD()-3,pRICH->C(%i)->ThetaD()-1); \n",fGenChamCO->GetSelected(),fGenChamCO->GetSelected()); - fprintf(pF," pBox1->SetPhiRange(pRICH->C(%i)->PhiD()-1,pRICH->C(%i)->PhiD()+1); \n",fGenChamCO->GetSelected(),fGenChamCO->GetSelected()); - fprintf(pF," pCocktail->AddGenerator(pBox1,\"box1\",1);\n\n"); + fprintf(pF," AliGenFixed *pG1=new AliGenFixed(1); pG1->SetPart(%i); pG1->SetMomentum(1.5);pG1->SetTheta(109.5-3); pG1->SetPhi(10);\n",pid); + fprintf(pF," pG->AddGenerator(pG1,\"g1\",1);\n"); + fprintf(pF," AliGenFixed *pG2=new AliGenFixed(1); pG2->SetPart(%i); pG2->SetMomentum(1.5);pG2->SetTheta( 90.0-3); pG2->SetPhi(10);\n",pid); + fprintf(pF," pG->AddGenerator(pG2,\"g2\",1);\n"); + fprintf(pF," AliGenFixed *pG3=new AliGenFixed(1); pG3->SetPart(%i); pG3->SetMomentum(1.5);pG3->SetTheta(109.5-3); pG3->SetPhi(30);\n",pid); + fprintf(pF," pG->AddGenerator(pG3,\"g3\",1);\n"); + fprintf(pF," AliGenFixed *pG4=new AliGenFixed(1); pG4->SetPart(%i); pG4->SetMomentum(1.5);pG4->SetTheta( 90.0-3); pG4->SetPhi(30);\n",pid); + fprintf(pF," pG->AddGenerator(pG4,\"g4\",1);\n"); + fprintf(pF," AliGenFixed *pG5=new AliGenFixed(1); pG5->SetPart(%i); pG5->SetMomentum(1.5);pG5->SetTheta( 70.0-3); pG5->SetPhi(30);\n",pid); + fprintf(pF," pG->AddGenerator(pG5,\"g5\",1);\n"); + fprintf(pF," AliGenFixed *pG6=new AliGenFixed(1); pG6->SetPart(%i); pG6->SetMomentum(1.5);pG6->SetTheta( 90.0-3); pG6->SetPhi(50);\n",pid); + fprintf(pF," pG->AddGenerator(pG6,\"g6\",1);\n"); + fprintf(pF," AliGenFixed *pG7=new AliGenFixed(1); pG7->SetPart(%i); pG7->SetMomentum(1.5);pG7->SetTheta( 70.0-3); pG7->SetPhi(50);\n",pid); + fprintf(pF," pG->AddGenerator(pG7,\"g7\",1);\n"); + } + + if(fGenBG->GetButton(kBox)->GetState()==kButtonDown){// box towards RICH phase space + fprintf(pF," AliGenBox *pB=new AliGenBox(%i); pB->SetPart(%i); pB->SetMomentumRange(%.1f,%.1f);\n",(int)fGenNprimCO->GetSelected(),pid,pmin,pmax); + fprintf(pF," pB->SetThetaRange(65,115); pB->SetPhiRange(5,55); pG->AddGenerator(pB,\"b\",1);\n"); } - if(fGenBG->GetButton(kBox7)->GetState()==kButtonDown){//7 boxes towards 7 RICH chambers - fprintf(pF," for(int i=1;i<=7;i++){\n"); - fprintf(pF," AliGenBox *pBox7=new AliGenBox(1);\n"); - fprintf(pF," pBox7->SetPart(%i); pBox7->SetMomentumRange(%.1f,%.1f); \n",fGenPidCO->GetSelected(),float(fGenPminCO->GetSelected())/10,float(fGenPmaxCO->GetSelected())/10); - fprintf(pF," pBox7->SetThetaRange(AliRICHParam::Norm(i)-3,AliRICHParam::Norm(i)+3); pBox7->SetPhiRange(pRICH->C(i)->PhiD()-1,pRICH->C(i)->PhiD()+1); \n"); - fprintf(pF," pCocktail->AddGenerator(pBox7,Form(\"Box %i\",i),1);\n }\n\n"); - } + if(fGenBG->GetButton(kHijing)->GetState()==kButtonDown){//normal HIJING - fprintf(pF," AliGenHijing *pHij=new AliGenHijing(-1); pHij->SetEnergyCMS(5500); pHij->SetReferenceFrame(\"CMS\");\n"); - fprintf(pF," pHij->SetProjectile(\"A\", 208, 82); pHij->SetTarget(\"A\", 208, 82);\n"); - fprintf(pF," pHij->SetJetQuenching(0); pHij->SetShadowing(0);\n"); - fprintf(pF," pHij->KeepFullEvent(); pHij->SetSelectAll(0); \n"); - fprintf(pF," pHij->SetImpactParameterRange(0, 5); //fermi\n"); - fprintf(pF," pCocktail->AddGenerator(pHij,\"hijing\",1);\n\n"); + fprintf(pF," AliGenHijing *pH=new AliGenHijing(-1); pH->SetEnergyCMS(5500); pH->SetReferenceFrame(\"CMS\");\n"); + fprintf(pF," pH->SetProjectile(\"A\", 208, 82); pH->SetTarget(\"A\", 208, 82); pH->SetJetQuenching(0);\n"); + fprintf(pF," pH->SetShadowing(0); pH->KeepFullEvent(); pH->SetSelectAll(0);\n"); + fprintf(pF," pH->SetImpactParameterRange(0, 5); //fermi\n"); + fprintf(pF," pG->AddGenerator(pH,\"h\",1);\n\n"); } + if(fGenBG->GetButton(kHijingPara)->GetState()==kButtonDown){//parametrized HIJING - fprintf(pF," AliGenHIJINGpara *pHijPara=new AliGenHIJINGpara(%i);\n",(int)fGenNprimCO->GetSelected()); - fprintf(pF," pHijPara->SetMomentumRange(0,999); pHijPara->SetThetaRange(%f,%f); pHijPara->SetPhiRange(0,360);\n",Eta2Theta(8),Eta2Theta(-8)); - fprintf(pF," pCocktail->AddGenerator(pHijPara,\"hijing para\",1);\n\n"); - } - if(fGenBG->GetButton(kPythia)->GetState()==kButtonDown){//Pythia + 7 guns towards 7 RICH chambers - fprintf(pF," AliGenPythia *pPythia = new AliGenPythia(-1);\n"); - fprintf(pF," pPythia->SetMomentumRange(0,999); pPythia->SetPhiRange(20,80); pPythia->SetThetaRange(75,115);\n"); - fprintf(pF," pPythia->SetYRange(-12,12); pPythia->SetPtRange(0,1000); pPythia->SetStrucFunc(kCTEQ4L);\n"); - fprintf(pF," pPythia->SetProcess(kPyMb); pPythia->SetEnergyCMS(14000);\n"); - fprintf(pF," pCocktail->AddGenerator(pPythia,\"Pythia\",1);\n\n"); + fprintf(pF," AliGenHIJINGpara *pHP=new AliGenHIJINGpara(%i);\n",(int)fGenNprimCO->GetSelected()); + fprintf(pF," pHP->SetMomentumRange(0,999); pHP->SetThetaRange(%f,%f); pHP->SetPhiRange(0,360);\n",Eta2Theta(8),Eta2Theta(-8)); + fprintf(pF," pG->AddGenerator(pHP,\"hp\",1);\n\n"); } - fprintf(pF," pCocktail->Init();\n\n"); + + if(fGenBG->GetButton(kPythia)->GetState()==kButtonDown){//Pythia + fprintf(pF," AliGenPythia *pP=new AliGenPythia(-1);\n"); + fprintf(pF," pP->SetMomentumRange(0,999); pP->SetPhiRange(20,80); pP->SetThetaRange(75,115);\n"); + fprintf(pF," pP->SetYRange(-12,12); pP->SetPtRange(0,1000); pP->SetStrucFunc(kCTEQ4L);\n"); + fprintf(pF," pP->SetProcess(kPyMb); pP->SetEnergyCMS(14000);\n"); + fprintf(pF," pG->AddGenerator(pP,\"p\",1);\n\n"); + } + fprintf(pF," pG->Init();\n\n"); }//WriteGenerator() //__________________________________________________________________________________________________ void RichConfig::GuiDet(TGHorizontalFrame *pMainHF) @@ -510,6 +512,10 @@ void RichConfig::WriteBatch() else if(fRawBG->GetButton(kRawRoot)->GetState()) fprintf(fp," pSim->SetWriteRawData(\"ITS TPC TRD TOF RICH\",\".root\");//raw data in ROOT format for ALL\n"); fprintf(fp," pSim->Run(iNevents);\n delete pSim;\n\n"); + fprintf(fp," delete AliRICHParam::Instance();\n\n"); + + + //reconstraction section if(!fClusBG->GetButton(kNo)->GetState()){ fprintf(fp," AliReconstruction *pRec=new AliReconstruction;\n"); diff --git a/RICH/RichGeom.C b/RICH/RichGeom.C index d9c94f65595..8778a55a6f2 100644 --- a/RICH/RichGeom.C +++ b/RICH/RichGeom.C @@ -1,97 +1,103 @@ -TGeoManager *g=0; -AliRICHParam *p=0; + Int_t copy; //volume copy number Double_t dx,dy,dz,r1,r2;//tmp vars for volume dimentions Double_t cm=1,m=100*cm,mm=0.1*cm,mkm=0.001*cm;//length units +TGeoManager *g=0; -void RichGeom() +void RichGeom(Bool_t isOnlyChambers=kFALSE) { - p=new AliRICHParam; - //gSystem->Load("libGeom.so"); - g=new TGeoManager("GEL","Aerogel test configuration"); + g=new TGeoManager("RICH","Private RICH geometry"); Materials(); - TGeoVolume *pMother=g->MakeBox("Mother",g->GetMedium("Air"),dx=30*m/2,dy=30*m/2,dz=30*m/2); //arbitrary values - g->SetTopVolume(g->GetVolume("Mother")); + gGeoManager->MakeBox("ALIC",gGeoManager->GetMedium("Air"),dx=30*m/2,dy=30*m/2,dz=30*m/2); //arbitrary values + gGeoManager->SetTopVolume(gGeoManager->GetVolume("ALIC")); - Rich(pMother); + Rich(isOnlyChambers); + +// RusGel(); + +// Vhmpid(); - Colors(); - g->CloseGeometry(); + gGeoManager->CloseGeometry(); - g->SetVisOption(0); g->SetVisLevel(5); + gGeoManager->SetVisOption(0); gGeoManager->SetVisLevel(5); - g->GetMasterVolume()->Draw(); + gGeoManager->GetMasterVolume()->Draw(); Axis(); // gPad->GetView()->SetView(3,94,-70,0); new TBrowser; } //__________________________________________________________________________________________________ -void Aerogel() -{ - - TGeoVolume *pGel =g->MakeBox("RGEL" ,g->GetMedium("Air"),dx=10*cm/2,dy= 10*cm/2 ,dz=10*cm/2);//10x10x10 cm aerogel cubic - for(int i=1;i<=7;i++)//put 7 cubics - g->GetVolume("Mother")->AddNode(pGel,copy=i,new TGeoCombiTrans(p->C(i)->Center().X(), p->C(i)->Center().Y(), p->C(i)->Center().Z(), - new TGeoRotation(Form("GelRot%i",i),p->C(i)->ThetaXd(),p->C(i)->PhiXd(), - p->C(i)->ThetaYd(),p->C(i)->PhiYd(), - p->C(i)->ThetaZd(),p->C(i)->PhiZd()))); - -} -//__________________________________________________________________________________________________ void Materials() { -// Defines all the materials and tracking media +//Media for RICH Double_t a=0,z=0,den=0,radlen=0,intlen=0;//tmp vars for material parameters - new TGeoMaterial("Air" ,a=26.98 ,z=13,den=0.4224 ); new TGeoMedium("Air" ,1,g->GetMaterial("Air")); - new TGeoMaterial("CH4" ,a=26.98 ,z=13,den=0.4224 ); pCH4 =new TGeoMedium("CH4" ,2,g->GetMaterial("CH4")); - new TGeoMaterial("CsI" ,a=26.98 ,z=13,den=2.7 ,radlen=24.01*cm,intlen=70.6*cm); pCsI =new TGeoMedium("CsI" ,3,g->GetMaterial("CsI")); - new TGeoMaterial("Al" ,a=26.98 ,z=13,den=2.7 ,radlen=24.01*cm,intlen=70.6*cm); pAl =new TGeoMedium("Al" ,4,g->GetMaterial("Al")); - new TGeoMaterial("W" ,a=183.84,z=27,den=19.3,radlen= 9.59*cm,intlen=0.35*cm); pW =new TGeoMedium("W" ,5,g->GetMaterial("W")); - new TGeoMaterial("Cu" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); pCu =new TGeoMedium("Cu" ,6,g->GetMaterial("Cu")); - new TGeoMaterial("Rohacell" ,a=12.01 ,z=6 ,den=0.1 ,radlen=18.8,intlen=0); pRoha =new TGeoMedium("Rohacell" ,7,g->GetMaterial("Rohacell")); - new TGeoMaterial("SiO2" ,a=0 ,z=0 ,den=0); pSiO2 =new TGeoMedium("SiO2" ,8,g->GetMaterial("SiO2")); - new TGeoMaterial("C6F14" ,a=0 ,z=0 ,den=0); pC6F14=new TGeoMedium("C6F14" ,9,g->GetMaterial("C6F14")); -//Medium for Sr90 source - new TGeoMaterial("Perpex" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); pPerpex=new TGeoMedium("Perpex" ,10,g->GetMaterial("Perpex")); - new TGeoMaterial("Steel" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); pSteel =new TGeoMedium("Steel" ,11,g->GetMaterial("Steel")); - new TGeoMaterial("Mylar" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); pMylar =new TGeoMedium("Mylar" ,12,g->GetMaterial("Mylar")); - new TGeoMaterial("Sr90" ,a=87.62 ,z=38,den=7.87,radlen=13.84*cm,intlen=82.8*cm); pSr =new TGeoMedium("Sr90" ,13,g->GetMaterial("Sr90")); + new TGeoMaterial("Air" ,a=26.98 ,z=13,den=0.4224 ); new TGeoMedium("Air" ,1,gGeoManager->GetMaterial("Air")); + new TGeoMaterial("RICH_CH4" ,a=26.98 ,z=13,den=0.4224 ); new TGeoMedium("RICH_CH4" ,2,gGeoManager->GetMaterial("RICH_CH4")); + new TGeoMaterial("RICH_CsI" ,a=26.98 ,z=13,den=2.7 ,radlen=24.01*cm,intlen=70.6*cm); new TGeoMedium("RICH_CsI" ,3,gGeoManager->GetMaterial("RICH_CsI")); + new TGeoMaterial("RICH_Al" ,a=26.98 ,z=13,den=2.7 ,radlen=24.01*cm,intlen=70.6*cm); new TGeoMedium("RICH_Al" ,4,gGeoManager->GetMaterial("RICH_Al")); + new TGeoMaterial("RICH_W" ,a=183.84,z=27,den=19.3,radlen= 9.59*cm,intlen=0.35*cm); new TGeoMedium("RICH_W" ,5,gGeoManager->GetMaterial("RICH_W")); + new TGeoMaterial("RICH_Cu" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("RICH_Cu" ,6,gGeoManager->GetMaterial("RICH_Cu")); + new TGeoMaterial("RICH_Rohacell" ,a=12.01 ,z=6 ,den=0.1 ,radlen=18.8,intlen=0); new TGeoMedium("RICH_Rohacell",7,gGeoManager->GetMaterial("RICH_Rohacell")); + new TGeoMaterial("RICH_SiO2" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_SiO2" ,8,gGeoManager->GetMaterial("RICH_SiO2")); + new TGeoMaterial("RICH_C6F14" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_C6F14" ,9,gGeoManager->GetMaterial("RICH_C6F14")); +//Media for Sr90 source + new TGeoMaterial("RICH_Perpex" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("RICH_Perpex" ,10,gGeoManager->GetMaterial("RICH_Perpex")); + new TGeoMaterial("RICH_Steel" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("RICH_Steel" ,11,gGeoManager->GetMaterial("RICH_Steel")); + new TGeoMaterial("RICH_Mylar" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("RICH_Mylar" ,12,gGeoManager->GetMaterial("RICH_Mylar")); + new TGeoMaterial("RICH_Sr90" ,a=87.62 ,z=38,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("RICH_Sr90" ,13,gGeoManager->GetMaterial("RICH_Sr90")); +//Media for VHMPID Gas option + new TGeoMaterial("RICH_CF4" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_CF4" ,14,gGeoManager->GetMaterial("RICH_CF4")); + new TGeoMaterial("RICH_C4F10" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_C4F10" ,15,gGeoManager->GetMaterial("RICH_C4F10")); + new TGeoMaterial("RICH_Ag" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_Ag" ,16,gGeoManager->GetMaterial("RICH_Ag")); +//Media for VHMPID aerogel option + new TGeoMaterial("RICH_Gel24" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_Gel24" ,17,gGeoManager->GetMaterial("RICH_Gel24")); + new TGeoMaterial("RICH_Gel26" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_Gel26" ,18,gGeoManager->GetMaterial("RICH_Gel26")); + new TGeoMaterial("RICH_Gel28" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_Gel28" ,19,gGeoManager->GetMaterial("RICH_Gel28")); + new TGeoMaterial("RICH_Gel30" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_Gel30" ,20,gGeoManager->GetMaterial("RICH_Gel30")); + new TGeoMaterial("RICH_Si" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_Si" ,21,gGeoManager->GetMaterial("RICH_Si")); + new TGeoMaterial("RICH_Apd" ,a=0 ,z=0 ,den=0); new TGeoMedium("RICH_Apd" ,22,gGeoManager->GetMaterial("RICH_Apd")); }//Materials() //__________________________________________________________________________________________________ -void Rich(TGeoVolume *pTop) -{ -//Rich - TGeoVolume *pRich=g->MakeBox( "Rich" ,g->GetMedium("CH4"),dx=(6*mm+1681*mm+6*mm)/2, //main RICH volume - dy=(6*mm+1466*mm+6*mm)/2, - dz=(80*mm+40*mm)*2/2); //x,y taken from 2033P1 z from p84 TDR - for(int i=1;i<=p->Nchambers();i++)//put 7 chambers - pTop->AddNode(pRich,copy=i,new TGeoCombiTrans(p->C(i)->Center().X(), p->C(i)->Center().Y(), p->C(i)->Center().Z(), - new TGeoRotation(Form("RichRot%i",i),p->C(i)->ThetaXd(),p->C(i)->PhiXd(), - p->C(i)->ThetaYd(),p->C(i)->PhiYd(), - p->C(i)->ThetaZd(),p->C(i)->PhiZd()))); //Rich to Mother - - PadPanelFrame(pRich); //photocathode - Gap(pRich); //anod wires - Frame3(pRich); //cathode wires - Frame4(pRich); //collection wires - Sandbox(pRich); -}//Rich() -//__________________________________________________________________________________________________ -void PadPanelFrame(TGeoVolume *pTop) +void Rich(Bool_t isOnlyChambers) { +//Rich chamber + TGeoVolume *pRich=gGeoManager->MakeBox("RICH",gGeoManager->GetMedium("Air"),dx=(6*mm+1681*mm+6*mm)/2, //main RICH volume + dy=(6*mm+1466*mm+6*mm)/2, + dz=(80*mm+40*mm)*2/2); //x,y taken from 2033P1 z from p84 TDR + 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 + 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 + 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 + } + pMatrix->RotateZ(kAngCom); //apply common rotation in XY plane + gGeoManager->GetVolume("ALIC")->AddNode(pRich,iCh,pMatrix); + } + if(isOnlyChambers) return; //do not construct the detailed geometry //Pad Panel frame - TGeoVolume *pPpf =g->MakeBox("PPF" ,g->GetMedium("Al") ,dx=648*mm/2,dy= 411*mm/2 ,dz=40 *mm/2);//PPF 2001P2 inner size of the slab by 1mm more - TGeoVolume *pPpfLarge=g->MakeBox("PPFlarge" ,g->GetMedium("Air") ,dx=181*mm/2,dy=89.25*mm/2 ,dz=38.3*mm/2);//large whole - TGeoVolume *pPpfSmall=g->MakeBox("PPFsmall" ,g->GetMedium("Air") ,dx=114*mm/2,dy=89.25*mm/2 ,dz=38.3*mm/2);//small whole - TGeoVolume *pPc =g->MakeBox("PC" ,g->GetMedium("CsI") ,dx=644*mm/2,dy= 407*mm/2 ,dz= 1.7*mm/2);//by 0.2 mm more then actual size (PCB 2006P1) - - pTop->AddNode(pPpf,copy=1,new TGeoTranslation(-335*mm,-433*mm,8*cm+20*mm));//F1 2040P1 z p.84 TDR - pTop->AddNode(pPpf,copy=2,new TGeoTranslation(+335*mm,-433*mm,8*cm+20*mm)); - pTop->AddNode(pPpf,copy=3,new TGeoTranslation(-335*mm, 0*mm,8*cm+20*mm)); - pTop->AddNode(pPpf,copy=4,new TGeoTranslation(+335*mm, 0*mm,8*cm+20*mm)); - pTop->AddNode(pPpf,copy=5,new TGeoTranslation(-335*mm,+433*mm,8*cm+20*mm)); - pTop->AddNode(pPpf,copy=6,new TGeoTranslation(+335*mm,+433*mm,8*cm+20*mm)); + TGeoVolume *pPpf =gGeoManager->MakeBox("Rppf" ,gGeoManager->GetMedium("RICH_Al") ,dx=648*mm/2,dy= 411*mm/2 ,dz=40 *mm/2);//PPF 2001P2 inner size of the slab by 1mm more + TGeoVolume *pPpfLarge=gGeoManager->MakeBox("Rppf1" ,gGeoManager->GetMedium("Air") ,dx=181*mm/2,dy=89.25*mm/2 ,dz=38.3*mm/2); //large whole + TGeoVolume *pPpfSmall=gGeoManager->MakeBox("Rppf2" ,gGeoManager->GetMedium("Air") ,dx=114*mm/2,dy=89.25*mm/2 ,dz=38.3*mm/2);//small whole + TGeoVolume *pPc =gGeoManager->MakeBox("Rpc" ,gGeoManager->GetMedium("RICH_CsI") ,dx=644*mm/2,dy= 407*mm/2 ,dz= 1.7*mm/2);//by 0.2 mm more then actual size (PCB 2006P1) + + pRich->AddNode(pPpf,copy=1,new TGeoTranslation(-335*mm,-433*mm,8*cm+20*mm));//F1 2040P1 z p.84 TDR + pRich->AddNode(pPpf,copy=2,new TGeoTranslation(+335*mm,-433*mm,8*cm+20*mm)); + pRich->AddNode(pPpf,copy=3,new TGeoTranslation(-335*mm, 0*mm,8*cm+20*mm)); + pRich->AddNode(pPpf,copy=4,new TGeoTranslation(+335*mm, 0*mm,8*cm+20*mm)); + pRich->AddNode(pPpf,copy=5,new TGeoTranslation(-335*mm,+433*mm,8*cm+20*mm)); + pRich->AddNode(pPpf,copy=6,new TGeoTranslation(+335*mm,+433*mm,8*cm+20*mm)); pPpf->AddNode( pPc ,copy=1,new TGeoTranslation( 0*mm, 0*mm,-19.15*mm));//PPF 2001P2 pPpf->AddNode(pPpfLarge,copy=1,new TGeoTranslation(-224.5*mm,-151.875*mm, 0.85*mm)); pPpf->AddNode(pPpfLarge,copy=2,new TGeoTranslation(-224.5*mm,- 50.625*mm, 0.85*mm)); @@ -109,61 +115,47 @@ void PadPanelFrame(TGeoVolume *pTop) pPpf->AddNode(pPpfLarge,copy=6,new TGeoTranslation(+224.5*mm,- 50.625*mm, 0.85*mm)); pPpf->AddNode(pPpfLarge,copy=7,new TGeoTranslation(+224.5*mm,+ 50.625*mm, 0.85*mm)); pPpf->AddNode(pPpfLarge,copy=8,new TGeoTranslation(+224.5*mm,+151.875*mm, 0.85*mm)); -}//PadPanelFrame() -//__________________________________________________________________________________________________ -void Gap(TGeoVolume *pTop) -{ -//Gap - anod wires - TGeoVolume *pGap =g->MakeBox ("Gap" ,g->GetMedium("CH4") ,dx=648*mm/2,dy= 411*mm/2 ,dz=4.45*mm/2);//xy as PPF 2001P2 z WP 2099P1 - TGeoVolume *pAnod=g->MakeTube("Anod" ,g->GetMedium("W") ,r1= 0*mm ,r2= 20*mkm/2 ,dz=648*mm/2); //WP 2099P1 z = gap x PPF 2001P2 - TGeoRotation *pAnodRot=new TGeoRotation("AnodRot",90,90,0); - - pTop->AddNode(pGap,copy=1,new TGeoTranslation(-335*mm,-433*mm,8*cm-2.225*mm)); //F1 2040P1 z WP 2099P1 - pTop->AddNode(pGap,copy=2,new TGeoTranslation(+335*mm,-433*mm,8*cm-2.225*mm)); - pTop->AddNode(pGap,copy=3,new TGeoTranslation(-335*mm, 0*mm,8*cm-2.225*mm)); - pTop->AddNode(pGap,copy=4,new TGeoTranslation(+335*mm, 0*mm,8*cm-2.225*mm)); - pTop->AddNode(pGap,copy=5,new TGeoTranslation(-335*mm,+433*mm,8*cm-2.225*mm)); - pTop->AddNode(pGap,copy=6,new TGeoTranslation(+335*mm,+433*mm,8*cm-2.225*mm)); +//gap - anod wires + TGeoVolume *pGap =gGeoManager->MakeBox ("Rgap" ,gGeoManager->GetMedium("RICH_CH4") ,dx=648*mm/2,dy= 411*mm/2 ,dz=4.45*mm/2);//xy as PPF 2001P2 z WP 2099P1 + TGeoVolume *pAnod=gGeoManager->MakeTube("Rano" ,gGeoManager->GetMedium("RICH_W") ,r1= 0*mm ,r2= 20*mkm/2 ,dz=648*mm/2); //WP 2099P1 z = gap x PPF 2001P2 + TGeoRotation *pAnodRot=new TGeoRotation("RanW",90,90,0); + + pRich->AddNode(pGap,copy=1,new TGeoTranslation(-335*mm,-433*mm,8*cm-2.225*mm)); //F1 2040P1 z WP 2099P1 + pRich->AddNode(pGap,copy=2,new TGeoTranslation(+335*mm,-433*mm,8*cm-2.225*mm)); + pRich->AddNode(pGap,copy=3,new TGeoTranslation(-335*mm, 0*mm,8*cm-2.225*mm)); + pRich->AddNode(pGap,copy=4,new TGeoTranslation(+335*mm, 0*mm,8*cm-2.225*mm)); + pRich->AddNode(pGap,copy=5,new TGeoTranslation(-335*mm,+433*mm,8*cm-2.225*mm)); + pRich->AddNode(pGap,copy=6,new TGeoTranslation(+335*mm,+433*mm,8*cm-2.225*mm)); for(int i=1;i<=96;i++) pGap->AddNode(pAnod,copy=i,new TGeoCombiTrans( 0*mm, -411/2*mm+i*4*mm, 0.185*mm,pAnodRot)); //WP 2099P1 -}//Gap() -//__________________________________________________________________________________________________ -void Frame3(TGeoVolume *pTop) -{//Frame 3- cathode wires - TGeoVolume *pCath=g->MakeTube("Cath" ,g->GetMedium("Cu") ,r1=0 ,r2=100*mkm/2,dz=1323*mm/2);//r WP 2099P1 z F3 2041P1 +//frame 3- cathode wires + TGeoVolume *pCath=gGeoManager->MakeTube("RcaW" ,gGeoManager->GetMedium("Cu") ,r1=0 ,r2=100*mkm/2,dz=1323*mm/2);//r WP 2099P1 z F3 2041P1 TGeoRotation *pCathRot=new TGeoRotation("CathRot",90,90,0); for(int i=1;i<=618;i++) - pTop->AddNode(pCath,copy=i,new TGeoCombiTrans( 0*mm, -649.5*mm+i*2.1*mm, 75*mm,pCathRot)); //WP 2099P1 -}//Frame3() -//__________________________________________________________________________________________________ -void Frame4(TGeoVolume *pTop) -{ + pRich->AddNode(pCath,copy=i,new TGeoCombiTrans( 0*mm, -649.5*mm+i*2.1*mm, 75*mm,pCathRot)); //WP 2099P1 //Frame 4- collection wires - TGeoVolume *pF4 =g->MakeBox( "F4" ,g->GetMedium("CH4") ,dx=1407*mm/2 ,dy=1366*mm/2 ,dz= 15*mm/2);//F4 2043P1 - TGeoVolume *pF4al=g->MakeBox( "F4al" ,g->GetMedium("Al") ,dx=1407*mm/2 ,dy=1366*mm/2 ,dz= 10*mm/2); - TGeoVolume *pF4in=g->MakeBox( "F4in" ,g->GetMedium("CH4") ,dx=1323*mm/2 ,dy=1296*mm/2 ,dz= 10*mm/2); - TGeoVolume *pColl=g->MakeTube("Coll" ,g->GetMedium("Cu") ,r1= 0*mm ,r2=100*mkm/2 ,dz=1323*mm/2); - TGeoRotation *pCollRot=new TGeoRotation("CollRot",90,90,0); + TGeoVolume *pF4 =gGeoManager->MakeBox( "Rfr4" ,gGeoManager->GetMedium("RICH_CH4") ,dx=1407*mm/2 ,dy=1366*mm/2 ,dz= 15*mm/2);//F4 2043P1 + TGeoVolume *pF4al=gGeoManager->MakeBox( "Rfr4al" ,gGeoManager->GetMedium("RICH_Al") ,dx=1407*mm/2 ,dy=1366*mm/2 ,dz= 10*mm/2); + TGeoVolume *pF4in=gGeoManager->MakeBox( "Rfr4in" ,gGeoManager->GetMedium("RICH_CH4") ,dx=1323*mm/2 ,dy=1296*mm/2 ,dz= 10*mm/2); + TGeoVolume *pColl=gGeoManager->MakeTube("RcoW" ,gGeoManager->GetMedium("RICH_Cu") ,r1= 0*mm ,r2=100*mkm/2 ,dz=1323*mm/2); + TGeoRotation *pCollRot=new TGeoRotation("RcoRot",90,90,0); - pTop->AddNode(pF4 ,copy=1,new TGeoTranslation( 0*mm,0*mm, 9*mm)); //F4 to Rich p.84 TDR + pRich->AddNode(pF4 ,copy=1,new TGeoTranslation( 0*mm,0*mm, 9*mm)); //F4 to Rich p.84 TDR pF4 ->AddNode(pF4al ,copy=1,new TGeoTranslation( 0*mm,0*mm, 2.5*mm)); //F4 al to F4 2043P1 pF4al->AddNode(pF4in ,copy=1,new TGeoTranslation( 0*mm,0*mm, 0*mm)); //F4 whole F4 al 2043P1 for(int i=1;i<=322;i++) pF4->AddNode(pColl,copy=i,new TGeoCombiTrans( 0*mm, -1296/2*mm+i*4*mm, -5*mm,pCollRot)); //F4 2043P1 -}//void Frame4() -//__________________________________________________________________________________________________ -void Radiators(TGeoVolume *pTop) -{ - TGeoVolume *pRad =g->MakeBox( "Rad" ,g->GetMedium("C6F14") ,dx=1330*mm/2 ,dy= 413*mm/2 ,dz= 24*mm/2); // Rad 2011P1 - TGeoVolume *pRadFront =g->MakeBox( "RadFront" ,g->GetMedium("Neoceram") ,dx=1330*mm/2 ,dy= 413*mm/2 ,dz= 4*mm/2); - TGeoVolume *pRadWin =g->MakeBox( "RadWin" ,g->GetMedium("SiO2") ,dx=1330*mm/2 ,dy= 413*mm/2 ,dz= 5*mm/2); - TGeoVolume *pRadLong =g->MakeBox( "RadLong" ,g->GetMedium("Neoceram") ,dx=1330*mm/2 ,dy= 5*mm/2 ,dz= 15*mm/2); - TGeoVolume *pRadShort =g->MakeBox( "RadShort" ,g->GetMedium("Neoceram") ,dx= 10*mm/2 ,dy= 403*mm/2 ,dz= 15*mm/2); - TGeoVolume *pRadSpacer=g->MakeTube("RadSpacer",g->GetMedium("SiO2") ,r1= 0 ,r2=10*mm/2 ,dz= 15*mm/2); +//radiators + TGeoVolume *pRad =gGeoManager->MakeBox( "Rad" ,gGeoManager->GetMedium("RICH_C6F14") ,dx=1330*mm/2 ,dy= 413*mm/2 ,dz= 24*mm/2); // Rad 2011P1 + TGeoVolume *pRadFront =gGeoManager->MakeBox( "RadFront" ,gGeoManager->GetMedium("RICH_Neoceram") ,dx=1330*mm/2 ,dy= 413*mm/2 ,dz= 4*mm/2); + TGeoVolume *pRadWin =gGeoManager->MakeBox( "RadWin" ,gGeoManager->GetMedium("RICH_SiO2") ,dx=1330*mm/2 ,dy= 413*mm/2 ,dz= 5*mm/2); + TGeoVolume *pRadLong =gGeoManager->MakeBox( "RadLong" ,gGeoManager->GetMedium("RICH_Neoceram") ,dx=1330*mm/2 ,dy= 5*mm/2 ,dz= 15*mm/2); + TGeoVolume *pRadShort =gGeoManager->MakeBox( "RadShort" ,gGeoManager->GetMedium("RICH_Neoceram") ,dx= 10*mm/2 ,dy= 403*mm/2 ,dz= 15*mm/2); + TGeoVolume *pRadSpacer=gGeoManager->MakeTube("RadSpacer",gGeoManager->GetMedium("RICH_SiO2") ,r1= 0 ,r2=10*mm/2 ,dz= 15*mm/2); - pTop->AddNode(pRad ,copy=1,new TGeoTranslation( 0*mm,-434*mm, -12*mm)); - pTop->AddNode(pRad ,copy=2,new TGeoTranslation( 0*mm, 0*mm, -12*mm)); - pTop->AddNode(pRad ,copy=3,new TGeoTranslation( 0*mm,+434*mm, -12*mm)); + pRich->AddNode(pRad ,copy=1,new TGeoTranslation( 0*mm,-434*mm, -12*mm)); + pRich->AddNode(pRad ,copy=2,new TGeoTranslation( 0*mm, 0*mm, -12*mm)); + pRich->AddNode(pRad ,copy=3,new TGeoTranslation( 0*mm,+434*mm, -12*mm)); pRad ->AddNode(pRadFront ,copy=1,new TGeoTranslation( 0*mm, 0*mm, -10.0*mm)); pRad ->AddNode(pRadWin ,copy=1,new TGeoTranslation( 0*mm, 0*mm, 9.5*mm)); @@ -171,22 +163,29 @@ void Radiators(TGeoVolume *pTop) pRad ->AddNode(pRadLong ,copy=2,new TGeoTranslation( 0*mm,+204*mm, -0.5*mm)); pRad ->AddNode(pRadShort ,copy=1,new TGeoTranslation(-660*mm, 0*mm, -0.5*mm)); pRad ->AddNode(pRadShort ,copy=2,new TGeoTranslation(+660*mm, 0*mm, -0.5*mm)); - for(int i=0;i<3;i++) - for(int j=0;j<10;j++) - pRad->AddNode(pRadSpacer,copy=10*i+j,new TGeoTranslation(-1330*mm/2+116*mm+j*122*mm,(i-1)*105*mm,-0.5*mm)); -}//Radiators() + for(int i=0;i<3;i++) for(int j=0;j<10;j++) pRad->AddNode(pRadSpacer,copy=10*i+j,new TGeoTranslation(-1330*mm/2+116*mm+j*122*mm,(i-1)*105*mm,-0.5*mm)); +//sandbox + TGeoVolume *pSandBox =gGeoManager->MakeBox( "RSandBox" ,gGeoManager->GetMedium("Air") ,dx=1419*mm/2 ,dy=1378*mm/2 ,dz=50.5*mm/2); //2072P1 + TGeoVolume *pSandCover=gGeoManager->MakeBox( "RSandCover",gGeoManager->GetMedium("RICH_Al") ,dx=1419*mm/2 ,dy=1378*mm/2 ,dz= 0.5*mm/2); + TGeoVolume *pSandComb =gGeoManager->MakeBox( "RSandComb" ,gGeoManager->GetMedium("RICH_Rohacell") ,dx=1359*mm/2 ,dy=1318*mm/2 ,dz=49.5*mm/2); + + pRich->AddNode(pSandBox,copy=1,new TGeoTranslation( 0*mm,0*mm, -73.75*mm)); //p.84 TDR + pSandBox->AddNode(pSandComb ,copy=1,new TGeoTranslation( 0*mm,0*mm, 0*mm)); //2072P1 + pSandBox->AddNode(pSandCover ,copy=1,new TGeoTranslation( 0*mm,0*mm, +25*mm)); + pSandBox->AddNode(pSandCover ,copy=2,new TGeoTranslation( 0*mm,0*mm, -25*mm)); +}//Rich() //__________________________________________________________________________________________________ void Sr90(TGeoVolume *pTop) { - pSrc =g->MakeTube("Src" ,g->GetMedium("CH4") , 0 , 70*mm/2 , 30*mm/2); //top container - pAlGlass =g->MakeTube("SrcAlGlass" ,g->GetMedium("Al") , 0 , 38*mm/2 ,21.8*mm/2); //Al glass wall - pPerpexPlug =g->MakeTube("SrcPerpex" ,g->GetMedium("Perpex"), 0 , 34*mm/2 , 20*mm/2); //Perpex plug - pScrewCentral=g->MakeTube("SrcScrewCentral" ,g->GetMedium("Steel") , 0 , 5*mm/2 , 15*mm/2); //Steel screw in the center - pScrewSr90 =g->MakeTube("SrcScrewSr90" ,g->GetMedium("Steel") , 0 , 2*mm/2 , 10*mm/2); //Steel screw to support Sr90 - pSr90 =g->MakeTube("SrcSr90" ,g->GetMedium("Sr90") , 0 , 1*mm/2 , 1*mm/2); //Sr90 source - pHolePerpex =g->MakeTube("SrcHolePerpex" ,g->GetMedium("Air") , 0 , 4*mm/2 , 10*mm/2); //Air hole in perpex plug - pHoleAl =g->MakeTube("SrcHoleAl" ,g->GetMedium("Air") , 0 , 5*mm/2 , 1.8*mm/2); //Air hole in Al glass bottom - pMylarFoil =g->MakeTube("SrcMylarFoil" ,g->GetMedium("Mylar") , 0 , 30*mm/2 , 50*mkm/2); //Mylar foil + pSrc =gGeoManager->MakeTube("Src" ,gGeoManager->GetMedium("Air") , 0 , 70*mm/2 , 30*mm/2); //top container + pAlGlass =gGeoManager->MakeTube("SrcAlGlass" ,gGeoManager->GetMedium("RICH_Al") , 0 , 38*mm/2 ,21.8*mm/2); //Al glass wall + pPerpexPlug =gGeoManager->MakeTube("SrcPerpex" ,gGeoManager->GetMedium("RICH_Perpex"), 0 , 34*mm/2 , 20*mm/2); //Perpex plug + pScrewCentral=gGeoManager->MakeTube("SrcScrewCentral" ,gGeoManager->GetMedium("RICH_Steel") , 0 , 5*mm/2 , 15*mm/2); //Steel screw in the center + pScrewSr90 =gGeoManager->MakeTube("SrcScrewSr90" ,gGeoManager->GetMedium("RICH_Steel") , 0 , 2*mm/2 , 10*mm/2); //Steel screw to support Sr90 + pSr90 =gGeoManager->MakeTube("SrcSr90" ,gGeoManager->GetMedium("RICH_Sr90") , 0 , 1*mm/2 , 1*mm/2); //Sr90 source + pHolePerpex =gGeoManager->MakeTube("SrcHolePerpex" ,gGeoManager->GetMedium("Air") , 0 , 4*mm/2 , 10*mm/2); //Air hole in perpex plug + pHoleAl =gGeoManager->MakeTube("SrcHoleAl" ,gGeoManager->GetMedium("Air") , 0 , 5*mm/2 , 1.8*mm/2); //Air hole in Al glass bottom + pMylarFoil =gGeoManager->MakeTube("SrcMylarFoil" ,gGeoManager->GetMedium("RICH_Mylar") , 0 , 30*mm/2 , 50*mkm/2); //Mylar foil pTop->AddNode(pSrc,1,new TGeoTranslation(30*cm,0,1*cm)); pSrc ->AddNode(pMylarFoil,1,new TGeoTranslation(0,0,21.8*mm/2+50*mkm/2)); @@ -199,17 +198,230 @@ void Sr90(TGeoVolume *pTop) pScrewSr90->AddNode( pSr90 ,1,new TGeoTranslation(0 ,0,-4.5*mm)); }//Sr90() //__________________________________________________________________________________________________ -void Sandbox(TGeoVolume *pTop) -{//Sandbox - TGeoVolume *pSandBox =g->MakeBox( "SandBox" ,g->GetMedium("Air") ,dx=1419*mm/2 ,dy=1378*mm/2 ,dz=50.5*mm/2); //2072P1 - TGeoVolume *pSandCover=g->MakeBox( "SandCover",g->GetMedium("Al") ,dx=1419*mm/2 ,dy=1378*mm/2 ,dz= 0.5*mm/2); - TGeoVolume *pSandComb =g->MakeBox( "SandComb" ,g->GetMedium("Roha") ,dx=1359*mm/2 ,dy=1318*mm/2 ,dz=49.5*mm/2); +void RusGel() +{ +//Defines VHMPID aerogel option geometry. +// top view normal position side view normal position +// ^ y +// -------- | +// | | | +// | | z<-----* y z<-------* x ----> MUON side +// | | | ---- +// | | | | | +// ________ v x | | +// |--| +// | | +// ---- +//Chamber consists from Al box filled with air where 4 aerogel blocks and APD wall are positioned. +// ------------------------------ +// |-| |-| |-| |-| |-|| +// |-| | | | | | | | || +// |-| | | | | | | | || +// |-| APD wall | | | | | | | || z<---* y top view +// |-| | | | | | | | || | +// |-| | | | | | | | || | +// |-| |_| |_| |_| |_|| v x +// ------------------------------ +// +// ALIC +// | +// Vbox (Al) +// | +// Vair (Air) +// _______|________ +// | | +// 4*Vgel Vwall +// | +// Vcolumn (division along X) +// | +// Vcell (division along Y) +// | +// Vapd + + Double_t cm=1 , m=100 , mm=0.1 ;//dimentions, default is cm - pTop->AddNode(pSandBox,copy=1,new TGeoTranslation( 0*mm,0*mm, -73.75*mm)); //p.84 TDR - pSandBox->AddNode(pSandComb ,copy=1,new TGeoTranslation( 0*mm,0*mm, 0*mm)); //2072P1 - pSandBox->AddNode(pSandCover ,copy=1,new TGeoTranslation( 0*mm,0*mm, +25*mm)); - pSandBox->AddNode(pSandCover ,copy=2,new TGeoTranslation( 0*mm,0*mm, -25*mm)); -}//Sandbox() + Int_t iNapdsX =10 ;//number of APDs along x + Int_t iNapdsY =16 ;//number of APDs along y + Double_t dCellX =1.5*mm *0.5 ;//cell X half size + Double_t dCellY =1.5*mm *0.5 ;//cell Y half size + Double_t dCellZ =0.5*mm *0.5 ;//APD wall thickness + Double_t dWallX = iNapdsX*dCellX;//APD wall X half size + Double_t dWallY = iNapdsY*dCellY;//APD wall Y half size + Double_t dWallZ = dCellZ;//APD wall half thickness + Double_t dApdR =0.5*mm ;//APD radius + Double_t dApdZ = dCellZ;//APD Z half size + Double_t dGelX = dWallX;//gel block X half size + Double_t dGelY = dWallY;//gel block Y half size + Double_t dGelZ =10*mm *0.5 ;//gel block Z half size + Double_t dProxGap =50*cm ;//half distance between APD wall and last aerogel block + Double_t dAirX = dWallX;//internal air X hald size + Double_t dAirY = dWallY;//internal air Y hald size + Double_t dAirZ = dWallZ+dProxGap+7*dGelZ;//internal air Z hald size + Double_t dBoxWall =2*mm *0.5 ;//Al box walls thickness + Double_t dBoxX = dAirX+dBoxWall;//Al box x half size + Double_t dBoxY = dAirY+dBoxWall;//Al box y half size + Double_t dBoxZ = dAirZ+dBoxWall;//Al box z half size + + Int_t copy; Double_t rmin,rmax,dx,dy,dz; +//make external Al box + TGeoVolume *pBox=gGeoManager->MakeBox("Gbox",gGeoManager->GetMedium("RICH_Al"),dx=dBoxX,dy=dBoxY,dz=dBoxZ); + TGeoRotation *pRot=new TGeoRotation("GboxRot"); pRot->RotateX(90); + gGeoManager->GetVolume("ALIC")->AddNode(pBox,copy=1,new TGeoCombiTrans(0*m,-5.2*m,2.5*m,pRot));//normal position +//position Air to Al box + TGeoVolume *pAir=gGeoManager->MakeBox( "Gair",gGeoManager->GetMedium("Air"),dx=dAirX,dy=dAirY,dz=dAirZ); + pBox->AddNode(pAir,copy=1); +//position 4 gel blocks to Air + TGeoVolume *pGel24=gGeoManager->MakeBox( "Ggel24",gGeoManager->GetMedium("RICH_Gel24"),dx=dGelX,dy=dGelY,dz=dGelZ); + pAir->AddNode(pGel24,copy=1,new TGeoTranslation(0,0,-dAirZ+1*dGelZ)); + TGeoVolume *pGel26=gGeoManager->MakeBox( "Ggel26",gGeoManager->GetMedium("RICH_Gel26"),dx=dGelX,dy=dGelY,dz=dGelZ); + pAir->AddNode(pGel26,copy=1,new TGeoTranslation(0,0,-dAirZ+5*dGelZ)); + TGeoVolume *pGel28=gGeoManager->MakeBox( "Ggel28",gGeoManager->GetMedium("RICH_Gel28"),dx=dGelX,dy=dGelY,dz=dGelZ); + pAir->AddNode(pGel28,copy=1,new TGeoTranslation(0,0,-dAirZ+9*dGelZ)); + TGeoVolume *pGel30=gGeoManager->MakeBox( "Ggel30",gGeoManager->GetMedium("RICH_Gel30"),dx=dGelX,dy=dGelY,dz=dGelZ); + pAir->AddNode(pGel30,copy=1,new TGeoTranslation(0,0,-dAirZ+13*dGelZ)); +//position APD wall to air + TGeoVolume *pWall =gGeoManager->MakeBox ("Gwall",gGeoManager->GetMedium("RICH_Si"),dx=dWallX , dy=dWallY , dz=dWallZ ); + pAir->AddNode(pWall,copy=1,new TGeoTranslation(0,0,dAirZ-dWallZ)); +//divide wall into cells + Int_t axis,ndiv; Double_t start,step; + TGeoVolume *pWallCol =pWall ->Divide("Gcol",axis=1,ndiv=iNapdsX,start=0,step=0);//divide VhGap along X by NpadsX columns + TGeoVolume *pWallCell=pWallCol ->Divide("Gcel",axis=2,ndiv=iNapdsY,start=0,step=0);//divide VhGapCol along Y by NpadsY cells +//position APD to wall cell + TGeoVolume *pApd=gGeoManager->MakeTube("Gapd",gGeoManager->GetMedium("RICH_Apd"),rmin=0,rmax=dApdR,dz=dApdZ); pWallCell->AddNode(pApd,copy=1); +}//RusGel() +//__________________________________________________________________________________________________ +void Vhmpid() +{ +//Defines VHMPID geometry for TIC option. +// top view normal position side view normal position +// ^ y +// -------- | +// |------| | +// | | z<-----* y z<-------* x ----> MUON side +// | | | ---- +// | | | | | +// ________ v x | | +// |--| +// | | +// ---- +//Chamber consists from Al box filled with radiator CF4 and C4F10 quartz window in between , Al mirror and MWPC. +// --------------------------------------------------- top view chamber in test position +// | -------------- MWPC | quartz window | +// | . . . . . . | | +// | \ | | +// | \ CF4 | C4F10 | z<-----* y +// | \ mirror | | | +// | \ | | | +// | \ | | v x +// --------------------------------------------------- +// z ^ +// | +// | +// <-Y0-> X <--Y1--> X <--Y1--> X <--Y1--> X <-Y0-> | cath wires: r 50mkm; shift Y0=1.05m;, pitch Y1=2.1; center to PC 4.45mm; material Cu +// x *------->y +// +// <--Y0--> x <-----------Y1-----------> x <--Y0--> anod wires: r 20mkm; shift Y0=2.2mm; pitch Y1=4.0mm; center to PC 2.04mm; material W +// +// +// |________________________________________________| pad size y 8.4mm +// +// ALIC +// | +// Vbox +// _______|______ +// | | | +// Vc4f Vwin Vcf4 +// _____|________ +// | | +// Vmir | +// | +// Vgap +// | +// Vcol (column of gap cells) X +// | +// Vcel cell in the column Y +// ______|______ +// | | | +// Vpad Vano Vcat + Double_t cm=1 , m=100 , mm=0.1 , um=1e-4 ;//dimentions, default is cm + + Int_t iNpadsX = AliRICHParam::NpadsX() ;//number of pads along x parametrised + Int_t iNpadsY = AliRICHParam::NpadsY() ;//number of pads along y parametrised + Double_t wCathR =50 *um ;//cathode wire radius defined by USER + Double_t wCathShift =1.05*mm ;//cathode wire shift from pad edge defined by USER + Double_t wCathPitch =2.1 *mm ;//cathode wire pitch defined by USER + Double_t wCathPc =4.45*mm ;//distance from pc to cathode wire defined by USER + Double_t wAnodR =20 *um ;//anod wire radius defined by USER + Double_t wAnodShift =2.2 *mm ;//anod wire shift from pad edge defined by USER + Double_t wAnodPc =2.04*mm ;//distance from anod wire center to pc defined by USER + Double_t dPadX = 0.5* AliRICHParam::PadSizeX() ;//pad X half size parametrised + Double_t dPadY = 0.5* AliRICHParam::PadSizeY() ;//pad Y half size parametrised + Double_t dPadZ =1.0 *mm *0.5 ;//CsI film thickness + Double_t dGapX = 0.5* iNpadsX*2*dPadX ;//gap x half size n. pads x * pad size + Double_t dGapY = 0.5* iNpadsY*2*dPadY ;//gap y half size + Double_t dGapZ = 0.5* (2*dPadZ+wCathPc+wCathR) ;//gap half thickness + Double_t dMirX = 0.5* 2*dGapX/TMath::Cos(45*TMath::DegToRad());//Ag mirror x half size defined by gap size and angle 45 degrees + Double_t dMirY = 0.5* 2*dGapY ;//Ag mirror y half size defined by gap size + Double_t dMirZ =1.0 *mm *0.5 ;//Ag mirror z half size defined by USER + Double_t wBoxWall =2.0 *mm ;//Al box walls thickness defined by USER + Double_t dBoxX = 0.5* (2*dGapX+2*cm) ;//Al box x half size defined by gap size 2 cm for tolerance + Double_t dBoxY = 0.5* (2*dGapY+2*cm) ;//Al box y half size defined by gap size 2 cm for tolerance + Double_t dBoxZ =1.8*m *0.5 ;//Al box z half size defined by USER + Double_t dWinX = (dBoxX-wBoxWall) ;//SiO2 window x half size defined by box size + Double_t dWinY = (dBoxY-wBoxWall) ;//SiO2 window y half size defined by box size + Double_t dWinZ =1.0*cm *0.5 ;//SiO2 window z half size defined by USER + Double_t dCF4X = (dBoxX-wBoxWall) ;//CF4 radiator x half size defined by box size + Double_t dCF4Y = (dBoxY-wBoxWall) ;//CF4 radiator y half size defined by box size + Double_t dCF4Z = 0.4*dBoxZ ;//CF4 radiator z half size defined by box size or by USER + Double_t dC4F10X = (dBoxX-wBoxWall) ;//C4F10 radiator x half size defined by box size + Double_t dC4F10Y = (dBoxY-wBoxWall) ;//C4F10 radiator y half size defined by box size + Double_t dC4F10Z = (dBoxZ-dWinZ-dCF4Z-wBoxWall) ;//C4F10 radiator z half size defined by box, CF4 and window sizes + + Int_t copy; + Double_t rmin,rmax,dx,dy,dz; + +//make VHMPID type 2 volume (2 radiators) + TGeoVolume *pBox=gGeoManager->MakeBox("Vbox",gGeoManager->GetMedium("RICH_Al"),dx=dBoxX,dy=dBoxY,dz=dBoxZ); + + TGeoRotation *pRot=new TGeoRotation("VboxRot"); pRot->RotateX(90);//normal position + gGeoManager->GetVolume("ALIC")->AddNode(pBox,copy=1,new TGeoCombiTrans(0*m,-5.2*m,2.5*m,pRot)); +//position C4F10 radiator to Al box + TGeoVolume *pC4F10=gGeoManager->MakeBox("Vc4f",gGeoManager->GetMedium("RICH_C4F10"),dx=dC4F10X,dy=dC4F10Y,dz=dC4F10Z); + pBox->AddNode(pC4F10,copy=1,new TGeoTranslation(0*cm,0*cm,-dBoxZ+wBoxWall+dC4F10Z)); +//position quartz window to Al box + TGeoVolume *pWindow=gGeoManager->MakeBox( "Vwin",gGeoManager->GetMedium("RICH_SiO2"),dx=dWinX,dy=dWinY,dz=dWinZ); + pBox->AddNode(pWindow,copy=1,new TGeoTranslation(0*cm,0*cm,-dBoxZ+wBoxWall+2*dCF4Z+dWinZ)); +//position CF4 radiator to Al box + TGeoVolume *pCF4=gGeoManager->MakeBox( "Vcf4",gGeoManager->GetMedium("RICH_CF4"),dx=dCF4X,dy=dCF4Y,dz=dCF4Z); + pBox->AddNode(pCF4,copy=1,new TGeoTranslation(0*cm,0*cm,dBoxZ-wBoxWall-dCF4Z)); +//position mirror to CF4 radiator + TGeoVolume *pMirror=gGeoManager->MakeBox( "Vmir",gGeoManager->GetMedium("RICH_Ag"),dx=dMirX,dy=dMirY,dz=dMirZ); + TGeoRotation *pMirrorRot=new TGeoRotation("VmirRot"); pMirrorRot->RotateY(45); + pCF4->AddNode(pMirror,copy=1,new TGeoCombiTrans(0*cm,0*cm,dCF4Z-1*cm-dGapX,pMirrorRot)); +//position gap to CF4 radiator + TGeoVolume *pGap =gGeoManager->MakeBox ("Vgap" ,gGeoManager->GetMedium("RICH_CF4"),dx=dGapX , dy=dGapY , dz=dGapZ ); + TGeoRotation *pMwpcRot=new TGeoRotation("VmpcRot"); pMwpcRot->RotateY(90); + pCF4->AddNode(pGap,copy=1,new TGeoCombiTrans(-dBoxX+1*cm,0*cm,dCF4Z-1*cm-dGapX,pMwpcRot)); +//divide gap into 80x48 cells + Int_t axis,ndiv; Double_t start,step; + TGeoVolume *pGapCol =pGap ->Divide("Vcol",axis=1,ndiv=iNpadsX,start=0,step=0);//divide VhGap along X by NpadsX columns + TGeoVolume *pGapCell=pGapCol ->Divide("Vcel",axis=2,ndiv=iNpadsY,start=0,step=0);//divide VhGapCol along Y by NpadsY cells +//position pad to gap cell + TGeoVolume *pPad=gGeoManager->MakeBox ("Vpad",gGeoManager->GetMedium("RICH_CsI"),dx=dPadX,dy=dPadY,dz=dPadZ); + pGapCell->AddNode(pPad,copy=1,new TGeoTranslation(0,0,-dGapZ+dPadZ)); +//define wire rotation common for both anod and cathode wires + TGeoRotation *pWireRot=new TGeoRotation("VwireRot"); pWireRot->RotateY(90); //rotate wires around Y to be along X (initially along Z) +//position 2 anod wires to gap cell + TGeoVolume *pAnodWire =gGeoManager->MakeTube("Vano",gGeoManager->GetMedium("RICH_W") ,rmin=0 , rmax=wAnodR , dz=dPadX ); + pGapCell->AddNode(pAnodWire,copy=1,new TGeoCombiTrans (0, -dPadY+wAnodShift , -dGapZ+wAnodPc+2*dPadZ , pWireRot)); + pGapCell->AddNode(pAnodWire,copy=2,new TGeoCombiTrans (0, dPadY-wAnodShift , -dGapZ+wAnodPc+2*dPadZ , pWireRot)); +//position 4 cathode wires to gap cell + TGeoVolume *pCathWire =gGeoManager->MakeTube("Vcat",gGeoManager->GetMedium("RICH_Cu") ,rmin=0 , rmax=wCathR , dz=dPadX ); + pGapCell->AddNode(pCathWire,copy=1,new TGeoCombiTrans (0, -dPadY+wCathShift , -dGapZ+wCathPc+2*dPadZ , pWireRot)); + pGapCell->AddNode(pCathWire,copy=2,new TGeoCombiTrans (0, -dPadY+wCathShift+wCathPitch , -dGapZ+wCathPc+2*dPadZ , pWireRot)); + pGapCell->AddNode(pCathWire,copy=3,new TGeoCombiTrans (0, dPadY-wCathShift-wCathPitch , -dGapZ+wCathPc+2*dPadZ , pWireRot)); + pGapCell->AddNode(pCathWire,copy=4,new TGeoCombiTrans (0, dPadY-wCathShift , -dGapZ+wCathPc+2*dPadZ , pWireRot)); +}//Vhmpid() //__________________________________________________________________________________________________ void Axis() { @@ -220,20 +432,3 @@ void Axis() TPolyLine3D *pZaxis=new TPolyLine3D(2,Z);pZaxis->SetLineColor(kBlue); pZaxis->Draw(); } //__________________________________________________________________________________________________ -void Colors() -{ -//Set volume colors - TGeoVolume *pVol=0; - pVol=g->GetVolume("Pc") ; if(pVol) pVol->SetLineColor(kGreen); - pVol=g->GetVolume("PPFlarge") ; if(pVol) pVol->SetLineColor(kYellow); - pVol=g->GetVolume("PPFsmall") ; if(pVol) pVol->SetLineColor(kYellow); - pVol=g->GetVolume("RadFront") ; if(pVol) pVol->SetLineColor(kRed); - pVol=g->GetVolume("RadLong") ; if(pVol) pVol->SetLineColor(46); - pVol=g->GetVolume("RadShort") ; if(pVol) pVol->SetLineColor(kMagenta); - pVol=g->GetVolume("RadWin") ; if(pVol) pVol->SetLineColor(kBlue); - pVol=g->GetVolume("RadSpacer"); if(pVol) pVol->SetLineColor(kYellow); - pVol=g->GetVolume("SrcSr90") ; if(pVol) pVol->SetLineColor(kRed); - pVol=g->GetVolume("SrcScrewSr90") ; if(pVol) pVol->SetLineColor(kGreen); - pVol=g->GetVolume("SrcHolePerpex") ; if(pVol) pVol->SetLineColor(26); - pVol=g->GetVolume("SrcHoleAl") ; if(pVol) pVol->SetLineColor(27); -} diff --git a/RICH/RichMake b/RICH/RichMake index e19bc30c376..724e17f20cc 100644 --- a/RICH/RichMake +++ b/RICH/RichMake @@ -41,11 +41,11 @@ DepFile := $(DirOut)/$(Module).depend ifeq ($(RootTarget),linuxicc) Compiler :=icc CompilerOpt :=-O0 -fpstkchk -I$(shell root-config --incdir) -I$(ALICE_ROOT)/include - LibOpt :=-O -g -shared -Wl + LibOpt :=-g -shared -Wl else Compiler :=g++ CompilerOpt :=-g -W -Wall -Woverloaded-virtual -fPIC -pipe -fmessage-length=0 -Wno-long-long -pedantic-errors -ansi -I$(shell root-config --incdir) -I$(ALICE_ROOT)/include - LibOpt :=-O -g -shared -Wl + LibOpt :=-g -shared -Wl endif ifdef ALIVERBOSE diff --git a/RICH/RichMenu.C b/RICH/RichMenu.C index e40092db729..0e619d7a73d 100644 --- a/RICH/RichMenu.C +++ b/RICH/RichMenu.C @@ -1,60 +1,7 @@ -#if !defined( __CINT__) || defined(__MAKECINT__) -#include -#include -#include -#include - -#include "AliRICH.h" -#include "AliRICHDisplFast.h" -#endif - -//globals for easy manual manipulations -AliRun *a; AliStack *s; AliRunLoader *al; +AliRun *a; AliStack *s; AliRunLoader *al; //globals for easy manual manipulations AliRICH *r; AliLoader *rl; - -//__________________________________________________________________________________________________ -void pp(int tid) -{ - if(!al) return; - al->LoadHeader(); al->LoadKinematics(); - - if(tid<0||tid>=al->Stack()->GetNtrack()) - cout<<"Valid tid number is 0-"<Stack()->GetNtrack()-1<<" for this event.\n"; - else - PrintParticleInfo(tid); - - al->UnloadKinematics(); al->UnloadHeader(); -} -//__________________________________________________________________________________________________ -void PrintParticleInfo(int tid) -{ -// Prints particle info for a given TID - TParticle *p=al->Stack()->Particle(tid); - cout<GetName()<<"("<IsPrimary()){cout<<" from "; PrintParticleInfo(p->GetFirstMother());} - else {cout<LoadHeader(); al->LoadKinematics(); - - if(tid<0||tid>=al->Stack()->GetNtrack()) - cout<<"Valid tid number is 0-"<Stack()->GetNtrack()-1<<" for this event.\n"; - else - while(1){ - TParticle *p=al->Stack()->Particle(tid); - if(p->IsPrimary()) break; - tid=p->GetFirstMother(); - } - - al->UnloadKinematics(); al->UnloadHeader(); - return tid; -} -//__________________________________________________________________________________________________ - +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Bool_t AliceRead() { Info("ReadAlice","Tring to read ALICE from SIMULATED FILE..."); @@ -89,16 +36,10 @@ void AliceNew() //__________________________________________________________________________________________________ void RichGet() { - if(!(r=r())) Warning("RICH/menu.C::ReadAlice","No RICH in file"); - if(!(rl=rl())) Warning("RICH/menu.C::ReadAlice","No RICH loader in file"); + if(!(r=(AliRICH*)al->GetAliRun()->GetDetector("RICH"))) Warning("RICH/menu.C::ReadAlice","No RICH in file"); + if(!(rl=al->GetDetectorLoader("RICH"))) Warning("RICH/menu.C::ReadAlice","No RICH loader in file"); } -//__________________________________________________________________________________________________ -void MenuRich() -{ - TControlBar *pMenu = new TControlBar("vertical","RICH"); - pMenu->Show(); -}//TestMenu() //__________________________________________________________________________________________________ void RichMenu() { @@ -107,25 +48,26 @@ void RichMenu() if(AliceRead()){//it's from file, show some info pMenu->AddButton("Display single chambers" ,"r->Display();" , "Display Fast"); pMenu->AddButton("Display ALL chambers" ,"r->DisplayEvent(0,0);" , "Display Fast"); - pMenu->AddButton("Hits QA" ,"hqa()" ,"QA plots for hits: hqa()"); pMenu->AddButton("Recon with stack" ,"AliRICHReconstructor::CheckPR( )","Create RSR.root with ntuple hn"); pMenu->AddButton("RichAna no Recon" ,"AliRICHReconstructor::RichAna(0,0,kFALSE)","Create RichAna.root with ntuple hn without PatRec"); pMenu->AddButton("RichAna with Recon" ,"AliRICHReconstructor::RichAna(0,0,kTRUE )","Create RichAna.root with ntuple hn with PatRec"); - pMenu->AddButton("Print hits" ,"h();" ,"To print hits: h()"); + pMenu->AddButton("HITS Print" ,"h();" ,"To print hits: h()"); + pMenu->AddButton("HITS QA" ,"hqa()" ,"QA plots for hits: hqa()"); pMenu->AddButton("Print sdigits" ,"s();" ,"To print sdigits: s()"); pMenu->AddButton("Print digits" ,"d();" ,"To print digits: d()"); - pMenu->AddButton("Print clusters" ,"c();" ,"To print clusters: c()"); + pMenu->AddButton("Clusters print" ,"c();" ,"To print clusters: c()"); + pMenu->AddButton("Clusters QA" ,"cqa();" ,"Clusters QA: cqa() or AliRICHReconstructor::CluQA(al)"); + pMenu->AddButton("Print ESD" ,"e();" ,"To print ESD status"); pMenu->AddButton("Print occupancy" ,"r->OccupancyPrint(-1);" ,"To print occupancy"); pMenu->AddButton("Print event summary " ,"r->SummaryOfEvent();" ,"To print a summary of the event"); }else{//it's aliroot, simulate pMenu->AddButton("Debug ON", "DebugON();", "Switch debug on-off"); pMenu->AddButton("Debug OFF", "DebugOFF();", "Switch debug on-off"); - pMenu->AddButton("Run", "a()->Run(1)", "Process!"); + pMenu->AddButton("Run", "a->Run(1)", "Process!"); } pMenu->AddButton("Test segmentation" ,"rp->TestSeg()" ,"Test AliRICHParam segmentation methods" ); pMenu->AddButton("Test response" ,"rp->TestResp()" ,"Test AliRICHParam response methods" ); pMenu->AddButton("Test transformation","rp->TestTrans()","Test AliRICHParam transformation methods" ); - pMenu->AddButton("Optics" ,"opt()" ,"Shows optical properties"); pMenu->AddButton("Geo GUI" ,"geo();" ,"Shows geometry" ); pMenu->AddButton("Debug ON" ,"AliLog::SetGlobalDebugLevel(AliLog::kDebug);" ,"Switch debug on" ); pMenu->AddButton("Debug OFF" ,"AliLog::SetGlobalDebugLevel(0);" ,"Switch debug off" ); @@ -136,48 +78,38 @@ void RichMenu() //__________________________________________________________________________________________________ void DebugOFF(){ Info("DebugOFF",""); AliLog::SetGlobalDebugLevel(0);} void DebugON() { Info("DebugON",""); AliLog::SetGlobalDebugLevel(AliLog::kDebug);} -//__________________________________________________________________________________________________ -void GeomGui() -{ - if(gGeoManager){ - gGeoManager->GetTopVolume()->Draw(); - AliRICHParam::DrawAxis(); - }else - new G3GeometryGUI; -} - -AliRun *a() {return al->GetAliRun();} //provides pointer to main AliRun object (aka gAlice) -AliRICH *r() {return (AliRICH*) a()->GetDetector("RICH");} //provides pointer to RICH detector -AliLoader *rl(){return al->GetLoader("RICHLoader");} - - -void geo ( ) { gGeoManager->SetVisOption(0);gGeoManager->GetTopVolume()->Draw(); AliRICHParam::DrawAxis();} -void opt ( ) { AliRICHParam::Materials(); } //draw optical properties +//void geo ( ) { gGeoManager->SetVisOption(0);gGeoManager->GetTopVolume()->Draw(); AliRICHParam::DrawAxis();} +void geo() { if(!gGeoManager) TGeoManager::Import("geometry.root");gGeoManager->GetTopVolume()->Draw();AliRICHParam::DrawAxis();} + void dis (Int_t evt=-1) {r->Display (evt);} //utility display void dum ( ) {r->Dump ( );} //utility display -void h (Int_t evt=0 ) {r->HitsPrint (evt);} //print hits for requested event -void s (Int_t evt=0 ) {r->SDigitsPrint (evt);} //print sdigits for requested event -void d (Int_t evt=0 ) {r->DigitsPrint (evt);} //print digits for requested event -void c (Int_t evt=0 ) {r->ClustersPrint(evt);} //print clusters for requested event +void h (Int_t evt=0 ) {r->HitPrint (evt);} //print hits for requested event +void hqa ( ) {r->HitQA ( );} //hits QA plots for all events + +void s (Int_t evt=0 ) {r->SDigPrint (evt);} //print sdigits for requested event + +void d (Int_t evt=0 ) {r->DigPrint (evt);} //print digits for requested event +void dqa ( ) {AliRICHReconstructor::DigQA (al );} //digits QA plots for all events -void hqa ( ) {r->HitsQA ( );} //hits QA plots for all events -void dqa ( ) {r->DigitsQA ( );} //digits QA plots for all events -void cqa ( ) {r->ClustersQA ( );} //clusters QA plots for all events +void c (Int_t evt=0 ) {r->CluPrint (evt);} //print clusters for requested event +void cqa ( ) {AliRICHReconstructor::CluQA (al );} //clusters QA plots for all events +void ct ( ) {AliRICHReconstructor::Test ( );} //test clusters by predifined list of digits -Int_t t (Int_t pid,Int_t evt=0) {return (AliRICH*)v())->TrackPrint(pid,evt);} //print track +void t (Int_t evt=0 ) {AliRICHParam::Stack(evt);} +void tid (Int_t tid,Int_t evt=0) {AliRICHParam::Stack(evt,tid);} +void e ( ) {AliRICHTracker::EsdPrint();} -void rt(Int_t event=0) {r->PrintTracks (event);} //utility print tracks -Int_t nem(Int_t event=0) {AliRICH::Nparticles(kElectron ,event,al);} //utility number of electrons -Int_t nep(Int_t event=0) {AliRICH::Nparticles(kPositron ,event,al);} //utility number of positrons -Int_t nmup(Int_t event=0) {AliRICH::Nparticles(kMuonPlus ,event,al);} //utility number of positive muons -Int_t nmum(Int_t event=0) {AliRICH::Nparticles(kMuonMinus ,event,al);} //utility number of negative muons -Int_t npi0(Int_t event=0) {AliRICH::Nparticles(kPi0 ,event,al);} //utility number of neutral pions -Int_t npip(Int_t event=0) {AliRICH::Nparticles(kPiPlus ,event,al);} //utility number of positive pions -Int_t npim(Int_t event=0) {AliRICH::Nparticles(kPiMinus ,event,al);} //utility number of negative pions -Int_t nk0(Int_t event=0) {AliRICH::Nparticles(kK0 ,event,al);} //utility number of neutral kaons -Int_t nkp(Int_t event=0) {AliRICH::Nparticles(kKPlus ,event,al);} //utility number of positive kaons -Int_t nkm(Int_t event=0) {AliRICH::Nparticles(kKMinus ,event,al);} //utility number of negative kaons -Int_t npp(Int_t event=0) {AliRICH::Nparticles(kProton ,event,al);} //utility number of protons -Int_t npm(Int_t event=0) {AliRICH::Nparticles(kProtonBar ,event,al);} //utility number of antiprotons +Int_t nem (Int_t evt=0) {AliRICHParam::StackCount(kElectron ,evt);} //utility number of electrons +Int_t nep (Int_t evt=0) {AliRICHParam::StackCount(kPositron ,evt);} //utility number of positrons +Int_t nmup(Int_t evt=0) {AliRICHParam::StackCount(kMuonPlus ,evt);} //utility number of positive muons +Int_t nmum(Int_t evt=0) {AliRICHParam::StackCount(kMuonMinus ,evt);} //utility number of negative muons +Int_t npi0(Int_t evt=0) {AliRICHParam::StackCount(kPi0 ,evt);} //utility number of neutral pions +Int_t npip(Int_t evt=0) {AliRICHParam::StackCount(kPiPlus ,evt);} //utility number of positive pions +Int_t npim(Int_t evt=0) {AliRICHParam::StackCount(kPiMinus ,evt);} //utility number of negative pions +Int_t nk0 (Int_t evt=0) {AliRICHParam::StackCount(kK0 ,evt);} //utility number of neutral kaons +Int_t nkp (Int_t evt=0) {AliRICHParam::StackCount(kKPlus ,evt);} //utility number of positive kaons +Int_t nkm (Int_t evt=0) {AliRICHParam::StackCount(kKMinus ,evt);} //utility number of negative kaons +Int_t npp (Int_t evt=0) {AliRICHParam::StackCount(kProton ,evt);} //utility number of protons +Int_t npm (Int_t evt=0) {AliRICHParam::StackCount(kProtonBar ,evt);} //utility number of antiprotons diff --git a/RICH/api.txt b/RICH/api.txt index 1254a3a5249..ec958e92e7c 100644 --- a/RICH/api.txt +++ b/RICH/api.txt @@ -1,7 +1,7 @@ How to open session: use static method AliRunLoader::Open("galice.root","AlicE","update") How to get total number of events in galice.root: - use AliRun::GetEventsPerRun() + use AliRun::GetEventsPerRun() or AliRunLoader::GetNumberOfEvents() How to avoid using gAlice: detector->GetLoader()->GetRunLoader()->GetAliRun() returns gAlice global pointer. How to retrieve pointer to alice run loader: @@ -92,28 +92,52 @@ hits->sdigit: Then, total charge collected for this hit is calculated by AliRICHParam::Hit2Qdc. Area of disintegration is a list of pads affected by current hit. This is a parameter of Mathienson sdigits->digits: - The necessety of sdigits is dictated by the fact that trasport engine transports track by track. It means that it may happen that the same - pad is affected by few tracks. But this might be known after the trasport of full event only. + The necessety of sdigits is dictated by the fact that trasport engine transports tracks in a continious sequence track by track. + It means that it may happen that the same pad is affected by few tracks. But this might be known only after the trasport of full event is finished. + +digits->clusters + A set of neighbouring digits compose cluster. The aim of this trasformation is to construct a list of clusters out of digits list. + The calling sequence is: + AliReconstruction::Run() + + AliRICHReconstructor::Reconstruct() creates an empty clusters list, loops on chambers, retrives a list of digits for a given chamber, gives it to the methode Dig2Clu() and finally serializes + the list + + AliRICHReconstructor::Dig2Clu() which knows no details about + + +clusters+tracks->theta cerenkov + + + + + + + + + + Generalized structure of AliReconstruction: Run() { - if(there is galice.root) | - AliRunLoader::Open(....) | this is done in InitRunLoader() - else | + if(there is galice.root) <-| + AliRunLoader::Open(....) | + else | this is done in InitRunLoader() if(raw data process requested) | - create galice.root on the base of AliRawReader::NextEvent | + create galice.root on the base of AliRawReader::NextEvent <-| - for(all detectors){ | - if(detector not selected to run) skip this detector | - reconstructor=get detector's reconstructor | this is done in RunLocalReconstruction() + for(all detectors){ <-| + if(detector not selected to run) skip this detector | this is done in RunLocalReconstruction() + reconstructor=get detector's reconstructor | + | if(detector HasLocalReconstruction) skip this detector | IMPORTANT! if HasLocalReconstruction() returns YES use RunLocalEventReconstruction instead if(run upon raw data) | reconstructor->Reconstruct(fRunLoader, fRawReader); | - else | + else | <- this approach is currently used by RICH as all branches are mounted in AliRICH.cxx reconstructor->Reconstruct(fRunLoader); | - } + } <-| for(all events){ @@ -146,3 +170,98 @@ Run() }//events loop } + + +RICH calibration and alignment. + +Abstract +RICH calibrartion and alignment strategy is described with emphasis put on those aspects of the procedure which are relevant for reconstruction and thus the final detector +figure of merit. In particulare, the refractive index calibration tecknique based on mass plot shifts analisys and chamber alignment with respect to core detectors +are explained in details. External sources of calibration and alignment data are aslo mentioned as well as the way RICH intends to handle those data, including initial CDB +creater. + +Calibration. +Looking on RICH chamber structure, full description of which is availbale elsewhere (ref RichTDR), easy to compile the table of all possible parameters affecting reconstruction. +The first one of major importance is a freon refractive index. Although the full optical path visiable by photons includes freon vessel, proximity and amplification gaps filled +with methane and quartz window seperating above mentioned volumes, only freon refractive index is subject for calibration. Refractive index of SiO2 window is not practically +affected by any external parameters, while influence of methane temperature to it's refractive index is negligable. So it's enough to measure there optical curves just once. +In the rest, the only changable parameter is refractive index of freon. Temperature influence on freon refractive index was measured experimentally. The parametrization +found to be: + n=n0-0.0005(T-20) where T is freon temperature in degrees Celsius + n0=Sqrt(1+ 0.554*lamda^2/(lamda^2-5796)) where lamda is photon wavelength in nm taken at 20 degress Celsius +Preliminary, the parametrization itself is considered to be permamnent one. The only parameter to store and retrieve is freon temperature. Since this value is available from +DCS DB and expected to be served by a SHUTTLE program which is not yet ready, the following temporaroly solution has been adopted. +In local CDB storage (deafult directory is $ALICE_ROOT) two versions of freon refractive index are written by external macro RichCdb.C : +Run0_0_v0_s0.root contains DiMauro's parametrization and the temperature is set to 20 degrees. To be used as default for simulation and reconstruction. +Run0_0_v0_s1.root contains DiMauro's parametrization and the temperature is set to 50 degrees. To be used in special uncalibrated reconstruction to test calibration procedure. +Both of them are valid in run range from run number 0 to run number 0, thus in no way affecting any normal operations. + +Refractive index of freon (C6F14) is taken in AliRICHRecon for 3 different photon energies by means of 2 methodes: Set + + + +Alignment. +Information about detector position and orientation is needed during reconstruction phase. This information affects track-cluster matching procedure, the relevant peace of +code comes to AliRICHTracker::PropogateBack(). Matching precedure consists in prolongation of the track reconstructed in core detectores up to each RICH chamber plane in +a sequenmce. The plane used is the entrance to RICH radiators. If the intersection exists and inside the sensitive area, the point of intersection is to be tranformed to RICH +local reference system. Note, that in this check, the dead zones inbetween radiators are not taken into account. This operation requiring MARS to LORS transformations is done +in AliRICHHelix::RichIntersection(). Plane to be intersected is defined by a point beloging to that plane served by AliRICHParam::Center(ChamberNumber) and a vector normal +to the plane served by AliRICHParam::Norm(ChamberNumber). Transformations itself are done in AliRICHParam::Mars2Lors() and AliRICHParam::Lors2Mars(). Internaly in AliRICHParam, +each chamber is reresented by TGeoHMatrix. It's worth to stress again that geometry related operations are needed to be done for 3 different planes per chamber, namly entrance +to radiator, anod wires plane and photocathode plane. So AliRICHParam sustains 7*3=21 planes. Also important to say, that direct usage of TGeoHMatrix::MasterToLocal() +and virce versa is not possible due to special nature of RICH LORS. According to the decision made about 3 years ago, RICH local reference system is centered in low left +hand corner of the chamber if one looks from outside to direction pointing to interection point. +So the most obvious candidate for alignable objects to be stored are thess 21 TGeoHMatrix objects. +The approach suggested in AliAlignObj is not quite feasable mainly due to the fact it relays on incrementing procedure using import from geometry.root. RICH geometry is defined +in a way that there is no volumes exactly corresponding to the RICH planes. + +Geometry of RICH chambers. +After the decision to rotate the whole RICH setup from 12 o'clock position to 2 o'clock position we have the following situtation: + +Theta = 109.5 degress for chambers 1,3 +Theta = 90.0 degress for chambers 2,4,6 +Theta = 70.5 degress for chambers 5,7 + +Phi = 50.0 degress for chambers 6,7 +Phi = 30.0 degress for chambers 3,4,5 +Phi = 10.0 degress for chambers 1,2 + + +Old parametrisation by AliRICHChamber: +RICH chamber 1 (454.877118 , 80.207109 , -163.565361)(rho,theta,phi)=(490.0,109.5,10.0) +RICH chamber 2 (482.555799 , 85.087607 , 0.000000)(rho,theta,phi)=(490.0, 90.0,10.0) +RICH chamber 3 (400.012224 , 230.947165 , -163.565361)(rho,theta,phi)=(490.0,109.5,30.0) +RICH chamber 4 (424.352448 , 245.000000 , 0.000000)(rho,theta,phi)=(490.0, 90.0,30.0) +RICH chamber 5 (400.012224 , 230.947165 , 163.565361)(rho,theta,phi)=(490.0, 70.5,30.0) +RICH chamber 6 (314.965929 , 375.361777 , 0.000000)(rho,theta,phi)=(490.0, 90.0,50.0) +RICH chamber 7 (296.899953 , 353.831585 , 163.565361)(rho,theta,phi)=(490.0, 70.5,50.0) + +New parametrization by TGeoHMatrix: +RICH 1 + -0.328736 -0.173648 0.928321 Tx = 454.877118 + -0.057965 0.984808 0.163688 Ty = 80.207109 + -0.942641 0.000000 -0.333807 Tz = -163.565361 +RICH 2 + 0.000000 -0.173648 0.984808 Tx = 482.555799 + 0.000000 0.984808 0.173648 Ty = 85.087607 + -1.000000 0.000000 0.000000 Tz = 0.000000 +RICH 3 + -0.289085 -0.500000 0.816351 Tx = 400.012224 + -0.166903 0.866025 0.471321 Ty = 230.947165 + -0.942641 0.000000 -0.333807 Tz = -163.565361 +RICH 4 + 0.000000 -0.500000 0.866025 Tx = 424.352448 + 0.000000 0.866025 0.500000 Ty = 245.000000 + -1.000000 0.000000 0.000000 Tz = 0.000000 +RICH 5 + 0.289085 -0.500000 0.816351 Tx = 400.012224 + 0.166903 0.866025 0.471321 Ty = 230.947165 + -0.942641 0.000000 0.333807 Tz = 163.565361 +RICH 6 + 0.000000 -0.766044 0.642788 Tx = 314.965929 + 0.000000 0.642788 0.766044 Ty = 375.361777 + -1.000000 0.000000 0.000000 Tz = 0.000000 +RICH 7 + 0.214567 -0.766044 0.605918 Tx = 296.899953 + 0.255711 0.642788 0.722105 Ty = 353.831585 + -0.942641 0.000000 0.333807 Tz = 163.565361 diff --git a/RICH/libRICHbase.pkg b/RICH/libRICHbase.pkg index 7118cf65691..a1a5d5f7653 100644 --- a/RICH/libRICHbase.pkg +++ b/RICH/libRICHbase.pkg @@ -1,4 +1,4 @@ -SRCS:= AliRICHParam.cxx AliRICHChamber.cxx AliRICHHit.cxx AliRICHDigit.cxx AliRICHCluster.cxx AliRICHHelix.cxx AliRICH.cxx +SRCS:= AliRICHParam.cxx AliRICHHit.cxx AliRICHDigit.cxx AliRICHCluster.cxx AliRICHHelix.cxx AliRICH.cxx HDRS:= $(SRCS:.cxx=.h) DHDR:= RICHbaseLinkDef.h diff --git a/RICH/libRICHrec.pkg b/RICH/libRICHrec.pkg index 0a36e50a79f..bc77d9657e4 100644 --- a/RICH/libRICHrec.pkg +++ b/RICH/libRICHrec.pkg @@ -1,4 +1,4 @@ -SRCS:= AliRICHReconstructor.cxx AliRICHClusterFinder.cxx AliRICHMap.cxx AliRICHTracker.cxx AliRICHRecon.cxx +SRCS:= AliRICHReconstructor.cxx AliRICHTracker.cxx AliRICHRecon.cxx HDRS:= $(SRCS:.cxx=.h) DHDR:= RICHrecLinkDef.h -- 2.43.0