void SBGaussian::SBGaussianImpl::shoot(PhotonArray& photons, UniformDeviate ud) const { const int N = photons.size(); dbg<<"Gaussian shoot: N = "<<N<<std::endl; dbg<<"Target flux = "<<getFlux()<<std::endl; double fluxPerPhoton = _flux/N; for (int i=0; i<N; i++) { // First get a point uniformly distributed on unit circle #ifdef USE_COS_SIN double theta = 2.*M_PI*ud(); double rsq = ud(); // cumulative dist function P(<r) = r^2 for unit circle double sint,cost; math::sincos(theta, sint, cost); // Then map radius to the desired Gaussian with analytic transformation double rFactor = _sigma * std::sqrt( -2. * std::log(rsq)); photons.setPhoton(i, rFactor*cost, rFactor*sint, fluxPerPhoton); #else double xu, yu, rsq; do { xu = 2.*ud()-1.; yu = 2.*ud()-1.; rsq = xu*xu+yu*yu; } while (rsq>=1. || rsq==0.); // Then map radius to the desired Gaussian with analytic transformation double rFactor = _sigma * std::sqrt( -2. * std::log(rsq) / rsq); photons.setPhoton(i, rFactor*xu, rFactor*yu, fluxPerPhoton); #endif } dbg<<"Gaussian Realized flux = "<<photons.getTotalFlux()<<std::endl; }
void SBAutoConvolve::SBAutoConvolveImpl::shoot(PhotonArray& photons, UniformDeviate ud) const { const int N = photons.size(); dbg<<"AutoConvolve shoot: N = "<<N<<std::endl; dbg<<"Target flux = "<<getFlux()<<std::endl; _adaptee.shoot(photons, ud); PhotonArray temp(N); _adaptee.shoot(temp, ud); photons.convolve(temp, ud); dbg<<"AutoConvolve Realized flux = "<<photons.getTotalFlux()<<std::endl; }
void SBAutoCorrelate::SBAutoCorrelateImpl::shoot(PhotonArray& photons, UniformDeviate ud) const { const int N = photons.size(); dbg<<"AutoCorrelate shoot: N = "<<N<<std::endl; dbg<<"Target flux = "<<getFlux()<<std::endl; _adaptee.shoot(photons, ud); PhotonArray temp(N); _adaptee.shoot(temp, ud); // Flip sign of (x,y) in one of the results temp.scaleXY(-1.); photons.convolve(temp, ud); dbg<<"AutoCorrelate Realized flux = "<<photons.getTotalFlux()<<std::endl; }
void SBConvolve::SBConvolveImpl::shoot(PhotonArray& photons, UniformDeviate ud) const { const int N = photons.size(); dbg<<"Convolve shoot: N = "<<N<<std::endl; dbg<<"Target flux = "<<getFlux()<<std::endl; std::list<SBProfile>::const_iterator pptr = _plist.begin(); if (pptr==_plist.end()) throw SBError("Cannot shoot() for empty SBConvolve"); pptr->shoot(photons, ud); // It may be necessary to shuffle when convolving because we do // do not have a gaurantee that the convolvee's photons are // uncorrelated, e.g. they might both have their negative ones // at the end. // However, this decision is now made by the convolve method. for (++pptr; pptr != _plist.end(); ++pptr) { PhotonArray temp(N); pptr->shoot(temp, ud); photons.convolve(temp, ud); } dbg<<"Convolve Realized flux = "<<photons.getTotalFlux()<<std::endl; }