00001 #include "FastShowerUtils/HaloDepositor.h"
00002 #include "FastShowerUtils/IDeposits.h"
00003 #include "FastShowerUtils/IConfigurer.h"
00004 #include "FastShowerUtils/ParticleParameters.h"
00005 #include "FastShowerUtils/Normalisations.h"
00006 #include "FastShowerUtils/IFnOfParticleParameters.h"
00007 #include "FastShowerUtils/LinearProcessor.h"
00008 #include "FastShowerUtils/TriangleProcessor.h"
00009 #include "FastShowerUtils/ProcessedFlat.h"
00010 #include <boost/array.hpp>
00011 #include <cmath>
00012 #include <numeric>
00013 #include <vector>
00014 #include <iostream>
00015 #include <iomanip>
00016 #include <iterator>
00017 #include <algorithm>
00018 #include <strstream>
00019
00020 namespace FastShower{
00022
00023
00024
00026
00041
00042 public:
00043 CalcPeak(const ParticleParameters& pp,
00044 HaloDepositor::HaloFnsIter hfIter ):m_pp(pp), m_hfIter(hfIter){}
00045 double operator()(){
00046 m_sp.setBoundary( (*m_hfIter++)->value(m_pp) );
00047 if(m_sp.lower()){
00048 LinearProcessor lp(0.01, 0.0);
00049 return m_pf.sample(&lp);
00050 }else{
00051 TriangleProcessor tp(1.0, 0.01);
00052 return m_pf.sample(&tp);
00053 }
00054 }
00055 private:
00056 const ParticleParameters& m_pp;
00057 SplitDecision m_sp;
00058 ProcessedFlat m_pf;
00059 HaloDepositor::HaloFnsIter m_hfIter;
00060 };
00061 class ApplyNorm{
00062 public:
00063 ApplyNorm(double norm):m_norm(norm){}
00064 void operator()(double& proxDep){
00065 proxDep *= m_norm;
00066 }
00067 private:
00068 double m_norm;
00069 };
00070 class GreaterThanOne{
00071 public:
00072 bool operator()(double arg){return arg>1.0;}
00073 };
00074 class HaloProxToGeom{
00076 public:
00077
00078 HaloProxToGeom(HaloDepositor::HaloDepIter pdIter, IDeposits& deposits):
00079 m_proxIter(pdIter), m_deposits(deposits){}
00080
00081 void operator()(std::pair<int, int> geom){
00082
00083
00084 m_deposits.accept(geom.first, geom.second, *m_proxIter++);
00085 }
00086
00087 private:
00088 HaloDepositor::HaloDepIter m_proxIter;
00089 IDeposits& m_deposits;
00090 };
00091 class PrintFnValue{
00093
00094 public:
00095 PrintFnValue(const ParticleParameters& pp):m_pp(pp){}
00096 void operator()(IFnOfParticleParameters* f){
00097 cout<<( f->value(m_pp) )<<" ";
00098 }
00099 private:
00100 const ParticleParameters& m_pp;
00101 };
00102
00103 template<class T>
00104 class PrintValues{
00105 public:
00106 void operator()(T iter, const T& end){
00107 cout<<setiosflags(ios::fixed);
00108 for(;iter!=end; ++iter){cout<<setw(4)<<setprecision(3)<<*iter<<" ";}
00109 cout<<endl;
00110 }
00111 };
00112
00114
00115
00116
00118
00119
00120 HaloDepositor::HaloDepositor(const IConfigurer* c, const std::string& s):
00121 IDepositor(),DebugBase(s){
00122
00124 cout<<"HaloDepositor: setting HaloOrder"<<endl;
00125 int order[14]={7, 6, 0, 8, 4, 1, 3, 13, 5, 10, 2, 11, 9, 12};
00126 for (std::size_t i=0; i<s_nHaloCells; ++i){
00127 m_order.push_back(order[i]);
00128 }
00129 assert(m_order.size() == s_nHaloCells);
00130
00132 cout<<"HaloDepositor: getting HaloFns"<<endl;
00133 for (int i=1; i<=14; ++i){
00134 std::ostrstream no;
00135 no<<i<<ends;
00136 m_fns.push_back(c->findFnPP( text()+"Cell"+no.str() ));
00137 }
00138 assert(m_fns.size() == s_nHaloCells);
00139
00140 cout<<"HaloDepositor: done with the configurer"<<endl;
00142 array<pair<int, int>, 14> q0, q1, q2, q3;
00143
00145
00146 q0[1] =pair<int, int>( 2, 1);
00147 q0[2] =pair<int, int>( 2, 2);
00148 q0[3] =pair<int, int>( 1, 2);
00149 q0[4] =pair<int, int>( 0, 2);
00150 q0[5] =pair<int, int>( -1, 2);
00151 q0[6] =pair<int, int>( -1, 1);
00152 q0[7] =pair<int, int>( -1, 0);
00153 q0[8] =pair<int, int>( -1, -1);
00154 q0[9] =pair<int, int>( -1, -2);
00155 q0[10]=pair<int, int>( 0, -2);
00156 q0[11]=pair<int, int>( 1, -2);
00157 q0[12]=pair<int, int>( 2, -2);
00158 q0[13]=pair<int, int>( 2, -1);
00159 assert(q0.size() == s_nHaloCells);
00160 m_mappers[0]=q0;
00161
00162 q1[0] =pair<int, int>( -2, 0);
00163 q1[1] =pair<int, int>( -2, 1);
00164 q1[2] =pair<int, int>( -2, 2);
00165 q1[3] =pair<int, int>( -1, 2);
00166 q1[4] =pair<int, int>( 0, 2);
00167 q1[5] =pair<int, int>( 1, 2);
00168 q1[6] =pair<int, int>( 1, 1);
00169 q1[7] =pair<int, int>( 1, 0);
00170 q1[8] =pair<int, int>( 1, -1);
00171 q1[9] =pair<int, int>( 1, -2);
00172 q1[10]=pair<int, int>( 0, -2);
00173 q1[11]=pair<int, int>( -1, -2);
00174 q1[12]=pair<int, int>( -2, -2);
00175 q1[13]=pair<int, int>( -2, -1);
00176 assert(q1.size() == s_nHaloCells);
00177 m_mappers[1]=q1;
00178
00179 q2[0] =pair<int, int>( -2, 0);
00180 q2[1] =pair<int, int>( -2, -1);
00181 q2[2] =pair<int, int>( -2, -2);
00182 q2[3] =pair<int, int>( -1, -2);
00183 q2[4] =pair<int, int>( 0, -2);
00184 q2[5] =pair<int, int>( 1, -2);
00185 q2[6] =pair<int, int>( 1, -1);
00186 q2[7] =pair<int, int>( 1, 0);
00187 q2[8] =pair<int, int>( 1, 1);
00188 q2[9] =pair<int, int>( 1, 2);
00189 q2[10]=pair<int, int>( 0, 2);
00190 q2[11]=pair<int, int>( -1, 2);
00191 q2[12]=pair<int, int>( -2, 2);
00192 q2[13]=pair<int, int>( -2, 1);
00193 assert(q2.size() == s_nHaloCells);
00194 m_mappers[2]=q2;
00195
00196 q3[0] =pair<int, int>( 2, 0);
00197 q3[1] =pair<int, int>( 2, -1);
00198 q3[2] =pair<int, int>( 2, -2);
00199 q3[3] =pair<int, int>( 1, -2);
00200 q3[4] =pair<int, int>( 0, -2);
00201 q3[5] =pair<int, int>( -1, -2);
00202 q3[6] =pair<int, int>( -1, -1);
00203 q3[7] =pair<int, int>( -1, 0);
00204 q3[8] =pair<int, int>( -1, 1);
00205 q3[9] =pair<int, int>( -1, 2);
00206 q3[10]=pair<int, int>( 0, 2);
00207 q3[11]=pair<int, int>( 1, 2);
00208 q3[12]=pair<int, int>( 2, 2);
00209 q3[13]=pair<int, int>( 2, 1);
00210 assert(q3.size() == s_nHaloCells);
00211 m_mappers[3]=q3;
00212
00213 }
00214 HaloDepositor::~HaloDepositor(){};
00215 void HaloDepositor::deposit(const ParticleParameters& pp,
00216 const Normalisations& ns,
00217 IDeposits& geomDeposits) {
00219 HaloDeposits proximDeps(s_nHaloCells);
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 std::generate(proximDeps.begin(),
00233 proximDeps.end(),
00234 CalcPeak(pp, m_fns.begin() )
00235 );
00236
00237
00238
00239
00240
00241
00242 double eDep = 0.0;
00243 eDep = accumulate(proximDeps.begin(), proximDeps.end(), eDep);
00244
00245
00246
00247
00248
00249 if(eDep<=1.0){
00251 assert(eDep>0.001);
00252 HaloDepIter hdi = proximDeps.begin();
00253 for(; hdi != proximDeps.end(); *hdi++ *= 1/eDep ){}
00254
00255 }else{
00258
00259 HaloDeposits shuffledDeps(s_nHaloCells);
00260 this->invShuffle(proximDeps, shuffledDeps);
00261
00262 HaloDeposits sumDeps(s_nHaloCells);
00263 std::partial_sum(
00264 shuffledDeps.begin(),
00265 shuffledDeps.end(),
00266 sumDeps.begin()
00267 );
00268
00269
00270
00271
00272 HaloDepIter where =
00273 std::find_if(sumDeps.begin(), sumDeps.end(), GreaterThanOne());
00274
00275 HaloDepIter shdIter = shuffledDeps.begin()+(where-sumDeps.begin());
00276
00277 *shdIter++ -= (*where)-1.;
00278 for(; shdIter!=shuffledDeps.end(); *shdIter++=0.){}
00279
00280 this->shuffle(shuffledDeps, proximDeps);
00281 }
00282
00283
00284
00285
00287 double depSum=0.;
00288 assert(abs(std::accumulate(proximDeps.begin(),
00289 proximDeps.end(),
00290 depSum)
00291 )-1.0<0.001);
00292
00293
00294 std::for_each(proximDeps.begin(), proximDeps.end(), ApplyNorm(ns.halo()));
00295
00296
00297
00298 std::for_each(
00299 m_mappers[pp.quadrant()].begin(),
00300 m_mappers[pp.quadrant()].end(),
00301 HaloProxToGeom( proximDeps.begin(), geomDeposits )
00302 );
00303
00304 }
00305
00306 void HaloDepositor::shuffle(const HaloDeposits& src,
00307 HaloDeposits& dest) const{
00308 HaloDepCIter sI;
00309 HaloArrCIter oI;
00310 for(sI = src.begin(), oI= m_order.begin(); sI != src.end(); ++sI, ++oI){
00311 dest[*oI] = *sI;
00312 }
00313 }
00314
00315 void HaloDepositor::invShuffle(const HaloDeposits& src,
00316 HaloDeposits& dest) const{
00317 HaloDepIter dI;
00318 HaloArrCIter oI;
00319 for(dI = dest.begin(), oI= m_order.begin(); dI != dest.end(); ++dI, ++oI){
00320 *dI = src[*oI];
00321 }
00322 }
00323
00324 IDepositor* HaloDepositor::clone() const{
00325 IDepositor* id = new HaloDepositor(*this);
00326 return id;
00327 }
00328 void HaloDepositor::components(IDebug::Cpts& v)const{
00329 v.clear();
00330 HaloFnsCIter itr;
00331 for (itr = m_fns.begin(); itr != m_fns.end(); ++itr) {
00332 v.push_back(*itr);
00333 }
00334 }
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347