3#include "FairRootManager.h"
4#include "FairRuntimeDb.h"
5#include "Math/Factory.h"
6#include "Math/Functor.h"
7#include "Math/Minimizer.h"
10#include "TDirectory.h"
12#include <RtypesCore.h>
17#include <fairlogger/Logger.h>
40 std::string_view tracks,
41 std::string_view phits)
42 : FairTask(
"R3BNeulandMultiplicityCalorimetricTrain")
49 , fEdepOffOpt({ 5, 1, 0, 250 })
50 , fNclusterOpt({ 10, 5, 5, 50 })
51 , fNclusterOffOpt({ 2, 1, 0, 10 })
58 for (
auto& nc :
fCuts)
72 auto* ioman = FairRootManager::Instance();
75 LOG(fatal) <<
"R3BNeulandMultiplicityCalorimetricTrain:Init: No FairRootManager";
79 auto* rtdb = FairRuntimeDb::instance();
82 LOG(fatal) <<
"R3BNeulandMultiplicityCalorimetricTrain::Init: No FairRuntimeDb!";
86 rtdb->getContainer(
"R3BNeulandMultiplicityCalorimetricPar"));
89 LOG(fatal) <<
"R3BNeulandMultiplicityCalorimetricTrain::Init: No R3BNeulandMultiplicityCalorimetricPar!";
103 const auto nClusters = clusters.size();
111 std::accumulate(clusters.cbegin(),
114 [](
double sum,
const R3BNeulandCluster& cluster) { return sum + cluster.GetE(); });
116 GetOrBuildHist(nPN)->Fill(
static_cast<int>(std::ceil(Edep)),
static_cast<double>(nClusters));
123 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug))
128 auto* rtdb = FairRuntimeDb::instance();
132 rtdb->writeContainer(
fPar, rtdb->getRun(1),
nullptr);
134 TDirectory* tmp = gDirectory;
135 FairRootManager::Instance()->GetOutFile()->cd();
137 gDirectory->mkdir(
"NeulandMultiplicityCalorimetricTrain");
138 gDirectory->cd(
"NeulandMultiplicityCalorimetricTrain");
150 ROOT::Math::Minimizer* min = ROOT::Math::Factory::CreateMinimizer(
"Genetic");
152 const ROOT::Math::Functor minimizor_functor([&](
const double* cut) {
return WastedEfficiency(cut); }, 4);
153 min->SetFunction(minimizor_functor);
157 min->SetLimitedVariable(
159 min->SetLimitedVariable(
164 LOG(info) <<
"R3BNeulandMultiplicityCalorimetricTrain::Optimize done!";
169 const double edepoff,
170 const double ncluster,
171 const double nclusteroff)
173 if (!
fCuts[nNeutrons])
175 fCuts[nNeutrons] =
new TCutG(TString(std::to_string(nNeutrons)), 4);
176 fCuts.at(nNeutrons)->SetVarX(
"Total Energy [MeV]");
177 fCuts.at(nNeutrons)->SetVarY(
"Number of Clusters");
179 auto cut =
fCuts[nNeutrons];
182 if (nNeutrons ==
fHists.begin()->first)
184 cut->SetPoint(0, -1, -1);
185 cut->SetPoint(1, -1, -1);
189 cut->SetPoint(0, -1, ncluster * (nNeutrons - 1) + nclusteroff);
190 cut->SetPoint(1, edep * (nNeutrons - 1) + edepoff, -1);
194 if (nNeutrons ==
fHists.rbegin()->first)
196 cut->SetPoint(2, 100000, -1);
197 cut->SetPoint(3, -1, 100000);
201 cut->SetPoint(2, edep * nNeutrons + edepoff, -1);
202 cut->SetPoint(3, -1, ncluster * nNeutrons + nclusteroff);
211 double edepoff = d[1];
212 double ncluster = d[2];
213 double nclusteroff = d[3];
215 double wasted_efficiency = 0;
218 const unsigned int nNeutrons = nh.first;
219 const double efficiency =
220 ((double)
GetCut(nNeutrons, edep, edepoff, ncluster, nclusteroff)->IntegralHist(nh.second) /
221 (double)nh.second->GetEntries());
222 wasted_efficiency += (1. - efficiency) * (1. +
fWeight * nNeutrons);
224 return wasted_efficiency;
230 for (
const auto& nh :
fHists)
232 std::cout << nh.first <<
"n\t";
234 std::cout << std::endl;
236 for (
const auto& nc :
fCuts)
238 const unsigned int nOut = nc.first;
239 const TCutG* cut = nc.second;
241 std::cout << nOut <<
"n:\t";
242 for (
const auto& nh :
fHists)
244 std::cout << ((double)cut->IntegralHist(nh.second) / (
double)nh.second->GetEntries()) <<
"\t";
246 std::cout << std::endl;
248 std::cout << std::endl;
255 const TString name =
"hnPN" + std::to_string(i);
256 fHists[i] =
new TH2D(name, name, 150, 0, 5000, 50, 0, 100);
257 fHists.at(i)->GetXaxis()->SetTitle(
"Total Energy [MeV]");
258 fHists.at(i)->GetYaxis()->SetTitle(
"Number of Clusters");
NeuLAND number of clusters / energy - neutron multiplicity parameter storage.
auto Init() -> InitStatus override
~R3BNeulandMultiplicityCalorimetricTrain() override
std::map< unsigned int, TCutG * > fCuts
R3BNeulandMultiplicityCalorimetricTrain(std::string_view clusters="NeulandClusters", std::string_view tracks="NeulandPrimaryTracks", std::string_view phits="NeulandPrimaryHits")
void FinishTask() override
R3B::InputVectorConnector< R3BNeulandHit > fPHits
auto GetCut(unsigned int nNeutrons, double edep, double edepoff, double ncluster, double nclusteroff) -> TCutG *
auto GetOrBuildHist(unsigned int index) -> TH2D *
std::array< double, 4 > fEdepOpt
void Print(Option_t *="") const override
std::array< double, 4 > fNclusterOpt
auto WastedEfficiency(const double *cut) -> double
R3B::InputVectorConnector< R3BMCTrack > fTracks
std::map< unsigned int, TH2D * > fHists
R3B::InputVectorConnector< R3BNeulandCluster > fClusters
std::array< double, 4 > fNclusterOffOpt
void Exec(Option_t *) override
std::array< double, 4 > fEdepOffOpt
R3BNeulandMultiplicityCalorimetricPar * fPar