Newer
Older
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
*/
#include "ISF_FastCaloSimEvent/TFCSLateralShapeParametrizationHitChain.h"
#include "ISF_FastCaloSimEvent/FastCaloSim_CaloCell_ID.h"
#include "ISF_FastCaloSimEvent/TFCSSimulationState.h"
//=============================================

Michael Duehrssen-Debling
committed
//======= TFCSLateralShapeParametrizationHitChain =========
//=============================================
TFCSLateralShapeParametrizationHitChain::TFCSLateralShapeParametrizationHitChain(const char* name, const char* title):TFCSLateralShapeParametrization(name,title),m_number_of_hits_simul(nullptr)
{
}
TFCSLateralShapeParametrizationHitChain::TFCSLateralShapeParametrizationHitChain(TFCSLateralShapeParametrizationHitBase* hitsim):TFCSLateralShapeParametrization(TString("hit_chain_")+hitsim->GetName(),TString("hit chain for ")+hitsim->GetTitle()),m_number_of_hits_simul(nullptr)
{

Michael Duehrssen-Debling
committed
set_pdgid_Ekin_eta_Ekin_bin_calosample(*hitsim);
m_chain.push_back(hitsim);
}
void TFCSLateralShapeParametrizationHitChain::set_geometry(ICaloGeometry* geo)
{

Michael Duehrssen-Debling
committed
TFCSLateralShapeParametrization::set_geometry(geo);
if(m_number_of_hits_simul) m_number_of_hits_simul->set_geometry(geo);
}
int TFCSLateralShapeParametrizationHitChain::get_number_of_hits(TFCSSimulationState& simulstate,const TFCSTruthState* truth, const TFCSExtrapolationState* extrapol) const
{
// TODO: should we still do it?
if(m_number_of_hits_simul) {

Michael Duehrssen-Debling
committed
int n=m_number_of_hits_simul->get_number_of_hits(simulstate,truth,extrapol);
if(n<1) n=1;
return n;
}
for(TFCSLateralShapeParametrizationHitBase* hitsim : m_chain) {
int n=hitsim->get_number_of_hits(simulstate,truth,extrapol);

Michael Duehrssen-Debling
committed
if(n>0) return n;
}

Michael Duehrssen-Debling
committed
return 1;
}

Michael Duehrssen-Debling
committed
float TFCSLateralShapeParametrizationHitChain::get_sigma2_fluctuation(TFCSSimulationState& simulstate,const TFCSTruthState* truth, const TFCSExtrapolationState* extrapol) const
{
if(m_number_of_hits_simul) {
double sigma2=m_number_of_hits_simul->get_sigma2_fluctuation(simulstate,truth,extrapol);
if(sigma2>0) return sigma2;
}
for(TFCSLateralShapeParametrizationHitBase* hitsim : m_chain) {
double sigma2=hitsim->get_sigma2_fluctuation(simulstate,truth,extrapol);
if(sigma2>0) return sigma2;
}
//Limit to factor 1000 fluctuations
return 1000;
}
FCSReturnCode TFCSLateralShapeParametrizationHitChain::simulate(TFCSSimulationState& simulstate,const TFCSTruthState* truth, const TFCSExtrapolationState* extrapol)
{
// Call get_number_of_hits() only once, as it could contain a random number
int nhit = get_number_of_hits(simulstate, truth, extrapol);
if (nhit <= 0) {
ATH_MSG_ERROR("TFCSLateralShapeParametrizationHitChain::simulate(): number of hits could not be calculated");
return FCSFatal;
}

Michael Duehrssen-Debling
committed
float Elayer=simulstate.E(calosample());
float Ehit=Elayer/nhit;
float sumEhit=0;
bool debug = msgLvl(MSG::DEBUG);
if (debug) {

Michael Duehrssen-Debling
committed
ATH_MSG_DEBUG("E("<<calosample()<<")="<<simulstate.E(calosample())<<" #hits~"<<nhit);

Michael Duehrssen-Debling
committed
int ihit=0;

Michael Duehrssen-Debling
committed
TFCSLateralShapeParametrizationHitBase::Hit hit;
hit.reset_center();

Michael Duehrssen-Debling
committed
do {
hit.reset();
hit.E()=Ehit;
for(TFCSLateralShapeParametrizationHitBase* hitsim : m_chain) {
if (debug) {

Michael Duehrssen-Debling
committed
if (ihit < 2) hitsim->setLevel(MSG::DEBUG);
else hitsim->setLevel(MSG::INFO);
}
for (int i = 0; i <= FCS_RETRY_COUNT; i++) {

Michael Duehrssen-Debling
committed
//TODO: potentially change logic in case of a retry to redo the whole hit chain from an empty hit instead of just redoing one step in the hit chain
if (i > 0) ATH_MSG_WARNING("TFCSLateralShapeParametrizationHitChain::simulate(): Retry simulate_hit call " << i << "/" << FCS_RETRY_COUNT);
FCSReturnCode status = hitsim->simulate_hit(hit, simulstate, truth, extrapol);

Michael Duehrssen-Debling
committed
if (status == FCSSuccess) {
if(sumEhit+hit.E()>Elayer) hit.E()=Elayer-sumEhit;//sum of all hit energies needs to be Elayer: correct last hit accordingly

Michael Duehrssen-Debling
committed
} else {
if (status == FCSFatal) return FCSFatal;
}
if (i == FCS_RETRY_COUNT) {
ATH_MSG_ERROR("TFCSLateralShapeParametrizationHitChain::simulate(): simulate_hit call failed after " << FCS_RETRY_COUNT << "retries");
}
}
}

Michael Duehrssen-Debling
committed
sumEhit+=hit.E();
++ihit;
if(ihit>10*nhit) {
ATH_MSG_WARNING("TFCSLateralShapeParametrizationHitChain::simulate(): aborting hit chain, iterated " << 10*nhit << " times, expected " << nhit<<" times. Deposited E("<<calosample()<<")="<<sumEhit);
break;
}

Michael Duehrssen-Debling
committed
} while (sumEhit<Elayer);
return FCSSuccess;
}
void TFCSLateralShapeParametrizationHitChain::Print(Option_t *option) const
{
TFCSLateralShapeParametrization::Print(option);
TString opt(option);

Michael Duehrssen-Debling
committed
bool shortprint=opt.Index("short")>=0;
bool longprint=msgLvl(MSG::DEBUG) || (msgLvl(MSG::INFO) && !shortprint);
TString optprint=opt;optprint.ReplaceAll("short","");
if(m_number_of_hits_simul) {

Michael Duehrssen-Debling
committed
if(longprint) ATH_MSG_INFO(optprint <<"#:Number of hits simulation:");
m_number_of_hits_simul->Print(opt+"#:");
}

Michael Duehrssen-Debling
committed
if(longprint) ATH_MSG_INFO(optprint <<"- Simulation chain:");

Michael Duehrssen-Debling
committed
char count='A';
for(TFCSLateralShapeParametrizationHitBase* hitsim : m_chain) {

Michael Duehrssen-Debling
committed
hitsim->Print(opt+count+" ");
count++;