SourceXtractorPlusPlus  0.13
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FlexibleModelFittingParameter.cpp
Go to the documentation of this file.
1 
17 /*
18  * FlexibleModelFittingParameter.cpp
19  *
20  * Created on: Oct 8, 2018
21  * Author: mschefer
22  */
23 
24 #include <iostream>
25 
26 #include <boost/version.hpp>
27 #if BOOST_VERSION >= 106700
28 
29 #if BOOST_VERSION >= 107000
30 #include <boost/math/differentiation/finite_difference.hpp>
31 namespace bmd = boost::math::differentiation;
32 #else
33 #include <boost/math/tools/numerical_differentiation.hpp>
34 namespace bmd = boost::math::tools;
35 #endif
36 
37 #endif
38 
44 
45 #include "SEUtils/Python.h"
47 
49 
51 
55 
56 
58 
59 
60 namespace SourceXtractor {
61 
62 using namespace ModelFitting;
63 
65 
67  return m_id;
68 }
69 
71  : FlexibleModelFittingParameter(id), m_value(value) { }
72 
74  FlexibleModelFittingParameterManager& /*parameter_manager*/,
75  ModelFitting::EngineParameterManager& /*engine_manager*/,
76  const SourceInterface& source) const {
77  return std::make_shared<ManualParameter>(m_value(source));
78 }
79 
81  FlexibleModelFittingParameterManager& /*parameter_manager*/,
83  const SourceInterface& source) const {
84  double initial_value = m_initial_value(source);
85 
86  auto converter = m_converter_factory->getConverter(initial_value, source);
87  auto parameter = std::make_shared<EngineParameter>(initial_value, std::move(converter));
88  engine_manager.registerParameter(parameter);
89 
90  return parameter;
91 }
92 
94  const std::vector<double>& free_parameter_sigmas) const {
95  auto modelfitting_parameter = parameter_manager.getParameter(source, shared_from_this());
96  return free_parameter_sigmas[parameter_manager.getParameterIndex(source, shared_from_this())];
97 }
98 
99 
100 namespace {
101 
102 template <typename T>
103 double doubleResolver(const T&) {
104  return 0;
105 }
106 
107 
108 template<typename ... Parameters>
109 std::shared_ptr<ModelFitting::BasicParameter> createDependentParameterHelper(
110  FlexibleModelFittingParameterManager& parameter_manager,
111  const SourceInterface& source,
113  std::shared_ptr<Parameters>... parameters) {
114  auto coordinate_system = source.getProperty<DetectionFrameCoordinates>().getCoordinateSystem();
115 
116  auto calc = [value_calculator, coordinate_system] (decltype(doubleResolver(std::declval<Parameters>()))... params) -> double {
117  std::vector<double> materialized{params...};
118  return value_calculator(coordinate_system, materialized);
119  };
120  return createDependentParameter(calc, parameter_manager.getParameter(source, parameters)...);
121 }
122 
123 }
124 
125 
127  FlexibleModelFittingParameterManager& parameter_manager,
129  const SourceInterface& source) const {
130  switch (m_parameters.size()) {
131  case 1:
132  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
133  m_parameters[0]);
134  case 2:
135  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
136  m_parameters[0], m_parameters[1]);
137  case 3:
138  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
140  case 4:
141  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
143  case 5:
144  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
146  case 6:
147  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
149  m_parameters[5]);
150  case 7:
151  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
153  m_parameters[5], m_parameters[6]);
154  case 8:
155  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
158  case 9:
159  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
162  case 10:
163  return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
166  }
167  throw Elements::Exception() << "Dependent parameters can depend on maximum 10 other parameters";
168 }
169 
171  const SourceInterface& source, const std::vector<double>& param_values) const {
172  assert(param_values.size() == m_parameters.size());
173 
174  std::vector<double> result(param_values.size());
175  auto cs = source.getProperty<DetectionFrameCoordinates>().getCoordinateSystem();
176 
177  for (unsigned int i = 0; i < result.size(); i++) {
178 
179  auto f = [&](double x) {
180  auto params = param_values;
181  params[i] = x;
182  return m_value_calculator(cs, params);
183  };
184 
185 #if BOOST_VERSION >= 106700
186  result[i] = bmd::finite_difference_derivative(f, param_values[i]);
187 #else
188  // if boost's function is unavailable use our own function
189  result[i] = NumericalDerivative::centralDifference(f, param_values[i]);
190 #endif
191  }
192 
193  return result;
194 }
195 
197  const std::vector<double>& free_parameter_sigmas) const {
198  auto dependees = getDependees();
199  std::vector<double> values;
200 
201  for (auto& dependee : dependees) {
202  values.emplace_back(parameter_manager.getParameter(source, dependee)->getValue());
203  }
204 
205  double sigma = 0.0;
206  auto partial_derivatives = getPartialDerivatives(source, values);
207 
208  assert(dependees.size() == partial_derivatives.size());
209  for (unsigned int i = 0; i < partial_derivatives.size(); i++) {
210  auto dependee_sigma = dependees[i]->getSigma(parameter_manager, source, free_parameter_sigmas);
211  sigma += partial_derivatives[i] * partial_derivatives[i] * dependee_sigma * dependee_sigma;
212  }
213  sigma = sqrt(sigma);
214 
215  return sigma;
216 }
217 
218 }
const PropertyType & getProperty(unsigned int index=0) const
Convenience template method to call getProperty() with a more user-friendly syntax.
std::vector< double > getPartialDerivatives(const SourceInterface &source, const std::vector< double > &param_values) const
std::function< double(const std::shared_ptr< CoordinateSystem > &, const std::vector< double > &)> ValueFunc
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
int getParameterIndex(std::shared_ptr< ModelFitting::BasicParameter > engine_parameter) const
double getSigma(FlexibleModelFittingParameterManager &parameter_manager, const SourceInterface &source, const std::vector< double > &free_parameter_sigmas) const override
std::shared_ptr< DependentParameter< Parameters...> > createDependentParameter(typename DependentParameter< Parameters...>::ValueCalculator value_calculator, Parameters...parameters)
std::shared_ptr< ModelFitting::BasicParameter > create(FlexibleModelFittingParameterManager &parameter_manager, ModelFitting::EngineParameterManager &engine_manager, const SourceInterface &source) const override
double getSigma(FlexibleModelFittingParameterManager &parameter_manager, const SourceInterface &source, const std::vector< double > &free_parameter_sigmas) const override
std::shared_ptr< ModelFitting::BasicParameter > create(FlexibleModelFittingParameterManager &parameter_manager, ModelFitting::EngineParameterManager &engine_manager, const SourceInterface &source) const override
static Elements::Logging logger
std::shared_ptr< ModelFitting::BasicParameter > create(FlexibleModelFittingParameterManager &parameter_manager, ModelFitting::EngineParameterManager &engine_manager, const SourceInterface &source) const override
std::shared_ptr< FlexibleModelFittingConverterFactory > m_converter_factory
void registerParameter(std::shared_ptr< EngineParameter > parameter)
Registers an EngineParameter to the EngineParameterManager.
T move(T...args)
T size(T...args)
const std::vector< std::shared_ptr< FlexibleModelFittingParameter > > & getDependees() const
std::shared_ptr< ModelFitting::BasicParameter > getParameter(const SourceInterface &source, std::shared_ptr< const FlexibleModelFittingParameter > parameter) const
Class responsible for managing the parameters the least square engine minimizes.
std::vector< std::shared_ptr< FlexibleModelFittingParameter > > m_parameters
T sqrt(T...args)
The SourceInterface is an abstract &quot;source&quot; that has properties attached to it.
static Logging getLogger(const std::string &name="")
static double centralDifference(std::function< double(double)> f, double x)
T emplace_back(T...args)