Newer
Older

Michael Duehrssen-Debling
committed
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration

Michael Duehrssen-Debling
committed
*/
#include "ISF_FastCaloSimEvent/TFCSLateralShapeParametrizationFluctChain.h"
#include "ISF_FastCaloSimEvent/TFCSSimulationState.h"

Michael Duehrssen-Debling
committed
#include "CLHEP/Random/RandGauss.h"

Michael Duehrssen-Debling
committed
#include "TMath.h"
//=============================================
//======= TFCSLateralShapeParametrizationFluctChain =========
//=============================================
TFCSLateralShapeParametrizationFluctChain::TFCSLateralShapeParametrizationFluctChain(const char* name, const char* title, float RMS):TFCSLateralShapeParametrizationHitChain(name,title), m_RMS(RMS)

Michael Duehrssen-Debling
committed
{
}
TFCSLateralShapeParametrizationFluctChain::TFCSLateralShapeParametrizationFluctChain(TFCSLateralShapeParametrizationHitBase* hitsim):TFCSLateralShapeParametrizationHitChain(hitsim)
{
}
FCSReturnCode TFCSLateralShapeParametrizationFluctChain::simulate(TFCSSimulationState& simulstate,const TFCSTruthState* truth, const TFCSExtrapolationState* extrapol)
{
// Call get_number_of_hits() only once, as it could contain a random number
float sigma2 = get_sigma2_fluctuation(simulstate, truth, extrapol);
if (sigma2 >= s_max_sigma2_fluctuation) {

Michael Duehrssen-Debling
committed
ATH_MSG_ERROR("TFCSLateralShapeParametrizationHitChain::simulate(): fluctuation of hits could not be calculated");
return FCSFatal;
}
//Limit to relative precision of 10^-4=0.01%. ATLAS calorimeter is ~0.1% at best
if(sigma2<1e-8) sigma2=1e-8;
float Elayer=simulstate.E(calosample());
int nhit = 1.0 / sigma2;
//Make a good guess of the needed hit energy, assuming all hits would have the same energy
float Eavghit=Elayer/nhit;

Michael Duehrssen-Debling
committed
float Eavghit_tenth=Eavghit/10;

Michael Duehrssen-Debling
committed
float sumEhit=0;
float error2_sumEhit=0;
float error2=2*s_max_sigma2_fluctuation;

Michael Duehrssen-Debling
committed
bool debug = msgLvl(MSG::DEBUG);
if (debug) {
ATH_MSG_DEBUG("E("<<calosample()<<")="<<Elayer<<" sigma2="<<sigma2);
}
int ihit=0;
int ifail=0;
int itotalfail=0;
TFCSLateralShapeParametrizationHitBase::Hit hit;
hit.reset_center();
do {
hit.reset();

Michael Duehrssen-Debling
committed
//hit.E()=Eavghit;
do {
hit.E()=CLHEP::RandGauss::shoot(simulstate.randomEngine(), Eavghit, m_RMS*Eavghit);
} while (hit.E()<Eavghit_tenth);

Michael Duehrssen-Debling
committed
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
bool failed=false;
for(TFCSLateralShapeParametrizationHitBase* hitsim : m_chain) {
if (debug) {
if (ihit < 2) hitsim->setLevel(MSG::DEBUG);
else hitsim->setLevel(MSG::INFO);
}
FCSReturnCode status = hitsim->simulate_hit(hit, simulstate, truth, extrapol);
if (status == FCSSuccess) continue;
if (status == FCSFatal) return FCSFatal;
failed=true;
++ifail;
++itotalfail;
break;
}
if(!failed) {
ifail=0;
++ihit;
float Ehit=hit.E();
sumEhit+=Ehit;
error2_sumEhit+=Ehit*Ehit;
if(sumEhit>0) error2=error2_sumEhit/(sumEhit*sumEhit);
} else {
if (ifail >= FCS_RETRY_COUNT) {
ATH_MSG_ERROR("TFCSLateralShapeParametrizationFluctChain::simulate(): simulate_hit call failed after " << FCS_RETRY_COUNT << "retries");
}
if(ifail >= FCS_RETRY_COUNT*FCS_RETRY_COUNT) {
return FCSFatal;
}
}
} while (error2>sigma2);
if (debug) {
ATH_MSG_DEBUG("E("<<calosample()<<")="<<Elayer<<" sumE="<<sumEhit<<"+-"<<TMath::Sqrt(error2_sumEhit)<<" ~ "<<TMath::Sqrt(error2_sumEhit)/sumEhit*100<<"% rel error^2="<<error2<<" sigma^2="<<sigma2<<" ~ "<<TMath::Sqrt(sigma2)*100<<"% hits="<<ihit<<" fail="<<itotalfail);
}
return FCSSuccess;
}

Michael Duehrssen-Debling
committed
void TFCSLateralShapeParametrizationFluctChain::Print(Option_t *option) const
{
TString opt(option);
bool shortprint=opt.Index("short")>=0;
bool longprint=msgLvl(MSG::DEBUG) || (msgLvl(MSG::INFO) && !shortprint);
TString optprint=opt;optprint.ReplaceAll("short","");
TFCSLateralShapeParametrizationHitChain::Print(option);
if(longprint) ATH_MSG_INFO(optprint <<" hit energy fluctuation RMS="<<m_RMS);