Exemplo n.º 1
0
    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;
    }
Exemplo n.º 2
0
 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;
 }
Exemplo n.º 3
0
 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;
 }
Exemplo n.º 4
0
    void PhotonArray::convolveShuffle(const PhotonArray& rhs, UniformDeviate ud)
    {
        int N = size();
        if (rhs.size() != N)
            throw std::runtime_error("PhotonArray::convolve with unequal size arrays");
        double xSave=0.;
        double ySave=0.;
        double fluxSave=0.;

        for (int iOut = N-1; iOut>=0; iOut--) {
            // Randomly select an input photon to use at this output
            // NB: don't need floor, since rhs is positive, so floor is superfluous.
            int iIn = int((iOut+1)*ud());
            if (iIn > iOut) iIn=iOut;  // should not happen, but be safe
            if (iIn < iOut) {
                // Save input information
                xSave = _x[iOut];
                ySave = _y[iOut];
                fluxSave = _flux[iOut];
            }
            _x[iOut] = _x[iIn] + rhs._x[iOut];
            _y[iOut] = _y[iIn] + rhs._y[iOut];
            _flux[iOut] = _flux[iIn] * rhs._flux[iOut] * N;
            if (iIn < iOut) {
                // Move saved info to new location in array
                _x[iIn] = xSave;
                _y[iIn] = ySave ;
                _flux[iIn] = fluxSave;
            }
        }
    }
Exemplo n.º 5
0
 void PhotonArray::takeYFrom(const PhotonArray& rhs)
 {
     assert(rhs.size()==size());
     int N = size();
     for (int i=0; i<N; i++) {
         _y[i] = rhs._x[i];
         _flux[i] *= rhs._flux[i]*N;
     }
 }
Exemplo n.º 6
0
 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;
 }
Exemplo n.º 7
0
    void PhotonArray::assignAt(int istart, const PhotonArray& rhs)
    {
        if (istart + rhs.size() > size())
            throw std::runtime_error("Trying to assign past the end of PhotonArray");

        std::copy(rhs._x.begin(), rhs._x.end(), _x.begin()+istart);
        std::copy(rhs._y.begin(), rhs._y.end(), _y.begin()+istart);
        std::copy(rhs._flux.begin(), rhs._flux.end(), _flux.begin()+istart);
        if (rhs._dxdz.size() > 0) {
            allocateAngleVectors();
            std::copy(rhs._dxdz.begin(), rhs._dxdz.end(), _dxdz.begin()+istart);
            std::copy(rhs._dydz.begin(), rhs._dydz.end(), _dydz.begin()+istart);
        }
        if (rhs._wavelength.size() > 0) {
            allocateWavelengthVector();
            std::copy(rhs._wavelength.begin(), rhs._wavelength.end(), _wavelength.begin()+istart);
        }
    }
Exemplo n.º 8
0
    void PhotonArray::convolve(const PhotonArray& rhs, UniformDeviate ud)
    {
        // If both arrays have correlated photons, then we need to shuffle the photons
        // as we convolve them.
        if (_is_correlated && rhs._is_correlated) return convolveShuffle(rhs,ud);

        // If neither or only one is correlated, we are ok to just use them in order.
        if (rhs.size() != size())
            throw std::runtime_error("PhotonArray::convolve with unequal size arrays");
        // Add x coordinates:
        std::transform(_x.begin(), _x.end(), rhs._x.begin(), _x.begin(), std::plus<double>());
        // Add y coordinates:
        std::transform(_y.begin(), _y.end(), rhs._y.begin(), _y.begin(), std::plus<double>());
        // Multiply fluxes, with a factor of N needed:
        std::transform(_flux.begin(), _flux.end(), rhs._flux.begin(), _flux.begin(),
                       MultXYScale(size()));

        // If rhs was correlated, then the output will be correlated.
        // This is ok, but we need to mark it as such.
        if (rhs._is_correlated) _is_correlated = true;
    }