8 #include "TrkNeuralNetworkUtils/NetworkToHistoTool.hh"
15 std::map<std::string,TH1*>
16 NetworkToHistoTool::histsFromNetwork(
const TTrainedNetwork* trainedNetwork)
20 std::map<std::string,TH1*> outputHistos;
25 unsigned nInput=trainedNetwork->
getnInput();
27 Int_t nHidden=nHiddenLayerSize.size();
32 std::vector<TMatrixD*> weightMatrices=trainedNetwork->
weightMatrices();
38 TH1D* histoLayersInfo=
new TH1D(li_string.c_str(),
44 histoLayersInfo->SetBinContent(1,nInput);
46 for (Int_t
i=0;
i<nHidden;++
i)
48 histoLayersInfo->SetBinContent(2+
i,nHiddenLayerSize[
i]);
51 histoLayersInfo->SetBinContent(2+nHidden,nOutput);
55 histoLayersInfo->SetBinContent(0,1);
59 histoLayersInfo->SetBinContent(nHidden+3,1);
63 outputHistos[
"LayersInfo"] = histoLayersInfo;
66 for (Int_t
i=0;
i<nHidden+1;++
i)
68 std::string threName =
std::format(
"Layer{}_thresholds",
i);
70 Int_t layerSize=(
i<nHidden)?nHiddenLayerSize[
i]:nOutput;
71 Int_t previousLayerSize=(
i==0)?nInput:nHiddenLayerSize[
i-1];
76 TH1D* histoThreshLayer=
new TH1D(th_str.c_str(),
82 for (Int_t
s=0;
s<layerSize;
s++)
84 histoThreshLayer->SetBinContent(
s+1,(*thresholdVectors[
i])(
s));
87 std::string weightsName =
std::format(
"Layer{}_weights",
i);
89 outputHistos[threName] = histoThreshLayer;
93 TH2D* histoWeightsLayer=
new TH2D(wt_str.c_str(),
102 for (Int_t
s=0;
s<layerSize;
s++)
104 for (Int_t
p=0;
p<previousLayerSize;++
p)
106 histoWeightsLayer->SetBinContent(
p+1,
s+1,(*weightMatrices[
i])(
p,
s));
110 outputHistos[weightsName] = histoWeightsLayer;
120 assert(
inputs.size() == nInput);
124 TH2D* histoInputs =
new TH2D(ii_str.c_str(),
"InputsInfo",
128 for (
unsigned input_n = 0; input_n < nInput; input_n++ ) {
130 histoInputs->SetBinContent(input_n + 1, 1,
input.offset);
131 histoInputs->SetBinContent(input_n + 1, 2,
input.scale);
132 histoInputs->GetXaxis()->SetBinLabel(input_n + 1,
input.name.c_str());
134 outputHistos[
"InputsInfo"] = histoInputs;
142 NetworkToHistoTool::networkFromHists(
const std::map<std::string,const TH1*>& inputHistos)
145 auto getHist = [&inputHistos] (
const std::string&
name) ->
const TH1*
147 auto it = inputHistos.find (
name);
148 if (
it == inputHistos.end())
return nullptr;
152 const TH1* histoLayersInfo =
getHist (
"LayersInfo");
154 if (histoLayersInfo==
nullptr)
156 throw std::runtime_error(
" Could not find LayersInfo histogram...");
160 Int_t nHidden=histoLayersInfo->GetNbinsX()-2;
161 unsigned nInput =
static_cast<unsigned>
162 (std::floor(histoLayersInfo->GetBinContent(1)+0.5));
164 std::vector<Int_t> nHiddenLayerSize;
165 nHiddenLayerSize.reserve(nHidden);
167 for (Int_t
i=0;
i<nHidden;++
i)
169 nHiddenLayerSize.push_back( (Int_t)std::floor
170 (histoLayersInfo->GetBinContent(2+
i)+0.5));
173 Int_t nOutput=(Int_t)std::floor
174 (histoLayersInfo->GetBinContent(2+nHidden)+0.5);
177 if (histoLayersInfo->GetBinContent(0)>0.5)
181 if (histoLayersInfo->GetBinContent(nHidden+3)>0.5)
187 std::vector<TVectorD*> thresholdVectors;
188 std::vector<TMatrixD*> weightMatrices;
192 for (Int_t
i=0;
i<nHidden+1;++
i)
194 std::string threName =
std::format(
"Layer{}_thresholds",
i);
196 Int_t layerSize=(
i<nHidden)?nHiddenLayerSize[
i]:nOutput;
197 Int_t previousLayerSize=(
i==0)?nInput:nHiddenLayerSize[
i-1];
199 TVectorD* thresholdVector=
new TVectorD(layerSize);
200 TMatrixD* weightMatrix=
new TMatrixD(previousLayerSize,layerSize);
202 const TH1* histoThreshLayer =
getHist (threName);
203 if (!histoThreshLayer)
204 throw std::runtime_error(
"could not find " + threName);
206 if (layerSize != histoThreshLayer->GetNbinsX()) {
207 std::string
err =
std::format(
"inconsistency between LayersInfo and {} found: LayersInfo reports {} layers, {} has {} bins", threName, layerSize, threName, histoThreshLayer->GetNbinsX());
208 throw std::runtime_error(
err);
211 for (Int_t
s=0;
s<layerSize;
s++)
213 (*thresholdVector)(
s) = histoThreshLayer->GetBinContent(
s+1);
216 std::string weightsName =
std::format(
"Layer{}_weights",
i);
218 const TH1* histoWeightsLayer =
getHist (weightsName);
219 if (!histoWeightsLayer) {
220 throw std::runtime_error(
"could not find " + weightsName);
223 if (layerSize != histoWeightsLayer->GetNbinsY()) {
224 std::string
err =
std::format(
"inconsistency between LayersInfo and {} found: LayersInfo reports {} layers, {} has {} bins", weightsName, layerSize, weightsName, histoWeightsLayer->GetNbinsY());
225 throw std::runtime_error(
err);
229 for (Int_t
s=0;
s<layerSize;
s++)
231 for (Int_t
p=0;
p<previousLayerSize;++
p)
233 (*weightMatrix)(
p,
s) = histoWeightsLayer->GetBinContent(
p+1,
s+1);
237 thresholdVectors.push_back(thresholdVector);
238 weightMatrices.push_back(weightMatrix);
242 const TH1* histoInputs =
getHist (
"InputsInfo");
243 std::vector<TTrainedNetwork::Input>
inputs;
248 for (
unsigned i = 0 ;
i < nInput;
i++) {
249 const auto &
name = histoInputs->GetXaxis()->GetBinLabel(
i + 1);
250 const auto &
offset = histoInputs->GetBinContent(
i + 1, 1);
251 const auto &
scale = histoInputs->GetBinContent(
i + 1, 2);
262 return trainedNetwork;
266 std::vector<TH1*> NetworkToHistoTool
269 std::map<std::string, TH1*>
hists = histsFromNetwork(net);
270 std::vector<TH1*> hist_vec;
271 for (std::map<std::string, TH1*>::const_iterator itr =
hists.begin();
272 itr !=
hists.end(); ++itr) {
273 itr->second->SetName(itr->first.c_str());
274 hist_vec.push_back(itr->second);
280 ::fromHistoToTrainedNetwork(
const std::vector<TH1*>&
hists)
282 std::map<std::string, const TH1*> hist_map;
283 for (
const TH1*
h :
hists) {
284 hist_map[
h->GetName()] =
h;
286 return networkFromHists(hist_map);
290 ::fromHistoToTrainedNetwork(
const std::vector<const TH1*>&
hists)
292 std::map<std::string, const TH1*> hist_map;
293 for (
const TH1*
h :
hists) {
294 hist_map[
h->GetName()] =
h;
296 return networkFromHists(hist_map);