00001
00002
00003
00004
00005 #include "FastShowerUtils/Samplers/C0EmEcalEc1.h"
00006
00007 #include "FastShowerUtils/ParticleParameters.h"
00008 #include "FastShowerUtils/PolyArgs.h"
00009 #include "FastShowerUtils/IFn.h"
00010 #include "FastShowerUtils/CoreSamples.h"
00011 #include "FastShowerUtils/LinearProcessor.h"
00012 #include "FastShowerUtils/UpdatingGaussian.h"
00013 #include "FastShowerUtils/ProcessedNormal.h"
00014 #include "FastShowerUtils/IInTail.h"
00015 #include "FastShowerUtils/SplitDecision.h"
00016 #include "FastShowerUtils/IConfigurer.h"
00017 #include "CLHEP/Random/RandFlat.h"
00018 #include <cmath>
00019 #include <algorithm>
00020 #include <iostream>
00021
00022 namespace FastShower{
00023
00024 using std::pair;
00025
00026 const double C0EmEcalEc1::s_nSigma1(3.0);
00027 const double C0EmEcalEc1::s_nSigma2(5.0);
00028
00029 const double C0EmEcalEc1::s_tailFluctScale(0.125);
00030
00032 C0EmEcalEc1::C0EmEcalEc1(IUpdatingGaussian* g,
00033 IProcessedDist* t,
00034 IInTail* inTail,
00035 IFn* ts):
00036 ISampler(), ICell0(), DebugBase("C0EmEcalEc1"),
00037 m_peak(g), m_tail(t), m_inTail(inTail), m_tailLowerBound(ts){}
00039 C0EmEcalEc1::C0EmEcalEc1(const IConfigurer* configurer,
00040 const std::string&
00041 ):
00042 DebugBase("C0"), m_peak(0), m_tail(0), m_inTail(0), m_tailLowerBound(0){
00043 m_peak = configurer->findIUG( text()+"Peak" ) ;
00044 m_tail = configurer->makeProcessedFlat( text() );
00045 m_inTail = configurer->makeIInTail( text() );
00046 m_tailLowerBound = configurer->findFn( text()+"TailLowerBound");
00047 cout<<text()<<" finishing construction"<<endl;
00048 }
00050 ISampler* C0EmEcalEc1::clone() const {return new C0EmEcalEc1(*this);}
00052
00053 void C0EmEcalEc1::sample(const PolyArgs& pa, CoreSamples& cs) const{
00054
00055 if( m_inTail->operator()(pa) ){
00056 cs.fill(this, evalTail(pa) );
00057 }else{
00058 cs.fill(this, evalPeak(pa) );
00059 }
00060 }
00062 double C0EmEcalEc1::evalTail(const PolyArgs& pa) const {
00063
00064 pair<double, double> peakParams = m_peak->parameters(pa);
00065 double peakMean = peakParams.first;
00066 double peakSigma = peakParams.second;
00067
00068 double fracBelow01 = 0.0;
00069
00070
00071 double energy = pa.pp()->energy();
00072 double aDelPhi = pa.pp()->delPhi();
00073
00074 fracBelow01 = (0.7-0.03*energy)+(0.3*energy-3.0)*aDelPhi;
00075 fracBelow01 = max(fracBelow01, 0.0);
00076
00077 SplitDecision below01(fracBelow01);
00078 if (below01.lower()) {
00079 double base = 0.1+RandFlat::shoot()*0.05;
00080 return (RandFlat::shoot())*base;
00081 } else {
00082
00083
00084
00085
00086 double uLimit2 = (aDelPhi<0.037)?
00087 min(peakMean+s_nSigma2*peakSigma, 0.99) : 0.99;
00088 uLimit2 = min(uLimit2, 1.0);
00089
00090 double lLimit2 = peakMean + s_nSigma1*peakSigma;
00091 if(lLimit2>uLimit2){lLimit2 = uLimit2-peakSigma;}
00092
00093
00094 double uLimit1 = peakMean - s_nSigma1*peakSigma;
00095
00096 double lLimit1 = uLimit1 - ( m_tailLowerBound->value(pa) );
00097
00098 lLimit1 -= s_tailFluctScale*( RandFlat::shoot() );
00099 if (fracBelow01>0.0) { lLimit1 = max(lLimit1, 0.1); }
00100
00101 lLimit1 = max(lLimit1,0.0);
00102
00103 if(uLimit1<lLimit1){ uLimit1=peakMean;}
00104
00105
00106
00107 double base1 = uLimit1-lLimit1;
00108 double base2 = uLimit2-lLimit2;
00109
00110 SplitDecision sp(0.422-0.002*energy);
00111 if ( sp.lower() ){
00112 LinearProcessor lp(base2,lLimit2);
00113 return m_tail->sample(&lp);
00114 }else{
00115 LinearProcessor lp(base1,lLimit1);
00116 return m_tail->sample(&lp);
00117 }
00118 }
00119 }
00121 double C0EmEcalEc1::evalPeak(const PolyArgs& pa)const{
00122 return m_peak->sample(0.0,s_nSigma1,1.0,s_nSigma1,pa);
00123 }
00125 double C0EmEcalEc1::lastValue(const CoreSamples& cs) const {
00126 return cs.give(this);
00127 }
00128 void C0EmEcalEc1::components(IDebug::Cpts& v) const{
00129 v.push_back(m_peak);
00130 v.push_back(m_tail);
00131 v.push_back(m_inTail);
00132 v.push_back(m_tailLowerBound);
00133 }
00134
00135 }
00136
00137
00138
00139
00140
00141
00142