1 /** Copyright © 2019 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
3 * This library is free software; you can redistribute it and/or modify it under
4 * the terms of the GNU Lesser General Public License as published by the Free
5 * Software Foundation; either version 3.0 of the License, or (at your option)
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 * @file CircularlySymmetricModelComponent.icpp
19 * @date September 1, 2015
20 * @author Nikolaos Apostolakos
23 #include <utility> // for std::forward
24 #include <cmath> // for std::sqrt, std::cos, std::sin
25 #include <tuple> // for std::tie
26 #include <functional> // for std::ref
28 namespace ModelFitting {
30 template <typename Profile>
31 template <typename... ProfileParameters>
32 CircularlySymmetricModelComponent<Profile>::CircularlySymmetricModelComponent(
33 std::unique_ptr<SharpRegionManager> sharp_manager,
34 ProfileParameters&&... proj_parameters)
35 : m_sharp_manager{std::move(sharp_manager)},
36 m_profile(std::forward<ProfileParameters>(proj_parameters)...) {
39 template <typename Profile>
40 CircularlySymmetricModelComponent<Profile>::~CircularlySymmetricModelComponent() = default;
42 template <typename Profile>
43 double CircularlySymmetricModelComponent<Profile>::getValue(double x, double y) {
44 return m_profile(std::sqrt(x*x + y*y));
47 template <typename Profile>
48 void CircularlySymmetricModelComponent<Profile>::updateRasterizationInfo(
49 double scale, double r_max) {
50 m_sharp_manager->updateRasterizationInfo(scale, r_max, std::ref(m_profile));
53 template <typename Profile>
54 auto CircularlySymmetricModelComponent<Profile>::getSharpSampling()
55 -> std::vector<ModelSample> {
56 std::vector<ModelSample> result {};
58 for (double r2=0.; m_sharp_manager->insideSharpRegion(r2); r1=r2) {
60 std::tie(r2, angle_no) = m_sharp_manager->nextRadiusAndAngleNo(r1);
61 double r_half = (r1 + r2) / 2.;
62 double area = M_PI * (r2*r2 - r1*r1);
63 double integral = m_profile(r_half) * area / angle_no;
64 double angle_step = 2 * M_PI / angle_no;
65 for (double angle=0.; angle_no!=0; --angle_no, angle+=angle_step) {
66 double x = r_half * std::cos(angle);
67 double y = r_half * std::sin(angle);
68 result.emplace_back(x, y, integral);
74 template <typename Profile>
75 bool CircularlySymmetricModelComponent<Profile>:: insideSharpRegion(double x, double y) {
76 return m_sharp_manager->insideSharpRegion(std::sqrt(x*x + y*y));
79 } // end of namespace ModelFitting