ATLAS Offline Software
NetworkToHistoTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 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  //weak random function, not used for crypto
36  //coverity[dont_call]
37  std::string li_string = std::format("LayersInfo_{}", rand());
38  TH1D* histoLayersInfo=new TH1D(li_string.c_str(),
39  "LayersInfo",
40  nHidden+2,
41  0,
42  nHidden+2);
43 
44  histoLayersInfo->SetBinContent(1,nInput);
45 
46  for (Int_t i=0;i<nHidden;++i)
47  {
48  histoLayersInfo->SetBinContent(2+i,nHiddenLayerSize[i]);
49  }
50 
51  histoLayersInfo->SetBinContent(2+nHidden,nOutput);
52 
53  //underflow for linear output
54  if (trainedNetwork->getIfLinearOutput()){
55  histoLayersInfo->SetBinContent(0,1);
56  }
57  //overflow for normalized output (Pott nodes)
58  if (trainedNetwork->getIfNormalizeOutput()){
59  histoLayersInfo->SetBinContent(nHidden+3,1);
60  }
61 
62 
63  outputHistos["LayersInfo"] = histoLayersInfo;
64 
65  //ThresholdInfo
66  for (Int_t i=0;i<nHidden+1;++i)
67  {
68  std::string threName = std::format("Layer{}_thresholds", i);
69 
70  Int_t layerSize=(i<nHidden)?nHiddenLayerSize[i]:nOutput;
71  Int_t previousLayerSize=(i==0)?nInput:nHiddenLayerSize[i-1];
72  //weak random function, not used for crypto
73  //coverity[dont_call]
74  std::string th_str = std::format("{}_{}", threName, rand());
75 
76  TH1D* histoThreshLayer=new TH1D(th_str.c_str(),
77  threName.c_str(),
78  layerSize,
79  0,
80  layerSize);
81 
82  for (Int_t s=0;s<layerSize;s++)
83  {
84  histoThreshLayer->SetBinContent(s+1,(*thresholdVectors[i])(s));
85  }
86 
87  std::string weightsName = std::format("Layer{}_weights", i);
88 
89  outputHistos[threName] = histoThreshLayer;
90  //weak random function, not used for crypto
91  //coverity[dont_call]
92  std::string wt_str = std::format("{}_{}", weightsName, rand());
93  TH2D* histoWeightsLayer=new TH2D(wt_str.c_str(),
94  weightsName.c_str(),
95  previousLayerSize,
96  0,
97  previousLayerSize,
98  layerSize,
99  0,
100  layerSize);
101 
102  for (Int_t s=0;s<layerSize;s++)
103  {
104  for (Int_t p=0;p<previousLayerSize;++p)
105  {
106  histoWeightsLayer->SetBinContent(p+1,s+1,(*weightMatrices[i])(p,s));
107  }
108  }
109 
110  outputHistos[weightsName] = histoWeightsLayer;
111 
112  }
113 
114  using Input = TTrainedNetwork::Input;
115  std::vector<Input> inputs = trainedNetwork->getInputs();
116 
117  if (inputs.empty()) {
118  return outputHistos;
119  }
120  assert(inputs.size() == nInput);
121  //weak random function, not used for crypto
122  //coverity[dont_call]
123  std::string ii_str = std::format("InputsInfo_{}", rand());
124  TH2D* histoInputs = new TH2D(ii_str.c_str(), "InputsInfo",
125  nInput, 0, 1,
126  2, 0, 1);
127 
128  for (unsigned input_n = 0; input_n < nInput; input_n++ ) {
129  Input input = inputs.at(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());
133  }
134  outputHistos["InputsInfo"] = histoInputs;
135 
136  return outputHistos;
137 
138 }
139 
140 
142 NetworkToHistoTool::networkFromHists(const std::map<std::string,const TH1*>& inputHistos)
143 
144 {
145  auto getHist = [&inputHistos] (const std::string& name) -> const TH1*
146  {
147  auto it = inputHistos.find (name);
148  if (it == inputHistos.end()) return nullptr;
149  return it->second;
150  };
151 
152  const TH1* histoLayersInfo = getHist ("LayersInfo");
153 
154  if (histoLayersInfo==nullptr)
155  {
156  throw std::runtime_error(" Could not find LayersInfo histogram...");
157  }
158 
159 
160  Int_t nHidden=histoLayersInfo->GetNbinsX()-2;
161  unsigned nInput = static_cast<unsigned>
162  (std::floor(histoLayersInfo->GetBinContent(1)+0.5));
163 
164  std::vector<Int_t> nHiddenLayerSize;
165  nHiddenLayerSize.reserve(nHidden);
166 
167 for (Int_t i=0;i<nHidden;++i)
168  {
169  nHiddenLayerSize.push_back( (Int_t)std::floor
170  (histoLayersInfo->GetBinContent(2+i)+0.5));
171  }
172 
173  Int_t nOutput=(Int_t)std::floor
174  (histoLayersInfo->GetBinContent(2+nHidden)+0.5);
175 
176  unsigned options = 0;
177  if (histoLayersInfo->GetBinContent(0)>0.5)
178  {
180  }
181  if (histoLayersInfo->GetBinContent(nHidden+3)>0.5)
182  {
184  }
185 
186 
187  std::vector<TVectorD*> thresholdVectors;
188  std::vector<TMatrixD*> weightMatrices;
189 
190 
191  //Reconstruct thresholdInfo
192  for (Int_t i=0;i<nHidden+1;++i)
193  {
194  std::string threName = std::format("Layer{}_thresholds", i);
195 
196  Int_t layerSize=(i<nHidden)?nHiddenLayerSize[i]:nOutput;
197  Int_t previousLayerSize=(i==0)?nInput:nHiddenLayerSize[i-1];
198 
199  TVectorD* thresholdVector=new TVectorD(layerSize);
200  TMatrixD* weightMatrix=new TMatrixD(previousLayerSize,layerSize);
201 
202  const TH1* histoThreshLayer = getHist (threName);
203  if (!histoThreshLayer)
204  throw std::runtime_error("could not find " + threName);
205 
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);
209  }
210 
211  for (Int_t s=0;s<layerSize;s++)
212  {
213  (*thresholdVector)(s) = histoThreshLayer->GetBinContent(s+1);
214  }
215 
216  std::string weightsName = std::format("Layer{}_weights", i);
217 
218  const TH1* histoWeightsLayer = getHist (weightsName);
219  if (!histoWeightsLayer) {
220  throw std::runtime_error("could not find " + weightsName);
221  }
222 
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);
226  }
227 
228 
229  for (Int_t s=0;s<layerSize;s++)
230  {
231  for (Int_t p=0;p<previousLayerSize;++p)
232  {
233  (*weightMatrix)(p,s) = histoWeightsLayer->GetBinContent(p+1,s+1);
234  }
235  }
236 
237  thresholdVectors.push_back(thresholdVector);
238  weightMatrices.push_back(weightMatrix);
239 
240  }
241 
242  const TH1* histoInputs = getHist ("InputsInfo");
243  std::vector<TTrainedNetwork::Input> inputs;
244  if (!histoInputs) {
245  inputs.resize(nInput);
246  }
247  else {
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);
252  inputs.emplace_back(name, offset, scale);
253  }
254  }
255  TTrainedNetwork* trainedNetwork =
257  nOutput,
258  thresholdVectors,
259  weightMatrices,
261  options);
262  return trainedNetwork;
263 
264 }
265 
266 std::vector<TH1*> NetworkToHistoTool
267 ::fromTrainedNetworkToHisto(const TTrainedNetwork* net)
268 {
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);
275  }
276  return hist_vec;
277 }
278 
279 TTrainedNetwork* NetworkToHistoTool
280 ::fromHistoToTrainedNetwork(const std::vector<TH1*>& hists)
281 {
282  std::map<std::string, const TH1*> hist_map;
283  for (const TH1* h : hists) {
284  hist_map[h->GetName()] = h;
285  }
286  return networkFromHists(hist_map);
287 }
288 
289 TTrainedNetwork* NetworkToHistoTool
290 ::fromHistoToTrainedNetwork(const std::vector<const TH1*>& hists)
291 {
292  std::map<std::string, const TH1*> hist_map;
293  for (const TH1* h : hists) {
294  hist_map[h->GetName()] = h;
295  }
296  return networkFromHists(hist_map);
297 }
TTrainedNetwork::getnInput
Int_t getnInput() const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.h:46
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:407
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
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
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:209
LArG4FSStartPointFilter.rand
rand
Definition: LArG4FSStartPointFilter.py:80
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:183
lumiFormat.i
int i
Definition: lumiFormat.py:85
extractSporadic.h
list h
Definition: extractSporadic.py:96
MakeTH3DFromTH2Ds.hists
hists
Definition: MakeTH3DFromTH2Ds.py:72
python.AtlRunQueryLib.options
options
Definition: AtlRunQueryLib.py:378
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
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
module_driven_slicing.getHist
def getHist(name, makehist)
Definition: module_driven_slicing.py:120
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
trigbs_mixBSevents.input
input
Definition: trigbs_mixBSevents.py:56
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
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