//-------------------------------------------------------------------------- // File and Version Information: // $Id: FsmTpc.cc,v 1.9 2007/05/24 08:07:40 klausg Exp $ // // Description: // Class FsmTpc // // Implementation of the TPC for the FastSim // // This software was developed for the PANDA collaboration. If you // use all or part of it, please give an appropriate acknowledgement. // // Author List: // Klaus Goetzen Original Author // // Copyright Information: // Copyright (C) 2006 GSI // //------------------------------------------------------------------------ //----------------------- // This Class's Header -- //----------------------- #include "PndFsmTpc.h" //------------- // C Headers -- //------------- //--------------- // C++ Headers -- //--------------- #include #include using std::cout; using std::endl; using std::ostream; using std::string; //------------------------------- // Collaborating Class Headers -- //------------------------------- #include "ArgList.h" #include "PndFsmResponse.h" #include "PndFsmTrack.h" //----------------------------------------------------------------------- // Local Macros, Typedefs, Structures, Unions and Forward Declarations -- //----------------------------------------------------------------------- //---------------- // Constructors -- //---------------- PndFsmTpc::PndFsmTpc() { initParameters(); _thtMin=_thtMin*M_PI/180.0; _thtMax=_thtMax*M_PI/180.0; print(std::cout); } PndFsmTpc::PndFsmTpc(ArgList &par) { initParameters(); //set default parameter values and parses a parameter list //i.e. std::list of the form //"a=1" "b=2" "c=3" parseParameterList(par); _thtMin=_thtMin*M_PI/180.0; _thtMax=_thtMax*M_PI/180.0; print(std::cout); } //-------------- // Destructor -- //-------------- PndFsmTpc::~PndFsmTpc() { } //-------------- // Operations -- //-------------- PndFsmResponse* PndFsmTpc::respond(PndFsmTrack *t) { PndFsmResponse *result=new PndFsmResponse(); result->setDetector(this); bool wasDetected=detected(t); result->setDetected(wasDetected); if (wasDetected && fabs(t->charge())>1e-8) { result->setdp(dp(t)); result->setdphi(dphi(t)); result->setdtheta(dtheta(t)); // now the dEdx information double mass = _fdbPDG->GetParticle(t->pdt())->Mass(); //*************************************** double p=t->p4().Vect().Mag(); // overall resolution for the tht_c measurement double dEdx = compdEdx(p,mass); double sig = _dEdxRes*dEdx; double m_e = _fdbPDG->GetParticle(11)->Mass(); double m_mu = _fdbPDG->GetParticle(13)->Mass(); double m_pi = _fdbPDG->GetParticle(211)->Mass(); double m_K = _fdbPDG->GetParticle(321)->Mass(); double m_p = _fdbPDG->GetParticle(2212)->Mass(); // compute the expected dEdx values for all particle types // we need these to determine the pdf's (gaussian around nominal dEdx with res sig) double dEdx_e = compdEdx(p,m_e); double dEdx_mu = compdEdx(p,m_mu); double dEdx_pi = compdEdx(p,m_pi); double dEdx_K = compdEdx(p,m_K); double dEdx_p = compdEdx(p,m_p); double measdEdx = _rand->Gaus(dEdx,sig); result ->setTpcdEdx(measdEdx,sig); if (dEdx_e) result->setLHElectron( gauss(measdEdx,dEdx_e,sig) ); if (dEdx_mu) result->setLHMuon( gauss(measdEdx,dEdx_mu,sig) ); if (dEdx_pi) result->setLHPion( gauss(measdEdx,dEdx_pi,sig) ); if (dEdx_K) result->setLHKaon( gauss(measdEdx,dEdx_K,sig) ); if (dEdx_p) result->setLHProton(gauss(measdEdx,dEdx_p,sig) ); } return result; } double PndFsmTpc::gauss(double x, double x0, double s) { return (1.0/(sqrt(2.0*M_PI)*s))* exp(-(x-x0)*(x-x0)/(2.0*s*s)); } double PndFsmTpc::compdEdx(double p, double M) { double dEdX; p*=1000; M*=1000; const double Z=10; const double A=20; const double z=1;//charge of incident particle in unit of e double beta; beta=p/sqrt(M*M+p*p); //CalculateBeta(KE,M); double gamma; gamma=1./sqrt(1-beta*beta); const double I=10e-6*Z;//0.000188;//MeV const double me=0.511;//Mev/c2 double Wmax; Wmax=(2*me*beta*beta*gamma*gamma) / (1 + 2*gamma*me/M + (me/M)*(me/M)); //const double C1=0.1535;//MeV cm2/g double X,X0,X1; double kappa=0.307075; X0=0.201; X1=3; X=log10(beta*gamma); double delta; double C,a; C=-5.217; a=0.196; if(X<=X0) delta=0; else if(X<=X1) delta=2*log(10.)*X+C+a*(X1-X)*(X1-X)*(X1-X); else delta=2*log(10.)*X+C; dEdX= ( kappa * (Z/A) * z*z /(beta*beta)) * (log(2*me*beta*beta*gamma*gamma*Wmax / (I*I)) - 2*beta*beta - delta); //-Dshell?? return dEdX; } bool PndFsmTpc::detected(PndFsmTrack *t) const { if (t->hitMapValid()) { return t->hitMapResponse(FsmDetEnum::Tpc); } else { double theta = t->p4().Theta(); double p = t->p4().Vect().Mag(); double p_t = t->p4().Vect().Pt(); double charge=t->charge(); //only charged particles give signal if (fabs(charge)<0.001) return false; // due to track curvature particle doesn't reach barrel double rho = 3.3356 * p_t / _Bfield; if (_rmin>(2*rho)) return false; //due to helix trajectory particle doesn't hit detector (even with dip angle in tht range) double z=2*rho*asin(_rmin/(2*rho))/tan(theta); double polar=atan2(_rmin,z); if (polar<_thtMin || polar>_thtMax) return false; //finally check for efficiency; return ( _rand->Rndm()<=_efficiency); /* double theta = t->p4().Theta(); double p=t->p4().Vect().Mag(); double charge=t->charge(); return ( charge!=0.0 && theta>=_thtMin && theta<=_thtMax && p>_pmin && _rand->Rndm()<=_efficiency);*/ } } double PndFsmTpc::dp(PndFsmTrack *t) const { double p=t->p4().Vect().Mag(); double Dp=_pRes*p; return ( Dp ); //to be refined } double PndFsmTpc::dphi(PndFsmTrack *t) const { double Dphi=_phiRes*M_PI/180.0; return Dphi; //to be refined } double PndFsmTpc::dtheta(PndFsmTrack *t) const { double dt=_thetaRes*M_PI/180.0; return dt; //to be refined } void PndFsmTpc::print(ostream &o) { o <<"Parameters for detector <"<"<