//-------------------------------------------------------------------------- // File and Version Information: // $Id: FsmDrcBarrel.cc,v 1.9 2007/05/24 08:07:40 klausg Exp $ // // Description: // Class FsmDrcBarrel // // Implementation of the barrel DIRC 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 "PndFsmDrcBarrel.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 -- //---------------- PndFsmDrcBarrel::PndFsmDrcBarrel() { initParameters(); _thtMin=_thtMin*M_PI/180.0; _thtMax=_thtMax*M_PI/180.0; print(std::cout); } PndFsmDrcBarrel::PndFsmDrcBarrel(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 -- //-------------- PndFsmDrcBarrel::~PndFsmDrcBarrel() { } //-------------- // Operations -- //-------------- PndFsmResponse* PndFsmDrcBarrel::respond(PndFsmTrack *t) { PndFsmResponse *result=new PndFsmResponse(); result->setDetector(this); bool wasDetected=detected(t); result->setDetected(wasDetected); if (wasDetected && fabs(t->charge())>1e-8) { double mass =_fdbPDG->GetParticle(t->pdt())->Mass(); double theta = t->p4().Theta(); double p=t->p4().Vect().Mag(); double stht=sin(theta); double p_t=p*stht; if ( p==0 || p_t==0 || stht==0 ) {result->setDetected(false);return result;} // floating point check ******************** double lambda1 = 280e-9; //range of wavelength, which is seen by the PMT/PD double lambda2 = 330e-9; double alpha=7.2974e-3; //finestructure constant // curvature of track due to magnet field double r = 3.3356 * p_t / _Bfield; if (_rBarrel>(2*r)) {result->setDetected(false);return result;} // floating point check ******************** // dip angle in phi direction (due to curvature of track in magnet field) double psi = acos(_rBarrel/(2*r)); // path length in radiator double tpsi=tan(psi); if ( tpsi==0 ) {result->setDetected(false);return result;} // floating point check ******************** double l = _dSlab*sqrt( 1/(stht*stht) + 1/(tpsi*tpsi) ); // estimate the number of cherenkov photons hitting our photosensor double nPhot = _effNPhotons*2*M_PI*alpha*l*(1./lambda1 - 1./lambda2)*(1 - (mass*mass+p*p)/(p*p*_nRefrac*_nRefrac)); nPhot = _rand->Poisson(nPhot); // ************** reset detected and quit due to low numbers of photons if (nPhot<=_nPhotMin) { result->setDetected(false); return result; } if (nPhot>100) nPhot=100; // overall resolution for the tht_c measurement double sig = _dthtc/sqrt(nPhot); double thtC = compThetaC(p,mass); 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 cherenkov angles for all particle types // we need these to determine the pdf's (gaussian around nominal tht_c with res sig) double thtc_e = compThetaC(p,m_e); double thtc_mu = compThetaC(p,m_mu); double thtc_pi = compThetaC(p,m_pi); double thtc_K = compThetaC(p,m_K); double thtc_p = compThetaC(p,m_p); double measThetaC = _rand->Gaus(thtC,sig); result->setDrcBarrelThtc(measThetaC); if (thtc_e) result->setLHElectron( gauss(measThetaC,thtc_e,sig) ); if (thtc_mu) result->setLHMuon( gauss(measThetaC,thtc_mu,sig) ); if (thtc_pi) result->setLHPion( gauss(measThetaC,thtc_pi,sig) ); if (thtc_K) result->setLHKaon( gauss(measThetaC,thtc_K,sig) ); if (thtc_p) result->setLHProton(gauss(measThetaC,thtc_p,sig) ); } return result; } double PndFsmDrcBarrel::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 PndFsmDrcBarrel::compThetaC(double p, double m) { double val=0.0; if (p==0) return 0.0; if ( (val = (p*p+m*m)/(p*p*_nRefrac*_nRefrac)) <= 1.0 ) return acos(sqrt(val)); else return 0.0; } bool PndFsmDrcBarrel::detected(PndFsmTrack *t) const { if (t->hitMapValid()) { return t->hitMapResponse(FsmDetEnum::Drc); } else { int lundId=abs(t->pdt()); double mass = _fdbPDG->GetParticle(t->pdt())->Mass(); //*************************************** // double mass = t->pdt()->mass(); double p_cerenkov_min=mass/sqrt(_nRefrac*_nRefrac - 1.0); double theta = t->p4().Theta(); double p=t->p4().Vect().Mag(); double p_t=p*sin(theta); //double p_t=t->p4().vect().perp(Hep3Vector(0.,0.,1.)); //double charge=t->charge(); bool correctPidType=false; if (lundId==11 || lundId==13 || lundId==211 || lundId==321 || lundId==2212) correctPidType=true; return ( p_t>_pmin && p>p_cerenkov_min && theta>=_thtMin && theta<=_thtMax && correctPidType && _rand->Rndm()<=_efficiency); } } void PndFsmDrcBarrel::print(ostream &o) { o <<"Parameters for detector <"<"<