ATLAS Offline Software
NetworkToHistoTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <TH1D.h>
6 #include <TH2D.h>
8 #include "TrkNeuralNetworkUtils/NetworkToHistoTool.hh"
9 #include <cmath>
10 #include <stdexcept>
11 #include <cassert>
12 #include <cstdlib> // rand
13 #include <format>
14 
15 std::map<std::string,TH1*>
16 NetworkToHistoTool::histsFromNetwork(const TTrainedNetwork* trainedNetwork)
17 
18 {
19 
20  std::map<std::string,TH1*> outputHistos;
21 
22 
23  assert(trainedNetwork->getActivationFunction() == 1);
24 
25  unsigned nInput=trainedNetwork->getnInput();
26  std::vector<Int_t> nHiddenLayerSize=trainedNetwork->getnHiddenLayerSize();
27  Int_t nHidden=nHiddenLayerSize.size();
28 
29  Int_t nOutput=trainedNetwork->getnOutput();
30 
31  std::vector<TVectorD*> thresholdVectors=trainedNetwork->getThresholdVectors();
32  std::vector<TMatrixD*> weightMatrices=trainedNetwork->weightMatrices();
33 
34  //LayersInfo
35  std::string li_string = std::format("LayersInfo_{}", rand());
36  TH1D* histoLayersInfo=new TH1D(li_string.c_str(),
37  "LayersInfo",
38  nHidden+2,
39  0,
40  nHidden+2);
41 
42  histoLayersInfo->SetBinContent(1,nInput);
43 
44  for (Int_t i=0;i<nHidden;++i)
45  {
46  histoLayersInfo->SetBinContent(2+i,nHiddenLayerSize[i]);
47  }
48 
49  histoLayersInfo->SetBinContent(2+nHidden,nOutput);
50 
51  //underflow for linear output
52  if (trainedNetwork->getIfLinearOutput()){
53  histoLayersInfo->SetBinContent(0,1);
54  }
55  //overflow for normalized output (Pott nodes)
56  if (trainedNetwork->getIfNormalizeOutput()){
57  histoLayersInfo->SetBinContent(nHidden+3,1);
58  }
59 
60 
61  outputHistos["LayersInfo"] = histoLayersInfo;
62 
63  //ThresholdInfo
64  for (Int_t i=0;i<nHidden+1;++i)
65  {
66  std::string threName = std::format("Layer{}_thresholds", i);
67 
68  Int_t layerSize=(i<nHidden)?nHiddenLayerSize[i]:nOutput;
69  Int_t previousLayerSize=(i==0)?nInput:nHiddenLayerSize[i-1];
70 
71  std::string th_str = std::format("{}_{}", threName, rand());
72 
73  TH1D* histoThreshLayer=new TH1D(th_str.c_str(),
74  threName.c_str(),
75  layerSize,
76  0,
77  layerSize);
78 
79  for (Int_t s=0;s<layerSize;s++)
80  {
81  histoThreshLayer->SetBinContent(s+1,(*thresholdVectors[i])(s));
82  }
83 
84  std::string weightsName = std::format("Layer{}_weights", i);
85 
86  outputHistos[threName] = histoThreshLayer;
87 
88  std::string wt_str = std::format("{}_{}", weightsName, rand());
89  TH2D* histoWeightsLayer=new TH2D(wt_str.c_str(),
90  weightsName.c_str(),
91  previousLayerSize,
92  0,
93  previousLayerSize,
94  layerSize,
95  0,
96  layerSize);
97 
98  for (Int_t s=0;s<layerSize;s++)
99  {
100  for (Int_t p=0;p<previousLayerSize;++p)
101  {
102  histoWeightsLayer->SetBinContent(p+1,s+1,(*weightMatrices[i])(p,s));
103  }
104  }
105 
106  outputHistos[weightsName] = histoWeightsLayer;
107 
108  }
109 
110  using Input = TTrainedNetwork::Input;
111  std::vector<Input> inputs = trainedNetwork->getInputs();
112 
113  if (inputs.empty()) {
114  return outputHistos;
115  }
116  assert(inputs.size() == nInput);
117 
118  std::string ii_str = std::format("InputsInfo_{}", rand());
119  TH2D* histoInputs = new TH2D(ii_str.c_str(), "InputsInfo",
120  nInput, 0, 1,
121  2, 0, 1);
122 
123  for (unsigned input_n = 0; input_n < nInput; input_n++ ) {
124  Input input = inputs.at(input_n);
125  histoInputs->SetBinContent(input_n + 1, 1, input.offset);
126  histoInputs->SetBinContent(input_n + 1, 2, input.scale);
127  histoInputs->GetXaxis()->SetBinLabel(input_n + 1, input.name.c_str());
128  }
129  outputHistos["InputsInfo"] = histoInputs;
130 
131  return outputHistos;
132 
133 }
134 
135 
137 NetworkToHistoTool::networkFromHists(const std::map<std::string,const TH1*>& inputHistos)
138 
139 {
140  auto getHist = [&inputHistos] (const std::string& name) -> const TH1*
141  {
142  auto it = inputHistos.find (name);
143  if (it == inputHistos.end()) return nullptr;
144  return it->second;
145  };
146 
147  const TH1* histoLayersInfo = getHist ("LayersInfo");
148 
149  if (histoLayersInfo==nullptr)
150  {
151  throw std::runtime_error(" Could not find LayersInfo histogram...");
152  }
153 
154 
155  Int_t nHidden=histoLayersInfo->GetNbinsX()-2;
156  unsigned nInput = static_cast<unsigned>
157  (std::floor(histoLayersInfo->GetBinContent(1)+0.5));
158 
159  std::vector<Int_t> nHiddenLayerSize;
160  nHiddenLayerSize.reserve(nHidden);
161 
162 for (Int_t i=0;i<nHidden;++i)
163  {
164  nHiddenLayerSize.push_back( (Int_t)std::floor
165  (histoLayersInfo->GetBinContent(2+i)+0.5));
166  }
167 
168  Int_t nOutput=(Int_t)std::floor
169  (histoLayersInfo->GetBinContent(2+nHidden)+0.5);
170 
171  unsigned options = 0;
172  if (histoLayersInfo->GetBinContent(0)>0.5)
173  {
175  }
176  if (histoLayersInfo->GetBinContent(nHidden+3)>0.5)
177  {
179  }
180 
181 
182  std::vector<TVectorD*> thresholdVectors;
183  std::vector<TMatrixD*> weightMatrices;
184 
185 
186  //Reconstruct thresholdInfo
187  for (Int_t i=0;i<nHidden+1;++i)
188  {
189  std::string threName = std::format("Layer{}_thresholds", i);
190 
191  Int_t layerSize=(i<nHidden)?nHiddenLayerSize[i]:nOutput;
192  Int_t previousLayerSize=(i==0)?nInput:nHiddenLayerSize[i-1];
193 
194  TVectorD* thresholdVector=new TVectorD(layerSize);
195  TMatrixD* weightMatrix=new TMatrixD(previousLayerSize,layerSize);
196 
197  const TH1* histoThreshLayer = getHist (threName);
198  if (!histoThreshLayer)
199  throw std::runtime_error("could not find " + threName);
200 
201  if (layerSize != histoThreshLayer->GetNbinsX()) {
202  std::string err = std::format("inconsistency between LayersInfo and {} found: LayersInfo reports {} layers, {} has {} bins", threName, layerSize, threName, histoThreshLayer->GetNbinsX());
203  throw std::runtime_error(err);
204  }
205 
206  for (Int_t s=0;s<layerSize;s++)
207  {
208  (*thresholdVector)(s) = histoThreshLayer->GetBinContent(s+1);
209  }
210 
211  std::string weightsName = std::format("Layer{}_weights", i);
212 
213  const TH1* histoWeightsLayer = getHist (weightsName);
214  if (!histoWeightsLayer) {
215  throw std::runtime_error("could not find " + weightsName);
216  }
217 
218  if (layerSize != histoWeightsLayer->GetNbinsY()) {
219  std::string err = std::format("inconsistency between LayersInfo and {} found: LayersInfo reports {} layers, {} has {} bins", weightsName, layerSize, weightsName, histoWeightsLayer->GetNbinsY());
220  throw std::runtime_error(err);
221  }
222 
223 
224  for (Int_t s=0;s<layerSize;s++)
225  {
226  for (Int_t p=0;p<previousLayerSize;++p)
227  {
228  (*weightMatrix)(p,s) = histoWeightsLayer->GetBinContent(p+1,s+1);
229  }
230  }
231 
232  thresholdVectors.push_back(thresholdVector);
233  weightMatrices.push_back(weightMatrix);
234 
235  }
236 
237  const TH1* histoInputs = getHist ("InputsInfo");
238  std::vector<TTrainedNetwork::Input> inputs;
239  if (!histoInputs) {
240  for (unsigned i = 0 ; i < nInput; i++) {
241  TTrainedNetwork::Input the_input;
242  the_input.offset = 0;
243  // setting all scales to zero disables normalized output
244  the_input.scale = 0;
245  inputs.push_back(the_input);
246  }
247  }
248  else {
249  for (unsigned i = 0 ; i < nInput; i++) {
250  TTrainedNetwork::Input the_input;
251  the_input.name = histoInputs->GetXaxis()->GetBinLabel(i + 1);
252  the_input.offset = histoInputs->GetBinContent(i + 1, 1);
253  the_input.scale = histoInputs->GetBinContent(i + 1, 2);
254  inputs.push_back(the_input);
255  }
256  }
257  TTrainedNetwork* trainedNetwork =
259  nOutput,
260  thresholdVectors,
261  weightMatrices,
263  options);
264  return trainedNetwork;
265 
266 }
267 
268 std::vector<TH1*> NetworkToHistoTool
269 ::fromTrainedNetworkToHisto(const TTrainedNetwork* net)
270 {
271  std::map<std::string, TH1*> hists = histsFromNetwork(net);
272  std::vector<TH1*> hist_vec;
273  for (std::map<std::string, TH1*>::const_iterator itr = hists.begin();
274  itr != hists.end(); ++itr) {
275  itr->second->SetName(itr->first.c_str());
276  hist_vec.push_back(itr->second);
277  }
278  return hist_vec;
279 }
280 
281 TTrainedNetwork* NetworkToHistoTool
282 ::fromHistoToTrainedNetwork(const std::vector<TH1*>& hists)
283 {
284  std::map<std::string, const TH1*> hist_map;
285  for (const TH1* h : hists) {
286  hist_map[h->GetName()] = h;
287  }
288  return networkFromHists(hist_map);
289 }
290 
291 TTrainedNetwork* NetworkToHistoTool
292 ::fromHistoToTrainedNetwork(const std::vector<const TH1*>& hists)
293 {
294  std::map<std::string, const TH1*> hist_map;
295  for (const TH1* h : hists) {
296  hist_map[h->GetName()] = h;
297  }
298  return networkFromHists(hist_map);
299 }
TTrainedNetwork::Input
Definition: Tracking/TrkUtilityPackages/TrkNeuralNetworkUtils/TrkNeuralNetworkUtils/TTrainedNetwork.h:37
TTrainedNetwork::getnInput
Int_t getnInput() const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:46
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
vtune_athena.format
format
Definition: vtune_athena.py:14
TTrainedNetwork::getActivationFunction
Int_t getActivationFunction() const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:54
skel.it
it
Definition: skel.GENtoEVGEN.py:396
TTrainedNetwork::Input::offset
double offset
Definition: Tracking/TrkUtilityPackages/TrkNeuralNetworkUtils/TrkNeuralNetworkUtils/TTrainedNetwork.h:39
TTrainedNetwork::getnHiddenLayerSize
const std::vector< Int_t > & getnHiddenLayerSize() const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:52
TTrainedNetwork::getIfNormalizeOutput
bool getIfNormalizeOutput() const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:64
postInclude.inputs
inputs
Definition: postInclude.SortInput.py:15
TTrainedNetwork::weightMatrices
const std::vector< TMatrixD * > & weightMatrices() const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:58
TTrainedNetwork::getInputs
std::vector< Input > getInputs() const
Definition: Tracking/TrkUtilityPackages/TrkNeuralNetworkUtils/src/TTrainedNetwork.cxx:163
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
LArG4FSStartPointFilter.rand
rand
Definition: LArG4FSStartPointFilter.py:80
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:182
lumiFormat.i
int i
Definition: lumiFormat.py:85
extractSporadic.h
list h
Definition: extractSporadic.py:97
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
TTrainedNetwork::Input::scale
double scale
Definition: Tracking/TrkUtilityPackages/TrkNeuralNetworkUtils/TrkNeuralNetworkUtils/TTrainedNetwork.h:40
MakeTH3DFromTH2Ds.hists
hists
Definition: MakeTH3DFromTH2Ds.py:72
python.AtlRunQueryLib.options
options
Definition: AtlRunQueryLib.py:379
TTrainedNetwork::getThresholdVectors
const std::vector< TVectorD * > & getThresholdVectors() const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:56
TTrainedNetwork
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:21
TTrainedNetwork.h
TTrainedNetwork::Input::name
std::string name
Definition: Tracking/TrkUtilityPackages/TrkNeuralNetworkUtils/TrkNeuralNetworkUtils/TTrainedNetwork.h:38
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
module_driven_slicing.getHist
def getHist(name, makehist)
Definition: module_driven_slicing.py:121
TTrainedNetwork::SIGMOID
@ SIGMOID
Definition: Tracking/TrkUtilityPackages/TrkNeuralNetworkUtils/TrkNeuralNetworkUtils/TTrainedNetwork.h:34
TTrainedNetwork::normalizeOutput
static const unsigned normalizeOutput
Definition: Tracking/TrkUtilityPackages/TrkNeuralNetworkUtils/TrkNeuralNetworkUtils/TTrainedNetwork.h:31
h
TTrainedNetwork::getIfLinearOutput
bool getIfLinearOutput() const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:62
TTrainedNetwork::getnOutput
Int_t getnOutput() const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:50
NswErrorCalibData::Input
Helper struct to be parsed to the object to derive the specific error of the cluster.
Definition: NswErrorCalibData.h:25
Input
NswErrorCalibData::Input Input
Definition: NswErrorCalibData.cxx:6
TTrainedNetwork::linearOutput
static const unsigned linearOutput
Definition: Tracking/TrkUtilityPackages/TrkNeuralNetworkUtils/TrkNeuralNetworkUtils/TTrainedNetwork.h:30