3#include "FairRootManager.h"
4#include "FairRuntimeDb.h"
5#include "Math/Factory.h"
6#include "Math/Functor.h"
7#include "Math/Minimizer.h"
29 std::string_view tracks,
30 std::string_view phits)
31 : FairTask(
"R3BNeulandMultiplicityCalorimetricTrain")
34 , fPHits(std::move(phits))
37 , fEdepOpt({ 200, 25, 50, 1500 })
38 , fEdepOffOpt({ 5, 1, 0, 250 })
39 , fNclusterOpt({ 10, 5, 5, 50 })
40 , fNclusterOffOpt({ 2, 1, 0, 10 })
47 for (
auto& nc : fCuts)
61 auto* ioman = FairRootManager::Instance();
64 LOG(fatal) <<
"R3BNeulandMultiplicityCalorimetricTrain:Init: No FairRootManager";
68 auto* rtdb = FairRuntimeDb::instance();
71 LOG(fatal) <<
"R3BNeulandMultiplicityCalorimetricTrain::Init: No FairRuntimeDb!";
75 rtdb->getContainer(
"R3BNeulandMultiplicityCalorimetricPar"));
78 LOG(fatal) <<
"R3BNeulandMultiplicityCalorimetricTrain::Init: No R3BNeulandMultiplicityCalorimetricPar!";
89 const int nPN = fUseHits ? fPHits.get().size() : fTracks.get().size();
91 const auto& clusters = fClusters.get();
92 const auto nClusters = clusters.size();
100 std::accumulate(clusters.cbegin(),
103 [](
double sum,
const R3BNeulandCluster& cluster) { return sum + cluster.GetE(); });
105 GetOrBuildHist(nPN)->Fill(
static_cast<int>(std::ceil(Edep)),
static_cast<double>(nClusters));
112 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug))
117 auto* rtdb = FairRuntimeDb::instance();
119 fPar->SetNeutronCuts(fCuts);
121 rtdb->writeContainer(fPar, rtdb->getRun(1),
nullptr);
123 TDirectory* tmp = gDirectory;
124 FairRootManager::Instance()->GetOutFile()->cd();
126 gDirectory->mkdir(
"NeulandMultiplicityCalorimetricTrain");
127 gDirectory->cd(
"NeulandMultiplicityCalorimetricTrain");
129 for (
auto& nh : fHists)
137void R3BNeulandMultiplicityCalorimetricTrain::Optimize()
139 ROOT::Math::Minimizer* min = ROOT::Math::Factory::CreateMinimizer(
"Genetic");
141 ROOT::Math::Functor minimizor_functor([&](
const double* cut) {
return WastedEfficiency(cut); }, 4);
142 min->SetFunction(minimizor_functor);
144 min->SetLimitedVariable(0,
"edep", fEdepOpt.at(0), fEdepOpt.at(1), fEdepOpt.at(2), fEdepOpt.at(3));
145 min->SetLimitedVariable(1,
"edepoff", fEdepOffOpt.at(0), fEdepOffOpt.at(1), fEdepOffOpt.at(2), fEdepOffOpt.at(3));
146 min->SetLimitedVariable(
147 2,
"ncluster", fNclusterOpt.at(0), fNclusterOpt.at(1), fNclusterOpt.at(2), fNclusterOpt.at(3));
148 min->SetLimitedVariable(
149 3,
"nclusteroff", fNclusterOffOpt.at(0), fNclusterOffOpt.at(1), fNclusterOffOpt.at(2), fNclusterOffOpt.at(3));
153 LOG(info) <<
"R3BNeulandMultiplicityCalorimetricTrain::Optimize done!";
156TCutG* R3BNeulandMultiplicityCalorimetricTrain::GetCut(
const unsigned int nNeutrons,
158 const double edepoff,
159 const double ncluster,
160 const double nclusteroff)
162 if (!fCuts[nNeutrons])
164 fCuts[nNeutrons] =
new TCutG(TString(std::to_string(nNeutrons)), 4);
165 fCuts.at(nNeutrons)->SetVarX(
"Total Energy [MeV]");
166 fCuts.at(nNeutrons)->SetVarY(
"Number of Clusters");
168 auto cut = fCuts[nNeutrons];
171 if (nNeutrons == fHists.begin()->first)
173 cut->SetPoint(0, -1, -1);
174 cut->SetPoint(1, -1, -1);
178 cut->SetPoint(0, -1, ncluster * (nNeutrons - 1) + nclusteroff);
179 cut->SetPoint(1, edep * (nNeutrons - 1) + edepoff, -1);
183 if (nNeutrons == fHists.rbegin()->first)
185 cut->SetPoint(2, 100000, -1);
186 cut->SetPoint(3, -1, 100000);
190 cut->SetPoint(2, edep * nNeutrons + edepoff, -1);
191 cut->SetPoint(3, -1, ncluster * nNeutrons + nclusteroff);
197double R3BNeulandMultiplicityCalorimetricTrain::WastedEfficiency(
const double* d)
200 double edepoff = d[1];
201 double ncluster = d[2];
202 double nclusteroff = d[3];
204 double wasted_efficiency = 0;
205 for (
auto& nh : fHists)
207 const unsigned int nNeutrons = nh.first;
208 const double efficiency =
209 ((double)GetCut(nNeutrons, edep, edepoff, ncluster, nclusteroff)->IntegralHist(nh.second) /
210 (double)nh.second->GetEntries());
211 wasted_efficiency += (1. - efficiency) * (1. + fWeight * nNeutrons);
213 return wasted_efficiency;
219 for (
const auto& nh : fHists)
221 std::cout << nh.first <<
"n\t";
223 std::cout << std::endl;
225 for (
const auto& nc : fCuts)
227 const unsigned int nOut = nc.first;
228 const TCutG* cut = nc.second;
230 std::cout << nOut <<
"n:\t";
231 for (
const auto& nh : fHists)
233 std::cout << ((double)cut->IntegralHist(nh.second) / (
double)nh.second->GetEntries()) <<
"\t";
235 std::cout << std::endl;
237 std::cout << std::endl;
240TH2D* R3BNeulandMultiplicityCalorimetricTrain::GetOrBuildHist(
const unsigned int i)
242 if (fHists.find(i) == fHists.end())
244 const TString name =
"hnPN" + std::to_string(i);
245 fHists[i] =
new TH2D(name, name, 150, 0, 5000, 50, 0, 100);
246 fHists.at(i)->GetXaxis()->SetTitle(
"Total Energy [MeV]");
247 fHists.at(i)->GetYaxis()->SetTitle(
"Number of Clusters");
NeuLAND number of clusters / energy - neutron multiplicity parameter storage.
auto Init() -> InitStatus override
~R3BNeulandMultiplicityCalorimetricTrain() override
R3BNeulandMultiplicityCalorimetricTrain(std::string_view clusters="NeulandClusters", std::string_view tracks="NeulandPrimaryTracks", std::string_view phits="NeulandPrimaryHits")
void FinishTask() override
void Print(Option_t *="") const override
void Exec(Option_t *) override