From d3da6dc43093d4c8277bc65a3e807cd347986007 Mon Sep 17 00:00:00 2001 From: hristov Date: Wed, 29 Nov 2006 09:14:09 +0000 Subject: [PATCH] This commit was generated by cvs2svn to compensate for changes in r15977, which included commits to RCS files with non-trunk default branches. --- HMPID/AliHMPID.cxx | 240 +++++++ HMPID/AliHMPID.h | 63 ++ HMPID/AliHMPIDCluster.cxx | 148 ++++ HMPID/AliHMPIDCluster.h | 60 ++ HMPID/AliHMPIDDigit.cxx | 198 ++++++ HMPID/AliHMPIDDigit.h | 176 +++++ HMPID/AliHMPIDDigitN.cxx | 168 +++++ HMPID/AliHMPIDDigitN.h | 90 +++ HMPID/AliHMPIDDigitizer.cxx | 104 +++ HMPID/AliHMPIDDigitizer.h | 24 + HMPID/AliHMPIDHelix.cxx | 25 + HMPID/AliHMPIDHelix.h | 71 ++ HMPID/AliHMPIDHit.cxx | 43 ++ HMPID/AliHMPIDHit.h | 35 + HMPID/AliHMPIDParam.cxx | 99 +++ HMPID/AliHMPIDParam.h | 57 ++ HMPID/AliHMPIDPreprocessor.cxx | 75 ++ HMPID/AliHMPIDPreprocessor.h | 19 + HMPID/AliHMPIDRecon.cxx | 442 ++++++++++++ HMPID/AliHMPIDRecon.h | 71 ++ HMPID/AliHMPIDReconstructor.cxx | 237 +++++++ HMPID/AliHMPIDReconstructor.h | 54 ++ HMPID/AliHMPIDSelector.C | 186 +++++ HMPID/AliHMPIDTracker.cxx | 112 +++ HMPID/AliHMPIDTracker.h | 28 + HMPID/AliHMPIDv0.cxx | 26 + HMPID/AliHMPIDv0.h | 22 + HMPID/AliHMPIDv1.cxx | 657 ++++++++++++++++++ HMPID/AliHMPIDv1.h | 42 ++ HMPID/Align/Data/Run0_9999999_v0_s0.root | Bin 0 -> 2060 bytes HMPID/HMPIDAlign.C | 28 + HMPID/HMPIDAna.C | 68 ++ HMPID/HMPIDConfig.C | 620 +++++++++++++++++ .../HMPIDConfig/RefIdxC6F14/Run0_0_v0_s0.root | Bin 0 -> 3317 bytes .../HMPIDConfig/RefIdxC6F14/Run0_0_v0_s1.root | Bin 0 -> 3319 bytes HMPID/HMPIDGeom.C | 434 ++++++++++++ HMPID/HMPIDMake | 135 ++++ HMPID/HMPIDMenu.C | 501 +++++++++++++ HMPID/HMPIDTestShuttle.C | 62 ++ HMPID/HMPIDbaseLinkDef.h | 11 + HMPID/HMPIDrecLinkDef.h | 9 + HMPID/HMPIDsimLinkDef.h | 8 + HMPID/MakeHMPIDFullMisAlignment.C | 45 ++ HMPID/MakeHMPIDResMisAlignment.C | 44 ++ HMPID/api.txt | 315 +++++++++ HMPID/libHMPIDbase.pkg | 4 + HMPID/libHMPIDrec.pkg | 4 + HMPID/libHMPIDsim.pkg | 4 + HMPID/red.C | 49 ++ 49 files changed, 5913 insertions(+) create mode 100644 HMPID/AliHMPID.cxx create mode 100644 HMPID/AliHMPID.h create mode 100644 HMPID/AliHMPIDCluster.cxx create mode 100644 HMPID/AliHMPIDCluster.h create mode 100644 HMPID/AliHMPIDDigit.cxx create mode 100644 HMPID/AliHMPIDDigit.h create mode 100644 HMPID/AliHMPIDDigitN.cxx create mode 100644 HMPID/AliHMPIDDigitN.h create mode 100644 HMPID/AliHMPIDDigitizer.cxx create mode 100644 HMPID/AliHMPIDDigitizer.h create mode 100644 HMPID/AliHMPIDHelix.cxx create mode 100644 HMPID/AliHMPIDHelix.h create mode 100644 HMPID/AliHMPIDHit.cxx create mode 100644 HMPID/AliHMPIDHit.h create mode 100644 HMPID/AliHMPIDParam.cxx create mode 100644 HMPID/AliHMPIDParam.h create mode 100644 HMPID/AliHMPIDPreprocessor.cxx create mode 100644 HMPID/AliHMPIDPreprocessor.h create mode 100644 HMPID/AliHMPIDRecon.cxx create mode 100644 HMPID/AliHMPIDRecon.h create mode 100644 HMPID/AliHMPIDReconstructor.cxx create mode 100644 HMPID/AliHMPIDReconstructor.h create mode 100644 HMPID/AliHMPIDSelector.C create mode 100644 HMPID/AliHMPIDTracker.cxx create mode 100644 HMPID/AliHMPIDTracker.h create mode 100644 HMPID/AliHMPIDv0.cxx create mode 100644 HMPID/AliHMPIDv0.h create mode 100644 HMPID/AliHMPIDv1.cxx create mode 100644 HMPID/AliHMPIDv1.h create mode 100644 HMPID/Align/Data/Run0_9999999_v0_s0.root create mode 100644 HMPID/HMPIDAlign.C create mode 100644 HMPID/HMPIDAna.C create mode 100644 HMPID/HMPIDConfig.C create mode 100644 HMPID/HMPIDConfig/RefIdxC6F14/Run0_0_v0_s0.root create mode 100644 HMPID/HMPIDConfig/RefIdxC6F14/Run0_0_v0_s1.root create mode 100644 HMPID/HMPIDGeom.C create mode 100644 HMPID/HMPIDMake create mode 100644 HMPID/HMPIDMenu.C create mode 100644 HMPID/HMPIDTestShuttle.C create mode 100644 HMPID/HMPIDbaseLinkDef.h create mode 100644 HMPID/HMPIDrecLinkDef.h create mode 100644 HMPID/HMPIDsimLinkDef.h create mode 100644 HMPID/MakeHMPIDFullMisAlignment.C create mode 100644 HMPID/MakeHMPIDResMisAlignment.C create mode 100644 HMPID/api.txt create mode 100644 HMPID/libHMPIDbase.pkg create mode 100644 HMPID/libHMPIDrec.pkg create mode 100644 HMPID/libHMPIDsim.pkg create mode 100644 HMPID/red.C diff --git a/HMPID/AliHMPID.cxx b/HMPID/AliHMPID.cxx new file mode 100644 index 00000000000..a11e9f0f395 --- /dev/null +++ b/HMPID/AliHMPID.cxx @@ -0,0 +1,240 @@ +// ************************************************************************** +// * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +// * * +// * Author: The ALICE Off-line Project. * +// * Contributors are mentioned in the code where appropriate. * +// * * +// * Permission to use, copy, modify and distribute this software and its * +// * documentation strictly for non-commercial purposes is hereby granted * +// * without fee, provided that the above copyright notice appears in all * +// * copies and that both the copyright notice and this permission notice * +// * appear in the supporting documentation. The authors make no claims * +// * about the suitability of this software for any purpose. It is * +// * provided "as is" without express or implied warranty. * +// ************************************************************************** + +#include "AliHMPID.h" +#include "AliHMPIDHit.h" //OccupancyPrint(), HitQa() +#include "AliHMPIDDigit.h" //OccupancyPrint() +#include //SummaryOfEvent(), HitQa() +#include //HitQA() +#include //HitQA() +#include //OccupancyPrint(), SummaryOfEvent(), HitQa() +#include //HitQa() +#include //ctor +#include +#include +#include +#include //HitQA() +#include //in many methods to print AliInfo +ClassImp(AliHMPID) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliHMPID::AliHMPID(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); + AliDebug(1,"Stop."); +}//AliHMPID::AliHMPID(const char *name, const char *title) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliHMPID::~AliHMPID() +{ +//dtor + AliDebug(1,"Start."); + + + if(fHits) delete fHits; + if(fDigits) delete fDigits; + if(fSdi) delete fSdi; + if(fDig) {fDig->Delete(); delete fDig;} + if(fClu) {fClu->Delete(); delete fClu;} + AliDebug(1,"Stop."); +}//AliHMPID::~AliHMPID() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPID::MakeBranch(Option_t* option) +{ +//Create Tree branches for the HMPID. + AliDebug(1,Form("Start with option= %s.",option)); + + 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()){HitCreate(); MakeBranchInTree( TreeH(), "HMPID" ,&fHits ,kBufSize,0);} + if(cS&&fLoader->TreeS()){SdiCreate(); MakeBranchInTree(fLoader->TreeS(), "HMPID" ,&fSdi ,kBufSize,0);} + if(cD&&fLoader->TreeD()){DigCreate();for(Int_t i=0;i<7;i++) MakeBranchInTree(fLoader->TreeD(),Form("HMPID%d",i),&((*fDig)[i]),kBufSize,0);} + if(cR&&fLoader->TreeR()){CluCreate();for(Int_t i=0;i<7;i++) MakeBranchInTree(fLoader->TreeR(),Form("HMPID%d",i),&((*fClu)[i]),kBufSize,0);} + + AliDebug(1,"Stop."); +}//void AliHMPID::MakeBranch(Option_t* option) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPID::SetTreeAddress() +{ +//Set branch address for the Hits and Digits Tree. + AliDebug(1,"Start."); + if(fLoader->TreeH() && fLoader->TreeH()->GetBranch("HMPID" )){HitCreate(); fLoader->TreeH()->SetBranchAddress( "HMPID" ,&fHits );} + if(fLoader->TreeS() && fLoader->TreeS()->GetBranch("HMPID" )){SdiCreate(); fLoader->TreeS()->SetBranchAddress( "HMPID" ,&fSdi );} + if(fLoader->TreeD() && fLoader->TreeD()->GetBranch("HMPID0")){DigCreate(); for(int i=0;i<7;i++) fLoader->TreeD()->SetBranchAddress(Form("HMPID%d",i),&((*fDig)[i]));} + if(fLoader->TreeR() && fLoader->TreeR()->GetBranch("HMPID0")){CluCreate(); for(int i=0;i<7;i++) fLoader->TreeR()->SetBranchAddress(Form("HMPID%d",i),&((*fClu)[i]));} + AliDebug(1,"Stop."); +}//void AliHMPID::SetTreeAddress() +//__________________________________________________________________________________________________ +// AliHMPIDHit* AliHMPID::Hit(Int_t tid)const +// { +// // Search for the first HMPID hit belonging to the given tid +// GetLoader()->LoadHits(); +// for(Int_t iPrimN=0;iPrimNTreeH()->GetEntries();iPrimN++){//prims loop +// GetLoader()->TreeH()->GetEntry(iPrimN); +// for(Int_t iHitN=0;iHitNGetEntries();iHitN++){ +// AliHMPIDHit *pHit=(AliHMPIDHit*)Hits()->At(iHitN); +// if(tid==pHit->Track()) {GetLoader()->UnloadHits();return pHit;} +// }//hits +// }//prims loop +// GetLoader()->UnloadHits(); +// return 0; +// } +//__________________________________________________________________________________________________ +void AliHMPID::HitPrint(Int_t iEvtN)const +{ +//Prints a list of HMPID hits for a given event. Default is event number 0. + if(GetLoader()->GetRunLoader()->GetEvent(iEvtN)) return; + AliInfo(Form("List of HMPID hits for event %i",iEvtN)); + if(GetLoader()->LoadHits()) return; + + Int_t iTotalHits=0; + for(Int_t iPrimN=0;iPrimNTreeH()->GetEntries();iPrimN++){//prims loop + GetLoader()->TreeH()->GetEntry(iPrimN); + Hits()->Print(); + iTotalHits+=Hits()->GetEntries(); + } + GetLoader()->UnloadHits(); + AliInfo(Form("totally %i hits",iTotalHits)); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPID::SdiPrint(Int_t iEvt)const +{ +//prints a list of HMPID sdigits for a given event + if(GetLoader()->GetRunLoader()->GetEvent(iEvt)) return; + Info("PrintSDigits","List of HMPID sdigits for event %i",iEvt); + if(GetLoader()->LoadSDigits()) return; + + GetLoader()->TreeS()->GetEntry(0); + SdiLst()->Print(); + GetLoader()->UnloadSDigits(); + Printf("totally %i sdigits",SdiLst()->GetEntries()); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPID::DigPrint(Int_t iEvt)const +{ +//prints a list of HMPID digits for a given event + if(GetLoader()->GetRunLoader()->GetEvent(iEvt)) return; + Printf("List of HMPID digits for event %i",iEvt); + if(GetLoader()->LoadDigits()) return; + + GetLoader()->TreeD()->GetEntry(0); + DigLst()->Print(); + GetLoader()->UnloadDigits(); + Printf("totally %i Digits",DigLst()->GetEntries()); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPID::OccupancyPrint(Int_t iEvtNreq) +{ +//prints occupancy for each chamber in a given event + Int_t iEvtNmin,iEvtNmax; + if(iEvtNreq==-1){ + iEvtNmin=0; + iEvtNmax=gAlice->GetEventsPerRun(); + } else { + iEvtNmin=iEvtNreq;iEvtNmax=iEvtNreq+1; + } + + if(GetLoader()->GetRunLoader()->LoadHeader()) return; + if(GetLoader()->GetRunLoader()->LoadKinematics()) return; + +// Info("Occupancy","for event %i",iEvtN); + if(GetLoader()->LoadHits()) return; + if(GetLoader()->LoadDigits()) return; + + + 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++){ + AliHMPIDHit *pHit = (AliHMPIDHit*)Hits()->At(iHitN); + if(pHit->E()>0){ + iChHits[pHit->Ch()]++; + if(pStack->Particle(pHit->GetTrack())->Rho()<0.01) nPrim[pHit->Ch()]++;else nSec[pHit->Ch()]++; + } + } + } + + GetLoader()->TreeD()->GetEntry(0); + for(Int_t iCh=0;iCh<7;iCh++){ + for(Int_t iDig=0;iDigGetEntries();iDig++){ + AliHMPIDDigit *pDig=(AliHMPIDDigit*)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/AliHMPIDDigit::kPadAll,nPrim[iCh],nSec[iCh],iChHits[iCh]); + } + + + }//events loop + GetLoader()->UnloadHits(); + GetLoader()->UnloadDigits(); + GetLoader()->GetRunLoader()->UnloadHeader(); + GetLoader()->GetRunLoader()->UnloadKinematics(); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPID::CluPrint(Int_t iEvtN)const +{ +//prints a list of HMPID clusters for a given event + Printf("List of HMPID clusters for event %i",iEvtN); + GetLoader()->GetRunLoader()->GetEvent(iEvtN); + if(GetLoader()->LoadRecPoints()) return; + + Int_t iCluCnt=0; + GetLoader()->TreeR()->GetEntry(0); + 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 AliHMPID::SummaryOfEvent(Int_t iEvtN) const +{ +//prints a summary for a given event + AliInfo(Form("Summary of event %i",iEvtN)); + GetLoader()->GetRunLoader()->GetEvent(iEvtN); + if(GetLoader()->GetRunLoader()->LoadHeader()) return; + if(GetLoader()->GetRunLoader()->LoadKinematics()) return; + AliStack *pStack=GetLoader()->GetRunLoader()->Stack(); + + AliGenEventHeader* pGenHeader = gAlice->GetHeader()->GenEventHeader(); + if(pGenHeader->InheritsFrom("AliGenHijingEventHeader")) { + AliInfo(Form(" Hijing event with impact parameter b = %.2f (fm)",((AliGenHijingEventHeader*) pGenHeader)->ImpactParameter())); + } + Int_t nChargedPrimaries=0; + for(Int_t i=0;iGetNtrack();i++) { + TParticle *pParticle = pStack->Particle(i); + if(pParticle->IsPrimary()&&pParticle->GetPDG()->Charge()!=0) nChargedPrimaries++; + } + AliInfo(Form("Total number of primaries %i",pStack->GetNprimary())); + AliInfo(Form("Total number of charged primaries %i",nChargedPrimaries)); + AliInfo(Form("Total n. of tracks in stack(+sec) %i",pStack->GetNtrack())); + GetLoader()->GetRunLoader()->UnloadHeader(); + GetLoader()->GetRunLoader()->UnloadKinematics(); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/HMPID/AliHMPID.h b/HMPID/AliHMPID.h new file mode 100644 index 00000000000..89812cb7c9a --- /dev/null +++ b/HMPID/AliHMPID.h @@ -0,0 +1,63 @@ +#ifndef AliHMPID_h +#define AliHMPID_h +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +#include //base class +#include //XxxCreate() +#include //fClu field + + + +class AliHMPID : public AliDetector //TObject-TNamed-AliModule-AliDetector-AliHMPID +{ +public: +//ctor & dtor + AliHMPID(const char *nm,const char *ttl); //named ctor + AliHMPID( ):AliDetector( ),fSdi(0),fDig(0),fClu(0) {} //default ctor + virtual ~AliHMPID(); +//framework part + 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 HMPID 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("AliHMPIDHit"); 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("AliHMPIDDigit"); }//create sdigits list + void SdiReset ( ) {if(fSdi) fSdi ->Clear(); }//clean sdigits list + void SdiPrint (Int_t evt)const; //print sdigits + + 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("AliHMPIDDigit"),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* 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("AliHMPIDCluster"),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 OccupancyPrint(Int_t evt=-1); //print chambers occupancy + void SummaryOfEvent(Int_t evt=0)const; + +protected: + TClonesArray *fSdi; //! list of sdigits + TObjArray *fDig; //! each chamber holds it's one list of digits + TObjArray *fClu; //! each chamber holds it's one list of clusters + + private: + AliHMPID(const AliHMPID &rich ); + AliHMPID& operator=(const AliHMPID&); + + ClassDef(AliHMPID,11) //Main HMPID class +};//class AliHMPID +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#endif diff --git a/HMPID/AliHMPIDCluster.cxx b/HMPID/AliHMPIDCluster.cxx new file mode 100644 index 00000000000..70cd58bb85e --- /dev/null +++ b/HMPID/AliHMPIDCluster.cxx @@ -0,0 +1,148 @@ +// ************************************************************************** +// * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +// * * +// * Author: The ALICE Off-line Project. * +// * Contributors are mentioned in the code where appropriate. * +// * * +// * Permission to use, copy, modify and distribute this software and its * +// * documentation strictly for non-commercial purposes is hereby granted * +// * without fee, provided that the above copyright notice appears in all * +// * copies and that both the copyright notice and this permission notice * +// * appear in the supporting documentation. The authors make no claims * +// * about the suitability of this software for any purpose. It is * +// * provided "as is" without express or implied warranty. * +// ************************************************************************** + +#include "AliHMPIDCluster.h" //class header +#include //Solve() +#include //Solve() + +ClassImp(AliHMPIDCluster) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDCluster::CoG() +{ +// Calculates naive cluster position as a center of gravity of its digits. +// Arguments: none +// Returns: shape of the cluster i.e. the box which fully contains the cluster + if(fDigs==0) return; //no digits in this cluster + fX=fY=0; //set cluster position to (0,0) to start to collect contributions + for(Int_t iDig=0;iDigGetEntriesFast();iDig++){//digits loop + AliHMPIDDigit *pDig=(AliHMPIDDigit*)fDigs->At(iDig); //get pointer to next digit + Float_t q=pDig->Q(); //get QDC + fX += pDig->LorsX()*q;fY +=pDig->LorsY()*q; //add digit center weighted by QDC + }//digits loop + fX/=fQ;fY/=fQ; //final center of gravity + + CorrSin(); + + fSt=kCoG; +}//CoG() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDCluster::CorrSin() +{ +// Correction of cluster x position due to sinoid, see HMPID TDR page 30 +// Arguments: none +// Returns: none + AliHMPIDDigit 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 AliHMPIDCluster::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 +// 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 + AliHMPIDCluster *pClu=(AliHMPIDCluster*)gMinuit->GetObjectFit(); + Int_t iNshape = iNpars/3; + + chi2 = 0; + for(Int_t i=0;iSize();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((pClu->Dig(i)->Q()-dQpadMath),2); // + } //loop on all pads of the cluster +}//FitFunction() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDCluster::Print(Option_t* opt)const +{ +//Print current cluster + const char *status=0; + 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,Ch(),Size(),X(),Y(),Q(),status); + for(Int_t i=0;iPrint(); +}//Print() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliHMPIDCluster::Solve(TClonesArray *pCluLst,Bool_t isTryUnfold) +{ +//This methode is invoked when the cluster is formed to solve it. Solve the cluster means to try to unfold the cluster +//into the local maxima number of clusters. This methode is invoked by AliHMPIDRconstructor::Dig2Clu() on cluster by cluster basis. +//At this point, cluster contains a list of digits, cluster charge and size is precalculated in AddDigit(), position is preset to (-1,-1) in ctor, +//status is preset to kFormed in AddDigit(), chamber-sector info is preseted to actual values in AddDigit() +//Method first finds number of local maxima and if it's more then one tries to unfold this cluster into local maxima number of clusters +//Arguments: pCluLst - cluster list pointer where to add new cluster(s) +// isTryUnfold - flag to switch on/off unfolding +// Returns: number of local maxima of original cluster + +//Phase 0. Initialise TMinuit + const Int_t kMaxLocMax=6; //max allowed number of loc max for fitting + TMinuit *pMinuit = new TMinuit(3*kMaxLocMax); //init MINUIT with this number of parameters (3 params per mathieson) + pMinuit->SetObjectFit((TObject*)this); pMinuit->SetFCN(AliHMPIDCluster::FitFunc); //set fit function + Double_t aArg=-1,parStart,parStep,parLow,parHigh; Int_t iErrFlg; //tmp vars for TMinuit + pMinuit->mnexcm("SET PRI",&aArg,1,iErrFlg); //suspend all printout from TMinuit + pMinuit->mnexcm("SET NOW",&aArg,0,iErrFlg); //suspend all warning printout from TMinuit +//Phase 1. Find number of local maxima. Strategy is to check if the current pad has QDC more then all neigbours + Int_t iLocMaxCnt=0; + for(Int_t iDig1=0;iDig1PadX()-pDig2->PadX()),1)+TMath::Sign(Int_t(pDig1->PadY()-pDig2->PadY()),1);//distance between pads + if(dist==1) //means dig2 is a neighbour of dig1 + if(pDig2->Q()>=pDig1->Q()) iHowManyMoreCnt++; //count number of pads with Q more then Q of current pad + }//second digits loop + if(iHowManyMoreCnt==0&&iLocMaxCntmnparm(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 +//Phase 2. Fit loc max number of Mathiesons or add this current cluster to the list + Int_t iCluCnt=pCluLst->GetEntriesFast(); //get current number of clusters already stored in the list by previous operations + if(isTryUnfold==kTRUE && iLocMaxCntmnexcm("MIGRAD" ,&aArg,0,iErrFlg); //start fitting + if (!iErrFlg) { // Only if MIGRAD converged normally + Double_t fitX,fitY,fitQ,d1,d2,d3; TString sName; //vars to get results from TMinuit + for(Int_t i=0;imnpout(3*i ,sName, fitX, d1 , d2, d3, iErrFlg); + pMinuit->mnpout(3*i+1 ,sName, fitY, d1 , d2, d3, iErrFlg); + pMinuit->mnpout(3*i+2 ,sName, fitQ, d1 , d2, d3, iErrFlg); + if (TMath::Abs(fitQ)>2147483647.0) fitQ = TMath::Sign((Double_t)2147483647,fitQ);//??????????????? + new ((*pCluLst)[iCluCnt++]) AliHMPIDCluster(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 + CoG(); + new ((*pCluLst)[iCluCnt++]) AliHMPIDCluster(*this); //add this raw cluster + } + delete pMinuit; + return iLocMaxCnt; +}//Solve() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/HMPID/AliHMPIDCluster.h b/HMPID/AliHMPIDCluster.h new file mode 100644 index 00000000000..99bebfea7dd --- /dev/null +++ b/HMPID/AliHMPIDCluster.h @@ -0,0 +1,60 @@ +#ifndef AliHMPIDCluster_h +#define AliHMPIDCluster_h +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +#include "AliHMPIDDigit.h" //DigAdd() +#include //DigAdd() +class TClonesArray; //Solve() + +class AliHMPIDCluster :public TObject +{ +public: + enum EClusterStatus {kFor,kCoG,kUnf,kEmp=-1}; //status flags + AliHMPIDCluster( ):TObject( ),fSt(kEmp ),fCh(-1 ),fQ(-1 ),fX(-1 ),fY(-1 ),fDigs(0 ) {} + AliHMPIDCluster(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 ) {} + AliHMPIDCluster(const AliHMPIDCluster &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) {} + AliHMPIDCluster &operator=(const AliHMPIDCluster &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 ~AliHMPIDCluster( ) {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 + void CorrSin ( ); //sinoidal correction + Int_t Ch ( )const{return fCh; } //chamber number + inline void DigAdd (AliHMPIDDigit *pDig ); //add new digit ot the cluster + void DigDel ( ) {if(fDigs) {delete fDigs;fDigs=0;} } //deletes the list of digits (not digits!) + AliHMPIDDigit* Dig (Int_t i )const{return (AliHMPIDDigit*)fDigs->At(i); } //pointer to i-th digit + 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 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 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(AliHMPIDCluster,5) //HMPID cluster class +};//class AliHMPIDCluster +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDCluster::DigAdd(AliHMPIDDigit *pDig) +{ +// 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); + fQ+=(Int_t)pDig->Q(); + fCh=pDig->Ch(); + fSt=kFor; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#endif diff --git a/HMPID/AliHMPIDDigit.cxx b/HMPID/AliHMPIDDigit.cxx new file mode 100644 index 00000000000..6df0e81b2dd --- /dev/null +++ b/HMPID/AliHMPIDDigit.cxx @@ -0,0 +1,198 @@ +// ************************************************************************** +// * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +// * * +// * Author: The ALICE Off-line Project. * +// * Contributors are mentioned in the code where appropriate. * +// * * +// * Permission to use, copy, modify and distribute this software and its * +// * documentation strictly for non-commercial purposes is hereby granted * +// * without fee, provided that the above copyright notice appears in all * +// * copies and that both the copyright notice and this permission notice * +// * appear in the supporting documentation. The authors make no claims * +// * about the suitability of this software for any purpose. It is * +// * provided "as is" without express or implied warranty. * +// ************************************************************************** + +#include "AliHMPIDDigit.h" //class header +#include "AliHMPIDHit.h" //Hit2Sdi() +#include //Hit2Sdi() +#include //TestSeg() +#include //TestSeg() +#include //TestSeg() +#include //DrawPc() +#include //Zoom() +#include //Zoom() +ClassImp(AliHMPIDDigit) + +/* +Any given LDC collects data from a number of D-RORC cards connected to this same LDC by separate DDLs. This data is stored in corresponding number +of DDL buffers. + +Each DDL buffer corresponds to a single D-RORC. The data this buffer contains are hardware generated by D-RORC. The buffer starts with common header +which size and structure is standartized and mandatory for all detectors. +The header contains among other words, so called Equipment ID word. This unique value for each D-RORC is calculated as detector ID << 8 + DDL index. +For HMPID the detector ID is 6 (reffered in the code as kRichRawId) while DDL indexes are from 0 to 13. + +Common header might be followed by the private one although HMPID has no any private header, just uses the common one. + +Single HMPID 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: +DDL index 0 -> ch 1 left -> DDL ID 0x600 DDL index 1 -> ch 1 right -> DDL ID 0x601 +DDL index 2 -> ch 2 left -> DDL ID 0x602 DDL index 3 -> ch 2 right -> DDL ID 0x603 +DDL index 4 -> ch 3 left -> DDL ID 0x604 DDL index 5 -> ch 3 right -> DDL ID 0x605 +DDL index 6 -> ch 4 left -> DDL ID 0x606 DDL index 7 -> ch 4 right -> DDL ID 0x607 +DDL index 8 -> ch 5 left -> DDL ID 0x608 DDL index 9 -> ch 5 right -> DDL ID 0x609 +DDL index 10 -> ch 6 left -> DDL ID 0x60a DDL index 11 -> ch 6 right -> DDL ID 0x60b +DDL index 12 -> ch 7 left -> DDL ID 0x60c DDL index 13 -> ch 7 right -> DDL ID 0x60d + +HMPID 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 kDilX,kDilY). Channels counted from 0 to 47. + +The mapping inside DILOGIC chip has the following structure (see from electronics side): + +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 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. +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. + +HMPID 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 AliHMPIDDigit::Hit2Sdi(AliHMPIDHit *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 + + AliHMPIDDigit 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 + AliHMPIDDigit 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++]) AliHMPIDDigit(dig); + } + return qdcTot; +}//Hit2Sdi() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDDigit::Print(Option_t*)const +{ +// 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 AliHMPIDDigit::PrintSize() +{ +// 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 AliHMPIDDigit::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","AliHMPIDDigit::Zoom()"); + DrawPc(); +}//TestSeg() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDDigit::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()); + AliHMPIDDigit 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 AliHMPIDDigit::DrawPc(Bool_t isFill) +{ +// Utility methode draws HMPID 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/HMPID/AliHMPIDDigit.h b/HMPID/AliHMPIDDigit.h new file mode 100644 index 00000000000..bf89f760bdc --- /dev/null +++ b/HMPID/AliHMPIDDigit.h @@ -0,0 +1,176 @@ +#ifndef AliHMPIDDigit_h +#define AliHMPIDDigit_h +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +#include //base class +#include //Mathieson() +#include //IsOverTh() +#include //Raw() + +class AliHMPIDHit; //Hit2Sdi() +class TClonesArray; //Hit2Sdi() + +class AliHMPIDDigit :public AliDigit //TObject-AliDigit-AliHMPIDDigit +{ +public: + 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 + AliHMPIDDigit( ):AliDigit( ),fPad(Abs(-1,-1,-1,-1)),fQ(-1) {} //default ctor + AliHMPIDDigit(Int_t pad,Int_t q,Int_t *t ):AliDigit(t),fPad(pad ),fQ(q ) {} //digit ctor + inline AliHMPIDDigit(Int_t c,Float_t q,Int_t t,Float_t x,Float_t y,Int_t f=0); //sdigit ctor + virtual ~AliHMPIDDigit() {} //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 +//private part + 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 AliHMPIDDigit::Compare(const TObject *pObj) const +{ +// Used in Sort() method to compare to objects. Note that abs pad structure is first x then y, hence will be sorted on column basis. +// This feature is used in digitizer to facilitate finding of sdigits for the same pad 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 (fPad==((AliHMPIDDigit*)pObj)->Pad()) return 0; + else if(fPad >((AliHMPIDDigit*)pObj)->Pad()) return 1; + else return -1; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Bool_t AliHMPIDDigit::IsInDead(Float_t x,Float_t y) +{ +// 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 + + if(x>SizePcX() && xSizePcY() && ySizeAllY()-SizePcY()-SizeDead() && y //TestSeg() +#include //TestSeg() +#include //TestSeg() +#include //DrawPc() +#include //Zoom() +#include //Zoom() +ClassImp(AliHMPIDDigitN) + +/* +Any given LDC collects data from a number of D-RORC cards connected to this same LDC by separate DDLs. This data is stored in corresponding number +of DDL buffers. + +Each DDL buffer corresponds to a single D-RORC. The data this buffer contains are hardware generated by D-RORC. The buffer starts with common header +which size and structure is standartized and mandatory for all detectors. +The header contains among other words, so called Equipment ID word. This unique value for each D-RORC is calculated as detector ID << 8 + DDL index. +For HMPID the detector ID is 6 (reffered in the code as kRichRawId) while DDL indexes are from 0 to 13. + +Common header might be followed by the private one although HMPID has no any private header, just uses the common one. + +Single HMPID 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: +DDL index 0 -> ch 1 left -> DDL ID 0x600 DDL index 1 -> ch 1 right -> DDL ID 0x601 +DDL index 2 -> ch 2 left -> DDL ID 0x602 DDL index 3 -> ch 2 right -> DDL ID 0x603 +DDL index 4 -> ch 3 left -> DDL ID 0x604 DDL index 5 -> ch 3 right -> DDL ID 0x605 +DDL index 6 -> ch 4 left -> DDL ID 0x606 DDL index 7 -> ch 4 right -> DDL ID 0x607 +DDL index 8 -> ch 5 left -> DDL ID 0x608 DDL index 9 -> ch 5 right -> DDL ID 0x609 +DDL index 10 -> ch 6 left -> DDL ID 0x60a DDL index 11 -> ch 6 right -> DDL ID 0x60b +DDL index 12 -> ch 7 left -> DDL ID 0x60c DDL index 13 -> ch 7 right -> DDL ID 0x60d + +HMPID 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 kDilX,kDilY). Channels counted from 0 to 47. + +The mapping inside DILOGIC chip has the following structure (see from electronics side): + +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 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. +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. + +HMPID 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) +*/ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDDigitN::Print(Option_t*)const +{ +// Print current digit +// Arguments: option string not used +// Returns: none + Printf("pad=(%2i,%2i,%3i,%3i),pos=(%.2f,%.2f) QDC=%8.3f, TID=(%5i,%5i,%5i) raw r=%2i d=%2i a=%2i", + Ch(),Pc(),PadX(),PadY(),LorsX(),LorsY(), Qdc(), fTracks[0],fTracks[1],fTracks[2], Row(), Dilogic(), Addr()); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDDigitN::PrintSize() +{ +// 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 AliHMPIDDigitN::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","AliHMPIDDigitN::Zoom()"); + DrawPc(); +}//TestSeg() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDDigitN::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()); + AliHMPIDDigitN dig(1,x,y,100); + pBar->SetText(Form("(p=%i,x=%i,y=%i) (r%i d%i a%i)",dig.Pc(),dig.PadX(),dig.PadY(),dig.Row(),dig.Dilogic(),dig.Addr()),4); + if(gPad->GetEvent()==1){ + new TCanvas("zoom",Form("Row %i DILOGIC %i",dig.Row(),dig.Dilogic())); + } +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDDigitN::DrawPc() +{ +// Utility methode draws HMPID chamber PCs on event display. +// Arguments: none +// Returns: none +// y6 ---------- ---------- +// | | | | +// | 4 | | 5 | +// y5 ---------- ---------- +// +// y4 ---------- ---------- +// | | | | +// | 2 | | 3 | view from electronic 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); + pc->Draw("f"); + 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/HMPID/AliHMPIDDigitN.h b/HMPID/AliHMPIDDigitN.h new file mode 100644 index 00000000000..260f29fff08 --- /dev/null +++ b/HMPID/AliHMPIDDigitN.h @@ -0,0 +1,90 @@ +#ifndef AliHMPIDDigitN_h +#define AliHMPIDDigitN_h +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +#include //base class + +class AliHMPIDDigitN :public AliDigit //TObject-AliDigit-AliHMPIDDigit +{ +public: + 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{kPadsPcX=80,kPadsPcY=48,kPadsChamX=160,kPadsChamY=144,kNpc=6}; //Segmentation structure +//ctor&dtor + AliHMPIDDigitN( ):AliDigit(),fPad(Abs(-1,-1,-1,-1)) ,fQdc(-1) {} //default ctor + inline AliHMPIDDigitN(Int_t c,Float_t x,Float_t y,Float_t q); //ctor + virtual ~AliHMPIDDigitN() {} //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 +//private part + 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 ( ); //draw PCs + Int_t Ddl ( )const{return (PadX()Pad()) return 0; + else if(fPad >((AliHMPIDDigitN*)pObj)->Pad()) return 1; + else return -1; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliHMPIDDigitN::AliHMPIDDigitN(Int_t c,Float_t x,Float_t y,Float_t q):AliDigit(),fPad(Abs(-1,-1,-1,-1)),fQdc(-1) +{ +// 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 ^ 4 5 +// | 2 3 +// | 0 1 +// -------> x + Int_t pc,padx,pady; + if (x>= 0 && x<= SizePcX() ) {pc=0; padx=Int_t( x / SizePadX());}//PC 0 or 2 or 4 + else if(x>=SizePcX()+SizeDead() && x<= SizeAllX() ) {pc=1; padx=Int_t((x- SizePcX()- SizeDead()) / SizePadX());}//PC 2 or 4 or 6 + else return; + if (y>= 0 && y<= SizePcY() ) { pady=Int_t( y / SizePadY());}//PC 0 or 1 + else if(y>=SizePcY()+SizeDead() && y<=2*SizePcY()+SizeDead() ) {pc+=2;pady=Int_t((y- SizePcY()- SizeDead()) / SizePadY());}//PC 2 or 3 + else if(y>=SizeAllY()-SizePcY() && y<= SizeAllY() ) {pc+=4;pady=Int_t((y-2*SizePcY()-2*SizeDead()) / SizePadY());}//PC 4 or 5 + else return; + fPad=Abs(c,pc,padx,pady); + fQdc=q; +} +#endif diff --git a/HMPID/AliHMPIDDigitizer.cxx b/HMPID/AliHMPIDDigitizer.cxx new file mode 100644 index 00000000000..6b41fb234ff --- /dev/null +++ b/HMPID/AliHMPIDDigitizer.cxx @@ -0,0 +1,104 @@ +/************************************************************************** + * Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +#include "AliHMPIDDigitizer.h" +#include "AliHMPID.h" +#include "AliHMPIDDigit.h" +#include +#include +#include "AliRunDigitizer.h" +#include +#include + + +ClassImp(AliHMPIDDigitizer) + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDDigitizer::Exec(Option_t*) +{ +// 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 HMPID loaders + TClonesArray sdigs("AliHMPIDDigit");//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 + pInRichLoader = pInRunLoader->GetLoader("HMPIDLoader"); if(pInRichLoader==0) continue; //no HMPID in this input, check the next input + if (!pInRunLoader->GetAliRun()) pInRunLoader->LoadgAlice(); + AliHMPID* pInRich=(AliHMPID*)pInRunLoader->GetAliRun()->GetDetector("HMPID"); //take HMPID from current input + pInRichLoader->LoadSDigits(); pInRichLoader->TreeS()->GetEntry(0); //take list of HMPID sdigits from current input + 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 + AliHMPIDDigit *pSDig=(AliHMPIDDigit*)pInRich->SdiLst()->At(i); + pSDig->AddTidOffset(fManager->GetMask(inFileN)); //apply TID shift since all inputs count tracks independently starting from 0 + new(sdigs[total++]) AliHMPIDDigit(*pSDig); + } + pInRichLoader->UnloadSDigits(); pInRich->SdiReset(); //close current input and reset + }//files loop + + //PH 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("HMPIDLoader"); //take output HMPID loader + AliHMPID *pOutRich = (AliHMPID*)pOutRunLoader->GetAliRun()->GetDetector("HMPID"); //take output HMPID + pOutRichLoader->MakeTree("D"); pOutRich->MakeBranch("D"); //create TreeD in output stream + + Sdi2Dig(&sdigs,pOutRich->DigLst()); + + pOutRichLoader->TreeD()->Fill(); //fill the output tree with the list of digits + pOutRichLoader->WriteDigits("OVERWRITE"); //serialize them to file + + sdigs.Clear(); //remove all tmp sdigits + pOutRichLoader->UnloadDigits(); pOutRich->DigReset(); +}//Exec() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDDigitizer::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) + AliHMPIDDigit *pSdig=(AliHMPIDDigit*)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 && AliHMPIDDigit::IsOverTh(q)) new((*pLst[iCh])[iCnt[iCh]++]) AliHMPIDDigit(iPad,(Int_t)q,aTids); //do not create digit for the very first sdigit + iPad=pSdig->Pad(); iCh=AliHMPIDDigit::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(AliHMPIDDigit::IsOverTh(q)) new((*pLst[iCh])[iCnt[iCh]++]) AliHMPIDDigit(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/HMPID/AliHMPIDDigitizer.h b/HMPID/AliHMPIDDigitizer.h new file mode 100644 index 00000000000..4ab8033f664 --- /dev/null +++ b/HMPID/AliHMPIDDigitizer.h @@ -0,0 +1,24 @@ +#ifndef AliHMPIDDigitizer_h +#define AliHMPIDDigitizer_h +/* Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + + +#include +class AliRunDigitizer; +class TClonesArray; +class TObjArray; + +class AliHMPIDDigitizer : public AliDigitizer //TObject-TNamed-TTask-AliDigitizer-AliHMPIDDigitizer +{ +public: + AliHMPIDDigitizer() {} + AliHMPIDDigitizer(AliRunDigitizer *pRunDig):AliDigitizer(pRunDig) {} + virtual ~AliHMPIDDigitizer() {} + void Exec(Option_t* option=0); //virtual +// + static void Sdi2Dig(TClonesArray *pSDigLst,TObjArray *pDigLst); +protected: + ClassDef(AliHMPIDDigitizer,0) +}; +#endif diff --git a/HMPID/AliHMPIDHelix.cxx b/HMPID/AliHMPIDHelix.cxx new file mode 100644 index 00000000000..8e57efa194c --- /dev/null +++ b/HMPID/AliHMPIDHelix.cxx @@ -0,0 +1,25 @@ +#include "AliHMPIDHelix.h" //class header +#include //Draw() + +ClassImp(AliHMPIDHelix) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDHelix::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()); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDHelix::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,pos.X(),pos.Y(),pos.Z()); + } + pHelDraw->Draw(); +} diff --git a/HMPID/AliHMPIDHelix.h b/HMPID/AliHMPIDHelix.h new file mode 100644 index 00000000000..bd0db6299c6 --- /dev/null +++ b/HMPID/AliHMPIDHelix.h @@ -0,0 +1,71 @@ +#ifndef AliHMPIDHelix_h +#define AliHMPIDHelix_h + +#include //base class +#include //used extensively + +class AliHMPIDHelix: public TObject +{ +public: + AliHMPIDHelix( ):TObject(),fX0(TVector3(0,0,0)),fP0(TVector3(0,0,0)),fQ(0),fBz(0 ) {} + AliHMPIDHelix(const TVector3 &x0,const TVector3 &p0,Int_t q=1,Double_t b=2):TObject(),fX0(x0 ),fP0(p0 ),fQ(q),fBz(b ) {} + AliHMPIDHelix(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 ~AliHMPIDHelix() {} + + void Draw (const Option_t *opt="" ); //from TObject, draw helix + void Print (const Option_t *opt="" )const; //from TObject, print status +//private part++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + inline Bool_t 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 + Int_t fQ; //sign of track charge + Float_t fBz; //magnetic field along z, [kGaus] + ClassDef(AliHMPIDHelix,0) //General helix +};//class AliHMPIDHelix +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDHelix::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 + x=fX0+fP0.Unit()*len; + p=fP0; + }else{ + 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 AliHMPIDHelix::Intersect(TVector3 &pnt,TVector3 &norm) +{ +// Finds point of intersection (if exists) of the helix with the plane. Stores result in fX and fP. +// 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; +}//Intersect() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#endif diff --git a/HMPID/AliHMPIDHit.cxx b/HMPID/AliHMPIDHit.cxx new file mode 100644 index 00000000000..6390076d3c0 --- /dev/null +++ b/HMPID/AliHMPIDHit.cxx @@ -0,0 +1,43 @@ +// ************************************************************************** +// * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +// * * +// * Author: The ALICE Off-line Project. * +// * Contributors are mentioned in the code where appropriate. * +// * * +// * Permission to use, copy, modify and distribute this software and its * +// * documentation strictly for non-commercial purposes is hereby granted * +// * without fee, provided that the above copyright notice appears in all * +// * copies and that both the copyright notice and this permission notice * +// * appear in the supporting documentation. The authors make no claims * +// * about the suitability of this software for any purpose. It is * +// * provided "as is" without express or implied warranty. * +// ************************************************************************** + +#include "AliHMPIDHit.h" //class header +#include //Print() +#include + +ClassImp(AliHMPIDHit) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDHit::Print(Option_t*)const +{ +//Print hit + char *sPart=Form("pid=%i",Pid()); + switch(Pid()){ + case kProton: sPart="p+ ";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 kElectron: sPart="e- ";break; + case kPositron: sPart="e+ ";break; + case 50000050: sPart="ckov";break; + case 50000051: sPart="feed";break; + } + + 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/HMPID/AliHMPIDHit.h b/HMPID/AliHMPIDHit.h new file mode 100644 index 00000000000..3feeea81c6d --- /dev/null +++ b/HMPID/AliHMPIDHit.h @@ -0,0 +1,35 @@ +#ifndef AliHMPIDHit_h +#define AliHMPIDHit_h +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +#include //base class +#include //ctor + +class AliHMPIDHit : public AliHit // TObject-AliHit-AliHMPIDHit +{ +public: + AliHMPIDHit( ):AliHit( ),fCh(-1),fPid(-1 ),fE(-1),fLorsX(-1),fLorsY(-1) {} //default ctor + AliHMPIDHit(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();} + AliHMPIDHit(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 ~AliHMPIDHit() {} +//framework part + void Print(Option_t *option="")const; //from TObject to print current status +//private part + 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(AliHMPIDHit,4) //HMPID hit class +};//class AliHMPIDhit + +#endif diff --git a/HMPID/AliHMPIDParam.cxx b/HMPID/AliHMPIDParam.cxx new file mode 100644 index 00000000000..c264b6805a1 --- /dev/null +++ b/HMPID/AliHMPIDParam.cxx @@ -0,0 +1,99 @@ +// ************************************************************************** +// * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +// * * +// * Author: The ALICE Off-line Project. * +// * Contributors are mentioned in the code where appropriate. * +// * * +// * Permission to use, copy, modify and distribute this software and its * +// * documentation strictly for non-commercial purposes is hereby granted * +// * without fee, provided that the above copyright notice appears in all * +// * copies and that both the copyright notice and this permission notice * +// * appear in the supporting documentation. The authors make no claims * +// * about the suitability of this software for any purpose. It is * +// * provided "as is" without express or implied warranty. * +// ************************************************************************** +#include "AliHMPIDParam.h" //class header +#include "AliHMPIDDigit.h" //ctor +#include //TestXXX() +#include //TestTrans() +#include //TestTrans() +#include //TestTrans() +#include +#include //Stack() +#include //Stack() +#include //Stack() +#include "AliHMPIDHelix.h" //TestTrans() + +ClassImp(AliHMPIDParam) + +AliHMPIDParam* AliHMPIDParam::fgInstance=0x0; //singleton pointer +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliHMPIDParam::AliHMPIDParam():TNamed("RichParam","default version") +{ +// Here all the intitializition is taken place when AliHMPIDParam::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 + fX=0.5*AliHMPIDDigit::SizeAllX(); + fY=0.5*AliHMPIDDigit::SizeAllY(); + for(Int_t i=0;i<7;i++) fM[i]=(TGeoHMatrix*)gGeoManager->GetVolume("ALIC")->GetNode(Form("HMPID_%i",i))->GetMatrix(); + fgInstance=this; +}//ctor +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDParam::Print(Option_t* opt) const +{ +// print some usefull (hopefully) info on some internal guts of HMPID parametrisation + + for(Int_t i=0;i<7;i++) fM[i]->Print(opt); +}//Print() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliHMPIDParam::Stack(Int_t evt,Int_t tid) +{ +// Prints some usefull info from stack +// Arguments: evt - event number. if not -1 print info only for that event +// tid - track id. if not -1 then print it and all it's mothers if any +// Returns: mother tid of the given tid if any + AliRunLoader *pAL=AliRunLoader::Open(); + if(pAL->LoadHeader()) return -1; + if(pAL->LoadKinematics()) return -1; + + Int_t mtid=-1; + Int_t iNevt=pAL->GetNumberOfEvents(); Printf("This session contains %i event(s)",iNevt); + + for(Int_t iEvt=0;iEvtGetEvent(iEvt); + AliStack *pStack=pAL->Stack(); + if(tid==-1){ //print all tids for this event + for(Int_t i=0;iGetNtrack();i++) pStack->Particle(i)->Print(); + Printf("totally %i tracks including %i primaries for event %i out of %i event(s)",pStack->GetNtrack(),pStack->GetNprimary(),iEvt,iNevt); + }else{ //print only this tid and it;s mothers + if(tid<0 || tid>pStack->GetNtrack()) {Printf("Wrong tid, valid tid range for event %i is 0-%i",iEvt,pStack->GetNtrack());break;} + TParticle *pTrack=pStack->Particle(tid); mtid=pTrack->GetFirstMother(); + TString str=pTrack->GetName(); + while((tid=pTrack->GetFirstMother()) >= 0){ + pTrack=pStack->Particle(tid); + str+=" from ";str+=pTrack->GetName(); + } + Printf("%s",str.Data()); + }//if(tid==-1) + }//events loop + pAL->UnloadHeader(); pAL->UnloadKinematics(); + return mtid; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliHMPIDParam::StackCount(Int_t pid,Int_t evt) +{ +// Counts total number of particles of given sort (including secondary) for a given event + AliRunLoader *pAL=AliRunLoader::Open(); + pAL->GetEvent(evt); + if(pAL->LoadHeader()) return 0; + if(pAL->LoadKinematics()) return 0; + AliStack *pStack=pAL->Stack(); + + Int_t iCnt=0; + for(Int_t i=0;iGetNtrack();i++) if(pStack->Particle(i)->GetPdgCode()==pid) iCnt++; + + pAL->UnloadHeader(); pAL->UnloadKinematics(); + return iCnt; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/HMPID/AliHMPIDParam.h b/HMPID/AliHMPIDParam.h new file mode 100644 index 00000000000..8b16361489f --- /dev/null +++ b/HMPID/AliHMPIDParam.h @@ -0,0 +1,57 @@ +#ifndef AliHMPIDParam_h +#define AliHMPIDParam_h + +#include //base class +#include //Instance() +#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 + +// Class providing all the needed parametrised information +// to construct the geometry, to define segmentation and to provide response model +// In future will also provide all the staff needed for alignment and calibration + +class AliHMPIDParam :public TNamed +{ +public: +//ctor&dtor + virtual ~AliHMPIDParam() {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 inline AliHMPIDParam* Instance(); //pointer to AliHMPIDParam 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 +//trasformation methodes + 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: + AliHMPIDParam(); //default ctor is protected to enforce it to be singleton + static AliHMPIDParam *fgInstance; //static pointer to instance of AliHMPIDParam singleton + TGeoHMatrix *fM[7]; //poiners to matrices defining HMPID 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(AliHMPIDParam,0) //HMPID main parameters class +}; +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliHMPIDParam* AliHMPIDParam::Instance() +{ +// Return pointer to the AliHMPIDParam singleton. +// Arguments: none +// Returns: pointer to the instance of AliHMPIDParam or 0 if no geometry + if(!fgInstance) + if(gGeoManager) new AliHMPIDParam; + else Printf("AliHMPIDParam> Error:: No geometry defined!"); + return fgInstance; +}//Instance() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +#endif diff --git a/HMPID/AliHMPIDPreprocessor.cxx b/HMPID/AliHMPIDPreprocessor.cxx new file mode 100644 index 00000000000..6198ce63385 --- /dev/null +++ b/HMPID/AliHMPIDPreprocessor.cxx @@ -0,0 +1,75 @@ +#include "AliHMPIDPreprocessor.h" //header + +#include +#include +#include //Test() +#include //Test() +#include //Test() +#include //Test() +//#include //Test() +#include //Test() +#include //Process() +#include //Process() +#include //Process() + +ClassImp(AliHMPIDPreprocessor) + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDPreprocessor::Initialize(Int_t run, UInt_t startTime,UInt_t endTime) +{ + AliPreprocessor::Initialize(run, startTime, endTime); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +UInt_t AliHMPIDPreprocessor::Process(TMap* pDcsMap) +{ +// +// Argumets: pDcsMap - map of structure "alias name" - TObjArray of AliDCSValue + +// TList* list = GetFileSources(kDAQ, "MAP"); //first analyse a set of pedestal files +// if (list){ +// Log("The following sources produced files with the id MAP"); +// list->Print(); +// delete list; +// } + + if(!pDcsMap) return 0; //no DCS map provided + + TF2 idxC6F14("RidxC4F14","sqrt(1+0.554*(1239.84/x)^2/((1239.84/x)^2-5796)-0.0005*(y-20))",5.5,8.5,0,50); //DiMauro mail temp 0-50 degrees C + Double_t eMean=6.67786; //mean energy of photon defined by transperancy window + + TObjArray radTemp; radTemp.SetOwner(kTRUE); //store temp versus time as TF1 array for all radiators (21) + TObjArray meanIdx; meanIdx.SetOwner(kTRUE); //store ref idx versus time as TF1 array for all radiators (21) + + + for(Int_t iCh=0;iCh<7;iCh++){ //aliases loop + for(Int_t iRad=0;iRad<3;iRad++){ + TObjArray *pValLst=(TObjArray*)pDcsMap->GetValue(Form("HMP_DET/HMP_MP%i/HMP_MP%i_LIQ_LOOP.actual.sensors.Rad%iIn_Temp",iCh,iCh,iRad));//get data points for this alias + if(!pValLst) continue; //no data points + TF1 *pRadTempF=new TF1(Form("RadTemp%i%i",iCh,iRad),"[0]+[1]*x+[2]*sin([3]*x)",0,10); pRadTempF->SetLineColor(iRad+2); //temp=f(time) + TF1 *pMeanIdxF=new TF1(Form("MeanIdx%i%i",iCh,iRad),"[0]+[1]*x+[2]*sin([3]*x)",0,10); pMeanIdxF->SetLineColor(iRad+2); //idx=f(time) + TGraph *pRadTempG=new TGraph; //tmp graph of rad temp versus time + TGraph *pMeanIdxG=new TGraph; //tmp graph of mean ref idx versus time + TIter next(pValLst); AliDCSValue *pDcsVal; Int_t i=0; + while((pDcsVal=(AliDCSValue*)next())){ //loop over data points for this sensor + pRadTempG->SetPoint(i,pDcsVal->GetTimeStamp(), pDcsVal->GetFloat()); //and fill the temp graph + pMeanIdxG->SetPoint(i,pDcsVal->GetTimeStamp(),idxC6F14.Eval(eMean,pDcsVal->GetFloat())); //and fill the maen ref idx graph + i++; + } + pRadTempG->Fit(pRadTempF,"Q"); //now fit the temp graph + pMeanIdxG->Fit(pMeanIdxF,"Q"); //now fit the mean idx graph + delete pRadTempG; + delete pMeanIdxG; + radTemp.Add(pRadTempF); + meanIdx.Add(pMeanIdxF); + }//radiators loop + }//chambers loop + + AliCDBMetaData metaData; metaData.SetBeamPeriod(0); metaData.SetResponsible("AliHMPIDPreprocessor"); metaData.SetComment("SIMULATED"); + + Store("DCS", "RadTemp" , &radTemp , &metaData); //use AliPreprocessor::Store(), not allowed to use AliCDBManager directly + Store("DCS", "MeanIdx" , &meanIdx , &metaData); + + return 1; + +}//Process() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/HMPID/AliHMPIDPreprocessor.h b/HMPID/AliHMPIDPreprocessor.h new file mode 100644 index 00000000000..2648875e286 --- /dev/null +++ b/HMPID/AliHMPIDPreprocessor.h @@ -0,0 +1,19 @@ +#ifndef AliHMPIDPreprocessor_h +#define AliHMPIDPreprocessor_h + +#include //base class + +class TMap; + +class AliHMPIDPreprocessor : public AliPreprocessor +{ +public: + AliHMPIDPreprocessor(AliShuttleInterface* pShuttle):AliPreprocessor("HMPID",pShuttle) {} + virtual ~AliHMPIDPreprocessor( ) {} +protected: + virtual void Initialize(Int_t run, UInt_t startTime, UInt_t endTime); + virtual UInt_t Process (TMap* pDcsMap ); + ClassDef(AliHMPIDPreprocessor, 0); +}; + +#endif diff --git a/HMPID/AliHMPIDRecon.cxx b/HMPID/AliHMPIDRecon.cxx new file mode 100644 index 00000000000..a005e4e0a19 --- /dev/null +++ b/HMPID/AliHMPIDRecon.cxx @@ -0,0 +1,442 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliHMPIDRecon // +// // +// HMPID class to perfom pattern recognition based on Hough transfrom // +// for single chamber // +////////////////////////////////////////////////////////////////////////// + +#include "AliHMPIDRecon.h" //class header +#include "AliHMPIDCluster.h" //CkovAngle() +#include //TracePhoton() +#include //HoughResponse() +#include //CkovAngle() + +#include //Display() +#include //Display() +#include //Display() +#include //Display() +#include //Display() +#include //Display() + + +const Double_t AliHMPIDRecon::fgkRadThick=1.5; +const Double_t AliHMPIDRecon::fgkWinThick=0.5; +const Double_t AliHMPIDRecon::fgkGapThick=8.0; +const Double_t AliHMPIDRecon::fgkRadIdx =1.292; +const Double_t AliHMPIDRecon::fgkWinIdx =1.5787; +const Double_t AliHMPIDRecon::fgkGapIdx =1.0005; + + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliHMPIDRecon::AliHMPIDRecon():TTask("RichRec","RichPat"), + fPhotCnt(-1), + fCkovSigma2(0), + fIsWEIGHT(kFALSE), + fDTheta(0.001), + fWindowWidth(0.045), + fTrkDir(TVector3(0,0,1)),fTrkPos(TVector2(30,40)) +{ +// main ctor + for (Int_t i=0; i<3000; i++) { + fPhotFlag[i] = 0; + fPhotCkov[i] = -1; + fPhotPhi [i] = -1; + fPhotWei [i] = 0; + } +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliHMPIDRecon::CkovAngle(TClonesArray *pCluLst,Int_t &iNaccepted) +{ +// Pattern recognition method based on Hough transform +// Arguments: pCluLst - list of clusters for this chamber +// Returns: - track ckov angle, [rad], + + if(pCluLst->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction + else fIsWEIGHT = kFALSE; + + // Photon Flag: Flag = 0 initial set; Flag = 1 good candidate (charge compatible with photon); Flag = 2 photon used for the ring; + + fPhotCnt=0; + for (Int_t iClu=0; iCluGetEntriesFast();iClu++){//clusters loop + AliHMPIDCluster *pClu=(AliHMPIDCluster*)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 + + 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() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliHMPIDRecon::FindPhotCkov(Double_t cluX,Double_t cluY) +{ +// 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-TracePhot(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 + } +}//FindPhotTheta() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliHMPIDRecon::FindPhotPhi(Double_t cluX,Double_t cluY) +{ +// Finds phi angle og photon candidate by considering the cluster's position of this candudate w.r.t track position + + 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())); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliHMPIDRecon::FindRingArea(Double_t ckovAng)const +{ +// 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 + + + TVector2 pos1,pos2; + + const Int_t kN=100; + Double_t area=0; + 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(fPhotCkov[i]<=0) continue;//?????????????????Flag photos = 2 may imply CkovEta = 0?????????????? + + sigma2 += 1./Sigma2(fPhotCkov[i],fPhotPhi[i]); + } + }//candidates loop + + if(sigma2>0) fCkovSigma2=1./sigma2; + else fCkovSigma2=1e10; + + + if(wei != 0.) weightThetaCerenkov /= wei; else weightThetaCerenkov = 0.; + return weightThetaCerenkov; +}//FindCkovRing() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliHMPIDRecon::FlagPhot(Double_t ckov) +{ +// 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)((ckov )/ fDTheta); //how many times we need to have fDTheta to fill the distance between 0 and thetaCkovHough + + 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 ckov inside the window + for(Int_t i=0;i= tmin && fPhotCkov[i] <= tmax) { + fPhotFlag[i]=2; + iInsideCnt++; + } + } + return iInsideCnt; +}//FlagPhot() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliHMPIDRecon::TracePhot(Double_t ckovThe,Double_t ckovPhi,TVector2 &pos)const +{ +// 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; + + TVector3 posCkov(fTrkPos.X(),fTrkPos.Y(),-0.5*fgkRadThick-fgkWinThick-fgkGapThick); //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./fgkRadIdx)) return -999;//total refraction on WIN-GAP boundary + + Propagate(dirCkov,posCkov,-fgkWinThick-fgkGapThick); //go to RAD-WIN boundary remeber that z=0 is PC plane + Refract (dirCkov, fgkRadIdx,fgkWinIdx ); //RAD-WIN refraction + Propagate(dirCkov,posCkov,-fgkGapThick ); //go to WIN-GAP boundary + Refract (dirCkov, fgkWinIdx,fgkGapIdx ); //WIN-GAP refraction + Propagate(dirCkov,posCkov,0 ); //go to PC + + pos.Set(posCkov.X(),posCkov.Y()); + return (pos-fTrkPos).Mod(); +}//TracePhoton() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDRecon::Propagate(const TVector3 &dir,TVector3 &pos,Double_t z)const +{ +// 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); + + TVector3 diff=pnt-pos; + Double_t sint=(nrm*diff)/(nrm*dir); + pos+=sint*dir; +}//Propagate() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDRecon::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 AliHMPIDRecon::HoughResponse() +{ +// +// +// + 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)); + + 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 = ((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; + } + photsw->Fill(angle,weight); + fPhotWei[i]=weight; + }//photon candidates loop + + for (Int_t i=1; i<=nBin;i++){ + Int_t bin1= i-nCorrBand; + Int_t bin2= i+nCorrBand; + if(bin1<1) bin1=1; + if(bin2>nBin)bin2=nBin; + Double_t sumPhots=phots->Integral(bin1,bin2); + if(sumPhots<3) continue; // if less then 3 photons don't trust to this ring + Double_t sumPhotsw=photsw->Integral(bin1,bin2); + resultw->Fill((Double_t)((i+0.5)*fDTheta),sumPhotsw); + } +// evaluate the "BEST" theta ckov as the maximum value of histogramm + 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() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliHMPIDRecon::Sigma2(Double_t ckovTh, Double_t ckovPh)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)*fgkRadIdx); + + v.SetX(SigLoc (ckovTh,ckovPh,trkBeta)); + v.SetY(SigGeom(ckovTh,ckovPh,trkBeta)); + v.SetZ(SigCrom(ckovTh,ckovPh,trkBeta)); + + return v.Mag2(); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliHMPIDRecon::SigLoc(Double_t thetaC, Double_t phiC,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 - fTrkDir.Phi(); + + Double_t alpha =TMath::Cos(fTrkDir.Theta())-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(fTrkDir.Theta()); + Double_t k = 1.-fgkRadIdx*fgkRadIdx+alpha*alpha/(betaM*betaM); + if (k<0) return 1e10; + + Double_t mu =TMath::Sin(fTrkDir.Theta())*TMath::Sin(fTrkDir.Phi())+TMath::Tan(thetaC)*(TMath::Cos(fTrkDir.Theta())*TMath::Cos(phiDelta)*TMath::Sin(fTrkDir.Phi())+TMath::Sin(phiDelta)*TMath::Cos(fTrkDir.Phi())); + Double_t e =TMath::Sin(fTrkDir.Theta())*TMath::Cos(fTrkDir.Phi())+TMath::Tan(thetaC)*(TMath::Cos(fTrkDir.Theta())*TMath::Cos(phiDelta)*TMath::Cos(fTrkDir.Phi())-TMath::Sin(phiDelta)*TMath::Sin(fTrkDir.Phi())); + + Double_t kk = betaM*TMath::Sqrt(k)/(8*alpha); + Double_t dtdxc = kk*(k*(TMath::Cos(phiDelta)*TMath::Cos(fTrkDir.Phi())-TMath::Cos(fTrkDir.Theta())*TMath::Sin(phiDelta)*TMath::Sin(fTrkDir.Phi()))-(alpha*mu/(betaM*betaM))*TMath::Sin(fTrkDir.Theta())*TMath::Sin(phiDelta)); + Double_t dtdyc = kk*(k*(TMath::Cos(phiDelta)*TMath::Sin(fTrkDir.Phi())+TMath::Cos(fTrkDir.Theta())*TMath::Sin(phiDelta)*TMath::Cos(fTrkDir.Phi()))+(alpha* e/(betaM*betaM))*TMath::Sin(fTrkDir.Theta())*TMath::Sin(phiDelta)); + + return TMath::Sqrt(0.2*0.2*dtdxc*dtdxc + 0.25*0.25*dtdyc*dtdyc); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliHMPIDRecon::SigCrom(Double_t thetaC, Double_t phiC,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 - fTrkDir.Phi(); + Double_t alpha =TMath::Cos(fTrkDir.Theta())-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(fTrkDir.Theta()); + + Double_t dtdn = TMath::Cos(fTrkDir.Theta())*fgkRadIdx*betaM*betaM/(alpha*TMath::Tan(thetaC)); + + Double_t f = 0.00928*(7.75-5.635)/TMath::Sqrt(12.); + + return f*dtdn; +}//SigCrom() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Double_t AliHMPIDRecon::SigGeom(Double_t thetaC, Double_t phiC,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 - fTrkDir.Phi(); + Double_t alpha =TMath::Cos(fTrkDir.Theta())-TMath::Tan(thetaC)*TMath::Cos(phiDelta)*TMath::Sin(fTrkDir.Theta()); + + Double_t k = 1.-fgkRadIdx*fgkRadIdx+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(fTrkDir.Theta())*TMath::Sin(fTrkDir.Theta())*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(fTrkDir.Theta())); + + return trErr*err; +}//SigGeom() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDRecon::Display() +{ +// Display digits, reconstructed tracks intersections and HMPID rings if available +// Arguments: none +// Returns: none + TFile *pEsdFl=TFile::Open("AliESDs.root"); if(!pEsdFl || !pEsdFl->IsOpen()) return;//open AliESDs.root + TTree *pEsdTr=(TTree*) pEsdFl->Get("esdTree"); if(!pEsdTr) return;//get ESD tree + + AliESD *pEsd=new AliESD; pEsdTr->SetBranchAddress("ESD", &pEsd); + + TPolyMarker *pDigMap[7]; //digits map + TPolyMarker *pTrkMap[7]; Int_t aTrkCnt[7]; //TRKxPC intersection map + + for(Int_t i=0;i<7;i++){ + pDigMap[i]=new TPolyMarker(); pDigMap[i]->SetMarkerStyle(25); pDigMap[i]->SetMarkerSize(0.5); pDigMap[i]->SetMarkerColor(kGreen); + aTrkCnt[i]=0; pTrkMap[i]=new TPolyMarker(); pTrkMap[i]->SetMarkerStyle(4); pTrkMap[i]->SetMarkerSize(0.5); pTrkMap[i]->SetMarkerColor(kRed); + } + + AliHMPIDRecon rec; + + TLatex t; + TCanvas *pC = new TCanvas("HMPIDDisplay","HMPID Display",0,0,1226,900); pC->Divide(3,3); + + for(Int_t iEvt=0;iEvtGetEntries();iEvt++) { //events loop + pC->cd(3); t.DrawText(0.2,0.4,Form("Event %i",iEvt)); //print current event number + pEsdTr->GetEntry(iEvt); //get ESD for this event + for(Int_t iTrk=0;iTrkGetNumberOfTracks();iTrk++){//ESD tracks loop + AliESDtrack *pTrk = pEsd->GetTrack(iTrk); // + Float_t th,ph,x,y; pTrk->GetHMPIDtrk(x,y,th,ph); if(x<0) continue; + Int_t ch=pTrk->GetHMPIDcluIdx()/1000000; Printf("ch=%i",ch); + pTrkMap[ch]->SetPoint(aTrkCnt[ch]++,x,y); + }//ESD tracks loop + +// al->GetEvent(iEvt); rl->TreeD()->GetEntry(0); //get digits list + for(Int_t iCh=0;iCh<7;iCh++) {//chambers loop +// for(Int_t iDig=0;iDig < r->DigLst(iCh)->GetEntries();iDig++) { //digits loop +// AliHMPIDDigit *pDig = (AliHMPIDDigit*)r->DigLst(iCh)->At(iDig); +// pDigMap[iCh]->SetPoint(iDig,pDig->LorsX(),pDig->LorsY()); +// } //digits loop +// +// + if(iCh==6) pC->cd(1); if(iCh==5) pC->cd(2); + if(iCh==4) pC->cd(4); if(iCh==3) pC->cd(5); if(iCh==2) pC->cd(6); + if(iCh==1) pC->cd(8); if(iCh==0) pC->cd(9); + + AliHMPIDDigit::DrawPc(); pTrkMap[iCh]->Draw(); pDigMap[iCh]->Draw(); + }//chambers loop +// pC->Update(); +// pC->Modified(); +// if(iEvtWaitPrimitive();pC->Clear();} + + + + }//events loop + delete pEsd; pEsdFl->Close();//close AliESDs.root +// rl->UnloadDigits(); +}//Display() diff --git a/HMPID/AliHMPIDRecon.h b/HMPID/AliHMPIDRecon.h new file mode 100644 index 00000000000..394995f94c6 --- /dev/null +++ b/HMPID/AliHMPIDRecon.h @@ -0,0 +1,71 @@ +#ifndef AliHMPIDRecon_h +#define AliHMPIDRecon_h + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +////////////////////////////////////////////////////////////////////////// +// // +// AliHMPIDRecon // +// // +// HMPID class to perfom pattern recognition based on Hough transfrom // +// // +////////////////////////////////////////////////////////////////////////// + + +#include //base class +#include //fields + +class TClonesArray; +class AliHMPIDRecon : public TTask +{ +public : + AliHMPIDRecon(); + virtual ~AliHMPIDRecon() {} + + + 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 TracePhot (Double_t ckovTh,Double_t ckovPh,TVector2 &pos )const;//trace photon created by track to PC + 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 + Double_t SigLoc (Double_t ckovTh,Double_t ckovPh,Double_t beta )const;//error due to cathode segmetation + Double_t SigGeom (Double_t ckovTh,Double_t ckovPh,Double_t beta )const;//error due to unknown photon origin + Double_t SigCrom (Double_t ckovTh,Double_t ckovPh,Double_t beta )const;//error due to unknonw photon energy + Double_t Sigma2 (Double_t ckovTh,Double_t ckovPh )const;//photon candidate sigma + + static void Display ( ); //event display + + +protected: + const static Double_t fgkRadThick; //radiator thickness + const static Double_t fgkWinThick; //window thickness + const static Double_t fgkGapThick; //proximity gap thickness + const static Double_t fgkRadIdx; //mean refractive index of RAD material (C6F14) + const static Double_t fgkWinIdx; //mean refractive index of WIN material (SiO2) + const static Double_t fgkGapIdx; //mean refractive index of GAP material (CH4) + 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 + + Bool_t fIsWEIGHT; // flag to consider weight procedure + Float_t fDTheta; // Step for sliding window + Float_t fWindowWidth; // Hough width of sliding window + + TVector3 fTrkDir; //track direction in LORS + TVector2 fTrkPos; //track positon in LORS at the middle of radiator + ClassDef(AliHMPIDRecon,0) +}; + +#endif // #ifdef AliHMPIDRecon_cxx + diff --git a/HMPID/AliHMPIDReconstructor.cxx b/HMPID/AliHMPIDReconstructor.cxx new file mode 100644 index 00000000000..2b3d96c947c --- /dev/null +++ b/HMPID/AliHMPIDReconstructor.cxx @@ -0,0 +1,237 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +#include "AliHMPIDReconstructor.h" //class header +#include "AliHMPID.h" //Reconstruct() +#include "AliHMPIDCluster.h" //CluQA() +#include "AliHMPIDParam.h" //FillEsd() +#include //FillEsd() +#include //Reconstruct() for simulated digits +#include //Reconstruct() for raw digits +#include //Reconstruct() +#include //CluQA() +#include //CluQA() +#include //CluQA() +#include //CheckPR() +ClassImp(AliHMPIDReconstructor) + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDReconstructor::CluQA(AliRunLoader *pAL) +{ +// Quality assesment plots for clusters. +// This methode takes list of digits and form list of clusters again in order to +// calculate cluster shape and cluster particle mixture + AliLoader *pRL=pAL->GetDetectorLoader("HMPID"); AliHMPID *pRich=(AliHMPID*)pAL->GetAliRun()->GetDetector("HMPID");//get pointers for HMPID and HMPID loader + Int_t iNevt=pAL->GetNumberOfEvents(); if(iNevt==0) {AliInfoClass("No events");return;} + if(pRL->LoadDigits()) {AliInfoClass("No digits file");return;} + pAL->LoadHeader(); + pAL->LoadKinematics(); +// AliStack *pStack=pAL->Stack(); + TH1::AddDirectory(kFALSE); + + + TH1F* 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 ,AliHMPIDDigit::SizePcX(),1000,0,AliHMPIDDigit::SizePcY()); // maps + TH2F* pMipM=new TH2F("RichCluMipMap" ,"MIP map;x [cm];y [cm]" ,1000 ,0 ,AliHMPIDDigit::SizePcX(),1000,0,AliHMPIDDigit::SizePcY()); + TH2F* pCerM=new TH2F("RichCluCerMap" ,"Ckov map;x [cm];y [cm]" ,1000 ,0 ,AliHMPIDDigit::SizePcX(),1000,0,AliHMPIDDigit::SizePcY()); + + + + for(Int_t iEvt=0;iEvtGetEvent(iEvt); + pRL->TreeD()->GetEntry(0); + TClonesArray *pCluLst=new TClonesArray("AliHMPIDCluster");//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 iClu=0;iCluGetEntriesFast();iClu++){ + AliHMPIDCluster *pClu = (AliHMPIDCluster*)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 + if(iNckov!=0 && iNfee==0 && iNmip==0) {pCerQ->Fill(pClu->Q()) ; pCerS->Fill(pClu->Size()) ; pCerM ->Fill(pClu->X(),pClu->Y());}//ckov only cluster + if(iNckov==0 && iNfee==0 && iNmip!=0) {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(); + TCanvas *pC=new TCanvas("RichCluQA",Form("QA for cluster from %i events",iNevt),1000,900); pC->Divide(3,3); + pC->cd(1); pM->Draw(); pC->cd(2); pQ->Draw(); pC->cd(3); pS->Draw(); + pC->cd(4); pMipM->Draw(); pC->cd(5); pMipQ->Draw(); pC->cd(6); pMipS->Draw(); + pC->cd(7); pCerM->Draw(); pC->cd(8); pCerQ->Draw(); pC->cd(9); pCerS->Draw(); +}//CluQA() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDReconstructor::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. +// 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(AliHMPIDDigit::kPadAllX,AliHMPIDDigit::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 + AliHMPIDDigit *pDig= (AliHMPIDDigit*)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 + + AliHMPIDCluster clu; //tmp cluster to be used as current + + for(Int_t iDig=0;iDigGetEntriesFast();iDig++){ //digits loop to form clusters list + AliHMPIDDigit *pDig=(AliHMPIDDigit*)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 AliHMPIDReconstructor::FormClu(AliHMPIDCluster *pClu,AliHMPIDDigit *pDig,TClonesArray *pDigLst,TMatrixF *pDigMap) +{ +// Forms the initial cluster as a sum of all adjascent digits. Starts from the given digit +// then calls itself recursevly for all neighbours. +// Arguments: pClu - pointer to cluster being formed +// Returns: none + pClu->DigAdd(pDig);//take this digit in cluster + + Int_t x[4],y[4]; + + + Int_t iPadCnt=0; Int_t iPadX=pDig->PadX(); Int_t iPadY=pDig->PadY(); + if(iPadX != AliHMPIDDigit::kPad1) {x[iPadCnt]=iPadX-1; y[iPadCnt]=iPadY; iPadCnt++;} //left + if(iPadX != AliHMPIDDigit::kPadPcX) {x[iPadCnt]=iPadX+1; y[iPadCnt]=iPadY; iPadCnt++;} //right + if(iPadY != AliHMPIDDigit::kPad1) {x[iPadCnt]=iPadX; y[iPadCnt]=iPadY-1; iPadCnt++;} //down + if(iPadY != AliHMPIDDigit::kPadPcY) {x[iPadCnt]=iPadX; y[iPadCnt]=iPadY+1; iPadCnt++;} //up + + for (Int_t i=0;iGetDetectorLoader("HMPID"); + AliHMPID *pRich=(AliHMPID*)pAL->GetAliRun()->GetDetector("HMPID");//get pointers for HMPID and HMPID loader + pRL->LoadDigits(); + pRL->LoadRecPoints("recreate"); + + for(Int_t iEvtN=0;iEvtNGetNumberOfEvents();iEvtN++){//events loop + pAL->GetEvent(iEvtN); AliDebug(1,Form("Processing event %i...",iEvtN)); //switch current directory to next event + pRL->TreeD()->GetEntry(0); pRL->MakeTree("R"); pRich->MakeBranch("R"); //load digits to memory and create branches for clusters + + for(Int_t 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(); + }//events loop + + pRL->UnloadDigits(); + pRL->UnloadRecPoints(); + + AliDebug(1,"Stop."); +}//Reconstruct(for simulated digits) +//__________________________________________________________________________________________________ +void AliHMPIDReconstructor::Reconstruct(AliRunLoader *pAL,AliRawReader* pRR)const +{ +//Invoked by AliReconstruction to convert raw digits from DDL files to clusters +//Arguments: pAL - ALICE run loader pointer +// pRR - ALICE raw reader pointer +// Returns: none + AliLoader *pRL=pAL->GetDetectorLoader("HMPID"); AliHMPID *pRich=(AliHMPID*)pAL->GetAliRun()->GetDetector("HMPID");//get pointers for HMPID and HMPID loader + + AliHMPIDDigit dig; //tmp digit, raw digit will be converted to it + + Int_t iEvtN=0; + while(pRR->NextEvent()){//events loop + pAL->GetEvent(iEvtN++); + pRL->MakeTree("R"); pRich->MakeBranch("R"); + + for(Int_t iCh=0;iCh<7;iCh++){//chambers loop + TClonesArray *pDigLst=new TClonesArray("AliHMPIDDigit"); Int_t iDigCnt=0; //tmp list of digits for single chamber + pRR->Select("HMPID",2*iCh,2*iCh+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.ReadRaw(ddl,w32); + AliDebug(1,Form("Ch=%i DDL=%i raw=0x%x digit=(%3i,%3i,%3i,%3i) Q=%5.2f",iCh,ddl,w32,dig.Ch(),dig.Pc(),dig.PadX(),dig.PadY(),dig.Q())); + new((*pDigLst)[iDigCnt++]) AliHMPIDDigit(dig); //add this digit to the tmp list + }//raw records loop + if(iDigCnt) Dig2Clu(pDigLst,pRich->CluLst(iCh));//cluster finder for the current chamber if any digits present + pRR->Reset(); + 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 + pRich->CluReset(); + }//events loop + pRL->UnloadRecPoints(); +}//Reconstruct raw data +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void AliHMPIDReconstructor::FillESD(AliRunLoader *, AliESD *pESD) const +{ +// Calculates probability to be a electron-muon-pion-kaon-proton +// from the given Cerenkov angle and momentum assuming no initial particle composition +// (i.e. apriory probability to be the particle of the given sort is the same for all sorts) + + AliPID ppp; //needed + Double_t pid[AliPID::kSPECIES],h[AliPID::kSPECIES]; + + for(Int_t iTrk=0;iTrkGetNumberOfTracks();iTrk++){//ESD tracks loop + AliESDtrack *pTrk = pESD->GetTrack(iTrk);// get next reconstructed track + if(pTrk->GetHMPIDsignal()<=0){//HMPID does not find anything reasonable for this track, assign 0.2 for all species + for(Int_t iPart=0;iPartSetHMPIDpid(pid); + continue; + } + 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),pTrk->GetHMPIDsignal(),TMath::Sqrt(pTrk->GetHMPIDchi2()),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(pTrk->GetHMPIDsignal()-4*TMath::Sqrt(pTrk->GetHMPIDchi2()),pTrk->GetHMPIDsignal(),TMath::Sqrt(pTrk->GetHMPIDchi2()),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; + pTrk->SetHMPIDpid(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/HMPID/AliHMPIDReconstructor.h b/HMPID/AliHMPIDReconstructor.h new file mode 100644 index 00000000000..ccf3c1546dd --- /dev/null +++ b/HMPID/AliHMPIDReconstructor.h @@ -0,0 +1,54 @@ +#ifndef AliHMPIDReconstructor_h +#define AliHMPIDReconstructor_h +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +#include //base class +#include "AliHMPIDTracker.h" //CreateTracker() +#include //UseDig() +#include //UseDig() +class AliRawReader; //Reconstruct() with raw data +class AliHMPIDDigit; //Dig2Clu(), UseDig() +class AliHMPIDCluster; //Dig2Clu() + +class AliHMPIDReconstructor: public AliReconstructor +{ +public: + AliHMPIDReconstructor(): AliReconstructor() {}//default ctor + virtual ~AliHMPIDReconstructor() {}//dtor +//framework part + AliTracker* CreateTracker (AliRunLoader* )const{return new AliHMPIDTracker;} //from AliReconstructor for clusters->PID + void Reconstruct (AliRunLoader* pAL )const; //from AliReconstruction for digits->clusters + void Reconstruct (AliRunLoader* pAL,AliRawReader *pRR)const; //from AliReconstruction for raws->clusters + virtual void FillESD (AliRunLoader* pAL,AliESD *pESD)const; //calculate pid for HMPID + virtual void FillESD(AliRunLoader*, AliRawReader*, AliESD*) const { }; + virtual void FillESD(AliRawReader*, TTree*, AliESD*) const { }; + virtual void FillESD(TTree*, TTree*, AliESD*) const { }; + + + using AliReconstructor::Reconstruct; //to get rid of virtual hidden warning + + //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 FormClu (AliHMPIDCluster *pClu,AliHMPIDDigit *pDig,TClonesArray *pDigLst,TMatrixF *pDigMap);//cluster formation recursive algorithm + static inline AliHMPIDDigit* UseDig (Int_t padX,Int_t padY,TClonesArray *pDigList,TMatrixF *pDigMap );//use this pad's digit to form a cluster + + protected: + ClassDef(AliHMPIDReconstructor, 0) //class for the HMPID reconstruction +}; +//__________________________________________________________________________________________________ +AliHMPIDDigit* AliHMPIDReconstructor::UseDig(Int_t padX,Int_t padY,TClonesArray *pDigLst,TMatrixF *pDigMap) +{ +//Digit map contains a matrix if digit numbers. +//Main operation in forming initial cluster is done here. Requested digit pointer is returned and this digit marked as taken. +//Arguments: padX,padY - pad number +// pDigLst - list of digits for one sector +// pDigMap - map of those digits +// Returns: pointer to digit if not yet used or 0 if used + Int_t iDig=(Int_t)(*pDigMap)(padX,padY);(*pDigMap)(padX,padY)=-1;//take digit number from the map and reset this map cell to -1 + if(iDig!=-1) return (AliHMPIDDigit*)pDigLst->At(iDig); //digit pointer + else return 0; +} + +#endif diff --git a/HMPID/AliHMPIDSelector.C b/HMPID/AliHMPIDSelector.C new file mode 100644 index 00000000000..841e640ade1 --- /dev/null +++ b/HMPID/AliHMPIDSelector.C @@ -0,0 +1,186 @@ +#include +#include +#include //Terminate() +#include +#include +#include //caf() +#include //caf() +#include //base class +#include + + +class AliHMPIDSelector : public AliSelector { + public : + AliHMPIDSelector():AliSelector(),fChain(0),fEsd(0),fCkovP(0),fMipXY(0),fDifXY(0),fSigP(0) {for(Int_t i=0;i<5;i++) fProb[i]=0;} + virtual ~AliHMPIDSelector() {delete fEsd;} + + + virtual Int_t Version () const {return 2;} + virtual void Begin (TTree *) {} + virtual void SlaveBegin (TTree *tree); + virtual void Init (TTree *tree); + virtual Bool_t Notify () {return kTRUE;} + virtual Bool_t Process (Long64_t entry); + virtual void SetOption (const char *option) { fOption = option; } + virtual void SetObject (TObject *obj) { fObject = obj; } + virtual void SetInputList (TList *input) {fInput = input;} + virtual TList *GetOutputList () const { return fOutput; } + virtual void SlaveTerminate (); + virtual void Terminate (); + + private: + TTree *fChain ; //!pointer to the analyzed TTree or TChain + AliESD *fEsd ; //! + + TH2F *fCkovP,*fMipXY,*fDifXY,*fSigP; //! + TH1F *fProb[5]; //! + + ClassDef(AliHMPIDSelector,0); +}; + + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDSelector::SlaveBegin(TTree *tree) +{ +// The SlaveBegin() function is called after the Begin() function. When running with PROOF SlaveBegin() is called on each slave server. +// The tree argument is deprecated (on PROOF 0 is passed). + + Init(tree); + + TString option = GetOption(); + + // create histograms on each slave server + fCkovP = new TH2F("CkovP" , "#theta_{c}, [rad];P, [GeV]", 150, 0, 7 ,100, -3, 1); + fSigP = new TH2F("SigP" ,"#sigma_{#theta_c}" , 150, 0, 7 ,100, 0, 1e20); + fMipXY = new TH2F("MipXY" ,"mip position" , 260, 0,130 ,252,0,126); + fDifXY = new TH2F("DifXY" ,"diff" , 260, -10, 10 ,252,-10,10); + + fProb[0] = new TH1F("PidE" ,"PID: e yellow #mu magenta" ,100,0,1); fProb[0]->SetLineColor(kYellow); + fProb[1] = new TH1F("PidMu","pid of #mu" ,100,0,1); fProb[1]->SetLineColor(kMagenta); + fProb[2] = new TH1F("PidPi","PID: #pi red K green p blue",100,0,1); fProb[2]->SetLineColor(kRed); + fProb[3] = new TH1F("PidK" ,"pid of K" ,100,0,1); fProb[3]->SetLineColor(kGreen); + fProb[4] = new TH1F("PidP" ,"pid of p" ,100,0,1); fProb[4]->SetLineColor(kBlue); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDSelector::Init(TTree *pTr) +{ + // The Init() function is called when the selector needs to initialize + // a new tree or chain. Typically here the branch addresses of the tree + // will be set. It is normaly not necessary to make changes to the + // generated code, but the routine can be extended by the user if needed. + // Init() will be called many times when running with PROOF. + + // Set branch addresses + if ( !pTr ) return ; + fChain = pTr ; + fChain->SetBranchAddress("ESD", &fEsd) ; + fChain->SetBranchStatus("*", 0); + fChain->SetBranchStatus("fTracks.*", 1); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Bool_t AliHMPIDSelector::Process(Long64_t entry) +{ + + fChain->GetTree()->GetEntry(entry); + + for(Int_t iTrk=0;iTrkGetNumberOfTracks();iTrk++){ + AliESDtrack *pTrk=fEsd->GetTrack(iTrk); + +// if(pTrk->GetHMPIDsignal()<0) continue; + + fCkovP->Fill(pTrk->GetP(),pTrk->GetHMPIDsignal()) ; + fSigP ->Fill(pTrk->GetP(),TMath::Sqrt(pTrk->GetHMPIDchi2())); + +// Float_t xm,ym; Int_t q,np; pTrk->GetHMPIDmip(xm,ym,q,np); fMipXY->Fill(xm,ym); //mip info +// Float_t xd,yd,th,ph; pTrk->GetHMPIDtrk(xd,yd,th,ph); fDifXY->Fill(xd,yd); //track info + + Double_t pid[5]; pTrk->GetHMPIDpid(pid); for(Int_t i =0;i<5;i++) fProb[i]->Fill(pid[i]); + }//tracks loop + + return kTRUE; +}//Process() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDSelector::SlaveTerminate() +{ + // The SlaveTerminate() function is called after all entries or objects + // have been processed. When running with PROOF SlaveTerminate() is called + // on each slave server. + + // Add the histograms to the output on each slave server + + fOutput->Add(fCkovP); + fOutput->Add(fSigP); + fOutput->Add(fMipXY); + fOutput->Add(fDifXY); + + for(Int_t i=0;i<5;i++) fOutput->Add(fProb[i]); +}//SlaveTerminate() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDSelector::Terminate() +{ + // The Terminate() function is the last function to be called during + // a query. It always runs on the client, it can be used to present + // the results graphically or save the results to file. + + fCkovP = dynamic_cast(fOutput->FindObject("CkovP")) ; + fSigP = dynamic_cast(fOutput->FindObject("SigP")) ; + fMipXY = dynamic_cast(fOutput->FindObject("MipXY")) ; + fDifXY = dynamic_cast(fOutput->FindObject("DifXY")) ; + + fProb[0] = dynamic_cast(fOutput->FindObject("PidE")) ; + fProb[1] = dynamic_cast(fOutput->FindObject("PidMu")) ; + fProb[2] = dynamic_cast(fOutput->FindObject("PidPi")) ; + fProb[3] = dynamic_cast(fOutput->FindObject("PidK")) ; + fProb[4] = dynamic_cast(fOutput->FindObject("PidP")) ; + + Float_t n=1.292; //mean freon ref idx + TF1 *pPi=new TF1("RiPiTheo","acos(sqrt(x*x+[0]*[0])/(x*[1]))",1.2,7); pPi->SetLineWidth(1); pPi->SetParameter(1,n); + AliPID ppp; pPi->SetLineColor(kRed); pPi->SetParameter(0,AliPID::ParticleMass(AliPID::kPion)); //mass + TF1 *pK=(TF1*)pPi->Clone(); pK ->SetLineColor(kGreen); pK ->SetParameter(0,AliPID::ParticleMass(AliPID::kKaon)); + TF1 *pP=(TF1*)pPi->Clone(); pP ->SetLineColor(kBlue); pP ->SetParameter(0,AliPID::ParticleMass(AliPID::kProton)); + + TCanvas *pC=new TCanvas("c1","ESD QA");pC->SetFillColor(10); pC->SetHighLightColor(10); pC->Divide(3,2); + pC->cd(1); fCkovP->Draw(); pPi->Draw("same"); pK->Draw("same"); pP->Draw("same"); pC->cd(2); fMipXY->Draw(); pC->cd(3); fProb[0]->Draw(); fProb[1]->Draw("same"); + pC->cd(4); fSigP ->Draw(); pC->cd(5); fDifXY->Draw(); pC->cd(6); fProb[2]->Draw(); fProb[3]->Draw("same"); fProb[4]->Draw("same"); + +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + +void loc() +{ + TChain* pChain =new TChain("esdTree"); + pChain->Add("AliESDs.root"); + + pChain->Process("AliHMPIDSelector.C+"); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void caf() +{ + gBenchmark->Start("PRooF exec"); + TChain* pChain =new TChain("esdTree"); + + ifstream list; list.open("list.txt"); + + TString file; + while(list.good()) { + list>>file; + if (!file.Contains("root")) continue; //it's wrong file name + pChain->Add(file.Data()); + } + list.close(); + + pChain->GetListOfFiles()->Print(); + + TVirtualProof *pProof=TProof::Open("kir@lxb6046.cern.ch"); + pProof->UploadPackage("ESD.par"); + pProof->EnablePackage("ESD"); + + pChain->SetProof(pProof); + pChain->Process("AliHMPIDSelector.C+"); + + gBenchmark->Show("PRooF exec"); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + diff --git a/HMPID/AliHMPIDTracker.cxx b/HMPID/AliHMPIDTracker.cxx new file mode 100644 index 00000000000..46a1da76b32 --- /dev/null +++ b/HMPID/AliHMPIDTracker.cxx @@ -0,0 +1,112 @@ +#include "AliHMPIDTracker.h" //class header +#include "AliHMPID.h" //GetTrackPoint(),PropagateBack() +#include "AliHMPIDCluster.h" //GetTrackPoint(),PropagateBack() +#include "AliHMPIDParam.h" //GetTrackPoint(),PropagateBack() +#include "AliHMPIDRecon.h" //PropagateBack() +#include //PropagateBack() +#include //GetTrackPoint(),PropagateBack() +#include //GetTrackPoint() +#include //GetTrackPoint() +ClassImp(AliHMPIDTracker) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +AliHMPIDTracker::AliHMPIDTracker():AliTracker() +{ +// AliHMPIDTracker is created from AliReconstraction::Run() which invokes AliReconstraction::CreateTrackers() +// which in turn invokes AliHMPIDReconstructor::CreateTracker(). +// Note that this is done just once per session before AliReconstruction::Run() goes to events loop. +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Bool_t AliHMPIDTracker::GetTrackPoint(Int_t idx, AliTrackPoint& point) const +{ +// Interface callback methode invoked from AliReconstruction::WriteAlignmentData() to get position of MIP cluster in MARS associated to a current track. +// MIP cluster is reffered by index which is stored in AliESDtrack ??????? +// Arguments: idx- cluster index which is stored by HMPID in AliESDtrack +// point- reference to the object where to store the point +// Returns: status of operation if FALSE then AliReconstruction::WriteAlignmentData() do not store this point to array of points for current track. + if(idx<0) return kFALSE; //no MIP cluster assigned to this track in PropagateBack() + Int_t iCham=idx/1000000; + Int_t iClu=idx%1000000; + point.SetVolumeID(AliAlignObj::LayerToVolUID(AliAlignObj::kHMPID,iCham-1));//layer and chamber number + AliHMPID *pRich=((AliHMPID*)gAlice->GetDetector("HMPID")); + AliHMPIDCluster *pClu=(AliHMPIDCluster*)pRich->CluLst(iCham)->UncheckedAt(iClu);//get pointer to cluster + Double_t mars[3]; + AliHMPIDParam::Instance()->Lors2Mars(iCham,pClu->X(),pClu->Y(),mars); + point.SetXYZ(mars[0],mars[1],mars[2]); + return kTRUE; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliHMPIDTracker::LoadClusters(TTree *pCluTree) +{ +// Interface callback methode invoked from AliReconstruction::RunTracking() to load HMPID clusters before PropagateBack() gets control +// Arguments: pCluTree- pointer to clusters tree got by AliHMPIDLoader::LoadRecPoints("read") then AliHMPIDLoader::TreeR() +// Returns: error code (currently ignored in AliReconstruction::RunTraking()) + AliDebug(1,"Start."); pCluTree->GetEntry(0); AliDebug(1,"Stop."); return 0; +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Int_t AliHMPIDTracker::PropagateBack(AliESD *pESD) +{ +// Interface callback methode invoked by AliRecontruction::RunTracking() during tracking after TOF. It's done just once per event +// Arguments: pESD - pointer to Event Summary Data class instance which contains a list of tracks +// Returns: error code, 0 if no errors + Int_t iNtracks=pESD->GetNumberOfTracks(); AliDebug(1,Form("Start with %i tracks",iNtracks)); + AliHMPID *pRich=((AliHMPID*)gAlice->GetDetector("HMPID")); + AliHMPIDRecon recon; //instance of reconstruction class, nothing important in ctor + + AliHMPIDParam *pParam=AliHMPIDParam::Instance(); + + 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,AliHMPIDParam::kRad); //point & norm for RAD + Double_t p2[3],n2[3]; pParam->Norm(i,n2); pParam->Lors2Mars(i,0,0,p2,AliHMPIDParam::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 + + if(AliHMPIDDigit::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 + + TClonesArray *pCluLst=pRich->CluLst(iCh); //get clusters list for intersected chamber + + 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 + AliHMPIDCluster *pClu=(AliHMPIDCluster*)pCluLst->At(iClu); //get pointer to current cluster + if(pClu->Q()<100) continue; //QDC is incompartible with mip, go after another one + + 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( d < dMin) {iMip=iClu; dMin=d;} //current cluster is closer, overwrite data for min cluster + }//clusters loop for intersected chamber + + pTrk->SetHMPIDtrk (xPc,yPc,th,ph); //store track info + if(iMip==-1) {pTrk->SetHMPIDsignal (kMipQdcCut); continue;} //no clusters with QDC more the threshold at all + + AliHMPIDCluster *pMipClu=(AliHMPIDCluster*)pCluLst->At(iMip); //take mip cluster + + pTrk->SetHMPIDmip (pMipClu->X(),pMipClu->Y(),pMipClu->Q()); //store mip info + if(dMin>1) {pTrk->SetHMPIDsignal (kMipDistCut); continue;} //closest cluster with enough charge is still too far + pTrk->SetHMPIDcluIdx (iCh,iMip); //set mip cluster index + recon.SetTrack(th,ph,xRa,yRa); Int_t iNphot=0; //initialize track parameters + pTrk->SetHMPIDsignal (recon.CkovAngle(pCluLst,iNphot)); //search for Cerenkov angle for this track + pTrk->SetHMPIDchi2 (recon.CkovSigma2()); //error squared + pTrk->SetHMPIDmip (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->GetHMPIDsignal(),pTrk->GetHMPIDchi2()); + }//ESD tracks loop + AliDebug(1,"Stop pattern recognition"); + return 0; // error code: 0=no error; +}//PropagateBack() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/HMPID/AliHMPIDTracker.h b/HMPID/AliHMPIDTracker.h new file mode 100644 index 00000000000..116aec36a34 --- /dev/null +++ b/HMPID/AliHMPIDTracker.h @@ -0,0 +1,28 @@ +#ifndef AliHMPIDTracker_h +#define AliHMPIDTracker_h + +#include //base class + +class TNtupleD; //RecWithStack() +class AliESD; //Clusters2Tracks(), RefitInward(), PropagateBack(), RecWithESD() + +class AliHMPIDTracker : public AliTracker +{ +public: + AliHMPIDTracker(); + virtual ~AliHMPIDTracker() {} +//framework part + AliCluster *GetCluster (Int_t )const {return 0;} //pure virtual from AliTracker + Bool_t GetTrackPoint (Int_t idx,AliTrackPoint &pt)const; // from AliTracker + Int_t Clusters2Tracks(AliESD * ) {return 0;} //pure virtual from AliTracker + Int_t LoadClusters (TTree *pCluTr ); //pure virtual from AliTracker + Int_t PropagateBack (AliESD * ); //pure virtual from AliTracker invoked from AliReconstruction::RunTracking() + Int_t RefitInward (AliESD * ) {return 0;} //pure virtual from AliTracker + void UnloadClusters ( ) { } //pure virtual from AliTracker +//private part + enum ETrackingFlags {kMipDistCut=-9,kMipQdcCut=-5}; +protected: + ClassDef(AliHMPIDTracker,0) +};//class AliHMPIDTracker + +#endif//AliHMPIDTracker_h diff --git a/HMPID/AliHMPIDv0.cxx b/HMPID/AliHMPIDv0.cxx new file mode 100644 index 00000000000..8fb2ea1070f --- /dev/null +++ b/HMPID/AliHMPIDv0.cxx @@ -0,0 +1,26 @@ +//************************************************************************** +// Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +// * +// Author: The ALICE Off-line Project. * +// Contributors are mentioned in the code where appropriate. * +// * +// Permission to use, copy, modify and distribute this software and its * +// documentation strictly for non-commercial purposes is hereby granted * +// without fee, provided that the above copyright notice appears in all * +// copies and that both the copyright notice and this permission notice * +// appear in the supporting documentation. The authors make no claims * +// about the suitability of this software for any purpose. It is * +// provided "as is" without express or implied warranty. * +//************************************************************************** + +#include "AliHMPIDv0.h" + +#include + +ClassImp(AliHMPIDv0) + +void AliHMPIDv0::StepManager() +{ +//This StepManager is a provision for different test-learn activities on the current MC layer + +}//StepManager() diff --git a/HMPID/AliHMPIDv0.h b/HMPID/AliHMPIDv0.h new file mode 100644 index 00000000000..085005414b3 --- /dev/null +++ b/HMPID/AliHMPIDv0.h @@ -0,0 +1,22 @@ +#ifndef AliHMPIDv0_h +#define AliHMPIDv0_h + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +#include "AliHMPID.h" + +class AliHMPIDv0 : public AliHMPID +{ +public: + AliHMPIDv0():AliHMPID() {;} //default ctor + AliHMPIDv0(const char *name, const char *title):AliHMPID(name,title) {;} //named ctor + virtual ~AliHMPIDv0() {;} //dtor + virtual void Init() {;} //interface from AliHMPID + virtual Int_t IsVersion() const{return 0;} //interface from AliHMPID + virtual void StepManager(); //interface from AliHMPID +protected: + ClassDef(AliHMPIDv0,1) //HMPID coarse version for material budget study and debuging +}; + +#endif diff --git a/HMPID/AliHMPIDv1.cxx b/HMPID/AliHMPIDv1.cxx new file mode 100644 index 00000000000..7ff7967ade8 --- /dev/null +++ b/HMPID/AliHMPIDv1.cxx @@ -0,0 +1,657 @@ +// ************************************************************************** +// * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +// * * +// * Author: The ALICE Off-line Project. * +// * Contributors are mentioned in the code where appropriate. * +// * * +// * Permission to use, copy, modify and distribute this software and its * +// * documentation strictly for non-commercial purposes is hereby granted * +// * without fee, provided that the above copyright notice appears in all * +// * copies and that both the copyright notice and this permission notice * +// * appear in the supporting documentation. The authors make no claims * +// * about the suitability of this software for any purpose. It is * +// * provided "as is" without express or implied warranty. * +// ************************************************************************** + + +#include "AliHMPIDv1.h" //class header +#include "AliHMPIDParam.h" //CreateMaterials() +#include "AliHMPIDHit.h" //Hits2SDigs(),StepManager() +#include "AliHMPIDDigit.h" //CreateMaterials() +#include "AliRawReader.h" //Raw2SDigits() +#include //Hits2SDigits() +#include +#include //StepManager() for gMC +#include //StepHistory() +#include //StepManager(),Hits2SDigits() +#include //Hits2SDigits() +#include //Hits2SDigits() +#include +#include +#include //StepManager() +#include //Digits2Raw() +#include //Digits2Raw() +#include //CreateMaterials() +#include //CreateMaterials() +#include //CreateGeometry() +#include //Optics() +#include //Optics() +#include //Optics() +#include //Optics() +#include //CreateMaterials() +#include //CreateMaterials() +#include //CreateMaterials() + +ClassImp(AliHMPIDv1) +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::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("/HMPID/Chamber%i",i),Form("ALIC_1/HMPID_%i",i)); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::CreateMaterials() +{ +// Definition of available HMPID materials +// Arguments: none +// Returns: none + AliDebug(1,"Start v1 HMPID."); + + 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 + + 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]; + + 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] + Float_t aAir[4]={12,14,16,36} , zAir[4]={6,7,8,18} , wAir[4]={0.000124,0.755267,0.231781,0.012827} , dAir=0.00120479; Int_t nAir=4;//mixture 0.9999999 + Float_t aC6F14[2]={ 12.01 , 18.99} , zC6F14[2]={ 6 , 9} , wC6F14[2]={6 , 14} , dC6F14=1.68 ; Int_t nC6F14=-2; + Float_t aSiO2[2]={ 28.09 , 15.99} , zSiO2[2]={14 , 8} , wSiO2[2]={1 , 2} , dSiO2=2.64 ; Int_t nSiO2=-2; + Float_t aCH4[2]={ 12.01 , 1.01} , zCH4[2]={ 6 , 1} , wCH4[2]={1 , 4} , dCH4=7.17e-4 ; Int_t nCH4=-2; + Float_t aCsI[2]={132.90 ,126.90} , zCsI[2]={55 ,53} , wCsI[2]={1 , 1} , dCsI=0.1 ; Int_t nCsI=-2; + Float_t aRoha= 12.01 , zRoha= 6 , dRoha= 0.10 , radRoha= 18.80 , absRoha= 86.3/dRoha; //special material- quazi carbon + Float_t aCu= 63.55 , zCu= 29 , dCu= 8.96 , radCu= 1.43 , absCu= 134.9/dCu ; + Float_t aW=183.84 , zW= 74 , dW= 19.30 , radW= 0.35 , absW= 185.0/dW ; + Float_t aAl= 26.98 , zAl= 13 , dAl= 2.70 , radAl= 8.90 , absAl= 106.4/dAl ; + + Int_t matId=0; //tmp material id number + Int_t unsens = 0, sens=1; //sensitive or unsensitive medium + Int_t itgfld = gAlice->Field()->Integ(); //type of field intergration 0 no field -1 user in guswim 1 Runge Kutta 2 helix 3 const field along z + Float_t maxfld = gAlice->Field()->Max(); //max field value + Float_t tmaxfd = -10.0; //max deflection angle due to magnetic field in one step + Float_t deemax = - 0.2; //max fractional energy loss in one step + Float_t stemax = - 0.1; //mas step allowed [cm] + Float_t epsil = 0.001; //abs tracking precision [cm] + Float_t stmin = - 0.001; //min step size [cm] in continius process transport, negative value: choose it automatically + AliMixture(++matId,"Air" ,aAir ,zAir ,dAir ,nAir ,wAir ); AliMedium(kAir ,"Air" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMixture(++matId,"C6F14",aC6F14,zC6F14,dC6F14,nC6F14,wC6F14); AliMedium(kC6F14,"C6F14",matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMixture(++matId,"SiO2" ,aSiO2 ,zSiO2 ,dSiO2 ,nSiO2 ,wSiO2 ); AliMedium(kSiO2 ,"SiO2" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMixture(++matId,"CH4" ,aCH4 ,zCH4 ,dCH4 ,nCH4 ,wCH4 ); AliMedium(kCH4 ,"CH4" ,matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMixture(++matId,"CsI" ,aCsI ,zCsI ,dCsI ,nCsI ,wCsI ); AliMedium(kCsI ,"CsI" ,matId, sens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);//sensitive + + AliMaterial(++matId,"Roha",aRoha,zRoha,dRoha,radRoha,absRoha); AliMedium(kRoha,"Roha", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMaterial(++matId,"Cu" ,aCu ,zCu ,dCu ,radCu ,absCu ); AliMedium(kCu ,"Cu" , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMaterial(++matId,"W" ,aW ,zW ,dW ,radW ,absW ); AliMedium(kW ,"W" , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + AliMaterial(++matId,"Al" ,aAl ,zAl ,dAl ,radAl ,absAl ); AliMedium(kAl ,"Al" , matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin); + + gMC->SetCerenkov((*fIdtmed)[kC6F14] , kNbins, aEckov, 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 HMPID."); + + TString ttl=GetTitle(); if(!ttl.Contains("ShowOptics")) return; //user didn't aks to plot optical curves + + 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; + + Float_t aTraRad[kNbins],aTraWin[kNbins],aTraGap[kNbins],aTraTot[kNbins]; + for(Int_t i=0;iSetMarkerStyle(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","HMPID optics to check",1100,900); pC->Divide(2,2); + 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 AliHMPID::CreateMaterials() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::CreateGeometry() +{ +//Creates detailed geometry simulation (currently GEANT volumes tree) + AliDebug(1,"Start main."); + if(!gMC->IsRootGeometrySupported()) return; + + Double_t cm=1,mm=0.1*cm,mkm=0.001*mm,dx,dy,dz;//default is cm + + TGeoVolume *pRich=gGeoManager->MakeBox("HMPID",gGeoManager->GetMedium("HMPID_CH4"),dx=(6*mm+1681*mm+6*mm)/2, //main HMPID volume + dy=(6*mm+1466*mm+6*mm)/2, + dz=(80*mm+40*mm)*2/2); //x,y taken from 2033P1 z from p84 TDR + const Double_t kAngHor=19.5; // horizontal angle between chambers 19.5 grad + const Double_t kAngVer=20; // vertical angle between chambers 20 grad + const Double_t kAngCom=30; // common HMPID 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=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 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); + } + + Float_t par[3]; + Int_t matrixIdReturn=0; //matrix id returned by AliMatrix +//Pad Panel frame 6 sectors + par[0]=648*mm/2;par[1]= 411*mm/2;par[2]=40 *mm/2;gMC->Gsvolu("Rppf" ,"BOX ",(*fIdtmed)[kAl] ,par,3);//PPF 2001P2 inner size of the slab by 1mm more + par[0]=181*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("RppfLarge","BOX ",(*fIdtmed)[kAir] ,par,3);//large whole + par[0]=114*mm/2;par[1]=89.25*mm/2;par[2]=38.3*mm/2;gMC->Gsvolu("RppfSmall","BOX ",(*fIdtmed)[kAir] ,par,3);//small whole + par[0]=644*mm/2;par[1]= 407*mm/2;par[2]= 1.7*mm/2;gMC->Gsvolu("Rpc" ,"BOX ",(*fIdtmed)[kCsI] ,par,3);//by 0.2 mm more then actual size (PCB 2006P1) + + gMC->Gspos("Rppf",0,"HMPID", -335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY");//F1 2040P1 z p.84 TDR + gMC->Gspos("Rppf",1,"HMPID", +335*mm, -433*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",2,"HMPID", -335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",3,"HMPID", +335*mm, 0*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",4,"HMPID", -335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rppf",5,"HMPID", +335*mm, +433*mm, 8*cm+20*mm, 0,"ONLY"); + gMC->Gspos("Rpc" ,1,"Rppf", 0*mm, 0*mm, -19.15*mm, 0,"ONLY");//PPF 2001P2 + gMC->Gspos("RppfLarge",1,"Rppf", -224.5*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",2,"Rppf", -224.5*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",3,"Rppf", -224.5*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",4,"Rppf", -224.5*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",1,"Rppf", - 65.0*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",2,"Rppf", - 65.0*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",3,"Rppf", - 65.0*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",4,"Rppf", - 65.0*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",5,"Rppf", + 65.0*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",6,"Rppf", + 65.0*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",7,"Rppf", + 65.0*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfSmall",8,"Rppf", + 65.0*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",5,"Rppf", +224.5*mm, -151.875*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",6,"Rppf", +224.5*mm, - 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",7,"Rppf", +224.5*mm, + 50.625*mm, 0.85*mm, 0,"ONLY"); + gMC->Gspos("RppfLarge",8,"Rppf", +224.5*mm, +151.875*mm, 0.85*mm, 0,"ONLY"); +//Gap - anod wires 6 copies to HMPID + par[0]=648*mm/2;par[1]= 411*mm/2 ;par[2]=4.45*mm/2;gMC->Gsvolu("Rgap","BOX ",(*fIdtmed)[kCH4] ,par,3);//xy as PPF 2001P2 z WP 2099P1 + par[0]= 0*mm ;par[1]= 20*mkm/2 ;par[2]= 648*mm/2;gMC->Gsvolu("Rano","TUBE",(*fIdtmed)[kW] ,par,3);//WP 2099P1 z = gap x PPF 2001P2 + AliMatrix(matrixIdReturn,180,0, 90,90, 90,0); //wires along x + + gMC->Gspos("Rgap",0,"HMPID", -335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); //F1 2040P1 z WP 2099P1 + gMC->Gspos("Rgap",1,"HMPID", +335*mm, -433*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",2,"HMPID", -335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",3,"HMPID", +335*mm, 0*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",4,"HMPID", -335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); + gMC->Gspos("Rgap",5,"HMPID", +335*mm, +433*mm,8*cm-2.225*mm, 0,"ONLY"); + for(int i=1;i<=96;i++) + gMC->Gspos("Rano",i,"Rgap", 0*mm, -411/2*mm+i*4*mm, 0.185*mm, matrixIdReturn,"ONLY"); //WP 2099P1 +//Defines radiators geometry + par[0]=1330*mm/2 ;par[1]= 413*mm/2 ;par[2]= 24*mm/2; gMC->Gsvolu("Rrad" ,"BOX ",(*fIdtmed)[kC6F14] ,par,3); // Rad 2011P1 + par[0]=1330*mm/2 ;par[1]= 413*mm/2 ;par[2]= 4*mm/2; gMC->Gsvolu("RradFront" ,"BOX ",(*fIdtmed)[kRoha] ,par,3); //front + par[0]=1330*mm/2 ;par[1]= 413*mm/2 ;par[2]= 5*mm/2; gMC->Gsvolu("RradWin" ,"BOX ",(*fIdtmed)[kSiO2] ,par,3); //window + par[0]=1330*mm/2 ;par[1]= 5*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RradLong" ,"BOX ",(*fIdtmed)[kRoha] ,par,3); //long side + par[0]= 10*mm/2 ;par[1]= 403*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RradShort" ,"BOX ",(*fIdtmed)[kRoha] ,par,3); //short side + par[0]= 0 ;par[1]= 10*mm/2 ;par[2]= 15*mm/2; gMC->Gsvolu("RradSpacer","TUBE",(*fIdtmed)[kSiO2] ,par,3); //spacer + + gMC->Gspos("Rrad",1,"HMPID", 0*mm,-434*mm, -12*mm, 0,"ONLY"); //3 radiators to HMPID + gMC->Gspos("Rrad",2,"HMPID", 0*mm, 0*mm, -12*mm, 0,"ONLY"); + gMC->Gspos("Rrad",3,"HMPID", 0*mm,+434*mm, -12*mm, 0,"ONLY"); + gMC->Gspos("RradFront",1,"Rrad", 0*mm, 0*mm, -10.0*mm, 0,"ONLY"); //front cover + gMC->Gspos("RradWin" ,1,"Rrad", 0*mm, 0*mm, 9.5*mm, 0,"ONLY"); //quartz window (back cover) + gMC->Gspos("RradLong" ,1,"Rrad", 0*mm,-204*mm, -0.5*mm, 0,"ONLY"); //long side + gMC->Gspos("RradLong" ,2,"Rrad", 0*mm,+204*mm, -0.5*mm, 0,"ONLY"); //long side + gMC->Gspos("RradShort",1,"Rrad",-660*mm, 0*mm, -0.5*mm, 0,"ONLY"); //short side + gMC->Gspos("RradShort",2,"Rrad",+660*mm, 0*mm, -0.5*mm, 0,"ONLY"); //short side + for(int i=0;i<3;i++) + for(int j=0;j<10;j++) + gMC->Gspos("RradSpacer",10*i+j,"Rrad",-1330*mm/2+116*mm+j*122*mm,(i-1)*105*mm,-0.5*mm,0,"ONLY");//spacers +//Defines SandBox geometry + par[0]=1419*mm/2 ;par[1]=1378*mm/2;par[2]=50.5*mm/2; gMC->Gsvolu("Rsb" ,"BOX ",(*fIdtmed)[kAir] ,par,3); //2072P1 + par[0]=1419*mm/2 ;par[1]=1378*mm/2;par[2]= 0.5*mm/2; gMC->Gsvolu("RsbCover","BOX ",(*fIdtmed)[kAl] ,par,3); //cover + par[0]=1359*mm/2 ;par[1]=1318*mm/2;par[2]=49.5*mm/2; gMC->Gsvolu("RsbComb" ,"BOX ",(*fIdtmed)[kRoha] ,par,3); //honeycomb structure + + gMC->Gspos("Rsb",1,"HMPID", 0*mm, 0*mm, -73.75*mm, 0,"ONLY"); //p.84 TDR sandbox to rich + gMC->Gspos("RsbComb" ,1,"Rsb", 0*mm, 0*mm, 0*mm, 0,"ONLY"); //2072P1 honeycomv to sandbox + gMC->Gspos("RsbCover",1,"Rsb", 0*mm, 0*mm, +25*mm, 0,"ONLY"); //cover to sandbox + gMC->Gspos("RsbCover",2,"Rsb", 0*mm, 0*mm, -25*mm, 0,"ONLY"); //cover to sandbox + AliDebug(1,"Stop v1. HMPID option"); +}//CreateGeometry() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::Init() +{ +// This methode defines ID for sensitive volumes, i.e. such geometry volumes for which there are if(gMC->CurrentVolID()==XXX) statements in StepManager() +// Arguments: none +// Returns: none + AliDebug(1,"Start v1 HMPID."); + fIdRad = gMC->VolId("Rrad"); + fIdWin = gMC->VolId("RradWin"); + fIdPc = gMC->VolId("Rpc"); + fIdAmpGap = gMC->VolId("Rgap"); + fIdProxGap = gMC->VolId("Rgap"); + AliDebug(1,"Stop v1 HMPID."); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Bool_t AliHMPIDv1::IsLostByFresnel() +{ +// Calculate probability for the photon to be lost by Fresnel reflection. + TLorentzVector p4; + Double_t mom[3],localMom[3]; + gMC->TrackMomentum(p4); mom[0]=p4(1); mom[1]=p4(2); mom[2]=p4(3); + localMom[0]=0; localMom[1]=0; localMom[2]=0; + gMC->Gmtod(mom,localMom,2); + Double_t localTc = localMom[0]*localMom[0]+localMom[2]*localMom[2]; + Double_t localTheta = TMath::ATan2(TMath::Sqrt(localTc),localMom[1]); + Double_t cotheta = TMath::Abs(TMath::Cos(localTheta)); + if(gMC->GetRandom()->Rndm() < Fresnel(p4.E()*1e9,cotheta,1)){ + AliDebug(1,"Photon lost"); + return kTRUE; + }else + return kFALSE; +}//IsLostByFresnel() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::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 AliHMPIDParam::TotQdc() + TLorentzVector x4; + 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]; +//Generate photons + for(Int_t i=0;iGetRandom()->RndmArray(2,ranf); //Sample direction + cthf=ranf[0]*2-1.0; + if(cthf<0) continue; + sthf = TMath::Sqrt((1 - cthf) * (1 + cthf)); + phif = ranf[1] * 2 * TMath::Pi(); + + if(Double_t randomNumber=gMC->GetRandom()->Rndm()<=0.57) + enfp = 7.5e-9; + else if(randomNumber<=0.7) + enfp = 6.4e-9; + else + enfp = 7.9e-9; + + + dir[0] = sthf * TMath::Sin(phif); dir[1] = cthf; dir[2] = sthf * TMath::Cos(phif); + gMC->Gdtom(dir, mom, 2); + mom[0]*=enfp; mom[1]*=enfp; mom[2]*=enfp; + mom[3] = TMath::Sqrt(mom[0]*mom[0]+mom[1]*mom[1]+mom[2]*mom[2]); + + // Polarisation + e1[0]= 0; e1[1]=-dir[2]; e1[2]= dir[1]; + e2[0]=-dir[1]; e2[1]= dir[0]; e2[2]= 0; + e3[0]= dir[1]; e3[1]= 0; e3[2]=-dir[0]; + + vmod=0; + for(j=0;j<3;j++) vmod+=e1[j]*e1[j]; + if (!vmod) for(j=0;j<3;j++) { + uswop=e1[j]; + e1[j]=e3[j]; + e3[j]=uswop; + } + vmod=0; + for(j=0;j<3;j++) vmod+=e2[j]*e2[j]; + if (!vmod) for(j=0;j<3;j++) { + uswop=e2[j]; + e2[j]=e3[j]; + e3[j]=uswop; + } + + vmod=0; for(j=0;j<3;j++) vmod+=e1[j]*e1[j]; vmod=TMath::Sqrt(1/vmod); for(j=0;j<3;j++) e1[j]*=vmod; + vmod=0; for(j=0;j<3;j++) vmod+=e2[j]*e2[j]; vmod=TMath::Sqrt(1/vmod); for(j=0;j<3;j++) e2[j]*=vmod; + + phi = gMC->GetRandom()->Rndm()* 2 * TMath::Pi(); + for(j=0;j<3;j++) pol[j]=e1[j]*TMath::Sin(phi)+e2[j]*TMath::Cos(phi); + gMC->Gdtom(pol, pol, 2); + Int_t outputNtracksStored; + gAlice->GetMCApp()->PushTrack(1, //transport + gAlice->GetMCApp()->GetCurrentTrackNumber(),//parent track + kFeedback, //PID + mom[0],mom[1],mom[2],mom[3], //track momentum + x4.X(),x4.Y(),x4.Z(),x4.T(), //track origin + pol[0],pol[1],pol[2], //polarization + kPFeedBackPhoton, //process ID + outputNtracksStored, //on return how many new photons stored on stack + 1.0); //weight + }//feedbacks loop + AliDebug(1,"Stop."); +}//GenerateFeedbacks() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::Hits2SDigits() +{ +// 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 iEvt=0;iEvt < GetLoader()->GetRunLoader()->GetNumberOfEvents();iEvt++){ //events loop + GetLoader()->GetRunLoader()->GetEvent(iEvt); //get next event + + 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); + Hit2Sdi(Hits(),SdiLst()); + }//prims loop + GetLoader()->TreeS()->Fill(); + GetLoader()->WriteSDigits("OVERWRITE"); + SdiReset(); + }//events loop + GetLoader()->UnloadHits(); + GetLoader()->UnloadSDigits(); + AliDebug(1,"Stop."); +}//Hits2SDigits() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::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 + AliHMPIDHit *pHit=(AliHMPIDHit*)pHitLst->At(iHit); //get pointer to current hit + AliHMPIDDigit::Hit2Sdi(pHit,pSdiLst); //convert this hit to list of sdigits + }//hits loop loop +}//Hits2SDigs() for TVector2 +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::Digits2Raw() +{ +// 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(); + TTree * treeD = GetLoader()->TreeD(); + if(!treeD) { + AliError("No digits tree!"); + return; + } + treeD->GetEntry(0); + + ofstream file[AliHMPIDDigit::kNddls]; //output streams + Int_t cnt[AliHMPIDDigit::kNddls]; //data words counters for DDLs + AliRawDataHeader header; //empty DDL header + UInt_t w32=0; //32 bits data word + + for(Int_t i=0;iGetEntriesFast();iDig++){//digits loop for a given chamber + AliHMPIDDigit *pDig=(AliHMPIDDigit*)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 + + + for(Int_t i=0;iUnloadDigits(); + AliDebug(1,"Stop."); +}//Digits2Raw() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Float_t AliHMPIDv1::Fresnel(Float_t ene,Float_t pdoti, Bool_t pola) +{ +// Correction for Fresnel ??????????? +// Arguments: ene - photon energy [GeV], +// PDOTI=COS(INC.ANG.), PDOTR=COS(POL.PLANE ROT.ANG.) +// Returns: + Float_t en[36] = {5.0,5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6.0,6.1,6.2, + 6.3,6.4,6.5,6.6,6.7,6.8,6.9,7.0,7.1,7.2,7.3,7.4,7.5,7.6,7.7, + 7.8,7.9,8.0,8.1,8.2,8.3,8.4,8.5}; + Float_t csin[36] = {2.14,2.21,2.33,2.48,2.76,2.97,2.99,2.59,2.81,3.05, + 2.86,2.53,2.55,2.66,2.79,2.96,3.18,3.05,2.84,2.81,2.38,2.11, + 2.01,2.13,2.39,2.73,3.08,3.15,2.95,2.73,2.56,2.41,2.12,1.95, + 1.72,1.53}; + Float_t csik[36] = {0.,0.,0.,0.,0.,0.196,0.408,0.208,0.118,0.49,0.784,0.543, + 0.424,0.404,0.371,0.514,0.922,1.102,1.139,1.376,1.461,1.253,0.878, + 0.69,0.612,0.649,0.824,1.347,1.571,1.678,1.763,1.857,1.824,1.824, + 1.714,1.498}; + Float_t xe=ene; + Int_t j=Int_t(xe*10)-49; + Float_t cn=csin[j]+((csin[j+1]-csin[j])/0.1)*(xe-en[j]); + Float_t ck=csik[j]+((csik[j+1]-csik[j])/0.1)*(xe-en[j]); + + //FORMULAE FROM HANDBOOK OF OPTICS, 33.23 OR + //W.R. HUNTER, J.O.S.A. 54 (1964),15 , J.O.S.A. 55(1965),1197 + + Float_t sinin=TMath::Sqrt(1-pdoti*pdoti); + Float_t tanin=sinin/pdoti; + + Float_t c1=cn*cn-ck*ck-sinin*sinin; + Float_t c2=4*cn*cn*ck*ck; + Float_t aO=TMath::Sqrt(0.5*(TMath::Sqrt(c1*c1+c2)+c1)); + Float_t b2=0.5*(TMath::Sqrt(c1*c1+c2)-c1); + + Float_t rs=((aO-pdoti)*(aO-pdoti)+b2)/((aO+pdoti)*(aO+pdoti)+b2); + Float_t rp=rs*((aO-sinin*tanin)*(aO-sinin*tanin)+b2)/((aO+sinin*tanin)*(aO+sinin*tanin)+b2); + + + //CORRECTION FACTOR FOR SURFACE ROUGHNESS + //B.J. STAGG APPLIED OPTICS, 30(1991),4113 + + Float_t sigraf=18.; + Float_t lamb=1240/ene; + Float_t fresn; + + Float_t rO=TMath::Exp(-(4*TMath::Pi()*pdoti*sigraf/lamb)*(4*TMath::Pi()*pdoti*sigraf/lamb)); + + if(pola) + { + Float_t pdotr=0.8; //DEGREE OF POLARIZATION : 1->P , -1->S + fresn=0.5*(rp*(1+pdotr)+rs*(1-pdotr)); + } + else + fresn=0.5*(rp+rs); + + fresn = fresn*rO; + return fresn; +}//Fresnel() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::Print(Option_t *option)const +{ +// Debug printout + TObject::Print(option); +}//void AliHMPID::Print(Option_t *option)const +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Bool_t AliHMPIDv1::Raw2SDigits(AliRawReader *pRR) +{ +// Interface methode ivoked from AliSimulation to create a list of sdigits from raw digits. Events loop is done in AliSimulation +// Arguments: pRR- raw reader +// Returns: kTRUE on success (currently ignored in AliSimulation::ConvertRaw2SDigits()) + AliHMPIDDigit sdi; //tmp sdigit, raw digit will be converted to it + + if(!GetLoader()->TreeS()) {MakeTree("S"); MakeBranch("S");} + + TClonesArray *pSdiLst=SdiLst(); Int_t iSdiCnt=0; //tmp list of sdigits for all chambers + pRR->Select("HMPID",0,13);//select all HMPID 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++]) AliHMPIDDigit(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 AliHMPIDv1::StepCount() +{ +// Count number of ckovs created +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::StepHistory() +{ +// This methode is invoked from StepManager() in order to print out + static Int_t iStepN; + const char *sParticle; + switch(gMC->TrackPid()){ + case kProton: sParticle="PROTON" ;break; + case kNeutron: sParticle="neutron" ;break; + case kGamma: sParticle="gamma" ;break; + case kCerenkov: sParticle="CKOV" ;break; + case kPi0: sParticle="Pi0" ;break; + case kPiPlus: sParticle="Pi+" ;break; + case kPiMinus: sParticle="Pi-" ;break; + case kElectron: sParticle="electron" ;break; + default: sParticle="not known" ;break; + } + + TString flag="fanny combination"; + if(gMC->IsTrackAlive()) + if(gMC->IsTrackEntering()) flag="enters to"; + else if(gMC->IsTrackExiting()) flag="exits from"; + else if(gMC->IsTrackInside()) flag="inside"; + else + if(gMC->IsTrackStop()) flag="stoped in"; + + Int_t vid=0,copy=0; + TString path=gMC->CurrentVolName(); path.Prepend("-");path.Prepend(gMC->CurrentVolOffName(1));//current volume and his mother are always there + vid=gMC->CurrentVolOffID(2,copy); if(vid) {path.Prepend("-");path.Prepend(gMC->VolName(vid));} + vid=gMC->CurrentVolOffID(3,copy); if(vid) {path.Prepend("-");path.Prepend(gMC->VolName(vid));} + + Printf("Step %i: %s (%i) %s %s m=%.6f GeV q=%.1f dEdX=%.4f",iStepN,sParticle,gMC->TrackPid(),flag.Data(),path.Data(),gMC->TrackMass(),gMC->TrackCharge(),gMC->Edep()*1e9); + + Printf("Step %i: tid=%i flags alive=%i disap=%i enter=%i exit=%i inside=%i out=%i stop=%i new=%i", + iStepN, gAlice->GetMCApp()->GetCurrentTrackNumber(), + gMC->IsTrackAlive(), gMC->IsTrackDisappeared(),gMC->IsTrackEntering(), gMC->IsTrackExiting(), + gMC->IsTrackInside(),gMC->IsTrackOut(), gMC->IsTrackStop(), gMC->IsNewTrack()); + + Float_t a,z,den,rad,abs; a=z=den=rad=abs=-1; + Int_t mid=gMC->CurrentMaterial(a,z,den,rad,abs); + Printf("Step %i: id=%i a=%7.2f z=%7.2f den=%9.4f rad=%9.2f abs=%9.2f\n\n",iStepN,mid,a,z,den,rad,abs); + iStepN++; +}//StepHistory() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void AliHMPIDv1::StepManager() +{ +// Full Step Manager. +// Arguments: none +// Returns: none +// StepHistory(); return; //uncomment to print tracks history +// StepCount(); return; //uncomment to count photons + + Int_t copy; //volume copy aka node + +//Treat photons + 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 HMPID-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; AliHMPIDParam::Instance()->Mars2Lors(copy,x,xl,yl); //take LORS position + new((*fHits)[fNhits++])AliHMPIDHit(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 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 HMPID-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;AliHMPIDParam::Instance()->Mars2Lors(copy,out,xl,yl); //take LORS position + new((*fHits)[fNhits++])AliHMPIDHit(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/HMPID/AliHMPIDv1.h b/HMPID/AliHMPIDv1.h new file mode 100644 index 00000000000..33a8cc419e4 --- /dev/null +++ b/HMPID/AliHMPIDv1.h @@ -0,0 +1,42 @@ +#ifndef AliHMPIDv1_h +#define AliHMPIDv1_h + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +#include "AliHMPID.h" //base class +#include "AliHMPIDDigitizer.h" //CreateDigitizer() + +class AliHMPIDv1 : public AliHMPID //TObject-TNamed-AliModule-AliDetector-AliHMPID-AliHMPIDv0 +{ +public: + AliHMPIDv1() :AliHMPID( ),fIdRad(-1),fIdWin(-1),fIdProxGap(-1),fIdAmpGap(-1),fIdPc(-1),fIdAnod(-1),fIdCath(-1),fIdColl(-1) {;} //default ctor + AliHMPIDv1(const char *name, const char *title):AliHMPID(name,title),fIdRad(-1),fIdWin(-1),fIdProxGap(-1),fIdAmpGap(-1),fIdPc(-1),fIdAnod(-1),fIdCath(-1),fIdColl(-1) {;} //named ctor + virtual ~AliHMPIDv1() {;} //dtor +//framework part++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 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 AliHMPIDDigitizer(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 + 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 + Int_t fIdRad,fIdWin,fIdProxGap,fIdAmpGap,fIdPc,fIdAnod,fIdCath,fIdColl; //! volumes ID's used in StepManager() and Count() + ClassDef(AliHMPIDv1,2) //HMPID full version for simulation +}; + +#endif diff --git a/HMPID/Align/Data/Run0_9999999_v0_s0.root b/HMPID/Align/Data/Run0_9999999_v0_s0.root new file mode 100644 index 0000000000000000000000000000000000000000..1436080556d10836c7d38a42961ab14e3c6f9735 GIT binary patch literal 2060 zcmbtVYc!kb7XC!UEj^Y(yizs1Ei;_}QOnbg$&X4(bF7vLn*WT-W*WT~5*R$7tXjCd4 z0Q$%P0E7d8iZTEwSAj7JGzHLD&_4o58vsDhfLAG={^5fg;uZ>!2uwVNh`|1=nC0>p1tcX1cdc>|z@Q3Q*6!;+N!>a3X83q&8XmV6rQ2>*zmr zM6M0m-#^oYe?I=?=K_Cqu0ZZn#}J6A@;H24Vf-3RV`FO4YO1U+-J4$)R>I5Jz&*IS zD-9u*NInv+f-KJ|2rNEWzx!$WH9qnxAM1@nbnko@Av#lCvNf^eTa$CXY1?m-miMlC zWvgtCu~E;#@r}*d{m14!Z3~YE^{;65+{hNTT-Nz4j2^I0G(~F=%SRIALUl;a#c>%I zvOxvHl}>q)6X@`hbXo){HiG6!iKJ>`sf^H=i^efzN_0dx=o084F*;CSNEIZegWyg5 zoS^Nv&ph5GZPtSiRpox>>}x@tStm*$`fI56pjQ;&NaElrZ0ZG|XY{OOwzp!rRH5-#U`twyq2sYFTXZu0x_S z+eUC^Y5_)LwUK*q$;RDnE6|yGYG@a9D6VxHkJVo!49|xQi=stIy)4(w159cEYlCOn z{JZy_t@_%*m-BGG*!Z>}66e0z$gm0JWuBO3ix)Ej<}fzhNhEaLDe`o7`rY-C2e*tG!(lL>CIEeY93AnqR`)1WGyG@-RL%6f&^Bup}1e> zKL%b<7dbunmRqy2L*0ksym|gB5kqRX5gm49ZO!<5|(QeGJCLyjjS5e^I(Y#&kt#8NN9G7g}@O^xZNz>}I`d?*_KiD9~`2 zwZBx*h?F|N5Mtn3QHyFc10rLcxW10Bjp`GpZY0HNY-#T|VRNV>*>uKP#6nE#9{9_$ zam3!rBF#*$*`4jx(%~}koo6cd(LS%zw}XqOhcX)>lbreyo$@UE0Z8IW!4D{}nMN2B zqs|xGPT*Vja2Hcet872b9UI+o+|_U-?TZ5mH~Eqey6Cf0lkvCFW;wa=kK83{!j+qS zCbzJf6OX?-0k;fVq4g)W)OKp$Qc)VB7V+LMEmyID2CkXp;_gQc<^^vTV4;K-yJTy}p64hTj?`GVaoK1Q_p literal 0 HcmV?d00001 diff --git a/HMPID/HMPIDAlign.C b/HMPID/HMPIDAlign.C new file mode 100644 index 00000000000..e8e1897041d --- /dev/null +++ b/HMPID/HMPIDAlign.C @@ -0,0 +1,28 @@ +void RichAlign(Float_t sigmaTrans=0.1, Float_t sigmaRot=0.001) +{ + Float_t dX, dY, dZ; Float_t dPsi, dTheta, dPhi; //displacements + + TClonesArray *pCA = new TClonesArray("AliAlignObjMatrix",10000); + + TRandom *pRnd = new TRandom(4357); + + AliAlignObjMatrix o; + + Int_t idHMPID = AliAlignObj::kHMPID; + for (Int_t iCh = 0; iCh < 7; iCh++) { + dX = pRnd->Gaus(0,sigmaTrans); dY = pRnd->Gaus(0,sigmaTrans); dZ = pRnd->Gaus(0,sigmaTrans); + dPsi = pRnd->Gaus(0,sigmaRot); dTheta = pRnd->Gaus(0,sigmaRot); dPhi = pRnd->Gaus(0,sigmaRot); + new((*pCA)[iCh]) AliAlignObjMatrix(AliAlignObj::GetVolPath(idHMPID,iCh), AliAlignObj::LayerToVolUID(idHMPID,iCh),dX,dY,dZ,dPsi,dTheta,dPhi); + } + + pCA->Print(); + + AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT"); + + AliCDBMetaData *pMeta= new AliCDBMetaData(); + pMeta->SetResponsible("HMPID Expert"); + pMeta->SetComment("Alignment objects for ideal geometry, i.e. applying them to TGeo has to leave geometry unchanged"); + AliCDBId id("HMPID/Align/Data",0,0); //you have to specify the run validity, although in the case of saving ideal objects makes not much sense + AliCDBManager::Instance()->Put(pCA,id,pMeta); + pCA->Delete(); +} diff --git a/HMPID/HMPIDAna.C b/HMPID/HMPIDAna.C new file mode 100644 index 00000000000..f4ca4ce0bb4 --- /dev/null +++ b/HMPID/HMPIDAna.C @@ -0,0 +1,68 @@ +//This script is a skeleton for HMPID analisys. It consequently reads events in a givent set of directories and provides +//resulting RANA.root file in home directory which contains all the requested hists. +#if !defined( __CINT__) || defined(__MAKECINT__) +#include +#include +#include +#include +#include +#include +#endif + + +TH2F *pMassLen2; + +void HistBook() +{ + pMassLen2=new TH2F("masslen","Particle mass versus track length;cm;GeV",200,0,600,200,0,1.2); +} +//__________________________________________________________________________________________________ +void HistFill(AliESDtrack *pTrack) +{ + pMassLen2->Fill(pTrack->GetIntegratedLength(),pTrack->GetMass()); + +} +//__________________________________________________________________________________________________ +void HistOut() +{ + TCanvas *pC=new TCanvas("HMPID analisys"); + pMassLen2->Draw(); + + TFile outFile("~/RANA.root","RECREATE"); pC->Write(); outFile.Close(); +} +//__________________________________________________________________________________________________ +void Analyse(char *sDirName) +{ +//Analyse info from single directory + ::Info("","Tring to open from %s",sDirName); + TFile *pFile=TFile::Open(Form("%s/AliESDs.root",sDirName));if(!pFile || !pFile->IsOpen()) return;//open AliESDs.root + TTree* pTree = (TTree*) pFile->Get("esdTree"); if(!pTree) return;//get ESD tree + + AliESD *pESD=new AliESD; pTree->SetBranchAddress("ESD", &pESD); + + Int_t iNevents=pTree->GetEntries(); //how many events in this given directory + ::Info("","have %i events",iNevents); + for(Int_t iEventN=0;iEventNGetEvent(iEventN); + Int_t iNtracks=pESD->GetNumberOfTracks(); + for(Int_t iTrackN=0;iTrackNGetTrack(iTrackN)); + }//ESD tracks loop + }//ESD events loop + + delete pESD; pFile->Close();//close AliESDs.root +} +//__________________________________________________________________________________________________ +void RichAna(Int_t iDirFirst=1,Int_t iDirLast=4) +{ + gBenchmark->Start("HMPIDanalisys"); + + HistBook(); + + for(Int_t iDirN=iDirFirst;iDirN<=iDirLast;iDirN++) Analyse(Form("Ev%04i",iDirN)); //analise for single directory + + HistOut(); + + gBenchmark->Stop("HMPIDanalisys"); + gBenchmark->Show("HMPIDanalisys"); +} diff --git a/HMPID/HMPIDConfig.C b/HMPID/HMPIDConfig.C new file mode 100644 index 00000000000..e4bfa40f6cb --- /dev/null +++ b/HMPID/HMPIDConfig.C @@ -0,0 +1,620 @@ +#include + +class RichConfig : public TGMainFrame +{ +RQ_OBJECT() +public: + RichConfig(const char*sFileName); + ~RichConfig() {Info("ctor","");Cleanup();} + + enum EVersOpts {kNo=101,kVer0,kVer1,kVer2,kTest, kDeclust=301,kSagita,kFeedback,kSecRad,kQe0=400,kQeNorm,kOptics}; + enum EGenTypes {kGunZ=1,kGun1,kGun7,kBox,kHijing,kHijingPara,kPythia,kRichLib,kNotUsed=999}; + + enum EDetectors {kPIPE=1,kITS,kTPC,kTRD,kTOF,kFRAME,kMAG,kCRT,kHALL,kPHOS,kSTART,kFMD,kABSO,kPMD,kDIPO,kEMCAL,kVZERO,kMUON,kZDC,kSHILD}; + enum EProcesses {kDCAY=1,kPAIR,kCOMP,kPHOT,kPFIS,kDRAY,kANNI,kBREM,kMUNU,kCKOV,kHADR,kLOSS,kMULS,kRAYL,kALL}; + 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));} + + void GuiRich (TGHorizontalFrame *pMainF); void WriteRich (FILE *pF); void RichSlot (Int_t ver); + void GuiPhys (TGHorizontalFrame *pMainF); void WritePhys (FILE *pF); void PhysAddSlot(Int_t id); void PhysRemSlot(Int_t id); + void GuiGen (TGCompositeFrame *pMainF); void WriteGen (FILE *pF); void GenAddSlot (Int_t id); void GenRemSlot (Int_t id); + void GuiDet (TGHorizontalFrame *pMainF); void WriteDet (FILE *pF); void DetAddSlot (Int_t id); void DetRemSlot (Int_t id); + void GuiBatch(TGHorizontalFrame *pMainF); void WriteBatch( ); void SlotBatch (Int_t id); + + void WriteConfig(); + void ExitSlot(); + + TGButtonGroup *fVerBG,*fOptBG,*fQeBG; //Rich widgets + TGButtonGroup *fMagBG; //mag field widgets + TGButton *fDecayerB; //external decayer widgets + + TGComboBox *fGenPidCO,*fGenPminCO,*fGenPmaxCO,*fGenChamCO,*fGenNprimCO; //generator widgets combos + TGCompositeFrame *fGenF; //generator widgets frames + TGButtonGroup *fGenBG; //generator widgets + + TGButtonGroup *fDetBG,*fProcBG; //detectors and processes widgets + TGButtonGroup *fSimBG,*fSDigBG,*fDigBG,*fRawBG,*fClusBG,*fRecoBG; //batch control widgets + + char *fFileName; +};//class RichConfig +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +RichConfig::RichConfig(const char *sFileName):TGMainFrame(gClient->GetRoot(),700,400) +{ + fFileName=sFileName; + + AddFrame(pMainF=new TGHorizontalFrame(this,100,200)); //main horizontal frame + + GuiRich (pMainF); + GuiGen (pMainF); + GuiDet (pMainF); + GuiPhys (pMainF); + GuiBatch(pMainF); + +//File + AddFrame(pFileHF=new TGHorizontalFrame(this,100,200)); + pFileHF->AddFrame(pCrtTB=new TGTextButton(pFileHF,"Create")); + pCrtTB->Connect("Clicked()","RichConfig",this,"ExitSlot()"); + pFileHF->AddFrame(new TGLabel(pFileHF,Form(" config file as %s",fFileName))); + + MapSubwindows(); + Resize(GetDefaultSize()); + SetWindowName("Create AliROOT scripts"); + MapWindow(); +}//ctor +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::GuiRich(TGHorizontalFrame *pMainHF) +{ + pMainHF->AddFrame(pLeftVF=new TGVerticalFrame(pMainHF,100,200)); + pLeftVF->AddFrame(pRichGF=new TGGroupFrame(pLeftVF,"HMPID")); + pRichGF->AddFrame(fVerBG=new TGButtonGroup(pRichGF,"")); fVerBG->Connect("Pressed(Int_t)" ,"RichConfig",this,"RichVerSlot(Int_t)"); + new TGRadioButton(fVerBG, "No" ,kNo )); + new TGRadioButton(fVerBG, "ver0" ,kVer0 )); + new TGRadioButton(fVerBG, "ver1" ,kVer1 )); fVerBG->SetButton(kVer1); + new TGRadioButton(fVerBG, "ver2" ,kVer2 )); + pRichGF->AddFrame(fOptBG=new TGButtonGroup(pRichGF,"")); fOptBG->Connect("Pressed(Int_t)" ,"RichConfig",this,"RichVerSlot(Int_t)"); + new TGCheckButton(fOptBG,"Test beam position?" ,kTest); + new TGCheckButton(fOptBG,"Second radiator?" ,kSecRad); + new TGCheckButton(fOptBG,"Decluster?" ,kDeclust); fOptBG->SetButton(kDeclust); + new TGCheckButton(fOptBG,"Wire sagita?" ,kSagita); fOptBG->SetButton(kSagita); + new TGCheckButton(fOptBG,"Feedbacks?" ,kFeedback); fOptBG->SetButton(kFeedback); + new TGCheckButton(fOptBG,"Plot optics?" ,kOptics); + pRichGF->AddFrame(fQeBG=new TGButtonGroup(pRichGF,"")); + new TGRadioButton(fQeBG,"QE=0" ,kQe0); + new TGRadioButton(fQeBG,"QE normal" ,kQeNorm); fQeBG->SetButton(kQeNorm); + pLeftVF->AddFrame(fDecayerB=new TGCheckButton(pLeftVF,"Puthia decayer On/Off")); fDecayerB->SetState(kButtonDown); + pLeftVF->AddFrame(fMagBG=new TGButtonGroup(pLeftVF,"Mag field")); + new TGRadioButton(fMagBG, "0.5 T" ,kFld5 )); + new TGRadioButton(fMagBG, "0.4 T" ,kFld4 )); + new TGRadioButton(fMagBG, "0.2 T" ,kFld2 )); fMagBG->SetButton(kFld2); + new TGRadioButton(fMagBG, "0 T" ,kFld0 )); + new TGRadioButton(fMagBG, "-0.2 T" ,kFld_2 )); + new TGRadioButton(fMagBG, "-0.4 T" ,kFld_4 )); + new TGRadioButton(fMagBG, "-0.5 T" ,kFld_5 )); +}//Rich() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::RichVerSlot(Int_t ver) +{ + if(ver==kTest) {fMagBG->SetButton(kFld0); fGenBG->SetButton(kGunZ); } +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::WriteRich(FILE *pF) +{ + if(!fVerBG->GetButton(kNo)->GetState()){ + TString title; + if( fOptBG->GetButton(kSecRad)->GetState()) title+=" Radiator2 "; + if(!fOptBG->GetButton(kSagita)->GetState()) fprintf(pF," AliHMPIDParam::fgIsWireSagita=kFALSE;\n"); + if( fOptBG->GetButton(kTest) ->GetState()) title+=" TestBeam "; + if( fOptBG->GetButton(kOptics)->GetState()) title+=" ShowOptics "; + if(title.Length()==0) title="Default"; + + if (fVerBG->GetButton(kVer0)->GetState()) fprintf(pF," new AliHMPIDv0(\"Gel %s\");\n\n",title.Data()); + else if(fVerBG->GetButton(kVer1)->GetState()) fprintf(pF," new AliHMPIDv1(\"HMPID\",\"%s\");\n\n",title.Data()); + else if(fVerBG->GetButton(kVer2)->GetState()) fprintf(pF," new AliHMPIDv2(\"Tic %s\");\n\n",title.Data()); + } +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::GuiPhys(TGHorizontalFrame *pMainHF) +{ + pMainHF->AddFrame(fProcBG=new TGButtonGroup(pMainHF,"Procs")); + fProcBG->Connect("Pressed(Int_t)" ,"RichConfig",this,"PhysAddSlot(Int_t)"); + fProcBG->Connect("Released(Int_t)","RichConfig",this,"PhysRemSlot(Int_t)"); + new TGCheckButton(fProcBG,"ALL ON/OFF" ,kALL)) ; + new TGCheckButton(fProcBG,"DCAY Decay" ,kDCAY)); fProcBG->SetButton(kDCAY); + new TGCheckButton(fProcBG,"PAIR Pair production" ,kPAIR)); fProcBG->SetButton(kPAIR); + new TGCheckButton(fProcBG,"COMP Compton" ,kCOMP)); fProcBG->SetButton(kCOMP); + new TGCheckButton(fProcBG,"PHOT" ,kPHOT)); fProcBG->SetButton(kPHOT); + new TGCheckButton(fProcBG,"PFIS Photofission" ,kPFIS)); + new TGCheckButton(fProcBG,"DRAY Delta electrons" ,kDRAY)); + new TGCheckButton(fProcBG,"ANNI Annihilation" ,kANNI)); fProcBG->SetButton(kANNI); + new TGCheckButton(fProcBG,"BREM Bremstraslung" ,kBREM)); fProcBG->SetButton(kBREM); + new TGCheckButton(fProcBG,"MUNU Muon-Nuclear" ,kMUNU)); fProcBG->SetButton(kMUNU); + new TGCheckButton(fProcBG,"CKOV Cerenkovs" ,kCKOV)); fProcBG->SetButton(kCKOV); + new TGCheckButton(fProcBG,"HADR Hadronic interactions " ,kHADR)); fProcBG->SetButton(kHADR); + new TGCheckButton(fProcBG,"LOSS Energy losses" ,kLOSS)); fProcBG->SetButton(kLOSS); + new TGCheckButton(fProcBG,"MULS Multiple scattering" ,kMULS)); fProcBG->SetButton(kMULS); + new TGCheckButton(fProcBG,"RAYL Rayleigh scattering" ,kRAYL)); fProcBG->SetButton(kRAYL); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::PhysAddSlot(Int_t id) +{//slot is invoked when any of physics check button is pressed + if(id==kALL) //if the pressed check button is kALL then switch on all the buttons + for(int i=1;i<=fProcBG->GetCount();i++) + fProcBG->SetButton(i,kButtonDown); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::PhysRemSlot(Int_t id) +{//slot is invoked when any of physics check button is released + if(id==kALL) //if the released check button is kALL then switch off all the buttons + for(int i=1;i<=fProcBG->GetCount();i++) + fProcBG->SetButton(i,kButtonUp); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::WritePhys(FILE *pF) +{ + if(fProcBG->GetButton(kDCAY)->GetState()) fprintf(pF," gMC->SetProcess(\"DCAY\",1); ");else fprintf(pF," gMC->SetProcess(\"DCAY\",0); "); + if(fProcBG->GetButton(kPAIR)->GetState()) fprintf(pF," gMC->SetProcess(\"PAIR\",1); ");else fprintf(pF," gMC->SetProcess(\"PAIR\",0); "); + if(fProcBG->GetButton(kCOMP)->GetState()) fprintf(pF," gMC->SetProcess(\"COMP\",1);\n");else fprintf(pF," gMC->SetProcess(\"COMP\",0);\n"); + if(fProcBG->GetButton(kPHOT)->GetState()) fprintf(pF," gMC->SetProcess(\"PHOT\",1); ");else fprintf(pF," gMC->SetProcess(\"PHOT\",0); "); + if(fProcBG->GetButton(kPFIS)->GetState()) fprintf(pF," gMC->SetProcess(\"PFIS\",1); ");else fprintf(pF," gMC->SetProcess(\"PFIS\",0); "); + if(fProcBG->GetButton(kDRAY)->GetState()) fprintf(pF," gMC->SetProcess(\"DRAY\",1);\n");else fprintf(pF," gMC->SetProcess(\"DRAY\",0);\n"); + if(fProcBG->GetButton(kANNI)->GetState()) fprintf(pF," gMC->SetProcess(\"ANNI\",1); ");else fprintf(pF," gMC->SetProcess(\"ANNI\",0); "); + if(fProcBG->GetButton(kBREM)->GetState()) fprintf(pF," gMC->SetProcess(\"BREM\",1); ");else fprintf(pF," gMC->SetProcess(\"BREM\",0); "); + if(fProcBG->GetButton(kMUNU)->GetState()) fprintf(pF," gMC->SetProcess(\"MUNU\",1);\n");else fprintf(pF," gMC->SetProcess(\"MUNU\",0);\n"); + if(fProcBG->GetButton(kCKOV)->GetState()) fprintf(pF," gMC->SetProcess(\"CKOV\",1); ");else fprintf(pF," gMC->SetProcess(\"CKOV\",0); "); + if(fProcBG->GetButton(kHADR)->GetState()) fprintf(pF," gMC->SetProcess(\"HADR\",1); ");else fprintf(pF," gMC->SetProcess(\"HADR\",0); "); + if(fProcBG->GetButton(kLOSS)->GetState()) fprintf(pF," gMC->SetProcess(\"LOSS\",2);\n");else fprintf(pF," gMC->SetProcess(\"LOSS\",0);\n"); + if(fProcBG->GetButton(kMULS)->GetState()) fprintf(pF," gMC->SetProcess(\"MULS\",1); ");else fprintf(pF," gMC->SetProcess(\"MULS\",0); "); + if(fProcBG->GetButton(kRAYL)->GetState()) fprintf(pF," gMC->SetProcess(\"RAYL\",1);\n");else fprintf(pF," gMC->SetProcess(\"RAYL\",0);\n"); + + fprintf(pF,"\n"); + fprintf(pF," gMC->SetCut(\"CUTGAM\",0.001); "); fprintf(pF," gMC->SetCut(\"CUTELE\",0.001); "); fprintf(pF," gMC->SetCut(\"CUTNEU\",0.001);\n"); + fprintf(pF," gMC->SetCut(\"CUTHAD\",0.001); "); fprintf(pF," gMC->SetCut(\"CUTMUO\",0.001); "); fprintf(pF," gMC->SetCut(\"BCUTE\" ,0.001);\n"); + fprintf(pF," gMC->SetCut(\"BCUTM\" ,0.001); "); fprintf(pF," gMC->SetCut(\"DCUTE\" ,0.001); "); fprintf(pF," gMC->SetCut(\"DCUTM\" ,0.001);\n"); + fprintf(pF," gMC->SetCut(\"PPCUTM\",0.001); "); fprintf(pF," gMC->SetCut(\"TOFMAX\",1e10);\n\n"); +}//WritePhys() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::GuiGen(TGCompositeFrame *pMainF) +{//generator configurator implemented as group of radio buttons + pMainF->AddFrame(fGenF=new TGVerticalFrame(pMainF));//add generator vertical frame to horizontal main frame + fGenF->AddFrame(fGenBG=new TGButtonGroup(fGenF,"Gene"));//add type button group to vertical generator frame + fGenBG->Connect("Pressed(Int_t)","RichConfig",this,"GenAddSlot(Int_t)"); fGenBG->Connect("Released(Int_t)","RichConfig",this,"GenRemSlot(Int_t)"); + new TGCheckButton(fGenBG,"gun along z" ,kGunZ); + new TGCheckButton(fGenBG,"gun to 1 chamber" ,kGun1); + new TGCheckButton(fGenBG,"gun to 7 chambers" ,kGun7); + new TGCheckButton(fGenBG,"box HMPID phase space" ,kBox ); + new TGCheckButton(fGenBG,"HIJING" ,kHijing); + new TGCheckButton(fGenBG,"HIJING para" ,kHijingPara); + new TGCheckButton(fGenBG,"Pythia" ,kPythia); + new TGCheckButton(fGenBG,"HMPID lib" ,kRichLib); +//N prims for box and Hijing para + fGenF->AddFrame(fGenNprimCO=new TGComboBox(fGenF,100)); //add N prims combo to generator vertical frame + fGenNprimCO->AddEntry("not used" ,kNotUsed); + fGenNprimCO->AddEntry("N prim=1" ,1); + fGenNprimCO->AddEntry("N prim=2" ,2); + fGenNprimCO->AddEntry("N prim=5" ,5); + fGenNprimCO->AddEntry("N prim=100" ,100); + fGenNprimCO->AddEntry("N prim=500" ,500); + fGenNprimCO->AddEntry("N prim=1000" ,1000); + fGenNprimCO->AddEntry("N prim=10000",10000); + fGenNprimCO->AddEntry("N prim=80000",80000); fGenNprimCO->Resize(160,20); fGenNprimCO->Select(kNotUsed); +//PID + fGenF->AddFrame(fGenPidCO=new TGComboBox(fGenF,100)); //add pid combo to generator vertical frame + fGenPidCO->AddEntry("not used" ,kNotUsed); + fGenPidCO->AddEntry("electron" ,kElectron); + fGenPidCO->AddEntry("positron" ,kPositron); + fGenPidCO->AddEntry("pion +" ,kPiPlus); + fGenPidCO->AddEntry("pion -" ,kPiMinus); + fGenPidCO->AddEntry("kaon +" ,kKPlus); + fGenPidCO->AddEntry("kaon -" ,kKMinus); + fGenPidCO->AddEntry("kaon 0" ,kK0Short); + fGenPidCO->AddEntry("proton" ,kProton); + fGenPidCO->AddEntry("antiproton" ,kProtonBar); + fGenPidCO->AddEntry("lambda" ,kLambda0); + fGenPidCO->AddEntry("antilambda" ,kLambda0Bar); fGenPidCO->Resize(160,20); fGenPidCO->Select(kNotUsed); +//Pmin + fGenF->AddFrame(fGenPminCO=new TGComboBox(fGenF,100)); //add Pmin combo to generator vertical frame + fGenPminCO->AddEntry("not used",kNotUsed); + for(Int_t i=5;i<=295;i+=5) fGenPminCO->AddEntry(Form("Pmin=%3.1f GeV",0.1*i), i); fGenPminCO->Resize(160,20); fGenPminCO->Select(kNotUsed); +//Pmax + fGenF->AddFrame(fGenPmaxCO=new TGComboBox(fGenF,100)); //add Pmax combo to generator vertical frame + fGenPmaxCO->AddEntry("not used",kNotUsed); + for(Int_t i=10;i<=295;i+=5) fGenPmaxCO->AddEntry(Form("Pmax=%3.1f GeV",0.1*i), i); fGenPmaxCO->Resize(160,20); fGenPmaxCO->Select(kNotUsed); +//Chamber number + fGenF->AddFrame(fGenChamCO=new TGComboBox(fGenF,100)); //add chamber number combo to generator vertical frame + fGenChamCO->AddEntry("not used",kNotUsed); + for(int i=1;i<=7;i++) fGenChamCO->AddEntry(Form("Chamber %i",i),i); fGenChamCO->Resize(160,20); fGenChamCO->Select(kNotUsed); +}//GuiGen() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::GenAddSlot(Int_t id) +{//is invoked when any of generator check button is pressed + if(id==kGunZ){ + fGenBG->GetButton(kGun1)->SetEnabled(kFALSE); fGenF->HideFrame(fGenNprimCO); fGenF->HideFrame(fGenPmaxCO); + fGenBG->GetButton(kGun7)->SetEnabled(kFALSE); + fGenBG->GetButton(kBox )->SetEnabled(kFALSE); fGenPidCO->Select(kProton); fGenPminCO->Select(25); + } + if(id==kGun1){ + fGenBG->GetButton(kGunZ)->SetEnabled(kFALSE); fGenF->HideFrame(fGenNprimCO); fGenF->HideFrame(fGenPmaxCO); + fGenBG->GetButton(kGun7)->SetEnabled(kFALSE); fGenPidCO->Select(kProton); fGenPminCO->Select(25); fGenChamCO->Select(4); + fGenBG->GetButton(kBox )->SetEnabled(kFALSE); + } + if(id==kGun7){ + fGenBG->GetButton(kGunZ)->SetEnabled(kFALSE); fGenF->HideFrame(fGenNprimCO); + fGenBG->GetButton(kGun1)->SetEnabled(kFALSE); fGenPidCO->Select(kProton); + fGenBG->GetButton(kBox )->SetEnabled(kFALSE); fGenF->HideFrame(fGenPmaxCO); fGenPminCO->Select(25); + fGenF->HideFrame(fGenChamCO); + } + if(id==kBox){ + fGenBG->GetButton(kGunZ)->SetEnabled(kFALSE); fGenNprimCO->Select(500); + fGenBG->GetButton(kGun1)->SetEnabled(kFALSE); fGenPidCO ->Select(kProton); + fGenBG->GetButton(kGun7)->SetEnabled(kFALSE); fGenPminCO ->Select(15); fGenPmaxCO->Select(15); + } + if(id==kHijing){ + fGenBG->GetButton(kHijing)->ChangeBackground(0xff0000); + fGenBG->GetButton(kHijingPara)->SetEnabled(kFALSE); + fGenBG->GetButton(kPythia)->SetEnabled(kFALSE); + } + if(id==kHijingPara){ + fGenBG->GetButton(kHijing)->SetEnabled(kFALSE); fGenNprimCO->Select(500); + fGenBG->GetButton(kPythia)->SetEnabled(kFALSE); + } + if(id==kPythia){ + fGenBG->GetButton(kHijing)->SetEnabled(kFALSE); + fGenBG->GetButton(kHijingPara)->SetEnabled(kFALSE); + } +}//GenAddSlot() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::GenRemSlot(Int_t id) +{//is invoked when any of generator check button is released + if(id==kGunZ){ + fGenBG->GetButton(kGun1)->SetEnabled(); fGenF->ShowFrame(fGenNprimCO); + fGenBG->GetButton(kGun7)->SetEnabled(); fGenPidCO ->Select(kNotUsed); + fGenBG->GetButton(kBox )->SetEnabled(); fGenF->ShowFrame(fGenPmaxCO); fGenPminCO ->Select(kNotUsed); + } + if(id==kGun1){ + fGenBG->GetButton(kGunZ)->SetEnabled(); fGenF->ShowFrame(fGenNprimCO); + fGenBG->GetButton(kGun7)->SetEnabled(); fGenPidCO ->Select(kNotUsed); + fGenBG->GetButton(kBox )->SetEnabled(); fGenF->ShowFrame(fGenPmaxCO); fGenPminCO ->Select(kNotUsed); + } + if(id==kGun7){ + fGenBG->GetButton(kGunZ)->SetEnabled(); fGenF->ShowFrame(fGenNprimCO); + fGenBG->GetButton(kGun1)->SetEnabled(); fGenPidCO ->Select(kNotUsed); + fGenBG->GetButton(kBox )->SetEnabled(); fGenF->ShowFrame(fGenPmaxCO); fGenPminCO ->Select(kNotUsed); + fGenF->ShowFrame(fGenChamCO); + } + if(id==kBox){ + fGenBG->GetButton(kGunZ)->SetEnabled(); fGenNprimCO->Select(kNotUsed); + fGenBG->GetButton(kGun1)->SetEnabled(); fGenPidCO ->Select(kNotUsed); + fGenBG->GetButton(kGun7)->SetEnabled(); fGenPminCO ->Select(kNotUsed); fGenPmaxCO->Select(kNotUsed); + fGenChamCO ->Select(kNotUsed); + } + if(id==kHijing){ + fGenBG->GetButton(kHijing)->ChangeBackground(0xbebebe); + fGenBG->GetButton(kHijingPara)->SetEnabled(); + fGenBG->GetButton(kPythia)->SetEnabled(); + } + if(id==kHijingPara){ + fGenBG->GetButton(kHijing)->SetEnabled(); + fGenBG->GetButton(kPythia)->SetEnabled(); + } + if(id==kPythia){ + fGenBG->GetButton(kHijing)->SetEnabled(); + fGenBG->GetButton(kHijingPara)->SetEnabled(); + } +}//GenRemSlot() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::WriteGen(FILE *pF) +{ + Int_t pid=fGenPidCO->GetSelected(); + Float_t pmin=0.1*fGenPminCO->GetSelected(); //particle momentum, GeV + Float_t pmax=0.1*fGenPmaxCO->GetSelected(); //particle momentum, GeV + + fprintf(pF," AliGenCocktail *pG=new AliGenCocktail();\n\n"); + + if(fGenBG->GetButton(kGunZ)->GetState()==kButtonDown)//1 particle along Z axis + fprintf(pF," AliGenFixed *pGz=new AliGenFixed(1); pGz->SetPart(%i); pGz->SetMomentum(%.1f); pGz->SetOrigin(0,0,-200); pG->AddGenerator(pGz,\"Gz\",1);\n",pid,p); + + if(fGenBG->GetButton(kGun1)->GetState()==kButtonDown){//1 gun towards 1 HMPID chamber + switch(fGenChamCO->GetSelected()){ + case 1: fprintf(pF," AliGenFixed *pG1=new AliGenFixed(1); pG1->SetPart(%i); pG1->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG1->SetTheta(109.5); pG1->SetPhi(10); pG->AddGenerator(pG1,\"g1\",1);\n"); break; + case 2: fprintf(pF," AliGenFixed *pG2=new AliGenFixed(1); pG2->SetPart(%i); pG2->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG2->SetTheta( 90.0); pG2->SetPhi(10); pG->AddGenerator(pG2,\"g2\",1);\n"); break; + case 3: fprintf(pF," AliGenFixed *pG3=new AliGenFixed(1); pG3->SetPart(%i); pG3->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG3->SetTheta(109.5); pG3->SetPhi(30); pG->AddGenerator(pG3,\"g3\",1);\n"); break; + case 4: fprintf(pF," AliGenFixed *pG4=new AliGenFixed(1); pG4->SetPart(%i); pG4->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG4->SetTheta( 90.0); pG4->SetPhi(30); pG->AddGenerator(pG4,\"g4\",1);\n"); break; + case 5: fprintf(pF," AliGenFixed *pG5=new AliGenFixed(1); pG5->SetPart(%i); pG5->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG5->SetTheta( 70.5); pG5->SetPhi(30); pG->AddGenerator(pG5,\"g5\",1);\n"); break; + case 6: fprintf(pF," AliGenFixed *pG6=new AliGenFixed(1); pG6->SetPart(%i); pG6->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG6->SetTheta( 90.0); pG6->SetPhi(50); pG->AddGenerator(pG6,\"g6\",1);\n"); break; + case 7: fprintf(pF," AliGenFixed *pG7=new AliGenFixed(1); pG7->SetPart(%i); pG7->SetMomentum(%.1f);\n",pid,pmin); + fprintf(pF," pG7->SetTheta( 70.5); pG7->SetPhi(50); pG->AddGenerator(pG7,\"g7\",1);\n"); break; + } + } + + if(fGenBG->GetButton(kGun7)->GetState()==kButtonDown){//7 guns towards 7 HMPID chambers + fprintf(pF," AliGenFixed *pG1=new AliGenFixed(1); pG1->SetPart(%i); pG1->SetMomentum(%.1f);pG1->SetTheta(109.5-3); pG1->SetPhi(10);\n",pid,pmin); + fprintf(pF," pG->AddGenerator(pG1,\"g1\",1);\n"); + fprintf(pF," AliGenFixed *pG2=new AliGenFixed(1); pG2->SetPart(%i); pG2->SetMomentum(%.1f);pG2->SetTheta( 90.0-3); pG2->SetPhi(10);\n",pid,pmin); + fprintf(pF," pG->AddGenerator(pG2,\"g2\",1);\n"); + fprintf(pF," AliGenFixed *pG3=new AliGenFixed(1); pG3->SetPart(%i); pG3->SetMomentum(%.1f);pG3->SetTheta(109.5-3); pG3->SetPhi(30);\n",pid,pmin); + fprintf(pF," pG->AddGenerator(pG3,\"g3\",1);\n"); + fprintf(pF," AliGenFixed *pG4=new AliGenFixed(1); pG4->SetPart(%i); pG4->SetMomentum(%.1f);pG4->SetTheta( 90.0-3); pG4->SetPhi(30);\n",pid,pmin); + fprintf(pF," pG->AddGenerator(pG4,\"g4\",1);\n"); + fprintf(pF," AliGenFixed *pG5=new AliGenFixed(1); pG5->SetPart(%i); pG5->SetMomentum(%.1f);pG5->SetTheta( 70.0-3); pG5->SetPhi(30);\n",pid,pmin); + fprintf(pF," pG->AddGenerator(pG5,\"g5\",1);\n"); + fprintf(pF," AliGenFixed *pG6=new AliGenFixed(1); pG6->SetPart(%i); pG6->SetMomentum(%.1f);pG6->SetTheta( 90.0-3); pG6->SetPhi(50);\n",pid,pmin); + fprintf(pF," pG->AddGenerator(pG6,\"g6\",1);\n"); + fprintf(pF," AliGenFixed *pG7=new AliGenFixed(1); pG7->SetPart(%i); pG7->SetMomentum(%.1f);pG7->SetTheta( 70.0-3); pG7->SetPhi(50);\n",pid,pmin); + fprintf(pF," pG->AddGenerator(pG7,\"g7\",1);\n"); + } + + if(fGenBG->GetButton(kBox)->GetState()==kButtonDown){// box towards HMPID phase space + fprintf(pF," AliGenBox *pB=new AliGenBox(%i); pB->SetPart(%i); pB->SetMomentumRange(%.1f,%.1f);\n",(int)fGenNprimCO->GetSelected(),pid,pmin,pmax); + fprintf(pF," pB->SetThetaRange(65,115); pB->SetPhiRange(5,55); pG->AddGenerator(pB,\"b\",1);\n"); + } + + if(fGenBG->GetButton(kHijing)->GetState()==kButtonDown){//normal HIJING + fprintf(pF," AliGenHijing *pH=new AliGenHijing(-1); pH->SetEnergyCMS(5500); pH->SetReferenceFrame(\"CMS\");\n"); + fprintf(pF," pH->SetProjectile(\"A\", 208, 82); pH->SetTarget(\"A\", 208, 82); pH->SetJetQuenching(0);\n"); + fprintf(pF," pH->SetShadowing(0); pH->KeepFullEvent(); pH->SetSelectAll(0);\n"); + fprintf(pF," pH->SetImpactParameterRange(0, 5); //fermi\n"); + fprintf(pF," pG->AddGenerator(pH,\"h\",1);\n\n"); + } + + if(fGenBG->GetButton(kHijingPara)->GetState()==kButtonDown){//parametrized HIJING + fprintf(pF," AliGenHIJINGpara *pHP=new AliGenHIJINGpara(%i);\n",(int)fGenNprimCO->GetSelected()); + fprintf(pF," pHP->SetMomentumRange(0,999); pHP->SetThetaRange(%f,%f); pHP->SetPhiRange(0,360);\n",Eta2Theta(8),Eta2Theta(-8)); + fprintf(pF," pG->AddGenerator(pHP,\"hp\",1);\n\n"); + } + + if(fGenBG->GetButton(kPythia)->GetState()==kButtonDown){//Pythia + fprintf(pF," AliGenPythia *pP=new AliGenPythia(-1);\n"); + fprintf(pF," pP->SetMomentumRange(0,999); pP->SetPhiRange(20,80); pP->SetThetaRange(75,115);\n"); + fprintf(pF," pP->SetYRange(-12,12); pP->SetPtRange(0,1000); pP->SetStrucFunc(kCTEQ4L);\n"); + fprintf(pF," pP->SetProcess(kPyMb); pP->SetEnergyCMS(14000);\n"); + fprintf(pF," pG->AddGenerator(pP,\"p\",1);\n\n"); + } + fprintf(pF," pG->Init();\n\n"); +}//WriteGenerator() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::GuiDet(TGHorizontalFrame *pMainHF) +{ + pMainHF->AddFrame(fDetBG=new TGButtonGroup(pMainHF,"Dets")); + fDetBG->Connect("Pressed(Int_t)" ,"RichConfig",this,"DetAddSlot(Int_t)"); + fDetBG->Connect("Released(Int_t)","RichConfig",this,"DetRemSlot(Int_t)"); + new TGCheckButton(fDetBG,"PIPE" ,kPIPE)); new TGCheckButton(fDetBG,"ITS" ,kITS)); new TGCheckButton(fDetBG,"TPC" ,kTPC)); + new TGCheckButton(fDetBG,"TRD" ,kTRD)); new TGCheckButton(fDetBG,"TOF" ,kTOF)); new TGCheckButton(fDetBG,"FRAME" ,kFRAME)); + new TGCheckButton(fDetBG,"MAG" ,kMAG)); new TGCheckButton(fDetBG,"CRT" ,kCRT)); new TGCheckButton(fDetBG,"HALL" ,kHALL)); + new TGCheckButton(fDetBG,"PHOS" ,kPHOS)); new TGCheckButton(fDetBG,"START" ,kSTART)); new TGCheckButton(fDetBG,"FMD" ,kFMD)); + new TGCheckButton(fDetBG,"ABSO" ,kABSO)); new TGCheckButton(fDetBG,"PMD" ,kPMD)); new TGCheckButton(fDetBG,"DIPO" ,kDIPO)); + new TGCheckButton(fDetBG,"EMCAL" ,kEMCAL)); new TGCheckButton(fDetBG,"VZERO" ,kVZERO)); new TGCheckButton(fDetBG,"MUON" ,kMUON)); + new TGCheckButton(fDetBG,"ZDC" ,kZDC)); new TGCheckButton(fDetBG,"SHILD" ,kSHILD)); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::DetAddSlot(Int_t id) +{//slot is invoked when any detector check button is pressed + if(id==kTRD || id==kTOF) //TRD and TOF geometries depend on FRAME + fDetBG->SetButton(kFRAME); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::DetRemSlot(Int_t id) +{//slot is invoked when any detector check button is released + if(id==kFRAME){ + fDetBG->SetButton(kTRD,kFALSE); //switch off TRD and TOF when FRAME is switched off by user hence TRD&TOF depend on FRAME + fDetBG->SetButton(kTOF,kFALSE); + } +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::WriteDet(FILE *pF) +{ +//CORE detectors + if(fDetBG->GetButton(kPIPE )->GetState()) fprintf(pF,"\n new AliPIPEv0(\"PIPE\",\"Beam Pipe\");\n"); + if(fDetBG->GetButton(kSHILD)->GetState()) fprintf(pF,"\n new AliSHILv2(\"SHIL\",\"Shielding Version 2\");\n"); + if(fDetBG->GetButton(kITS )->GetState()){ + fprintf(pF,"\n AliITSvPPRasymmFMD *pIts =new AliITSvPPRasymmFMD(\"ITS\",\"ITS PPR detailed version\");\n"); + fprintf(pF," pIts->SetMinorVersion(2); pIts->SetReadDet(kFALSE);\n"); + fprintf(pF," pIts->SetThicknessDet1(200.); pIts->SetThicknessDet2(200.);\n"); + fprintf(pF," pIts->SetThicknessChip1(150.); pIts->SetThicknessChip2(150.);\n"); + fprintf(pF," pIts->SetRails(0); pIts->SetCoolingFluid(1);\n"); + fprintf(pF," pIts->SetEUCLID(0);\n"); + } + if(fDetBG->GetButton(kTPC )->GetState()) fprintf(pF,"\n new AliTPCv2(\"TPC\",\"Default\");\n"); + if(fDetBG->GetButton(kFRAME)->GetState()) fprintf(pF,"\n AliFRAMEv2 *pFrame=new AliFRAMEv2(\"FRAME\",\"Space Frame\"); pFrame->SetHoles(1);\n"); + if(fDetBG->GetButton(kTRD )->GetState()) fprintf(pF,"\n AliTRD *pTrd=new AliTRDv1(\"TRD\",\"TRD slow simulator\");\n"); + if(fDetBG->GetButton(kTOF )->GetState()) fprintf(pF,"\n new AliTOFv4T0(\"TOF\", \"normal TOF\");\n"); +//central detectors behind HMPID + if(fDetBG->GetButton(kMAG )->GetState()) fprintf(pF,"\n new AliMAG(\"MAG\",\"Magnet\");\n"); + if(fDetBG->GetButton(kHALL )->GetState()) fprintf(pF,"\n new AliHALL(\"HALL\",\"Alice Hall\");\n"); +//forward detectors + if(fDetBG->GetButton(kFMD )->GetState()) fprintf(pF,"\n new AliFMDv1(\"FMD\",\"normal FMD\");\n"); + if(fDetBG->GetButton(kABSO )->GetState()) fprintf(pF,"\n new AliABSOv0(\"ABSO\",\"Muon absorber\");\n"); + if(fDetBG->GetButton(kDIPO )->GetState()) fprintf(pF,"\n new AliDIPOv2(\"DIPO\",\"Dipole version 2\");\n"); + if(fDetBG->GetButton(kMUON )->GetState()) fprintf(pF,"\n new AliMUONv1(\"MUON\",\"default\");\n"); + if(fDetBG->GetButton(kPMD )->GetState()) fprintf(pF,"\n new AliPMDv1(\"PMD\",\"normal PMD\");\n"); + if(fDetBG->GetButton(kSTART)->GetState()) fprintf(pF,"\n new AliSTARTv1(\"START\",\"START Detector\");\n"); + if(fDetBG->GetButton(kVZERO)->GetState()) fprintf(pF,"\n new AliVZEROv2(\"VZERO\",\"normal VZERO\");\n"); + if(fDetBG->GetButton(kZDC )->GetState()) fprintf(pF,"\n new AliZDCv2(\"ZDC\",\"normal ZDC\");\n"); +//different phase space detectors + if(fDetBG->GetButton(kPHOS )->GetState()) fprintf(pF,"\n new AliPHOSv1(\"PHOS\",\"IHEP\");\n"); + if(fDetBG->GetButton(kEMCAL)->GetState()) fprintf(pF,"\n new AliEMCALv1(\"EMCAL\",\"G56_2_55_19_104_14\");\n"); + if(fDetBG->GetButton(kCRT )->GetState()) fprintf(pF,"\n new AliCRTv0(\"CRT\",\"normal ACORDE\");\n"); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::GuiBatch(TGHorizontalFrame *pMainF) +{ + TGGroupFrame *pSimF=new TGGroupFrame(pMainF,"Simu"); pMainF->AddFrame(pSimF); + pSimF->AddFrame(fSimBG=new TGButtonGroup(pSimF,"" )); + new TGCheckButton(fSimBG, "Primary" ,kPrim )); fSimBG->SetButton(kPrim); + new TGCheckButton(fSimBG, "Transport" ,kTransport)); fSimBG->SetButton(kTransport); + pSimF->AddFrame (fSDigBG=new TGButtonGroup(pSimF,"" )); + new TGRadioButton(fSDigBG, "No SDigits" ,kNo )); + new TGRadioButton(fSDigBG, "SDigits CORE" ,kAll )); + new TGRadioButton(fSDigBG, "SDigits HMPID" ,kOnly )); fSDigBG->SetButton(kOnly); + pSimF->AddFrame (fDigBG=new TGButtonGroup(pSimF,"" )); + new TGRadioButton(fDigBG, "No Digits" ,kNo )); + new TGRadioButton(fDigBG, "Digits CORE" ,kAll )); + new TGRadioButton(fDigBG, "Digits HMPID" ,kOnly )); fDigBG->SetButton(kOnly); + pSimF->AddFrame(fRawBG=new TGButtonGroup(pSimF,"" )); + new TGRadioButton(fRawBG, "No RAW files" ,kNo )); fRawBG->SetButton(kNo); + new TGRadioButton(fRawBG, "RAW DDL" ,kRawDdl )); + new TGRadioButton(fRawBG, "RAW DATE" ,kRawDate )); + new TGRadioButton(fRawBG, "RAW ROOT" ,kRawRoot )); + + TGCompositeFrame *pRecF=new TGGroupFrame(pMainF,"Reco"); pMainF->AddFrame(pRecF); + pRecF->AddFrame(fClusBG=new TGButtonGroup(pRecF,"" )); + new TGRadioButton(fClusBG, "No Clusters" ,kNo )); + new TGRadioButton(fClusBG, "Clusters CORE" ,kAll )); + new TGRadioButton(fClusBG, "Clusters HMPID" ,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 )); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::SlotBatch(Int_t id) +{//slot is invoked when any button in fRecoBG is pressed + if(id==kTrack){ + fSDigBG->SetButton(kAll); + fDigBG->SetButton(kAll); + fClusBG->SetButton(kAll); + fDetBG->SetButton(kITS); + fDetBG->SetButton(kTPC); + fDetBG->SetButton(kTRD); + } +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +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;} + + fprintf(fp,"void %s(const Int_t iNevents,const Bool_t isDebug,const char *sConfigFileName)\n{\n",sBatchName); + + 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"); + + 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"); + else + fprintf(fp," pSim->SetRunSimulation(kFALSE); //no transport and hits creation\n"); +//sdigits + if (fSDigBG->GetButton(kNo) ->GetState()) fprintf(fp," pSim->SetMakeSDigits(\"\"); //no sdigits created\n"); + else if(fSDigBG->GetButton(kAll) ->GetState()) fprintf(fp," pSim->SetMakeSDigits(\"ITS TPC TRD TOF HMPID\"); //sdigits created for these detectors\n"); + else if(fSDigBG->GetButton(kOnly) ->GetState()) fprintf(fp," pSim->SetMakeSDigits(\"HMPID\"); //sdigits created for HMPID only\n"); +//digits + if (fDigBG->GetButton(kNo) ->GetState()) fprintf(fp," pSim->SetMakeDigits(\"\"); //no digits created\n"); + else if(fDigBG->GetButton(kAll) ->GetState()) fprintf(fp," pSim->SetMakeDigits(\"ITS TPC TRD TOF HMPID\"); //digits created for these detectors\n"); + else if(fDigBG->GetButton(kOnly) ->GetState()) fprintf(fp," pSim->SetMakeDigits(\"HMPID\"); //digits created for HMPID only\n"); +//raw data generation + if (fRawBG->GetButton(kRawDdl)->GetState()) fprintf(fp," pSim->SetWriteRawData(\"ITS TPC TRD TOF HMPID\");//raw data in DDL format for these detectors\n"); + else if(fRawBG->GetButton(kRawDate)->GetState()) fprintf(fp," pSim->SetWriteRawData(\"ITS TPC TRD TOF HMPID\",\".date\");//raw data in DATE format for these detectors\n"); + else if(fRawBG->GetButton(kRawRoot)->GetState()) fprintf(fp," pSim->SetWriteRawData(\"ITS TPC TRD TOF HMPID\",\".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 HMPID\"); //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 HMPID\"); //clusters created for these detectors\n"); + else if(fClusBG->GetButton(kOnly) ->GetState()) fprintf(fp," pRec->SetRunLocalReconstruction(\"HMPID\"); //clusters created for HMPID only\n"); + else if(fClusBG->GetButton(kNo) ->GetState()) fprintf(fp," pRec->SetRunLocalReconstruction(\"\"); //clusters are not created\n"); +//reconstraction section - vertex finder + if (fRecoBG->GetButton(kVertex)->GetState()) fprintf(fp," pRec->SetRunVertexFinder(kTRUE); //run vertex finder\n"); + else fprintf(fp," pRec->SetRunVertexFinder(kFALSE); //do not run vertex finder\n"); +//reconstraction section - tracks finder + if (fRecoBG->GetButton(kTrack) ->GetState()) fprintf(fp," pRec->SetRunTracking(\"ITS TPC TRD TOF HMPID\"); //run tracking for these detectors\n"); + else fprintf(fp," pRec->SetRunTracking(\"\"); //do not run tracking\n"); +//reconstraction section - fill ESD (prob vector creator) + if (fRecoBG->GetButton(kEsd) ->GetState()) fprintf(fp," pRec->SetFillESD(\"ITS TPC TRD TOF HMPID\"); //run fill ESD (prob vect)\n"); + else fprintf(fp," pRec->SetFillESD(\"\"); //do not run fill ESD (prob vect)\n"); + fprintf(fp," pRec->Run();delete pRec;\n\n"); +//benchmarks + fprintf(fp," cout<<\"!!!!!!!!!!!!Info in : Start time: \";time.Print();\n"); + fprintf(fp," cout<<\"!!!!!!!!!!!!Info in : Stop time: \";time.Set(); time.Print();\n"); + fprintf(fp," gBenchmark->Show(\"ALICE\");\n"); + + fprintf(fp," gSystem->Exec(\"play -c 2 ~/my/end.wav\");\n"); + fprintf(fp," gSystem->Exec(\"touch ZZZ______finished_______ZZZ\");\n}\n"); + fclose(fp); +}//WriteBatch() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::ExitSlot() +{ +//slot to be invoked by clik on the Create button + WriteConfig(); + WriteBatch(); + SendCloseMessage(); + gApplication->Terminate(0); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig::WriteConfig() +{ + FILE *pF=fopen(fFileName,"w"); if(!pF){Info("CreateConfigFile","Cannot open output file:%sn",fFileName);return;} + + fprintf(pF,"void Config()\n"); + fprintf(pF,"{\n"); + fprintf(pF,"\n ::Info(\"\\n\\n\\n----------> HMPID private config\",\"Start\");\n"); +//Random + fprintf(pF," gRandom->SetSeed(123456);//put 0 to use system time\n\n"); +//Geant + fprintf(pF," gSystem->Load(\"libgeant321\");\n"); + fprintf(pF," new TGeant3TGeo(\"C++ Interface to Geant3\");\n\n"); +//File + fprintf(pF," AliRunLoader *pAL=AliRunLoader::Open(\"galice.root\",AliConfig::GetDefaultEventFolderName(),\"recreate\");\n"); + fprintf(pF," pAL->SetCompressionLevel(2);\n"); + fprintf(pF," pAL->SetNumberOfEventsPerFile(1000);\n"); + fprintf(pF," gAlice->SetRunLoader(pAL);\n\n"); +//Decayer + if(fDecayerB->GetState()==kButtonDown){ + fprintf(pF," TVirtualMCDecayer *pDecayer=new AliDecayerPythia();\n"); + fprintf(pF," pDecayer->SetForceDecay(kAll);\n"); + fprintf(pF," pDecayer->Init();\n"); + fprintf(pF," gMC->SetExternalDecayer(pDecayer);\n\n"); + } + WritePhys(pF); //physics processes + +//Field + if(fMagBG->GetButton(kFld0)->GetState()) fprintf(pF," gAlice->SetField(0); //no field\n\n"); + else if(fMagBG->GetButton(kFld2)->GetState()) fprintf(pF," gAlice->SetField(new AliMagFMaps(\"Maps\",\"Maps\",2,1,10,0));//0.2 Tesla field\n\n"); + else if(fMagBG->GetButton(kFld4)->GetState()) fprintf(pF," gAlice->SetField(new AliMagFMaps(\"Maps\",\"Maps\",2,1,10,1));//0.4 Tesla field\n\n"); + else if(fMagBG->GetButton(kFld5)->GetState()) fprintf(pF," gAlice->SetField(new AliMagFMaps(\"Maps\",\"Maps\",2,1,10,2));//0.5 Tesla field\n\n"); + else if(fMagBG->GetButton(kFld_2)->GetState()) fprintf(pF," gAlice->SetField(new AliMagFMaps(\"Maps\",\"Maps\",2,-1,10,0));//-0.2 Tesla field\n\n"); + else if(fMagBG->GetButton(kFld_4)->GetState()) fprintf(pF," gAlice->SetField(new AliMagFMaps(\"Maps\",\"Maps\",2,-1,10,1));//-0.4 Tesla field\n\n"); + else if(fMagBG->GetButton(kFld_5)->GetState()) fprintf(pF," gAlice->SetField(new AliMagFMaps(\"Maps\",\"Maps\",2,-1,10,2));//-0.5 Tesla field\n\n"); + + fprintf(pF," pAL->CdGAFile();\n\n"); //???? +//Generator + WriteGen(pF);//generator +//BODY-ALIC + fprintf(pF," new AliBODY(\"BODY\",\"Alice envelop\");\n\n"); +//HMPID + WriteRich(pF); //private HMPID part + WriteDet(pF); //other detectors +//end of Config.C file: + fprintf(pF,"\n ::Info(\"----------> HMPID private config\",\"Stop\\n\\n\\n\");\n"); + fprintf(pF,"}\n"); + fclose(pF); +}//WriteConfig() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichConfig() +{ + new RichConfig("Config.C"); +} diff --git a/HMPID/HMPIDConfig/RefIdxC6F14/Run0_0_v0_s0.root b/HMPID/HMPIDConfig/RefIdxC6F14/Run0_0_v0_s0.root new file mode 100644 index 0000000000000000000000000000000000000000..bc34bea5f30a788384cb64d0bcf8041ca7206e9e GIT binary patch literal 3317 zcmb_fXEa>v8XhfrC&EY&EzyP`dN8B6=t7hk87-JmMhhvTM;W6edUOe*27?$9$6>UP zA$pe}oaj-4xx@K!@4tKRT4%5I?ES9&t@qi_yY};~^?ZIvBnklNRs;Y5Z~%Z|gM@HW z?MVU|35Aq@7Zer%0L@F%E3a{=vLVOKBqV9|DQ=Ur`afN>fODe95{Cy!0PKR9^fds0 z%2LO}%S9dJj`Vf`dHcKgc_2Z~FlQJ@&)8I7>+d@RiE#CB1DU(H>cfK}w{>LXK;{7m zX(wr?Kxrp`X(_++3H|{J0Oh$l5`0L)GDs*S;X)+rX?@p~k3yzX099|XQqiylX!XjH%d%1j;fT&Sp!fM`|m1#1~1UJ7k+-}gy zvQP4Zjx9(^vXb7mN^wJ-W*`j*(+0?>KvjTtJz~R_yWVN!!(Fv0iIslypz0-2e{MBT zTUX^w+1ZtPJ|mj}&o;}Mp_J6vhmzm9%**pe17-|FnXMpqOD-WbsH!oYaQ@-eEg4ga zsBd6rFkJ50euhZELEd$`M5q|yo-%JgEGDHuFhytZ#-6kF9SRK*Ny()vv`TEyRGg7v zp(6bv-FFLzSf5XSu$k%NL5@XQVrNGVO)t8M^y(m|yukyv!|F}4!KQK>g_Xw$I-8Sx zt*L0G4Smz_%OCpO~2(loAXF{tPBm##5J zR^SiV^=gK9`FRw)aW`oQ#xHphp{MyM#5gB za?)nQ{WzW0)YV6=zl|51ABVm7*rS}GxY#WuLvYVr7((OR5a)Xc0H?Av^6*D7SfKn| zVBRi%`UqDfn-(&_*(-$K%LC!*0w+EEQ6zU5(*S0;0bRCJNRBaXqN;0KBLs-~@_tB6 zDeengKm=;Z)_}qDB(U3c2+hiwO2GnG64ZWe^xu-DU)T7Ou3=VQ=vb(?_s)Ez2`3N2 z?C4m&H6KyWf2uiJc4xojvHR0G1-HLsaq|xOKWYbanse0JHv@5fzUjYC(hcOa+?kw) zdaZblPt@HTjwFT=7NVkp>LMRb(*iBy0w1)TK(D0gK6I1rEP6^jZQxX8f_*hU`pf>Y zhqC@O=h+M!WA!O{{Z_2C@Ix+WQuEvIO`Bh&tB~~LySMK(M_UC5PDN#ELfYgNY%FR& zeDv!c+MEjH&CXK~=g!B}kxL&k6jDXw^q8vDSyxxQR#QHQ{p=mKoL{>^f1)9(C6{>T z1c<)zOP|P-LRa5 z7_0>&uIo|K+LhbL5|oTdT{%r3tu!J+=JmTsIc$QHTgiz=w$;lu+Os~!c{iwqm;@D348~ zCO9j@hq{*y58@5mi~)+S=?4#0&F(}v>96G`+`@F~QXQnl#ID5(GRxyX2582rI7HMhI7-T8@81tp)ejZx zZ0`owWYr30(5YNgshLfB4J{TMW;DXa$OtzsX;`1Y!s92sa^$88e)9rlC0=Y=UG=q; z2P+t-?}+EdrNN>_K&qB3>*^RHcIaN6I%F%mIeT6v3 zG))g+c%GvilYb#KoL@C&gPIjWeXzn5He6VHi{D;YU#8Tu8Mv)z>&}8eMtpztHvTP} z1M7FDad%-NZ%(IUpHi{*rUr#_G>&Cv(6LWORcJ9Lx|=z&J8A1MdO%PmYOoKO^QkE4 z(v-RRj#7}4d8V=u*hE%gXPQz9e|Uxh8<%%rC4;4dqi02DHBVbhMtb13@Iq}7Dn83- zqZ2@tuYWDSkWW}gLO8SSz zG5HKfQkmB(E79nOBjNYg4r3n{6{!A7D=;8pXGMlR2c3VwMeR({&c9XF(GKrK|L*3B z*n0@X52e=Y%t$zmuC`tJsv&TQjv5lo+_q&3y1`Jc^_oUNAu@R^K9YZ15hLWAa_s{^ z+$Ysg3=J`T{_>!bX_)M()oM=JYNW%u07N)?VCo)7e;mE(k|uR{@s zI_n!@$+_!>@AC{gRkm;j3@}cy$x)9~PMGwdMGLws{yd>5C==M@ty|;XzuTIdKY{ou z|A0vXQN#JC?Vs9P&w%-SL;Ss(yW23$+S=aNC}F(V9IMEf6;?#JP(4QdjBbOUAQqZ| zHmV5oeO$U9U^Jh5EK73Qwz6+&dT3Qq<3_(y_mjc;WGAYS4=AfY%J{ysfUOQa!1}|3 zwTp_!kF#?r+K?k-B4q|?*#ytqwBy~5Lpd3=S;_`x#j%|~Luz}MIq0s0S;v$y^(7AS zM0AOJ(~Q@>>A#9c^o2}0zJ03RCdsm)tb^Z4loxt}lEoUv)<5N+^Fi5aWvzs8-Y<^r z==nwH2dB7kQT1u)6=?2IuGM9@2LsRqO+6mBQ!FwvpT?z~^(9PuLsbx(iFoL+kUdLX~vf z7_QqR8c>TP)a6hjJj|Y^y=)QNm3>soV#QU+G^v$-!VW!X_381t`)cGZ|3EO;J6f_W z2$7QZz*tddAS6%A=0QbZ@M%9~v^vezc2?yojD5+;f*vHPAk0rC#hzCbC9mh|x-nq`XYYm^1hZ7BY1|z+A9T%7r18#ki_s=qZ zhA@K)6ykxUW(Gr6R7-9Yml|gC-U}boLnbBt%C!u^lYO^6QfjaRd)!0O@G=eVJU-vE zJ+oIhd?b{8KI^qq*qjKpPPkrjIpfH)m#XO04jF8NcmKC1j^pG<3)INx72v75*dLtP zjlS)#j!VC9P^jeFEZpGjio7|dY8;eVzj>i9ZKl~<-NR;2+ zb2AMRu3q;u>aGd7ujc=YA?pI8$hZjN3Kyy5B8Zcs?L{j2hk`hXj1+bL?=(zm d^Sn?-_itqv2N6)r2~y}p^}^FyJ~002P^006)M0Ol1+ zL{f4uN>EXvi1zP<#ufme&!oIUF(5U9xi2T7D60?gtCZFM>6!$b2tAP5+bsY?TaJ3NJsHJu&@wbb(a6yOYKhI{LXcG2s=yqxf;(eEHMwy`NlPfL*)vVF z#5UIDSMSRxG|gZ1c_f!VXGp5^8p#BzDNFdg+9H;utB8H?{tIs2b77?^TYPg>Cnl?5;o0EtrmRR68-7l1p;F~xd3Eh*CIN3!27@dtN+#k(s zjrMbcBHa8SNOu&c0V=@NJ4DDEj`VVaQ6Bzi%6yp7119(YoetwDZW13^%e}QhADH_2 z?Vyx;{AZZ3xQh*EeQGyIcVT~qV~?OzAK7M%etR4bS=w@oQjOL-dGJc z;*~+E8-_Not%h|99_o!?uWrA5;Q4S$)#JA!e)>+qQq4eKQ=WF)Y9PMXH)H28!&u3{ zlht{!$Cm%#P{*@=UuFntEg>PIBmV9vJUp$Sp*;aYe2s798YkvR2@;*t;N}i-Q#shYI^;%arLu&C5mZuQ{`q;jBS9(cyzX&eyg&o zy>-pI_kM)I)$u@q+~+zGdZmI{O#P zi2%(@jKx{A;5+XpEuL3Fy+kXR*Ot-uGRPw%6<)lF(jXY^pDVxWml#A1y4|Nxxrrd3 zuSmhRG=cH;(O~yT`4SR&SS{9VOoJS;Z$W>AXa!?HGDgiNm$FUfrWY?b>_iuBg_xxt zf4{nto{)bCkXqm}vT>ned3CmWE^Lg4Pu-bbvBldx#;YzCzH(G$&bfYlz7fN?uGZ!R zdd?|c9h`&lVJj|$I)b{Ma4p;A9hxI7%j=Mj5l<(^EYi-pr%xsEJFs6LzP{X)c14J@ zI9beZZH{5OgyrVOC)LP>*VgL+`LFJOOVav5i0{z_&l)n_qDyrpcZbj6@i4SFlB9nm zx0;N%m>94|HQq{Q-_D95v2|0i+?m;~=wD_fn|l3N$PTPy9UirRqZU_d(*zZeeZ@0k zzRkbM6hD58nIHLzbHW(S*to<`SG_qFLHTR>iC0oPuG8(N$HpzjiLfbmzYoxh({klf zUlL3%mO)C~FiE#^sCXxYh+bg~j1RLY#FuuY$0Zf58cfw@c-3|>vlFIg#`cr)x%##P zwIHEV9c=_~bxw^4hEemPX7yy!3zrh9Ar@0ytb$m>cU`+fXhgzS?>wdP!ao8)MVTk7 zwikSDl)E;>g1O8tdN@~oV+OvS98h9H zjDOL0jcxqapUVFj?Ub^E(sj*h$OSd2hWg;dXzY1$j@Ey?alWi+*a?_}M9apEFeafd zX1)70=N*optfQV{WP!X6r(X4vYpc368ZmhGi2dG@DA-(4b>kbYT=(8F8f;e9j*|_R5006XnAAIJc{$t#bAT0H z6Q>iji7`C{RQmeY2#NZHwI@cnQ~^hCy7*()BLm7X*$<#BL?ToCm&+~p1XZ2B&3SGK z4X)Wg%PgUu;7-DNFL01emz;=yzOb%ql%&La!0XTInP?Y?pI9(Ez>&a$w+SWN%;O%P->dDSglZg1ZcWMdN_ zPI_52@gX=%z)^?&ARI=t-}%(sy(pwn8-cU9f|2*Eoj4{#(3(Jqw@LG6o5Xrj>MSDF zRmLi8B-0gQilgSM9lFgw;9Swn6VT5x&Z%^ExMIw_D_NqDQ2y5;O(9lzOQ3dT%FNeRbtvv!32o4JM=xwe;^=fK*UZBOgrKUKs z!NHKBftp#hg9o|!G_9y%k~r2lJ(uXE!Z1p38qC8m>bua5>g$AZI>= z=XOb4d)E%J5B$u7m#$aWs8DZ%cCi-YCcFiJFcxXIifZ>P7k_|Qk()ZrBC{BrM1$!< zqbsLvogC8&c=zz;7S2$zSVRKJd}N>nOfM;Nz)thg=P?>oecy2A8MZ zMJpKjQh8N|bzQ9Y(dRXu3qBVw1Z74!^p;615w@rPBUyz1Fn2f z_RleUgtT-KF6suBS{e`9(tY=!Ia5FR{H@pllm1s(zcK?8@Yh}y__JzU{}$h13=FHw z_gv8Tc*`;i-yP+`HJ$T9E^JEttYL&vN*T-WqfD*jv~~qtJ)-YNxYH>0{>)j_<8ttL zZQK%1Zi8=I)g6^L^++%|+&w_%(74Lcpe*?XGGunVP~Mm{Sy2J*ARU6sN%LDV6*~C{7Whpw9oz f!;~_wQ)i6-c6NFcq43f_<&5Hsc_m0W9l-c6^1s*f literal 0 HcmV?d00001 diff --git a/HMPID/HMPIDGeom.C b/HMPID/HMPIDGeom.C new file mode 100644 index 00000000000..fe46f4f476e --- /dev/null +++ b/HMPID/HMPIDGeom.C @@ -0,0 +1,434 @@ + +Int_t copy; //volume copy number +Double_t dx,dy,dz,r1,r2;//tmp vars for volume dimentions +Double_t cm=1,m=100*cm,mm=0.1*cm,mkm=0.001*cm;//length units +TGeoManager *g=0; + +void RichGeom(Bool_t isOnlyChambers=kFALSE) +{ + + g=new TGeoManager("HMPID","Private HMPID geometry"); + Materials(); + gGeoManager->MakeBox("ALIC",gGeoManager->GetMedium("Air"),dx=30*m/2,dy=30*m/2,dz=30*m/2); //arbitrary values + gGeoManager->SetTopVolume(gGeoManager->GetVolume("ALIC")); + + Rich(isOnlyChambers); + +// RusGel(); + +// Vhmpid(); + + gGeoManager->CloseGeometry(); + + gGeoManager->SetVisOption(0); gGeoManager->SetVisLevel(5); + + gGeoManager->GetMasterVolume()->Draw(); + Axis(); +// gPad->GetView()->SetView(3,94,-70,0); + new TBrowser; +} +//__________________________________________________________________________________________________ +void Materials() +{ +//Media for HMPID + Double_t a=0,z=0,den=0,radlen=0,intlen=0;//tmp vars for material parameters + new TGeoMaterial("Air" ,a=26.98 ,z=13,den=0.4224 ); new TGeoMedium("Air" ,1,gGeoManager->GetMaterial("Air")); + new TGeoMaterial("HMPID_CH4" ,a=26.98 ,z=13,den=0.4224 ); new TGeoMedium("HMPID_CH4" ,2,gGeoManager->GetMaterial("HMPID_CH4")); + new TGeoMaterial("HMPID_CsI" ,a=26.98 ,z=13,den=2.7 ,radlen=24.01*cm,intlen=70.6*cm); new TGeoMedium("HMPID_CsI" ,3,gGeoManager->GetMaterial("HMPID_CsI")); + new TGeoMaterial("HMPID_Al" ,a=26.98 ,z=13,den=2.7 ,radlen=24.01*cm,intlen=70.6*cm); new TGeoMedium("HMPID_Al" ,4,gGeoManager->GetMaterial("HMPID_Al")); + new TGeoMaterial("HMPID_W" ,a=183.84,z=27,den=19.3,radlen= 9.59*cm,intlen=0.35*cm); new TGeoMedium("HMPID_W" ,5,gGeoManager->GetMaterial("HMPID_W")); + new TGeoMaterial("HMPID_Cu" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("HMPID_Cu" ,6,gGeoManager->GetMaterial("HMPID_Cu")); + new TGeoMaterial("HMPID_Rohacell" ,a=12.01 ,z=6 ,den=0.1 ,radlen=18.8,intlen=0); new TGeoMedium("HMPID_Rohacell",7,gGeoManager->GetMaterial("HMPID_Rohacell")); + new TGeoMaterial("HMPID_SiO2" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_SiO2" ,8,gGeoManager->GetMaterial("HMPID_SiO2")); + new TGeoMaterial("HMPID_C6F14" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_C6F14" ,9,gGeoManager->GetMaterial("HMPID_C6F14")); +//Media for Sr90 source + new TGeoMaterial("HMPID_Perpex" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("HMPID_Perpex" ,10,gGeoManager->GetMaterial("HMPID_Perpex")); + new TGeoMaterial("HMPID_Steel" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("HMPID_Steel" ,11,gGeoManager->GetMaterial("HMPID_Steel")); + new TGeoMaterial("HMPID_Mylar" ,a=55.845,z=26,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("HMPID_Mylar" ,12,gGeoManager->GetMaterial("HMPID_Mylar")); + new TGeoMaterial("HMPID_Sr90" ,a=87.62 ,z=38,den=7.87,radlen=13.84*cm,intlen=82.8*cm); new TGeoMedium("HMPID_Sr90" ,13,gGeoManager->GetMaterial("HMPID_Sr90")); +//Media for VHMPID Gas option + new TGeoMaterial("HMPID_CF4" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_CF4" ,14,gGeoManager->GetMaterial("HMPID_CF4")); + new TGeoMaterial("HMPID_C4F10" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_C4F10" ,15,gGeoManager->GetMaterial("HMPID_C4F10")); + new TGeoMaterial("HMPID_Ag" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_Ag" ,16,gGeoManager->GetMaterial("HMPID_Ag")); +//Media for VHMPID aerogel option + new TGeoMaterial("HMPID_Gel24" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_Gel24" ,17,gGeoManager->GetMaterial("HMPID_Gel24")); + new TGeoMaterial("HMPID_Gel26" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_Gel26" ,18,gGeoManager->GetMaterial("HMPID_Gel26")); + new TGeoMaterial("HMPID_Gel28" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_Gel28" ,19,gGeoManager->GetMaterial("HMPID_Gel28")); + new TGeoMaterial("HMPID_Gel30" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_Gel30" ,20,gGeoManager->GetMaterial("HMPID_Gel30")); + new TGeoMaterial("HMPID_Si" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_Si" ,21,gGeoManager->GetMaterial("HMPID_Si")); + new TGeoMaterial("HMPID_Apd" ,a=0 ,z=0 ,den=0); new TGeoMedium("HMPID_Apd" ,22,gGeoManager->GetMaterial("HMPID_Apd")); +}//Materials() +//__________________________________________________________________________________________________ +void Rich(Bool_t isOnlyChambers) +{ +//Rich chamber + TGeoVolume *pRich=gGeoManager->MakeBox("HMPID",gGeoManager->GetMedium("Air"),dx=(6*mm+1681*mm+6*mm)/2, //main HMPID volume + dy=(6*mm+1466*mm+6*mm)/2, + dz=(80*mm+40*mm)*2/2); //x,y taken from 2033P1 z from p84 TDR + const Double_t kAngHor=19.5; // horizontal angle between chambers 19.5 grad + const Double_t kAngVer=20; // vertical angle between chambers 20 grad + const Double_t kAngCom=30; // common HMPID rotation with respect to x axis 30 grad + const Double_t trans[3]={490,0,0}; //center of the chamber is on window-gap surface + for(Int_t iCh=1;iCh<=7;iCh++){//place 7 chambers + TGeoHMatrix *pMatrix=new TGeoHMatrix; + pMatrix->RotateY(90); //rotate around y since initial position is in XY plane -> now in YZ plane + pMatrix->SetTranslation(trans); //now plane in YZ is shifted along x + switch(iCh){ + case 1: pMatrix->RotateY(kAngHor); pMatrix->RotateZ(-kAngVer); break; //right and down + case 2: pMatrix->RotateZ(-kAngVer); break; //down + case 3: pMatrix->RotateY(kAngHor); break; //right + case 4: break; //no rotation + case 5: pMatrix->RotateY(-kAngHor); break; //left + case 6: pMatrix->RotateZ(kAngVer); break; //up + case 7: pMatrix->RotateY(-kAngHor); pMatrix->RotateZ(kAngVer); break; //left and up + } + pMatrix->RotateZ(kAngCom); //apply common rotation in XY plane + gGeoManager->GetVolume("ALIC")->AddNode(pRich,iCh,pMatrix); + } + if(isOnlyChambers) return; //do not construct the detailed geometry +//Pad Panel frame + TGeoVolume *pPpf =gGeoManager->MakeBox("Rppf" ,gGeoManager->GetMedium("HMPID_Al") ,dx=648*mm/2,dy= 411*mm/2 ,dz=40 *mm/2);//PPF 2001P2 inner size of the slab by 1mm more + TGeoVolume *pPpfLarge=gGeoManager->MakeBox("Rppf1" ,gGeoManager->GetMedium("Air") ,dx=181*mm/2,dy=89.25*mm/2 ,dz=38.3*mm/2); //large whole + TGeoVolume *pPpfSmall=gGeoManager->MakeBox("Rppf2" ,gGeoManager->GetMedium("Air") ,dx=114*mm/2,dy=89.25*mm/2 ,dz=38.3*mm/2);//small whole + TGeoVolume *pPc =gGeoManager->MakeBox("Rpc" ,gGeoManager->GetMedium("HMPID_CsI") ,dx=644*mm/2,dy= 407*mm/2 ,dz= 1.7*mm/2);//by 0.2 mm more then actual size (PCB 2006P1) + + pRich->AddNode(pPpf,copy=1,new TGeoTranslation(-335*mm,-433*mm,8*cm+20*mm));//F1 2040P1 z p.84 TDR + pRich->AddNode(pPpf,copy=2,new TGeoTranslation(+335*mm,-433*mm,8*cm+20*mm)); + pRich->AddNode(pPpf,copy=3,new TGeoTranslation(-335*mm, 0*mm,8*cm+20*mm)); + pRich->AddNode(pPpf,copy=4,new TGeoTranslation(+335*mm, 0*mm,8*cm+20*mm)); + pRich->AddNode(pPpf,copy=5,new TGeoTranslation(-335*mm,+433*mm,8*cm+20*mm)); + pRich->AddNode(pPpf,copy=6,new TGeoTranslation(+335*mm,+433*mm,8*cm+20*mm)); + pPpf->AddNode( pPc ,copy=1,new TGeoTranslation( 0*mm, 0*mm,-19.15*mm));//PPF 2001P2 + pPpf->AddNode(pPpfLarge,copy=1,new TGeoTranslation(-224.5*mm,-151.875*mm, 0.85*mm)); + pPpf->AddNode(pPpfLarge,copy=2,new TGeoTranslation(-224.5*mm,- 50.625*mm, 0.85*mm)); + pPpf->AddNode(pPpfLarge,copy=3,new TGeoTranslation(-224.5*mm,+ 50.625*mm, 0.85*mm)); + pPpf->AddNode(pPpfLarge,copy=4,new TGeoTranslation(-224.5*mm,+151.875*mm, 0.85*mm)); + pPpf->AddNode(pPpfSmall,copy=1,new TGeoTranslation(- 65.0*mm,-151.875*mm, 0.85*mm)); + pPpf->AddNode(pPpfSmall,copy=2,new TGeoTranslation(- 65.0*mm,- 50.625*mm, 0.85*mm)); + pPpf->AddNode(pPpfSmall,copy=3,new TGeoTranslation(- 65.0*mm,+ 50.625*mm, 0.85*mm)); + pPpf->AddNode(pPpfSmall,copy=4,new TGeoTranslation(- 65.0*mm,+151.875*mm, 0.85*mm)); + pPpf->AddNode(pPpfSmall,copy=5,new TGeoTranslation(+ 65.0*mm,-151.875*mm, 0.85*mm)); + pPpf->AddNode(pPpfSmall,copy=6,new TGeoTranslation(+ 65.0*mm,- 50.625*mm, 0.85*mm)); + pPpf->AddNode(pPpfSmall,copy=7,new TGeoTranslation(+ 65.0*mm,+ 50.625*mm, 0.85*mm)); + pPpf->AddNode(pPpfSmall,copy=8,new TGeoTranslation(+ 65.0*mm,+151.875*mm, 0.85*mm)); + pPpf->AddNode(pPpfLarge,copy=5,new TGeoTranslation(+224.5*mm,-151.875*mm, 0.85*mm)); + pPpf->AddNode(pPpfLarge,copy=6,new TGeoTranslation(+224.5*mm,- 50.625*mm, 0.85*mm)); + pPpf->AddNode(pPpfLarge,copy=7,new TGeoTranslation(+224.5*mm,+ 50.625*mm, 0.85*mm)); + pPpf->AddNode(pPpfLarge,copy=8,new TGeoTranslation(+224.5*mm,+151.875*mm, 0.85*mm)); +//gap - anod wires + TGeoVolume *pGap =gGeoManager->MakeBox ("Rgap" ,gGeoManager->GetMedium("HMPID_CH4") ,dx=648*mm/2,dy= 411*mm/2 ,dz=4.45*mm/2);//xy as PPF 2001P2 z WP 2099P1 + TGeoVolume *pAnod=gGeoManager->MakeTube("Rano" ,gGeoManager->GetMedium("HMPID_W") ,r1= 0*mm ,r2= 20*mkm/2 ,dz=648*mm/2); //WP 2099P1 z = gap x PPF 2001P2 + TGeoRotation *pAnodRot=new TGeoRotation("RanW",90,90,0); + + pRich->AddNode(pGap,copy=1,new TGeoTranslation(-335*mm,-433*mm,8*cm-2.225*mm)); //F1 2040P1 z WP 2099P1 + pRich->AddNode(pGap,copy=2,new TGeoTranslation(+335*mm,-433*mm,8*cm-2.225*mm)); + pRich->AddNode(pGap,copy=3,new TGeoTranslation(-335*mm, 0*mm,8*cm-2.225*mm)); + pRich->AddNode(pGap,copy=4,new TGeoTranslation(+335*mm, 0*mm,8*cm-2.225*mm)); + pRich->AddNode(pGap,copy=5,new TGeoTranslation(-335*mm,+433*mm,8*cm-2.225*mm)); + pRich->AddNode(pGap,copy=6,new TGeoTranslation(+335*mm,+433*mm,8*cm-2.225*mm)); + for(int i=1;i<=96;i++) + pGap->AddNode(pAnod,copy=i,new TGeoCombiTrans( 0*mm, -411/2*mm+i*4*mm, 0.185*mm,pAnodRot)); //WP 2099P1 +//frame 3- cathode wires + TGeoVolume *pCath=gGeoManager->MakeTube("RcaW" ,gGeoManager->GetMedium("Cu") ,r1=0 ,r2=100*mkm/2,dz=1323*mm/2);//r WP 2099P1 z F3 2041P1 + TGeoRotation *pCathRot=new TGeoRotation("CathRot",90,90,0); + for(int i=1;i<=618;i++) + pRich->AddNode(pCath,copy=i,new TGeoCombiTrans( 0*mm, -649.5*mm+i*2.1*mm, 75*mm,pCathRot)); //WP 2099P1 +//Frame 4- collection wires + TGeoVolume *pF4 =gGeoManager->MakeBox( "Rfr4" ,gGeoManager->GetMedium("HMPID_CH4") ,dx=1407*mm/2 ,dy=1366*mm/2 ,dz= 15*mm/2);//F4 2043P1 + TGeoVolume *pF4al=gGeoManager->MakeBox( "Rfr4al" ,gGeoManager->GetMedium("HMPID_Al") ,dx=1407*mm/2 ,dy=1366*mm/2 ,dz= 10*mm/2); + TGeoVolume *pF4in=gGeoManager->MakeBox( "Rfr4in" ,gGeoManager->GetMedium("HMPID_CH4") ,dx=1323*mm/2 ,dy=1296*mm/2 ,dz= 10*mm/2); + TGeoVolume *pColl=gGeoManager->MakeTube("RcoW" ,gGeoManager->GetMedium("HMPID_Cu") ,r1= 0*mm ,r2=100*mkm/2 ,dz=1323*mm/2); + TGeoRotation *pCollRot=new TGeoRotation("RcoRot",90,90,0); + + pRich->AddNode(pF4 ,copy=1,new TGeoTranslation( 0*mm,0*mm, 9*mm)); //F4 to Rich p.84 TDR + pF4 ->AddNode(pF4al ,copy=1,new TGeoTranslation( 0*mm,0*mm, 2.5*mm)); //F4 al to F4 2043P1 + pF4al->AddNode(pF4in ,copy=1,new TGeoTranslation( 0*mm,0*mm, 0*mm)); //F4 whole F4 al 2043P1 + for(int i=1;i<=322;i++) + pF4->AddNode(pColl,copy=i,new TGeoCombiTrans( 0*mm, -1296/2*mm+i*4*mm, -5*mm,pCollRot)); //F4 2043P1 +//radiators + TGeoVolume *pRad =gGeoManager->MakeBox( "Rad" ,gGeoManager->GetMedium("HMPID_C6F14") ,dx=1330*mm/2 ,dy= 413*mm/2 ,dz= 24*mm/2); // Rad 2011P1 + TGeoVolume *pRadFront =gGeoManager->MakeBox( "RadFront" ,gGeoManager->GetMedium("HMPID_Neoceram") ,dx=1330*mm/2 ,dy= 413*mm/2 ,dz= 4*mm/2); + TGeoVolume *pRadWin =gGeoManager->MakeBox( "RadWin" ,gGeoManager->GetMedium("HMPID_SiO2") ,dx=1330*mm/2 ,dy= 413*mm/2 ,dz= 5*mm/2); + TGeoVolume *pRadLong =gGeoManager->MakeBox( "RadLong" ,gGeoManager->GetMedium("HMPID_Neoceram") ,dx=1330*mm/2 ,dy= 5*mm/2 ,dz= 15*mm/2); + TGeoVolume *pRadShort =gGeoManager->MakeBox( "RadShort" ,gGeoManager->GetMedium("HMPID_Neoceram") ,dx= 10*mm/2 ,dy= 403*mm/2 ,dz= 15*mm/2); + TGeoVolume *pRadSpacer=gGeoManager->MakeTube("RadSpacer",gGeoManager->GetMedium("HMPID_SiO2") ,r1= 0 ,r2=10*mm/2 ,dz= 15*mm/2); + + pRich->AddNode(pRad ,copy=1,new TGeoTranslation( 0*mm,-434*mm, -12*mm)); + pRich->AddNode(pRad ,copy=2,new TGeoTranslation( 0*mm, 0*mm, -12*mm)); + pRich->AddNode(pRad ,copy=3,new TGeoTranslation( 0*mm,+434*mm, -12*mm)); + + pRad ->AddNode(pRadFront ,copy=1,new TGeoTranslation( 0*mm, 0*mm, -10.0*mm)); + pRad ->AddNode(pRadWin ,copy=1,new TGeoTranslation( 0*mm, 0*mm, 9.5*mm)); + pRad ->AddNode(pRadLong ,copy=1,new TGeoTranslation( 0*mm,-204*mm, -0.5*mm)); + pRad ->AddNode(pRadLong ,copy=2,new TGeoTranslation( 0*mm,+204*mm, -0.5*mm)); + pRad ->AddNode(pRadShort ,copy=1,new TGeoTranslation(-660*mm, 0*mm, -0.5*mm)); + pRad ->AddNode(pRadShort ,copy=2,new TGeoTranslation(+660*mm, 0*mm, -0.5*mm)); + for(int i=0;i<3;i++) for(int j=0;j<10;j++) pRad->AddNode(pRadSpacer,copy=10*i+j,new TGeoTranslation(-1330*mm/2+116*mm+j*122*mm,(i-1)*105*mm,-0.5*mm)); +//sandbox + TGeoVolume *pSandBox =gGeoManager->MakeBox( "RSandBox" ,gGeoManager->GetMedium("Air") ,dx=1419*mm/2 ,dy=1378*mm/2 ,dz=50.5*mm/2); //2072P1 + TGeoVolume *pSandCover=gGeoManager->MakeBox( "RSandCover",gGeoManager->GetMedium("HMPID_Al") ,dx=1419*mm/2 ,dy=1378*mm/2 ,dz= 0.5*mm/2); + TGeoVolume *pSandComb =gGeoManager->MakeBox( "RSandComb" ,gGeoManager->GetMedium("HMPID_Rohacell") ,dx=1359*mm/2 ,dy=1318*mm/2 ,dz=49.5*mm/2); + + pRich->AddNode(pSandBox,copy=1,new TGeoTranslation( 0*mm,0*mm, -73.75*mm)); //p.84 TDR + pSandBox->AddNode(pSandComb ,copy=1,new TGeoTranslation( 0*mm,0*mm, 0*mm)); //2072P1 + pSandBox->AddNode(pSandCover ,copy=1,new TGeoTranslation( 0*mm,0*mm, +25*mm)); + pSandBox->AddNode(pSandCover ,copy=2,new TGeoTranslation( 0*mm,0*mm, -25*mm)); +}//Rich() +//__________________________________________________________________________________________________ +void Sr90(TGeoVolume *pTop) +{ + pSrc =gGeoManager->MakeTube("Src" ,gGeoManager->GetMedium("Air") , 0 , 70*mm/2 , 30*mm/2); //top container + pAlGlass =gGeoManager->MakeTube("SrcAlGlass" ,gGeoManager->GetMedium("HMPID_Al") , 0 , 38*mm/2 ,21.8*mm/2); //Al glass wall + pPerpexPlug =gGeoManager->MakeTube("SrcPerpex" ,gGeoManager->GetMedium("HMPID_Perpex"), 0 , 34*mm/2 , 20*mm/2); //Perpex plug + pScrewCentral=gGeoManager->MakeTube("SrcScrewCentral" ,gGeoManager->GetMedium("HMPID_Steel") , 0 , 5*mm/2 , 15*mm/2); //Steel screw in the center + pScrewSr90 =gGeoManager->MakeTube("SrcScrewSr90" ,gGeoManager->GetMedium("HMPID_Steel") , 0 , 2*mm/2 , 10*mm/2); //Steel screw to support Sr90 + pSr90 =gGeoManager->MakeTube("SrcSr90" ,gGeoManager->GetMedium("HMPID_Sr90") , 0 , 1*mm/2 , 1*mm/2); //Sr90 source + pHolePerpex =gGeoManager->MakeTube("SrcHolePerpex" ,gGeoManager->GetMedium("Air") , 0 , 4*mm/2 , 10*mm/2); //Air hole in perpex plug + pHoleAl =gGeoManager->MakeTube("SrcHoleAl" ,gGeoManager->GetMedium("Air") , 0 , 5*mm/2 , 1.8*mm/2); //Air hole in Al glass bottom + pMylarFoil =gGeoManager->MakeTube("SrcMylarFoil" ,gGeoManager->GetMedium("HMPID_Mylar") , 0 , 30*mm/2 , 50*mkm/2); //Mylar foil + + pTop->AddNode(pSrc,1,new TGeoTranslation(30*cm,0,1*cm)); + pSrc ->AddNode(pMylarFoil,1,new TGeoTranslation(0,0,21.8*mm/2+50*mkm/2)); + pSrc ->AddNode(pAlGlass,1,new TGeoTranslation(0,0,0)); //Al glass to fake Src volume + pAlGlass->AddNode( pHoleAl ,1,new TGeoTranslation(6*mm,0, -10*mm)); + pAlGlass->AddNode( pPerpexPlug ,1,new TGeoTranslation(0*mm,0, 0.9*mm)); + pPerpexPlug->AddNode( pHolePerpex ,1,new TGeoTranslation(6*mm,0, -5*mm)); + pPerpexPlug->AddNode( pScrewCentral,1,new TGeoTranslation(0 ,0, 2.5*mm)); + pPerpexPlug->AddNode( pScrewSr90 ,1,new TGeoTranslation(6*mm,0, 5*mm)); + pScrewSr90->AddNode( pSr90 ,1,new TGeoTranslation(0 ,0,-4.5*mm)); +}//Sr90() +//__________________________________________________________________________________________________ +void RusGel() +{ +//Defines VHMPID aerogel option geometry. +// top view normal position side view normal position +// ^ y +// -------- | +// | | | +// | | z<-----* y z<-------* x ----> MUON side +// | | | ---- +// | | | | | +// ________ v x | | +// |--| +// | | +// ---- +//Chamber consists from Al box filled with air where 4 aerogel blocks and APD wall are positioned. +// ------------------------------ +// |-| |-| |-| |-| |-|| +// |-| | | | | | | | || +// |-| | | | | | | | || +// |-| APD wall | | | | | | | || z<---* y top view +// |-| | | | | | | | || | +// |-| | | | | | | | || | +// |-| |_| |_| |_| |_|| v x +// ------------------------------ +// +// ALIC +// | +// Vbox (Al) +// | +// Vair (Air) +// _______|________ +// | | +// 4*Vgel Vwall +// | +// Vcolumn (division along X) +// | +// Vcell (division along Y) +// | +// Vapd + + Double_t cm=1 , m=100 , mm=0.1 ;//dimentions, default is cm + + Int_t iNapdsX =10 ;//number of APDs along x + Int_t iNapdsY =16 ;//number of APDs along y + Double_t dCellX =1.5*mm *0.5 ;//cell X half size + Double_t dCellY =1.5*mm *0.5 ;//cell Y half size + Double_t dCellZ =0.5*mm *0.5 ;//APD wall thickness + Double_t dWallX = iNapdsX*dCellX;//APD wall X half size + Double_t dWallY = iNapdsY*dCellY;//APD wall Y half size + Double_t dWallZ = dCellZ;//APD wall half thickness + Double_t dApdR =0.5*mm ;//APD radius + Double_t dApdZ = dCellZ;//APD Z half size + Double_t dGelX = dWallX;//gel block X half size + Double_t dGelY = dWallY;//gel block Y half size + Double_t dGelZ =10*mm *0.5 ;//gel block Z half size + Double_t dProxGap =50*cm ;//half distance between APD wall and last aerogel block + Double_t dAirX = dWallX;//internal air X hald size + Double_t dAirY = dWallY;//internal air Y hald size + Double_t dAirZ = dWallZ+dProxGap+7*dGelZ;//internal air Z hald size + Double_t dBoxWall =2*mm *0.5 ;//Al box walls thickness + Double_t dBoxX = dAirX+dBoxWall;//Al box x half size + Double_t dBoxY = dAirY+dBoxWall;//Al box y half size + Double_t dBoxZ = dAirZ+dBoxWall;//Al box z half size + + Int_t copy; Double_t rmin,rmax,dx,dy,dz; +//make external Al box + TGeoVolume *pBox=gGeoManager->MakeBox("Gbox",gGeoManager->GetMedium("HMPID_Al"),dx=dBoxX,dy=dBoxY,dz=dBoxZ); + TGeoRotation *pRot=new TGeoRotation("GboxRot"); pRot->RotateX(90); + gGeoManager->GetVolume("ALIC")->AddNode(pBox,copy=1,new TGeoCombiTrans(0*m,-5.2*m,2.5*m,pRot));//normal position +//position Air to Al box + TGeoVolume *pAir=gGeoManager->MakeBox( "Gair",gGeoManager->GetMedium("Air"),dx=dAirX,dy=dAirY,dz=dAirZ); + pBox->AddNode(pAir,copy=1); +//position 4 gel blocks to Air + TGeoVolume *pGel24=gGeoManager->MakeBox( "Ggel24",gGeoManager->GetMedium("HMPID_Gel24"),dx=dGelX,dy=dGelY,dz=dGelZ); + pAir->AddNode(pGel24,copy=1,new TGeoTranslation(0,0,-dAirZ+1*dGelZ)); + TGeoVolume *pGel26=gGeoManager->MakeBox( "Ggel26",gGeoManager->GetMedium("HMPID_Gel26"),dx=dGelX,dy=dGelY,dz=dGelZ); + pAir->AddNode(pGel26,copy=1,new TGeoTranslation(0,0,-dAirZ+5*dGelZ)); + TGeoVolume *pGel28=gGeoManager->MakeBox( "Ggel28",gGeoManager->GetMedium("HMPID_Gel28"),dx=dGelX,dy=dGelY,dz=dGelZ); + pAir->AddNode(pGel28,copy=1,new TGeoTranslation(0,0,-dAirZ+9*dGelZ)); + TGeoVolume *pGel30=gGeoManager->MakeBox( "Ggel30",gGeoManager->GetMedium("HMPID_Gel30"),dx=dGelX,dy=dGelY,dz=dGelZ); + pAir->AddNode(pGel30,copy=1,new TGeoTranslation(0,0,-dAirZ+13*dGelZ)); +//position APD wall to air + TGeoVolume *pWall =gGeoManager->MakeBox ("Gwall",gGeoManager->GetMedium("HMPID_Si"),dx=dWallX , dy=dWallY , dz=dWallZ ); + pAir->AddNode(pWall,copy=1,new TGeoTranslation(0,0,dAirZ-dWallZ)); +//divide wall into cells + Int_t axis,ndiv; Double_t start,step; + TGeoVolume *pWallCol =pWall ->Divide("Gcol",axis=1,ndiv=iNapdsX,start=0,step=0);//divide VhGap along X by NpadsX columns + TGeoVolume *pWallCell=pWallCol ->Divide("Gcel",axis=2,ndiv=iNapdsY,start=0,step=0);//divide VhGapCol along Y by NpadsY cells +//position APD to wall cell + TGeoVolume *pApd=gGeoManager->MakeTube("Gapd",gGeoManager->GetMedium("HMPID_Apd"),rmin=0,rmax=dApdR,dz=dApdZ); pWallCell->AddNode(pApd,copy=1); +}//RusGel() +//__________________________________________________________________________________________________ +void Vhmpid() +{ +//Defines VHMPID geometry for TIC option. +// top view normal position side view normal position +// ^ y +// -------- | +// |------| | +// | | z<-----* y z<-------* x ----> MUON side +// | | | ---- +// | | | | | +// ________ v x | | +// |--| +// | | +// ---- +//Chamber consists from Al box filled with radiator CF4 and C4F10 quartz window in between , Al mirror and MWPC. +// --------------------------------------------------- top view chamber in test position +// | -------------- MWPC | quartz window | +// | . . . . . . | | +// | \ | | +// | \ CF4 | C4F10 | z<-----* y +// | \ mirror | | | +// | \ | | | +// | \ | | v x +// --------------------------------------------------- +// z ^ +// | +// | +// <-Y0-> X <--Y1--> X <--Y1--> X <--Y1--> X <-Y0-> | cath wires: r 50mkm; shift Y0=1.05m;, pitch Y1=2.1; center to PC 4.45mm; material Cu +// x *------->y +// +// <--Y0--> x <-----------Y1-----------> x <--Y0--> anod wires: r 20mkm; shift Y0=2.2mm; pitch Y1=4.0mm; center to PC 2.04mm; material W +// +// +// |________________________________________________| pad size y 8.4mm +// +// ALIC +// | +// Vbox +// _______|______ +// | | | +// Vc4f Vwin Vcf4 +// _____|________ +// | | +// Vmir | +// | +// Vgap +// | +// Vcol (column of gap cells) X +// | +// Vcel cell in the column Y +// ______|______ +// | | | +// Vpad Vano Vcat + Double_t cm=1 , m=100 , mm=0.1 , um=1e-4 ;//dimentions, default is cm + + Int_t iNpadsX = AliHMPIDParam::NpadsX() ;//number of pads along x parametrised + Int_t iNpadsY = AliHMPIDParam::NpadsY() ;//number of pads along y parametrised + Double_t wCathR =50 *um ;//cathode wire radius defined by USER + Double_t wCathShift =1.05*mm ;//cathode wire shift from pad edge defined by USER + Double_t wCathPitch =2.1 *mm ;//cathode wire pitch defined by USER + Double_t wCathPc =4.45*mm ;//distance from pc to cathode wire defined by USER + Double_t wAnodR =20 *um ;//anod wire radius defined by USER + Double_t wAnodShift =2.2 *mm ;//anod wire shift from pad edge defined by USER + Double_t wAnodPc =2.04*mm ;//distance from anod wire center to pc defined by USER + Double_t dPadX = 0.5* AliHMPIDParam::PadSizeX() ;//pad X half size parametrised + Double_t dPadY = 0.5* AliHMPIDParam::PadSizeY() ;//pad Y half size parametrised + Double_t dPadZ =1.0 *mm *0.5 ;//CsI film thickness + Double_t dGapX = 0.5* iNpadsX*2*dPadX ;//gap x half size n. pads x * pad size + Double_t dGapY = 0.5* iNpadsY*2*dPadY ;//gap y half size + Double_t dGapZ = 0.5* (2*dPadZ+wCathPc+wCathR) ;//gap half thickness + Double_t dMirX = 0.5* 2*dGapX/TMath::Cos(45*TMath::DegToRad());//Ag mirror x half size defined by gap size and angle 45 degrees + Double_t dMirY = 0.5* 2*dGapY ;//Ag mirror y half size defined by gap size + Double_t dMirZ =1.0 *mm *0.5 ;//Ag mirror z half size defined by USER + Double_t wBoxWall =2.0 *mm ;//Al box walls thickness defined by USER + Double_t dBoxX = 0.5* (2*dGapX+2*cm) ;//Al box x half size defined by gap size 2 cm for tolerance + Double_t dBoxY = 0.5* (2*dGapY+2*cm) ;//Al box y half size defined by gap size 2 cm for tolerance + Double_t dBoxZ =1.8*m *0.5 ;//Al box z half size defined by USER + Double_t dWinX = (dBoxX-wBoxWall) ;//SiO2 window x half size defined by box size + Double_t dWinY = (dBoxY-wBoxWall) ;//SiO2 window y half size defined by box size + Double_t dWinZ =1.0*cm *0.5 ;//SiO2 window z half size defined by USER + Double_t dCF4X = (dBoxX-wBoxWall) ;//CF4 radiator x half size defined by box size + Double_t dCF4Y = (dBoxY-wBoxWall) ;//CF4 radiator y half size defined by box size + Double_t dCF4Z = 0.4*dBoxZ ;//CF4 radiator z half size defined by box size or by USER + Double_t dC4F10X = (dBoxX-wBoxWall) ;//C4F10 radiator x half size defined by box size + Double_t dC4F10Y = (dBoxY-wBoxWall) ;//C4F10 radiator y half size defined by box size + Double_t dC4F10Z = (dBoxZ-dWinZ-dCF4Z-wBoxWall) ;//C4F10 radiator z half size defined by box, CF4 and window sizes + + Int_t copy; + Double_t rmin,rmax,dx,dy,dz; + +//make VHMPID type 2 volume (2 radiators) + TGeoVolume *pBox=gGeoManager->MakeBox("Vbox",gGeoManager->GetMedium("HMPID_Al"),dx=dBoxX,dy=dBoxY,dz=dBoxZ); + + TGeoRotation *pRot=new TGeoRotation("VboxRot"); pRot->RotateX(90);//normal position + gGeoManager->GetVolume("ALIC")->AddNode(pBox,copy=1,new TGeoCombiTrans(0*m,-5.2*m,2.5*m,pRot)); +//position C4F10 radiator to Al box + TGeoVolume *pC4F10=gGeoManager->MakeBox("Vc4f",gGeoManager->GetMedium("HMPID_C4F10"),dx=dC4F10X,dy=dC4F10Y,dz=dC4F10Z); + pBox->AddNode(pC4F10,copy=1,new TGeoTranslation(0*cm,0*cm,-dBoxZ+wBoxWall+dC4F10Z)); +//position quartz window to Al box + TGeoVolume *pWindow=gGeoManager->MakeBox( "Vwin",gGeoManager->GetMedium("HMPID_SiO2"),dx=dWinX,dy=dWinY,dz=dWinZ); + pBox->AddNode(pWindow,copy=1,new TGeoTranslation(0*cm,0*cm,-dBoxZ+wBoxWall+2*dCF4Z+dWinZ)); +//position CF4 radiator to Al box + TGeoVolume *pCF4=gGeoManager->MakeBox( "Vcf4",gGeoManager->GetMedium("HMPID_CF4"),dx=dCF4X,dy=dCF4Y,dz=dCF4Z); + pBox->AddNode(pCF4,copy=1,new TGeoTranslation(0*cm,0*cm,dBoxZ-wBoxWall-dCF4Z)); +//position mirror to CF4 radiator + TGeoVolume *pMirror=gGeoManager->MakeBox( "Vmir",gGeoManager->GetMedium("HMPID_Ag"),dx=dMirX,dy=dMirY,dz=dMirZ); + TGeoRotation *pMirrorRot=new TGeoRotation("VmirRot"); pMirrorRot->RotateY(45); + pCF4->AddNode(pMirror,copy=1,new TGeoCombiTrans(0*cm,0*cm,dCF4Z-1*cm-dGapX,pMirrorRot)); +//position gap to CF4 radiator + TGeoVolume *pGap =gGeoManager->MakeBox ("Vgap" ,gGeoManager->GetMedium("HMPID_CF4"),dx=dGapX , dy=dGapY , dz=dGapZ ); + TGeoRotation *pMwpcRot=new TGeoRotation("VmpcRot"); pMwpcRot->RotateY(90); + pCF4->AddNode(pGap,copy=1,new TGeoCombiTrans(-dBoxX+1*cm,0*cm,dCF4Z-1*cm-dGapX,pMwpcRot)); +//divide gap into 80x48 cells + Int_t axis,ndiv; Double_t start,step; + TGeoVolume *pGapCol =pGap ->Divide("Vcol",axis=1,ndiv=iNpadsX,start=0,step=0);//divide VhGap along X by NpadsX columns + TGeoVolume *pGapCell=pGapCol ->Divide("Vcel",axis=2,ndiv=iNpadsY,start=0,step=0);//divide VhGapCol along Y by NpadsY cells +//position pad to gap cell + TGeoVolume *pPad=gGeoManager->MakeBox ("Vpad",gGeoManager->GetMedium("HMPID_CsI"),dx=dPadX,dy=dPadY,dz=dPadZ); + pGapCell->AddNode(pPad,copy=1,new TGeoTranslation(0,0,-dGapZ+dPadZ)); +//define wire rotation common for both anod and cathode wires + TGeoRotation *pWireRot=new TGeoRotation("VwireRot"); pWireRot->RotateY(90); //rotate wires around Y to be along X (initially along Z) +//position 2 anod wires to gap cell + TGeoVolume *pAnodWire =gGeoManager->MakeTube("Vano",gGeoManager->GetMedium("HMPID_W") ,rmin=0 , rmax=wAnodR , dz=dPadX ); + pGapCell->AddNode(pAnodWire,copy=1,new TGeoCombiTrans (0, -dPadY+wAnodShift , -dGapZ+wAnodPc+2*dPadZ , pWireRot)); + pGapCell->AddNode(pAnodWire,copy=2,new TGeoCombiTrans (0, dPadY-wAnodShift , -dGapZ+wAnodPc+2*dPadZ , pWireRot)); +//position 4 cathode wires to gap cell + TGeoVolume *pCathWire =gGeoManager->MakeTube("Vcat",gGeoManager->GetMedium("HMPID_Cu") ,rmin=0 , rmax=wCathR , dz=dPadX ); + pGapCell->AddNode(pCathWire,copy=1,new TGeoCombiTrans (0, -dPadY+wCathShift , -dGapZ+wCathPc+2*dPadZ , pWireRot)); + pGapCell->AddNode(pCathWire,copy=2,new TGeoCombiTrans (0, -dPadY+wCathShift+wCathPitch , -dGapZ+wCathPc+2*dPadZ , pWireRot)); + pGapCell->AddNode(pCathWire,copy=3,new TGeoCombiTrans (0, dPadY-wCathShift-wCathPitch , -dGapZ+wCathPc+2*dPadZ , pWireRot)); + pGapCell->AddNode(pCathWire,copy=4,new TGeoCombiTrans (0, dPadY-wCathShift , -dGapZ+wCathPc+2*dPadZ , pWireRot)); +}//Vhmpid() +//__________________________________________________________________________________________________ +void Axis() +{ +// Draw axises on top of geometry + 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(); +} +//__________________________________________________________________________________________________ diff --git a/HMPID/HMPIDMake b/HMPID/HMPIDMake new file mode 100644 index 00000000000..b008622a18c --- /dev/null +++ b/HMPID/HMPIDMake @@ -0,0 +1,135 @@ +Module :=HMPID + +include lib$(Module)base.pkg +SrcBase :=$(SRCS) + +include lib$(Module)sim.pkg +SrcSim :=$(SRCS) + +include lib$(Module)rec.pkg +SrcRec :=$(SRCS) + +RootTarget :=$(shell root-config --arch) +DirOut :=/tmp/$(USER)_$(Module)_obj +LibBase :=$(LIB_MY)/lib$(Module)base.so +LibSim :=$(LIB_MY)/lib$(Module)sim.so +LibRec :=$(LIB_MY)/lib$(Module)rec.so + + +HdrBase := $(SrcBase:.cxx=.h) $(Module)baseLinkDef.h +HdrSim := $(SrcSim:.cxx=.h) $(Module)simLinkDef.h +HdrRec := $(SrcRec:.cxx=.h) $(Module)recLinkDef.h + +DictSrcBase := $(DirOut)/Dict$(Module)base.cxx +DictObjBase := $(DictSrcBase:.cxx=.o) + +DictSrcSim := $(DirOut)/Dict$(Module)sim.cxx +DictObjSim := $(DictSrcSim:.cxx=.o) + +DictSrcRec := $(DirOut)/Dict$(Module)rec.cxx +DictObjRec := $(DictSrcRec:.cxx=.o) + + + +ObjBase := $(patsubst %.cxx,$(DirOut)/%.o,$(SrcBase)) $(DictObjBase) +ObjSim := $(patsubst %.cxx,$(DirOut)/%.o,$(SrcSim)) $(DictObjSim) +ObjRec := $(patsubst %.cxx,$(DirOut)/%.o,$(SrcRec)) $(DictObjRec) + + +DepFile := $(DirOut)/$(Module).depend + +ifeq ($(RootTarget),linuxicc) + Compiler :=icc + CompilerOpt :=-fpstkchk -I$(shell root-config --incdir) -I$(ALICE_ROOT)/include + LibOpt :=-g -shared -Wl +else + Compiler :=g++ + 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 + +ifdef ALIVERBOSE + Mute := +else + Mute :=@ +endif + +##### TARGETS ##### + +all: $(LibBase) $(LibSim) $(LibRec) +$(LibBase): $(ObjBase) + @echo "Creating $@" + $(Mute)$(Compiler) $(LibOpt) $^ -o $@ + +$(LibSim): $(ObjSim) + @echo "Creating $@" + $(Mute)$(Compiler) $(LibOpt) $^ -o $@ + +$(LibRec): $(ObjRec) + @echo "Creating $@" + $(Mute)$(Compiler) $(LibOpt) $^ -o $@ + +$(DepFile): $(HdrBase) $(HdrSim) $(HdrRec) + @[ -d $(DirOut) ] || mkdir -p $(DirOut) + @[ -d $(LIB_MY) ] || mkdir -p $(LIB_MY) + @touch $(DepFile) + @echo "Generating dependency $@" + $(Mute)rmkdepend -f$(DepFile) -p$(DirOut)/ -- $(CompilerOpt) -- $(SrcBase) $(SrcSim) $(SrcRec) 2>/dev/null + +$(DictSrcBase): $(HdrBase) + @echo "Generating $@" + $(Mute)rootcint -f $@ -c $(filter -I%,$(CompilerOpt)) $^ + +$(DictSrcSim): $(HdrSim) + @echo "Generating $@" + $(Mute)rootcint -f $@ -c $(filter -I%,$(CompilerOpt)) $^ + +$(DictSrcRec): $(HdrRec) + @echo "Generating $@" + $(Mute)rootcint -f $@ -c $(filter -I%,$(CompilerOpt)) $^ + +$(DictObjBase) : $(DictSrcBase) + @echo "Compiling $^" + $(Mute)$(Compiler) $(CompilerOpt) -I. -c $^ -o $@ + +$(DictObjSim) : $(DictSrcSim) + @echo "Compiling $^" + $(Mute)$(Compiler) $(CompilerOpt) -I. -c $^ -o $@ + +$(DictObjRec) : $(DictSrcRec) + @echo "Compiling $^" + $(Mute)$(Compiler) $(CompilerOpt) -I. -c $^ -o $@ + +show: + @echo "Base Headers: $(HdrBase)" + @echo "Base Sources: $(SrcBase)" + @echo "Base Objects: $(ObjBase)" + @echo "Base Dict: $(DictSrcBase)" + @echo -e "Base Library: $(LibBase)\n" + + @echo "Sim Headers: $(HdrSim)" + @echo "Sim Sources: $(SrcSim)" + @echo "Sim Objects: $(ObjSim)" + @echo -e "Sim Library: $(LibSim)\n" + + @echo "Rec Headers: $(HdrRec)" + @echo "Rec Sources: $(SrcRec)" + @echo "Rec Objects: $(ObjRec)" + @echo -e "Rec Library: $(LibRec)\n" + +spec: $(SrcBase) + @echo "^ $^" + @echo "@ $@" + @echo "< $<" + +clean: + @echo "Cleaning..." + $(Mute)rm -rf $(DirOut) $(LibBase) $(LibSim) $(LibRec) + +############################ cxx rule ######################################### +$(DirOut)/%.o : %.cxx + @echo $*.cxx + $(Mute)$(Compiler) $(CompilerOpt) -c $*.cxx -o $(DirOut)/$*.o +############################ Dependencies ##################################### + +-include $(DepFile) diff --git a/HMPID/HMPIDMenu.C b/HMPID/HMPIDMenu.C new file mode 100644 index 00000000000..16ccc7e6599 --- /dev/null +++ b/HMPID/HMPIDMenu.C @@ -0,0 +1,501 @@ +AliRun *a; AliStack *s; AliRunLoader *al; TGeoManager *g; //globals for easy manual manipulations +AliHMPID *r; AliLoader *rl; AliHMPIDParam *rp; +Bool_t isGeomType=kFALSE; + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void GetParam() +{ + isGeomType=!isGeomType; + if(g) delete g; if(rp) delete rp; //delete current TGeoManager and AliHMPIDParam + if(isGeomType) g=TGeoManager::Import("geometry.root"); + else g=TGeoManager::Import("misaligned_geometry.root"); + rp=AliHMPIDParam::Instance(); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RichMenu() +{ + TString status="Status: "; + if(gSystem->IsFileInIncludePath("galice.root")){ + status+="galice.root found"; + al=AliRunLoader::Open(); //try to open galice.root from current dir + if(gAlice) delete gAlice; //in case we execute this in aliroot delete default AliRun object + al->LoadgAlice(); a=al->GetAliRun(); //take new AliRun object from galice.root + rl=al->GetDetectorLoader("HMPID"); r=(AliHMPID*)a->GetDetector("HMPID"); //get HMPID object from galice.root + + status+=Form(" with %i event(s)",al->GetNumberOfEvents()); status+=(r)? " with HMPID": " without HMPID"; + }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(" ","print()" ,""); + pMenu->AddButton("Test" ,"Test()" ,"all test utilities"); + pMenu->AddButton(" ","GetParam()" ,""); + pMenu->AddButton("Quit" ,".q" ,"close session" ); + pMenu->Show(); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +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("Geo GUI" ,"geo();" ,"Shows geometry" ); + pMenu->AddButton("Browser" ,"new TBrowser;" ,"Start ROOT TBrowser" ); + pMenu->Show(); +}//menu() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void SimData() +{ + TControlBar *pMenu = new TControlBar("vertical","Sim",190,50); + pMenu->AddButton("Display ALL chambers" ,"ed();" , "Display Fast"); + pMenu->AddButton("HITS QA" ,"hqa()" ,"QA plots for hits: hqa()"); + + 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(); +} +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +void RawData() +{ + TControlBar *pMenu = new TControlBar("vertical","Raw",350,50); + pMenu->AddButton("ESD print" ,"ep();" ,"To print ESD info: ep()" ); + pMenu->AddButton("ESD QA" ,"eq();" ,"To draw ESD hists: eq()" ); + pMenu->AddButton("Clusters print" ,"cp();" ,"To print clusters: cp()" ); + pMenu->AddButton("Clusters QA" ,"cq();" ,"To draw clusters hists: cq()" ); + pMenu->AddButton("Print Matrix" ,"mp();" ,"To print prob matrix: mp()" ); + 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" ,"AliHMPIDParam::TestResp();" ,"Test AliHMPIDParam response methods" ); + pMenu->AddButton("Test transformation","AliHMPIDParam::TestTrans();","Test AliHMPIDParam transformation methods" ); + pMenu->AddButton("Test Recon" ,"rec();" ,"Test AliHMPIDRecon" ); + pMenu->Show(); +}//Test() +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +void doff(){ Printf("DebugOFF"); AliLog::SetGlobalDebugLevel(0);} +void don() { Printf("DebugON"); AliLog::SetGlobalDebugLevel(AliLog::kDebug);} + +void geo ( ) {gGeoManager->GetTopVolume()->Draw("ogl");} + +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 ( ) {AliHMPIDReconstructor::DigQA (al );} //digits QA plots for all events +void cp (Int_t evt=0 ) {r->CluPrint (evt); } //print clusters for requested event +void cq ( ) {AliHMPIDReconstructor::CluQA (al );} //clusters QA plots for all events + +void ep ( ) {AliHMPIDTracker::EsdQA(1); } +void eq ( ) {AliHMPIDTracker::EsdQA(); } +void mp (Double_t probCut=0.7 ) {AliHMPIDTracker::MatrixPrint(probCut);} + + +void t (Int_t evt=0 ) {AliHMPIDParam::Stack(evt);} +void tid (Int_t tid,Int_t evt=0) {AliHMPIDParam::Stack(evt,tid);} + + +Int_t nem (Int_t evt=0) {AliHMPIDParam::StackCount(kElectron ,evt);} //utility number of electrons +Int_t nep (Int_t evt=0) {AliHMPIDParam::StackCount(kPositron ,evt);} //utility number of positrons +Int_t nmup(Int_t evt=0) {AliHMPIDParam::StackCount(kMuonPlus ,evt);} //utility number of positive muons +Int_t nmum(Int_t evt=0) {AliHMPIDParam::StackCount(kMuonMinus ,evt);} //utility number of negative muons +Int_t npi0(Int_t evt=0) {AliHMPIDParam::StackCount(kPi0 ,evt);} //utility number of neutral pions +Int_t npip(Int_t evt=0) {AliHMPIDParam::StackCount(kPiPlus ,evt);} //utility number of positive pions +Int_t npim(Int_t evt=0) {AliHMPIDParam::StackCount(kPiMinus ,evt);} //utility number of negative pions +Int_t nk0 (Int_t evt=0) {AliHMPIDParam::StackCount(kK0 ,evt);} //utility number of neutral kaons +Int_t nkp (Int_t evt=0) {AliHMPIDParam::StackCount(kKPlus ,evt);} //utility number of positive kaons +Int_t nkm (Int_t evt=0) {AliHMPIDParam::StackCount(kKMinus ,evt);} //utility number of negative kaons +Int_t npp (Int_t evt=0) {AliHMPIDParam::StackCount(kProton ,evt);} //utility number of protons +Int_t npm (Int_t evt=0) {AliHMPIDParam::StackCount(kProtonBar ,evt);} //utility number of antiprotons +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void tst() +{ + Int_t ch=3; + TClonesArray hitLst("AliHMPIDHit"); + TClonesArray sdiLst("AliHMPIDDigit"); + TObjArray digLst; for(Int_t i=0;i<7;i++) digLst.AddAt(new TClonesArray("AliHMPIDDigit"),i); + TClonesArray cluLst("AliHMPIDCluster"); + + Int_t iHitCnt=0; new(hitLst[iHitCnt++]) AliHMPIDHit(ch,200e-9,kProton,1, 8.40 , 60.14); //c,e,pid,tid,xl,yl +// new(hitLst[iHitCnt++]) AliHMPIDHit(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(""); + AliHMPIDv1::Hit2Sdi(&hitLst,&sdiLst); Printf("SDI------DIG---------SDI--------SDI------SDI------SDI");sdiLst.Print();Printf(""); + AliHMPIDDigitizer::Sdi2Dig(&sdiLst,&digLst); Printf("DIG------DIG---------DIG--------DIG------DIG------DIG");digLst.Print();Printf(""); + AliHMPIDReconstructor::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=AliHMPIDDigit::SizeAllX(),y=AliHMPIDDigit::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()*AliHMPIDDigit::SizeAllX(); //101.59; + Double_t y=gRandom->Rndm()*2*AliHMPIDDigit::SizePcY();//38.06; + + + Double_t ckovMax=0.75,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("AliHMPIDCluster"); + 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++]) AliHMPIDCluster(1,x,y,200); //add mip cluster + +// for(int j=0;j<30;j++){ //add bkg photons +// Float_t bkgX=gRandom->Rndm()*AliHMPIDDigit::SizeAllX(); +// Float_t bkgY=gRandom->Rndm()*AliHMPIDDigit::SizeAllY(); +// pBkgMap->SetPoint(iCluCnt,bkgX,bkgY); new((*pCluLst)[iCluCnt++]) AliHMPIDCluster(1,bkgX,bkgY,35); +// } + + + + + AliHMPIDRecon rec; rec.SetTrack(th,ph,x,y); + AliHMPIDReconOld old; old.SetTrack(th,ph,x,y); + + TVector2 pos; + for(int i=0;iRndm()*2*TMath::Pi(),pos); //add photons + if(AliHMPIDDigit::IsInDead(pos.X(),pos.Y())) continue; + pPhoMap->SetPoint(iCluCnt,pos.X(),pos.Y()); new((*pCluLst)[iCluCnt++]) AliHMPIDCluster(1,pos.X(),pos.Y(),35); + } + + for(int i=0;iGetEntries();i++){ + AliHMPIDCluster *pClu=(AliHMPIDCluster*)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.TracePhot(ckovRec,j*0.0628,pos); pRing->SetPoint(j,pos.X(),pos.Y());} + for(int j=0;j<100;j++){rec.TracePhot(ckovOld,j*0.0628,pos); pOld->SetPoint(j,pos.X(),pos.Y());} + + new TCanvas; AliHMPIDDigit::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() + +AliHMPIDRecon rec; AliHMPIDReconOld 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.TracePhot(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 AliHMPID::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 + AliHMPIDHit *pHit = (AliHMPIDHit*)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/HMPID/HMPIDTestShuttle.C b/HMPID/HMPIDTestShuttle.C new file mode 100644 index 00000000000..2fb1f0eb93a --- /dev/null +++ b/HMPID/HMPIDTestShuttle.C @@ -0,0 +1,62 @@ +void RichTestShuttle() +{ +// this macro is to simulate the functionality of SHUTTLE. +// Here the list of DCS aliases is created and packed in TMap of structure "alias name" - TObjArray of AliDCSValue + TMultiGraph *pMG[7]; for(Int_t i=0;i<7;i++) {pMG[i]=new TMultiGraph; pMG[i]->SetTitle("T,grad C;time");} + TGraph *pGr[21];for(Int_t i=0;i<21;i++){pGr[i]=new TGraph; pGr[i]->SetMarkerStyle(i%3+24); pGr[i]->SetMarkerColor(i%3+2); pMG[i/3]->Add(pGr[i]);} + TMap *pDcsMap = new TMap; pDcsMap->SetOwner(1); //DCS archive map + + for(Int_t iCh=0;iCh<7;iCh++){//chambers loop + for(Int_t iRad=0;iRad<3;iRad++){//radiators loop + TObjArray* pValLst = new TObjArray; pValLst->SetOwner(1); + Int_t iPoint=0; + for (Int_t time=0;time<1000;time+=50) { + AliDCSValue* pVal = new AliDCSValue(Float_t(iCh*3+iRad+0.1*gRandom->Gaus()), time); //sample new data point + pValLst->Add(pVal); //add it to the list + pGr[3*iCh+iRad]->SetPoint(iPoint++,time,pVal->GetFloat()); //and also to the graph + } + pDcsMap->Add(new TObjString(Form("HMP_DET/HMP_MP%i/HMP_MP%i_LIQ_LOOP.actual.sensors.Rad%iIn_Temp",iCh,iCh,iRad)),pValLst); //add new list to the map + }//radiators loop + }//chambers loop + + + AliCDBManager::Instance()->SetDefaultStorage("local://$HOME/tstCDB"); // initialize location of CDB + + gSystem->Load("libTestShuttle.so"); + Int_t iRun=1; + AliTestShuttle* pShuttle = new AliTestShuttle(iRun,0,100000); + pShuttle->SetDCSInput(pDcsMap); //DCS map + AliPreprocessor* pp = new AliHMPIDPreprocessor(pShuttle); //actual ipreprocessor is created here + pShuttle->Process(); //run SHUTTLE simulator + delete pp; + + + AliCDBEntry *pTempEn=AliCDBManager::Instance()->Get("HMPID/DCS/RadTemp",iRun); + if(!pTempEn) {Printf("ERROR file is not retrieved!!!");return;} + + TObjArray *pTempLst=(TObjArray*)pTempEn->GetObject(); TF1 *pRad0,*pRad1,*pRad2; + TCanvas *pC=new TCanvas; pC->Divide(3,3); + for(Int_t iCh=0;iCh<7;iCh++){//chambers loop + if(iCh==6) pC->cd(1); if(iCh==5) pC->cd(2); //this is just to see the input + if(iCh==4) pC->cd(4); if(iCh==3) pC->cd(5); if(iCh==2) pC->cd(6); + if(iCh==1) pC->cd(8); if(iCh==0) pC->cd(9); + pMG[iCh]->Draw("ap"); pMG[iCh]->GetXaxis()->SetTimeDisplay(kTRUE); + pRad0=(TF1*)pTempLst->At(iCh*3+0); pRad0->Draw("same"); + pRad1=(TF1*)pTempLst->At(iCh*3+1); pRad1->Draw("same"); + pRad2=(TF1*)pTempLst->At(iCh*3+2); pRad2->Draw("same"); + } + + AliCDBEntry *pIdxEn=AliCDBManager::Instance()->Get("HMPID/DCS/MeanIdx",iRun); + if(!pIdxEn) {Printf("ERROR file is not retrieved!!!");return;} + + TObjArray *pIdxLst=(TObjArray*)pIdxEn->GetObject(); TF1 *pRad0,*pRad1,*pRad2; + TCanvas *pC=new TCanvas("c2","Ref Idx"); pC->Divide(3,3); + for(Int_t iCh=0;iCh<7;iCh++){//chambers loop + if(iCh==6) pC->cd(1); if(iCh==5) pC->cd(2); //this is just to see the input + if(iCh==4) pC->cd(4); if(iCh==3) pC->cd(5); if(iCh==2) pC->cd(6); + if(iCh==1) pC->cd(8); if(iCh==0) pC->cd(9); + pRad0=(TF1*)pIdxLst->At(iCh*3+0); pRad0->Draw(); pRad0->GetXaxis()->SetTimeDisplay(kTRUE); pRad0->GetYaxis()->SetRangeUser(1.28,1.3); + pRad1=(TF1*)pIdxLst->At(iCh*3+1); pRad1->Draw("same"); + pRad2=(TF1*)pIdxLst->At(iCh*3+2); pRad2->Draw("same"); + } +}//Test() diff --git a/HMPID/HMPIDbaseLinkDef.h b/HMPID/HMPIDbaseLinkDef.h new file mode 100644 index 00000000000..3fe943c0cd8 --- /dev/null +++ b/HMPID/HMPIDbaseLinkDef.h @@ -0,0 +1,11 @@ +#ifdef __CINT__ +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; +#pragma link C++ class AliHMPIDHelix+; +#pragma link C++ class AliHMPIDDigit+; +#pragma link C++ class AliHMPIDHit+; +#pragma link C++ class AliHMPIDCluster+; +#pragma link C++ class AliHMPIDParam+; +#pragma link C++ class AliHMPID+; +#endif diff --git a/HMPID/HMPIDrecLinkDef.h b/HMPID/HMPIDrecLinkDef.h new file mode 100644 index 00000000000..35ddeedac67 --- /dev/null +++ b/HMPID/HMPIDrecLinkDef.h @@ -0,0 +1,9 @@ +#ifdef __CINT__ +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; +#pragma link C++ class AliHMPIDReconstructor+; +#pragma link C++ class AliHMPIDTracker+; +#pragma link C++ class AliHMPIDRecon+; +#pragma link C++ class AliHMPIDPreprocessor+; +#endif diff --git a/HMPID/HMPIDsimLinkDef.h b/HMPID/HMPIDsimLinkDef.h new file mode 100644 index 00000000000..c54839b8c83 --- /dev/null +++ b/HMPID/HMPIDsimLinkDef.h @@ -0,0 +1,8 @@ +#ifdef __CINT__ +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; +#pragma link C++ class AliHMPIDv0+; +#pragma link C++ class AliHMPIDv1+; +#pragma link C++ class AliHMPIDDigitizer+; +#endif diff --git a/HMPID/MakeHMPIDFullMisAlignment.C b/HMPID/MakeHMPIDFullMisAlignment.C new file mode 100644 index 00000000000..dad1e742059 --- /dev/null +++ b/HMPID/MakeHMPIDFullMisAlignment.C @@ -0,0 +1,45 @@ +void MakeHMPIDFullMisAlignment(){ + // Create TClonesArray of full misalignment objects for HMPID + // + Float_t sigmaTrans=0.1; // 1mm + Float_t sigmaRot=0.001*180/TMath::Pi(); // 1 mrad + Float_t dX, dY, dX; Float_t dPsi, dTheta, dPhi; //displacements + + TClonesArray *pCA = new TClonesArray("AliAlignObjMatrix",10); + + TRandom *pRnd = new TRandom(4357); + + AliAlignObjMatrix o; + + Int_t idHMPID = AliAlignObj::kHMPID; + for (Int_t iCh = 0; iCh < 7; iCh++) { + dX = (pRnd->Uniform()-0.5)*sigmaTrans; dY = (pRnd->Uniform()-0.5)*sigmaTrans; dZ = (pRnd->Uniform()-0.5)*sigmaTrans; + dPsi = (pRnd->Uniform()-0.5)*sigmaRot; dTheta = (pRnd->Uniform()-0.5)*sigmaRot; dPhi = (pRnd->Uniform()-0.5)*sigmaRot; + new((*pCA)[iCh]) AliAlignObjMatrix(AliAlignObj::SymName(idHMPID,iCh), + AliAlignObj::LayerToVolUID(idHMPID,iCh),dX,dY,dZ,dPsi,dTheta,dPhi,kTRUE); + } + +// pCA->Print(); + + if(!gSystem->Getenv("$TOCDB")){ + // save on file + TFile f("HMPIDfullMisalignment.root","RECREATE"); + if(!f) cerr<<"cannot open file for output\n"; + f.cd(); + f.WriteObject(pCA,"HMPIDAlignObjs","kSingleKey"); + f.Close(); + }else{ + // save in CDB storage + const char* Storage = gSystem->Getenv("$STORAGE"); + AliCDBManager* cdb = AliCDBManager::Instance(); + AliCDBStorage* storage = cdb->GetStorage(Storage); + AliCDBMetaData *pMeta= new AliCDBMetaData(); + pMeta->SetResponsible("HMPID Expert"); + pMeta->SetComment("Full alignment objects for HMPID produced with sigmaTrans=1mm and sigmaRot=1mrad"); + pMeta->SetAliRootVersion(gSystem->Getenv("$ARVERSION")); + AliCDBId id("HMPID/Align/Data",0,9999999); + storage->Put(pCA,id,pMeta); + } + + pCA->Delete(); +} diff --git a/HMPID/MakeHMPIDResMisAlignment.C b/HMPID/MakeHMPIDResMisAlignment.C new file mode 100644 index 00000000000..3de1a7aa5b2 --- /dev/null +++ b/HMPID/MakeHMPIDResMisAlignment.C @@ -0,0 +1,44 @@ +void MakeHMPIDResMisAlignment(){ + // Create TClonesArray of residual misalignment objects for HMPID + // + Float_t sigmaTrans=0.1; // 1mm + Float_t sigmaRot=0.001*180/TMath::Pi(); // 1 mrad + Float_t dX, dY, dX; Float_t dPsi, dTheta, dPhi; //displacements + + TClonesArray *pCA = new TClonesArray("AliAlignObjMatrix",10); + + TRandom *pRnd = new TRandom(4357); + + AliAlignObjMatrix o; + + Int_t idHMPID = AliAlignObj::kHMPID; + for (Int_t iCh = 0; iCh < 7; iCh++) { + dX = (pRnd->Uniform()-0.5)*sigmaTrans; dY = (pRnd->Uniform()-0.5)*sigmaTrans; dZ = (pRnd->Uniform()-0.5)*sigmaTrans; + dPsi = (pRnd->Uniform()-0.5)*sigmaRot; dTheta = (pRnd->Uniform()-0.5)*sigmaRot; dPhi = (pRnd->Uniform()-0.5)*sigmaRot; + new((*pCA)[iCh]) AliAlignObjMatrix(AliAlignObj::SymName(idHMPID,iCh),AliAlignObj::LayerToVolUID(idHMPID,iCh),dX,dY,dZ,dPsi,dTheta,dPhi,kTRUE); + } + +// pCA->Print(); + + if(!gSystem->Getenv("$TOCDB")){ + // save on file + TFile f("HMPIDresidualMisalignment.root","RECREATE"); + if(!f) cerr<<"cannot open file for output\n"; + f.cd(); + f.WriteObject(pCA,"HMPIDAlignObjs","kSingleKey"); + f.Close(); + }else{ + // save in CDB storage + const char* Storage = gSystem->Getenv("$STORAGE"); + AliCDBManager* cdb = AliCDBManager::Instance(); + AliCDBStorage* storage = cdb->GetStorage(Storage); + AliCDBMetaData *pMeta= new AliCDBMetaData(); + pMeta->SetResponsible("HMPID Expert"); + pMeta->SetComment("Residual alignment objects for HMPID produced with sigmaTrans=1mm and sigmaRot=1mrad"); + pMeta->SetAliRootVersion(gSystem->Getenv("$ARVERSION")); + AliCDBId id("HMPID/Align/Data",0,9999999); + storage->Put(pCA,id,pMeta); + } + + pCA->Delete(); +} diff --git a/HMPID/api.txt b/HMPID/api.txt new file mode 100644 index 00000000000..a84e21dcbc8 --- /dev/null +++ b/HMPID/api.txt @@ -0,0 +1,315 @@ +How to open session: + use static method AliRunLoader::Open("galice.root","AlicE","update") or just AliRunLoader::Open() for defaults. + Returns pointer to AliRunLoader on success or fatal termination on error +How to get total number of events in galice.root: + AliRunLoader::GetNumberOfEvents() (or AliRun::GetEventsPerRun() using f.e. gAlice deprecated) +How to get pointer to HMPID: + AliRunLoader()->GetAliRun()->GetDetector("HMPID") but before one needs to AliRunLoade()->Set +How to avoid using gAlice: + detector->GetLoader()->GetRunLoader()->GetAliRun() returns gAlice global pointer. +How to retrieve pointer to alice run loader: + use pHMPID->GetLoader()->GetRunLoader() (all detector classes inherit from AliDetector which has GetLoader()) + use method AliRun::GetRunLoader for gAlice (deprecated) +How to get pointers to different root trees: + TreeE belongs to AliRunLoader, available after AliRunLoader::LoadHeader() + TreeK belongs to AliRunLoader, available after AliRunLoader::LoadKinematics() + TreeH belongs to AliLoader , available after AliLoader::LoadHits() + TreeS belongs to AliLoader , available after AliLoader::LoadSDigits() + TreeD belongs to AliLoader , available after AliLoader::LoadDigits() + TreeR belongs to AliLoader , available after AliLoader::LoadRecPoints() + all methods return 0 on success. +How to get event of interest: + AliRunLoader::GetEvent(event_number) returns 0 on success +How to deal with the stack of particles? + - first of all, the stack includes primary as well as secondary particles + - pointer to the stack is taken: + AliRun::Stack() (global gAlice of type AliRun - deprecated way to do) + AliRunLoader::Stack() but before one needs to load event header by AliRunLoader::LoadHeader() otherwise both methods return 0. + Moreover loading header gives the information about number of particles only. + To retrieve the list of particle one also needs to load kinematics by AliRunLoader::LoadKinematics() + - total amount of particles in stack for a given event: + AliStack::GetNtrack() + AliRun::GetEvent() (after LoadHeader()) + - total amount of primary particles in stack for a given event (after LoadHeader()): + AliStack::GetNprimary() +How to retrieve hits: + Hits are stored on primary by primary basis. Hits for the given primary is TClonesArray. + To retrieve all hits one needs to do: + -initialize the root tree and containers: pRich->GetLoader()->LoadHits(); (AliLoader::LoadHits() returns 0 on success) + -read number of entries in TreeH: pRich->GetLoader()->TreeH()->GetEntries() + -then for each entry: pRich->GetLoader()->TreeH()->GetEntry(i) +How to retrieve sdigits? + Sdigits stored in tree S with the branch of TClonesArray, all sdigits in a single TClonesArray + So the tree has only one entry. + One needs to say: + -pRich->GetLoader()->LoadSDigits(); this one open file, get the tree and invoke AliHMPID::SetTreeAddress() +How to retrieve digits? + Digits stored in tree D with the 7 branches of TClonesArray, one per chamber, all digits of a given chamber in a single TClonesArray + So the tree has only one entry. + -One needs to say: + pRich->GetLoader()->LoadDigits(); this one opens file, gets the tree and invoke AliHMPID::SetTreeAddress() which in turn corresponds + branches of the tree to the digits containers in memory. There are 7 containers, one per chamber, all of them belong to AliHMPID. + -Then one needs to take the tree entry (only one) to the memory: + pRich->GetLoader()->TreeD()->GetEntry(0) + -Finally pRich->Digits(chamber_number) returns the pointer to TClonesArray of AliHMPIDdigit +What are the debug methods avail: + AliLog::SetGlobalDebugLevel(AliLog::kDebug) +How to get info for a given particle number: + Header and Kinematics trees must be loaded, then possible to retrieve pointer to Stack of particles + Int_t AliRunLoader::LoadHeader(); Int_t AliRunLoader::LoadKinematics() + AliStack *AliRunLoader::Stack() + TParticle *AliStack::Particle(tid) + TParticle::Print() +How to deal with AliRunDigitizer: + AliRunDigitizer::Exec() just call AliRunDigitizer::Digitize() +What are the meanings of different VMC flags: + gMC->IsTrackAlive() + gMC->IsTrackStop() + gMC->IsTrackDisappeared() +How to get pad number for a local position: + use static TVector AliHMPIDParam::Loc2Pad(TVector2 position); +Why list of chambers belongs to AliHMPIDParam: + +How to check if a given stack particle is primary: + Stack is TClonesArray of TParticle. TParticle::GetMother(0) returns -1 if it's primary (no mother) +How to loop over all possible object: + for(Int_t iEventN=0;iEventN < GetLoader()->GetRunLoader()->GetAliRun()->GetEventsPerRun();iEventN++){//events loop + for(Int_t iEntryN=0;iEntryN < GetLoader()->TreeH()->GetEntries();iEntryN++){//TreeH loop + GetLoader()->TreeH()->GetEntry(iEntryN);//get current entry (prim) + for(Int_t iHitN=0;iHitNGetEntries();iHitN++){//hits loop + AliVHMPIDHit *pHit=(AliVHMPIDHit*)Hits()->At(iHitN);//get current hit + + }//hits loop + }//TreeH loop + }//events loop + + +HMPID full simulation-reconstruction sequence + +hits->sdigit: + Responsible method is AliHMPID::Hits2SDigits + One hit may affect one or more pads. + Hit position is taken on the anode wires plane as the most of avalanche is developed there. + This position is not directly available, track intersections with entrance and exit of amplification gap are only stored. + So the position in the middle of the gap is calculated as average out of pHit->In() and pHit->Out() positions. + Then, total charge collected for this hit is calculated by AliHMPIDParam::Hit2Qdc. + Area of disintegration is a list of pads affected by current hit. This is a parameter of Mathienson +sdigits->digits: + The necessety of sdigits is dictated by the fact that transport engine transports tracks in a continuous sequence track by track. + It means that it may happen that the same pad is affected by few tracks. But this might be known only after the transport of full event is finished. + +digits->clusters + A set of neighboring digits compose cluster. The aim of this transformation is to construct a list of clusters out of digits list. + The calling sequence is: + AliReconstruction::Run() + + AliHMPIDReconstructor::Reconstruct() creates an empty clusters list, loops on chambers, retrieves a list of digits for a given chamber, gives it to the method Dig2Clu() and finally serializes + the list + + AliHMPIDReconstructor::Dig2Clu() which knows no details about + + +clusters+tracks->theta cerenkov + + + + + + + + + + + +Generalized structure of AliReconstruction: + +Run() +{ + if(there is galice.root) <-| + AliRunLoader::Open(....) | + else | this is done in InitRunLoader() + if(raw data process requested) | + create galice.root on the base of AliRawReader::NextEvent <-| + + for(all detectors){ <-| + if(detector not selected to run) skip this detector | this is done in RunLocalReconstruction() + reconstructor=get detector's reconstructor | + | + if(detector HasLocalReconstruction) skip this detector | IMPORTANT! if HasLocalReconstruction() returns YES use RunLocalEventReconstruction instead + if(run upon raw data) | + reconstructor->Reconstruct(fRunLoader, fRawReader); | + else | <- this approach is currently used by HMPID as all branches are mounted in AliHMPID.cxx + reconstructor->Reconstruct(fRunLoader); | + } <-| + + for(all events){ + + for(all detectors){ | + if(detector not selected to run) skip this detector | + reconstructor=get detector's reconstructor | + loader=get detector's loader | this is done in RunLocalEventReconstruction() + if(raw data process requested and detector HasDigitConversion){ | + loader->LoadDigits("update"); | open file and invoke detector->SetTreeAddress(); + loader->CleanDigits(); | + loader->MakeDigitsContainer(); | create tree + reconstructor->Reconstruct(fRawReader,loader->TreeD()); | expected to fill TreeD out of raw reader + loader->WriteDigits("overwrite"); | + loader->UnloadDigits(); | + } | + if(detector do not HasLocalReconstruction) skip this detector | IMPORTANT! assumed that this detector is already processed in RunLocalReconstruction() + loader->LoadRecPoints("update"); | + loader->CleanRecPoints(); | + loader->MakeRecPointsContainer(); | + if(fRawReader && reconstructor do not HasDigitConversion()){ | + reconstructor->Reconstruct(fRawReader, loader->TreeR()); | expected to fill TreeR out of raw reader + }else{ | + loader->LoadDigits("read"); | + reconstructor->Reconstruct(loader->TreeD(),loader->TreeR()); | the only operations inside are pDigTree->GetEntry(0) and pCluTree->Fill(); + loader->UnloadDigits(); | + } | + loader->WriteRecPoints("OVERWRITE"); | + loader->UnloadRecPoints(); | + }//detectors loop | + + }//events loop +} + + +HMPID calibration and alignment. + +Abstract +HMPID calibration and alignment strategy is described with emphasis put on those aspects of the procedure which are relevant for reconstruction and thus the final detector +figure of merit. In particular, the refractive index calibration technique based on mass plot shifts analysis and chamber alignment with respect to core detectors +are explained in details. External sources of calibration and alignment data are also mentioned as well as the way HMPID intends to handle those data, including initial CDB +creator. + +Calibration. +Looking on HMPID chamber structure, full description of which is available elsewhere (ref RichTDR), easy to compile the table of all possible parameters affecting reconstruction. +The first one of major importance is a freon refractive index. Although the full optical path visible by photons includes freon vessel, proximity and amplification gaps filled +with methane and quartz window separating above mentioned volumes, only freon refractive index is subject for calibration. Refractive index of SiO2 window is not practically +affected by any external parameters, while influence of methane temperature to it's refractive index is negligible. So it's enough to measure there optical curves just once. +In the rest, the only changeable parameter is refractive index of freon. Temperature influence on freon refractive index was measured experimentally. The parametrization +found to be: + n=n0-0.0005(T-20) where T is freon temperature in degrees Celsius + n0=Sqrt(1+ 0.554*lamda^2/(lamda^2-5796)) where lamda is photon wavelength in nm taken at 20 degrees Celsius +Preliminary, the parametrization itself is considered to be permanent one. The only parameter to store and retrieve is freon temperature. Since this value is available from +DCS DB and expected to be served by a SHUTTLE program which is not yet ready, the following temporarily solution has been adopted. +In local CDB storage (default directory is $ALICE_ROOT) two versions of freon refractive index are written by external macro RichCdb.C : +Run0_0_v0_s0.root contains DiMauro's parametrization and the temperature is set to 20 degrees. To be used as default for simulation and reconstruction. +Run0_0_v0_s1.root contains DiMauro's parametrization and the temperature is set to 50 degrees. To be used in special uncalibrated reconstruction to test calibration procedure. +Both of them are valid in run range from run number 0 to run number 0, thus in no way affecting any normal operations. + +Refractive index of freon (C6F14) is taken in AliHMPIDRecon for 3 different photon energies by means of 2 methods: Set + + + +Alignment. +Information about detector position and orientation is needed during reconstruction phase. This information affects track-cluster matching procedure, the relevant peace of +code comes to AliHMPIDTracker::PropogateBack(). Matching procedure consists in prolongation of the track reconstructed in core detectors up to each HMPID chamber plane in +a sequence. The plane used is the entrance to HMPID radiators. If the intersection exists and inside the sensitive area, the point of intersection is to be transformed to HMPID +local reference system. Note, that in this check, the dead zones in-between radiators are not taken into account. This operation requiring MARS to LORS transformations is done +in AliHMPIDHelix::RichIntersection(). Plane to be intersected is defined by a point belonging to that plane served by AliHMPIDParam::Center(ChamberNumber) and a vector normal +to the plane served by AliHMPIDParam::Norm(ChamberNumber). Transformations itself are done in AliHMPIDParam::Mars2Lors() and AliHMPIDParam::Lors2Mars(). Internaly in AliHMPIDParam, +each chamber is represented by TGeoHMatrix. It's worth to stress again that geometry related operations are needed to be done for 3 different planes per chamber, namely entrance +to radiator, anode wires plane and photocathode plane. So AliHMPIDParam sustains 7*3=21 planes. Also important to say, that direct usage of TGeoHMatrix::MasterToLocal() +and vice versa is not possible due to special nature of HMPID LORS. According to the decision made about 3 years ago, HMPID local reference system is centered in low left +hand corner of the chamber if one looks from outside to direction pointing to intersection point. +So the most obvious candidate for alignable objects to be stored are these 21 TGeoHMatrix objects. +The approach suggested in AliAlignObj is not quite feasible mainly due to the fact it relays on incrementing procedure using import from geometry.root. HMPID geometry is defined +in a way that there is no volumes exactly corresponding to the HMPID planes. + +Geometry of HMPID chambers. +After the decision to rotate the whole HMPID setup from 12 o'clock position to 2 o'clock position we have the following situation: + +Theta = 109.5 degrees for chambers 1,3 +Theta = 90.0 degrees for chambers 2,4,6 +Theta = 70.5 degrees for chambers 5,7 + +Phi = 50.0 degrees for chambers 6,7 +Phi = 30.0 degrees for chambers 3,4,5 +Phi = 10.0 degrees for chambers 1,2 + + +Old parametrization by AliHMPIDChamber: +HMPID chamber 1 (454.877118 , 80.207109 , -163.565361)(rho,theta,phi)=(490.0,109.5,10.0) +HMPID chamber 2 (482.555799 , 85.087607 , 0.000000)(rho,theta,phi)=(490.0, 90.0,10.0) +HMPID chamber 3 (400.012224 , 230.947165 , -163.565361)(rho,theta,phi)=(490.0,109.5,30.0) +HMPID chamber 4 (424.352448 , 245.000000 , 0.000000)(rho,theta,phi)=(490.0, 90.0,30.0) +HMPID chamber 5 (400.012224 , 230.947165 , 163.565361)(rho,theta,phi)=(490.0, 70.5,30.0) +HMPID chamber 6 (314.965929 , 375.361777 , 0.000000)(rho,theta,phi)=(490.0, 90.0,50.0) +HMPID chamber 7 (296.899953 , 353.831585 , 163.565361)(rho,theta,phi)=(490.0, 70.5,50.0) + +New parametrization by TGeoHMatrix: perfect geometry, no misalignment +HMPID 0 + -0.328736 -0.173648 0.928321 Tx = 454.877118 + -0.057965 0.984808 0.163688 Ty = 80.207109 + -0.942641 0.000000 -0.333807 Tz = -163.565361 +HMPID 1 + 0.000000 -0.173648 0.984808 Tx = 482.555799 + 0.000000 0.984808 0.173648 Ty = 85.087607 + -1.000000 0.000000 0.000000 Tz = 0.000000 +HMPID 2 + -0.289085 -0.500000 0.816351 Tx = 400.012224 + -0.166903 0.866025 0.471321 Ty = 230.947165 + -0.942641 0.000000 -0.333807 Tz = -163.565361 +HMPID 3 + 0.000000 -0.500000 0.866025 Tx = 424.352448 + 0.000000 0.866025 0.500000 Ty = 245.000000 + -1.000000 0.000000 0.000000 Tz = 0.000000 +HMPID 4 + 0.289085 -0.500000 0.816351 Tx = 400.012224 + 0.166903 0.866025 0.471321 Ty = 230.947165 + -0.942641 0.000000 0.333807 Tz = 163.565361 +HMPID 5 + 0.000000 -0.766044 0.642788 Tx = 314.965929 + 0.000000 0.642788 0.766044 Ty = 375.361777 + -1.000000 0.000000 0.000000 Tz = 0.000000 +HMPID 6 + 0.214567 -0.766044 0.605918 Tx = 296.899953 + 0.255711 0.642788 0.722105 Ty = 353.831585 + -0.942641 0.000000 0.333807 Tz = 163.565361 + + +Map of all HMPID 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) +| 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 6 42.68| | 42.78 5 42.78| +------------------------------- ------------------------------- + +_______________________________ _______________________________ _______________________________ +| 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| +| | | | | | +| 498.00 | | 498.00 | | 498.00 | +| 70.50 | | 90.00 | | 109.50 | +| 30.00 | | 30.00 | | 30.00 | +| | | | | | +| 506.21 506.21| | 506.21 506.21| | 506.21 506.21| +| 63.26 78.07| | 82.59 97.41| | 101.93 116.74| +| 21.98 4 22.68| | 22.78 3 22.78| | 37.32 2 38.02| +------------------------------- ------------------------------- ------------------------------- + + _______________________________ _______________________________ + | 506.21 506.21| | 506.21 506.21| + | 82.59 97.41| | 101.93 116.74| + | 17.22 17.22| | 17.32 18.02| + | | | | + | 498.00 | | 498.00 | + | 90.00 | | 109.50 | + | 10.00 | | 10.00 | + | | | | + | 506.21 506.21| | 506.21 506.21| + | 82.59 97.41| | 101.93 116.74| + | 2.78 1 2.78| | 2.68 0 1.98| + ------------------------------- ------------------------------- + diff --git a/HMPID/libHMPIDbase.pkg b/HMPID/libHMPIDbase.pkg new file mode 100644 index 00000000000..65c4057cda7 --- /dev/null +++ b/HMPID/libHMPIDbase.pkg @@ -0,0 +1,4 @@ +SRCS:= AliHMPIDHelix.cxx AliHMPIDHit.cxx AliHMPIDDigit.cxx AliHMPIDCluster.cxx AliHMPIDParam.cxx AliHMPID.cxx + +HDRS:= $(SRCS:.cxx=.h) +DHDR:= HMPIDbaseLinkDef.h diff --git a/HMPID/libHMPIDrec.pkg b/HMPID/libHMPIDrec.pkg new file mode 100644 index 00000000000..b25ca000a93 --- /dev/null +++ b/HMPID/libHMPIDrec.pkg @@ -0,0 +1,4 @@ +SRCS:= AliHMPIDReconstructor.cxx AliHMPIDTracker.cxx AliHMPIDRecon.cxx AliHMPIDPreprocessor.cxx + +HDRS:= $(SRCS:.cxx=.h) +DHDR:= HMPIDrecLinkDef.h diff --git a/HMPID/libHMPIDsim.pkg b/HMPID/libHMPIDsim.pkg new file mode 100644 index 00000000000..f46d1fc772f --- /dev/null +++ b/HMPID/libHMPIDsim.pkg @@ -0,0 +1,4 @@ +SRCS:= AliHMPIDv0.cxx AliHMPIDv1.cxx AliHMPIDDigitizer.cxx + +HDRS:= $(SRCS:.cxx=.h) +DHDR:= HMPIDsimLinkDef.h diff --git a/HMPID/red.C b/HMPID/red.C new file mode 100644 index 00000000000..3470a99da54 --- /dev/null +++ b/HMPID/red.C @@ -0,0 +1,49 @@ +red() +{ + gSystem->Load("libMinuit.so"); + gSystem->Load("libVMC.so"); + gSystem->Load("libESD.so"); + gSystem->Load("libSTEER.so"); + gSystem->Load("libCDB.so"); + + gSystem->Load("libGed.so"); + gSystem->Load("libRGL.so"); + gSystem->Load("libGeom.so"); + gSystem->Load("libVMC.so"); + + gSystem->Load("libReve.so"); + + gSystem->Load("libHMPIDbase.so"); + gSystem->Load("libHMPIDsim.so"); + gSystem->Load("libHMPIDrec.so"); + + TGeoManager::Import("geometry.root"); + + AliHMPIDParam *pParam=AliHMPIDParam::Instance(); + + AliRunLoader *pAL=AliRunLoader::Open(); pAL->LoadHits ("HMPID"); TTree *pHitT=pAL->GetTreeH("HMPID", false); + pAL->LoadDigits("HMPID"); TTree *pDigT=pAL->GetTreeD("HMPID", false); + + Reve::PointSet *pHitPnt=new Reve::PointSet("Hits")); + TPolyMarker3D *pDigPnt=new TPolyMarker3D; pDigPnt->SetName("Digits"); pDigPnt->SetMarkerColor(kGreen);iPntCnt=0; + + TPointSelector ps(pHitT,pHitPnt,"fX:fY:fZ",""); ps.Select(); + + TClonesArray *pDigLst=new TClonesArray("AliHMPIDDigit"); //this is tmp dig list per chamber + + for(Int_t iCh=0;iCh<7;iCh++){ + pDigT->SetBranchAddress(Form("HMPID%i",iCh+1),&pDigLst); + pDigT->GetEntry(0); + for(Int_t iDig=0;iDigGetEntries();iDig++){ + AliHMPIDDigit *pDig=(AliHMPIDDigit*)pDigLst->At(iDig); + TVector2 lors=pParam->Pad2Loc(pDig->PadX(),pDig->PadY()); + TVector3 mars=pParam->Lors2Mars(iCh,lors.X(),lors.Y()); + pDigPnt->SetPoint(iPntCnt++,mars.X(),mars.Y(),mars.Z()); + }//digits loop for chamber + }//chambers loop + + if(!gReve) new Reve::RGTopFrame(0,0,0,2); + gReve->AddGlobalRenderElement(new Reve::RenderElementObjPtr(pDigPnt)); + gReve->AddRenderElement(pHitPnt); + gReve->Redraw3D(); +} -- 2.43.5