BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
ParticleSetAccumulator.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2023.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "ParticleSet.hh"
20#include "ParticleSetAccumulator.hh"
21
22#include <cmath>
23#include <string>
24
26
28 n(0),
29 terminated(false),
30 resultHistName(""),
31 resultHistTitle(""),
32 mean(nullptr),
33 variance(nullptr),
34 result(nullptr)
35{;}
36
38 const std::string& resultHistNameIn,
39 const std::string& resultHistTitleIn):
40 n(0),
41 terminated(false),
42 resultHistName(resultHistNameIn),
43 resultHistTitle(resultHistTitleIn),
44 mean(nullptr),
45 variance(nullptr),
46 result(nullptr)
47{
48 std::string meanName = resultHistName + "_Mean";
49 std::string variName = resultHistName + "_Vari";
50 mean = new ParticleSet(*baseParticleSet);
51 variance = new ParticleSet(*baseParticleSet);
52 result = new ParticleSet(*baseParticleSet);
53}
54
56{
57 delete mean;
58 delete variance;
59 delete result;
60}
61
63{
64 // temporary variables
65 double newMean = 0;
66 double newVari = 0;
67 const double error = 0; // needed to pass reference to unused parameter
68 const unsigned long nEntriesToAccumulate = 1;
69
70 n++;
71 for (auto& keyBin : *mean)
72 {
73 AccumulateSingleValue(keyBin.second.value,
74 ((*variance)[keyBin.first]).value,
75 ((*newValue)[keyBin.first]).value,
76 error, n, nEntriesToAccumulate,
77 newMean, newVari);
78 (*mean)[keyBin.first].value = newMean;
79 (*variance)[keyBin.first].sumOfWeightsSquared = newVari;
80 }
81}
82
84{
85 // error on mean is sqrt(1/n) * std = sqrt(1/n) * sqrt(1/(n-1)) * sqrt(variance)
86 // the only variable is the variance, so take the rest out as a factor.
87 const double nD = (double)n; // cast only once
88 const double factor = std::sqrt(1./(nD * (nD - 1))); // nan if n = 1 -> won't be used
89 double mn = 0; // temporary variable for mean
90 double err = 0; // temporary variable for standard error on mean
91 double var = 0; // temporary variable for variance
92
93 // note here we set the std to 0 if there's only one entry (ie n = 1) to avoid
94 // division by zero and nans
95 for (auto& keyBin : *mean)
96 {
97 mn = keyBin.second.value;
98 var = keyBin.second.sumOfWeightsSquared;
99 err = n > 1 ? factor*std::sqrt(var) : 0;
100 (*result)[keyBin.first].value = mn;
101 (*result)[keyBin.first].sumOfWeightsSquared = err;
102 }
103 result->nEntries = n;
104 return result;
105}
106
108 double oldVari,
109 double x,
110 double /*xVari*/,
111 unsigned long nEntriesAccumulated,
112 unsigned long/*nEntriesToAccumulate*/,
113 double& newMean,
114 double& newVari) const
115{
116 newMean = oldMean + ((x - oldMean) / (double)nEntriesAccumulated);
117 newVari = oldVari + ((x - oldMean) * (x - newMean));
118}
Class to accumulate and merge ParticleSets in different ways.
virtual ParticleSet * Terminate()
virtual void AccumulateSingleValue(double oldMean, double oldVari, double x, double xVari, unsigned long nEntriesAccumulated, unsigned long nEntriesToAccumulate, double &newMean, double &newVari) const
ParticleSetAccumulator()
Default constructor only for ROOT reflexivity - not intended for use.
virtual void Accumulate(ParticleSet *newValue)
const std::string resultHistName
Name for resultant histogram.
A very simple 'map' type histogram axis.
Definition: ParticleSet.hh:63