From e30ca504cc4a0fb28e7b427f6e5edd0ea0fdf3a4 Mon Sep 17 00:00:00 2001 From: kir Date: Fri, 27 Oct 2006 14:02:41 +0000 Subject: [PATCH] MAJOR UPGRADE: 1. all objects are counted from 0 2. new AliRICHRecon 3. calib off for while --- RICH/AliRICH.cxx | 541 ++--------------- RICH/AliRICH.h | 135 ++--- RICH/AliRICHCluster.cxx | 131 ++-- RICH/AliRICHCluster.h | 101 +--- RICH/AliRICHDigit.cxx | 176 ++++-- RICH/AliRICHDigit.h | 225 ++++--- RICH/AliRICHDigitizer.cxx | 82 ++- RICH/AliRICHDigitizer.h | 4 + RICH/AliRICHHelix.cxx | 24 +- RICH/AliRICHHelix.h | 129 ++-- RICH/AliRICHHit.cxx | 21 +- RICH/AliRICHHit.h | 62 +- RICH/AliRICHParam.cxx | 400 +------------ RICH/AliRICHParam.h | 688 +-------------------- RICH/AliRICHRecon.cxx | 1065 +++++++++------------------------ RICH/AliRICHRecon.h | 207 ++----- RICH/AliRICHReconstructor.cxx | 204 ++----- RICH/AliRICHReconstructor.h | 3 - RICH/AliRICHTracker.cxx | 305 ++-------- RICH/AliRICHTracker.h | 5 - RICH/AliRICHv1.cxx | 463 +++++++------- RICH/AliRICHv1.h | 31 +- RICH/RICHbaseLinkDef.h | 8 +- RICH/RICHrecLinkDef.h | 1 + RICH/RichConfig.C | 24 +- RICH/RichMake | 4 +- RICH/RichMenu.C | 517 ++++++++++++++-- RICH/api.txt | 11 +- RICH/libRICHbase.pkg | 2 +- RICH/libRICHrec.pkg | 2 +- 30 files changed, 1787 insertions(+), 3784 deletions(-) diff --git a/RICH/AliRICH.cxx b/RICH/AliRICH.cxx index bc594e8f1d8..054d130cf49 100644 --- a/RICH/AliRICH.cxx +++ b/RICH/AliRICH.cxx @@ -14,53 +14,30 @@ // ************************************************************************** #include "AliRICH.h" -#include "AliRICHParam.h" -#include "AliRICHHelix.h" //ReadESD -#include -#include -#include -#include -#include +#include "AliRICHHit.h" //OccupancyPrint(), HitQa() +#include "AliRICHDigit.h" //OccupancyPrint() +#include //SummaryOfEvent(), HitQa() +#include //HitQA() +#include //HitQA() +#include //OccupancyPrint(), SummaryOfEvent(), HitQa() +#include //HitQa() #include //ctor #include #include #include -#include #include //HitQA() -#include //Display() -#include -#include -#include //Display() -#include //Display() -#include //Display() -#include //Display() -#include //Display() +#include //in many methods to print AliInfo ClassImp(AliRICH) -//__________________________________________________________________________________________________ -// RICH manager class -//BEGIN_HTML -/* - -*/ -//END_HTML -//__________________________________________________________________________________________________ -AliRICH::AliRICH():AliDetector(),fSdig(0),fSdigCnt(0),fDig(0),fClu(0),fCounters(0),fNcham(0) -{ -//Default ctor should not contain any new operators -//AliDetector ctor deals with Hits and Digits -}//AliRICH::AliRICH() -//__________________________________________________________________________________________________ -AliRICH::AliRICH(const char *name, const char *title):AliDetector(name,title),fSdig(0),fSdigCnt(0),fDig(0),fClu(0),fCounters(0),fNcham(0) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliRICH::AliRICH(const char *name, const char *title):AliDetector(name,title),fSdi(0),fDig(0),fClu(0) { //Named ctor AliDebug(1,"Start."); //AliDetector ctor deals with Hits and Digits (reset them to 0, does not create them) HitCreate(); gAlice->GetMCApp()->AddHitList(fHits); - fNcham=7; - fCounters.ResizeTo(40); fCounters.Zero(); AliDebug(1,"Stop."); }//AliRICH::AliRICH(const char *name, const char *title) -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AliRICH::~AliRICH() { //dtor @@ -68,84 +45,41 @@ AliRICH::~AliRICH() if(fHits) delete fHits; - if(fSdig) delete fSdig; if(fDigits) delete fDigits; + if(fSdi) delete fSdi; if(fDig) {fDig->Delete(); delete fDig;} if(fClu) {fClu->Delete(); delete fClu;} AliDebug(1,"Stop."); }//AliRICH::~AliRICH() -//__________________________________________________________________________________________________ -void AliRICH::BuildGeometry() -{ -//Builds a TNode geometry for event display - AliDebug(1,"Start."); - - AliDebug(1,"Stop."); -}//void AliRICH::BuildGeometry() -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICH::MakeBranch(Option_t* option) { //Create Tree branches for the RICH. AliDebug(1,Form("Start with option= %s.",option)); - const Int_t kBufferSize = 4000; + const Int_t kBufSize = 4000; const char *cH = strstr(option,"H"); const char *cD = strstr(option,"D"); const char *cR = strstr(option,"R"); const char *cS = strstr(option,"S"); - if(cH&&TreeH()){//H - HitCreate(); //branch will be created in AliDetector::MakeBranch - }//H - AliDetector::MakeBranch(option);//this is after cH because we need to guarantee that fHits array is created - - if(cS&&fLoader->TreeS()){//S - SDigCreate(); MakeBranchInTree(fLoader->TreeS(),"RICH",&fSdig,kBufferSize,0) ; - }//S - - if(cD&&fLoader->TreeD()){//D - DigCreate(); - for(Int_t i=0;iTreeD(),Form("%s%d",GetName(),i+1),&((*fDig)[i]),kBufferSize,0); - } - }//D + if(cH&& TreeH()){HitCreate(); MakeBranchInTree( TreeH(), "RICH" ,&fHits ,kBufSize,0);} + if(cS&&fLoader->TreeS()){SdiCreate(); MakeBranchInTree(fLoader->TreeS(), "RICH" ,&fSdi ,kBufSize,0);} + if(cD&&fLoader->TreeD()){DigCreate();for(Int_t i=0;i<7;i++) MakeBranchInTree(fLoader->TreeD(),Form("RICH%d",i),&((*fDig)[i]),kBufSize,0);} + if(cR&&fLoader->TreeR()){CluCreate();for(Int_t i=0;i<7;i++) MakeBranchInTree(fLoader->TreeR(),Form("RICH%d",i),&((*fClu)[i]),kBufSize,0);} - if(cR&&fLoader->TreeR()){//R - CluCreate(); - for(Int_t i=0;iTreeR(),Form("%sClusters%d",GetName(),i+1), &((*fClu)[i]), kBufferSize, 0); - }//R AliDebug(1,"Stop."); }//void AliRICH::MakeBranch(Option_t* option) -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICH::SetTreeAddress() { //Set branch address for the Hits and Digits Tree. AliDebug(1,"Start."); - - TBranch *branch; - - if(fLoader->TreeH()){//H - AliDebug(1,"tree H is requested."); - HitCreate();//branch map will be in AliDetector::SetTreeAddress - }//H - AliDetector::SetTreeAddress();//this is after TreeH because we need to guarantee that fHits array is created - - if(fLoader->TreeS()){//S - AliDebug(1,"tree S is requested."); - branch=fLoader->TreeS()->GetBranch(GetName()); if(branch){SDigCreate(); branch->SetAddress(&fSdig);} - }//S - - if(fLoader->TreeD()){//D - AliDebug(1,"tree D is requested."); - for(int i=0;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){CluCreate(); branch->SetAddress(&((*fClu)[i]));}} - }//R + if(fLoader->TreeH() && fLoader->TreeH()->GetBranch("RICH" )){HitCreate(); fLoader->TreeH()->SetBranchAddress( "RICH" ,&fHits );} + if(fLoader->TreeS() && fLoader->TreeS()->GetBranch("RICH" )){SdiCreate(); fLoader->TreeS()->SetBranchAddress( "RICH" ,&fSdi );} + if(fLoader->TreeD() && fLoader->TreeD()->GetBranch("RICH0")){DigCreate(); for(int i=0;i<7;i++) fLoader->TreeD()->SetBranchAddress(Form("RICH%d",i),&((*fDig)[i]));} + if(fLoader->TreeR() && fLoader->TreeR()->GetBranch("RICH0")){CluCreate(); for(int i=0;i<7;i++) fLoader->TreeR()->SetBranchAddress(Form("RICH%d",i),&((*fClu)[i]));} AliDebug(1,"Stop."); }//void AliRICH::SetTreeAddress() //__________________________________________________________________________________________________ @@ -180,38 +114,34 @@ void AliRICH::HitPrint(Int_t iEvtN)const GetLoader()->UnloadHits(); AliInfo(Form("totally %i hits",iTotalHits)); } -//__________________________________________________________________________________________________ -void AliRICH::SDigPrint(Int_t iEvtN)const +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICH::SdiPrint(Int_t iEvt)const { //prints a list of RICH sdigits for a given event - if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return; - Info("PrintSDigits","List of RICH sdigits for event %i",iEvtN); + if(GetLoader()->GetRunLoader()->GetEvent(iEvt)) return; + Info("PrintSDigits","List of RICH sdigits for event %i",iEvt); if(GetLoader()->LoadSDigits()) return; GetLoader()->TreeS()->GetEntry(0); - fSdig->Print(); + SdiLst()->Print(); GetLoader()->UnloadSDigits(); - Printf("totally %i sdigits",fSdig->GetEntries()); + Printf("totally %i sdigits",SdiLst()->GetEntries()); } -//__________________________________________________________________________________________________ -void AliRICH::DigPrint(Int_t iEvtN)const +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICH::DigPrint(Int_t iEvt)const { //prints a list of RICH digits for a given event - if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return; - Printf("List of RICH digits for event %i",iEvtN); + if(GetLoader()->GetRunLoader()->GetEvent(iEvt)) return; + Printf("List of RICH digits for event %i",iEvt); if(GetLoader()->LoadDigits()) return; - Int_t iTotalDigits=0; GetLoader()->TreeD()->GetEntry(0); - if(!fDig) return; - for(Int_t iCham=0;iChamAt(iCham); iTotalDigits+=pDigs->GetEntries(); pDigs->Print(); - } + DigLst()->Print(); GetLoader()->UnloadDigits(); - Printf("totally %i Digits",iTotalDigits); + Printf("totally %i Digits",DigLst()->GetEntries()); } -//__________________________________________________________________________________________________ -void AliRICH::OccupancyPrint(Int_t iEvtNreq)const +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICH::OccupancyPrint(Int_t iEvtNreq) { //prints occupancy for each chamber in a given event Int_t iEvtNmin,iEvtNmax; @@ -229,41 +159,44 @@ void AliRICH::OccupancyPrint(Int_t iEvtNreq)const if(GetLoader()->LoadHits()) return; if(GetLoader()->LoadDigits()) return; - Int_t totPadsPerChamber = AliRICHParam::NpadsX()*AliRICHParam::NpadsY(); - for(Int_t iEvtN=iEvtNmin;iEvtNGetRunLoader()->GetEvent(iEvtN)) return; AliStack *pStack = GetLoader()->GetRunLoader()->Stack(); 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(pHit->Eloss()>0){ - iChHits[pHit->C()-1]++; - if(pStack->Particle(pHit->GetTrack())->Rho()<0.01) nPrim[pHit->C()-1]++;else nSec[pHit->C()-1]++; + AliRICHHit *pHit = (AliRICHHit*)Hits()->At(iHitN); + if(pHit->E()>0){ + iChHits[pHit->Ch()]++; + if(pStack->Particle(pHit->GetTrack())->Rho()<0.01) nPrim[pHit->Ch()]++;else nSec[pHit->Ch()]++; } } } + GetLoader()->TreeD()->GetEntry(0); - for(Int_t iCh=0;iChAt(iCh))->GetEntries(); - Double_t occupancy = (Double_t)nDigCh[iCh]/(Double_t)totPadsPerChamber; - Info("Occupancy","for chamber %i = %4.2f %% and charged prim tracks %i and sec. tracks %i with total %i", - iCh+1,occupancy*100.,nPrim[iCh],nSec[iCh],iChHits[iCh]); - } - } + for(Int_t iCh=0;iCh<7;iCh++){ + for(Int_t iDig=0;iDigGetEntries();iDig++){ + AliRICHDigit *pDig=(AliRICHDigit*)DigLst(iCh)->At(iDig); + nDigCh[pDig->Ch()]++; + } + Printf("Occupancy for chamber %i = %4.2f %% and charged prim tracks %i and sec. tracks %i with total %i", + iCh,Float_t(nDigCh[iCh])*100/AliRICHDigit::kPadAll,nPrim[iCh],nSec[iCh],iChHits[iCh]); + } + + + }//events loop GetLoader()->UnloadHits(); GetLoader()->UnloadDigits(); GetLoader()->GetRunLoader()->UnloadHeader(); GetLoader()->GetRunLoader()->UnloadKinematics(); } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICH::CluPrint(Int_t iEvtN)const { //prints a list of RICH clusters for a given event @@ -273,210 +206,13 @@ void AliRICH::CluPrint(Int_t iEvtN)const Int_t iCluCnt=0; GetLoader()->TreeR()->GetEntry(0); - for(Int_t iCham=0;iChamAt(iCham); iCluCnt+=pClus->GetEntries(); pClus->Print(); + for(Int_t iCh=0;iCh<7;iCh++){ + TClonesArray *pCluLst=(TClonesArray*)fClu->At(iCh); iCluCnt+=pCluLst->GetEntries(); pCluLst->Print(); } GetLoader()->UnloadRecPoints(); Printf("totally %i clusters for event %i",iCluCnt,iEvtN); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICH::DisplayEvent(Int_t iEvtNmin,Int_t iEvtNmax)const -{ -// Display digits, reconstructed tracks intersections and RICH rings if available - TH2F *pH2[8]; - - GetLoader()->LoadDigits(); - - TLatex t; t.SetTextSize(0.1); - TCanvas *pC = new TCanvas("RICHDisplay","RICH Display",0,0,1226,900); pC->Divide(3,3); pC->cd(9); t.DrawText(0.2,0.4,"View to IP"); - gStyle->SetPalette(1); - - - for(Int_t iCh=1;iCh<=fNcham;iCh++) { - pH2[iCh] = new TH2F(Form("RichDigH2_%i",iCh),Form("Chamber %i;cm;cm",iCh),165,0,AliRICHParam::PcSizeX(),144,0,AliRICHParam::PcSizeY()); - pH2[iCh]->SetMarkerColor(kGreen); - pH2[iCh]->SetMarkerStyle(29); - pH2[iCh]->SetMarkerSize(0.4); - pH2[iCh]->SetStats(kFALSE); - pH2[iCh]->SetMaximum(300); - } - - if(iEvtNmax>gAlice->GetEventsPerRun()||iEvtNmax==0) iEvtNmax=gAlice->GetEventsPerRun()-1; - - for(Int_t iEvt=iEvtNmin;iEvt<=iEvtNmax;iEvt++) {//events loop - pC->cd(3); t.DrawText(0.2,0.4,Form("Event %i",iEvt)); - - GetLoader()->GetRunLoader()->GetEvent(iEvt); //get event - GetLoader()->TreeD()->GetEntry(0); //get list of digits - for(Int_t iCh=1;iCh<=fNcham;iCh++) {//chambers loop - pH2[iCh]->Reset(); - for(Int_t iDig=0;iDig < Digs(iCh)->GetEntries();iDig++) {//digits loop - AliRICHDigit *pDig = (AliRICHDigit*)Digs(iCh)->At(iDig); - TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad()); - pH2[pDig->C()]->Fill(x2.X(),x2.Y(),pDig->Qdc()); - }//digits loop - if(iCh==1) pC->cd(9); - if(iCh==2) pC->cd(8); - if(iCh==3) pC->cd(6); - if(iCh==4) pC->cd(5); - if(iCh==5) pC->cd(4); - if(iCh==6) pC->cd(2); - if(iCh==7) pC->cd(1); - pH2[iCh]->Draw("col"); - ReadESD(iEvt,iCh); - AliRICHParam::DrawSectors(); - }//chambers loop - pC->Update(); - pC->Modified(); - - if(iEvtWaitPrimitive();pC->Clear();} - }//events loop -}//ShowEvent() -//__________________________________________________________________________________________________ -void AliRICH::Display()const -{ -//Provides fast event display -//For RICH only, full display is .x Display.C - Bool_t isHits =!GetLoader()->LoadHits(); - Bool_t isDigits =!GetLoader()->LoadDigits(); - Bool_t isClusters=!GetLoader()->LoadRecPoints(); - - if(!isHits && !isDigits && !isClusters){Error("Exec","No hits digits and clusters. Nothing to display.");return;} - - TCanvas *pCanvas = new TCanvas("Display","RICH Display",0,0,600,600); - - TH2F *pHitsH2=0,*pDigitsH2=0,*pClustersH2=0; - - if(isHits) pHitsH2 = new TH2F("pHitsH2" , "Event Display;x,cm;y,cm",165,0,AliRICHParam::PcSizeX(), - 144,0,AliRICHParam::PcSizeY()); - if(pHitsH2) pHitsH2->SetStats(kFALSE); - - if(isDigits) pDigitsH2 = new TH2F("pDigitsH2" ,"Event Display",165,0,AliRICHParam::PcSizeX(), - 144,0,AliRICHParam::PcSizeY()); - if(isClusters) pClustersH2 = new TH2F("pClustersH2","Event Display",165,0,AliRICHParam::PcSizeX(), - 144,0,AliRICHParam::PcSizeY()); - - for(Int_t iEvt=0;iEvtGetRunLoader()->GetNumberOfEvents();iEvt++){//events Loop - GetLoader()->GetRunLoader()->GetEvent(iEvt); -//display all the staff on chamber by chamber basis - for(Int_t iCh=1;iCh<=fNcham;iCh++){//chambers loop - if(isHits) pHitsH2 ->Reset(); - if(isDigits) pDigitsH2 ->Reset(); - if(isClusters) pClustersH2->Reset(); -//deals with hits - for(Int_t i=0;iTreeH()->GetEntries();i++){//TreeH loop - GetLoader()->TreeH()->GetEntry(i); - 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",iEvt,iCh)); - pHitsH2->SetMarkerColor(kRed); pHitsH2->SetMarkerStyle(29); pHitsH2->SetMarkerSize(0.4); - pHitsH2->Draw(); - AliRICHParam::DrawSectors(); - TLatex l; l.SetNDC(); l.SetTextSize(0.02); - if(!isHits) {l.SetTextColor(kRed) ;l.DrawLatex(0.1,0.01,"No Hits" );} - if(!isDigits) {l.SetTextColor(kGreen);l.DrawLatex(0.4,0.01,"No DIGITS" );} - if(!isClusters) {l.SetTextColor(kBlue) ;l.DrawLatex(0.8,0.01,"No CLUSTERS");} - pCanvas->Update(); pCanvas->Modified(); gPad->WaitPrimitive(); -//deals with digits - if(isDigits){ - GetLoader()->TreeD()->GetEntry(0); - for(Int_t iDig=0;iDig < Digs(iCh)->GetEntries();iDig++){//digits loop - AliRICHDigit *pDig = (AliRICHDigit*)Digs(iCh)->At(iDig); - TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad()); - pDigitsH2->Fill(x2.X(),x2.Y(),100); - }//digits loop - pDigitsH2->SetMarkerColor(kGreen); pDigitsH2->SetMarkerStyle(29); pDigitsH2->SetMarkerSize(0.4); - pDigitsH2->Draw("same"); - pCanvas->Update(); pCanvas->Modified(); gPad->WaitPrimitive(); - }//if(isDigits) -//deals with clusters - if(isClusters){ - GetLoader()->TreeR()->GetEntry(0); - for(Int_t iClu=0;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"); - pCanvas->Update(); pCanvas->Modified(); gPad->WaitPrimitive(); - }//if(isClusters) - }//chambers loop - }//events Loop - - delete pCanvas; - GetLoader()->UnloadHits(); - if(isDigits) GetLoader()->UnloadDigits(); - if(isClusters) GetLoader()->UnloadRecPoints(); -}//Display() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICH::ReadESD(Int_t iEventN, Int_t iChamber)const -{ -// - TFile *pFile=TFile::Open("AliESDs.root","read"); - if(!pFile || !pFile->IsOpen()) {AliInfo("ESD file not open.");return;} //open AliESDs.root - TTree *pTree = (TTree*) pFile->Get("esdTree"); - if(!pTree){AliInfo("ESD not found.");return;} //get ESD tree - - - AliESD *pESD=new AliESD; pTree->SetBranchAddress("ESD", &pESD); - - pTree->GetEvent(iEventN); - - Int_t iNtracks=pESD->GetNumberOfTracks(); - - for(Int_t iTrackN=0;iTrackNGetTrack(iTrackN);// get next reconstructed track - Double_t mom[3], pos[3]; - pTrack->GetPxPyPz(mom); TVector3 mom3(mom[0],mom[1],mom[2]); - pTrack->GetXYZ(pos); TVector3 pos3(pos[0],pos[1],pos[2]); - AliRICHHelix helix(pos3,mom3,(Int_t)pTrack->GetSign(),-0.1*pESD->GetMagneticField()); - Int_t iChamberOnRICH=helix.RichIntersect(AliRICHParam::Instance()); - if(iChamberOnRICH==iChamber) { - TMarker *trackImpact = new TMarker(helix.PosPc().X(),helix.PosPc().Y(),kStar); - trackImpact->SetMarkerColor(kRed); - trackImpact->Draw(); -// - Int_t iChamberRecon = pTrack->GetRICHcluster()/1000000; - if(iChamberRecon==iChamber) { - Double_t thetaCer = pTrack->GetRICHsignal(); - if(thetaCer<0) continue; - TVector3 entrance(helix.PosRad().X(),helix.PosRad().Y(),0); - Float_t thetaTrack,phiTrack; - pTrack->GetRICHthetaPhi(thetaTrack,phiTrack); - TVector3 vectorTrack; - vectorTrack.SetMagThetaPhi(pTrack->GetP(),thetaTrack,phiTrack); - AliInfo(Form("Draw ring started for track %i on chamber %i",iTrackN,iChamber)); - AliInfo(Form("ThetaCer %f TrackTheta %f TrackPhi %f Momentum %f",thetaCer,thetaTrack,phiTrack,pTrack->GetP())); - Float_t dx,dy; - pTrack->GetRICHdxdy(dx,dy); - DrawRing(entrance,vectorTrack,thetaCer); - } - } - } - delete pESD; pFile->Close();//close AliESDs.root -} -//__________________________________________________________________________________________________ -void AliRICH::DrawRing(TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)const -{ - Double_t xGraph[100],yGraph[100]; - Int_t nPointsToDraw = 0; - for(Int_t i=0;i<100;i++) { - Double_t phiCer = 2*TMath::Pi()*i/100; - TVector3 pos = AliRICHParam::Instance()->ForwardTracing(entrance,vectorTrack,thetaCer,phiCer); - if(pos.X()==-999) continue; - xGraph[nPointsToDraw] = pos.X();yGraph[nPointsToDraw] = pos.Y();nPointsToDraw++; - } -// AliInfo(Form("Npoints per ring %i",nPointsToDraw)); - TGraph *gra = new TGraph(nPointsToDraw,xGraph,yGraph); - gra->Draw("C"); -} -//__________________________________________________________________________________________________ void AliRICH::SummaryOfEvent(Int_t iEvtN) const { //prints a summary for a given event @@ -501,159 +237,4 @@ void AliRICH::SummaryOfEvent(Int_t iEvtN) const GetLoader()->GetRunLoader()->UnloadHeader(); GetLoader()->GetRunLoader()->UnloadKinematics(); } -//__________________________________________________________________________________________________ -void AliRICH::HitQA(Double_t cut,Double_t cutele,Double_t cutR) -{ -// Provides a set of control plots intended primarily for charged particle flux analisys -// Arguments: cut (GeV) - cut on momentum of any charged particles but electrons, -// cetele (GeV) - the same for electrons-positrons -// cutR (cm) - cut on production vertex radius (cylindrical system) - gBenchmark->Start("HitsAna"); - - Double_t cutPantiproton =cut; - Double_t cutPkaonminus =cut; - Double_t cutPpionminus =cut; - Double_t cutPmuonminus =cut; - Double_t cutPpositron =cutele; - - Double_t cutPelectron =cutele; - Double_t cutPmuonplus =cut; - Double_t cutPpionplus =cut; - Double_t cutPkaonplus =cut; - Double_t cutPproton =cut; - - - TH2F *pEleHitRZ =new TH2F("EleHitRZ" ,Form("e^{+} e^{-} hit %s;z[cm];R[cm]" ,GetName()) , 400,-300,300 ,400,-500,500); //R-z plot 0cmSetStats(0); - pFlux->GetXaxis()->SetBinLabel(1 ,Form("p^{-}>%.3fGeV/c" ,cutPantiproton)); - pFlux->GetXaxis()->SetBinLabel(2 ,Form("K^{-}>%.3fGeV/c" ,cutPkaonminus )); - pFlux->GetXaxis()->SetBinLabel(3 ,Form("#pi^{-}>%.3fGeV/c" ,cutPpionminus )); - pFlux->GetXaxis()->SetBinLabel(4 ,Form("#mu^{-}>%.3fGeV/c" ,cutPmuonminus )); - pFlux->GetXaxis()->SetBinLabel(5 ,Form("e^{+}>%.3fGeV/c" ,cutPpositron )); - - pFlux->GetXaxis()->SetBinLabel(6 ,Form("e^{-}>%.3fGeV/c" ,cutPelectron )); - pFlux->GetXaxis()->SetBinLabel(7 ,Form("#mu^{+}>%.3fGeV/c" ,cutPmuonplus )); - pFlux->GetXaxis()->SetBinLabel(8 ,Form("#pi^{+}>%.3fGeV/c" ,cutPpionplus )); - pFlux->GetXaxis()->SetBinLabel(9 ,Form("K^{+}>%.3fGeV/c" ,cutPkaonplus )); - pFlux->GetXaxis()->SetBinLabel(10,Form("p^{+}>%.3fGeV/c" ,cutPproton )); - - pFlux->GetYaxis()->SetBinLabel(1,"sum"); - pFlux->GetYaxis()->SetBinLabel(2,"ch1"); - pFlux->GetYaxis()->SetBinLabel(3,"ch2"); - pFlux->GetYaxis()->SetBinLabel(4,"ch3"); - pFlux->GetYaxis()->SetBinLabel(5,"ch4"); - pFlux->GetYaxis()->SetBinLabel(6,"ch5"); - pFlux->GetYaxis()->SetBinLabel(7,"ch6"); - pFlux->GetYaxis()->SetBinLabel(8,"ch7"); - pFlux->GetYaxis()->SetBinLabel(9,"prim"); - pFlux->GetYaxis()->SetBinLabel(10,"tot"); - -//end of hists definition - - Int_t iNevents=fLoader->GetRunLoader()->GetAliRun()->GetEventsPerRun(),iCntPrimParts=0,iCntTotParts=0; -//load all needed trees - fLoader->LoadHits(); - fLoader->GetRunLoader()->LoadHeader(); - fLoader->GetRunLoader()->LoadKinematics(); - - for(Int_t iEvtN=0;iEvtN < iNevents;iEvtN++){//events loop - fLoader->GetRunLoader()->GetEvent(iEvtN); - AliInfo(Form(" %i event processes",fLoader->GetRunLoader()->GetEventNumber())); - AliStack *pStack= fLoader->GetRunLoader()->Stack(); - - for(Int_t iParticleN=0;iParticleNGetNtrack();iParticleN++){//stack loop - TParticle *pPart=pStack->Particle(iParticleN); - - if(iParticleN%10000==0) AliInfo(Form(" %i particles read",iParticleN)); - - switch(pPart->GetPdgCode()){ - case kProtonBar: pFlux->Fill(-4.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-4.5,8); break; - case kKMinus: pFlux->Fill(-3.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-3.5,8); break; - case kPiMinus: pFlux->Fill(-2.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-2.5,8); break; - case kMuonMinus: pFlux->Fill(-1.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-1.5,8); break; - case kPositron: pFlux->Fill(-0.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-0.5,8); pEleAllP->Fill(-pPart->P()); break; - - case kElectron: pFlux->Fill( 0.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 0.5,8); pEleAllP->Fill( pPart->P()); break; - case kMuonPlus: pFlux->Fill( 1.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 1.5,8); break; - case kPiPlus: pFlux->Fill( 2.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 2.5,8); break; - case kKPlus: pFlux->Fill( 3.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 3.5,8); break; - case kProton: pFlux->Fill( 4.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 4.5,8); break; - }//switch - }//stack loop -//now hits analiser - for(Int_t iEntryN=0;iEntryN < fLoader->TreeH()->GetEntries();iEntryN++){//TreeH loop - fLoader->TreeH()->GetEntry(iEntryN); //get current entry (prim) - for(Int_t iHitN=0;iHitN < Hits()->GetEntries();iHitN++){//hits loop - AliRICHHit *pHit = (AliRICHHit*)Hits()->At(iHitN); //get current hit - TParticle *pPart=pStack->Particle(pHit->GetTrack()); //get stack particle which produced the current hit - - if(pPart->GetPDG()->Charge()!=0&&pPart->Rho()>0.1) pVertex->Fill(pPart->Vx(),pPart->Vy()); //safe margin for sec. - if(pPart->GetPDG()->Charge()!=0) pRho->Fill(pPart->Rho()); //safe margin for sec. - if(pPart->R()>cutR) continue; //cut on production radius (cylindrical system) - - switch(pPart->GetPdgCode()){ - case kProtonBar: if(pPart->P()>cutPantiproton) {pProHitP->Fill(-pPart->P()); pFlux->Fill(-4.5,pHit->C());}break; - case kKMinus : if(pPart->P()>cutPkaonminus) {pKaoHitP->Fill(-pPart->P()); pFlux->Fill(-3.5,pHit->C());}break; - case kPiMinus : if(pPart->P()>cutPpionminus) {pPioHitP->Fill(-pPart->P()); pFlux->Fill(-2.5,pHit->C());}break; - case kMuonMinus: if(pPart->P()>cutPmuonminus) {pMuoHitP->Fill(-pPart->P()); pFlux->Fill(-1.5,pHit->C());}break; - case kPositron : if(pPart->P()>cutPpositron) {pEleHitP->Fill(-pPart->P()); pFlux->Fill(-0.5,pHit->C()); - pEleHitRP->Fill(-pPart->P(),pPart->R()); pEleHitRZ->Fill(pPart->Vz(),pPart->R()); }break; - - case kElectron : if(pPart->P()>cutPelectron) {pEleHitP->Fill( pPart->P()); pFlux->Fill( 0.5,pHit->C()); - pEleHitRP->Fill( pPart->P(),pPart->R()); pEleHitRZ->Fill(pPart->Vz(),pPart->R()); }break; - case kMuonPlus : if(pPart->P()>cutPmuonplus) {pMuoHitP->Fill( pPart->P()); pFlux->Fill( 1.5,pHit->C());}break; - case kPiPlus : if(pPart->P()>cutPpionplus) {pPioHitP->Fill( pPart->P()); pFlux->Fill( 2.5,pHit->C());}break; - case kKPlus : if(pPart->P()>cutPkaonplus) {pKaoHitP->Fill( pPart->P()); pFlux->Fill( 3.5,pHit->C());}break; - case kProton : if(pPart->P()>cutPproton) {pProHitP->Fill( pPart->P()); pFlux->Fill( 4.5,pHit->C());}break; - } - }//hits loop - }//TreeH loop - iCntPrimParts +=pStack->GetNprimary(); - iCntTotParts +=pStack->GetNtrack(); - }//events loop -//unload all loaded staff - fLoader->UnloadHits(); - fLoader->GetRunLoader()->UnloadHeader(); - fLoader->GetRunLoader()->UnloadKinematics(); -//Calculater some sums - Stat_t sum=0; -//sum row, sum over rows - for(Int_t i=1;i<=pFlux->GetNbinsX();i++){ - sum=0; for(Int_t j=2;j<=8;j++) sum+=pFlux->GetBinContent(i,j); - pFlux->SetBinContent(i,1,sum); - } - -//display everything - new TCanvas("canvas1",Form("Events %i Nprims=%i Nparticles=%i",iNevents,iCntPrimParts,iCntTotParts),1000,900); pFlux->Draw("text"); gPad->SetGrid(); -//total prims and particles - TLatex latex; latex.SetTextSize(0.02); - sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,10); latex.DrawLatex(5.1,9.5,Form("%.0f",sum)); - sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,9); latex.DrawLatex(5.1,8.5,Form("%.0f",sum)); - for(Int_t iChN=1;iChN<=kNchambers;iChN++) { - sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,iChN+1);latex.DrawLatex(5.1,iChN+0.5,Form("%.0f",sum)); - } - sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,1); latex.DrawLatex(5.1,0.5,Form("%.0f",sum)); - - new TCanvas("cEleAllP" ,"e" ,200,100); pEleAllP->Draw(); - new TCanvas("cEleHitRP" ,"e" ,200,100); pEleHitRP->Draw(); - new TCanvas("cEleHitRZ" ,"e" ,200,100); pEleHitRZ->Draw(); - new TCanvas("cEleHitP" ,"e" ,200,100); pEleHitP->Draw(); - new TCanvas("cMuoHitP" ,"mu",200,100); pMuoHitP->Draw(); - new TCanvas("cPioHitP" ,"pi",200,100); pPioHitP->Draw(); - new TCanvas("cKaoHitP" ,"K" ,200,100); pKaoHitP->Draw(); - new TCanvas("cProHitP" ,"p" ,200,100); pProHitP->Draw(); - new TCanvas("cVertex" ,"2d vertex" ,200,100); pVertex->Draw(); - new TCanvas("cRho" ,"Rho of sec" ,200,100); pRho->Draw(); - - gBenchmark->Show("HitsPlots"); -}//HitsPlots() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICH.h b/RICH/AliRICH.h index bde915cbf44..19957fdbfd1 100644 --- a/RICH/AliRICH.h +++ b/RICH/AliRICH.h @@ -4,121 +4,58 @@ * See cxx source for full Copyright notice */ #include //base class -#include -#include -#include -#include +#include //XxxCreate() +#include //fClu field -#include "AliRICHCluster.h" -#include "AliRICHHit.h" -//__________________AliRICH_________________________________________________________________________ -class AliESD; class AliRICH : public AliDetector //TObject-TNamed-AliModule-AliDetector-AliRICH { public: //ctor & dtor - AliRICH(); - AliRICH(const char *name, const char *title); - AliRICH(const AliRICH& RICH ):AliDetector(RICH),fSdig(0),fSdigCnt(0),fDig(0),fClu(0),fCounters(0),fNcham(0) {;} //copy ctor not implemented + AliRICH(const char *nm,const char *ttl); //named ctor + AliRICH( ):AliDetector( ),fSdi(0),fDig(0),fClu(0) {} //default ctor + AliRICH(const AliRICH &rich ):AliDetector(rich),fSdi(0),fDig(0),fClu(0) {} //copy ctor not implemented virtual ~AliRICH(); - - AliRICH& operator=(const AliRICH&) {return *this;} + AliRICH& operator=(const AliRICH&) {return *this;} //not implemented //framework part - void BuildGeometry ( ); //from AliModule invoked from AliMC::InitGeometry() to build geometry for event display - virtual void CreateMaterials ( )=0; //from AliModule invoked from AliMC::ConstructGeometry() to define detector materials - virtual void CreateGeometry ( )=0; //from AliModule invoked from AliMC::ConstructGeometry() to build detector for simulation - virtual Int_t IsVersion ( )const=0; //from AliModule not used - virtual void Init ( )=0; //from AliModule invoked from AliMC::InitGeometry() after CreateGeometry() to do VolID initialization - void MakeBranch (Option_t *opt="" ); //from AliModule invokde from AliRun::Tree2Tree() to make requested RICH branch -// virtual void Print (const Option_t *opt)const=0; //from TObject - virtual void StepManager ( )=0; //from AliModule invoked from AliMC - void SetTreeAddress ( ); //from AliModule invoked from AliRun::GetEvent(), AliLoader::SetTAddrInDet() -//private part - void HitAdd (Int_t c,Int_t tid,Int_t pid,TVector3 in,TVector3 out,Double_t e=0 ){new((*fHits)[fNhits++])AliRICHHit(c,tid,in,out,e,pid); } - void HitAdd (Int_t tid,Double_t e,Int_t pad,Double_t x,Double_t y,Double_t z,Int_t pid){new((*fHits)[fNhits++])AliRICHHit(tid,e,pad,x,y,z,pid); } - void HitCreate ( ){if(fHits)return; fHits=new TClonesArray("AliRICHHit"); fNhits=0;} - void HitPrint (Int_t iEvent=0 )const; - void HitQA (Double_t cut=0,Double_t cutele=0,Double_t cutR=999 ); - - TClonesArray* SDigs ( )const{return fSdig;} //pointer to sdigits list - inline void SDigAdd (Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid ) ; //add new sdigit - void SDigCreate ( ) {if(fSdig) return; fSdig=new TClonesArray("AliRICHDigit"); fSdigCnt=0;} - void SDigReset ( ) {fSdigCnt=0; if(fSdig) fSdig ->Clear();} //clean a list of sdigits - void SDigPrint (Int_t iEvent=0 )const; //prints sdigits + void BuildGeometry ( ) {} //from AliModule invoked from AliMC::InitGeometry() to build geometry for old event display + virtual void CreateMaterials ( )=0; //from AliModule invoked from AliMC::ConstructGeometry() to define detector materials + virtual void CreateGeometry ( )=0; //from AliModule invoked from AliMC::ConstructGeometry() to build detector for simulation + virtual Int_t IsVersion ( )const=0; //from AliModule not used + virtual void Init ( )=0; //from AliModule invoked from AliMC::InitGeometry() after CreateGeometry() to do VolID initialization + void MakeBranch (Option_t *opt=""); //from AliModule invokde from AliRun::Tree2Tree() to make requested RICH branch + void SetTreeAddress ( ); //from AliModule invoked from AliRun::GetEvent(), AliLoader::SetTAddrInDet() + virtual void StepManager ( )=0; //from AliModule invoked from AliMC +//private part +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + void HitCreate( ) {if(fHits)return; fHits=new TClonesArray("AliRICHHit"); fNhits=0; }//create hits list + void HitPrint (Int_t evt)const; //print hits list + + TClonesArray* SdiLst ( )const{return fSdi; }//get sdigits list + void SdiCreate( ) {if(fSdi)return; fSdi=new TClonesArray("AliRICHDigit"); }//create sdigits list + void SdiReset ( ) {if(fSdi) fSdi ->Clear(); }//clean sdigits list + void SdiPrint (Int_t evt)const; //print sdigits - TClonesArray* Digs (Int_t iC )const{return fDig ? (TClonesArray *)fDig->At(iC-1):0;} - inline void DigAdd (Int_t c,TVector pad,int q,int cfm,int *tid ) ; //add new digit - inline void DigAdd (AliRICHDigit &dif ) ; //add new digit - inline void DigCreate ( ) ; //create digits - void DigReset ( ) {if(fDig)for(int i=0;iAt(i)->Clear();fDigCnt[i]=0;}} - void DigPrint (Int_t iEvent=0 )const; //prints digits + TObjArray* DigLst ( )const{return fDig; }//get digits list for all chambers + TClonesArray* DigLst (Int_t c )const{return fDig ? (TClonesArray *)fDig->At(c):0; }//get digits list for chamber + void DigCreate( ) {fDig=new TObjArray(7);for(Int_t i=0;i<7;i++)fDig->AddAt(new TClonesArray("AliRICHDigit"),i);}//create digits list + void DigReset ( ) {if(fDig)for(int i=0;i<7;i++)fDig->At(i)->Clear(); }//clean digits list + void DigPrint (Int_t evt)const; //print digits - TClonesArray* Clus (Int_t iC )const{return fClu ? (TClonesArray *)fClu->At(iC-1):0;} - inline void CluCreate ( ) ; //create clusters container - void CluReset ( ) {if(fClu)for(int i=0;iAt(i)->Clear();fCluCnt[i]=0;}} - void CluPrint (Int_t iEvent=0 )const; //prints a list of clusters for a given event + TClonesArray* CluLst (Int_t c )const{return fClu ? (TClonesArray *)fClu->At(c):0; }//get clusters list for chamber + inline void CluCreate( ) {fClu=new TObjArray(7); for(Int_t i=0;i<7;i++)fClu->AddAt(new TClonesArray("AliRICHCluster"),i);}//create clusters list + void CluReset ( ) {if(fClu)for(int i=0;i<7;i++)fClu->At(i)->Clear(); }//clean clusters list + void CluPrint (Int_t evt)const; //print clusters list - void Display ( )const; //Display event - void DisplayEvent (Int_t,Int_t )const; //Display event - void DrawRing (TVector3 entrance,TVector3 vectorTrack,Double_t thetaCer)const; - void OccupancyPrint(Int_t iEvent=-1 )const; //print chambers occupancy - void ReadESD (Int_t iEventN, Int_t iChamber )const; - void SummaryOfEvent(Int_t iEvent=0 )const; + void OccupancyPrint(Int_t evt=-1); //print chambers occupancy + void SummaryOfEvent(Int_t evt=0)const; protected: - TClonesArray *fSdig; //! list of sdigits - Int_t fSdigCnt; //! current number of sdigits - + TClonesArray *fSdi; //! list of sdigits TObjArray *fDig; //! each chamber holds it's one list of digits - Int_t fDigCnt[7]; //! array of current numbers of digits - TObjArray *fClu; //! each chamber holds it's one list of clusters - Int_t fCluCnt[7]; //! array of current numbers of raw clusters - - TVector fCounters; // Particle history counters, explanation in StepManager() - Int_t fNcham; // Number of RICH chambers during simulation ClassDef(AliRICH,11) //Main RICH class };//class AliRICH - -//__________________________________________________________________________________________________ -void AliRICH::SDigAdd(Int_t c,TVector pad,Double_t q,Int_t pid,Int_t tid) -{ - Int_t cfm; - switch(pid){ - case 50000050: cfm=1000000;break;//cerenkov - case 50000051: cfm=1000; break;//feedback - default: cfm=1; break;//mip - } - new((*fSdig)[fSdigCnt++])AliRICHDigit(c,pad,q,cfm,tid,-1,-1); -} -//__________________________________________________________________________________________________ -void AliRICH::DigCreate() -{ - if(fDig) return; - fDig = new TObjArray(fNcham); - for(Int_t i=0;iAddAt(new TClonesArray("AliRICHDigit"), i); fDigCnt[i]=0;} -} -//__________________________________________________________________________________________________ -void AliRICH::DigAdd(AliRICHDigit &dig) -{ -//special for digit formed from raw - TClonesArray &tmp=*((TClonesArray*)fDig->At(dig.C()-1)); - new(tmp[fDigCnt[dig.C()-1]++])AliRICHDigit(dig); -} -//__________________________________________________________________________________________________ -void AliRICH::DigAdd(int c,TVector pad,int q,int cfm,int *tid) -{ - TClonesArray &tmp=*((TClonesArray*)fDig->At(c-1)); - new(tmp[fDigCnt[c-1]++])AliRICHDigit(c,pad,q,cfm,tid[0],tid[1],tid[2]); -} -//__________________________________________________________________________________________________ -void AliRICH::CluCreate() -{ - if(fClu) return; - fClu = new TObjArray(fNcham); - for(Int_t i=0;iAddAt(new TClonesArray("AliRICHCluster"), i); fCluCnt[i]=0;} -} -#endif//#ifndef AliRICH_h +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#endif diff --git a/RICH/AliRICHCluster.cxx b/RICH/AliRICHCluster.cxx index e05c2886ef7..b9e5e1875fc 100644 --- a/RICH/AliRICHCluster.cxx +++ b/RICH/AliRICHCluster.cxx @@ -15,12 +15,10 @@ #include "AliRICHCluster.h" //class header #include //Solve() -#include //FindCfm(), Solve() -#include //FindCfm() -#include //Solve() Test() +#include //Solve() ClassImp(AliRICHCluster) -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHCluster::CoG() { // Calculates naive cluster position as a center of gravity of its digits. @@ -30,61 +28,65 @@ void AliRICHCluster::CoG() fX=fY=0; //set cluster position to (0,0) to start to collect contributions for(Int_t iDig=0;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 + Float_t q=pDig->Q(); //get QDC + fX += pDig->LorsX()*q;fY +=pDig->LorsY()*q; //add digit center weighted by QDC }//digits loop - fX/=fQdc;fY/=fQdc; //final center of gravity + fX/=fQ;fY/=fQ; //final center of gravity - TVector2 center = AliRICHParam::Pad2Loc(AliRICHParam::Loc2Pad(TVector2(fX,fY)));//center of the pad containing calculated cluster position - fX += AliRICHParam::CogCorr(fX-center.X()); //correct cluster position for sinoid - - fStatus=kCoG; + CorrSin(); + + fSt=kCoG; }//CoG() -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHCluster::CorrSin() +{ +// Correction of cluster x position due to sinoid, see HMPID TDR page 30 +// Arguments: none +// Returns: none + AliRICHDigit dig(Ch(),100,1,fX,fY); //tmp digit to get it center + Float_t x=fX-dig.LorsX(); + fX+=3.31267e-2*TMath::Sin(2*TMath::Pi()/0.8*x)-2.66575e-3*TMath::Sin(4*TMath::Pi()/0.8*x)+2.80553e-3*TMath::Sin(6*TMath::Pi()/0.8*x)+0.0070; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHCluster::FitFunc(Int_t &iNpars, Double_t *, Double_t &chi2, Double_t *par, Int_t ) { // Cluster fit function // par[0]=x par[1]=y par[2]=q for the first Mathieson shape // par[3]=x par[4]=y par[5]=q for the second Mathieson shape and so on up to iNpars/3 Mathieson shapes -// We need to calculate QpadExp - QpadMathieson summup over all pads of the cluster -// Here QpadExp is a actual charge of the pad, QpadMathieson is calculated charge of the pad induced by all Mathiesons +// For each pad of the cluster calculates the difference between actual pad charge and the charge induced to this pad by all Mathieson distributions +// Then the chi2 is calculated as the sum of this value squared for all pad in the cluster. // Arguments: iNpars - number of parameters which is number of local maxima of cluster * 3 // chi2 - function result to be minimised // par - parameters array of size iNpars // Returns: none AliRICHCluster *pClu=(AliRICHCluster*)gMinuit->GetObjectFit(); - Int_t iNmathiesons = iNpars/3; + Int_t iNshape = iNpars/3; - TVector2 curMathiesonPos; chi2 = 0; - for(Int_t i=0;iSize();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;jSize();i++){ //loop on all pads of the cluster + Double_t dQpadMath = 0; //pad charge collector + for(Int_t j=0;jDig(i)->Mathieson(par[3*j],par[3*j+1]); // par[3*j+2] is charge par[3*j] is x par[3*j+1] is y of current Mathieson } - chi2 += TMath::Power((dQpadMathieson-dQpadExp),2); // + chi2 +=TMath::Power((pClu->Dig(i)->Q()-dQpadMath),2); // } //loop on all pads of the cluster }//FitFunction() -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHCluster::Print(Option_t* opt)const { //Print current cluster const char *status=0; - switch(fStatus){ - case kFormed: status="formed" ;break; - case kUnfolded: status="unfolded" ;break; - case kCoG: status="coged" ;break; - case kEmpty: status="empty" ;break; + switch(fSt){ + case kFor: status="formed" ;break; + case kUnf: status="unfolded" ;break; + case kCoG: status="coged" ;break; + case kEmp: status="empty" ;break; } Printf("%s cs=%2i, Size=%2i (x=%7.3f cm,y=%7.3f cm,Q=%4i qdc), %s", - opt,fCham,Size(),fX,fY,fQdc,status); + opt,Ch(),Size(),X(),Y(),Q(),status); for(Int_t i=0;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 @@ -113,13 +115,12 @@ Int_t AliRICHCluster::Solve(TClonesArray *pCluLst,Bool_t isTryUnfold) AliRICHDigit *pDig2 = Dig(iDig2); //take second digit to compare with the first one Int_t dist = TMath::Sign(Int_t(pDig1->PadX()-pDig2->PadX()),1)+TMath::Sign(Int_t(pDig1->PadY()-pDig2->PadY()),1);//distance between pads if(dist==1) //means dig2 is a neighbour of dig1 - if(pDig2->Qdc()>=pDig1->Qdc()) iHowManyMoreCnt++; //count number of pads with Q more then Q of current pad + if(pDig2->Q()>=pDig1->Q()) iHowManyMoreCnt++; //count number of pads with Q more then Q of current pad }//second digits loop if(iHowManyMoreCnt==0&&iLocMaxCntPad()); //take pad center position and use it as parameter for current Mathienson shape - pMinuit->mnparm(3*iLocMaxCnt ,Form("x%i",iLocMaxCnt),parStart=x2.X() ,parStep=0.01,parLow=0,parHigh=0,iErrFlg); - pMinuit->mnparm(3*iLocMaxCnt+1,Form("y%i",iLocMaxCnt),parStart=x2.Y() ,parStep=0.01,parLow=0,parHigh=0,iErrFlg); - pMinuit->mnparm(3*iLocMaxCnt+2,Form("q%i",iLocMaxCnt),parStart=pDig1->Qdc(),parStep=0.01,parLow=0,parHigh=0,iErrFlg); + pMinuit->mnparm(3*iLocMaxCnt ,Form("x%i",iLocMaxCnt),parStart=pDig1->LorsX(),parStep=0.01,parLow=0,parHigh=0,iErrFlg); + pMinuit->mnparm(3*iLocMaxCnt+1,Form("y%i",iLocMaxCnt),parStart=pDig1->LorsY(),parStep=0.01,parLow=0,parHigh=0,iErrFlg); + pMinuit->mnparm(3*iLocMaxCnt+2,Form("q%i",iLocMaxCnt),parStart=pDig1->Q() ,parStep=0.01,parLow=0,parHigh=0,iErrFlg); iLocMaxCnt++; }//if this pad is local maximum }//first digits loop @@ -133,13 +134,8 @@ Int_t AliRICHCluster::Solve(TClonesArray *pCluLst,Bool_t isTryUnfold) pMinuit->mnpout(3*i ,sName, fitX, d1 , d2, d3, iErrFlg); pMinuit->mnpout(3*i+1 ,sName, fitY, d1 , d2, d3, iErrFlg); pMinuit->mnpout(3*i+2 ,sName, fitQ, d1 , d2, d3, iErrFlg); - if (TMath::Abs(fitQ)>2147483647.0) { - //PH 2147483647 is the max. integer - //PH This apparently is a problem which needs investigation - AliWarning(Form("Too big or too small fitQ %f",fitQ)); - fitQ = TMath::Sign((Double_t)2147483647,fitQ); - } - new ((*pCluLst)[iCluCnt++]) AliRICHCluster(C(),fitX,fitY,(Int_t)fitQ); //add new unfolded clusters + if (TMath::Abs(fitQ)>2147483647.0) fitQ = TMath::Sign((Double_t)2147483647,fitQ);//??????????????? + new ((*pCluLst)[iCluCnt++]) AliRICHCluster(Ch(),fitX,fitY,(Int_t)fitQ); //add new unfolded clusters }//local maxima loop } }else{//do not unfold since number of loc max is unresonably high or user's baned unfolding @@ -149,47 +145,4 @@ Int_t AliRICHCluster::Solve(TClonesArray *pCluLst,Bool_t isTryUnfold) delete pMinuit; return iLocMaxCnt; }//Solve() -//__________________________________________________________________________________________________ -void AliRICHCluster::Test(Double_t x,Double_t y,Double_t e,Bool_t isTryUnfold) -{ -//This is to test all cluster functionality -//Uses AddDigit() to add a predifined pad structure and then calls Solve - TVector2 hitX2(x,y); - Int_t iQtot=AliRICHParam::TotQdc(hitX2,e); - if(iQtot==0){ - Printf("Provided hit position out of sensitive area"); - return; - } - TVector area=AliRICHParam::Loc2Area(hitX2); - TVector pad(2); - AliRICHCluster clu; - for(pad[1]=area[1];pad[1]<=area[3];pad[1]++){//affected pads loop first y - for(pad[0]=area[0];pad[0]<=area[2];pad[0]++){//then x - Double_t dQpad=iQtot*AliRICHParam::FracQdc(hitX2,pad);//charge fraction from Mathieson centered at x to pad - clu.DigAdd(new AliRICHDigit(pad,dQpad)); - }//affected pads loop - } - clu.CoG(); clu.Print("Initial cluster:"); - TClonesArray *pCluLst=new TClonesArray("AliRICHCluster",1); - clu.Solve(pCluLst,isTryUnfold); - Printf("Initial hit : (%.2f,%.2f) Qtot=%i E=%.2f eV",x,y,iQtot,e*1e9); - ((AliRICHCluster *)pCluLst->At(0))->Print("Solved cluster:"); - - delete pCluLst; clu.Reset(); -}//Test() -//__________________________________________________________________________________________________ -void AliRICHCluster::Test() -{ -//Test cluster builder by a number of predefined digit patterns -//Arguments: none -// Returns: none - AliRICHCluster clu; Int_t ch,padx,pady,qdc; TClonesArray *pCluLst=new TClonesArray("AliRICHCluster",10); - Printf("2 digits vertical cluster"); - clu.DigAdd(new AliRICHDigit(AliRICHDigit::P2A(ch=1,padx=3,pady=3),qdc=101)); - clu.DigAdd(new AliRICHDigit(AliRICHDigit::P2A(ch=1,padx=3,pady=4),qdc=202)); - - clu.Print("Formed cluster:"); - clu.Solve(pCluLst,kTRUE); - pCluLst->Print(); - delete pCluLst; -} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHCluster.h b/RICH/AliRICHCluster.h index f4cd57169c3..2c740d0cda5 100644 --- a/RICH/AliRICHCluster.h +++ b/RICH/AliRICHCluster.h @@ -3,97 +3,58 @@ /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ -#include "AliRICHParam.h" //DigAdd(), Dig() +#include "AliRICHDigit.h" //DigAdd() +#include //DigAdd() +class TClonesArray; //Solve() class AliRICHCluster :public TObject { public: - enum EClusterStatus {kFormed,kCoG,kUnfolded,kEmpty=-1}; - AliRICHCluster(): - TObject(), - fQdc(-1), - fCham(-1), - fX(-1), - fY(-1), - fStatus(kEmpty), - fDigs(0) { - // Default constructor - } - AliRICHCluster(Int_t c,Double_t x,Double_t y,Int_t q): - TObject(), - fQdc(q ), - fCham(c) , - fX(x), - fY(y), - fStatus(kUnfolded), - fDigs(0x0) { - // Constructor - } - AliRICHCluster(const AliRICHCluster & src) : - TObject(src), - fQdc(src.fQdc), - fCham(src.fCham), - fX(src.fX), - fY(src.fY), - fStatus(src.fStatus), - fDigs(src.fDigs ? new TObjArray(*src.fDigs) : 0x0) { - // Copy constructor - } - AliRICHCluster & operator=(const AliRICHCluster & src) { - // Assigment operator - if ( this == &src ) return *this; - - // Base class assignment - TObject::operator=(src); - - fQdc = src.fQdc; - fCham = src.fCham; - fX = src.fX; - fY = src.fY; - fStatus = src.fStatus; - fDigs = src.fDigs ? new TObjArray(*src.fDigs) : 0x0; - return *this; - } - virtual ~AliRICHCluster( ) {DigDel();} + enum EClusterStatus {kFor,kCoG,kUnf,kEmp=-1}; //status flags + AliRICHCluster( ):TObject( ),fSt(kEmp ),fCh(-1 ),fQ(-1 ),fX(-1 ),fY(-1 ),fDigs(0 ) {} + AliRICHCluster(Int_t c,Float_t x,Float_t y,Int_t q):TObject( ),fSt(kUnf ),fCh(c ),fQ(q ),fX(x ),fY(y ),fDigs(0 ) {} + AliRICHCluster(const AliRICHCluster &c ):TObject(c),fSt(c.fSt),fCh(c.fCh),fQ(c.fQ),fX(c.fX),fY(c.fY),fDigs(c.fDigs ? new TObjArray(*c.fDigs):0) {} + AliRICHCluster &operator=(const AliRICHCluster &c) { + if(this == &c)return *this;TObject::operator=(c); fSt=c.fSt; fCh=c.fCh; fQ=c.fQ; fX=c.fX; fY=c.fY; fDigs=c.fDigs ? new TObjArray(*c.fDigs):0; return *this;} + + virtual ~AliRICHCluster( ) {DigDel();} //framework part void Print (Option_t *opt="" )const; //overloaded TObject::Print() to print cluster info static void FitFunc(Int_t &, Double_t *, Double_t &, Double_t *, Int_t); //fit function to be used by MINUIT //private part void CoG ( ); //calculates center of gravity - Int_t C ( )const{return fCham; } //chamber number + void CorrSin ( ); //sinoidal correction + Int_t Ch ( )const{return fCh; } //chamber number inline void DigAdd (AliRICHDigit *pDig ); //add new digit ot the cluster void DigDel ( ) {if(fDigs) {delete fDigs;fDigs=0;} } //deletes the list of digits (not digits!) - void DistXY (const TVector2 &p,Double_t &x,Double_t &y)const{ x=p.X()-fX; y=p.Y()-fY; } //distance in x to given point AliRICHDigit* Dig (Int_t i )const{return (AliRICHDigit*)fDigs->At(i); } //pointer to i-th digit - TObjArray* Digits ( )const{return fDigs; } //list of digits - TVector3 Lors2Mars() const{return AliRICHParam::Instance()->Lors2Mars(fCham,fX,fY); } //cluster position in MARS - void Reset ( ) {DigDel();fQdc=fCham=-1;fX=fY=-1;fStatus=kEmpty;} //cleans the cluster + TObjArray* DigLst ( )const{return fDigs; } //list of digits + void Reset ( ) {DigDel();fQ=fCh=-1;fX=fY=-1;fSt=kEmp; } //cleans the cluster Int_t Solve (TClonesArray *pCluLst,Bool_t isUnfold ); //solve cluster: MINUIT fit or CoG Int_t Size ( )const{return (fDigs)?fDigs->GetEntriesFast():0; } //number of pads in cluster - Int_t Q ( )const{return fQdc; } //cluster charge in QDC channels - Double_t X ( )const{return fX; } //cluster x position in LRS - Double_t Y ( )const{return fY; } //cluster y position in LRS -//test part - static void Test (Double_t x,Double_t y,Double_t e=0,Bool_t isUnfold=kTRUE); //test by hit (x [cm] , y [cm] , e [GeV]) - static void Test ( ); //test by predifined patterns + Int_t Q ( )const{return fQ; } //cluster charge in QDC channels + Float_t X ( )const{return fX; } //cluster x position in LRS + Float_t Y ( )const{return fY; } //cluster y position in LRS protected: - Int_t fQdc; //QDC value - Int_t fCham; //10*chamber number+sector number - Double_t fX; //local x postion, cm - Double_t fY; //local y postion, cm - Int_t fStatus; //flag to mark the quality of the cluster + Int_t fSt; //flag to mark the quality of the cluster + Int_t fCh; //chamber number + Int_t fQ; //QDC value + Float_t fX; //local x postion, [cm] + Float_t fY; //local y postion, [cm] TObjArray *fDigs; //! list of digits forming this cluster - ClassDef(AliRICHCluster,3) //RICH cluster class + ClassDef(AliRICHCluster,5) //RICH cluster class };//class AliRICHCluster //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHCluster::DigAdd(AliRICHDigit *pDig) { -// Adds a given digit to the list of digits belonging to this cluster - if(!fDigs) {fQdc=0;fDigs = new TObjArray;} +// Adds a given digit to the list of digits belonging to this cluster, cluster is not owner of digits +// Arguments: pDig - pointer to digit to be added +// Returns: none + if(!fDigs) {fQ=0;fDigs = new TObjArray;} fDigs->Add(pDig); - fQdc+=(Int_t)pDig->Qdc(); - fCham=pDig->C(); - fStatus=kFormed; + fQ+=(Int_t)pDig->Q(); + fCh=pDig->Ch(); + fSt=kFor; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #endif diff --git a/RICH/AliRICHDigit.cxx b/RICH/AliRICHDigit.cxx index 28875ed302c..65807f6159f 100644 --- a/RICH/AliRICHDigit.cxx +++ b/RICH/AliRICHDigit.cxx @@ -13,8 +13,15 @@ // * provided "as is" without express or implied warranty. * // ************************************************************************** -#include "AliRICHDigit.h"//class header - +#include "AliRICHDigit.h" //class header +#include "AliRICHHit.h" //Hit2Sdi() +#include //Hit2Sdi() +#include //TestSeg() +#include //TestSeg() +#include //TestSeg() +#include //DrawPc() +#include //Zoom() +#include //Zoom() ClassImp(AliRICHDigit) /* @@ -28,7 +35,7 @@ For RICH the detector ID is 6 (reffered in the code as kRichRawId) while DDL ind Common header might be followed by the private one although RICH has no any private header, just uses the common one. -Single RICH D-RORC serves one half of a chamber i.e. 3 photocathodes aka sectors, even LDC for left part( sectors 1-3-5) and odd LDC for right part(2-4-6) +Single RICH D-RORC serves one half of a chamber i.e. 3 photocathodes even LDC for left part( PCs 0-2-4) and odd LDC for right part(1-3-5) as it's seen from electronics side. So the LDC -chamber-ddl map is: @@ -41,50 +48,151 @@ DDL index 10 -> ch 6 left -> DDL ID 0x60a DDL index 11 -> ch 6 right -> DDL index 12 -> ch 7 left -> DDL ID 0x60c DDL index 13 -> ch 7 right -> DDL ID 0x60d RICH FEE as seen by single D-RORC is composed from a number of DILOGIC chips organized in vertical stack of rows. -Each DILOGIC chip serves 48 channels for the 8x6 pads (reffered in the code as kDiloX,kDiloY). Channels counted from 0 to 47. +Each DILOGIC chip serves 48 channels for the 8x6 pads (reffered in the code as kDilX,kDilY). Channels counted from 0 to 47. + +The mapping inside DILOGIC chip has the following structure (see from electronics side): -??????? Currently the exact mapping of DILOGIC addresses to pads is not known. So we invented horizontal zig-zag ??????? +5 04 10 16 22 28 34 40 46 +4 02 08 14 20 26 32 38 44 +3 00 06 12 18 24 30 36 42 +2 01 07 13 19 25 31 37 43 +1 03 09 15 21 27 33 39 45 +0 05 11 17 23 29 35 41 47 + + 0 1 2 3 4 5 6 7 padx -10 DILOGIC chips composes so called "row" in horizontal direction (reffered in the code as kNdilo), so the row is 80x6 pads structure. +10 DILOGIC chips composes so called "row" in horizontal direction (reffered in the code as kNdil), so the row is 80x6 pads structure. DILOGIC chips in the row are counted from right to left as seen from electronics side, from 1 to 10. -24 rows are piled up forming the whole FEE served by single D-RORC, so one DDL sees 80x144 pads separated in 3 photocathodes aka sectors. -Rows are counted from 1 to 24 from top to bottom for right half of the chamber (sectors 2-4-6) as seen from electronics side, meaning even LDC number - and from bottom to top for left half of the chamber (sectors 1-3-5) as seen from electronics side, meaning odd LDC number. +24 rows are piled up forming the whole FEE served by single D-RORC, so one DDL sees 80x144 pads separated in 3 photocathodes. +Rows are counted from 1 to 24 from top to bottom for right half of the chamber (PCs 1-3-5) as seen from electronics side, meaning even LDC number + and from bottom to top for left half of the chamber (PCs 0-2-4) as seen from electronics side, meaning odd LDC number. RICH raw word is 32 bits with the structure: 00000 rrrrr dddd aaaaaa qqqqqqqqqqqq 5 bits zero 5 bits row number (1..24) 4 bits DILOGIC chip number (1..10) 6 bits DILOGIC address (0..47) 12 bits QDC value (0..4095) */ - +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Float_t AliRICHDigit::Hit2Sdi(AliRICHHit *pHit,TClonesArray *pSdiLst) +{ +// Creates a list of sdigits out of provided hit +// Arguments: pHit- hit +// Returns: none + + Float_t x=(pHit->LorsX() > SizePcX())? pHit->LorsX()-SizePcX()-SizeDead():pHit->LorsX(); //sagita is for PC (0-64) and not for chamber + Float_t qdcEle=34.06311+0.2337070*x+5.807476e-3*x*x-2.956471e-04*x*x*x+2.310001e-06*x*x*x*x; //reparametrised from DiMauro + + Int_t iNele=Int_t(pHit->E()/26e-9); if(iNele<1) iNele=1; //number of electrons created by hit + Float_t qdcTot=0; for(Int_t i=1;i<=iNele;i++) qdcTot-=qdcEle*TMath::Log(gRandom->Rndm()+1e-6); //total qdc fro hit, 1e-6 is a protection against 0 from rndm + + AliRICHDigit dd(1,1,1,pHit->LorsX(),pHit->LorsY()); //tmp digit to shift hit y to the nearest anod wire + Float_t y= (pHit->LorsY() > dd.LorsY()) ? dd.LorsY()+0.21 : dd.LorsY()-0.21; + + Int_t iSdiCnt=pSdiLst->GetEntries(); + for(Int_t i=0;i<9;i++){ //affected pads loop + AliRICHDigit dig(pHit->Ch(),qdcTot,pHit->Tid(),pHit->LorsX(),y,i); //c,q,tid,x,y create tmp sdigit for pad i around hit position + if(dig.PadX()==-1) continue; + new((*pSdiLst)[iSdiCnt++]) AliRICHDigit(dig); + } + return qdcTot; +}//Hit2Sdi() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHDigit::Print(Option_t*)const { -//Print current digit -//Arguments: option string not used -// Returns: none - Printf("pad=(%2i,%2i,%3i,%3i), QDC=%8.3f, cfm=%9i, TID=(%5i,%5i,%5i) raw r=%2i d=%2i a=%2i", - C(),Pad2Sec(PadX(),PadY()),PadX(),PadY() , Qdc(), Cfm() , fTracks[0],fTracks[1],fTracks[2], R(), D(), A()); +// Print current digit +// Arguments: option string not used +// Returns: none + Printf("pad=(%2i,%2i,%3i,%3i),pos=(%7.2f,%7.2f) QDC=%8.3f, TID=(%5i,%5i,%5i) raw r=%2i d=%2i a=%2i", + Ch(),Pc(),PadX(),PadY(),LorsX(),LorsY(), Q(), fTracks[0],fTracks[1],fTracks[2], Row(), Dilogic(), Addr()); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHDigit::Test() +void AliRICHDigit::PrintSize() { - Printf("Test of Pad2Sec:"); - Int_t x1=kFirstPad, x2=kPadsSecX, x3=kPadsSecX+1, x4=kPadsChamX;//all possible padx for corners - Int_t y; - - y=kPadsChamY; - Printf("Sector5:(%3i,%3i)->%i (%3i,%3i)->%i Sector6:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y)); - y=2*kPadsSecY+1; - Printf("Sector5:(%3i,%3i)->%i (%3i,%3i)->%i Sector6:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y)); - Printf(""); - y=2*kPadsSecY; - Printf("Sector3:(%3i,%3i)->%i (%3i,%3i)->%i Sector4:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y)); - y=kPadsSecY+1; - Printf("Sector3:(%3i,%3i)->%i (%3i,%3i)->%i Sector4:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y)); - Printf(""); - y=kPadsSecY; - Printf("Sector1:(%3i,%3i)->%i (%3i,%3i)->%i Sector2:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y)); - y=kFirstPad; - Printf("Sector1:(%3i,%3i)->%i (%3i,%3i)->%i Sector2:(%3i,%3i)->%i (%3i,%3i)->%i",x1,y,Pad2Sec(x1,y),x2,y,Pad2Sec(x2,y),x3,y,Pad2Sec(x3,y),x4,y,Pad2Sec(x4,y)); +// Print all segmentaion related sizes +// Arguments: none +// Returns: none + Printf("-->pad =(%6.2f,%6.2f) cm dead zone %.2f cm\n" + "-->PC =(%6.2f,%6.2f) cm\n" + "-->all PCs=(%6.2f,%6.2f) cm", + SizePadX(),SizePadY(),SizeDead(),SizePcX(),SizePcY(),SizeAllX(),SizeAllY()); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHDigit::TestSeg() +{ +// Draws the picture of segmentation +// Arguments: none +// Returns: none + TCanvas *pC=new TCanvas("pads","View from electronics side, IP is behind the picture.");pC->ToggleEventStatus(); + gPad->AddExec("test","AliRICHDigit::Zoom()"); + DrawPc(); +}//TestSeg() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHDigit::Zoom() +{ +// Show info about current cursur position in status bar of the canvas +// Arguments: none +// Returns: none + TCanvas *pC=(TCanvas*)gPad; + TRootCanvas *pRC= (TRootCanvas*)pC->GetCanvasImp(); + TGStatusBar *pBar=pRC->GetStatusBar(); + pBar->SetParts(5); + Float_t x=gPad->AbsPixeltoX(gPad->GetEventX()); + Float_t y=gPad->AbsPixeltoY(gPad->GetEventY()); + AliRICHDigit dig(1,100,1,x,y); + if(IsInDead(x,y)) + pBar->SetText("Out of sensitive area",4); + else + pBar->SetText(Form("p%i x%i y%i r%i d%i a%i (%.2f,%.2f)",dig.Pc(),dig.PadX(),dig.PadY(),dig.Row(),dig.Dilogic(),dig.Addr(),dig.LorsX(),dig.LorsY()),4); + if(gPad->GetEvent()==1){ + new TCanvas("zoom",Form("Row %i DILOGIC %i",dig.Row(),dig.Dilogic())); + } +}//Zoom() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHDigit::DrawPc(Bool_t isFill) +{ +// Utility methode draws RICH chamber PCs on event display. +// Arguments: none +// Returns: none +// y6 ---------- ---------- +// | | | | +// | 4 | | 5 | +// y5 ---------- ---------- +// +// y4 ---------- ---------- +// | | | | +// | 2 | | 3 | view from electronics side +// y3 ---------- ---------- +// +// y2 ---------- ---------- +// | | | | +// | 0 | | 1 | +// y1 ---------- ---------- +// x1 x2 x3 x4 + gPad->Range(-5,-5,SizeAllX()+5,SizeAllY()+5); + Float_t x1=0,x2=SizePcX(),x3=SizePcX()+SizeDead(), x4=SizeAllX(); + Float_t y1=0,y2=SizePcY(),y3=SizePcY()+SizeDead(),y4=2*SizePcY()+SizeDead(),y5=SizeAllY()-SizePcY(),y6=SizeAllY(); + + Float_t xL[5]={x1,x1,x2,x2,x1}; //clockwise + Float_t xR[5]={x3,x3,x4,x4,x3}; + Float_t yD[5]={y1,y2,y2,y1,y1}; + Float_t yC[5]={y3,y4,y4,y3,y3}; + Float_t yU[5]={y5,y6,y6,y5,y5}; + + TLatex t; t.SetTextSize(0.01); t.SetTextAlign(22); + Int_t iColLeft=29,iColRight=41; + TPolyLine *pc=0; TLine *pL; Float_t x0=0,y0=0,wRow=kDilY*SizePadY(),wDil=kDilX*SizePadX(); + for(Int_t iPc=0;iPcSetFillColor(iColLeft): pc->SetFillColor(iColRight); + if(isFill) pc->Draw("f"); else pc->Draw(); + for(Int_t i=1;i<=8 ;i++){//draw row lines (horizontal) + Float_t y=y0+i*wRow; + Int_t row=i+iPc/2*8; if(iPc%2!=0) row=25-row; t.DrawText(x0-1,y -3,Form("r%i",row)); + if(i==8) break; //do not draw the last line of PC + pL=new TLine(x0,y,x0+SizePcX(),y); pL->Draw(); + } + for(Int_t iDil=1;iDil<=10;iDil++){Float_t x=x0+iDil*wDil;t.DrawText(x -3,y0-1,Form("d%i",11-iDil)); if(iDil==10) break; pL=new TLine(x,y0,x,y0+SizePcY()); pL->Draw();} + } +}//DrawPc() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHDigit.h b/RICH/AliRICHDigit.h index 902a2346336..5a92fb5a3a3 100644 --- a/RICH/AliRICHDigit.h +++ b/RICH/AliRICHDigit.h @@ -4,60 +4,109 @@ * See cxx source for full Copyright notice */ #include //base class -#include //ToRaw(), FromRaw() -#include //ctor +#include //Mathieson() +#include //IsOverTh() +#include //Raw() +class AliRICHHit; //Hit2Sdi() +class TClonesArray; //Hit2Sdi() + class AliRICHDigit :public AliDigit //TObject-AliDigit-AliRICHDigit { public: - enum EAbsPad {kChamAbs=10000000,kSecAbs=1000000,kPadAbsX=1000,kPadAbsY=1}; //absolute pad number structure - enum ERawData{kDiloX=8,kDiloY=6,kNdilo=10}; //DILOGIC structure - enum EPadData{kFirstPad=1,kPadsSecX=80,kPadsSecY=48,kPadsChamX=160,kPadsChamY=144,kSecX=2,kSecY=3}; //Segmentation structure - enum EDdlData{kNddls=14}; //DDL structure + enum EAbsPad {kChAbs=100000000,kPcAbs=1000000,kPadAbsX=1000,kPadAbsY=1}; //absolute pad number structure + enum ERawData{kDilX=8,kDilY=6,kNdil=10,kNrow=24,kNddls=14}; //RAW data structure + enum EPadData{kPcX=2,kPcY=3,kPad1=0,kPadPcX=80,kPadPcY=48,kPadAllX=kPadPcX*kPcX,kPadAllY=kPadPcY*kPcY,kPcAll=kPcX*kPcY,kPadAll=kPadAllX*kPadAllY}; //Segmentation structure + enum EPadShif{kC=0,kU=1,kUR=2,kR=3,kDR=4,kD=5,kDL=6,kL=7,kUL=8}; //ctor&dtor - AliRICHDigit() :AliDigit(),fCFM(-1) ,fChamber(-1 ) ,fPadX(-1) ,fPadY(-1) ,fQdc(-1) {} - AliRICHDigit(Int_t pad,Double_t qdc,Int_t cfm=-1,Int_t tid=-1):AliDigit(),fCFM(cfm),fChamber(P2C(pad)) ,fPadX(P2X(pad)),fPadY(P2Y(pad)),fQdc(qdc) {fTracks[0]=tid;} - AliRICHDigit(TVector pad,Double_t q ):AliDigit(),fCFM(-1) ,fChamber(-1) ,fPadX((Int_t)pad[0]) ,fPadY((Int_t)pad[1]) ,fQdc(q) {} - AliRICHDigit(Int_t c,TVector pad,Double_t q,Int_t cfm,Int_t tid0,Int_t tid1,Int_t tid2):fCFM(cfm),fChamber(c),fPadX((Int_t)pad[0]),fPadY((Int_t)pad[1]),fQdc(q) - {fTracks[0]=tid0;fTracks[1]=tid1;fTracks[2]=tid2;} - virtual ~AliRICHDigit() {;} + AliRICHDigit( ):AliDigit( ),fPad(Abs(-1,-1,-1,-1)),fQ(-1) {} //default ctor + AliRICHDigit(Int_t pad,Int_t q,Int_t *t ):AliDigit(t),fPad(pad ),fQ(q ) {} //digit ctor + inline AliRICHDigit(Int_t c,Float_t q,Int_t t,Float_t x,Float_t y,Int_t f=0); //sdigit ctor + virtual ~AliRICHDigit() {} //dtor //framework part - Bool_t IsSortable ( )const{return kTRUE;} //provision to use TObject::Sort() - inline Int_t Compare (const TObject *pObj )const; //provision to use TObject::Sort() - void Print (Option_t *opt="" )const; //TObject::Print() overloaded + Bool_t IsSortable ( )const{return kTRUE;} //provision to use TObject::Sort() + inline Int_t Compare (const TObject *pObj )const; //provision to use TObject::Sort() + void Print (Option_t *opt="" )const; //TObject::Print() overloaded //private part - Int_t A ( )const{return (PadY()-1)%kDiloY*kDiloX+(PadX()-1)%kDiloX;} //DILOGIC address 0..47 invented ????? - void AddTidOffset(Int_t offset ) {for (Int_t i=0; i<3; i++) if (fTracks[i]>0) fTracks[i]+=offset;}; //needed for merging - Int_t Cfm ( )const{return fCFM;} //ckov-feed-mip mixture - Int_t Chamber ( )const{return fChamber;} //chamber number - Int_t C ( )const{return fChamber;} //chamber number - Int_t D ( )const{return 1+(PadX()-1)/kDiloX;} //DILOGIC chip number 1..10 - Int_t Ddl ( )const{return (PadX()<=kPadsSecX) ? 2*C()-2 : 2*C()-1;} //DDL number 0..13 - inline Int_t Dig2Raw ( UInt_t &w )const; //returns DDL ID and fill raw word - Int_t PadX ( )const{return fPadX;} //x position of the pad - Int_t PadY ( )const{return fPadY;} //y postion of the pad - TVector Pad ( )const{Float_t v[2]={fPadX,fPadY}; return TVector(2,v);} - Int_t PadAbs ( )const{return fChamber*kChamAbs+fPadX*kPadAbsX+fPadY;} //absolute id of this pad - static inline Int_t Pad2Sec (Int_t x,Int_t y ); - static Int_t P2A (Int_t c, Int_t x,Int_t y) {Int_t s=Pad2Sec(x,y);return c*kChamAbs+s*kSecAbs+x*kPadAbsX+y;} //(cham,padx,pady)-> abs pad - static Int_t P2A (Int_t c,Int_t s,Int_t x,Int_t y) {return Pad2Sec(x,y)==s?c*kChamAbs+s*kSecAbs+x*kPadAbsX+y:-1;} //(cham,sec,padx,pady)-> abs pad - static Int_t P2C (Int_t pad ) {return pad/kChamAbs;} //abs pad -> chamber - static Int_t P2S (Int_t pad ) {return pad%kChamAbs/kSecAbs;} //abs pad -> sector - static Int_t P2X (Int_t pad ) {return pad%kSecAbs/kPadAbsX;} //abs pad -> pad X - static Int_t P2Y (Int_t pad ) {return pad%kPadAbsX;} //abs pad number-> pad Y - Double_t Qdc ( )const{return fQdc;} //charge, QDC - Int_t R ( )const{return 1+(PadY()-1)/kDiloY;} //DILOGIC row number 1..24 - inline void Raw2Dig (Int_t ddl,UInt_t w32 ); //(DDL,w32)->(ch,sec,x,y,QDC) - Int_t S ( )const{return -1;} //sector number ????? - static void Test ( ); //test raw-digit manipulations -protected: - Int_t fCFM; //1000000*Ncerenkovs+1000*Nfeedbacks+Nmips - Int_t fChamber; //chamber number - Int_t fPadX; //pad along X counts from kFirstPad to kPadsChamX - Int_t fPadY; //pad along Y counts from kFirstPad to kPadsChamY - Double_t fQdc; //QDC value, fractions are permitted for summable procedure - ClassDef(AliRICHDigit,3) //RICH digit class -};//class AliRICHDigit + static Int_t Abs (Int_t c,Int_t s,Int_t x,Int_t y) {return c*kChAbs+s*kPcAbs+x*kPadAbsX+y*kPadAbsY; } //(ch,pc,padx,pady)-> abs pad + static Int_t A2C (Int_t pad ) {return pad/kChAbs; } //abs pad -> chamber + static Int_t A2P (Int_t pad ) {return pad%kChAbs/kPcAbs; } //abs pad -> pc + static Int_t A2X (Int_t pad ) {return pad%kPcAbs/kPadAbsX; } //abs pad -> pad X + static Int_t A2Y (Int_t pad ) {return pad%kPadAbsX; } //abs pad -> pad Y + Int_t Addr ( )const{Int_t mapY2A[kDilY]={5,3,1,0,2,4}; return mapY2A[A2Y(fPad)%kDilY]+kDilY*(A2X(fPad)%kDilX);}//raw a=0..47 + void AddTidOffset(Int_t offset ) {for (Int_t i=0; i<3; i++) if (fTracks[i]>0) fTracks[i]+=offset;}; //needed for merging + Int_t Ch ( )const{return A2C(fPad); } //chamber number + Int_t Dilogic ( )const{return 10-PadX()/kDilX; } //raw d=1..10 + static void DrawPc (Bool_t isFill=kTRUE ); //draw PCs + Int_t Ddl ( )const{return (PadX() 9 sdigits, returns total QDC + static Bool_t IsOverTh (Float_t q ) {return q > 6; } //is digit over threshold???? + static Bool_t IsInside (Float_t x,Float_t y ) {return x>0&&y>0&&x= 0 && x<= SizePcX() ) {pc=0; padx=Int_t( x / SizePadX());}//PC 0 or 2 or 4 + else if(x>=SizePcX()+SizeDead() && x<= SizeAllX() ) {pc=1; padx=Int_t((x- SizePcX()- SizeDead()) / SizePadX());}//PC 2 or 4 or 6 + else return; + if (y>= 0 && y<= SizePcY() ) { pady=Int_t( y / SizePadY());}//PC 0 or 1 + else if(y>=SizePcY()+SizeDead() && y<=2*SizePcY()+SizeDead() ) {pc+=2;pady=Int_t((y- SizePcY()- SizeDead()) / SizePadY());}//PC 2 or 3 + else if(y>=SizeAllY()-SizePcY() && y<= SizeAllY() ) {pc+=4;pady=Int_t((y-2*SizePcY()-2*SizeDead()) / SizePadY());}//PC 4 or 5 + else return; + + switch(flag){ + case kUL:padx--;pady++;break; case kU:pady++;break; case kUR:padx++; pady++;break; + + case kL: padx--; break; case kC: break; case kR:padx++; break; + + case kDL:padx--;pady--;break; case kD:pady--;break; case kDR:padx++; pady--;break; + } + if(padx<0 || padx>=kPadPcX) return; + if(pady<0 || pady>=kPadPcY) return; + fPad=Abs(c,pc,padx,pady); + fQ=q*Mathieson(x,y); + fTracks[0]=t; +} //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Int_t AliRICHDigit::Compare(const TObject *pObj) const { @@ -65,57 +114,63 @@ Int_t AliRICHDigit::Compare(const TObject *pObj) const // This feature is used in digitizer to facilitate finding of sdigits for the same pad since they all will come together after sorting. // Arguments: pObj - pointer to object to compare with // Retunrs: -1 if AbsPad less then in pObj, 1 if more and 0 if they are the same - if (PadAbs()==((AliRICHDigit*)pObj)->PadAbs()) return 0; - else if(PadAbs() >((AliRICHDigit*)pObj)->PadAbs()) return 1; - else return -1; + if (fPad==((AliRICHDigit*)pObj)->Pad()) return 0; + else if(fPad >((AliRICHDigit*)pObj)->Pad()) return 1; + else return -1; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHDigit::Raw2Dig(Int_t ddl,UInt_t w32) +Bool_t AliRICHDigit::IsInDead(Float_t x,Float_t y) { -//Converts a given raw data word to a digit -//Arguments: w32 - 32 bits raw data word -// ddl - DDL file number 0 1 2 3 4 ... 13 -// Returns: none - fQdc = AliBitPacking::UnpackWord(w32, 0,11); // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq Qdc bits (00..11) counts (0..4095) - UInt_t a = AliBitPacking::UnpackWord(w32,12,17); // 3322 2222 2222 1111 1111 1000 0000 0000 DILOGIC address bits (12..17) counts (0..47) - UInt_t d = AliBitPacking::UnpackWord(w32,18,21); // 1098 7654 3210 9876 5432 1098 7654 3210 DILOGIC number bits (18..21) counts (1..10) - UInt_t r = AliBitPacking::UnpackWord(w32,22,26); // Row number bits (22..26) counts (1..24) +// Check is the current point is outside of sensitive area or in dead zones +// Arguments: x,y -position +// Returns: 1 if not in sensitive zone + if(x<0 || x>SizeAllX() || y<0 || y>SizeAllY()) return kTRUE; //out of pc - fPadY = (r-1)*kDiloY+a/kDiloX+1; - fPadX = (d-1)*kDiloX+a%kDiloX+1; fPadX+=(ddl%2)*kDiloX*kNdilo;//if ddl is odd then right half of the chamber - fChamber = (ddl+2)/2; // ddl 0..13 to chamber 1..7 -} + if(x>SizePcX() && xSizePcY() && ySizeAllY()-SizePcY()-SizeDead() && y x - Int_t sector=-1; - if (padx >= kFirstPad && padx <= kPadsSecX ) sector=1; - else if(padx > kPadsSecX && padx <= kPadsChamX) sector=2; - else return -1;//padx out of range - if (pady >= kFirstPad && pady <= kPadsSecY ) return sector; - else if(pady > kPadsSecY && pady <= 2*kPadsSecY ) return sector+2; - else if(pady >2*kPadsSecY && pady <= kPadsChamY) return sector+4; - else return -1; //pady out of range -}//Pad2Sec() +// Converts a given raw data word to a digit +// Arguments: w32 - 32 bits raw data word +// ddl - DDL idx 0 1 2 3 4 ... 13 +// Returns: none + fQ = AliBitPacking::UnpackWord(w32, 0,11); // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq Qdc bits (00..11) counts (0..4095) + UInt_t a = AliBitPacking::UnpackWord(w32,12,17); // 3322 2222 2222 1111 1111 1000 0000 0000 DILOGIC address bits (12..17) counts (0..47) + UInt_t d = AliBitPacking::UnpackWord(w32,18,21); // 1098 7654 3210 9876 5432 1098 7654 3210 DILOGIC number bits (18..21) counts (1..10) + UInt_t r = AliBitPacking::UnpackWord(w32,22,26); // Row number bits (22..26) counts (1..24) + ReadRaw(ddl,r,d,a); +} //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #endif diff --git a/RICH/AliRICHDigitizer.cxx b/RICH/AliRICHDigitizer.cxx index 0129130f9cc..031fb1874ff 100644 --- a/RICH/AliRICHDigitizer.cxx +++ b/RICH/AliRICHDigitizer.cxx @@ -15,6 +15,7 @@ #include "AliRICHDigitizer.h" #include "AliRICH.h" +#include "AliRICHDigit.h" #include #include #include "AliRunDigitizer.h" @@ -24,17 +25,16 @@ ClassImp(AliRICHDigitizer) -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHDigitizer::Exec(Option_t*) { -//This methode is responsible for merging sdigits to a list of digits -//Disintegration leeds to the fact that one hit affected several neighbouring pads, which means that the same pad might be -//affected by few hits. +// This methode is responsible for merging sdigits to a list of digits +//Disintegration leeds to the fact that one hit affects several neighbouring pads, which means that the same pad might be affected by few hits. AliDebug(1,Form("Start with %i input(s) for event %i",fManager->GetNinputs(),fManager->GetOutputEventNr())); //First we read all sdigits from all inputs AliRunLoader *pInRunLoader=0;//in and out Run loaders AliLoader *pInRichLoader=0;//in and out RICH loaders - TClonesArray tmpCA("AliRICHDigit");//tmp storage for sdigits sum up from all input files + TClonesArray sdigs("AliRICHDigit");//tmp storage for sdigits sum up from all input files Int_t total=0; for(Int_t inFileN=0;inFileNGetNinputs();inFileN++){//files loop pInRunLoader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inFileN)); //get run loader from current input @@ -42,41 +42,63 @@ void AliRICHDigitizer::Exec(Option_t*) if (!pInRunLoader->GetAliRun()) pInRunLoader->LoadgAlice(); AliRICH* pInRich=(AliRICH*)pInRunLoader->GetAliRun()->GetDetector("RICH"); //take RICH from current input pInRichLoader->LoadSDigits(); pInRichLoader->TreeS()->GetEntry(0); //take list of RICH sdigits from current input - AliDebug(1,Form("input %i has %i sdigits",inFileN,pInRich->SDigs()->GetEntries())); - for(Int_t i=0;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 + AliDebug(1,Form("input %i has %i sdigits",inFileN,pInRich->SdiLst()->GetEntries())); + for(Int_t i=0;iSdiLst()->GetEntries();i++){ //collect sdigits from current input + AliRICHDigit *pSDig=(AliRICHDigit*)pInRich->SdiLst()->At(i); + pSDig->AddTidOffset(fManager->GetMask(inFileN)); //apply TID shift since all inputs count tracks independently starting from 0 + new(sdigs[total++]) AliRICHDigit(*pSDig); } - pInRichLoader->UnloadSDigits(); pInRich->SDigReset(); //close current input and reset + pInRichLoader->UnloadSDigits(); pInRich->SdiReset(); //close current input and reset }//files loop - - tmpCA.Sort(); //at this point we have a list of all sdigits from all inputs, now sort them according to fPad field + + if(sdigs.GetEntries()==0) return; //no sdigits collected, nothing to convert AliRunLoader *pOutRunLoader = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName()); //open output stream (only 1 possible) AliLoader *pOutRichLoader = pOutRunLoader->GetLoader("RICHLoader"); //take output RICH loader AliRICH *pOutRich = (AliRICH*)pOutRunLoader->GetAliRun()->GetDetector("RICH"); //take output RICH pOutRichLoader->MakeTree("D"); pOutRich->MakeBranch("D"); //create TreeD in output stream - - TVector pad(2); pad[0]=0; pad[1]=0; Int_t iChamber=0,iCfm=0,aTids[3]={0,0,0},iId=-1; Double_t dQdc=0;//current pad info - Int_t iNdigsPerPad=0; //how many sdigits for a given pad - for(Int_t i=0;iPadAbs()==iId){//still the same pad - iNdigsPerPad++; dQdc+=pSdig->Qdc(); iCfm+=pSdig->Cfm();//sum up charge and cfm - if(pSdig->Cfm()==1) aTids[0] = pSdig->GetTrack(0); // force the first tid to be mip's tid if it exists in the current pad - if(iNdigsPerPad<=3) aTids[iNdigsPerPad-1]=pSdig->GetTrack(0); - else AliDebug(1,Form("More then 3 sdigits in (%d,%d,%f,%f) with Q= %f",pSdig->Chamber(),-1,pSdig->Pad()(0),pSdig->Pad()(1),pSdig->Qdc())); - }else{//new pad, add the pevious one - if(iId!=-1 && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids); //add newly created dig - iChamber=pSdig->Chamber(); pad=pSdig->Pad(); iCfm=pSdig->Cfm(); dQdc=pSdig->Qdc(); iId=pSdig->PadAbs(); //init all values by current sdig - iNdigsPerPad=1; aTids[0]=pSdig->GetTrack(0); aTids[1]=aTids[2]=-1; - } - }//sdigits loop (sorted) - if(tmpCA.GetEntries() && AliRICHParam::IsOverTh(iChamber,pad,dQdc)) pOutRich->DigAdd(iChamber,pad,(Int_t)dQdc,iCfm,aTids);//add the last dig + + Sdi2Dig(&sdigs,pOutRich->DigLst()); pOutRichLoader->TreeD()->Fill(); //fill the output tree with the list of digits pOutRichLoader->WriteDigits("OVERWRITE"); //serialize them to file - tmpCA.Clear(); //remove all tmp sdigits + sdigs.Clear(); //remove all tmp sdigits pOutRichLoader->UnloadDigits(); pOutRich->DigReset(); }//Exec() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHDigitizer::Sdi2Dig(TClonesArray *pSdiLst,TObjArray *pDigLst) +{ +// Converts list of sdigits to 7 lists of digits, one per each chamber +// Arguments: pSDigLst - list of all sdigits +// pDigLst - list of 7 lists of digits +// Returns: none + + TClonesArray *pLst[7]; Int_t iCnt[7]; + + for(Int_t i=0;i<7;i++){ + pLst[i]=(TClonesArray*)(*pDigLst)[i]; + iCnt[i]=pLst[i]->GetEntries(); //in principle those lists should be empty + } + + pSdiLst->Sort(); + + Int_t iPad=-1,iCh=-1,iNdigPad=-1,aTids[3]={-1,-1,-1}; Float_t q=-1; + for(Int_t i=0;iGetEntries();i++){ //sdigits loop (sorted) + AliRICHDigit *pSdig=(AliRICHDigit*)pSdiLst->At(i); //take current sdigit + if(pSdig->Pad()==iPad){ //if the same pad + q+=pSdig->Q(); //sum up charge + iNdigPad++; if(iNdigPad<=3) aTids[iNdigPad-1]=pSdig->GetTrack(0); //collect TID + continue; + } + if(i!=0 && AliRICHDigit::IsOverTh(q)) new((*pLst[iCh])[iCnt[iCh]++]) AliRICHDigit(iPad,(Int_t)q,aTids); //do not create digit for the very first sdigit + iPad=pSdig->Pad(); iCh=AliRICHDigit::A2C(iPad); //new sdigit comes, reset collectors + iNdigPad=1; + aTids[0]=pSdig->GetTrack(0);aTids[1]=aTids[2]=-1; + q=pSdig->Q(); + }//sdigits loop (sorted) + + if(AliRICHDigit::IsOverTh(q)) new((*pLst[iCh])[iCnt[iCh]++]) AliRICHDigit(iPad,(Int_t)q,aTids); //add the last one, in case of empty sdigits list q=-1 + //so digit is not created +}//Sdi2Dig() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHDigitizer.h b/RICH/AliRICHDigitizer.h index 8893185c39d..70096b506ff 100644 --- a/RICH/AliRICHDigitizer.h +++ b/RICH/AliRICHDigitizer.h @@ -6,6 +6,8 @@ #include class AliRunDigitizer; +class TClonesArray; +class TObjArray; class AliRICHDigitizer : public AliDigitizer //TObject-TNamed-TTask-AliDigitizer-AliRICHDigitizer { @@ -14,6 +16,8 @@ public: AliRICHDigitizer(AliRunDigitizer *pRunDig):AliDigitizer(pRunDig) {} virtual ~AliRICHDigitizer() {} void Exec(Option_t* option=0); //virtual +// + static void Sdi2Dig(TClonesArray *pSDigLst,TObjArray *pDigLst); protected: ClassDef(AliRICHDigitizer,0) }; diff --git a/RICH/AliRICHHelix.cxx b/RICH/AliRICHHelix.cxx index 408b33af229..2602a520b22 100644 --- a/RICH/AliRICHHelix.cxx +++ b/RICH/AliRICHHelix.cxx @@ -3,41 +3,23 @@ ClassImp(AliRICHHelix) //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -AliRICHHelix::AliRICHHelix(Double_t p,Double_t theta,Double_t phi,Double_t bz):TObject(), - fX0(TVector3(0,0,0)), - fP0(TVector3(0,0,0)), - fX(TVector3(0,0,0)), - fP(TVector3(0,0,0)), - fLen(0), - fQ(0), - fBz(bz), - fPosRad(TVector2(0,0)), - fPosPc(TVector2(0,0)), - fPloc(TVector3(0,0,0)) -{ - fP0.SetMagThetaPhi(p,theta*TMath::DegToRad(),phi*TMath::DegToRad()); fP=fP0; -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHHelix::Print(Option_t *opt) const { // Debug printout Printf("%s helix for Q=%i in B=(0,0,%.2f) tesla",opt,fQ,fBz); Printf("Helix parametrised @ x0=(%6.2f,%6.2f,%6.2f) cm p0=(%6.2f,%6.2f,%6.2f) GeV P=%.2f GeV Theta=%.2f Phi=%.2f degrees", fX0.X(),fX0.Y(),fX0.Z(), fP0.Px(),fP0.Py(),fP0.Pz(), fP0.Mag(),fP0.Theta()*TMath::RadToDeg(),fP0.Phi()*TMath::RadToDeg()); - Printf("@ %7.2f cm x=(%6.2f,%6.2f,%6.2f) cm p=(%6.2f,%6.2f,%6.2f) GeV P=%.2f GeV Theta=%.2f Phi=%.2f degrees", - fLen, fX.X(), fX.Y(), fX.Z(), fP.Px(),fP.Py(),fP.Pz(), fP.Mag(), fP.Theta()*TMath::RadToDeg(),fP.Phi()*TMath::RadToDeg()); - Printf(" in LORS rad=(%5.2f,%5.2f) pc=(%5.2f,%5.2f)",fPosRad.X(), fPosRad.Y(),fPosPc.X(),fPosPc.Y()); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHHelix::Draw(const Option_t *) { // Draw helix by a set of points seperated by 1 cm distance - + TVector3 pos,mom; const Int_t kNpoints=500; TPolyLine3D *pHelDraw = new TPolyLine3D(kNpoints); pHelDraw->SetLineColor(kGreen); for(Int_t i=0;iSetPoint(i,fX.X(),fX.Y(),fX.Z()); + Propagate(i,pos,mom); + pHelDraw->SetPoint(i,pos.X(),pos.Y(),pos.Z()); } pHelDraw->Draw(); } diff --git a/RICH/AliRICHHelix.h b/RICH/AliRICHHelix.h index 5288748a9f2..0139905cecb 100644 --- a/RICH/AliRICHHelix.h +++ b/RICH/AliRICHHelix.h @@ -3,124 +3,69 @@ #include //base class #include //used extensively -#include "AliRICHParam.h" //RichIntersect() class AliRICHHelix: public TObject { public: - AliRICHHelix():TObject(), - fX0(TVector3(0,0,0)), - fP0(TVector3(0,0,0)), - fX(TVector3(0,0,0)), - fP(TVector3(0,0,0)), - fLen(0), - fQ(0), - fBz(0), - fPosRad(TVector2(0,0)), - fPosPc(TVector2(0,0)), - fPloc(TVector3(0,0,0)) {} - AliRICHHelix(Double_t p,Double_t theta,Double_t phi,Double_t bz=0.2);//p [GeV], theta,phi [deg], Bz [Tesla]; - AliRICHHelix(const TVector3 &x0,const TVector3 &p0,Int_t q=1,Double_t b=0.2):TObject(), - fX0(x0), - fP0(p0), - fX(x0), - fP(p0), - fLen(0), - fQ(q), - fBz(b), - fPosRad(TVector2(0,0)), - fPosPc(TVector2(0,0)), - fPloc(TVector3(0,0,0)) {} + AliRICHHelix( ):TObject(),fX0(TVector3(0,0,0)),fP0(TVector3(0,0,0)),fQ(0),fBz(0 ) {} + AliRICHHelix(const TVector3 &x0,const TVector3 &p0,Int_t q=1,Double_t b=2):TObject(),fX0(x0 ),fP0(p0 ),fQ(q),fBz(b ) {} + AliRICHHelix(Double_t p,Double_t theta,Double_t phi,Double_t bz=2 ):TObject(),fX0(TVector3(0,0,0)),fP0(TVector3(0,0,0)),fQ(0),fBz(bz) + {fP0.SetMagThetaPhi(p,theta*TMath::DegToRad(),phi*TMath::DegToRad());} //p [GeV], theta,phi [deg], Bz [Tesla]; virtual ~AliRICHHelix() {} void Draw (const Option_t *opt="" ); //from TObject, draw helix - void Print (const Option_t *opt="" )const; //from TObject, print status + void Print (const Option_t *opt="" )const; //from TObject, print status //private part++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - inline Bool_t Intersection (TVector3 planePnt,TVector3 planeNorm); //intersection with plane given by point and normal vector - inline void Propagate (Double_t len ); //propogate helix by given length along it - inline Int_t RichIntersect (AliRICHParam *pParam ); //search intersection with any RICH chamber - TVector2 PosRad ( )const{return fPosRad;} //intersection with radiator LORS - TVector2 PosPc ( )const{return fPosPc;} //returns position of intersection with PC (local system) - TVector3 Ploc ( )const{return fPloc;} //returns momentum at the position of intersection with radiator -// Double_t Length () const{return fLen;} //returns length of the track from initial point to RICH - TVector3 X ( )const{return fX;} + inline Bool_t Intersect( TVector3 &pnt,TVector3 &norm ); //intersection with plane given by point and normal vector + inline void Propagate(Float_t len,TVector3 &x, TVector3 &p ); //propogate helix by given length along it protected: TVector3 fX0; //helix position in point of definition, [cm] in MARS TVector3 fP0; //helix momentum in point of definition, [GeV/c] in MARS - TVector3 fX; //helix position in point of interest, [cm] in MARS - TVector3 fP; //helix momentum in point of interest, [GeV/c] in MARS - Double_t fLen; //helix length from point of definition to point of interest, [cm] - Int_t fQ; //sign of track charge (value not provided by current ESD) - Double_t fBz; //magnetic field along z, [Tesla] - TVector2 fPosRad; //helix intersection with radiator entrance, LORS [cm] - TVector2 fPosPc; //helix intersection with PC, LORS [cm] - TVector3 fPloc; //helix momentum, LORS [GeV/c] + Int_t fQ; //sign of track charge + Float_t fBz; //magnetic field along z, [kGaus] ClassDef(AliRICHHelix,0) //General helix };//class AliRICHHelix //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHHelix::Propagate(Double_t len) +void AliRICHHelix::Propagate(Float_t len,TVector3 &x,TVector3 &p) { // Propogates the helix from inintial point by a given distance along helix. Assumes uniform magnetic field along z direction. // Arguments: len - distance to propagate by, [cm] // Returns: none if(fBz==0){//no magnetic field->straight line - fX=fX0+fP0.Unit()*len; + x=fX0+fP0.Unit()*len; + p=fP0; }else{ - const Double_t c = 0.00299792458;//this speed of light value provides that coordinates are in cm momentum in GeV/c - Double_t a = -c*fBz*fQ; - Double_t rho = a/fP0.Mag(); - fX.SetX( fX0.X()+fP0.X()*TMath::Sin(rho*len)/a-fP0.Y()*(1-TMath::Cos(rho*len))/a ); - fX.SetY( fX0.Y()+fP0.Y()*TMath::Sin(rho*len)/a+fP0.X()*(1-TMath::Cos(rho*len))/a ); - fX.SetZ( fX0.Z()+fP0.Z()*len/fP0.Mag() ); - fP.SetX( fP0.X()*TMath::Cos(rho*len)-fP0.Y()*TMath::Sin(rho*len) ); - fP.SetY( fP0.Y()*TMath::Cos(rho*len)+fP0.X()*TMath::Sin(rho*len) ); - fP.SetZ( fP0.Z() ); - fLen=len; + const Float_t c = 0.000299792458;//this speed of light value provides that coordinates are in [cm] momentum in [GeV/c] field in [kGaus] + Float_t a = -c*fBz*fQ; + Float_t rho = a/fP0.Mag(); + x.SetX( fX0.X()+fP0.X()*TMath::Sin(rho*len)/a-fP0.Y()*(1-TMath::Cos(rho*len))/a ); + x.SetY( fX0.Y()+fP0.Y()*TMath::Sin(rho*len)/a+fP0.X()*(1-TMath::Cos(rho*len))/a ); + x.SetZ( fX0.Z()+fP0.Z()*len/fP0.Mag() ); + x.SetX( fP0.X()*TMath::Cos(rho*len)-fP0.Y()*TMath::Sin(rho*len) ); + p.SetY( fP0.Y()*TMath::Cos(rho*len)+fP0.X()*TMath::Sin(rho*len) ); + p.SetZ( fP0.Z() ); } -} +}//Propagate() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Bool_t AliRICHHelix::Intersection(TVector3 planePoint,TVector3 planeNorm) +Bool_t AliRICHHelix::Intersect(TVector3 &pnt,TVector3 &norm) { // Finds point of intersection (if exists) of the helix with the plane. Stores result in fX and fP. -// Arguments: planePoint,planeNorm - the plane defined by any plane's point and vector, normal to the plane -// Returns: kTrue if helix intersects the plane, kFALSE otherwise. - - Double_t s=(planePoint-fX0)*planeNorm,dist=99999,distPrev=dist;//estimates initial distance to plane - - while(TMath::Abs(dist)>0.00001){ - Propagate(s); //calculates helix at the distance s from x0 ALONG the helix - dist=(fX-planePoint)*planeNorm; //distance between current helix position and plane - if(TMath::Abs(dist) >= TMath::Abs(distPrev)) { return kFALSE;} +// Arguments: pnt - arbitrary point of the plane, [cm] in MARS +// norm - vector, normal to the plane, [cm] in MARS +// Returns: - kTrue if helix intersects the plane, kFALSE otherwise. +// - pnt contains the point of intersection, [cm] in MARS + TVector3 x,p; //current helix position and momentum + Double_t s=(pnt-fX0)*norm,dist=99999,distPrev=dist; //estimates initial distance to plane + while(TMath::Abs(dist)>0.00001){ //loop while the distance is less then precision + Propagate(s,x,p); //calculates helix at the distance s from x0 ALONG the helix + dist=(x-pnt)*norm; //distance between current helix position and plane + if(TMath::Abs(dist) >= TMath::Abs(distPrev)) { return kFALSE;} //if distance increases then no intersection distPrev=dist; s-=dist; - } + } + norm=p; + pnt=x; return kTRUE; -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Int_t AliRICHHelix::RichIntersect(AliRICHParam *pParam) -{ -// Searchs for intersection of this helix with all RICH chambers, returns chamber number or 0 if no intersection -// On exit fPosRad contain position of intersection in radiator LORS (cm) -// fPosPc contains the same for photocathode - for(Int_t iCh=1;iCh<=AliRICHParam::kNch;iCh++){//chambers loop - TVector3 norm =pParam->Lors2MarsVec(iCh,TVector3(0,0,1)); - if(Intersection(pParam->Lors2Mars(iCh,0,0,AliRICHParam::kRad),norm)){//there is intersection with radiator plane - fPosRad=pParam->Mars2Lors(iCh,fX,AliRICHParam::kRad);//position on radiator plane - if(pParam->IsAccepted(fPosRad)){//intersection within radiator (even if in dead zone) - - if(Intersection(pParam->Lors2Mars(iCh,0,0,AliRICHParam::kPc),norm)){//there is intersection with photocathode - fPosPc=pParam->Mars2Lors(iCh,fX,AliRICHParam::kPc);//position on radiator plane - if(pParam->IsAccepted(fPosPc)){//intersection within pc (even if in dead zone) - - fPloc=pParam->Mars2LorsVec(iCh,fP);//trasform p to local system - return iCh; - }//if inside PC - }//if intersects PC - - }//if inside radiator - }//if for radiator - }//chambers loop - return 0; -} +}//Intersect() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #endif diff --git a/RICH/AliRICHHit.cxx b/RICH/AliRICHHit.cxx index 2bd9c2b00d9..b1b07b237ba 100644 --- a/RICH/AliRICHHit.cxx +++ b/RICH/AliRICHHit.cxx @@ -15,28 +15,29 @@ #include "AliRICHHit.h" //class header #include //Print() +#include ClassImp(AliRICHHit) -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHHit::Print(Option_t*)const { //Print hit - char *sPart=Form("pid=%i",fPid); - switch(fPid){ + char *sPart=Form("pid=%i",Pid()); + switch(Pid()){ case kProton: sPart="p+ ";break; - case kProtonBar: sPart="a- ";break; + case kProtonBar: sPart="p- ";break; case kKPlus: sPart="K+ ";break; case kKMinus: sPart="K- ";break; - case kPiPlus: sPart="pi+ ";break; - case kPiMinus: sPart="pi- ";break; - case kMuonPlus: sPart="mu+ ";break; - case kMuonMinus: sPart="mu- ";break; + case kPiPlus: sPart="Pi+ ";break; + case kPiMinus: sPart="Pi- ";break; + case kMuonPlus: sPart="Mu+ ";break; + case kMuonMinus: sPart="Mu- ";break; case kElectron: sPart="e- ";break; case kPositron: sPart="e+ ";break; case 50000050: sPart="ckov";break; case 50000051: sPart="feed";break; } - Printf("%s TID=%6i,Ch=(%2i),E=%9.3f eV, pos=(%7.2f,%7.2f,%7.2f)cm",sPart,Track(),C(),fE*1e9,fX,fY,fZ); + Printf("%s Ch:%i TID:%6i,E:%9.3f eV, LORS:(%7.2f,%7.2f) MARS:(%7.2f,%7.2f,%7.2f)cm",sPart,Ch(),Tid(),E()*1e9,LorsX(),LorsY(),X(),Y(),Z()); } -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHHit.h b/RICH/AliRICHHit.h index a75bb66da66..2ad639233ed 100644 --- a/RICH/AliRICHHit.h +++ b/RICH/AliRICHHit.h @@ -3,49 +3,33 @@ /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ -#include -#include +#include //base class +#include //ctor -//RICH hit container -class AliRICHHit : public AliHit +class AliRICHHit : public AliHit // TObject-AliHit-AliRICHHit { public: - AliRICHHit():AliHit(), - fCham(-1) , - fE(-1), - fPid(-1 ), - fInX3(TVector3(0,0,0)), - fOutX3(TVector3(0,0,0)) {} - AliRICHHit(Int_t c,Int_t tid,TVector3 in,TVector3 out,Double_t e,Int_t pid):AliHit(0,tid), - fCham(c ), - fE(e), - fPid(pid), - fInX3(in), - fOutX3(out) {fX=out.X();fY=out.Y();fZ=out.Z();} - AliRICHHit(Int_t tid,Double_t e,Int_t pad,Double_t x,Double_t y,Double_t z,Int_t pid):AliHit(0,tid), - fCham(pad), - fE(e), - fPid(pid), - fInX3(TVector3(x,y,z)), - fOutX3(TVector3(x,y,z)) {fX=x;fY=y;fZ=z;} - - virtual ~AliRICHHit() {} + AliRICHHit( ):AliHit( ),fCh(-1),fPid(-1 ),fE(-1),fLorsX(-1),fLorsY(-1) {} //default ctor + AliRICHHit(Int_t c,Float_t e,Int_t pid,Int_t tid,Float_t xl,Float_t yl,const TVector3 &p):AliHit(0,tid),fCh(c ),fPid(pid),fE(e ),fLorsX(xl),fLorsY(yl) {fX=p.X();fY=p.Y();fZ=p.Z();} + AliRICHHit(Int_t c,Float_t e,Int_t pid,Int_t tid,Float_t xl,Float_t yl ): fCh(c ),fPid(pid),fE(e ),fLorsX(xl),fLorsY(yl) {fTrack=tid;} + virtual ~AliRICHHit() {} //framework part - void Print(Option_t *option="")const; //from TObject to print current status + void Print(Option_t *option="")const; //from TObject to print current status //private part - Int_t C ()const{return fCham;} //chamber number - Int_t Chamber()const{return fCham;} //chamber number - Int_t Pad ()const{return fCham;} //absolute pad number, definition in AliRICHParam - Float_t Eloss ()const{return fE; } //Eloss for MIP hit or Etot for photon hit - TVector3 InX3 ()const{return fInX3;} //track position at the faceplane of the gap - TVector3 OutX3 ()const{return fOutX3;} //track position at the backplane of the gap - Double_t Length ()const{return (fOutX3-fInX3).Mag();} //track length inside the amplification gap -protected: - Int_t fCham; //chamber number or in future absolute pad number - Double_t fE; //Eloss for MIP or Etot for photon [GeV] - Int_t fPid; //PID of particle created this hit - TVector3 fInX3; //position at the entrance of the GAP - TVector3 fOutX3; //position at the exit of the GAP - ClassDef(AliRICHHit,3) //RICH hit class + Int_t Ch ()const{return fCh; } //Chamber + Float_t E ()const{return fE; } //Eloss for MIP hit or Etot for photon hit, [GeV] + Float_t LorsX ()const{return fLorsX; } //hit X position in LORS, [cm] + Float_t LorsY ()const{return fLorsY; } //hit Y position in LORS, [cm] + Int_t Pid ()const{return fPid; } //PID + Int_t Tid ()const{return fTrack; } //TID + +protected: //AliHit has fTid,fX,fY,fZ + Int_t fCh; //Chamber + Int_t fPid; //PID + Float_t fE; //Eloss for MIP or Etot for photon [GeV] + Float_t fLorsX; //hit X position in chamber LORS, [cm] + Float_t fLorsY; //hit Y position in chamber LORS, [cm] + ClassDef(AliRICHHit,4) //RICH hit class };//class AliRICHhit + #endif diff --git a/RICH/AliRICHParam.cxx b/RICH/AliRICHParam.cxx index 165709debf1..7b140efcdb7 100644 --- a/RICH/AliRICHParam.cxx +++ b/RICH/AliRICHParam.cxx @@ -12,416 +12,40 @@ // * about the suitability of this software for any purpose. It is * // * provided "as is" without express or implied warranty. * // ************************************************************************** -#include "AliRICHParam.h" //class header -#include "AliESD.h" -#include //TestXXX() -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "AliRICHParam.h" //class header +#include "AliRICHDigit.h" //ctor +#include //TestXXX() +#include //TestTrans() +#include //TestTrans() +#include //TestTrans() #include -#include //CdbRead() -#include //CdbRead() -#include //CdbRead() #include //Stack() #include //Stack() #include //Stack() #include "AliRICHHelix.h" //TestTrans() -#include - - ClassImp(AliRICHParam) -AliRICHParam * AliRICHParam::fgInstance =0x0; //singleton pointer + +AliRICHParam* AliRICHParam::fgInstance=0x0; //singleton pointer //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AliRICHParam::AliRICHParam():TNamed("RichParam","default version") { // Here all the intitializition is taken place when AliRICHParam::Instance() is invoked for the first time. // In particulare, matrices to be used for LORS<->MARS trasnformations are initialized from TGeo structure. // Note that TGeoManager should be already initialized from geometry.root file - for(Int_t iCh=0;iChGetVolume("ALIC")->GetNode(Form("RICH_%i",iCh+1))->GetMatrix(); - CdbRead(0,0); + fX=0.5*AliRICHDigit::SizeAllX(); + fY=0.5*AliRICHDigit::SizeAllY(); + for(Int_t i=0;i<7;i++) fM[i]=(TGeoHMatrix*)gGeoManager->GetVolume("ALIC")->GetNode(Form("RICH_%i",i))->GetMatrix(); fgInstance=this; }//ctor //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Float_t AliRICHParam::AbsCH4(Float_t eV) -{ -// Evaluate the absorbtion lenght of CH4 for a photon of energy eV in electron-volts - const Float_t kLoschmidt=2.686763e19; // LOSCHMIDT NUMBER IN CM-3 - const Float_t kPressure=750.0; //mm of Hg - const Float_t kTemperature=283.0; //K (10 grad C) - const Float_t kPn=kPressure/760.; - const Float_t kTn=kTemperature/273.16; - const Float_t kC0=-1.655279e-1; - const Float_t kC1= 6.307392e-2; - const Float_t kC2=-8.011441e-3; - const Float_t kC3= 3.392126e-4; - - Float_t crossSection=0; - if (eV<7.75) - crossSection=0.06e-22; - else //------ METHANE CROSS SECTION cm-2 ASTROPH. J. 214, L47 (1978) - crossSection=(kC0+kC1*eV+kC2*eV*eV+kC3*eV*eV*eV)*1.e-18; - - Float_t density=kLoschmidt*kPn/kTn; //CH4 molecular concentration (cm^-3) - return 1.0/(density*crossSection); -}//AbsoCH4() -//__________________________________________________________________________________________________sss -void AliRICHParam::CdbRead(Int_t run,Int_t version) -{ -// This methode read all the calibration information and initialise corresponding fields for requested run number -// Arguments: run - run number for which to retrieve calibration -// version- version number -// Returns: none - - AliCDBEntry *pEntry=AliCDBManager::Instance()->Get("RICH/RICHConfig/RefIdxC6F14",run,0,version); //try to get from common local storage - if(pEntry){ - fIdxC6F14=(TF2*)pEntry->GetObject(); - if(!(AliCDBManager::Instance()->GetCacheFlag())) delete pEntry; - }else{ - AliWarning("No valid calibarion, the hardcoded will be used!"); - fIdxC6F14=new TF2("RidxC4F14","sqrt(1+0.554*(1239.84e-9/x)^2/((1239.84e-9/x)^2-5796)-0.0005*(y-20))",5.5e-9,8.5e-9,0,50); //DiMauro mail - fIdxC6F14->SetUniqueID(20);//T=20 deg C - } -}//CdbRead() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHParam::Print(Option_t* opt) const { // print some usefull (hopefully) info on some internal guts of RICH parametrisation - Printf("Pads in chamber (%3i,%3i) in sector (%2i,%2i) pad size (%4.2f,%4.2f)",NpadsX(),NpadsY(),NpadsXsec(),NpadsYsec(),PadSizeX(),PadSizeY()); - for(Int_t i=0;iPrint(opt); + for(Int_t i=0;i<7;i++) fM[i]->Print(opt); }//Print() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHParam::TestSeg() -{ -// Provides a set of pictures to test segementation currently in use. -// Arguments: none -// Returns: none - new TCanvas("pads","View from electronics side, IP is behind the picture."); - gPad->Range(-5,-5,PcSizeX()+5,PcSizeY()+5); -// list of corners: - DrawSectors(kTRUE); - TLatex t; - t.SetTextSize(0.02); - t.SetTextColor(kRed) ;t.SetTextAlign(11); t.DrawLatex(0 ,PcSizeY(),Form("Pad size %.2fx%.2fcm dead zone %.2fcm",PadSizeX(),PadSizeY(),DeadZone())); - t.SetTextColor(kBlue) ;t.SetTextAlign(21); t.DrawLatex(SecSizeX(),PcSizeY(),Form("Pc size %.2fx%.2fcm %ix%i pads" ,PcSizeX() ,PcSizeY() ,NpadsX() ,NpadsY())); - t.SetTextColor(kMagenta);t.SetTextAlign(31); t.DrawLatex(PcSizeX() ,PcSizeY(),Form("Sec size %.2fx%.2fcm %ix%i pads" ,SecSizeX(),SecSizeY(),NpadsXsec() ,NpadsYsec())); - - -// TVector p(2); TVector2 c; TVector2 b; //current: pad, pad center, pad boundary -// Double_t x0=0,x1=SecSizeX(),x2=SecSizeX()+DeadZone() ,x3=PcSizeX(); -// Double_t y0=0,y1=SecSizeY(),y2=SecSizeY()+DeadZone(),y3=2*SecSizeY()+DeadZone(),y4=PcSizeY()-SecSizeY(),y5=PcSizeY(); - t.SetTextSize(0.015); t.SetTextColor(kBlue); - -// b.Set(x0,y0);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x0,y1);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x0,y2);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x0,y3);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x0,y4);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x0,y5);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// -// b.Set(x1,y0);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x1,y1);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x1,y2);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x1,y3);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x1,y4);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x1,y5);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// -// b.Set(x2,y0);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x2,y1);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x2,y2);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x2,y3);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x2,y4);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(11);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x2,y5);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(13);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// -// b.Set(x3,y0);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x3,y1);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x3,y2);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x3,y3);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x3,y4);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(31);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); -// b.Set(x3,y5);p=Loc2Pad(b);c=Pad2Loc(p);t.SetTextAlign(33);t.DrawText(c.X(),c.Y(),Form("(%.2f,%.2f)-(%.0f,%.0f)-(%.2f,%.2f)",b.X(),b.Y(),p(0),p(1),c.X(),c.Y())); - -//Now all chambers view - TCanvas *pC=new TCanvas("cc","Chambers view from electronics side - IP is behind the picture"); pC->Divide(3,3); - t.SetTextSize(0.05); - for(Int_t i=1;i<=7;i++){ - if(i==1) pC->cd(9); if(i==2) pC->cd(8); if(i==3) pC->cd(6); if(i==4) pC->cd(5); if(i==5) pC->cd(4); if(i==6) pC->cd(2); if(i==7) pC->cd(1); - gPad->Range(-5,-5,PcSizeX()+5,PcSizeY()+10); - DrawSectors(kTRUE); - t.SetTextColor(kBlack); t.SetTextAlign(21); t.DrawText(SecSizeX(),PcSizeY(),Form("Cham %i",i)); - t.SetTextColor(41); t.SetTextAlign(11); t.DrawText(0 ,PcSizeY(),Form("DDL ID %i",1536+2*i-2)); //left half of chamber - t.SetTextColor(29); t.SetTextAlign(31); t.DrawText(PcSizeX() ,PcSizeY(),Form("DDL ID %i",1536+2*i-1)); //right half of chamber - } -}//TestSeg() -//__________________________________________________________________________________________________ -void AliRICHParam::TestResp() -{ -// Provides a set of plot to check the response parametrisation currently in use. -// Arguments: none -// Returns: none - TCanvas *pC=new TCanvas("c","Amplification test",900,800); - pC->Divide(1,2); - - - const Int_t kNpoints=8; - THStack *pStackPhot=new THStack("StackPhot","photons"); - THStack *pStackMip =new THStack("StackMip","mips"); - TLegend *pLeg=new TLegend(0.6,0.2,0.9,0.5,"legend"); - TH1F *apHphot[kNpoints]; - TH1F *apHmip[kNpoints]; - - Double_t starty=0; - Double_t deltay=AliRICHParam::SecSizeY()/kNpoints; - - for(int i=0;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-SecSizeY()/2)); - } - - - TVector2 x2(0,0); - for(Int_t i=0;i<10000;i++){//events loop - for(int j=0;jFill(TotQdc(x2,0)); - apHmip[j]->Fill(TotQdc(x2,gRandom->Landau(600,150)*1e-9)); - } - } - - pC->cd(1); pStackMip->Draw("nostack"); - pC->cd(2); pStackPhot->Draw("nostack"); pLeg->Draw(); -}//TestResp() -//__________________________________________________________________________________________________ -void AliRICHParam::TestTrans() -{ -// Tests transformation methods -// Arguments: none -// Returns: none - - AliRICHParam *pParam=AliRICHParam::Instance(); - Int_t iNpointsX=50,iNpointsY=50; - new TCanvas("trasform","Test LORS-MARS transform"); TLatex t; t.SetTextSize(0.02); - - TView *pView=new TView(1); pView->SetRange(-400,-400,-400,400,400,400); - DrawAxis(); - for(Int_t iCham=1;iCham<=7;iCham++){//chamber loop - AliRICHHelix helix(2.5,Norm(iCham).Theta()*TMath::RadToDeg(),Norm(iCham).Phi()*TMath::RadToDeg()); - helix.RichIntersect(AliRICHParam::Instance()); - TPolyMarker3D *pChamber=new TPolyMarker3D(iNpointsX*iNpointsY); - Int_t i=0; - for(Double_t x=0;xLors2Mars(iCham,x,y,kPc); TVector2 v2=pParam->Mars2Lors(iCham,v3,kPc);//LORS->MARS->LORS - Double_t dx=v2.X()-x , dy=v2.Y()-y; - if(dx>0.000001 || dy>0.000001) Printf("Problem in MARS<->LORS transformations dx=%f dy=%f!!!",dx,dy); - pChamber->SetPoint(i++,v3.X(),v3.Y(),v3.Z());//Pc plane point in MARS - }//step loop - pChamber->SetMarkerSize(1); - pChamber->SetMarkerColor(iCham); - pChamber->Draw(); - helix.Draw(); - t.SetNDC();t.SetTextColor(iCham); t.DrawText(0.1,iCham*0.1,Form("Chamber %i",iCham)); - }//chambers loop -}//TestTrans() -//__________________________________________________________________________________________________ -void AliRICHParam::DrawAxis() -{ -// This utility methode draws axis on geometry scene -// Arguments: none -// Returns: none - Double_t x[6]={0,0,0,300,0,0}; Double_t y[6]={0,0,0,0,300,0}; Double_t z[6]={0,0,0,0,0,300}; - TPolyLine3D *pXaxis=new TPolyLine3D(2,x);pXaxis->SetLineColor(kRed); pXaxis->Draw(); - TPolyLine3D *pYaxis=new TPolyLine3D(2,y);pYaxis->SetLineColor(kGreen); pYaxis->Draw(); - TPolyLine3D *pZaxis=new TPolyLine3D(2,z);pZaxis->SetLineColor(kBlue); pZaxis->Draw(); -} -//__________________________________________________________________________________________________ -void AliRICHParam::DrawSectors(Bool_t isInfo) -{ -// Utility methode draws RICH chamber sectors on event display. -// Arguments: none -// Returns: none - Double_t xLeft[5] = {0,0,SecSizeX(),SecSizeX(),0}; - Double_t xRight[5] = {SecSizeX()+DeadZone(),SecSizeX()+DeadZone(),PcSizeX(),PcSizeX(),SecSizeX()+DeadZone()}; - - Double_t yDown[5] = {0,SecSizeY(),SecSizeY(),0,0}; - Double_t yCenter[5] = { SecSizeY()+DeadZone(),2*SecSizeY()+DeadZone(),2*SecSizeY()+DeadZone(), - SecSizeY()+DeadZone(),SecSizeY()+DeadZone()}; - Double_t yUp[5] = {2*SecSizeY()+2*DeadZone(),PcSizeY(),PcSizeY(),2*SecSizeY()+2*DeadZone(),2*SecSizeY()+2*DeadZone()}; - - Int_t iColorLeft=29,iColorRight=41; - TPolyLine *sec[6]; - - sec[0]= new TPolyLine(5,xLeft ,yDown); - sec[1]= new TPolyLine(5,xRight,yDown); - sec[2]= new TPolyLine(5,xLeft ,yCenter); - sec[3]= new TPolyLine(5,xRight,yCenter); - sec[4]= new TPolyLine(5,xLeft, yUp); - sec[5]= new TPolyLine(5,xRight,yUp); - - for(Int_t iSec=0;iSec<6;iSec++){ - if(isInfo){ - (iSec%2)? sec[iSec]->SetFillColor(iColorLeft): sec[iSec]->SetFillColor(iColorRight); - sec[iSec]->Draw("f"); - }else - sec[iSec]->Draw(); - } - - if(!isInfo) return; - - TText t; t.SetTextSize(0.02); - t.DrawText(32,20,"Sec 1"); - t.DrawText(98,20,"Sec 2"); - t.DrawText(32,65,"Sec 3"); - t.DrawText(98,65,"Sec 4"); - t.DrawText(32,106,"Sec 5"); - t.DrawText(98,106,"Sec 6"); - - Double_t x246=SecSizeX()+DeadZone(); - Double_t y34=SecSizeY()+DeadZone(); - Double_t y56=2*y34; - - for(Int_t iRow=1;iRow<=8;iRow++){//dilogic chip serves 8x6 pads - Double_t y=(iRow-1)*6*PadSizeY(); - TLine *pL1=new TLine(0 ,y ,SecSizeX(),y ); pL1->Draw(); t.SetTextAlign(31); t.DrawText(0 ,y ,Form("r%i",iRow) );//sec1 - TLine *pL2=new TLine(x246,y ,PcSizeX() ,y ); pL2->Draw(); t.SetTextAlign(11); t.DrawText(PcSizeX(),y ,Form("r%i",25-iRow));//sec2 - - TLine *pL3=new TLine(0 ,y+y34,SecSizeX(),y+y34); pL3->Draw(); t.SetTextAlign(31); t.DrawText(0 ,y+y34,Form("r%i",iRow+8) );//sec3 - TLine *pL4=new TLine(x246,y+y34,PcSizeX() ,y+y34); pL4->Draw(); t.SetTextAlign(11); t.DrawText(PcSizeX(),y+y34,Form("r%i",17-iRow));//sec4 - - TLine *pL5=new TLine(0 ,y+y56,SecSizeX(),y+y56); pL5->Draw(); t.SetTextAlign(31); t.DrawText(0 ,y+y56,Form("r%i",iRow+16));//sec5 - TLine *pL6=new TLine(x246,y+y56,PcSizeX() ,y+y56); pL6->Draw(); t.SetTextAlign(11); t.DrawText(PcSizeX(),y+y56,Form("r%i",9-iRow) );//sec4 - } - - for(Int_t iDilogic=1;iDilogic<=10;iDilogic++){ - Double_t x=(iDilogic-1)*8*PadSizeX(); - TLine *pL1=new TLine(x ,0,x ,SecSizeY()); pL1->Draw(); t.DrawText(x ,0,Form("d%i",11-iDilogic)); - TLine *pL2=new TLine(x+x246,0,x+x246,SecSizeY()); pL2->Draw(); t.DrawText(x+x246,0,Form("d%i",11-iDilogic)); - - TLine *pL3=new TLine(x ,y34,x ,y34+SecSizeY()); pL3->Draw(); t.DrawText(x ,y34,Form("d%i",11-iDilogic)); - TLine *pL4=new TLine(x+x246,y34,x+x246,y34+SecSizeY()); pL4->Draw(); t.DrawText(x+x246,y34,Form("d%i",11-iDilogic)); - - TLine *pL5=new TLine(x ,y56,x ,y56+SecSizeY()); pL5->Draw(); t.DrawText(x ,y56,Form("d%i",11-iDilogic)); - TLine *pL6=new TLine(x+x246,y56,x+x246,y56+SecSizeY()); pL6->Draw(); t.DrawText(x+x246,y56,Form("d%i",11-iDilogic)); - } - - t.SetTextAlign(13); t.DrawText(0 ,0,"pad1"); t.DrawText(x246 ,0,"pad81"); - t.SetTextAlign(33); t.DrawText(SecSizeX(),0,"pad80"); t.DrawText(PcSizeX(),0,"pad160"); -}//DrawSectors() -//__________________________________________________________________________________________________ -TVector3 AliRICHParam::ForwardTracing(TVector3 entranceTrackPoint, TVector3 vectorTrack, Double_t thetaC, Double_t phiC) -{ -// Trace a single Ckov photon from a given emission point up to photocathode taking into account ref indexes of materials it travereses - TVector3 vBad(-999,-999,-999); - TVector3 nPlane(0,0,1); - Double_t planeZposition = 0.5*RadThick(); - TVector3 planePoint(0,0,0.5*RadThick()); //this is plane parallel to window which contains emission point - TVector3 emissionPoint = PlaneIntersect(vectorTrack,entranceTrackPoint,nPlane,planePoint); - Double_t thetaout,phiout; - AnglesInDRS(vectorTrack.Theta(),vectorTrack.Phi(),thetaC,phiC,thetaout,phiout); - TVector3 vectorPhotonInC6F14; - vectorPhotonInC6F14.SetMagThetaPhi(1,thetaout,phiout); - planeZposition=RadThick(); - planePoint.SetXYZ(0,0,planeZposition); - TVector3 entranceToSiO2Point = PlaneIntersect(vectorPhotonInC6F14,emissionPoint,nPlane,planePoint); - - Double_t photonEn = EckovMean(); - Double_t angleInSiO2 = SnellAngle(IdxC6F14(EckovMean()),IdxSiO2(EckovMean()),vectorPhotonInC6F14.Theta());if(angleInSiO2<0) return vBad; - TVector3 vectorPhotonInSiO2; - vectorPhotonInSiO2.SetMagThetaPhi(1,angleInSiO2,phiout); -// planeZposition+=AliRICHParam::SiO2Thickness(); - planeZposition+=WinThick(); - planePoint.SetXYZ(0,0,planeZposition); - TVector3 entranceToCH4 = PlaneIntersect(vectorPhotonInSiO2,entranceToSiO2Point,nPlane,planePoint); -// entranceToCH4.Dump(); - - // Double_t angleInCH4 = SnellAngle(AliRICHParam::IndOfRefSiO2(6.755),AliRICHParam::IndOfRefCH4,angleInSiO2); - Double_t angleInCH4 = SnellAngle(IdxSiO2(photonEn),IdxCH4(photonEn),vectorPhotonInSiO2.Theta());if(angleInCH4<0) return vBad; - TVector3 vectorPhotonInCH4; - vectorPhotonInCH4.SetMagThetaPhi(1,angleInCH4,phiout); -// planeZposition+=AliRICHParam::GapProx(); - planeZposition+=Pc2Win(); - planePoint.SetXYZ(0,0,planeZposition); - TVector3 impactToPC = PlaneIntersect(vectorPhotonInCH4,entranceToCH4,nPlane,planePoint); -// impactToPC.Dump(); - return impactToPC; -}//FowardTracing -//__________________________________________________________________________________________________ -TVector3 AliRICHParam::PlaneIntersect(const TVector3 &lineDir,const TVector3 &linePoint,const TVector3 &planeNorm,const TVector3 &planePoint) -{ -// Finds an intersection point between a line and plane. -// Arguments: lineDir,linePoint - vector along the line and any point of the line -// planeNorm,planePoint - vector normal to the plane and any point of the plane -// Returns: point of intersection if any - if(planeNorm*lineDir==0) return TVector3(-999,-999,-999); - TVector3 diff=planePoint-linePoint; - Double_t sint=(planeNorm*diff)/(planeNorm*lineDir); - return linePoint+sint*lineDir; -}//PlaneIntersect -//__________________________________________________________________________________________________ -Double_t AliRICHParam::SnellAngle(Float_t n1, Float_t n2, Float_t theta1) -{ -// Compute the angle of refraction out of Snell law -// Arguments: n1 - ref idx of first substance -// n2 - ref idx of second substance -// n1 - photon impact angle in the first substance i.e. angle between the photon direction and vector normal to the surface (radians) -// Returns: photon refraction angle, i.e. angle in the second substance (radians) - Double_t sinref=(n1/n2)*TMath::Sin(theta1); - if(sinref>1.) return -999; - else return TMath::ASin(sinref); -}//SnellAngle -//__________________________________________________________________________________________________ -void AliRICHParam::AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t thetaCerenkov,Double_t phiCerenkov,Double_t &tout,Double_t &pout) -{ -// Setup the rotation matrix of the track... - - TRotation mtheta; - TRotation mphi; - TRotation minv; - TRotation mrot; - - mtheta.RotateY(trackTheta); - mphi.RotateZ(trackPhi); - - mrot = mphi * mtheta; - // minv = mrot.Inverse(); - - TVector3 photonInRadiator(1,1,1); - - photonInRadiator.SetTheta(thetaCerenkov); - photonInRadiator.SetPhi(phiCerenkov); - photonInRadiator = mrot * photonInRadiator; - tout=photonInRadiator.Theta(); - pout=photonInRadiator.Phi(); -}//AnglesInDRS -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHParam::TestHit2SDigs(Double_t x,Double_t y,Double_t e,Bool_t isNew) -{ -//Test hit->sdigits procedures -//Arguments: isNew - if true use new (abs pad) procedure else use old one (TVector) -// Returns: none - TClonesArray *pSDigLst=new TClonesArray("AliRICHDigit"); - Int_t iQtot=-1; - if(isNew){ - iQtot=Hit2SDigs(10101,e,pSDigLst); //new technique - }else{ - iQtot=Hit2SDigs(TVector2(x,y),e,pSDigLst);//old technique - } - pSDigLst->Print(); - Double_t dQsum=0; - for(Int_t i=0;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 diff --git a/RICH/AliRICHParam.h b/RICH/AliRICHParam.h index 3cab5b40666..8af9dbb2df7 100644 --- a/RICH/AliRICHParam.h +++ b/RICH/AliRICHParam.h @@ -1,26 +1,10 @@ #ifndef AliRICHParam_h #define AliRICHParam_h -#include //base class -#include //QdcTot() -#include //old style -#include -#include -#include //---------to be deleted------------- -#include -#include //Hit2SDigs() -#include -#include //Mars2Lors() Lors2Mars() -#include //fields -#include //fields -#include "AliRICHDigit.h" //Hit2Sdigs() +#include //base class #include //Instance() - -static const int kNchambers=7; //number of RICH chambers -static const int kNpadsX = 160; //number of pads along X in single chamber -static const int kNpadsY = 144; //number of pads along Y in single chamber -static const int kNsectors=6; //number of sectors per chamber - +#include //Lors2Mars() Mars2Lors() + static const int kCerenkov=50000050; //??? go to something more general like TPDGCode static const int kFeedback=50000051; //??? go to something more general like TPDGCode @@ -28,672 +12,46 @@ static const int kFeedback=50000051; //??? go to something more general like TP // to construct the geometry, to define segmentation and to provide response model // In future will also provide all the staff needed for alignment and calibration - class AliRICHParam :public TNamed { public: //ctor&dtor - virtual ~AliRICHParam() {delete fIdxC6F14;fgInstance=0;} -//test methodes + virtual ~AliRICHParam() {for(Int_t i=0;i<7;i++) delete fM[i]; delete fgInstance; fgInstance=0;} void Print(Option_t *opt="") const; //print current parametrization - static void DrawAxis(); - static void DrawSectors(Bool_t isInfo=kFALSE); //draw sectors contour and print on top some info -//flags staff static inline AliRICHParam* Instance(); //pointer to AliRICHParam singleton + + Double_t MeanIdxRad () {return 1.29204;}//??????????? + Double_t MeanIdxWin () {return 1.57819;}//??????????? static Int_t Stack(Int_t evt=-1,Int_t tid=-1); //Print stack info for event and tid static Int_t StackCount(Int_t pid,Int_t evt); //Counts stack particles of given sort in given event - static inline Double_t ErrLoc (Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta); - static inline Double_t ErrGeom (Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta); - static inline Double_t ErrCrom (Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta); - static inline Double_t SigmaSinglePhotonFormula(Double_t thetaC,Double_t phiC,Double_t thetaT,Double_t phiT,Double_t beta); -//Geometrical properties - static Int_t NpadsX () {return kNpadsX;} //number of pads along X in chamber - static Int_t NpadsY () {return kNpadsY;} //number of pads along Y in chamber - static Int_t NpadsXsec () {return NpadsX()/2;} //number of pads along X in sector - static Int_t NpadsYsec () {return NpadsY()/3;} //number of pads along Y in sector - - static Double_t AnodPitch () {return PadSizeY()/2;} //cm between anode wires - static Double_t AnodZ () {return 7.806;} //Z positon of anod plane in LORS of the chamber, [cm] - static Double_t CathPitch () {return PadSizeY()/4;} //dist between cathode wires [cm] - static Double_t CollPitch () {return 0.5;} //dist between collection wires [cm] - static Double_t DeadZone () {return 2.6;} //dead zone thickness [cm] - static Double_t PadSizeX () {return 0.8;} //pad size x [cm] - static Double_t PadSizeY () {return 0.84;} //pad size y [cm] - static Double_t PcSizeX () {return NpadsX()*PadSizeX()+DeadZone();} //PC size x [cm] - static Double_t PcSizeY () {return NpadsY()*PadSizeY()+2*DeadZone();} //PC size y [cm] - static Double_t Pc2Cath () {return 0.445;} //dist between PC entrance plane and cathode wires plane [cm] - static Double_t Pc2Win () {return PcZ();} //dist between PC entrance plane and window exit plane [cm] - static Double_t PcZ () {return 8.0; } //Z positon of PC entrance plane in LORS of the chamber [cm] - static Double_t RadThick () {return 1.5;} //radiator thickness [cm] - static Double_t RadZ () {return -2.0; } //Z positon of radiator entrance plane in LORS of the chamber [cm] - static Double_t SecSizeX () {return NpadsX()*PadSizeX()/2;} //sector size x [cm] - static Double_t SecSizeY () {return NpadsY()*PadSizeY()/3;} //sector size y [cm ] - static Double_t WinThick () {return 0.5;} //radiator window thickness [cm] - - //trasformation methodes - inline TVector3 Lors2Mars (Int_t c,Double_t x,Double_t y,Int_t p=kPc); //LORS->MARS transform of point [cm] for chamber c and plane p - inline TVector3 Lors2MarsVec (Int_t c,const TVector3 &p ); //LORS->MARS transform of vector for chamber c - inline TVector2 Mars2Lors (Int_t c,const TVector3 &x ,Int_t p=kPc); //MARS->LORS transform of point [cm] for chamber c and plane p - inline TVector3 Mars2LorsVec (Int_t c,const TVector3 &p ); //MARS->LORS transform of vector for chamber c - - static inline TVector3 Lors2MarsOld (Int_t c,Double_t x,Double_t y,Int_t p); //LORS->MARS transform of position (cm) for chamber c and plane p - static inline TVector2 Mars2LorsOld (Int_t c,const TVector3 &x,Int_t p ); //MARS->LORS transform of position (cm) for chamber c and plane p - static inline TVector3 Center (Int_t c,Int_t p ); //Center of plane p of chamber c in MARS (cm) - static inline TVector3 Norm (Int_t c ); //Norm vector to the chamber c in MARS (cm) - static inline TGeoMatrix*Matrix (Int_t iCh, Int_t iPlane ); //TGeoMatrix for the given chamber plain - - static Int_t Pad2Cha (Int_t pad ){return pad/100000000; }//abs pad -> chamber - static Int_t Pad2Sec (Int_t pad ){return pad%100000000/1000000; }//abs pad -> sector - static Int_t Pad2PadX (Int_t pad ){return pad%1000000/1000; }//abs pad -> pad x - static Int_t Pad2PadY (Int_t pad ){return pad%1000000%100; }//abs pad -> pad y - static Int_t PadAbs (Int_t c,Int_t s,Int_t x,Int_t y){return 100000000*c+1000000*s+1000*x+y; }//(c,s,x,y) -> abs pad - static inline TVector2 Pad2Loc (Int_t pad ); //abs pad ->LORS - static inline TVector2 Pad2Loc (TVector pad ); //pad -> LORS returns center of the pad - static TVector2 Pad2Loc (Int_t x,Int_t y ){TVector pad(2);pad[0]=x;pad[1]=y;return Pad2Loc(pad);}//return center of the pad (x,y) - static inline TVector Loc2Area (const TVector2 &x2 ); //pads area affected by hit x2. area is LeftDown-RightUp pad numbers - static inline Int_t Loc2Sec (const TVector2 &x2 ); //LORS -> sector - static Int_t Loc2Sec (Double_t x,Double_t y ){return Loc2Sec(TVector2(x,y));} //LORS -> sector - static inline TVector Loc2Pad (const TVector2 &x2 ); //LORS -> pad - static TVector Loc2Pad (Double_t x,Double_t y ){return Loc2Pad(TVector2(x,y));} //LORS -> pad - static inline Int_t Pad2Sec (const TVector &pad ); //pad -> sector - static inline Int_t PadNeighbours (Int_t iPadX,Int_t iPadY,Int_t aListX[4],Int_t aListY[4]); //pad -> list of it neighbours - static Bool_t IsAccepted (const TVector2 &x2 ){return ( x2.X()>=0 && x2.X()<=PcSizeX() && x2.Y()>=0 && x2.Y()<=PcSizeY() ) ? kTRUE:kFALSE;} -//optical properties methodes - static Float_t EckovMean ( ){return 6.766e-9;} //mean Ckov energy according to the total trasmission curve - static Float_t EckovMin ( ){return 5.5e-9;} //min photon energy [GeV] defined in optical curves - static Float_t EckovMax ( ){return 8.5e-9;} //min photon energy [GeV] defined in optical curves - - Float_t IdxC6F14 (Float_t gev ){return fIdxC6F14->Eval(gev,fIdxC6F14->GetUniqueID());} //n=f(Eckov) [GeV] for C6H14 used as radiator - static Float_t IdxSiO2 (Float_t gev ){return TMath::Sqrt(1+46.411/(10.666*10.666-gev*gev*1e18)+228.71/(18.125*18.125-gev*gev*1e18));} //n=f(Eckov) [GeV] for SiO2 used as window TDR p.35 - static Float_t IdxCH4 (Float_t gev ){return 1+0.12489e-6/(2.62e-4 - TMath::Power(1239.84e-9/gev,-2));} //n=f(Eckov) [GeV] for CF4 - static Float_t AbsCH4 (Float_t gev ); //abs len=f(Eckov) [GeV] for CF4 - - void CdbRead (Int_t run,Int_t version ); //read all calibration information for requested run - - static Double_t IonisationPotential() {return 26.0e-9;} //for CH4 in GeV taken from ???? - static TVector2 MathiesonDelta() {return TVector2(5*0.18,5*0.18);} //area of 5 sigmas of Mathieson distribution (cm) - static Int_t MaxQdc() {return 4095;} //QDC number of channels - - - static Int_t QthMIP() {return 100;} - static Double_t DmatchMIP() {return 1.;} - static Double_t PmodMax() {return 6.5;} - static Int_t HV(Int_t sector) {if (sector>=1 && sector <=6) return 2050; else return -1;} //high voltage for this sector -//charge response methodes - inline static Double_t Mathieson(Double_t x1,Double_t x2,Double_t y1,Double_t y2); //Mathienson integral over given limits - - inline static Double_t GainSag(Double_t x,Int_t sector); //gain variations in % - static Double_t Gain(const TVector2 &x2,Bool_t isSag=kTRUE){//gives chamber gain in terms of QDC channels for given point in local ref system - if(isSag) return QdcSlope(Loc2Sec(x2))*(1+GainSag(x2.X(),Loc2Sec(x2))/100); - else return QdcSlope(Loc2Sec(x2));} - inline static Double_t FracQdc(const TVector2 &x2,const TVector &pad); //charge fraction to pad from hit - inline static Int_t TotQdc(TVector2 x2,Double_t e ); //total charge for Eloss (GeV) 0 for photons - static Double_t QdcSlope(Int_t sec){switch(sec){case -1: return 0; default: return 33;}} //weight of electon in QDC channels - - static inline Int_t Lors2Pad (Double_t x,Double_t y ); //LORS (x,y) [cm] -> abs pad number - static Double_t IonPot ( ){return 26.0e-9;} //for CH4 in GeV taken from ???? - static inline Int_t QdcTot (Int_t iPad,Double_t e ); //total QDC generated by Eloss or Etot [GeV] - static inline Double_t QdcSag (Int_t iPad ); //mean QDC variation due to sagita [0,1] - static Double_t QdcEle (Int_t iPad,Bool_t isSag=kTRUE ){return isSag?33*(1+QdcSag(iPad)):33;} //mean QDC per electron - static inline Int_t Hit2SDigs (Int_t iPad, Double_t e,TClonesArray* pSDigLst); //hit->sdigits, returns Qtot - static inline Int_t Hit2SDigs (TVector2 hit,Double_t e,TClonesArray* pSDigLst); //hit->sdigits, returns Qtot, old style - static void TestHit2SDigs (Double_t x,Double_t y,Double_t e,Bool_t isNew=kFALSE); //test hit->sdigits - - inline static Bool_t IsOverTh(Int_t c,TVector pad,Double_t q); //is QDC of the pad registered by FEE - static Int_t NsigmaTh() {return 4;} // - static Float_t SigmaThMean() {return 1.132;} //QDC electronic noise mean - static Float_t SigmaThSpread() {return 0.035;} //QDC electronic noise width - - static Double_t CogCorr(Double_t x) {return 3.31267e-2*TMath::Sin(2*TMath::Pi()/PadSizeX()*x) //correction of cluster CoG due to sinoidal - -2.66575e-3*TMath::Sin(4*TMath::Pi()/PadSizeX()*x) - +2.80553e-3*TMath::Sin(6*TMath::Pi()/PadSizeX()*x)+0.0070;} - - TVector3 ForwardTracing(TVector3 entranceTrackPoint,TVector3 vectorTrack, Double_t thetaC, Double_t phiC); //it traces foward a photon from Emission Point to PC - static TVector3 PlaneIntersect(const TVector3 &lineDir,const TVector3 &linePoint,const TVector3 &planeNorm,const TVector3 &planePoint); //intersection between line and plane - static Double_t SnellAngle(Float_t n1, Float_t n2, Float_t theta1); // Snell law - static void AnglesInDRS(Double_t trackTheta,Double_t trackPhi,Double_t thetaCerenkov,Double_t phiCerenkov,Double_t &tout,Double_t &pout);//It finds photon angles in - static Double_t AlphaFeedback(Int_t c,Int_t s) {c++;s++; return 0.02;} //for sector s of chamber c -//test part - static void Test() {TestSeg();TestTrans();TestResp();} //test all groups of methodes - static void TestResp(); //test the response group of methodes - static void TestSeg(); //test the segmentation group of methodes - static void TestTrans(); //test the transform group of methodes - - enum EPlaneId {kCenter,kPc,kRad,kAnod,kNch=7}; //4 planes in chamber and total number of chambers + void Lors2Mars (Int_t c,Float_t x,Float_t y,Double_t *m,Int_t pl=kPc)const{Double_t z=0; switch(pl){case kPc:z=8.0;break; case kAnod:z=7.806;break; case kRad:z=-1.25; break;} Double_t l[3]={x-fX,y-fY,z}; fM[c]->LocalToMaster(l,m); } + TVector3 Lors2Mars (Int_t c,Float_t x,Float_t y, Int_t pl=kPc)const{Double_t m[3];Lors2Mars(c,x,y,m,pl); return TVector3(m); }//MRS->LRS + void Mars2Lors (Int_t c,Double_t *m,Float_t &x,Float_t &y )const{Double_t l[3];fM[c]->MasterToLocal(m,l);x=l[0]+fX;y=l[1]+fY;}//MRS->LRS + void Mars2LorsVec(Int_t c,Double_t *m,Float_t &th,Float_t &ph )const{Double_t l[3]; fM[c]->MasterToLocalVect(m,l); Float_t pt=TMath::Sqrt(l[0]*l[0]+l[1]*l[1]); th=TMath::ATan(l[3]/pt); ph=TMath::ATan(l[0]/pt);} + TVector3 Norm (Int_t c )const{Double_t n[3]; Norm(c,n); return TVector3(n); }//norm + void Norm (Int_t c,Double_t *n )const{Double_t l[3]={0,0,1};fM[c]->LocalToMasterVect(l,n); }//norm + + enum EPlaneId {kPc,kRad,kAnod}; //3 planes in chamber protected: AliRICHParam(); //default ctor is protected to enforce it to be singleton static AliRICHParam *fgInstance; //static pointer to instance of AliRICHParam singleton - TF2 *fIdxC6F14; //n=f(Ephot,T) [GeV] for radiator freon C6F14 - TGeoHMatrix *fMatrix[kNchambers]; //poiners to matrices defining RICH chambers rotations-translations + TGeoHMatrix *fM[7]; //poiners to matrices defining RICH chambers rotations-translations + Float_t fX; //x shift of LORS with respect to rotated MARS + Float_t fY; //y shift of LORS with respect to rotated MARS ClassDef(AliRICHParam,0) //RICH main parameters class }; - +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AliRICHParam* AliRICHParam::Instance() { // Return pointer to the AliRICHParam singleton. // Arguments: none // Returns: pointer to the instance of AliRICHParam or 0 if no geometry - if(!fgInstance&&gGeoManager) new AliRICHParam; - else if(!gGeoManager) Printf("No geometry imported"); + if(!fgInstance) + if(gGeoManager) new AliRICHParam; + else Printf("AliRICHParam> Error:: No geometry defined!"); return fgInstance; }//Instance() -//__________________________________________________________________________________________________ -Int_t AliRICHParam::PadNeighbours(Int_t iPadX,Int_t iPadY,Int_t listX[4],Int_t listY[4]) -{ -//Determines all the neighbouring pads for the given one (iPadX,iPadY). Returns total number of these pads. -//Dead zones are taken into account, meaning pads from different sector are not taken. -// 1 -// 2 3 -// 4 - Int_t nPads=0; - if(iPadY!=NpadsY()&&iPadY!=2*NpadsYsec()&&iPadY!=NpadsYsec()){listX[nPads]=iPadX; listY[nPads]=iPadY+1; nPads++;} //1 - if(iPadX!=1&&iPadX!=NpadsXsec()+1) {listX[nPads]=iPadX-1; listY[nPads]=iPadY; nPads++;} //2 - if(iPadX!=NpadsXsec()&&iPadX!=NpadsX()) {listX[nPads]=iPadX+1; listY[nPads]=iPadY; nPads++;} //3 - if(iPadY!=1&&iPadY!=NpadsYsec()+1&&2*NpadsYsec()+1) {listX[nPads]=iPadX; listY[nPads]=iPadY-1; nPads++;} //4 - - return nPads; -}//Pad2ClosePads() -//__________________________________________________________________________________________________ -Int_t AliRICHParam::Loc2Sec(const TVector2 &v2) -{ -// Determines sector containing the given point. y ^ 5 6 -// | 3 4 -// | 1 2 -// -------> x -// Arguments: v2- LORS position [cm] -// Returns: sector code - Double_t x0=0; Double_t x1=SecSizeX(); Double_t x2=SecSizeX()+DeadZone(); Double_t x3=PcSizeX(); - Double_t y0=0; Double_t y1=SecSizeY(); Double_t y2=SecSizeY()+DeadZone(); Double_t y3=2*SecSizeY()+DeadZone(); - Double_t y4=PcSizeY()-SecSizeY(); Double_t y5=PcSizeY(); - - Int_t sector=-1; - if (v2.X() >= x0 && v2.X() <= x1 ) sector=1; - else if(v2.X() >= x2 && v2.X() <= x3 ) sector=2; - else return -1; - - if (v2.Y() >= y0 && v2.Y() <= y1 ) ; //sectors 1 or 2 - else if(v2.Y() >= y2 && v2.Y() <= y3 ) sector+=2; //sectors 3 or 4 - else if(v2.Y() >= y4 && v2.Y() <= y5 ) sector+=4; //sectors 5 or 6 - else return -1; - return sector; -}//Loc2Sec(Double_t x, Double_t y) -//__________________________________________________________________________________________________ -TVector AliRICHParam::Loc2Pad(const TVector2 &loc) -{ -//Determines pad number TVector(padx,pady) containing the given point x2 defined in the chamber RS. -//Pad count starts in lower left corner from 1,1 to 144,160 in upper right corner of a chamber. -//y ^ 5 6 -// | 3 4 -// | 1 2 -// -------> x - TVector pad(2); - Int_t sec=Loc2Sec(loc);//trasforms x2 to sector reference system - if(sec==-1) {pad[0]=pad[1]=-1; return pad;} -//first we deal with x - if(sec==1||sec==3||sec==5) pad[0]= Int_t( loc.X() / PadSizeX() )+1; //sector 1 or 3 or 5 - else pad[0]=NpadsX() - Int_t( (PcSizeX()-loc.X()) / PadSizeX() ) ; //sector 2 or 4 or 6 -//second deal with y - if(sec==1||sec==2) pad[1]=Int_t( loc.Y() / PadSizeY())+1; //sector 1 or 2 - else if(sec==3||sec==4) pad[1]=Int_t( (loc.Y()-SecSizeY()-DeadZone()) / PadSizeY())+NpadsYsec()+1; //sector 3 or 4 - else pad[1]=NpadsY() - Int_t( (PcSizeY()-loc.Y()) / PadSizeY()); //sector 5 or 6 - return pad; -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Int_t AliRICHParam::Lors2Pad(Double_t x,Double_t y) -{ -// Determines abs pad number containing the given point (x,y) defined in the chamber RS. -// Pad count starts in lower left corner from 1,1 to 144,160 in upper right corner of a chamber. -// y ^ 5 6 -// | 3 4 -// | 1 2 -// -------> x - Int_t padx,pady; - if (x>= 0 && x<= SecSizeX() ) padx= 1 + Int_t( x /PadSizeX() ); //sector 1 or 3 or 5 - else if(x>=SecSizeX()+DeadZone() && x<= PcSizeX() ) padx= NpadsX() - Int_t( (PcSizeX()-x)/PadSizeX() ); //sector 2 or 4 or 6 - else return -1; //dead zone or out of chamber - - - if (y>= 0 && y<= SecSizeY() ) pady= 1 + Int_t( y /PadSizeY() ); //sector 1 or 2 - else if(y>=SecSizeY()+DeadZone() && y<=2*SecSizeY()+DeadZone() ) pady= 1 + NpadsYsec() + Int_t( (y-SecSizeY()-DeadZone()) / PadSizeY()); //sector 3 or 4 - else if(y>= PcSizeY()-SecSizeY() && y<= PcSizeY() ) pady= NpadsY() - Int_t( (PcSizeY()-y)/PadSizeY() ); //sector 5 or 6 - else return -1; //dead zone or out of chamber - - return AliRICHDigit::P2A(0,padx,pady); -}//Lors2Pad() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Int_t AliRICHParam::Pad2Sec(const TVector &pad) -{ -//Determines sector containing the given pad. - Int_t sector=-1; - if (pad[0] >= 1 && pad[0] <= NpadsXsec() ) {sector=1;} - else if(pad[0] > NpadsXsec() && pad[0] <= NpadsX() ) {sector=2;} - else AliDebugClass(1,Form("Wrong pad (%3.0f,%3.0f)",pad[0],pad[1])); - - if (pad[1] >= 1 && pad[1] <= NpadsYsec() ) {} - else if(pad[1] > NpadsYsec() && pad[1] <= 2*NpadsYsec() ) {sector+=2;} - else if(pad[1] > 2*NpadsYsec() && pad[1] <= NpadsY() ) {sector+=4;} - else AliDebugClass(1,Form("Wrong pad (%3.0f,%3.0f)",pad[0],pad[1])); - - return sector; -}//Pad2Sec() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector2 AliRICHParam::Pad2Loc(TVector pad) -{ -//Returns position of the center of the given pad in local system of the chamber (cm) -// y ^ 5 6 -// | 3 4 sector numbers -// | 1 2 -// -------> x - Double_t x=-1,y=-1; - if(pad[0] > 0 && pad[0] <= NpadsXsec())//it's 1 or 3 or 5 - x=(pad[0]-0.5)*PadSizeX(); - else if(pad[0] > NpadsXsec() && pad[0] <= NpadsX())//it's 2 or 4 or 6 - x=(pad[0]-0.5)*PadSizeX()+DeadZone(); - else - AliDebugClass(1,Form("Wrong pad (%3.0f,%3.0f)",pad[0],pad[1])); - - if(pad[1] > 0 && pad[1] <= NpadsYsec())//it's 1 or 2 - y=(pad[1]-0.5)*PadSizeY(); - else if(pad[1] > NpadsYsec() && pad[1] <= 2*NpadsYsec())//it's 3 or 4 - y=(pad[1]-0.5)*PadSizeY()+DeadZone(); - else if(pad[1] > 2*NpadsYsec() && pad[1]<= NpadsY())//it's 5 or 6 - y=(pad[1]-0.5)*PadSizeY()+2*DeadZone(); - else - AliDebugClass(1,Form("Wrong pad (%3.0f,%3.0f)",pad[0],pad[1])); - - return TVector2(x,y); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector2 AliRICHParam::Pad2Loc(Int_t pad) -{ -// Converts absolute pad number to local position in LORS -// LORS is a chamber reference system with origin in left-down coner looking from IP -// Arguments: pad- absolute pad number -// Returns: pad center position as TVector2 in PCRS - TVector2 pos; - pos.Set((Pad2PadX(pad)-0.5)*PadSizeX() , (Pad2PadY(pad)-0.5)*PadSizeY());//set to sector LORS - return pos; -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Double_t AliRICHParam::GainSag(Double_t x,Int_t sector) -{ -//Returns % of gain variation due to wire sagita. -//All curves are parametrized as per sector basis, so x must be apriory transformed to the Sector RS. -//Here x is a distance along wires. - x-=SecSizeX()/2; - if(x>SecSizeX()) x-=SecSizeX(); - switch(HV(sector)){ - case 2150: return 9e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0316*TMath::Power(x,2)-3e-4*x+25.367;//% - case 2100: return 8e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0283*TMath::Power(x,2)-2e-4*x+23.015; - case 2050: return 7e-6*TMath::Power(x,4)+1e-7*TMath::Power(x,3)-0.0254*TMath::Power(x,2)-2e-4*x+20.888; - case 2000: return 6e-6*TMath::Power(x,4)+8e-8*TMath::Power(x,3)-0.0227*TMath::Power(x,2)-1e-4*x+18.961; - default: return 0; - } -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Double_t AliRICHParam::QdcSag(Int_t iPad) -{ -// It was observed at BNL that wires are affected by gravitation field providing a significant sagita leading to the local electric field variation -// which means that different pads produce different signals. -// Arguments: iPad- absolute pad number -// Returns: gain variation due to wire sagita 0 < QdcSag < 1. -// Curves are parametrised in terms of distance x (cm) along wires having 0 on the left edge of the photocathode - Double_t x=AliRICHDigit::P2X(iPad)*PadSizeX()-0.5*PadSizeX(); //center of the padx (count from 1) - switch(HV(iPad)){ - case 2150: return 0.01*(9e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0316*TMath::Power(x,2)-3e-4*x+25.367);//function is a fit in % so multiply by 0.01 - case 2100: return 0.01*(8e-6*TMath::Power(x,4)+2e-7*TMath::Power(x,3)-0.0283*TMath::Power(x,2)-2e-4*x+23.015); - case 2050: return 0.01*(7e-6*TMath::Power(x,4)+1e-7*TMath::Power(x,3)-0.0254*TMath::Power(x,2)-2e-4*x+20.888); - case 2000: return 0.01*(6e-6*TMath::Power(x,4)+8e-8*TMath::Power(x,3)-0.0227*TMath::Power(x,2)-1e-4*x+18.961); - default: return 0; - } -}//QdcSag() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Int_t AliRICHParam::QdcTot(Int_t iPad,Double_t e) -{ -// Calculates the total charge produced by the hit. Method: -// 1. number of electrons is calculated as energy lost in amp gas divided by ionisation potential (for photon only one electron as Etot is always less then ionization potential) -// 2. each electron imposes a charge distributed as Poisson with QdcEle() mean. Different pads produce different means. See QdcEle(). -// Arguments: iPad- absolute pad number contaning the hit; -// e- Eloss for mip in amplification gas or Etot for photon -// Returns: charge parametrised in QDC channels. - Int_t iNele=Int_t(e/IonPot()); if(iNele==0) iNele=1;//e < ion. pot. means it's photoelectron - Double_t dQdc=0; - for(Int_t i=1;i<=iNele;i++) dQdc+=-QdcEle(iPad)*TMath::Log(gRandom->Rndm()+1e-6);//1e-6 is a protection against 0 from rndm - return Int_t(dQdc); -}//QdcTot() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Int_t AliRICHParam::TotQdc(TVector2 x2,Double_t eloss) -{ -//Calculates the total charge produced by the eloss in point x2 (Chamber RS). -//Returns this change parametrised in QDC channels, or 0 if the hit in the dead zone. -//eloss=0 means photon which produces 1 electron only eloss > 0 for Mip - if(Loc2Sec(x2)==-1) return 0; //hit in the dead zone - Int_t iNelectrons=Int_t(eloss/IonisationPotential()); if(iNelectrons==0) iNelectrons=1; - Double_t qdc=0; - for(Int_t i=1;i<=iNelectrons;i++) qdc+=-Gain(x2)*TMath::Log(gRandom->Rndm()+1e-06);//ie-06 is a protection against 0 from rndm - return Int_t(qdc); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Double_t AliRICHParam::FracQdc(const TVector2 &x2,const TVector &pad) -{ -//Calculates the charge fraction induced to given pad by the hit from the given point. -//Integrated Mathieson distribution is used. - TVector2 center2=Pad2Loc(pad);//gives center of requested pad - Double_t normXmin=(x2.X()-center2.X()-PadSizeX()/2) /Pc2Cath();//parametrise for Mathienson - Double_t normXmax=(x2.X()-center2.X()+PadSizeX()/2) /Pc2Cath(); - Double_t normYmin=(x2.Y()-center2.Y()-PadSizeY()/2) /Pc2Cath(); - Double_t normYmax=(x2.Y()-center2.Y()+PadSizeY()/2) /Pc2Cath(); - -//requested pad might not belong to the sector of the given hit position, hence the check: - return (Loc2Sec(x2)!=Pad2Sec(pad)) ? 0:Mathieson(normXmin, normYmin, normXmax, normYmax); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Double_t AliRICHParam::Mathieson(Double_t x1,Double_t y1,Double_t x2,Double_t y2) -{ -// This is the answer to electrostatic problem of charge distrubution in MWPC described elsewhere. (NIM A370(1988)602-603) -// Arguments: x1- diff between center of distribution which is a hit position and left edge of interested pad divided by anod-cathode distance -// x2- right edge of the pad -// y1- up edge of the pad -// y2- bottom edge of the pad -// Returns: a charge fraction [0-1] imposed into the pad - const Double_t kSqrtKx3=0.77459667;const Double_t kX2=0.962;const Double_t kX4=0.379; - const Double_t kSqrtKy3=0.77459667;const Double_t kY2=0.962;const Double_t kY4=0.379; - - Double_t ux1=kSqrtKx3*TMath::TanH(kX2*x1); - Double_t ux2=kSqrtKx3*TMath::TanH(kX2*x2); - Double_t uy1=kSqrtKy3*TMath::TanH(kY2*y1); - Double_t uy2=kSqrtKy3*TMath::TanH(kY2*y2); - return 4*kX4*(TMath::ATan(ux2)-TMath::ATan(ux1))*kY4*(TMath::ATan(uy2)-TMath::ATan(uy1)); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector AliRICHParam::Loc2Area(const TVector2 &x2) -{ -// Calculates the area of disintegration for a given point. It's assumed here that this points lays on anode wire. -// Area is a rectangulare set of pads defined by its left-down and right-up coners. - TVector area(4); - TVector pad=Loc2Pad(x2); - area[0]=area[2]=pad[0]; area[1]=area[3]=pad[1];//area is just a pad fired - if(pad[0]!=1 && pad[0]!= NpadsXsec()+1 ) area[0]--; //left down coner X - if(pad[1]!=1 && pad[1]!= NpadsYsec()+1 && pad[1]!= 2*NpadsYsec()+1) area[1]--; //left down coner Y - if(pad[0]!=NpadsXsec() && pad[0]!= NpadsX() ) area[2]++; //right up coner X - if(pad[1]!=NpadsYsec() && pad[1]!= 2*NpadsYsec() && pad[1]!= NpadsY() ) area[3]++; //right up coner Y - return area; -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Bool_t AliRICHParam::IsOverTh(Int_t ,TVector ,Double_t qdc) -{ -// Checks if the current QDC is over threshold and FEE will save this value to data concentrator. -// This is done on pad by pad level, so the pad pedestal map is to be used. ?????????????? -// Arguments: -// Returns: true if QDC over treshold - return (qdc>NsigmaTh()*(SigmaThMean()+(1.-2*gRandom->Rndm())*SigmaThSpread())); //??????????? to be change to real values -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TGeoMatrix* AliRICHParam::Matrix(Int_t iChamN,Int_t iPlane) -{ - TGeoHMatrix *pMatrix=new TGeoHMatrix; - - const Double_t kAngHor=19.5; // horizontal angle between chambers 19.5 grad - const Double_t kAngVer=20; // vertical angle between chambers 20 grad - const Double_t kAngCom=30; // common RICH rotation with respect to x axis 30 grad - - pMatrix->RotateY(90); //rotate around y since initial position is in XY plane -> now in YZ plane - Double_t trans[3]={490,0,0}; //center of the chamber is on window-gap surface - - switch(iPlane){ - case kCenter: break; - case kPc : trans[0]+=PcZ(); break; - case kRad : trans[0]+=RadZ(); break; - case kAnod : trans[0]+=AnodZ(); break; - default: return 0; break; - } - pMatrix->SetTranslation(trans); //now plane in YZ is shifted along x - - switch(iChamN){ - case 1: pMatrix->RotateY(kAngHor); pMatrix->RotateZ(-kAngVer); break; //right and down - case 2: pMatrix->RotateZ(-kAngVer); break; //down - case 3: pMatrix->RotateY(kAngHor); break; //right - case 4: break; //no rotation - case 5: pMatrix->RotateY(-kAngHor); break; //left - case 6: pMatrix->RotateZ(kAngVer); break; //up - case 7: pMatrix->RotateY(-kAngHor); pMatrix->RotateZ(kAngVer); break; //left and up - default: return 0; break; - }//switch(iChamber) - pMatrix->RotateZ(kAngCom); //apply common rotation in XY plane - return pMatrix; -}//Matrix() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector3 AliRICHParam::Lors2Mars(Int_t iChId,Double_t x,Double_t y,Int_t iPlnId) -{ -// Trasform from LORS to MARS -// Arguments: iChId - chamber code 1..7 -// x,y - point in LORS -// iPlnN - chamber plane code might be kPc kRad kCenter kAnod - Double_t z=0; - switch(iPlnId){ - case kPc : z=PcZ() ; break; - case kAnod : z=AnodZ(); break; - case kCenter: z=0 ; break; - case kRad : z=RadZ() ; break; - } - Double_t lors[3]={x-0.5*PcSizeX(),y-0.5*PcSizeY(),z}, mars[3]; - fMatrix[iChId-1]->LocalToMaster(lors,mars); - return TVector3(mars); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector3 AliRICHParam::Lors2MarsVec(Int_t iCh,const TVector3 &p) -{ - Double_t mars[3], lors[3]; p.GetXYZ(lors); - fMatrix[iCh-1]->LocalToMasterVect(lors,mars); - return TVector3(mars); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector2 AliRICHParam::Mars2Lors(Int_t iChId,const TVector3 &x,Int_t iPlnId) -{ -// Trasform from MARS to LORS -// Arguments: iChId - chamber code 1..7 -// mars - point in MARS -// iPlnN - chamber plane code might be kPc kRad kCenter kAnod - Double_t z=0; - switch(iPlnId){ - case kPc : z=PcZ() ; break; - case kAnod : z=AnodZ(); break; - case kCenter: z=0 ; break; - case kRad : z=RadZ() ; break; - } - Double_t lors[3],mars[3]; - x.GetXYZ(mars); - fMatrix[iChId-1]->MasterToLocal(mars,lors); - return TVector2(lors[0]+0.5*PcSizeX(),lors[1]+0.5*PcSizeY()); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector3 AliRICHParam::Mars2LorsVec(Int_t iCh,const TVector3 &p) -{ - Double_t mars[3], lors[3]; p.GetXYZ(mars); - fMatrix[iCh-1]->MasterToLocalVect(mars,lors); - return TVector3(lors); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector3 AliRICHParam::Lors2MarsOld(Int_t iChId,Double_t x,Double_t y,Int_t iPlnId) -{ -// Trasform from LORS to MARS -// Arguments: iChId - chamber code 0..6 -// x,y - point in LORS -// iPlnN - chamber plane code might be kPc kRad kCenter kAnod - TGeoMatrix *pMatrix=Matrix(iChId,iPlnId); - Double_t lors[3]={x-0.5*PcSizeX(),y-0.5*PcSizeY(),0}, mars[3]; pMatrix->LocalToMaster(lors,mars); delete pMatrix; - return TVector3(mars); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector2 AliRICHParam::Mars2LorsOld(Int_t iChamN,const TVector3 &x,Int_t iPlaneN) -{ - TGeoMatrix *pMatrix=Matrix(iChamN,iPlaneN); - Double_t mars[3]={x.X(),x.Y(),x.Z()} , lors[3]; pMatrix->MasterToLocal(mars,lors); delete pMatrix; - return TVector2(lors[0]+0.5*PcSizeX(),lors[1]+0.5*PcSizeY()); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector3 AliRICHParam::Center(Int_t iChamN,Int_t iPlaneN) -{ - TGeoMatrix *pMatrix=Matrix(iChamN,iPlaneN); - Double_t mars[3] , lors[3]={0,0,0}; pMatrix->LocalToMaster(lors,mars); delete pMatrix; - return TVector3(mars); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TVector3 AliRICHParam::Norm(Int_t iChamN) -{ - TGeoMatrix *pMatrix=Matrix(iChamN,kPc); - Double_t mars[3] , lors[3]={0,0,1}; pMatrix->LocalToMasterVect(lors,mars); delete pMatrix; - return TVector3(mars); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Int_t AliRICHParam::Hit2SDigs(Int_t iHitPad,Double_t e,TClonesArray *pSDigLst) -{ -// Determines a number of pads affected by the hit and calculates the charge induced to each pad. -// Integrated Mathieson distribution is used. Invoked from AliRICHvX::Hits2SDigits() -// Arguments: iHitPad - hit pad absolute number -// e - energy (GeV) of this hit (Eloss for mip or Etot for photon) -// pSDigLst - pointer to clones array to store in calculated sdigits -// Returns: total QDC for this hit - Int_t iQtot=QdcTot(iHitPad,e); //total QDC value collected for this hit - Int_t a=1; //analise current pad +- a pads in both directions - Int_t iLeftX=0,iBotY=0,iRightX=0,iTopY=0; //area of disintegration for cluster formation, shifts to hit pad, not pad numbers - if(AliRICHDigit::P2X(iHitPad) > a) iLeftX =-a;//determine area of disintegration as hit pad +- parametrised number - if(AliRICHDigit::P2X(iHitPad) < AliRICHDigit::kPadsSecX-a) iRightX= a;//of pads. this number is determined by5 sigmas of Mathieson shape - if(AliRICHDigit::P2Y(iHitPad) > a) iBotY =-a;//see RICH TDR page 29 - if(AliRICHDigit::P2Y(iHitPad) < AliRICHDigit::kPadsSecY-a) iTopY = a;//also boundary conditions are checked (edge of sector aka PC) - Int_t iPadsCnt=0; - for(Int_t iShiftX=iLeftX;iShiftX<=iRightX;iShiftX++){//affected pads loop iShiftX is a distance (in pads) between hit pad and pad under analisys - for(Int_t iShiftY=iBotY;iShiftY<=iTopY;iShiftY++){//affected pads loop - iHitPad+=AliRICHDigit::kPadAbsX*iShiftX+iShiftY; - Double_t x1=PadSizeX()/Pc2Cath()*(iShiftX-0.5);//parametrise for Mathienson - Double_t x2=PadSizeX()/Pc2Cath()*(iShiftX+0.5);//parametrise for Mathienson - Double_t y1=PadSizeY()/Pc2Cath()*(iShiftY-0.5);//parametrise for Mathienson - Double_t y2=PadSizeY()/Pc2Cath()*(iShiftY+0.5);//parametrise for Mathienson - (*pSDigLst)[iPadsCnt++]= new AliRICHDigit(iHitPad,iQtot*Mathieson(x1,y1,x2,y2)); - }//Y loop - }//X loop - return iQtot; -}//Hit2SDigs() for abs pad //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Int_t AliRICHParam::Hit2SDigs(TVector2 hitX2,Double_t e,TClonesArray *pSDigLst) -{ -// Determines a number of pads affected by the hit and calculates the charge induced to each pad. -// Integrated Mathieson distribution is used. Invoked from AliRICHvX::Hits2SDigits() -// Arguments: hitX2 - hit position in LORS, cm -// e - energy (GeV) of this hit (Eloss for mip or Etot for photon) -// pSDigLst - pointer to clones array to store in calculated sdigits -// Returns: total QDC for this hit - Int_t iQtot=TotQdc(hitX2,e);//total charge produced by hit, 0 if hit in dead zone - if(iQtot==0) return 0; - - TVector hitPad=Loc2Pad(hitX2); TVector2 padCenterX2=Pad2Loc(hitPad); //shift the hit position to the nearest anod wire - TVector2 anod; - if((hitX2.Y()-padCenterX2.Y())>0) anod.Set(hitX2.X(),padCenterX2.Y()+AnodPitch()/2); //upper part of the pad: shift to upper anod wire - else anod.Set(hitX2.X(),padCenterX2.Y()-AnodPitch()/2); //lower part of the pad: shift to lower anod wire - - TVector area=Loc2Area(anod);//determine affected pads, dead zones analysed inside - TVector pad(2); //current pad - Int_t iPadsCnt=0; - for(pad[1]=area[1];pad[1]<=area[3];pad[1]++){//affected pads loop - for(pad[0]=area[0];pad[0]<=area[2];pad[0]++){ - Double_t dQpad=iQtot*FracQdc(anod,pad); - if(dQpad>0.1) (*pSDigLst)[iPadsCnt++]= new AliRICHDigit(pad,dQpad);//make sdigit if Qpad is large enough, meaning after merging there is a chance to go above threshold - }//X loop - }//Y loop - return iQtot; -}//Hit2SDigs() for TVector2 -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Double_t AliRICHParam::SigmaSinglePhotonFormula(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM) -{ -// Analithical calculation of total error (as a sum of localization, geometrical and chromatic errors) on Cerenkov angle for a given Cerenkov photon -// created by a given MIP. Fromulae according to CERN-EP-2000-058 -// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians] -// dip and azimuthal angles for MIP taken at the entrance to radiator, [radians] -// MIP beta -// Returns: absolute error on Cerenkov angle, [radians] - - TVector3 v(-999,-999,-999); - - v.SetX(ErrLoc (thetaC,phiC,thetaM,phiM,betaM)); - v.SetY(ErrGeom(thetaC,phiC,thetaM,phiM,betaM)); - v.SetZ(ErrCrom(thetaC,phiC,thetaM,phiM,betaM)); - - return v.Mag2(); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Double_t AliRICHParam::ErrLoc(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM) -{ -// Analithical calculation of localization error (due to finite segmentation of PC) on Cerenkov angle for a given Cerenkov photon -// created by a given MIP. Fromulae according to CERN-EP-2000-058 -// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians] -// dip and azimuthal angles for MIP taken at the entrance to radiator, [radians] -// MIP beta -// Returns: absolute error on Cerenkov angle, [radians] - Double_t refC6F14m = 1.29337; - Double_t phiDelta = phiC - phiM; - - Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM); - Double_t k = 1.-refC6F14m*refC6F14m+alpha*alpha/(betaM*betaM); - if (k<0) return 1e10; - - Double_t mu =TMath::Sin(thetaM)*TMath::Sin(phiM)+TMath::Tan(thetaC)*(TMath::Cos(thetaM)*TMath::Cos(phiDelta)*TMath::Sin(phiM)+TMath::Sin(phiDelta)*TMath::Cos(phiM)); - Double_t e =TMath::Sin(thetaM)*TMath::Cos(phiM)+TMath::Tan(thetaC)*(TMath::Cos(thetaM)*TMath::Cos(phiDelta)*TMath::Cos(phiM)-TMath::Sin(phiDelta)*TMath::Sin(phiM)); - - Double_t kk = betaM*TMath::Sqrt(k)/(Pc2Win()*alpha); - Double_t dtdxc = kk*(k*(TMath::Cos(phiDelta)*TMath::Cos(phiM)-TMath::Cos(thetaM)*TMath::Sin(phiDelta)*TMath::Sin(phiM))-(alpha*mu/(betaM*betaM))*TMath::Sin(thetaM)*TMath::Sin(phiDelta)); - Double_t dtdyc = kk*(k*(TMath::Cos(phiDelta)*TMath::Sin(phiM)+TMath::Cos(thetaM)*TMath::Sin(phiDelta)*TMath::Cos(phiM))+(alpha* e/(betaM*betaM))*TMath::Sin(thetaM)*TMath::Sin(phiDelta)); - - return TMath::Sqrt(0.2*0.2*dtdxc*dtdxc + 0.25*0.25*dtdyc*dtdyc); -} -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Double_t AliRICHParam::ErrCrom(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM) -{ -// Analithical calculation of chromatic error (due to lack of knowledge of Cerenkov photon energy) on Cerenkov angle for a given Cerenkov photon -// created by a given MIP. Fromulae according to CERN-EP-2000-058 -// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians] -// dip and azimuthal angles for MIP taken at the entrance to radiator, [radians] -// MIP beta -// Returns: absolute error on Cerenkov angle, [radians] - Double_t phiDelta = phiC - phiM; - Double_t refC6F14m = 1.29337; - Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM); - - //cout << "alpha : "< -#include -#include -#include +#include "AliRICHCluster.h" //CkovAngle() +#include //AliInfo() +#include //many +#include // +#include //HoughResponse() +#include //CkovAngle() -#include "AliRICHCluster.h" //ThetaCerenkov() -#include "AliRICHParam.h" -#include "AliRICHHelix.h" //ThetaCerenkov() -#include +const Double_t AliRICHRecon::fkRadThick=1.5; +const Double_t AliRICHRecon::fkWinThick=0.5; +const Double_t AliRICHRecon::fkGapThick=8.0; +const Double_t AliRICHRecon::fkRadIdx =1.292; +const Double_t AliRICHRecon::fkWinIdx =1.5787; +const Double_t AliRICHRecon::fkGapIdx =1.0005; -#define NPointsOfRing 201 -//__________________________________________________________________________________________________ -AliRICHRecon::AliRICHRecon(): - TTask ("RichRec","RichPat"), - fPhotonsNumber(0), - fPhotonIndex(0), // should we use -1? - fFittedHoughPhotons(0), - fMinNumPhots(3), - fTrackTheta(0), - fTrackPhi(0), - fMinDist(999), - fTrackBeta(0), - fXtoentr(999), - fYtoentr(999), - fThetaPhotonInTRS(0), - fPhiPhotonInTRS(0), - fThetaPhotonInDRS(0), - fPhiPhotonInDRS(0), - fThetaAtQuartz(0), - fXEmiss(-999), - fYEmiss(-999), - fXInner(-999), - fYInner(-999), - fXOuter(-999), - fYOuter(-999), - fInnerRadius(-999), - fOuterRadius(-999), - fEphot(0), - fLengthEmissionPoint(0), - fPhotonLimitX(999), - fPhotonLimitY(999), - fDistanceFromCluster(999), - fCerenkovAnglePad(999), - fThetaPhotonCerenkov(0), - fShiftX(0), - fShiftY(0), - fXcoord(999), - fYcoord(999), - fIntersectionX(999), - fIntersectionY(999), - fMassHypotesis(0.139567), - fThetaOfRing(0), - fAreaOfRing(0), - fPortionOfRing(0), - fHoughArea(0), - fHoughRMS(999), - fFittedTrackTheta(0), - fFittedTrackPhi(0), - fFittedThetaCerenkov(0), - fThetaMin(0.0), - fThetaMax(0.75), +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliRICHRecon::AliRICHRecon():TTask("RichRec","RichPat"), + fPhotCnt(-1), + fCkovSigma2(0), fIsWEIGHT(kFALSE), - fIsBACKGROUND(kFALSE), fDTheta(0.001), fWindowWidth(0.045), - fNumEtaPhotons(0), - fnPhotBKG(0), - fThetaCerenkov(0), - fWeightThetaCerenkov(0), - fThetaPeakPos(0), - fRingSigma2(0) + fTrkDir(TVector3(0,0,1)),fTrkPos(TVector2(30,40)) { // main ctor for (Int_t i=0; i<3000; i++) { - fPhotonFlag[i] = 0; - fPhiPoint[i] = -999; - fPhotonEta[i] = -999; - fPhotonWeight[i] = 0.0; - fEtaFlag[i] = 0; - fEtaPhotons[i] = 0; - fWeightPhotons[i] = 0; + fPhotFlag[i] = 0; + fPhotCkov[i] = -1; + fPhotPhi [i] = -1; + fPhotWei [i] = 0; } } -//__________________________________________________________________________________________________ -Double_t AliRICHRecon::ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t &nphot) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::CkovAngle(TClonesArray *pCluLst,Int_t &iNaccepted) { // Pattern recognition method based on Hough transform -// Return theta Cerenkov for a given track and list of clusters which are set in ctor -// Remeber that list of clusters must contain more then 1 cluster. This considiration implies that normally we have 1 mip cluster and few photon clusters per track. -// Argume -// Returns: Track theta ckov in rad, nphot is the number of photon candidates accepted for reconstruction track theta ckov - SetTrackTheta(pHelix->Ploc().Theta()); SetTrackPhi(pHelix->Ploc().Phi()); - SetShiftX(pHelix->PosRad().X()); SetShiftY(pHelix->PosRad().Y()); - if(pClusters->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction - else fIsWEIGHT = kFALSE; - - - - SetThetaCerenkov(-1); - - // - // Photon Flag: Flag = 0 initial set; Flag = 1 good candidate (charge compatible with photon); Flag = 2 photon used for the ring; - // +// Arguments: pCluLst - list of clusters for this chamber +// Returns: - track ckov angle, [rad], - for (Int_t iClu=0; iCluGetEntriesFast();iClu++){//clusters loop - if(iClu == nphot) continue; // do not consider MIP cluster as a photon candidate - SetPhotonIndex(iClu); - SetPhotonFlag(0); - SetPhotonEta(-999.); - SetPhotonWeight(0.); - AliRICHCluster *pClu=(AliRICHCluster*)pClusters->UncheckedAt(iClu); //get pointer to current cluster - if(pClu->Q()>AliRICHParam::QthMIP()) continue; //avoid MIP clusters from bkg - SetEntranceX(pClu->X() - GetShiftX()); SetEntranceY(pClu->Y() - GetShiftY()); //cluster position with respect to track intersection - FindPhiPoint(); - SetPhotonFlag(1); - FindThetaPhotonCerenkov(); - Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov(); - AliDebug(1,Form("Track Theta=%5.2f deg, Phi=%5.2f deg Photon clus=%2i ThetaCkov=%5.2f rad",GetTrackTheta()*TMath::RadToDeg(),GetTrackPhi()*TMath::RadToDeg() - ,iClu,thetaPhotonCerenkov )); - SetPhotonEta(thetaPhotonCerenkov); - }//clusters loop + if(pCluLst->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction + else fIsWEIGHT = kFALSE; - SetPhotonsNumber(pClusters->GetEntries()); - - if((nphot=FlagPhotons(HoughResponse()))<1) return -11; //flag photons according to individual theta ckov with respect to most probable track theta ckov - - -// Float_t thetaCerenkov = GetThetaCerenkov(); -// SetThetaOfRing(thetaCerenkov); -// FindAreaAndPortionOfRing(); - -// Float_t nPhotonHoughNorm = ((Float_t)nPhotonHough)/GetPortionOfRing(); -// SetHoughPhotonsNorm(nPhotonHoughNorm); - - // Calculate the area where the photon are accepted... -/* - Float_t thetaInternal = thetaCerenkov - 0.5*fWindowWidth; - SetThetaOfRing(thetaInternal); - FindAreaAndPortionOfRing(); - Float_t internalArea = GetAreaOfRing(); - - Float_t thetaExternal = thetaCerenkov + 0.5*fWindowWidth; - SetThetaOfRing(thetaExternal); - FindAreaAndPortionOfRing(); - Float_t externalArea = GetAreaOfRing(); + // Photon Flag: Flag = 0 initial set; Flag = 1 good candidate (charge compatible with photon); Flag = 2 photon used for the ring; - Float_t houghArea = externalArea - internalArea; + fPhotCnt=0; + for (Int_t iClu=0; iCluGetEntriesFast();iClu++){//clusters loop + AliRICHCluster *pClu=(AliRICHCluster*)pCluLst->UncheckedAt(iClu); //get pointer to current cluster + if(pClu->Q()>100) continue; //avoid MIP clusters from bkg + + fPhotCkov[fPhotCnt]=FindPhotCkov(pClu->X(),pClu->Y()); //find ckov angle for this photon candidate + fPhotCnt++; //increment counter of photon candidates + }//clusters loop - SetHoughArea(houghArea); -*/ - FindThetaCerenkov(pClusters->GetEntries()); - return GetThetaCerenkov(); + iNaccepted=FlagPhot(HoughResponse()); //flag photons according to individual theta ckov with respect to most probable track theta ckov + if(iNaccepted<1) return -11; + else return FindRingCkov(pCluLst->GetEntries()); //find best Theta ckov for ring i.e. track }//ThetaCerenkov() -//__________________________________________________________________________________________________ -Int_t AliRICHRecon::PhotonInBand() -{ -// Define valid band for photon candidates. For that photons with ThetaMin and ThetaMax are traced up to photcathode - - Float_t nfreon; - - Float_t thetacer; - - Float_t xtoentr = GetEntranceX(); - Float_t ytoentr = GetEntranceY(); - - Float_t innerRadius; - Float_t outerRadius; - - Float_t phpad = GetPhiPoint(); - - - // inner radius // - SetEmissionPoint(AliRICHParam::RadThick() -0.0001); - - nfreon = AliRICHParam::Instance()->IdxC6F14(AliRICHParam::Instance()->EckovMin()); - thetacer = 0.; - - AliDebug(1,Form("thetacer in photoninband min %f",thetacer)); - - FindThetaAtQuartz(thetacer); - - if(thetacer == 999. || GetThetaAtQuartz() == 999.) { - innerRadius = -999.; - SetXInnerRing(-999.); - SetYInnerRing(-999.); - SetRadiusInnerRing(-999.); - } - else - { - SetThetaPhotonInDRS(GetThetaAtQuartz()); - SetPhiPhotonInDRS(phpad); - - innerRadius = FromEmissionToCathode(); - if(innerRadius == 999.) innerRadius = -999.; - - SetXInnerRing(GetXPointOnCathode()); - SetYInnerRing(GetYPointOnCathode()); - SetRadiusInnerRing(innerRadius); - } - - // outer radius // - SetEmissionPoint(0.); -// SetMassHypotesis(0.139567); - - nfreon = AliRICHParam::Instance()->IdxC6F14(AliRICHParam::Instance()->EckovMax()); - - thetacer = Cerenkovangle(nfreon,1); - - // thetacer = 0.75; - - AliDebug(1,Form("thetacer in photoninband max %f",thetacer)); - - FindThetaAtQuartz(thetacer); - - if(thetacer == 999. || GetThetaAtQuartz() == 999.) - { - outerRadius = 999.; - SetXOuterRing(999.); - SetYOuterRing(999.); - SetRadiusOuterRing(999.); - } - else - { - SetThetaPhotonInDRS(GetThetaAtQuartz()); - SetPhiPhotonInDRS(phpad); - - outerRadius = FromEmissionToCathode(); -// cout << " outerRadius " << outerRadius << endl; - SetXOuterRing(GetXPointOnCathode()); - SetYOuterRing(GetYPointOnCathode()); - SetRadiusOuterRing(outerRadius); - } - - Float_t padradius = sqrt(TMath::Power(xtoentr,2)+TMath::Power(ytoentr,2)); - - AliDebug(1,Form("rmin %f r %f rmax %f",innerRadius,padradius,outerRadius)); - - if(padradius>=innerRadius && padradius<=outerRadius) return 1; - return 0; -}//PhotonInBand() -//__________________________________________________________________________________________________ -void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::FindPhotCkov(Double_t cluX,Double_t cluY) { -// find the theta at the quartz plate - - if(thetaCerenkov == 999.) { SetThetaAtQuartz(999.); return; } - - Float_t thetaAtQuartz = 999.; - - Float_t trackTheta = GetTrackTheta(); - - if(trackTheta == 0) { - thetaAtQuartz = thetaCerenkov; - SetThetaAtQuartz(thetaAtQuartz); - return; - } - - Float_t trackPhi = GetTrackPhi(); - Float_t phiPoint = GetPhiPoint(); - - Double_t den = TMath::Sin((Double_t)trackTheta)*TMath::Cos((Double_t)trackPhi)*TMath::Cos((Double_t)phiPoint) + - TMath::Sin((Double_t)trackTheta)*TMath::Sin((Double_t)trackPhi)*TMath::Sin((Double_t)phiPoint); - Double_t b = TMath::Cos((Double_t)trackTheta)/den; - Double_t c = -TMath::Cos((Double_t)thetaCerenkov)/den; - - Double_t underSqrt = 1 + b*b - c*c; - - if(underSqrt < 0) { - SetThetaAtQuartz(999.); - return; +// Finds Cerenkov angle for this photon candidate +// Arguments: cluX,cluY - position of cadidate's cluster +// Returns: Cerenkov angle + + TVector2 pos(cluX,cluY); Double_t cluR=(pos-fTrkPos).Mod(); Double_t phi=FindPhotPhi(cluX,cluY); + Printf("new dist %f phi %f",cluR,phi); + Double_t ckov1=0,ckov2=0.75; + const Double_t kTol=0.05; + Int_t iIterCnt = 0; + while(1){ + if(iIterCnt>=50) return -1; + Double_t ckov=0.5*(ckov1+ckov2); + Double_t dist=cluR-TracePhoton(ckov,phi,pos); iIterCnt++; //get distance between trial point and cluster position + Printf("New: phi %f ckov %f dist %f",phi,ckov,dist); + if (dist> kTol) ckov1=ckov; //cluster @ larger ckov + else if(dist<-kTol) ckov2=ckov; //cluster @ smaller ckov + else return ckov; //precision achived } - - Double_t sol1 = (1+TMath::Sqrt(underSqrt))/(b-c); - Double_t sol2 = (1-TMath::Sqrt(underSqrt))/(b-c); - - Double_t thetaSol1 = 2*TMath::ATan(sol1); - Double_t thetaSol2 = 2*TMath::ATan(sol2); - - if(thetaSol1>0 && thetaSol1 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol1; - if(thetaSol2>0 && thetaSol2 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol2; - -// AliDebug(1,Form(" Theta @ quartz window %f ",thetaAtQuartz)); - - SetThetaAtQuartz(thetaAtQuartz); -} -//__________________________________________________________________________________________________ -void AliRICHRecon::FindThetaPhotonCerenkov() +}//FindPhotTheta() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::FindPhotPhi(Double_t cluX,Double_t cluY) { - //find theta cerenkov of ring - - Float_t thetaCerMin = 0.; - Float_t thetaCerMax = 0.75; - Float_t thetaCerMean; - - Float_t radiusMin, radiusMax, radiusMean; - Int_t nIteration = 0; - - const Float_t kTollerance = 0.05; - - - Float_t phiPoint = GetPhiPoint(); - - SetEmissionPoint(AliRICHParam::RadThick()/2); - - Float_t xPoint = GetEntranceX(); - Float_t yPoint = GetEntranceY(); - Float_t distPoint = TMath::Sqrt(xPoint*xPoint + yPoint*yPoint); - -// AliDebug(1,Form(" DistPoint %f ",distPoint)); - - // Star minimization... - - // First value... - - FindThetaAtQuartz(thetaCerMin); +// Finds phi angle og photon candidate by considering the cluster's position of this candudate w.r.t track position - if(GetThetaAtQuartz() == 999.) - { - radiusMin = -999.; - } - else - { - SetThetaPhotonInDRS(GetThetaAtQuartz()); - SetPhiPhotonInDRS(phiPoint); - - radiusMin = FromEmissionToCathode(); - } - - // Second value... - - FindThetaAtQuartz(thetaCerMax); - if(GetThetaAtQuartz() == 999.) - { - radiusMax = 999.; - } - else - { - SetThetaPhotonInDRS(GetThetaAtQuartz()); - SetPhiPhotonInDRS(phiPoint); - - radiusMax = FromEmissionToCathode(); - } - // Mean value... - - thetaCerMean = (thetaCerMax + thetaCerMin)/2; - - FindThetaAtQuartz(thetaCerMean); - if(GetThetaAtQuartz() == 999.) - { - radiusMean = 999.; - } - else - { - SetThetaPhotonInDRS(GetThetaAtQuartz()); - SetPhiPhotonInDRS(phiPoint); - - radiusMean = FromEmissionToCathode(); - } - -// AliDebug(1,Form(" r1 %f rmean %f r2 %f",radiusMin,radiusMean,radiusMax)); - - while (TMath::Abs(radiusMean-distPoint) > kTollerance) - { - - if((radiusMin-distPoint)*(radiusMean-distPoint) < 0) thetaCerMax = thetaCerMean; - if((radiusMin-distPoint)*(radiusMean-distPoint) > 0) { - - thetaCerMin = thetaCerMean; - - FindThetaAtQuartz(thetaCerMin); - SetThetaPhotonInDRS(GetThetaAtQuartz()); - SetPhiPhotonInDRS(phiPoint); - - radiusMin =FromEmissionToCathode(); - } - - thetaCerMean = (thetaCerMax + thetaCerMin)/2; - - FindThetaAtQuartz(thetaCerMean); - SetThetaPhotonInDRS(GetThetaAtQuartz()); - SetPhiPhotonInDRS(phiPoint); - - radiusMean = FromEmissionToCathode(); - - nIteration++; - if(nIteration>=50) { -// AliDebug(1,Form(" max iterations in FindPhotonCerenkov ",nIteration)); - SetThetaPhotonCerenkov(999.); - return; - } - } - -// AliDebug(1,Form(" distpoint %f radius %f ",distPoint,radiusMean)); - SetThetaPhotonCerenkov(thetaCerMean); - + Double_t emiss=0; + return fPhotPhi[fPhotCnt]=TMath::ATan2(cluY-fTrkPos.Y()-emiss*TMath::Tan(fTrkDir.Theta())*TMath::Sin(fTrkDir.Phi()), + cluX-fTrkPos.X()-emiss*TMath::Tan(fTrkDir.Theta())*TMath::Cos(fTrkDir.Phi())); } -//__________________________________________________________________________________________________ -void AliRICHRecon::FindAreaAndPortionOfRing() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::FindRingArea(Double_t ckovAng)const { - //find fraction of the ring accepted by the RICH - - Float_t xPoint[NPointsOfRing], yPoint[NPointsOfRing]; - - // Float_t xtoentr = GetEntranceX(); - // Float_t ytoentr = GetEntranceY(); - Float_t shiftX = GetShiftX(); - Float_t shiftY = GetShiftY(); - - Float_t xemiss = GetXCoordOfEmission(); - Float_t yemiss = GetYCoordOfEmission(); - - Float_t x0 = xemiss + shiftX; - Float_t y0 = yemiss + shiftY; - - - - SetEmissionPoint(AliRICHParam::RadThick()/2.); - - Float_t theta = GetThetaOfRing(); +// Find area inside the cerenkov ring which lays inside PCs +// Arguments: ckovThe - cernkov +// Returns: area of the ring in cm^2 for given theta ckov + - Int_t nPoints = 0; - Int_t nPsiAccepted = 0; - Int_t nPsiTotal = 0; - - for(Int_t i=0;i %d",zone)); - - if (zone != 0){ - FindIntersectionWithDetector(); - xPoint[nPoints] = GetIntersectionX(); yPoint[nPoints] = GetIntersectionY(); - }else{ - xPoint[nPoints] = xPointRing; yPoint[nPoints] = yPointRing; - nPsiAccepted++; - } - nPoints++; } - - xPoint[nPoints] = xPoint[0]; yPoint[nPoints] = yPoint[0]; - - // find area... - - Float_t area = 0; - - for (Int_t i = 0; i < nPoints; i++) - { - area += TMath::Abs((xPoint[i]-x0)*(yPoint[i+1]-y0) - (xPoint[i+1]-x0)*(yPoint[i]-y0)); - } - - area *= 0.5; - - Float_t portionOfRing = 0; - if (nPsiTotal>0) - portionOfRing = ((Float_t)nPsiAccepted)/((Float_t)(nPsiTotal)); - - - SetAreaOfRing(area); - SetPortionOfRing(portionOfRing); -}//FindAreaAndPortionOfRing() -//__________________________________________________________________________________________________ -void AliRICHRecon::FindIntersectionWithDetector() -{ - // find ring intersection with CsI edges - - Float_t xIntersect, yIntersect; - Float_t x1, x2, y1, y2; - - Float_t shiftX = GetShiftX(); - Float_t shiftY = GetShiftY(); - - Float_t xPoint = GetXPointOnCathode() + shiftX; - Float_t yPoint = GetYPointOnCathode() + shiftY; - - Float_t xemiss = GetXCoordOfEmission(); - Float_t yemiss = GetYCoordOfEmission(); - - Float_t phi = GetPhiPhotonInDRS(); - Float_t m = tan(phi); - - Float_t x0 = xemiss + shiftX; - Float_t y0 = yemiss + shiftY; - - if(xPoint > x0) - { - x1 = x0; - x2 = xPoint; - } - else - { - x2 = x0; - x1 = xPoint; - } - if(yPoint > y0) - { - y1 = y0; - y2 = yPoint; - } - else - { - y2 = y0; - y1 = yPoint; - } - // - xIntersect = AliRICHParam::PcSizeX(); - yIntersect = m*(xIntersect - x0) + y0; - if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2) - { - SetIntersectionX(xIntersect); - SetIntersectionY(yIntersect); - return; - } - // - xIntersect = 0; - yIntersect = m*(xIntersect - x0) + y0; - if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2) - { - SetIntersectionX(xIntersect); - SetIntersectionY(yIntersect); - return; - } - // - yIntersect = AliRICHParam::PcSizeY(); - xIntersect = (yIntersect - y0)/m + x0; - if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2) - { - SetIntersectionX(xIntersect); - SetIntersectionY(yIntersect); - return; - } - // - yIntersect = 0; - xIntersect = (yIntersect - y0)/m + x0; - if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2) - { - SetIntersectionX(xIntersect); - SetIntersectionY(yIntersect); - return; - } -} - -//__________________________________________________________________________________________________ -Int_t AliRICHRecon::CheckDetectorAcceptance() const -{ - // check for the acceptance - - // crosses X -2.6 2.6 cm - // crosses Y -1 1 cm - - Float_t xcoord = GetDetectorWhereX(); - Float_t ycoord = GetDetectorWhereY(); - - if(xcoord > AliRICHParam::PcSizeX()) - { - if(ycoord > AliRICHParam::PcSizeY()) return 2; - if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 3; - if(ycoord < 0) return 4; - } - if(xcoord < 0) - { - if(ycoord > AliRICHParam::PcSizeY()) return 8; - if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 7; - if(ycoord < 0) return 6; - } - if(xcoord > 0 && xcoord < AliRICHParam::PcSizeX()) - { - if(ycoord > AliRICHParam::PcSizeY()) return 1; - if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 0; - if(ycoord < 0) return 5; - } - return 999; -} -//__________________________________________________________________________________________________ -void AliRICHRecon::FindPhotonAnglesInDRS() + return area; +}//RingArea() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::TracePhoton(Double_t ckovThe,Double_t ckovPhi,TVector2 &pos)const { - // Setup the rotation matrix of the track... - - TRotation mtheta; - TRotation mphi; - TRotation minv; - TRotation mrot; +// Trace a single Ckov photon from emission point somewhere in radiator up to photocathode taking into account ref indexes of materials it travereses +// Arguments: ckovThe,ckovPhi- photon ckov angles, [rad] (warning: not photon theta and phi) +// Returns: distance between photon point on PC and track projection + TRotation mtheta; mtheta.RotateY(fTrkDir.Theta()); + TRotation mphi; mphi.RotateZ(fTrkDir.Phi()); + TRotation mrot=mphi*mtheta; - Float_t trackTheta = GetTrackTheta(); - Float_t trackPhi = GetTrackPhi(); - - mtheta.RotateY(trackTheta); - mphi.RotateZ(trackPhi); + TVector3 posCkov(fTrkPos.X(),fTrkPos.Y(),-0.5*fkRadThick-fkWinThick-fkGapThick); //RAD: photon position is track position @ middle of RAD + TVector3 dirCkov; dirCkov.SetMagThetaPhi(1,ckovThe,ckovPhi); //initially photon is directed according to requested ckov angle + dirCkov=mrot*dirCkov; //now we know photon direction in LORS + dirCkov.SetPhi(ckovPhi); + if(dirCkov.Theta() > TMath::ASin(1./fkRadIdx)) return -999;//total refraction on WIN-GAP boundary - mrot = mphi * mtheta; - // minv = mrot.Inverse(); - - TVector3 photonInRadiator(1,1,1); - - Float_t thetaCerenkov = GetThetaPhotonInTRS(); - Float_t phiCerenkov = GetPhiPhotonInTRS(); - - photonInRadiator.SetTheta(thetaCerenkov); - photonInRadiator.SetPhi(phiCerenkov); - photonInRadiator = mrot * photonInRadiator; - Float_t theta = photonInRadiator.Theta(); - Float_t phi = photonInRadiator.Phi(); - SetThetaPhotonInDRS(theta); - SetPhiPhotonInDRS(phi); - -} -//__________________________________________________________________________________________________ -Float_t AliRICHRecon::FromEmissionToCathode() -{ -// Trace current photon from emission point somewhere in radiator to photocathode -// Arguments: none -// Returns: - - Float_t nfreon, nquartz, ngas; - - nfreon = AliRICHParam::Instance()->IdxC6F14(AliRICHParam::Instance()->EckovMean()); - nquartz = AliRICHParam::Instance()->IdxSiO2(AliRICHParam::Instance()->EckovMean()); - ngas = AliRICHParam::Instance()->IdxCH4(AliRICHParam::Instance()->EckovMean()); - - Float_t trackTheta = GetTrackTheta(); - Float_t trackPhi = GetTrackPhi(); - Float_t lengthOfEmissionPoint = GetEmissionPoint(); - - Float_t theta = GetThetaPhotonInDRS(); - Float_t phi = GetPhiPhotonInDRS(); - - Float_t xemiss = lengthOfEmissionPoint*tan(trackTheta)*cos(trackPhi); - Float_t yemiss = lengthOfEmissionPoint*tan(trackTheta)*sin(trackPhi); - - SetXCoordOfEmission(xemiss); - SetYCoordOfEmission(yemiss); + Propagate(dirCkov,posCkov,-fkWinThick-fkGapThick); //go to RAD-WIN boundary remeber that z=0 is PC plane + Refract (dirCkov, fkRadIdx,fkWinIdx ); //RAD-WIN refraction + Propagate(dirCkov,posCkov,-fkGapThick ); //go to WIN-GAP boundary + Refract (dirCkov, fkWinIdx,fkGapIdx ); //WIN-GAP refraction + Propagate(dirCkov,posCkov,0 ); //go to PC - Float_t thetaquar = SnellAngle(nfreon, nquartz, theta); - - if(thetaquar == 999.) - { - SetXPointOnCathode(999.); - SetYPointOnCathode(999.); - return thetaquar; - } - - Float_t thetagap = SnellAngle( nquartz, ngas, thetaquar); - - if(thetagap == 999.) - { - SetXPointOnCathode(999.); - SetYPointOnCathode(999.); - return thetagap; - } - - Float_t xw = (AliRICHParam::RadThick() - lengthOfEmissionPoint)*cos(phi)*tan(theta); - Float_t xq = AliRICHParam::WinThick()*cos(phi)*tan(thetaquar); - Float_t xg = AliRICHParam::Pc2Win()*cos(phi)*tan(thetagap); - Float_t yw = (AliRICHParam::RadThick() - lengthOfEmissionPoint)*sin(phi)*tan(theta); - Float_t yq = AliRICHParam::WinThick()*sin(phi)*tan(thetaquar); - Float_t yg = AliRICHParam::Pc2Win()*sin(phi)*tan(thetagap); - - - Float_t xtot = xemiss + xw + xq + xg; - Float_t ytot = yemiss + yw + yq + yg; - - SetXPointOnCathode(xtot); - SetYPointOnCathode(ytot); - - - Float_t distanceFromEntrance = TMath::Sqrt(TMath::Power(fPhotonLimitX,2)+TMath::Power(fPhotonLimitY,2)); - - return distanceFromEntrance; - -} -//__________________________________________________________________________________________________ -void AliRICHRecon::FindPhiPoint() -{ - //find phi of generated point - - Float_t xtoentr = GetEntranceX(); - Float_t ytoentr = GetEntranceY(); - - Float_t trackTheta = GetTrackTheta(); - Float_t trackPhi = GetTrackPhi(); - - Float_t emissionPoint = GetEmissionPoint(); - - Float_t argY = ytoentr - emissionPoint*tan(trackTheta)*sin(trackPhi); - Float_t argX = xtoentr - emissionPoint*tan(trackTheta)*cos(trackPhi); - Float_t phi = atan2(argY,argX); - - SetPhiPoint(phi); - -} -//__________________________________________________________________________________________________ -Float_t AliRICHRecon::Cerenkovangle(Float_t n, Float_t beta) -{ - // cerenkov angle from n and beta - -// Compute the cerenkov angle - - Float_t thetacer; - - if((n*beta)<1.) { - thetacer = 999.; - // cout << " warning in Cerenkoangle !!!!!! " << endl; - return thetacer; - } - - thetacer = acos (1./(n*beta)); - return thetacer; -} -//__________________________________________________________________________________________________ -Float_t AliRICHRecon::SnellAngle(Float_t n1, Float_t n2, Float_t theta1) + pos.Set(posCkov.X(),posCkov.Y()); + return (pos-fTrkPos).Mod(); +}//TracePhoton() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHRecon::Propagate(const TVector3 &dir,TVector3 &pos,Double_t z)const { - // Snell law - -// Compute the Snell angle - - Float_t sinrefractangle; - Float_t refractangle; - - sinrefractangle = (n1/n2)*sin(theta1); - - if(sinrefractangle>1.) { - // cout << " PROBLEMS IN SNELL ANGLE !!!!! " << endl; - refractangle = 999.; - return refractangle; - } +// Finds an intersection point between a line and XY plane shifted along Z. +// Arguments: dir,pos - vector along the line and any point of the line +// z - z coordinate of plain +// Returns: none +// On exit: pos is the position if this intesection if any + static TVector3 nrm(0,0,1); + TVector3 pnt(0,0,z); - refractangle = asin(sinrefractangle); - return refractangle; -} -//__________________________________________________________________________________________________ + TVector3 diff=pnt-pos; + Double_t sint=(nrm*diff)/(nrm*dir); + pos+=sint*dir; +}//Propagate() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHRecon::Refract(TVector3 &dir,Double_t n1,Double_t n2)const +{ +// Refract direction vector according to Snell law +// Arguments: +// n1 - ref idx of first substance +// n2 - ref idx of second substance +// Returns: none +// On exit: dir is new direction + Double_t sinref=(n1/n2)*TMath::Sin(dir.Theta()); + if(sinref>1.) dir.SetXYZ(-999,-999,-999); + else dir.SetTheta(TMath::ASin(sinref)); +}//Refract() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Double_t AliRICHRecon::HoughResponse() { // // // - Int_t nChannels = (Int_t)(fThetaMax/fDTheta+0.5); - TH1F *phots = new TH1F("phots" ,"phots" ,nChannels,0,fThetaMax); - TH1F *photsw = new TH1F("photsw" ,"photsw" ,nChannels,0,fThetaMax); - TH1F *resultw = new TH1F("resultw","resultw",nChannels,0,fThetaMax); - Int_t nBin = (Int_t)(fThetaMax/fDTheta); + Double_t kThetaMax=0.75; + Int_t nChannels = (Int_t)(kThetaMax/fDTheta+0.5); + TH1D *phots = new TH1D("Rphot" ,"phots" ,nChannels,0,kThetaMax); + TH1D *photsw = new TH1D("RphotWeighted" ,"photsw" ,nChannels,0,kThetaMax); + TH1D *resultw = new TH1D("resultw","resultw" ,nChannels,0,kThetaMax); + Int_t nBin = (Int_t)(kThetaMax/fDTheta); Int_t nCorrBand = (Int_t)(fWindowWidth/(2*fDTheta)); - AliDebug(1,Form("Ring reconstruction for track with theta %f",GetTrackTheta()*TMath::RadToDeg())); - for (Int_t kPhot=0; kPhot< GetPhotonsNumber(); kPhot++){ - SetPhotonIndex(kPhot); - Double_t angle = GetPhotonEta(); - if(angle<0||angle>fThetaMax) continue; + + for (Int_t i=0; i< fPhotCnt; i++){//photon cadidates loop + Double_t angle = fPhotCkov[i]; if(angle<0||angle>kThetaMax) continue; phots->Fill(angle); Int_t bin = (Int_t)(0.5+angle/(fDTheta)); Double_t weight=1.; if(fIsWEIGHT){ - Double_t lowerlimit = ((Float_t)bin)*fDTheta - 0.5*fDTheta; - SetThetaOfRing(lowerlimit); - FindAreaAndPortionOfRing(); - Float_t area1 = GetAreaOfRing(); - Double_t upperlimit = ((Float_t)bin)*fDTheta + 0.5*fDTheta; - SetThetaOfRing(upperlimit); - FindAreaAndPortionOfRing(); - Float_t area2 = GetAreaOfRing(); - AliDebug(1,Form("lowerlimit %f area %f ; upperlimit %f area %f",lowerlimit,area1,upperlimit,area2)); - Float_t diffarea = area2 - area1; - if(diffarea>0){weight = 1./(area2-area1);}else{weight = 1.;} + Double_t lowerlimit = ((Double_t)bin)*fDTheta - 0.5*fDTheta; Double_t upperlimit = ((Double_t)bin)*fDTheta + 0.5*fDTheta; + Double_t diffArea = FindRingArea(upperlimit)-FindRingArea(lowerlimit); + if(diffArea>0) weight = 1./diffArea; } - AliDebug(1,Form("Calculated weight %f",weight)); photsw->Fill(angle,weight); - SetPhotonWeight(weight); - } + fPhotWei[i]=weight; + }//photon candidates loop + for (Int_t i=1; i<=nBin;i++){ Int_t bin1= i-nCorrBand; Int_t bin2= i+nCorrBand; if(bin1<1) bin1=1; if(bin2>nBin)bin2=nBin; Double_t sumPhots=phots->Integral(bin1,bin2); - if(sumPhotsIntegral(bin1,bin2); - resultw->Fill((Float_t)((i+0.5)*fDTheta),sumPhotsw); + resultw->Fill((Double_t)((i+0.5)*fDTheta),sumPhotsw); } // evaluate the "BEST" theta ckov as the maximum value of histogramm - Float_t *pVec = resultw->GetArray(); + Double_t *pVec = resultw->GetArray(); Int_t locMax = TMath::LocMax(nBin,pVec); phots->Delete();photsw->Delete();resultw->Delete(); // Reset and delete objects return (Double_t)(locMax*fDTheta+0.5*fDTheta); //final most probable track theta ckov -}//HoughResponse -//__________________________________________________________________________________________________ -void AliRICHRecon::FindThetaCerenkov(Int_t iNclus) +}//HoughResponse() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::FindRingCkov(Int_t) { // Loops on all Ckov candidates and estimates the best Theta Ckov for a ring formed by those candidates. Also estimates an error for that Theat Ckov // collecting errors for all single Ckov candidates thetas. (Assuming they are independent) // Arguments: iNclus- total number of clusters in chamber for background estimation -// Return: none +// Return: best estimation of track Theta ckov - Float_t wei = 0.; - Float_t weightThetaCerenkov = 0.; + Double_t wei = 0.; + Double_t weightThetaCerenkov = 0.; - Double_t etaMin=9999.,etaMax=0.; + Double_t ckovMin=9999.,ckovMax=0.; Double_t sigma2 = 0; //to collect error squared for this ring - for(Int_t i=0;ietaMax) etaMax=photonEta; - Float_t photonWeight = GetPhotonWeight(); - weightThetaCerenkov += photonEta*photonWeight; - wei += photonWeight; - //here comes sigma of the reconstructed ring + for(Int_t i=0;ickovMax) ckovMax=fPhotCkov[i]; + weightThetaCerenkov += fPhotCkov[i]*fPhotWei[i]; wei += fPhotWei[i]; //collect weight as sum of all candidate weghts //Double_t phiref=(GetPhiPoint()-GetTrackPhi()); - if(GetPhotonEta()<=0) continue;//?????????????????Flag photos = 2 may imply CkovEta = 0?????????????? - //??????????? Look at SetPhoton Flag method - Double_t phiref=GetTrackPhi(); - - Double_t beta = 1./(TMath::Cos(GetPhotonEta())*AliRICHParam::Instance()->IdxC6F14(AliRICHParam::EckovMean())); - sigma2 += 1./AliRICHParam::SigmaSinglePhotonFormula(GetPhotonEta(),GetPhiPoint(),GetTrackTheta(),phiref,beta); + if(fPhotCkov[i]<=0) continue;//?????????????????Flag photos = 2 may imply CkovEta = 0?????????????? + + sigma2 += 1./Sigma2(fPhotCkov[i],fPhotPhi[i],fTrkDir.Theta(),fTrkDir.Phi()); } - } + }//candidates loop - if(sigma2>0) SetRingSigma2(1./sigma2); - else SetRingSigma2(1e10); + if(sigma2>0) fCkovSigma2=1./sigma2; + else fCkovSigma2=1e10; - if(wei != 0.) weightThetaCerenkov /= wei; else weightThetaCerenkov = 0.; - SetThetaCerenkov(weightThetaCerenkov); - - // estimate of the n. of bkg photons - SetThetaOfRing(etaMin); FindAreaAndPortionOfRing(); Double_t internalArea = GetAreaOfRing(); - SetThetaOfRing(etaMax); FindAreaAndPortionOfRing(); Double_t externalArea = GetAreaOfRing(); - Double_t effArea = (AliRICHParam::PcSizeX()-AliRICHParam::DeadZone())*(AliRICHParam::PcSizeY()-2*AliRICHParam::DeadZone()); - Double_t nPhotBKG = (externalArea-internalArea)/effArea*iNclus;//????? is the division right? - if(nPhotBKG<0) nPhotBKG=0; //just protection from funny angles... - SetPhotBKG(nPhotBKG); - - AliDebug(1,Form(" thetac weighted -> %f",weightThetaCerenkov)); -}//FindThetaCerenkov() + if(wei != 0.) weightThetaCerenkov /= wei; else weightThetaCerenkov = 0.; + return weightThetaCerenkov; +}//FindCkovRing() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Int_t AliRICHRecon::FlagPhotons(Double_t thetaCkovHough) +Int_t AliRICHRecon::FlagPhot(Double_t ckov) { -// flag photon candidates if their individual theta ckov inside the window around theta ckov of Hough transform -// Arguments: thetaCkovHough- value of most probable theta ckov for track as returned by HoughResponse() +// Flag photon candidates if their individual ckov angle is inside the window around ckov angle returned by HoughResponse() +// Arguments: ckov- value of most probable ckov angle for track as returned by HoughResponse() // Returns: number of photon candidates happened to be inside the window - Int_t steps = (Int_t)((thetaCkovHough - fThetaMin)/ fDTheta); //how many times we need to have fDTheta to fill the distance betwee fThetaMin and thetaCkovHough + + Int_t steps = (Int_t)((ckov )/ fDTheta); //how many times we need to have fDTheta to fill the distance between 0 and thetaCkovHough - Float_t tmin = fThetaMin + (Float_t)(steps - 1)*fDTheta; - Float_t tmax = fThetaMin + (Float_t)(steps)*fDTheta; - Float_t tavg = 0.5*(tmin+tmax); + Double_t tmin = (Double_t)(steps - 1)*fDTheta; + Double_t tmax = (Double_t)(steps)*fDTheta; + Double_t tavg = 0.5*(tmin+tmax); tmin = tavg - 0.5*fWindowWidth; tmax = tavg + 0.5*fWindowWidth; - Int_t iInsideCnt = 0; //count photons which theta inside prdefined window - for(Int_t i=0;i= tmin && photonEta <= tmax) { - SetPhotonFlag(2); + Int_t iInsideCnt = 0; //count photons which Theta ckov inside the window + for(Int_t i=0;i= tmin && fPhotCkov[i] <= tmax) { + fPhotFlag[i]=2; iInsideCnt++; } } return iInsideCnt; -}//FlagPhotons +}//FlagPhotons() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::Sigma2(Double_t ckovTh, Double_t ckovPh, Double_t trkTh, Double_t trkPh)const +{ +// Analithical calculation of total error (as a sum of localization, geometrical and chromatic errors) on Cerenkov angle for a given Cerenkov photon +// created by a given MIP. Fromulae according to CERN-EP-2000-058 +// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians] +// dip and azimuthal angles for MIP taken at the entrance to radiator, [radians] +// MIP beta +// Returns: absolute error on Cerenkov angle, [radians] + + TVector3 v(-999,-999,-999); + Double_t trkBeta = 1./(TMath::Cos(ckovTh)*fkRadIdx); + + v.SetX(SigLoc (ckovTh,ckovPh,trkTh,trkPh,trkBeta)); + v.SetY(SigGeom(ckovTh,ckovPh,trkTh,trkPh,trkBeta)); + v.SetZ(SigCrom(ckovTh,ckovPh,trkTh,trkPh,trkBeta)); + + return v.Mag2(); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::SigLoc(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM)const +{ +// Analithical calculation of localization error (due to finite segmentation of PC) on Cerenkov angle for a given Cerenkov photon +// created by a given MIP. Fromulae according to CERN-EP-2000-058 +// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians] +// dip and azimuthal angles for MIP taken at the entrance to radiator, [radians] +// MIP beta +// Returns: absolute error on Cerenkov angle, [radians] + Double_t phiDelta = phiC - phiM; + + Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM); + Double_t k = 1.-fkRadIdx*fkRadIdx+alpha*alpha/(betaM*betaM); + if (k<0) return 1e10; + + Double_t mu =TMath::Sin(thetaM)*TMath::Sin(phiM)+TMath::Tan(thetaC)*(TMath::Cos(thetaM)*TMath::Cos(phiDelta)*TMath::Sin(phiM)+TMath::Sin(phiDelta)*TMath::Cos(phiM)); + Double_t e =TMath::Sin(thetaM)*TMath::Cos(phiM)+TMath::Tan(thetaC)*(TMath::Cos(thetaM)*TMath::Cos(phiDelta)*TMath::Cos(phiM)-TMath::Sin(phiDelta)*TMath::Sin(phiM)); + + Double_t kk = betaM*TMath::Sqrt(k)/(8*alpha); + Double_t dtdxc = kk*(k*(TMath::Cos(phiDelta)*TMath::Cos(phiM)-TMath::Cos(thetaM)*TMath::Sin(phiDelta)*TMath::Sin(phiM))-(alpha*mu/(betaM*betaM))*TMath::Sin(thetaM)*TMath::Sin(phiDelta)); + Double_t dtdyc = kk*(k*(TMath::Cos(phiDelta)*TMath::Sin(phiM)+TMath::Cos(thetaM)*TMath::Sin(phiDelta)*TMath::Cos(phiM))+(alpha* e/(betaM*betaM))*TMath::Sin(thetaM)*TMath::Sin(phiDelta)); + + return TMath::Sqrt(0.2*0.2*dtdxc*dtdxc + 0.25*0.25*dtdyc*dtdyc); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::SigCrom(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM)const +{ +// Analithical calculation of chromatic error (due to lack of knowledge of Cerenkov photon energy) on Cerenkov angle for a given Cerenkov photon +// created by a given MIP. Fromulae according to CERN-EP-2000-058 +// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians] +// dip and azimuthal angles for MIP taken at the entrance to radiator, [radians] +// MIP beta +// Returns: absolute error on Cerenkov angle, [radians] + Double_t phiDelta = phiC - phiM; + Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM); + + Double_t dtdn = TMath::Cos(thetaM)*fkRadIdx*betaM*betaM/(alpha*TMath::Tan(thetaC)); + + Double_t f = 0.00928*(7.75-5.635)/TMath::Sqrt(12.); + + return f*dtdn; +}//SigCrom() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliRICHRecon::SigGeom(Double_t thetaC, Double_t phiC, Double_t thetaM, Double_t phiM, Double_t betaM)const +{ +// Analithical calculation of geometric error (due to lack of knowledge of creation point in radiator) on Cerenkov angle for a given Cerenkov photon +// created by a given MIP. Formulae according to CERN-EP-2000-058 +// Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians] +// dip and azimuthal angles for MIP taken at the entrance to radiator, [radians] +// MIP beta +// Returns: absolute error on Cerenkov angle, [radians] + + Double_t phiDelta = phiC - phiM; + Double_t alpha =TMath::Cos(thetaM)-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(thetaM); + + Double_t k = 1.-fkRadIdx*fkRadIdx+alpha*alpha/(betaM*betaM); + if (k<0) return 1e10; + + Double_t eTr = 0.5*1.5*betaM*TMath::Sqrt(k)/(8*alpha); + Double_t lambda = 1.-TMath::Sin(thetaM)*TMath::Sin(thetaM)*TMath::Sin(phiC)*TMath::Sin(phiC); + + Double_t c = 1./(1.+ eTr*k/(alpha*alpha*TMath::Cos(thetaC)*TMath::Cos(thetaC))); + Double_t i = betaM*TMath::Tan(thetaC)*lambda*TMath::Power(k,1.5); + Double_t ii = 1.+eTr*betaM*i; + + Double_t err = c * (i/(alpha*alpha*8) + ii*(1.-lambda) / ( alpha*alpha*8*betaM*(1.+eTr)) ); + Double_t trErr = 1.5/(TMath::Sqrt(12.)*TMath::Cos(thetaM)); + + return trErr*err; +}//SigGeom() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHRecon.h b/RICH/AliRICHRecon.h index 98dd42ba6b7..ea9bc20695d 100644 --- a/RICH/AliRICHRecon.h +++ b/RICH/AliRICHRecon.h @@ -14,9 +14,8 @@ #include //base class +#include -class AliRICHHelix; -class AliRICHParam; class TClonesArray; class AliRICHRecon : public TTask { @@ -24,182 +23,46 @@ public : AliRICHRecon(); virtual ~AliRICHRecon() {} - Double_t ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pCluLst,Int_t &iMipId); // it returns reconstructed Theta Cerenkov - void FindThetaPhotonCerenkov(); // - void FindAreaAndPortionOfRing(); // - void FindPhotonAnglesInDRS(); // - void FindPhiPoint(); // - void FindThetaAtQuartz(Float_t ThetaCer); // - Double_t HoughResponse ( ); //most probable track theta ckov out of all photon candidate thetas - Int_t FlagPhotons (Double_t theta); //n. of photon candidates which thetas are inside a window around most probable track theta ckov - void FindThetaCerenkov(Int_t iNclus); // - void FindIntersectionWithDetector(); // - Float_t Cerenkovangle(Float_t n, Float_t b);// - Int_t PhotonInBand(); // - Int_t CheckDetectorAcceptance() const; // - Int_t GetFittedHoughPhotons() const{ return fFittedHoughPhotons;} // - Int_t GetPhotonFlag() const{ return fPhotonFlag[fPhotonIndex];} // - Int_t GetPhotonsNumber() const{ return fPhotonsNumber;} // - Int_t GetPhotonIndex() const{ return fPhotonIndex;} // - Float_t GetPhotonEnergy() const{ return fEphot;} // - Float_t GetEmissionPoint() const{ return fLengthEmissionPoint;} // - Float_t GetMassHypotesis() const{ return fMassHypotesis;} // - Float_t GetBetaOfParticle() const{ return fTrackBeta;} // - Float_t GetEntranceX() const{ return fXtoentr;} // - Float_t GetEntranceY() const{ return fYtoentr;} // - Float_t GetThetaCerenkov() const{ return fThetaCerenkov;} // - Float_t GetThetaPhotonCerenkov() const{ return fThetaPhotonCerenkov;} // - Float_t GetTrackTheta() const{ return fTrackTheta;} // - Float_t GetTrackPhi() const{ return fTrackPhi;} // - Float_t GetXPointOnCathode() const{ return fPhotonLimitX;} // - Float_t GetYPointOnCathode() const{ return fPhotonLimitY;} // - Float_t GetThetaPhotonInDRS() const{ return fThetaPhotonInDRS;} // - Float_t GetPhiPhotonInDRS() const{ return fPhiPhotonInDRS;} // - Float_t GetThetaPhotonInTRS() const{ return fThetaPhotonInTRS;} // - Float_t GetPhiPhotonInTRS() const{ return fPhiPhotonInTRS;} // - Float_t GetThetaAtQuartz() const{ return fThetaAtQuartz;} // - Float_t GetPhiPoint() const{ return fPhiPoint[fPhotonIndex];} // - Float_t GetXCoordOfEmission() const{ return fXEmiss;} // - Float_t GetYCoordOfEmission() const{ return fYEmiss;} // - Float_t GetXInnerRing() const{ return fXInner;} // - Float_t GetYInnerRing() const{ return fYInner;} // - Float_t GetRadiusInnerRing() const{ return fInnerRadius;} // - Float_t GetXOuterRing() const{ return fXOuter;} // - Float_t GetYOuterRing() const{ return fYOuter;} // - Float_t GetRadiusOuterRing() const{ return fOuterRadius;} // - Float_t GetShiftX() const{ return fShiftX;} // - Float_t GetShiftY() const{ return fShiftY;} // - Float_t GetDetectorWhereX() const{ return fXcoord;} // - Float_t GetDetectorWhereY() const{ return fYcoord;} // - Float_t GetIntersectionX() const{ return fIntersectionX;} // - Float_t GetIntersectionY() const{ return fIntersectionY;} // - Float_t GetThetaOfRing() const{ return fThetaOfRing;} // - Float_t GetAreaOfRing() const{ return fAreaOfRing;} // - Float_t GetPortionOfRing() const{ return fPortionOfRing;} // - Float_t GetHoughArea() const{ return fHoughArea;} // - Float_t GetPhotonEta() const{ return fPhotonEta[fPhotonIndex];} // - Float_t GetPhotonWeight() const{ return fPhotonWeight[fPhotonIndex];} // - Float_t GetHoughRMS() const{ return fHoughRMS;} // - Double_t GetPhotBKG() const{ return fnPhotBKG;} // - Float_t GetFittedTrackTheta() const{ return fFittedTrackTheta;} // - Float_t GetFittedTrackPhi() const{ return fFittedTrackPhi;} // - Float_t GetFittedThetaCerenkov() const{ return fFittedThetaCerenkov;} // - Float_t GetRingSigma2() const{ return fRingSigma2;} // - void SetPhotonEnergy(Float_t e) { fEphot = e;} // - void SetEmissionPoint(Float_t LengthEmissionPoint) { fLengthEmissionPoint = LengthEmissionPoint;} // - void SetEntranceX(Float_t Xtoentr) { fXtoentr = Xtoentr;} // - void SetEntranceY(Float_t Ytoentr) { fYtoentr = Ytoentr;} // - void SetThetaPhotonInTRS(Float_t Theta) {fThetaPhotonInTRS = Theta;} // - void SetPhiPhotonInTRS(Float_t Phi) {fPhiPhotonInTRS = Phi;} // - void SetThetaPhotonInDRS(Float_t Theta) {fThetaPhotonInDRS = Theta;} // - void SetPhiPhotonInDRS(Float_t Phi) {fPhiPhotonInDRS = Phi;} // - void SetThetaAtQuartz(Float_t ThetaAtQuartz) {fThetaAtQuartz = ThetaAtQuartz;} // - void SetPhiPoint(Float_t PhiPoint){ fPhiPoint[fPhotonIndex] = PhiPoint;} // - void SetXCoordOfEmission(Float_t XEmiss) {fXEmiss = XEmiss;} // - void SetYCoordOfEmission(Float_t YEmiss) {fYEmiss = YEmiss;} // - void SetXPointOnCathode(Float_t PhotonLimitX) { fPhotonLimitX = PhotonLimitX;} // - void SetYPointOnCathode(Float_t PhotonLimitY) { fPhotonLimitY = PhotonLimitY;} // - void SetXInnerRing(Float_t XInner) {fXInner = XInner;} // - void SetYInnerRing(Float_t YInner) {fYInner = YInner;} // - void SetRadiusInnerRing(Float_t InnerRadius) {fInnerRadius = InnerRadius;} // - void SetXOuterRing(Float_t XOuter) {fXOuter = XOuter;} // - void SetYOuterRing(Float_t YOuter) {fYOuter = YOuter;} // - void SetRadiusOuterRing(Float_t OuterRadius) {fOuterRadius = OuterRadius;} // - void SetThetaCerenkov(Float_t ThetaCer) {fThetaCerenkov = ThetaCer;} // - void SetThetaPhotonCerenkov(Float_t ThetaPhotCer) {fThetaPhotonCerenkov = ThetaPhotCer;} // - void SetTrackTheta(Float_t TrackTheta) { fTrackTheta = TrackTheta;} // - void SetTrackPhi(Float_t TrackPhi) { fTrackPhi = TrackPhi;} // - void SetShiftX(Float_t ShiftX) { fShiftX = ShiftX;} // - void SetShiftY(Float_t ShiftY) { fShiftY = ShiftY;} // - void SetDetectorWhereX(Float_t Xcoord) { fXcoord = Xcoord;} // - void SetDetectorWhereY(Float_t Ycoord) { fYcoord = Ycoord;} // - void SetIntersectionX(Float_t IntersectionX) { fIntersectionX = IntersectionX;} // - void SetIntersectionY(Float_t IntersectionY) { fIntersectionY = IntersectionY;} // - void SetThetaOfRing(Float_t ThetaOfRing) { fThetaOfRing = ThetaOfRing;} // - void SetAreaOfRing(Float_t AreaOfRing) { fAreaOfRing = AreaOfRing;} // - void SetPortionOfRing(Float_t PortionOfRing) { fPortionOfRing = PortionOfRing;} // - void SetHoughArea(Float_t HoughArea) { fHoughArea = HoughArea;} // - void SetPhotonsNumber(Int_t PhotonsNumber) { fPhotonsNumber = PhotonsNumber;} // - void SetPhotonIndex(Int_t PhotonIndex) { fPhotonIndex = PhotonIndex;} // - void SetPhotonEta(Float_t PhotonEta) { fPhotonEta[fPhotonIndex] = PhotonEta;} // - void SetPhotonFlag(Int_t PhotonFlag) { fPhotonFlag[fPhotonIndex] = PhotonFlag;} // - void SetPhotonWeight(Float_t PhotonWeight) { fPhotonWeight[fPhotonIndex] = PhotonWeight;} // - void SetPhotBKG(Double_t nPhotBKG) {fnPhotBKG=nPhotBKG;} // - void SetHoughRMS(Float_t HoughRMS) { fHoughRMS = HoughRMS;} // - void SetFittedTrackTheta(Float_t FittedTrackTheta) { fFittedTrackTheta = FittedTrackTheta;} // - void SetFittedTrackPhi(Float_t FittedTrackPhi) { fFittedTrackPhi = FittedTrackPhi;} // - void SetFittedThetaCerenkov(Float_t FittedThetaCerenkov) { fFittedThetaCerenkov = FittedThetaCerenkov;}// - void SetFittedHoughPhotons(Int_t FittedHoughPhotons) { fFittedHoughPhotons = FittedHoughPhotons;} // - void SetRingSigma2(Float_t RingSigma2) { fRingSigma2 = RingSigma2;} // - Float_t SnellAngle(Float_t n1, Float_t n2, Float_t theta1); // - Float_t FromEmissionToCathode(); // - + + Double_t CkovAngle (TClonesArray *pCluLst,Int_t &iNaccepted); //reconstructed Theta Cerenkov + Double_t CkovSigma2 ( )const{ return fCkovSigma2;} //track ckov angle error squared + Double_t FindPhotCkov (Double_t cluX,Double_t cluY ); //find ckov angle for single photon candidate + Double_t FindPhotPhi (Double_t cluX,Double_t cluY ); //find phi angle for single photon candidate + Double_t FindRingCkov (Int_t iNclus ); //best ckov for ring formed by found photon candidates + Double_t FindRingArea (Double_t ckov )const;//estimated area of ring in cm^2 + Int_t FlagPhot (Double_t ckov ); //is photon ckov near most probable track ckov + Double_t HoughResponse( ); //most probable track ckov angle + void Propagate (const TVector3 &dir, TVector3 &pos,Double_t z )const;//propagate photon alogn the line + void Refract ( TVector3 &dir, Double_t n1, Double_t n2 )const;//refract photon on the boundary + Double_t TracePhoton (Double_t ckovTh,Double_t ckovPh,TVector2 &pos )const;//trace photon created by track to PC + + Double_t SigLoc (Double_t ckovTh,Double_t ckovPh,Double_t trkTh,Double_t trkPh,Double_t beta)const; //localization error + Double_t SigGeom (Double_t ckovTh,Double_t ckovPh,Double_t trkTh,Double_t trkPh,Double_t beta)const; //geometry error + Double_t SigCrom (Double_t ckovTh,Double_t ckovPh,Double_t trkTh,Double_t trkPh,Double_t beta)const; //cromasity error + Double_t Sigma2 (Double_t ckovTh,Double_t ckovPh,Double_t trkTh,Double_t trkPh )const; //photon candidate sigma + void SetTrack(Double_t th,Double_t ph,Double_t x,Double_t y){ fTrkDir.SetMagThetaPhi(1,th,ph); fTrkPos.Set(x,y);}//set track info + + const static Double_t fkRadThick; //radiator thickness + const static Double_t fkWinThick; //window thickness + const static Double_t fkGapThick; //proximity gap thickness + const static Double_t fkRadIdx; //mean refractive index of RAD material (C6F14) + const static Double_t fkWinIdx; //mean refractive index of WIN material (SiO2) + const static Double_t fkGapIdx; //mean refractive index of GAP material (CH4) + protected: - Int_t fPhotonsNumber; // Number of photons candidate - Int_t fPhotonIndex; // index of photons - Int_t fPhotonFlag[3000]; // flag for photons - Int_t fFittedHoughPhotons; // n. photons after Hough and after minimization - Int_t fMinNumPhots; // minimum number of photons for a given ring + Int_t fPhotCnt; // counter of photons candidate + Int_t fPhotFlag[3000]; // flags of photon candidates + Double_t fPhotCkov[3000]; // Ckov angles of photon candidates, [rad] + Double_t fPhotPhi [3000]; // phis of photons candidates, [rad] + Double_t fPhotWei [3000]; // weigths of photon candidates + Double_t fCkovSigma2; // sigma2 of the reconstructed ring - Float_t fTrackTheta; // Theta of track at RICH - Float_t fTrackPhi; // Phi of track at RICH - Float_t fMinDist; // min distance between extrapolated track and MIP - Float_t fTrackBeta; // beta of the track - Float_t fXtoentr; // X entrance to RICH - Float_t fYtoentr; // Y entrance to RICH - Float_t fThetaPhotonInTRS; // Theta of photon in the Track Reference System (TRS) - Float_t fPhiPhotonInTRS; // Phi of photon in TRS - Float_t fThetaPhotonInDRS; // Theta of photon in Detector Reference System (DRS) - Float_t fPhiPhotonInDRS; // Phi of photon in DRS - Float_t fThetaAtQuartz; // Theta at the quartz entrance - Float_t fPhiPoint[3000]; // array of phi of ring photons - Float_t fXEmiss; // x emission - Float_t fYEmiss; // y emission - Float_t fXInner; // X inner ring - Float_t fYInner; // Y inner ring - Float_t fXOuter; // X outer ring - Float_t fYOuter; // Y outer ring - Float_t fInnerRadius; // inner radius - Float_t fOuterRadius; // outer radius - Float_t fEphot; // photon energy - Float_t fLengthEmissionPoint; // lenght of emmission point - Float_t fPhotonLimitX; // X phys limit for photon - Float_t fPhotonLimitY; // Y phys limit for photon - Float_t fDistanceFromCluster; // distance from cluster - Float_t fCerenkovAnglePad; // cherenkov angle of pad - Float_t fThetaPhotonCerenkov; // theta cerenkov for photon - Float_t fShiftX; // x shift to entrance in radiator - Float_t fShiftY; // y shift to entrance in radiator - Float_t fXcoord; // .. - Float_t fYcoord; // .. - Float_t fIntersectionX; // .. - Float_t fIntersectionY; // .. - Float_t fMassHypotesis; // - Float_t fThetaOfRing; // theta of ring - Float_t fAreaOfRing; // area of the ring - Float_t fPortionOfRing; // fraction of the accepted ring - Float_t fHoughArea; // area Hough - Float_t fPhotonEta[3000]; // theta cerenkov of photon candidates - Float_t fPhotonWeight[3000]; // weigth - Float_t fHoughRMS; // rms Hough - Float_t fFittedTrackTheta; // theta track after minim. - Float_t fFittedTrackPhi; // phi track after minim. - Float_t fFittedThetaCerenkov; // thetacerenkov after minim. - Float_t fThetaMin,fThetaMax; // min max Bool_t fIsWEIGHT; // flag to consider weight procedure - Bool_t fIsBACKGROUND; // flag to simulate bkg Float_t fDTheta; // Step for sliding window Float_t fWindowWidth; // Hough width of sliding window - Int_t fNumEtaPhotons; // Number of photons - Int_t fEtaFlag[3000]; // flag for good photons - Float_t fEtaPhotons[3000]; // Cerenkov angle each photon - Float_t fWeightPhotons[3000]; // weight for each photon - Double_t fnPhotBKG; // # estimated BKG photons in the ring - Float_t fThetaCerenkov; // Theta angle for Hough - Float_t fWeightThetaCerenkov; // Theta Cerenkov angle weighted - Float_t fThetaPeakPos; // Peak position - Float_t fRingSigma2; // sigma2 of the reconstructed ring + TVector3 fTrkDir; //track direction in LORS + TVector2 fTrkPos; //track positon in LORS at the middle of radiator ClassDef(AliRICHRecon,0) }; diff --git a/RICH/AliRICHReconstructor.cxx b/RICH/AliRICHReconstructor.cxx index 141ebb03cdc..debb31a4cb6 100644 --- a/RICH/AliRICHReconstructor.cxx +++ b/RICH/AliRICHReconstructor.cxx @@ -14,19 +14,17 @@ **************************************************************************/ #include "AliRICHReconstructor.h" //class header -#include "AliRICH.h" //Reconstruct(...) -#include //Reconstruct(...) -#include //ConvertDigits uses gAlice -#include //RichAna() -#include //RichAna() -#include //RichAna() -#include //RichAna() -#include //RichAna() +#include "AliRICH.h" //Reconstruct() +#include "AliRICHCluster.h" //CluQA() +#include "AliRICHParam.h" //FillEsd() +#include //FillEsd() +#include //Reconstruct() for simulated digits +#include //Reconstruct() for raw digits +#include //Reconstruct() #include //CluQA() #include //CluQA() #include //CluQA() #include //CheckPR() -#include //Test() ClassImp(AliRICHReconstructor) //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -44,31 +42,30 @@ void AliRICHReconstructor::CluQA(AliRunLoader *pAL) TH1::AddDirectory(kFALSE); - TH1F* pQ=new TH1F("RichCluQdc" ,"All QDC;q [QDC]" ,4000 ,0 ,4000);// QDC hists - TH1F* pCerQ=new TH1F("RichCluCerQdc" ,"Ckov QDC;q [QDC]" ,4000 ,0 ,4000); - TH1F* pMipQ=new TH1F("RichCluMipQdc" ,"MIP QDC;q [QDC]" ,4000 ,0 ,4000); + TH1F* pQ=new TH1F("RiAllQ" ,"Charge All" ,4000 ,0 ,4000);// Q hists + TH1F* pCerQ=new TH1F("RiCerQ" ,"Charge Ckov" ,4000 ,0 ,4000); + TH1F* pMipQ=new TH1F("RiMipQ" ,"Charge MIP" ,4000 ,0 ,4000); TH1F* pS=new TH1F("RichCluSize" ,"Cluster size;size" ,100 ,0 ,100 );// size hists TH1F* pCerS=new TH1F("RichCluCerSize" ,"Ckov size;size" ,100 ,0 ,100 ); TH1F* pMipS=new TH1F("RichCluMipSize" ,"MIP size;size" ,100 ,0 ,100 ); - TH2F* pM=new TH2F("RichCluMap" ,"Cluster map;x [cm];y [cm]" ,1000 ,0 ,AliRICHParam::PcSizeX(),1000,0,AliRICHParam::PcSizeY()); // maps - TH2F* pMipM=new TH2F("RichCluMipMap" ,"MIP map;x [cm];y [cm]" ,1000 ,0 ,AliRICHParam::PcSizeX(),1000,0,AliRICHParam::PcSizeY()); - TH2F* pCerM=new TH2F("RichCluCerMap" ,"Ckov map;x [cm];y [cm]" ,1000 ,0 ,AliRICHParam::PcSizeX(),1000,0,AliRICHParam::PcSizeY()); + TH2F* pM=new TH2F("RichCluMap" ,"Cluster map;x [cm];y [cm]" ,1000 ,0 ,AliRICHDigit::SizePcX(),1000,0,AliRICHDigit::SizePcY()); // maps + TH2F* pMipM=new TH2F("RichCluMipMap" ,"MIP map;x [cm];y [cm]" ,1000 ,0 ,AliRICHDigit::SizePcX(),1000,0,AliRICHDigit::SizePcY()); + TH2F* pCerM=new TH2F("RichCluCerMap" ,"Ckov map;x [cm];y [cm]" ,1000 ,0 ,AliRICHDigit::SizePcX(),1000,0,AliRICHDigit::SizePcY()); - TClonesArray *pCluLst=new TClonesArray("AliRICHCluster");//tmp list of clusters - for(Int_t iEvtN=0; iEvtNGetEvent(iEvtN); + for(Int_t iEvt=0;iEvtGetEvent(iEvt); pRL->TreeD()->GetEntry(0); - for(Int_t iChN=1;iChN<=AliRICHParam::kNch;iChN++){//chambers loop - if(pRich->Digs(iChN)->GetEntriesFast()>0) Dig2Clu(pRich->Digs(iChN),pCluLst,kFALSE);//cluster finder for the current chamber if any digits present - }//chambers loop + TClonesArray *pCluLst=new TClonesArray("AliRICHCluster");//tmp list of clusters for this event + + for(Int_t iCh=0;iCh<7;iCh++) Dig2Clu(pRich->DigLst(iCh),pCluLst,kFALSE);//cluster finder for all chamber if any digits present - for(Int_t iCluN=0 ; iCluN < pCluLst->GetEntriesFast() ; iCluN++){ - AliRICHCluster *pClu = (AliRICHCluster*)pCluLst->At(iCluN); - Int_t cfm=0; for(Int_t iDig=0;iDigSize();iDig++) cfm+=pClu->Dig(iDig)->Cfm(); //collect ckov-fee-mip structure of current cluster + for(Int_t iClu=0;iCluGetEntriesFast();iClu++){ + AliRICHCluster *pClu = (AliRICHCluster*)pCluLst->At(iClu); + Int_t cfm=0; for(Int_t iDig=0;iDigSize();iDig++) cfm+=pClu->Dig(iDig)->Ch(); //collect ckov-fee-mip structure of current cluster ????? Int_t iNckov=cfm/1000000; Int_t iNfee =cfm%1000000/1000; Int_t iNmip =cfm%1000000%1000; pQ ->Fill(pClu->Q()) ; pS ->Fill(pClu->Size()) ; pM ->Fill(pClu->X(),pClu->Y()); //all clusters @@ -76,6 +73,7 @@ void AliRICHReconstructor::CluQA(AliRunLoader *pAL) if(iNckov==0 && iNfee==0 && iNmip!=0) {pMipQ->Fill(pClu->Q()) ; pMipS->Fill(pClu->Size()) ; pMipM ->Fill(pClu->X(),pClu->Y());}//mip only cluster }//clusters loop + pCluLst->Clear();delete pCluLst; }//events loop pRL->UnloadDigits(); pAL->UnloadKinematics(); pAL->UnloadHeader(); @@ -85,68 +83,52 @@ void AliRICHReconstructor::CluQA(AliRunLoader *pAL) pC->cd(7); pCerM->Draw(); pC->cd(8); pCerQ->Draw(); pC->cd(9); pCerS->Draw(); }//CluQA() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHReconstructor::CheckPR() -{ -//Pattern recognition with stack particles - TFile *pFile = new TFile("$(HOME)/RPR.root","RECREATE","RICH Pattern Recognition"); - TNtupleD *hn = new TNtupleD("hn","ntuple","Pmod:Charge:TrackTheta:TrackPhi:TrackX:TrackY:MinX:MinY:ChargeMIP:ThetaCerenkov:NPhotons:MipIndex:Chamber:Particle"); -// printf("\n\n"); -// printf("Pattern Recognition done for event %5i",0); - AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH")); - AliMagF * magf = gAlice->Field(); - AliTracker::SetFieldMap(magf,kTRUE); - for(Int_t iEvtN=0;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 +// Finds all clusters for a given digits list provided not empty. Currently digits list is a list of all digits for a single chamber. +// Puts all found clusters in separate lists, one per clusters. +// Arguments: pDigLst - list of digits provided not empty +// pCluLst - list of clusters, provided empty +// isTryUnfold - flag to choose between CoG and Mathieson fitting // Returns: none - TMatrixF digMap(1,AliRICHParam::NpadsX(),1,AliRICHParam::NpadsY()); digMap=(Float_t)-1; //digit map for one chamber reseted to -1 - for(Int_t iDigN=0 ; iDigN < pDigLst->GetEntriesFast() ; iDigN++){ //digits loop to fill digits map - AliRICHDigit *pDig= (AliRICHDigit*)pDigLst->At(iDigN); //get current digit - digMap( pDig->PadX(), pDig->PadY() )=iDigN; //fill the map, (padx,pady) cell takes digit index + TMatrixF digMap(AliRICHDigit::kPadAllX,AliRICHDigit::kPadAllY); digMap=(Float_t)-1; //digit map for single chamber reseted to -1 + for(Int_t iDig=0;iDigGetEntriesFast();iDig++){ //digits loop to fill digits map + AliRICHDigit *pDig= (AliRICHDigit*)pDigLst->At(iDig); //get current digit + digMap( pDig->PadX(), pDig->PadY() )=iDig; //fill the map, (padx,pady) cell takes digit index } //digits loop to fill digits map AliRICHCluster clu; //tmp cluster to be used as current - for(Int_t iDigN=0;iDigNGetEntriesFast();iDigN++){ //digits loop to form clusters list - AliRICHDigit *pDig=(AliRICHDigit*)pDigLst->At(iDigN); //take current digit + for(Int_t iDig=0;iDigGetEntriesFast();iDig++){ //digits loop to form clusters list + AliRICHDigit *pDig=(AliRICHDigit*)pDigLst->At(iDig); //take current digit if(!(pDig=UseDig(pDig->PadX(),pDig->PadY(),pDigLst,&digMap))) continue; //this digit is already taken in FormClu(), go after next digit FormClu(&clu,pDig,pDigLst,&digMap); //form cluster starting from this digit by recursion clu.Solve(pCluLst,isTryUnfold); //solve this cluster and add all unfolded clusters to provided list clu.Reset(); //empty current cluster } //digits loop to form clusters list }//Dig2Clu() -//__________________________________________________________________________________________________ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHReconstructor::FormClu(AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigLst,TMatrixF *pDigMap) { -//Forms the initial cluster as a sum of all adjascent digits. Starts from the given digit -//then calls itself recursevly for all neighbours. -//Arguments: pClu - pointer to cluster being formed +// Forms the initial cluster as a sum of all adjascent digits. Starts from the given digit +// then calls itself recursevly for all neighbours. +// Arguments: pClu - pointer to cluster being formed // Returns: none pClu->DigAdd(pDig);//take this digit in cluster Int_t x[4],y[4]; - Int_t iNnei=AliRICHParam::PadNeighbours(pDig->PadX(),pDig->PadY(),x,y);//returns in x,y all possible neighbours of the given padx,pady - for (Int_t i=0;iPadX(); Int_t iPadY=pDig->PadY(); + if(iPadX != AliRICHDigit::kPad1) {x[iPadCnt]=iPadX-1; y[iPadCnt]=iPadY; iPadCnt++;} //left + if(iPadX != AliRICHDigit::kPadPcX) {x[iPadCnt]=iPadX+1; y[iPadCnt]=iPadY; iPadCnt++;} //right + if(iPadY != AliRICHDigit::kPad1) {x[iPadCnt]=iPadX; y[iPadCnt]=iPadY-1; iPadCnt++;} //down + if(iPadY != AliRICHDigit::kPadPcY) {x[iPadCnt]=iPadX; y[iPadCnt]=iPadY+1; iPadCnt++;} //up + + for (Int_t i=0;iGetNumberOfEvents();iEvtN++){//events loop pAL->GetEvent(iEvtN); AliDebug(1,Form("Processing event %i...",iEvtN)); //switch current directory to next event pRL->TreeD()->GetEntry(0); pRL->MakeTree("R"); pRich->MakeBranch("R"); //load digits to memory and create branches for clusters - for(Int_t iChN=1;iChN<=7;iChN++){//chambers loop - if(pRich->Digs(iChN)->GetEntriesFast()>0) Dig2Clu(pRich->Digs(iChN),pRich->Clus(iChN));//cluster finder for the current chamber if any digits present - }//chambers loop + + for(Int_t iCh=0;iCh<7;iCh++) Dig2Clu(pRich->DigLst(iCh),pRich->CluLst(iCh));//cluster finder + pRL->TreeR()->Fill(); //fill tree for current event pRL->WriteRecPoints("OVERWRITE");//write out clusters for current event pRich->DigReset(); pRich->CluReset(); @@ -184,7 +166,6 @@ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const AliLoader *pRL=pAL->GetDetectorLoader("RICH"); AliRICH *pRich=(AliRICH*)pAL->GetAliRun()->GetDetector("RICH");//get pointers for RICH and RICH loader AliRICHDigit dig; //tmp digit, raw digit will be converted to it - TClonesArray *pDigList=new TClonesArray("AliRICHDigit"); Int_t iDigCnt=0; //tmp list of digits for single chamber only Int_t iEvtN=0; while(pRR->NextEvent()){//events loop @@ -192,17 +173,18 @@ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const pRL->MakeTree("R"); pRich->MakeBranch("R"); for(Int_t iChN=1;iChN<=7;iChN++){//chambers loop + TClonesArray *pDigLst=new TClonesArray("AliRICHDigit"); Int_t iDigCnt=0; //tmp list of digits for single chamber pRR->Select("RICH",2*iChN-2,2*iChN-1);//select only DDL files for the current chamber UInt_t w32=0; while(pRR->ReadNextInt(w32)){//raw records loop (in selected DDL files) UInt_t ddl=pRR->GetDDLID(); //returns 0,1,2 ... 13 - dig.Raw2Dig(ddl,w32); - AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iChN,ddl,w32,dig.C(),dig.S(),dig.PadX(),dig.PadY(),dig.Qdc())); - new((*pDigList)[iDigCnt++]) AliRICHDigit(dig); //add this digit to the tmp list + dig.ReadRaw(ddl,w32); + AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iChN,ddl,w32,dig.Ch(),dig.Pc(),dig.PadX(),dig.PadY(),dig.Q())); + new((*pDigLst)[iDigCnt++]) AliRICHDigit(dig); //add this digit to the tmp list }//raw records loop - if(iDigCnt) Dig2Clu(pDigList,pRich->Clus(iChN));//cluster finder for the current chamber if any digits present + if(iDigCnt) Dig2Clu(pDigLst,pRich->CluLst(iChN));//cluster finder for the current chamber if any digits present pRR->Reset(); - pDigList->Delete(); iDigCnt=0;//clean up list of digits for the current chamber + pDigLst->Delete(); iDigCnt=0;//clean up list of digits for the current chamber }//chambers loop pRL->TreeR()->Fill(); //fill tree for current event pRL->WriteRecPoints("OVERWRITE");//write out clusters for current event @@ -211,64 +193,6 @@ void AliRICHReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const pRL->UnloadRecPoints(); }//Reconstruct raw data //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHReconstructor::Test(Bool_t isTryUnfold) -{ -// Test the cluster finding algorithm by providing predifined set of digits -// Arguments: none -// Returns: none - TClonesArray *pDigTst=new TClonesArray("AliRICHDigit"); TClonesArray *pCluTst=new TClonesArray("AliRICHCluster"); - Int_t iDigCnt=0; - Int_t c,padx,pady,qdc; -//ckov cluster - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 89,pady=13),qdc= 10); - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 90,pady=13),qdc= 7); - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 90,pady=12),qdc= 6); - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 91,pady=12),qdc= 7); -//mip cluster - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 99,pady=21),qdc= 9); - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx= 99,pady=22),qdc= 26); - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx=100,pady=21),qdc= 39); - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx=100,pady=22),qdc=109); - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx=100,pady=23),qdc= 7); - new((*pDigTst)[iDigCnt++]) AliRICHDigit(AliRICHDigit::P2A(c=1,padx=101,pady=22),qdc= 11); - - Printf("Initial digits (1 ckov cluster and 1 mip cluster):"); pDigTst->Print(); - Dig2Clu(pDigTst,pCluTst,isTryUnfold); - Printf("Resulting clusters (expecting to have 2):"); pCluTst->Print(); - delete pDigTst; delete pCluTst; -}//Test() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHReconstructor::Test(TClonesArray *pDigLst,Bool_t isTryUnfold) -{ -// Test the cluster finding algorithm for given list of digits. Note that list of digits will not be deleted. -// Arguments: pDigLst- list of digits -// Returns: none - TClonesArray *pCluLst=new TClonesArray("AliRICHCluster"); - Dig2Clu(pDigLst,pCluLst,isTryUnfold); - - Int_t iNdig=pDigLst->GetEntriesFast(); - Int_t iNclu=pCluLst->GetEntriesFast(); - - TH2F *pH2=new TH2F("RDH2",Form("Tst dig->clu Digs: %i Clus: %i;cm;cm",iNdig,iNclu),AliRICHParam::NpadsX(),0,AliRICHParam::PcSizeX(),AliRICHParam::NpadsY(),0,AliRICHParam::PcSizeY()); - pH2->SetStats(kFALSE); - for(Int_t iDig=0;iDig < iNdig;iDig++) {//digits loop - AliRICHDigit *pDig = (AliRICHDigit*)pDigLst->At(iDig); - TVector2 x2=AliRICHParam::Pad2Loc(pDig->Pad()); - pH2->Fill(x2.X(),x2.Y(),pDig->Qdc()); - }//digits loop - - TPolyMarker *pCluMarker=new TPolyMarker(iNclu); pCluMarker->SetMarkerStyle(5); pCluMarker->SetMarkerColor(kBlue); - for(Int_t iClu=0;iClu < iNclu;iClu++) {//clusters loop - AliRICHCluster *pClu = (AliRICHCluster*)pCluLst->At(iClu); - pCluMarker->SetNextPoint(pClu->X(),pClu->Y()); - }//digits loop - - pH2->Draw("col"); - pCluMarker->Draw(); - AliRICHParam::DrawSectors(); - delete pCluLst; -}//Test() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHReconstructor::FillESD(AliRunLoader *, AliESD *pESD) const { @@ -278,36 +202,36 @@ void AliRICHReconstructor::FillESD(AliRunLoader *, AliESD *pESD) const AliPID ppp; //needed Double_t pid[AliPID::kSPECIES],h[AliPID::kSPECIES]; - Double_t refIndex=AliRICHParam::Instance()->IdxC6F14(AliRICHParam::EckovMean()); for(Int_t iTrk=0;iTrkGetNumberOfTracks();iTrk++){//ESD tracks loop - AliESDtrack *pTrack = pESD->GetTrack(iTrk);// get next reconstructed track - if(pTrack->GetRICHsignal()<=0){//RICH does not find anything reasonable for this track, assign 0.2 for all species + AliESDtrack *pTrk = pESD->GetTrack(iTrk);// get next reconstructed track + if(pTrk->GetRICHsignal()<=0){//RICH does not find anything reasonable for this track, assign 0.2 for all species for(Int_t iPart=0;iPartSetRICHpid(pid); + pTrk->SetRICHpid(pid); continue; } - Double_t pmod = pTrack->GetP(); + Double_t pmod = pTrk->GetP(); Double_t hTot=0; for(Int_t iPart=0;iPartMeanIdxRad()*pmod); if(cosThetaTh<1) //calculate the height of theortical theta ckov on the gaus of experimental one - h[iPart] =TMath::Gaus(TMath::ACos(cosThetaTh),pTrack->GetRICHsignal(),TMath::Sqrt(pTrack->GetRICHchi2()),kTRUE); + h[iPart] =TMath::Gaus(TMath::ACos(cosThetaTh),pTrk->GetRICHsignal(),TMath::Sqrt(pTrk->GetRICHchi2()),kTRUE); else //beta < 1/ref. idx. => no light at all h[iPart] =0 ; hTot +=h[iPart]; //total height of all theoretical heights for normalization }//species loop - Double_t hMin=TMath::Gaus(pTrack->GetRICHsignal()-4*TMath::Sqrt(pTrack->GetRICHchi2()),pTrack->GetRICHsignal(),TMath::Sqrt(pTrack->GetRICHchi2()),kTRUE);//5 sigma protection + Double_t hMin=TMath::Gaus(pTrk->GetRICHsignal()-4*TMath::Sqrt(pTrk->GetRICHchi2()),pTrk->GetRICHsignal(),TMath::Sqrt(pTrk->GetRICHchi2()),kTRUE);//5 sigma protection for(Int_t iPart=0;iParthMin) pid[iPart]=h[iPart]/hTot; else //all theoretical values are far away from experemental one pid[iPart]=1.0/AliPID::kSPECIES; - pTrack->SetRICHpid(pid); + pTrk->SetRICHpid(pid); }//ESD tracks loop //last line is to check if the nearest thetacerenkov to the teorethical one is within 5 sigma, otherwise no response (equal prob to every particle }//FillESD +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHReconstructor.h b/RICH/AliRICHReconstructor.h index 53bcf76fc25..136ae34d312 100644 --- a/RICH/AliRICHReconstructor.h +++ b/RICH/AliRICHReconstructor.h @@ -31,11 +31,8 @@ public: //private part static void Dig2Clu (TClonesArray*pDigLst,TClonesArray *pCluLst,Bool_t isTryUnfold=kTRUE );//digits list -> clusters list static void CluQA (AliRunLoader* pAL );//QA for clusters - static void CheckPR ( );//utility-> run staff for stack static void FormClu (AliRICHCluster *pClu,AliRICHDigit *pDig,TClonesArray *pDigLst,TMatrixF *pDigMap);//cluster formation recursive algorithm static inline AliRICHDigit* UseDig (Int_t padX,Int_t padY,TClonesArray *pDigList,TMatrixF *pDigMap );//use this pad's digit to form a cluster - static void Test (Bool_t isTryUnfold=kTRUE );//test digits->clusters conversion - static void Test (TClonesArray *pDigLst,Bool_t isTryUnfold=kTRUE );//test digits->clusters conversion protected: ClassDef(AliRICHReconstructor, 0) //class for the RICH reconstruction diff --git a/RICH/AliRICHTracker.cxx b/RICH/AliRICHTracker.cxx index b4876601b31..c0912ec01fe 100644 --- a/RICH/AliRICHTracker.cxx +++ b/RICH/AliRICHTracker.cxx @@ -2,6 +2,7 @@ #include "AliRICH.h" #include "AliRICHRecon.h" #include "AliRICHParam.h" +#include "AliRICHCluster.h" #include #include //EsdQA() #include @@ -27,8 +28,6 @@ AliRICHTracker::AliRICHTracker():AliTracker() // AliRICHTracker is created from AliReconstraction::Run() which invokes AliReconstraction::CreateTrackers() // which in turn invokes AliRICHReconstructor::CreateTracker(). // Note that this is done just once per session before AliReconstruction::Run() goes to events loop. - AliRICHParam::Instance()->CdbRead(0,0); - for(Int_t i=0;i<5;i++)fErrPar[i]=0; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Bool_t AliRICHTracker::GetTrackPoint(Int_t idx, AliTrackPoint& point) const @@ -43,7 +42,7 @@ Bool_t AliRICHTracker::GetTrackPoint(Int_t idx, AliTrackPoint& point) const Int_t iClu=idx%1000000; point.SetVolumeID(AliAlignObj::LayerToVolUID(AliAlignObj::kRICH,iCham-1));//layer and chamber number AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH")); - AliRICHCluster *pClu=(AliRICHCluster*)pRich->Clus(iCham)->UncheckedAt(iClu);//get pointer to cluster + AliRICHCluster *pClu=(AliRICHCluster*)pRich->CluLst(iCham)->UncheckedAt(iClu);//get pointer to cluster TVector3 mars=AliRICHParam::Instance()->Lors2Mars(iCham,pClu->X(),pClu->Y()); point.SetXYZ(mars.X(),mars.Y(),mars.Z()); return kTRUE; @@ -51,7 +50,7 @@ Bool_t AliRICHTracker::GetTrackPoint(Int_t idx, AliTrackPoint& point) const //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Int_t AliRICHTracker::LoadClusters(TTree *pCluTree) { -// Interface callback methode invoked from AliReconstruction::RunTracking() to load RICH clusters for RICH +// Interface callback methode invoked from AliReconstruction::RunTracking() to load RICH clusters before PropagateBack() gets control // Arguments: pCluTree- pointer to clusters tree got by AliRICHLoader::LoadRecPoints("read") then AliRICHLoader::TreeR() // Returns: error code (currently ignored in AliReconstruction::RunTraking()) AliDebug(1,"Start."); pCluTree->GetEntry(0); AliDebug(1,"Stop."); return 0; @@ -64,265 +63,63 @@ Int_t AliRICHTracker::PropagateBack(AliESD *pESD) // Returns: error code, 0 if no errors Int_t iNtracks=pESD->GetNumberOfTracks(); AliDebug(1,Form("Start with %i tracks",iNtracks)); AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH")); - AliRICHRecon recon; - Int_t nphots =0; + AliRICHRecon recon; //instance of reconstruction class, nothing important in ctor - for(Int_t iTrk=0;iTrkGetTrack(iTrk);// get next reconstructed track - Double_t mom[3], pos[3]; - pTrk->GetPxPyPz(mom); TVector3 mom3(mom[0],mom[1],mom[2]); - pTrk->GetXYZ(pos); TVector3 pos3(pos[0],pos[1],pos[2]); - AliRICHHelix helix(pos3,mom3,(Int_t)pTrk->GetSign(),-0.1*GetBz()); //construct helix out of track running parameters - //Printf(" magnetic field %f charged %f\n",GetBz(),pTrack->GetSign()); helix.Print("Track"); - Int_t iChamber=helix.RichIntersect(AliRICHParam::Instance()); - if(!iChamber) continue; //no intersection with chambers, ignore this track go after the next one - - //find MIP cluster candidate (closest to track intersection point cluster with large enough QDC) - Double_t dR=9999, dX=9999, dY=9999; //distance between track-PC intersection point and current cluster - Double_t mipDr=9999,mipDx=9999,mipDy=9999,mipX=9999,mipY=9999; Int_t mipQ=0; //nearest cluster parameters - Int_t iMipId=-1; //index of this nearest cluster - for(Int_t iClu=0;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(dRX(); mipY=pClu->Y(); mipQ=pClu->Q();} //current cluster is closer, overwrite data for min cluster - }//clusters loop for intersected chamber + AliRICHParam *pParam=AliRICHParam::Instance(); - pTrk->SetRICHthetaPhi(helix.Ploc().Theta(),helix.Ploc().Phi()); //store track impact angles with respect to RICH planes - pTrk->SetRICHdxdy(mipDx,mipDy); //distance between track-PC intersection and closest cluster with Qdc>100 - pTrk->SetRICHmipXY(mipX,mipY); //position of that closest cluster with Qdc>100 - pTrk->SetRICHnclusters(1000000*mipQ); //charge of that closest cluster with Qdc>100 - - if(iMipId==-1) {pTrk->SetRICHsignal(kMipQdcCut); continue;} //no cluster with enough QDC found - if(mipDr>AliRICHParam::DmatchMIP()) {pTrk->SetRICHsignal(kMipDistCut); continue;} //closest cluster with enough carge is still too far - - pTrk->SetRICHcluster(iMipId+1000000*iChamber); //set mip cluster index - pTrk->SetRICHsignal(recon.ThetaCerenkov(&helix,pRich->Clus(iChamber),nphots));//search for mean Cerenkov angle for this track - pTrk->SetRICHnclusters(1000000*mipQ+nphots); //on return nphots is number of photon clusters accepted in reconstruction - pTrk->SetRICHchi2(recon.GetRingSigma2()); - - AliDebug(1,Form("Ch=%i PC Intersection=(%5.2f,%5.2f) cm MIP cluster dist=(%5.2f,%5.2f)=%5.2f cm ThetaCkov=%f", - iChamber,helix.PosPc().X(),helix.PosPc().Y(), mipDx,mipDy,mipDr, pTrk->GetRICHsignal())); - -//here comes PID calculations -// CalcProb(pTrack->GetRICHsignal(),pTrack->GetP(),sigmaPID,richPID); - }//ESD tracks loop - AliDebug(1,"Stop pattern recognition"); - return 0; // error code: 0=no error; -}//PropagateBack() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHTracker::RecWithStack(TNtupleD *hn) -{ -// Reconstruction for particles from STACK. This methode is to be used for RICH standalone when no other detectors are switched on, so normal tracking is not available. -// Arguments: hn- output ntuple where to store all variables -// Returns: none - AliDebug(1,"Start."); - AliRICH *pRich=((AliRICH*)gAlice->GetDetector("RICH")); - -// pRich->GetLoader()->GetRunLoader()->LoadHeader(); - if(!pRich->GetLoader()->GetRunLoader()->TreeK()) pRich->GetLoader()->GetRunLoader()->LoadKinematics(); - AliStack *pStack = pRich->GetLoader()->GetRunLoader()->Stack(); - if(!pStack) {AliDebug(1,Form("No STACK found in AliRoot"));return;} - Int_t iNtracks=pStack->GetNtrack(); - AliDebug(1,Form(" Start reconstruction with %i track(s) from Stack",iNtracks)); - - Double_t hnvec[20]; - - Double_t b=GetFieldMap()->SolenoidField()/10;// magnetic field in Tesla - AliDebug(1,Form("Start with simulated %i tracks in %f Tesla field",iNtracks,b)); - TVector3 x0(0,0,0); TVector3 p0(0,0,0);//tmp storage for AliRICHHelix - - - if(pRich->GetLoader()->LoadRecPoints()) {AliDebug(1,Form("No clusters found in RICH"));return;} - pRich->GetLoader()->TreeR()->GetEntry(0); - - AliRICHRecon recon; - for(Int_t iTrackN=0;iTrackNParticle(iTrackN); - if(!pParticle) {AliDebug(1,Form("Not a valid TParticle pointer. Track skipped"));continue;} - AliDebug(1,Form(" PDG code : %i",pParticle->GetPdgCode())); -// -// problem of PDG code of some extra particles to be solved!!!!!!!!! -// -// found problem! Look in TRD directory : codes from Fluka are : -// -// if ((pdg_code == 10010020) || -// (pdg_code == 10010030) || -// (pdg_code == 50000050) || -// (pdg_code == 50000051) || -// (pdg_code == 10020040)) { -// - if(pParticle->GetPdgCode()>=50000050||pParticle->GetPdgCode()==0||pParticle->GetPdgCode()>10000) {AliDebug(1,Form("A photon as track... Track skipped"));continue;} - if(!pParticle->GetPDG()) continue; -// -// to be updated for us!! -// - AliDebug(1,Form("Track %i is a %s with charge %i and momentum %f", - iTrackN,pParticle->GetPDG()->GetName(),Int_t(pParticle->GetPDG()->Charge()),pParticle->P())); -// if(pParticle->GetMother(0)!=-1) continue; //consider only primaries - if(pParticle->GetPDG()->Charge()==0||TMath::Abs(Int_t(pParticle->GetPDG()->Charge()))!=3) continue; //to avoid photons from stack... - hnvec[0]=pParticle->P(); - hnvec[1]=pParticle->GetPDG()->Charge(); - - p0.SetMagThetaPhi(pParticle->P(),pParticle->Theta(),pParticle->Phi()); x0.SetXYZ(pParticle->Vx(),pParticle->Vy(),pParticle->Vz()); - AliRICHHelix helix(x0,p0,TMath::Sign(1,(Int_t)pParticle->GetPDG()->Charge()),b); - Int_t iChamber=helix.RichIntersect(AliRICHParam::Instance()); - if(!iChamber) continue;// no intersection with RICH found - - hnvec[2]=helix.Ploc().Theta(); - hnvec[3]=helix.Ploc().Phi(); - hnvec[4]=helix.PosPc().X(); - hnvec[5]=helix.PosPc().Y(); - - Double_t dX,dY,dR,dRmip=9999; //min distance between clusters and track position on PC - Int_t iMipId=-1; //index of that min distance cluster - for(Int_t iClu=0;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 + for(Int_t iTrk=0;iTrkGetTrack(iTrk); //get next reconstructed track + + Float_t xRa=0,yRa=0,xPc=0,yPc=0,th=0,ph=0; //track intersection point and angles, LORS + Int_t iCh=-1; //intersected chamber + for(Int_t i=0;i<7;i++){ //chambers loop + Double_t p1[3],n1[3]; pParam->Norm(i,n1); pParam->Lors2Mars(i,0,0,p1,AliRICHParam::kRad); //point & norm for RAD + Double_t p2[3],n2[3]; pParam->Norm(i,n2); pParam->Lors2Mars(i,0,0,p2,AliRICHParam::kPc); //point & norm for PC + + if(pTrk->Intersect(p1,n1,-GetBz())==kFALSE) continue; //try to intersect track with the middle of radiator + if(pTrk->Intersect(p2,n2,-GetBz())==kFALSE) continue; //try to intersect track with PC + + pParam->Mars2LorsVec(i,n1,th,ph); //track angles + pParam->Mars2Lors (i,p1,xRa,yRa); //TRKxRAD position + pParam->Mars2Lors (i,p2,xPc,yPc); //TRKxPC position - }//clusters loop for intersected chamber + if(AliRICHDigit::IsInside(xPc,yPc)==kFALSE) continue; //not in active area + iCh=i; + break; + }//chambers loop + if(iCh==-1) continue; //no intersection at all, go after next track - hnvec[9]=recon.ThetaCerenkov(&helix,pRich->Clus(iChamber),iMipId); //search for mean Cerenkov angle for this track - hnvec[10]=iMipId;//on return from ThetaCerenkov() contains number of photon candidates accepted - hnvec[11]=(Double_t)iMipId; - hnvec[12]=(Double_t)iChamber; - hnvec[13]=(Double_t)pParticle->GetPdgCode(); - if(hn) hn->Fill(hnvec); - AliDebug(1,Form("FINAL Theta Cerenkov=%f",hnvec[9])); - }//stack particles loop - - pRich->GetLoader()->UnloadRecPoints(); - AliDebug(1,"Stop."); -}//RecWithStack -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHTracker::EsdQA(Bool_t isPrint) -{ -// Reads ESD file and print out or plot some information for QA -// Arguments: isPrint is a flag to choose between printing (isPrint = kTRUE) and plotting (isPrint = kFALSE) -// Returns: none + TClonesArray *pCluLst=pRich->CluLst(iCh); //get clusters list for intersected chamber - TFile *pFile=TFile::Open("AliESDs.root","read"); if(!pFile) {Printf("ERROR: AliESDs.root does not exist!");return;} - TTree *pTr=(TTree*)pFile->Get("esdTree"); if(!pTr) {Printf("ERROR: AliESDs.root, no ESD tree inside!");return;} - AliESD *pEsd=new AliESD; pTr->SetBranchAddress("ESD", &pEsd); - - TH1D *pProbEl=0,*pProbMu=0,*pProbPi=0,*pProbKa=0,*pProbPr=0,*pMom=0,*pMipQ=0; - TH2F *pThP=0,*pDxDy=0; - TProfile *pChiTh=0; - if(!isPrint){ - TH1::AddDirectory(kFALSE); - pProbEl=new TH1D("RiProbE" ,"Prob e" ,101 ,0 ,1.05); pProbEl->SetLineColor(kGreen); - pProbPi=new TH1D("RiProbPi","Prob #pi" ,101 ,0 ,1.05); pProbPi->SetLineColor(kRed); - pProbMu=new TH1D("RiProbMu","Prob #mu" ,101 ,0 ,1.05); pProbMu->SetLineColor(kBlue); - pProbKa=new TH1D("RiProbK" ,"Prob K" ,101 ,0 ,1.05); - pProbPr=new TH1D("RiProbP" ,"Prob p" ,101 ,0 ,1.05); - pMom =new TH1D("pMom" ,"Track P, GeV" ,200 ,0 ,20 ); - pMipQ =new TH1D("RiMipQ" ,"Mip Q, ADC" ,2000 ,0 ,4000); - pThP =new TH2F("RiThP" ,"#theta_{Ckov} radian;P GeV" ,65 ,-0.5,6.0,75,0,0.75); pThP->SetStats(0); - pDxDy =new TH2F("RiDxDy" ,"distance between mip and track;cm",300,-2.5,2.5, 300,-2.5,2.5); - pChiTh =new TProfile("RiChiTh","#chi^{2};#theta_{C}" ,80 ,0,0.8 , -2,2); - } - - Int_t iEvtCnt=0,iTrkCnt=0,iGoodCnt=0; Float_t bz=0; - for(Int_t iEvt=0;iEvtGetEntries();iEvt++){//ESD events loop - pTr->GetEvent(iEvt); iEvtCnt++; if(isPrint) Printf(""); - bz=pEsd->GetMagneticField()/10.; - for(Int_t iTrk=0;iTrkGetNumberOfTracks();iTrk++){//ESD tracks loop - AliESDtrack *pTrk=pEsd->GetTrack(iTrk); iTrkCnt++; //get next reconstructed track and increment total tracks counter + Double_t dMin=999; //distance between track-PC intersection point and current cluster + Int_t iMip=-1; //index of cluster nearest to intersection point + for(Int_t iClu=0;iCluGetEntries();iClu++){ //clusters loop for intersected chamber + AliRICHCluster *pClu=(AliRICHCluster*)pCluLst->At(iClu); //get pointer to current cluster + if(pClu->Q()<100) continue; //QDC is incompartible with mip, go after another one - Float_t mom =pTrk->GetP(); //track momentum - Double_t sign =pTrk->GetSign(); //track sign - Float_t ckov =pTrk->GetRICHsignal(); //Theta ckov for this track, rad - Float_t chi2 =pTrk->GetRICHchi2(); //Theta ckov error for this track, rad^2 - Int_t qdc =pTrk->GetRICHnclusters()/1000000; //Mip candidate charge, qdc - Int_t nphot =pTrk->GetRICHnclusters()%1000000; //number of photon candidates - Float_t dx,dy; pTrk->GetRICHdxdy(dx,dy); //distance between mip position and track instersection - Float_t theta,phi; pTrk->GetRICHthetaPhi(theta,phi); //track inclination angles in LORS - Double_t pid[5]; pTrk->GetRICHpid(pid); //pid vector + Float_t dX=xPc-pClu->X(); //distance between current cluster and intersection point + Float_t dY=yPc-pClu->Y(); + Float_t d =TMath::Sqrt(dX*dX+dY*dY); - if(ckov>0) iGoodCnt++; - if(isPrint){ - TString comment; - if(ckov>0) comment="OK"; - else if(ckov==kMipQdcCut) comment="small QDC"; - else if(ckov==kMipDistCut) comment="mip too far"; - else if(ckov==-1) comment="no intersection"; - Printf("Tr=%2i Q=%4.1f P=%.3f R=%4.2f Th=%6.3f MipQ= %4i Nph=%2i" " rad Prob : e=%.4f mu=%.4f pi=%.4f K=%.4f p=%.4f %s" , - iTrk,sign,mom,TMath::Sqrt(dx*dx+dy*dy),ckov,qdc,nphot, pid[0],pid[1],pid[2],pid[3],pid[4], comment.Data()); - }else{//collect hists - pMom->Fill(mom); - pMipQ->Fill(qdc); - pDxDy->Fill(dx,dy); - pThP->Fill(mom,ckov); - pChiTh->Fill(ckov,chi2); - pProbEl->Fill(pid[0]); - pProbMu->Fill(pid[1]); - pProbPi->Fill(pid[2]); - pProbKa->Fill(pid[3]); - pProbPr->Fill(pid[4]); - }//if plot - }//ESD tracks loop - }//ESD events loop - delete pEsd; pFile->Close();//close AliESDs.root - - TString summary=Form("Events: %i Tracks %i Good RICH: %i Mag Fld %.2f Tesla",iEvtCnt,iTrkCnt,iGoodCnt,bz); - if(isPrint){ - Printf(summary.Data()); - }else{ - TCanvas *pC=new TCanvas("c",summary.Data()); pC->Divide(2,2); - TF1 *pPion = new TF1("RITheor","acos(sqrt(x*x+[0]*[0])/(x*[1]))",1.2,6); pPion->SetLineWidth(1); - pPion->SetParameter(1,1.292); //ref idx - AliPID ppp; pPion->SetLineColor(kRed); pPion->SetParameter(0,AliPID::ParticleMass(AliPID::kPion)); //mass - TF1 *pKaon = (TF1*)pPion->Clone(); pKaon->SetLineColor(kGreen); pKaon->SetParameter(0,AliPID::ParticleMass(AliPID::kKaon)); - TF1 *pProt = (TF1*)pPion->Clone(); pProt->SetLineColor(kBlue); pProt->SetParameter(0,AliPID::ParticleMass(AliPID::kProton)); + if( d < dMin) {iMip=iClu; dMin=d;} //current cluster is closer, overwrite data for min cluster + }//clusters loop for intersected chamber - pC->cd(1); pDxDy->Draw(); //distance between mip and track intersection - pC->cd(2); pMipQ->Draw(); - pC->cd(3); pThP->Draw(); pPion->Draw("same"); pKaon->Draw("same"); pProt->Draw("same"); //Theta Ckov versus p + theoretical curves - pC->cd(4); pChiTh->Draw(); //Theta Ckov error versus theta Ckov +// pTrk->SetRICHtrk (xPc,yPc,th,ph); //store track info +// if(iMip==-1) {pTrk->SetRICHsignal (kMipQdcCut); continue;} //no clusters with QDC more the threshold at all - TCanvas *pC2=new TCanvas("c2",summary.Data()); pC2->Divide(2,2); - pC2->cd(1); pProbPi->Draw(); pProbMu->Draw("same"); pProbEl->Draw("same"); - pC2->cd(2); pProbKa->Draw(); - pC2->cd(3); pProbPr->Draw(); - pC2->cd(4); pMom->Draw(); - } -}//EsdQA() -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHTracker::MatrixPrint(Double_t probCut) -{ -// Reads a set of 3 ESD files from current directory and prints out the matrix of probabilities to pion kaon or proton completely blindly withou nay assumption on the contents of files. -// Normally it implies that those 3 ESDs contain only particles of the same sort namly pions, kaons and protons in that order. -// Arguments: probCut - cut on probability -// Returns: none - for(Int_t iFile=0;iFile<3;iFile++){ - TFile *pFile=TFile::Open(Form("Esd%1i.root",iFile+1),"read"); if(!pFile) {Printf("ERROR: Esd%1i.root does not exist!",iFile+1);return;} - TTree *pTr=(TTree*)pFile->Get("esdTree"); if(!pTr) {Printf("ERROR: Esd%1i.root, no ESD tree inside!",iFile+1);return;} - AliESD *pEsd=new AliESD; pTr->SetBranchAddress("ESD", &pEsd); - Int_t iProtCnt=0,iKaonCnt=0,iPionCnt=0,iUnreconCnt=0,iTrkCnt=0; //counters +// AliRICHCluster *pMipClu=(AliRICHCluster*)pCluLst->At(iMip); //take mip cluster - for(Int_t iEvt=0;iEvtGetEntries();iEvt++){//ESD events loop - pTr->GetEvent(iEvt); - iTrkCnt+=pEsd->GetNumberOfTracks(); - for(Int_t iTrk=0;iTrkGetNumberOfTracks();iTrk++){//ESD tracks loop - AliESDtrack *pTrack = pEsd->GetTrack(iTrk);// get next reconstructed track - Float_t dx,dy; pTrack->GetRICHdxdy(dx,dy); - Float_t theta,phi; pTrack->GetRICHthetaPhi(theta,phi); - Double_t prob[5]; pTrack->GetRICHpid(prob); - if(pTrack->GetRICHsignal()>0){ - if(prob[4]>probCut) iProtCnt++; - if(prob[3]>probCut) iKaonCnt++; - if((prob[0]+prob[1]+prob[2])>probCut) iPionCnt++; - } else - iUnreconCnt++; - }//ESD tracks loop - - }//ESD events loop - Printf("Bz=%5.2f Events=%i Total tracks=%i No recognized tracks=%i Pion=%i Kaon=%i Proton=%i ProbCut=%.2f", - 0.1*pEsd->GetMagneticField(),pTr->GetEntries(),iTrkCnt,iUnreconCnt,iPionCnt,iKaonCnt,iProtCnt,probCut); - delete pEsd; pFile->Close();//close AliESDs.root - }//files loop -} +// pTrk->SetRICHmip (pMipClu->X(),pMipClu->Y(),pMipClu->Q()); //store mip info + if(dMin>1) {pTrk->SetRICHsignal (kMipDistCut); continue;} //closest cluster with enough charge is still too far +// pTrk->SetRICHcluIdx (iCh,iMip); //set mip cluster index + recon.SetTrack(th,ph,xRa,yRa); Int_t iNphot=0; //initialize track parameters + pTrk->SetRICHsignal (recon.CkovAngle(pCluLst,iNphot)); //search for Cerenkov angle for this track + pTrk->SetRICHchi2 (recon.CkovSigma2()); //error squared +// pTrk->SetRICHmip (pMipClu->X(),pMipClu->Y(),pMipClu->Q(),iMip); //info on mip cluster + n. phot. + Printf("Ch=%i MIP-TRK=%5.2f cm Th=%f+-%f", iCh, dMin,pTrk->GetRICHsignal(),pTrk->GetRICHchi2()); + }//ESD tracks loop + AliDebug(1,"Stop pattern recognition"); + return 0; // error code: 0=no error; +}//PropagateBack() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHTracker.h b/RICH/AliRICHTracker.h index 730deaeb41c..eb786db1493 100644 --- a/RICH/AliRICHTracker.h +++ b/RICH/AliRICHTracker.h @@ -17,14 +17,9 @@ public: Int_t Clusters2Tracks(AliESD * ) {return 0;} //pure virtual from AliTracker Int_t LoadClusters (TTree *pCluTr ); //pure virtual from AliTracker Int_t PropagateBack (AliESD * ); //pure virtual from AliTracker invoked from AliReconstruction::RunTracking() - //void FillESD (AliESD *pESD ); //calculate pid for RICH Int_t RefitInward (AliESD * ) {return 0;} //pure virtual from AliTracker void UnloadClusters ( ) { } //pure virtual from AliTracker //private part - void RecWithStack(TNtupleD *hn ); //recon from Stack in case ESD empty - static void EsdQA (Bool_t isPrint=kFALSE ); //print QA info - static void MatrixPrint (Double_t probCut=0.7 ); //print prob matrix with cut on probability - Double_t fErrPar[5]; //Temporary stored for debug purpose enum ETrackingFlags {kMipDistCut=-9,kMipQdcCut=-5}; protected: ClassDef(AliRICHTracker,0) diff --git a/RICH/AliRICHv1.cxx b/RICH/AliRICHv1.cxx index 8f7c8c83c41..99d9e3c87aa 100644 --- a/RICH/AliRICHv1.cxx +++ b/RICH/AliRICHv1.cxx @@ -15,7 +15,10 @@ #include "AliRICHv1.h" //class header -#include "AliRICHParam.h" +#include "AliRICHParam.h" //CreateMaterials() +#include "AliRICHHit.h" //Hits2SDigs(),StepManager() +#include "AliRICHDigit.h" //CreateMaterials() +#include "AliRawReader.h" //Raw2SDigits() #include //Hits2SDigits() #include #include //StepManager() for gMC @@ -40,7 +43,15 @@ #include //CreateMaterials() ClassImp(AliRICHv1) - +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHv1::AddAlignableVolumes()const +{ +// Associates the symbolic volume name with the corresponding volume path. Interface methode from AliModule ivoked from AliMC +// Arguments: none +// Returns: none + for(Int_t i=0;i<7;i++) + gGeoManager->SetAlignableEntry(Form("/RICH/CH%i",i),Form("ALIC_1/RICH_%i",i)); +} //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHv1::CreateMaterials() { @@ -49,50 +60,34 @@ void AliRICHv1::CreateMaterials() // Returns: none AliDebug(1,"Start v1 RICH."); - const Int_t kNbins=30; //number of photon energy points + Float_t emin=5.5,emax=8.5; //Photon energy range,[eV] + + TF2 *pRaIF=new TF2("RidxRad","sqrt(1+0.554*(1239.84/x)^2/((1239.84/x)^2-5796)-0.0005*(y-20))" ,emin,emax,0,50); //DiMauro mail temp 0-50 degrees C + TF1 *pWiIF=new TF1("RidxWin","sqrt(1+46.411/(10.666*10.666-x*x)+228.71/(18.125*18.125-x*x))" ,emin,emax); //SiO2 idx TDR p.35 + TF1 *pGaIF=new TF1("RidxGap","1+0.12489e-6/(2.62e-4 - x*x/1239.84/1239.84)" ,emin,emax); //?????? from where + + TF1 *pRaAF=new TF1("RabsRad","(x<7.8)*(gaus+gaus(3))+(x>=7.8)*0.0001" ,emin,emax); //fit from DiMauro data 28.10.03 + pRaAF->SetParameters(3.20491e16,-0.00917890,0.742402,3035.37,4.81171,0.626309); + TF1 *pWiAF=new TF1("RabsWin","(x<8.2)*(818.8638-301.0436*x+36.89642*x*x-1.507555*x*x*x)+(x>=8.2)*0.0001" ,emin,emax); //fit from DiMauro data 28.10.03 + TF1 *pGaAF=new TF1("RabsGap","(x<7.75)*6512.399+(x>=7.75)*3.90743e-2/(-1.655279e-1+6.307392e-2*x-8.011441e-3*x*x+3.392126e-4*x*x*x)",emin,emax); //????? from where - Float_t aAbsC6F14[kNbins]={//New values from A.DiMauro 28.10.03 total 30 - 32701.4219, 17996.1141, 10039.7281, 1799.1230, 1799.1231, 1799.1231, 1241.4091, 179.0987, 179.0986, 179.0987, - 179.0987, 118.9800, 39.5058, 23.7244, 11.1283, 7.1573, 3.6249, 2.1236, 0.7362, 0.5348, - 0.3387, 0.3074, 0.3050, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001}; - - Float_t aAbsSiO2[kNbins]={//New values from A.DiMauro 28.10.03 total 30 - 34.4338, 30.5424, 30.2584, 31.4928, 31.7868, 17.8397, 9.3410, 6.4492, 6.1128, 5.8128, - 5.5589, 5.2877, 5.0162, 4.7999, 4.5734, 4.2135, 3.7471, 2.6033, 1.5223, 0.9658, - 0.4242, 0.2500, 0.1426, 0.0863, 0.0793, 0.0724, 0.0655, 0.0587, 0.0001, 0.0001}; - - Float_t aQeCsI[kNbins] = {//New values from A.DiMauro 28.10.03 total 31 the last one cut to provide 30 - 0.0002, 0.0006, 0.0007, 0.0010, 0.0049, 0.0073, 0.0104, 0.0519, 0.0936, 0.1299, - 0.1560, 0.1768, 0.1872, 0.1976, 0.2142, 0.2288, 0.2434, 0.2599, 0.2673, 0.2808, - 0.2859, 0.2954, 0.3016, 0.3120, 0.3172, 0.3224, 0.3266, 0.3328, 0.3359, 0.3390}; //0.3431}; - - Float_t aQeCsIold[kNbins]={//previous values 26 in total added 0.0001 to the 30 - 0.0002, 0.0006, 0.0007, 0.0050, 0.0075, 0.0101, 0.0243, 0.0405, 0.0689, 0.1053, - 0.1215, 0.1417, 0.1579, 0.1620, 0.1661, 0.1677, 0.1743, 0.1768, 0.1793, 0.1826, - 0.1859, 0.1876, 0.1892, 0.1909, 0.2075, 0.2158, 0.0001, 0.0001, 0.0001, 0.0001 }; - -// radiator window gas metal - Float_t aIdxC6F14[kNbins] , aIdxSiO2[kNbins] , aIdxCH4[kNbins] , aIdx0[kNbins] , aIdx1[kNbins] ; - Float_t aAbsCH4[kNbins] , aAbsMet[kNbins] ; - Float_t aQe1[kNbins] ; //QE for all but PC - Float_t aEckov[kNbins]; //Ckov energy in GeV + TF1 *pQeF =new TF1("Qe" ,"0+(x>6.07267)*0.344811*(1-exp(-1.29730*(x-6.07267)))" ,emin,emax); //fit from DiMauro data 28.10.03 + + const Int_t kNbins=30; //number of photon energy points + Float_t aEckov [kNbins]; + Float_t aAbsRad[kNbins], aAbsWin[kNbins], aAbsGap[kNbins], aAbsMet[kNbins], ; + Float_t aIdxRad[kNbins], aIdxWin[kNbins], aIdxGap[kNbins], aIdxMet[kNbins], aIdxPc[kNbins]; + Float_t aQeAll [kNbins], aQePc [kNbins]; - - Double_t eCkovMin=5.5e-9,eCkovMax=8.5e-9; //in GeV - TF2 idxC6F14("RidxC4F14","sqrt(1+0.554*(1239.84e-9/x)^2/((1239.84e-9/x)^2-5796)-0.0005*(y-20))" ,eCkovMin,eCkovMax,0,50); //DiMauro mail temp 0-50 degrees C - TF1 idxSiO2( "RidxSiO2" ,"sqrt(1+46.411/(10.666*10.666-x*x*1e18)+228.71/(18.125*18.125-x*x*1e18))",eCkovMin,eCkovMax); //TDR p.35 - - for(Int_t i=0;iEval(eV); aIdxRad[i]=1.292;//pRaIF->Eval(eV,20); //Simulation for 20 degress C + aAbsWin[i]=pWiAF->Eval(eV); aIdxWin[i]=1.5787;//pWiIF->Eval(eV); + aAbsGap[i]=pGaAF->Eval(eV); aIdxGap[i]=1.0005;//pGaIF->Eval(eV); aQeAll[i] =1; //QE for all other materials except for PC must be 1. + aAbsMet[i] =0.0001; aIdxMet[i]=0; //metal ref idx must be 0 in order to reflect photon + aIdxPc [i]=1; aQePc [i]=pQeF->Eval(eV); //PC ref idx must be 1 in order to apply photon to QE conversion + } //data from PDG booklet 2002 density [gr/cm^3] rad len [cm] abs len [cm] @@ -105,93 +100,82 @@ void AliRICHv1::CreateMaterials() Float_t aCu= 63.55 , zCu= 29 , dCu= 8.96 , radCu= 1.43 , absCu= 134.9/dCu ; Float_t aW=183.84 , zW= 74 , dW= 19.30 , radW= 0.35 , absW= 185.0/dW ; Float_t aAl= 26.98 , zAl= 13 , dAl= 2.70 , radAl= 8.90 , absAl= 106.4/dAl ; - - Int_t matId=0; //tmp material id number - Int_t unsens = 0, sens=1; //sensitive or unsensitive medium - Int_t itgfld = gAlice->Field()->Integ(); //type of field intergration 0 no field -1 user in guswim 1 Runge Kutta 2 helix 3 const field along z - Float_t maxfld = gAlice->Field()->Max(); //max field value - Float_t tmaxfd = -10.0; //max deflection angle due to magnetic field in one step - Float_t deemax = - 0.2; //max fractional energy loss in one step - Float_t stemax = - 0.1; //mas step allowed [cm] - Float_t epsil = 0.001; //abs tracking precision [cm] - Float_t stmin = - 0.001; //min step size [cm] in continius process transport, negative value: choose it automatically - AliMixture(++matId,"Air" ,aAir ,zAir ,dAir ,nAir ,wAir ); AliMedium(kAir ,"Air" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); - AliMixture(++matId,"C6F14",aC6F14,zC6F14,dC6F14,nC6F14,wC6F14); AliMedium(kC6F14,"C6F14",matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); - AliMixture(++matId,"SiO2" ,aSiO2 ,zSiO2 ,dSiO2 ,nSiO2 ,wSiO2 ); AliMedium(kSiO2 ,"SiO2" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); - AliMixture(++matId,"CH4" ,aCH4 ,zCH4 ,dCH4 ,nCH4 ,wCH4 ); AliMedium(kCH4 ,"CH4" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); - AliMixture(++matId,"CsI" ,aCsI ,zCsI ,dCsI ,nCsI ,wCsI ); AliMedium(kCsI ,"CsI" ,matId, sens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);//sensitive - AliMaterial(++matId,"Roha",aRoha,zRoha,dRoha,radRoha,absRoha); AliMedium(kRoha,"Roha", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); - AliMaterial(++matId,"Cu" ,aCu ,zCu ,dCu ,radCu ,absCu ); AliMedium(kCu ,"Cu" , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); - AliMaterial(++matId,"W" ,aW ,zW ,dW ,radW ,absW ); AliMedium(kW ,"W" , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); - AliMaterial(++matId,"Al" ,aAl ,zAl ,dAl ,radAl ,absAl ); AliMedium(kAl ,"Al" , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + Int_t matId=0; //tmp material id number + Int_t unsens = 0, sens=1; //sensitive or unsensitive medium + Int_t itgfld = gAlice->Field()->Integ(); //type of field intergration 0 no field -1 user in guswim 1 Runge Kutta 2 helix 3 const field along z + Float_t maxfld = gAlice->Field()->Max(); //max field value + Float_t tmaxfd = -10.0; //max deflection angle due to magnetic field in one step + Float_t deemax = - 0.2; //max fractional energy loss in one step + Float_t stemax = - 0.1; //mas step allowed [cm] + Float_t epsil = 0.001; //abs tracking precision [cm] + Float_t stmin = - 0.001; //min step size [cm] in continius process transport, negative value: choose it automatically + AliMixture(++matId,"Air" ,aAir ,zAir ,dAir ,nAir ,wAir ); AliMedium(kAir ,"Air" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMixture(++matId,"C6F14",aC6F14,zC6F14,dC6F14,nC6F14,wC6F14); AliMedium(kC6F14,"C6F14",matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMixture(++matId,"SiO2" ,aSiO2 ,zSiO2 ,dSiO2 ,nSiO2 ,wSiO2 ); AliMedium(kSiO2 ,"SiO2" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMixture(++matId,"CH4" ,aCH4 ,zCH4 ,dCH4 ,nCH4 ,wCH4 ); AliMedium(kCH4 ,"CH4" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMixture(++matId,"CsI" ,aCsI ,zCsI ,dCsI ,nCsI ,wCsI ); AliMedium(kCsI ,"CsI" ,matId, sens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);//sensitive - gMC->SetCerenkov((*fIdtmed)[kC6F14] , kNbins, aEckov, aAbsC6F14 , aQe1 , aIdxC6F14 ); - gMC->SetCerenkov((*fIdtmed)[kSiO2] , kNbins, aEckov, aAbsSiO2 , aQe1 , aIdxSiO2 ); - gMC->SetCerenkov((*fIdtmed)[kCH4] , kNbins, aEckov, aAbsCH4 , aQe1 , aIdxCH4 ); - gMC->SetCerenkov((*fIdtmed)[kCu] , kNbins, aEckov, aAbsMet , aQe1 , aIdx0 ); - gMC->SetCerenkov((*fIdtmed)[kW] , kNbins, aEckov, aAbsMet , aQe1 , aIdx0 ); //n=0 means reflect photons - gMC->SetCerenkov((*fIdtmed)[kCsI] , kNbins, aEckov, aAbsMet , aQeCsI, aIdx1 ); //n=1 means convert photons - gMC->SetCerenkov((*fIdtmed)[kAl] , kNbins, aEckov, aAbsMet , aQe1 , aIdx0 ); + AliMaterial(++matId,"Roha",aRoha,zRoha,dRoha,radRoha,absRoha); AliMedium(kRoha,"Roha", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMaterial(++matId,"Cu" ,aCu ,zCu ,dCu ,radCu ,absCu ); AliMedium(kCu ,"Cu" , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMaterial(++matId,"W" ,aW ,zW ,dW ,radW ,absW ); AliMedium(kW ,"W" , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMaterial(++matId,"Al" ,aAl ,zAl ,dAl ,radAl ,absAl ); AliMedium(kAl ,"Al" , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); - AliDebug(1,"Stop v1 RICH."); - TString ttl=GetTitle(); - if(!ttl.Contains("ShowOptics")) return; //do not plot optical curves - { - const Double_t kWidth=0.25,kHeight=0.2; - const Int_t kC6F14Marker=24 , kC6F14Color=kRed; - const Int_t kCH4Marker =25 , kCH4Color =kGreen; - const Int_t kSiO2M =26 , kSiO2Color =kBlue; - const Int_t kCsIMarker = 2 , kCsIColor =kMagenta; + gMC->SetCerenkov((*fIdtmed)[kC6F14] , kNbins, aEckov, aAbsRad , aQeAll , aIdxRad ); + gMC->SetCerenkov((*fIdtmed)[kSiO2] , kNbins, aEckov, aAbsWin , aQeAll , aIdxWin ); + gMC->SetCerenkov((*fIdtmed)[kCH4] , kNbins, aEckov, aAbsGap , aQeAll , aIdxGap ); + gMC->SetCerenkov((*fIdtmed)[kCu] , kNbins, aEckov, aAbsMet , aQeAll , aIdxMet ); + gMC->SetCerenkov((*fIdtmed)[kW] , kNbins, aEckov, aAbsMet , aQeAll , aIdxMet ); //n=0 means reflect photons + gMC->SetCerenkov((*fIdtmed)[kCsI] , kNbins, aEckov, aAbsMet , aQePc , aIdxPc ); //n=1 means convert photons + gMC->SetCerenkov((*fIdtmed)[kAl] , kNbins, aEckov, aAbsMet , aQeAll , aIdxMet ); + + delete pRaAF;delete pWiAF;delete pGaAF; delete pRaIF; delete pWiIF; delete pGaIF; delete pQeF; + AliDebug(1,"Stop v1 RICH."); + + TString ttl=GetTitle(); if(!ttl.Contains("ShowOptics")) return; //user didn't aks to plot optical curves -//Ref index - TGraph *pIdxC6F14=new TGraph(kNbins,aEckov,aIdxC6F14);pIdxC6F14->SetMarkerStyle(kC6F14Marker);pIdxC6F14->SetMarkerColor(kC6F14Color); - TGraph *pIdxSiO2 =new TGraph(kNbins,aEckov,aIdxSiO2); pIdxSiO2 ->SetMarkerStyle(kSiO2M) ;pIdxSiO2 ->SetMarkerColor(kSiO2Color); - TGraph *pIdxCH4 =new TGraph(kNbins,aEckov,aIdxCH4); pIdxCH4 ->SetMarkerStyle(kCH4Marker) ;pIdxCH4 ->SetMarkerColor(kCH4Color); - TMultiGraph *pIdxMG=new TMultiGraph("refidx","Ref index;E_{#check{C}} [GeV]"); TLegend *pIdxLe=new TLegend(0.5,0.21,0.5+kWidth,0.21+kHeight); - pIdxMG->Add(pIdxC6F14); pIdxLe->AddEntry(pIdxC6F14,"C6F14" ,"p"); - pIdxMG->Add(pIdxSiO2) ; pIdxLe->AddEntry(pIdxSiO2 ,"SiO2" ,"p"); - pIdxMG->Add(pIdxCH4) ; pIdxLe->AddEntry(pIdxCH4 ,"CH4" ,"p"); -//Absorbtion - TGraph *pAbsC6F14=new TGraph(kNbins,aEckov,aAbsC6F14);pAbsC6F14->SetMarkerStyle(kC6F14Marker); pAbsC6F14->SetMarkerColor(kC6F14Color); - TGraph *pAbsSiO2 =new TGraph(kNbins,aEckov,aAbsSiO2) ;pAbsSiO2 ->SetMarkerStyle(kSiO2M) ; pAbsSiO2 ->SetMarkerColor(kSiO2Color); - TGraph *pAbsCH4 =new TGraph(kNbins,aEckov,aAbsCH4) ;pAbsCH4 ->SetMarkerStyle(kCH4Marker) ; pAbsCH4 ->SetMarkerColor(kCH4Color); + const Double_t kWidth=0.25,kHeight=0.2; + const Int_t kRadM=24 , kRadC=kRed; + const Int_t kWinM=26 , kWinC=kBlue; + const Int_t kGapM=25 , kGapC=kGreen; + const Int_t kPcM = 2 , kPcC =kMagenta; - TMultiGraph *pAbsMG=new TMultiGraph("abs","Absorption [cm];E_{#check{C}} [GeV]"); TLegend *pAbsLe=new TLegend(0.2,0.15,0.2+kWidth,0.15+kHeight); - pAbsMG->Add(pAbsC6F14); pAbsLe->AddEntry(pAbsC6F14, "C6F14" ,"p"); - pAbsMG->Add(pAbsSiO2); pAbsLe->AddEntry(pAbsSiO2 , "SiO2" ,"p"); - pAbsMG->Add(pAbsCH4); pAbsLe->AddEntry(pAbsCH4 , "CH4" ,"p"); -//QE new and old - TGraph *pQeCsI =new TGraph(kNbins,aEckov,aQeCsI); pQeCsI ->SetMarkerStyle(kCsIMarker); pQeCsI ->SetMarkerColor(kCsIColor); - TGraph *pQeCsIold=new TGraph(kNbins,aEckov,aQeCsIold); pQeCsIold->SetMarkerStyle(kC6F14Marker);pQeCsIold->SetMarkerColor(kC6F14Color); - TMultiGraph *pCompMG=new TMultiGraph("qe","QE;E_{#check{C}} [GeV]"); TLegend *pCompLe=new TLegend(0.2,0.6,0.2+kWidth,0.6+kHeight); - pCompMG->Add(pQeCsI); pCompLe->AddEntry(pQeCsI, "QE new 30.10.03", "p"); - pCompMG->Add(pQeCsIold); pCompLe->AddEntry(pQeCsIold, "QE old 01.01.02", "p"); -//transmission - Float_t aTrC6F14[kNbins],aTrSiO2[kNbins],aTrCH4[kNbins],aTrTotal[kNbins]; + Float_t aTraRad[kNbins],aTraWin[kNbins],aTraGap[kNbins],aTraTot[kNbins]; for(Int_t i=0;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"); + TGraph *pRaAG=new TGraph(kNbins,aEckov,aAbsRad);pRaAG->SetMarkerStyle(kRadM);pRaAG->SetMarkerColor(kRadC); + TGraph *pRaIG=new TGraph(kNbins,aEckov,aIdxRad);pRaIG->SetMarkerStyle(kRadM);pRaIG->SetMarkerColor(kRadC); + TGraph *pRaTG=new TGraph(kNbins,aEckov,aTraRad);pRaTG->SetMarkerStyle(kRadM);pRaTG->SetMarkerColor(kRadC); + + TGraph *pWiAG=new TGraph(kNbins,aEckov,aAbsWin);pWiAG->SetMarkerStyle(kWinM);pWiAG->SetMarkerColor(kWinC); + TGraph *pWiIG=new TGraph(kNbins,aEckov,aIdxWin);pWiIG->SetMarkerStyle(kWinM);pWiIG->SetMarkerColor(kWinC); + TGraph *pWiTG=new TGraph(kNbins,aEckov,aTraWin);pWiTG->SetMarkerStyle(kWinM);pWiTG->SetMarkerColor(kWinC); + + TGraph *pGaAG=new TGraph(kNbins,aEckov,aAbsGap);pGaAG->SetMarkerStyle(kGapM);pGaAG->SetMarkerColor(kGapC); + TGraph *pGaIG=new TGraph(kNbins,aEckov,aIdxGap);pGaIG->SetMarkerStyle(kGapM);pGaIG->SetMarkerColor(kGapC); + TGraph *pGaTG=new TGraph(kNbins,aEckov,aTraGap);pGaTG->SetMarkerStyle(kGapM);pGaTG->SetMarkerColor(kGapC); + + TGraph *pQeG =new TGraph(kNbins,aEckov,aQePc); pQeG ->SetMarkerStyle(kPcM );pQeG->SetMarkerColor(kPcC); + TGraph *pToG =new TGraph(kNbins,aEckov,aTraTot);pToG ->SetMarkerStyle(30) ;pToG->SetMarkerColor(kYellow); + + TMultiGraph *pIdxMG=new TMultiGraph("idx","Ref index;E_{#check{C}} [GeV]"); + TMultiGraph *pAbsMG=new TMultiGraph("abs","Absorption [cm];E_{#check{C}} [GeV]"); + TMultiGraph *pTraMG=new TMultiGraph("tra","Transmission;E_{#check{C}} [GeV]"); TLegend *pTraLe=new TLegend(0.2,0.4,0.2+kWidth,0.4+kHeight); + pAbsMG->Add(pRaAG); pIdxMG->Add(pRaIG); pTraMG->Add(pRaTG); pTraLe->AddEntry(pRaTG, "Rad", "p"); + pAbsMG->Add(pWiAG); pIdxMG->Add(pWiIG); pTraMG->Add(pWiTG); pTraLe->AddEntry(pWiTG, "Win", "p"); + pAbsMG->Add(pGaAG); pIdxMG->Add(pGaIG); pTraMG->Add(pGaTG); pTraLe->AddEntry(pGaTG, "Gap", "p"); + pTraMG->Add(pToG); pTraLe->AddEntry(pToG, "Tot", "p"); + pTraMG->Add(pQeG); pTraLe->AddEntry(pQeG, "QE" , "p"); TCanvas *pC=new TCanvas("c1","RICH optics to check",1100,900); pC->Divide(2,2); - pC->cd(1); pIdxMG ->Draw("AP"); pIdxLe ->Draw(); //ref idx - pC->cd(2); gPad->SetLogy(); pAbsMG ->Draw("AP"); pAbsLe ->Draw(); //absorption - pC->cd(3); pCompMG->Draw("AP"); pCompLe->Draw(); //QE - pC->cd(4); pTrMG ->Draw("AP"); pTrLe ->Draw(); //transmission - } + pC->cd(1); pIdxMG->Draw("AP"); + pC->cd(2); gPad->SetLogy(); pAbsMG->Draw("AP"); + pC->cd(3); pTraLe->Draw(); + pC->cd(4); pTraMG->Draw("AP"); }//void AliRICH::CreateMaterials() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHv1::CreateGeometry() @@ -209,18 +193,18 @@ void AliRICHv1::CreateGeometry() const Double_t kAngVer=20; // vertical angle between chambers 20 grad const Double_t kAngCom=30; // common RICH rotation with respect to x axis 30 grad const Double_t trans[3]={490,0,0}; //center of the chamber is on window-gap surface - for(Int_t iCh=1;iCh<=7;iCh++){//place 7 chambers + for(Int_t iCh=0;iCh<7;iCh++){//place 7 chambers TGeoHMatrix *pMatrix=new TGeoHMatrix; pMatrix->RotateY(90); //rotate around y since initial position is in XY plane -> now in YZ plane pMatrix->SetTranslation(trans); //now plane in YZ is shifted along x switch(iCh){ - case 1: pMatrix->RotateY(kAngHor); pMatrix->RotateZ(-kAngVer); break; //right and down - case 2: pMatrix->RotateZ(-kAngVer); break; //down - case 3: pMatrix->RotateY(kAngHor); break; //right - case 4: break; //no rotation - case 5: pMatrix->RotateY(-kAngHor); break; //left - case 6: pMatrix->RotateZ(kAngVer); break; //up - case 7: pMatrix->RotateY(-kAngHor); pMatrix->RotateZ(kAngVer); break; //left and up + case 0: pMatrix->RotateY(kAngHor); pMatrix->RotateZ(-kAngVer); break; //right and down + case 1: pMatrix->RotateZ(-kAngVer); break; //down + case 2: pMatrix->RotateY(kAngHor); break; //right + case 3: break; //no rotation + case 4: pMatrix->RotateY(-kAngHor); break; //left + case 5: pMatrix->RotateZ(kAngVer); break; //up + case 6: pMatrix->RotateY(-kAngHor); pMatrix->RotateZ(kAngVer); break; //left and up } pMatrix->RotateZ(kAngCom); //apply common rotation in XY plane gGeoManager->GetVolume("ALIC")->AddNode(pRich,iCh,pMatrix); @@ -234,12 +218,12 @@ void AliRICHv1::CreateGeometry() par[0]=114*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("RppfSmall","BOX ",(*fIdtmed)[kAir] ,par,3);//small whole par[0]=644*mm/2;par[1]= 407*mm/2;par[2]= 1.7*mm/2;gMC->Gsvolu("Rpc" ,"BOX ",(*fIdtmed)[kCsI] ,par,3);//by 0.2 mm more then actual size (PCB 2006P1) - gMC->Gspos("Rppf",1,"RICH", -335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY");//F1 2040P1 z p.84 TDR - gMC->Gspos("Rppf",2,"RICH", +335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY"); - gMC->Gspos("Rppf",3,"RICH", -335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); - gMC->Gspos("Rppf",4,"RICH", +335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); - gMC->Gspos("Rppf",5,"RICH", -335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); - gMC->Gspos("Rppf",6,"RICH", +335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",0,"RICH", -335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY");//F1 2040P1 z p.84 TDR + gMC->Gspos("Rppf",1,"RICH", +335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",2,"RICH", -335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",3,"RICH", +335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",4,"RICH", -335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",5,"RICH", +335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); gMC->Gspos("Rpc" ,1,"Rppf", 0*mm, 0*mm, -19.15*mm, 0,"ONLY");//PPF 2001P2 gMC->Gspos("RppfLarge",1,"Rppf", -224.5*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); gMC->Gspos("RppfLarge",2,"Rppf", -224.5*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); @@ -262,12 +246,12 @@ void AliRICHv1::CreateGeometry() par[0]= 0*mm ;par[1]= 20*mkm/2 ;par[2]= 648*mm/2;gMC->Gsvolu("Rano","TUBE",(*fIdtmed)[kW] ,par,3);//WP 2099P1 z = gap x PPF 2001P2 AliMatrix(matrixIdReturn,180,0, 90,90, 90,0); //wires along x - gMC->Gspos("Rgap",1,"RICH", -335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); //F1 2040P1 z WP 2099P1 - gMC->Gspos("Rgap",2,"RICH", +335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); - gMC->Gspos("Rgap",3,"RICH", -335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); - gMC->Gspos("Rgap",4,"RICH", +335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); - gMC->Gspos("Rgap",5,"RICH", -335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); - gMC->Gspos("Rgap",6,"RICH", +335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",0,"RICH", -335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); //F1 2040P1 z WP 2099P1 + gMC->Gspos("Rgap",1,"RICH", +335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",2,"RICH", -335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",3,"RICH", +335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",4,"RICH", -335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",5,"RICH", +335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); for(int i=1;i<=96;i++) gMC->Gspos("Rano",i,"Rgap", 0*mm, -411/2*mm+i*4*mm, 0.185*mm, matrixIdReturn,"ONLY"); //WP 2099P1 //Defines radiators geometry @@ -334,18 +318,13 @@ Bool_t AliRICHv1::IsLostByFresnel() return kFALSE; }//IsLostByFresnel() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void AliRICHv1::GenFee(Int_t iChamber,Float_t eloss) +void AliRICHv1::GenFee(Int_t iCh,Float_t eloss) { // Generate FeedBack photons for the current particle. To be invoked from StepManager(). // eloss=0 means photon so only pulse height distribution is to be analysed. This one is done in AliRICHParam::TotQdc() - TLorentzVector x4; - gMC->TrackPosition(x4); - TVector2 x2=AliRICHParam::Instance()->Mars2Lors(iChamber,x4.Vect(),AliRICHParam::kPc);//hit position on photocathode plane - TVector2 xspe=x2; - Int_t sector=AliRICHParam::Loc2Sec(xspe); if(sector==-1) return; //hit in dead zone, nothing to produce - Int_t iTotQdc=AliRICHParam::TotQdc(x2,eloss); - Int_t iNphotons=gMC->GetRandom()->Poisson(AliRICHParam::AlphaFeedback(iChamber,sector)*iTotQdc); + gMC->TrackPosition(x4); + Int_t iNphotons=gMC->GetRandom()->Poisson(0.02*200); eloss++; iCh++; //?????????????????????? AliDebug(1,Form("N photons=%i",iNphotons)); Int_t j; Float_t cthf, phif, enfp = 0, sthf, e1[3], e2[3], e3[3], vmod, uswop,dir[3], phi,pol[3], mom[4]; @@ -413,57 +392,50 @@ void AliRICHv1::GenFee(Int_t iChamber,Float_t eloss) //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHv1::Hits2SDigits() { -// Create a list of sdigits corresponding to list of hits. Every hit generates one or more sdigits. +// Interface methode ivoked from AliSimulation to create a list of sdigits corresponding to list of hits. Every hit generates one or more sdigits. +// Arguments: none +// Returns: none AliDebug(1,"Start."); - for(Int_t iEventN=0;iEventNGetRunLoader()->GetAliRun()->GetEventsPerRun();iEventN++){//events loop - GetLoader()->GetRunLoader()->GetEvent(iEventN);//get next event + for(Int_t iEvt=0;iEvt < GetLoader()->GetRunLoader()->GetNumberOfEvents();iEvt++){ //events loop + GetLoader()->GetRunLoader()->GetEvent(iEvt); //get next event - if(!GetLoader()->TreeH()) GetLoader()->LoadHits(); GetLoader()->GetRunLoader()->LoadHeader(); - if(!GetLoader()->GetRunLoader()->TreeK()) GetLoader()->GetRunLoader()->LoadKinematics();//from - if(!GetLoader()->TreeS()) GetLoader()->MakeTree("S"); MakeBranch("S");//to + if(!GetLoader()->TreeH()) {GetLoader()->LoadHits(); } + if(!GetLoader()->TreeS()) {GetLoader()->MakeTree("S"); MakeBranch("S");}//to for(Int_t iPrimN=0;iPrimNTreeH()->GetEntries();iPrimN++){//prims loop GetLoader()->TreeH()->GetEntry(iPrimN); - for(Int_t iHitN=0;iHitNGetEntries();iHitN++){//hits loop - AliRICHHit *pHit=(AliRICHHit*)Hits()->At(iHitN);//get current hit - TVector2 x2 = AliRICHParam::Instance()->Mars2Lors(pHit->C(),0.5*(pHit->InX3()+pHit->OutX3()),AliRICHParam::kAnod);//hit position in the anod plane - Int_t iTotQdc=AliRICHParam::TotQdc(x2,pHit->Eloss());//total charge produced by hit, 0 if hit in dead zone - if(iTotQdc==0) continue; - // - //need to quantize the anod.... - TVector padHit=AliRICHParam::Loc2Pad(x2); - TVector2 padHitXY=AliRICHParam::Pad2Loc(padHit); - TVector2 anod; - if((x2.Y()-padHitXY.Y())>0) anod.Set(x2.X(),padHitXY.Y()+AliRICHParam::AnodPitch()/2); - else anod.Set(x2.X(),padHitXY.Y()-AliRICHParam::AnodPitch()/2); - //end to quantize anod - // - TVector area=AliRICHParam::Loc2Area(anod);//determine affected pads, dead zones analysed inside - AliDebug(1,Form("hitanod(%6.2f,%6.2f)->area(%3.0f,%3.0f)-(%3.0f,%3.0f) QDC=%4i",anod.X(),anod.Y(),area[0],area[1],area[2],area[3],iTotQdc)); - TVector pad(2); - for(pad[1]=area[1];pad[1]<=area[3];pad[1]++)//affected pads loop - for(pad[0]=area[0];pad[0]<=area[2];pad[0]++){ - Double_t padQdc=iTotQdc*AliRICHParam::FracQdc(anod,pad); - AliDebug(1,Form("current pad(%3.0f,%3.0f) with QDC =%6.2f",pad[0],pad[1],padQdc)); - if(padQdc>0.1) SDigAdd(pHit->C(),pad,padQdc,GetLoader()->GetRunLoader()->Stack()->Particle(pHit->GetTrack())->GetPdgCode(),pHit->GetTrack()); - }//affected pads loop - }//hits loop + Hit2Sdi(Hits(),SdiLst()); }//prims loop GetLoader()->TreeS()->Fill(); GetLoader()->WriteSDigits("OVERWRITE"); - SDigReset(); + SdiReset(); }//events loop - GetLoader()->UnloadHits(); GetLoader()->GetRunLoader()->UnloadHeader(); GetLoader()->GetRunLoader()->UnloadKinematics(); + GetLoader()->UnloadHits(); GetLoader()->UnloadSDigits(); AliDebug(1,"Stop."); }//Hits2SDigits() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliRICHv1::Hit2Sdi(TClonesArray *pHitLst,TClonesArray *pSdiLst) +{ +// Converts list of hits to list of sdigits. For each hit in a loop the following steps are done: +// - calcultion of the total charge induced by the hit +// - determination of the pad contaning the hit and shifting hit y position to the nearest anod wire y +// - defining a set of pads affected (up to 9 including the hitted pad) +// - calculating charge induced to all those pads using integrated Mathieson distribution and creating sdigit +// Arguments: pHitLst - list of hits provided not empty +// pSDigLst - list of sdigits where to store the results +// Returns: none + for(Int_t iHit=0;iHitGetEntries();iHit++){ //hits loop + AliRICHHit *pHit=(AliRICHHit*)pHitLst->At(iHit); //get pointer to current hit + AliRICHDigit::Hit2Sdi(pHit,pSdiLst); //convert this hit to list of sdigits + }//hits loop loop +}//Hits2SDigs() for TVector2 +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHv1::Digits2Raw() { -//Creates raw data files in DDL format. Invoked by AliSimulation -//loop over events is done outside in AliSimulation -//Arguments: none -// Returns: none +// Creates raw data files in DDL format. Invoked by AliSimulation where loop over events is done +// Arguments: none +// Returns: none AliDebug(1,"Start."); GetLoader()->LoadDigits(); GetLoader()->TreeD()->GetEntry(0); @@ -473,22 +445,22 @@ void AliRICHv1::Digits2Raw() AliRawDataHeader header; //empty DDL header UInt_t w32=0; //32 bits data word - for(Int_t i=0;iUncheckedAt(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 + for(Int_t iCh=0;iCh<7;iCh++) + for(Int_t iDig=0;iDigGetEntriesFast();iDig++){//digits loop for a given chamber + AliRICHDigit *pDig=(AliRICHDigit*)DigLst(iCh)->At(iDig); + Int_t ddl=pDig->Raw(w32); //ddl is 0..13 file[ddl].write((char*)&w32,sizeof(w32)); cnt[ddl]++;//write formated digit to the propriate file (as decided in Dig2Raw) and increment corresponding counter - }//digits loop for a given chamber - }//chambers loop + }//digits + + for(Int_t i=0;iTreeS()) {MakeTree("S"); MakeBranch("S");} + + TClonesArray *pSdiLst=SdiLst(); Int_t iSdiCnt=0; //tmp list of sdigits for all chambers + pRR->Select("RICH",0,13);//select all RICH DDL files + UInt_t w32=0; + while(pRR->ReadNextInt(w32)){//raw records loop (in selected DDL files) + UInt_t ddl=pRR->GetDDLID(); //returns 0,1,2 ... 13 + sdi.ReadRaw(ddl,w32); + new((*pSdiLst)[iSdiCnt++]) AliRICHDigit(sdi); //add this digit to the tmp list + }//raw records loop + GetLoader()->TreeS()->Fill(); GetLoader()->WriteSDigits("OVERWRITE");//write out sdigits + SdiReset(); + return kTRUE; +}//Raw2SDigits +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHv1::StepCount() { // Count number of ckovs created - Int_t copy; - if(gMC->TrackCharge() &&gMC->CurrentVolID(copy)==fIdRad &&gMC->IsTrackEntering() ) fCounters(kMipEnterRad)++; - if(gMC->TrackPid()==kCerenkov &&gMC->IsNewTrack() ) fCounters(kCkovNew)++; - if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdRad &&gMC->IsNewTrack() ) fCounters(kCkovNewRad)++; - if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdWin &&gMC->IsNewTrack() ) fCounters(kCkovNewWin)++; - if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdProxGap&&gMC->IsNewTrack() ) fCounters(kCkovNewProxGap)++; - if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdAmpGap &&gMC->IsNewTrack() ) fCounters(kCkovNewAmpGap)++; - if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdPc &&gMC->IsTrackEntering() ) fCounters(kCkovEnterPc)++; - if(gMC->TrackPid()==kCerenkov&&gMC->CurrentVolID(copy)==fIdPc &&gMC->IsTrackEntering() &&gMC->Edep()>0) fCounters(kPhotoEle)++; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void AliRICHv1::StepHistory() @@ -634,34 +611,42 @@ void AliRICHv1::StepManager() // StepHistory(); return; //uncomment to print tracks history // StepCount(); return; //uncomment to count photons - Int_t copy; //volume copy aka node - static Int_t iCham; + Int_t copy; //volume copy aka node + //Treat photons - static TLorentzVector cerX4; - if((gMC->TrackPid()==kCerenkov||gMC->TrackPid()==kFeedback)&&gMC->CurrentVolID(copy)==fIdPc){//photon in PC - if(gMC->Edep()>0){//photon survided QE test i.e. produces electron - if(IsLostByFresnel()){ gMC->StopTrack(); return;} //photon lost due to fersnel reflection - gMC->TrackPosition(cerX4); gMC->CurrentVolOffID(2,iCham);//RICH-Rppf-Rpc - HitAdd(iCham,gMC->GetStack()->GetCurrentTrackNumber(),gMC->TrackPid(),cerX4.Vect(),cerX4.Vect());//HIT for PHOTON in conditions CF+CSI+DE - GenFee(iCham); - }//photon in PC and DE >0 - }//photon in PC + if((gMC->TrackPid()==kCerenkov||gMC->TrackPid()==kFeedback)&&gMC->CurrentVolID(copy)==fIdPc){ //photon (Ckov or feedback) hit PC (fIdPc) + if(gMC->Edep()>0){ //photon survided QE test i.e. produces electron + if(IsLostByFresnel()){ gMC->StopTrack(); return;} //photon lost due to fersnel reflection on PC + gMC->CurrentVolOffID(2,copy); //current chamber since geomtry tree is RICH-Rppf-Rpc + Int_t tid= gMC->GetStack()->GetCurrentTrackNumber(); //take TID + Int_t pid= gMC->TrackPid(); //take PID + Float_t etot= gMC->Etot(); //total hpoton energy, [GeV] + Double_t x[3]; gMC->TrackPosition(x[0],x[1],x[2]); //take MARS position at entrance to PC + Float_t xl,yl; AliRICHParam::Instance()->Mars2Lors(copy,x,xl,yl); //take LORS position + new((*fHits)[fNhits++])AliRICHHit(copy,etot,pid,tid,xl,yl,x); //HIT for photon, position at PC + GenFee(copy); //generate feedback photons + }//photon hit PC and DE >0 + }//photon hit PC //Treat charged particles - static Float_t eloss; - static TLorentzVector mipInX4,mipOutX4; - if(gMC->TrackCharge() && gMC->CurrentVolID(copy)==fIdAmpGap){//MIP in amplification gap - gMC->CurrentVolOffID(1,iCham);//RICH-Rgap - if(gMC->IsTrackEntering()||gMC->IsNewTrack()) {//MIP in GAP entering or newly created - eloss=0; - gMC->TrackPosition(mipInX4); - }else if(gMC->IsTrackExiting()||gMC->IsTrackStop()||gMC->IsTrackDisappeared()){//MIP in GAP exiting or disappeared - eloss+=gMC->Edep();//take into account last step dEdX - gMC->TrackPosition(mipOutX4); - HitAdd(iCham,gMC->GetStack()->GetCurrentTrackNumber(),gMC->TrackPid(),mipInX4.Vect(),mipOutX4.Vect(),eloss);//HIT for MIP: MIP in GAP Exiting - GenFee(iCham,eloss);//MIP+GAP+Exit - }else//MIP in GAP going inside - eloss += gMC->Edep(); + static Double_t dEdX; //need to store mip parameters between different steps + static Double_t in[3]; + if(gMC->TrackCharge() && gMC->CurrentVolID(copy)==fIdAmpGap){ //charged particle in amplification gap (fIdAmpGap) + if(gMC->IsTrackEntering()||gMC->IsNewTrack()) { //entering or newly created + dEdX=0; //reset dEdX collector + gMC->TrackPosition(in[0],in[1],in[2]); //take position at the entrance + }else if(gMC->IsTrackExiting()||gMC->IsTrackStop()||gMC->IsTrackDisappeared()){ //exiting or disappeared + dEdX +=gMC->Edep(); //take into account last step dEdX + gMC->CurrentVolOffID(1,copy); //take current chamber since geometry tree is RICH-Rgap + Int_t tid= gMC->GetStack()->GetCurrentTrackNumber(); //take TID + Int_t pid= gMC->TrackPid(); //take PID + Double_t out[3]; gMC->TrackPosition(out[0],out[1],out[2]); //take MARS position at exit + out[0]=0.5*(out[0]+in[0]); out[1]=0.5*(out[1]+in[1]); out[1]=0.5*(out[1]+in[1]); //take hit position at the anod plane + Float_t xl,yl;AliRICHParam::Instance()->Mars2Lors(copy,out,xl,yl); //take LORS position + new((*fHits)[fNhits++])AliRICHHit(copy,dEdX,pid,tid,xl,yl,out); //HIT for MIP, position near anod plane + GenFee(copy,dEdX); //generate feedback photons + }else //just going inside + dEdX += gMC->Edep(); //collect this step dEdX }//MIP in GAP }//StepManager() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/RICH/AliRICHv1.h b/RICH/AliRICHv1.h index 1ad850b8fbd..ded555d24ff 100644 --- a/RICH/AliRICHv1.h +++ b/RICH/AliRICHv1.h @@ -14,21 +14,24 @@ public: AliRICHv1(const char *name, const char *title):AliRICH(name,title),fIdRad(-1),fIdWin(-1),fIdProxGap(-1),fIdAmpGap(-1),fIdPc(-1),fIdAnod(-1),fIdCath(-1),fIdColl(-1) {;} //named ctor virtual ~AliRICHv1() {;} //dtor //framework part++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 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() + void AddAlignableVolumes( )const; //from AliModule invoked from AliMC + void CreateMaterials ( ); //from AliModule invoked from AliMC + void CreateGeometry ( ); //from AliModule invoked from AliMC + 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 + Bool_t Raw2SDigits (AliRawReader * ); //from AliMOdule invoked from AliSimulation + 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() + 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 + static void Hit2Sdi (TClonesArray *pH,TClonesArray *pS); + 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: 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 diff --git a/RICH/RICHbaseLinkDef.h b/RICH/RICHbaseLinkDef.h index 0938cffe02e..27c74f8fe5c 100644 --- a/RICH/RICHbaseLinkDef.h +++ b/RICH/RICHbaseLinkDef.h @@ -2,10 +2,10 @@ #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class AliRICHParam+; -#pragma link C++ class AliRICH+; -#pragma link C++ class AliRICHHit+; +#pragma link C++ class AliRICHHelix+; #pragma link C++ class AliRICHDigit+; +#pragma link C++ class AliRICHHit+; #pragma link C++ class AliRICHCluster+; -#pragma link C++ class AliRICHHelix+; +#pragma link C++ class AliRICHParam+; +#pragma link C++ class AliRICH+; #endif diff --git a/RICH/RICHrecLinkDef.h b/RICH/RICHrecLinkDef.h index b76cb1d4ade..2f36e542152 100644 --- a/RICH/RICHrecLinkDef.h +++ b/RICH/RICHrecLinkDef.h @@ -5,5 +5,6 @@ #pragma link C++ class AliRICHReconstructor+; #pragma link C++ class AliRICHTracker+; #pragma link C++ class AliRICHRecon+; +#pragma link C++ class AliRICHReconOld+; #pragma link C++ class AliRICHPreprocessor+; #endif diff --git a/RICH/RichConfig.C b/RICH/RichConfig.C index c808fd30a72..06b29c282b7 100644 --- a/RICH/RichConfig.C +++ b/RICH/RichConfig.C @@ -12,7 +12,7 @@ public: 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}; - enum EBatchFlags{kPrim=555,kTransport,kAll,kOnly,kRawDdl,kRawDate,kRawRoot,kVertex,kTrack,kHlt,kEsd}; + enum EBatchFlags{kPrim=555,kTransport,kAll,kOnly,kRawDdl,kRawDate,kRawRoot,kVertex,kTrack,kHlt,kEsd,kAlign}; enum EMagField {kFld0,kFld2,kFld4,kFld5,kFld_2,kFld_4,kFld_5}; Float_t Eta2Theta (Float_t arg) const{return (180./TMath::Pi())*2.*TMath::ATan(TMath::Exp(-arg));} @@ -470,6 +470,7 @@ void RichConfig::GuiBatch(TGHorizontalFrame *pMainF) new TGRadioButton(fClusBG, "Clusters RICH" ,kOnly )); fClusBG->SetButton(kOnly); pRecF->AddFrame(fRecoBG=new TGButtonGroup(pRecF,"" )); fRecoBG->Connect("Pressed(Int_t)","RichConfig",this,"SlotBatch(Int_t)"); + new TGCheckButton(fRecoBG, "Load Align data" ,kAlign )); new TGCheckButton(fRecoBG, "Find ESD tracks" ,kTrack )); new TGCheckButton(fRecoBG, "Find vertex" ,kVertex )); new TGCheckButton(fRecoBG, "Fill ESD" ,kEsd )); @@ -491,18 +492,20 @@ void RichConfig::WriteBatch() {//creates Batch.C file char *sBatchName="RichBatch"; FILE *fp=fopen(Form("%s.C",sBatchName),"w"); if(!fp){Info("CreateBatch","Cannot open output file: %s.C",sBatchName);return;} -//header and debug + fprintf(fp,"void %s(const Int_t iNevents,const Bool_t isDebug,const char *sConfigFileName)\n{\n",sBatchName); - fprintf(fp," gSystem->Exec(\"rm -rf *.root hlt hough fort* raw* ZZZ*\");\n"); + + if(fSimBG->GetButton(kPrim)->GetState()) fprintf(fp," gSystem->Exec(\"rm -rf *.root hlt hough fort* raw* ZZZ*\");\n"); + else fprintf(fp," gSystem->Exec(\"rm -rf hlt hough raw* ZZZ*\");\n"); + fprintf(fp," if(isDebug) AliLog::SetGlobalDebugLevel(AliLog::kDebug);\n"); fprintf(fp," gBenchmark->Start(\"ALICE\");\n TDatime time;\n\n"); //simulation section + if(fSimBG->GetButton(kPrim)->GetState()){ fprintf(fp," AliSimulation *pSim=new AliSimulation(sConfigFileName);\n"); -//generate initial kinematics - if(fSimBG->GetButton(kPrim)->GetState()) - fprintf(fp," pSim->SetRunGeneration(kTRUE); //initial kinematics generated\n"); - else - fprintf(fp," pSim->SetRunGeneration(kFALSE); //no initial kinematics generated\n"); + + if(fSimBG->GetButton(kPrim)->GetState()) fprintf(fp," pSim->SetRunGeneration(kTRUE); //initial kinematics generated\n"); + else fprintf(fp," pSim->SetRunGeneration(kFALSE); //no initial kinematics generated\n"); //transport and hit creations if(fSimBG->GetButton(kTransport)->GetState()) fprintf(fp," pSim->SetRunSimulation(kTRUE); //transport and hits creation\n"); @@ -522,11 +525,14 @@ 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 these detectors\n"); fprintf(fp," pSim->Run(iNevents);\n delete pSim;\n\n"); - + } //reconstraction section - cluster finder fprintf(fp," AliReconstruction *pRec=new AliReconstruction;\n"); + if(fRecoBG->GetButton(kAlign)->GetState()) fprintf(fp," pRec->SetLoadAlignData(\"ITS TPC TRD TOF RICH\"); //Misalign data for these detectors\n"); + else fprintf(fp," pRec->SetLoadAlignData(\"\"); //Misalign data not loaded\n"); + if (fClusBG->GetButton(kAll) ->GetState()) fprintf(fp," pRec->SetRunLocalReconstruction(\"ITS TPC TRD TOF RICH\"); //clusters created for these detectors\n"); else if(fClusBG->GetButton(kOnly) ->GetState()) fprintf(fp," pRec->SetRunLocalReconstruction(\"RICH\"); //clusters created for RICH only\n"); else if(fClusBG->GetButton(kNo) ->GetState()) fprintf(fp," pRec->SetRunLocalReconstruction(\"\"); //clusters are not created\n"); diff --git a/RICH/RichMake b/RICH/RichMake index b814b6a75c4..afe30c63439 100644 --- a/RICH/RichMake +++ b/RICH/RichMake @@ -40,11 +40,11 @@ DepFile := $(DirOut)/$(Module).depend ifeq ($(RootTarget),linuxicc) Compiler :=icc - CompilerOpt :=-O0 -fpstkchk -I$(shell root-config --incdir) -I$(ALICE_ROOT)/include + CompilerOpt :=-fpstkchk -I$(shell root-config --incdir) -I$(ALICE_ROOT)/include LibOpt :=-g -shared -Wl else Compiler :=g++ - CompilerOpt :=-O -g -W -Wall -Werror -Woverloaded-virtual -fPIC -pipe -fmessage-length=0 -Wno-long-long -pedantic-errors -ansi -Dlinux -D`uname` -I$(shell root-config --incdir) -I$(ALICE_ROOT)/include + CompilerOpt :=-g -W -Wall -Werror -Woverloaded-virtual -fPIC -pipe -fmessage-length=0 -Wno-long-long -pedantic-errors -ansi -Dlinux -D`uname` -I$(shell root-config --incdir) -I$(ALICE_ROOT)/include LibOpt :=-g -shared -Wl endif diff --git a/RICH/RichMenu.C b/RICH/RichMenu.C index 8c533c3728c..2c8bd1abee9 100644 --- a/RICH/RichMenu.C +++ b/RICH/RichMenu.C @@ -1,14 +1,15 @@ -AliRun *a; AliStack *s; AliRunLoader *al; //globals for easy manual manipulations -AliRICH *r; AliLoader *rl; +AliRun *a; AliStack *s; AliRunLoader *al; TGeoManager *g; //globals for easy manual manipulations +AliRICH *r; AliLoader *rl; AliRICHParam *rp; +Bool_t isGeomType=kFALSE; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void GeomAlign(Bool_t isAlign) +void GetParam() { - if(gGeoManager) delete gGeoManager; - if(AliRICHParam::Instance()) delete AliRICHParam::Instance(); - if(isAlign) TGeoManager::Import("geometry.root"); - else TGeoManager::Import("misaligned_geometry.root"); - AliRICHParam::Instance(); + isGeomType=!isGeomType; + if(g) delete g; if(rp) delete rp; //delete current TGeoManager and AliRICHParam + if(isGeomType) g=TGeoManager::Import("geometry.root"); + else g=TGeoManager::Import("misaligned_geometry.root"); + rp=AliRICHParam::Instance(); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void RichMenu() @@ -25,15 +26,19 @@ void RichMenu() }else status+="No galice.root"; + GetParam(); + TControlBar *pMenu = new TControlBar("horizontal",status.Data(),0,0); pMenu->AddButton(" ","",""); - pMenu->AddButton(" General " ,"General()" ,"general items which do not depend on any files"); - pMenu->AddButton(" ","",""); - pMenu->AddButton(" Sim data " ,"SimData()" ,"items which expect to have simulated files" ); - pMenu->AddButton(" ","",""); - pMenu->AddButton(" Raw data " ,"RawData()" ,"items which expect to have raw files" ); - pMenu->AddButton(" ","",""); - pMenu->AddButton("Quit" ,".q" ,"close session" ); + pMenu->AddButton(" General " ,"General()" ,"general items which do not depend on any files"); + pMenu->AddButton(" ","" ,""); + pMenu->AddButton(" Sim data " ,"SimData()" ,"items which expect to have simulated files" ); + pMenu->AddButton(" ","" ,""); + pMenu->AddButton(" Raw data " ,"RawData()" ,"items which expect to have raw files" ); + pMenu->AddButton(" ","print()" ,""); + pMenu->AddButton("Test" ,"Test()" ,"all test utilities"); + pMenu->AddButton(" ","GetParam()" ,""); + pMenu->AddButton("Quit" ,".q" ,"close session" ); pMenu->Show(); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -42,9 +47,6 @@ void General() TControlBar *pMenu = new TControlBar("vertical","Sim data",60,50); pMenu->AddButton("Debug ON" ,"don();" ,"Switch debug on-off" ); pMenu->AddButton("Debug OFF" ,"doff();" ,"Switch debug on-off" ); - pMenu->AddButton("Test segmentation" ,"AliRICHParam::TestSeg();" ,"Test AliRICHParam segmentation methods" ); - pMenu->AddButton("Test response" ,"AliRICHParam::TestResp();" ,"Test AliRICHParam response methods" ); - pMenu->AddButton("Test transformation","AliRICHParam::TestTrans();","Test AliRICHParam transformation methods" ); pMenu->AddButton("Geo GUI" ,"geo();" ,"Shows geometry" ); pMenu->AddButton("Browser" ,"new TBrowser;" ,"Start ROOT TBrowser" ); pMenu->Show(); @@ -53,12 +55,14 @@ void General() void SimData() { TControlBar *pMenu = new TControlBar("vertical","Sim",190,50); - pMenu->AddButton("Display single chambers" ,"r->Display();" , "Display Fast"); - pMenu->AddButton("Display ALL chambers" ,"r->DisplayEvent(0,0);" , "Display Fast"); - pMenu->AddButton("HITS Print" ,"h();" ,"To print hits: h()"); + pMenu->AddButton("Display ALL chambers" ,"ed();" , "Display Fast"); 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 hits" ,"hp();" ,"To print hits: hp(evt)"); + pMenu->AddButton("Print sdigits" ,"sp();" ,"To print sdigits: sp(evt)"); + pMenu->AddButton("Print digits" ,"dp();" ,"To print digits: dp(evt)"); + pMenu->AddButton("Print clusters" ,"cp();" ,"To print clusters: cp(evt)"); + pMenu->Show(); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -73,29 +77,40 @@ void RawData() pMenu->AddButton("Print occupancy" ,"r->OccupancyPrint(-1);" ,"To print occupancy" ); pMenu->AddButton("Print event summary " ,"r->SummaryOfEvent();" ,"To print a summary of the event" ); pMenu->Show(); -} +}//RawData +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void Test() +{ + TControlBar *pMenu = new TControlBar("vertical","Test",400,50); + pMenu->AddButton("Hits->Digits" ,"thd();" ,"test hits->sdigits->digits" ); + pMenu->AddButton("Segmentation" ,"ts()" ,"test segmentation methods" ); + pMenu->AddButton("Test response" ,"AliRICHParam::TestResp();" ,"Test AliRICHParam response methods" ); + pMenu->AddButton("Test transformation","AliRICHParam::TestTrans();","Test AliRICHParam transformation methods" ); + pMenu->AddButton("Test Recon" ,"rec();" ,"Test AliRICHRecon" ); + pMenu->Show(); +}//Test() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void doff(){ Printf("DebugOFF"); AliLog::SetGlobalDebugLevel(0);} void don() { Printf("DebugON"); AliLog::SetGlobalDebugLevel(AliLog::kDebug);} -void geo() { if(!gGeoManager) TGeoManager::Import("geometry.root");gGeoManager->GetTopVolume()->Draw();AliRICHParam::DrawAxis();} +void geo ( ) {gGeoManager->GetTopVolume()->Draw("ogl");} -void di (Int_t evt=-1 ) {r->Display (evt);} //utility display -void du ( ) {r->Dump ( );} //utility display +void du ( ) {r->Dump ( );} //utility display + +void hp (Int_t evt=0 ) {r->HitPrint (evt);} //print hits for requested event +void hq ( ) {r->HitQA ( );} //hits QA plots for all events +void sp (Int_t evt=0 ) {r->SdiPrint (evt);} //print sdigits for requested event +void sq (Int_t evt=0 ) {r->SdiPrint (evt);} //print sdigits for requested event +void dp (Int_t evt=0 ) {r->DigPrint (evt);} //print digits for requested event +void dq ( ) {AliRICHReconstructor::DigQA (al );} //digits QA plots for all events +void cp (Int_t evt=0 ) {r->CluPrint (evt); } //print clusters for requested event +void cq ( ) {AliRICHReconstructor::CluQA (al );} //clusters QA plots for all events -void hp (Int_t evt=0 ) {r->HitPrint (evt);} //print hits for requested event -void hq ( ) {r->HitQA ( );} //hits QA plots for all events -void sp (Int_t evt=0 ) {r->SDigPrint (evt);} //print sdigits for requested event -void sq (Int_t evt=0 ) {r->SDigPrint (evt);} //print sdigits for requested event -void dp (Int_t evt=0 ) {r->DigPrint (evt);} //print digits for requested event -void dq ( ) {AliRICHReconstructor::DigQA (al );} //digits QA plots for all events -void cp (Int_t evt=0 ) {r->CluPrint (evt);} //print clusters for requested event -void cq ( ) {AliRICHReconstructor::CluQA (al );} //clusters QA plots for all events -void ep ( ) {AliRICHTracker::EsdQA(1);} -void eq ( ) {AliRICHTracker::EsdQA();} -void mp (Double_t probCut=0.7 ) {AliRICHTracker::MatrixPrint(probCut);} +void ep ( ) {AliRICHTracker::EsdQA(1); } +void eq ( ) {AliRICHTracker::EsdQA(); } +void mp (Double_t probCut=0.7 ) {AliRICHTracker::MatrixPrint(probCut);} void t (Int_t evt=0 ) {AliRICHParam::Stack(evt);} @@ -114,3 +129,429 @@ Int_t nkp (Int_t evt=0) {AliRICHParam::StackCount(kKPlus ,evt);} //utility n 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 +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void tst() +{ + Int_t ch=3; + TClonesArray hitLst("AliRICHHit"); + TClonesArray sdiLst("AliRICHDigit"); + TObjArray digLst; for(Int_t i=0;i<7;i++) digLst.AddAt(new TClonesArray("AliRICHDigit"),i); + TClonesArray cluLst("AliRICHCluster"); + + Int_t iHitCnt=0; new(hitLst[iHitCnt++]) AliRICHHit(ch,200e-9,kProton,1, 8.40 , 60.14); //c,e,pid,tid,xl,yl +// new(hitLst[iHitCnt++]) AliRICHHit(ch,e*1e-9,kProton,2,x,y); //c,e,pid,tid,xl,yl,x,y,z + + Printf("HIT------HIT---------HIT--------HIT------HIT------HIT");hitLst.Print();Printf(""); + AliRICHv1::Hit2Sdi(&hitLst,&sdiLst); Printf("SDI------DIG---------SDI--------SDI------SDI------SDI");sdiLst.Print();Printf(""); + AliRICHDigitizer::Sdi2Dig(&sdiLst,&digLst); Printf("DIG------DIG---------DIG--------DIG------DIG------DIG");digLst.Print();Printf(""); + AliRICHReconstructor::Dig2Clu((TClonesArray*)digLst[ch],&cluLst); Printf("CLU------CLU---------CLU--------CLU------CLU------CLU");cluLst.Print();Printf(""); + + +} + + +void print() +{ + + Double_t r2d=TMath::RadToDeg(); + + Double_t x=AliRICHDigit::SizeAllX(),y=AliRICHDigit::SizeAllY(); + + TVector3 c6lt=rp->Lors2Mars(6,0,y); TVector3 c6rt=rp->Lors2Mars(6,x,y); + TVector3 c6ce=rp->Lors2Mars(6,x/2,y/2); + TVector3 c6lb=rp->Lors2Mars(6,0,0); TVector3 c6rb=rp->Lors2Mars(6,x,0); +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + TVector3 c5lt=rp->Lors2Mars(5,0,y); TVector3 c5rt=rp->Lors2Mars(5,x,y); + TVector3 c5ce=rp->Lors2Mars(5,x/2,y/2); + TVector3 c5lb=rp->Lors2Mars(5,0,0); TVector3 c5rb=rp->Lors2Mars(5,x,0); +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + TVector3 c4lt=rp->Lors2Mars(4,0,y); TVector3 c4rt=rp->Lors2Mars(4,x,y); + TVector3 c4ce=rp->Lors2Mars(4,x/2,y/2); + TVector3 c4lb=rp->Lors2Mars(4,0,0); TVector3 c4rb=rp->Lors2Mars(4,x,0); +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + TVector3 c3lt=rp->Lors2Mars(3,0,y); TVector3 c3rt=rp->Lors2Mars(3,x,y); + TVector3 c3ce=rp->Lors2Mars(3,x/2,y/2); + TVector3 c3lb=rp->Lors2Mars(3,0,0); TVector3 c3rb=rp->Lors2Mars(3,x,0); +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + TVector3 c2lt=rp->Lors2Mars(2,0,y); TVector3 c2rt=rp->Lors2Mars(2,x,y); + TVector3 c2ce=rp->Lors2Mars(2,x/2,y/2); + TVector3 c2lb=rp->Lors2Mars(2,0,0); TVector3 c2rb=rp->Lors2Mars(2,x,0); +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + TVector3 c1lt=rp->Lors2Mars(1,0,y); TVector3 c1rt=rp->Lors2Mars(1,x,y); + TVector3 c1ce=rp->Lors2Mars(1,x/2,y/2); + TVector3 c1lb=rp->Lors2Mars(1,0,0); TVector3 c1rb=rp->Lors2Mars(1,x,0); +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + TVector3 c0lt=rp->Lors2Mars(0,0,y); TVector3 c0rt=rp->Lors2Mars(0,x,y); + TVector3 c0ce=rp->Lors2Mars(0,x/2,y/2); + TVector3 c0lb=rp->Lors2Mars(0,0,0); TVector3 c0rb=rp->Lors2Mars(0,x,0); + + + Printf("\n\n\n"); + + Printf("_______________________________ _______________________________"); + Printf("|%7.2f %7.2f| |%7.2f %7.2f|",c6lt.Mag() ,c6rt.Mag() ,c5lt.Mag() ,c5rt.Mag() ); + Printf("|%7.2f %7.2f| |%7.2f %7.2f|",c6lt.Theta()*r2d ,c6rt.Theta()*r2d ,c5lt.Theta()*r2d ,c5rt.Theta()*r2d ); + Printf("|%7.2f %7.2f| |%7.2f %7.2f|",c6lt.Phi()*r2d ,c6rt.Phi()*r2d ,c5lt.Phi()*r2d ,c5rt.Phi()*r2d ); + Printf("| | | |"); + Printf("| %7.2f | | %7.2f | Sensitive area (130.60,126.16)" ,c6ce.Mag() ,c5ce.Mag() ); + Printf("| %7.2f | | %7.2f | Lors Center ( 65.30, 63.08)" ,c6ce.Theta()*r2d ,c5ce.Theta()*r2d ); + Printf("| %7.2f | | %7.2f |" ,c6ce.Phi()*r2d ,c5ce.Phi()*r2d ); + Printf("| | | |"); + Printf("|%7.2f %7.2f| |%7.2f %7.2f|",c6lb.Mag() ,c6rb.Mag() ,c5lb.Mag() ,c5rb.Mag() ); + Printf("|%7.2f %7.2f| |%7.2f %7.2f|",c6lb.Theta()*r2d ,c6rb.Theta()*r2d ,c5lb.Theta()*r2d ,c5rb.Theta()*r2d ); + Printf("|%7.2f %7.2f| |%7.2f %7.2f|",c6lb.Phi()*r2d ,c6rb.Phi()*r2d ,c5lb.Phi()*r2d ,c5rb.Phi()*r2d ); + Printf("------------------------------- -------------------------------"); + Printf(""); + Printf("_______________________________ _______________________________ _______________________________"); + Printf("|%7.2f %7.2f| |%7.2f %7.2f| |%7.2f %7.2f|",c4lt.Mag() ,c4rt.Mag() ,c3lt.Mag() ,c3rt.Mag() ,c2lt.Mag() ,c2rt.Mag() ); + Printf("|%7.2f %7.2f| |%7.2f %7.2f| |%7.2f %7.2f|",c4lt.Theta()*r2d,c4rt.Theta()*r2d,c3lt.Theta()*r2d,c3rt.Theta()*r2d,c2lt.Theta()*r2d ,c2rt.Theta()*r2d); + Printf("|%7.2f %7.2f| |%7.2f %7.2f| |%7.2f %7.2f|",c4lt.Phi()*r2d ,c4rt.Phi()*r2d ,c3lt.Phi()*r2d ,c3rt.Phi()*r2d ,c2lt.Phi()*r2d ,c2rt.Phi()*r2d ); + Printf("| | | | | |"); + Printf("| %7.2f | | %7.2f | | %7.2f |" ,c4ce.Mag() ,c3ce.Mag() ,c2ce.Mag()); + Printf("| %7.2f | | %7.2f | | %7.2f |" ,c4ce.Theta()*r2d,c3ce.Theta()*r2d,c2ce.Theta()*r2d); + Printf("| %7.2f | | %7.2f | | %7.2f |" ,c4ce.Phi()*r2d ,c3ce.Phi()*r2d ,c3ce.Phi()*r2d); + Printf("| | | | | |"); + Printf("|%7.2f %7.2f| |%7.2f %7.2f| |%7.2f %7.2f|",c4lb.Mag() ,c4rb.Mag() ,c3lb.Mag() ,c3rb.Mag() ,c2lt.Mag() ,c2rt.Mag() ); + Printf("|%7.2f %7.2f| |%7.2f %7.2f| |%7.2f %7.2f|",c4lb.Theta()*r2d,c4rb.Theta()*r2d,c3lb.Theta()*r2d,c3rb.Theta()*r2d,c2lt.Theta()*r2d ,c2rt.Theta()*r2d); + Printf("|%7.2f %7.2f| |%7.2f %7.2f| |%7.2f %7.2f|",c4lb.Phi()*r2d ,c4rb.Phi()*r2d ,c3lb.Phi()*r2d ,c3rb.Phi()*r2d ,c2lt.Phi()*r2d ,c2rt.Phi()*r2d ); + Printf("------------------------------- ------------------------------- -------------------------------"); + Printf(""); + Printf(" _______________________________ _______________________________"); + Printf(" |%7.2f %7.2f| |%7.2f %7.2f|",c1lt.Mag() ,c1rt.Mag() ,c0lt.Mag() ,c0rt.Mag() ); + Printf(" |%7.2f %7.2f| |%7.2f %7.2f|",c1lt.Theta()*r2d,c1rt.Theta()*r2d,c0lt.Theta()*r2d,c0rt.Theta()*r2d); + Printf(" |%7.2f %7.2f| |%7.2f %7.2f|",c1lt.Phi()*r2d ,c1rt.Phi()*r2d ,c0lt.Phi()*r2d ,c0rt.Phi()*r2d ); + Printf(" | | | |"); + Printf(" | %7.2f | | %7.2f |" ,c1ce.Mag() ,c0ce.Mag() ); + Printf(" | %7.2f | | %7.2f |" ,c1ce.Theta()*r2d,c0ce.Theta()*r2d); + Printf(" | %7.2f | | %7.2f |" ,c1ce.Phi()*r2d ,c0ce.Phi()*r2d ); + Printf(" | | | |"); + Printf(" |%7.2f %7.2f| |%7.2f %7.2f|",c1lb.Mag() ,c1rb.Mag() ,c0lb.Mag() ,c0rb.Mag() ); + Printf(" |%7.2f %7.2f| |%7.2f %7.2f|",c1lb.Theta()*r2d,c1rb.Theta()*r2d,c0lb.Theta()*r2d,c0rb.Theta()*r2d ); + Printf(" |%7.2f %7.2f| |%7.2f %7.2f|",c1lb.Phi()*r2d ,c1rb.Phi()*r2d ,c0lb.Phi()*r2d ,c0rb.Phi()*r2d ); + Printf(" ------------------------------- -------------------------------"); + + + Double_t m[3]; + for(int i=0;i<1000;i++){ + Float_t xout=0,xin=gRandom->Rndm()*130.60; + Float_t yout=0,yin=gRandom->Rndm()*126.16; + Int_t c=gRandom->Rndm()*6; + rp->Lors2Mars(c,xin,yin,m); + rp->Mars2Lors(c,m,xout,yout); + if( (xin-xout) != 0) Printf("Problem in X"); + if( (yin-yout) != 0) Printf("Problem in Y"); + } +}//print() + + +void rec() +{ + Double_t th=8*TMath::DegToRad();//gRandom->Rndm()*TMath::PiOver4(); + Double_t ph=gRandom->Rndm()*TMath::TwoPi(); 172.51*TMath::DegToRad(); + Double_t x=gRandom->Rndm()*AliRICHDigit::SizeAllX(); //101.59; + Double_t y=gRandom->Rndm()*2*AliRICHDigit::SizePcY();//38.06; + + + Double_t ckovMax=TMath::ACos(1./AliRICHRecon::fkRadIdx),ckovSim; + Int_t nSim=0; + while(nSim<3){ + ckovSim=gRandom->Rndm()*ckovMax;//0.6468; + nSim=20*TMath::Power(TMath::Sin(ckovSim)/TMath::Sin(ckovMax),2); //scale number of photons + } + + + TClonesArray *pCluLst=new TClonesArray("AliRICHCluster"); + TPolyMarker *pMipMap=new TPolyMarker(); pMipMap->SetMarkerStyle(8); pMipMap->SetMarkerColor(kRed); + TPolyMarker *pPhoMap=new TPolyMarker(); pPhoMap->SetMarkerStyle(4); pPhoMap->SetMarkerColor(kRed); + TPolyMarker *pBkgMap=new TPolyMarker(); pBkgMap->SetMarkerStyle(25); pBkgMap->SetMarkerColor(kRed); + TPolyLine *pRing =new TPolyLine; pRing->SetLineColor(kGreen); + TPolyLine *pOld =new TPolyLine; pOld->SetLineColor(kBlue); + + Int_t iCluCnt=0; pMipMap->SetPoint(iCluCnt,x,y); new((*pCluLst)[iCluCnt++]) AliRICHCluster(1,x,y,200); //add mip cluster + +// for(int j=0;j<30;j++){ //add bkg photons +// Float_t bkgX=gRandom->Rndm()*AliRICHDigit::SizeAllX(); +// Float_t bkgY=gRandom->Rndm()*AliRICHDigit::SizeAllY(); +// pBkgMap->SetPoint(iCluCnt,bkgX,bkgY); new((*pCluLst)[iCluCnt++]) AliRICHCluster(1,bkgX,bkgY,35); +// } + + + + + AliRICHRecon rec; rec.SetTrack(th,ph,x,y); + AliRICHReconOld old; old.SetTrack(th,ph,x,y); + + TVector2 pos; + for(int i=0;iRndm()*2*TMath::Pi(),pos); //add photons + if(AliRICHDigit::IsInDead(pos.X(),pos.Y())) continue; + pPhoMap->SetPoint(iCluCnt,pos.X(),pos.Y()); new((*pCluLst)[iCluCnt++]) AliRICHCluster(1,pos.X(),pos.Y(),35); + } + + for(int i=0;iGetEntries();i++){ + AliRICHCluster *pClu=(AliRICHCluster*)pCluLst->At(i); + Printf("diff phi %f ckov new %f ckov old %f",rec.FindPhotPhi(pClu->X(),pClu->Y())-old.FindPhotPhi(pClu->X(),pClu->Y()),rec.FindPhotCkov(pClu->X(),pClu->Y()),old.FindPhotCkov(pClu->X(),pClu->Y())); + } + + Int_t nRec=0,nOld=0; + Double_t ckovRec=rec.CkovAngle(pCluLst,nRec); Double_t err=TMath::Sqrt(rec.CkovSigma2()); + Double_t ckovOld=old.CkovAngle(pCluLst,nOld); + + Printf("---------------- Now reconstructed --------------------"); + + + for(int j=0;j<100;j++){rec.TracePhoton(ckovRec,j*0.0628,pos); pRing->SetPoint(j,pos.X(),pos.Y());} + for(int j=0;j<100;j++){rec.TracePhoton(ckovOld,j*0.0628,pos); pOld->SetPoint(j,pos.X(),pos.Y());} + + new TCanvas; AliRICHDigit::DrawPc(); pMipMap->Draw(); pPhoMap->Draw(); pBkgMap->Draw(); pRing->Draw(); pOld->Draw(); + + TLatex txt; txt.SetTextSize(0.03); + txt.DrawLatex(65,127,Form("#theta=%.4f#pm%.5f with %2i #check{C}" ,ckovSim, 0.,nSim )); + txt.DrawLatex(65,122,Form("#theta=%.4f#pm%.5f with %2i #check{C} Old=%.4f with %i #check{C}" ,ckovRec,err,nRec,ckovOld,nOld)); + txt.DrawLatex(0 ,127,Form("#theta=%.2f#circ #phi=%.2f#circ @(%.2f,%.2f) ",th*TMath::RadToDeg(),ph*TMath::RadToDeg(),x,y)); + +// for(int i=0;i<35;i++){ +// Double_t ckov=0.1+i*0.02; +// Printf("Ckov=%.2f Old=%.3f New=%.3f",ckov,old.FindRingArea(ckov),rec.FindRingArea(ckov)); +// } + + +}//rec() + +AliRICHRecon rec; AliRICHReconOld old; + +void aaa() +{ + rec.SetTrack(10*TMath::DegToRad(),1,30,60); old.SetTrack(10*TMath::DegToRad(),1,30,60); + TVector2 pos; + Double_t ckovSim=0.6234; + rec.TracePhoton(ckovSim,1,pos); + Printf("ckovSim %f",ckovSim); + double ckovRec=rec.FindPhotCkov(pos.X(),pos.Y()); + double ckovOld=old.FindPhotCkov(pos.X(),pos.Y()); + Printf("new %f old %f",ckovRec,ckovOld); +} + + + + + +void ed(Int_t e1=-1,Int_t e2=-1) +{r->Display(e1,e2); } +void AliRICH::Display(Int_t iEvtFrom,Int_t iEvtTo)const +{ +// Display digits, reconstructed tracks intersections and RICH rings if available + TH2F *pDigH[7]; + + GetLoader()->LoadDigits(); + + + + for(Int_t iCh=0;iCh<7;iCh++) { + pDigH[iCh]=new TH2F(Form("RichDigH_%i",iCh),Form("Cham %i;cm;cm",iCh),165,0,AliRICHDigit::SizeAllX(),144,0,AliRICHDigit::SizeAllY()); + pDigH[iCh]->SetMarkerColor(kGreen); + pDigH[iCh]->SetMarkerStyle(29); + pDigH[iCh]->SetMarkerSize(0.4); + pDigH[iCh]->SetStats(kFALSE); + pDigH[iCh]->SetMaximum(300); + } + + Int_t iNevt=GetLoader()->GetRunLoader()->GetNumberOfEvents(); + if(iEvtFrom< 0 ){iEvtFrom=0;iEvtTo=iNevt-1;} + if(iEvtTo >=iNevt){ iEvtTo=iNevt-1;} + + 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 iEvt=iEvtFrom;iEvt<=iEvtTo;iEvt++) { //events loop + pC->cd(3); t.DrawText(0.2,0.4,Form("Event %i",iEvt)); //print current event number + for(Int_t iCh=0;iCh<7;iCh++) pDigH[iCh]->Reset(); //reset all histograms + + GetLoader()->GetRunLoader()->GetEvent(iEvt); //switch to event directory + GetLoader()->TreeD()->GetEntry(0); //load digits list + for(Int_t iCh=0;iCh<7;iCh++) {//chambers loop + for(Int_t iDig=0;iDig < DigLst(iCh)->GetEntries();iDig++) { //digits loop + AliRICHDigit *pDig = (AliRICHDigit*)DigLst(iCh)->At(iDig); + pDigH[pDig->Ch()]->Fill(pDig->LorsX(),pDig->LorsY(),pDig->Q()); + } //digits loop + + if(iCh==0) pC->cd(9); + if(iCh==1) pC->cd(8); + if(iCh==2) pC->cd(6); + if(iCh==3) pC->cd(5); + if(iCh==4) pC->cd(4); + if(iCh==5) pC->cd(2); + if(iCh==6) pC->cd(1); + pDigH[iCh]->Draw("col"); + // AliRICHDigit::DrawPc(); + }//chambers loop + pC->Update(); + pC->Modified(); + + if(iEvtWaitPrimitive();pC->Clear();} + }//events loop +}//Display() + + +void AliRICH::HitQA(Double_t cut,Double_t cutele,Double_t cutR) +{ +// Provides a set of control plots intended primarily for charged particle flux analisys +// Arguments: cut (GeV) - cut on momentum of any charged particles but electrons, +// cetele (GeV) - the same for electrons-positrons +// cutR (cm) - cut on production vertex radius (cylindrical system) + gBenchmark->Start("HitsAna"); + + Double_t cutPantiproton =cut; + Double_t cutPkaonminus =cut; + Double_t cutPpionminus =cut; + Double_t cutPmuonminus =cut; + Double_t cutPpositron =cutele; + + Double_t cutPelectron =cutele; + Double_t cutPmuonplus =cut; + Double_t cutPpionplus =cut; + Double_t cutPkaonplus =cut; + Double_t cutPproton =cut; + + + TH2F *pEleHitRZ =new TH2F("EleHitRZ" ,Form("e^{+} e^{-} hit %s;z[cm];R[cm]" ,GetName()) , 400,-300,300 ,400,-500,500); //R-z plot 0cmSetStats(0); + pFlux->GetXaxis()->SetBinLabel(1 ,Form("p^{-}>%.3fGeV/c" ,cutPantiproton)); + pFlux->GetXaxis()->SetBinLabel(2 ,Form("K^{-}>%.3fGeV/c" ,cutPkaonminus )); + pFlux->GetXaxis()->SetBinLabel(3 ,Form("#pi^{-}>%.3fGeV/c" ,cutPpionminus )); + pFlux->GetXaxis()->SetBinLabel(4 ,Form("#mu^{-}>%.3fGeV/c" ,cutPmuonminus )); + pFlux->GetXaxis()->SetBinLabel(5 ,Form("e^{+}>%.3fGeV/c" ,cutPpositron )); + + pFlux->GetXaxis()->SetBinLabel(6 ,Form("e^{-}>%.3fGeV/c" ,cutPelectron )); + pFlux->GetXaxis()->SetBinLabel(7 ,Form("#mu^{+}>%.3fGeV/c" ,cutPmuonplus )); + pFlux->GetXaxis()->SetBinLabel(8 ,Form("#pi^{+}>%.3fGeV/c" ,cutPpionplus )); + pFlux->GetXaxis()->SetBinLabel(9 ,Form("K^{+}>%.3fGeV/c" ,cutPkaonplus )); + pFlux->GetXaxis()->SetBinLabel(10,Form("p^{+}>%.3fGeV/c" ,cutPproton )); + + pFlux->GetYaxis()->SetBinLabel(1,"sum"); + pFlux->GetYaxis()->SetBinLabel(2,"ch1"); + pFlux->GetYaxis()->SetBinLabel(3,"ch2"); + pFlux->GetYaxis()->SetBinLabel(4,"ch3"); + pFlux->GetYaxis()->SetBinLabel(5,"ch4"); + pFlux->GetYaxis()->SetBinLabel(6,"ch5"); + pFlux->GetYaxis()->SetBinLabel(7,"ch6"); + pFlux->GetYaxis()->SetBinLabel(8,"ch7"); + pFlux->GetYaxis()->SetBinLabel(9,"prim"); + pFlux->GetYaxis()->SetBinLabel(10,"tot"); + +//end of hists definition + + Int_t iNevents=fLoader->GetRunLoader()->GetAliRun()->GetEventsPerRun(),iCntPrimParts=0,iCntTotParts=0; +//load all needed trees + fLoader->LoadHits(); + fLoader->GetRunLoader()->LoadHeader(); + fLoader->GetRunLoader()->LoadKinematics(); + + for(Int_t iEvtN=0;iEvtN < iNevents;iEvtN++){//events loop + fLoader->GetRunLoader()->GetEvent(iEvtN); + AliInfo(Form(" %i event processes",fLoader->GetRunLoader()->GetEventNumber())); + AliStack *pStack= fLoader->GetRunLoader()->Stack(); + + for(Int_t iParticleN=0;iParticleNGetNtrack();iParticleN++){//stack loop + TParticle *pPart=pStack->Particle(iParticleN); + + if(iParticleN%10000==0) AliInfo(Form(" %i particles read",iParticleN)); + + switch(pPart->GetPdgCode()){ + case kProtonBar: pFlux->Fill(-4.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-4.5,8); break; + case kKMinus: pFlux->Fill(-3.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-3.5,8); break; + case kPiMinus: pFlux->Fill(-2.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-2.5,8); break; + case kMuonMinus: pFlux->Fill(-1.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-1.5,8); break; + case kPositron: pFlux->Fill(-0.5,9); if(pPart->Rho()<0.01) pFlux->Fill(-0.5,8); pEleAllP->Fill(-pPart->P()); break; + + case kElectron: pFlux->Fill( 0.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 0.5,8); pEleAllP->Fill( pPart->P()); break; + case kMuonPlus: pFlux->Fill( 1.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 1.5,8); break; + case kPiPlus: pFlux->Fill( 2.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 2.5,8); break; + case kKPlus: pFlux->Fill( 3.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 3.5,8); break; + case kProton: pFlux->Fill( 4.5,9); if(pPart->Rho()<0.01) pFlux->Fill( 4.5,8); break; + }//switch + }//stack loop +//now hits analiser + for(Int_t iEntryN=0;iEntryN < fLoader->TreeH()->GetEntries();iEntryN++){//TreeH loop + fLoader->TreeH()->GetEntry(iEntryN); //get current entry (prim) + for(Int_t iHitN=0;iHitN < Hits()->GetEntries();iHitN++){//hits loop + AliRICHHit *pHit = (AliRICHHit*)Hits()->At(iHitN); //get current hit + TParticle *pPart=pStack->Particle(pHit->GetTrack()); //get stack particle which produced the current hit + + if(pPart->GetPDG()->Charge()!=0&&pPart->Rho()>0.1) pVertex->Fill(pPart->Vx(),pPart->Vy()); //safe margin for sec. + if(pPart->GetPDG()->Charge()!=0) pRho->Fill(pPart->Rho()); //safe margin for sec. + if(pPart->R()>cutR) continue; //cut on production radius (cylindrical system) + + switch(pPart->GetPdgCode()){ + case kProtonBar: if(pPart->P()>cutPantiproton) {pProHitP->Fill(-pPart->P()); pFlux->Fill(-4.5,pHit->Ch());}break; + case kKMinus : if(pPart->P()>cutPkaonminus) {pKaoHitP->Fill(-pPart->P()); pFlux->Fill(-3.5,pHit->Ch());}break; + case kPiMinus : if(pPart->P()>cutPpionminus) {pPioHitP->Fill(-pPart->P()); pFlux->Fill(-2.5,pHit->Ch());}break; + case kMuonMinus: if(pPart->P()>cutPmuonminus) {pMuoHitP->Fill(-pPart->P()); pFlux->Fill(-1.5,pHit->Ch());}break; + case kPositron : if(pPart->P()>cutPpositron) {pEleHitP->Fill(-pPart->P()); pFlux->Fill(-0.5,pHit->Ch()); + pEleHitRP->Fill(-pPart->P(),pPart->R()); pEleHitRZ->Fill(pPart->Vz(),pPart->R()); }break; + + case kElectron : if(pPart->P()>cutPelectron) {pEleHitP->Fill( pPart->P()); pFlux->Fill( 0.5,pHit->Ch()); + pEleHitRP->Fill( pPart->P(),pPart->R()); pEleHitRZ->Fill(pPart->Vz(),pPart->R()); }break; + case kMuonPlus : if(pPart->P()>cutPmuonplus) {pMuoHitP->Fill( pPart->P()); pFlux->Fill( 1.5,pHit->Ch());}break; + case kPiPlus : if(pPart->P()>cutPpionplus) {pPioHitP->Fill( pPart->P()); pFlux->Fill( 2.5,pHit->Ch());}break; + case kKPlus : if(pPart->P()>cutPkaonplus) {pKaoHitP->Fill( pPart->P()); pFlux->Fill( 3.5,pHit->Ch());}break; + case kProton : if(pPart->P()>cutPproton) {pProHitP->Fill( pPart->P()); pFlux->Fill( 4.5,pHit->Ch());}break; + } + }//hits loop + }//TreeH loop + iCntPrimParts +=pStack->GetNprimary(); + iCntTotParts +=pStack->GetNtrack(); + }//events loop +//unload all loaded staff + fLoader->UnloadHits(); + fLoader->GetRunLoader()->UnloadHeader(); + fLoader->GetRunLoader()->UnloadKinematics(); +//Calculater some sums + Stat_t sum=0; +//sum row, sum over rows + for(Int_t i=1;i<=pFlux->GetNbinsX();i++){ + sum=0; for(Int_t j=2;j<=8;j++) sum+=pFlux->GetBinContent(i,j); + pFlux->SetBinContent(i,1,sum); + } + +//display everything + new TCanvas("canvas1",Form("Events %i Nprims=%i Nparticles=%i",iNevents,iCntPrimParts,iCntTotParts),1000,900); pFlux->Draw("text"); gPad->SetGrid(); +//total prims and particles + TLatex latex; latex.SetTextSize(0.02); + sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,10); latex.DrawLatex(5.1,9.5,Form("%.0f",sum)); + sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,9); latex.DrawLatex(5.1,8.5,Form("%.0f",sum)); + for(Int_t iCh=0;iCh<7;iCh++) { + sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,iCh+2);latex.DrawLatex(5.1,iCh+1.5,Form("%.0f",sum)); + } + sum=0; for(Int_t i=1;i<=pFlux->GetNbinsX();i++) sum+=pFlux->GetBinContent(i,1); latex.DrawLatex(5.1,0.5,Form("%.0f",sum)); + + new TCanvas("cEleAllP" ,"e" ,200,100); pEleAllP->Draw(); + new TCanvas("cEleHitRP" ,"e" ,200,100); pEleHitRP->Draw(); + new TCanvas("cEleHitRZ" ,"e" ,200,100); pEleHitRZ->Draw(); + new TCanvas("cEleHitP" ,"e" ,200,100); pEleHitP->Draw(); + new TCanvas("cMuoHitP" ,"mu",200,100); pMuoHitP->Draw(); + new TCanvas("cPioHitP" ,"pi",200,100); pPioHitP->Draw(); + new TCanvas("cKaoHitP" ,"K" ,200,100); pKaoHitP->Draw(); + new TCanvas("cProHitP" ,"p" ,200,100); pProHitP->Draw(); + new TCanvas("cVertex" ,"2d vertex" ,200,100); pVertex->Draw(); + new TCanvas("cRho" ,"Rho of sec" ,200,100); pRho->Draw(); + + gBenchmark->Show("HitsPlots"); +}//HitQA() + + + + + diff --git a/RICH/api.txt b/RICH/api.txt index eeb2a495f7e..12ff91b2242 100644 --- a/RICH/api.txt +++ b/RICH/api.txt @@ -271,19 +271,18 @@ RICH 6 Map of all RICH PC planes, coordinates are in spherical system= distance from IP in cm, Theta and Phi in degrees: - - _______________________________ _______________________________ +_______________________________ _______________________________ | 506.21 506.21| | 506.21 506.21| | 63.26 78.07| | 82.59 97.41| | 58.02 57.32| | 57.22 57.22| | | | | -| 498.00 | | 498.00 | Sensitive area (130.60,126.16) +| 498.00 | | 498.00 | Sensitive area (130.60,126.16) | 70.50 | | 90.00 | Lors Center ( 65.30, 63.08) | 50.00 | | 50.00 | | | | | | 506.21 506.21| | 506.21 506.21| | 63.26 78.07| | 82.59 97.41| -| 41.98 42.68| | 57.22 57.22| +| 41.98 6 42.68| | 42.78 5 42.78| ------------------------------- ------------------------------- _______________________________ _______________________________ _______________________________ @@ -297,7 +296,7 @@ _______________________________ _______________________________ ____________ | | | | | | | 506.21 506.21| | 506.21 506.21| | 506.21 506.21| | 63.26 78.07| | 82.59 97.41| | 101.93 116.74| -| 38.02 37.32| | 37.22 37.22| | 37.32 38.02| +| 21.98 4 22.68| | 22.78 3 22.78| | 37.32 2 38.02| ------------------------------- ------------------------------- ------------------------------- _______________________________ _______________________________ @@ -311,6 +310,6 @@ _______________________________ _______________________________ ____________ | | | | | 506.21 506.21| | 506.21 506.21| | 82.59 97.41| | 101.93 116.74| - | 17.22 17.22| | 17.32 18.02| + | 2.78 1 2.78| | 2.68 0 1.98| ------------------------------- ------------------------------- diff --git a/RICH/libRICHbase.pkg b/RICH/libRICHbase.pkg index a1a5d5f7653..b73c2aa1893 100644 --- a/RICH/libRICHbase.pkg +++ b/RICH/libRICHbase.pkg @@ -1,4 +1,4 @@ -SRCS:= AliRICHParam.cxx AliRICHHit.cxx AliRICHDigit.cxx AliRICHCluster.cxx AliRICHHelix.cxx AliRICH.cxx +SRCS:= AliRICHHelix.cxx AliRICHHit.cxx AliRICHDigit.cxx AliRICHCluster.cxx AliRICHParam.cxx AliRICH.cxx HDRS:= $(SRCS:.cxx=.h) DHDR:= RICHbaseLinkDef.h diff --git a/RICH/libRICHrec.pkg b/RICH/libRICHrec.pkg index 1cbca653d3d..668d3fbb77d 100644 --- a/RICH/libRICHrec.pkg +++ b/RICH/libRICHrec.pkg @@ -1,4 +1,4 @@ -SRCS:= AliRICHReconstructor.cxx AliRICHTracker.cxx AliRICHRecon.cxx AliRICHPreprocessor.cxx +SRCS:= AliRICHReconstructor.cxx AliRICHTracker.cxx AliRICHRecon.cxx AliRICHReconOld.cxx AliRICHPreprocessor.cxx HDRS:= $(SRCS:.cxx=.h) DHDR:= RICHrecLinkDef.h -- 2.43.0